diff --git a/.travis.yml b/.travis.yml index 184c62fae..9cf181bf9 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,7 +3,7 @@ sudo: false install: true before_install: - cd PlanPluginBridge - - mvn install:install-file -Dfile=./PlanPluginBridge-4.4.0.jar -DpomFile=./pom.xml + - mvn install:install-file -Dfile=./PlanPluginBridge-4.5.0.jar -DpomFile=./pom.xml - cd ../Plan install: - mvn clean diff --git a/Plan/dependency-reduced-pom.xml b/Plan/dependency-reduced-pom.xml index 4a214d000..1112e4a87 100644 --- a/Plan/dependency-reduced-pom.xml +++ b/Plan/dependency-reduced-pom.xml @@ -3,7 +3,7 @@ 4.0.0 com.djrapitops Plan - 4.3.0-SNAPSHOT + 4.5.0-SNAPSHOT ${basedir}/src/main/java ${basedir}/src/test/java @@ -20,6 +20,7 @@ **/*.js **/*.css locale/*.txt + **/*.ico @@ -31,6 +32,23 @@ 1.8 1.8 + + + com.google.dagger + dagger-compiler + 2.17 + + + com.velocitypowered + velocity-api + 1.0-SNAPSHOT + + + org.spongepowered + spongeapi + 7.1.0 + + @@ -58,6 +76,7 @@ org.mockito:* org.easymock:* junit:* + org.slf4j:* @@ -80,10 +99,6 @@ com.zaxxer plan.com.zaxxer - - org.slf4j - plan.org.slf4j - org.bstats com.djrapitops.plan.utilities.metrics @@ -147,9 +162,13 @@ https://repo.spongepowered.org/maven - md_5-snapshots - http://repo.md-5.net/content/repositories/snapshots/ + velocity-repo + https://repo.velocitypowered.com/snapshots/ + + md_5-snapshots + http://repo.md-5.net/content/repositories/snapshots/ + bstats-repo http://repo.bstats.org/content/repositories/releases/ @@ -293,71 +312,109 @@ - org.spongepowered - spongeapi - 7.0.0 - provided - - - error_prone_annotations - com.google.errorprone - - - guice - com.google.inject - - - guava - com.github.ben-manes.caffeine - - - plugin-meta - org.spongepowered - - - configurate-hocon - ninja.leaping.configurate - - - configurate-gson - ninja.leaping.configurate - - - configurate-yaml - ninja.leaping.configurate - - - flow-math - com.flowpowered - - - flow-noise - com.flowpowered - - - jsr305 - com.google.code.findbugs - - - asm - org.ow2.asm - - - gson - com.google.code.gson - - - guava - com.google.guava - - + com.velocitypowered + velocity-api + 1.0-SNAPSHOT + provided + + + text + net.kyori + + + toml4j + com.moandjiezana.toml + + + guice + com.google.inject + + + checker-qual + org.checkerframework + + + gson + com.google.code.gson + + + guava + com.google.guava + + + + org.spongepowered + spongeapi + 7.1.0 + provided + + + error_prone_annotations + com.google.errorprone + + + guava + com.github.ben-manes.caffeine + + + plugin-meta + org.spongepowered + + + configurate-hocon + org.spongepowered + + + configurate-gson + org.spongepowered + + + configurate-yaml + org.spongepowered + + + flow-math + com.flowpowered + + + flow-noise + com.flowpowered + + + jsr305 + com.google.code.findbugs + + + guice + com.google.inject + + + asm + org.ow2.asm + + + gson + com.google.code.gson + + + guava + com.google.guava + + + com.imaginarycode.minecraft RedisBungee 0.3.8-SNAPSHOT provided + + org.slf4j + slf4j-nop + 1.7.25 + runtime + org.mockito mockito-core diff --git a/Plan/pom.xml b/Plan/pom.xml index 316381126..112cf59c4 100644 --- a/Plan/pom.xml +++ b/Plan/pom.xml @@ -4,7 +4,7 @@ 4.0.0 com.djrapitops Plan - 4.3.0-SNAPSHOT + 4.5.0-SNAPSHOT jar @@ -24,6 +24,10 @@ sponge-repo https://repo.spongepowered.org/maven + + velocity-repo + https://repo.velocitypowered.com/snapshots/ + md_5-snapshots @@ -41,13 +45,13 @@ com.djrapitops AbstractPluginFramework - 3.2.0 + 3.3.1 com.djrapitops PlanPluginBridge - 4.3.0-SNAPSHOT + 4.5.0-SNAPSHOT @@ -79,11 +83,19 @@ jar provided + + + com.velocitypowered + velocity-api + 1.0-SNAPSHOT + jar + provided + org.spongepowered spongeapi - 7.0.0 + 7.1.0 jar provided @@ -114,6 +126,12 @@ HikariCP 3.2.0 + + org.slf4j + slf4j-nop + 1.7.25 + runtime + @@ -180,6 +198,12 @@ 1.3 test + + + com.google.dagger + dagger + 2.17 + @@ -199,6 +223,7 @@ **/*.js **/*.css locale/*.txt + **/*.ico @@ -209,6 +234,23 @@ 1.8 1.8 + + + com.google.dagger + dagger-compiler + 2.17 + + + com.velocitypowered + velocity-api + 1.0-SNAPSHOT + + + org.spongepowered + spongeapi + 7.1.0 + + @@ -237,7 +279,7 @@ org.mockito:* org.easymock:* junit:* - + org.slf4j:* @@ -260,10 +302,10 @@ com.zaxxer plan.com.zaxxer - - org.slf4j - plan.org.slf4j - + + + + org.bstats com.djrapitops.plan.utilities.metrics diff --git a/Plan/src/main/java/com/djrapitops/plan/Plan.java b/Plan/src/main/java/com/djrapitops/plan/Plan.java index 85d6905f4..0daa33c33 100644 --- a/Plan/src/main/java/com/djrapitops/plan/Plan.java +++ b/Plan/src/main/java/com/djrapitops/plan/Plan.java @@ -21,19 +21,14 @@ package com.djrapitops.plan; import com.djrapitops.plan.api.exceptions.EnableException; import com.djrapitops.plan.command.PlanCommand; -import com.djrapitops.plan.system.BukkitSystem; +import com.djrapitops.plan.system.PlanSystem; import com.djrapitops.plan.system.locale.Locale; import com.djrapitops.plan.system.locale.lang.PluginLang; -import com.djrapitops.plan.system.processing.importing.ImporterManager; -import com.djrapitops.plan.system.processing.importing.importers.OfflinePlayerImporter; import com.djrapitops.plan.system.settings.theme.PlanColorScheme; import com.djrapitops.plan.utilities.metrics.BStatsBukkit; import com.djrapitops.plugin.BukkitPlugin; -import com.djrapitops.plugin.StaticHolder; -import com.djrapitops.plugin.api.Benchmark; -import com.djrapitops.plugin.api.utility.log.DebugLog; -import com.djrapitops.plugin.api.utility.log.Log; -import com.djrapitops.plugin.settings.ColorScheme; +import com.djrapitops.plugin.benchmarking.Benchmark; +import com.djrapitops.plugin.command.ColorScheme; import org.bukkit.configuration.file.FileConfiguration; import java.util.logging.Level; @@ -47,55 +42,45 @@ import java.util.logging.Logger; */ public class Plan extends BukkitPlugin implements PlanPlugin { - private BukkitSystem system; + private PlanSystem system; private Locale locale; - /** - * Used to get the plugin-instance singleton. - * - * @return this object. - */ - public static Plan getInstance() { - return (Plan) StaticHolder.getInstance(Plan.class); - } - @Override public void onEnable() { - super.onEnable(); + PlanBukkitComponent component = DaggerPlanBukkitComponent.builder().plan(this).build(); try { - Benchmark.start("Enable"); - system = new BukkitSystem(this); + timings.start("Enable"); + system = component.system(); locale = system.getLocaleSystem().getLocale(); system.enable(); - ImporterManager.registerImporter(new OfflinePlayerImporter()); - new BStatsBukkit(this).registerMetrics(); - Log.debug("Verbose debug messages are enabled."); - Benchmark.stop("Enable", "Enable"); - Log.logDebug("Enable"); - Log.info(locale.getString(PluginLang.ENABLED)); + logger.debug("Verbose debug messages are enabled."); + String benchTime = " (" + timings.end("Enable").map(Benchmark::toDurationString).orElse("-") + ")"; + logger.info(locale.getString(PluginLang.ENABLED) + benchTime); } catch (AbstractMethodError e) { - Log.error("Plugin ran into AbstractMethodError - Server restart is required. Likely cause is updating the jar without a restart."); + logger.error("Plugin ran into AbstractMethodError - Server restart is required. Likely cause is updating the jar without a restart."); } catch (EnableException e) { - Log.error("----------------------------------------"); - Log.error("Error: " + e.getMessage()); - Log.error("----------------------------------------"); - Log.error("Plugin Failed to Initialize Correctly. If this issue is caused by config settings you can use /plan reload"); + logger.error("----------------------------------------"); + logger.error("Error: " + e.getMessage()); + logger.error("----------------------------------------"); + logger.error("Plugin Failed to Initialize Correctly. If this issue is caused by config settings you can use /plan reload"); onDisable(); } catch (Exception e) { Logger.getGlobal().log(Level.SEVERE, this.getClass().getSimpleName() + "-v" + getVersion(), e); - Log.error("Plugin Failed to Initialize Correctly. If this issue is caused by config settings you can use /plan reload"); - Log.error("This error should be reported at https://github.com/Rsl1122/Plan-PlayerAnalytics/issues"); + logger.error("Plugin Failed to Initialize Correctly. If this issue is caused by config settings you can use /plan reload"); + logger.error("This error should be reported at https://github.com/Rsl1122/Plan-PlayerAnalytics/issues"); onDisable(); } - registerCommand("plan", new PlanCommand(this)); + PlanCommand command = component.planCommand(); + command.registerCommands(); + registerCommand("plan", command); } @Override public ColorScheme getColorScheme() { - return PlanColorScheme.create(); + return PlanColorScheme.create(system.getConfigSystem().getConfig(), logger); } /** @@ -103,11 +88,11 @@ public class Plan extends BukkitPlugin implements PlanPlugin { */ @Override public void onDisable() { - system.disable(); + if (system != null) { + system.disable(); + } - Log.info(locale.getString(PluginLang.DISABLED)); - Benchmark.pluginDisabled(Plan.class); - DebugLog.pluginDisabled(Plan.class); + logger.info(locale != null ? locale.getString(PluginLang.DISABLED) : PluginLang.DISABLED.getDefault()); } @Override @@ -162,7 +147,7 @@ public class Plan extends BukkitPlugin implements PlanPlugin { } @Override - public BukkitSystem getSystem() { + public PlanSystem getSystem() { return system; } -} +} \ No newline at end of file diff --git a/Plan/src/main/java/com/djrapitops/plan/PlanBukkitComponent.java b/Plan/src/main/java/com/djrapitops/plan/PlanBukkitComponent.java new file mode 100644 index 000000000..76d46cd81 --- /dev/null +++ b/Plan/src/main/java/com/djrapitops/plan/PlanBukkitComponent.java @@ -0,0 +1,50 @@ +package com.djrapitops.plan; + +import com.djrapitops.plan.command.PlanCommand; +import com.djrapitops.plan.modules.APFModule; +import com.djrapitops.plan.modules.FilesModule; +import com.djrapitops.plan.modules.SuperClassBindingModule; +import com.djrapitops.plan.modules.SystemObjectBindingModule; +import com.djrapitops.plan.modules.plugin.BukkitPlanModule; +import com.djrapitops.plan.modules.server.ServerSuperClassBindingModule; +import com.djrapitops.plan.modules.server.bukkit.BukkitServerPropertiesModule; +import com.djrapitops.plan.modules.server.bukkit.BukkitSuperClassBindingModule; +import com.djrapitops.plan.system.PlanSystem; +import com.djrapitops.pluginbridge.plan.PluginBridgeModule; +import dagger.BindsInstance; +import dagger.Component; + +import javax.inject.Singleton; + +/** + * Dagger Component that constructs the plugin systems running on Bukkit. + * + * @author Rsl1122 + */ +@Singleton +@Component(modules = { + BukkitPlanModule.class, + SuperClassBindingModule.class, + SystemObjectBindingModule.class, + APFModule.class, + FilesModule.class, + BukkitServerPropertiesModule.class, + ServerSuperClassBindingModule.class, + BukkitSuperClassBindingModule.class, + PluginBridgeModule.Bukkit.class +}) +public interface PlanBukkitComponent { + + PlanCommand planCommand(); + + PlanSystem system(); + + @Component.Builder + interface Builder { + + @BindsInstance + Builder plan(Plan plan); + + PlanBukkitComponent build(); + } +} \ No newline at end of file diff --git a/Plan/src/main/java/com/djrapitops/plan/PlanBungee.java b/Plan/src/main/java/com/djrapitops/plan/PlanBungee.java index fa17df538..b9e45c8b6 100644 --- a/Plan/src/main/java/com/djrapitops/plan/PlanBungee.java +++ b/Plan/src/main/java/com/djrapitops/plan/PlanBungee.java @@ -6,21 +6,16 @@ package com.djrapitops.plan; import com.djrapitops.plan.api.exceptions.EnableException; import com.djrapitops.plan.command.PlanBungeeCommand; -import com.djrapitops.plan.system.BungeeSystem; +import com.djrapitops.plan.system.PlanSystem; import com.djrapitops.plan.system.locale.Locale; import com.djrapitops.plan.system.locale.lang.PluginLang; import com.djrapitops.plan.system.settings.theme.PlanColorScheme; import com.djrapitops.plan.utilities.metrics.BStatsBungee; import com.djrapitops.plugin.BungeePlugin; -import com.djrapitops.plugin.StaticHolder; -import com.djrapitops.plugin.api.Benchmark; -import com.djrapitops.plugin.api.utility.log.DebugLog; -import com.djrapitops.plugin.api.utility.log.Log; -import com.djrapitops.plugin.settings.ColorScheme; +import com.djrapitops.plugin.command.ColorScheme; +import com.djrapitops.plugin.logging.L; import java.io.InputStream; -import java.util.logging.Level; -import java.util.logging.Logger; /** * Bungee Main class. @@ -29,48 +24,48 @@ import java.util.logging.Logger; */ public class PlanBungee extends BungeePlugin implements PlanPlugin { - private BungeeSystem system; + private PlanSystem system; private Locale locale; - public static PlanBungee getInstance() { - return (PlanBungee) StaticHolder.getInstance(PlanBungee.class); - } - @Override public void onEnable() { - super.onEnable(); + PlanBungeeComponent component = DaggerPlanBungeeComponent.builder().plan(this).build(); try { - system = new BungeeSystem(this); + system = component.system(); locale = system.getLocaleSystem().getLocale(); system.enable(); - new BStatsBungee(this).registerMetrics(); + new BStatsBungee( + this, + system.getDatabaseSystem().getDatabase(), + system.getInfoSystem().getConnectionSystem() + ).registerMetrics(); - Log.info(locale.getString(PluginLang.ENABLED)); + logger.info(locale.getString(PluginLang.ENABLED)); } catch (AbstractMethodError e) { - Log.error("Plugin ran into AbstractMethodError - Server restart is required. Likely cause is updating the jar without a restart."); + logger.error("Plugin ran into AbstractMethodError - Server restart is required. Likely cause is updating the jar without a restart."); } catch (EnableException e) { - Log.error("----------------------------------------"); - Log.error("Error: " + e.getMessage()); - Log.error("----------------------------------------"); - Log.error("Plugin Failed to Initialize Correctly. If this issue is caused by config settings you can use /planbungee reload"); + logger.error("----------------------------------------"); + logger.error("Error: " + e.getMessage()); + logger.error("----------------------------------------"); + logger.error("Plugin Failed to Initialize Correctly. If this issue is caused by config settings you can use /planbungee reload"); onDisable(); } catch (Exception e) { - Logger.getGlobal().log(Level.SEVERE, this.getClass().getSimpleName() + "-v" + getVersion(), e); - Log.error("Plugin Failed to Initialize Correctly. If this issue is caused by config settings you can use /planbungee reload"); - Log.error("This error should be reported at https://github.com/Rsl1122/Plan-PlayerAnalytics/issues"); + errorHandler.log(L.CRITICAL, this.getClass(), e); + logger.error("Plugin Failed to Initialize Correctly. If this issue is caused by config settings you can use /planbungee reload"); + logger.error("This error should be reported at https://github.com/Rsl1122/Plan-PlayerAnalytics/issues"); onDisable(); } - registerCommand("planbungee", new PlanBungeeCommand(this)); + PlanBungeeCommand command = component.planCommand(); + command.registerCommands(); + registerCommand("planbungee", command); } @Override public void onDisable() { system.disable(); - Log.info(locale.getString(PluginLang.DISABLED)); - Benchmark.pluginDisabled(PlanBungee.class); - DebugLog.pluginDisabled(PlanBungee.class); + logger.info(locale.getString(PluginLang.DISABLED)); } @Override @@ -90,11 +85,11 @@ public class PlanBungee extends BungeePlugin implements PlanPlugin { @Override public ColorScheme getColorScheme() { - return PlanColorScheme.create(); + return PlanColorScheme.create(system.getConfigSystem().getConfig(), logger); } @Override - public BungeeSystem getSystem() { + public PlanSystem getSystem() { return system; } diff --git a/Plan/src/main/java/com/djrapitops/plan/PlanBungeeComponent.java b/Plan/src/main/java/com/djrapitops/plan/PlanBungeeComponent.java new file mode 100644 index 000000000..4a91702d1 --- /dev/null +++ b/Plan/src/main/java/com/djrapitops/plan/PlanBungeeComponent.java @@ -0,0 +1,50 @@ +package com.djrapitops.plan; + +import com.djrapitops.plan.command.PlanBungeeCommand; +import com.djrapitops.plan.modules.APFModule; +import com.djrapitops.plan.modules.FilesModule; +import com.djrapitops.plan.modules.SuperClassBindingModule; +import com.djrapitops.plan.modules.SystemObjectBindingModule; +import com.djrapitops.plan.modules.plugin.BungeePlanModule; +import com.djrapitops.plan.modules.proxy.ProxySuperClassBindingModule; +import com.djrapitops.plan.modules.proxy.bungee.BungeeServerPropertiesModule; +import com.djrapitops.plan.modules.proxy.bungee.BungeeSuperClassBindingModule; +import com.djrapitops.plan.system.PlanSystem; +import com.djrapitops.pluginbridge.plan.PluginBridgeModule; +import dagger.BindsInstance; +import dagger.Component; + +import javax.inject.Singleton; + +/** + * Dagger Component that constructs the plugin systems running on Bungee. + * + * @author Rsl1122 + */ +@Singleton +@Component(modules = { + BungeePlanModule.class, + SuperClassBindingModule.class, + SystemObjectBindingModule.class, + APFModule.class, + FilesModule.class, + ProxySuperClassBindingModule.class, + BungeeSuperClassBindingModule.class, + BungeeServerPropertiesModule.class, + PluginBridgeModule.Bungee.class +}) +public interface PlanBungeeComponent { + + PlanBungeeCommand planCommand(); + + PlanSystem system(); + + @Component.Builder + interface Builder { + + @BindsInstance + Builder plan(PlanBungee plan); + + PlanBungeeComponent build(); + } +} \ No newline at end of file diff --git a/Plan/src/main/java/com/djrapitops/plan/PlanPlugin.java b/Plan/src/main/java/com/djrapitops/plan/PlanPlugin.java index c4d263d3e..4159cbedf 100644 --- a/Plan/src/main/java/com/djrapitops/plan/PlanPlugin.java +++ b/Plan/src/main/java/com/djrapitops/plan/PlanPlugin.java @@ -6,8 +6,7 @@ package com.djrapitops.plan; import com.djrapitops.plan.system.PlanSystem; import com.djrapitops.plugin.IPlugin; -import com.djrapitops.plugin.api.Check; -import com.djrapitops.plugin.settings.ColorScheme; +import com.djrapitops.plugin.command.ColorScheme; import java.io.File; import java.io.InputStream; @@ -18,39 +17,6 @@ import java.io.InputStream; * @author Rsl1122 */ public interface PlanPlugin extends IPlugin { - static PlanPlugin getInstance() { - boolean bukkitAvailable = Check.isBukkitAvailable(); - boolean bungeeAvailable = Check.isBungeeAvailable(); - boolean spongeAvailable = Check.isSpongeAvailable(); - if (bukkitAvailable) { - try { - Plan instance = Plan.getInstance(); - if (instance != null) { - return instance; - } - } catch (IllegalStateException ignored) { - } - } - if (bungeeAvailable) { - try { - PlanBungee instance = PlanBungee.getInstance(); - if (instance != null) { - return instance; - } - } catch (IllegalStateException ignored) { - } - } - if (spongeAvailable) { - try { - PlanSponge instance = PlanSponge.getInstance(); - if (instance != null) { - return instance; - } - } catch (IllegalStateException ignored) { - } - } - throw new IllegalAccessError("Plugin instance not available"); - } @Override File getDataFolder(); diff --git a/Plan/src/main/java/com/djrapitops/plan/PlanSponge.java b/Plan/src/main/java/com/djrapitops/plan/PlanSponge.java index 858ed6b6c..802be0ebc 100644 --- a/Plan/src/main/java/com/djrapitops/plan/PlanSponge.java +++ b/Plan/src/main/java/com/djrapitops/plan/PlanSponge.java @@ -2,20 +2,18 @@ package com.djrapitops.plan; import com.djrapitops.plan.api.exceptions.EnableException; import com.djrapitops.plan.command.PlanCommand; -import com.djrapitops.plan.system.SpongeSystem; +import com.djrapitops.plan.system.PlanSystem; import com.djrapitops.plan.system.locale.Locale; import com.djrapitops.plan.system.locale.lang.PluginLang; import com.djrapitops.plan.system.settings.theme.PlanColorScheme; import com.djrapitops.plan.utilities.metrics.BStatsSponge; import com.djrapitops.plugin.SpongePlugin; -import com.djrapitops.plugin.StaticHolder; -import com.djrapitops.plugin.api.Benchmark; -import com.djrapitops.plugin.api.utility.log.DebugLog; -import com.djrapitops.plugin.api.utility.log.Log; -import com.djrapitops.plugin.settings.ColorScheme; -import com.google.inject.Inject; +import com.djrapitops.plugin.command.ColorScheme; +import com.djrapitops.plugin.logging.L; import org.bstats.sponge.Metrics; import org.slf4j.Logger; +import org.spongepowered.api.Game; +import org.spongepowered.api.Sponge; import org.spongepowered.api.config.ConfigDir; import org.spongepowered.api.event.Listener; import org.spongepowered.api.event.game.state.GameStartedServerEvent; @@ -29,7 +27,7 @@ import java.io.InputStream; @Plugin( id = "plan", name = "Plan", - version = "4.4.7", + version = "4.5.0", description = "Player Analytics Plugin by Rsl1122", authors = {"Rsl1122"}, dependencies = { @@ -39,16 +37,16 @@ import java.io.InputStream; ) public class PlanSponge extends SpongePlugin implements PlanPlugin { - @Inject + @com.google.inject.Inject private Metrics metrics; - @Inject - private Logger logger; + @com.google.inject.Inject + private Logger slf4jLogger; - @Inject + @com.google.inject.Inject @ConfigDir(sharedRoot = false) private File dataFolder; - private SpongeSystem system; + private PlanSystem system; private Locale locale; @Listener @@ -61,36 +59,37 @@ public class PlanSponge extends SpongePlugin implements PlanPlugin { onDisable(); } - public static PlanSponge getInstance() { - return (PlanSponge) StaticHolder.getInstance(PlanSponge.class); - } - @Override public void onEnable() { - super.onEnable(); + PlanSpongeComponent component = DaggerPlanSpongeComponent.builder().plan(this).build(); try { - system = new SpongeSystem(this); + system = component.system(); locale = system.getLocaleSystem().getLocale(); system.enable(); - new BStatsSponge(metrics).registerMetrics(); + new BStatsSponge( + metrics, + system.getDatabaseSystem().getDatabase() + ).registerMetrics(); - Log.info(locale.getString(PluginLang.ENABLED)); + slf4jLogger.info(locale.getString(PluginLang.ENABLED)); } catch (AbstractMethodError e) { - Log.error("Plugin ran into AbstractMethodError - Server restart is required. Likely cause is updating the jar without a restart."); + slf4jLogger.error("Plugin ran into AbstractMethodError - Server restart is required. Likely cause is updating the jar without a restart."); } catch (EnableException e) { - Log.error("----------------------------------------"); - Log.error("Error: " + e.getMessage()); - Log.error("----------------------------------------"); - Log.error("Plugin Failed to Initialize Correctly. If this issue is caused by config settings you can use /plan reload"); + slf4jLogger.error("----------------------------------------"); + slf4jLogger.error("Error: " + e.getMessage()); + slf4jLogger.error("----------------------------------------"); + slf4jLogger.error("Plugin Failed to Initialize Correctly. If this issue is caused by config settings you can use /plan reload"); onDisable(); } catch (Exception e) { - Log.toLog(this.getClass().getSimpleName() + "-v" + getVersion(), e); - Log.error("Plugin Failed to Initialize Correctly. If this issue is caused by config settings you can use /plan reload"); - Log.error("This error should be reported at https://github.com/Rsl1122/Plan-PlayerAnalytics/issues"); + errorHandler.log(L.CRITICAL, this.getClass(), e); + slf4jLogger.error("Plugin Failed to Initialize Correctly. If this issue is caused by config settings you can use /plan reload"); + slf4jLogger.error("This error should be reported at https://github.com/Rsl1122/Plan-PlayerAnalytics/issues"); onDisable(); } - registerCommand("plan", new PlanCommand(this)); + PlanCommand command = component.planCommand(); + command.registerCommands(); + registerCommand("plan", command); } @Override @@ -99,9 +98,7 @@ public class PlanSponge extends SpongePlugin implements PlanPlugin { system.disable(); } - Log.info(locale.getString(PluginLang.DISABLED)); - Benchmark.pluginDisabled(PlanSponge.class); - DebugLog.pluginDisabled(PlanSponge.class); + logger.info(locale.getString(PluginLang.DISABLED)); } @Override @@ -111,7 +108,7 @@ public class PlanSponge extends SpongePlugin implements PlanPlugin { @Override public ColorScheme getColorScheme() { - return PlanColorScheme.create(); + return PlanColorScheme.create(system.getConfigSystem().getConfig(), logger); } @Override @@ -126,7 +123,7 @@ public class PlanSponge extends SpongePlugin implements PlanPlugin { @Override public Logger getLogger() { - return logger; + return slf4jLogger; } @Override @@ -140,7 +137,11 @@ public class PlanSponge extends SpongePlugin implements PlanPlugin { } @Override - public SpongeSystem getSystem() { + public PlanSystem getSystem() { return system; } + + public Game getGame() { + return Sponge.getGame(); + } } diff --git a/Plan/src/main/java/com/djrapitops/plan/PlanSpongeComponent.java b/Plan/src/main/java/com/djrapitops/plan/PlanSpongeComponent.java new file mode 100644 index 000000000..61f3c40c0 --- /dev/null +++ b/Plan/src/main/java/com/djrapitops/plan/PlanSpongeComponent.java @@ -0,0 +1,50 @@ +package com.djrapitops.plan; + +import com.djrapitops.plan.command.PlanCommand; +import com.djrapitops.plan.modules.APFModule; +import com.djrapitops.plan.modules.FilesModule; +import com.djrapitops.plan.modules.SuperClassBindingModule; +import com.djrapitops.plan.modules.SystemObjectBindingModule; +import com.djrapitops.plan.modules.plugin.SpongePlanModule; +import com.djrapitops.plan.modules.server.ServerSuperClassBindingModule; +import com.djrapitops.plan.modules.server.sponge.SpongeServerPropertiesModule; +import com.djrapitops.plan.modules.server.sponge.SpongeSuperClassBindingModule; +import com.djrapitops.plan.system.PlanSystem; +import com.djrapitops.pluginbridge.plan.PluginBridgeModule; +import dagger.BindsInstance; +import dagger.Component; + +import javax.inject.Singleton; + +/** + * Dagger Component that constructs the plugin systems running on Sponge. + * + * @author Rsl1122 + */ +@Singleton +@Component(modules = { + SpongePlanModule.class, + SuperClassBindingModule.class, + SystemObjectBindingModule.class, + APFModule.class, + FilesModule.class, + ServerSuperClassBindingModule.class, + SpongeSuperClassBindingModule.class, + SpongeServerPropertiesModule.class, + PluginBridgeModule.Sponge.class +}) +public interface PlanSpongeComponent { + + PlanCommand planCommand(); + + PlanSystem system(); + + @Component.Builder + interface Builder { + + @BindsInstance + Builder plan(PlanSponge plan); + + PlanSpongeComponent build(); + } +} \ No newline at end of file diff --git a/Plan/src/main/java/com/djrapitops/plan/PlanVelocity.java b/Plan/src/main/java/com/djrapitops/plan/PlanVelocity.java new file mode 100644 index 000000000..6e18ab749 --- /dev/null +++ b/Plan/src/main/java/com/djrapitops/plan/PlanVelocity.java @@ -0,0 +1,120 @@ +/* + * License is provided in the jar as LICENSE also here: + * https://github.com/Rsl1122/Plan-PlayerAnalytics/blob/master/Plan/src/main/resources/LICENSE + */ +package com.djrapitops.plan; + +import com.djrapitops.plan.api.exceptions.EnableException; +import com.djrapitops.plan.command.PlanVelocityCommand; +import com.djrapitops.plan.system.PlanSystem; +import com.djrapitops.plan.system.locale.Locale; +import com.djrapitops.plan.system.locale.lang.PluginLang; +import com.djrapitops.plan.system.settings.theme.PlanColorScheme; +import com.djrapitops.plugin.VelocityPlugin; +import com.djrapitops.plugin.command.ColorScheme; +import com.djrapitops.plugin.logging.L; +import com.velocitypowered.api.event.Subscribe; +import com.velocitypowered.api.event.proxy.ProxyInitializeEvent; +import com.velocitypowered.api.event.proxy.ProxyShutdownEvent; +import com.velocitypowered.api.plugin.Plugin; +import com.velocitypowered.api.plugin.annotation.DataDirectory; +import com.velocitypowered.api.proxy.ProxyServer; +import org.slf4j.Logger; + +import java.io.InputStream; +import java.nio.file.Path; + +/** + * Velocity Main class. + *

+ * Based on the PlanBungee class + * + * @author MicleBrick + */ +@Plugin( + id = "plan", + name = "Plan", + version = "4.5.0", + description = "Player Analytics Plugin by Rsl1122", + authors = {"Rsl1122"} +) +public class PlanVelocity extends VelocityPlugin implements PlanPlugin { + + private PlanSystem system; + private Locale locale; + + @com.google.inject.Inject + public PlanVelocity(ProxyServer proxy, Logger slf4jLogger, @DataDirectory Path dataFolderPath) { + super(proxy, slf4jLogger, dataFolderPath); + } + + @Subscribe + public void onProxyStart(ProxyInitializeEvent event) { + onEnable(); + } + + @Subscribe + public void onProxyShutdown(ProxyShutdownEvent event) { + onDisable(); + } + + @Override + public void onEnable() { + PlanVelocityComponent component = DaggerPlanVelocityComponent.builder().plan(this).build(); + try { + system = component.system(); + locale = system.getLocaleSystem().getLocale(); + system.enable(); + + logger.info(locale.getString(PluginLang.ENABLED)); + } catch (AbstractMethodError e) { + logger.error("Plugin ran into AbstractMethodError - Server restart is required. Likely cause is updating the jar without a restart."); + } catch (EnableException e) { + logger.error("----------------------------------------"); + logger.error("Error: " + e.getMessage()); + logger.error("----------------------------------------"); + logger.error("Plugin Failed to Initialize Correctly. If this issue is caused by config settings you can use /planvelocity reload"); + onDisable(); + } catch (Exception e) { + errorHandler.log(L.CRITICAL, this.getClass(), e); + logger.error("Plugin Failed to Initialize Correctly. If this issue is caused by config settings you can use /planvelocity reload"); + logger.error("This error should be reported at https://github.com/Rsl1122/Plan-PlayerAnalytics/issues"); + onDisable(); + } + PlanVelocityCommand command = component.planCommand(); + command.registerCommands(); + registerCommand("planvelocity", command); + } + + @Override + public void onDisable() { + system.disable(); + + logger.info(locale.getString(PluginLang.DISABLED)); + } + + @Override + public void onReload() { + // Nothing to be done, systems are disabled + } + + @Override + public InputStream getResource(String resource) { + return getClass().getResourceAsStream("/" + resource); + } + + @Override + public ColorScheme getColorScheme() { + return PlanColorScheme.create(system.getConfigSystem().getConfig(), logger); + } + + @Override + public PlanSystem getSystem() { + return system; + } + + @Override + public boolean isReloading() { + return reloading; + } +} diff --git a/Plan/src/main/java/com/djrapitops/plan/PlanVelocityComponent.java b/Plan/src/main/java/com/djrapitops/plan/PlanVelocityComponent.java new file mode 100644 index 000000000..1feea2985 --- /dev/null +++ b/Plan/src/main/java/com/djrapitops/plan/PlanVelocityComponent.java @@ -0,0 +1,50 @@ +package com.djrapitops.plan; + +import com.djrapitops.plan.command.PlanVelocityCommand; +import com.djrapitops.plan.modules.APFModule; +import com.djrapitops.plan.modules.FilesModule; +import com.djrapitops.plan.modules.SuperClassBindingModule; +import com.djrapitops.plan.modules.SystemObjectBindingModule; +import com.djrapitops.plan.modules.plugin.VelocityPlanModule; +import com.djrapitops.plan.modules.proxy.ProxySuperClassBindingModule; +import com.djrapitops.plan.modules.proxy.velocity.VelocityServerPropertiesModule; +import com.djrapitops.plan.modules.proxy.velocity.VelocitySuperClassBindingModule; +import com.djrapitops.plan.system.PlanSystem; +import com.djrapitops.pluginbridge.plan.PluginBridgeModule; +import dagger.BindsInstance; +import dagger.Component; + +import javax.inject.Singleton; + +/** + * Dagger Component that constructs the plugin systems running on Velocity. + * + * @author Rsl1122 + */ +@Singleton +@Component(modules = { + VelocityPlanModule.class, + SuperClassBindingModule.class, + SystemObjectBindingModule.class, + APFModule.class, + FilesModule.class, + ProxySuperClassBindingModule.class, + VelocitySuperClassBindingModule.class, + VelocityServerPropertiesModule.class, + PluginBridgeModule.Velocity.class +}) +public interface PlanVelocityComponent { + + PlanVelocityCommand planCommand(); + + PlanSystem system(); + + @Component.Builder + interface Builder { + + @BindsInstance + Builder plan(PlanVelocity plan); + + PlanVelocityComponent build(); + } +} \ No newline at end of file diff --git a/Plan/src/main/java/com/djrapitops/plan/ShutdownHook.java b/Plan/src/main/java/com/djrapitops/plan/ShutdownHook.java index 2a8a7adff..53bcb506f 100644 --- a/Plan/src/main/java/com/djrapitops/plan/ShutdownHook.java +++ b/Plan/src/main/java/com/djrapitops/plan/ShutdownHook.java @@ -10,9 +10,12 @@ import com.djrapitops.plan.api.exceptions.database.DBOpException; import com.djrapitops.plan.data.container.Session; import com.djrapitops.plan.data.store.keys.SessionKeys; import com.djrapitops.plan.system.cache.SessionCache; +import com.djrapitops.plan.system.database.DBSystem; import com.djrapitops.plan.system.database.databases.Database; -import com.djrapitops.plugin.api.utility.log.Log; +import com.djrapitops.plugin.logging.L; +import com.djrapitops.plugin.logging.error.ErrorHandler; +import javax.inject.Inject; import java.util.Map; import java.util.Optional; import java.util.UUID; @@ -26,50 +29,57 @@ import java.util.UUID; */ public class ShutdownHook extends Thread { - private static boolean activated = false; + private static ShutdownHook activated; + private final DBSystem dbSystem; + private final ErrorHandler errorHandler; + + @Inject + public ShutdownHook(DBSystem dbSystem, ErrorHandler errorHandler) { + this.dbSystem = dbSystem; + this.errorHandler = errorHandler; + } private static boolean isActivated() { - return activated; + return activated != null; } private static void activate(ShutdownHook hook) { - activated = true; + activated = hook; Runtime.getRuntime().addShutdownHook(hook); } + private static void deactivate() { + Runtime.getRuntime().removeShutdownHook(activated); + activated = null; + } + public void register() { if (isActivated()) { - return; + deactivate(); } activate(this); } @Override public void run() { - Log.debug("Shutdown hook triggered."); - - Database db = null; try { Map activeSessions = SessionCache.getActiveSessions(); long now = System.currentTimeMillis(); - db = Database.getActive(); - saveActiveSessions(db, activeSessions, now); + saveActiveSessions(activeSessions, now); } catch (IllegalStateException ignored) { /* Database is not initialized */ } catch (DBInitException e) { - Log.toLog(this.getClass(), e); + errorHandler.log(L.ERROR, this.getClass(), e); } finally { - if (db != null) { - try { - db.close(); - } catch (DBException e) { - Log.toLog(this.getClass(), e); - } + try { + dbSystem.getDatabase().close(); + } catch (DBException e) { + errorHandler.log(L.ERROR, this.getClass(), e); } } } - private void saveActiveSessions(Database db, Map activeSessions, long now) throws DBInitException { + private void saveActiveSessions(Map activeSessions, long now) throws DBInitException { for (Map.Entry entry : activeSessions.entrySet()) { UUID uuid = entry.getKey(); Session session = entry.getValue(); @@ -77,13 +87,14 @@ public class ShutdownHook extends Thread { if (!end.isPresent()) { session.endSession(now); } - if (!db.isOpen()) { - db.init(); + Database database = dbSystem.getDatabase(); + if (!database.isOpen()) { + database.init(); } try { - db.save().session(uuid, session); + database.save().session(uuid, session); } catch (DBOpException e) { - Log.toLog(this.getClass(), e); + errorHandler.log(L.ERROR, this.getClass(), e); } } activeSessions.clear(); diff --git a/Plan/src/main/java/com/djrapitops/plan/api/BungeeAPI.java b/Plan/src/main/java/com/djrapitops/plan/api/BungeeAPI.java deleted file mode 100644 index 394231e52..000000000 --- a/Plan/src/main/java/com/djrapitops/plan/api/BungeeAPI.java +++ /dev/null @@ -1,40 +0,0 @@ -/* - * License is provided in the jar as LICENSE also here: - * https://github.com/Rsl1122/Plan-PlayerAnalytics/blob/master/Plan/src/main/resources/LICENSE - */ -package com.djrapitops.plan.api; - -import com.djrapitops.plan.data.plugin.PluginData; -import com.djrapitops.plan.system.BungeeSystem; -import com.djrapitops.plan.system.database.databases.operation.FetchOperations; - -import java.util.UUID; - -/** - * PlanAPI extension for Bungee. - * - * @author Rsl1122 - */ -public class BungeeAPI extends CommonAPI { - - private final BungeeSystem bungeeSystem; - - public BungeeAPI(BungeeSystem bungeeSystem) { - this.bungeeSystem = bungeeSystem; - } - - @Override - public void addPluginDataSource(PluginData pluginData) { - bungeeSystem.getHookHandler().addPluginDataSource(pluginData); - } - - @Override - public String getPlayerName(UUID uuid) { - return bungeeSystem.getCacheSystem().getDataCache().getName(uuid); - } - - @Override - public FetchOperations fetchFromPlanDB() { - return bungeeSystem.getDatabaseSystem().getActiveDatabase().fetch(); - } -} diff --git a/Plan/src/main/java/com/djrapitops/plan/api/CommonAPI.java b/Plan/src/main/java/com/djrapitops/plan/api/CommonAPI.java index c87f9336d..0f6ecd529 100644 --- a/Plan/src/main/java/com/djrapitops/plan/api/CommonAPI.java +++ b/Plan/src/main/java/com/djrapitops/plan/api/CommonAPI.java @@ -6,7 +6,8 @@ package com.djrapitops.plan.api; import com.djrapitops.plan.api.exceptions.database.DBOpException; import com.djrapitops.plan.utilities.uuid.UUIDUtility; -import com.djrapitops.plugin.api.utility.log.Log; +import com.djrapitops.plugin.logging.L; +import com.djrapitops.plugin.logging.error.ErrorHandler; import java.util.HashMap; import java.util.Map; @@ -19,6 +20,15 @@ import java.util.UUID; */ public abstract class CommonAPI implements PlanAPI { + private final UUIDUtility uuidUtility; + private final ErrorHandler errorHandler; + + CommonAPI(UUIDUtility uuidUtility, ErrorHandler errorHandler) { + this.uuidUtility = uuidUtility; + this.errorHandler = errorHandler; + PlanAPIHolder.set(this); + } + @Override public String getPlayerInspectPageLink(UUID uuid) { return getPlayerInspectPageLink(getPlayerName(uuid)); @@ -31,7 +41,7 @@ public abstract class CommonAPI implements PlanAPI { @Override public UUID playerNameToUUID(String playerName) { - return UUIDUtility.getUUIDOf(playerName); + return uuidUtility.getUUIDOf(playerName); } @Override @@ -39,7 +49,7 @@ public abstract class CommonAPI implements PlanAPI { try { return fetchFromPlanDB().getPlayerNames(); } catch (DBOpException e) { - Log.toLog(this.getClass(), e); + errorHandler.log(L.ERROR, this.getClass(), e); return new HashMap<>(); } } diff --git a/Plan/src/main/java/com/djrapitops/plan/api/PlanAPI.java b/Plan/src/main/java/com/djrapitops/plan/api/PlanAPI.java index 739910c6b..465d51633 100644 --- a/Plan/src/main/java/com/djrapitops/plan/api/PlanAPI.java +++ b/Plan/src/main/java/com/djrapitops/plan/api/PlanAPI.java @@ -5,10 +5,10 @@ package com.djrapitops.plan.api; import com.djrapitops.plan.data.plugin.PluginData; -import com.djrapitops.plan.system.PlanSystem; import com.djrapitops.plan.system.database.databases.operation.FetchOperations; import java.util.Map; +import java.util.Optional; import java.util.UUID; /** @@ -19,7 +19,16 @@ import java.util.UUID; public interface PlanAPI { static PlanAPI getInstance() { - return PlanSystem.getInstance().getPlanAPI(); + return Optional.ofNullable(PlanAPIHolder.API) + .orElseThrow(() -> new IllegalStateException("PlanAPI has not been initialised yet.")); + } + + class PlanAPIHolder { + static PlanAPI API; + + static void set(PlanAPI api) { + PlanAPIHolder.API = api; + } } void addPluginDataSource(PluginData pluginData); diff --git a/Plan/src/main/java/com/djrapitops/plan/api/ProxyAPI.java b/Plan/src/main/java/com/djrapitops/plan/api/ProxyAPI.java new file mode 100644 index 000000000..dc73dc6a0 --- /dev/null +++ b/Plan/src/main/java/com/djrapitops/plan/api/ProxyAPI.java @@ -0,0 +1,56 @@ +/* + * License is provided in the jar as LICENSE also here: + * https://github.com/Rsl1122/Plan-PlayerAnalytics/blob/master/Plan/src/main/resources/LICENSE + */ +package com.djrapitops.plan.api; + +import com.djrapitops.plan.data.plugin.HookHandler; +import com.djrapitops.plan.data.plugin.PluginData; +import com.djrapitops.plan.system.database.DBSystem; +import com.djrapitops.plan.system.database.databases.operation.FetchOperations; +import com.djrapitops.plan.utilities.uuid.UUIDUtility; +import com.djrapitops.plugin.logging.error.ErrorHandler; + +import javax.inject.Inject; +import javax.inject.Singleton; +import java.util.UUID; + +/** + * PlanAPI extension for proxy servers. + * + * @author Rsl1122 + */ +@Singleton +public class ProxyAPI extends CommonAPI { + + private final HookHandler hookHandler; + private final DBSystem dbSystem; + + @Inject + public ProxyAPI( + UUIDUtility uuidUtility, + DBSystem dbSystem, + HookHandler hookHandler, + ErrorHandler errorHandler + ) { + super(uuidUtility, errorHandler); + + this.dbSystem = dbSystem; + this.hookHandler = hookHandler; + } + + @Override + public void addPluginDataSource(PluginData pluginData) { + hookHandler.addPluginDataSource(pluginData); + } + + @Override + public String getPlayerName(UUID uuid) { + return dbSystem.getDatabase().fetch().getPlayerName(uuid); + } + + @Override + public FetchOperations fetchFromPlanDB() { + return dbSystem.getDatabase().fetch(); + } +} diff --git a/Plan/src/main/java/com/djrapitops/plan/api/ServerAPI.java b/Plan/src/main/java/com/djrapitops/plan/api/ServerAPI.java index adf22252a..6bd9d8eb2 100644 --- a/Plan/src/main/java/com/djrapitops/plan/api/ServerAPI.java +++ b/Plan/src/main/java/com/djrapitops/plan/api/ServerAPI.java @@ -4,10 +4,15 @@ */ package com.djrapitops.plan.api; +import com.djrapitops.plan.data.plugin.HookHandler; import com.djrapitops.plan.data.plugin.PluginData; -import com.djrapitops.plan.system.ServerSystem; +import com.djrapitops.plan.system.database.DBSystem; import com.djrapitops.plan.system.database.databases.operation.FetchOperations; +import com.djrapitops.plan.utilities.uuid.UUIDUtility; +import com.djrapitops.plugin.logging.error.ErrorHandler; +import javax.inject.Inject; +import javax.inject.Singleton; import java.util.UUID; /** @@ -15,26 +20,36 @@ import java.util.UUID; * * @author Rsl1122 */ +@Singleton public class ServerAPI extends CommonAPI { - private final ServerSystem serverSystem; + private final HookHandler hookHandler; + private final DBSystem dbSystem; - public ServerAPI(ServerSystem serverSystem) { - this.serverSystem = serverSystem; + @Inject + public ServerAPI( + UUIDUtility uuidUtility, + HookHandler hookHandler, + DBSystem dbSystem, + ErrorHandler errorHandler + ) { + super(uuidUtility, errorHandler); + this.hookHandler = hookHandler; + this.dbSystem = dbSystem; } @Override public void addPluginDataSource(PluginData pluginData) { - serverSystem.getHookHandler().addPluginDataSource(pluginData); + hookHandler.addPluginDataSource(pluginData); } @Override public String getPlayerName(UUID uuid) { - return serverSystem.getCacheSystem().getDataCache().getName(uuid); + return dbSystem.getDatabase().fetch().getPlayerName(uuid); } @Override public FetchOperations fetchFromPlanDB() { - return serverSystem.getDatabaseSystem().getActiveDatabase().fetch(); + return dbSystem.getDatabase().fetch(); } } diff --git a/Plan/src/main/java/com/djrapitops/plan/command/PlanBungeeCommand.java b/Plan/src/main/java/com/djrapitops/plan/command/PlanBungeeCommand.java index 7e37fd8f3..48c950a43 100644 --- a/Plan/src/main/java/com/djrapitops/plan/command/PlanBungeeCommand.java +++ b/Plan/src/main/java/com/djrapitops/plan/command/PlanBungeeCommand.java @@ -1,6 +1,5 @@ package com.djrapitops.plan.command; -import com.djrapitops.plan.PlanPlugin; import com.djrapitops.plan.command.commands.*; import com.djrapitops.plan.command.commands.manage.ManageConDebugCommand; import com.djrapitops.plan.command.commands.manage.ManageRawDataCommand; @@ -8,10 +7,14 @@ import com.djrapitops.plan.command.commands.manage.ManageUninstalledCommand; import com.djrapitops.plan.system.locale.Locale; import com.djrapitops.plan.system.locale.lang.DeepHelpLang; import com.djrapitops.plan.system.settings.Permissions; +import com.djrapitops.plugin.command.ColorScheme; import com.djrapitops.plugin.command.CommandNode; import com.djrapitops.plugin.command.CommandType; import com.djrapitops.plugin.command.TreeCmdNode; -import com.djrapitops.plugin.command.defaultcmds.StatusCommand; +import dagger.Lazy; + +import javax.inject.Inject; +import javax.inject.Singleton; /** * TreeCommand for the /plan command, and all subcommands. @@ -21,36 +24,86 @@ import com.djrapitops.plugin.command.defaultcmds.StatusCommand; * @author Rsl1122 * @since 1.0.0 */ +@Singleton public class PlanBungeeCommand extends TreeCmdNode { - public PlanBungeeCommand(PlanPlugin plugin) { + private final NetworkCommand networkCommand; + private final ListServersCommand listServersCommand; + private final ListPlayersCommand listPlayersCommand; + private final RegisterCommand registerCommand; + private final Lazy webUserCommand; + private final ManageConDebugCommand conDebugCommand; + private final ManageRawDataCommand rawDataCommand; + private final BungeeSetupToggleCommand setupToggleCommand; + private final ReloadCommand reloadCommand; + private final DisableCommand disableCommand; + private final ManageUninstalledCommand uninstalledCommand; + + private boolean commandsRegistered; + + @Inject + public PlanBungeeCommand( + ColorScheme colorScheme, + Locale locale, + // Group 1 + NetworkCommand networkCommand, + ListServersCommand listServersCommand, + ListPlayersCommand listPlayersCommand, + // Group 2 + RegisterCommand registerCommand, + Lazy webUserCommand, + // Group 3 + ManageConDebugCommand conDebugCommand, + ManageRawDataCommand rawDataCommand, + BungeeSetupToggleCommand setupToggleCommand, + ManageUninstalledCommand uninstalledCommand, + ReloadCommand reloadCommand, + DisableCommand disableCommand + ) { super("planbungee", Permissions.MANAGE.getPermission(), CommandType.CONSOLE, null); - super.setColorScheme(plugin.getColorScheme()); + this.uninstalledCommand = uninstalledCommand; - Locale locale = plugin.getSystem().getLocaleSystem().getLocale(); + commandsRegistered = false; + this.networkCommand = networkCommand; + this.listServersCommand = listServersCommand; + this.listPlayersCommand = listPlayersCommand; + this.registerCommand = registerCommand; + this.webUserCommand = webUserCommand; + this.conDebugCommand = conDebugCommand; + this.rawDataCommand = rawDataCommand; + this.setupToggleCommand = setupToggleCommand; + this.reloadCommand = reloadCommand; + this.disableCommand = disableCommand; + + getHelpCommand().setPermission(Permissions.MANAGE.getPermission()); + setColorScheme(colorScheme); setInDepthHelp(locale.getArray(DeepHelpLang.PLAN)); + } + + public void registerCommands() { + if (commandsRegistered) { + return; + } - RegisterCommand registerCommand = new RegisterCommand(plugin); CommandNode[] analyticsGroup = { - new NetworkCommand(plugin), - new ListServersCommand(plugin), - new ListPlayersCommand(plugin), + networkCommand, + listServersCommand, + listPlayersCommand }; CommandNode[] webGroup = { registerCommand, - new WebUserCommand(plugin, registerCommand, this), + webUserCommand.get() }; CommandNode[] manageGroup = { - new ManageConDebugCommand(plugin), - new ManageRawDataCommand(plugin), - new BungeeSetupToggleCommand(plugin), - new ManageUninstalledCommand(plugin), - new ReloadCommand(plugin), - new DisableCommand(plugin), - new StatusCommand<>(plugin, Permissions.MANAGE.getPermission(), plugin.getColorScheme()), -// (Settings.ALLOW_UPDATE.isTrue() ? new UpdateCommand() : null) + conDebugCommand, + rawDataCommand, + setupToggleCommand, + uninstalledCommand, + reloadCommand, + disableCommand }; setNodeGroups(analyticsGroup, webGroup, manageGroup); + commandsRegistered = true; } } diff --git a/Plan/src/main/java/com/djrapitops/plan/command/PlanCommand.java b/Plan/src/main/java/com/djrapitops/plan/command/PlanCommand.java index e740df78a..6e3a9ea99 100644 --- a/Plan/src/main/java/com/djrapitops/plan/command/PlanCommand.java +++ b/Plan/src/main/java/com/djrapitops/plan/command/PlanCommand.java @@ -1,15 +1,19 @@ package com.djrapitops.plan.command; -import com.djrapitops.plan.PlanPlugin; import com.djrapitops.plan.command.commands.*; import com.djrapitops.plan.system.locale.Locale; import com.djrapitops.plan.system.locale.lang.DeepHelpLang; import com.djrapitops.plan.system.settings.Permissions; import com.djrapitops.plan.system.settings.Settings; +import com.djrapitops.plan.system.settings.config.PlanConfig; +import com.djrapitops.plugin.command.ColorScheme; import com.djrapitops.plugin.command.CommandNode; import com.djrapitops.plugin.command.CommandType; import com.djrapitops.plugin.command.TreeCmdNode; -import com.djrapitops.plugin.command.defaultcmds.StatusCommand; +import dagger.Lazy; + +import javax.inject.Inject; +import javax.inject.Singleton; /** * TreeCommand for the /plan command, and all SubCommands. @@ -19,39 +23,98 @@ import com.djrapitops.plugin.command.defaultcmds.StatusCommand; * @author Rsl1122 * @since 1.0.0 */ +@Singleton public class PlanCommand extends TreeCmdNode { - public PlanCommand(PlanPlugin plugin) { + private final PlanConfig config; + private final InspectCommand inspectCommand; + private final QInspectCommand qInspectCommand; + private final SearchCommand searchCommand; + private final ListPlayersCommand listPlayersCommand; + private final AnalyzeCommand analyzeCommand; + private final NetworkCommand networkCommand; + private final ListServersCommand listServersCommand; + private final Lazy webUserCommand; + private final RegisterCommand registerCommand; + private final InfoCommand infoCommand; + private final ReloadCommand reloadCommand; + private final Lazy manageCommand; + private final DevCommand devCommand; + + private boolean commandsRegistered; + + @Inject + public PlanCommand( + ColorScheme colorScheme, + Locale locale, + PlanConfig config, + // Group 1 + InspectCommand inspectCommand, + QInspectCommand qInspectCommand, + SearchCommand searchCommand, + ListPlayersCommand listPlayersCommand, + AnalyzeCommand analyzeCommand, + NetworkCommand networkCommand, + ListServersCommand listServersCommand, + // Group 2 + Lazy webUserCommand, + RegisterCommand registerCommand, + // Group 3 + InfoCommand infoCommand, + ReloadCommand reloadCommand, + Lazy manageCommand, + DevCommand devCommand + ) { super("plan", "", CommandType.CONSOLE, null); - super.setDefaultCommand("inspect"); - super.setColorScheme(plugin.getColorScheme()); - Locale locale = plugin.getSystem().getLocaleSystem().getLocale(); + commandsRegistered = false; + this.config = config; + this.inspectCommand = inspectCommand; + this.qInspectCommand = qInspectCommand; + this.searchCommand = searchCommand; + this.listPlayersCommand = listPlayersCommand; + this.analyzeCommand = analyzeCommand; + this.networkCommand = networkCommand; + this.listServersCommand = listServersCommand; + this.webUserCommand = webUserCommand; + this.registerCommand = registerCommand; + this.infoCommand = infoCommand; + this.reloadCommand = reloadCommand; + this.manageCommand = manageCommand; + this.devCommand = devCommand; + + getHelpCommand().setPermission(Permissions.HELP.getPermission()); + setDefaultCommand("inspect"); + setColorScheme(colorScheme); setInDepthHelp(locale.getArray(DeepHelpLang.PLAN)); + } + + public void registerCommands() { + if (commandsRegistered) { + return; + } - RegisterCommand registerCommand = new RegisterCommand(plugin); CommandNode[] analyticsGroup = { - new InspectCommand(plugin), - new QInspectCommand(plugin), - new SearchCommand(plugin), - new ListPlayersCommand(plugin), - new AnalyzeCommand(plugin), - new NetworkCommand(plugin), - new ListServersCommand(plugin) + inspectCommand, + qInspectCommand, + searchCommand, + listPlayersCommand, + analyzeCommand, + networkCommand, + listServersCommand }; CommandNode[] webGroup = { - new WebUserCommand(plugin, registerCommand, this), + webUserCommand.get(), registerCommand }; CommandNode[] manageGroup = { - new InfoCommand(plugin), - new ReloadCommand(plugin), - new ManageCommand(plugin, this), - new StatusCommand<>(plugin, Permissions.MANAGE.getPermission(), plugin.getColorScheme()), - (Settings.DEV_MODE.isTrue() ? new DevCommand(plugin) : null), -// (Settings.ALLOW_UPDATE.isTrue() ? new UpdateCommand() : null) + infoCommand, + reloadCommand, + manageCommand.get(), + config.isTrue(Settings.DEV_MODE) ? devCommand : null }; setNodeGroups(analyticsGroup, webGroup, manageGroup); + commandsRegistered = true; } } diff --git a/Plan/src/main/java/com/djrapitops/plan/command/PlanVelocityCommand.java b/Plan/src/main/java/com/djrapitops/plan/command/PlanVelocityCommand.java new file mode 100644 index 000000000..2bc393ef3 --- /dev/null +++ b/Plan/src/main/java/com/djrapitops/plan/command/PlanVelocityCommand.java @@ -0,0 +1,109 @@ +package com.djrapitops.plan.command; + +import com.djrapitops.plan.command.commands.*; +import com.djrapitops.plan.command.commands.manage.ManageConDebugCommand; +import com.djrapitops.plan.command.commands.manage.ManageRawDataCommand; +import com.djrapitops.plan.command.commands.manage.ManageUninstalledCommand; +import com.djrapitops.plan.system.locale.Locale; +import com.djrapitops.plan.system.locale.lang.DeepHelpLang; +import com.djrapitops.plan.system.settings.Permissions; +import com.djrapitops.plugin.command.ColorScheme; +import com.djrapitops.plugin.command.CommandNode; +import com.djrapitops.plugin.command.CommandType; +import com.djrapitops.plugin.command.TreeCmdNode; +import dagger.Lazy; + +import javax.inject.Inject; +import javax.inject.Singleton; + +/** + * TreeCommand for the /plan command, and all subcommands. + *

+ * Uses the Abstract Plugin Framework for easier command management. + * + * @author Rsl1122 + * @since 1.0.0 + */ +@Singleton +public class PlanVelocityCommand extends TreeCmdNode { + + private final NetworkCommand networkCommand; + private final ListServersCommand listServersCommand; + private final ListPlayersCommand listPlayersCommand; + private final RegisterCommand registerCommand; + private final Lazy webUserCommand; + private final ManageConDebugCommand conDebugCommand; + private final ManageRawDataCommand rawDataCommand; + private final BungeeSetupToggleCommand setupToggleCommand; + private final ReloadCommand reloadCommand; + private final DisableCommand disableCommand; + private final ManageUninstalledCommand uninstalledCommand; + + private boolean commandsRegistered; + + @Inject + public PlanVelocityCommand( + ColorScheme colorScheme, + Locale locale, + // Group 1 + NetworkCommand networkCommand, + ListServersCommand listServersCommand, + ListPlayersCommand listPlayersCommand, + // Group 2 + RegisterCommand registerCommand, + Lazy webUserCommand, + // Group 3 + ManageConDebugCommand conDebugCommand, + ManageRawDataCommand rawDataCommand, + BungeeSetupToggleCommand setupToggleCommand, + ManageUninstalledCommand uninstalledCommand, + ReloadCommand reloadCommand, + DisableCommand disableCommand + ) { + super("planvelocity", Permissions.MANAGE.getPermission(), CommandType.CONSOLE, null); + this.uninstalledCommand = uninstalledCommand; + + commandsRegistered = false; + + this.networkCommand = networkCommand; + this.listServersCommand = listServersCommand; + this.listPlayersCommand = listPlayersCommand; + this.registerCommand = registerCommand; + this.webUserCommand = webUserCommand; + this.conDebugCommand = conDebugCommand; + this.rawDataCommand = rawDataCommand; + this.setupToggleCommand = setupToggleCommand; + this.reloadCommand = reloadCommand; + this.disableCommand = disableCommand; + + getHelpCommand().setPermission(Permissions.MANAGE.getPermission()); + setColorScheme(colorScheme); + setInDepthHelp(locale.getArray(DeepHelpLang.PLAN)); + } + + public void registerCommands() { + if (commandsRegistered) { + return; + } + + CommandNode[] analyticsGroup = { + networkCommand, + listServersCommand, + listPlayersCommand + }; + CommandNode[] webGroup = { + registerCommand, + webUserCommand.get() + }; + CommandNode[] manageGroup = { + conDebugCommand, + rawDataCommand, + setupToggleCommand, + uninstalledCommand, + reloadCommand, + disableCommand + }; + setNodeGroups(analyticsGroup, webGroup, manageGroup); + commandsRegistered = true; + } +} diff --git a/Plan/src/main/java/com/djrapitops/plan/command/commands/AnalyzeCommand.java b/Plan/src/main/java/com/djrapitops/plan/command/commands/AnalyzeCommand.java index 47ef1639a..89d565dcf 100644 --- a/Plan/src/main/java/com/djrapitops/plan/command/commands/AnalyzeCommand.java +++ b/Plan/src/main/java/com/djrapitops/plan/command/commands/AnalyzeCommand.java @@ -1,9 +1,8 @@ package com.djrapitops.plan.command.commands; -import com.djrapitops.plan.PlanPlugin; import com.djrapitops.plan.api.exceptions.connection.WebException; import com.djrapitops.plan.api.exceptions.database.DBOpException; -import com.djrapitops.plan.system.database.databases.Database; +import com.djrapitops.plan.system.database.DBSystem; import com.djrapitops.plan.system.info.InfoSystem; import com.djrapitops.plan.system.info.connection.ConnectionSystem; import com.djrapitops.plan.system.info.server.Server; @@ -15,13 +14,16 @@ import com.djrapitops.plan.system.locale.lang.DeepHelpLang; import com.djrapitops.plan.system.locale.lang.ManageLang; import com.djrapitops.plan.system.processing.Processing; import com.djrapitops.plan.system.settings.Permissions; -import com.djrapitops.plan.system.webserver.WebServerSystem; -import com.djrapitops.plugin.api.utility.log.Log; +import com.djrapitops.plan.system.webserver.WebServer; import com.djrapitops.plugin.command.CommandNode; import com.djrapitops.plugin.command.CommandType; import com.djrapitops.plugin.command.CommandUtils; -import com.djrapitops.plugin.command.ISender; +import com.djrapitops.plugin.command.Sender; +import com.djrapitops.plugin.logging.L; +import com.djrapitops.plugin.logging.error.ErrorHandler; +import javax.inject.Inject; +import javax.inject.Singleton; import java.util.Map; import java.util.Optional; import java.util.UUID; @@ -32,14 +34,38 @@ import java.util.UUID; * @author Rsl1122 * @since 2.0.0 */ +@Singleton public class AnalyzeCommand extends CommandNode { private final Locale locale; + private final Processing processing; + private final InfoSystem infoSystem; + private final ServerInfo serverInfo; + private final WebServer webServer; + private final DBSystem dbSystem; + private final ConnectionSystem connectionSystem; + private final ErrorHandler errorHandler; - public AnalyzeCommand(PlanPlugin plugin) { + @Inject + public AnalyzeCommand( + Locale locale, + Processing processing, + InfoSystem infoSystem, + ServerInfo serverInfo, + WebServer webServer, + DBSystem dbSystem, + ErrorHandler errorHandler + ) { super("analyze|analyse|analysis|a", Permissions.ANALYZE.getPermission(), CommandType.CONSOLE); - locale = plugin.getSystem().getLocaleSystem().getLocale(); + this.locale = locale; + this.processing = processing; + this.infoSystem = infoSystem; + connectionSystem = infoSystem.getConnectionSystem(); + this.serverInfo = serverInfo; + this.webServer = webServer; + this.dbSystem = dbSystem; + this.errorHandler = errorHandler; setShortHelp(locale.getString(CmdHelpLang.ANALYZE)); setInDepthHelp(locale.getArray(DeepHelpLang.ANALYZE)); @@ -47,27 +73,27 @@ public class AnalyzeCommand extends CommandNode { } @Override - public void onCommand(ISender sender, String commandLabel, String[] args) { + public void onCommand(Sender sender, String commandLabel, String[] args) { sender.sendMessage(locale.getString(ManageLang.PROGRESS_START)); - Processing.submitNonCritical(() -> { + processing.submitNonCritical(() -> { try { - Server server = getServer(args).orElseGet(ServerInfo::getServer); + Server server = getServer(args).orElseGet(serverInfo::getServer); UUID serverUUID = server.getUuid(); - InfoSystem.getInstance().generateAnalysisPage(serverUUID); + infoSystem.generateAnalysisPage(serverUUID); sendWebUserNotificationIfNecessary(sender); sendLink(server, sender); } catch (DBOpException | WebException e) { sender.sendMessage("§cError occurred: " + e.toString()); - Log.toLog(this.getClass(), e); + errorHandler.log(L.ERROR, this.getClass(), e); } }); } - private void sendLink(Server server, ISender sender) { + private void sendLink(Server server, Sender sender) { String target = "/server/" + server.getName(); - String url = ConnectionSystem.getAddress() + target; + String url = connectionSystem.getMainAddress() + target; String linkPrefix = locale.getString(CommandLang.LINK_PREFIX); sender.sendMessage(locale.getString(CommandLang.HEADER_ANALYSIS)); // Link @@ -81,19 +107,17 @@ public class AnalyzeCommand extends CommandNode { sender.sendMessage(">"); } - private void sendWebUserNotificationIfNecessary(ISender sender) { - if (WebServerSystem.getInstance().getWebServer().isAuthRequired() && CommandUtils.isPlayer(sender)) { - - boolean senderHasWebUser = Database.getActive().check().doesWebUserExists(sender.getName()); - if (!senderHasWebUser) { - sender.sendMessage("§e" + locale.getString(CommandLang.NO_WEB_USER_NOTIFY)); - } + private void sendWebUserNotificationIfNecessary(Sender sender) { + if (webServer.isAuthRequired() && + CommandUtils.isPlayer(sender) && + !dbSystem.getDatabase().check().doesWebUserExists(sender.getName())) { + sender.sendMessage("§e" + locale.getString(CommandLang.NO_WEB_USER_NOTIFY)); } } private Optional getServer(String[] args) { - if (args.length >= 1 && ConnectionSystem.getInstance().isServerAvailable()) { - Map bukkitServers = Database.getActive().fetch().getBukkitServers(); + if (args.length >= 1 && connectionSystem.isServerAvailable()) { + Map bukkitServers = dbSystem.getDatabase().fetch().getBukkitServers(); String serverIdentifier = getGivenIdentifier(args); for (Map.Entry entry : bukkitServers.entrySet()) { Server server = entry.getValue(); diff --git a/Plan/src/main/java/com/djrapitops/plan/command/commands/BungeeSetupToggleCommand.java b/Plan/src/main/java/com/djrapitops/plan/command/commands/BungeeSetupToggleCommand.java index e4c23e393..1ad623968 100644 --- a/Plan/src/main/java/com/djrapitops/plan/command/commands/BungeeSetupToggleCommand.java +++ b/Plan/src/main/java/com/djrapitops/plan/command/commands/BungeeSetupToggleCommand.java @@ -4,7 +4,6 @@ */ package com.djrapitops.plan.command.commands; -import com.djrapitops.plan.PlanPlugin; import com.djrapitops.plan.system.info.connection.ConnectionSystem; import com.djrapitops.plan.system.locale.Locale; import com.djrapitops.plan.system.locale.lang.CmdHelpLang; @@ -13,7 +12,9 @@ import com.djrapitops.plan.system.locale.lang.DeepHelpLang; import com.djrapitops.plan.system.settings.Permissions; import com.djrapitops.plugin.command.CommandNode; import com.djrapitops.plugin.command.CommandType; -import com.djrapitops.plugin.command.ISender; +import com.djrapitops.plugin.command.Sender; + +import javax.inject.Inject; /** * Command for Toggling whether or not BungeeCord accepts set up requests. @@ -25,27 +26,28 @@ import com.djrapitops.plugin.command.ISender; public class BungeeSetupToggleCommand extends CommandNode { private final Locale locale; + private final ConnectionSystem connectionSystem; - public BungeeSetupToggleCommand(PlanPlugin plugin) { + @Inject + public BungeeSetupToggleCommand(Locale locale, ConnectionSystem connectionSystem) { super("setup", Permissions.MANAGE.getPermission(), CommandType.ALL); - locale = plugin.getSystem().getLocaleSystem().getLocale(); + this.locale = locale; + this.connectionSystem = connectionSystem; setShortHelp(locale.getString(CmdHelpLang.SETUP)); setInDepthHelp(locale.getArray(DeepHelpLang.SETUP)); } @Override - public void onCommand(ISender sender, String s, String[] strings) { - boolean setupAllowed = ConnectionSystem.isSetupAllowed(); - ConnectionSystem connectionSystem = ConnectionSystem.getInstance(); - - if (setupAllowed) { + public void onCommand(Sender sender, String s, String[] strings) { + if (connectionSystem.isSetupAllowed()) { connectionSystem.setSetupAllowed(false); } else { connectionSystem.setSetupAllowed(true); } - String msg = locale.getString(!setupAllowed ? CommandLang.SETUP_ALLOWED : CommandLang.CONNECT_FORBIDDEN); + + String msg = locale.getString(connectionSystem.isSetupAllowed() ? CommandLang.SETUP_ALLOWED : CommandLang.CONNECT_FORBIDDEN); sender.sendMessage(msg); } } diff --git a/Plan/src/main/java/com/djrapitops/plan/command/commands/DevCommand.java b/Plan/src/main/java/com/djrapitops/plan/command/commands/DevCommand.java index 8ca20e7f6..5784b46a9 100644 --- a/Plan/src/main/java/com/djrapitops/plan/command/commands/DevCommand.java +++ b/Plan/src/main/java/com/djrapitops/plan/command/commands/DevCommand.java @@ -4,15 +4,15 @@ */ package com.djrapitops.plan.command.commands; -import com.djrapitops.plan.PlanPlugin; import com.djrapitops.plan.system.locale.Locale; import com.djrapitops.plan.system.locale.lang.CmdHelpLang; import com.djrapitops.plan.system.locale.lang.CommandLang; import com.djrapitops.plugin.command.CommandNode; import com.djrapitops.plugin.command.CommandType; -import com.djrapitops.plugin.command.ISender; +import com.djrapitops.plugin.command.Sender; import com.djrapitops.plugin.utilities.Verify; +import javax.inject.Inject; import java.util.Arrays; /** @@ -24,17 +24,18 @@ public class DevCommand extends CommandNode { private final Locale locale; - public DevCommand(PlanPlugin plugin) { + @Inject + public DevCommand(Locale locale) { super("dev", "plan.*", CommandType.PLAYER_OR_ARGS); - locale = plugin.getSystem().getLocaleSystem().getLocale(); + this.locale = locale; setShortHelp(locale.get(CmdHelpLang.DEV).toString()); setArguments(""); } @Override - public void onCommand(ISender sender, String cmd, String[] args) { + public void onCommand(Sender sender, String cmd, String[] args) { Verify.isTrue(args.length >= 1, () -> new IllegalArgumentException(locale.getString(CommandLang.FAIL_REQ_ONE_ARG, Arrays.toString(this.getArguments())))); diff --git a/Plan/src/main/java/com/djrapitops/plan/command/commands/DisableCommand.java b/Plan/src/main/java/com/djrapitops/plan/command/commands/DisableCommand.java index b54e40b34..9fa0ba748 100644 --- a/Plan/src/main/java/com/djrapitops/plan/command/commands/DisableCommand.java +++ b/Plan/src/main/java/com/djrapitops/plan/command/commands/DisableCommand.java @@ -7,24 +7,29 @@ import com.djrapitops.plan.system.locale.lang.CommandLang; import com.djrapitops.plan.system.locale.lang.DeepHelpLang; import com.djrapitops.plugin.command.CommandNode; import com.djrapitops.plugin.command.CommandType; -import com.djrapitops.plugin.command.ISender; +import com.djrapitops.plugin.command.Sender; + +import javax.inject.Inject; public class DisableCommand extends CommandNode { private final Locale locale; + private final PlanPlugin plugin; - public DisableCommand(PlanPlugin plugin) { + @Inject + public DisableCommand(PlanPlugin plugin, Locale locale) { super("disable", "plan.reload", CommandType.ALL); - locale = plugin.getSystem().getLocaleSystem().getLocale(); + this.plugin = plugin; + this.locale = locale; setShortHelp(locale.getString(CmdHelpLang.DISABLE)); setInDepthHelp(locale.getArray(DeepHelpLang.DISABLE)); } @Override - public void onCommand(ISender sender, String commandLabel, String[] args) { - PlanPlugin.getInstance().onDisable(); + public void onCommand(Sender sender, String commandLabel, String[] args) { + plugin.onDisable(); sender.sendMessage(locale.getString(CommandLang.DISABLE_DISABLED)); } } diff --git a/Plan/src/main/java/com/djrapitops/plan/command/commands/InfoCommand.java b/Plan/src/main/java/com/djrapitops/plan/command/commands/InfoCommand.java index 12210e0de..63e6b2dc5 100644 --- a/Plan/src/main/java/com/djrapitops/plan/command/commands/InfoCommand.java +++ b/Plan/src/main/java/com/djrapitops/plan/command/commands/InfoCommand.java @@ -1,7 +1,7 @@ package com.djrapitops.plan.command.commands; import com.djrapitops.plan.PlanPlugin; -import com.djrapitops.plan.system.database.databases.Database; +import com.djrapitops.plan.system.database.DBSystem; import com.djrapitops.plan.system.info.connection.ConnectionSystem; import com.djrapitops.plan.system.locale.Locale; import com.djrapitops.plan.system.locale.lang.CmdHelpLang; @@ -11,7 +11,9 @@ import com.djrapitops.plan.system.settings.Permissions; import com.djrapitops.plan.system.update.VersionCheckSystem; import com.djrapitops.plugin.command.CommandNode; import com.djrapitops.plugin.command.CommandType; -import com.djrapitops.plugin.command.ISender; +import com.djrapitops.plugin.command.Sender; + +import javax.inject.Inject; /** * This SubCommand is used to view the version and the database type in use. @@ -23,29 +25,42 @@ public class InfoCommand extends CommandNode { private final PlanPlugin plugin; private final Locale locale; + private final DBSystem dbSystem; + private final ConnectionSystem connectionSystem; + private final VersionCheckSystem versionCheckSystem; - public InfoCommand(PlanPlugin plugin) { + @Inject + public InfoCommand( + PlanPlugin plugin, + Locale locale, + DBSystem dbSystem, + ConnectionSystem connectionSystem, + VersionCheckSystem versionCheckSystem + ) { super("info", Permissions.INFO.getPermission(), CommandType.CONSOLE); - locale = plugin.getSystem().getLocaleSystem().getLocale(); + this.plugin = plugin; + this.locale = locale; + this.dbSystem = dbSystem; + this.connectionSystem = connectionSystem; + this.versionCheckSystem = versionCheckSystem; setShortHelp(locale.get(CmdHelpLang.INFO).toString()); - this.plugin = plugin; } @Override - public void onCommand(ISender sender, String commandLabel, String[] args) { + public void onCommand(Sender sender, String commandLabel, String[] args) { String yes = locale.getString(GenericLang.YES); String no = locale.getString(GenericLang.NO); - String updateAvailable = VersionCheckSystem.isNewVersionAvailable() ? yes : no; - String connectedToBungee = ConnectionSystem.getInstance().isServerAvailable() ? yes : no; + String updateAvailable = versionCheckSystem.isNewVersionAvailable() ? yes : no; + String connectedToBungee = connectionSystem.isServerAvailable() ? yes : no; String[] messages = { locale.getString(CommandLang.HEADER_INFO), "", locale.getString(CommandLang.INFO_VERSION, plugin.getVersion()), locale.getString(CommandLang.INFO_UPDATE, updateAvailable), - locale.getString(CommandLang.INFO_DATABASE, Database.getActive().getName()), + locale.getString(CommandLang.INFO_DATABASE, dbSystem.getDatabase().getName()), locale.getString(CommandLang.INFO_BUNGEE_CONNECTION, connectedToBungee), "", ">" diff --git a/Plan/src/main/java/com/djrapitops/plan/command/commands/InspectCommand.java b/Plan/src/main/java/com/djrapitops/plan/command/commands/InspectCommand.java index 1cb962999..9db60f18d 100644 --- a/Plan/src/main/java/com/djrapitops/plan/command/commands/InspectCommand.java +++ b/Plan/src/main/java/com/djrapitops/plan/command/commands/InspectCommand.java @@ -1,26 +1,26 @@ package com.djrapitops.plan.command.commands; -import com.djrapitops.plan.PlanPlugin; import com.djrapitops.plan.api.exceptions.database.DBOpException; -import com.djrapitops.plan.system.database.databases.Database; +import com.djrapitops.plan.system.database.DBSystem; +import com.djrapitops.plan.system.info.connection.ConnectionSystem; import com.djrapitops.plan.system.locale.Locale; import com.djrapitops.plan.system.locale.lang.CmdHelpLang; import com.djrapitops.plan.system.locale.lang.CommandLang; import com.djrapitops.plan.system.locale.lang.DeepHelpLang; import com.djrapitops.plan.system.processing.Processing; -import com.djrapitops.plan.system.processing.processors.info.InspectCacheRequestProcessor; +import com.djrapitops.plan.system.processing.processors.info.InfoProcessors; import com.djrapitops.plan.system.settings.Permissions; import com.djrapitops.plan.system.webserver.WebServer; import com.djrapitops.plan.utilities.MiscUtils; import com.djrapitops.plan.utilities.uuid.UUIDUtility; -import com.djrapitops.plugin.api.utility.log.Log; import com.djrapitops.plugin.command.CommandNode; import com.djrapitops.plugin.command.CommandType; import com.djrapitops.plugin.command.CommandUtils; -import com.djrapitops.plugin.command.ISender; -import com.djrapitops.plugin.task.AbsRunnable; -import com.djrapitops.plugin.task.RunnableFactory; +import com.djrapitops.plugin.command.Sender; +import com.djrapitops.plugin.logging.L; +import com.djrapitops.plugin.logging.error.ErrorHandler; +import javax.inject.Inject; import java.util.UUID; /** @@ -32,19 +32,43 @@ import java.util.UUID; public class InspectCommand extends CommandNode { private final Locale locale; + private final DBSystem dbSystem; + private final WebServer webServer; + private final InfoProcessors processorFactory; + private final Processing processing; + private final ConnectionSystem connectionSystem; + private final UUIDUtility uuidUtility; + private final ErrorHandler errorHandler; - public InspectCommand(PlanPlugin plugin) { + @Inject + public InspectCommand( + Locale locale, + InfoProcessors processorFactory, + Processing processing, + DBSystem dbSystem, + WebServer webServer, + ConnectionSystem connectionSystem, + UUIDUtility uuidUtility, + ErrorHandler errorHandler + ) { super("inspect", Permissions.INSPECT.getPermission(), CommandType.PLAYER_OR_ARGS); + this.processorFactory = processorFactory; + this.processing = processing; + this.connectionSystem = connectionSystem; setArguments(""); - locale = plugin.getSystem().getLocaleSystem().getLocale(); + this.locale = locale; + this.dbSystem = dbSystem; + this.webServer = webServer; + this.uuidUtility = uuidUtility; + this.errorHandler = errorHandler; setShortHelp(locale.getString(CmdHelpLang.INSPECT)); setInDepthHelp(locale.getArray(DeepHelpLang.INSPECT)); } @Override - public void onCommand(ISender sender, String commandLabel, String[] args) { + public void onCommand(Sender sender, String commandLabel, String[] args) { String playerName = MiscUtils.getPlayerName(args, sender); if (playerName == null) { @@ -54,42 +78,53 @@ public class InspectCommand extends CommandNode { runInspectTask(playerName, sender); } - private void runInspectTask(String playerName, ISender sender) { - RunnableFactory.createNew(new AbsRunnable("InspectTask") { - @Override - public void run() { - try { - UUID uuid = UUIDUtility.getUUIDOf(playerName); - if (uuid == null) { - sender.sendMessage(locale.getString(CommandLang.FAIL_USERNAME_NOT_VALID)); - return; - } - - Database activeDB = Database.getActive(); - if (!activeDB.check().isPlayerRegistered(uuid)) { - sender.sendMessage(locale.getString(CommandLang.FAIL_USERNAME_NOT_KNOWN)); - return; - } - - checkWebUserAndNotify(activeDB, sender); - Processing.submit(new InspectCacheRequestProcessor(uuid, sender, playerName, locale)); - } catch (DBOpException e) { - sender.sendMessage("§eDatabase exception occurred: " + e.getMessage()); - Log.toLog(this.getClass(), e); - } finally { - this.cancel(); + private void runInspectTask(String playerName, Sender sender) { + processing.submitNonCritical(() -> { + try { + UUID uuid = uuidUtility.getUUIDOf(playerName); + if (uuid == null) { + sender.sendMessage(locale.getString(CommandLang.FAIL_USERNAME_NOT_VALID)); + return; } + + if (!dbSystem.getDatabase().check().isPlayerRegistered(uuid)) { + sender.sendMessage(locale.getString(CommandLang.FAIL_USERNAME_NOT_KNOWN)); + return; + } + + checkWebUserAndNotify(sender); + processing.submit(processorFactory.inspectCacheRequestProcessor(uuid, sender, playerName, this::sendInspectMsg)); + } catch (DBOpException e) { + sender.sendMessage("§eDatabase exception occurred: " + e.getMessage()); + errorHandler.log(L.ERROR, this.getClass(), e); } - }).runTaskAsynchronously(); + }); } - private void checkWebUserAndNotify(Database activeDB, ISender sender) { - if (CommandUtils.isPlayer(sender) && WebServer.getInstance().isAuthRequired()) { - boolean senderHasWebUser = activeDB.check().doesWebUserExists(sender.getName()); + private void checkWebUserAndNotify(Sender sender) { + if (CommandUtils.isPlayer(sender) && webServer.isAuthRequired()) { + boolean senderHasWebUser = dbSystem.getDatabase().check().doesWebUserExists(sender.getName()); if (!senderHasWebUser) { sender.sendMessage("§e" + locale.getString(CommandLang.NO_WEB_USER_NOTIFY)); } } } + + private void sendInspectMsg(Sender sender, String playerName) { + sender.sendMessage(locale.getString(CommandLang.HEADER_INSPECT, playerName)); + + String url = connectionSystem.getMainAddress() + "/player/" + playerName; + String linkPrefix = locale.getString(CommandLang.LINK_PREFIX); + + boolean console = !CommandUtils.isPlayer(sender); + if (console) { + sender.sendMessage(linkPrefix + url); + } else { + sender.sendMessage(linkPrefix); + sender.sendLink(" ", locale.getString(CommandLang.LINK_CLICK_ME), url); + } + + sender.sendMessage(">"); + } } \ No newline at end of file diff --git a/Plan/src/main/java/com/djrapitops/plan/command/commands/ListPlayersCommand.java b/Plan/src/main/java/com/djrapitops/plan/command/commands/ListPlayersCommand.java index e5d903293..694c9f0cf 100644 --- a/Plan/src/main/java/com/djrapitops/plan/command/commands/ListPlayersCommand.java +++ b/Plan/src/main/java/com/djrapitops/plan/command/commands/ListPlayersCommand.java @@ -1,6 +1,5 @@ package com.djrapitops.plan.command.commands; -import com.djrapitops.plan.PlanPlugin; import com.djrapitops.plan.system.info.connection.ConnectionSystem; import com.djrapitops.plan.system.locale.Locale; import com.djrapitops.plan.system.locale.lang.CmdHelpLang; @@ -10,7 +9,9 @@ import com.djrapitops.plan.system.settings.Permissions; import com.djrapitops.plugin.command.CommandNode; import com.djrapitops.plugin.command.CommandType; import com.djrapitops.plugin.command.CommandUtils; -import com.djrapitops.plugin.command.ISender; +import com.djrapitops.plugin.command.Sender; + +import javax.inject.Inject; /** * Command used to display url to the player list page. @@ -21,26 +22,29 @@ import com.djrapitops.plugin.command.ISender; public class ListPlayersCommand extends CommandNode { private final Locale locale; + private final ConnectionSystem connectionSystem; - public ListPlayersCommand(PlanPlugin plugin) { + @Inject + public ListPlayersCommand(Locale locale, ConnectionSystem connectionSystem) { super("players|pl|playerlist|list", Permissions.INSPECT_OTHER.getPermission(), CommandType.CONSOLE); - locale = plugin.getSystem().getLocaleSystem().getLocale(); + this.locale = locale; + this.connectionSystem = connectionSystem; setShortHelp(locale.getString(CmdHelpLang.PLAYERS)); setInDepthHelp(locale.getArray(DeepHelpLang.PLAYERS)); } @Override - public void onCommand(ISender sender, String commandLabel, String[] args) { + public void onCommand(Sender sender, String commandLabel, String[] args) { sendListMsg(sender); } - private void sendListMsg(ISender sender) { + private void sendListMsg(Sender sender) { sender.sendMessage(locale.getString(CommandLang.HEADER_PLAYERS)); // Link - String url = ConnectionSystem.getAddress() + "/players/"; + String url = connectionSystem.getMainAddress() + "/players/"; String linkPrefix = locale.getString(CommandLang.LINK_PREFIX); boolean console = !CommandUtils.isPlayer(sender); if (console) { diff --git a/Plan/src/main/java/com/djrapitops/plan/command/commands/ListServersCommand.java b/Plan/src/main/java/com/djrapitops/plan/command/commands/ListServersCommand.java index 65c4bf3a1..3e324e2d1 100644 --- a/Plan/src/main/java/com/djrapitops/plan/command/commands/ListServersCommand.java +++ b/Plan/src/main/java/com/djrapitops/plan/command/commands/ListServersCommand.java @@ -1,20 +1,22 @@ package com.djrapitops.plan.command.commands; -import com.djrapitops.plan.PlanPlugin; import com.djrapitops.plan.api.exceptions.database.DBOpException; -import com.djrapitops.plan.system.database.databases.Database; +import com.djrapitops.plan.system.database.DBSystem; import com.djrapitops.plan.system.info.server.Server; import com.djrapitops.plan.system.locale.Locale; import com.djrapitops.plan.system.locale.lang.CmdHelpLang; import com.djrapitops.plan.system.locale.lang.CommandLang; import com.djrapitops.plan.system.locale.lang.DeepHelpLang; import com.djrapitops.plan.system.settings.Permissions; -import com.djrapitops.plugin.api.utility.log.Log; +import com.djrapitops.plan.utilities.formatting.Formatter; +import com.djrapitops.plugin.command.ColorScheme; import com.djrapitops.plugin.command.CommandNode; import com.djrapitops.plugin.command.CommandType; -import com.djrapitops.plugin.command.ISender; -import com.djrapitops.plugin.settings.ColorScheme; +import com.djrapitops.plugin.command.Sender; +import com.djrapitops.plugin.logging.L; +import com.djrapitops.plugin.logging.error.ErrorHandler; +import javax.inject.Inject; import java.util.List; /** @@ -24,35 +26,53 @@ import java.util.List; */ public class ListServersCommand extends CommandNode { - private final PlanPlugin plugin; private final Locale locale; + private final ColorScheme colorScheme; + private final DBSystem dbSystem; + private final ErrorHandler errorHandler; - public ListServersCommand(PlanPlugin plugin) { + @Inject + public ListServersCommand( + Locale locale, + ColorScheme colorScheme, + DBSystem dbSystem, + ErrorHandler errorHandler + ) { super("servers|serverlist|listservers|sl|ls", Permissions.MANAGE.getPermission(), CommandType.CONSOLE); - this.plugin = plugin; - this.locale = plugin.getSystem().getLocaleSystem().getLocale(); + this.locale = locale; + this.colorScheme = colorScheme; + this.dbSystem = dbSystem; + this.errorHandler = errorHandler; setShortHelp(locale.getString(CmdHelpLang.SERVERS)); setInDepthHelp(locale.getArray(DeepHelpLang.SERVERS)); } @Override - public void onCommand(ISender sender, String commandLabel, String[] args) { - ColorScheme colorScheme = plugin.getColorScheme(); + public void onCommand(Sender sender, String commandLabel, String[] args) { String sCol = colorScheme.getSecondaryColor(); String tCol = colorScheme.getTertiaryColor(); + Formatter serverFormatter = serverLister(sCol, tCol); try { sender.sendMessage(locale.getString(CommandLang.HEADER_SERVERS)); - List servers = Database.getActive().fetch().getServers(); - for (Server server : servers) { - sender.sendMessage(" " + tCol + server.getId() + sCol + " : " + server.getName() + " : " + server.getWebAddress()); - } + sendServers(sender, serverFormatter); sender.sendMessage(">"); } catch (DBOpException e) { sender.sendMessage("§cDatabase Exception occurred."); - Log.toLog(this.getClass(), e); + errorHandler.log(L.WARN, this.getClass(), e); } } + private void sendServers(Sender sender, Formatter serverFormatter) { + List servers = dbSystem.getDatabase().fetch().getServers(); + for (Server server : servers) { + sender.sendMessage(serverFormatter.apply(server)); + } + } + + private Formatter serverLister(String tertiaryColor, String secondaryColor) { + return server -> " " + tertiaryColor + server.getId() + secondaryColor + " : " + server.getName() + " : " + server.getWebAddress(); + } + } diff --git a/Plan/src/main/java/com/djrapitops/plan/command/commands/ManageCommand.java b/Plan/src/main/java/com/djrapitops/plan/command/commands/ManageCommand.java index 58a7a6020..82da516e1 100644 --- a/Plan/src/main/java/com/djrapitops/plan/command/commands/ManageCommand.java +++ b/Plan/src/main/java/com/djrapitops/plan/command/commands/ManageCommand.java @@ -1,14 +1,18 @@ package com.djrapitops.plan.command.commands; -import com.djrapitops.plan.PlanPlugin; import com.djrapitops.plan.command.commands.manage.*; import com.djrapitops.plan.system.locale.Locale; import com.djrapitops.plan.system.locale.lang.CmdHelpLang; import com.djrapitops.plan.system.locale.lang.DeepHelpLang; import com.djrapitops.plan.system.settings.Permissions; +import com.djrapitops.plugin.command.ColorScheme; import com.djrapitops.plugin.command.CommandNode; import com.djrapitops.plugin.command.CommandType; import com.djrapitops.plugin.command.TreeCmdNode; +import dagger.Lazy; + +import javax.inject.Inject; +import javax.inject.Named; /** * This SubCommand is used to manage the the plugin's database and components. @@ -18,29 +22,43 @@ import com.djrapitops.plugin.command.TreeCmdNode; */ public class ManageCommand extends TreeCmdNode { - public ManageCommand(PlanPlugin plugin, CommandNode parent) { - super("manage|m", Permissions.MANAGE.getPermission(), CommandType.CONSOLE, parent); - - Locale locale = plugin.getSystem().getLocaleSystem().getLocale(); + @Inject + public ManageCommand(ColorScheme colorScheme, Locale locale, @Named("mainCommand") Lazy parent, + // Group 1 + ManageRawDataCommand rawDataCommand, + ManageMoveCommand moveCommand, + ManageBackupCommand backupCommand, + ManageRemoveCommand removeCommand, + ManageRestoreCommand restoreCommand, + ManageHotSwapCommand hotSwapCommand, + ManageClearCommand clearCommand, + // Group 2 + ManageSetupCommand setupCommand, + ManageConDebugCommand conDebugCommand, + ManageImportCommand importCommand, + ManageDisableCommand disableCommand, + ManageUninstalledCommand uninstalledCommand + ) { + super("manage|m", Permissions.MANAGE.getPermission(), CommandType.CONSOLE, parent.get()); + super.setColorScheme(colorScheme); setShortHelp(locale.getString(CmdHelpLang.MANAGE)); setInDepthHelp(locale.getArray(DeepHelpLang.MANAGE)); - super.setColorScheme(plugin.getColorScheme()); CommandNode[] databaseGroup = { - new ManageRawDataCommand(plugin), - new ManageMoveCommand(plugin), - new ManageBackupCommand(plugin), - new ManageRestoreCommand(plugin), - new ManageRemoveCommand(plugin), - new ManageHotSwapCommand(plugin), - new ManageClearCommand(plugin), + rawDataCommand, + moveCommand, + backupCommand, + restoreCommand, + hotSwapCommand, + removeCommand, + clearCommand, }; CommandNode[] pluginGroup = { - new ManageSetupCommand(plugin), - new ManageConDebugCommand(plugin), - new ManageImportCommand(plugin), - new ManageDisableCommand(plugin), - new ManageUninstalledCommand(plugin) + setupCommand, + conDebugCommand, + importCommand, + disableCommand, + uninstalledCommand }; setNodeGroups(databaseGroup, pluginGroup); } diff --git a/Plan/src/main/java/com/djrapitops/plan/command/commands/NetworkCommand.java b/Plan/src/main/java/com/djrapitops/plan/command/commands/NetworkCommand.java index 85f165364..a899ff7f6 100644 --- a/Plan/src/main/java/com/djrapitops/plan/command/commands/NetworkCommand.java +++ b/Plan/src/main/java/com/djrapitops/plan/command/commands/NetworkCommand.java @@ -1,6 +1,5 @@ package com.djrapitops.plan.command.commands; -import com.djrapitops.plan.PlanPlugin; import com.djrapitops.plan.system.info.connection.ConnectionSystem; import com.djrapitops.plan.system.locale.Locale; import com.djrapitops.plan.system.locale.lang.CmdHelpLang; @@ -10,7 +9,9 @@ import com.djrapitops.plan.system.settings.Permissions; import com.djrapitops.plugin.command.CommandNode; import com.djrapitops.plugin.command.CommandType; import com.djrapitops.plugin.command.CommandUtils; -import com.djrapitops.plugin.command.ISender; +import com.djrapitops.plugin.command.Sender; + +import javax.inject.Inject; /** * Command used to display url to the network page. @@ -20,26 +21,29 @@ import com.djrapitops.plugin.command.ISender; public class NetworkCommand extends CommandNode { private final Locale locale; + private final ConnectionSystem connectionSystem; - public NetworkCommand(PlanPlugin plugin) { + @Inject + public NetworkCommand(Locale locale, ConnectionSystem connectionSystem) { super("network|n|netw", Permissions.ANALYZE.getPermission(), CommandType.CONSOLE); - locale = plugin.getSystem().getLocaleSystem().getLocale(); + this.locale = locale; + this.connectionSystem = connectionSystem; setShortHelp(locale.getString(CmdHelpLang.NETWORK)); setInDepthHelp(locale.getArray(DeepHelpLang.NETWORK)); } @Override - public void onCommand(ISender sender, String commandLabel, String[] args) { + public void onCommand(Sender sender, String commandLabel, String[] args) { sendNetworkMsg(sender); } - private void sendNetworkMsg(ISender sender) { + private void sendNetworkMsg(Sender sender) { sender.sendMessage(locale.getString(CommandLang.HEADER_NETWORK)); // Link - String url = ConnectionSystem.getAddress() + "/network/"; + String url = connectionSystem.getMainAddress() + "/network/"; String linkPrefix = locale.getString(CommandLang.LINK_PREFIX); boolean console = !CommandUtils.isPlayer(sender); if (console) { diff --git a/Plan/src/main/java/com/djrapitops/plan/command/commands/QInspectCommand.java b/Plan/src/main/java/com/djrapitops/plan/command/commands/QInspectCommand.java index 86ac1c98a..52e0c3bf1 100644 --- a/Plan/src/main/java/com/djrapitops/plan/command/commands/QInspectCommand.java +++ b/Plan/src/main/java/com/djrapitops/plan/command/commands/QInspectCommand.java @@ -1,6 +1,5 @@ package com.djrapitops.plan.command.commands; -import com.djrapitops.plan.PlanPlugin; import com.djrapitops.plan.api.exceptions.database.DBOpException; import com.djrapitops.plan.data.container.GeoInfo; import com.djrapitops.plan.data.store.containers.PlayerContainer; @@ -8,25 +7,29 @@ import com.djrapitops.plan.data.store.keys.PlayerKeys; import com.djrapitops.plan.data.store.mutators.ActivityIndex; import com.djrapitops.plan.data.store.mutators.GeoInfoMutator; import com.djrapitops.plan.data.store.mutators.SessionsMutator; -import com.djrapitops.plan.data.store.mutators.formatting.Formatter; -import com.djrapitops.plan.data.store.mutators.formatting.Formatters; import com.djrapitops.plan.data.store.objects.DateHolder; -import com.djrapitops.plan.system.database.databases.Database; +import com.djrapitops.plan.system.database.DBSystem; import com.djrapitops.plan.system.locale.Locale; import com.djrapitops.plan.system.locale.lang.CmdHelpLang; import com.djrapitops.plan.system.locale.lang.CommandLang; import com.djrapitops.plan.system.locale.lang.DeepHelpLang; import com.djrapitops.plan.system.locale.lang.GenericLang; +import com.djrapitops.plan.system.processing.Processing; import com.djrapitops.plan.system.settings.Permissions; +import com.djrapitops.plan.system.settings.Settings; +import com.djrapitops.plan.system.settings.config.PlanConfig; import com.djrapitops.plan.utilities.MiscUtils; +import com.djrapitops.plan.utilities.formatting.Formatter; +import com.djrapitops.plan.utilities.formatting.Formatters; import com.djrapitops.plan.utilities.uuid.UUIDUtility; -import com.djrapitops.plugin.api.utility.log.Log; import com.djrapitops.plugin.command.CommandNode; import com.djrapitops.plugin.command.CommandType; -import com.djrapitops.plugin.command.ISender; -import com.djrapitops.plugin.task.AbsRunnable; -import com.djrapitops.plugin.task.RunnableFactory; +import com.djrapitops.plugin.command.Sender; +import com.djrapitops.plugin.logging.L; +import com.djrapitops.plugin.logging.error.ErrorHandler; +import javax.inject.Inject; +import javax.inject.Singleton; import java.util.ArrayList; import java.util.List; import java.util.Optional; @@ -38,27 +41,44 @@ import java.util.UUID; * @author Rsl1122 * @since 1.0.0 */ +@Singleton public class QInspectCommand extends CommandNode { private final Locale locale; + private final DBSystem dbSystem; + private final PlanConfig config; + private final Processing processing; + private final Formatters formatters; + private final UUIDUtility uuidUtility; + private final ErrorHandler errorHandler; - /** - * Class Constructor. - * - * @param plugin Current instance of Plan - */ - public QInspectCommand(PlanPlugin plugin) { + @Inject + public QInspectCommand( + PlanConfig config, + Locale locale, + Processing processing, + DBSystem dbSystem, + UUIDUtility uuidUtility, + Formatters formatters, + ErrorHandler errorHandler + ) { super("qinspect", Permissions.QUICK_INSPECT.getPermission(), CommandType.PLAYER_OR_ARGS); + this.config = config; + this.processing = processing; + this.formatters = formatters; setArguments(""); - locale = plugin.getSystem().getLocaleSystem().getLocale(); + this.locale = locale; + this.dbSystem = dbSystem; + this.uuidUtility = uuidUtility; + this.errorHandler = errorHandler; setShortHelp(locale.getString(CmdHelpLang.QINSPECT)); setInDepthHelp(locale.getArray(DeepHelpLang.QINSPECT)); } @Override - public void onCommand(ISender sender, String commandLabel, String[] args) { + public void onCommand(Sender sender, String commandLabel, String[] args) { String playerName = MiscUtils.getPlayerName(args, sender, Permissions.QUICK_INSPECT_OTHER); if (playerName == null) { @@ -69,43 +89,42 @@ public class QInspectCommand extends CommandNode { runInspectTask(playerName, sender); } - private void runInspectTask(String playerName, ISender sender) { - RunnableFactory.createNew(new AbsRunnable("InspectTask") { - @Override - public void run() { - try { - UUID uuid = UUIDUtility.getUUIDOf(playerName); - if (uuid == null) { - sender.sendMessage(locale.getString(CommandLang.FAIL_USERNAME_NOT_VALID)); - return; - } - - PlayerContainer container = Database.getActive().fetch().getPlayerContainer(uuid); - if (!container.getValue(PlayerKeys.REGISTERED).isPresent()) { - sender.sendMessage(locale.getString(CommandLang.FAIL_USERNAME_NOT_KNOWN)); - return; - } - - sendMessages(sender, container); - } catch (DBOpException e) { - sender.sendMessage("§eDatabase exception occurred: " + e.getMessage()); - Log.toLog(this.getClass(), e); - } finally { - this.cancel(); + private void runInspectTask(String playerName, Sender sender) { + processing.submitNonCritical(() -> { + try { + UUID uuid = uuidUtility.getUUIDOf(playerName); + if (uuid == null) { + sender.sendMessage(locale.getString(CommandLang.FAIL_USERNAME_NOT_VALID)); + return; } + + PlayerContainer container = dbSystem.getDatabase().fetch().getPlayerContainer(uuid); + if (!container.getValue(PlayerKeys.REGISTERED).isPresent()) { + sender.sendMessage(locale.getString(CommandLang.FAIL_USERNAME_NOT_KNOWN)); + return; + } + + sendMessages(sender, container); + } catch (DBOpException e) { + sender.sendMessage("§eDatabase exception occurred: " + e.getMessage()); + errorHandler.log(L.WARN, this.getClass(), e); } - }).runTaskAsynchronously(); + }); } - private void sendMessages(ISender sender, PlayerContainer player) { + private void sendMessages(Sender sender, PlayerContainer player) { long now = System.currentTimeMillis(); - Formatter timestamp = Formatters.year(); - Formatter length = Formatters.timeAmount(); + Formatter timestamp = formatters.year(); + Formatter length = formatters.timeAmount(); String playerName = player.getValue(PlayerKeys.NAME).orElse(locale.getString(GenericLang.UNKNOWN)); - ActivityIndex activityIndex = player.getActivityIndex(now); + ActivityIndex activityIndex = player.getActivityIndex( + now, + config.getNumber(Settings.ACTIVE_PLAY_THRESHOLD), + config.getNumber(Settings.ACTIVE_LOGIN_THRESHOLD) + ); Long registered = player.getValue(PlayerKeys.REGISTERED).orElse(0L); Long lastSeen = player.getValue(PlayerKeys.LAST_SEEN).orElse(0L); List geoInfo = player.getValue(PlayerKeys.GEO_INFO).orElse(new ArrayList<>()); @@ -115,7 +134,7 @@ public class QInspectCommand extends CommandNode { String[] messages = new String[]{ locale.getString(CommandLang.HEADER_INSPECT, playerName), - locale.getString(CommandLang.QINSPECT_ACTIVITY_INDEX, activityIndex.getFormattedValue(), activityIndex.getGroup()), + locale.getString(CommandLang.QINSPECT_ACTIVITY_INDEX, activityIndex.getFormattedValue(formatters.decimals()), activityIndex.getGroup()), locale.getString(CommandLang.QINSPECT_REGISTERED, timestamp.apply(() -> registered)), locale.getString(CommandLang.QINSPECT_LAST_SEEN, timestamp.apply(() -> lastSeen)), locale.getString(CommandLang.QINSPECT_GEOLOCATION, geolocation), diff --git a/Plan/src/main/java/com/djrapitops/plan/command/commands/RegisterCommand.java b/Plan/src/main/java/com/djrapitops/plan/command/commands/RegisterCommand.java index 133c5d583..9a17b50bf 100644 --- a/Plan/src/main/java/com/djrapitops/plan/command/commands/RegisterCommand.java +++ b/Plan/src/main/java/com/djrapitops/plan/command/commands/RegisterCommand.java @@ -1,24 +1,27 @@ package com.djrapitops.plan.command.commands; -import com.djrapitops.plan.PlanPlugin; import com.djrapitops.plan.data.WebUser; +import com.djrapitops.plan.system.database.DBSystem; import com.djrapitops.plan.system.database.databases.Database; import com.djrapitops.plan.system.locale.Locale; import com.djrapitops.plan.system.locale.lang.CmdHelpLang; import com.djrapitops.plan.system.locale.lang.CommandLang; import com.djrapitops.plan.system.locale.lang.DeepHelpLang; +import com.djrapitops.plan.system.processing.Processing; import com.djrapitops.plan.system.settings.Permissions; import com.djrapitops.plan.utilities.PassEncryptUtil; import com.djrapitops.plugin.api.Check; -import com.djrapitops.plugin.api.utility.log.Log; import com.djrapitops.plugin.command.CommandNode; import com.djrapitops.plugin.command.CommandType; import com.djrapitops.plugin.command.CommandUtils; -import com.djrapitops.plugin.command.ISender; -import com.djrapitops.plugin.task.AbsRunnable; -import com.djrapitops.plugin.task.RunnableFactory; +import com.djrapitops.plugin.command.Sender; +import com.djrapitops.plugin.logging.L; +import com.djrapitops.plugin.logging.console.PluginLogger; +import com.djrapitops.plugin.logging.error.ErrorHandler; import com.djrapitops.plugin.utilities.Verify; +import javax.inject.Inject; +import javax.inject.Singleton; import java.util.Arrays; /** @@ -32,17 +35,32 @@ import java.util.Arrays; * @author Rsl1122 * @since 3.5.2 */ +@Singleton public class RegisterCommand extends CommandNode { private final String notEnoughArgsMsg; - private final String hashErrorMsg; private final Locale locale; + private final Processing processing; + private final DBSystem dbSystem; + private final PluginLogger logger; + private final ErrorHandler errorHandler; - public RegisterCommand(PlanPlugin plugin) { + @Inject + public RegisterCommand( + Locale locale, + Processing processing, + DBSystem dbSystem, + PluginLogger logger, + ErrorHandler errorHandler + ) { // No Permission Requirement super("register", "", CommandType.PLAYER_OR_ARGS); - locale = plugin.getSystem().getLocaleSystem().getLocale(); + this.locale = locale; + this.processing = processing; + this.logger = logger; + this.dbSystem = dbSystem; + this.errorHandler = errorHandler; setArguments("", "[name]", "[lvl]"); setShortHelp(locale.getString(CmdHelpLang.WEB_REGISTER)); @@ -52,11 +70,10 @@ public class RegisterCommand extends CommandNode { } notEnoughArgsMsg = locale.getString(CommandLang.FAIL_REQ_ARGS, 3, Arrays.toString(getArguments())); - hashErrorMsg = "§cPassword hash error."; } @Override - public void onCommand(ISender sender, String commandLabel, String[] args) { + public void onCommand(Sender sender, String commandLabel, String[] args) { try { if (CommandUtils.isPlayer(sender)) { playerRegister(args, sender); @@ -64,16 +81,16 @@ public class RegisterCommand extends CommandNode { consoleRegister(args, sender, notEnoughArgsMsg); } } catch (PassEncryptUtil.CannotPerformOperationException e) { - Log.toLog(this.getClass().getSimpleName(), e); - sender.sendMessage(hashErrorMsg); + errorHandler.log(L.WARN, this.getClass(), e); + sender.sendMessage("§cPassword hash error."); } catch (NumberFormatException e) { throw new NumberFormatException(args[2]); } catch (Exception e) { - Log.toLog(this.getClass().getSimpleName(), e); + errorHandler.log(L.WARN, this.getClass(), e); } } - private void consoleRegister(String[] args, ISender sender, String notEnoughArgsMsg) throws PassEncryptUtil.CannotPerformOperationException { + private void consoleRegister(String[] args, Sender sender, String notEnoughArgsMsg) throws PassEncryptUtil.CannotPerformOperationException { Verify.isTrue(args.length >= 3, () -> new IllegalArgumentException(notEnoughArgsMsg)); int permLevel; @@ -82,7 +99,7 @@ public class RegisterCommand extends CommandNode { registerUser(new WebUser(args[1], passHash, permLevel), sender); } - private void playerRegister(String[] args, ISender sender) throws PassEncryptUtil.CannotPerformOperationException { + private void playerRegister(String[] args, Sender sender) throws PassEncryptUtil.CannotPerformOperationException { boolean registerSenderAsUser = args.length == 1; if (registerSenderAsUser) { String user = sender.getName(); @@ -96,7 +113,7 @@ public class RegisterCommand extends CommandNode { } } - private int getPermissionLevel(ISender sender) { + private int getPermissionLevel(Sender sender) { final String permAnalyze = Permissions.ANALYZE.getPerm(); final String permInspectOther = Permissions.INSPECT_OTHER.getPerm(); final String permInspect = Permissions.INSPECT.getPerm(); @@ -112,30 +129,23 @@ public class RegisterCommand extends CommandNode { return 100; } - private void registerUser(WebUser webUser, ISender sender) { - RunnableFactory.createNew(new AbsRunnable("Register WebUser Task") { - @Override - public void run() { - final String existsMsg = locale.getString(CommandLang.FAIL_WEB_USER_EXISTS); - final String userName = webUser.getName(); - final String successMsg = locale.getString(CommandLang.WEB_USER_REGISTER_SUCCESS); - try { - Database database = Database.getActive(); - boolean userExists = database.check().doesWebUserExists(userName); - if (userExists) { - sender.sendMessage(existsMsg); - return; - } - database.save().webUser(webUser); - sender.sendMessage(successMsg); - Log.info(locale.getString(CommandLang.WEB_USER_REGISTER_NOTIFY, userName, webUser.getPermLevel())); - } catch (Exception e) { - Log.toLog(this.getClass(), e); - } finally { - this.cancel(); + private void registerUser(WebUser webUser, Sender sender) { + processing.submitCritical(() -> { + String userName = webUser.getName(); + try { + Database database = dbSystem.getDatabase(); + boolean userExists = database.check().doesWebUserExists(userName); + if (userExists) { + sender.sendMessage(locale.getString(CommandLang.FAIL_WEB_USER_EXISTS)); + return; } + database.save().webUser(webUser); + sender.sendMessage(locale.getString(CommandLang.WEB_USER_REGISTER_SUCCESS)); + logger.info(locale.getString(CommandLang.WEB_USER_REGISTER_NOTIFY, userName, webUser.getPermLevel())); + } catch (Exception e) { + errorHandler.log(L.WARN, this.getClass(), e); } - }).runTaskAsynchronously(); + }); } /** diff --git a/Plan/src/main/java/com/djrapitops/plan/command/commands/ReloadCommand.java b/Plan/src/main/java/com/djrapitops/plan/command/commands/ReloadCommand.java index 4fb703aae..0cfe4fbdc 100644 --- a/Plan/src/main/java/com/djrapitops/plan/command/commands/ReloadCommand.java +++ b/Plan/src/main/java/com/djrapitops/plan/command/commands/ReloadCommand.java @@ -6,13 +6,16 @@ import com.djrapitops.plan.system.locale.lang.CmdHelpLang; import com.djrapitops.plan.system.locale.lang.CommandLang; import com.djrapitops.plan.system.locale.lang.DeepHelpLang; import com.djrapitops.plan.system.settings.Permissions; -import com.djrapitops.plugin.api.utility.log.Log; import com.djrapitops.plugin.command.CommandNode; import com.djrapitops.plugin.command.CommandType; -import com.djrapitops.plugin.command.ISender; +import com.djrapitops.plugin.command.Sender; +import com.djrapitops.plugin.logging.L; +import com.djrapitops.plugin.logging.error.ErrorHandler; import com.djrapitops.plugin.task.AbsRunnable; import com.djrapitops.plugin.task.RunnableFactory; +import javax.inject.Inject; + /** * This SubCommand is used to reload the plugin. * @@ -23,26 +26,31 @@ public class ReloadCommand extends CommandNode { private final PlanPlugin plugin; private final Locale locale; + private final ErrorHandler errorHandler; + private final RunnableFactory runnableFactory; - public ReloadCommand(PlanPlugin plugin) { + @Inject + public ReloadCommand(PlanPlugin plugin, Locale locale, RunnableFactory runnableFactory, ErrorHandler errorHandler) { super("reload", Permissions.RELOAD.getPermission(), CommandType.CONSOLE); - this.plugin = plugin; - locale = plugin.getSystem().getLocaleSystem().getLocale(); + this.plugin = plugin; + this.locale = locale; + this.runnableFactory = runnableFactory; + this.errorHandler = errorHandler; setShortHelp(locale.getString(CmdHelpLang.RELOAD)); setInDepthHelp(locale.getArray(DeepHelpLang.RELOAD)); } @Override - public void onCommand(ISender sender, String commandLabel, String[] args) { - RunnableFactory.createNew("Reload task", new AbsRunnable() { + public void onCommand(Sender sender, String commandLabel, String[] args) { + runnableFactory.create("Reload task", new AbsRunnable() { @Override public void run() { try { plugin.reloadPlugin(true); } catch (Exception e) { - Log.toLog(this.getClass(), e); + errorHandler.log(L.CRITICAL, this.getClass(), e); sender.sendMessage(locale.getString(CommandLang.RELOAD_FAILED)); } sender.sendMessage(locale.getString(CommandLang.RELOAD_COMPLETE)); diff --git a/Plan/src/main/java/com/djrapitops/plan/command/commands/SearchCommand.java b/Plan/src/main/java/com/djrapitops/plan/command/commands/SearchCommand.java index 5a0e33173..c2bdd8f5f 100644 --- a/Plan/src/main/java/com/djrapitops/plan/command/commands/SearchCommand.java +++ b/Plan/src/main/java/com/djrapitops/plan/command/commands/SearchCommand.java @@ -1,24 +1,25 @@ package com.djrapitops.plan.command.commands; -import com.djrapitops.plan.PlanPlugin; import com.djrapitops.plan.api.exceptions.database.DBOpException; +import com.djrapitops.plan.system.database.DBSystem; import com.djrapitops.plan.system.locale.Locale; import com.djrapitops.plan.system.locale.lang.CmdHelpLang; import com.djrapitops.plan.system.locale.lang.CommandLang; import com.djrapitops.plan.system.locale.lang.DeepHelpLang; import com.djrapitops.plan.system.locale.lang.ManageLang; +import com.djrapitops.plan.system.processing.Processing; import com.djrapitops.plan.system.settings.Permissions; -import com.djrapitops.plan.utilities.MiscUtils; -import com.djrapitops.plugin.api.utility.log.Log; import com.djrapitops.plugin.command.CommandNode; import com.djrapitops.plugin.command.CommandType; -import com.djrapitops.plugin.command.ISender; -import com.djrapitops.plugin.task.AbsRunnable; -import com.djrapitops.plugin.task.RunnableFactory; -import com.djrapitops.plugin.utilities.FormatUtils; +import com.djrapitops.plugin.command.Sender; +import com.djrapitops.plugin.logging.L; +import com.djrapitops.plugin.logging.error.ErrorHandler; import com.djrapitops.plugin.utilities.Verify; +import javax.inject.Inject; +import javax.inject.Singleton; import java.util.Arrays; +import java.util.Collections; import java.util.List; /** @@ -27,14 +28,26 @@ import java.util.List; * @author Rsl1122 * @since 2.0.0 */ +@Singleton public class SearchCommand extends CommandNode { private final Locale locale; + private final Processing processing; + private final DBSystem dbSystem; + private final ErrorHandler errorHandler; - public SearchCommand(PlanPlugin plugin) { + @Inject + public SearchCommand( + Locale locale, + Processing processing, + DBSystem dbSystem, + ErrorHandler errorHandler) { super("search", Permissions.SEARCH.getPermission(), CommandType.PLAYER_OR_ARGS); - locale = plugin.getSystem().getLocaleSystem().getLocale(); + this.locale = locale; + this.processing = processing; + this.dbSystem = dbSystem; + this.errorHandler = errorHandler; setArguments(""); setShortHelp(locale.getString(CmdHelpLang.SEARCH)); @@ -42,7 +55,7 @@ public class SearchCommand extends CommandNode { } @Override - public void onCommand(ISender sender, String commandLabel, String[] args) { + public void onCommand(Sender sender, String commandLabel, String[] args) { Verify.isTrue(args.length >= 1, () -> new IllegalArgumentException(locale.getString(CommandLang.FAIL_REQ_ONE_ARG, Arrays.toString(this.getArguments())))); @@ -51,30 +64,26 @@ public class SearchCommand extends CommandNode { runSearchTask(args, sender); } - private void runSearchTask(String[] args, ISender sender) { - RunnableFactory.createNew(new AbsRunnable("SearchTask: " + Arrays.toString(args)) { - @Override - public void run() { - try { - String searchTerm = args[0]; - List names = MiscUtils.getMatchingPlayerNames(searchTerm); + private void runSearchTask(String[] args, Sender sender) { + processing.submitNonCritical(() -> { + try { + String searchTerm = args[0]; + List names = dbSystem.getDatabase().search().matchingPlayers(searchTerm); + Collections.sort(names); + boolean empty = Verify.isEmpty(names); - boolean empty = Verify.isEmpty(names); - - sender.sendMessage(locale.getString(CommandLang.HEADER_SEARCH, empty ? 0 : names.size(), searchTerm)); - // Results - if (!empty) { - sender.sendMessage(FormatUtils.collectionToStringNoBrackets(names)); - } - - sender.sendMessage(">"); - } catch (DBOpException e) { - sender.sendMessage("§cDatabase error occurred: " + e.getMessage()); - Log.toLog(this.getClass(), e); - } finally { - this.cancel(); + sender.sendMessage(locale.getString(CommandLang.HEADER_SEARCH, empty ? 0 : names.size(), searchTerm)); + // Results + if (!empty) { + String message = names.toString(); + sender.sendMessage(message.substring(1, message.length() - 1)); } + + sender.sendMessage(">"); + } catch (DBOpException e) { + sender.sendMessage("§cDatabase error occurred: " + e.getMessage()); + errorHandler.log(L.ERROR, this.getClass(), e); } - }).runTaskAsynchronously(); + }); } } diff --git a/Plan/src/main/java/com/djrapitops/plan/command/commands/UpdateCommand.java b/Plan/src/main/java/com/djrapitops/plan/command/commands/UpdateCommand.java deleted file mode 100644 index 7e34f18aa..000000000 --- a/Plan/src/main/java/com/djrapitops/plan/command/commands/UpdateCommand.java +++ /dev/null @@ -1,237 +0,0 @@ -package com.djrapitops.plan.command.commands; - -import com.djrapitops.plan.PlanPlugin; -import com.djrapitops.plan.api.exceptions.connection.*; -import com.djrapitops.plan.api.exceptions.database.DBOpException; -import com.djrapitops.plan.command.commands.manage.ManageConDebugCommand; -import com.djrapitops.plan.system.database.databases.Database; -import com.djrapitops.plan.system.database.databases.operation.FetchOperations; -import com.djrapitops.plan.system.info.InfoSystem; -import com.djrapitops.plan.system.info.request.UpdateCancelRequest; -import com.djrapitops.plan.system.info.request.UpdateRequest; -import com.djrapitops.plan.system.info.server.Server; -import com.djrapitops.plan.system.locale.Locale; -import com.djrapitops.plan.system.locale.lang.CmdHelpLang; -import com.djrapitops.plan.system.locale.lang.CommandLang; -import com.djrapitops.plan.system.locale.lang.DeepHelpLang; -import com.djrapitops.plan.system.locale.lang.PluginLang; -import com.djrapitops.plan.system.settings.Permissions; -import com.djrapitops.plan.system.update.VersionCheckSystem; -import com.djrapitops.plan.system.update.VersionInfo; -import com.djrapitops.plan.system.webserver.WebServerSystem; -import com.djrapitops.plugin.api.utility.log.Log; -import com.djrapitops.plugin.command.CommandNode; -import com.djrapitops.plugin.command.CommandType; -import com.djrapitops.plugin.command.CommandUtils; -import com.djrapitops.plugin.command.ISender; -import com.djrapitops.plugin.task.AbsRunnable; -import com.djrapitops.plugin.task.RunnableFactory; - -import java.util.List; -import java.util.Map; -import java.util.Optional; -import java.util.UUID; - -/** - * Command that updates all servers in the network - * - * @author Rsl1122 - */ -public class UpdateCommand extends CommandNode { - - private final Locale locale; - - public UpdateCommand(PlanPlugin plugin) { - super("update", Permissions.MANAGE.getPermission(), CommandType.ALL); - - locale = plugin.getSystem().getLocaleSystem().getLocale(); - - setArguments("[-u]/[cancel]"); - setShortHelp(locale.getString(CmdHelpLang.UPDATE)); - setInDepthHelp(locale.getArray(DeepHelpLang.UPDATE)); - } - - @Override - public void onCommand(ISender sender, String commandLabel, String[] args) { - if (!VersionCheckSystem.isNewVersionAvailable()) { - sender.sendMessage("§a" + locale.getString(PluginLang.VERSION_NEWEST)); - return; - } - - VersionInfo available = VersionCheckSystem.getInstance().getNewVersionAvailable(); - String downloadUrl = available.getDownloadUrl(); - - if (!available.isTrusted()) { - sender.sendMessage(locale.getString(CommandLang.UPDATE_WRONG_URL, "https://github.com/Rsl1122/Plan-PlayerAnalytics/releases/")); - sender.sendLink(downloadUrl, downloadUrl); - return; - } - - if (args.length == 0) { - String message = locale.getString(CommandLang.UPDATE_CHANGE_LOG, available.getVersion().toString()); - String url = available.getChangeLogUrl(); - if (CommandUtils.isConsole(sender)) { - sender.sendMessage(message + url); - } else { - sender.sendMessage(message); - sender.sendLink(" ", locale.getString(CommandLang.LINK_CLICK_ME), url); - } - return; - } - - String firstArgument = args[0]; - RunnableFactory.createNew("Update Command Task", new AbsRunnable() { - @Override - public void run() { - try { - if ("-u".equals(firstArgument)) { - handleUpdate(sender, args); - } else if ("cancel".equals(firstArgument)) { - handleCancel(sender); - } else { - throw new IllegalArgumentException("Unknown argument, use '-u' or 'cancel'"); - } - } finally { - cancel(); - } - } - }).runTaskAsynchronously(); - } - - private void handleCancel(ISender sender) { - try { - cancel(sender, Database.getActive().fetch().getServers()); - sender.sendMessage(locale.getString(CommandLang.UPDATE_CANCEL_SUCCESS)); - } catch (DBOpException e) { - sender.sendMessage("§cDatabase error occurred, cancel could not be performed."); - Log.toLog(this.getClass().getName(), e); - } - } - - private void handleUpdate(ISender sender, String[] args) { - sender.sendMessage(locale.getString(CommandLang.UPDATE_NOTIFY_CANCEL)); - sender.sendMessage(locale.getString(CommandLang.UPDATE_ONLINE_CHECK)); - if (!checkNetworkStatus(sender)) { - sender.sendMessage(locale.getString(CommandLang.UPDATE_FAIL_NOT_ONLINE)); - // If -force, continue, otherwise return. - if (args.length < 2 || !"-force".equals(args[1])) { - return; - } - } - try { - List servers = Database.getActive().fetch().getServers(); - update(sender, servers, args); - } catch (DBOpException e) { - Log.toLog(this.getClass().getName(), e); - } - } - - private void update(ISender sender, List servers, String[] args) { - for (Server server : servers) { - if (update(sender, server)) { - sender.sendMessage(locale.getString(CommandLang.UPDATE_SCHEDULED, server.getName())); - } else { - if (args.length > 1 && "-force".equals(args[1])) { - sender.sendMessage(locale.getString(CommandLang.UPDATE_FAIL_FORCED)); - continue; - } - sender.sendMessage(locale.getString(CommandLang.UPDATE_FAIL_CANCEL)); - cancel(sender, servers); - sender.sendMessage(locale.getString(CommandLang.UPDATE_CANCELLED)); - break; - } - } - } - - private void cancel(ISender sender, List servers) { - for (Server server : servers) { - cancel(sender, server); - } - } - - private void cancel(ISender sender, Server server) { - try { - InfoSystem.getInstance().getConnectionSystem().sendInfoRequest(new UpdateCancelRequest(), server); - } catch (ForbiddenException | GatewayException | InternalErrorException e) { - sender.sendMessage("§cCancel failed on " + server.getName() + ": Odd Exception: " + e.getClass().getSimpleName()); - } catch (UnauthorizedServerException e) { - sender.sendMessage("§cCancel failed on " + server.getName() + ": Unauthorized. " + server.getName() + " might be using different database."); - } catch (ConnectionFailException e) { - sender.sendMessage("§cCancel failed on " + server.getName() + ": " + e.getCause().getClass().getSimpleName() + " " + e.getCause().getMessage()); - String address = server.getWebAddress(); - boolean local = address.contains("localhost") - || address.startsWith("https://:") // IP empty = Localhost - || address.startsWith("http://:") // IP empty = Localhost - || address.contains("127.0.0.1"); - if (!local) { - sender.sendMessage("§cNon-local address, check that port is open"); - } - } catch (NotFoundException e) { - /* Ignored, older version */ - } catch (WebException e) { - sender.sendMessage("§cCancel failed on " + server.getName() + ": Odd Exception:" + e.getClass().getSimpleName()); - } - } - - private boolean update(ISender sender, Server server) { - try { - InfoSystem.getInstance().getConnectionSystem().sendInfoRequest(new UpdateRequest(), server); - return true; - } catch (BadRequestException e) { - sender.sendMessage("§c" + server.getName() + " has Allow-Update set to false, aborting update."); - return false; - } catch (ForbiddenException | GatewayException | InternalErrorException | NoServersException e) { - sender.sendMessage("§c" + server.getName() + ": Odd Exception: " + e.getClass().getSimpleName()); - return false; - } catch (UnauthorizedServerException e) { - sender.sendMessage("§cFail reason: Unauthorized. " + server.getName() + " might be using different database."); - return false; - } catch (ConnectionFailException e) { - sender.sendMessage("§cFail reason: " + e.getCause().getClass().getSimpleName() + " " + e.getCause().getMessage()); - String address = server.getWebAddress(); - boolean local = address.contains("localhost") - || address.startsWith("https://:") // IP empty = Localhost - || address.startsWith("http://:") // IP empty = Localhost - || address.contains("127.0.0.1"); - if (!local) { - sender.sendMessage("§cNon-local address, check that port is open"); - } - return false; - } catch (NotFoundException e) { - sender.sendMessage("§e" + server.getName() + " is using older version and can not be scheduled for update. " + - "You can update it manually, update will proceed."); - return true; - } catch (WebException e) { - sender.sendMessage("§eOdd Exception: " + e.getClass().getSimpleName()); - return false; - } - } - - private boolean checkNetworkStatus(ISender sender) { - try { - FetchOperations fetch = Database.getActive().fetch(); - Optional bungeeInformation = fetch.getBungeeInformation(); - if (!bungeeInformation.isPresent()) { - sender.sendMessage("Bungee address not found in the database, assuming this is not a network."); - return true; - } - Map bukkitServers = fetch.getBukkitServers(); - String accessAddress = WebServerSystem.getInstance().getWebServer().getAccessAddress(); - boolean success = true; - for (Server server : bukkitServers.values()) { - if (!ManageConDebugCommand.testServer(sender, accessAddress, server, locale)) { - success = false; - } - } - Server bungee = bungeeInformation.get(); - if (!ManageConDebugCommand.testServer(sender, accessAddress, bungee, locale)) { - success = false; - } - return success; - } catch (DBOpException e) { - sender.sendMessage("§cDatabase error occurred, update has been cancelled."); - Log.toLog(this.getClass().getName(), e); - return false; - } - } -} \ No newline at end of file diff --git a/Plan/src/main/java/com/djrapitops/plan/command/commands/WebUserCommand.java b/Plan/src/main/java/com/djrapitops/plan/command/commands/WebUserCommand.java index 61eacf38f..dfbcbcb9c 100644 --- a/Plan/src/main/java/com/djrapitops/plan/command/commands/WebUserCommand.java +++ b/Plan/src/main/java/com/djrapitops/plan/command/commands/WebUserCommand.java @@ -1,6 +1,5 @@ package com.djrapitops.plan.command.commands; -import com.djrapitops.plan.PlanPlugin; import com.djrapitops.plan.command.commands.webuser.WebCheckCommand; import com.djrapitops.plan.command.commands.webuser.WebDeleteCommand; import com.djrapitops.plan.command.commands.webuser.WebLevelCommand; @@ -9,9 +8,14 @@ import com.djrapitops.plan.system.locale.Locale; import com.djrapitops.plan.system.locale.lang.CmdHelpLang; import com.djrapitops.plan.system.locale.lang.DeepHelpLang; import com.djrapitops.plan.system.settings.Permissions; +import com.djrapitops.plugin.command.ColorScheme; import com.djrapitops.plugin.command.CommandNode; import com.djrapitops.plugin.command.CommandType; import com.djrapitops.plugin.command.TreeCmdNode; +import dagger.Lazy; + +import javax.inject.Inject; +import javax.inject.Named; /** * Web subcommand used to manage Web users. @@ -21,20 +25,25 @@ import com.djrapitops.plugin.command.TreeCmdNode; */ public class WebUserCommand extends TreeCmdNode { - public WebUserCommand(PlanPlugin plugin, RegisterCommand register, CommandNode parent) { - super("webuser|web", Permissions.MANAGE_WEB.getPerm(), CommandType.CONSOLE, parent); - super.setColorScheme(plugin.getColorScheme()); - - Locale locale = plugin.getSystem().getLocaleSystem().getLocale(); + @Inject + public WebUserCommand(ColorScheme colorScheme, Locale locale, @Named("mainCommand") Lazy parent, + RegisterCommand registerCommand, + WebLevelCommand levelCommand, + WebListUsersCommand listUsersCommand, + WebCheckCommand checkCommand, + WebDeleteCommand deleteCommand + ) { + super("webuser|web", Permissions.MANAGE_WEB.getPerm(), CommandType.CONSOLE, parent.get()); + super.setColorScheme(colorScheme); setShortHelp(locale.getString(CmdHelpLang.WEB)); setInDepthHelp(locale.getArray(DeepHelpLang.WEB)); CommandNode[] webGroup = { - register, - new WebLevelCommand(plugin), - new WebListUsersCommand(plugin), - new WebCheckCommand(plugin), - new WebDeleteCommand(plugin) + registerCommand, + levelCommand, + listUsersCommand, + checkCommand, + deleteCommand }; setNodeGroups(webGroup); } diff --git a/Plan/src/main/java/com/djrapitops/plan/command/commands/manage/ManageBackupCommand.java b/Plan/src/main/java/com/djrapitops/plan/command/commands/manage/ManageBackupCommand.java index 61c7cb34c..6a7d3995b 100644 --- a/Plan/src/main/java/com/djrapitops/plan/command/commands/manage/ManageBackupCommand.java +++ b/Plan/src/main/java/com/djrapitops/plan/command/commands/manage/ManageBackupCommand.java @@ -1,9 +1,7 @@ package com.djrapitops.plan.command.commands.manage; -import com.djrapitops.plan.PlanPlugin; import com.djrapitops.plan.api.exceptions.database.DBException; import com.djrapitops.plan.api.exceptions.database.DBInitException; -import com.djrapitops.plan.data.store.mutators.formatting.Formatters; import com.djrapitops.plan.system.database.DBSystem; import com.djrapitops.plan.system.database.databases.Database; import com.djrapitops.plan.system.database.databases.sql.SQLiteDB; @@ -12,15 +10,19 @@ import com.djrapitops.plan.system.locale.lang.CmdHelpLang; import com.djrapitops.plan.system.locale.lang.CommandLang; import com.djrapitops.plan.system.locale.lang.DeepHelpLang; import com.djrapitops.plan.system.locale.lang.ManageLang; +import com.djrapitops.plan.system.processing.Processing; import com.djrapitops.plan.system.settings.Permissions; -import com.djrapitops.plugin.api.utility.log.Log; +import com.djrapitops.plan.utilities.formatting.Formatter; +import com.djrapitops.plan.utilities.formatting.Formatters; import com.djrapitops.plugin.command.CommandNode; import com.djrapitops.plugin.command.CommandType; -import com.djrapitops.plugin.command.ISender; -import com.djrapitops.plugin.task.AbsRunnable; -import com.djrapitops.plugin.task.RunnableFactory; +import com.djrapitops.plugin.command.Sender; +import com.djrapitops.plugin.logging.L; +import com.djrapitops.plugin.logging.error.ErrorHandler; import com.djrapitops.plugin.utilities.Verify; +import javax.inject.Inject; +import javax.inject.Singleton; import java.util.Arrays; import java.util.Collection; import java.util.UUID; @@ -31,14 +33,35 @@ import java.util.UUID; * @author Rsl1122 * @since 2.3.0 */ +@Singleton public class ManageBackupCommand extends CommandNode { private final Locale locale; + private final Processing processing; + private final DBSystem dbSystem; + private final SQLiteDB.Factory sqliteFactory; + private final ErrorHandler errorHandler; - public ManageBackupCommand(PlanPlugin plugin) { + private final Formatter iso8601LongFormatter; + + @Inject + public ManageBackupCommand( + Locale locale, + Processing processing, + DBSystem dbSystem, + SQLiteDB.Factory sqliteFactory, + Formatters formatters, + ErrorHandler errorHandler + ) { super("backup", Permissions.MANAGE.getPermission(), CommandType.CONSOLE); - locale = plugin.getSystem().getLocaleSystem().getLocale(); + this.locale = locale; + this.processing = processing; + this.dbSystem = dbSystem; + this.sqliteFactory = sqliteFactory; + this.errorHandler = errorHandler; + + this.iso8601LongFormatter = formatters.iso8601NoClockLong(); setShortHelp(locale.getString(CmdHelpLang.MANAGE_BACKUP)); setInDepthHelp(locale.getArray(DeepHelpLang.MANAGE_BACKUP)); @@ -47,7 +70,7 @@ public class ManageBackupCommand extends CommandNode { } @Override - public void onCommand(ISender sender, String commandLabel, String[] args) { + public void onCommand(Sender sender, String commandLabel, String[] args) { try { Verify.isTrue(args.length >= 1, () -> new IllegalArgumentException(locale.getString(CommandLang.FAIL_REQ_ONE_ARG, Arrays.toString(this.getArguments())))); @@ -58,7 +81,8 @@ public class ManageBackupCommand extends CommandNode { Verify.isTrue(isCorrectDB, () -> new IllegalArgumentException(locale.getString(ManageLang.FAIL_INCORRECT_DB, dbName))); - Database database = DBSystem.getActiveDatabaseByName(dbName); + Database database = dbSystem.getActiveDatabaseByName(dbName); + database.init(); runBackupTask(sender, args, database); } catch (DBInitException e) { @@ -66,24 +90,17 @@ public class ManageBackupCommand extends CommandNode { } } - private void runBackupTask(ISender sender, String[] args, Database database) { - RunnableFactory.createNew(new AbsRunnable("BackupTask") { - @Override - public void run() { - try { - Log.debug("Backup", "Start"); - sender.sendMessage(locale.getString(ManageLang.PROGRESS_START)); - createNewBackup(args[0], database); - sender.sendMessage(locale.getString(ManageLang.PROGRESS_SUCCESS)); - } catch (Exception e) { - Log.toLog(ManageBackupCommand.class, e); - sender.sendMessage(locale.getString(ManageLang.PROGRESS_FAIL, e.getMessage())); - } finally { - Log.logDebug("Backup"); - this.cancel(); - } + private void runBackupTask(Sender sender, String[] args, Database database) { + processing.submitCritical(() -> { + try { + sender.sendMessage(locale.getString(ManageLang.PROGRESS_START)); + createNewBackup(args[0], database); + sender.sendMessage(locale.getString(ManageLang.PROGRESS_SUCCESS)); + } catch (Exception e) { + errorHandler.log(L.ERROR, ManageBackupCommand.class, e); + sender.sendMessage(locale.getString(ManageLang.PROGRESS_FAIL, e.getMessage())); } - }).runTaskAsynchronously(); + }); } /** @@ -95,9 +112,9 @@ public class ManageBackupCommand extends CommandNode { private void createNewBackup(String dbName, Database copyFromDB) { SQLiteDB backupDB = null; try { - String timeStamp = Formatters.iso8601NoClock().apply(System::currentTimeMillis); + String timeStamp = iso8601LongFormatter.apply(System.currentTimeMillis()); String fileName = dbName + "-backup-" + timeStamp; - backupDB = new SQLiteDB(fileName, () -> locale); + backupDB = sqliteFactory.usingFileCalled(fileName); Collection uuids = copyFromDB.fetch().getSavedUUIDs(); if (uuids.isEmpty()) { return; @@ -105,7 +122,7 @@ public class ManageBackupCommand extends CommandNode { backupDB.init(); copyFromDB.backup().backup(backupDB); } catch (DBException e) { - Log.toLog(this.getClass(), e); + errorHandler.log(L.ERROR, this.getClass(), e); } finally { if (backupDB != null) { backupDB.close(); diff --git a/Plan/src/main/java/com/djrapitops/plan/command/commands/manage/ManageClearCommand.java b/Plan/src/main/java/com/djrapitops/plan/command/commands/manage/ManageClearCommand.java index 3da5ee20b..e3c153c8f 100644 --- a/Plan/src/main/java/com/djrapitops/plan/command/commands/manage/ManageClearCommand.java +++ b/Plan/src/main/java/com/djrapitops/plan/command/commands/manage/ManageClearCommand.java @@ -1,6 +1,5 @@ package com.djrapitops.plan.command.commands.manage; -import com.djrapitops.plan.PlanPlugin; import com.djrapitops.plan.api.exceptions.database.DBInitException; import com.djrapitops.plan.api.exceptions.database.DBOpException; import com.djrapitops.plan.system.database.DBSystem; @@ -10,15 +9,17 @@ import com.djrapitops.plan.system.locale.lang.CmdHelpLang; import com.djrapitops.plan.system.locale.lang.CommandLang; import com.djrapitops.plan.system.locale.lang.DeepHelpLang; import com.djrapitops.plan.system.locale.lang.ManageLang; +import com.djrapitops.plan.system.processing.Processing; import com.djrapitops.plan.system.settings.Permissions; -import com.djrapitops.plugin.api.utility.log.Log; import com.djrapitops.plugin.command.CommandNode; import com.djrapitops.plugin.command.CommandType; -import com.djrapitops.plugin.command.ISender; -import com.djrapitops.plugin.task.AbsRunnable; -import com.djrapitops.plugin.task.RunnableFactory; +import com.djrapitops.plugin.command.Sender; +import com.djrapitops.plugin.logging.L; +import com.djrapitops.plugin.logging.error.ErrorHandler; import com.djrapitops.plugin.utilities.Verify; +import javax.inject.Inject; +import javax.inject.Singleton; import java.util.Arrays; /** @@ -27,14 +28,27 @@ import java.util.Arrays; * @author Rsl1122 * @since 2.3.0 */ +@Singleton public class ManageClearCommand extends CommandNode { private final Locale locale; + private final Processing processing; + private final DBSystem dbSystem; + private final ErrorHandler errorHandler; - public ManageClearCommand(PlanPlugin plugin) { + @Inject + public ManageClearCommand( + Locale locale, + Processing processing, + DBSystem dbSystem, + ErrorHandler errorHandler + ) { super("clear", Permissions.MANAGE.getPermission(), CommandType.PLAYER_OR_ARGS); - locale = plugin.getSystem().getLocaleSystem().getLocale(); + this.locale = locale; + this.processing = processing; + this.dbSystem = dbSystem; + this.errorHandler = errorHandler; setArguments("", "[-a]"); setShortHelp(locale.getString(CmdHelpLang.MANAGE_CLEAR)); @@ -42,7 +56,7 @@ public class ManageClearCommand extends CommandNode { } @Override - public void onCommand(ISender sender, String commandLabel, String[] args) { + public void onCommand(Sender sender, String commandLabel, String[] args) { Verify.isTrue(args.length >= 1, () -> new IllegalArgumentException(locale.getString(CommandLang.FAIL_REQ_ONE_ARG, Arrays.toString(this.getArguments())))); @@ -58,30 +72,26 @@ public class ManageClearCommand extends CommandNode { } try { - Database database = DBSystem.getActiveDatabaseByName(dbName); + Database database = dbSystem.getActiveDatabaseByName(dbName); + database.init(); runClearTask(sender, database); } catch (DBInitException e) { sender.sendMessage(locale.getString(ManageLang.PROGRESS_FAIL, e.getMessage())); } } - private void runClearTask(ISender sender, Database database) { - RunnableFactory.createNew(new AbsRunnable("DBClearTask") { - @Override - public void run() { - try { - sender.sendMessage(locale.getString(ManageLang.PROGRESS_START)); + private void runClearTask(Sender sender, Database database) { + processing.submitCritical(() -> { + try { + sender.sendMessage(locale.getString(ManageLang.PROGRESS_START)); - database.remove().everything(); + database.remove().everything(); - sender.sendMessage(locale.getString(ManageLang.PROGRESS_SUCCESS)); - } catch (DBOpException e) { - sender.sendMessage(locale.getString(ManageLang.PROGRESS_FAIL, e.getMessage())); - Log.toLog(this.getClass(), e); - } finally { - this.cancel(); - } + sender.sendMessage(locale.getString(ManageLang.PROGRESS_SUCCESS)); + } catch (DBOpException e) { + sender.sendMessage(locale.getString(ManageLang.PROGRESS_FAIL, e.getMessage())); + errorHandler.log(L.ERROR, this.getClass(), e); } - }).runTaskAsynchronously(); + }); } } diff --git a/Plan/src/main/java/com/djrapitops/plan/command/commands/manage/ManageConDebugCommand.java b/Plan/src/main/java/com/djrapitops/plan/command/commands/manage/ManageConDebugCommand.java index 8c1f163cd..e4d420ad3 100644 --- a/Plan/src/main/java/com/djrapitops/plan/command/commands/manage/ManageConDebugCommand.java +++ b/Plan/src/main/java/com/djrapitops/plan/command/commands/manage/ManageConDebugCommand.java @@ -1,10 +1,9 @@ package com.djrapitops.plan.command.commands.manage; -import com.djrapitops.plan.PlanPlugin; import com.djrapitops.plan.api.exceptions.connection.*; -import com.djrapitops.plan.system.database.databases.Database; -import com.djrapitops.plan.system.info.InfoSystem; -import com.djrapitops.plan.system.info.request.CheckConnectionRequest; +import com.djrapitops.plan.system.database.DBSystem; +import com.djrapitops.plan.system.info.connection.ConnectionSystem; +import com.djrapitops.plan.system.info.request.InfoRequestFactory; import com.djrapitops.plan.system.info.server.Server; import com.djrapitops.plan.system.info.server.ServerInfo; import com.djrapitops.plan.system.locale.Locale; @@ -14,13 +13,15 @@ import com.djrapitops.plan.system.locale.lang.DeepHelpLang; import com.djrapitops.plan.system.locale.lang.ManageLang; import com.djrapitops.plan.system.processing.Processing; import com.djrapitops.plan.system.settings.Permissions; -import com.djrapitops.plan.system.webserver.WebServerSystem; +import com.djrapitops.plan.system.webserver.WebServer; import com.djrapitops.plugin.api.Check; +import com.djrapitops.plugin.command.ColorScheme; import com.djrapitops.plugin.command.CommandNode; import com.djrapitops.plugin.command.CommandType; -import com.djrapitops.plugin.command.ISender; -import com.djrapitops.plugin.settings.ColorScheme; +import com.djrapitops.plugin.command.Sender; +import javax.inject.Inject; +import javax.inject.Singleton; import java.util.List; import java.util.UUID; @@ -30,20 +31,45 @@ import java.util.UUID; * @author Rsl1122 * @since 2.3.0 */ +@Singleton public class ManageConDebugCommand extends CommandNode { + private final ColorScheme colorScheme; private final Locale locale; + private final Processing processing; + private final ServerInfo serverInfo; + private final ConnectionSystem connectionSystem; + private final InfoRequestFactory infoRequestFactory; + private final WebServer webServer; + private final DBSystem dbSystem; - public ManageConDebugCommand(PlanPlugin plugin) { + @Inject + public ManageConDebugCommand( + ColorScheme colorScheme, + Locale locale, + Processing processing, + ServerInfo serverInfo, + ConnectionSystem connectionSystem, + InfoRequestFactory infoRequestFactory, + WebServer webServer, + DBSystem dbSystem + ) { super("con", Permissions.MANAGE.getPermission(), CommandType.ALL); - locale = plugin.getSystem().getLocaleSystem().getLocale(); + this.colorScheme = colorScheme; + this.locale = locale; + this.processing = processing; + this.serverInfo = serverInfo; + this.connectionSystem = connectionSystem; + this.infoRequestFactory = infoRequestFactory; + this.webServer = webServer; + this.dbSystem = dbSystem; - setShortHelp(locale.getString(Check.isBungeeAvailable() ? CmdHelpLang.CON : CmdHelpLang.MANAGE_CON)); + setShortHelp(locale.getString(Check.isBungeeAvailable() || Check.isVelocityAvailable() ? CmdHelpLang.CON : CmdHelpLang.MANAGE_CON)); setInDepthHelp(locale.getArray(DeepHelpLang.MANAGE_CON)); } - public static boolean testServer(ISender sender, String accessAddress, Server server, Locale locale) { + private void testServer(Sender sender, String accessAddress, Server server, Locale locale) { String address = server.getWebAddress().toLowerCase(); boolean usingHttps = address.startsWith("https"); boolean local = address.contains("localhost") @@ -52,11 +78,8 @@ public class ManageConDebugCommand extends CommandNode { || address.contains("127.0.0.1"); try { - - InfoSystem.getInstance().getConnectionSystem().sendInfoRequest(new CheckConnectionRequest(accessAddress), server); + connectionSystem.sendInfoRequest(infoRequestFactory.checkConnectionRequest(address), server); sender.sendMessage(getMsgFor(address, usingHttps, local, true, true)); - return true; - } catch (ForbiddenException | BadRequestException | InternalErrorException e) { sender.sendMessage(getMsgFor(address, usingHttps, local, false, false)); sender.sendMessage(locale.getString(ManageLang.CON_EXCEPTION, e.getClass().getSimpleName())); @@ -78,28 +101,27 @@ public class ManageConDebugCommand extends CommandNode { sender.sendMessage(getMsgFor(address, usingHttps, local, false, false)); sender.sendMessage(locale.getString(ManageLang.CON_EXCEPTION, e.getClass().getSimpleName())); } - return false; } @Override - public void onCommand(ISender sender, String commandLabel, String[] args) { - if (!WebServerSystem.isWebServerEnabled()) { + public void onCommand(Sender sender, String commandLabel, String[] args) { + if (!webServer.isEnabled()) { sender.sendMessage(locale.getString(CommandLang.CONNECT_WEBSERVER_NOT_ENABLED)); return; } - Processing.submitNonCritical(() -> testServers(sender)); + processing.submitNonCritical(() -> testServers(sender)); } - private void testServers(ISender sender) { - List servers = Database.getActive().fetch().getServers(); + private void testServers(Sender sender) { + List servers = dbSystem.getDatabase().fetch().getServers(); if (servers.isEmpty()) { sender.sendMessage(locale.getString(ManageLang.CON_NO_SERVERS)); } - String accessAddress = WebServerSystem.getInstance().getWebServer().getAccessAddress(); - UUID thisServer = ServerInfo.getServerUUID(); + String accessAddress = webServer.getAccessAddress(); + UUID thisServer = serverInfo.getServerUUID(); for (Server server : servers) { if (thisServer.equals(server.getUuid())) { continue; @@ -108,10 +130,9 @@ public class ManageConDebugCommand extends CommandNode { } } - private static String getMsgFor(String address, boolean usingHttps, boolean local, boolean successTo, boolean successFrom) { - ColorScheme cs = PlanPlugin.getInstance().getColorScheme(); - String tCol = cs.getTertiaryColor(); - String sCol = cs.getSecondaryColor(); + private String getMsgFor(String address, boolean usingHttps, boolean local, boolean successTo, boolean successFrom) { + String tCol = colorScheme.getTertiaryColor(); + String sCol = colorScheme.getSecondaryColor(); return tCol + address + sCol + ": " + (usingHttps ? "HTTPS" : "HTTP") + " : " + (local ? "Local" : "External") + " : " diff --git a/Plan/src/main/java/com/djrapitops/plan/command/commands/manage/ManageDisableCommand.java b/Plan/src/main/java/com/djrapitops/plan/command/commands/manage/ManageDisableCommand.java index 30725c900..963c9c95c 100644 --- a/Plan/src/main/java/com/djrapitops/plan/command/commands/manage/ManageDisableCommand.java +++ b/Plan/src/main/java/com/djrapitops/plan/command/commands/manage/ManageDisableCommand.java @@ -1,6 +1,5 @@ package com.djrapitops.plan.command.commands.manage; -import com.djrapitops.plan.PlanPlugin; import com.djrapitops.plan.system.listeners.bukkit.PlayerOnlineListener; import com.djrapitops.plan.system.locale.Locale; import com.djrapitops.plan.system.locale.lang.CmdHelpLang; @@ -9,9 +8,10 @@ import com.djrapitops.plan.system.locale.lang.DeepHelpLang; import com.djrapitops.plan.system.settings.Permissions; import com.djrapitops.plugin.command.CommandNode; import com.djrapitops.plugin.command.CommandType; -import com.djrapitops.plugin.command.ISender; +import com.djrapitops.plugin.command.Sender; import com.djrapitops.plugin.utilities.Verify; +import javax.inject.Inject; import java.util.Arrays; /** @@ -24,10 +24,11 @@ public class ManageDisableCommand extends CommandNode { private final Locale locale; - public ManageDisableCommand(PlanPlugin plugin) { + @Inject + public ManageDisableCommand(Locale locale) { super("disable", Permissions.MANAGE.getPermission(), CommandType.PLAYER_OR_ARGS); - locale = plugin.getSystem().getLocaleSystem().getLocale(); + this.locale = locale; setArguments(""); setShortHelp(locale.getString(CmdHelpLang.MANAGE_DISABLE)); @@ -35,7 +36,7 @@ public class ManageDisableCommand extends CommandNode { } @Override - public void onCommand(ISender sender, String commandLabel, String[] args) { + public void onCommand(Sender sender, String commandLabel, String[] args) { Verify.isTrue(args.length >= 1, () -> new IllegalArgumentException(locale.getString(CommandLang.FAIL_REQ_ONE_ARG, Arrays.toString(this.getArguments())))); diff --git a/Plan/src/main/java/com/djrapitops/plan/command/commands/manage/ManageHotSwapCommand.java b/Plan/src/main/java/com/djrapitops/plan/command/commands/manage/ManageHotSwapCommand.java index d8194edce..520f5ca6a 100644 --- a/Plan/src/main/java/com/djrapitops/plan/command/commands/manage/ManageHotSwapCommand.java +++ b/Plan/src/main/java/com/djrapitops/plan/command/commands/manage/ManageHotSwapCommand.java @@ -9,12 +9,16 @@ import com.djrapitops.plan.system.locale.lang.CommandLang; import com.djrapitops.plan.system.locale.lang.ManageLang; import com.djrapitops.plan.system.settings.Permissions; import com.djrapitops.plan.system.settings.Settings; -import com.djrapitops.plugin.api.utility.log.Log; +import com.djrapitops.plan.system.settings.config.PlanConfig; import com.djrapitops.plugin.command.CommandNode; import com.djrapitops.plugin.command.CommandType; -import com.djrapitops.plugin.command.ISender; +import com.djrapitops.plugin.command.Sender; +import com.djrapitops.plugin.logging.L; +import com.djrapitops.plugin.logging.error.ErrorHandler; import com.djrapitops.plugin.utilities.Verify; +import javax.inject.Inject; +import java.io.IOException; import java.util.Arrays; /** @@ -28,19 +32,26 @@ public class ManageHotSwapCommand extends CommandNode { private final PlanPlugin plugin; private final Locale locale; + private final DBSystem dbSystem; + private final PlanConfig config; + private final ErrorHandler errorHandler; - public ManageHotSwapCommand(PlanPlugin plugin) { + @Inject + public ManageHotSwapCommand(PlanPlugin plugin, Locale locale, DBSystem dbSystem, PlanConfig config, ErrorHandler errorHandler) { super("hotswap", Permissions.MANAGE.getPermission(), CommandType.PLAYER_OR_ARGS); - this.plugin = plugin; - locale = plugin.getSystem().getLocaleSystem().getLocale(); + this.plugin = plugin; + this.locale = locale; + this.dbSystem = dbSystem; + this.config = config; + this.errorHandler = errorHandler; setArguments(""); setShortHelp(locale.getString(CmdHelpLang.MANAGE_HOTSWAP)); } @Override - public void onCommand(ISender sender, String commandLabel, String[] args) { + public void onCommand(Sender sender, String commandLabel, String[] args) { Verify.isTrue(args.length >= 1, () -> new IllegalArgumentException(locale.getString(CommandLang.FAIL_REQ_ONE_ARG, Arrays.toString(this.getArguments())))); @@ -50,24 +61,29 @@ public class ManageHotSwapCommand extends CommandNode { Verify.isTrue(isCorrectDB, () -> new IllegalArgumentException(locale.getString(ManageLang.FAIL_INCORRECT_DB, dbName))); - Verify.isFalse(dbName.equals(Database.getActive().getConfigName()), + Verify.isFalse(dbName.equals(dbSystem.getDatabase().getConfigName()), () -> new IllegalArgumentException(locale.getString(ManageLang.FAIL_SAME_DB))); try { - Database database = DBSystem.getActiveDatabaseByName(dbName); + Database database = dbSystem.getActiveDatabaseByName(dbName); + database.init(); if (!database.isOpen()) { return; } } catch (Exception e) { - Log.toLog(this.getClass(), e); + errorHandler.log(L.ERROR, this.getClass(), e); sender.sendMessage(locale.getString(ManageLang.PROGRESS_FAIL, e.getMessage())); return; } - Settings.DB_TYPE.set(dbName); - - Settings.save(); + try { + config.set(Settings.DB_TYPE, dbName); + config.save(); + } catch (IOException e) { + errorHandler.log(L.ERROR, this.getClass(), e); + return; + } plugin.reloadPlugin(true); } } diff --git a/Plan/src/main/java/com/djrapitops/plan/command/commands/manage/ManageImportCommand.java b/Plan/src/main/java/com/djrapitops/plan/command/commands/manage/ManageImportCommand.java index 86dcfd8e8..82f4d3f5c 100644 --- a/Plan/src/main/java/com/djrapitops/plan/command/commands/manage/ManageImportCommand.java +++ b/Plan/src/main/java/com/djrapitops/plan/command/commands/manage/ManageImportCommand.java @@ -1,22 +1,23 @@ package com.djrapitops.plan.command.commands.manage; -import com.djrapitops.plan.PlanPlugin; +import com.djrapitops.plan.system.importing.ImportSystem; +import com.djrapitops.plan.system.importing.importers.Importer; import com.djrapitops.plan.system.locale.Locale; import com.djrapitops.plan.system.locale.lang.CmdHelpLang; import com.djrapitops.plan.system.locale.lang.CommandLang; import com.djrapitops.plan.system.locale.lang.DeepHelpLang; import com.djrapitops.plan.system.locale.lang.ManageLang; -import com.djrapitops.plan.system.processing.importing.ImporterManager; -import com.djrapitops.plan.system.processing.importing.importers.Importer; +import com.djrapitops.plan.system.processing.Processing; import com.djrapitops.plan.system.settings.Permissions; import com.djrapitops.plugin.command.CommandNode; import com.djrapitops.plugin.command.CommandType; -import com.djrapitops.plugin.command.ISender; -import com.djrapitops.plugin.task.AbsRunnable; -import com.djrapitops.plugin.task.RunnableFactory; +import com.djrapitops.plugin.command.Sender; import com.djrapitops.plugin.utilities.Verify; +import javax.inject.Inject; +import javax.inject.Singleton; import java.util.Arrays; +import java.util.Optional; /** * This manage SubCommand is used to import data from 3rd party plugins. @@ -24,14 +25,24 @@ import java.util.Arrays; * @author Rsl1122 * @since 2.3.0 */ +@Singleton public class ManageImportCommand extends CommandNode { private final Locale locale; + private final Processing processing; + private final ImportSystem importSystem; - public ManageImportCommand(PlanPlugin plugin) { + @Inject + public ManageImportCommand( + Locale locale, + Processing processing, + ImportSystem importSystem + ) { super("import", Permissions.MANAGE.getPermission(), CommandType.CONSOLE); - locale = plugin.getSystem().getLocaleSystem().getLocale(); + this.locale = locale; + this.processing = processing; + this.importSystem = importSystem; setArguments("/list", "[import args]"); setShortHelp(locale.getString(CmdHelpLang.MANAGE_IMPORT)); @@ -39,7 +50,7 @@ public class ManageImportCommand extends CommandNode { } @Override - public void onCommand(ISender sender, String commandLabel, String[] args) { + public void onCommand(Sender sender, String commandLabel, String[] args) { Verify.isTrue(args.length >= 1, () -> new IllegalArgumentException(locale.getString(CommandLang.FAIL_REQ_ARGS, "1+", Arrays.toString(this.getArguments())))); @@ -47,28 +58,20 @@ public class ManageImportCommand extends CommandNode { if (importArg.equals("list")) { sender.sendMessage(locale.getString(ManageLang.IMPORTERS)); - ImporterManager.getImporters().stream() - .map(Importer::getNames) - .map(list -> list.get(0)) - .forEach(name -> sender.sendMessage("- " + name)); + importSystem.getImporterNames().forEach(name -> sender.sendMessage("- " + name)); return; } - Importer importer = ImporterManager.getImporter(importArg); - if (importer == null) { + findImporter(sender, importArg); + } + + private void findImporter(Sender sender, String importArg) { + Optional foundImporter = importSystem.getImporter(importArg); + if (foundImporter.isPresent()) { + Importer importer = foundImporter.get(); + processing.submitNonCritical(importer::processImport); + } else { sender.sendMessage(locale.getString(ManageLang.FAIL_IMPORTER_NOT_FOUND, importArg)); - return; } - - RunnableFactory.createNew("Import:" + importArg, new AbsRunnable() { - @Override - public void run() { - try { - importer.processImport(); - } finally { - cancel(); - } - } - }).runTaskAsynchronously(); } } diff --git a/Plan/src/main/java/com/djrapitops/plan/command/commands/manage/ManageMoveCommand.java b/Plan/src/main/java/com/djrapitops/plan/command/commands/manage/ManageMoveCommand.java index 4f8d59075..d5e9adeb5 100644 --- a/Plan/src/main/java/com/djrapitops/plan/command/commands/manage/ManageMoveCommand.java +++ b/Plan/src/main/java/com/djrapitops/plan/command/commands/manage/ManageMoveCommand.java @@ -1,6 +1,5 @@ package com.djrapitops.plan.command.commands.manage; -import com.djrapitops.plan.PlanPlugin; import com.djrapitops.plan.system.database.DBSystem; import com.djrapitops.plan.system.database.databases.Database; import com.djrapitops.plan.system.locale.Locale; @@ -8,15 +7,17 @@ import com.djrapitops.plan.system.locale.lang.CmdHelpLang; import com.djrapitops.plan.system.locale.lang.CommandLang; import com.djrapitops.plan.system.locale.lang.DeepHelpLang; import com.djrapitops.plan.system.locale.lang.ManageLang; +import com.djrapitops.plan.system.processing.Processing; import com.djrapitops.plan.system.settings.Permissions; -import com.djrapitops.plugin.api.utility.log.Log; import com.djrapitops.plugin.command.CommandNode; import com.djrapitops.plugin.command.CommandType; -import com.djrapitops.plugin.command.ISender; -import com.djrapitops.plugin.task.AbsRunnable; -import com.djrapitops.plugin.task.RunnableFactory; +import com.djrapitops.plugin.command.Sender; +import com.djrapitops.plugin.logging.L; +import com.djrapitops.plugin.logging.error.ErrorHandler; import com.djrapitops.plugin.utilities.Verify; +import javax.inject.Inject; +import javax.inject.Singleton; import java.util.Arrays; /** @@ -27,14 +28,27 @@ import java.util.Arrays; * @author Rsl1122 * @since 2.3.0 */ +@Singleton public class ManageMoveCommand extends CommandNode { private final Locale locale; + private final Processing processing; + private final DBSystem dbSystem; + private final ErrorHandler errorHandler; - public ManageMoveCommand(PlanPlugin plugin) { + @Inject + public ManageMoveCommand( + Locale locale, + Processing processing, + DBSystem dbSystem, + ErrorHandler errorHandler + ) { super("move", Permissions.MANAGE.getPermission(), CommandType.PLAYER_OR_ARGS); - locale = plugin.getSystem().getLocaleSystem().getLocale(); + this.locale = locale; + this.processing = processing; + this.dbSystem = dbSystem; + this.errorHandler = errorHandler; setArguments("", "", "[-a]"); setShortHelp(locale.getString(CmdHelpLang.MANAGE_MOVE)); @@ -42,7 +56,7 @@ public class ManageMoveCommand extends CommandNode { } @Override - public void onCommand(ISender sender, String commandLabel, String[] args) { + public void onCommand(Sender sender, String commandLabel, String[] args) { Verify.isTrue(args.length >= 2, () -> new IllegalArgumentException(locale.getString(CommandLang.FAIL_REQ_ARGS, 2, Arrays.toString(this.getArguments())))); @@ -65,8 +79,10 @@ public class ManageMoveCommand extends CommandNode { } try { - final Database fromDatabase = DBSystem.getActiveDatabaseByName(fromDB); - final Database toDatabase = DBSystem.getActiveDatabaseByName(toDB); + final Database fromDatabase = dbSystem.getActiveDatabaseByName(fromDB); + final Database toDatabase = dbSystem.getActiveDatabaseByName(toDB); + fromDatabase.init(); + toDatabase.init(); runMoveTask(fromDatabase, toDatabase, sender); } catch (Exception e) { @@ -74,28 +90,23 @@ public class ManageMoveCommand extends CommandNode { } } - private void runMoveTask(final Database fromDatabase, final Database toDatabase, ISender sender) { - RunnableFactory.createNew(new AbsRunnable("DBMoveTask") { - @Override - public void run() { - try { - sender.sendMessage(locale.getString(ManageLang.PROGRESS_START)); + private void runMoveTask(final Database fromDatabase, final Database toDatabase, Sender sender) { + processing.submitCritical(() -> { + try { + sender.sendMessage(locale.getString(ManageLang.PROGRESS_START)); - fromDatabase.backup().backup(toDatabase); + fromDatabase.backup().backup(toDatabase); - sender.sendMessage(locale.getString(ManageLang.PROGRESS_SUCCESS)); + sender.sendMessage(locale.getString(ManageLang.PROGRESS_SUCCESS)); - boolean movingToCurrentDB = toDatabase.getConfigName().equalsIgnoreCase(Database.getActive().getConfigName()); - if (movingToCurrentDB) { - sender.sendMessage(locale.getString(ManageLang.HOTSWAP_REMINDER, toDatabase.getConfigName())); - } - } catch (Exception e) { - Log.toLog(this.getClass(), e); - sender.sendMessage(locale.getString(ManageLang.PROGRESS_FAIL, e.getMessage())); - } finally { - this.cancel(); + boolean movingToCurrentDB = toDatabase.getConfigName().equalsIgnoreCase(dbSystem.getDatabase().getConfigName()); + if (movingToCurrentDB) { + sender.sendMessage(locale.getString(ManageLang.HOTSWAP_REMINDER, toDatabase.getConfigName())); } + } catch (Exception e) { + errorHandler.log(L.ERROR, this.getClass(), e); + sender.sendMessage(locale.getString(ManageLang.PROGRESS_FAIL, e.getMessage())); } - }).runTaskAsynchronously(); + }); } } diff --git a/Plan/src/main/java/com/djrapitops/plan/command/commands/manage/ManageRawDataCommand.java b/Plan/src/main/java/com/djrapitops/plan/command/commands/manage/ManageRawDataCommand.java index 6cbf86df0..2773d7094 100644 --- a/Plan/src/main/java/com/djrapitops/plan/command/commands/manage/ManageRawDataCommand.java +++ b/Plan/src/main/java/com/djrapitops/plan/command/commands/manage/ManageRawDataCommand.java @@ -1,6 +1,5 @@ package com.djrapitops.plan.command.commands.manage; -import com.djrapitops.plan.PlanPlugin; import com.djrapitops.plan.system.info.connection.ConnectionSystem; import com.djrapitops.plan.system.locale.Locale; import com.djrapitops.plan.system.locale.lang.CmdHelpLang; @@ -11,9 +10,10 @@ import com.djrapitops.plan.utilities.MiscUtils; import com.djrapitops.plugin.command.CommandNode; import com.djrapitops.plugin.command.CommandType; import com.djrapitops.plugin.command.CommandUtils; -import com.djrapitops.plugin.command.ISender; +import com.djrapitops.plugin.command.Sender; import com.djrapitops.plugin.utilities.Verify; +import javax.inject.Inject; import java.util.Arrays; /** @@ -25,11 +25,14 @@ import java.util.Arrays; public class ManageRawDataCommand extends CommandNode { private final Locale locale; + private final ConnectionSystem connectionSystem; - public ManageRawDataCommand(PlanPlugin plugin) { + @Inject + public ManageRawDataCommand(Locale locale, ConnectionSystem connectionSystem) { super("raw", Permissions.MANAGE.getPermission(), CommandType.PLAYER_OR_ARGS); - locale = plugin.getSystem().getLocaleSystem().getLocale(); + this.locale = locale; + this.connectionSystem = connectionSystem; setArguments(""); setShortHelp(locale.getString(CmdHelpLang.MANAGE_RAW_DATA)); @@ -37,7 +40,7 @@ public class ManageRawDataCommand extends CommandNode { } @Override - public void onCommand(ISender sender, String commandLabel, String[] args) { + public void onCommand(Sender sender, String commandLabel, String[] args) { Verify.isTrue(args.length >= 1, () -> new IllegalArgumentException(locale.getString(CommandLang.FAIL_REQ_ONE_ARG, Arrays.toString(this.getArguments())))); @@ -45,7 +48,7 @@ public class ManageRawDataCommand extends CommandNode { sender.sendMessage(locale.getString(CommandLang.HEADER_INSPECT, playerName)); // Link - String url = ConnectionSystem.getInstance().getMainAddress() + "/player/" + playerName + "/raw"; + String url = connectionSystem.getMainAddress() + "/player/" + playerName + "/raw"; String linkPrefix = locale.getString(CommandLang.LINK_PREFIX); boolean console = !CommandUtils.isPlayer(sender); if (console) { diff --git a/Plan/src/main/java/com/djrapitops/plan/command/commands/manage/ManageRemoveCommand.java b/Plan/src/main/java/com/djrapitops/plan/command/commands/manage/ManageRemoveCommand.java index 25cba8866..b91a2d4f1 100644 --- a/Plan/src/main/java/com/djrapitops/plan/command/commands/manage/ManageRemoveCommand.java +++ b/Plan/src/main/java/com/djrapitops/plan/command/commands/manage/ManageRemoveCommand.java @@ -1,41 +1,59 @@ package com.djrapitops.plan.command.commands.manage; -import com.djrapitops.plan.PlanPlugin; import com.djrapitops.plan.api.exceptions.database.DBOpException; +import com.djrapitops.plan.system.database.DBSystem; import com.djrapitops.plan.system.database.databases.Database; import com.djrapitops.plan.system.locale.Locale; import com.djrapitops.plan.system.locale.lang.CmdHelpLang; import com.djrapitops.plan.system.locale.lang.CommandLang; import com.djrapitops.plan.system.locale.lang.DeepHelpLang; import com.djrapitops.plan.system.locale.lang.ManageLang; +import com.djrapitops.plan.system.processing.Processing; import com.djrapitops.plan.system.settings.Permissions; import com.djrapitops.plan.utilities.MiscUtils; import com.djrapitops.plan.utilities.uuid.UUIDUtility; -import com.djrapitops.plugin.api.utility.log.Log; import com.djrapitops.plugin.command.CommandNode; import com.djrapitops.plugin.command.CommandType; -import com.djrapitops.plugin.command.ISender; -import com.djrapitops.plugin.task.AbsRunnable; -import com.djrapitops.plugin.task.RunnableFactory; +import com.djrapitops.plugin.command.Sender; +import com.djrapitops.plugin.logging.L; +import com.djrapitops.plugin.logging.error.ErrorHandler; import com.djrapitops.plugin.utilities.Verify; +import javax.inject.Inject; +import javax.inject.Singleton; import java.util.Arrays; import java.util.UUID; /** * This manage subcommand is used to remove a single player's data from the - * database. + * dbSystem. * * @author Rsl1122 */ +@Singleton public class ManageRemoveCommand extends CommandNode { private final Locale locale; + private final Processing processing; + private final DBSystem dbSystem; + private final UUIDUtility uuidUtility; + private final ErrorHandler errorHandler; - public ManageRemoveCommand(PlanPlugin plugin) { + @Inject + public ManageRemoveCommand( + Locale locale, + Processing processing, + DBSystem dbSystem, + UUIDUtility uuidUtility, + ErrorHandler errorHandler + ) { super("remove|delete", Permissions.MANAGE.getPermission(), CommandType.PLAYER_OR_ARGS); - locale = plugin.getSystem().getLocaleSystem().getLocale(); + this.locale = locale; + this.processing = processing; + this.dbSystem = dbSystem; + this.uuidUtility = uuidUtility; + this.errorHandler = errorHandler; setArguments("", "[-a]"); setShortHelp(locale.getString(CmdHelpLang.MANAGE_REMOVE)); @@ -43,7 +61,7 @@ public class ManageRemoveCommand extends CommandNode { } @Override - public void onCommand(ISender sender, String commandLabel, String[] args) { + public void onCommand(Sender sender, String commandLabel, String[] args) { Verify.isTrue(args.length >= 1, () -> new IllegalArgumentException(locale.getString(CommandLang.FAIL_REQ_ONE_ARG, Arrays.toString(this.getArguments())))); @@ -57,41 +75,40 @@ public class ManageRemoveCommand extends CommandNode { runRemoveTask(playerName, sender, args); } - private void runRemoveTask(String playerName, ISender sender, String[] args) { - RunnableFactory.createNew(new AbsRunnable("DBRemoveTask " + playerName) { - @Override - public void run() { - try { - UUID uuid = UUIDUtility.getUUIDOf(playerName); + private void runRemoveTask(String playerName, Sender sender, String[] args) { + processing.submitCritical(() -> { + try { + UUID uuid = uuidUtility.getUUIDOf(playerName); - if (uuid == null) { - sender.sendMessage(locale.getString(CommandLang.FAIL_USERNAME_NOT_VALID)); - return; - } - - Database database = Database.getActive(); - if (!database.check().isPlayerRegistered(uuid)) { - sender.sendMessage(locale.getString(CommandLang.FAIL_USERNAME_NOT_KNOWN)); - return; - } - - if (!Verify.contains("-a", args)) { - sender.sendMessage(locale.getString(ManageLang.CONFIRMATION, locale.getString(ManageLang.CONFIRM_REMOVAL, database.getName()))); - return; - } - - sender.sendMessage(locale.getString(ManageLang.PROGRESS_START)); - - database.remove().player(uuid); - - sender.sendMessage(locale.getString(ManageLang.PROGRESS_SUCCESS)); - } catch (DBOpException e) { - Log.toLog(this.getClass(), e); - sender.sendMessage(locale.getString(ManageLang.PROGRESS_FAIL, e.getMessage())); - } finally { - this.cancel(); + if (uuid == null) { + sender.sendMessage(locale.getString(CommandLang.FAIL_USERNAME_NOT_VALID)); + return; } + + Database db = dbSystem.getDatabase(); + if (!db.check().isPlayerRegistered(uuid)) { + sender.sendMessage(locale.getString(CommandLang.FAIL_USERNAME_NOT_KNOWN)); + return; + } + + if (!Verify.contains("-a", args)) { + sender.sendMessage( + locale.getString(ManageLang.CONFIRMATION, + locale.getString(ManageLang.CONFIRM_REMOVAL, db.getName()) + ) + ); + return; + } + + sender.sendMessage(locale.getString(ManageLang.PROGRESS_START)); + + db.remove().player(uuid); + + sender.sendMessage(locale.getString(ManageLang.PROGRESS_SUCCESS)); + } catch (DBOpException e) { + errorHandler.log(L.ERROR, this.getClass(), e); + sender.sendMessage(locale.getString(ManageLang.PROGRESS_FAIL, e.getMessage())); } - }).runTaskAsynchronously(); + }); } } diff --git a/Plan/src/main/java/com/djrapitops/plan/command/commands/manage/ManageRestoreCommand.java b/Plan/src/main/java/com/djrapitops/plan/command/commands/manage/ManageRestoreCommand.java index db56b97d1..12dd7cfa3 100644 --- a/Plan/src/main/java/com/djrapitops/plan/command/commands/manage/ManageRestoreCommand.java +++ b/Plan/src/main/java/com/djrapitops/plan/command/commands/manage/ManageRestoreCommand.java @@ -1,23 +1,24 @@ package com.djrapitops.plan.command.commands.manage; -import com.djrapitops.plan.PlanPlugin; import com.djrapitops.plan.system.database.DBSystem; import com.djrapitops.plan.system.database.databases.Database; import com.djrapitops.plan.system.database.databases.sql.SQLiteDB; +import com.djrapitops.plan.system.file.PlanFiles; import com.djrapitops.plan.system.locale.Locale; import com.djrapitops.plan.system.locale.lang.CmdHelpLang; import com.djrapitops.plan.system.locale.lang.CommandLang; import com.djrapitops.plan.system.locale.lang.DeepHelpLang; import com.djrapitops.plan.system.locale.lang.ManageLang; +import com.djrapitops.plan.system.processing.Processing; import com.djrapitops.plan.system.settings.Permissions; -import com.djrapitops.plugin.api.utility.log.Log; import com.djrapitops.plugin.command.CommandNode; import com.djrapitops.plugin.command.CommandType; -import com.djrapitops.plugin.command.ISender; -import com.djrapitops.plugin.task.AbsRunnable; -import com.djrapitops.plugin.task.RunnableFactory; +import com.djrapitops.plugin.command.Sender; +import com.djrapitops.plugin.logging.L; +import com.djrapitops.plugin.logging.error.ErrorHandler; import com.djrapitops.plugin.utilities.Verify; +import javax.inject.Inject; import java.io.File; import java.util.Arrays; @@ -29,14 +30,30 @@ import java.util.Arrays; */ public class ManageRestoreCommand extends CommandNode { - private final PlanPlugin plugin; private final Locale locale; + private final Processing processing; + private final DBSystem dbSystem; + private final ErrorHandler errorHandler; + private final SQLiteDB.Factory sqliteFactory; + private final PlanFiles files; - public ManageRestoreCommand(PlanPlugin plugin) { + @Inject + public ManageRestoreCommand( + Locale locale, + Processing processing, + DBSystem dbSystem, + SQLiteDB.Factory sqliteFactory, + PlanFiles files, + ErrorHandler errorHandler + ) { super("restore", Permissions.MANAGE.getPermission(), CommandType.CONSOLE); - this.plugin = plugin; - locale = plugin.getSystem().getLocaleSystem().getLocale(); + this.locale = locale; + this.processing = processing; + this.dbSystem = dbSystem; + this.sqliteFactory = sqliteFactory; + this.files = files; + this.errorHandler = errorHandler; setArguments("", "", "[-a]"); setShortHelp(locale.getString(CmdHelpLang.MANAGE_RESTORE)); @@ -44,7 +61,7 @@ public class ManageRestoreCommand extends CommandNode { } @Override - public void onCommand(ISender sender, String commandLabel, String[] args) { + public void onCommand(Sender sender, String commandLabel, String[] args) { Verify.isTrue(args.length >= 2, () -> new IllegalArgumentException(locale.getString(CommandLang.FAIL_REQ_ARGS, 2, Arrays.toString(this.getArguments())))); @@ -56,9 +73,11 @@ public class ManageRestoreCommand extends CommandNode { () -> new IllegalArgumentException(locale.getString(ManageLang.FAIL_INCORRECT_DB, dbName))); try { - Database database = DBSystem.getActiveDatabaseByName(dbName); + Database database = dbSystem.getActiveDatabaseByName(dbName); + Verify.isFalse(backupDbName.contains("database") && database instanceof SQLiteDB, () -> new IllegalArgumentException(locale.getString(ManageLang.FAIL_SAME_DB))); + database.init(); if (!Verify.contains("-a", args)) { sender.sendMessage(locale.getString(ManageLang.CONFIRMATION, locale.getString(ManageLang.CONFIRM_OVERWRITE, database.getName()))); @@ -71,40 +90,35 @@ public class ManageRestoreCommand extends CommandNode { } } - private void runRestoreTask(String backupDbName, ISender sender, final Database database) { - RunnableFactory.createNew(new AbsRunnable("RestoreTask") { - @Override - public void run() { - try { - String backupDBName = backupDbName; - boolean containsDBFileExtension = backupDBName.endsWith(".db"); + private void runRestoreTask(String backupDbName, Sender sender, Database database) { + processing.submitCritical(() -> { + try { + String backupDBName = backupDbName; + boolean containsDBFileExtension = backupDBName.endsWith(".db"); - File backupDBFile = new File(plugin.getDataFolder(), backupDBName + (containsDBFileExtension ? "" : ".db")); + File backupDBFile = files.getFileFromPluginFolder(backupDBName + (containsDBFileExtension ? "" : ".db")); - if (!backupDBFile.exists()) { - sender.sendMessage(locale.getString(ManageLang.FAIL_FILE_NOT_FOUND, backupDBFile.getAbsolutePath())); - return; - } - - if (containsDBFileExtension) { - backupDBName = backupDBName.substring(0, backupDBName.length() - 3); - } - - SQLiteDB backupDB = new SQLiteDB(backupDBName, () -> locale); - backupDB.init(); - - sender.sendMessage(locale.getString(ManageLang.PROGRESS_START)); - - database.backup().restore(backupDB); - - sender.sendMessage(locale.getString(ManageLang.PROGRESS_SUCCESS)); - } catch (Exception e) { - Log.toLog(this.getClass(), e); - sender.sendMessage(locale.getString(ManageLang.PROGRESS_FAIL, e.getMessage())); - } finally { - this.cancel(); + if (!backupDBFile.exists()) { + sender.sendMessage(locale.getString(ManageLang.FAIL_FILE_NOT_FOUND, backupDBFile.getAbsolutePath())); + return; } + + if (containsDBFileExtension) { + backupDBName = backupDBName.substring(0, backupDBName.length() - 3); + } + + SQLiteDB backupDB = sqliteFactory.usingFile(backupDBFile); + backupDB.init(); + + sender.sendMessage(locale.getString(ManageLang.PROGRESS_START)); + + database.backup().restore(backupDB); + + sender.sendMessage(locale.getString(ManageLang.PROGRESS_SUCCESS)); + } catch (Exception e) { + errorHandler.log(L.ERROR, this.getClass(), e); + sender.sendMessage(locale.getString(ManageLang.PROGRESS_FAIL, e.getMessage())); } - }).runTaskAsynchronously(); + }); } } diff --git a/Plan/src/main/java/com/djrapitops/plan/command/commands/manage/ManageSetupCommand.java b/Plan/src/main/java/com/djrapitops/plan/command/commands/manage/ManageSetupCommand.java index cbd00231a..dff524d68 100644 --- a/Plan/src/main/java/com/djrapitops/plan/command/commands/manage/ManageSetupCommand.java +++ b/Plan/src/main/java/com/djrapitops/plan/command/commands/manage/ManageSetupCommand.java @@ -1,6 +1,5 @@ package com.djrapitops.plan.command.commands.manage; -import com.djrapitops.plan.PlanPlugin; import com.djrapitops.plan.api.exceptions.connection.*; import com.djrapitops.plan.system.info.InfoSystem; import com.djrapitops.plan.system.locale.Locale; @@ -10,13 +9,17 @@ import com.djrapitops.plan.system.locale.lang.DeepHelpLang; import com.djrapitops.plan.system.processing.Processing; import com.djrapitops.plan.system.settings.Permissions; import com.djrapitops.plan.system.settings.Settings; -import com.djrapitops.plan.system.webserver.WebServerSystem; -import com.djrapitops.plugin.api.utility.log.Log; +import com.djrapitops.plan.system.settings.config.PlanConfig; +import com.djrapitops.plan.system.webserver.WebServer; import com.djrapitops.plugin.command.CommandNode; import com.djrapitops.plugin.command.CommandType; -import com.djrapitops.plugin.command.ISender; +import com.djrapitops.plugin.command.Sender; +import com.djrapitops.plugin.logging.L; +import com.djrapitops.plugin.logging.error.ErrorHandler; import com.djrapitops.plugin.utilities.Verify; +import javax.inject.Inject; +import javax.inject.Singleton; import java.util.Arrays; /** @@ -25,14 +28,33 @@ import java.util.Arrays; * @author Rsl1122 * @since 2.3.0 */ +@Singleton public class ManageSetupCommand extends CommandNode { private final Locale locale; + private final PlanConfig config; + private final Processing processing; + private final InfoSystem infoSystem; + private final WebServer webServer; + private final ErrorHandler errorHandler; - public ManageSetupCommand(PlanPlugin plugin) { + @Inject + public ManageSetupCommand( + Locale locale, + PlanConfig config, + Processing processing, + InfoSystem infoSystem, + WebServer webServer, + ErrorHandler errorHandler + ) { super("setup", Permissions.MANAGE.getPermission(), CommandType.PLAYER_OR_ARGS); - locale = plugin.getSystem().getLocaleSystem().getLocale(); + this.locale = locale; + this.config = config; + this.processing = processing; + this.infoSystem = infoSystem; + this.webServer = webServer; + this.errorHandler = errorHandler; setArguments(""); setShortHelp(locale.getString(CmdHelpLang.MANAGE_SETUP)); @@ -40,11 +62,11 @@ public class ManageSetupCommand extends CommandNode { } @Override - public void onCommand(ISender sender, String commandLabel, String[] args) { + public void onCommand(Sender sender, String commandLabel, String[] args) { Verify.isTrue(args.length >= 1, () -> new IllegalArgumentException(locale.getString(CommandLang.FAIL_REQ_ONE_ARG, Arrays.toString(this.getArguments())))); - if (!WebServerSystem.isWebServerEnabled()) { + if (!webServer.isEnabled()) { sender.sendMessage(locale.getString(CommandLang.CONNECT_WEBSERVER_NOT_ENABLED)); return; } @@ -60,13 +82,13 @@ public class ManageSetupCommand extends CommandNode { requestSetup(sender, address); } - private void requestSetup(ISender sender, String address) { - Processing.submitNonCritical(() -> { + private void requestSetup(Sender sender, String address) { + processing.submitNonCritical(() -> { try { - Settings.BUNGEE_OVERRIDE_STANDALONE_MODE.set(false); - Settings.BUNGEE_COPY_CONFIG.set(true); + config.set(Settings.BUNGEE_OVERRIDE_STANDALONE_MODE, false); + config.set(Settings.BUNGEE_COPY_CONFIG, true); - InfoSystem.getInstance().requestSetUp(address); + infoSystem.requestSetUp(address); sender.sendMessage(locale.getString(CommandLang.CONNECT_SUCCESS)); } catch (ForbiddenException e) { @@ -82,7 +104,7 @@ public class ManageSetupCommand extends CommandNode { } catch (GatewayException e) { sender.sendMessage(locale.getString(CommandLang.CONNECT_GATEWAY)); } catch (WebException e) { - Log.toLog(this.getClass(), e); + errorHandler.log(L.WARN, this.getClass(), e); sender.sendMessage(locale.getString(CommandLang.CONNECT_FAIL, e.toString())); } }); diff --git a/Plan/src/main/java/com/djrapitops/plan/command/commands/manage/ManageUninstalledCommand.java b/Plan/src/main/java/com/djrapitops/plan/command/commands/manage/ManageUninstalledCommand.java index 456f388f0..b3d925b60 100644 --- a/Plan/src/main/java/com/djrapitops/plan/command/commands/manage/ManageUninstalledCommand.java +++ b/Plan/src/main/java/com/djrapitops/plan/command/commands/manage/ManageUninstalledCommand.java @@ -1,8 +1,7 @@ package com.djrapitops.plan.command.commands.manage; -import com.djrapitops.plan.PlanPlugin; import com.djrapitops.plan.api.exceptions.database.DBOpException; -import com.djrapitops.plan.system.database.databases.Database; +import com.djrapitops.plan.system.database.DBSystem; import com.djrapitops.plan.system.info.server.Server; import com.djrapitops.plan.system.info.server.ServerInfo; import com.djrapitops.plan.system.locale.Locale; @@ -11,11 +10,14 @@ import com.djrapitops.plan.system.locale.lang.DeepHelpLang; import com.djrapitops.plan.system.locale.lang.ManageLang; import com.djrapitops.plan.system.processing.Processing; import com.djrapitops.plan.system.settings.Permissions; -import com.djrapitops.plugin.api.utility.log.Log; import com.djrapitops.plugin.command.CommandNode; import com.djrapitops.plugin.command.CommandType; -import com.djrapitops.plugin.command.ISender; +import com.djrapitops.plugin.command.Sender; +import com.djrapitops.plugin.logging.L; +import com.djrapitops.plugin.logging.error.ErrorHandler; +import javax.inject.Inject; +import javax.inject.Singleton; import java.util.Map; import java.util.Optional; import java.util.UUID; @@ -26,14 +28,30 @@ import java.util.UUID; * @author Rsl1122 * @since 2.0.0 */ +@Singleton public class ManageUninstalledCommand extends CommandNode { private final Locale locale; + private final Processing processing; + private final DBSystem dbSystem; + private final ErrorHandler errorHandler; + private final ServerInfo serverInfo; - public ManageUninstalledCommand(PlanPlugin plugin) { + @Inject + public ManageUninstalledCommand( + Locale locale, + Processing processing, + DBSystem dbSystem, + ServerInfo serverInfo, + ErrorHandler errorHandler + ) { super("uninstalled", Permissions.MANAGE.getPermission(), CommandType.ALL_WITH_ARGS); - locale = plugin.getSystem().getLocaleSystem().getLocale(); + this.locale = locale; + this.processing = processing; + this.dbSystem = dbSystem; + this.serverInfo = serverInfo; + this.errorHandler = errorHandler; setShortHelp(locale.getString(CmdHelpLang.MANAGE_UNINSTALLED)); setInDepthHelp(locale.getArray(DeepHelpLang.MANAGE_UNINSTALLED)); @@ -41,10 +59,10 @@ public class ManageUninstalledCommand extends CommandNode { } @Override - public void onCommand(ISender sender, String commandLabel, String[] args) { + public void onCommand(Sender sender, String commandLabel, String[] args) { sender.sendMessage(locale.getString(ManageLang.PROGRESS_START)); - Processing.submitNonCritical(() -> { + processing.submitNonCritical(() -> { try { Optional serverOptional = getServer(args); if (!serverOptional.isPresent()) { @@ -53,23 +71,23 @@ public class ManageUninstalledCommand extends CommandNode { } Server server = serverOptional.get(); UUID serverUUID = server.getUuid(); - if (ServerInfo.getServerUUID().equals(serverUUID)) { + if (serverInfo.getServerUUID().equals(serverUUID)) { sender.sendMessage(locale.getString(ManageLang.UNINSTALLING_SAME_SERVER)); return; } - Database.getActive().save().setAsUninstalled(serverUUID); + dbSystem.getDatabase().save().setAsUninstalled(serverUUID); sender.sendMessage(locale.getString(ManageLang.PROGRESS_SUCCESS)); } catch (DBOpException e) { sender.sendMessage("§cError occurred: " + e.toString()); - Log.toLog(this.getClass(), e); + errorHandler.log(L.ERROR, this.getClass(), e); } }); } private Optional getServer(String[] args) { if (args.length >= 1) { - Map bukkitServers = Database.getActive().fetch().getBukkitServers(); + Map bukkitServers = dbSystem.getDatabase().fetch().getBukkitServers(); String serverIdentifier = getGivenIdentifier(args); for (Map.Entry entry : bukkitServers.entrySet()) { Server server = entry.getValue(); diff --git a/Plan/src/main/java/com/djrapitops/plan/command/commands/webuser/WebCheckCommand.java b/Plan/src/main/java/com/djrapitops/plan/command/commands/webuser/WebCheckCommand.java index 85b327061..2b51491eb 100644 --- a/Plan/src/main/java/com/djrapitops/plan/command/commands/webuser/WebCheckCommand.java +++ b/Plan/src/main/java/com/djrapitops/plan/command/commands/webuser/WebCheckCommand.java @@ -1,21 +1,23 @@ package com.djrapitops.plan.command.commands.webuser; -import com.djrapitops.plan.PlanPlugin; import com.djrapitops.plan.data.WebUser; +import com.djrapitops.plan.system.database.DBSystem; import com.djrapitops.plan.system.database.databases.Database; import com.djrapitops.plan.system.locale.Locale; import com.djrapitops.plan.system.locale.lang.CmdHelpLang; import com.djrapitops.plan.system.locale.lang.CommandLang; import com.djrapitops.plan.system.locale.lang.ManageLang; +import com.djrapitops.plan.system.processing.Processing; import com.djrapitops.plan.system.settings.Permissions; -import com.djrapitops.plugin.api.utility.log.Log; import com.djrapitops.plugin.command.CommandNode; import com.djrapitops.plugin.command.CommandType; -import com.djrapitops.plugin.command.ISender; -import com.djrapitops.plugin.task.AbsRunnable; -import com.djrapitops.plugin.task.RunnableFactory; +import com.djrapitops.plugin.command.Sender; +import com.djrapitops.plugin.logging.L; +import com.djrapitops.plugin.logging.error.ErrorHandler; import com.djrapitops.plugin.utilities.Verify; +import javax.inject.Inject; +import javax.inject.Singleton; import java.util.Arrays; /** @@ -24,45 +26,53 @@ import java.util.Arrays; * @author Rsl1122 * @since 3.5.2 */ +@Singleton public class WebCheckCommand extends CommandNode { private final Locale locale; + private final Processing processing; + private final DBSystem dbSystem; + private final ErrorHandler errorHandler; - public WebCheckCommand(PlanPlugin plugin) { + @Inject + public WebCheckCommand( + Locale locale, + Processing processing, + DBSystem dbSystem, + ErrorHandler errorHandler + ) { super("check", Permissions.MANAGE_WEB.getPerm(), CommandType.PLAYER_OR_ARGS); - locale = plugin.getSystem().getLocaleSystem().getLocale(); + this.locale = locale; + this.processing = processing; + this.dbSystem = dbSystem; + this.errorHandler = errorHandler; setShortHelp(locale.getString(CmdHelpLang.WEB_CHECK)); setArguments(""); } @Override - public void onCommand(ISender sender, String commandLabel, String[] args) { + public void onCommand(Sender sender, String commandLabel, String[] args) { Verify.isTrue(args.length >= 1, () -> new IllegalArgumentException(locale.getString(CommandLang.FAIL_REQ_ONE_ARG, Arrays.toString(this.getArguments())))); - Database database = Database.getActive(); String user = args[0]; - RunnableFactory.createNew(new AbsRunnable("Webuser Check Task: " + user) { - @Override - public void run() { - try { - if (!database.check().doesWebUserExists(user)) { - sender.sendMessage(locale.getString(CommandLang.FAIL_WEB_USER_NOT_EXISTS)); - return; - } - WebUser info = database.fetch().getWebUser(user); - sender.sendMessage(locale.getString(CommandLang.WEB_USER_LIST, info.getName(), info.getPermLevel())); - } catch (Exception e) { - Log.toLog(this.getClass(), e); - sender.sendMessage(locale.getString(ManageLang.PROGRESS_FAIL, e.getMessage())); - } finally { - this.cancel(); + processing.submitNonCritical(() -> { + try { + Database db = dbSystem.getDatabase(); + if (!db.check().doesWebUserExists(user)) { + sender.sendMessage(locale.getString(CommandLang.FAIL_WEB_USER_NOT_EXISTS)); + return; } + WebUser info = db.fetch().getWebUser(user); + sender.sendMessage(locale.getString(CommandLang.WEB_USER_LIST, info.getName(), info.getPermLevel())); + } catch (Exception e) { + errorHandler.log(L.ERROR, this.getClass(), e); + sender.sendMessage(locale.getString(ManageLang.PROGRESS_FAIL, e.getMessage())); } - }).runTaskAsynchronously(); + }); } } diff --git a/Plan/src/main/java/com/djrapitops/plan/command/commands/webuser/WebDeleteCommand.java b/Plan/src/main/java/com/djrapitops/plan/command/commands/webuser/WebDeleteCommand.java index bd9df7675..cad0252c7 100644 --- a/Plan/src/main/java/com/djrapitops/plan/command/commands/webuser/WebDeleteCommand.java +++ b/Plan/src/main/java/com/djrapitops/plan/command/commands/webuser/WebDeleteCommand.java @@ -1,20 +1,22 @@ package com.djrapitops.plan.command.commands.webuser; -import com.djrapitops.plan.PlanPlugin; +import com.djrapitops.plan.system.database.DBSystem; import com.djrapitops.plan.system.database.databases.Database; import com.djrapitops.plan.system.locale.Locale; import com.djrapitops.plan.system.locale.lang.CmdHelpLang; import com.djrapitops.plan.system.locale.lang.CommandLang; import com.djrapitops.plan.system.locale.lang.ManageLang; +import com.djrapitops.plan.system.processing.Processing; import com.djrapitops.plan.system.settings.Permissions; -import com.djrapitops.plugin.api.utility.log.Log; import com.djrapitops.plugin.command.CommandNode; import com.djrapitops.plugin.command.CommandType; -import com.djrapitops.plugin.command.ISender; -import com.djrapitops.plugin.task.AbsRunnable; -import com.djrapitops.plugin.task.RunnableFactory; +import com.djrapitops.plugin.command.Sender; +import com.djrapitops.plugin.logging.L; +import com.djrapitops.plugin.logging.error.ErrorHandler; import com.djrapitops.plugin.utilities.Verify; +import javax.inject.Inject; +import javax.inject.Singleton; import java.util.Arrays; /** @@ -23,45 +25,53 @@ import java.util.Arrays; * @author Rsl1122 * @since 3.5.2 */ +@Singleton public class WebDeleteCommand extends CommandNode { private final Locale locale; + private final Processing processing; + private final DBSystem dbSystem; + private final ErrorHandler errorHandler; - public WebDeleteCommand(PlanPlugin plugin) { + @Inject + public WebDeleteCommand( + Locale locale, + Processing processing, + DBSystem dbSystem, + ErrorHandler errorHandler + ) { super("delete|remove", Permissions.MANAGE_WEB.getPerm(), CommandType.PLAYER_OR_ARGS); - locale = plugin.getSystem().getLocaleSystem().getLocale(); + this.locale = locale; + this.processing = processing; + this.dbSystem = dbSystem; + this.errorHandler = errorHandler; setShortHelp(locale.getString(CmdHelpLang.WEB_DELETE)); setArguments(""); } @Override - public void onCommand(ISender sender, String commandLabel, String[] args) { + public void onCommand(Sender sender, String commandLabel, String[] args) { Verify.isTrue(args.length >= 1, () -> new IllegalArgumentException(locale.getString(CommandLang.FAIL_REQ_ONE_ARG, Arrays.toString(this.getArguments())))); - Database database = Database.getActive(); String user = args[0]; - RunnableFactory.createNew("Webuser Delete Task: " + user, new AbsRunnable() { - @Override - public void run() { - try { - if (!database.check().doesWebUserExists(user)) { - sender.sendMessage("§c[Plan] User Doesn't exist."); - return; - } - database.remove().webUser(user); - sender.sendMessage(locale.getString(ManageLang.PROGRESS_SUCCESS)); - } catch (Exception e) { - Log.toLog(this.getClass(), e); - sender.sendMessage(locale.getString(ManageLang.PROGRESS_FAIL, e.getMessage())); - } finally { - this.cancel(); + processing.submitNonCritical(() -> { + try { + Database db = dbSystem.getDatabase(); + if (!db.check().doesWebUserExists(user)) { + sender.sendMessage("§c[Plan] User Doesn't exist."); + return; } + db.remove().webUser(user); + sender.sendMessage(locale.getString(ManageLang.PROGRESS_SUCCESS)); + } catch (Exception e) { + errorHandler.log(L.ERROR, this.getClass(), e); + sender.sendMessage(locale.getString(ManageLang.PROGRESS_FAIL, e.getMessage())); } - }).runTaskAsynchronously(); + }); } } diff --git a/Plan/src/main/java/com/djrapitops/plan/command/commands/webuser/WebLevelCommand.java b/Plan/src/main/java/com/djrapitops/plan/command/commands/webuser/WebLevelCommand.java index 105fdbb6a..27e8589d0 100644 --- a/Plan/src/main/java/com/djrapitops/plan/command/commands/webuser/WebLevelCommand.java +++ b/Plan/src/main/java/com/djrapitops/plan/command/commands/webuser/WebLevelCommand.java @@ -1,13 +1,14 @@ package com.djrapitops.plan.command.commands.webuser; -import com.djrapitops.plan.PlanPlugin; import com.djrapitops.plan.system.locale.Locale; import com.djrapitops.plan.system.locale.lang.CmdHelpLang; import com.djrapitops.plan.system.locale.lang.CommandLang; import com.djrapitops.plan.system.settings.Permissions; import com.djrapitops.plugin.command.CommandNode; import com.djrapitops.plugin.command.CommandType; -import com.djrapitops.plugin.command.ISender; +import com.djrapitops.plugin.command.Sender; + +import javax.inject.Inject; /** * Subcommand for info about permission levels. @@ -19,16 +20,17 @@ public class WebLevelCommand extends CommandNode { private final Locale locale; - public WebLevelCommand(PlanPlugin plugin) { + @Inject + public WebLevelCommand(Locale locale) { super("level", Permissions.MANAGE_WEB.getPerm(), CommandType.CONSOLE); - locale = plugin.getSystem().getLocaleSystem().getLocale(); + this.locale = locale; setShortHelp(locale.getString(CmdHelpLang.WEB_LEVEL)); } @Override - public void onCommand(ISender sender, String commandLabel, String[] args) { + public void onCommand(Sender sender, String commandLabel, String[] args) { sender.sendMessage(locale.getArray(CommandLang.WEB_PERMISSION_LEVELS)); } diff --git a/Plan/src/main/java/com/djrapitops/plan/command/commands/webuser/WebListUsersCommand.java b/Plan/src/main/java/com/djrapitops/plan/command/commands/webuser/WebListUsersCommand.java index 87780fc78..5a1730c0f 100644 --- a/Plan/src/main/java/com/djrapitops/plan/command/commands/webuser/WebListUsersCommand.java +++ b/Plan/src/main/java/com/djrapitops/plan/command/commands/webuser/WebListUsersCommand.java @@ -1,21 +1,22 @@ package com.djrapitops.plan.command.commands.webuser; -import com.djrapitops.plan.PlanPlugin; import com.djrapitops.plan.data.WebUser; -import com.djrapitops.plan.system.database.databases.Database; +import com.djrapitops.plan.system.database.DBSystem; import com.djrapitops.plan.system.locale.Locale; import com.djrapitops.plan.system.locale.lang.CmdHelpLang; import com.djrapitops.plan.system.locale.lang.CommandLang; import com.djrapitops.plan.system.locale.lang.ManageLang; +import com.djrapitops.plan.system.processing.Processing; import com.djrapitops.plan.system.settings.Permissions; import com.djrapitops.plan.utilities.comparators.WebUserComparator; -import com.djrapitops.plugin.api.utility.log.Log; import com.djrapitops.plugin.command.CommandNode; import com.djrapitops.plugin.command.CommandType; -import com.djrapitops.plugin.command.ISender; -import com.djrapitops.plugin.task.AbsRunnable; -import com.djrapitops.plugin.task.RunnableFactory; +import com.djrapitops.plugin.command.Sender; +import com.djrapitops.plugin.logging.L; +import com.djrapitops.plugin.logging.error.ErrorHandler; +import javax.inject.Inject; +import javax.inject.Singleton; import java.util.List; /** @@ -24,39 +25,47 @@ import java.util.List; * @author Rsl1122 * @since 3.5.2 */ +@Singleton public class WebListUsersCommand extends CommandNode { private final Locale locale; + private final Processing processing; + private final DBSystem dbSystem; + private final ErrorHandler errorHandler; - public WebListUsersCommand(PlanPlugin plugin) { + @Inject + public WebListUsersCommand( + Locale locale, + Processing processing, + DBSystem dbSystem, + ErrorHandler errorHandler + ) { super("list", Permissions.MANAGE_WEB.getPerm(), CommandType.CONSOLE); - locale = plugin.getSystem().getLocaleSystem().getLocale(); + this.locale = locale; + this.processing = processing; + this.dbSystem = dbSystem; + this.errorHandler = errorHandler; setShortHelp(locale.getString(CmdHelpLang.WEB_LIST)); } @Override - public void onCommand(ISender sender, String commandLabel, String[] args) { - RunnableFactory.createNew(new AbsRunnable("Web user List Task") { - @Override - public void run() { - try { - List users = Database.getActive().fetch().getWebUsers(); - users.sort(new WebUserComparator()); - sender.sendMessage(locale.getString(CommandLang.HEADER_WEB_USERS, users.size())); - for (WebUser user : users) { - sender.sendMessage(locale.getString(CommandLang.WEB_USER_LIST, user.getName(), user.getPermLevel())); - } - sender.sendMessage(">"); - } catch (Exception e) { - Log.toLog(this.getClass(), e); - sender.sendMessage(locale.getString(ManageLang.PROGRESS_FAIL, e.getMessage())); - } finally { - this.cancel(); + public void onCommand(Sender sender, String commandLabel, String[] args) { + processing.submitNonCritical(() -> { + try { + List users = dbSystem.getDatabase().fetch().getWebUsers(); + users.sort(new WebUserComparator()); + sender.sendMessage(locale.getString(CommandLang.HEADER_WEB_USERS, users.size())); + for (WebUser user : users) { + sender.sendMessage(locale.getString(CommandLang.WEB_USER_LIST, user.getName(), user.getPermLevel())); } + sender.sendMessage(">"); + } catch (Exception e) { + errorHandler.log(L.ERROR, this.getClass(), e); + sender.sendMessage(locale.getString(ManageLang.PROGRESS_FAIL, e.getMessage())); } - }).runTaskAsynchronously(); + }); } } diff --git a/Plan/src/main/java/com/djrapitops/plan/data/container/GeoInfo.java b/Plan/src/main/java/com/djrapitops/plan/data/container/GeoInfo.java index 2ed38a28d..72a59b33e 100644 --- a/Plan/src/main/java/com/djrapitops/plan/data/container/GeoInfo.java +++ b/Plan/src/main/java/com/djrapitops/plan/data/container/GeoInfo.java @@ -6,11 +6,11 @@ package com.djrapitops.plan.data.container; import com.djrapitops.plan.data.store.objects.DateHolder; import com.djrapitops.plan.data.store.objects.DateMap; -import com.djrapitops.plan.utilities.FormatUtils; import com.djrapitops.plan.utilities.SHA256Hash; import com.google.common.base.Objects; import java.io.Serializable; +import java.net.Inet6Address; import java.net.InetAddress; import java.security.NoSuchAlgorithmException; @@ -26,9 +26,8 @@ public class GeoInfo implements DateHolder, Serializable { private final String ipHash; private final long date; - public GeoInfo(InetAddress address, String geolocation, long lastUsed) - throws NoSuchAlgorithmException { - this(FormatUtils.formatIP(address), geolocation, lastUsed, new SHA256Hash(address.getHostAddress()).create()); + public GeoInfo(InetAddress address, String geolocation, long lastUsed) throws NoSuchAlgorithmException { + this(formatIP(address), geolocation, lastUsed, new SHA256Hash(address.getHostAddress()).create()); } public GeoInfo(String ip, String geolocation, long date, String ipHash) { @@ -46,6 +45,42 @@ public class GeoInfo implements DateHolder, Serializable { return map; } + static String formatIP(InetAddress address) { + String ip = address.getHostAddress(); + if ("localhost".equals(ip)) { + return ip; + } + if (address instanceof Inet6Address) { + StringBuilder b = new StringBuilder(); + int i = 0; + for (String part : ip.split(":")) { + if (i >= 3) { + break; + } + + b.append(part).append(':'); + + i++; + } + + return b.append("xx..").toString(); + } else { + StringBuilder b = new StringBuilder(); + int i = 0; + for (String part : ip.split("\\.")) { + if (i >= 2) { + break; + } + + b.append(part).append('.'); + + i++; + } + + return b.append("xx.xx").toString(); + } + } + public String getIp() { return ip; } diff --git a/Plan/src/main/java/com/djrapitops/plan/data/container/PlayerDeath.java b/Plan/src/main/java/com/djrapitops/plan/data/container/PlayerDeath.java index 1eb7f35b5..dd28dc674 100644 --- a/Plan/src/main/java/com/djrapitops/plan/data/container/PlayerDeath.java +++ b/Plan/src/main/java/com/djrapitops/plan/data/container/PlayerDeath.java @@ -7,11 +7,13 @@ import java.util.UUID; public class PlayerDeath implements DateHolder { private final UUID killer; + private final String killerName; private final long date; private final String weapon; - public PlayerDeath(UUID killer, String weapon, long date) { + public PlayerDeath(UUID killer, String killerName, String weapon, long date) { this.killer = killer; + this.killerName = killerName; this.date = date; this.weapon = weapon; } @@ -20,6 +22,10 @@ public class PlayerDeath implements DateHolder { return killer; } + public String getKillerName() { + return killerName; + } + @Override public long getDate() { return date; diff --git a/Plan/src/main/java/com/djrapitops/plan/data/container/PlayerKill.java b/Plan/src/main/java/com/djrapitops/plan/data/container/PlayerKill.java index 7eece6d25..8b865f210 100644 --- a/Plan/src/main/java/com/djrapitops/plan/data/container/PlayerKill.java +++ b/Plan/src/main/java/com/djrapitops/plan/data/container/PlayerKill.java @@ -2,8 +2,8 @@ package com.djrapitops.plan.data.container; import com.djrapitops.plan.data.store.objects.DateHolder; -import java.io.Serializable; import java.util.Objects; +import java.util.Optional; import java.util.UUID; /** @@ -12,11 +12,13 @@ import java.util.UUID; * * @author Rsl1122 */ -public class PlayerKill implements DateHolder, Serializable { +public class PlayerKill implements DateHolder { private final UUID victim; - private final long date; private final String weapon; + private final long date; + + private String victimName; /** * Creates a PlayerKill object with given parameters. @@ -31,6 +33,13 @@ public class PlayerKill implements DateHolder, Serializable { this.date = date; } + public PlayerKill(UUID victim, String weapon, long date, String victimName) { + this.victim = victim; + this.date = date; + this.weapon = weapon; + this.victimName = victimName; + } + /** * Get the victim's UUID. * @@ -40,6 +49,10 @@ public class PlayerKill implements DateHolder, Serializable { return victim; } + public Optional getVictimName() { + return Optional.ofNullable(victimName); + } + @Override public long getDate() { return date; diff --git a/Plan/src/main/java/com/djrapitops/plan/data/container/Session.java b/Plan/src/main/java/com/djrapitops/plan/data/container/Session.java index 704ad2346..6522dcf7f 100644 --- a/Plan/src/main/java/com/djrapitops/plan/data/container/Session.java +++ b/Plan/src/main/java/com/djrapitops/plan/data/container/Session.java @@ -2,11 +2,8 @@ package com.djrapitops.plan.data.container; import com.djrapitops.plan.data.store.containers.DataContainer; import com.djrapitops.plan.data.store.keys.SessionKeys; -import com.djrapitops.plan.data.store.mutators.formatting.Formatters; import com.djrapitops.plan.data.store.objects.DateHolder; import com.djrapitops.plan.data.time.WorldTimes; -import com.djrapitops.plan.system.info.server.ServerInfo; -import com.djrapitops.plan.system.settings.WorldAliasSettings; import java.util.*; @@ -30,11 +27,12 @@ public class Session extends DataContainer implements DateHolder { * Creates a new session. * * @param uuid UUID of the Player. + * @param serverUUID UUID of the server. * @param sessionStart Epoch ms the session started. * @param world Starting world. * @param gm Starting GameMode. */ - public Session(UUID uuid, long sessionStart, String world, String gm) { + public Session(UUID uuid, UUID serverUUID, long sessionStart, String world, String gm) { this.sessionStart = sessionStart; worldTimes = new WorldTimes(world, gm, sessionStart); playerKills = new ArrayList<>(); @@ -44,6 +42,7 @@ public class Session extends DataContainer implements DateHolder { afkTime = 0; putRawData(SessionKeys.UUID, uuid); + putRawData(SessionKeys.SERVER_UUID, serverUUID); putSupplier(SessionKeys.START, this::getSessionStart); putSupplier(SessionKeys.WORLD_TIMES, this::getWorldTimes); putSupplier(SessionKeys.PLAYER_KILLS, this::getPlayerKills); @@ -56,9 +55,8 @@ public class Session extends DataContainer implements DateHolder { putSupplier(SessionKeys.LENGTH, () -> getValue(SessionKeys.END).orElse(System.currentTimeMillis()) - getUnsafe(SessionKeys.START)); putSupplier(SessionKeys.ACTIVE_TIME, () -> getUnsafe(SessionKeys.LENGTH) - getUnsafe(SessionKeys.AFK_TIME)); - putSupplier(SessionKeys.SERVER_UUID, ServerInfo::getServerUUID); - putSupplier(SessionKeys.LONGEST_WORLD_PLAYED, this::getLongestWorldPlayed); + putRawData(SessionKeys.LONGEST_WORLD_PLAYED, "Key is Deprecated, use WorldAliasSettings#getLongestWorldPlayed(Session) instead."); } /** @@ -101,7 +99,7 @@ public class Session extends DataContainer implements DateHolder { getValue(SessionKeys.END).orElse(System.currentTimeMillis()) - getUnsafe(SessionKeys.START)); putSupplier(SessionKeys.ACTIVE_TIME, () -> getUnsafe(SessionKeys.LENGTH) - getUnsafe(SessionKeys.AFK_TIME)); - putSupplier(SessionKeys.LONGEST_WORLD_PLAYED, this::getLongestWorldPlayed); + putRawData(SessionKeys.LONGEST_WORLD_PLAYED, "Key is Deprecated, use WorldAliasSettings#getLongestWorldPlayed(Session) instead."); } /** @@ -157,8 +155,17 @@ public class Session extends DataContainer implements DateHolder { this.worldTimes = worldTimes; } - public void setPlayerKills(List playerKills) { - this.playerKills = playerKills; + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + Session session = (Session) o; + return getUnsafe(SessionKeys.START).equals(session.getUnsafe(SessionKeys.START)) && + getValue(SessionKeys.END).orElse(-1L).equals(session.getValue(SessionKeys.END).orElse(-1L)) && + mobKills == session.mobKills && + deaths == session.deaths && + Objects.equals(playerKills, session.playerKills) && + Objects.equals(worldTimes, session.worldTimes); } public boolean isFetchedFromDB() { @@ -173,17 +180,8 @@ public class Session extends DataContainer implements DateHolder { putRawData(SessionKeys.DB_ID, sessionID); } - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - Session session = (Session) o; - return getUnsafe(SessionKeys.START).equals(session.getUnsafe(SessionKeys.START)) && - getValue(SessionKeys.END).orElse(-1L).equals(session.getValue(SessionKeys.END).orElse(-1L)) && - mobKills == session.mobKills && - deaths == session.deaths && - Objects.equals(playerKills, session.playerKills) && - Objects.equals(worldTimes, session.worldTimes); + public List getPlayerKills() { + return playerKills; } @Override @@ -199,8 +197,8 @@ public class Session extends DataContainer implements DateHolder { return worldTimes; } - public List getPlayerKills() { - return playerKills; + public void setPlayerKills(List playerKills) { + this.playerKills = playerKills; } private int getMobKills() { @@ -214,48 +212,4 @@ public class Session extends DataContainer implements DateHolder { private long getAfkTime() { return afkTime; } - - private String getLongestWorldPlayed() { - Map aliases = WorldAliasSettings.getAliases(); - if (worldTimes == null) { - return "No World Time Data"; - } - if (!supports(SessionKeys.END)) { - return "Current: " + aliases.get(worldTimes.getCurrentWorld()); - } - - Map playtimePerAlias = worldTimes.getPlaytimePerAlias(); - - long longest = 0; - String theWorld = "-"; - for (Map.Entry entry : playtimePerAlias.entrySet()) { - String world = entry.getKey(); - long time = entry.getValue(); - if (time > longest) { - longest = time; - theWorld = world; - } - } - - long total = worldTimes.getTotal(); - // Prevent arithmetic error if 0 - if (total <= 0) { - total = -1; - } - double quotient = longest * 1.0 / total; - - return theWorld + " (" + Formatters.percentage().apply(quotient) + ")"; - } - - @Override - public String toString() { - return "Session{" + - "sessionStart=" + sessionStart + - ", worldTimes=" + worldTimes + - ", playerKills=" + playerKills + - ", mobKills=" + mobKills + - ", deaths=" + deaths + - ", afkTime=" + afkTime + - '}'; - } } diff --git a/Plan/src/main/java/com/djrapitops/plan/data/container/TPS.java b/Plan/src/main/java/com/djrapitops/plan/data/container/TPS.java index 2765f705a..787447d55 100644 --- a/Plan/src/main/java/com/djrapitops/plan/data/container/TPS.java +++ b/Plan/src/main/java/com/djrapitops/plan/data/container/TPS.java @@ -24,6 +24,7 @@ public class TPS implements DateHolder { private final long usedMemory; private final int entityCount; private final int chunksLoaded; + private final long freeDiskSpace; /** * Constructor. @@ -32,11 +33,21 @@ public class TPS implements DateHolder { * @param ticksPerSecond average ticksPerSecond for the last minute. * @param players players for the minute. * @param cpuUsage CPU usage for the minute - * @param usedMemory used memory at the time of fetching + * @param usedMemory used memory (megabytes) at the time of fetching * @param entityCount amount of entities at the time of fetching * @param chunksLoaded amount of chunks loaded at the time of fetching + * @param freeDiskSpace free megabytes in the partition the server is running in. */ - public TPS(long date, double ticksPerSecond, int players, double cpuUsage, long usedMemory, int entityCount, int chunksLoaded) { + public TPS( + long date, + double ticksPerSecond, + int players, + double cpuUsage, + long usedMemory, + int entityCount, + int chunksLoaded, + long freeDiskSpace + ) { this.date = date; this.ticksPerSecond = ticksPerSecond; this.players = players; @@ -44,6 +55,7 @@ public class TPS implements DateHolder { this.usedMemory = usedMemory; this.entityCount = entityCount; this.chunksLoaded = chunksLoaded; + this.freeDiskSpace = freeDiskSpace; } @Override @@ -105,6 +117,15 @@ public class TPS implements DateHolder { return chunksLoaded; } + /** + * Get free megabytes of disk space on the server disk. + * + * @return Amount of megabytes in use. + */ + public long getFreeDiskSpace() { + return freeDiskSpace; + } + @Override public boolean equals(Object o) { if (this == o) return true; @@ -116,12 +137,13 @@ public class TPS implements DateHolder { Double.compare(tps.cpuUsage, cpuUsage) == 0 && usedMemory == tps.usedMemory && entityCount == tps.entityCount && - chunksLoaded == tps.chunksLoaded; + chunksLoaded == tps.chunksLoaded && + freeDiskSpace == tps.freeDiskSpace; } @Override public int hashCode() { - return Objects.hash(date, ticksPerSecond, players, cpuUsage, usedMemory, entityCount, chunksLoaded); + return Objects.hash(date, ticksPerSecond, players, cpuUsage, usedMemory, entityCount, chunksLoaded, freeDiskSpace); } @Override @@ -133,6 +155,7 @@ public class TPS implements DateHolder { "cpuUsage=" + cpuUsage + ", " + "usedMemory=" + usedMemory + ", " + "entityCount=" + entityCount + ", " + - "chunksLoaded=" + chunksLoaded + '}'; + "chunksLoaded=" + chunksLoaded + ", " + + "freeDiskSpace=" + freeDiskSpace + '}'; } } diff --git a/Plan/src/main/java/com/djrapitops/plan/data/container/builders/TPSBuilder.java b/Plan/src/main/java/com/djrapitops/plan/data/container/builders/TPSBuilder.java index 785c9f6ca..113dedd99 100644 --- a/Plan/src/main/java/com/djrapitops/plan/data/container/builders/TPSBuilder.java +++ b/Plan/src/main/java/com/djrapitops/plan/data/container/builders/TPSBuilder.java @@ -20,6 +20,7 @@ public class TPSBuilder { protected long usedMemory = -1; protected int entityCount = -1; protected int chunksLoaded = -1; + protected long freeDiskSpace = -1; /** * Hides constructor. @@ -28,11 +29,11 @@ public class TPSBuilder { } public static TPSBuilder.Date get() { - return new TPSBuilder.Chunks(); + return new TPSBuilder.DiskSpace(); } public TPS toTPS() { - return new TPS(date, ticksPerSecond, players, cpuUsage, usedMemory, entityCount, chunksLoaded); + return new TPS(date, ticksPerSecond, players, cpuUsage, usedMemory, entityCount, chunksLoaded, freeDiskSpace); } public static class Date extends TPSBuilder { @@ -89,8 +90,15 @@ public class TPSBuilder { public static class Chunks extends Entities { - public TPSBuilder chunksLoaded(int chunksLoaded) { + public DiskSpace chunksLoaded(int chunksLoaded) { this.chunksLoaded = chunksLoaded; + return (DiskSpace) this; + } + } + + public static class DiskSpace extends Chunks { + public TPSBuilder freeDiskSpace(long freeDiskSpace) { + this.freeDiskSpace = freeDiskSpace; return this; } } diff --git a/Plan/src/main/java/com/djrapitops/plan/data/element/TableContainer.java b/Plan/src/main/java/com/djrapitops/plan/data/element/TableContainer.java index 76ec2cba4..fc4b6f6fb 100644 --- a/Plan/src/main/java/com/djrapitops/plan/data/element/TableContainer.java +++ b/Plan/src/main/java/com/djrapitops/plan/data/element/TableContainer.java @@ -4,10 +4,10 @@ */ package com.djrapitops.plan.data.element; -import com.djrapitops.plan.data.store.mutators.formatting.Formatter; -import com.djrapitops.plan.utilities.FormatUtils; +import com.djrapitops.plan.utilities.formatting.Formatter; import com.djrapitops.plan.utilities.html.Html; import com.djrapitops.plan.utilities.html.icon.Icon; +import com.djrapitops.plugin.utilities.ArrayUtil; import java.io.Serializable; import java.util.ArrayList; @@ -40,10 +40,9 @@ public class TableContainer { } public TableContainer(boolean players, String... header) { - this(FormatUtils.mergeArrays( - new String[]{Icon.called("user").build() + " Player"}, - header - )); + this( + ArrayUtil.merge(new String[]{Icon.called("user").build() + " Player"}, header) + ); } public final void addRow(Serializable... values) { diff --git a/Plan/src/main/java/com/djrapitops/plan/data/plugin/HookHandler.java b/Plan/src/main/java/com/djrapitops/plan/data/plugin/HookHandler.java index a6dd3824d..878069675 100644 --- a/Plan/src/main/java/com/djrapitops/plan/data/plugin/HookHandler.java +++ b/Plan/src/main/java/com/djrapitops/plan/data/plugin/HookHandler.java @@ -1,14 +1,14 @@ package com.djrapitops.plan.data.plugin; -import com.djrapitops.plan.PlanPlugin; import com.djrapitops.plan.data.element.InspectContainer; -import com.djrapitops.plan.system.PlanSystem; import com.djrapitops.plan.system.SubSystem; -import com.djrapitops.plugin.StaticHolder; -import com.djrapitops.plugin.api.utility.log.Log; -import com.djrapitops.plugin.utilities.Verify; +import com.djrapitops.plugin.logging.L; +import com.djrapitops.plugin.logging.console.PluginLogger; +import com.djrapitops.plugin.logging.error.ErrorHandler; import com.djrapitops.pluginbridge.plan.Bridge; +import javax.inject.Inject; +import javax.inject.Singleton; import java.util.*; import java.util.stream.Collectors; @@ -19,29 +19,38 @@ import java.util.stream.Collectors; * @author Rsl1122 * @since 2.6.0 */ +@Singleton public class HookHandler implements SubSystem { private final List additionalDataSources; + + private final Bridge bridge; private PluginsConfigSection configHandler; + private final PluginLogger logger; + private final ErrorHandler errorHandler; + + @Inject + public HookHandler( + Bridge bridge, + PluginsConfigSection configHandler, + PluginLogger logger, + ErrorHandler errorHandler + ) { + this.bridge = bridge; + this.configHandler = configHandler; + this.logger = logger; + this.errorHandler = errorHandler; - public HookHandler() { additionalDataSources = new ArrayList<>(); } - public static HookHandler getInstance() { - HookHandler hookHandler = PlanSystem.getInstance().getHookHandler(); - Verify.nullCheck(hookHandler, () -> new IllegalStateException("Plugin Hooks were not initialized.")); - return hookHandler; - } - @Override public void enable() { - configHandler = new PluginsConfigSection(); try { - Bridge.hook(this); + bridge.hook(this); } catch (Exception e) { - Log.toLog(this.getClass(), e); - Log.error("Plan Plugin Bridge not included in the plugin jar."); + errorHandler.log(L.ERROR, this.getClass(), e); + logger.error("Plan Plugin Bridge not included in the plugin jar."); } } @@ -65,17 +74,16 @@ public class HookHandler implements SubSystem { return; } try { - StaticHolder.saveInstance(dataSource.getClass(), PlanPlugin.getInstance().getClass()); if (!configHandler.hasSection(dataSource)) { configHandler.createSection(dataSource); } if (configHandler.isEnabled(dataSource)) { - Log.debug("Registered a new datasource: " + dataSource.getSourcePlugin()); + logger.debug("Registered a new datasource: " + dataSource.getSourcePlugin()); additionalDataSources.add(dataSource); } } catch (Exception e) { - Log.toLog(this.getClass(), e); - Log.error("Attempting to register PluginDataSource caused an exception."); + errorHandler.log(L.WARN, this.getClass(), e); + logger.error("Attempting to register PluginDataSource caused an exception."); } } @@ -107,8 +115,8 @@ public class HookHandler implements SubSystem { } } catch (Exception | NoClassDefFoundError | NoSuchFieldError | NoSuchMethodError e) { String sourcePlugin = pluginData.getSourcePlugin(); - Log.error("PluginData caused exception: " + sourcePlugin); - Log.toLog(this.getClass().getName() + " " + sourcePlugin, e); + logger.error("PluginData caused exception: " + sourcePlugin); + errorHandler.log(L.WARN, pluginData.getClass(), e); } } return containers; diff --git a/Plan/src/main/java/com/djrapitops/plan/data/plugin/PluginsConfigSection.java b/Plan/src/main/java/com/djrapitops/plan/data/plugin/PluginsConfigSection.java index efcd64f4a..60f973aaa 100644 --- a/Plan/src/main/java/com/djrapitops/plan/data/plugin/PluginsConfigSection.java +++ b/Plan/src/main/java/com/djrapitops/plan/data/plugin/PluginsConfigSection.java @@ -1,8 +1,7 @@ package com.djrapitops.plan.data.plugin; -import com.djrapitops.plan.system.settings.config.ConfigSystem; -import com.djrapitops.plugin.api.config.ConfigNode; -import com.djrapitops.plugin.api.utility.log.Log; +import com.djrapitops.plan.system.settings.config.PlanConfig; +import com.djrapitops.plugin.config.ConfigNode; import java.io.IOException; @@ -15,6 +14,14 @@ import java.io.IOException; */ public class PluginsConfigSection { + private final PlanConfig config; + + public PluginsConfigSection( + PlanConfig config + ) { + this.config = config; + } + public boolean hasSection(PluginData dataSource) { ConfigNode section = getPluginsSection(); String pluginName = dataSource.getSourcePlugin(); @@ -23,20 +30,16 @@ public class PluginsConfigSection { } private ConfigNode getPluginsSection() { - return ConfigSystem.getConfig().getConfigNode("Plugins"); + return config.getConfigNode("Plugins"); } - public void createSection(PluginData dataSource) { + public void createSection(PluginData dataSource) throws IOException { ConfigNode section = getPluginsSection(); String pluginName = dataSource.getSourcePlugin(); section.set(pluginName + ".Enabled", true); - try { - section.sort(); - section.save(); - } catch (IOException e) { - Log.toLog(this.getClass(), e); - } + section.sort(); + section.save(); } public boolean isEnabled(PluginData dataSource) { diff --git a/Plan/src/main/java/com/djrapitops/plan/data/store/CachingSupplier.java b/Plan/src/main/java/com/djrapitops/plan/data/store/CachingSupplier.java index ec3abff37..c05893c66 100644 --- a/Plan/src/main/java/com/djrapitops/plan/data/store/CachingSupplier.java +++ b/Plan/src/main/java/com/djrapitops/plan/data/store/CachingSupplier.java @@ -1,12 +1,11 @@ package com.djrapitops.plan.data.store; -import com.djrapitops.plugin.api.TimeAmount; - +import java.util.concurrent.TimeUnit; import java.util.function.Supplier; /** * Caching layer between Supplier and caller. - * + *

* Refreshes the value if 30 seconds have passed since the last call. * * @author Rsl1122 @@ -19,7 +18,7 @@ public class CachingSupplier implements Supplier { private long timeToLive; public CachingSupplier(Supplier original) { - this(original, TimeAmount.SECOND.ms() * 30L); + this(original, TimeUnit.SECONDS.toMillis(30L)); } public CachingSupplier(Supplier original, long timeToLive) { diff --git a/Plan/src/main/java/com/djrapitops/plan/data/store/containers/AnalysisContainer.java b/Plan/src/main/java/com/djrapitops/plan/data/store/containers/AnalysisContainer.java index d871e35c0..30ed8c9aa 100644 --- a/Plan/src/main/java/com/djrapitops/plan/data/store/containers/AnalysisContainer.java +++ b/Plan/src/main/java/com/djrapitops/plan/data/store/containers/AnalysisContainer.java @@ -1,42 +1,38 @@ package com.djrapitops.plan.data.store.containers; -import com.djrapitops.plan.PlanPlugin; import com.djrapitops.plan.data.store.Key; import com.djrapitops.plan.data.store.Type; import com.djrapitops.plan.data.store.keys.AnalysisKeys; import com.djrapitops.plan.data.store.keys.PlayerKeys; import com.djrapitops.plan.data.store.keys.ServerKeys; import com.djrapitops.plan.data.store.mutators.*; -import com.djrapitops.plan.data.store.mutators.combiners.MultiBanCombiner; -import com.djrapitops.plan.data.store.mutators.formatting.Formatters; import com.djrapitops.plan.data.store.mutators.health.HealthInformation; import com.djrapitops.plan.data.time.WorldTimes; -import com.djrapitops.plan.system.database.databases.Database; -import com.djrapitops.plan.system.info.server.ServerInfo; +import com.djrapitops.plan.system.database.DBSystem; import com.djrapitops.plan.system.info.server.properties.ServerProperties; +import com.djrapitops.plan.system.locale.Locale; import com.djrapitops.plan.system.settings.Settings; +import com.djrapitops.plan.system.settings.config.PlanConfig; import com.djrapitops.plan.system.settings.theme.Theme; import com.djrapitops.plan.system.settings.theme.ThemeVal; -import com.djrapitops.plan.utilities.MiscUtils; -import com.djrapitops.plan.utilities.analysis.ServerBanDataReader; -import com.djrapitops.plan.utilities.html.graphs.ActivityStackGraph; -import com.djrapitops.plan.utilities.html.graphs.PunchCardGraph; -import com.djrapitops.plan.utilities.html.graphs.WorldMap; -import com.djrapitops.plan.utilities.html.graphs.bar.GeolocationBarGraph; -import com.djrapitops.plan.utilities.html.graphs.calendar.ServerCalendar; -import com.djrapitops.plan.utilities.html.graphs.line.*; -import com.djrapitops.plan.utilities.html.graphs.pie.ActivityPie; +import com.djrapitops.plan.utilities.formatting.Formatters; +import com.djrapitops.plan.utilities.html.graphs.Graphs; +import com.djrapitops.plan.utilities.html.graphs.bar.BarGraph; +import com.djrapitops.plan.utilities.html.graphs.line.PingGraph; import com.djrapitops.plan.utilities.html.graphs.pie.WorldPie; +import com.djrapitops.plan.utilities.html.graphs.stack.StackGraph; +import com.djrapitops.plan.utilities.html.structure.Accordions; import com.djrapitops.plan.utilities.html.structure.AnalysisPluginsTabContentCreator; import com.djrapitops.plan.utilities.html.structure.RecentLoginList; import com.djrapitops.plan.utilities.html.structure.SessionAccordion; -import com.djrapitops.plan.utilities.html.tables.CommandUseTable; -import com.djrapitops.plan.utilities.html.tables.PingTable; -import com.djrapitops.plan.utilities.html.tables.PlayersTable; -import com.djrapitops.plan.utilities.html.tables.ServerSessionTable; +import com.djrapitops.plan.utilities.html.tables.HtmlTables; import com.djrapitops.plugin.api.TimeAmount; +import javax.inject.Inject; +import javax.inject.Named; +import javax.inject.Singleton; import java.util.*; +import java.util.concurrent.TimeUnit; import java.util.stream.Collectors; /** @@ -50,10 +46,46 @@ public class AnalysisContainer extends DataContainer { private final ServerContainer serverContainer; + private final String version; + private final Locale locale; + private final PlanConfig config; + private final Theme theme; + private final DBSystem dbSystem; + private final ServerProperties serverProperties; + private final Formatters formatters; + private final Graphs graphs; + private final HtmlTables tables; + private final Accordions accordions; + private final AnalysisPluginsTabContentCreator pluginsTabContentCreator; + private static final Key> serverNames = new Key<>(new Type>() {}, "SERVER_NAMES"); - public AnalysisContainer(ServerContainer serverContainer) { + public AnalysisContainer( + ServerContainer serverContainer, + String version, + Locale locale, + PlanConfig config, + Theme theme, + DBSystem dbSystem, + ServerProperties serverProperties, + Formatters formatters, + Graphs graphs, + HtmlTables tables, + Accordions accordions, + AnalysisPluginsTabContentCreator pluginsTabContentCreator + ) { this.serverContainer = serverContainer; + this.version = version; + this.locale = locale; + this.config = config; + this.theme = theme; + this.dbSystem = dbSystem; + this.serverProperties = serverProperties; + this.formatters = formatters; + this.graphs = graphs; + this.tables = tables; + this.accordions = accordions; + this.pluginsTabContentCreator = pluginsTabContentCreator; addAnalysisSuppliers(); } @@ -74,27 +106,24 @@ public class AnalysisContainer extends DataContainer { addCommandSuppliers(); addServerHealth(); addPluginSuppliers(); - - runCombiners(); - } - - private void runCombiners() { - new MultiBanCombiner(this.serverContainer).combine(getUnsafe(AnalysisKeys.BAN_DATA)); } private void addConstants() { long now = System.currentTimeMillis(); putRawData(AnalysisKeys.ANALYSIS_TIME, now); - putRawData(AnalysisKeys.ANALYSIS_TIME_DAY_AGO, now - TimeAmount.DAY.ms()); - putRawData(AnalysisKeys.ANALYSIS_TIME_WEEK_AGO, now - TimeAmount.WEEK.ms()); - putRawData(AnalysisKeys.ANALYSIS_TIME_MONTH_AGO, now - TimeAmount.MONTH.ms()); - putSupplier(AnalysisKeys.REFRESH_TIME_F, () -> Formatters.second().apply(() -> getUnsafe(AnalysisKeys.ANALYSIS_TIME))); + putRawData(AnalysisKeys.ANALYSIS_TIME_DAY_AGO, now - TimeUnit.DAYS.toMillis(1L)); + putRawData(AnalysisKeys.ANALYSIS_TIME_WEEK_AGO, now - TimeAmount.WEEK.toMillis(1L)); + putRawData(AnalysisKeys.ANALYSIS_TIME_MONTH_AGO, now - TimeAmount.MONTH.toMillis(1L)); + putSupplier(AnalysisKeys.REFRESH_TIME_F, () -> formatters.clockLong().apply(getUnsafe(AnalysisKeys.ANALYSIS_TIME))); + putSupplier(AnalysisKeys.REFRESH_TIME_FULL_F, () -> formatters.secondLong().apply(getUnsafe(AnalysisKeys.ANALYSIS_TIME))); - putRawData(AnalysisKeys.VERSION, PlanPlugin.getInstance().getVersion()); - putSupplier(AnalysisKeys.TIME_ZONE, MiscUtils::getTimeZoneOffsetHours); + putRawData(AnalysisKeys.VERSION, version); + putSupplier(AnalysisKeys.TIME_ZONE, config::getTimeZoneOffsetHours); putRawData(AnalysisKeys.FIRST_DAY, 1); - putRawData(AnalysisKeys.TPS_MEDIUM, Settings.THEME_GRAPH_TPS_THRESHOLD_MED.getNumber()); - putRawData(AnalysisKeys.TPS_HIGH, Settings.THEME_GRAPH_TPS_THRESHOLD_HIGH.getNumber()); + putRawData(AnalysisKeys.TPS_MEDIUM, config.getNumber(Settings.THEME_GRAPH_TPS_THRESHOLD_MED)); + putRawData(AnalysisKeys.TPS_HIGH, config.getNumber(Settings.THEME_GRAPH_TPS_THRESHOLD_HIGH)); + putRawData(AnalysisKeys.DISK_MEDIUM, config.getNumber(Settings.THEME_GRAPH_DISK_THRESHOLD_MED)); + putRawData(AnalysisKeys.DISK_HIGH, config.getNumber(Settings.THEME_GRAPH_DISK_THRESHOLD_HIGH)); addServerProperties(); addThemeColors(); @@ -105,24 +134,23 @@ public class AnalysisContainer extends DataContainer { getUnsafe(serverNames).getOrDefault(serverContainer.getUnsafe(ServerKeys.SERVER_UUID), "Plan") ); - ServerProperties serverProperties = ServerInfo.getServerProperties(); putRawData(AnalysisKeys.PLAYERS_MAX, serverProperties.getMaxPlayers()); putRawData(AnalysisKeys.PLAYERS_ONLINE, serverProperties.getOnlinePlayers()); } private void addThemeColors() { - putRawData(AnalysisKeys.ACTIVITY_PIE_COLORS, Theme.getValue(ThemeVal.GRAPH_ACTIVITY_PIE)); - putRawData(AnalysisKeys.GM_PIE_COLORS, Theme.getValue(ThemeVal.GRAPH_GM_PIE)); - putRawData(AnalysisKeys.PLAYERS_GRAPH_COLOR, Theme.getValue(ThemeVal.GRAPH_PLAYERS_ONLINE)); - putRawData(AnalysisKeys.TPS_LOW_COLOR, Theme.getValue(ThemeVal.GRAPH_TPS_LOW)); - putRawData(AnalysisKeys.TPS_MEDIUM_COLOR, Theme.getValue(ThemeVal.GRAPH_TPS_MED)); - putRawData(AnalysisKeys.TPS_HIGH_COLOR, Theme.getValue(ThemeVal.GRAPH_TPS_HIGH)); - putRawData(AnalysisKeys.WORLD_MAP_LOW_COLOR, Theme.getValue(ThemeVal.WORLD_MAP_LOW)); - putRawData(AnalysisKeys.WORLD_MAP_HIGH_COLOR, Theme.getValue(ThemeVal.WORLD_MAP_HIGH)); - putRawData(AnalysisKeys.WORLD_PIE_COLORS, Theme.getValue(ThemeVal.GRAPH_WORLD_PIE)); - putRawData(AnalysisKeys.AVG_PING_COLOR, Theme.getValue(ThemeVal.GRAPH_AVG_PING)); - putRawData(AnalysisKeys.MAX_PING_COLOR, Theme.getValue(ThemeVal.GRAPH_MAX_PING)); - putRawData(AnalysisKeys.MIN_PING_COLOR, Theme.getValue(ThemeVal.GRAPH_MIN_PING)); + putRawData(AnalysisKeys.ACTIVITY_PIE_COLORS, theme.getValue(ThemeVal.GRAPH_ACTIVITY_PIE)); + putRawData(AnalysisKeys.GM_PIE_COLORS, theme.getValue(ThemeVal.GRAPH_GM_PIE)); + putRawData(AnalysisKeys.PLAYERS_GRAPH_COLOR, theme.getValue(ThemeVal.GRAPH_PLAYERS_ONLINE)); + putRawData(AnalysisKeys.TPS_LOW_COLOR, theme.getValue(ThemeVal.GRAPH_TPS_LOW)); + putRawData(AnalysisKeys.TPS_MEDIUM_COLOR, theme.getValue(ThemeVal.GRAPH_TPS_MED)); + putRawData(AnalysisKeys.TPS_HIGH_COLOR, theme.getValue(ThemeVal.GRAPH_TPS_HIGH)); + putRawData(AnalysisKeys.WORLD_MAP_LOW_COLOR, theme.getValue(ThemeVal.WORLD_MAP_LOW)); + putRawData(AnalysisKeys.WORLD_MAP_HIGH_COLOR, theme.getValue(ThemeVal.WORLD_MAP_HIGH)); + putRawData(AnalysisKeys.WORLD_PIE_COLORS, theme.getValue(ThemeVal.GRAPH_WORLD_PIE)); + putRawData(AnalysisKeys.AVG_PING_COLOR, theme.getValue(ThemeVal.GRAPH_AVG_PING)); + putRawData(AnalysisKeys.MAX_PING_COLOR, theme.getValue(ThemeVal.GRAPH_MAX_PING)); + putRawData(AnalysisKeys.MIN_PING_COLOR, theme.getValue(ThemeVal.GRAPH_MIN_PING)); } private void addPlayerSuppliers() { @@ -142,18 +170,18 @@ public class AnalysisContainer extends DataContainer { ); putSupplier(AnalysisKeys.LAST_PEAK_TIME_F, () -> serverContainer.getValue(ServerKeys.RECENT_PEAK_PLAYERS) - .map(dateObj -> Formatters.year().apply(dateObj)).orElse("-") + .map(dateObj -> formatters.year().apply(dateObj)).orElse("-") ); putSupplier(AnalysisKeys.ALL_TIME_PEAK_TIME_F, () -> serverContainer.getValue(ServerKeys.ALL_TIME_PEAK_PLAYERS) - .map(dateObj -> Formatters.year().apply(dateObj)).orElse("-") + .map(dateObj -> formatters.year().apply(dateObj)).orElse("-") ); putSupplier(AnalysisKeys.OPERATORS, () -> serverContainer.getValue(ServerKeys.OPERATORS).map(List::size).orElse(0)); putSupplier(AnalysisKeys.PLAYERS_TABLE, () -> - PlayersTable.forServerPage(getUnsafe(AnalysisKeys.PLAYERS_MUTATOR).all()).parseHtml() + tables.playerTableForServerPage(getUnsafe(AnalysisKeys.PLAYERS_MUTATOR).all()).parseHtml() ); putSupplier(AnalysisKeys.PING_TABLE, () -> - new PingTable( + tables.pingTable( getUnsafe(AnalysisKeys.PLAYERS_MUTATOR) .getPingPerCountry(serverContainer.getUnsafe(ServerKeys.SERVER_UUID)) ).parseHtml() @@ -201,20 +229,20 @@ public class AnalysisContainer extends DataContainer { putSupplier(AnalysisKeys.UNIQUE_PLAYERS_PER_DAY, () -> getUnsafe(AnalysisKeys.SESSIONS_MUTATOR).uniqueJoinsPerDay()); putSupplier(AnalysisKeys.NEW_PLAYERS_PER_DAY, () -> getUnsafe(AnalysisKeys.PLAYERS_MUTATOR).newPerDay()); - putSupplier(AnalysisKeys.UNIQUE_PLAYERS_SERIES, () -> new AbstractLineGraph( - MutatorFunctions.toPoints(getUnsafe(AnalysisKeys.UNIQUE_PLAYERS_PER_DAY)) - ).toHighChartsSeries() + putSupplier(AnalysisKeys.UNIQUE_PLAYERS_SERIES, () -> graphs.line().lineGraph( + MutatorFunctions.toPoints(getUnsafe(AnalysisKeys.UNIQUE_PLAYERS_PER_DAY))).toHighChartsSeries() ); - putSupplier(AnalysisKeys.NEW_PLAYERS_SERIES, () -> new AbstractLineGraph( - MutatorFunctions.toPoints(getUnsafe(AnalysisKeys.NEW_PLAYERS_PER_DAY)) - ).toHighChartsSeries() + putSupplier(AnalysisKeys.NEW_PLAYERS_SERIES, () -> graphs.line().lineGraph( + MutatorFunctions.toPoints(getUnsafe(AnalysisKeys.NEW_PLAYERS_PER_DAY))).toHighChartsSeries() ); Key retentionDay = new Key<>(Integer.class, "RETENTION_DAY"); // compareAndFindThoseLikelyToBeRetained can throw exception. putCachingSupplier(retentionDay, () -> getUnsafe(AnalysisKeys.PLAYERS_MUTATOR).compareAndFindThoseLikelyToBeRetained( getUnsafe(newDay).all(), getUnsafe(AnalysisKeys.ANALYSIS_TIME_MONTH_AGO), - getUnsafe(AnalysisKeys.PLAYERS_ONLINE_RESOLVER) + getUnsafe(AnalysisKeys.PLAYERS_ONLINE_RESOLVER), + config.getNumber(Settings.ACTIVE_PLAY_THRESHOLD), + config.getNumber(Settings.ACTIVE_LOGIN_THRESHOLD) ).count() ); putSupplier(AnalysisKeys.PLAYERS_RETAINED_DAY, () -> { @@ -239,29 +267,31 @@ public class AnalysisContainer extends DataContainer { putSupplier(AnalysisKeys.PLAYERS_RETAINED_DAY_PERC, () -> { try { Integer playersNewDay = getUnsafe(AnalysisKeys.PLAYERS_NEW_DAY); - return playersNewDay != 0 ? Formatters.percentage().apply(1.0 * getUnsafe(retentionDay) / playersNewDay) : "-"; + return playersNewDay != 0 + ? formatters.percentage().apply(1.0 * getUnsafe(retentionDay) / playersNewDay) + : "-"; } catch (IllegalStateException noPlayersAfterDateFiltering) { return "Not enough data"; } }); putSupplier(AnalysisKeys.PLAYERS_RETAINED_WEEK_PERC, () -> { Integer playersNewWeek = getUnsafe(AnalysisKeys.PLAYERS_NEW_WEEK); - return playersNewWeek != 0 ? Formatters.percentage().apply( - 1.0 * getUnsafe(AnalysisKeys.PLAYERS_RETAINED_WEEK) / playersNewWeek) : "-"; + return playersNewWeek != 0 ? formatters.percentage().apply(1.0 * getUnsafe(AnalysisKeys.PLAYERS_RETAINED_WEEK) / playersNewWeek) : "-"; } ); putSupplier(AnalysisKeys.PLAYERS_RETAINED_MONTH_PERC, () -> { Integer playersNewMonth = getUnsafe(AnalysisKeys.PLAYERS_NEW_MONTH); - return playersNewMonth != 0 ? Formatters.percentage().apply( - 1.0 * getUnsafe(AnalysisKeys.PLAYERS_RETAINED_MONTH) / playersNewMonth) : "-"; + return playersNewMonth != 0 + ? formatters.percentage().apply(1.0 * getUnsafe(AnalysisKeys.PLAYERS_RETAINED_MONTH) / playersNewMonth) + : "-"; } ); } private void addSessionSuppliers() { Key sessionAccordion = new Key<>(SessionAccordion.class, "SESSION_ACCORDION"); - putCachingSupplier(serverNames, () -> Database.getActive().fetch().getServerNames()); - putCachingSupplier(sessionAccordion, () -> SessionAccordion.forServer( + putCachingSupplier(serverNames, () -> dbSystem.getDatabase().fetch().getServerNames()); + putCachingSupplier(sessionAccordion, () -> accordions.serverSessionAccordion( getUnsafe(AnalysisKeys.SESSIONS_MUTATOR).all(), getSupplier(serverNames), () -> getUnsafe(AnalysisKeys.PLAYER_NAMES) @@ -270,32 +300,33 @@ public class AnalysisContainer extends DataContainer { putSupplier(AnalysisKeys.SESSION_ACCORDION_FUNCTIONS, () -> getUnsafe(sessionAccordion).toViewScript()); putSupplier(AnalysisKeys.RECENT_LOGINS, () -> new RecentLoginList( - serverContainer.getValue(ServerKeys.PLAYERS).orElse(new ArrayList<>()) - ).toHtml() + serverContainer.getValue(ServerKeys.PLAYERS).orElse(new ArrayList<>()), + formatters.secondLong()).toHtml() ); - putSupplier(AnalysisKeys.SESSION_TABLE, () -> new ServerSessionTable( + putSupplier(AnalysisKeys.SESSION_TABLE, () -> tables.serverSessionTable( getUnsafe(AnalysisKeys.PLAYER_NAMES), getUnsafe(AnalysisKeys.SESSIONS_MUTATOR).all()).parseHtml() ); - putSupplier(AnalysisKeys.AVERAGE_SESSION_LENGTH_F, () -> Formatters.timeAmount() - .apply(getUnsafe(AnalysisKeys.SESSIONS_MUTATOR).toAverageSessionLength()) + putSupplier(AnalysisKeys.AVERAGE_SESSION_LENGTH_F, + () -> formatters.timeAmount().apply(getUnsafe(AnalysisKeys.SESSIONS_MUTATOR).toAverageSessionLength()) ); putSupplier(AnalysisKeys.SESSION_COUNT, () -> getUnsafe(AnalysisKeys.SESSIONS_MUTATOR).count()); putSupplier(AnalysisKeys.PLAYTIME_TOTAL, () -> getUnsafe(AnalysisKeys.SESSIONS_MUTATOR).toPlaytime()); putSupplier(AnalysisKeys.DEATHS, () -> getUnsafe(AnalysisKeys.SESSIONS_MUTATOR).toDeathCount()); putSupplier(AnalysisKeys.MOB_KILL_COUNT, () -> getUnsafe(AnalysisKeys.SESSIONS_MUTATOR).toMobKillCount()); putSupplier(AnalysisKeys.PLAYER_KILL_COUNT, () -> getUnsafe(AnalysisKeys.SESSIONS_MUTATOR).toPlayerKillCount()); - putSupplier(AnalysisKeys.PLAYTIME_F, () -> Formatters.timeAmount() - .apply(getUnsafe(AnalysisKeys.PLAYTIME_TOTAL)) + putSupplier(AnalysisKeys.PLAYTIME_F, + () -> formatters.timeAmount().apply(getUnsafe(AnalysisKeys.PLAYTIME_TOTAL)) ); putSupplier(AnalysisKeys.AVERAGE_PLAYTIME_F, () -> { long players = getUnsafe(AnalysisKeys.PLAYERS_TOTAL); - return players != 0 ? Formatters.timeAmount() - .apply(getUnsafe(AnalysisKeys.PLAYTIME_TOTAL) / players) : "-"; + return players != 0 + ? formatters.timeAmount().apply(getUnsafe(AnalysisKeys.PLAYTIME_TOTAL) / players) + : "-"; } ); - putSupplier(AnalysisKeys.AVERAGE_SESSION_LENGTH_F, () -> Formatters.timeAmount() - .apply(getUnsafe(AnalysisKeys.SESSIONS_MUTATOR).toAverageSessionLength()) + putSupplier(AnalysisKeys.AVERAGE_SESSION_LENGTH_F, + () -> formatters.timeAmount().apply(getUnsafe(AnalysisKeys.SESSIONS_MUTATOR).toAverageSessionLength()) ); Key sessionsDay = new Key<>(SessionsMutator.class, "SESSIONS_DAY"); @@ -311,7 +342,7 @@ public class AnalysisContainer extends DataContainer { .filterSessionsBetween(getUnsafe(AnalysisKeys.ANALYSIS_TIME_MONTH_AGO), getUnsafe(AnalysisKeys.ANALYSIS_TIME)) ); - putSupplier(AnalysisKeys.PUNCHCARD_SERIES, () -> new PunchCardGraph(getUnsafe(sessionsMonth).all()).toHighChartsSeries()); + putSupplier(AnalysisKeys.PUNCHCARD_SERIES, () -> graphs.special().punchCard(getUnsafe(sessionsMonth).all()).toHighChartsSeries()); putSupplier(AnalysisKeys.AVG_PLAYERS, () -> getUnsafe(AnalysisKeys.SESSIONS_MUTATOR).toAverageUniqueJoinsPerDay()); putSupplier(AnalysisKeys.AVG_PLAYERS_DAY, () -> getUnsafe(sessionsDay).toAverageUniqueJoinsPerDay()); putSupplier(AnalysisKeys.AVG_PLAYERS_WEEK, () -> getUnsafe(sessionsWeek).toAverageUniqueJoinsPerDay()); @@ -320,46 +351,49 @@ public class AnalysisContainer extends DataContainer { private void addGraphSuppliers() { Key worldPie = new Key<>(WorldPie.class, "WORLD_PIE"); - putCachingSupplier(worldPie, () -> new WorldPie(serverContainer.getValue(ServerKeys.WORLD_TIMES).orElse(new WorldTimes(new HashMap<>())))); + putCachingSupplier(worldPie, () -> graphs.pie().worldPie( + serverContainer.getValue(ServerKeys.WORLD_TIMES).orElse(new WorldTimes(new HashMap<>())) + )); putSupplier(AnalysisKeys.WORLD_PIE_SERIES, () -> getUnsafe(worldPie).toHighChartsSeries()); putSupplier(AnalysisKeys.GM_PIE_SERIES, () -> getUnsafe(worldPie).toHighChartsDrilldown()); putSupplier(AnalysisKeys.PLAYERS_ONLINE_SERIES, () -> - new OnlineActivityGraph(getUnsafe(AnalysisKeys.TPS_MUTATOR)).toHighChartsSeries() + graphs.line().playersOnlineGraph(getUnsafe(AnalysisKeys.TPS_MUTATOR)).toHighChartsSeries() ); - putSupplier(AnalysisKeys.TPS_SERIES, () -> new TPSGraph(getUnsafe(AnalysisKeys.TPS_MUTATOR)).toHighChartsSeries()); - putSupplier(AnalysisKeys.CPU_SERIES, () -> new CPUGraph(getUnsafe(AnalysisKeys.TPS_MUTATOR)).toHighChartsSeries()); - putSupplier(AnalysisKeys.RAM_SERIES, () -> new RamGraph(getUnsafe(AnalysisKeys.TPS_MUTATOR)).toHighChartsSeries()); - putSupplier(AnalysisKeys.ENTITY_SERIES, () -> new EntityGraph(getUnsafe(AnalysisKeys.TPS_MUTATOR)).toHighChartsSeries()); - putSupplier(AnalysisKeys.CHUNK_SERIES, () -> new ChunkGraph(getUnsafe(AnalysisKeys.TPS_MUTATOR)).toHighChartsSeries()); + putSupplier(AnalysisKeys.TPS_SERIES, () -> graphs.line().tpsGraph(getUnsafe(AnalysisKeys.TPS_MUTATOR)).toHighChartsSeries()); + putSupplier(AnalysisKeys.CPU_SERIES, () -> graphs.line().cpuGraph(getUnsafe(AnalysisKeys.TPS_MUTATOR)).toHighChartsSeries()); + putSupplier(AnalysisKeys.RAM_SERIES, () -> graphs.line().ramGraph(getUnsafe(AnalysisKeys.TPS_MUTATOR)).toHighChartsSeries()); + putSupplier(AnalysisKeys.DISK_SERIES, () -> graphs.line().diskGraph(getUnsafe(AnalysisKeys.TPS_MUTATOR)).toHighChartsSeries()); + putSupplier(AnalysisKeys.ENTITY_SERIES, () -> graphs.line().entityGraph(getUnsafe(AnalysisKeys.TPS_MUTATOR)).toHighChartsSeries()); + putSupplier(AnalysisKeys.CHUNK_SERIES, () -> graphs.line().cpuGraph(getUnsafe(AnalysisKeys.TPS_MUTATOR)).toHighChartsSeries()); putSupplier(AnalysisKeys.WORLD_MAP_SERIES, () -> - new WorldMap(getUnsafe(AnalysisKeys.PLAYERS_MUTATOR).getGeolocations()).toHighChartsSeries() + graphs.special().worldMap(getUnsafe(AnalysisKeys.PLAYERS_MUTATOR)).toHighChartsSeries() ); - Key geolocationBarChart = new Key<>(GeolocationBarGraph.class, "GEOLOCATION_BAR_CHART"); - putCachingSupplier(geolocationBarChart, () -> new GeolocationBarGraph(getUnsafe(AnalysisKeys.PLAYERS_MUTATOR))); + Key geolocationBarChart = new Key<>(BarGraph.class, "GEOLOCATION_BAR_GRAPH"); + putCachingSupplier(geolocationBarChart, () -> graphs.bar().geolocationBarGraph(getUnsafe(AnalysisKeys.PLAYERS_MUTATOR))); putSupplier(AnalysisKeys.COUNTRY_CATEGORIES, () -> getUnsafe(geolocationBarChart).toHighChartsCategories()); putSupplier(AnalysisKeys.COUNTRY_SERIES, () -> getUnsafe(geolocationBarChart).toHighChartsSeries()); Key pingGraph = new Key<>(PingGraph.class, "PING_GRAPH"); - putCachingSupplier(pingGraph, () -> new PingGraph( - PingMutator.forContainer(serverContainer).mutateToByMinutePings().all() - )); + putCachingSupplier(pingGraph, () -> + graphs.line().pingGraph(PingMutator.forContainer(serverContainer).mutateToByMinutePings().all()) + ); putSupplier(AnalysisKeys.AVG_PING_SERIES, () -> getUnsafe(pingGraph).toAvgSeries()); putSupplier(AnalysisKeys.MAX_PING_SERIES, () -> getUnsafe(pingGraph).toMaxSeries()); putSupplier(AnalysisKeys.MIN_PING_SERIES, () -> getUnsafe(pingGraph).toMinSeries()); - putSupplier(AnalysisKeys.CALENDAR_SERIES, () -> new ServerCalendar( + putSupplier(AnalysisKeys.CALENDAR_SERIES, () -> graphs.calendar().serverCalendar( getUnsafe(AnalysisKeys.PLAYERS_MUTATOR), getUnsafe(AnalysisKeys.UNIQUE_PLAYERS_PER_DAY), getUnsafe(AnalysisKeys.NEW_PLAYERS_PER_DAY) ).toCalendarSeries()); - putCachingSupplier(AnalysisKeys.ACTIVITY_DATA, () -> getUnsafe(AnalysisKeys.PLAYERS_MUTATOR).toActivityDataMap(getUnsafe(AnalysisKeys.ANALYSIS_TIME))); - Key activityStackGraph = new Key<>(ActivityStackGraph.class, "ACTIVITY_STACK_GRAPH"); - putCachingSupplier(activityStackGraph, () -> new ActivityStackGraph(getUnsafe(AnalysisKeys.ACTIVITY_DATA))); + putCachingSupplier(AnalysisKeys.ACTIVITY_DATA, () -> getUnsafe(AnalysisKeys.PLAYERS_MUTATOR).toActivityDataMap(getUnsafe(AnalysisKeys.ANALYSIS_TIME), config.getNumber(Settings.ACTIVE_PLAY_THRESHOLD), config.getNumber(Settings.ACTIVE_LOGIN_THRESHOLD))); + Key activityStackGraph = new Key<>(StackGraph.class, "ACTIVITY_STACK_GRAPH"); + putCachingSupplier(activityStackGraph, () -> graphs.stack().activityStackGraph(getUnsafe(AnalysisKeys.ACTIVITY_DATA))); putSupplier(AnalysisKeys.ACTIVITY_STACK_CATEGORIES, () -> getUnsafe(activityStackGraph).toHighChartsLabels()); putSupplier(AnalysisKeys.ACTIVITY_STACK_SERIES, () -> getUnsafe(activityStackGraph).toHighChartsSeries()); - putSupplier(AnalysisKeys.ACTIVITY_PIE_SERIES, () -> - new ActivityPie(getUnsafe(AnalysisKeys.ACTIVITY_DATA).get(getUnsafe(AnalysisKeys.ANALYSIS_TIME))).toHighChartsSeries() + putSupplier(AnalysisKeys.ACTIVITY_PIE_SERIES, () -> graphs.pie().activityPie( + getUnsafe(AnalysisKeys.ACTIVITY_DATA).get(getUnsafe(AnalysisKeys.ANALYSIS_TIME))).toHighChartsSeries() ); putSupplier(AnalysisKeys.PLAYERS_REGULAR, () -> { Map> activityNow = getUnsafe(AnalysisKeys.ACTIVITY_DATA) @@ -388,19 +422,21 @@ public class AnalysisContainer extends DataContainer { putCachingSupplier(AnalysisKeys.PLAYERS_ONLINE_RESOLVER, () -> new PlayersOnlineResolver(getUnsafe(AnalysisKeys.TPS_MUTATOR))); - putSupplier(AnalysisKeys.TPS_SPIKE_MONTH, () -> getUnsafe(tpsMonth).lowTpsSpikeCount()); + int threshold = config.getNumber(Settings.THEME_GRAPH_TPS_THRESHOLD_MED); + + putSupplier(AnalysisKeys.TPS_SPIKE_MONTH, () -> getUnsafe(tpsMonth).lowTpsSpikeCount(threshold)); putSupplier(AnalysisKeys.AVG_TPS_MONTH, () -> getUnsafe(tpsMonth).averageTPS()); putSupplier(AnalysisKeys.AVG_CPU_MONTH, () -> getUnsafe(tpsMonth).averageCPU()); putSupplier(AnalysisKeys.AVG_RAM_MONTH, () -> getUnsafe(tpsMonth).averageRAM()); putSupplier(AnalysisKeys.AVG_ENTITY_MONTH, () -> getUnsafe(tpsMonth).averageEntities()); putSupplier(AnalysisKeys.AVG_CHUNK_MONTH, () -> getUnsafe(tpsMonth).averageChunks()); - putSupplier(AnalysisKeys.TPS_SPIKE_WEEK, () -> getUnsafe(tpsWeek).lowTpsSpikeCount()); + putSupplier(AnalysisKeys.TPS_SPIKE_WEEK, () -> getUnsafe(tpsWeek).lowTpsSpikeCount(threshold)); putSupplier(AnalysisKeys.AVG_TPS_WEEK, () -> getUnsafe(tpsWeek).averageTPS()); putSupplier(AnalysisKeys.AVG_CPU_WEEK, () -> getUnsafe(tpsWeek).averageCPU()); putSupplier(AnalysisKeys.AVG_RAM_WEEK, () -> getUnsafe(tpsWeek).averageRAM()); putSupplier(AnalysisKeys.AVG_ENTITY_WEEK, () -> getUnsafe(tpsWeek).averageEntities()); putSupplier(AnalysisKeys.AVG_CHUNK_WEEK, () -> getUnsafe(tpsWeek).averageChunks()); - putSupplier(AnalysisKeys.TPS_SPIKE_DAY, () -> getUnsafe(tpsDay).lowTpsSpikeCount()); + putSupplier(AnalysisKeys.TPS_SPIKE_DAY, () -> getUnsafe(tpsDay).lowTpsSpikeCount(threshold)); putSupplier(AnalysisKeys.AVG_TPS_DAY, () -> getUnsafe(tpsDay).averageTPS()); putSupplier(AnalysisKeys.AVG_CPU_DAY, () -> getUnsafe(tpsDay).averageCPU()); putSupplier(AnalysisKeys.AVG_RAM_DAY, () -> getUnsafe(tpsDay).averageRAM()); @@ -409,14 +445,21 @@ public class AnalysisContainer extends DataContainer { } private void addCommandSuppliers() { - putSupplier(AnalysisKeys.COMMAND_USAGE_TABLE, () -> new CommandUseTable(serverContainer).parseHtml()); + putSupplier(AnalysisKeys.COMMAND_USAGE_TABLE, () -> tables.commandUseTable(serverContainer).parseHtml()); putSupplier(AnalysisKeys.COMMAND_COUNT_UNIQUE, () -> serverContainer.getValue(ServerKeys.COMMAND_USAGE).map(Map::size).orElse(0)); putSupplier(AnalysisKeys.COMMAND_COUNT, () -> CommandUseMutator.forContainer(serverContainer).commandUsageCount()); } private void addServerHealth() { Key healthInformation = new Key<>(HealthInformation.class, "HEALTH_INFORMATION"); - putCachingSupplier(healthInformation, () -> new HealthInformation(this)); + putCachingSupplier(healthInformation, () -> new HealthInformation( + this, + locale, + config.getNumber(Settings.THEME_GRAPH_TPS_THRESHOLD_MED), + config.getNumber(Settings.ACTIVE_PLAY_THRESHOLD), + config.getNumber(Settings.ACTIVE_LOGIN_THRESHOLD), + formatters.timeAmount(), formatters.decimals(), formatters.percentage() + )); putSupplier(AnalysisKeys.HEALTH_INDEX, () -> getUnsafe(healthInformation).getServerHealth()); putSupplier(AnalysisKeys.HEALTH_NOTES, () -> getUnsafe(healthInformation).toHtml()); } @@ -424,14 +467,70 @@ public class AnalysisContainer extends DataContainer { private void addPluginSuppliers() { // TODO Refactor into a system that supports running the analysis on Bungee Key navAndTabs = new Key<>(new Type() {}, "NAV_AND_TABS"); - putCachingSupplier(navAndTabs, () -> - AnalysisPluginsTabContentCreator.createContent( - getUnsafe(AnalysisKeys.PLAYERS_MUTATOR), - this - ) - ); - putCachingSupplier(AnalysisKeys.BAN_DATA, () -> new ServerBanDataReader().readBanDataForContainer(this)); + putCachingSupplier(navAndTabs, () -> pluginsTabContentCreator.createContent( + this, getValue(AnalysisKeys.PLAYERS_MUTATOR).orElse(new PlayersMutator(new ArrayList<>())) + )); putSupplier(AnalysisKeys.PLUGINS_TAB_NAV, () -> getUnsafe(navAndTabs)[0]); putSupplier(AnalysisKeys.PLUGINS_TAB, () -> getUnsafe(navAndTabs)[1]); } + + @Singleton + public static class Factory { + + private final String version; + private final PlanConfig config; + private final Locale locale; + private final Theme theme; + private final DBSystem dbSystem; + private final ServerProperties serverProperties; + private final Formatters formatters; + private final Graphs graphs; + private final HtmlTables tables; + private final Accordions accordions; + private final AnalysisPluginsTabContentCreator pluginsTabContentCreator; + + @Inject + public Factory( + @Named("currentVersion") String version, + PlanConfig config, + Locale locale, + Theme theme, + DBSystem dbSystem, + ServerProperties serverProperties, + Formatters formatters, + Graphs graphs, + HtmlTables tables, + Accordions accordions, + AnalysisPluginsTabContentCreator pluginsTabContentCreator + ) { + this.version = version; + this.config = config; + this.locale = locale; + this.theme = theme; + this.dbSystem = dbSystem; + this.serverProperties = serverProperties; + this.formatters = formatters; + this.graphs = graphs; + this.tables = tables; + this.accordions = accordions; + this.pluginsTabContentCreator = pluginsTabContentCreator; + } + + public AnalysisContainer forServerContainer(ServerContainer serverContainer) { + return new AnalysisContainer( + serverContainer, + version, + locale, + config, + theme, + dbSystem, + serverProperties, + formatters, + graphs, + tables, + accordions, + pluginsTabContentCreator + ); + } + } } \ No newline at end of file diff --git a/Plan/src/main/java/com/djrapitops/plan/data/store/containers/DataContainer.java b/Plan/src/main/java/com/djrapitops/plan/data/store/containers/DataContainer.java index b47d3ee03..e6c26f85c 100644 --- a/Plan/src/main/java/com/djrapitops/plan/data/store/containers/DataContainer.java +++ b/Plan/src/main/java/com/djrapitops/plan/data/store/containers/DataContainer.java @@ -2,12 +2,12 @@ package com.djrapitops.plan.data.store.containers; import com.djrapitops.plan.data.store.CachingSupplier; import com.djrapitops.plan.data.store.Key; -import com.djrapitops.plan.data.store.mutators.formatting.Formatter; -import com.djrapitops.plugin.api.TimeAmount; +import com.djrapitops.plan.utilities.formatting.Formatter; import java.util.HashMap; import java.util.Map; import java.util.Optional; +import java.util.concurrent.TimeUnit; import java.util.function.Supplier; /** @@ -24,7 +24,7 @@ public class DataContainer { private long timeToLive; public DataContainer() { - this(TimeAmount.SECOND.ms() * 30L); + this(TimeUnit.SECONDS.toMillis(30L)); } public DataContainer(long timeToLive) { diff --git a/Plan/src/main/java/com/djrapitops/plan/data/store/containers/NetworkContainer.java b/Plan/src/main/java/com/djrapitops/plan/data/store/containers/NetworkContainer.java index 5bc3e758d..5ae1ad998 100644 --- a/Plan/src/main/java/com/djrapitops/plan/data/store/containers/NetworkContainer.java +++ b/Plan/src/main/java/com/djrapitops/plan/data/store/containers/NetworkContainer.java @@ -1,33 +1,36 @@ package com.djrapitops.plan.data.store.containers; -import com.djrapitops.plan.PlanPlugin; -import com.djrapitops.plan.api.exceptions.database.DBOpException; +import com.djrapitops.plan.data.container.TPS; import com.djrapitops.plan.data.store.Key; import com.djrapitops.plan.data.store.keys.NetworkKeys; import com.djrapitops.plan.data.store.keys.ServerKeys; import com.djrapitops.plan.data.store.mutators.PlayersMutator; import com.djrapitops.plan.data.store.mutators.TPSMutator; -import com.djrapitops.plan.data.store.mutators.formatting.Formatters; import com.djrapitops.plan.data.store.mutators.health.NetworkHealthInformation; -import com.djrapitops.plan.system.database.databases.Database; -import com.djrapitops.plan.system.info.server.ServerInfo; +import com.djrapitops.plan.system.database.DBSystem; +import com.djrapitops.plan.system.info.server.properties.ServerProperties; +import com.djrapitops.plan.system.locale.Locale; import com.djrapitops.plan.system.settings.Settings; +import com.djrapitops.plan.system.settings.config.PlanConfig; import com.djrapitops.plan.system.settings.theme.Theme; import com.djrapitops.plan.system.settings.theme.ThemeVal; -import com.djrapitops.plan.utilities.MiscUtils; -import com.djrapitops.plan.utilities.html.graphs.ActivityStackGraph; -import com.djrapitops.plan.utilities.html.graphs.WorldMap; -import com.djrapitops.plan.utilities.html.graphs.bar.GeolocationBarGraph; -import com.djrapitops.plan.utilities.html.graphs.line.OnlineActivityGraph; -import com.djrapitops.plan.utilities.html.graphs.pie.ActivityPie; +import com.djrapitops.plan.utilities.formatting.Formatters; +import com.djrapitops.plan.utilities.html.graphs.Graphs; +import com.djrapitops.plan.utilities.html.graphs.bar.BarGraph; +import com.djrapitops.plan.utilities.html.graphs.stack.StackGraph; +import com.djrapitops.plan.utilities.html.structure.NetworkServerBox; import com.djrapitops.plugin.api.Check; import com.djrapitops.plugin.api.TimeAmount; -import com.djrapitops.plugin.api.utility.log.Log; +import dagger.Lazy; +import javax.inject.Inject; +import javax.inject.Named; +import javax.inject.Singleton; +import java.util.ArrayList; import java.util.HashMap; +import java.util.List; import java.util.Map; -import java.util.Optional; -import java.util.UUID; +import java.util.concurrent.TimeUnit; /** * DataContainer for the whole network. @@ -40,94 +43,131 @@ public class NetworkContainer extends DataContainer { private final ServerContainer bungeeContainer; - private final Map serverContainers; + private final String version; + private final PlanConfig config; + private final Locale locale; + private final Theme theme; + private final DBSystem dbSystem; + private final ServerProperties serverProperties; + private final Formatters formatters; + private final Graphs graphs; - public NetworkContainer(ServerContainer bungeeContainer) { + public NetworkContainer( + ServerContainer bungeeContainer, + String version, + PlanConfig config, + Locale locale, + Theme theme, + DBSystem dbSystem, + ServerProperties serverProperties, + Formatters formatters, + Graphs graphs + ) { this.bungeeContainer = bungeeContainer; - serverContainers = new HashMap<>(); + this.version = version; + this.config = config; + this.locale = locale; + this.theme = theme; + this.dbSystem = dbSystem; + this.serverProperties = serverProperties; + this.formatters = formatters; + this.graphs = graphs; putCachingSupplier(NetworkKeys.PLAYERS_MUTATOR, () -> PlayersMutator.forContainer(bungeeContainer)); addConstants(); + addServerBoxes(); addPlayerInformation(); addNetworkHealth(); } + private void addServerBoxes() { + putSupplier(NetworkKeys.NETWORK_PLAYER_ONLINE_DATA, () -> dbSystem.getDatabase().fetch().getPlayersOnlineForServers( + getValue(NetworkKeys.BUKKIT_SERVERS).orElse(new ArrayList<>())) + ); + putSupplier(NetworkKeys.SERVER_REGISTER_DATA, () -> dbSystem.getDatabase().fetch().getPlayersRegisteredForServers( + getValue(NetworkKeys.BUKKIT_SERVERS).orElse(new ArrayList<>())) + ); + putSupplier(NetworkKeys.SERVERS_TAB, () -> { + StringBuilder serverBoxes = new StringBuilder(); + Map> playersOnlineData = getValue(NetworkKeys.NETWORK_PLAYER_ONLINE_DATA).orElse(new HashMap<>()); + Map registerData = getValue(NetworkKeys.SERVER_REGISTER_DATA).orElse(new HashMap<>()); + getValue(NetworkKeys.BUKKIT_SERVERS).orElse(new ArrayList<>()) + .stream() + .sorted((one, two) -> String.CASE_INSENSITIVE_ORDER.compare(one.getName(), two.getName())) + .forEach(server -> { + int serverId = server.getId(); + TPSMutator tpsMutator = new TPSMutator(playersOnlineData.getOrDefault(serverId, new ArrayList<>())); + int registered = registerData.getOrDefault(serverId, 0); + NetworkServerBox serverBox = new NetworkServerBox(server, registered, tpsMutator, graphs); + serverBoxes.append(serverBox.toHtml()); + }); + return serverBoxes.toString(); + }); + } + private void addNetworkHealth() { Key healthInformation = new Key<>(NetworkHealthInformation.class, "HEALTH_INFORMATION"); - putCachingSupplier(healthInformation, () -> new NetworkHealthInformation(this)); + putCachingSupplier(healthInformation, () -> new NetworkHealthInformation( + this, + locale, + config.getNumber(Settings.ACTIVE_PLAY_THRESHOLD), + config.getNumber(Settings.ACTIVE_LOGIN_THRESHOLD), + formatters.timeAmount(), formatters.decimals(), formatters.percentage() + )); putCachingSupplier(NetworkKeys.HEALTH_INDEX, () -> getUnsafe(healthInformation).getServerHealth()); putCachingSupplier(NetworkKeys.HEALTH_NOTES, () -> getUnsafe(healthInformation).toHtml()); } - public void putAnalysisContainer(AnalysisContainer analysisContainer) { - serverContainers.put(analysisContainer.getServerContainer().getUnsafe(ServerKeys.SERVER_UUID), analysisContainer); - } - - public Optional getAnalysisContainer(UUID serverUUID) { - AnalysisContainer container = serverContainers.get(serverUUID); - if (container != null) { - return Optional.of(container); - } - try { - AnalysisContainer analysisContainer = new AnalysisContainer(Database.getActive().fetch().getServerContainer(serverUUID)); - serverContainers.put(serverUUID, analysisContainer); - return Optional.of(analysisContainer); - } catch (DBOpException e) { - Log.toLog(this.getClass(), e); - } - return Optional.empty(); - } - private void addConstants() { long now = System.currentTimeMillis(); putRawData(NetworkKeys.REFRESH_TIME, now); - putRawData(NetworkKeys.REFRESH_TIME_DAY_AGO, getUnsafe(NetworkKeys.REFRESH_TIME) - TimeAmount.DAY.ms()); - putRawData(NetworkKeys.REFRESH_TIME_WEEK_AGO, getUnsafe(NetworkKeys.REFRESH_TIME) - TimeAmount.WEEK.ms()); - putRawData(NetworkKeys.REFRESH_TIME_MONTH_AGO, getUnsafe(NetworkKeys.REFRESH_TIME) - TimeAmount.MONTH.ms()); - putSupplier(NetworkKeys.REFRESH_TIME_F, () -> Formatters.second().apply(() -> getUnsafe(NetworkKeys.REFRESH_TIME))); + putRawData(NetworkKeys.REFRESH_TIME_DAY_AGO, getUnsafe(NetworkKeys.REFRESH_TIME) - TimeUnit.DAYS.toMillis(1L)); + putRawData(NetworkKeys.REFRESH_TIME_WEEK_AGO, getUnsafe(NetworkKeys.REFRESH_TIME) - TimeAmount.WEEK.toMillis(1L)); + putRawData(NetworkKeys.REFRESH_TIME_MONTH_AGO, getUnsafe(NetworkKeys.REFRESH_TIME) - TimeAmount.MONTH.toMillis(1L)); + putSupplier(NetworkKeys.REFRESH_TIME_F, () -> formatters.secondLong().apply(getUnsafe(NetworkKeys.REFRESH_TIME))); - putRawData(NetworkKeys.VERSION, PlanPlugin.getInstance().getVersion()); - putSupplier(NetworkKeys.TIME_ZONE, MiscUtils::getTimeZoneOffsetHours); + putRawData(NetworkKeys.VERSION, version); + putSupplier(NetworkKeys.TIME_ZONE, config::getTimeZoneOffsetHours); putCachingSupplier(NetworkKeys.NETWORK_NAME, () -> - Check.isBungeeAvailable() ? - Settings.BUNGEE_NETWORK_NAME.toString() : + Check.isBungeeAvailable() || Check.isVelocityAvailable() ? + config.getString(Settings.BUNGEE_NETWORK_NAME) : bungeeContainer.getValue(ServerKeys.NAME).orElse("Plan") ); - putSupplier(NetworkKeys.PLAYERS_ONLINE, ServerInfo.getServerProperties()::getOnlinePlayers); - putRawData(NetworkKeys.WORLD_MAP_LOW_COLOR, Theme.getValue(ThemeVal.WORLD_MAP_LOW)); - putRawData(NetworkKeys.WORLD_MAP_HIGH_COLOR, Theme.getValue(ThemeVal.WORLD_MAP_HIGH)); - putRawData(NetworkKeys.PLAYERS_GRAPH_COLOR, Theme.getValue(ThemeVal.GRAPH_PLAYERS_ONLINE)); + putSupplier(NetworkKeys.PLAYERS_ONLINE, serverProperties::getOnlinePlayers); + putRawData(NetworkKeys.WORLD_MAP_LOW_COLOR, theme.getValue(ThemeVal.WORLD_MAP_LOW)); + putRawData(NetworkKeys.WORLD_MAP_HIGH_COLOR, theme.getValue(ThemeVal.WORLD_MAP_HIGH)); + putRawData(NetworkKeys.PLAYERS_GRAPH_COLOR, theme.getValue(ThemeVal.GRAPH_PLAYERS_ONLINE)); } private void addPlayerInformation() { putSupplier(NetworkKeys.PLAYERS_TOTAL, () -> getUnsafe(NetworkKeys.PLAYERS_MUTATOR).count()); putSupplier(NetworkKeys.WORLD_MAP_SERIES, () -> - new WorldMap(PlayersMutator.forContainer(bungeeContainer)).toHighChartsSeries() + graphs.special().worldMap(PlayersMutator.forContainer(bungeeContainer)).toHighChartsSeries() ); - Key geolocationBarChart = new Key<>(GeolocationBarGraph.class, "GEOLOCATION_BAR_CHART"); - putSupplier(geolocationBarChart, () -> new GeolocationBarGraph(getUnsafe(NetworkKeys.PLAYERS_MUTATOR))); + Key geolocationBarChart = new Key<>(BarGraph.class, "GEOLOCATION_BAR_GRAPH"); + putSupplier(geolocationBarChart, () -> graphs.bar().geolocationBarGraph(getUnsafe(NetworkKeys.PLAYERS_MUTATOR))); putSupplier(NetworkKeys.COUNTRY_CATEGORIES, () -> getUnsafe(geolocationBarChart).toHighChartsCategories()); putSupplier(NetworkKeys.COUNTRY_SERIES, () -> getUnsafe(geolocationBarChart).toHighChartsSeries()); putSupplier(NetworkKeys.PLAYERS_ONLINE_SERIES, () -> - new OnlineActivityGraph(TPSMutator.forContainer(bungeeContainer)).toHighChartsSeries() + graphs.line().playersOnlineGraph(TPSMutator.forContainer(bungeeContainer)).toHighChartsSeries() ); - Key activityStackGraph = new Key<>(ActivityStackGraph.class, "ACTIVITY_STACK_GRAPH"); - putSupplier(NetworkKeys.ACTIVITY_DATA, () -> getUnsafe(NetworkKeys.PLAYERS_MUTATOR).toActivityDataMap(getUnsafe(NetworkKeys.REFRESH_TIME))); - putSupplier(activityStackGraph, () -> new ActivityStackGraph(getUnsafe(NetworkKeys.ACTIVITY_DATA))); + Key activityStackGraph = new Key<>(StackGraph.class, "ACTIVITY_STACK_GRAPH"); + putSupplier(NetworkKeys.ACTIVITY_DATA, () -> getUnsafe(NetworkKeys.PLAYERS_MUTATOR).toActivityDataMap(getUnsafe(NetworkKeys.REFRESH_TIME), config.getNumber(Settings.ACTIVE_PLAY_THRESHOLD), config.getNumber(Settings.ACTIVE_LOGIN_THRESHOLD))); + putSupplier(activityStackGraph, () -> graphs.stack().activityStackGraph(getUnsafe(NetworkKeys.ACTIVITY_DATA))); putSupplier(NetworkKeys.ACTIVITY_STACK_CATEGORIES, () -> getUnsafe(activityStackGraph).toHighChartsLabels()); putSupplier(NetworkKeys.ACTIVITY_STACK_SERIES, () -> getUnsafe(activityStackGraph).toHighChartsSeries()); - putSupplier(NetworkKeys.ACTIVITY_PIE_SERIES, () -> - new ActivityPie(getUnsafe(NetworkKeys.ACTIVITY_DATA).get(getUnsafe(NetworkKeys.REFRESH_TIME))).toHighChartsSeries() + putSupplier(NetworkKeys.ACTIVITY_PIE_SERIES, () -> graphs.pie().activityPie( + getUnsafe(NetworkKeys.ACTIVITY_DATA).get(getUnsafe(NetworkKeys.REFRESH_TIME))).toHighChartsSeries() ); putSupplier(NetworkKeys.ALL_TIME_PEAK_TIME_F, () -> - bungeeContainer.getValue(ServerKeys.ALL_TIME_PEAK_PLAYERS).map(Formatters.year()::apply).orElse("No data") + bungeeContainer.getValue(ServerKeys.ALL_TIME_PEAK_PLAYERS).map(formatters.year()).orElse("No data") ); putSupplier(NetworkKeys.RECENT_PEAK_TIME_F, () -> - bungeeContainer.getValue(ServerKeys.RECENT_PEAK_PLAYERS).map(Formatters.year()::apply).orElse("No data") + bungeeContainer.getValue(ServerKeys.RECENT_PEAK_PLAYERS).map(formatters.year()).orElse("No data") ); putSupplier(NetworkKeys.PLAYERS_ALL_TIME_PEAK, () -> bungeeContainer.getValue(ServerKeys.ALL_TIME_PEAK_PLAYERS).map(dateObj -> "" + dateObj.getValue()).orElse("-") @@ -176,4 +216,53 @@ public class NetworkContainer extends DataContainer { public ServerContainer getBungeeContainer() { return bungeeContainer; } + + @Singleton + public static class Factory { + + private final Lazy version; + private final Lazy config; + private final Lazy locale; + private final Lazy theme; + private final Lazy dbSystem; + private final Lazy serverProperties; + private final Lazy formatters; + private final Lazy graphs; + + @Inject + public Factory( + @Named("currentVersion") Lazy version, + Lazy config, + Lazy locale, + Lazy theme, + Lazy dbSystem, + Lazy serverProperties, + Lazy formatters, + Lazy graphs + ) { + this.version = version; + this.config = config; + this.locale = locale; + this.theme = theme; + this.dbSystem = dbSystem; + this.serverProperties = serverProperties; + this.formatters = formatters; + this.graphs = graphs; + } + + public NetworkContainer forBungeeContainer(ServerContainer bungeeContainer) { + return new NetworkContainer( + bungeeContainer, + version.get(), + config.get(), + locale.get(), + theme.get(), + dbSystem.get(), + serverProperties.get(), + formatters.get(), + graphs.get() + ); + } + } + } \ No newline at end of file diff --git a/Plan/src/main/java/com/djrapitops/plan/data/store/containers/PlayerContainer.java b/Plan/src/main/java/com/djrapitops/plan/data/store/containers/PlayerContainer.java index a23752fe8..7f2882261 100644 --- a/Plan/src/main/java/com/djrapitops/plan/data/store/containers/PlayerContainer.java +++ b/Plan/src/main/java/com/djrapitops/plan/data/store/containers/PlayerContainer.java @@ -22,8 +22,8 @@ public class PlayerContainer extends DataContainer { activityIndexCache = new HashMap<>(); } - public ActivityIndex getActivityIndex(long date) { - return activityIndexCache.computeIfAbsent(date, time -> new ActivityIndex(this, time)); + public ActivityIndex getActivityIndex(long date, int minuteThreshold, int loginThreshold) { + return activityIndexCache.computeIfAbsent(date, time -> new ActivityIndex(this, time, minuteThreshold, loginThreshold)); } public boolean playedBetween(long after, long before) { diff --git a/Plan/src/main/java/com/djrapitops/plan/data/store/keys/AnalysisKeys.java b/Plan/src/main/java/com/djrapitops/plan/data/store/keys/AnalysisKeys.java index 978adbd72..c593759d2 100644 --- a/Plan/src/main/java/com/djrapitops/plan/data/store/keys/AnalysisKeys.java +++ b/Plan/src/main/java/com/djrapitops/plan/data/store/keys/AnalysisKeys.java @@ -30,6 +30,8 @@ public class AnalysisKeys { public static final PlaceholderKey FIRST_DAY = new PlaceholderKey<>(Integer.class, "firstDay"); public static final PlaceholderKey TPS_MEDIUM = new PlaceholderKey<>(Integer.class, "tpsMedium"); public static final PlaceholderKey TPS_HIGH = new PlaceholderKey<>(Integer.class, "tpsHigh"); + public static final PlaceholderKey DISK_MEDIUM = new PlaceholderKey<>(Integer.class, "diskMedium"); + public static final PlaceholderKey DISK_HIGH = new PlaceholderKey<>(Integer.class, "diskHigh"); public static final PlaceholderKey PLAYERS_MAX = new PlaceholderKey<>(Integer.class, "playersMax"); public static final PlaceholderKey PLAYERS_ONLINE = CommonPlaceholderKeys.PLAYERS_ONLINE; public static final PlaceholderKey PLAYERS_TOTAL = CommonPlaceholderKeys.PLAYERS_TOTAL; @@ -60,6 +62,7 @@ public class AnalysisKeys { public static final PlaceholderKey PLUGINS_TAB_NAV = new PlaceholderKey<>(String.class, "navPluginsTabs"); // Formatted time values public static final PlaceholderKey REFRESH_TIME_F = CommonPlaceholderKeys.REFRESH_TIME_F; + public static final PlaceholderKey REFRESH_TIME_FULL_F = CommonPlaceholderKeys.REFRESH_TIME_FULL_F; public static final PlaceholderKey LAST_PEAK_TIME_F = CommonPlaceholderKeys.LAST_PEAK_TIME_F; public static final PlaceholderKey ALL_TIME_PEAK_TIME_F = CommonPlaceholderKeys.ALL_TIME_PEAK_TIME_F; public static final PlaceholderKey AVERAGE_SESSION_LENGTH_F = new PlaceholderKey<>(String.class, "sessionAverage"); @@ -126,6 +129,7 @@ public class AnalysisKeys { public static final PlaceholderKey RAM_SERIES = new PlaceholderKey<>(String.class, "ramSeries"); public static final PlaceholderKey ENTITY_SERIES = new PlaceholderKey<>(String.class, "entitySeries"); public static final PlaceholderKey CHUNK_SERIES = new PlaceholderKey<>(String.class, "chunkSeries"); + public static final PlaceholderKey DISK_SERIES = new PlaceholderKey<>(String.class, "diskSeries"); public static final PlaceholderKey PUNCHCARD_SERIES = new PlaceholderKey<>(String.class, "punchCardSeries"); public static final PlaceholderKey WORLD_MAP_SERIES = CommonPlaceholderKeys.WORLD_MAP_SERIES; public static final PlaceholderKey ACTIVITY_STACK_SERIES = CommonPlaceholderKeys.ACTIVITY_STACK_SERIES; @@ -151,6 +155,7 @@ public class AnalysisKeys { public static final Key ANALYSIS_TIME_MONTH_AGO = new Key<>(Long.class, "ANALYSIS_TIME_MONTH_AGO"); public static final Key> PLAYER_NAMES = new Key<>(new Type>() {}, "PLAYER_NAMES"); public static final Key>>> ACTIVITY_DATA = CommonKeys.ACTIVITY_DATA; + @Deprecated public static final Key> BAN_DATA = new Key<>(new Type>() {}, "BAN_DATA"); public static final Key> UNIQUE_PLAYERS_PER_DAY = new Key<>(new Type>() {}, "UNIQUE_PLAYERS_PER_DAY"); public static final Key> NEW_PLAYERS_PER_DAY = new Key<>(new Type>() {}, "NEW_PLAYERS_PER_DAY"); diff --git a/Plan/src/main/java/com/djrapitops/plan/data/store/keys/CommonPlaceholderKeys.java b/Plan/src/main/java/com/djrapitops/plan/data/store/keys/CommonPlaceholderKeys.java index 25b253555..f8722b99d 100644 --- a/Plan/src/main/java/com/djrapitops/plan/data/store/keys/CommonPlaceholderKeys.java +++ b/Plan/src/main/java/com/djrapitops/plan/data/store/keys/CommonPlaceholderKeys.java @@ -22,8 +22,8 @@ class CommonPlaceholderKeys { static final PlaceholderKey ACTIVITY_STACK_SERIES = new PlaceholderKey<>(String.class, "activityStackSeries"); static final PlaceholderKey ACTIVITY_STACK_CATEGORIES = new PlaceholderKey<>(String.class, "activityStackCategories"); static final PlaceholderKey ACTIVITY_PIE_SERIES = new PlaceholderKey<>(String.class, "activityPieSeries"); - public static final PlaceholderKey COUNTRY_CATEGORIES = new PlaceholderKey<>(String.class, "countryCategories"); - public static final PlaceholderKey COUNTRY_SERIES = new PlaceholderKey<>(String.class, "countrySeries"); + static final PlaceholderKey COUNTRY_CATEGORIES = new PlaceholderKey<>(String.class, "countryCategories"); + static final PlaceholderKey COUNTRY_SERIES = new PlaceholderKey<>(String.class, "countrySeries"); static final PlaceholderKey HEALTH_NOTES = new PlaceholderKey<>(String.class, "healthNotes"); static final PlaceholderKey HEALTH_INDEX = new PlaceholderKey<>(Double.class, "healthIndex"); @@ -36,6 +36,7 @@ class CommonPlaceholderKeys { static final PlaceholderKey PLAYERS_NEW_MONTH = new PlaceholderKey<>(Integer.class, "playersNewMonth"); static final PlaceholderKey REFRESH_TIME_F = new PlaceholderKey<>(String.class, "refresh"); + static final PlaceholderKey REFRESH_TIME_FULL_F = new PlaceholderKey<>(String.class, "refreshFull"); static final PlaceholderKey LAST_PEAK_TIME_F = new PlaceholderKey<>(String.class, "lastPeakTime"); static final PlaceholderKey ALL_TIME_PEAK_TIME_F = new PlaceholderKey<>(String.class, "bestPeakTime"); static final PlaceholderKey PLAYERS_LAST_PEAK = new PlaceholderKey<>(String.class, "playersLastPeak"); diff --git a/Plan/src/main/java/com/djrapitops/plan/data/store/keys/NetworkKeys.java b/Plan/src/main/java/com/djrapitops/plan/data/store/keys/NetworkKeys.java index f85c0c4ed..c8a577a0f 100644 --- a/Plan/src/main/java/com/djrapitops/plan/data/store/keys/NetworkKeys.java +++ b/Plan/src/main/java/com/djrapitops/plan/data/store/keys/NetworkKeys.java @@ -1,5 +1,6 @@ package com.djrapitops.plan.data.store.keys; +import com.djrapitops.plan.data.container.TPS; import com.djrapitops.plan.data.store.Key; import com.djrapitops.plan.data.store.PlaceholderKey; import com.djrapitops.plan.data.store.Type; @@ -37,6 +38,7 @@ public class NetworkKeys { public static final PlaceholderKey PLAYERS_NEW_WEEK = CommonPlaceholderKeys.PLAYERS_NEW_WEEK; public static final PlaceholderKey PLAYERS_NEW_MONTH = CommonPlaceholderKeys.PLAYERS_NEW_MONTH; + public static final PlaceholderKey SERVERS_TAB = new PlaceholderKey<>(String.class, "tabContentServers"); public static final PlaceholderKey WORLD_MAP_SERIES = CommonPlaceholderKeys.WORLD_MAP_SERIES; public static final PlaceholderKey PLAYERS_ONLINE_SERIES = CommonPlaceholderKeys.PLAYERS_ONLINE_SERIES; public static final PlaceholderKey ACTIVITY_STACK_SERIES = CommonPlaceholderKeys.ACTIVITY_STACK_SERIES; @@ -55,6 +57,8 @@ public class NetworkKeys { public static final Key> BUKKIT_SERVERS = new Key<>(new Type>() {}, "BUKKIT_SERVERS"); public static final Key>>> ACTIVITY_DATA = CommonKeys.ACTIVITY_DATA; + public static final Key>> NETWORK_PLAYER_ONLINE_DATA = new Key<>(new Type>>() {}, "NETWORK_PLAYER_ONLINE_DATA"); + public static final Key> SERVER_REGISTER_DATA = new Key<>(new Type>() {}, "SERVER_REGISTER_DATA"); private NetworkKeys() { /* static variable class */ diff --git a/Plan/src/main/java/com/djrapitops/plan/data/store/keys/SessionKeys.java b/Plan/src/main/java/com/djrapitops/plan/data/store/keys/SessionKeys.java index 50344194c..bb0aae518 100644 --- a/Plan/src/main/java/com/djrapitops/plan/data/store/keys/SessionKeys.java +++ b/Plan/src/main/java/com/djrapitops/plan/data/store/keys/SessionKeys.java @@ -32,6 +32,7 @@ public class SessionKeys { public static final Key DEATH_COUNT = CommonKeys.DEATH_COUNT; public static final Key> PLAYER_DEATHS = CommonKeys.PLAYER_DEATHS; + @Deprecated public static final Key LONGEST_WORLD_PLAYED = new Key<>(String.class, "longest_world_played"); private SessionKeys() { diff --git a/Plan/src/main/java/com/djrapitops/plan/data/store/mutators/ActivityIndex.java b/Plan/src/main/java/com/djrapitops/plan/data/store/mutators/ActivityIndex.java index b909eab18..3554e3e8b 100644 --- a/Plan/src/main/java/com/djrapitops/plan/data/store/mutators/ActivityIndex.java +++ b/Plan/src/main/java/com/djrapitops/plan/data/store/mutators/ActivityIndex.java @@ -3,18 +3,27 @@ package com.djrapitops.plan.data.store.mutators; import com.djrapitops.plan.data.container.Session; import com.djrapitops.plan.data.store.containers.DataContainer; import com.djrapitops.plan.data.store.keys.PlayerKeys; -import com.djrapitops.plan.system.settings.Settings; -import com.djrapitops.plan.utilities.FormatUtils; +import com.djrapitops.plan.utilities.formatting.Formatter; import com.djrapitops.plugin.api.TimeAmount; import java.util.List; import java.util.Optional; +import java.util.concurrent.TimeUnit; public class ActivityIndex { private final double value; - public ActivityIndex(DataContainer container, long date) { + private final int playThreshold; + private final int loginThreshold; + + public ActivityIndex( + DataContainer container, long date, + int minuteThreshold, int loginThreshold + ) { + this.playThreshold = minuteThreshold; + this.loginThreshold = loginThreshold; + value = calculate(container, date); } @@ -22,22 +31,14 @@ public class ActivityIndex { return new String[]{"Very Active", "Active", "Regular", "Irregular", "Inactive"}; } - private long loadSetting(long value) { - return value <= 0 ? 1 : value; - } - - private int loadSetting(int value) { - return value <= 0 ? 1 : value; - } - private double calculate(DataContainer container, long date) { - long week = TimeAmount.WEEK.ms(); + long week = TimeAmount.WEEK.toMillis(1L); long weekAgo = date - week; long twoWeeksAgo = date - 2L * week; long threeWeeksAgo = date - 3L * week; - long activePlayThreshold = loadSetting(Settings.ACTIVE_PLAY_THRESHOLD.getNumber() * TimeAmount.MINUTE.ms()); - int activeLoginThreshold = loadSetting(Settings.ACTIVE_LOGIN_THRESHOLD.getNumber()); + long activePlayThreshold = TimeUnit.MINUTES.toMillis(playThreshold); + int activeLoginThreshold = loginThreshold; Optional> sessionsValue = container.getValue(PlayerKeys.SESSIONS); if (!sessionsValue.isPresent()) { @@ -109,8 +110,8 @@ public class ActivityIndex { return value; } - public String getFormattedValue() { - return FormatUtils.cutDecimals(value); + public String getFormattedValue(Formatter formatter) { + return formatter.apply(value); } public String getGroup() { diff --git a/Plan/src/main/java/com/djrapitops/plan/data/store/mutators/DateHoldersMutator.java b/Plan/src/main/java/com/djrapitops/plan/data/store/mutators/DateHoldersMutator.java index 640253aee..f182d0c43 100644 --- a/Plan/src/main/java/com/djrapitops/plan/data/store/mutators/DateHoldersMutator.java +++ b/Plan/src/main/java/com/djrapitops/plan/data/store/mutators/DateHoldersMutator.java @@ -1,12 +1,12 @@ package com.djrapitops.plan.data.store.mutators; import com.djrapitops.plan.data.store.objects.DateHolder; -import com.djrapitops.plugin.api.TimeAmount; import java.util.ArrayList; import java.util.List; import java.util.SortedMap; import java.util.TreeMap; +import java.util.concurrent.TimeUnit; public class DateHoldersMutator { @@ -17,7 +17,7 @@ public class DateHoldersMutator { } public SortedMap> groupByStartOfMinute() { - return groupByStartOfSections(TimeAmount.MINUTE.ms()); + return groupByStartOfSections(TimeUnit.MINUTES.toMillis(1L)); } private SortedMap> groupByStartOfSections(long sectionLength) { @@ -39,7 +39,7 @@ public class DateHoldersMutator { } public SortedMap> groupByStartOfDay() { - long twentyFourHours = 24L * TimeAmount.HOUR.ms(); + long twentyFourHours = TimeUnit.DAYS.toMillis(1L); SortedMap> map = groupByStartOfSections(twentyFourHours); // Empty map firstKey attempt causes NPE if not checked. diff --git a/Plan/src/main/java/com/djrapitops/plan/data/store/mutators/PlayersMutator.java b/Plan/src/main/java/com/djrapitops/plan/data/store/mutators/PlayersMutator.java index eb40bb448..cebbe56bd 100644 --- a/Plan/src/main/java/com/djrapitops/plan/data/store/mutators/PlayersMutator.java +++ b/Plan/src/main/java/com/djrapitops/plan/data/store/mutators/PlayersMutator.java @@ -70,8 +70,8 @@ public class PlayersMutator { ); } - public PlayersMutator filterActive(long date, double limit) { - return filterBy(player -> player.getActivityIndex(date).getValue() >= limit); + public PlayersMutator filterActive(long date, int minuteThreshold, int loginThreshold, double limit) { + return filterBy(player -> player.getActivityIndex(date, minuteThreshold, loginThreshold).getValue() >= limit); } public PlayersMutator filterPlayedOnServer(UUID serverUUID) { @@ -123,16 +123,16 @@ public class PlayersMutator { return pingPerCountry; } - public TreeMap>> toActivityDataMap(long date) { + public TreeMap>> toActivityDataMap(long date, int minuteThreshold, int loginThreshold) { TreeMap>> activityData = new TreeMap<>(); - for (long time = date; time >= date - TimeAmount.MONTH.ms() * 2L; time -= TimeAmount.WEEK.ms()) { + for (long time = date; time >= date - TimeAmount.MONTH.toMillis(2L); time -= TimeAmount.WEEK.toMillis(1L)) { Map> map = activityData.getOrDefault(time, new HashMap<>()); if (!players.isEmpty()) { for (PlayerContainer player : players) { if (player.getValue(PlayerKeys.REGISTERED).orElse(0L) > time) { continue; } - ActivityIndex activityIndex = player.getActivityIndex(time); + ActivityIndex activityIndex = player.getActivityIndex(time, minuteThreshold, loginThreshold); String activityGroup = activityIndex.getGroup(); Set uuids = map.getOrDefault(activityGroup, new HashSet<>()); @@ -175,9 +175,13 @@ public class PlayersMutator { * @return Mutator containing the players that are considered to be retained. * @throws IllegalStateException If all players are rejected due to dateLimit. */ - public PlayersMutator compareAndFindThoseLikelyToBeRetained(Iterable compareTo, - long dateLimit, - PlayersOnlineResolver onlineResolver) { + public PlayersMutator compareAndFindThoseLikelyToBeRetained( + Iterable compareTo, + long dateLimit, + PlayersOnlineResolver onlineResolver, + int activityMinuteThreshold, + int activityLoginThreshold + ) { Collection retainedAfterMonth = new ArrayList<>(); Collection notRetainedAfterMonth = new ArrayList<>(); @@ -189,8 +193,8 @@ public class PlayersMutator { continue; } - long monthAfterRegister = registered + TimeAmount.MONTH.ms(); - long half = registered + (TimeAmount.MONTH.ms() / 2L); + long monthAfterRegister = registered + TimeAmount.MONTH.toMillis(1L); + long half = registered + (TimeAmount.MONTH.toMillis(1L) / 2L); if (player.playedBetween(registered, half) && player.playedBetween(half, monthAfterRegister)) { retainedAfterMonth.add(player); } else { @@ -203,10 +207,10 @@ public class PlayersMutator { } List retained = retainedAfterMonth.stream() - .map(player -> new RetentionData(player, onlineResolver)) + .map(player -> new RetentionData(player, onlineResolver, activityMinuteThreshold, activityLoginThreshold)) .collect(Collectors.toList()); List notRetained = notRetainedAfterMonth.stream() - .map(player -> new RetentionData(player, onlineResolver)) + .map(player -> new RetentionData(player, onlineResolver, activityMinuteThreshold, activityLoginThreshold)) .collect(Collectors.toList()); RetentionData avgRetained = RetentionData.average(retained); @@ -214,7 +218,7 @@ public class PlayersMutator { List toBeRetained = new ArrayList<>(); for (PlayerContainer player : compareTo) { - RetentionData retentionData = new RetentionData(player, onlineResolver); + RetentionData retentionData = new RetentionData(player, onlineResolver, activityMinuteThreshold, activityLoginThreshold); if (retentionData.distance(avgRetained) < retentionData.distance(avgNotRetained)) { toBeRetained.add(player); } diff --git a/Plan/src/main/java/com/djrapitops/plan/data/store/mutators/RetentionData.java b/Plan/src/main/java/com/djrapitops/plan/data/store/mutators/RetentionData.java index 222df4371..148b43f04 100644 --- a/Plan/src/main/java/com/djrapitops/plan/data/store/mutators/RetentionData.java +++ b/Plan/src/main/java/com/djrapitops/plan/data/store/mutators/RetentionData.java @@ -6,11 +6,11 @@ package com.djrapitops.plan.data.store.mutators; import com.djrapitops.plan.data.store.containers.PlayerContainer; import com.djrapitops.plan.data.store.keys.PlayerKeys; -import com.djrapitops.plugin.api.TimeAmount; import com.google.common.base.Objects; import java.util.Collection; import java.util.Optional; +import java.util.concurrent.TimeUnit; /** * Utility class for player retention calculations. @@ -45,10 +45,20 @@ public class RetentionData { this.onlineOnJoin = onlineOnJoin; } - public RetentionData(PlayerContainer player, PlayersOnlineResolver onlineOnJoin) { + public RetentionData( + PlayerContainer player, + PlayersOnlineResolver onlineOnJoin, + int activityMinuteThreshold, + int activityLoginThreshold + ) { Optional registeredValue = player.getValue(PlayerKeys.REGISTERED); activityIndex = registeredValue - .map(registered -> new ActivityIndex(player, registered + TimeAmount.DAY.ms()).getValue()) + .map(registered -> new ActivityIndex( + player, + registered + TimeUnit.DAYS.toMillis(1L), + activityMinuteThreshold, + activityLoginThreshold + ).getValue()) .orElse(0.0); this.onlineOnJoin = registeredValue .map(registered -> onlineOnJoin.getOnlineOn(registered).orElse(-1)) diff --git a/Plan/src/main/java/com/djrapitops/plan/data/store/mutators/TPSMutator.java b/Plan/src/main/java/com/djrapitops/plan/data/store/mutators/TPSMutator.java index 8af6fa550..e7ce81f13 100644 --- a/Plan/src/main/java/com/djrapitops/plan/data/store/mutators/TPSMutator.java +++ b/Plan/src/main/java/com/djrapitops/plan/data/store/mutators/TPSMutator.java @@ -3,14 +3,13 @@ package com.djrapitops.plan.data.store.mutators; import com.djrapitops.plan.data.container.TPS; import com.djrapitops.plan.data.store.containers.DataContainer; import com.djrapitops.plan.data.store.keys.ServerKeys; -import com.djrapitops.plan.system.settings.Settings; import com.djrapitops.plan.utilities.comparators.TPSComparator; import com.djrapitops.plan.utilities.html.graphs.line.Point; -import com.djrapitops.plugin.api.TimeAmount; import java.util.ArrayList; import java.util.List; import java.util.OptionalDouble; +import java.util.concurrent.TimeUnit; import java.util.function.Predicate; import java.util.stream.Collectors; @@ -66,6 +65,7 @@ public class TPSMutator { public List cpuPoints() { return tpsData.stream() .map(tps -> new Point(tps.getDate(), tps.getCPUUsage())) + .filter(point -> point.getY() != -1) .collect(Collectors.toList()); } @@ -87,6 +87,13 @@ public class TPSMutator { .collect(Collectors.toList()); } + public List freeDiskPoints() { + return tpsData.stream() + .map(tps -> new Point(tps.getDate(), tps.getFreeDiskSpace())) + .filter(point -> point.getY() != -1) + .collect(Collectors.toList()); + } + public long serverDownTime() { long lastDate = -1; long downTime = 0; @@ -99,7 +106,7 @@ public class TPSMutator { } long diff = date - lastDate; - if (diff > TimeAmount.MINUTE.ms() * 3L) { + if (diff > TimeUnit.MINUTES.toMillis(3L)) { downTime += diff; } lastDate = date; @@ -134,13 +141,11 @@ public class TPSMutator { return idleTime; } - public double percentageTPSAboveLowThreshold() { + public double percentageTPSAboveThreshold(int threshold) { if (tpsData.isEmpty()) { return 1; } - int threshold = Settings.THEME_GRAPH_TPS_THRESHOLD_MED.getNumber(); - long count = 0; for (TPS tps : tpsData) { if (tps.getTicksPerSecond() >= threshold) { @@ -151,15 +156,13 @@ public class TPSMutator { return count * 1.0 / tpsData.size(); } - public int lowTpsSpikeCount() { - int mediumThreshold = Settings.THEME_GRAPH_TPS_THRESHOLD_MED.getNumber(); - + public int lowTpsSpikeCount(int threshold) { boolean wasLow = false; int spikeCount = 0; for (TPS tpsObj : tpsData) { double tps = tpsObj.getTicksPerSecond(); - if (tps < mediumThreshold) { + if (tps < threshold) { if (!wasLow) { spikeCount++; wasLow = true; diff --git a/Plan/src/main/java/com/djrapitops/plan/data/store/mutators/combiners/MultiBanCombiner.java b/Plan/src/main/java/com/djrapitops/plan/data/store/mutators/combiners/MultiBanCombiner.java deleted file mode 100644 index 39cc5417c..000000000 --- a/Plan/src/main/java/com/djrapitops/plan/data/store/mutators/combiners/MultiBanCombiner.java +++ /dev/null @@ -1,49 +0,0 @@ -package com.djrapitops.plan.data.store.mutators.combiners; - -import com.djrapitops.plan.data.store.containers.DataContainer; -import com.djrapitops.plan.data.store.containers.PerServerContainer; -import com.djrapitops.plan.data.store.containers.PlayerContainer; -import com.djrapitops.plan.data.store.keys.PerServerKeys; -import com.djrapitops.plan.data.store.keys.PlayerKeys; -import com.djrapitops.plan.data.store.keys.ServerKeys; -import com.djrapitops.plan.system.info.server.ServerInfo; - -import java.util.*; - -public class MultiBanCombiner { - - private final DataContainer container; - - /** - * Constructor. - * - * @param container DataContainer that supports {@link com.djrapitops.plan.data.store.keys.ServerKeys}.PLAYERS - */ - public MultiBanCombiner(DataContainer container) { - this.container = container; - } - - public void combine(Set banned) { - combine(Collections.singletonMap(ServerInfo.getServerUUID(), banned)); - } - - public void combine(Map> perServerBanned) { - List playerContainers = container.getValue(ServerKeys.PLAYERS).orElse(new ArrayList<>()); - - for (Map.Entry> entry : perServerBanned.entrySet()) { - UUID serverUUID = entry.getKey(); - Set banned = entry.getValue(); - for (PlayerContainer player : playerContainers) { - if (player.getValue(PlayerKeys.UUID).map(banned::contains).orElse(false)) { - PerServerContainer perServer = player.getValue(PlayerKeys.PER_SERVER) - .orElse(new PerServerContainer()); - DataContainer perServerContainer = perServer.getOrDefault(serverUUID, new DataContainer()); - - perServerContainer.putRawData(PerServerKeys.BANNED, true); - - perServer.put(serverUUID, perServerContainer); - } - } - } - } -} diff --git a/Plan/src/main/java/com/djrapitops/plan/data/store/mutators/formatting/Formatters.java b/Plan/src/main/java/com/djrapitops/plan/data/store/mutators/formatting/Formatters.java deleted file mode 100644 index b12e10668..000000000 --- a/Plan/src/main/java/com/djrapitops/plan/data/store/mutators/formatting/Formatters.java +++ /dev/null @@ -1,94 +0,0 @@ -package com.djrapitops.plan.data.store.mutators.formatting; - -import com.djrapitops.plan.data.store.objects.DateHolder; -import com.djrapitops.plan.utilities.FormatUtils; -import com.djrapitops.plugin.api.TimeAmount; -import com.djrapitops.plugin.utilities.Format; -import org.apache.commons.text.TextStringBuilder; - -import java.util.Arrays; -import java.util.Calendar; -import java.util.function.Function; - -/** - * Class that holds static methods for getting new instances of different {@link Formatter}s. - * - * @author Rsl1122 - */ -public class Formatters { - - private Formatters() { - /* Static method class */ - } - - public static Formatter year() { - return dateHolder -> { - long date = dateHolder.getDate(); - return date > 0 ? FormatUtils.formatTimeStampYear(date) : "-"; - }; - } - - public static Formatter yearLongValue() { - return date -> date > 0 ? FormatUtils.formatTimeStampYear(date) : "-"; - } - - public static Formatter day() { - return dateHolder -> { - long date = dateHolder.getDate(); - return date > 0 ? FormatUtils.formatTimeStampDay(date) : "-"; - }; - } - - public static Formatter second() { - return dateHolder -> { - long date = dateHolder.getDate(); - return date > 0 ? FormatUtils.formatTimeStampSecond(date) : "-"; - }; - } - - public static Formatter clock() { - return dateHolder -> { - long date = dateHolder.getDate(); - return date > 0 ? FormatUtils.formatTimeStampClock(date) : "-"; - }; - } - - public static Formatter iso8601NoClock() { - return dateHolder -> FormatUtils.formatTimeStampISO8601NoClock(dateHolder.getDate()); - } - - public static Formatter timeAmount() { - return new TimeAmountFormatter(); - } - - public static Function dayOfYear() { - return date -> { - Calendar day = Calendar.getInstance(); - day.setTimeInMillis(date); - return day.get(Calendar.DAY_OF_YEAR); - }; - } - - public static Formatter percentage() { - return value -> value >= 0 ? FormatUtils.cutDecimals(value * 100.0) + "%" : "-"; - } - - public static Formatter benchmark() { - return ns -> { - if (ns > TimeAmount.MILLISECOND.ns() * 5L) { - return (ns / TimeAmount.MILLISECOND.ns()) + "ms"; - } else { - return 1.0 * ns / TimeAmount.MILLISECOND.ns() + "ms"; - } - }; - } - - public static Formatter itemName() { - return name -> { - String[] parts = name.split("_"); - TextStringBuilder builder = new TextStringBuilder(); - builder.appendWithSeparators(Arrays.stream(parts).map(part -> new Format(part).capitalize()).iterator(), " "); - return builder.toString(); - }; - } -} \ No newline at end of file diff --git a/Plan/src/main/java/com/djrapitops/plan/data/store/mutators/health/AbstractHealthInfo.java b/Plan/src/main/java/com/djrapitops/plan/data/store/mutators/health/AbstractHealthInfo.java index f519456ad..6f733018f 100644 --- a/Plan/src/main/java/com/djrapitops/plan/data/store/mutators/health/AbstractHealthInfo.java +++ b/Plan/src/main/java/com/djrapitops/plan/data/store/mutators/health/AbstractHealthInfo.java @@ -3,12 +3,13 @@ package com.djrapitops.plan.data.store.mutators.health; import com.djrapitops.plan.data.store.containers.PlayerContainer; import com.djrapitops.plan.data.store.mutators.PlayersMutator; import com.djrapitops.plan.data.store.mutators.SessionsMutator; -import com.djrapitops.plan.data.store.mutators.formatting.Formatters; -import com.djrapitops.plan.utilities.FormatUtils; +import com.djrapitops.plan.system.locale.Locale; +import com.djrapitops.plan.system.locale.lang.HealthInfoLang; +import com.djrapitops.plan.utilities.formatting.Formatter; import com.djrapitops.plan.utilities.html.icon.Icons; -import com.djrapitops.plugin.api.TimeAmount; import java.util.*; +import java.util.concurrent.TimeUnit; public abstract class AbstractHealthInfo { @@ -20,9 +21,29 @@ public abstract class AbstractHealthInfo { protected double serverHealth; - public AbstractHealthInfo(long now, long monthAgo) { + protected final Locale locale; + protected final int activeMinuteThreshold; + protected final int activeLoginThreshold; + protected final Formatter timeAmountFormatter; + protected final Formatter decimalFormatter; + protected final Formatter percentageFormatter; + + public AbstractHealthInfo( + long now, long monthAgo, + Locale locale, int activeMinuteThreshold, + int activeLoginThreshold, + Formatter timeAmountFormatter, + Formatter decimalFormatter, + Formatter percentageFormatter + ) { this.now = now; this.monthAgo = monthAgo; + this.locale = locale; + this.activeMinuteThreshold = activeMinuteThreshold; + this.activeLoginThreshold = activeLoginThreshold; + this.timeAmountFormatter = timeAmountFormatter; + this.decimalFormatter = decimalFormatter; + this.percentageFormatter = percentageFormatter; serverHealth = 100.0; this.notes = new ArrayList<>(); @@ -63,43 +84,47 @@ public abstract class AbstractHealthInfo { regularRemainCompareSet.removeAll(veryActiveNow); int notRegularAnymore = regularRemainCompareSet.size(); int remain = activeFWAGNum - notRegularAnymore; - double percRemain = activeFWAGNum != 0 ? remain * 100.0 / activeFWAGNum : 100.0; + double percRemain = activeFWAGNum != 0 ? remain * 1.0 / activeFWAGNum : 1.0; int newActive = getNewActive(veryActiveNow, activeNow, regularNow, veryActiveFWAG, activeFWAG, regularFWAG); int change = newActive - notRegularAnymore; - String remainNote = ""; + StringBuilder remainNote = new StringBuilder(); if (activeFWAGNum != 0) { - remainNote = "
     "; - if (percRemain > 50) { - remainNote += Icons.GREEN_THUMB; - } else if (percRemain > 20) { - remainNote += Icons.YELLOW_FLAG; + remainNote.append(subNote); + if (percRemain > 0.5) { + remainNote.append(Icons.GREEN_THUMB); + } else if (percRemain > 0.2) { + remainNote.append(Icons.YELLOW_FLAG); } else { - remainNote += Icons.RED_WARN; + remainNote.append(Icons.RED_WARN); serverHealth -= 2.5; } - remainNote += " " + FormatUtils.cutDecimals(percRemain) + "% of regular players have remained active (" - + remain + "/" + activeFWAGNum + ")"; + remainNote.append(locale.getString(HealthInfoLang.REGULAR_ACTIVITY_REMAIN, + percentageFormatter.apply(percRemain), + remain, activeFWAGNum + )); } + + String sentenceStart = locale.getString(HealthInfoLang.REGULAR_CHANGE); if (change > 0) { - addNote(Icons.GREEN_THUMB + " Number of regular players has increased (+" + change + ")" + remainNote); + addNote(Icons.GREEN_THUMB + sentenceStart + locale.getString(HealthInfoLang.REGULAR_CHANGE_INCREASE, change) + remainNote); } else if (change == 0) { - addNote(Icons.GREEN_THUMB + " Number of regular players has stayed the same (+" + change + ")" + remainNote); + addNote(Icons.GREEN_THUMB + sentenceStart + locale.getString(HealthInfoLang.REGULAR_CHANGE_ZERO, change) + remainNote); } else if (change > -20) { - addNote(Icons.YELLOW_FLAG + " Number of regular players has decreased (" + change + ")" + remainNote); + addNote(Icons.YELLOW_FLAG + sentenceStart + locale.getString(HealthInfoLang.REGULAR_CHANGE_DECREASE, change) + remainNote); serverHealth -= 5; } else { - addNote(Icons.RED_WARN + " Number of regular players has decreased (" + change + ")" + remainNote); + addNote(Icons.RED_WARN + sentenceStart + locale.getString(HealthInfoLang.REGULAR_CHANGE_DECREASE, change) + remainNote); serverHealth -= 10; } } protected void activePlayerPlaytimeChange(PlayersMutator playersMutator) { - PlayersMutator currentlyActive = playersMutator.filterActive(now, 1.75); - long twoWeeksAgo = (now - (now - monthAgo)) / 2L; + PlayersMutator currentlyActive = playersMutator.filterActive(now, activeMinuteThreshold, activeLoginThreshold, 1.75); + long twoWeeksAgo = now - ((now - monthAgo) / 2L); long totalFourToTwoWeeks = 0; long totalLastTwoWeeks = 0; @@ -113,21 +138,18 @@ public abstract class AbstractHealthInfo { if (activeCount != 0) { long avgFourToTwoWeeks = totalFourToTwoWeeks / (long) activeCount; long avgLastTwoWeeks = totalLastTwoWeeks / (long) activeCount; - String avgLastTwoWeeksString = Formatters.timeAmount().apply(avgLastTwoWeeks); - String avgFourToTwoWeeksString = Formatters.timeAmount().apply(avgFourToTwoWeeks); + String avgLastTwoWeeksString = timeAmountFormatter.apply(avgLastTwoWeeks); + String avgFourToTwoWeeksString = timeAmountFormatter.apply(avgFourToTwoWeeks); if (avgFourToTwoWeeks >= avgLastTwoWeeks) { - addNote(Icons.GREEN_THUMB + " Active players seem to have things to do (Played " - + avgLastTwoWeeksString + " vs " + avgFourToTwoWeeksString - + ", last two weeks vs weeks 2-4)"); - } else if (avgFourToTwoWeeks - avgLastTwoWeeks > TimeAmount.HOUR.ms() * 2L) { - addNote(Icons.RED_WARN + " Active players might be running out of things to do (Played " - + avgLastTwoWeeksString + " vs " + avgFourToTwoWeeksString - + ", last two weeks vs weeks 2-4)"); + addNote(Icons.GREEN_THUMB + locale.getString(HealthInfoLang.ACTIVE_PLAY_COMPARISON_INCREASE, + avgLastTwoWeeksString, avgFourToTwoWeeksString)); + } else if (avgFourToTwoWeeks - avgLastTwoWeeks > TimeUnit.HOURS.toMillis(2L)) { + addNote(Icons.RED_WARN + locale.getString(HealthInfoLang.ACTIVE_PLAY_COMPARISON_DECREASE, + avgLastTwoWeeksString, avgFourToTwoWeeksString)); serverHealth -= 5; } else { - addNote(Icons.YELLOW_FLAG + " Active players might be running out of things to do (Played " - + avgLastTwoWeeksString + " vs " + avgFourToTwoWeeksString - + ", last two weeks vs weeks 2-4)"); + addNote(Icons.YELLOW_FLAG + locale.getString(HealthInfoLang.ACTIVE_PLAY_COMPARISON_DECREASE, + avgLastTwoWeeksString, avgFourToTwoWeeksString)); } } } diff --git a/Plan/src/main/java/com/djrapitops/plan/data/store/mutators/health/HealthInformation.java b/Plan/src/main/java/com/djrapitops/plan/data/store/mutators/health/HealthInformation.java index 7de0a8b2f..b5e7078cf 100644 --- a/Plan/src/main/java/com/djrapitops/plan/data/store/mutators/health/HealthInformation.java +++ b/Plan/src/main/java/com/djrapitops/plan/data/store/mutators/health/HealthInformation.java @@ -10,15 +10,15 @@ import com.djrapitops.plan.data.store.keys.AnalysisKeys; import com.djrapitops.plan.data.store.mutators.PlayersMutator; import com.djrapitops.plan.data.store.mutators.PlayersOnlineResolver; import com.djrapitops.plan.data.store.mutators.TPSMutator; -import com.djrapitops.plan.data.store.mutators.formatting.Formatter; -import com.djrapitops.plan.data.store.mutators.formatting.Formatters; -import com.djrapitops.plan.system.settings.Settings; -import com.djrapitops.plan.utilities.FormatUtils; +import com.djrapitops.plan.system.locale.Locale; +import com.djrapitops.plan.system.locale.lang.HealthInfoLang; +import com.djrapitops.plan.utilities.formatting.Formatter; import com.djrapitops.plan.utilities.html.icon.Icons; import com.djrapitops.plugin.api.TimeAmount; import java.util.ArrayList; import java.util.Optional; +import java.util.concurrent.TimeUnit; /** * Server Health analysis mutator. @@ -29,12 +29,27 @@ public class HealthInformation extends AbstractHealthInfo { private final AnalysisContainer analysisContainer; - public HealthInformation(AnalysisContainer analysisContainer) { + private final int lowTPSThreshold; + + public HealthInformation( + AnalysisContainer analysisContainer, + Locale locale, + int lowTPSThreshold, + int activeMinuteThreshold, + int activeLoginThreshold, + Formatter timeAmountFormatter, + Formatter decimalFormatter, + Formatter percentageFormatter + ) { super( analysisContainer.getUnsafe(AnalysisKeys.ANALYSIS_TIME), - analysisContainer.getUnsafe(AnalysisKeys.ANALYSIS_TIME_MONTH_AGO) + analysisContainer.getUnsafe(AnalysisKeys.ANALYSIS_TIME_MONTH_AGO), + locale, + activeMinuteThreshold, activeLoginThreshold, + timeAmountFormatter, decimalFormatter, percentageFormatter ); this.analysisContainer = analysisContainer; + this.lowTPSThreshold = lowTPSThreshold; calculate(); } @@ -66,11 +81,11 @@ public class HealthInformation extends AbstractHealthInfo { .mapToInt(Optional::get) .average().orElse(0); if (avgOnlineOnRegister >= 1) { - addNote(Icons.GREEN_THUMB + " New Players have players to play with when they join (" - + FormatUtils.cutDecimals(avgOnlineOnRegister) + " on average)"); + addNote(Icons.GREEN_THUMB + locale.getString(HealthInfoLang.NEW_PLAYER_JOIN_PLAYERS_GOOD, + decimalFormatter.apply(avgOnlineOnRegister))); } else { - addNote(Icons.YELLOW_FLAG + " New Players may not have players to play with when they join (" - + FormatUtils.cutDecimals(avgOnlineOnRegister) + " on average)"); + addNote(Icons.YELLOW_FLAG + locale.getString(HealthInfoLang.NEW_PLAYER_JOIN_PLAYERS_BAD, + decimalFormatter.apply(avgOnlineOnRegister))); serverHealth -= 5; } @@ -79,12 +94,12 @@ public class HealthInformation extends AbstractHealthInfo { if (playersNewMonth != 0) { double retainPercentage = playersRetainedMonth * 1.0 / playersNewMonth; + String stickinessSentence = locale.getString(HealthInfoLang.NEW_PLAYER_STICKINESS, + percentageFormatter.apply(retainPercentage), playersRetainedMonth, playersNewMonth); if (retainPercentage >= 0.25) { - addNote(Icons.GREEN_THUMB + " " + Formatters.percentage().apply(retainPercentage) - + " of new players have stuck around (" + playersRetainedMonth + "/" + playersNewMonth + ")"); + addNote(Icons.GREEN_THUMB + stickinessSentence); } else { - addNote(Icons.YELLOW_FLAG + " " + Formatters.percentage().apply(retainPercentage) - + " of new players have stuck around (" + playersRetainedMonth + "/" + playersNewMonth + ")"); + addNote(Icons.YELLOW_FLAG + stickinessSentence); } } } @@ -93,48 +108,46 @@ public class HealthInformation extends AbstractHealthInfo { Key tpsMonth = new Key<>(TPSMutator.class, "TPS_MONTH"); TPSMutator tpsMutator = analysisContainer.getUnsafe(tpsMonth); long serverDownTime = tpsMutator.serverDownTime(); - double aboveThreshold = tpsMutator.percentageTPSAboveLowThreshold(); + + double aboveThreshold = tpsMutator.percentageTPSAboveThreshold(lowTPSThreshold); long tpsSpikeMonth = analysisContainer.getValue(AnalysisKeys.TPS_SPIKE_MONTH).orElse(0); - String avgLowThresholdString = "
     "; + StringBuilder avgLowThresholdString = new StringBuilder(subNote); if (aboveThreshold >= 0.96) { - avgLowThresholdString += Icons.GREEN_THUMB; + avgLowThresholdString.append(Icons.GREEN_THUMB); } else if (aboveThreshold >= 0.9) { - avgLowThresholdString += Icons.YELLOW_FLAG; + avgLowThresholdString.append(Icons.YELLOW_FLAG); serverHealth *= 0.9; } else { - avgLowThresholdString += Icons.RED_WARN; + avgLowThresholdString.append(Icons.RED_WARN); serverHealth *= 0.6; } - avgLowThresholdString += " Average TPS was above Low Threshold " - + FormatUtils.cutDecimals(aboveThreshold * 100.0) + "% of the time"; + avgLowThresholdString.append(locale.getString(HealthInfoLang.TPS_ABOVE_LOW_THERSHOLD, percentageFormatter.apply(aboveThreshold))); - int threshold = Settings.THEME_GRAPH_TPS_THRESHOLD_MED.getNumber(); + String tpsDipSentence = locale.getString(HealthInfoLang.TPS_LOW_DIPS, lowTPSThreshold, tpsSpikeMonth); if (tpsSpikeMonth <= 5) { - addNote(Icons.GREEN_THUMB + " Average TPS dropped below Low Threshold (" + threshold + ")" + - " " + tpsSpikeMonth + " times" + - avgLowThresholdString); + addNote(Icons.GREEN_THUMB + tpsDipSentence + avgLowThresholdString); } else if (tpsSpikeMonth <= 25) { - addNote(Icons.YELLOW_FLAG + " Average TPS dropped below Low Threshold (" + threshold + ")" + - " " + tpsSpikeMonth + " times" + - avgLowThresholdString); + addNote(Icons.YELLOW_FLAG + tpsDipSentence + avgLowThresholdString); serverHealth *= 0.95; } else { - addNote(Icons.RED_WARN + " Average TPS dropped below Low Threshold (" + threshold + ")" + - " " + tpsSpikeMonth + " times" + - avgLowThresholdString); + addNote(Icons.RED_WARN + tpsDipSentence + avgLowThresholdString); serverHealth *= 0.8; } - Formatter formatter = Formatters.timeAmount(); - if (serverDownTime <= TimeAmount.DAY.ms()) { - addNote(Icons.GREEN_THUMB + " Total Server downtime (No Data) was " + formatter.apply(serverDownTime)); - } else if (serverDownTime <= TimeAmount.WEEK.ms()) { - addNote(Icons.YELLOW_FLAG + " Total Server downtime (No Data) was " + formatter.apply(serverDownTime)); - serverHealth *= (TimeAmount.WEEK.ms() - serverDownTime) * 1.0 / TimeAmount.WEEK.ms(); + String downtimeSentence = locale.getString(HealthInfoLang.DOWNTIME, timeAmountFormatter.apply(serverDownTime)); + if (serverDownTime <= TimeUnit.DAYS.toMillis(1L)) { + addNote(Icons.GREEN_THUMB + downtimeSentence); } else { - addNote(Icons.RED_WARN + " Total Server downtime (No Data) was " + formatter.apply(serverDownTime)); - serverHealth *= (TimeAmount.MONTH.ms() - serverDownTime) * 1.0 / TimeAmount.MONTH.ms(); + long weekMs = TimeAmount.WEEK.toMillis(1L); + if (serverDownTime <= weekMs) { + addNote(Icons.YELLOW_FLAG + downtimeSentence); + serverHealth *= (weekMs - serverDownTime) * 1.0 / weekMs; + } else { + addNote(Icons.RED_WARN + downtimeSentence); + long monthMs = TimeAmount.MONTH.toMillis(1L); + serverHealth *= (monthMs - serverDownTime) * 1.0 / monthMs; + } } } diff --git a/Plan/src/main/java/com/djrapitops/plan/data/store/mutators/health/NetworkHealthInformation.java b/Plan/src/main/java/com/djrapitops/plan/data/store/mutators/health/NetworkHealthInformation.java index 64bbffc91..3bc3242b8 100644 --- a/Plan/src/main/java/com/djrapitops/plan/data/store/mutators/health/NetworkHealthInformation.java +++ b/Plan/src/main/java/com/djrapitops/plan/data/store/mutators/health/NetworkHealthInformation.java @@ -8,7 +8,9 @@ import com.djrapitops.plan.data.store.keys.NetworkKeys; import com.djrapitops.plan.data.store.mutators.PlayersMutator; import com.djrapitops.plan.data.store.mutators.SessionsMutator; import com.djrapitops.plan.system.info.server.Server; -import com.djrapitops.plan.utilities.FormatUtils; +import com.djrapitops.plan.system.locale.Locale; +import com.djrapitops.plan.system.locale.lang.HealthInfoLang; +import com.djrapitops.plan.utilities.formatting.Formatter; import com.djrapitops.plan.utilities.html.icon.Icon; import com.djrapitops.plan.utilities.html.icon.Icons; @@ -18,10 +20,21 @@ public class NetworkHealthInformation extends AbstractHealthInfo { private final NetworkContainer container; - public NetworkHealthInformation(NetworkContainer container) { + public NetworkHealthInformation( + NetworkContainer container, + Locale locale, + int activeMinuteThreshold, + int activeLoginThreshold, + Formatter timeAmountFormatter, + Formatter decimalFormatter, + Formatter percentageFormatter + ) { super( container.getUnsafe(NetworkKeys.REFRESH_TIME), - container.getUnsafe(NetworkKeys.REFRESH_TIME_MONTH_AGO) + container.getUnsafe(NetworkKeys.REFRESH_TIME_MONTH_AGO), + locale, + activeMinuteThreshold, activeLoginThreshold, + timeAmountFormatter, decimalFormatter, percentageFormatter ); this.container = container; calculate(); @@ -40,12 +53,12 @@ public class NetworkHealthInformation extends AbstractHealthInfo { .orElse(Collections.emptyList()); if (servers.isEmpty()) { - addNote(Icons.HELP_RING + " No Bukkit/Sponge servers to gather session data - These measures are inaccurate."); + addNote(Icons.HELP_RING + locale.getString(HealthInfoLang.NO_SERVERS_INACCURACY)); return; } int serverCount = servers.size(); if (serverCount == 1) { - addNote(Icons.HELP_RING + " Single Bukkit/Sponge server to gather session data."); + addNote(Icons.HELP_RING + locale.getString(HealthInfoLang.SINGLE_SERVER_INACCURACY)); return; } @@ -60,7 +73,7 @@ public class NetworkHealthInformation extends AbstractHealthInfo { private void uniquePlayersNote(int serverCount, Key serverKey, List perServerContainers) { Icon icon; - String uniquePlayersNote = " players visit on servers per day/server on average."; + String uniquePlayersNote = locale.getString(HealthInfoLang.PLAYER_VISIT_PER_SERVER); double average = perServerContainers.stream() .mapToInt(c -> c.getUnsafe(AnalysisKeys.AVG_PLAYERS_MONTH)) .average().orElse(0.0); @@ -82,12 +95,12 @@ public class NetworkHealthInformation extends AbstractHealthInfo { return subNote + (playersPerMonth >= average && playersPerMonth > 0 ? Icons.GREEN_PLUS : Icons.RED_MINUS) + " " + server.getName() + ": " + playersPerMonth; }).forEach(subNotes::append); - addNote(icon + " " + FormatUtils.cutDecimals(average) + uniquePlayersNote + subNotes.toString()); + addNote(icon + " " + decimalFormatter.apply(average) + uniquePlayersNote + subNotes.toString()); } private void newPlayersNote(int serverCount, Key serverKey, List perServerContainers) { Icon icon; - String newPlayersNote = " players register on servers per day/server on average."; + String newPlayersNote = locale.getString(HealthInfoLang.PLAYER_REGISTER_PER_SERVER); double average = perServerContainers.stream() .mapToInt(c -> c.getUnsafe(AnalysisKeys.AVG_PLAYERS_NEW_MONTH)) .average().orElse(0.0); @@ -109,7 +122,7 @@ public class NetworkHealthInformation extends AbstractHealthInfo { return subNote + (playersPerMonth >= average && playersPerMonth > 0 ? Icons.GREEN_PLUS : Icons.RED_MINUS) + " " + server.getName() + ": " + playersPerMonth; }).forEach(subNotes::append); - addNote(icon + " " + FormatUtils.cutDecimals(average) + newPlayersNote + subNotes.toString()); + addNote(icon + " " + decimalFormatter.apply(average) + newPlayersNote + subNotes.toString()); } private List getPerServerContainers(PlayersMutator playersMutator, Collection servers, Key serverKey) { @@ -139,7 +152,7 @@ public class NetworkHealthInformation extends AbstractHealthInfo { private void playersNote(Key serverKey, List perServerContainers) { Icon icon = Icons.HELP_RING; - String uniquePlayersNote = "${playersMonth} players played on the network:"; + String uniquePlayersNote = "${playersMonth}" + locale.getString(HealthInfoLang.PLAYER_PLAY_ON_NETWORK); StringBuilder subNotes = new StringBuilder(); perServerContainers.stream() .sorted(Comparator.comparingInt(c -> 0 - c.getUnsafe(AnalysisKeys.PLAYERS_MONTH))) diff --git a/Plan/src/main/java/com/djrapitops/plan/data/time/WorldTimes.java b/Plan/src/main/java/com/djrapitops/plan/data/time/WorldTimes.java index 24ec27938..01c43746e 100644 --- a/Plan/src/main/java/com/djrapitops/plan/data/time/WorldTimes.java +++ b/Plan/src/main/java/com/djrapitops/plan/data/time/WorldTimes.java @@ -1,11 +1,8 @@ package com.djrapitops.plan.data.time; -import com.djrapitops.plan.system.settings.WorldAliasSettings; - import java.util.HashMap; import java.util.Map; import java.util.Objects; -import java.util.stream.Collectors; /** * Class that tracks the time spent in each World based on GMTimes. @@ -169,33 +166,4 @@ public class WorldTimes { } } - public Map getPlaytimePerAlias() { - if (times.isEmpty()) { - return new HashMap<>(); - } - - Map playtimePerWorld = times.entrySet().stream() // WorldTimes Map - .collect(Collectors.toMap( - Map.Entry::getKey, - entry -> entry.getValue().getTotal() // GMTimes.getTotal - )); - - Map aliases = WorldAliasSettings.getAliases(); - - Map playtimePerAlias = new HashMap<>(); - for (Map.Entry entry : playtimePerWorld.entrySet()) { - String worldName = entry.getKey(); - long playtime = entry.getValue(); - - if (!aliases.containsKey(worldName)) { - aliases.put(worldName, worldName); - WorldAliasSettings.addWorld(worldName); - } - - String alias = aliases.get(worldName); - - playtimePerAlias.put(alias, playtimePerAlias.getOrDefault(alias, 0L) + playtime); - } - return playtimePerAlias; - } } diff --git a/Plan/src/main/java/com/djrapitops/plan/modules/APFModule.java b/Plan/src/main/java/com/djrapitops/plan/modules/APFModule.java new file mode 100644 index 000000000..ed8b76536 --- /dev/null +++ b/Plan/src/main/java/com/djrapitops/plan/modules/APFModule.java @@ -0,0 +1,73 @@ +package com.djrapitops.plan.modules; + +import com.djrapitops.plan.PlanPlugin; +import com.djrapitops.plugin.IPlugin; +import com.djrapitops.plugin.benchmarking.Timings; +import com.djrapitops.plugin.command.ColorScheme; +import com.djrapitops.plugin.logging.console.PluginLogger; +import com.djrapitops.plugin.logging.debug.DebugLogger; +import com.djrapitops.plugin.logging.error.ErrorHandler; +import com.djrapitops.plugin.task.RunnableFactory; +import dagger.Module; +import dagger.Provides; + +import javax.inject.Named; +import javax.inject.Singleton; + +/** + * Dagger module for defining Abstract Plugin Framework utilities. + * + * @author Rsl1122 + */ +@Module +public class APFModule { + @Provides + @Singleton + IPlugin provideIPlugin(PlanPlugin plugin) { + return plugin; + } + + @Provides + @Named("currentVersion") + @Singleton + String provideCurrentVersion(IPlugin plugin) { + return plugin.getVersion(); + } + + @Provides + @Singleton + ColorScheme provideColorScheme(PlanPlugin plugin) { + return plugin.getColorScheme(); + } + + @Provides + @Singleton + DebugLogger provideDebugLogger(IPlugin plugin) { + return plugin.getDebugLogger(); + } + + @Provides + @Singleton + PluginLogger providePluginLogger(IPlugin plugin) { + return plugin.getPluginLogger(); + } + + @Provides + @Singleton + ErrorHandler provideErrorHandler(IPlugin plugin) { + return plugin.getErrorHandler(); + } + + @Provides + @Singleton + Timings provideTimings(IPlugin plugin) { + return plugin.getTimings(); + } + + @Provides + @Singleton + RunnableFactory provideRunnableFactory(IPlugin plugin) { + return plugin.getRunnableFactory(); + } + +} \ No newline at end of file diff --git a/Plan/src/main/java/com/djrapitops/plan/modules/FilesModule.java b/Plan/src/main/java/com/djrapitops/plan/modules/FilesModule.java new file mode 100644 index 000000000..4a36c429e --- /dev/null +++ b/Plan/src/main/java/com/djrapitops/plan/modules/FilesModule.java @@ -0,0 +1,26 @@ +package com.djrapitops.plan.modules; + +import com.djrapitops.plan.system.file.PlanFiles; +import dagger.Module; +import dagger.Provides; + +import javax.inject.Named; +import javax.inject.Singleton; +import java.io.File; + +/** + * Dagger Module for the Plan files. + * + * @author Rsl1122 + */ +@Module +public class FilesModule { + + @Provides + @Named("configFile") + @Singleton + File provideConfigFile(PlanFiles files) { + return files.getConfigFile(); + } + +} \ No newline at end of file diff --git a/Plan/src/main/java/com/djrapitops/plan/modules/SuperClassBindingModule.java b/Plan/src/main/java/com/djrapitops/plan/modules/SuperClassBindingModule.java new file mode 100644 index 000000000..8b54030a0 --- /dev/null +++ b/Plan/src/main/java/com/djrapitops/plan/modules/SuperClassBindingModule.java @@ -0,0 +1,24 @@ +package com.djrapitops.plan.modules; + +import com.djrapitops.plan.system.cache.DataCache; +import com.djrapitops.plan.system.cache.SessionCache; +import dagger.Module; +import dagger.Provides; + +import javax.inject.Singleton; + +/** + * Module for binding instances of implementations to super classes. + * + * @author Rsl1122 + */ +@Module +public class SuperClassBindingModule { + + @Provides + @Singleton + SessionCache provideSessionCache(DataCache cache) { + return cache; + } + +} \ No newline at end of file diff --git a/Plan/src/main/java/com/djrapitops/plan/modules/SystemObjectBindingModule.java b/Plan/src/main/java/com/djrapitops/plan/modules/SystemObjectBindingModule.java new file mode 100644 index 000000000..867183877 --- /dev/null +++ b/Plan/src/main/java/com/djrapitops/plan/modules/SystemObjectBindingModule.java @@ -0,0 +1,32 @@ +package com.djrapitops.plan.modules; + +import com.djrapitops.plan.data.plugin.PluginsConfigSection; +import com.djrapitops.plan.system.locale.Locale; +import com.djrapitops.plan.system.locale.LocaleSystem; +import com.djrapitops.plan.system.settings.config.PlanConfig; +import dagger.Module; +import dagger.Provides; + +import javax.inject.Singleton; + +/** + * Module for binding object instances found inside other systems. + * + * @author Rsl1122 + */ +@Module +public class SystemObjectBindingModule { + + @Provides + @Singleton + Locale provideLocale(LocaleSystem localeSystem) { + return localeSystem.getLocale(); + } + + @Provides + @Singleton + PluginsConfigSection providePluginsConfigSection(PlanConfig config) { + return config.getPluginsConfigSection(); + } + +} \ No newline at end of file diff --git a/Plan/src/main/java/com/djrapitops/plan/modules/plugin/BukkitPlanModule.java b/Plan/src/main/java/com/djrapitops/plan/modules/plugin/BukkitPlanModule.java new file mode 100644 index 000000000..be71d9b1c --- /dev/null +++ b/Plan/src/main/java/com/djrapitops/plan/modules/plugin/BukkitPlanModule.java @@ -0,0 +1,33 @@ +package com.djrapitops.plan.modules.plugin; + +import com.djrapitops.plan.Plan; +import com.djrapitops.plan.PlanPlugin; +import com.djrapitops.plan.command.PlanCommand; +import com.djrapitops.plugin.command.CommandNode; +import dagger.Module; +import dagger.Provides; + +import javax.inject.Named; +import javax.inject.Singleton; + +/** + * Dagger module for binding Plan instance. + * + * @author Rsl1122 + */ +@Module +public class BukkitPlanModule { + + @Provides + @Singleton + PlanPlugin providePlanPlugin(Plan plugin) { + return plugin; + } + + @Provides + @Singleton + @Named("mainCommand") + CommandNode provideMainCommand(PlanCommand command) { + return command; + } +} \ No newline at end of file diff --git a/Plan/src/main/java/com/djrapitops/plan/modules/plugin/BungeePlanModule.java b/Plan/src/main/java/com/djrapitops/plan/modules/plugin/BungeePlanModule.java new file mode 100644 index 000000000..ad4b8beef --- /dev/null +++ b/Plan/src/main/java/com/djrapitops/plan/modules/plugin/BungeePlanModule.java @@ -0,0 +1,33 @@ +package com.djrapitops.plan.modules.plugin; + +import com.djrapitops.plan.PlanBungee; +import com.djrapitops.plan.PlanPlugin; +import com.djrapitops.plan.command.PlanBungeeCommand; +import com.djrapitops.plugin.command.CommandNode; +import dagger.Module; +import dagger.Provides; + +import javax.inject.Named; +import javax.inject.Singleton; + +/** + * Dagger module for binding PlanBungee instance. + * + * @author Rsl1122 + */ +@Module +public class BungeePlanModule { + + @Provides + @Singleton + PlanPlugin providePlanPlugin(PlanBungee plugin) { + return plugin; + } + + @Provides + @Singleton + @Named("mainCommand") + CommandNode provideMainCommand(PlanBungeeCommand command) { + return command; + } +} \ No newline at end of file diff --git a/Plan/src/main/java/com/djrapitops/plan/modules/plugin/SpongePlanModule.java b/Plan/src/main/java/com/djrapitops/plan/modules/plugin/SpongePlanModule.java new file mode 100644 index 000000000..337ae8a13 --- /dev/null +++ b/Plan/src/main/java/com/djrapitops/plan/modules/plugin/SpongePlanModule.java @@ -0,0 +1,33 @@ +package com.djrapitops.plan.modules.plugin; + +import com.djrapitops.plan.PlanPlugin; +import com.djrapitops.plan.PlanSponge; +import com.djrapitops.plan.command.PlanCommand; +import com.djrapitops.plugin.command.CommandNode; +import dagger.Module; +import dagger.Provides; + +import javax.inject.Named; +import javax.inject.Singleton; + +/** + * Dagger module for binding PlanSponge instance. + * + * @author Rsl1122 + */ +@Module +public class SpongePlanModule { + + @Provides + @Singleton + PlanPlugin providePlanPlugin(PlanSponge plugin) { + return plugin; + } + + @Provides + @Singleton + @Named("mainCommand") + CommandNode provideMainCommand(PlanCommand command) { + return command; + } +} \ No newline at end of file diff --git a/Plan/src/main/java/com/djrapitops/plan/modules/plugin/VelocityPlanModule.java b/Plan/src/main/java/com/djrapitops/plan/modules/plugin/VelocityPlanModule.java new file mode 100644 index 000000000..3107fb7bd --- /dev/null +++ b/Plan/src/main/java/com/djrapitops/plan/modules/plugin/VelocityPlanModule.java @@ -0,0 +1,33 @@ +package com.djrapitops.plan.modules.plugin; + +import com.djrapitops.plan.PlanPlugin; +import com.djrapitops.plan.PlanVelocity; +import com.djrapitops.plan.command.PlanVelocityCommand; +import com.djrapitops.plugin.command.CommandNode; +import dagger.Module; +import dagger.Provides; + +import javax.inject.Named; +import javax.inject.Singleton; + +/** + * Dagger module for binding PlanVelocity instance. + * + * @author Rsl1122 + */ +@Module +public class VelocityPlanModule { + + @Provides + @Singleton + PlanPlugin providePlanPlugin(PlanVelocity plugin) { + return plugin; + } + + @Provides + @Singleton + @Named("mainCommand") + CommandNode provideMainCommand(PlanVelocityCommand command) { + return command; + } +} \ No newline at end of file diff --git a/Plan/src/main/java/com/djrapitops/plan/modules/proxy/ProxySuperClassBindingModule.java b/Plan/src/main/java/com/djrapitops/plan/modules/proxy/ProxySuperClassBindingModule.java new file mode 100644 index 000000000..99680672b --- /dev/null +++ b/Plan/src/main/java/com/djrapitops/plan/modules/proxy/ProxySuperClassBindingModule.java @@ -0,0 +1,72 @@ +package com.djrapitops.plan.modules.proxy; + +import com.djrapitops.plan.api.PlanAPI; +import com.djrapitops.plan.api.ProxyAPI; +import com.djrapitops.plan.system.cache.DataCache; +import com.djrapitops.plan.system.cache.ProxyDataCache; +import com.djrapitops.plan.system.database.DBSystem; +import com.djrapitops.plan.system.database.ProxyDBSystem; +import com.djrapitops.plan.system.importing.EmptyImportSystem; +import com.djrapitops.plan.system.importing.ImportSystem; +import com.djrapitops.plan.system.info.InfoSystem; +import com.djrapitops.plan.system.info.ProxyInfoSystem; +import com.djrapitops.plan.system.info.connection.ConnectionSystem; +import com.djrapitops.plan.system.info.connection.ProxyConnectionSystem; +import com.djrapitops.plan.system.settings.config.ConfigSystem; +import com.djrapitops.plan.system.settings.config.ProxyConfigSystem; +import dagger.Module; +import dagger.Provides; + +import javax.inject.Singleton; + +/** + * Dagger module for binding proxy server classes to super classes. + * + * @author Rsl1122 + */ +@Module +public class ProxySuperClassBindingModule { + + @Provides + @Singleton + PlanAPI provideProxyPlanAPI(ProxyAPI proxyAPI) { + return proxyAPI; + } + + @Provides + @Singleton + DBSystem provideProxyDatabaseSystem(ProxyDBSystem proxyDBSystem) { + return proxyDBSystem; + } + + @Provides + @Singleton + ConfigSystem provideProxyConfigSystem(ProxyConfigSystem proxyConfigSystem) { + return proxyConfigSystem; + } + + @Provides + @Singleton + InfoSystem provideProxyInfoSystem(ProxyInfoSystem proxyInfoSystem) { + return proxyInfoSystem; + } + + @Provides + @Singleton + ConnectionSystem provideProxyConnectionSystem(ProxyConnectionSystem proxyConnectionSystem) { + return proxyConnectionSystem; + } + + @Provides + @Singleton + DataCache provideProxyDataCache(ProxyDataCache proxyDataCache) { + return proxyDataCache; + } + + @Provides + @Singleton + ImportSystem provideImportSystem() { + return new EmptyImportSystem(); + } + +} \ No newline at end of file diff --git a/Plan/src/main/java/com/djrapitops/plan/modules/proxy/bungee/BungeeServerPropertiesModule.java b/Plan/src/main/java/com/djrapitops/plan/modules/proxy/bungee/BungeeServerPropertiesModule.java new file mode 100644 index 000000000..b3a1a4c5c --- /dev/null +++ b/Plan/src/main/java/com/djrapitops/plan/modules/proxy/bungee/BungeeServerPropertiesModule.java @@ -0,0 +1,26 @@ +package com.djrapitops.plan.modules.proxy.bungee; + +import com.djrapitops.plan.PlanBungee; +import com.djrapitops.plan.system.info.server.properties.BungeeServerProperties; +import com.djrapitops.plan.system.info.server.properties.ServerProperties; +import com.djrapitops.plan.system.settings.Settings; +import com.djrapitops.plan.system.settings.config.PlanConfig; +import dagger.Module; +import dagger.Provides; + +import javax.inject.Singleton; + +/** + * Dagger module for Bungee ServerProperties. + * + * @author Rsl1122 + */ +@Module +public class BungeeServerPropertiesModule { + + @Provides + @Singleton + ServerProperties provideServerProperties(PlanBungee plugin, PlanConfig config) { + return new BungeeServerProperties(plugin.getProxy(), config.getString(Settings.BUNGEE_IP)); + } +} \ No newline at end of file diff --git a/Plan/src/main/java/com/djrapitops/plan/modules/proxy/bungee/BungeeSuperClassBindingModule.java b/Plan/src/main/java/com/djrapitops/plan/modules/proxy/bungee/BungeeSuperClassBindingModule.java new file mode 100644 index 000000000..e9078f65b --- /dev/null +++ b/Plan/src/main/java/com/djrapitops/plan/modules/proxy/bungee/BungeeSuperClassBindingModule.java @@ -0,0 +1,39 @@ +package com.djrapitops.plan.modules.proxy.bungee; + +import com.djrapitops.plan.system.info.server.BungeeServerInfo; +import com.djrapitops.plan.system.info.server.ServerInfo; +import com.djrapitops.plan.system.listeners.BungeeListenerSystem; +import com.djrapitops.plan.system.listeners.ListenerSystem; +import com.djrapitops.plan.system.tasks.BungeeTaskSystem; +import com.djrapitops.plan.system.tasks.TaskSystem; +import dagger.Module; +import dagger.Provides; + +import javax.inject.Singleton; + +/** + * Module for binding Bungee specific classes to the interface implementations. + * + * @author Rsl1122 + */ +@Module +public class BungeeSuperClassBindingModule { + + @Provides + @Singleton + ServerInfo provideBungeeServerInfo(BungeeServerInfo bungeeServerInfo) { + return bungeeServerInfo; + } + + @Provides + @Singleton + TaskSystem provideBungeeTaskSystem(BungeeTaskSystem bungeeTaskSystem) { + return bungeeTaskSystem; + } + + @Provides + @Singleton + ListenerSystem provideBungeeListenerSystem(BungeeListenerSystem bungeeListenerSystem) { + return bungeeListenerSystem; + } +} \ No newline at end of file diff --git a/Plan/src/main/java/com/djrapitops/plan/modules/proxy/velocity/VelocityServerPropertiesModule.java b/Plan/src/main/java/com/djrapitops/plan/modules/proxy/velocity/VelocityServerPropertiesModule.java new file mode 100644 index 000000000..f3da3f3ad --- /dev/null +++ b/Plan/src/main/java/com/djrapitops/plan/modules/proxy/velocity/VelocityServerPropertiesModule.java @@ -0,0 +1,27 @@ +package com.djrapitops.plan.modules.proxy.velocity; + +import com.djrapitops.plan.PlanVelocity; +import com.djrapitops.plan.system.info.server.properties.ServerProperties; +import com.djrapitops.plan.system.info.server.properties.VelocityServerProperties; +import com.djrapitops.plan.system.settings.Settings; +import com.djrapitops.plan.system.settings.config.PlanConfig; +import dagger.Module; +import dagger.Provides; + +import javax.inject.Singleton; + +/** + * Dagger module for Bungee ServerProperties. + * + * @author Rsl1122 + */ +@Module +public class VelocityServerPropertiesModule { + + @Provides + @Singleton + ServerProperties provideServerProperties(PlanVelocity plugin, PlanConfig config) { + return new VelocityServerProperties(plugin.getProxy(), config.getString(Settings.BUNGEE_IP)); + } + +} \ No newline at end of file diff --git a/Plan/src/main/java/com/djrapitops/plan/modules/proxy/velocity/VelocitySuperClassBindingModule.java b/Plan/src/main/java/com/djrapitops/plan/modules/proxy/velocity/VelocitySuperClassBindingModule.java new file mode 100644 index 000000000..4397872a0 --- /dev/null +++ b/Plan/src/main/java/com/djrapitops/plan/modules/proxy/velocity/VelocitySuperClassBindingModule.java @@ -0,0 +1,39 @@ +package com.djrapitops.plan.modules.proxy.velocity; + +import com.djrapitops.plan.system.info.server.ServerInfo; +import com.djrapitops.plan.system.info.server.VelocityServerInfo; +import com.djrapitops.plan.system.listeners.ListenerSystem; +import com.djrapitops.plan.system.listeners.VelocityListenerSystem; +import com.djrapitops.plan.system.tasks.TaskSystem; +import com.djrapitops.plan.system.tasks.VelocityTaskSystem; +import dagger.Module; +import dagger.Provides; + +import javax.inject.Singleton; + +/** + * Module for binding Velocity specific classes to the interface implementations. + * + * @author Rsl1122 + */ +@Module +public class VelocitySuperClassBindingModule { + + @Provides + @Singleton + ServerInfo provideVelocityServerInfo(VelocityServerInfo velocityServerInfo) { + return velocityServerInfo; + } + + @Provides + @Singleton + TaskSystem provideVelocityTaskSystem(VelocityTaskSystem velocityTaskSystem) { + return velocityTaskSystem; + } + + @Provides + @Singleton + ListenerSystem provideVelocityListenerSystem(VelocityListenerSystem velocityListenerSystem) { + return velocityListenerSystem; + } +} \ No newline at end of file diff --git a/Plan/src/main/java/com/djrapitops/plan/modules/server/ServerSuperClassBindingModule.java b/Plan/src/main/java/com/djrapitops/plan/modules/server/ServerSuperClassBindingModule.java new file mode 100644 index 000000000..c7e591782 --- /dev/null +++ b/Plan/src/main/java/com/djrapitops/plan/modules/server/ServerSuperClassBindingModule.java @@ -0,0 +1,40 @@ +package com.djrapitops.plan.modules.server; + +import com.djrapitops.plan.api.PlanAPI; +import com.djrapitops.plan.api.ServerAPI; +import com.djrapitops.plan.system.info.InfoSystem; +import com.djrapitops.plan.system.info.ServerInfoSystem; +import com.djrapitops.plan.system.info.connection.ConnectionSystem; +import com.djrapitops.plan.system.info.connection.ServerConnectionSystem; +import dagger.Module; +import dagger.Provides; + +import javax.inject.Singleton; + +/** + * Module for binding Server specific classes to the interface implementations. + * + * @author Rsl1122 + */ +@Module +public class ServerSuperClassBindingModule { + + @Provides + @Singleton + PlanAPI provideServerPlanAPI(ServerAPI serverAPI) { + return serverAPI; + } + + @Provides + @Singleton + InfoSystem provideServerInfoSystem(ServerInfoSystem serverInfoSystem) { + return serverInfoSystem; + } + + @Provides + @Singleton + ConnectionSystem provideServerConnectionSystem(ServerConnectionSystem serverConnectionSystem) { + return serverConnectionSystem; + } + +} \ No newline at end of file diff --git a/Plan/src/main/java/com/djrapitops/plan/modules/server/bukkit/BukkitServerPropertiesModule.java b/Plan/src/main/java/com/djrapitops/plan/modules/server/bukkit/BukkitServerPropertiesModule.java new file mode 100644 index 000000000..32d14f7e1 --- /dev/null +++ b/Plan/src/main/java/com/djrapitops/plan/modules/server/bukkit/BukkitServerPropertiesModule.java @@ -0,0 +1,24 @@ +package com.djrapitops.plan.modules.server.bukkit; + +import com.djrapitops.plan.Plan; +import com.djrapitops.plan.system.info.server.properties.BukkitServerProperties; +import com.djrapitops.plan.system.info.server.properties.ServerProperties; +import dagger.Module; +import dagger.Provides; + +import javax.inject.Singleton; + +/** + * Dagger module for Bukkit ServerProperties. + * + * @author Rsl1122 + */ +@Module +public class BukkitServerPropertiesModule { + + @Provides + @Singleton + ServerProperties provideServerProperties(Plan plugin) { + return new BukkitServerProperties(plugin.getServer()); + } +} \ No newline at end of file diff --git a/Plan/src/main/java/com/djrapitops/plan/modules/server/bukkit/BukkitSuperClassBindingModule.java b/Plan/src/main/java/com/djrapitops/plan/modules/server/bukkit/BukkitSuperClassBindingModule.java new file mode 100644 index 000000000..f3475db22 --- /dev/null +++ b/Plan/src/main/java/com/djrapitops/plan/modules/server/bukkit/BukkitSuperClassBindingModule.java @@ -0,0 +1,64 @@ +package com.djrapitops.plan.modules.server.bukkit; + +import com.djrapitops.plan.system.database.BukkitDBSystem; +import com.djrapitops.plan.system.database.DBSystem; +import com.djrapitops.plan.system.importing.BukkitImportSystem; +import com.djrapitops.plan.system.importing.ImportSystem; +import com.djrapitops.plan.system.info.server.BukkitServerInfo; +import com.djrapitops.plan.system.info.server.ServerInfo; +import com.djrapitops.plan.system.listeners.BukkitListenerSystem; +import com.djrapitops.plan.system.listeners.ListenerSystem; +import com.djrapitops.plan.system.settings.config.BukkitConfigSystem; +import com.djrapitops.plan.system.settings.config.ConfigSystem; +import com.djrapitops.plan.system.tasks.BukkitTaskSystem; +import com.djrapitops.plan.system.tasks.TaskSystem; +import dagger.Module; +import dagger.Provides; + +import javax.inject.Singleton; + +/** + * Module for binding Bukkit specific classes to the interface implementations. + * + * @author Rsl1122 + */ +@Module +public class BukkitSuperClassBindingModule { + + @Provides + @Singleton + ServerInfo provideBukkitServerInfo(BukkitServerInfo bukkitServerInfo) { + return bukkitServerInfo; + } + + @Provides + @Singleton + DBSystem provideBukkitDatabaseSystem(BukkitDBSystem dbSystem) { + return dbSystem; + } + + @Provides + @Singleton + ConfigSystem provideBukkitConfigSystem(BukkitConfigSystem bukkitConfigSystem) { + return bukkitConfigSystem; + } + + @Provides + @Singleton + TaskSystem provideBukkitTaskSystem(BukkitTaskSystem bukkitTaskSystem) { + return bukkitTaskSystem; + } + + @Provides + @Singleton + ListenerSystem provideBukkitListenerSystem(BukkitListenerSystem bukkitListenerSystem) { + return bukkitListenerSystem; + } + + @Provides + @Singleton + ImportSystem provideImportSsytem(BukkitImportSystem bukkitImportSystem) { + return bukkitImportSystem; + } + +} \ No newline at end of file diff --git a/Plan/src/main/java/com/djrapitops/plan/modules/server/sponge/SpongeServerPropertiesModule.java b/Plan/src/main/java/com/djrapitops/plan/modules/server/sponge/SpongeServerPropertiesModule.java new file mode 100644 index 000000000..2d3088380 --- /dev/null +++ b/Plan/src/main/java/com/djrapitops/plan/modules/server/sponge/SpongeServerPropertiesModule.java @@ -0,0 +1,24 @@ +package com.djrapitops.plan.modules.server.sponge; + +import com.djrapitops.plan.PlanSponge; +import com.djrapitops.plan.system.info.server.properties.ServerProperties; +import com.djrapitops.plan.system.info.server.properties.SpongeServerProperties; +import dagger.Module; +import dagger.Provides; + +import javax.inject.Singleton; + +/** + * Dagger module for Sponge ServerProperties. + * + * @author Rsl1122 + */ +@Module +public class SpongeServerPropertiesModule { + + @Provides + @Singleton + ServerProperties provideServerProperties(PlanSponge plugin) { + return new SpongeServerProperties(plugin.getGame()); + } +} \ No newline at end of file diff --git a/Plan/src/main/java/com/djrapitops/plan/modules/server/sponge/SpongeSuperClassBindingModule.java b/Plan/src/main/java/com/djrapitops/plan/modules/server/sponge/SpongeSuperClassBindingModule.java new file mode 100644 index 000000000..185f4da4e --- /dev/null +++ b/Plan/src/main/java/com/djrapitops/plan/modules/server/sponge/SpongeSuperClassBindingModule.java @@ -0,0 +1,64 @@ +package com.djrapitops.plan.modules.server.sponge; + +import com.djrapitops.plan.system.database.DBSystem; +import com.djrapitops.plan.system.database.SpongeDBSystem; +import com.djrapitops.plan.system.importing.EmptyImportSystem; +import com.djrapitops.plan.system.importing.ImportSystem; +import com.djrapitops.plan.system.info.server.ServerInfo; +import com.djrapitops.plan.system.info.server.SpongeServerInfo; +import com.djrapitops.plan.system.listeners.ListenerSystem; +import com.djrapitops.plan.system.listeners.SpongeListenerSystem; +import com.djrapitops.plan.system.settings.config.ConfigSystem; +import com.djrapitops.plan.system.settings.config.SpongeConfigSystem; +import com.djrapitops.plan.system.tasks.SpongeTaskSystem; +import com.djrapitops.plan.system.tasks.TaskSystem; +import dagger.Module; +import dagger.Provides; + +import javax.inject.Singleton; + +/** + * Module for binding Sponge specific classes to the interface implementations. + * + * @author Rsl1122 + */ +@Module +public class SpongeSuperClassBindingModule { + + @Provides + @Singleton + ServerInfo provideSpongeServerInfo(SpongeServerInfo spongeServerInfo) { + return spongeServerInfo; + } + + @Provides + @Singleton + DBSystem provideSpongeDatabaseSystem(SpongeDBSystem dbSystem) { + return dbSystem; + } + + @Provides + @Singleton + ConfigSystem provideSpongeConfigSystem(SpongeConfigSystem spongeConfigSystem) { + return spongeConfigSystem; + } + + @Provides + @Singleton + TaskSystem provideSpongeTaskSystem(SpongeTaskSystem spongeTaskSystem) { + return spongeTaskSystem; + } + + @Provides + @Singleton + ListenerSystem provideSpongeListenerSystem(SpongeListenerSystem spongeListenerSystem) { + return spongeListenerSystem; + } + + @Provides + @Singleton + ImportSystem provideImportSystem() { + return new EmptyImportSystem(); + } + +} \ No newline at end of file diff --git a/Plan/src/main/java/com/djrapitops/plan/system/BukkitSystem.java b/Plan/src/main/java/com/djrapitops/plan/system/BukkitSystem.java deleted file mode 100644 index fa49b9eee..000000000 --- a/Plan/src/main/java/com/djrapitops/plan/system/BukkitSystem.java +++ /dev/null @@ -1,68 +0,0 @@ -/* - * License is provided in the jar as LICENSE also here: - * https://github.com/Rsl1122/Plan-PlayerAnalytics/blob/master/Plan/src/main/resources/LICENSE - */ -package com.djrapitops.plan.system; - -import com.djrapitops.plan.Plan; -import com.djrapitops.plan.ShutdownHook; -import com.djrapitops.plan.api.ServerAPI; -import com.djrapitops.plan.api.exceptions.EnableException; -import com.djrapitops.plan.data.plugin.HookHandler; -import com.djrapitops.plan.system.database.ServerDBSystem; -import com.djrapitops.plan.system.file.FileSystem; -import com.djrapitops.plan.system.info.ServerInfoSystem; -import com.djrapitops.plan.system.info.server.BukkitServerInfo; -import com.djrapitops.plan.system.listeners.BukkitListenerSystem; -import com.djrapitops.plan.system.locale.Locale; -import com.djrapitops.plan.system.settings.PlanErrorManager; -import com.djrapitops.plan.system.settings.config.ServerConfigSystem; -import com.djrapitops.plan.system.settings.network.NetworkSettings; -import com.djrapitops.plan.system.tasks.BukkitTaskSystem; -import com.djrapitops.plan.system.update.VersionCheckSystem; -import com.djrapitops.plugin.StaticHolder; -import com.djrapitops.plugin.api.utility.log.Log; - -import java.util.function.Supplier; - -/** - * Represents PlanSystem for Plan. - * - * @author Rsl1122 - */ -public class BukkitSystem extends PlanSystem implements ServerSystem { - - public BukkitSystem(Plan plugin) { - setTestSystem(this); - - Log.setErrorManager(new PlanErrorManager()); - - Supplier localeSupplier = () -> getLocaleSystem().getLocale(); - - versionCheckSystem = new VersionCheckSystem(plugin.getVersion(), localeSupplier); - fileSystem = new FileSystem(plugin); - configSystem = new ServerConfigSystem(); - databaseSystem = new ServerDBSystem(localeSupplier); - listenerSystem = new BukkitListenerSystem(plugin); - taskSystem = new BukkitTaskSystem(plugin); - - infoSystem = new ServerInfoSystem(localeSupplier); - serverInfo = new BukkitServerInfo(plugin); - - hookHandler = new HookHandler(); - planAPI = new ServerAPI(this); - - StaticHolder.saveInstance(ShutdownHook.class, plugin.getClass()); - new ShutdownHook().register(); - } - - public static BukkitSystem getInstance() { - return Plan.getInstance().getSystem(); - } - - @Override - public void enable() throws EnableException { - super.enable(); - NetworkSettings.loadSettingsFromDB(); - } -} diff --git a/Plan/src/main/java/com/djrapitops/plan/system/BungeeSystem.java b/Plan/src/main/java/com/djrapitops/plan/system/BungeeSystem.java index 0de142b74..e69de29bb 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/BungeeSystem.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/BungeeSystem.java @@ -1,70 +0,0 @@ -/* - * License is provided in the jar as LICENSE also here: - * https://github.com/Rsl1122/Plan-PlayerAnalytics/blob/master/Plan/src/main/resources/LICENSE - */ -package com.djrapitops.plan.system; - -import com.djrapitops.plan.PlanBungee; -import com.djrapitops.plan.api.BungeeAPI; -import com.djrapitops.plan.api.exceptions.EnableException; -import com.djrapitops.plan.data.plugin.HookHandler; -import com.djrapitops.plan.system.cache.BungeeCacheSystem; -import com.djrapitops.plan.system.database.BungeeDBSystem; -import com.djrapitops.plan.system.database.DBSystem; -import com.djrapitops.plan.system.file.FileSystem; -import com.djrapitops.plan.system.info.BungeeInfoSystem; -import com.djrapitops.plan.system.info.server.BungeeServerInfo; -import com.djrapitops.plan.system.listeners.BungeeListenerSystem; -import com.djrapitops.plan.system.locale.Locale; -import com.djrapitops.plan.system.settings.PlanErrorManager; -import com.djrapitops.plan.system.settings.config.BungeeConfigSystem; -import com.djrapitops.plan.system.settings.network.NetworkSettings; -import com.djrapitops.plan.system.tasks.BungeeTaskSystem; -import com.djrapitops.plan.system.update.VersionCheckSystem; -import com.djrapitops.plugin.api.utility.log.Log; - -import java.util.function.Supplier; - -/** - * Represents PlanSystem for PlanBungee. - * - * @author Rsl1122 - */ -public class BungeeSystem extends PlanSystem { - - public BungeeSystem(PlanBungee plugin) { - setTestSystem(this); - - Log.setErrorManager(new PlanErrorManager()); - - Supplier localeSupplier = () -> getLocaleSystem().getLocale(); - - versionCheckSystem = new VersionCheckSystem(plugin.getVersion(), localeSupplier); - fileSystem = new FileSystem(plugin); - configSystem = new BungeeConfigSystem(); - databaseSystem = new BungeeDBSystem(localeSupplier); - cacheSystem = new BungeeCacheSystem(this); - listenerSystem = new BungeeListenerSystem(plugin); - taskSystem = new BungeeTaskSystem(plugin); - - infoSystem = new BungeeInfoSystem(); - serverInfo = new BungeeServerInfo(plugin); - - hookHandler = new HookHandler(); - planAPI = new BungeeAPI(this); - } - - public static BungeeSystem getInstance() { - return PlanBungee.getInstance().getSystem(); - } - - public void setDatabaseSystem(DBSystem dbSystem) { - this.databaseSystem = dbSystem; - } - - @Override - public void enable() throws EnableException { - super.enable(); - NetworkSettings.placeSettingsToDB(); - } -} diff --git a/Plan/src/main/java/com/djrapitops/plan/system/DebugChannels.java b/Plan/src/main/java/com/djrapitops/plan/system/DebugChannels.java new file mode 100644 index 000000000..be4b30c6a --- /dev/null +++ b/Plan/src/main/java/com/djrapitops/plan/system/DebugChannels.java @@ -0,0 +1,17 @@ +package com.djrapitops.plan.system; + +/** + * Identifiers for different Debug channels. + * + * @author Rsl1122 + */ +public class DebugChannels { + + public static final String ANALYSIS = "Analysis"; + public static final String INFO_REQUESTS = "InfoRequests"; + public static final String CONNECTIONS = "Connections"; + public static final String WEB_REQUESTS = "Web Requests"; + public static final String IMPORTING = "Importing"; + public static final String SQL = "SQL"; + +} diff --git a/Plan/src/main/java/com/djrapitops/plan/system/PlanSystem.java b/Plan/src/main/java/com/djrapitops/plan/system/PlanSystem.java index a62975d40..e702d5e01 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/PlanSystem.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/PlanSystem.java @@ -9,22 +9,23 @@ import com.djrapitops.plan.api.exceptions.EnableException; import com.djrapitops.plan.data.plugin.HookHandler; import com.djrapitops.plan.system.cache.CacheSystem; import com.djrapitops.plan.system.database.DBSystem; -import com.djrapitops.plan.system.file.FileSystem; +import com.djrapitops.plan.system.export.ExportSystem; +import com.djrapitops.plan.system.file.PlanFiles; +import com.djrapitops.plan.system.importing.ImportSystem; import com.djrapitops.plan.system.info.InfoSystem; import com.djrapitops.plan.system.info.server.ServerInfo; import com.djrapitops.plan.system.listeners.ListenerSystem; -import com.djrapitops.plan.system.locale.Locale; import com.djrapitops.plan.system.locale.LocaleSystem; import com.djrapitops.plan.system.processing.Processing; import com.djrapitops.plan.system.settings.config.ConfigSystem; import com.djrapitops.plan.system.tasks.TaskSystem; import com.djrapitops.plan.system.update.VersionCheckSystem; import com.djrapitops.plan.system.webserver.WebServerSystem; -import com.djrapitops.plugin.api.Check; -import com.djrapitops.plugin.api.utility.log.Log; -import com.djrapitops.plugin.utilities.Verify; +import com.djrapitops.plugin.logging.L; +import com.djrapitops.plugin.logging.error.ErrorHandler; -import java.util.function.Supplier; +import javax.inject.Inject; +import javax.inject.Singleton; /** * PlanSystem contains everything Plan needs to run. @@ -33,67 +34,77 @@ import java.util.function.Supplier; * * @author Rsl1122 */ -public abstract class PlanSystem implements SubSystem { +@Singleton +public class PlanSystem implements SubSystem { - protected static PlanSystem testSystem; + private final PlanFiles files; + private final ConfigSystem configSystem; + private final VersionCheckSystem versionCheckSystem; + private final LocaleSystem localeSystem; + private final DBSystem databaseSystem; + private final CacheSystem cacheSystem; + private final ListenerSystem listenerSystem; + private final TaskSystem taskSystem; + private final InfoSystem infoSystem; + private final ServerInfo serverInfo; + private final WebServerSystem webServerSystem; - // Initialized in this class - private Processing processing; - protected final WebServerSystem webServerSystem; - protected final LocaleSystem localeSystem; - protected CacheSystem cacheSystem; + private final Processing processing; - // These need to be initialized in the sub class. - protected VersionCheckSystem versionCheckSystem; - protected FileSystem fileSystem; - protected ConfigSystem configSystem; - protected DBSystem databaseSystem; - protected InfoSystem infoSystem; + private final ImportSystem importSystem; + private final ExportSystem exportSystem; + private final HookHandler hookHandler; + private final PlanAPI planAPI; + private final ErrorHandler errorHandler; - protected ListenerSystem listenerSystem; - protected TaskSystem taskSystem; - protected ServerInfo serverInfo; - - protected HookHandler hookHandler; - - // Not a SubSystem. - protected PlanAPI planAPI; - - public PlanSystem() { - Supplier localeSupplier = () -> getLocaleSystem().getLocale(); - - processing = new Processing(localeSupplier); - webServerSystem = new WebServerSystem(localeSupplier); - localeSystem = new LocaleSystem(); - cacheSystem = new CacheSystem(this); - } - - public static PlanSystem getInstance() { - boolean bukkitAvailable = Check.isBukkitAvailable(); - boolean bungeeAvailable = Check.isBungeeAvailable(); - boolean spongeAvailable = Check.isSpongeAvailable(); - if (bukkitAvailable && bungeeAvailable) { - return testSystem; - } else if (bungeeAvailable) { - return BungeeSystem.getInstance(); - } else if (bukkitAvailable) { - return BukkitSystem.getInstance(); - } else if (spongeAvailable) { - return SpongeSystem.getInstance(); - } - throw new IllegalAccessError("PlanSystem is not available on this platform."); + @Inject + public PlanSystem( + PlanFiles files, + ConfigSystem configSystem, + VersionCheckSystem versionCheckSystem, + LocaleSystem localeSystem, + DBSystem databaseSystem, + CacheSystem cacheSystem, + ListenerSystem listenerSystem, + TaskSystem taskSystem, + InfoSystem infoSystem, + ServerInfo serverInfo, + WebServerSystem webServerSystem, + Processing processing, + ImportSystem importSystem, + ExportSystem exportSystem, + HookHandler hookHandler, + PlanAPI planAPI, + ErrorHandler errorHandler + ) { + this.files = files; + this.configSystem = configSystem; + this.versionCheckSystem = versionCheckSystem; + this.localeSystem = localeSystem; + this.databaseSystem = databaseSystem; + this.cacheSystem = cacheSystem; + this.listenerSystem = listenerSystem; + this.taskSystem = taskSystem; + this.infoSystem = infoSystem; + this.serverInfo = serverInfo; + this.webServerSystem = webServerSystem; + this.processing = processing; + this.importSystem = importSystem; + this.exportSystem = exportSystem; + this.hookHandler = hookHandler; + this.planAPI = planAPI; + this.errorHandler = errorHandler; } @Override public void enable() throws EnableException { - checkSubSystemInitialization(); - enableSystems( - fileSystem, + files, configSystem, localeSystem, versionCheckSystem, databaseSystem, + exportSystem, webServerSystem, processing, serverInfo, @@ -118,6 +129,7 @@ public abstract class PlanSystem implements SubSystem { hookHandler, cacheSystem, listenerSystem, + exportSystem, processing, databaseSystem, webServerSystem, @@ -125,7 +137,7 @@ public abstract class PlanSystem implements SubSystem { serverInfo, localeSystem, configSystem, - fileSystem, + files, versionCheckSystem ); } @@ -137,29 +149,11 @@ public abstract class PlanSystem implements SubSystem { system.disable(); } } catch (Exception e) { - Log.toLog(this.getClass(), e); + errorHandler.log(L.WARN, this.getClass(), e); } } } - private void checkSubSystemInitialization() throws EnableException { - try { - Verify.nullCheck(versionCheckSystem, () -> new IllegalStateException("Version Check system was not initialized.")); - Verify.nullCheck(fileSystem, () -> new IllegalStateException("File system was not initialized.")); - Verify.nullCheck(configSystem, () -> new IllegalStateException("Config system was not initialized.")); - Verify.nullCheck(localeSystem, () -> new IllegalStateException("Locale system was not initialized.")); - Verify.nullCheck(databaseSystem, () -> new IllegalStateException("Database system was not initialized.")); - Verify.nullCheck(infoSystem, () -> new IllegalStateException("Info system was not initialized.")); - Verify.nullCheck(serverInfo, () -> new IllegalStateException("ServerInfo was not initialized.")); - Verify.nullCheck(listenerSystem, () -> new IllegalStateException("Listener system was not initialized.")); - Verify.nullCheck(taskSystem, () -> new IllegalStateException("Task system was not initialized.")); - Verify.nullCheck(hookHandler, () -> new IllegalStateException("Plugin Hooks were not initialized.")); - Verify.nullCheck(planAPI, () -> new IllegalStateException("Plan API was not initialized.")); - } catch (Exception e) { - throw new EnableException("One of the subsystems is not initialized on enable for " + this.getClass().getSimpleName() + ": " + e.getMessage()); - } - } - // Accessor methods. public VersionCheckSystem getVersionCheckSystem() { @@ -170,8 +164,8 @@ public abstract class PlanSystem implements SubSystem { return configSystem; } - public FileSystem getFileSystem() { - return fileSystem; + public PlanFiles getPlanFiles() { + return files; } public DBSystem getDatabaseSystem() { @@ -190,6 +184,14 @@ public abstract class PlanSystem implements SubSystem { return webServerSystem; } + public ImportSystem getImportSystem() { + return importSystem; + } + + public ExportSystem getExportSystem() { + return exportSystem; + } + public ServerInfo getServerInfo() { return serverInfo; } @@ -214,11 +216,7 @@ public abstract class PlanSystem implements SubSystem { return processing; } - static void setTestSystem(PlanSystem testSystem) { - PlanSystem.testSystem = testSystem; - } - public LocaleSystem getLocaleSystem() { return localeSystem; } -} +} \ No newline at end of file diff --git a/Plan/src/main/java/com/djrapitops/plan/system/SpongeSystem.java b/Plan/src/main/java/com/djrapitops/plan/system/SpongeSystem.java deleted file mode 100644 index 2dd82a5a7..000000000 --- a/Plan/src/main/java/com/djrapitops/plan/system/SpongeSystem.java +++ /dev/null @@ -1,68 +0,0 @@ -/* - * License is provided in the jar as LICENSE also here: - * https://github.com/Rsl1122/Plan-PlayerAnalytics/blob/master/Plan/src/main/resources/LICENSE - */ -package com.djrapitops.plan.system; - -import com.djrapitops.plan.PlanSponge; -import com.djrapitops.plan.ShutdownHook; -import com.djrapitops.plan.api.ServerAPI; -import com.djrapitops.plan.api.exceptions.EnableException; -import com.djrapitops.plan.data.plugin.HookHandler; -import com.djrapitops.plan.system.database.ServerDBSystem; -import com.djrapitops.plan.system.file.FileSystem; -import com.djrapitops.plan.system.info.ServerInfoSystem; -import com.djrapitops.plan.system.info.server.SpongeServerInfo; -import com.djrapitops.plan.system.listeners.SpongeListenerSystem; -import com.djrapitops.plan.system.locale.Locale; -import com.djrapitops.plan.system.settings.PlanErrorManager; -import com.djrapitops.plan.system.settings.config.SpongeConfigSystem; -import com.djrapitops.plan.system.settings.network.NetworkSettings; -import com.djrapitops.plan.system.tasks.SpongeTaskSystem; -import com.djrapitops.plan.system.update.VersionCheckSystem; -import com.djrapitops.plugin.StaticHolder; -import com.djrapitops.plugin.api.utility.log.Log; - -import java.util.function.Supplier; - -/** - * Represents PlanSystem for PlanSponge. - * - * @author Rsl1122 - */ -public class SpongeSystem extends PlanSystem implements ServerSystem { - - public SpongeSystem(PlanSponge plugin) { - setTestSystem(this); - - Supplier localeSupplier = () -> getLocaleSystem().getLocale(); - - Log.setErrorManager(new PlanErrorManager()); - - versionCheckSystem = new VersionCheckSystem(plugin.getVersion(), localeSupplier); - fileSystem = new FileSystem(plugin); - configSystem = new SpongeConfigSystem(); - databaseSystem = new ServerDBSystem(localeSupplier); - listenerSystem = new SpongeListenerSystem(plugin); - taskSystem = new SpongeTaskSystem(plugin); - - infoSystem = new ServerInfoSystem(localeSupplier); - serverInfo = new SpongeServerInfo(); - - hookHandler = new HookHandler(); - planAPI = new ServerAPI(this); - - StaticHolder.saveInstance(ShutdownHook.class, plugin.getClass()); - new ShutdownHook().register(); - } - - public static SpongeSystem getInstance() { - return PlanSponge.getInstance().getSystem(); - } - - @Override - public void enable() throws EnableException { - super.enable(); - NetworkSettings.loadSettingsFromDB(); - } -} diff --git a/Plan/src/main/java/com/djrapitops/plan/system/afk/AFKTracker.java b/Plan/src/main/java/com/djrapitops/plan/system/afk/AFKTracker.java index 0dd7a512e..985cdb530 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/afk/AFKTracker.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/afk/AFKTracker.java @@ -3,9 +3,10 @@ package com.djrapitops.plan.system.afk; import com.djrapitops.plan.data.container.Session; import com.djrapitops.plan.system.cache.SessionCache; import com.djrapitops.plan.system.settings.Settings; -import com.djrapitops.plugin.api.TimeAmount; +import com.djrapitops.plan.system.settings.config.PlanConfig; import java.util.*; +import java.util.concurrent.TimeUnit; /** * Keeps track how long player has been afk during a session @@ -18,10 +19,10 @@ public class AFKTracker { private final Map lastMovement; private final long afkThresholdMs; - public AFKTracker() { + public AFKTracker(PlanConfig config) { usedAFKCommand = new HashSet<>(); lastMovement = new HashMap<>(); - afkThresholdMs = Settings.AFK_THRESHOLD_MINUTES.getNumber() * TimeAmount.MINUTE.ms(); + afkThresholdMs = TimeUnit.MINUTES.toMillis(config.getNumber(Settings.AFK_THRESHOLD_MINUTES)); } public void hasIgnorePermission(UUID uuid) { diff --git a/Plan/src/main/java/com/djrapitops/plan/system/cache/BungeeCacheSystem.java b/Plan/src/main/java/com/djrapitops/plan/system/cache/BungeeCacheSystem.java deleted file mode 100644 index cdb559730..000000000 --- a/Plan/src/main/java/com/djrapitops/plan/system/cache/BungeeCacheSystem.java +++ /dev/null @@ -1,18 +0,0 @@ -package com.djrapitops.plan.system.cache; - -import com.djrapitops.plan.system.PlanSystem; - -/** - * CacheSystem for Bungee. - *

- * Used for overriding {@link DataCache} with {@link BungeeDataCache} - * - * @author Rsl1122 - */ -public class BungeeCacheSystem extends CacheSystem { - - public BungeeCacheSystem(PlanSystem system) { - super(new BungeeDataCache(system), system); - } - -} diff --git a/Plan/src/main/java/com/djrapitops/plan/system/cache/BungeeDataCache.java b/Plan/src/main/java/com/djrapitops/plan/system/cache/BungeeDataCache.java deleted file mode 100644 index 56eaea59e..000000000 --- a/Plan/src/main/java/com/djrapitops/plan/system/cache/BungeeDataCache.java +++ /dev/null @@ -1,25 +0,0 @@ -package com.djrapitops.plan.system.cache; - -import com.djrapitops.plan.system.PlanSystem; - -import java.util.UUID; - -/** - * Bungee specific DataCache. - *

- * Used for overriding {@link SessionCache#endSession(UUID, long)}. - * - * @author Rsl1122 - */ -public class BungeeDataCache extends DataCache { - - public BungeeDataCache(PlanSystem system) { - super(system); - } - - @Override - public void endSession(UUID uuid, long time) { - removeSessionFromCache(uuid); - /* Bungee should not save sessions so session is not removed.. */ - } -} diff --git a/Plan/src/main/java/com/djrapitops/plan/system/cache/CacheSystem.java b/Plan/src/main/java/com/djrapitops/plan/system/cache/CacheSystem.java index 7e1e160cd..31f399d8e 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/cache/CacheSystem.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/cache/CacheSystem.java @@ -5,33 +5,26 @@ package com.djrapitops.plan.system.cache; import com.djrapitops.plan.api.exceptions.EnableException; -import com.djrapitops.plan.system.PlanSystem; import com.djrapitops.plan.system.SubSystem; -import com.djrapitops.plugin.utilities.Verify; + +import javax.inject.Inject; +import javax.inject.Singleton; /** * System that holds data caches of the plugin. * * @author Rsl1122 */ +@Singleton public class CacheSystem implements SubSystem { private final DataCache dataCache; private final GeolocationCache geolocationCache; - public CacheSystem(PlanSystem system) { - this(new DataCache(system), system); - } - - protected CacheSystem(DataCache dataCache, PlanSystem system) { + @Inject + public CacheSystem(DataCache dataCache, GeolocationCache geolocationCache) { this.dataCache = dataCache; - geolocationCache = new GeolocationCache(() -> system.getLocaleSystem().getLocale()); - } - - public static CacheSystem getInstance() { - CacheSystem cacheSystem = PlanSystem.getInstance().getCacheSystem(); - Verify.nullCheck(cacheSystem, () -> new IllegalStateException("Cache System was not initialized.")); - return cacheSystem; + this.geolocationCache = geolocationCache; } @Override diff --git a/Plan/src/main/java/com/djrapitops/plan/system/cache/DataCache.java b/Plan/src/main/java/com/djrapitops/plan/system/cache/DataCache.java index 4db45153e..6c4e2e619 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/cache/DataCache.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/cache/DataCache.java @@ -1,13 +1,17 @@ package com.djrapitops.plan.system.cache; import com.djrapitops.plan.api.exceptions.database.DBOpException; -import com.djrapitops.plan.system.PlanSystem; import com.djrapitops.plan.system.SubSystem; -import com.djrapitops.plan.system.database.databases.Database; -import com.djrapitops.plugin.api.utility.log.Log; -import com.djrapitops.plugin.utilities.Verify; +import com.djrapitops.plan.system.database.DBSystem; +import com.djrapitops.plugin.logging.L; +import com.djrapitops.plugin.logging.error.ErrorHandler; -import java.util.*; +import javax.inject.Inject; +import javax.inject.Singleton; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.UUID; /** * This Class contains the Cache. @@ -16,22 +20,27 @@ import java.util.*; *

    *
  • PlayerName cache, used for reducing database calls on chat events
  • *
  • DisplayName cache, used for reducing database calls on chat events
  • - *
  • FirstSession MessageCount Map, used for tracking first session and message count on that session.
  • *
* * @author Rsl1122 * @since 4.0.0 */ +@Singleton public class DataCache extends SessionCache implements SubSystem { - private Database db; + private final ErrorHandler errorHandler; + private final Map playerNames; private final Map uuids; private final Map displayNames; - public DataCache(PlanSystem system) { - super(system); - + @Inject + public DataCache( + DBSystem dbSystem, + ErrorHandler errorHandler + ) { + super(dbSystem); + this.errorHandler = errorHandler; playerNames = new HashMap<>(); displayNames = new HashMap<>(); uuids = new HashMap<>(); @@ -39,7 +48,6 @@ public class DataCache extends SessionCache implements SubSystem { @Override public void enable() { - db = system.getDatabaseSystem().getActiveDatabase(); } @Override @@ -49,12 +57,6 @@ public class DataCache extends SessionCache implements SubSystem { displayNames.clear(); } - public static DataCache getInstance() { - DataCache dataCache = CacheSystem.getInstance().getDataCache(); - Verify.nullCheck(dataCache, () -> new IllegalStateException("Data Cache was not initialized.")); - return dataCache; - } - /** * Used to update PlayerName and DisplayName caches. * @@ -87,10 +89,10 @@ public class DataCache extends SessionCache implements SubSystem { String name = playerNames.get(uuid); if (name == null) { try { - name = db.fetch().getPlayerName(uuid); + name = dbSystem.getDatabase().fetch().getPlayerName(uuid); playerNames.put(uuid, name); } catch (DBOpException e) { - Log.toLog(this.getClass(), e); + errorHandler.log(L.ERROR, this.getClass(), e); name = "Error occurred"; } } @@ -110,21 +112,17 @@ public class DataCache extends SessionCache implements SubSystem { if (cached == null) { List nicknames; try { - nicknames = db.fetch().getNicknames(uuid); + nicknames = dbSystem.getDatabase().fetch().getNicknames(uuid); if (!nicknames.isEmpty()) { return nicknames.get(nicknames.size() - 1); } } catch (DBOpException e) { - Log.toLog(this.getClass(), e); + errorHandler.log(L.ERROR, this.getClass(), e); } } return cached; } - public Set getUuids() { - return playerNames.keySet(); - } - public UUID getUUIDof(String playerName) { return uuids.get(playerName); } diff --git a/Plan/src/main/java/com/djrapitops/plan/system/cache/GeolocationCache.java b/Plan/src/main/java/com/djrapitops/plan/system/cache/GeolocationCache.java index 0dbe32cb0..dc7191506 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/cache/GeolocationCache.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/cache/GeolocationCache.java @@ -2,17 +2,20 @@ package com.djrapitops.plan.system.cache; import com.djrapitops.plan.api.exceptions.EnableException; import com.djrapitops.plan.system.SubSystem; -import com.djrapitops.plan.system.file.FileSystem; +import com.djrapitops.plan.system.file.PlanFiles; import com.djrapitops.plan.system.locale.Locale; import com.djrapitops.plan.system.locale.lang.PluginLang; import com.djrapitops.plan.system.settings.Settings; -import com.djrapitops.plugin.api.utility.log.Log; -import com.djrapitops.plugin.utilities.Verify; +import com.djrapitops.plan.system.settings.config.PlanConfig; +import com.djrapitops.plugin.logging.L; +import com.djrapitops.plugin.logging.console.PluginLogger; import com.maxmind.geoip2.DatabaseReader; import com.maxmind.geoip2.exception.GeoIp2Exception; import com.maxmind.geoip2.model.CountryResponse; import com.maxmind.geoip2.record.Country; +import javax.inject.Inject; +import javax.inject.Singleton; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; @@ -24,7 +27,6 @@ import java.nio.channels.Channels; import java.nio.channels.ReadableByteChannel; import java.util.HashMap; import java.util.Map; -import java.util.function.Supplier; import java.util.zip.GZIPInputStream; /** @@ -35,30 +37,45 @@ import java.util.zip.GZIPInputStream; * @author Fuzzlemann * @since 3.5.5 */ +@Singleton public class GeolocationCache implements SubSystem { - private final Supplier locale; + private final Locale locale; + private final PlanFiles files; + private final PlanConfig config; + private final PluginLogger logger; private final Map cached; + private File geolocationDB; - public GeolocationCache(Supplier locale) { + @Inject + public GeolocationCache( + Locale locale, + PlanFiles files, + PlanConfig config, + PluginLogger logger + ) { this.locale = locale; - cached = new HashMap<>(); + this.files = files; + this.config = config; + this.logger = logger; + + this.cached = new HashMap<>(); } @Override public void enable() throws EnableException { - geolocationDB = new File(FileSystem.getDataFolder(), "GeoIP.dat"); - if (Settings.DATA_GEOLOCATIONS.isTrue()) { + geolocationDB = files.getFileFromPluginFolder("GeoIP.dat"); + if (config.isTrue(Settings.DATA_GEOLOCATIONS)) { try { - GeolocationCache.checkDB(); + checkDB(); } catch (UnknownHostException e) { - Log.error(locale.get().getString(PluginLang.ENABLE_NOTIFY_GEOLOCATIONS_INTERNET_REQUIRED)); + logger.error(locale.getString(PluginLang.ENABLE_NOTIFY_GEOLOCATIONS_INTERNET_REQUIRED)); } catch (IOException e) { - throw new EnableException(locale.get().getString(PluginLang.ENABLE_FAIL_GEODB_WRITE), e); + throw new EnableException(locale.getString(PluginLang.ENABLE_FAIL_GEODB_WRITE), e); } } else { - Log.infoColor("§e" + locale.get().getString(PluginLang.ENABLE_NOTIFY_GEOLOCATIONS_DISABLED)); + logger.log(L.INFO_COLOR, "§e" + locale.getString(PluginLang.ENABLE_NOTIFY_GEOLOCATIONS_DISABLED)); } } @@ -74,33 +91,27 @@ public class GeolocationCache implements SubSystem { * if that happens, "Not Known" will be returned. * @see #getUnCachedCountry(String) */ - public static String getCountry(String ipAddress) { + public String getCountry(String ipAddress) { String country = getCachedCountry(ipAddress); if (country != null) { return country; } else { country = getUnCachedCountry(ipAddress); - getInstance().cached.put(ipAddress, country); + cached.put(ipAddress, country); return country; } } - private static GeolocationCache getInstance() { - GeolocationCache geolocationCache = CacheSystem.getInstance().getGeolocationCache(); - Verify.nullCheck(geolocationCache, () -> new IllegalStateException("GeolocationCache was not initialized.")); - return geolocationCache; - } - /** * Returns the cached country * * @param ipAddress The IP Address which is retrieved out of the cache * @return The cached country, {@code null} if the country is not cached */ - private static String getCachedCountry(String ipAddress) { - return getInstance().cached.get(ipAddress); + private String getCachedCountry(String ipAddress) { + return cached.get(ipAddress); } /** @@ -117,14 +128,14 @@ public class GeolocationCache implements SubSystem { * @see http://maxmind.com * @see #getCountry(String) */ - private static String getUnCachedCountry(String ipAddress) { + private String getUnCachedCountry(String ipAddress) { if ("127.0.0.1".equals(ipAddress)) { return "Local Machine"; } try { checkDB(); - try (DatabaseReader reader = new DatabaseReader.Builder(getInstance().geolocationDB).build()) { + try (DatabaseReader reader = new DatabaseReader.Builder(geolocationDB).build()) { InetAddress inetAddress = InetAddress.getByName(ipAddress); CountryResponse response = reader.country(inetAddress); @@ -143,8 +154,8 @@ public class GeolocationCache implements SubSystem { * * @throws IOException when an error at download or saving the DB happens */ - public static void checkDB() throws IOException { - if (getInstance().geolocationDB.exists()) { + private void checkDB() throws IOException { + if (geolocationDB.exists()) { return; } URL downloadSite = new URL("http://geolite.maxmind.com/download/geoip/database/GeoLite2-Country.mmdb.gz"); @@ -152,7 +163,7 @@ public class GeolocationCache implements SubSystem { InputStream in = downloadSite.openStream(); GZIPInputStream gzipIn = new GZIPInputStream(in); ReadableByteChannel rbc = Channels.newChannel(gzipIn); - FileOutputStream fos = new FileOutputStream(getInstance().geolocationDB.getAbsoluteFile()) + FileOutputStream fos = new FileOutputStream(geolocationDB.getAbsoluteFile()) ) { fos.getChannel().transferFrom(rbc, 0, Long.MAX_VALUE); } @@ -164,8 +175,8 @@ public class GeolocationCache implements SubSystem { * @param ipAddress The IP Address which is checked * @return true if the IP Address is cached */ - public static boolean isCached(String ipAddress) { - return getInstance().cached.containsKey(ipAddress); + boolean isCached(String ipAddress) { + return cached.containsKey(ipAddress); } @Override diff --git a/Plan/src/main/java/com/djrapitops/plan/system/cache/ProxyDataCache.java b/Plan/src/main/java/com/djrapitops/plan/system/cache/ProxyDataCache.java new file mode 100644 index 000000000..be6121406 --- /dev/null +++ b/Plan/src/main/java/com/djrapitops/plan/system/cache/ProxyDataCache.java @@ -0,0 +1,30 @@ +package com.djrapitops.plan.system.cache; + +import com.djrapitops.plan.system.database.DBSystem; +import com.djrapitops.plugin.logging.error.ErrorHandler; + +import javax.inject.Inject; +import javax.inject.Singleton; +import java.util.UUID; + +/** + * Proxy server specific DataCache. + *

+ * Used for overriding {@link SessionCache#endSession(UUID, long)}. + * + * @author Rsl1122 + */ +@Singleton +public class ProxyDataCache extends DataCache { + + @Inject + public ProxyDataCache(DBSystem dbSystem, ErrorHandler errorHandler) { + super(dbSystem, errorHandler); + } + + @Override + public void endSession(UUID uuid, long time) { + removeSessionFromCache(uuid); + /* Proxy should not save sessions so session is not removed.. */ + } +} diff --git a/Plan/src/main/java/com/djrapitops/plan/system/cache/SessionCache.java b/Plan/src/main/java/com/djrapitops/plan/system/cache/SessionCache.java index e195c7bdc..37eb34267 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/cache/SessionCache.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/cache/SessionCache.java @@ -1,12 +1,8 @@ package com.djrapitops.plan.system.cache; -import com.djrapitops.plan.api.exceptions.database.DBOpException; import com.djrapitops.plan.data.container.Session; import com.djrapitops.plan.data.store.keys.SessionKeys; -import com.djrapitops.plan.system.PlanSystem; -import com.djrapitops.plan.system.database.databases.Database; -import com.djrapitops.plugin.api.utility.log.Log; -import com.djrapitops.plugin.utilities.Verify; +import com.djrapitops.plan.system.database.DBSystem; import java.util.HashMap; import java.util.Map; @@ -22,16 +18,11 @@ import java.util.UUID; public class SessionCache { private static final Map activeSessions = new HashMap<>(); - protected final PlanSystem system; - public SessionCache(PlanSystem system) { - this.system = system; - } + protected final DBSystem dbSystem; - public static SessionCache getInstance() { - SessionCache dataCache = CacheSystem.getInstance().getDataCache(); - Verify.nullCheck(dataCache, () -> new IllegalStateException("Data Cache was not initialized.")); - return dataCache; + public SessionCache(DBSystem dbSystem) { + this.dbSystem = dbSystem; } public static Map getActiveSessions() { @@ -65,6 +56,13 @@ public class SessionCache { activeSessions.put(uuid, session); } + /** + * End a session and save it to database. + * + * @param uuid UUID of the player. + * @param time Time the session ended. + * @throws com.djrapitops.plan.api.exceptions.database.DBOpException If saving failed. + */ public void endSession(UUID uuid, long time) { Session session = activeSessions.get(uuid); if (session == null) { @@ -75,9 +73,8 @@ public class SessionCache { } try { session.endSession(time); - Database.getActive().save().session(uuid, session); - } catch (DBOpException e) { - Log.toLog(this.getClass(), e); + // Might throw a DBOpException + dbSystem.getDatabase().save().session(uuid, session); } finally { removeSessionFromCache(uuid); } diff --git a/Plan/src/main/java/com/djrapitops/plan/system/database/BukkitDBSystem.java b/Plan/src/main/java/com/djrapitops/plan/system/database/BukkitDBSystem.java new file mode 100644 index 000000000..29c27c8a8 --- /dev/null +++ b/Plan/src/main/java/com/djrapitops/plan/system/database/BukkitDBSystem.java @@ -0,0 +1,53 @@ +/* + * License is provided in the jar as LICENSE also here: + * https://github.com/Rsl1122/Plan-PlayerAnalytics/blob/master/Plan/src/main/resources/LICENSE + */ +package com.djrapitops.plan.system.database; + +import com.djrapitops.plan.api.exceptions.EnableException; +import com.djrapitops.plan.system.database.databases.sql.MySQLDB; +import com.djrapitops.plan.system.database.databases.sql.SQLiteDB; +import com.djrapitops.plan.system.locale.Locale; +import com.djrapitops.plan.system.settings.Settings; +import com.djrapitops.plan.system.settings.config.PlanConfig; +import com.djrapitops.plugin.benchmarking.Timings; +import com.djrapitops.plugin.logging.console.PluginLogger; +import com.djrapitops.plugin.logging.error.ErrorHandler; + +import javax.inject.Inject; +import javax.inject.Singleton; + +/** + * Bukkit Database system that initializes SQLite and MySQL database objects. + * + * @author Rsl1122 + */ +@Singleton +public class BukkitDBSystem extends DBSystem { + + private final PlanConfig config; + + @Inject + public BukkitDBSystem( + Locale locale, + MySQLDB mySQLDB, + SQLiteDB.Factory sqLiteDB, + PlanConfig config, + PluginLogger logger, + Timings timings, + ErrorHandler errorHandler + ) { + super(locale, sqLiteDB, logger, timings, errorHandler); + this.config = config; + + databases.add(mySQLDB); + databases.add(sqLiteDB.usingDefaultFile()); + } + + @Override + public void enable() throws EnableException { + String dbType = config.getString(Settings.DB_TYPE).toLowerCase().trim(); + db = getActiveDatabaseByName(dbType); + super.enable(); + } +} diff --git a/Plan/src/main/java/com/djrapitops/plan/system/database/BungeeDBSystem.java b/Plan/src/main/java/com/djrapitops/plan/system/database/BungeeDBSystem.java deleted file mode 100644 index 2cc2534b3..000000000 --- a/Plan/src/main/java/com/djrapitops/plan/system/database/BungeeDBSystem.java +++ /dev/null @@ -1,30 +0,0 @@ -/* - * License is provided in the jar as LICENSE also here: - * https://github.com/Rsl1122/Plan-PlayerAnalytics/blob/master/Plan/src/main/resources/LICENSE - */ -package com.djrapitops.plan.system.database; - -import com.djrapitops.plan.api.exceptions.database.DBInitException; -import com.djrapitops.plan.system.database.databases.sql.MySQLDB; -import com.djrapitops.plan.system.locale.Locale; - -import java.util.function.Supplier; - -/** - * Bungee Database system that initializes MySQL object. - * - * @author Rsl1122 - */ -public class BungeeDBSystem extends DBSystem { - - public BungeeDBSystem(Supplier locale) { - super(locale); - } - - @Override - protected void initDatabase() throws DBInitException { - db = new MySQLDB(locale); - databases.add(db); - db.init(); - } -} diff --git a/Plan/src/main/java/com/djrapitops/plan/system/database/DBSystem.java b/Plan/src/main/java/com/djrapitops/plan/system/database/DBSystem.java index a6aa0970d..352a48065 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/database/DBSystem.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/database/DBSystem.java @@ -7,56 +7,63 @@ package com.djrapitops.plan.system.database; import com.djrapitops.plan.api.exceptions.EnableException; import com.djrapitops.plan.api.exceptions.database.DBException; import com.djrapitops.plan.api.exceptions.database.DBInitException; -import com.djrapitops.plan.system.PlanSystem; import com.djrapitops.plan.system.SubSystem; import com.djrapitops.plan.system.database.databases.Database; +import com.djrapitops.plan.system.database.databases.sql.SQLiteDB; import com.djrapitops.plan.system.locale.Locale; import com.djrapitops.plan.system.locale.lang.PluginLang; -import com.djrapitops.plugin.api.Benchmark; -import com.djrapitops.plugin.api.utility.log.Log; +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; import com.djrapitops.plugin.utilities.Verify; +import javax.inject.Singleton; import java.util.HashSet; import java.util.Set; -import java.util.function.Supplier; /** * System that holds the active databases. * * @author Rsl1122 */ +@Singleton public abstract class DBSystem implements SubSystem { - protected final Supplier locale; + protected final Locale locale; + private final SQLiteDB.Factory sqLiteFactory; + protected final PluginLogger logger; + protected final Timings timings; + protected final ErrorHandler errorHandler; protected Database db; protected Set databases; - public DBSystem(Supplier locale) { + public DBSystem( + Locale locale, + SQLiteDB.Factory sqLiteDB, + PluginLogger logger, + Timings timings, + ErrorHandler errorHandler + ) { this.locale = locale; + sqLiteFactory = sqLiteDB; + this.logger = logger; + this.timings = timings; + this.errorHandler = errorHandler; databases = new HashSet<>(); } - public static DBSystem getInstance() { - DBSystem dbSystem = PlanSystem.getInstance().getDatabaseSystem(); - Verify.nullCheck(dbSystem, () -> new IllegalStateException("Database system was not initialized.")); - return dbSystem; - } - - public static Database getActiveDatabaseByName(String dbName) throws DBInitException { - DBSystem system = getInstance(); - for (Database database : system.getDatabases()) { + public Database getActiveDatabaseByName(String dbName) { + for (Database database : getDatabases()) { String dbConfigName = database.getConfigName(); if (Verify.equalsIgnoreCase(dbName, dbConfigName)) { - database.init(); return database; } } - throw new DBInitException(system.locale.get().getString(PluginLang.ENABLE_FAIL_WRONG_DB, dbName)); + throw new IllegalArgumentException(locale.getString(PluginLang.ENABLE_FAIL_WRONG_DB, dbName)); } - protected abstract void initDatabase() throws DBInitException; - public Set getDatabases() { return databases; } @@ -68,22 +75,20 @@ public abstract class DBSystem implements SubSystem { db.close(); } } catch (DBException e) { - Log.toLog(this.getClass(), e); + errorHandler.log(L.WARN, this.getClass(), e); } } - public Database getActiveDatabase() { + public Database getDatabase() { return db; } @Override public void enable() throws EnableException { try { - Benchmark.start("Init Database"); - initDatabase(); + db.init(); db.scheduleClean(20L); - Log.info(locale.get().getString(PluginLang.ENABLED_DATABASE, db.getName())); - Benchmark.stop("Enable", "Init Database"); + logger.info(locale.getString(PluginLang.ENABLED_DATABASE, db.getName())); } catch (DBInitException e) { Throwable cause = e.getCause(); String message = cause == null ? e.getMessage() : cause.getMessage(); @@ -95,4 +100,8 @@ public abstract class DBSystem implements SubSystem { this.db.close(); this.db = db; } + + public SQLiteDB.Factory getSqLiteFactory() { + return sqLiteFactory; + } } diff --git a/Plan/src/main/java/com/djrapitops/plan/system/database/ProxyDBSystem.java b/Plan/src/main/java/com/djrapitops/plan/system/database/ProxyDBSystem.java new file mode 100644 index 000000000..141a25517 --- /dev/null +++ b/Plan/src/main/java/com/djrapitops/plan/system/database/ProxyDBSystem.java @@ -0,0 +1,38 @@ +/* + * License is provided in the jar as LICENSE also here: + * https://github.com/Rsl1122/Plan-PlayerAnalytics/blob/master/Plan/src/main/resources/LICENSE + */ +package com.djrapitops.plan.system.database; + +import com.djrapitops.plan.system.database.databases.sql.MySQLDB; +import com.djrapitops.plan.system.database.databases.sql.SQLiteDB; +import com.djrapitops.plan.system.locale.Locale; +import com.djrapitops.plugin.benchmarking.Timings; +import com.djrapitops.plugin.logging.console.PluginLogger; +import com.djrapitops.plugin.logging.error.ErrorHandler; + +import javax.inject.Inject; +import javax.inject.Singleton; + +/** + * Bungee Database system that initializes MySQL object. + * + * @author Rsl1122 + */ +@Singleton +public class ProxyDBSystem extends DBSystem { + + @Inject + public ProxyDBSystem( + Locale locale, + MySQLDB mySQLDB, + SQLiteDB.Factory sqLiteDB, + PluginLogger logger, + Timings timings, + ErrorHandler errorHandler + ) { + super(locale, sqLiteDB, logger, timings, errorHandler); + databases.add(mySQLDB); + db = mySQLDB; + } +} diff --git a/Plan/src/main/java/com/djrapitops/plan/system/database/ServerDBSystem.java b/Plan/src/main/java/com/djrapitops/plan/system/database/ServerDBSystem.java deleted file mode 100644 index f04ac673b..000000000 --- a/Plan/src/main/java/com/djrapitops/plan/system/database/ServerDBSystem.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * License is provided in the jar as LICENSE also here: - * https://github.com/Rsl1122/Plan-PlayerAnalytics/blob/master/Plan/src/main/resources/LICENSE - */ -package com.djrapitops.plan.system.database; - -import com.djrapitops.plan.api.exceptions.database.DBInitException; -import com.djrapitops.plan.system.database.databases.sql.MySQLDB; -import com.djrapitops.plan.system.database.databases.sql.SQLiteDB; -import com.djrapitops.plan.system.database.databases.sql.SpongeMySQLDB; -import com.djrapitops.plan.system.locale.Locale; -import com.djrapitops.plan.system.settings.Settings; -import com.djrapitops.plugin.api.Check; - -import java.util.function.Supplier; - -/** - * Bukkit Database system that initializes SQLite and MySQL database objects. - * - * @author Rsl1122 - */ -public class ServerDBSystem extends DBSystem { - - public ServerDBSystem(Supplier locale) { - super(locale); - } - - @Override - protected void initDatabase() throws DBInitException { - databases.add(Check.isSpongeAvailable() ? new SpongeMySQLDB(locale) : new MySQLDB(locale)); - databases.add(new SQLiteDB(locale)); - - String dbType = Settings.DB_TYPE.toString().toLowerCase().trim(); - db = getActiveDatabaseByName(dbType); - } -} diff --git a/Plan/src/main/java/com/djrapitops/plan/system/database/SpongeDBSystem.java b/Plan/src/main/java/com/djrapitops/plan/system/database/SpongeDBSystem.java new file mode 100644 index 000000000..5f5e091c7 --- /dev/null +++ b/Plan/src/main/java/com/djrapitops/plan/system/database/SpongeDBSystem.java @@ -0,0 +1,49 @@ +package com.djrapitops.plan.system.database; + +import com.djrapitops.plan.api.exceptions.EnableException; +import com.djrapitops.plan.system.database.databases.sql.SQLiteDB; +import com.djrapitops.plan.system.database.databases.sql.SpongeMySQLDB; +import com.djrapitops.plan.system.locale.Locale; +import com.djrapitops.plan.system.settings.Settings; +import com.djrapitops.plan.system.settings.config.PlanConfig; +import com.djrapitops.plugin.benchmarking.Timings; +import com.djrapitops.plugin.logging.console.PluginLogger; +import com.djrapitops.plugin.logging.error.ErrorHandler; + +import javax.inject.Inject; +import javax.inject.Singleton; + +/** + * DBSystem for Sponge. + * + * @author Rsl1122 + */ +@Singleton +public class SpongeDBSystem extends DBSystem { + + private final PlanConfig config; + + @Inject + public SpongeDBSystem( + Locale locale, + SpongeMySQLDB spongeMySQLDB, + SQLiteDB.Factory sqLiteDB, + PlanConfig config, + PluginLogger logger, + Timings timings, + ErrorHandler errorHandler + ) { + super(locale, sqLiteDB, logger, timings, errorHandler); + this.config = config; + + databases.add(spongeMySQLDB); + databases.add(sqLiteDB.usingDefaultFile()); + } + + @Override + public void enable() throws EnableException { + String dbType = config.getString(Settings.DB_TYPE).toLowerCase().trim(); + db = getActiveDatabaseByName(dbType); + super.enable(); + } +} \ No newline at end of file diff --git a/Plan/src/main/java/com/djrapitops/plan/system/database/databases/Database.java b/Plan/src/main/java/com/djrapitops/plan/system/database/databases/Database.java index 692206289..0debac219 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/database/databases/Database.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/database/databases/Database.java @@ -1,11 +1,8 @@ package com.djrapitops.plan.system.database.databases; -import com.djrapitops.plan.api.exceptions.connection.UnsupportedTransferDatabaseException; import com.djrapitops.plan.api.exceptions.database.DBException; import com.djrapitops.plan.api.exceptions.database.DBInitException; -import com.djrapitops.plan.system.database.DBSystem; import com.djrapitops.plan.system.database.databases.operation.*; -import com.djrapitops.plugin.utilities.Verify; /** * Abstract class representing a Database. @@ -18,12 +15,6 @@ public abstract class Database { protected boolean open = false; - public static Database getActive() { - Database database = DBSystem.getInstance().getActiveDatabase(); - Verify.nullCheck(database, () -> new IllegalStateException("Database was not initialized.")); - return database; - } - public abstract void init() throws DBInitException; public abstract BackupOperations backup(); @@ -40,13 +31,6 @@ public abstract class Database { public abstract SaveOperations save(); - /** - * Used to get the name of the database type. - *

- * Thread safe. - * - * @return SQLite/MySQL - */ public abstract String getName(); /** @@ -68,5 +52,5 @@ public abstract class Database { public abstract void scheduleClean(long delay); - public abstract TransferOperations transfer() throws UnsupportedTransferDatabaseException; + public abstract TransferOperations transfer(); } diff --git a/Plan/src/main/java/com/djrapitops/plan/system/database/databases/operation/CheckOperations.java b/Plan/src/main/java/com/djrapitops/plan/system/database/databases/operation/CheckOperations.java index 3a61a83e5..fb4751661 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/database/databases/operation/CheckOperations.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/database/databases/operation/CheckOperations.java @@ -1,7 +1,5 @@ package com.djrapitops.plan.system.database.databases.operation; -import com.djrapitops.plan.system.info.server.ServerInfo; - import java.util.UUID; public interface CheckOperations { @@ -12,9 +10,7 @@ public interface CheckOperations { boolean doesWebUserExists(String username); - default boolean isPlayerRegisteredOnThisServer(UUID player) { - return isPlayerRegistered(player, ServerInfo.getServerUUID()); - } + boolean isPlayerRegisteredOnThisServer(UUID player); boolean isServerInDatabase(UUID serverUUID); } diff --git a/Plan/src/main/java/com/djrapitops/plan/system/database/databases/operation/FetchOperations.java b/Plan/src/main/java/com/djrapitops/plan/system/database/databases/operation/FetchOperations.java index 666385c97..786b4bd5e 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/database/databases/operation/FetchOperations.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/database/databases/operation/FetchOperations.java @@ -116,4 +116,7 @@ public interface FetchOperations { List getServerUUIDs(); + Map> getPlayersOnlineForServers(Collection servers); + + Map getPlayersRegisteredForServers(Collection servers); } diff --git a/Plan/src/main/java/com/djrapitops/plan/system/database/databases/sql/MySQLDB.java b/Plan/src/main/java/com/djrapitops/plan/system/database/databases/sql/MySQLDB.java index 248a4684c..f168ad4c7 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/database/databases/sql/MySQLDB.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/database/databases/sql/MySQLDB.java @@ -2,19 +2,27 @@ package com.djrapitops.plan.system.database.databases.sql; import com.djrapitops.plan.api.exceptions.database.DBInitException; import com.djrapitops.plan.api.exceptions.database.DBOpException; +import com.djrapitops.plan.data.store.containers.NetworkContainer; +import com.djrapitops.plan.system.info.server.ServerInfo; import com.djrapitops.plan.system.locale.Locale; import com.djrapitops.plan.system.locale.lang.PluginLang; import com.djrapitops.plan.system.settings.Settings; -import com.djrapitops.plugin.api.TimeAmount; -import com.djrapitops.plugin.api.utility.log.Log; +import com.djrapitops.plan.system.settings.config.PlanConfig; +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; +import com.djrapitops.plugin.task.RunnableFactory; import com.zaxxer.hikari.HikariConfig; import com.zaxxer.hikari.HikariDataSource; +import dagger.Lazy; +import javax.inject.Inject; import javax.sql.DataSource; import java.sql.Connection; import java.sql.SQLException; import java.util.Objects; -import java.util.function.Supplier; +import java.util.concurrent.TimeUnit; /** * @author Rsl1122 @@ -25,8 +33,18 @@ public class MySQLDB extends SQLDB { protected volatile DataSource dataSource; - public MySQLDB(Supplier locale) { - super(locale); + @Inject + public MySQLDB( + Locale locale, + PlanConfig config, + Lazy serverInfo, + NetworkContainer.Factory networkContainerFactory, + RunnableFactory runnableFactory, + PluginLogger pluginLogger, + Timings timings, + ErrorHandler errorHandler + ) { + super(() -> serverInfo.get().getServerUUID(), locale, config, networkContainerFactory, runnableFactory, pluginLogger, timings, errorHandler); } private static synchronized void increment() { @@ -47,33 +65,33 @@ public class MySQLDB extends SQLDB { @Override public void setupDataSource() throws DBInitException { try { - HikariConfig config = new HikariConfig(); + HikariConfig hikariConfig = new HikariConfig(); - String host = Settings.DB_HOST.toString(); - String port = Integer.toString(Settings.DB_PORT.getNumber()); - String database = Settings.DB_DATABASE.toString(); - String launchOptions = Settings.DB_LAUNCH_OPTIONS.toString(); + String host = config.getString(Settings.DB_HOST); + String port = config.getString(Settings.DB_PORT); + String database = config.getString(Settings.DB_DATABASE); + String launchOptions = config.getString(Settings.DB_LAUNCH_OPTIONS); if (launchOptions.isEmpty() || !launchOptions.startsWith("?") || launchOptions.endsWith("&")) { launchOptions = "?rewriteBatchedStatements=true&useSSL=false"; - Log.error(locale.get().getString(PluginLang.DB_MYSQL_LAUNCH_OPTIONS_FAIL, launchOptions)); + logger.error(locale.getString(PluginLang.DB_MYSQL_LAUNCH_OPTIONS_FAIL, launchOptions)); } - config.setJdbcUrl("jdbc:mysql://" + host + ":" + port + "/" + database + launchOptions); + hikariConfig.setJdbcUrl("jdbc:mysql://" + host + ":" + port + "/" + database + launchOptions); - String username = Settings.DB_USER.toString(); - String password = Settings.DB_PASS.toString(); + String username = config.getString(Settings.DB_USER); + String password = config.getString(Settings.DB_PASS); - config.setUsername(username); - config.setPassword(password); + hikariConfig.setUsername(username); + hikariConfig.setPassword(password); - config.setPoolName("Plan Connection Pool-" + increment); + hikariConfig.setPoolName("Plan Connection Pool-" + increment); increment(); - config.setAutoCommit(true); - config.setMaximumPoolSize(8); - config.setMaxLifetime(25L * TimeAmount.MINUTE.ms()); - config.setLeakDetectionThreshold(10L * TimeAmount.MINUTE.ms()); + hikariConfig.setAutoCommit(true); + hikariConfig.setMaximumPoolSize(8); + hikariConfig.setMaxLifetime(TimeUnit.MINUTES.toMillis(25L)); + hikariConfig.setLeakDetectionThreshold(TimeUnit.MINUTES.toMillis(10L)); - this.dataSource = new HikariDataSource(config); + this.dataSource = new HikariDataSource(hikariConfig); getConnection(); } catch (SQLException e) { @@ -115,7 +133,7 @@ public class MySQLDB extends SQLDB { connection.close(); } } catch (SQLException e) { - Log.toLog(this.getClass(), e); + errorHandler.log(L.ERROR, this.getClass(), e); } } @@ -124,6 +142,11 @@ public class MySQLDB extends SQLDB { returnToPool(connection); } + @Override + public boolean isUsingMySQL() { + return true; + } + @Override public boolean equals(Object o) { if (this == o) return true; diff --git a/Plan/src/main/java/com/djrapitops/plan/system/database/databases/sql/PatchTask.java b/Plan/src/main/java/com/djrapitops/plan/system/database/databases/sql/PatchTask.java index 3a5f79711..a72d00d9f 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/database/databases/sql/PatchTask.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/database/databases/sql/PatchTask.java @@ -1,14 +1,13 @@ package com.djrapitops.plan.system.database.databases.sql; -import com.djrapitops.plan.PlanPlugin; import com.djrapitops.plan.system.database.databases.sql.patches.Patch; import com.djrapitops.plan.system.locale.Locale; import com.djrapitops.plan.system.locale.lang.PluginLang; -import com.djrapitops.plugin.api.utility.log.Log; +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.function.Supplier; - /** * Task that is in charge on patching the database when the database enables. * @@ -17,26 +16,30 @@ import java.util.function.Supplier; public class PatchTask extends AbsRunnable { private final Patch[] patches; - private final Supplier locale; - public PatchTask(Patch[] patches, Supplier locale) { + private final Locale locale; + private final PluginLogger logger; + private final ErrorHandler errorHandler; + + public PatchTask(Patch[] patches, Locale locale, PluginLogger logger, ErrorHandler errorHandler) { this.patches = patches; this.locale = locale; + this.logger = logger; + this.errorHandler = errorHandler; } @Override public void run() { try { - boolean didApply = applyPatches(); - Log.info(locale.get().getString( - didApply ? PluginLang.DB_APPLIED_PATCHES : PluginLang.DB_APPLIED_PATCHES_ALREADY + boolean applied = applyPatches(); + logger.info(locale.getString( + applied ? PluginLang.DB_APPLIED_PATCHES : PluginLang.DB_APPLIED_PATCHES_ALREADY )); } catch (Exception e) { - Log.error("----------------------------------------------------"); - Log.error(locale.get().getString(PluginLang.ENABLE_FAIL_DB_PATCH)); - Log.error("----------------------------------------------------"); - Log.toLog(this.getClass(), e); - PlanPlugin.getInstance().onDisable(); + logger.error("----------------------------------------------------"); + logger.error(locale.getString(PluginLang.ENABLE_FAIL_DB_PATCH)); + logger.error("----------------------------------------------------"); + errorHandler.log(L.CRITICAL, this.getClass(), e); } } @@ -45,7 +48,7 @@ public class PatchTask extends AbsRunnable { for (Patch patch : patches) { if (!patch.hasBeenApplied()) { String patchName = patch.getClass().getSimpleName(); - Log.info(locale.get().getString(PluginLang.DB_APPLY_PATCH, patchName)); + logger.info(locale.getString(PluginLang.DB_APPLY_PATCH, patchName)); patch.apply(); didApply = true; } diff --git a/Plan/src/main/java/com/djrapitops/plan/system/database/databases/sql/SQLDB.java b/Plan/src/main/java/com/djrapitops/plan/system/database/databases/sql/SQLDB.java index 46b376125..f5c1b1cf7 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/database/databases/sql/SQLDB.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/database/databases/sql/SQLDB.java @@ -2,6 +2,7 @@ package com.djrapitops.plan.system.database.databases.sql; import com.djrapitops.plan.api.exceptions.database.DBInitException; import com.djrapitops.plan.api.exceptions.database.DBOpException; +import com.djrapitops.plan.data.store.containers.NetworkContainer; import com.djrapitops.plan.system.database.databases.Database; import com.djrapitops.plan.system.database.databases.operation.*; import com.djrapitops.plan.system.database.databases.sql.operation.*; @@ -12,10 +13,14 @@ import com.djrapitops.plan.system.database.databases.sql.tables.*; import com.djrapitops.plan.system.locale.Locale; import com.djrapitops.plan.system.locale.lang.PluginLang; import com.djrapitops.plan.system.settings.Settings; +import com.djrapitops.plan.system.settings.config.PlanConfig; import com.djrapitops.plugin.api.TimeAmount; -import com.djrapitops.plugin.api.utility.log.Log; +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; import com.djrapitops.plugin.task.AbsRunnable; -import com.djrapitops.plugin.task.ITask; +import com.djrapitops.plugin.task.PluginTask; import com.djrapitops.plugin.task.RunnableFactory; import com.djrapitops.plugin.utilities.Verify; @@ -26,6 +31,7 @@ import java.util.List; import java.util.Map; import java.util.Objects; import java.util.UUID; +import java.util.concurrent.TimeUnit; import java.util.function.Supplier; import java.util.stream.Collectors; @@ -37,7 +43,15 @@ import java.util.stream.Collectors; */ public abstract class SQLDB extends Database { - protected final Supplier locale; + private final Supplier serverUUIDSupplier; + + protected final Locale locale; + protected final PlanConfig config; + protected final NetworkContainer.Factory networkContainerFactory; + protected final RunnableFactory runnableFactory; + protected final PluginLogger logger; + protected final Timings timings; + protected final ErrorHandler errorHandler; private final UsersTable usersTable; private final UserInfoTable userInfoTable; @@ -63,12 +77,25 @@ public abstract class SQLDB extends Database { private final SQLSaveOps saveOps; private final SQLTransferOps transferOps; - private final boolean usingMySQL; - private ITask dbCleanTask; + private PluginTask dbCleanTask; - public SQLDB(Supplier locale) { + public SQLDB( + Supplier serverUUIDSupplier, + Locale locale, + PlanConfig config, + NetworkContainer.Factory networkContainerFactory, RunnableFactory runnableFactory, + PluginLogger logger, + Timings timings, + ErrorHandler errorHandler + ) { + this.serverUUIDSupplier = serverUUIDSupplier; this.locale = locale; - usingMySQL = this instanceof MySQLDB; + this.config = config; + this.networkContainerFactory = networkContainerFactory; + this.runnableFactory = runnableFactory; + this.logger = logger; + this.timings = timings; + this.errorHandler = errorHandler; serverTable = new ServerTable(this); securityTable = new SecurityTable(this); @@ -116,7 +143,7 @@ public abstract class SQLDB extends Database { @Override public void scheduleClean(long secondsDelay) { - dbCleanTask = RunnableFactory.createNew("DB Clean Task", new AbsRunnable() { + dbCleanTask = runnableFactory.create("DB Clean Task", new AbsRunnable() { @Override public void run() { try { @@ -124,11 +151,11 @@ public abstract class SQLDB extends Database { clean(); } } catch (DBOpException e) { - Log.toLog(this.getClass(), e); + errorHandler.log(L.ERROR, this.getClass(), e); cancel(); } } - }).runTaskTimerAsynchronously(TimeAmount.SECOND.ticks() * secondsDelay, TimeAmount.MINUTE.ticks() * 5L); + }).runTaskTimerAsynchronously(TimeAmount.toTicks(secondsDelay, TimeUnit.SECONDS), TimeAmount.toTicks(5L, TimeUnit.MINUTES)); } /** @@ -153,12 +180,13 @@ public abstract class SQLDB extends Database { new IPHashPatch(this), new IPAnonPatch(this), new NicknameLastSeenPatch(this), - new VersionTableRemovalPatch(this) + new VersionTableRemovalPatch(this), + new DiskUsagePatch(this) }; try { - RunnableFactory.createNew("Database Patch", new PatchTask(patches, locale)) - .runTaskLaterAsynchronously(TimeAmount.SECOND.ticks() * 5L); + runnableFactory.create("Database Patch", new PatchTask(patches, locale, logger, errorHandler)) + .runTaskLaterAsynchronously(TimeAmount.toTicks(5L, TimeUnit.SECONDS)); } catch (Exception ignore) { // Task failed to register because plugin is being disabled } @@ -222,7 +250,7 @@ public abstract class SQLDB extends Database { pingTable.clean(); long now = System.currentTimeMillis(); - long keepActiveAfter = now - TimeAmount.DAY.ms() * Settings.KEEP_INACTIVE_PLAYERS_DAYS.getNumber(); + long keepActiveAfter = now - TimeUnit.DAYS.toMillis(config.getNumber(Settings.KEEP_INACTIVE_PLAYERS_DAYS)); List inactivePlayers = sessionsTable.getLastSeenForAllPlayers().entrySet().stream() .filter(entry -> entry.getValue() < keepActiveAfter) @@ -233,7 +261,7 @@ public abstract class SQLDB extends Database { } int removed = inactivePlayers.size(); if (removed > 0) { - Log.info(locale.get().getString(PluginLang.DB_NOTIFY_CLEAN, removed)); + logger.info(locale.getString(PluginLang.DB_NOTIFY_CLEAN, removed)); } } @@ -243,25 +271,14 @@ public abstract class SQLDB extends Database { public abstract void returnToPool(Connection connection); - /** - * Reverts transaction when using SQLite Database. - *

- * MySQL has Auto Commit enabled. - */ - public void rollback(Connection connection) throws SQLException { - try { - if (!usingMySQL) { - connection.rollback(); - } - } finally { - returnToPool(connection); - } - } - public boolean execute(ExecStatement statement) { Connection connection = null; try { connection = getConnection(); + // Inject Timings to the statement for benchmarking + if (config.isTrue(Settings.DEV_MODE)) { + statement.setTimings(timings); + } try (PreparedStatement preparedStatement = connection.prepareStatement(statement.getSql())) { return statement.execute(preparedStatement); } @@ -287,8 +304,8 @@ public abstract class SQLDB extends Database { try { execute(statement); } catch (DBOpException e) { - if (Settings.DEV_MODE.isTrue()) { - Log.toLog(this.getClass(), e); + if (config.isTrue(Settings.DEV_MODE)) { + errorHandler.log(L.ERROR, this.getClass(), e); } } } @@ -298,6 +315,10 @@ public abstract class SQLDB extends Database { Connection connection = null; try { connection = getConnection(); + // Inject Timings to the statement for benchmarking + if (config.isTrue(Settings.DEV_MODE)) { + statement.setTimings(timings); + } try (PreparedStatement preparedStatement = connection.prepareStatement(statement.getSql())) { statement.executeBatch(preparedStatement); } @@ -312,6 +333,10 @@ public abstract class SQLDB extends Database { Connection connection = null; try { connection = getConnection(); + // Inject Timings to the statement for benchmarking + if (config.isTrue(Settings.DEV_MODE)) { + statement.setTimings(timings); + } try (PreparedStatement preparedStatement = connection.prepareStatement(statement.getSql())) { return statement.executeQuery(preparedStatement); } @@ -379,7 +404,7 @@ public abstract class SQLDB extends Database { } public boolean isUsingMySQL() { - return usingMySQL; + return false; } @Override @@ -427,11 +452,23 @@ public abstract class SQLDB extends Database { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; SQLDB sqldb = (SQLDB) o; - return usingMySQL == sqldb.usingMySQL && getName().equals(sqldb.getName()); + return getName().equals(sqldb.getName()); } @Override public int hashCode() { - return Objects.hash(usingMySQL, getName()); + return Objects.hash(getName()); + } + + public Supplier getServerUUIDSupplier() { + return serverUUIDSupplier; + } + + public PlanConfig getConfig() { + return config; + } + + public NetworkContainer.Factory getNetworkContainerFactory() { + return networkContainerFactory; } } diff --git a/Plan/src/main/java/com/djrapitops/plan/system/database/databases/sql/SQLiteDB.java b/Plan/src/main/java/com/djrapitops/plan/system/database/databases/sql/SQLiteDB.java index 3890c0e93..f3353d175 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/database/databases/sql/SQLiteDB.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/database/databases/sql/SQLiteDB.java @@ -1,19 +1,27 @@ package com.djrapitops.plan.system.database.databases.sql; -import com.djrapitops.plan.PlanPlugin; import com.djrapitops.plan.api.exceptions.database.DBInitException; +import com.djrapitops.plan.data.store.containers.NetworkContainer; +import com.djrapitops.plan.system.file.PlanFiles; +import com.djrapitops.plan.system.info.server.ServerInfo; import com.djrapitops.plan.system.locale.Locale; import com.djrapitops.plan.system.locale.lang.PluginLang; +import com.djrapitops.plan.system.settings.config.PlanConfig; import com.djrapitops.plan.utilities.MiscUtils; -import com.djrapitops.plugin.api.utility.log.Log; +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; import com.djrapitops.plugin.task.AbsRunnable; -import com.djrapitops.plugin.task.ITask; +import com.djrapitops.plugin.task.PluginTask; import com.djrapitops.plugin.task.RunnableFactory; +import dagger.Lazy; +import javax.inject.Inject; +import javax.inject.Singleton; import java.io.File; import java.sql.*; import java.util.Objects; -import java.util.function.Supplier; /** * @author Rsl1122 @@ -23,18 +31,20 @@ public class SQLiteDB extends SQLDB { private final File databaseFile; private final String dbName; private Connection connection; - private ITask connectionPingTask; + private PluginTask connectionPingTask; - public SQLiteDB(Supplier locale) { - this("database", locale); - } - - public SQLiteDB(String dbName, Supplier locale) { - this(new File(PlanPlugin.getInstance().getDataFolder(), dbName + ".db"), locale); - } - - public SQLiteDB(File databaseFile, Supplier locale) { - super(locale); + private SQLiteDB( + File databaseFile, + Locale locale, + PlanConfig config, + Lazy serverInfo, + NetworkContainer.Factory networkContainerFactory, + RunnableFactory runnableFactory, + PluginLogger logger, + Timings timings, + ErrorHandler errorHandler + ) { + super(() -> serverInfo.get().getServerUUID(), locale, config, networkContainerFactory, runnableFactory, logger, timings, errorHandler); dbName = databaseFile.getName(); this.databaseFile = databaseFile; } @@ -53,14 +63,14 @@ public class SQLiteDB extends SQLDB { try { Class.forName("org.sqlite.JDBC"); } catch (ClassNotFoundException e) { - Log.toLog(this.getClass(), e); + errorHandler.log(L.CRITICAL, this.getClass(), e); return null; // Should never happen. } String dbFilePath = dbFile.getAbsolutePath(); Connection newConnection = getConnectionFor(dbFilePath); - Log.debug("SQLite " + dbName + ": Opened a new Connection"); + logger.debug("SQLite " + dbName + ": Opened a new Connection"); newConnection.setAutoCommit(false); return newConnection; } @@ -69,7 +79,7 @@ public class SQLiteDB extends SQLDB { try { return DriverManager.getConnection("jdbc:sqlite:" + dbFilePath + "?journal_mode=WAL"); } catch (SQLException ignored) { - Log.info(locale.get().getString(PluginLang.DB_NOTIFY_SQLITE_WAL)); + logger.info(locale.getString(PluginLang.DB_NOTIFY_SQLITE_WAL)); return DriverManager.getConnection("jdbc:sqlite:" + dbFilePath); } } @@ -78,7 +88,7 @@ public class SQLiteDB extends SQLDB { stopConnectionPingTask(); try { // Maintains Connection. - connectionPingTask = RunnableFactory.createNew(new AbsRunnable("DBConnectionPingTask " + getName()) { + connectionPingTask = runnableFactory.create("DBConnectionPingTask " + getName(), new AbsRunnable() { @Override public void run() { Statement statement = null; @@ -89,12 +99,12 @@ public class SQLiteDB extends SQLDB { resultSet = statement.executeQuery("/* ping */ SELECT 1"); } } catch (SQLException e) { - Log.debug("Something went wrong during SQLite Connection upkeep task."); + logger.debug("Something went wrong during SQLite Connection upkeep task."); try { connection = getNewConnection(databaseFile); } catch (SQLException e1) { - Log.toLog(this.getClass(), e1); - Log.error("SQLite connection maintaining task had to be closed due to exception."); + errorHandler.log(L.ERROR, this.getClass(), e1); + logger.error("SQLite connection maintaining task had to be closed due to exception."); this.cancel(); } } finally { @@ -135,7 +145,7 @@ public class SQLiteDB extends SQLDB { public void close() { stopConnectionPingTask(); if (connection != null) { - Log.debug("SQLite " + dbName + ": Closed Connection"); + logger.debug("SQLite " + dbName + ": Closed Connection"); MiscUtils.close(connection); } super.close(); @@ -147,7 +157,7 @@ public class SQLiteDB extends SQLDB { connection.commit(); } catch (SQLException e) { if (!e.getMessage().contains("cannot commit")) { - Log.toLog(this.getClass(), e); + errorHandler.log(L.ERROR, this.getClass(), e); } } } @@ -170,4 +180,58 @@ public class SQLiteDB extends SQLDB { public int hashCode() { return Objects.hash(super.hashCode(), dbName); } + + @Singleton + public static class Factory { + + private final Locale locale; + private final PlanConfig config; + private final Lazy serverInfo; + private final NetworkContainer.Factory networkContainerFactory; + private final RunnableFactory runnableFactory; + private final PluginLogger logger; + private final Timings timings; + private final ErrorHandler errorHandler; + private PlanFiles files; + + @Inject + public Factory( + Locale locale, + PlanConfig config, + PlanFiles files, + Lazy serverInfo, + NetworkContainer.Factory networkContainerFactory, + RunnableFactory runnableFactory, + PluginLogger logger, + Timings timings, + ErrorHandler errorHandler + ) { + this.locale = locale; + this.config = config; + this.files = files; + this.serverInfo = serverInfo; + this.networkContainerFactory = networkContainerFactory; + this.runnableFactory = runnableFactory; + this.logger = logger; + this.timings = timings; + this.errorHandler = errorHandler; + } + + public SQLiteDB usingDefaultFile() { + return usingFileCalled("database"); + } + + public SQLiteDB usingFileCalled(String fileName) { + return usingFile(files.getFileFromPluginFolder(fileName + ".db")); + } + + public SQLiteDB usingFile(File databaseFile) { + return new SQLiteDB(databaseFile, + locale, config, serverInfo, + networkContainerFactory, + runnableFactory, logger, timings, errorHandler + ); + } + + } } diff --git a/Plan/src/main/java/com/djrapitops/plan/system/database/databases/sql/SpongeMySQLDB.java b/Plan/src/main/java/com/djrapitops/plan/system/database/databases/sql/SpongeMySQLDB.java index 7a9409d6b..e9a688e8b 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/database/databases/sql/SpongeMySQLDB.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/database/databases/sql/SpongeMySQLDB.java @@ -1,16 +1,23 @@ package com.djrapitops.plan.system.database.databases.sql; import com.djrapitops.plan.api.exceptions.database.DBInitException; +import com.djrapitops.plan.data.store.containers.NetworkContainer; +import com.djrapitops.plan.system.info.server.ServerInfo; import com.djrapitops.plan.system.locale.Locale; import com.djrapitops.plan.system.settings.Settings; -import com.djrapitops.plugin.api.utility.log.Log; +import com.djrapitops.plan.system.settings.config.PlanConfig; +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.Lazy; import org.spongepowered.api.Sponge; import org.spongepowered.api.service.sql.SqlService; +import javax.inject.Inject; import java.sql.Connection; import java.sql.SQLException; import java.util.Optional; -import java.util.function.Supplier; /** * MySQLDB implementation for Sponge since default driver is not available. @@ -19,8 +26,18 @@ import java.util.function.Supplier; */ public class SpongeMySQLDB extends MySQLDB { - public SpongeMySQLDB(Supplier locale) { - super(locale); + @Inject + public SpongeMySQLDB( + Locale locale, + PlanConfig config, + Lazy serverInfo, + NetworkContainer.Factory networkContainerFactory, + RunnableFactory runnableFactory, + PluginLogger pluginLogger, + Timings timings, + ErrorHandler errorHandler + ) { + super(locale, config, serverInfo, networkContainerFactory, runnableFactory, pluginLogger, timings, errorHandler); } @Override @@ -30,18 +47,18 @@ public class SpongeMySQLDB extends MySQLDB { return; } - String host = Settings.DB_HOST.toString(); - String port = Integer.toString(Settings.DB_PORT.getNumber()); - String database = Settings.DB_DATABASE.toString(); - String launchOptions = Settings.DB_LAUNCH_OPTIONS.toString(); + String host = config.getString(Settings.DB_HOST); + String port = config.getString(Settings.DB_PORT); + String database = config.getString(Settings.DB_DATABASE); + String launchOptions = config.getString(Settings.DB_LAUNCH_OPTIONS); if (launchOptions.isEmpty() || !launchOptions.startsWith("?") || launchOptions.endsWith("&")) { - Log.error("Launch Options were faulty, using default (?rewriteBatchedStatements=true&useSSL=false)"); + logger.error("Launch Options were faulty, using default (?rewriteBatchedStatements=true&useSSL=false)"); launchOptions = "?rewriteBatchedStatements=true&useSSL=false"; } String url = host + ":" + port + "/" + database + launchOptions; - String username = Settings.DB_USER.toString(); - String password = Settings.DB_PASS.toString(); + String username = config.getString(Settings.DB_USER); + String password = config.getString(Settings.DB_PASS); try { this.dataSource = sqlServiceProvider.get().getDataSource( "jdbc:mysql://" + username + ":" + password + "@" + url diff --git a/Plan/src/main/java/com/djrapitops/plan/system/database/databases/sql/operation/SQLBackupOps.java b/Plan/src/main/java/com/djrapitops/plan/system/database/databases/sql/operation/SQLBackupOps.java index 801ddb68a..af34c3ff1 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/database/databases/sql/operation/SQLBackupOps.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/database/databases/sql/operation/SQLBackupOps.java @@ -13,11 +13,15 @@ public class SQLBackupOps extends SQLOps implements BackupOperations { @Override public void backup(Database toDatabase) { - BatchOperationTable toDB = new BatchOperationTable((SQLDB) toDatabase); - BatchOperationTable fromDB = new BatchOperationTable(db); + if (toDatabase instanceof SQLDB) { + BatchOperationTable toDB = new BatchOperationTable((SQLDB) toDatabase); + BatchOperationTable fromDB = new BatchOperationTable(db); - toDB.removeAllData(); - fromDB.copyEverything(toDB); + toDB.removeAllData(); + fromDB.copyEverything(toDB); + } else { + throw new IllegalArgumentException("Database was not a SQL database - backup not implemented."); + } } @Override diff --git a/Plan/src/main/java/com/djrapitops/plan/system/database/databases/sql/operation/SQLCheckOps.java b/Plan/src/main/java/com/djrapitops/plan/system/database/databases/sql/operation/SQLCheckOps.java index 121d9c961..2e0bac214 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/database/databases/sql/operation/SQLCheckOps.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/database/databases/sql/operation/SQLCheckOps.java @@ -2,7 +2,6 @@ package com.djrapitops.plan.system.database.databases.sql.operation; import com.djrapitops.plan.system.database.databases.operation.CheckOperations; import com.djrapitops.plan.system.database.databases.sql.SQLDB; -import com.djrapitops.plan.system.info.server.ServerInfo; import java.util.UUID; @@ -23,13 +22,13 @@ public class SQLCheckOps extends SQLOps implements CheckOperations { } @Override - public boolean doesWebUserExists(String username) { - return securityTable.userExists(username); + public boolean isPlayerRegisteredOnThisServer(UUID player) { + return userInfoTable.isRegisteredOnThisServer(player); } @Override - public boolean isPlayerRegisteredOnThisServer(UUID player) { - return isPlayerRegistered(player, ServerInfo.getServerUUID()); + public boolean doesWebUserExists(String username) { + return securityTable.userExists(username); } @Override diff --git a/Plan/src/main/java/com/djrapitops/plan/system/database/databases/sql/operation/SQLFetchOps.java b/Plan/src/main/java/com/djrapitops/plan/system/database/databases/sql/operation/SQLFetchOps.java index 7868a8873..c9a379ebe 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/database/databases/sql/operation/SQLFetchOps.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/database/databases/sql/operation/SQLFetchOps.java @@ -13,7 +13,6 @@ import com.djrapitops.plan.system.cache.SessionCache; import com.djrapitops.plan.system.database.databases.operation.FetchOperations; import com.djrapitops.plan.system.database.databases.sql.SQLDB; import com.djrapitops.plan.system.info.server.Server; -import com.djrapitops.plan.system.info.server.ServerInfo; import java.util.*; import java.util.concurrent.TimeUnit; @@ -26,7 +25,7 @@ public class SQLFetchOps extends SQLOps implements FetchOperations { @Override public NetworkContainer getNetworkContainer() { - NetworkContainer networkContainer = new NetworkContainer(getBungeeServerContainer()); + NetworkContainer networkContainer = db.getNetworkContainerFactory().forBungeeContainer(getBungeeServerContainer()); networkContainer.putCachingSupplier(NetworkKeys.BUKKIT_SERVERS, () -> getBukkitServers().values()); return networkContainer; } @@ -72,7 +71,7 @@ public class SQLFetchOps extends SQLOps implements FetchOperations { return null; }); container.putCachingSupplier(ServerKeys.RECENT_PEAK_PLAYERS, () -> { - long twoDaysAgo = System.currentTimeMillis() - TimeUnit.DAYS.toMillis(2); + long twoDaysAgo = System.currentTimeMillis() - (TimeUnit.DAYS.toMillis(2L)); Optional lastPeak = tpsTable.getPeakPlayerCount(serverUUID, twoDaysAgo); if (lastPeak.isPresent()) { TPS peak = lastPeak.get(); @@ -88,7 +87,7 @@ public class SQLFetchOps extends SQLOps implements FetchOperations { container.putCachingSupplier(ServerKeys.OPERATORS, () -> PlayersMutator.forContainer(container).operators()); container.putCachingSupplier(ServerKeys.SESSIONS, () -> { List sessions = PlayersMutator.forContainer(container).getSessions(); - if (serverUUID.equals(ServerInfo.getServerUUID())) { + if (serverUUID.equals(serverInfo.get().getUuid())) { sessions.addAll(SessionCache.getActiveSessions().values()); } return sessions; @@ -469,4 +468,13 @@ public class SQLFetchOps extends SQLOps implements FetchOperations { return serverTable.getServerUUIDs(); } + @Override + public Map> getPlayersOnlineForServers(Collection servers) { + return tpsTable.getPlayersOnlineForServers(servers); + } + + @Override + public Map getPlayersRegisteredForServers(Collection servers) { + return userInfoTable.getPlayersRegisteredForServers(servers); + } } diff --git a/Plan/src/main/java/com/djrapitops/plan/system/database/databases/sql/operation/SQLSearchOps.java b/Plan/src/main/java/com/djrapitops/plan/system/database/databases/sql/operation/SQLSearchOps.java index 75d8f04c6..576118da5 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/database/databases/sql/operation/SQLSearchOps.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/database/databases/sql/operation/SQLSearchOps.java @@ -3,6 +3,7 @@ package com.djrapitops.plan.system.database.databases.sql.operation; import com.djrapitops.plan.system.database.databases.operation.SearchOperations; import com.djrapitops.plan.system.database.databases.sql.SQLDB; +import java.util.Collections; import java.util.List; public class SQLSearchOps extends SQLOps implements SearchOperations { @@ -13,6 +14,8 @@ public class SQLSearchOps extends SQLOps implements SearchOperations { @Override public List matchingPlayers(String search) { - return usersTable.getMatchingNames(search); + List matchingNames = usersTable.getMatchingNames(search); + Collections.sort(matchingNames); + return matchingNames; } } diff --git a/Plan/src/main/java/com/djrapitops/plan/system/database/databases/sql/patches/DiskUsagePatch.java b/Plan/src/main/java/com/djrapitops/plan/system/database/databases/sql/patches/DiskUsagePatch.java new file mode 100644 index 000000000..d4bc50421 --- /dev/null +++ b/Plan/src/main/java/com/djrapitops/plan/system/database/databases/sql/patches/DiskUsagePatch.java @@ -0,0 +1,23 @@ +package com.djrapitops.plan.system.database.databases.sql.patches; + +import com.djrapitops.plan.system.database.databases.sql.SQLDB; +import com.djrapitops.plan.system.database.databases.sql.tables.TPSTable; + +public class DiskUsagePatch extends Patch { + + public DiskUsagePatch(SQLDB db) { + super(db); + } + + @Override + public boolean hasBeenApplied() { + return hasColumn(TPSTable.TABLE_NAME, TPSTable.Col.FREE_DISK.get()); + } + + @Override + public void apply() { + addColumn(TPSTable.TABLE_NAME, + TPSTable.Col.FREE_DISK + " bigint NOT NULL DEFAULT -1" + ); + } +} diff --git a/Plan/src/main/java/com/djrapitops/plan/system/database/databases/sql/patches/IPAnonPatch.java b/Plan/src/main/java/com/djrapitops/plan/system/database/databases/sql/patches/IPAnonPatch.java index 353c2153a..4955fbe86 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/database/databases/sql/patches/IPAnonPatch.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/database/databases/sql/patches/IPAnonPatch.java @@ -8,8 +8,6 @@ import com.djrapitops.plan.system.database.databases.sql.processing.ExecStatemen import com.djrapitops.plan.system.database.databases.sql.processing.QueryStatement; import com.djrapitops.plan.system.database.databases.sql.tables.GeoInfoTable; import com.djrapitops.plan.system.database.databases.sql.tables.move.Version18TransferTable; -import com.djrapitops.plan.system.settings.Settings; -import com.djrapitops.plugin.api.utility.log.Log; import java.net.InetAddress; import java.net.UnknownHostException; @@ -83,10 +81,8 @@ public class IPAnonPatch extends Patch { statement.setString(2, updatedInfo.getIpHash()); statement.setString(3, geoInfo.getIp()); statement.addBatch(); - } catch (UnknownHostException | NoSuchAlgorithmException e) { - if (Settings.DEV_MODE.isTrue()) { - Log.toLog(this.getClass(), e); - } + } catch (UnknownHostException | NoSuchAlgorithmException ignore) { + // This ip is already anonymised or completely unusable. } } }); diff --git a/Plan/src/main/java/com/djrapitops/plan/system/database/databases/sql/patches/Patch.java b/Plan/src/main/java/com/djrapitops/plan/system/database/databases/sql/patches/Patch.java index 9ad3c26b5..921eb3c44 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/database/databases/sql/patches/Patch.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/database/databases/sql/patches/Patch.java @@ -9,6 +9,7 @@ import com.djrapitops.plan.system.settings.Settings; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; +import java.util.UUID; public abstract class Patch { @@ -38,7 +39,7 @@ public abstract class Patch { public void prepare(PreparedStatement statement) throws SQLException { statement.setString(1, tableName); if (usingMySQL) { - statement.setString(2, Settings.DB_DATABASE.toString()); + statement.setString(2, db.getConfig().getString(Settings.DB_DATABASE)); } } @@ -57,7 +58,7 @@ public abstract class Patch { public void prepare(PreparedStatement statement) throws SQLException { statement.setString(1, tableName); statement.setString(2, columnName); - statement.setString(3, Settings.DB_DATABASE.toString()); + statement.setString(3, db.getConfig().getString(Settings.DB_DATABASE)); } @Override @@ -93,4 +94,7 @@ public abstract class Patch { db.execute(sql); } + protected UUID getServerUUID() { + return db.getServerUUIDSupplier().get(); + } } diff --git a/Plan/src/main/java/com/djrapitops/plan/system/database/databases/sql/patches/Version10Patch.java b/Plan/src/main/java/com/djrapitops/plan/system/database/databases/sql/patches/Version10Patch.java index e55f65eb7..5cad46a01 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/database/databases/sql/patches/Version10Patch.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/database/databases/sql/patches/Version10Patch.java @@ -4,8 +4,6 @@ import com.djrapitops.plan.api.exceptions.database.DBInitException; import com.djrapitops.plan.api.exceptions.database.DBOpException; import com.djrapitops.plan.system.database.databases.sql.SQLDB; import com.djrapitops.plan.system.database.databases.sql.tables.*; -import com.djrapitops.plan.system.info.server.ServerInfo; -import com.djrapitops.plugin.api.Benchmark; import java.util.Optional; @@ -25,7 +23,7 @@ public class Version10Patch extends Patch { @Override public void apply() { try { - Optional fetchedServerID = db.getServerTable().getServerID(ServerInfo.getServerUUID()); + Optional fetchedServerID = db.getServerTable().getServerID(getServerUUID()); if (!fetchedServerID.isPresent()) { throw new IllegalStateException("Server UUID was not registered, try rebooting the plugin."); } @@ -37,7 +35,6 @@ public class Version10Patch extends Patch { } public void alterTablesToV10() throws DBInitException { - Benchmark.start("Schema copy from 8 to 10"); copyCommandUsage(); copyTPS(); @@ -56,7 +53,6 @@ public class Version10Patch extends Patch { dropTable("temp_nicks"); dropTable("temp_kills"); dropTable("temp_users"); - Benchmark.stop("Schema copy from 8 to 10"); } private void copyUsers() throws DBInitException { diff --git a/Plan/src/main/java/com/djrapitops/plan/system/database/databases/sql/processing/AbstractSQLStatement.java b/Plan/src/main/java/com/djrapitops/plan/system/database/databases/sql/processing/AbstractSQLStatement.java new file mode 100644 index 000000000..d49d0766e --- /dev/null +++ b/Plan/src/main/java/com/djrapitops/plan/system/database/databases/sql/processing/AbstractSQLStatement.java @@ -0,0 +1,50 @@ +package com.djrapitops.plan.system.database.databases.sql.processing; + +import com.djrapitops.plan.system.DebugChannels; +import com.djrapitops.plugin.benchmarking.Timings; + +/** + * Abstract class that performs an SQL statement. + *

+ * For Benchmarking purposes. + * + * @author Rsl1122 + */ +public abstract class AbstractSQLStatement { + + protected final String sql; + + private Timings timings; + + protected AbstractSQLStatement(String sql) { + this.sql = sql; + } + + protected void startBenchmark() { + if (timings != null) { + timings.start(DebugChannels.SQL + ": " + sql); + } + } + + protected void startBatchBenchmark() { + if (timings != null) { + timings.start(DebugChannels.SQL + ": " + sql + " (Batch)"); + } + } + + protected void stopBenchmark() { + if (timings != null) { + timings.end(DebugChannels.SQL, DebugChannels.SQL + ": " + sql); + } + } + + protected void stopBatchBenchmark() { + if (timings != null) { + timings.end(DebugChannels.SQL, DebugChannels.SQL + ": " + sql + " (Batch)"); + } + } + + public void setTimings(Timings timings) { + this.timings = timings; + } +} \ No newline at end of file diff --git a/Plan/src/main/java/com/djrapitops/plan/system/database/databases/sql/processing/ExecStatement.java b/Plan/src/main/java/com/djrapitops/plan/system/database/databases/sql/processing/ExecStatement.java index 9d266f116..a5d97a237 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/database/databases/sql/processing/ExecStatement.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/database/databases/sql/processing/ExecStatement.java @@ -4,10 +4,6 @@ */ package com.djrapitops.plan.system.database.databases.sql.processing; -import com.djrapitops.plan.system.settings.Settings; -import com.djrapitops.plugin.api.Benchmark; -import com.djrapitops.plugin.api.utility.log.Log; - import java.sql.PreparedStatement; import java.sql.SQLException; @@ -16,39 +12,31 @@ import java.sql.SQLException; * * @author Rsl1122 */ -public abstract class ExecStatement { - - private final String sql; - private final boolean devMode; +public abstract class ExecStatement extends AbstractSQLStatement { public ExecStatement(String sql) { - this.sql = sql; - devMode = Settings.DEV_MODE.isTrue(); + super(sql); } public boolean execute(PreparedStatement statement) throws SQLException { - Benchmark.start("SQL: " + sql); + startBenchmark(); try { prepare(statement); return statement.executeUpdate() > 0; } finally { statement.close(); - if (devMode) { - Log.debug(Benchmark.stopAndFormat("SQL: " + sql)); - } + stopBenchmark(); } } public void executeBatch(PreparedStatement statement) throws SQLException { - Benchmark.start("SQL: " + sql + " (Batch)"); + startBatchBenchmark(); try { prepare(statement); statement.executeBatch(); } finally { statement.close(); - if (devMode) { - Log.debug(Benchmark.stopAndFormat("SQL: " + sql + " (Batch)")); - } + stopBatchBenchmark(); } } diff --git a/Plan/src/main/java/com/djrapitops/plan/system/database/databases/sql/processing/QueryStatement.java b/Plan/src/main/java/com/djrapitops/plan/system/database/databases/sql/processing/QueryStatement.java index 94293f9c1..86e95cd9f 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/database/databases/sql/processing/QueryStatement.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/database/databases/sql/processing/QueryStatement.java @@ -4,10 +4,6 @@ */ package com.djrapitops.plan.system.database.databases.sql.processing; -import com.djrapitops.plan.system.settings.Settings; -import com.djrapitops.plugin.api.Benchmark; -import com.djrapitops.plugin.api.utility.log.Log; - import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; @@ -17,24 +13,21 @@ import java.sql.SQLException; * * @author Rsl1122 */ -public abstract class QueryStatement { +public abstract class QueryStatement extends AbstractSQLStatement { - private final String sql; private final int fetchSize; - private boolean devMode; public QueryStatement(String sql) { this(sql, 10); } public QueryStatement(String sql, int fetchSize) { - this.sql = sql; - devMode = Settings.DEV_MODE.isTrue(); + super(sql); this.fetchSize = fetchSize; } public T executeQuery(PreparedStatement statement) throws SQLException { - Benchmark.start("SQL: " + sql); + startBenchmark(); try { statement.setFetchSize(fetchSize); prepare(statement); @@ -43,9 +36,7 @@ public abstract class QueryStatement { } } finally { statement.close(); - if (devMode) { - Log.debug(Benchmark.stopAndFormat("SQL: " + sql)); - } + stopBenchmark(); } } diff --git a/Plan/src/main/java/com/djrapitops/plan/system/database/databases/sql/tables/CommandUseTable.java b/Plan/src/main/java/com/djrapitops/plan/system/database/databases/sql/tables/CommandUseTable.java index 24081843b..bb31ea024 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/database/databases/sql/tables/CommandUseTable.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/database/databases/sql/tables/CommandUseTable.java @@ -9,7 +9,6 @@ import com.djrapitops.plan.system.database.databases.sql.statements.Column; import com.djrapitops.plan.system.database.databases.sql.statements.Select; import com.djrapitops.plan.system.database.databases.sql.statements.Sql; import com.djrapitops.plan.system.database.databases.sql.statements.TableSqlParser; -import com.djrapitops.plan.system.info.server.ServerInfo; import java.sql.PreparedStatement; import java.sql.ResultSet; @@ -94,7 +93,7 @@ public class CommandUseTable extends Table { * @return command - times used Map */ public Map getCommandUse() { - return getCommandUse(ServerInfo.getServerUUID()); + return getCommandUse(getServerUUID()); } public void commandUsed(String command) { @@ -110,7 +109,7 @@ public class CommandUseTable extends Table { boolean updated = execute(new ExecStatement(sql) { @Override public void prepare(PreparedStatement statement) throws SQLException { - statement.setString(1, ServerInfo.getServerUUID().toString()); + statement.setString(1, getServerUUID().toString()); statement.setString(2, command); } }); @@ -144,7 +143,7 @@ public class CommandUseTable extends Table { public void prepare(PreparedStatement statement) throws SQLException { statement.setString(1, command); statement.setInt(2, 1); - statement.setString(3, ServerInfo.getServerUUID().toString()); + statement.setString(3, getServerUUID().toString()); } }); } diff --git a/Plan/src/main/java/com/djrapitops/plan/system/database/databases/sql/tables/KillsTable.java b/Plan/src/main/java/com/djrapitops/plan/system/database/databases/sql/tables/KillsTable.java index a48ed9e62..1380ceab0 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/database/databases/sql/tables/KillsTable.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/database/databases/sql/tables/KillsTable.java @@ -12,7 +12,6 @@ import com.djrapitops.plan.system.database.databases.sql.processing.QueryStateme import com.djrapitops.plan.system.database.databases.sql.statements.Column; import com.djrapitops.plan.system.database.databases.sql.statements.Sql; import com.djrapitops.plan.system.database.databases.sql.statements.TableSqlParser; -import com.djrapitops.plan.system.info.server.ServerInfo; import com.djrapitops.plugin.utilities.Verify; import java.sql.PreparedStatement; @@ -90,11 +89,13 @@ public class KillsTable extends UserIDTable { public void addKillsToSessions(UUID uuid, Map sessions) { String usersIDColumn = usersTable + "." + UsersTable.Col.ID; String usersUUIDColumn = usersTable + "." + UsersTable.Col.UUID + " as victim_uuid"; + String usersNameColumn = usersTable + "." + UsersTable.Col.USER_NAME + " as victim_name"; String sql = "SELECT " + Col.SESSION_ID + ", " + Col.DATE + ", " + Col.WEAPON + ", " + - usersUUIDColumn + + usersUUIDColumn + ", " + + usersNameColumn + " FROM " + tableName + " INNER JOIN " + usersTable + " on " + usersIDColumn + "=" + Col.VICTIM_ID + " WHERE " + Col.KILLER_ID + "=" + usersTable.statementSelectID; @@ -113,11 +114,11 @@ public class KillsTable extends UserIDTable { if (session == null) { continue; } - String uuidS = set.getString("victim_uuid"); - UUID victim = UUID.fromString(uuidS); + UUID victim = UUID.fromString(set.getString("victim_uuid")); + String victimName = set.getString("victim_name"); long date = set.getLong(Col.DATE.get()); String weapon = set.getString(Col.WEAPON.get()); - session.getPlayerKills().add(new PlayerKill(victim, weapon, date)); + session.getPlayerKills().add(new PlayerKill(victim, weapon, date, victimName)); } return null; } @@ -127,11 +128,13 @@ public class KillsTable extends UserIDTable { public void addDeathsToSessions(UUID uuid, Map sessions) { String usersIDColumn = usersTable + "." + UsersTable.Col.ID; String usersUUIDColumn = usersTable + "." + UsersTable.Col.UUID + " as killer_uuid"; + String usersNameColumn = usersTable + "." + UsersTable.Col.USER_NAME + " as killer_name"; String sql = "SELECT " + Col.SESSION_ID + ", " + Col.DATE + ", " + Col.WEAPON + ", " + - usersUUIDColumn + + usersUUIDColumn + ", " + + usersNameColumn + " FROM " + tableName + " INNER JOIN " + usersTable + " on " + usersIDColumn + "=" + Col.KILLER_ID + " WHERE " + Col.VICTIM_ID + "=" + usersTable.statementSelectID; @@ -150,11 +153,11 @@ public class KillsTable extends UserIDTable { if (session == null) { continue; } - String uuidS = set.getString("killer_uuid"); - UUID killer = UUID.fromString(uuidS); + UUID killer = UUID.fromString(set.getString("killer_uuid")); + String name = set.getString("killer_name"); long date = set.getLong(Col.DATE.get()); String weapon = set.getString(Col.WEAPON.get()); - session.getUnsafe(SessionKeys.PLAYER_DEATHS).add(new PlayerDeath(killer, weapon, date)); + session.getUnsafe(SessionKeys.PLAYER_DEATHS).add(new PlayerDeath(killer, name, weapon, date)); } return null; } @@ -179,7 +182,7 @@ public class KillsTable extends UserIDTable { statement.setString(1, uuid.toString()); statement.setString(2, victim.toString()); - statement.setString(3, ServerInfo.getServerUUID().toString()); + statement.setString(3, getServerUUID().toString()); statement.setInt(4, sessionID); statement.setLong(5, date); statement.setString(6, weapon); @@ -193,11 +196,13 @@ public class KillsTable extends UserIDTable { String usersVictimIDColumn = usersTable + "." + UsersTable.Col.ID; String usersKillerIDColumn = "a." + UsersTable.Col.ID; String usersVictimUUIDColumn = usersTable + "." + UsersTable.Col.UUID + " as victim_uuid"; + String usersVictimNameColumn = usersTable + "." + UsersTable.Col.USER_NAME + " as victim_name"; String usersKillerUUIDColumn = "a." + UsersTable.Col.UUID + " as killer_uuid"; String sql = "SELECT " + Col.DATE + ", " + Col.WEAPON + ", " + usersVictimUUIDColumn + ", " + + usersVictimNameColumn + ", " + usersKillerUUIDColumn + " FROM " + tableName + " INNER JOIN " + usersTable + " on " + usersVictimIDColumn + "=" + Col.VICTIM_ID + @@ -210,10 +215,12 @@ public class KillsTable extends UserIDTable { while (set.next()) { UUID killer = UUID.fromString(set.getString("killer_uuid")); UUID victim = UUID.fromString(set.getString("victim_uuid")); + String victimName = set.getString("victim_name"); long date = set.getLong(Col.DATE.get()); String weapon = set.getString(Col.WEAPON.get()); + List kills = allKills.getOrDefault(killer, new ArrayList<>()); - kills.add(new PlayerKill(victim, weapon, date)); + kills.add(new PlayerKill(victim, weapon, date, victimName)); allKills.put(killer, kills); } return allKills; @@ -224,11 +231,13 @@ public class KillsTable extends UserIDTable { public Map> getAllPlayerKillsBySessionID() { String usersIDColumn = usersTable + "." + UsersTable.Col.ID; String usersUUIDColumn = usersTable + "." + UsersTable.Col.UUID + " as victim_uuid"; + String usersNameColumn = usersTable + "." + UsersTable.Col.USER_NAME + " as victim_name"; String sql = "SELECT " + Col.SESSION_ID + ", " + Col.DATE + ", " + Col.WEAPON + ", " + - usersUUIDColumn + + usersUUIDColumn + ", " + + usersNameColumn + " FROM " + tableName + " INNER JOIN " + usersTable + " on " + usersIDColumn + "=" + Col.VICTIM_ID; @@ -241,11 +250,11 @@ public class KillsTable extends UserIDTable { List playerKills = allPlayerKills.getOrDefault(sessionID, new ArrayList<>()); - String uuidS = set.getString("victim_uuid"); - UUID victim = UUID.fromString(uuidS); + UUID victim = UUID.fromString(set.getString("victim_uuid")); + String victimName = set.getString("victim_name"); long date = set.getLong(Col.DATE.get()); String weapon = set.getString(Col.WEAPON.get()); - playerKills.add(new PlayerKill(victim, weapon, date)); + playerKills.add(new PlayerKill(victim, weapon, date, victimName)); allPlayerKills.put(sessionID, playerKills); } diff --git a/Plan/src/main/java/com/djrapitops/plan/system/database/databases/sql/tables/NicknamesTable.java b/Plan/src/main/java/com/djrapitops/plan/system/database/databases/sql/tables/NicknamesTable.java index bf9559483..3a81bb600 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/database/databases/sql/tables/NicknamesTable.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/database/databases/sql/tables/NicknamesTable.java @@ -9,7 +9,6 @@ import com.djrapitops.plan.system.database.databases.sql.processing.QueryStateme import com.djrapitops.plan.system.database.databases.sql.statements.Column; import com.djrapitops.plan.system.database.databases.sql.statements.Sql; import com.djrapitops.plan.system.database.databases.sql.statements.TableSqlParser; -import com.djrapitops.plan.system.info.server.ServerInfo; import com.djrapitops.plugin.utilities.Verify; import java.sql.PreparedStatement; @@ -111,7 +110,7 @@ public class NicknamesTable extends UserIDTable { * @return The nicknames of the User */ public List getNicknames(UUID uuid) { - return getNicknames(uuid, ServerInfo.getServerUUID()); + return getNicknames(uuid, getServerUUID()); } public Map>> getAllNicknames() { @@ -167,7 +166,7 @@ public class NicknamesTable extends UserIDTable { statement.setLong(1, name.getDate()); statement.setString(2, name.getName()); statement.setString(3, uuid.toString()); - statement.setString(4, ServerInfo.getServerUUID().toString()); + statement.setString(4, getServerUUID().toString()); } }); } @@ -177,7 +176,7 @@ public class NicknamesTable extends UserIDTable { @Override public void prepare(PreparedStatement statement) throws SQLException { statement.setString(1, uuid.toString()); - statement.setString(2, ServerInfo.getServerUUID().toString()); + statement.setString(2, getServerUUID().toString()); statement.setString(3, name.getName()); statement.setLong(4, name.getDate()); } diff --git a/Plan/src/main/java/com/djrapitops/plan/system/database/databases/sql/tables/PingTable.java b/Plan/src/main/java/com/djrapitops/plan/system/database/databases/sql/tables/PingTable.java index 2d9d47d42..3e00fe81c 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/database/databases/sql/tables/PingTable.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/database/databases/sql/tables/PingTable.java @@ -9,7 +9,6 @@ import com.djrapitops.plan.system.database.databases.sql.processing.QueryStateme import com.djrapitops.plan.system.database.databases.sql.statements.Column; import com.djrapitops.plan.system.database.databases.sql.statements.Sql; import com.djrapitops.plan.system.database.databases.sql.statements.TableSqlParser; -import com.djrapitops.plan.system.info.server.ServerInfo; import com.djrapitops.plugin.api.TimeAmount; import java.sql.PreparedStatement; @@ -62,7 +61,7 @@ public class PingTable extends UserIDTable { execute(new ExecStatement(sql) { @Override public void prepare(PreparedStatement statement) throws SQLException { - long twoWeeks = TimeAmount.WEEK.ms() * 2L; + long twoWeeks = TimeAmount.WEEK.toMillis(2L); statement.setLong(1, System.currentTimeMillis() - twoWeeks); } }); @@ -73,7 +72,7 @@ public class PingTable extends UserIDTable { @Override public void prepare(PreparedStatement statement) throws SQLException { statement.setString(1, uuid.toString()); - statement.setString(2, ServerInfo.getServerUUID().toString()); + statement.setString(2, getServerUUID().toString()); statement.setLong(3, ping.getDate()); statement.setInt(4, ping.getMin()); statement.setInt(5, ping.getMax()); diff --git a/Plan/src/main/java/com/djrapitops/plan/system/database/databases/sql/tables/SessionsTable.java b/Plan/src/main/java/com/djrapitops/plan/system/database/databases/sql/tables/SessionsTable.java index 5730b55e7..1a12e8ecd 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/database/databases/sql/tables/SessionsTable.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/database/databases/sql/tables/SessionsTable.java @@ -11,7 +11,6 @@ import com.djrapitops.plan.system.database.databases.sql.statements.Column; import com.djrapitops.plan.system.database.databases.sql.statements.Select; import com.djrapitops.plan.system.database.databases.sql.statements.Sql; import com.djrapitops.plan.system.database.databases.sql.statements.TableSqlParser; -import com.djrapitops.plan.system.info.server.ServerInfo; import com.djrapitops.plugin.utilities.Verify; import java.sql.PreparedStatement; @@ -134,7 +133,7 @@ public class SessionsTable extends UserIDTable { statement.setInt(4, session.getUnsafe(SessionKeys.DEATH_COUNT)); statement.setInt(5, session.getUnsafe(SessionKeys.MOB_KILL_COUNT)); statement.setLong(6, session.getUnsafe(SessionKeys.AFK_TIME)); - statement.setString(7, ServerInfo.getServerUUID().toString()); + statement.setString(7, getServerUUID().toString()); } }); } @@ -239,7 +238,7 @@ public class SessionsTable extends UserIDTable { * @return Milliseconds played on THIS server. 0 if player or server not found. */ public long getPlaytime(UUID uuid) { - return getPlaytime(uuid, ServerInfo.getServerUUID()); + return getPlaytime(uuid, getServerUUID()); } /** @@ -250,7 +249,7 @@ public class SessionsTable extends UserIDTable { * @return Milliseconds played on THIS server. 0 if player or server not found. */ public long getPlaytime(UUID uuid, long afterDate) { - return getPlaytime(uuid, ServerInfo.getServerUUID(), afterDate); + return getPlaytime(uuid, getServerUUID(), afterDate); } /** @@ -357,7 +356,7 @@ public class SessionsTable extends UserIDTable { * @return How many sessions player has. 0 if player or server not found. */ public int getSessionCount(UUID uuid, long afterDate) { - return getSessionCount(uuid, ServerInfo.getServerUUID(), afterDate); + return getSessionCount(uuid, getServerUUID(), afterDate); } public Map> getSessionInfoOfServer(UUID serverUUID) { @@ -404,7 +403,7 @@ public class SessionsTable extends UserIDTable { } public Map> getSessionInfoOfServer() { - return getSessionInfoOfServer(ServerInfo.getServerUUID()); + return getSessionInfoOfServer(getServerUUID()); } public Map getLastSeenForAllPlayers() { diff --git a/Plan/src/main/java/com/djrapitops/plan/system/database/databases/sql/tables/TPSTable.java b/Plan/src/main/java/com/djrapitops/plan/system/database/databases/sql/tables/TPSTable.java index 661f6db8d..886574e87 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/database/databases/sql/tables/TPSTable.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/database/databases/sql/tables/TPSTable.java @@ -12,9 +12,9 @@ import com.djrapitops.plan.system.database.databases.sql.statements.Select; import com.djrapitops.plan.system.database.databases.sql.statements.Sql; import com.djrapitops.plan.system.database.databases.sql.statements.TableSqlParser; import com.djrapitops.plan.system.info.server.Server; -import com.djrapitops.plan.system.info.server.ServerInfo; import com.djrapitops.plugin.api.TimeAmount; import com.djrapitops.plugin.utilities.Verify; +import org.apache.commons.text.TextStringBuilder; import java.sql.PreparedStatement; import java.sql.ResultSet; @@ -32,8 +32,10 @@ import java.util.*; */ public class TPSTable extends Table { + public static final String TABLE_NAME = "plan_tps"; + public TPSTable(SQLDB db) { - super("plan_tps", db); + super(TABLE_NAME, db); serverTable = db.getServerTable(); insertStatement = "INSERT INTO " + tableName + " (" + Col.SERVER_ID + ", " @@ -43,10 +45,11 @@ public class TPSTable extends Table { + Col.CPU_USAGE + ", " + Col.RAM_USAGE + ", " + Col.ENTITIES + ", " - + Col.CHUNKS + + Col.CHUNKS + ", " + + Col.FREE_DISK + ") VALUES (" + serverTable.statementSelectServerID + ", " - + "?, ?, ?, ?, ?, ?, ?)"; + + "?, ?, ?, ?, ?, ?, ?, ?)"; } private final ServerTable serverTable; @@ -63,6 +66,7 @@ public class TPSTable extends Table { .column(Col.RAM_USAGE, Sql.LONG).notNull() .column(Col.ENTITIES, Sql.INT).notNull() .column(Col.CHUNKS, Sql.INT).notNull() + .column(Col.FREE_DISK, Sql.LONG).notNull() .foreignKey(Col.SERVER_ID, serverTable.getTableName(), ServerTable.Col.SERVER_ID) .toString() ); @@ -92,6 +96,7 @@ public class TPSTable extends Table { .usedMemory(set.getLong(Col.RAM_USAGE.get())) .entities(set.getInt(Col.ENTITIES.get())) .chunksLoaded(set.getInt(Col.CHUNKS.get())) + .freeDiskSpace(set.getLong(Col.FREE_DISK.get())) .toTPS(); data.add(tps); @@ -105,7 +110,7 @@ public class TPSTable extends Table { * @return @throws SQLException */ public List getTPSData() { - return getTPSData(ServerInfo.getServerUUID()); + return getTPSData(getServerUUID()); } /** @@ -127,7 +132,7 @@ public class TPSTable extends Table { @Override public void prepare(PreparedStatement statement) throws SQLException { // More than 3 Months ago. - long threeMonths = TimeAmount.MONTH.ms() * 3L; + long threeMonths = TimeAmount.MONTH.toMillis(3L); statement.setLong(1, System.currentTimeMillis() - threeMonths); statement.setInt(2, pValue); } @@ -138,7 +143,7 @@ public class TPSTable extends Table { execute(new ExecStatement(insertStatement) { @Override public void prepare(PreparedStatement statement) throws SQLException { - statement.setString(1, ServerInfo.getServerUUID().toString()); + statement.setString(1, getServerUUID().toString()); statement.setLong(2, tps.getDate()); statement.setDouble(3, tps.getTicksPerSecond()); statement.setInt(4, tps.getPlayers()); @@ -146,6 +151,7 @@ public class TPSTable extends Table { statement.setLong(6, tps.getUsedMemory()); statement.setDouble(7, tps.getEntityCount()); statement.setDouble(8, tps.getChunksLoaded()); + statement.setLong(9, tps.getFreeDiskSpace()); } }); } @@ -180,6 +186,7 @@ public class TPSTable extends Table { .usedMemory(set.getLong(Col.RAM_USAGE.get())) .entities(set.getInt(Col.ENTITIES.get())) .chunksLoaded(set.getInt(Col.CHUNKS.get())) + .freeDiskSpace(set.getLong(Col.FREE_DISK.get())) .toTPS(); return Optional.of(tps); @@ -198,7 +205,7 @@ public class TPSTable extends Table { } public Optional getPeakPlayerCount(long afterDate) { - return getPeakPlayerCount(ServerInfo.getServerUUID(), afterDate); + return getPeakPlayerCount(getServerUUID(), afterDate); } public Map> getAllTPS() { @@ -212,6 +219,7 @@ public class TPSTable extends Table { Col.RAM_USAGE + ", " + Col.ENTITIES + ", " + Col.CHUNKS + ", " + + Col.FREE_DISK + ", " + serverUUIDColumn + " FROM " + tableName + " INNER JOIN " + serverTable + " on " + serverIDColumn + "=" + Col.SERVER_ID; @@ -233,6 +241,7 @@ public class TPSTable extends Table { .usedMemory(set.getLong(Col.RAM_USAGE.get())) .entities(set.getInt(Col.ENTITIES.get())) .chunksLoaded(set.getInt(Col.CHUNKS.get())) + .freeDiskSpace(set.getLong(Col.FREE_DISK.get())) .toTPS(); tpsList.add(tps); @@ -302,6 +311,7 @@ public class TPSTable extends Table { statement.setLong(6, tps.getUsedMemory()); statement.setDouble(7, tps.getEntityCount()); statement.setDouble(8, tps.getChunksLoaded()); + statement.setLong(9, tps.getFreeDiskSpace()); statement.addBatch(); } } @@ -309,6 +319,42 @@ public class TPSTable extends Table { }); } + public Map> getPlayersOnlineForServers(Collection servers) { + TextStringBuilder sql = new TextStringBuilder("SELECT "); + sql.append(Col.SERVER_ID).append(", ") + .append(Col.DATE).append(", ") + .append(Col.PLAYERS_ONLINE) + .append(" FROM ").append(tableName) + .append(" WHERE ") + .append(Col.DATE.get()).append(">").append(System.currentTimeMillis() - TimeAmount.WEEK.toMillis(2L)) + .append(" AND ("); + sql.appendWithSeparators(servers.stream().map(server -> Col.SERVER_ID + "=" + server.getId()).iterator(), " OR "); + sql.append(")"); + + return query(new QueryAllStatement>>(sql.toString(), 10000) { + @Override + public Map> processResults(ResultSet set) throws SQLException { + Map> map = new HashMap<>(); + while (set.next()) { + int serverID = set.getInt(Col.SERVER_ID.get()); + int playersOnline = set.getInt(Col.PLAYERS_ONLINE.get()); + long date = set.getLong(Col.DATE.get()); + + List tpsList = map.getOrDefault(serverID, new ArrayList<>()); + + TPS tps = TPSBuilder.get().date(date) + .skipTPS() + .playersOnline(playersOnline) + .toTPS(); + tpsList.add(tps); + + map.put(serverID, tpsList); + } + return map; + } + }); + } + public enum Col implements Column { SERVER_ID("server_id"), DATE("date"), @@ -317,7 +363,8 @@ public class TPSTable extends Table { CPU_USAGE("cpu_usage"), RAM_USAGE("ram_usage"), ENTITIES("entities"), - CHUNKS("chunks_loaded"); + CHUNKS("chunks_loaded"), + FREE_DISK("free_disk_space"); private final String column; diff --git a/Plan/src/main/java/com/djrapitops/plan/system/database/databases/sql/tables/Table.java b/Plan/src/main/java/com/djrapitops/plan/system/database/databases/sql/tables/Table.java index 6fc895155..d7e31a247 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/database/databases/sql/tables/Table.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/database/databases/sql/tables/Table.java @@ -10,6 +10,7 @@ import com.google.common.base.Objects; import java.sql.Connection; import java.sql.SQLException; +import java.util.UUID; /** * Abstract representation of a SQL database table. @@ -44,11 +45,8 @@ public abstract class Table { } } - protected void renameTable(String to) { - String sql = usingMySQL ? - "RENAME TABLE " + tableName + " TO " + to : - "ALTER TABLE " + tableName + " RENAME TO " + to; - execute(sql); + protected UUID getServerUUID() { + return db.getServerUUIDSupplier().get(); } /** diff --git a/Plan/src/main/java/com/djrapitops/plan/system/database/databases/sql/tables/TransferTable.java b/Plan/src/main/java/com/djrapitops/plan/system/database/databases/sql/tables/TransferTable.java index 66fbb1e77..800d3437b 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/database/databases/sql/tables/TransferTable.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/database/databases/sql/tables/TransferTable.java @@ -11,13 +11,12 @@ import com.djrapitops.plan.system.database.databases.sql.processing.QueryStateme import com.djrapitops.plan.system.database.databases.sql.statements.Column; import com.djrapitops.plan.system.database.databases.sql.statements.Sql; import com.djrapitops.plan.system.database.databases.sql.statements.TableSqlParser; -import com.djrapitops.plan.system.info.server.ServerInfo; -import com.djrapitops.plugin.api.TimeAmount; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.util.Optional; +import java.util.concurrent.TimeUnit; /** * Table that is in charge of transferring data between network servers. @@ -90,7 +89,7 @@ public class TransferTable extends Table { execute(new ExecStatement(sql) { @Override public void prepare(PreparedStatement statement) throws SQLException { - statement.setString(1, ServerInfo.getServerUUID().toString()); + statement.setString(1, getServerUUID().toString()); statement.setString(2, "onlineStatus"); } }); @@ -100,8 +99,8 @@ public class TransferTable extends Table { execute(new ExecStatement(insertStatementNoParts) { @Override public void prepare(PreparedStatement statement) throws SQLException { - statement.setString(1, ServerInfo.getServerUUID().toString()); - statement.setLong(2, System.currentTimeMillis() + TimeAmount.HOUR.ms()); + statement.setString(1, getServerUUID().toString()); + statement.setLong(2, System.currentTimeMillis() + TimeUnit.HOURS.toMillis(1L)); statement.setString(3, "configSettings"); statement.setString(4, null); statement.setString(5, encodedSettingString); diff --git a/Plan/src/main/java/com/djrapitops/plan/system/database/databases/sql/tables/UserInfoTable.java b/Plan/src/main/java/com/djrapitops/plan/system/database/databases/sql/tables/UserInfoTable.java index dc7bdac3c..2083b700c 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/database/databases/sql/tables/UserInfoTable.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/database/databases/sql/tables/UserInfoTable.java @@ -11,7 +11,7 @@ import com.djrapitops.plan.system.database.databases.sql.processing.ExecStatemen import com.djrapitops.plan.system.database.databases.sql.processing.QueryAllStatement; import com.djrapitops.plan.system.database.databases.sql.processing.QueryStatement; import com.djrapitops.plan.system.database.databases.sql.statements.*; -import com.djrapitops.plan.system.info.server.ServerInfo; +import com.djrapitops.plan.system.info.server.Server; import com.djrapitops.plugin.utilities.Verify; import java.sql.PreparedStatement; @@ -69,7 +69,7 @@ public class UserInfoTable extends UserIDTable { public void prepare(PreparedStatement statement) throws SQLException { statement.setString(1, uuid.toString()); statement.setLong(2, registered); - statement.setString(3, ServerInfo.getServerUUID().toString()); + statement.setString(3, getServerUUID().toString()); } }); } @@ -95,7 +95,7 @@ public class UserInfoTable extends UserIDTable { } public boolean isRegistered(UUID uuid) { - return isRegistered(uuid, ServerInfo.getServerUUID()); + return isRegistered(uuid, getServerUUID()); } public void updateOpStatus(UUID uuid, boolean op) { @@ -166,7 +166,7 @@ public class UserInfoTable extends UserIDTable { } public UserInfo getUserInfo(UUID uuid) { - return getAllUserInfo(uuid).get(ServerInfo.getServerUUID()); + return getAllUserInfo(uuid).get(getServerUUID()); } public List getServerUserInfo(UUID serverUUID) { @@ -213,7 +213,7 @@ public class UserInfoTable extends UserIDTable { * @return List of UserInfo objects. */ public List getServerUserInfo() { - return getServerUserInfo(ServerInfo.getServerUUID()); + return getServerUserInfo(getServerUUID()); } public Map> getAllUserInfo() { @@ -312,6 +312,34 @@ public class UserInfoTable extends UserIDTable { }); } + public boolean isRegisteredOnThisServer(UUID player) { + return isRegistered(player, getServerUUID()); + } + + public Map getPlayersRegisteredForServers(Collection servers) { + if (servers.isEmpty()) { + return new HashMap<>(); + } + + String sql = "SELECT " + Col.SERVER_ID + ", " + + "COUNT(" + Col.REGISTERED + ") AS count" + + " FROM " + tableName + + " GROUP BY " + Col.SERVER_ID; + return query(new QueryAllStatement>(sql, 10000) { + @Override + public Map processResults(ResultSet set) throws SQLException { + Map map = new HashMap<>(); + while (set.next()) { + int serverID = set.getInt(Col.SERVER_ID.get()); + int count = set.getInt("count"); + map.put(serverID, count); + } + return map; + } + }); + + } + public enum Col implements Column { USER_ID(UserIDTable.Col.USER_ID.get()), SERVER_ID("server_id"), diff --git a/Plan/src/main/java/com/djrapitops/plan/system/database/databases/sql/tables/WorldTable.java b/Plan/src/main/java/com/djrapitops/plan/system/database/databases/sql/tables/WorldTable.java index 482ea51ec..4e3a55967 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/database/databases/sql/tables/WorldTable.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/database/databases/sql/tables/WorldTable.java @@ -8,7 +8,6 @@ import com.djrapitops.plan.system.database.databases.sql.processing.QueryStateme import com.djrapitops.plan.system.database.databases.sql.statements.Column; import com.djrapitops.plan.system.database.databases.sql.statements.Sql; import com.djrapitops.plan.system.database.databases.sql.statements.TableSqlParser; -import com.djrapitops.plan.system.info.server.ServerInfo; import com.djrapitops.plugin.utilities.Verify; import java.sql.PreparedStatement; @@ -73,7 +72,7 @@ public class WorldTable extends Table { } public List getWorlds() { - return getWorlds(ServerInfo.getServerUUID()); + return getWorlds(getServerUUID()); } public List getWorlds(UUID serverUUID) { @@ -100,7 +99,7 @@ public class WorldTable extends Table { } public void saveWorlds(Collection worlds) { - saveWorlds(worlds, ServerInfo.getServerUUID()); + saveWorlds(worlds, getServerUUID()); } /** diff --git a/Plan/src/main/java/com/djrapitops/plan/system/database/databases/sql/tables/WorldTimesTable.java b/Plan/src/main/java/com/djrapitops/plan/system/database/databases/sql/tables/WorldTimesTable.java index d1fbaf1e1..f8a61a552 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/database/databases/sql/tables/WorldTimesTable.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/database/databases/sql/tables/WorldTimesTable.java @@ -12,7 +12,6 @@ import com.djrapitops.plan.system.database.databases.sql.processing.QueryStateme import com.djrapitops.plan.system.database.databases.sql.statements.Column; import com.djrapitops.plan.system.database.databases.sql.statements.Sql; import com.djrapitops.plan.system.database.databases.sql.statements.TableSqlParser; -import com.djrapitops.plan.system.info.server.ServerInfo; import com.djrapitops.plugin.utilities.Verify; import java.sql.PreparedStatement; @@ -143,7 +142,7 @@ public class WorldTimesTable extends UserIDTable { GMTimes gmTimes = entry.getValue(); statement.setString(1, uuid.toString()); statement.setString(2, worldName); - String serverUUID = ServerInfo.getServerUUID().toString(); + String serverUUID = getServerUUID().toString(); statement.setString(3, serverUUID); statement.setString(4, serverUUID); statement.setInt(5, sessionID); diff --git a/Plan/src/main/java/com/djrapitops/plan/system/database/databases/sql/tables/move/BatchOperationTable.java b/Plan/src/main/java/com/djrapitops/plan/system/database/databases/sql/tables/move/BatchOperationTable.java index 1a59df108..3419cbd14 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/database/databases/sql/tables/move/BatchOperationTable.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/database/databases/sql/tables/move/BatchOperationTable.java @@ -10,7 +10,6 @@ import com.djrapitops.plan.system.database.databases.sql.tables.ServerTable; import com.djrapitops.plan.system.database.databases.sql.tables.Table; import com.djrapitops.plan.system.database.databases.sql.tables.UsersTable; import com.djrapitops.plan.system.info.server.Server; -import com.djrapitops.plugin.api.utility.log.Log; import java.util.ArrayList; import java.util.List; @@ -71,7 +70,6 @@ public class BatchOperationTable extends Table { if (toDB.equals(this)) { return; } - Log.debug("Start Batch Copy Everything"); toDB.removeAllData(); copyServers(toDB); @@ -98,7 +96,6 @@ public class BatchOperationTable extends Table { if (toDB.equals(this)) { return; } - Log.debug("Batch Copy Commands"); toDB.db.getCommandUseTable().insertCommandUsage(db.getCommandUseTable().getAllCommandUsages()); } @@ -106,7 +103,6 @@ public class BatchOperationTable extends Table { if (toDB.equals(this)) { return; } - Log.debug("Batch Copy IPs, Geolocations & Last used dates"); toDB.db.getGeoInfoTable().insertAllGeoInfo(db.getGeoInfoTable().getAllGeoInfo()); } @@ -114,7 +110,6 @@ public class BatchOperationTable extends Table { if (toDB.equals(this)) { return; } - Log.debug("Batch Copy Nicknames"); toDB.db.getNicknamesTable().insertNicknames(db.getNicknamesTable().getAllNicknames()); } @@ -122,7 +117,6 @@ public class BatchOperationTable extends Table { if (toDB.equals(this)) { return; } - Log.debug("Batch Copy WebUsers"); toDB.db.getSecurityTable().addUsers(db.getSecurityTable().getUsers()); } @@ -130,7 +124,6 @@ public class BatchOperationTable extends Table { if (toDB.equals(this)) { return; } - Log.debug("Batch Copy Servers"); ServerTable serverTable = db.getServerTable(); List servers = new ArrayList<>(serverTable.getBukkitServers().values()); serverTable.getBungeeInfo().ifPresent(servers::add); @@ -141,7 +134,6 @@ public class BatchOperationTable extends Table { if (toDB.equals(this)) { return; } - Log.debug("Batch Copy TPS"); toDB.db.getTpsTable().insertAllTPS(db.getTpsTable().getAllTPS()); } @@ -149,7 +141,6 @@ public class BatchOperationTable extends Table { if (toDB.equals(this)) { return; } - Log.debug("Batch Copy UserInfo"); toDB.db.getUserInfoTable().insertUserInfo(db.getUserInfoTable().getAllUserInfo()); } @@ -157,7 +148,6 @@ public class BatchOperationTable extends Table { if (toDB.equals(this)) { return; } - Log.debug("Batch Copy Worlds"); toDB.db.getWorldTable().saveWorlds(db.getWorldTable().getAllWorlds()); } @@ -165,7 +155,6 @@ public class BatchOperationTable extends Table { if (toDB.equals(this)) { return; } - Log.debug("Batch Copy Users"); UsersTable fromTable = db.getUsersTable(); UsersTable toTable = toDB.db.getUsersTable(); Map users = fromTable.getUsers(); @@ -177,7 +166,6 @@ public class BatchOperationTable extends Table { if (toDB.equals(this)) { return; } - Log.debug("Batch Copy Sessions"); toDB.db.getSessionsTable().insertSessions(db.getSessionsTable().getAllSessions(true), true); } } diff --git a/Plan/src/main/java/com/djrapitops/plan/system/export/ExportSystem.java b/Plan/src/main/java/com/djrapitops/plan/system/export/ExportSystem.java new file mode 100644 index 000000000..f3da6b637 --- /dev/null +++ b/Plan/src/main/java/com/djrapitops/plan/system/export/ExportSystem.java @@ -0,0 +1,46 @@ +package com.djrapitops.plan.system.export; + +import com.djrapitops.plan.system.SubSystem; +import com.djrapitops.plan.system.processing.Processing; +import com.djrapitops.plan.system.settings.Settings; +import com.djrapitops.plan.system.settings.config.PlanConfig; +import com.djrapitops.plan.utilities.file.export.HtmlExport; + +import javax.inject.Inject; +import javax.inject.Singleton; + +/** + * System in charge of exporting html. + * + * @author Rsl1122 + */ +@Singleton +public class ExportSystem implements SubSystem { + + private final PlanConfig config; + private final Processing processing; + private final HtmlExport htmlExport; + + @Inject + public ExportSystem( + PlanConfig config, + Processing processing, + HtmlExport htmlExport + ) { + this.config = config; + this.processing = processing; + this.htmlExport = htmlExport; + } + + @Override + public void enable() { + if (config.isTrue(Settings.ANALYSIS_EXPORT)) { + processing.submitNonCritical(htmlExport); + } + } + + @Override + public void disable() { + + } +} \ No newline at end of file diff --git a/Plan/src/main/java/com/djrapitops/plan/system/file/FileSystem.java b/Plan/src/main/java/com/djrapitops/plan/system/file/FileSystem.java deleted file mode 100644 index ee11fe1b3..000000000 --- a/Plan/src/main/java/com/djrapitops/plan/system/file/FileSystem.java +++ /dev/null @@ -1,82 +0,0 @@ -/* - * License is provided in the jar as LICENSE also here: - * https://github.com/Rsl1122/Plan-PlayerAnalytics/blob/master/Plan/src/main/resources/LICENSE - */ -package com.djrapitops.plan.system.file; - -import com.djrapitops.plan.PlanPlugin; -import com.djrapitops.plan.api.exceptions.EnableException; -import com.djrapitops.plan.system.PlanSystem; -import com.djrapitops.plan.system.SubSystem; -import com.djrapitops.plan.system.tasks.LogsFolderCleanTask; -import com.djrapitops.plan.utilities.file.FileUtil; -import com.djrapitops.plugin.api.TimeAmount; -import com.djrapitops.plugin.api.utility.log.Log; -import com.djrapitops.plugin.task.RunnableFactory; -import com.djrapitops.plugin.utilities.Verify; - -import java.io.File; -import java.io.IOException; -import java.util.List; - -/** - * Abstracts File methods of Plugin classes so that they can be tested without Mocks. - * - * @author Rsl1122 - */ -public class FileSystem implements SubSystem { - - private final File dataFolder; - private File configFile; - - public FileSystem(PlanPlugin plugin) { - this(plugin.getDataFolder()); - } - - public FileSystem(File dataFolder) { - this.dataFolder = dataFolder; - configFile = new File(dataFolder, "config.yml"); - } - - public static FileSystem getInstance() { - FileSystem fileSystem = PlanSystem.getInstance().getFileSystem(); - Verify.nullCheck(fileSystem, () -> new IllegalStateException("File system was not initialized.")); - return fileSystem; - } - - public static File getDataFolder() { - return getInstance().dataFolder; - } - - public static File getConfigFile() { - return getInstance().configFile; - } - - public static File getLocaleFile() { - return new File(getInstance().dataFolder, "locale.txt"); - } - - public static List readFromResource(String fileName) throws IOException { - return FileUtil.lines(PlanPlugin.getInstance(), fileName); - } - - @Override - public void enable() throws EnableException { - Verify.isTrue((dataFolder.exists() && dataFolder.isDirectory()) || dataFolder.mkdirs(), - () -> new EnableException("Could not create data folder at " + dataFolder.getAbsolutePath())); - try { - Verify.isTrue((configFile.exists() && configFile.isFile()) || configFile.createNewFile(), - () -> new EnableException("Could not create config file at " + configFile.getAbsolutePath())); - - RunnableFactory.createNew(new LogsFolderCleanTask(Log.getLogsFolder())) - .runTaskLaterAsynchronously(TimeAmount.SECOND.ticks() * 30L); - } catch (IOException e) { - throw new EnableException("Failed to create config.yml", e); - } - } - - @Override - public void disable() { - // No disable actions necessary. - } -} diff --git a/Plan/src/main/java/com/djrapitops/plan/system/file/PlanFiles.java b/Plan/src/main/java/com/djrapitops/plan/system/file/PlanFiles.java new file mode 100644 index 000000000..61e7b4e7d --- /dev/null +++ b/Plan/src/main/java/com/djrapitops/plan/system/file/PlanFiles.java @@ -0,0 +1,125 @@ +/* + * License is provided in the jar as LICENSE also here: + * https://github.com/Rsl1122/Plan-PlayerAnalytics/blob/master/Plan/src/main/resources/LICENSE + */ +package com.djrapitops.plan.system.file; + +import com.djrapitops.plan.PlanPlugin; +import com.djrapitops.plan.api.exceptions.EnableException; +import com.djrapitops.plan.system.SubSystem; +import com.djrapitops.plan.utilities.file.FileUtil; +import com.djrapitops.plugin.utilities.Verify; + +import javax.inject.Inject; +import javax.inject.Singleton; +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.util.List; + +/** + * Abstracts File methods of Plugin classes so that they can be tested without Mocks. + * + * @author Rsl1122 + */ +@Singleton +public class PlanFiles implements SubSystem { + + private final PlanPlugin plugin; + + private final File dataFolder; + private final File configFile; + + @Inject + public PlanFiles(PlanPlugin plugin) { + this.dataFolder = plugin.getDataFolder(); + this.plugin = plugin; + this.configFile = getFileFromPluginFolder("config.yml"); + } + + public File getDataFolder() { + return dataFolder; + } + + public File getLogsFolder() { + File folder = getFileFromPluginFolder("logs"); + folder.mkdirs(); + return folder; + } + + public File getConfigFile() { + return configFile; + } + + public File getLocaleFile() { + return getFileFromPluginFolder("locale.txt"); + } + + public File getFileFromPluginFolder(String name) { + return new File(dataFolder, name); + } + + @Override + public void enable() throws EnableException { + Verify.isTrue((dataFolder.exists() && dataFolder.isDirectory()) || dataFolder.mkdirs(), + () -> new EnableException("Could not create data folder at " + dataFolder.getAbsolutePath())); + try { + Verify.isTrue((configFile.exists() && configFile.isFile()) || configFile.createNewFile(), + () -> new EnableException("Could not create config file at " + configFile.getAbsolutePath())); + } catch (IOException e) { + throw new EnableException("Failed to create config.yml", e); + } + } + + @Override + public void disable() { + // No disable actions necessary. + } + + /** + * Read a file from jar as lines. + * + * @param fileName Name of the file. + * @return lines of the file + * @throws IOException If the resource can not be read. + */ + public List readFromResource(String fileName) throws IOException { + return FileUtil.lines(plugin, fileName); + } + + /** + * Read a file from jar as a flat String. + * + * @param fileName Name of the file + * @return Flattened lines with {@code \r\n} line separators. + * @throws IOException If the resource can not be read. + */ + public String readFromResourceFlat(String fileName) throws IOException { + return flatten(readFromResource(fileName)); + } + + /** + * Read a file from jar or /plugins/Plan/ folder. + * + * @param fileName Name of the file + * @return Flattened lines with {@code \r\n} line separators. + * @throws IOException If the resource can not be read. + */ + public String readCustomizableResourceFlat(String fileName) throws IOException { + return flatten(FileUtil.lines( + plugin, new File(plugin.getDataFolder(), fileName.replace("/", File.separator)), fileName + )); + } + + public InputStream readCustomizableResource(String fileName) { + return FileUtil.stream(plugin, new File(plugin.getDataFolder(), fileName.replace("/", File.separator)), fileName); + } + + private String flatten(List lines) { + StringBuilder flat = new StringBuilder(); + for (String line : lines) { + flat.append(line).append("\r\n"); + } + return flat.toString(); + } +} diff --git a/Plan/src/main/java/com/djrapitops/plan/system/importing/BukkitImportSystem.java b/Plan/src/main/java/com/djrapitops/plan/system/importing/BukkitImportSystem.java new file mode 100644 index 000000000..c6dc9953c --- /dev/null +++ b/Plan/src/main/java/com/djrapitops/plan/system/importing/BukkitImportSystem.java @@ -0,0 +1,29 @@ +package com.djrapitops.plan.system.importing; + +import com.djrapitops.plan.system.importing.importers.OfflinePlayerImporter; + +import javax.inject.Inject; +import javax.inject.Singleton; + +/** + * ImportSystem implementation for Bukkit. + * + * @author Rsl1122 + */ +@Singleton +public class BukkitImportSystem extends ImportSystem { + + private final OfflinePlayerImporter offlinePlayerImporter; + + @Inject + public BukkitImportSystem( + OfflinePlayerImporter offlinePlayerImporter + ) { + this.offlinePlayerImporter = offlinePlayerImporter; + } + + @Override + void registerImporters() { + registerImporter(offlinePlayerImporter); + } +} \ No newline at end of file diff --git a/Plan/src/main/java/com/djrapitops/plan/system/importing/EmptyImportSystem.java b/Plan/src/main/java/com/djrapitops/plan/system/importing/EmptyImportSystem.java new file mode 100644 index 000000000..7e8c64ae0 --- /dev/null +++ b/Plan/src/main/java/com/djrapitops/plan/system/importing/EmptyImportSystem.java @@ -0,0 +1,14 @@ +package com.djrapitops.plan.system.importing; + +/** + * Placeholder for a ImportSystem. + * + * @author Rsl1122 + */ +public class EmptyImportSystem extends ImportSystem { + + @Override + void registerImporters() { + // No importers to register. + } +} \ No newline at end of file diff --git a/Plan/src/main/java/com/djrapitops/plan/system/importing/ImportSystem.java b/Plan/src/main/java/com/djrapitops/plan/system/importing/ImportSystem.java new file mode 100644 index 000000000..6c39db052 --- /dev/null +++ b/Plan/src/main/java/com/djrapitops/plan/system/importing/ImportSystem.java @@ -0,0 +1,49 @@ +package com.djrapitops.plan.system.importing; + +import com.djrapitops.plan.system.SubSystem; +import com.djrapitops.plan.system.importing.importers.Importer; +import com.djrapitops.plugin.utilities.Verify; + +import java.util.*; + +/** + * Abstract representation of an ImportSystem. + * + * @author Rsl1122 + */ +public abstract class ImportSystem implements SubSystem { + + protected Map importers; + + public ImportSystem() { + importers = new HashMap<>(); + } + + @Override + public void enable() { + registerImporters(); + } + + abstract void registerImporters(); + + public void registerImporter(Importer importer) { + Verify.nullCheck(importer, () -> new IllegalArgumentException("Importer cannot be null")); + + importers.put(importer.getName(), importer); + } + + public Optional getImporter(String name) { + return Optional.ofNullable(importers.get(name)); + } + + public List getImporterNames() { + List names = new ArrayList<>(importers.keySet()); + Collections.sort(names); + return names; + } + + @Override + public void disable() { + importers.clear(); + } +} \ No newline at end of file diff --git a/Plan/src/main/java/com/djrapitops/plan/system/processing/importing/ServerImportData.java b/Plan/src/main/java/com/djrapitops/plan/system/importing/data/ServerImportData.java similarity index 97% rename from Plan/src/main/java/com/djrapitops/plan/system/processing/importing/ServerImportData.java rename to Plan/src/main/java/com/djrapitops/plan/system/importing/data/ServerImportData.java index d6bee620f..d9bb3597e 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/processing/importing/ServerImportData.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/importing/data/ServerImportData.java @@ -2,7 +2,7 @@ * License is provided in the jar as LICENSE also here: * https://github.com/Rsl1122/Plan-PlayerAnalytics/blob/master/Plan/src/main/resources/LICENSE */ -package com.djrapitops.plan.system.processing.importing; +package com.djrapitops.plan.system.importing.data; import com.djrapitops.plan.data.container.TPS; import com.djrapitops.plan.data.container.builders.TPSBuilder; diff --git a/Plan/src/main/java/com/djrapitops/plan/system/processing/importing/UserImportData.java b/Plan/src/main/java/com/djrapitops/plan/system/importing/data/UserImportData.java similarity index 95% rename from Plan/src/main/java/com/djrapitops/plan/system/processing/importing/UserImportData.java rename to Plan/src/main/java/com/djrapitops/plan/system/importing/data/UserImportData.java index 37cf6d2f2..23e4d0b06 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/processing/importing/UserImportData.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/importing/data/UserImportData.java @@ -2,12 +2,11 @@ * License is provided in the jar as LICENSE also here: * https://github.com/Rsl1122/Plan-PlayerAnalytics/blob/master/Plan/src/main/resources/LICENSE */ -package com.djrapitops.plan.system.processing.importing; +package com.djrapitops.plan.system.importing.data; import com.djrapitops.plan.data.container.PlayerKill; import com.djrapitops.plan.data.store.objects.Nickname; import com.djrapitops.plan.data.time.GMTimes; -import com.djrapitops.plan.system.info.server.ServerInfo; import java.util.*; @@ -49,8 +48,8 @@ public class UserImportData { this.deaths = deaths; } - public static UserImportDataBuilder builder() { - return new UserImportDataBuilder(); + public static UserImportDataBuilder builder(UUID serverUUID) { + return new UserImportDataBuilder(serverUUID); } public String getName() { @@ -150,6 +149,8 @@ public class UserImportData { } public static final class UserImportDataBuilder { + private final UUID serverUUID; + private final List nicknames = new ArrayList<>(); private final List ips = new ArrayList<>(); private final Map worldTimes = new HashMap<>(); @@ -163,8 +164,8 @@ public class UserImportData { private int mobKills; private int deaths; - private UserImportDataBuilder() { - /* Private Constructor */ + private UserImportDataBuilder(UUID serverUUID) { + this.serverUUID = serverUUID; } public UserImportDataBuilder name(String name) { @@ -197,7 +198,6 @@ public class UserImportData { public UserImportDataBuilder nicknames(String... nicknames) { long time = System.currentTimeMillis(); - UUID serverUUID = ServerInfo.getServerUUID(); Arrays.stream(nicknames) .map(nick -> new Nickname(nick, time, serverUUID)) diff --git a/Plan/src/main/java/com/djrapitops/plan/system/processing/importing/UserImportRefiner.java b/Plan/src/main/java/com/djrapitops/plan/system/importing/data/UserImportRefiner.java similarity index 90% rename from Plan/src/main/java/com/djrapitops/plan/system/processing/importing/UserImportRefiner.java rename to Plan/src/main/java/com/djrapitops/plan/system/importing/data/UserImportRefiner.java index c401a3e63..5d34ca06f 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/processing/importing/UserImportRefiner.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/importing/data/UserImportRefiner.java @@ -2,12 +2,12 @@ * License is provided in the jar as LICENSE also here: * https://github.com/Rsl1122/Plan-PlayerAnalytics/blob/master/Plan/src/main/resources/LICENSE */ -package com.djrapitops.plan.system.processing.importing; +package com.djrapitops.plan.system.importing.data; import com.djrapitops.plan.Plan; -import com.djrapitops.plugin.api.Benchmark; +import com.djrapitops.plan.system.DebugChannels; import com.djrapitops.plugin.api.utility.UUIDFetcher; -import com.djrapitops.plugin.api.utility.log.Log; +import com.djrapitops.plugin.benchmarking.Timings; import org.bukkit.OfflinePlayer; import org.bukkit.World; @@ -25,6 +25,7 @@ import java.util.stream.Collectors; public class UserImportRefiner { private final Plan plugin; + private final Timings timings; private final boolean onlineMode; private final List importers = new ArrayList<>(); @@ -39,6 +40,7 @@ public class UserImportRefiner { public UserImportRefiner(Plan plugin, List importers) { this.plugin = plugin; + this.timings = plugin.getTimings(); this.importers.addAll(importers); onlineMode = plugin.getServer().getOnlineMode(); @@ -47,10 +49,10 @@ public class UserImportRefiner { public List refineData() { String benchmarkName = "Refining UserImportData"; - Benchmark.start(benchmarkName); + timings.start(benchmarkName); processMissingIdentifiers(); processOldWorlds(); - Benchmark.stop(benchmarkName); + timings.end(DebugChannels.IMPORTING, benchmarkName); return importers; } @@ -58,7 +60,7 @@ public class UserImportRefiner { private void processOldWorlds() { String benchmarkName = "Processing old worlds"; - Benchmark.start(benchmarkName); + timings.start(benchmarkName); importers.parallelStream() .flatMap(importer -> importer.getWorldTimes().keySet().stream()) @@ -73,7 +75,7 @@ public class UserImportRefiner { importers.parallelStream() .forEach(importer -> importer.getWorldTimes().keySet().removeAll(worlds.keySet())); - Benchmark.stop(benchmarkName); + timings.end(DebugChannels.IMPORTING, benchmarkName); } private void checkOldWorld(String worldName) { @@ -90,7 +92,7 @@ public class UserImportRefiner { private void processMissingIdentifiers() { String benchmarkName = "Processing missing identifiers"; - Benchmark.start(benchmarkName); + timings.start(benchmarkName); List invalidData = new ArrayList<>(); @@ -115,13 +117,13 @@ public class UserImportRefiner { processMissingUUIDs(); processMissingNames(); - Benchmark.stop(benchmarkName); + timings.end(DebugChannels.IMPORTING, benchmarkName); } private void processMissingUUIDs() { String benchmarkName = "Processing missing UUIDs"; - Benchmark.start(benchmarkName); + timings.start(benchmarkName); if (onlineMode) { addMissingUUIDsOverFetcher(); @@ -141,7 +143,7 @@ public class UserImportRefiner { importers.removeAll(uuidsMissing.keySet()); - Benchmark.stop(benchmarkName); + timings.end(DebugChannels.IMPORTING, benchmarkName); } private void addMissingUUIDsOverFetcher() { @@ -153,7 +155,6 @@ public class UserImportRefiner { result = uuidFetcher.call().entrySet().parallelStream() .collect(Collectors.toMap(entry -> entry.getValue().toString(), Map.Entry::getKey)); } catch (Exception e) { - Log.toLog(this.getClass(), e); return; } @@ -206,7 +207,7 @@ public class UserImportRefiner { private void processMissingNames() { String benchmarkNames = "Processing missing names"; - Benchmark.start(benchmarkNames); + timings.start(benchmarkNames); addMissingNames(); @@ -214,7 +215,7 @@ public class UserImportRefiner { importers.removeAll(namesMissing.keySet()); - Benchmark.stop(benchmarkNames); + timings.end(DebugChannels.IMPORTING, benchmarkNames); } private void addMissingNames() { diff --git a/Plan/src/main/java/com/djrapitops/plan/system/processing/importing/importers/Importer.java b/Plan/src/main/java/com/djrapitops/plan/system/importing/importers/Importer.java similarity index 58% rename from Plan/src/main/java/com/djrapitops/plan/system/processing/importing/importers/Importer.java rename to Plan/src/main/java/com/djrapitops/plan/system/importing/importers/Importer.java index 7c5f299d9..fc5c39060 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/processing/importing/importers/Importer.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/importing/importers/Importer.java @@ -2,25 +2,25 @@ * License is provided in the jar as LICENSE also here: * https://github.com/Rsl1122/Plan-PlayerAnalytics/blob/master/Plan/src/main/resources/LICENSE */ -package com.djrapitops.plan.system.processing.importing.importers; +package com.djrapitops.plan.system.importing.importers; import com.djrapitops.plan.Plan; import com.djrapitops.plan.api.exceptions.database.DBException; +import com.djrapitops.plan.api.exceptions.database.DBOpException; import com.djrapitops.plan.data.container.GeoInfo; import com.djrapitops.plan.data.container.Session; import com.djrapitops.plan.data.container.UserInfo; import com.djrapitops.plan.data.store.objects.Nickname; import com.djrapitops.plan.data.time.WorldTimes; import com.djrapitops.plan.system.cache.GeolocationCache; -import com.djrapitops.plan.system.database.databases.Database; +import com.djrapitops.plan.system.database.DBSystem; +import com.djrapitops.plan.system.database.databases.operation.FetchOperations; import com.djrapitops.plan.system.database.databases.operation.SaveOperations; +import com.djrapitops.plan.system.importing.data.ServerImportData; +import com.djrapitops.plan.system.importing.data.UserImportData; +import com.djrapitops.plan.system.importing.data.UserImportRefiner; import com.djrapitops.plan.system.info.server.ServerInfo; -import com.djrapitops.plan.system.processing.importing.ServerImportData; -import com.djrapitops.plan.system.processing.importing.UserImportData; -import com.djrapitops.plan.system.processing.importing.UserImportRefiner; import com.djrapitops.plan.utilities.SHA256Hash; -import com.djrapitops.plugin.api.Benchmark; -import com.djrapitops.plugin.api.utility.log.Log; import com.djrapitops.plugin.utilities.Verify; import com.google.common.collect.ImmutableMap; @@ -29,6 +29,7 @@ import java.util.*; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.TimeUnit; +import java.util.function.Supplier; import java.util.stream.Collectors; /** @@ -37,113 +38,92 @@ import java.util.stream.Collectors; */ public abstract class Importer { - public abstract List getNames(); + private final GeolocationCache geolocationCache; + private final DBSystem dbSystem; + protected final Supplier serverUUID; + + private final String name; + private final Plan plugin; + + protected Importer( + Plan plugin, + GeolocationCache geolocationCache, + DBSystem dbSystem, + ServerInfo serverInfo, + String name + ) { + this.geolocationCache = geolocationCache; + this.dbSystem = dbSystem; + this.serverUUID = serverInfo::getServerUUID; + + this.name = name; + this.plugin = plugin; + } + + @Deprecated + public List getNames() { + return new ArrayList<>(); + } + + public String getName() { + return name; + } public abstract ServerImportData getServerImportData(); public abstract List getUserImportData(); public final void processImport() { - String benchmarkName = "Import processing"; - String serverBenchmarkName = "Server Data processing"; - String userDataBenchmarkName = "User Data processing"; - - Benchmark.start(benchmarkName); - ExecutorService service = Executors.newCachedThreadPool(); - submitTo(service, () -> { - Benchmark.start(serverBenchmarkName); - processServerData(); - Benchmark.stop(serverBenchmarkName); - }); - - submitTo(service, () -> { - Benchmark.start(userDataBenchmarkName); - processUserData(); - Benchmark.stop(userDataBenchmarkName); - }); + submitTo(service, this::processServerData); + submitTo(service, this::processUserData); service.shutdown(); - try { - service.awaitTermination(Long.MAX_VALUE, TimeUnit.NANOSECONDS); + service.awaitTermination(20, TimeUnit.MINUTES); } catch (InterruptedException e) { - Log.toLog(this.getClass(), e); + service.shutdownNow(); Thread.currentThread().interrupt(); } - Benchmark.stop(benchmarkName); } private void processServerData() { - String benchmarkName = "Processing Server Data"; - String getDataBenchmarkName = "Getting Server Data"; - String insertDataIntoDatabaseBenchmarkName = "Insert Server Data into Database"; - - Benchmark.start(benchmarkName); - Benchmark.start(getDataBenchmarkName); - ServerImportData serverImportData = getServerImportData(); - Benchmark.stop(getDataBenchmarkName); - if (serverImportData == null) { - Log.debug("Server Import Data null, skipping"); return; } - UUID uuid = ServerInfo.getServerUUID(); - Database db = Database.getActive(); - ExecutorService service = Executors.newCachedThreadPool(); - Benchmark.start(insertDataIntoDatabaseBenchmarkName); - - SaveOperations save = db.save(); - submitTo(service, () -> save.insertTPS(ImmutableMap.of(uuid, serverImportData.getTpsData()))); - submitTo(service, () -> save.insertCommandUsage(ImmutableMap.of(uuid, serverImportData.getCommandUsages()))); + SaveOperations save = dbSystem.getDatabase().save(); + submitTo(service, () -> save.insertTPS(ImmutableMap.of(serverUUID.get(), serverImportData.getTpsData()))); + submitTo(service, () -> save.insertCommandUsage(ImmutableMap.of(serverUUID.get(), serverImportData.getCommandUsages()))); service.shutdown(); - try { - service.awaitTermination(Long.MAX_VALUE, TimeUnit.NANOSECONDS); + service.awaitTermination(20, TimeUnit.MINUTES); } catch (InterruptedException e) { + service.shutdownNow(); Thread.currentThread().interrupt(); - Log.toLog(this.getClass(), e); } - - Benchmark.stop(insertDataIntoDatabaseBenchmarkName); - Benchmark.stop(benchmarkName); } private void processUserData() { - String benchmarkName = "Processing User Data"; - String getDataBenchmarkName = "Getting User Data"; - String insertDataIntoCollectionsBenchmarkName = "Insert User Data into Collections"; - String insertDataIntoDatabaseBenchmarkName = "Insert User Data into Database"; - - Benchmark.start(benchmarkName); - Benchmark.start(getDataBenchmarkName); - List userImportData = getUserImportData(); - Benchmark.stop(getDataBenchmarkName); if (Verify.isEmpty(userImportData)) { - Log.debug("User Import Data null or empty, skipping"); return; } - UserImportRefiner userImportRefiner = new UserImportRefiner(Plan.getInstance(), userImportData); + UserImportRefiner userImportRefiner = new UserImportRefiner(plugin, userImportData); userImportData = userImportRefiner.refineData(); - UUID serverUUID = ServerInfo.getServerUUID(); - Database db = Database.getActive(); - - Set existingUUIDs = db.fetch().getSavedUUIDs(); - Set existingUserInfoTableUUIDs = db.fetch().getSavedUUIDs(serverUUID); - - Benchmark.start(insertDataIntoCollectionsBenchmarkName); + FetchOperations fetch = dbSystem.getDatabase().fetch(); + Set existingUUIDs = fetch.getSavedUUIDs(); + Set existingUserInfoTableUUIDs = fetch.getSavedUUIDs(serverUUID.get()); Map users = new HashMap<>(); List userInfo = new ArrayList<>(); @@ -170,32 +150,24 @@ public abstract class Importer { sessions.put(uuid, Collections.singletonList(toSession(data))); }); - Benchmark.stop(insertDataIntoCollectionsBenchmarkName); - ExecutorService service = Executors.newCachedThreadPool(); - Benchmark.start(insertDataIntoDatabaseBenchmarkName); - - SaveOperations save = db.save(); + SaveOperations save = dbSystem.getDatabase().save(); save.insertUsers(users); - submitTo(service, () -> save.insertSessions(ImmutableMap.of(serverUUID, sessions), true)); + submitTo(service, () -> save.insertSessions(ImmutableMap.of(serverUUID.get(), sessions), true)); submitTo(service, () -> save.kickAmount(timesKicked)); - submitTo(service, () -> save.insertUserInfo(ImmutableMap.of(serverUUID, userInfo))); - submitTo(service, () -> save.insertNicknames(ImmutableMap.of(serverUUID, nickNames))); + submitTo(service, () -> save.insertUserInfo(ImmutableMap.of(serverUUID.get(), userInfo))); + submitTo(service, () -> save.insertNicknames(ImmutableMap.of(serverUUID.get(), nickNames))); submitTo(service, () -> save.insertAllGeoInfo(geoInfo)); service.shutdown(); - try { - service.awaitTermination(Long.MAX_VALUE, TimeUnit.NANOSECONDS); + service.awaitTermination(20, TimeUnit.MINUTES); } catch (InterruptedException e) { + service.shutdownNow(); Thread.currentThread().interrupt(); - Log.toLog(this.getClass(), e); } - - Benchmark.stop(insertDataIntoDatabaseBenchmarkName); - Benchmark.stop(benchmarkName); } private void submitTo(ExecutorService service, ImportExecutorHelper helper) { @@ -216,7 +188,7 @@ public abstract class Importer { int mobKills = userImportData.getMobKills(); int deaths = userImportData.getDeaths(); - Session session = new Session(0, userImportData.getUuid(), ServerInfo.getServerUUID(), 0L, 0L, mobKills, deaths, 0); + Session session = new Session(0, userImportData.getUuid(), serverUUID.get(), 0L, 0L, mobKills, deaths, 0); session.setPlayerKills(userImportData.getKills()); session.setWorldTimes(new WorldTimes(userImportData.getWorldTimes())); @@ -229,7 +201,7 @@ public abstract class Importer { return userImportData.getIps().parallelStream() .map(ip -> { - String geoLoc = GeolocationCache.getCountry(ip); + String geoLoc = geolocationCache.getCountry(ip); try { return new GeoInfo(ip, geoLoc, date, new SHA256Hash(ip).create()); } catch (NoSuchAlgorithmException e) { @@ -242,14 +214,11 @@ public abstract class Importer { void execute() throws DBException; default void submit(ExecutorService service) { - service.submit(new Runnable() { - @Override - public void run() { - try { - execute(); - } catch (DBException e) { - Log.toLog(this.getClass(), e); - } + service.submit(() -> { + try { + execute(); + } catch (DBException e) { + throw new DBOpException("Import Execution failed", e); } }); } diff --git a/Plan/src/main/java/com/djrapitops/plan/system/processing/importing/importers/OfflinePlayerImporter.java b/Plan/src/main/java/com/djrapitops/plan/system/importing/importers/OfflinePlayerImporter.java similarity index 63% rename from Plan/src/main/java/com/djrapitops/plan/system/processing/importing/importers/OfflinePlayerImporter.java rename to Plan/src/main/java/com/djrapitops/plan/system/importing/importers/OfflinePlayerImporter.java index f31ea5d7a..0dbcb06f5 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/processing/importing/importers/OfflinePlayerImporter.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/importing/importers/OfflinePlayerImporter.java @@ -2,13 +2,19 @@ * License is provided in the jar as LICENSE also here: * https://github.com/Rsl1122/Plan-PlayerAnalytics/blob/master/Plan/src/main/resources/LICENSE */ -package com.djrapitops.plan.system.processing.importing.importers; +package com.djrapitops.plan.system.importing.importers; -import com.djrapitops.plan.system.processing.importing.ServerImportData; -import com.djrapitops.plan.system.processing.importing.UserImportData; +import com.djrapitops.plan.Plan; +import com.djrapitops.plan.system.cache.GeolocationCache; +import com.djrapitops.plan.system.database.DBSystem; +import com.djrapitops.plan.system.importing.data.ServerImportData; +import com.djrapitops.plan.system.importing.data.UserImportData; +import com.djrapitops.plan.system.info.server.ServerInfo; import org.bukkit.Bukkit; import org.bukkit.OfflinePlayer; +import javax.inject.Inject; +import javax.inject.Singleton; import java.util.ArrayList; import java.util.Arrays; import java.util.List; @@ -18,11 +24,17 @@ import java.util.Set; * @author Fuzzlemann * @since 4.0.0 */ +@Singleton public class OfflinePlayerImporter extends Importer { - @Override - public List getNames() { - return Arrays.asList("offline", "offlineplayer"); + @Inject + public OfflinePlayerImporter( + Plan plugin, + GeolocationCache geolocationCache, + DBSystem dbSystem, + ServerInfo serverInfo + ) { + super(plugin, geolocationCache, dbSystem, serverInfo, "offline"); } @Override @@ -38,7 +50,7 @@ public class OfflinePlayerImporter extends Importer { Set banned = Bukkit.getBannedPlayers(); Arrays.stream(Bukkit.getOfflinePlayers()).parallel().forEach(player -> { - UserImportData.UserImportDataBuilder builder = UserImportData.builder(); + UserImportData.UserImportDataBuilder builder = UserImportData.builder(serverUUID.get()); builder.name(player.getName()) .uuid(player.getUniqueId()) .registered(player.getFirstPlayed()); diff --git a/Plan/src/main/java/com/djrapitops/plan/system/info/BungeeInfoSystem.java b/Plan/src/main/java/com/djrapitops/plan/system/info/BungeeInfoSystem.java deleted file mode 100644 index 527597f46..000000000 --- a/Plan/src/main/java/com/djrapitops/plan/system/info/BungeeInfoSystem.java +++ /dev/null @@ -1,55 +0,0 @@ -/* - * License is provided in the jar as LICENSE also here: - * https://github.com/Rsl1122/Plan-PlayerAnalytics/blob/master/Plan/src/main/resources/LICENSE - */ -package com.djrapitops.plan.system.info; - -import com.djrapitops.plan.api.exceptions.ParseException; -import com.djrapitops.plan.api.exceptions.connection.NoServersException; -import com.djrapitops.plan.api.exceptions.connection.WebException; -import com.djrapitops.plan.system.info.connection.BungeeConnectionSystem; -import com.djrapitops.plan.system.info.request.CacheRequest; -import com.djrapitops.plan.system.info.request.GenerateInspectPageRequest; -import com.djrapitops.plan.system.info.request.GenerateInspectPluginsTabRequest; -import com.djrapitops.plan.system.info.request.InfoRequest; -import com.djrapitops.plan.system.info.server.ServerInfo; -import com.djrapitops.plan.system.webserver.cache.PageId; -import com.djrapitops.plan.system.webserver.cache.ResponseCache; -import com.djrapitops.plan.system.webserver.response.errors.InternalErrorResponse; -import com.djrapitops.plan.system.webserver.response.pages.NetworkPageResponse; - -/** - * InfoSystem for Bungee. - * - * @author Rsl1122 - */ -public class BungeeInfoSystem extends InfoSystem { - - public BungeeInfoSystem() { - super(new BungeeConnectionSystem()); - } - - @Override - public void runLocally(InfoRequest infoRequest) throws WebException { - if (infoRequest instanceof CacheRequest - || infoRequest instanceof GenerateInspectPageRequest - || infoRequest instanceof GenerateInspectPluginsTabRequest - ) { - infoRequest.runLocally(); - } else { - // runLocally is called when ConnectionSystem has no servers. - throw new NoServersException("No servers were available to process this request (Local attempt): " + infoRequest.getClass().getSimpleName()); - } - } - - @Override - public void updateNetworkPage() { - ResponseCache.cacheResponse(PageId.SERVER.of(ServerInfo.getServerUUID()), () -> { - try { - return new NetworkPageResponse(); - } catch (ParseException e) { - return new InternalErrorResponse("Network page parsing failed.", e); - } - }); - } -} diff --git a/Plan/src/main/java/com/djrapitops/plan/system/info/InfoSystem.java b/Plan/src/main/java/com/djrapitops/plan/system/info/InfoSystem.java index 713a4158b..f11f96b78 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/info/InfoSystem.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/info/InfoSystem.java @@ -4,24 +4,22 @@ */ package com.djrapitops.plan.system.info; -import com.djrapitops.plan.api.exceptions.EnableException; import com.djrapitops.plan.api.exceptions.connection.BadRequestException; import com.djrapitops.plan.api.exceptions.connection.ConnectionFailException; import com.djrapitops.plan.api.exceptions.connection.NoServersException; import com.djrapitops.plan.api.exceptions.connection.WebException; -import com.djrapitops.plan.system.PlanSystem; +import com.djrapitops.plan.system.DebugChannels; import com.djrapitops.plan.system.SubSystem; import com.djrapitops.plan.system.info.connection.ConnectionSystem; -import com.djrapitops.plan.system.info.request.GenerateAnalysisPageRequest; -import com.djrapitops.plan.system.info.request.GenerateInspectPageRequest; +import com.djrapitops.plan.system.info.request.GenerateRequest; import com.djrapitops.plan.system.info.request.InfoRequest; -import com.djrapitops.plan.system.info.request.SendDBSettingsRequest; +import com.djrapitops.plan.system.info.request.InfoRequestFactory; import com.djrapitops.plan.system.info.server.Server; import com.djrapitops.plan.system.info.server.ServerInfo; -import com.djrapitops.plan.system.webserver.WebServerSystem; +import com.djrapitops.plan.system.webserver.WebServer; import com.djrapitops.plugin.api.Check; -import com.djrapitops.plugin.api.utility.log.Log; -import com.djrapitops.plugin.utilities.Verify; +import com.djrapitops.plugin.logging.console.PluginLogger; +import dagger.Lazy; import java.util.UUID; @@ -36,16 +34,24 @@ import java.util.UUID; */ public abstract class InfoSystem implements SubSystem { + protected final InfoRequestFactory infoRequestFactory; protected final ConnectionSystem connectionSystem; + protected final ServerInfo serverInfo; + protected final Lazy webServer; + protected final PluginLogger logger; - protected InfoSystem(ConnectionSystem connectionSystem) { + protected InfoSystem( + InfoRequestFactory infoRequestFactory, + ConnectionSystem connectionSystem, + ServerInfo serverInfo, + Lazy webServer, + PluginLogger logger + ) { + this.infoRequestFactory = infoRequestFactory; this.connectionSystem = connectionSystem; - } - - public static InfoSystem getInstance() { - InfoSystem infoSystem = PlanSystem.getInstance().getInfoSystem(); - Verify.nullCheck(infoSystem, () -> new IllegalStateException("Info System was not initialized.")); - return infoSystem; + this.serverInfo = serverInfo; + this.webServer = webServer; + this.logger = logger; } /** @@ -57,7 +63,7 @@ public abstract class InfoSystem implements SubSystem { * @throws WebException If fails. */ public void generateAndCachePlayerPage(UUID player) throws WebException { - GenerateInspectPageRequest infoRequest = new GenerateInspectPageRequest(player); + GenerateRequest infoRequest = infoRequestFactory.generateInspectPageRequest(player); try { sendRequest(infoRequest); } catch (ConnectionFailException e) { @@ -74,8 +80,8 @@ public abstract class InfoSystem implements SubSystem { * @throws WebException If fails. */ public void generateAnalysisPage(UUID serverUUID) throws WebException { - GenerateAnalysisPageRequest request = new GenerateAnalysisPageRequest(serverUUID); - if (ServerInfo.getServerUUID().equals(serverUUID)) { + GenerateRequest request = infoRequestFactory.generateAnalysisPageRequest(serverUUID); + if (serverInfo.getServerUUID().equals(serverUUID)) { runLocally(request); } else { sendRequest(request); @@ -93,14 +99,14 @@ public abstract class InfoSystem implements SubSystem { public void sendRequest(InfoRequest infoRequest) throws WebException { try { if (!connectionSystem.isServerAvailable()) { - Log.debug("Main server unavailable, running locally."); + logger.getDebugLogger().logOn(DebugChannels.INFO_REQUESTS, "Main server unavailable, running locally."); runLocally(infoRequest); return; } connectionSystem.sendInfoRequest(infoRequest); } catch (WebException original) { try { - Log.debug("Exception during request: " + original.toString() + ", running locally."); + logger.getDebugLogger().logOn(DebugChannels.INFO_REQUESTS, "Exception during request: " + original.toString() + ", running locally."); runLocally(infoRequest); } catch (NoServersException e2) { throw original; @@ -119,7 +125,7 @@ public abstract class InfoSystem implements SubSystem { public abstract void runLocally(InfoRequest infoRequest) throws WebException; @Override - public void enable() throws EnableException { + public void enable() { connectionSystem.enable(); } @@ -132,15 +138,6 @@ public abstract class InfoSystem implements SubSystem { return connectionSystem; } - /** - * Updates Network page. - *

- * No calls from non-async thread found on 09.02.2018 - * - * @throws WebException If fails. - */ - public abstract void updateNetworkPage() throws WebException; - /** * Requests Set up from Bungee. *

@@ -153,10 +150,13 @@ public abstract class InfoSystem implements SubSystem { if (Check.isBungeeAvailable()) { throw new BadRequestException("Method not available on Bungee."); } + if (Check.isVelocityAvailable()) { + throw new BadRequestException("Method not available on Velocity."); + } Server bungee = new Server(-1, null, "Bungee", addressToRequestServer, -1); - String addressOfThisServer = WebServerSystem.getInstance().getWebServer().getAccessAddress(); + String addressOfThisServer = webServer.get().getAccessAddress(); connectionSystem.setSetupAllowed(true); - connectionSystem.sendInfoRequest(new SendDBSettingsRequest(addressOfThisServer), bungee); + connectionSystem.sendInfoRequest(infoRequestFactory.sendDBSettingsRequest(addressOfThisServer), bungee); } } diff --git a/Plan/src/main/java/com/djrapitops/plan/system/info/ProxyInfoSystem.java b/Plan/src/main/java/com/djrapitops/plan/system/info/ProxyInfoSystem.java new file mode 100644 index 000000000..2b973af21 --- /dev/null +++ b/Plan/src/main/java/com/djrapitops/plan/system/info/ProxyInfoSystem.java @@ -0,0 +1,50 @@ +/* + * License is provided in the jar as LICENSE also here: + * https://github.com/Rsl1122/Plan-PlayerAnalytics/blob/master/Plan/src/main/resources/LICENSE + */ +package com.djrapitops.plan.system.info; + +import com.djrapitops.plan.api.exceptions.connection.NoServersException; +import com.djrapitops.plan.api.exceptions.connection.WebException; +import com.djrapitops.plan.system.info.connection.ConnectionSystem; +import com.djrapitops.plan.system.info.request.*; +import com.djrapitops.plan.system.info.server.ServerInfo; +import com.djrapitops.plan.system.webserver.WebServer; +import com.djrapitops.plugin.logging.console.PluginLogger; +import dagger.Lazy; + +import javax.inject.Inject; +import javax.inject.Singleton; + +/** + * InfoSystem for Bungee. + * + * @author Rsl1122 + */ +@Singleton +public class ProxyInfoSystem extends InfoSystem { + + @Inject + public ProxyInfoSystem( + InfoRequestFactory infoRequestFactory, + ConnectionSystem connectionSystem, + ServerInfo serverInfo, + Lazy webServer, + PluginLogger logger + ) { + super(infoRequestFactory, connectionSystem, serverInfo, webServer, logger); + } + + @Override + public void runLocally(InfoRequest infoRequest) throws WebException { + if (infoRequest instanceof CacheRequest + || infoRequest instanceof GenerateInspectPageRequest + || infoRequest instanceof GenerateInspectPluginsTabRequest + ) { + infoRequest.runLocally(); + } else { + // runLocally is called when ConnectionSystem has no servers. + throw new NoServersException("No servers were available to process this request (Local attempt): " + infoRequest.getClass().getSimpleName()); + } + } +} diff --git a/Plan/src/main/java/com/djrapitops/plan/system/info/ServerInfoSystem.java b/Plan/src/main/java/com/djrapitops/plan/system/info/ServerInfoSystem.java index ed5b4908e..633ef1782 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/info/ServerInfoSystem.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/info/ServerInfoSystem.java @@ -6,26 +6,39 @@ package com.djrapitops.plan.system.info; import com.djrapitops.plan.api.exceptions.connection.NoServersException; import com.djrapitops.plan.api.exceptions.connection.WebException; -import com.djrapitops.plan.system.info.connection.ServerConnectionSystem; -import com.djrapitops.plan.system.info.request.CacheNetworkPageContentRequest; +import com.djrapitops.plan.system.DebugChannels; +import com.djrapitops.plan.system.info.connection.ConnectionSystem; import com.djrapitops.plan.system.info.request.InfoRequest; +import com.djrapitops.plan.system.info.request.InfoRequestFactory; import com.djrapitops.plan.system.info.request.SetupRequest; import com.djrapitops.plan.system.info.server.ServerInfo; -import com.djrapitops.plan.system.locale.Locale; -import com.djrapitops.plan.utilities.html.HtmlStructure; -import com.djrapitops.plugin.api.utility.log.Log; +import com.djrapitops.plan.system.webserver.WebServer; +import com.djrapitops.plugin.logging.console.PluginLogger; +import dagger.Lazy; -import java.util.function.Supplier; +import javax.inject.Inject; +import javax.inject.Singleton; /** * InfoSystem for Bukkit servers. * * @author Rsl1122 */ +@Singleton public class ServerInfoSystem extends InfoSystem { - public ServerInfoSystem(Supplier locale) { - super(new ServerConnectionSystem(locale)); + private final PluginLogger logger; + + @Inject + public ServerInfoSystem( + ConnectionSystem connectionSystem, + ServerInfo serverInfo, + InfoRequestFactory infoRequestFactory, + Lazy webServer, + PluginLogger logger + ) { + super(infoRequestFactory, connectionSystem, serverInfo, webServer, logger); + this.logger = logger; } @Override @@ -33,13 +46,7 @@ public class ServerInfoSystem extends InfoSystem { if (infoRequest instanceof SetupRequest) { throw new NoServersException("Set-up requests can not be run locally."); } - Log.debug("LocalRun: " + infoRequest.getClass().getSimpleName()); + logger.getDebugLogger().logOn(DebugChannels.INFO_REQUESTS, "Local: " + infoRequest.getClass().getSimpleName()); infoRequest.runLocally(); } - - @Override - public void updateNetworkPage() throws WebException { - String html = HtmlStructure.createServerContainer(); - sendRequest(new CacheNetworkPageContentRequest(ServerInfo.getServerUUID(), html)); - } } diff --git a/Plan/src/main/java/com/djrapitops/plan/system/info/connection/ConnectionIn.java b/Plan/src/main/java/com/djrapitops/plan/system/info/connection/ConnectionIn.java index ee38bfcb7..b578f2068 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/info/connection/ConnectionIn.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/info/connection/ConnectionIn.java @@ -7,7 +7,6 @@ import com.djrapitops.plan.system.info.request.InfoRequest; import com.djrapitops.plan.system.info.request.SetupRequest; import com.djrapitops.plan.system.webserver.Request; import com.djrapitops.plan.system.webserver.response.Response; -import com.djrapitops.plugin.api.utility.log.Log; import com.djrapitops.plugin.utilities.Verify; import java.io.ByteArrayOutputStream; @@ -23,8 +22,16 @@ public class ConnectionIn { private final Map variables; private final InfoRequest infoRequest; + private final Database database; + private final ConnectionSystem connectionSystem; - public ConnectionIn(Request httpRequest, InfoRequest infoRequest) throws WebException { + public ConnectionIn( + Request httpRequest, InfoRequest infoRequest, + Database database, + ConnectionSystem connectionSystem + ) throws WebException { + this.database = database; + this.connectionSystem = connectionSystem; Verify.nullCheck(httpRequest, infoRequest); this.variables = readVariables(httpRequest); @@ -37,17 +44,15 @@ public class ConnectionIn { UUID serverUUID = getServerUUID(); try { - if (Database.getActive().check().isServerInDatabase(serverUUID)) { + if (database.check().isServerInDatabase(serverUUID)) { return; } } catch (DBOpException e) { throw new TransferDatabaseException(e); } - Log.debug("ConnectionIn: " + infoRequest.getClass().getSimpleName()); - if (infoRequest instanceof SetupRequest) { - if (!ConnectionSystem.isSetupAllowed()) { + if (!connectionSystem.isSetupAllowed()) { throw new ForbiddenException("Setup not enabled on this server, use commands to enable."); } } else { diff --git a/Plan/src/main/java/com/djrapitops/plan/system/info/connection/ConnectionLog.java b/Plan/src/main/java/com/djrapitops/plan/system/info/connection/ConnectionLog.java index db16a8369..a7007cf2d 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/info/connection/ConnectionLog.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/info/connection/ConnectionLog.java @@ -5,60 +5,54 @@ package com.djrapitops.plan.system.info.connection; import com.djrapitops.plan.data.store.objects.DateHolder; +import com.djrapitops.plan.system.DebugChannels; import com.djrapitops.plan.system.info.request.InfoRequest; import com.djrapitops.plan.system.info.server.Server; -import com.djrapitops.plugin.api.utility.log.Log; +import com.djrapitops.plugin.logging.debug.DebugLogger; +import javax.inject.Inject; +import javax.inject.Singleton; import java.util.HashMap; import java.util.Map; import java.util.Objects; /** - * Class responsible for logging what ConnectionOut objects get in return. + * Class responsible for logging what {@link ConnectionOut} and {@link ConnectionIn} objects get as response. * * @author Rsl1122 */ +@Singleton public class ConnectionLog { - private Map> log; + private final DebugLogger debugLogger; - public ConnectionLog() { - this.log = new HashMap<>(); + private final Map> log; + + @Inject + public ConnectionLog(DebugLogger debugLogger) { + this.debugLogger = debugLogger; + log = new HashMap<>(); } - /** - * Get a map sorted by Addresses, then Requests and then Log entries. - * - * @return {@code Map<"In: "/"Out: "+Address, Map>} - */ - public static Map> getLogEntries() { - return getInstance().getLog(); - } - - public static void logConnectionTo(Server server, InfoRequest request, int responseCode) { + public void logConnectionTo(Server server, InfoRequest request, int responseCode) { String requestName = request.getClass().getSimpleName(); String address = server.getWebAddress(); logConnection(address, "Out: " + requestName, responseCode); - Log.debug("ConnectionOut: " + requestName + " to " + address); + debugLogger.logOn(DebugChannels.CONNECTIONS, "ConnectionOut: " + requestName + " to " + address); } - public static void logConnectionFrom(String server, String requestTarget, int responseCode) { + public void logConnectionFrom(String server, String requestTarget, int responseCode) { logConnection(server, "In: " + requestTarget, responseCode); - Log.debug("ConnectionIn: " + requestTarget + " from " + server); + debugLogger.logOn(DebugChannels.CONNECTIONS, "ConnectionIn: " + requestTarget + " from " + server); } - private static void logConnection(String address, String infoRequestName, int responseCode) { - Map> log = getInstance().log; + private void logConnection(String address, String infoRequestName, int responseCode) { Map requestMap = log.getOrDefault(address, new HashMap<>()); requestMap.put(infoRequestName, new Entry(responseCode, System.currentTimeMillis())); log.put(address, requestMap); } - private static ConnectionLog getInstance() { - return ConnectionSystem.getInstance().getConnectionLog(); - } - - public Map> getLog() { + public Map> getLogEntries() { return log; } diff --git a/Plan/src/main/java/com/djrapitops/plan/system/info/connection/ConnectionOut.java b/Plan/src/main/java/com/djrapitops/plan/system/info/connection/ConnectionOut.java index 15881c207..e781667e6 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/info/connection/ConnectionOut.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/info/connection/ConnectionOut.java @@ -8,10 +8,7 @@ import com.djrapitops.plan.api.exceptions.connection.*; import com.djrapitops.plan.system.info.request.InfoRequest; import com.djrapitops.plan.system.info.request.InfoRequestWithVariables; import com.djrapitops.plan.system.info.server.Server; -import com.djrapitops.plan.system.settings.Settings; import com.djrapitops.plan.utilities.MiscUtils; -import com.djrapitops.plugin.api.TimeAmount; -import com.djrapitops.plugin.api.utility.log.Log; import com.djrapitops.plugin.utilities.Verify; import org.apache.http.client.config.RequestConfig; import org.apache.http.client.methods.CloseableHttpResponse; @@ -32,6 +29,7 @@ import java.security.NoSuchAlgorithmException; import java.util.Map; import java.util.Properties; import java.util.UUID; +import java.util.concurrent.TimeUnit; import java.util.logging.Level; import java.util.logging.Logger; @@ -49,22 +47,28 @@ public class ConnectionOut { static { try { Properties properties = System.getProperties(); - properties.setProperty("sun.net.client.defaultConnectTimeout", Long.toString(TimeAmount.MINUTE.ms())); - properties.setProperty("sun.net.client.defaultReadTimeout", Long.toString(TimeAmount.MINUTE.ms())); + properties.setProperty("sun.net.client.defaultConnectTimeout", Long.toString(TimeUnit.MINUTES.toMillis(1L))); + properties.setProperty("sun.net.client.defaultReadTimeout", Long.toString(TimeUnit.MINUTES.toMillis(1L))); properties.setProperty("sun.net.http.retryPost", Boolean.toString(false)); } catch (Exception e) { Logger.getGlobal().log(Level.WARNING, "[Plan] Failed to set sun client timeout system properties.", e); } } + private final ConnectionLog connectionLog; + /** * Constructor. - * - * @param toServer Full address to another Plan webserver. (http://something:port) + * @param toServer Full address to another Plan webserver. (http://something:port) * @param serverUUID UUID of server this outbound connection. * @param infoRequest Type of the action this connection wants to be performed. + * @param connectionLog */ - public ConnectionOut(Server toServer, UUID serverUUID, InfoRequest infoRequest) { + public ConnectionOut( + Server toServer, UUID serverUUID, InfoRequest infoRequest, + ConnectionLog connectionLog + ) { + this.connectionLog = connectionLog; Verify.nullCheck(toServer, serverUUID, infoRequest); this.toServer = toServer; this.serverUUID = serverUUID; @@ -91,14 +95,10 @@ public class ConnectionOut { handleResult(url, parameters, responseCode); } catch (SocketTimeoutException e) { - ConnectionLog.logConnectionTo(toServer, infoRequest, 0); + connectionLog.logConnectionTo(toServer, infoRequest, 0); throw new ConnectionFailException("Connection to " + address + " timed out after 10 seconds.", e); } catch (NoSuchAlgorithmException | KeyStoreException | KeyManagementException | IOException e) { - if (Settings.DEV_MODE.isTrue()) { - Log.warn("THIS ERROR IS ONLY LOGGED IN DEV MODE:"); - Log.toLog(this.getClass(), e); - } - ConnectionLog.logConnectionTo(toServer, infoRequest, -1); + connectionLog.logConnectionTo(toServer, infoRequest, -1); throw new ConnectionFailException("Connection failed to address: " + address + " - Make sure the server is online.", e); } finally { if (post != null) { @@ -110,7 +110,7 @@ public class ConnectionOut { } private void handleResult(String url, String parameters, int responseCode) throws WebException { - ConnectionLog.logConnectionTo(toServer, infoRequest, responseCode); + connectionLog.logConnectionTo(toServer, infoRequest, responseCode); switch (responseCode) { case 200: return; diff --git a/Plan/src/main/java/com/djrapitops/plan/system/info/connection/ConnectionSystem.java b/Plan/src/main/java/com/djrapitops/plan/system/info/connection/ConnectionSystem.java index 080f33ee1..d0daa77ae 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/info/connection/ConnectionSystem.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/info/connection/ConnectionSystem.java @@ -8,10 +8,12 @@ import com.djrapitops.plan.api.exceptions.connection.NoServersException; import com.djrapitops.plan.api.exceptions.connection.WebException; import com.djrapitops.plan.system.SubSystem; import com.djrapitops.plan.system.info.InfoSystem; -import com.djrapitops.plan.system.info.request.*; +import com.djrapitops.plan.system.info.request.InfoRequest; +import com.djrapitops.plan.system.info.request.InfoRequests; +import com.djrapitops.plan.system.info.request.WideRequest; import com.djrapitops.plan.system.info.server.Server; import com.djrapitops.plan.system.info.server.ServerInfo; -import com.djrapitops.plugin.utilities.Verify; +import dagger.Lazy; import java.util.*; @@ -25,43 +27,39 @@ import java.util.*; public abstract class ConnectionSystem implements SubSystem { protected final ConnectionLog connectionLog; - protected final Map dataRequests; + protected final InfoRequests infoRequests; + protected final Lazy infoSystem; + protected final ServerInfo serverInfo; + protected Map bukkitServers; private boolean setupAllowed; - public ConnectionSystem() { + public ConnectionSystem( + ConnectionLog connectionLog, + InfoRequests infoRequests, + Lazy infoSystem, + ServerInfo serverInfo + ) { + this.connectionLog = connectionLog; + this.infoSystem = infoSystem; + this.serverInfo = serverInfo; setupAllowed = false; bukkitServers = new HashMap<>(); - dataRequests = loadDataRequests(); - connectionLog = new ConnectionLog(); - } - - public static ConnectionSystem getInstance() { - ConnectionSystem connectionSystem = InfoSystem.getInstance().getConnectionSystem(); - Verify.nullCheck(connectionSystem, () -> new IllegalStateException("Connection System was not initialized")); - return connectionSystem; - } - - public static boolean isSetupAllowed() { - return getInstance().setupAllowed; + this.infoRequests = infoRequests; } public InfoRequest getInfoRequest(String name) { - return dataRequests.get(name.toLowerCase()); + return infoRequests.get(name.toLowerCase()); } public void setSetupAllowed(boolean setupAllowed) { this.setupAllowed = setupAllowed; } - private void putRequest(Map requests, InfoRequest request) { - requests.put(request.getClass().getSimpleName().toLowerCase(), request); - } - protected abstract Server selectServerForRequest(InfoRequest infoRequest) throws NoServersException; - public static String getAddress() { - return getInstance().getMainAddress(); + public boolean isSetupAllowed() { + return setupAllowed; } public void sendInfoRequest(InfoRequest infoRequest) throws WebException { @@ -70,10 +68,11 @@ public abstract class ConnectionSystem implements SubSystem { } public void sendInfoRequest(InfoRequest infoRequest, Server toServer) throws WebException { - if (ServerInfo.getServerUUID().equals(toServer.getUuid())) { - InfoSystem.getInstance().runLocally(infoRequest); + UUID serverUUID = serverInfo.getServerUUID(); + if (serverUUID.equals(toServer.getUuid())) { + infoSystem.get().runLocally(infoRequest); } else { - new ConnectionOut(toServer, ServerInfo.getServerUUID(), infoRequest).sendRequest(); + new ConnectionOut(toServer, serverUUID, infoRequest, connectionLog).sendRequest(); } } @@ -87,35 +86,19 @@ public abstract class ConnectionSystem implements SubSystem { public abstract void sendWideInfoRequest(WideRequest infoRequest) throws NoServersException; - private Map loadDataRequests() { - Map requests = new HashMap<>(); - putRequest(requests, CacheInspectPageRequest.createHandler()); - putRequest(requests, CacheInspectPluginsTabRequest.createHandler()); - putRequest(requests, CacheAnalysisPageRequest.createHandler()); - putRequest(requests, CacheNetworkPageContentRequest.createHandler()); - - putRequest(requests, GenerateAnalysisPageRequest.createHandler()); - putRequest(requests, GenerateInspectPageRequest.createHandler()); - putRequest(requests, GenerateInspectPluginsTabRequest.createHandler()); - putRequest(requests, GenerateNetworkPageContentRequest.createHandler()); - - putRequest(requests, SaveDBSettingsRequest.createHandler()); - putRequest(requests, SendDBSettingsRequest.createHandler()); - putRequest(requests, CheckConnectionRequest.createHandler()); - -// putRequest(requests, UpdateRequest.createHandler()); -// putRequest(requests, UpdateCancelRequest.createHandler()); - return requests; - } - public List getBukkitServers() { return new ArrayList<>(bukkitServers.values()); } + @Override + public void enable() { + infoRequests.initializeRequests(); + } + @Override public void disable() { setupAllowed = false; bukkitServers.clear(); - dataRequests.clear(); + infoRequests.clear(); } } diff --git a/Plan/src/main/java/com/djrapitops/plan/system/info/connection/InfoRequestPageHandler.java b/Plan/src/main/java/com/djrapitops/plan/system/info/connection/InfoRequestPageHandler.java index ae81efed2..5d0291f55 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/info/connection/InfoRequestPageHandler.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/info/connection/InfoRequestPageHandler.java @@ -6,15 +6,18 @@ package com.djrapitops.plan.system.info.connection; import com.djrapitops.plan.api.exceptions.connection.NotFoundException; import com.djrapitops.plan.api.exceptions.connection.WebException; +import com.djrapitops.plan.system.database.DBSystem; import com.djrapitops.plan.system.info.request.InfoRequest; -import com.djrapitops.plan.system.locale.lang.ErrorPageLang; import com.djrapitops.plan.system.webserver.Request; import com.djrapitops.plan.system.webserver.pages.PageHandler; import com.djrapitops.plan.system.webserver.response.Response; +import com.djrapitops.plan.system.webserver.response.ResponseFactory; import com.djrapitops.plan.system.webserver.response.errors.BadRequestResponse; -import com.djrapitops.plan.system.webserver.response.errors.NotFoundResponse; +import com.djrapitops.plugin.logging.console.PluginLogger; import com.djrapitops.plugin.utilities.Verify; +import javax.inject.Inject; +import javax.inject.Singleton; import java.util.List; /** @@ -26,7 +29,25 @@ import java.util.List; * * @author Rsl1122 */ -public class InfoRequestPageHandler extends PageHandler { +@Singleton +public class InfoRequestPageHandler implements PageHandler { + + private final DBSystem dbSystem; + private final ConnectionSystem connectionSystem; + private final ResponseFactory responseFactory; + private final PluginLogger logger; + + @Inject + public InfoRequestPageHandler( + DBSystem dbSystem, + ConnectionSystem connectionSystem, + ResponseFactory responseFactory, PluginLogger logger + ) { + this.dbSystem = dbSystem; + this.connectionSystem = connectionSystem; + this.responseFactory = responseFactory; + this.logger = logger; + } @Override public Response getResponse(Request request, List target) throws WebException { @@ -34,7 +55,7 @@ public class InfoRequestPageHandler extends PageHandler { try { if (target.isEmpty()) { - return new NotFoundResponse(request.getLocale().getString(ErrorPageLang.UNKNOWN_PAGE_404)); + return responseFactory.pageNotFound404(); } if (!request.getRequestMethod().equals("POST")) { @@ -42,16 +63,17 @@ public class InfoRequestPageHandler extends PageHandler { } String requestName = target.get(0); - InfoRequest infoRequest = ConnectionSystem.getInstance().getInfoRequest(requestName); + InfoRequest infoRequest = connectionSystem.getInfoRequest(requestName); Verify.nullCheck(infoRequest, () -> new NotFoundException("Info Request has not been registered.")); - return new ConnectionIn(request, infoRequest).handleRequest(); + logger.debug("ConnectionIn: " + infoRequest.getClass().getSimpleName()); + return new ConnectionIn(request, infoRequest, dbSystem.getDatabase(), connectionSystem).handleRequest(); } catch (WebException e) { responseCode = getResponseCodeFor(e); throw e; } finally { - ConnectionLog.logConnectionFrom(request.getRemoteAddress(), request.getTarget(), responseCode); + connectionSystem.getConnectionLog().logConnectionFrom(request.getRemoteAddress(), request.getTarget(), responseCode); } } diff --git a/Plan/src/main/java/com/djrapitops/plan/system/info/connection/BungeeConnectionSystem.java b/Plan/src/main/java/com/djrapitops/plan/system/info/connection/ProxyConnectionSystem.java similarity index 59% rename from Plan/src/main/java/com/djrapitops/plan/system/info/connection/BungeeConnectionSystem.java rename to Plan/src/main/java/com/djrapitops/plan/system/info/connection/ProxyConnectionSystem.java index ae9516525..7e86576a9 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/info/connection/BungeeConnectionSystem.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/info/connection/ProxyConnectionSystem.java @@ -6,37 +6,62 @@ package com.djrapitops.plan.system.info.connection; import com.djrapitops.plan.api.exceptions.connection.NoServersException; import com.djrapitops.plan.api.exceptions.database.DBOpException; -import com.djrapitops.plan.system.database.databases.Database; +import com.djrapitops.plan.system.database.DBSystem; import com.djrapitops.plan.system.info.InfoSystem; import com.djrapitops.plan.system.info.request.*; import com.djrapitops.plan.system.info.server.Server; import com.djrapitops.plan.system.info.server.ServerInfo; -import com.djrapitops.plan.system.webserver.WebServerSystem; -import com.djrapitops.plugin.api.TimeAmount; -import com.djrapitops.plugin.api.utility.log.Log; +import com.djrapitops.plan.system.webserver.WebServer; +import com.djrapitops.plugin.logging.L; +import com.djrapitops.plugin.logging.error.ErrorHandler; +import dagger.Lazy; +import javax.inject.Inject; +import javax.inject.Singleton; import java.util.UUID; +import java.util.concurrent.TimeUnit; /** - * ConnectionSystem for Bungee. + * ConnectionSystem for proxy servers. * * @author Rsl1122 */ -public class BungeeConnectionSystem extends ConnectionSystem { +@Singleton +public class ProxyConnectionSystem extends ConnectionSystem { + + private final DBSystem dbSystem; + private final Lazy webServer; + private final ErrorHandler errorHandler; + private final WebExceptionLogger webExceptionLogger; private long latestServerMapRefresh; - public BungeeConnectionSystem() { + @Inject + public ProxyConnectionSystem( + DBSystem dbSystem, + Lazy webServer, + ConnectionLog connectionLog, + InfoRequests infoRequests, + Lazy infoSystem, + ServerInfo serverInfo, + ErrorHandler errorHandler, + WebExceptionLogger webExceptionLogger + ) { + super(connectionLog, infoRequests, infoSystem, serverInfo); + this.dbSystem = dbSystem; + this.webServer = webServer; + this.errorHandler = errorHandler; + this.webExceptionLogger = webExceptionLogger; latestServerMapRefresh = 0; } private void refreshServerMap() { - if (latestServerMapRefresh < System.currentTimeMillis() - TimeAmount.SECOND.ms() * 15L) { + if (latestServerMapRefresh < System.currentTimeMillis() - TimeUnit.SECONDS.toMillis(15L)) { try { - bukkitServers = Database.getActive().fetch().getBukkitServers(); + bukkitServers = dbSystem.getDatabase().fetch().getBukkitServers(); latestServerMapRefresh = System.currentTimeMillis(); } catch (DBOpException e) { - Log.toLog(this.getClass(), e); + errorHandler.log(L.ERROR, this.getClass(), e); } } } @@ -49,7 +74,7 @@ public class BungeeConnectionSystem extends ConnectionSystem { || infoRequest instanceof GenerateInspectPageRequest || infoRequest instanceof GenerateInspectPluginsTabRequest) { // Run locally - return ServerInfo.getServer(); + return serverInfo.getServer(); } else if (infoRequest instanceof GenerateAnalysisPageRequest) { UUID serverUUID = ((GenerateAnalysisPageRequest) infoRequest).getServerUUID(); server = bukkitServers.get(serverUUID); @@ -67,11 +92,11 @@ public class BungeeConnectionSystem extends ConnectionSystem { throw new NoServersException("No Servers available to make wide-request: " + infoRequest.getClass().getSimpleName()); } for (Server server : bukkitServers.values()) { - WebExceptionLogger.logIfOccurs(this.getClass(), () -> sendInfoRequest(infoRequest, server)); + webExceptionLogger.logIfOccurs(this.getClass(), () -> sendInfoRequest(infoRequest, server)); } - // Quick hack + // Quick hack for Bungee Plugins Tab if (infoRequest instanceof GenerateInspectPluginsTabRequest) { - WebExceptionLogger.logIfOccurs(this.getClass(), () -> InfoSystem.getInstance().sendRequest(infoRequest)); + webExceptionLogger.logIfOccurs(this.getClass(), infoRequest::runLocally); } } @@ -82,11 +107,12 @@ public class BungeeConnectionSystem extends ConnectionSystem { @Override public String getMainAddress() { - return WebServerSystem.getInstance().getWebServer().getAccessAddress(); + return webServer.get().getAccessAddress(); } @Override public void enable() { + super.enable(); refreshServerMap(); } diff --git a/Plan/src/main/java/com/djrapitops/plan/system/info/connection/ServerConnectionSystem.java b/Plan/src/main/java/com/djrapitops/plan/system/info/connection/ServerConnectionSystem.java index c4c7870b3..fe702cf69 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/info/connection/ServerConnectionSystem.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/info/connection/ServerConnectionSystem.java @@ -6,7 +6,9 @@ package com.djrapitops.plan.system.info.connection; import com.djrapitops.plan.api.exceptions.connection.ConnectionFailException; import com.djrapitops.plan.api.exceptions.connection.NoServersException; -import com.djrapitops.plan.system.database.databases.Database; +import com.djrapitops.plan.system.database.DBSystem; +import com.djrapitops.plan.system.database.databases.operation.FetchOperations; +import com.djrapitops.plan.system.info.InfoSystem; import com.djrapitops.plan.system.info.request.*; import com.djrapitops.plan.system.info.server.Server; import com.djrapitops.plan.system.info.server.ServerInfo; @@ -14,39 +16,68 @@ import com.djrapitops.plan.system.locale.Locale; import com.djrapitops.plan.system.locale.lang.PluginLang; import com.djrapitops.plan.system.processing.Processing; import com.djrapitops.plan.system.settings.Settings; -import com.djrapitops.plan.system.webserver.WebServerSystem; -import com.djrapitops.plugin.api.TimeAmount; -import com.djrapitops.plugin.api.utility.log.Log; +import com.djrapitops.plan.system.settings.config.PlanConfig; +import com.djrapitops.plan.system.webserver.WebServer; +import com.djrapitops.plugin.logging.L; +import com.djrapitops.plugin.logging.console.PluginLogger; +import dagger.Lazy; -import java.util.Optional; +import javax.inject.Inject; +import javax.inject.Singleton; import java.util.UUID; -import java.util.function.Supplier; +import java.util.concurrent.TimeUnit; /** * Connection system for Bukkit servers. * * @author Rsl1122 */ +@Singleton public class ServerConnectionSystem extends ConnectionSystem { - private final Supplier locale; + private final Locale locale; + private final PlanConfig config; + private final Processing processing; + private final DBSystem dbSystem; + private final Lazy webServer; + private final PluginLogger pluginLogger; + private final WebExceptionLogger webExceptionLogger; private long latestServerMapRefresh; private Server mainServer; - public ServerConnectionSystem(Supplier locale) { + @Inject + public ServerConnectionSystem( + Locale locale, + PlanConfig config, + Processing processing, + DBSystem dbSystem, + Lazy webServer, + ConnectionLog connectionLog, + InfoRequests infoRequests, + Lazy infoSystem, + ServerInfo serverInfo, + PluginLogger pluginLogger, + WebExceptionLogger webExceptionLogger + ) { + super(connectionLog, infoRequests, infoSystem, serverInfo); this.locale = locale; + this.config = config; + this.processing = processing; + this.dbSystem = dbSystem; + this.webServer = webServer; + this.pluginLogger = pluginLogger; + this.webExceptionLogger = webExceptionLogger; latestServerMapRefresh = 0; } private void refreshServerMap() { - Processing.submitNonCritical(() -> { - if (latestServerMapRefresh < System.currentTimeMillis() - TimeAmount.SECOND.ms() * 15L) { - Database database = Database.getActive(); - Optional bungeeInformation = database.fetch().getBungeeInformation(); - bungeeInformation.ifPresent(server -> mainServer = server); - bukkitServers = database.fetch().getBukkitServers(); + processing.submitNonCritical(() -> { + if (latestServerMapRefresh < System.currentTimeMillis() - TimeUnit.SECONDS.toMillis(15L)) { + FetchOperations fetch = dbSystem.getDatabase().fetch(); + mainServer = fetch.getBungeeInformation().orElse(null); + bukkitServers = fetch.getBukkitServers(); latestServerMapRefresh = System.currentTimeMillis(); } }); @@ -80,7 +111,7 @@ public class ServerConnectionSystem extends ConnectionSystem { throw new NoServersException("No Servers available to make wide-request: " + infoRequest.getClass().getSimpleName()); } for (Server server : bukkitServers.values()) { - WebExceptionLogger.logIfOccurs(this.getClass(), () -> { + webExceptionLogger.logIfOccurs(this.getClass(), () -> { try { sendInfoRequest(infoRequest, server); } catch (ConnectionFailException ignored) { @@ -92,28 +123,29 @@ public class ServerConnectionSystem extends ConnectionSystem { @Override public boolean isServerAvailable() { - return mainServer != null && Settings.BUNGEE_OVERRIDE_STANDALONE_MODE.isFalse(); + return mainServer != null && config.isFalse(Settings.BUNGEE_OVERRIDE_STANDALONE_MODE); } @Override public String getMainAddress() { - return isServerAvailable() ? mainServer.getWebAddress() : ServerInfo.getServer().getWebAddress(); + return isServerAvailable() ? mainServer.getWebAddress() : serverInfo.getServer().getWebAddress(); } @Override public void enable() { + super.enable(); refreshServerMap(); - boolean usingBungeeWebServer = ConnectionSystem.getInstance().isServerAvailable(); - boolean usingAlternativeIP = Settings.SHOW_ALTERNATIVE_IP.isTrue(); + boolean usingBungeeWebServer = isServerAvailable(); + boolean usingAlternativeIP = config.isTrue(Settings.SHOW_ALTERNATIVE_IP); - if (!usingAlternativeIP && ServerInfo.getServerProperties().getIp().isEmpty()) { - Log.infoColor("§e" + locale.get().getString(PluginLang.ENABLE_NOTIFY_EMPTY_IP)); + if (!usingAlternativeIP && serverInfo.getServerProperties().getIp().isEmpty()) { + pluginLogger.log(L.INFO_COLOR, "§e" + locale.getString(PluginLang.ENABLE_NOTIFY_EMPTY_IP)); } if (usingBungeeWebServer && usingAlternativeIP) { - String webServerAddress = WebServerSystem.getInstance().getWebServer().getAccessAddress(); - Log.info(locale.get().getString(PluginLang.ENABLE_NOTIFY_ADDRESS_CONFIRMATION, webServerAddress)); + String webServerAddress = webServer.get().getAccessAddress(); + pluginLogger.info(locale.getString(PluginLang.ENABLE_NOTIFY_ADDRESS_CONFIRMATION, webServerAddress)); } } } diff --git a/Plan/src/main/java/com/djrapitops/plan/system/info/connection/WebExceptionLogger.java b/Plan/src/main/java/com/djrapitops/plan/system/info/connection/WebExceptionLogger.java index 73bac53ff..731f8c6be 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/info/connection/WebExceptionLogger.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/info/connection/WebExceptionLogger.java @@ -6,8 +6,12 @@ package com.djrapitops.plan.system.info.connection; import com.djrapitops.plan.api.exceptions.connection.*; import com.djrapitops.plan.utilities.java.ThrowingVoidFunction; -import com.djrapitops.plugin.api.utility.log.Log; +import com.djrapitops.plugin.logging.L; +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.ArrayList; import java.util.Collections; import java.util.List; @@ -18,29 +22,45 @@ import java.util.Map; * * @author Rsl1122 */ +@Singleton public class WebExceptionLogger { - public static void logIfOccurs(Class c, ThrowingVoidFunction function) { + private final ConnectionLog connectionLog; + private final PluginLogger logger; + private final ErrorHandler errorHandler; + + @Inject + public WebExceptionLogger( + ConnectionLog connectionLog, + PluginLogger logger, + ErrorHandler errorHandler + ) { + this.connectionLog = connectionLog; + this.logger = logger; + this.errorHandler = errorHandler; + } + + public void logIfOccurs(Class definingClass, ThrowingVoidFunction function) { try { function.apply(); } catch (ConnectionFailException e) { if (shouldLog(e)) { - Log.debug(e.getMessage()); + logger.debug(e.getMessage()); } } catch (UnsupportedTransferDatabaseException | UnauthorizedServerException | NotFoundException | NoServersException e) { - Log.debug(e.getMessage()); + logger.debug(e.getMessage()); } catch (WebException e) { - Log.toLog(c, e); + errorHandler.log(L.WARN, definingClass, e); } } - private static boolean shouldLog(ConnectionFailException e) { + private boolean shouldLog(ConnectionFailException e) { String address = getAddress(e); if (address == null) { return true; } - Map> logEntries = ConnectionLog.getLogEntries(); + Map> logEntries = connectionLog.getLogEntries(); Map entries = logEntries.get("Out: " + address); if (entries != null) { List connections = new ArrayList<>(entries.values()); @@ -62,8 +82,4 @@ public class WebExceptionLogger { } return null; } - - private WebExceptionLogger() { - // Static method class. - } } diff --git a/Plan/src/main/java/com/djrapitops/plan/system/info/request/CacheAnalysisPageRequest.java b/Plan/src/main/java/com/djrapitops/plan/system/info/request/CacheAnalysisPageRequest.java index 251c165f3..ddb36c0fb 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/info/request/CacheAnalysisPageRequest.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/info/request/CacheAnalysisPageRequest.java @@ -8,6 +8,7 @@ import com.djrapitops.plan.api.exceptions.connection.BadRequestException; import com.djrapitops.plan.api.exceptions.connection.WebException; import com.djrapitops.plan.system.processing.Processing; import com.djrapitops.plan.system.settings.Settings; +import com.djrapitops.plan.system.settings.config.PlanConfig; import com.djrapitops.plan.system.webserver.cache.PageId; import com.djrapitops.plan.system.webserver.cache.ResponseCache; import com.djrapitops.plan.system.webserver.response.DefaultResponses; @@ -27,25 +28,45 @@ import java.util.UUID; */ public class CacheAnalysisPageRequest extends InfoRequestWithVariables implements CacheRequest { - private final UUID serverUUID; - private final String html; + private final PlanConfig config; + private final Processing processing; + private final HtmlExport htmlExport; - private CacheAnalysisPageRequest() { - serverUUID = null; - html = null; + private final UUID networkUUID; + + private UUID serverUUID; + private String html; + + CacheAnalysisPageRequest( + PlanConfig config, + Processing processing, + HtmlExport htmlExport, + UUID networkUUID + ) { + this.config = config; + this.processing = processing; + this.networkUUID = networkUUID; + this.htmlExport = htmlExport; } - public CacheAnalysisPageRequest(UUID serverUUID, String html) { + CacheAnalysisPageRequest( + UUID serverUUID, String html, + PlanConfig config, + Processing processing, + HtmlExport htmlExport, + UUID networkUUID + ) { + this.config = config; + this.processing = processing; + this.networkUUID = networkUUID; + this.htmlExport = htmlExport; + Verify.nullCheck(serverUUID, html); this.serverUUID = serverUUID; variables.put("html", Base64Util.encode(html)); this.html = html; } - public static CacheAnalysisPageRequest createHandler() { - return new CacheAnalysisPageRequest(); - } - @Override public Response handleRequest(Map variables) throws WebException { // Available variables: sender, html (Base64) @@ -55,20 +76,23 @@ public class CacheAnalysisPageRequest extends InfoRequestWithVariables implement String sentHtml = variables.get("html"); Verify.nullCheck(sentHtml, () -> new BadRequestException("HTML 'html' variable not supplied in the request")); - boolean export = Settings.ANALYSIS_EXPORT.isTrue(); - cache(export, sender, Base64Util.decode(sentHtml)); + cache(sender, Base64Util.decode(sentHtml)); return DefaultResponses.SUCCESS.get(); } - private void cache(boolean export, UUID serverUUID, String html) { + private void cache(UUID serverUUID, String html) { ResponseCache.cacheResponse(PageId.SERVER.of(serverUUID), () -> new AnalysisPageResponse(html)); - if (export) { - Processing.submitNonCritical(() -> HtmlExport.exportServer(serverUUID)); + if (!networkUUID.equals(serverUUID)) { + ResponseCache.clearResponse(PageId.SERVER.of(networkUUID)); + } + + if (config.isTrue(Settings.ANALYSIS_EXPORT)) { + processing.submitNonCritical(() -> htmlExport.exportServer(serverUUID)); } } @Override public void runLocally() { - cache(Settings.ANALYSIS_EXPORT.isTrue(), serverUUID, html); + cache(serverUUID, html); } } diff --git a/Plan/src/main/java/com/djrapitops/plan/system/info/request/CacheInspectPageRequest.java b/Plan/src/main/java/com/djrapitops/plan/system/info/request/CacheInspectPageRequest.java index 00c8c0a44..a07cb311a 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/info/request/CacheInspectPageRequest.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/info/request/CacheInspectPageRequest.java @@ -9,6 +9,7 @@ import com.djrapitops.plan.api.exceptions.connection.WebException; import com.djrapitops.plan.system.info.server.ServerInfo; import com.djrapitops.plan.system.processing.Processing; import com.djrapitops.plan.system.settings.Settings; +import com.djrapitops.plan.system.settings.config.PlanConfig; import com.djrapitops.plan.system.webserver.cache.PageId; import com.djrapitops.plan.system.webserver.cache.ResponseCache; import com.djrapitops.plan.system.webserver.response.DefaultResponses; @@ -30,15 +31,38 @@ import java.util.UUID; */ public class CacheInspectPageRequest extends InfoRequestWithVariables implements CacheRequest { - private final UUID player; - private final String html; + private final PlanConfig config; + private final Processing processing; + private final ServerInfo serverInfo; + private final HtmlExport htmlExport; - private CacheInspectPageRequest() { - player = null; - html = null; + private UUID player; + private String html; + + CacheInspectPageRequest( + PlanConfig config, + Processing processing, + ServerInfo serverInfo, + HtmlExport htmlExport + ) { + this.config = config; + this.processing = processing; + this.serverInfo = serverInfo; + this.htmlExport = htmlExport; } - public CacheInspectPageRequest(UUID player, String html) { + CacheInspectPageRequest( + UUID player, String html, + PlanConfig config, + Processing processing, + ServerInfo serverInfo, + HtmlExport htmlExport + ) { + this.config = config; + this.processing = processing; + this.serverInfo = serverInfo; + this.htmlExport = htmlExport; + Verify.nullCheck(player, html); variables.put("player", player.toString()); variables.put("html", Base64Util.encode(html)); @@ -46,10 +70,6 @@ public class CacheInspectPageRequest extends InfoRequestWithVariables implements this.html = html; } - public static CacheInspectPageRequest createHandler() { - return new CacheInspectPageRequest(); - } - @Override public Response handleRequest(Map variables) throws WebException { // Available variables: sender, player, html (Base64) @@ -61,22 +81,21 @@ public class CacheInspectPageRequest extends InfoRequestWithVariables implements String html = variables.get("html"); Verify.nullCheck(html, () -> new BadRequestException("HTML 'html' variable not supplied in the request")); - Map replace = Collections.singletonMap("networkName", ServerInfo.getServerName()); - boolean export = Settings.ANALYSIS_EXPORT.isTrue(); - cache(export, uuid, StringSubstitutor.replace(Base64Util.decode(html), replace)); + Map replace = Collections.singletonMap("networkName", serverInfo.getServer().getName()); + cache(uuid, StringSubstitutor.replace(Base64Util.decode(html), replace)); return DefaultResponses.SUCCESS.get(); } - private void cache(boolean export, UUID uuid, String html) { + private void cache(UUID uuid, String html) { ResponseCache.cacheResponse(PageId.PLAYER.of(uuid), () -> new InspectPageResponse(uuid, html)); - if (export) { - Processing.submitNonCritical(() -> HtmlExport.exportPlayer(uuid)); + if (config.isTrue(Settings.ANALYSIS_EXPORT)) { + processing.submitNonCritical(() -> htmlExport.exportPlayer(uuid)); } } @Override public void runLocally() { - cache(Settings.ANALYSIS_EXPORT.isTrue(), player, html); + cache(player, html); } } diff --git a/Plan/src/main/java/com/djrapitops/plan/system/info/request/CacheInspectPluginsTabRequest.java b/Plan/src/main/java/com/djrapitops/plan/system/info/request/CacheInspectPluginsTabRequest.java index 6a8a6b340..150b2ea65 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/info/request/CacheInspectPluginsTabRequest.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/info/request/CacheInspectPluginsTabRequest.java @@ -25,15 +25,18 @@ import java.util.UUID; */ public class CacheInspectPluginsTabRequest extends InfoRequestWithVariables implements CacheRequest { - private final UUID player; - private final String html; + private final ServerInfo serverInfo; - private CacheInspectPluginsTabRequest() { - player = null; - html = null; + private UUID player; + private String html; + + CacheInspectPluginsTabRequest(ServerInfo serverInfo) { + this.serverInfo = serverInfo; } - public CacheInspectPluginsTabRequest(UUID player, String nav, String html) { + CacheInspectPluginsTabRequest(UUID player, String nav, String html, ServerInfo serverInfo) { + this.serverInfo = serverInfo; + Verify.nullCheck(player, nav); variables.put("player", player.toString()); variables.put("nav", nav); @@ -42,10 +45,6 @@ public class CacheInspectPluginsTabRequest extends InfoRequestWithVariables impl this.html = html; } - public static CacheInspectPluginsTabRequest createHandler() { - return new CacheInspectPluginsTabRequest(); - } - @Override public Response handleRequest(Map variables) throws WebException { // Available variables: sender, player, nav, html @@ -72,6 +71,6 @@ public class CacheInspectPluginsTabRequest extends InfoRequestWithVariables impl @Override public void runLocally() { - getPluginsTab(player).addTab(ServerInfo.getServerUUID(), variables.get("nav"), html); + getPluginsTab(player).addTab(serverInfo.getServerUUID(), variables.get("nav"), html); } } diff --git a/Plan/src/main/java/com/djrapitops/plan/system/info/request/CacheNetworkPageContentRequest.java b/Plan/src/main/java/com/djrapitops/plan/system/info/request/CacheNetworkPageContentRequest.java index 7363c5710..728fec071 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/info/request/CacheNetworkPageContentRequest.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/info/request/CacheNetworkPageContentRequest.java @@ -27,18 +27,24 @@ import java.util.UUID; */ public class CacheNetworkPageContentRequest extends InfoRequestWithVariables implements CacheRequest { - private final String html; + private final ServerInfo serverInfo; + + private String html; + + CacheNetworkPageContentRequest(ServerInfo serverInfo) { + this.serverInfo = serverInfo; + } + + CacheNetworkPageContentRequest(UUID serverUUID, String html, ServerInfo serverInfo) { + this.serverInfo = serverInfo; - public CacheNetworkPageContentRequest(UUID serverUUID, String html) { Verify.nullCheck(serverUUID, html); - variables.put("serverName", ServerInfo.getServerName()); + variables.put("serverName", serverInfo.getServer().getName()); variables.put("html", Base64Util.encode(html)); this.html = html; } - private CacheNetworkPageContentRequest() { - html = null; - } + @Override public Response handleRequest(Map variables) throws WebException { @@ -52,7 +58,7 @@ public class CacheNetworkPageContentRequest extends InfoRequestWithVariables imp NetworkPageContent serversTab = getNetworkPageContent(); serversTab.addElement(serverName, Base64Util.decode(html)); - ResponseCache.clearResponse(PageId.SERVER.of(ServerInfo.getServerUUID())); + ResponseCache.clearResponse(PageId.SERVER.of(serverInfo.getServerUUID())); return DefaultResponses.SUCCESS.get(); } @@ -63,10 +69,7 @@ public class CacheNetworkPageContentRequest extends InfoRequestWithVariables imp @Override public void runLocally() { - getNetworkPageContent().addElement(ServerInfo.getServerName(), html); + getNetworkPageContent().addElement(serverInfo.getServer().getName(), html); } - public static CacheNetworkPageContentRequest createHandler() { - return new CacheNetworkPageContentRequest(); - } } diff --git a/Plan/src/main/java/com/djrapitops/plan/system/info/request/CheckConnectionRequest.java b/Plan/src/main/java/com/djrapitops/plan/system/info/request/CheckConnectionRequest.java index d71bc7f78..1efdc63a7 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/info/request/CheckConnectionRequest.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/info/request/CheckConnectionRequest.java @@ -8,7 +8,7 @@ import com.djrapitops.plan.api.exceptions.connection.BadRequestException; import com.djrapitops.plan.api.exceptions.connection.ConnectionFailException; import com.djrapitops.plan.api.exceptions.connection.GatewayException; import com.djrapitops.plan.api.exceptions.connection.WebException; -import com.djrapitops.plan.system.info.InfoSystem; +import com.djrapitops.plan.system.info.connection.ConnectionSystem; import com.djrapitops.plan.system.info.server.Server; import com.djrapitops.plan.system.webserver.response.DefaultResponses; import com.djrapitops.plan.system.webserver.response.Response; @@ -25,18 +25,18 @@ import java.util.UUID; */ public class CheckConnectionRequest extends InfoRequestWithVariables { - public CheckConnectionRequest(String webServerAddress) { + private final ConnectionSystem connectionSystem; + + CheckConnectionRequest(String webServerAddress, ConnectionSystem connectionSystem) { + this.connectionSystem = connectionSystem; Verify.nullCheck(webServerAddress, () -> new IllegalArgumentException("webServerAddress can not be null.")); variables.put("address", webServerAddress); variables.put("continue", "yes"); } - public CheckConnectionRequest() { - } - - public static CheckConnectionRequest createHandler() { - return new CheckConnectionRequest(); + CheckConnectionRequest(ConnectionSystem connectionSystem) { + this.connectionSystem = connectionSystem; } @Override @@ -48,7 +48,7 @@ public class CheckConnectionRequest extends InfoRequestWithVariables { public Response handleRequest(Map variables) throws WebException { // Available variables: sender, address - if (Check.isBungeeAvailable()) { + if (Check.isBungeeAvailable() || Check.isVelocityAvailable()) { attemptConnection(variables); } @@ -56,6 +56,7 @@ public class CheckConnectionRequest extends InfoRequestWithVariables { } private void attemptConnection(Map variables) throws WebException { + // Continue variable not present in rebound connection, leading to a single round ping. boolean shouldNotContinue = variables.get("continue") == null; if (shouldNotContinue) { return; @@ -69,7 +70,7 @@ public class CheckConnectionRequest extends InfoRequestWithVariables { Server bukkit = new Server(-1, serverUUID, "", address, -1); try { - InfoSystem.getInstance().getConnectionSystem().sendInfoRequest(new CheckConnectionRequest(), bukkit); + connectionSystem.sendInfoRequest(new CheckConnectionRequest(connectionSystem), bukkit); } catch (ConnectionFailException e) { throw new GatewayException(e.getMessage()); } diff --git a/Plan/src/main/java/com/djrapitops/plan/system/info/request/GenerateAnalysisPageRequest.java b/Plan/src/main/java/com/djrapitops/plan/system/info/request/GenerateAnalysisPageRequest.java index e5e47dae1..01dbf9153 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/info/request/GenerateAnalysisPageRequest.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/info/request/GenerateAnalysisPageRequest.java @@ -7,15 +7,11 @@ package com.djrapitops.plan.system.info.request; import com.djrapitops.plan.api.exceptions.connection.BadRequestException; import com.djrapitops.plan.api.exceptions.connection.InternalErrorException; import com.djrapitops.plan.api.exceptions.connection.WebException; -import com.djrapitops.plan.api.exceptions.database.DBOpException; -import com.djrapitops.plan.data.store.containers.AnalysisContainer; -import com.djrapitops.plan.system.database.databases.Database; import com.djrapitops.plan.system.info.InfoSystem; import com.djrapitops.plan.system.info.server.ServerInfo; import com.djrapitops.plan.system.webserver.response.DefaultResponses; import com.djrapitops.plan.system.webserver.response.Response; -import com.djrapitops.plan.utilities.html.pages.AnalysisPage; -import com.djrapitops.plugin.api.utility.log.Log; +import com.djrapitops.plan.utilities.html.pages.PageFactory; import com.djrapitops.plugin.utilities.Verify; import java.util.Collections; @@ -29,19 +25,43 @@ import java.util.UUID; */ public class GenerateAnalysisPageRequest extends InfoRequestWithVariables implements GenerateRequest { - private boolean runningAnalysis = false; - private final UUID serverUUID; + private final InfoRequestFactory infoRequestFactory; + private final ServerInfo serverInfo; + private final InfoSystem infoSystem; + private final PageFactory pageFactory; + + private boolean runningAnalysis = false; + private UUID serverUUID; + + GenerateAnalysisPageRequest( + InfoRequestFactory infoRequestFactory, + ServerInfo serverInfo, + InfoSystem infoSystem, + PageFactory pageFactory + ) { + this.infoRequestFactory = infoRequestFactory; + this.serverInfo = serverInfo; + this.infoSystem = infoSystem; + this.pageFactory = pageFactory; + } + + GenerateAnalysisPageRequest( + UUID serverUUID, + InfoRequestFactory infoRequestFactory, + ServerInfo serverInfo, + InfoSystem infoSystem, + PageFactory pageFactory + ) { + this.infoRequestFactory = infoRequestFactory; + this.serverInfo = serverInfo; + this.infoSystem = infoSystem; + this.pageFactory = pageFactory; - public GenerateAnalysisPageRequest(UUID serverUUID) { Verify.nullCheck(serverUUID); this.serverUUID = serverUUID; variables.put("server", serverUUID.toString()); } - private GenerateAnalysisPageRequest() { - serverUUID = null; - } - @Override public Response handleRequest(Map variables) throws WebException { // Variables available: sender, server @@ -50,7 +70,7 @@ public class GenerateAnalysisPageRequest extends InfoRequestWithVariables implem Verify.nullCheck(server, () -> new BadRequestException("Server UUID 'server' variable not supplied in the request.")); UUID serverUUID = UUID.fromString(server); - if (!ServerInfo.getServerUUID().equals(serverUUID)) { + if (!serverInfo.getServerUUID().equals(serverUUID)) { throw new BadRequestException("Requested Analysis page from wrong server."); } @@ -62,15 +82,14 @@ public class GenerateAnalysisPageRequest extends InfoRequestWithVariables implem } private void generateAndCache(UUID serverUUID) throws WebException { - InfoSystem infoSystem = InfoSystem.getInstance(); - infoSystem.sendRequest(new CacheAnalysisPageRequest(serverUUID, analyseAndGetHtml())); - infoSystem.updateNetworkPage(); + infoSystem.sendRequest(infoRequestFactory.cacheAnalysisPageRequest(serverUUID, analyseAndGetHtml())); } @Override public void runLocally() throws WebException { // Get the handler from ConnectionSystem and run the request. - InfoSystem.getInstance().getConnectionSystem() + // This is done to keep the concurrent analysis in check with runningAnalysis variable. + infoSystem.getConnectionSystem() .getInfoRequest(this.getClass().getSimpleName()) .handleRequest(Collections.singletonMap("server", serverUUID.toString())); } @@ -78,26 +97,15 @@ public class GenerateAnalysisPageRequest extends InfoRequestWithVariables implem private String analyseAndGetHtml() throws InternalErrorException { try { runningAnalysis = true; - UUID serverUUID = ServerInfo.getServerUUID(); - AnalysisContainer analysisContainer = new AnalysisContainer(Database.getActive().fetch().getServerContainer(serverUUID)); - return new AnalysisPage(analysisContainer).toHtml(); - } catch (DBOpException e) { - if (!e.getCause().getMessage().contains("Connection is closed")) { - Log.toLog(this.getClass(), e); - } - throw new InternalErrorException("Analysis failed due to exception", e); + UUID serverUUID = serverInfo.getServerUUID(); + return pageFactory.analysisPage(serverUUID).toHtml(); } catch (Exception e) { - Log.toLog(this.getClass(), e); throw new InternalErrorException("Analysis failed due to exception", e); } finally { runningAnalysis = false; } } - public static GenerateAnalysisPageRequest createHandler() { - return new GenerateAnalysisPageRequest(); - } - public UUID getServerUUID() { return serverUUID; } diff --git a/Plan/src/main/java/com/djrapitops/plan/system/info/request/GenerateInspectPageRequest.java b/Plan/src/main/java/com/djrapitops/plan/system/info/request/GenerateInspectPageRequest.java index aa5bc2fc7..3bd3f3002 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/info/request/GenerateInspectPageRequest.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/info/request/GenerateInspectPageRequest.java @@ -10,8 +10,8 @@ import com.djrapitops.plan.api.exceptions.database.DBException; import com.djrapitops.plan.system.info.InfoSystem; import com.djrapitops.plan.system.webserver.response.DefaultResponses; import com.djrapitops.plan.system.webserver.response.Response; -import com.djrapitops.plan.system.webserver.response.errors.NotFoundResponse; -import com.djrapitops.plan.utilities.html.pages.InspectPage; +import com.djrapitops.plan.system.webserver.response.ResponseFactory; +import com.djrapitops.plan.utilities.html.pages.PageFactory; import com.djrapitops.plugin.utilities.Verify; import java.util.Map; @@ -24,22 +24,40 @@ import java.util.UUID; */ public class GenerateInspectPageRequest extends InfoRequestWithVariables implements GenerateRequest { - private final UUID playerUUID; + private final InfoRequestFactory infoRequestFactory; + private final ResponseFactory responseFactory; + private final PageFactory pageFactory; + private final InfoSystem infoSystem; - private GenerateInspectPageRequest() { - playerUUID = null; + private UUID playerUUID; + + GenerateInspectPageRequest( + InfoRequestFactory infoRequestFactory, + ResponseFactory responseFactory, PageFactory pageFactory, + InfoSystem infoSystem + ) { + this.infoRequestFactory = infoRequestFactory; + this.responseFactory = responseFactory; + this.pageFactory = pageFactory; + this.infoSystem = infoSystem; } - public GenerateInspectPageRequest(UUID uuid) { + GenerateInspectPageRequest( + UUID uuid, + InfoRequestFactory infoRequestFactory, + ResponseFactory responseFactory, PageFactory pageFactory, + InfoSystem infoSystem + ) { + this.infoRequestFactory = infoRequestFactory; + this.responseFactory = responseFactory; + this.pageFactory = pageFactory; + this.infoSystem = infoSystem; + Verify.nullCheck(uuid); playerUUID = uuid; variables.put("player", uuid.toString()); } - public static GenerateInspectPageRequest createHandler() { - return new GenerateInspectPageRequest(); - } - @Override public Response handleRequest(Map variables) throws WebException { // Available variables: sender, player @@ -58,11 +76,11 @@ public class GenerateInspectPageRequest extends InfoRequestWithVariables impleme String html; try { html = getHtml(uuid); - InfoSystem.getInstance().getConnectionSystem().sendWideInfoRequest(new GenerateInspectPluginsTabRequest(uuid)); + infoSystem.getConnectionSystem().sendWideInfoRequest(infoRequestFactory.generateInspectPluginsTabRequest(uuid)); } catch (NotFoundException e) { - html = new NotFoundResponse(e.getMessage()).getContent(); + html = responseFactory.notFound404(e.getMessage()).getContent(); } - InfoSystem.getInstance().sendRequest(new CacheInspectPageRequest(uuid, html)); + infoSystem.sendRequest(infoRequestFactory.cacheInspectPageRequest(uuid, html)); } @Override @@ -73,7 +91,7 @@ public class GenerateInspectPageRequest extends InfoRequestWithVariables impleme private String getHtml(UUID uuid) throws WebException { try { - return new InspectPage(uuid).toHtml(); + return pageFactory.inspectPage(uuid).toHtml(); } catch (ParseException e) { Throwable cause = e.getCause(); diff --git a/Plan/src/main/java/com/djrapitops/plan/system/info/request/GenerateInspectPluginsTabRequest.java b/Plan/src/main/java/com/djrapitops/plan/system/info/request/GenerateInspectPluginsTabRequest.java index 64c18c834..55401d1a2 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/info/request/GenerateInspectPluginsTabRequest.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/info/request/GenerateInspectPluginsTabRequest.java @@ -9,7 +9,7 @@ import com.djrapitops.plan.api.exceptions.connection.WebException; import com.djrapitops.plan.system.info.InfoSystem; import com.djrapitops.plan.system.webserver.response.DefaultResponses; import com.djrapitops.plan.system.webserver.response.Response; -import com.djrapitops.plan.system.webserver.response.pages.parts.InspectPagePluginsContent; +import com.djrapitops.plan.utilities.html.pages.PageFactory; import com.djrapitops.plugin.utilities.Verify; import java.util.Map; @@ -22,22 +22,34 @@ import java.util.UUID; */ public class GenerateInspectPluginsTabRequest extends InfoRequestWithVariables implements GenerateRequest, WideRequest { - private final UUID playerUUID; + private final InfoSystem infoSystem; + private final InfoRequestFactory infoRequestFactory; + private final PageFactory pageFactory; - private GenerateInspectPluginsTabRequest() { - playerUUID = null; + private UUID playerUUID; + + GenerateInspectPluginsTabRequest( + InfoSystem infoSystem, + InfoRequestFactory infoRequestFactory, + PageFactory pageFactory + ) { + this.infoSystem = infoSystem; + this.infoRequestFactory = infoRequestFactory; + this.pageFactory = pageFactory; } - public GenerateInspectPluginsTabRequest(UUID uuid) { + GenerateInspectPluginsTabRequest( + UUID uuid, + InfoSystem infoSystem, + InfoRequestFactory infoRequestFactory, + PageFactory pageFactory + ) { + this(infoSystem, infoRequestFactory, pageFactory); Verify.nullCheck(uuid); playerUUID = uuid; variables.put("player", uuid.toString()); } - public static GenerateInspectPluginsTabRequest createHandler() { - return new GenerateInspectPluginsTabRequest(); - } - @Override public Response handleRequest(Map variables) throws WebException { // Available variables: sender, player @@ -53,8 +65,8 @@ public class GenerateInspectPluginsTabRequest extends InfoRequestWithVariables i } private void generateAndCache(UUID uuid) throws WebException { - String[] navAndHtml = InspectPagePluginsContent.generateForThisServer(uuid).getContents(); - InfoSystem.getInstance().sendRequest(new CacheInspectPluginsTabRequest(uuid, navAndHtml[0], navAndHtml[1])); + String[] navAndHtml = pageFactory.inspectPagePluginsContent(uuid).getContents(); + infoSystem.sendRequest(infoRequestFactory.cacheInspectPluginsTabRequest(uuid, navAndHtml[0], navAndHtml[1])); } @Override diff --git a/Plan/src/main/java/com/djrapitops/plan/system/info/request/GenerateNetworkPageContentRequest.java b/Plan/src/main/java/com/djrapitops/plan/system/info/request/GenerateNetworkPageContentRequest.java deleted file mode 100644 index 71c0b93b3..000000000 --- a/Plan/src/main/java/com/djrapitops/plan/system/info/request/GenerateNetworkPageContentRequest.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * License is provided in the jar as LICENSE also here: - * https://github.com/Rsl1122/Plan-PlayerAnalytics/blob/master/Plan/src/main/resources/LICENSE - */ -package com.djrapitops.plan.system.info.request; - -import com.djrapitops.plan.api.exceptions.connection.WebException; -import com.djrapitops.plan.system.info.InfoSystem; -import com.djrapitops.plan.system.webserver.response.DefaultResponses; -import com.djrapitops.plan.system.webserver.response.Response; - -import java.util.Map; - -/** - * InfoRequest for generating network page content of a Bukkit server. - * - * @author Rsl1122 - */ -public class GenerateNetworkPageContentRequest implements WideRequest, GenerateRequest { - - public static GenerateNetworkPageContentRequest createHandler() { - return new GenerateNetworkPageContentRequest(); - } - - @Override - public Response handleRequest(Map variables) throws WebException { - InfoSystem.getInstance().updateNetworkPage(); - return DefaultResponses.SUCCESS.get(); - } - - @Override - public void runLocally() throws WebException { - InfoSystem.getInstance().updateNetworkPage(); - } -} diff --git a/Plan/src/main/java/com/djrapitops/plan/system/info/request/InfoRequestFactory.java b/Plan/src/main/java/com/djrapitops/plan/system/info/request/InfoRequestFactory.java new file mode 100644 index 000000000..bbb62d01b --- /dev/null +++ b/Plan/src/main/java/com/djrapitops/plan/system/info/request/InfoRequestFactory.java @@ -0,0 +1,109 @@ +package com.djrapitops.plan.system.info.request; + +import com.djrapitops.plan.PlanPlugin; +import com.djrapitops.plan.system.info.InfoSystem; +import com.djrapitops.plan.system.info.connection.ConnectionSystem; +import com.djrapitops.plan.system.info.server.ServerInfo; +import com.djrapitops.plan.system.processing.Processing; +import com.djrapitops.plan.system.settings.config.PlanConfig; +import com.djrapitops.plan.system.webserver.response.ResponseFactory; +import com.djrapitops.plan.utilities.file.export.HtmlExport; +import com.djrapitops.plan.utilities.html.pages.PageFactory; +import com.djrapitops.plugin.logging.console.PluginLogger; +import com.djrapitops.plugin.task.RunnableFactory; +import dagger.Lazy; + +import javax.inject.Inject; +import javax.inject.Singleton; +import java.util.UUID; + +/** + * Factory for {@link InfoRequest} objects used for server-server communications. + * + * @author Rsl1122 + */ +@Singleton +public class InfoRequestFactory { + + private final Lazy plugin; + private final Lazy config; + private final Lazy processing; + private final Lazy infoSystem; + private final Lazy connectionSystem; + private final Lazy serverInfo; + private final Lazy infoRequestFactory; + private final Lazy responseFactory; + private final Lazy pageFactory; + private final Lazy htmlExport; + private final Lazy logger; + private final Lazy runnableFactory; + + @Inject + public InfoRequestFactory( + Lazy plugin, + Lazy config, + Lazy processing, + Lazy infoSystem, + Lazy connectionSystem, + Lazy serverInfo, + Lazy infoRequestFactory, + Lazy responseFactory, + Lazy pageFactory, + Lazy htmlExport, + Lazy logger, + Lazy runnableFactory + ) { + this.plugin = plugin; + this.config = config; + this.processing = processing; + this.infoSystem = infoSystem; + this.connectionSystem = connectionSystem; + this.serverInfo = serverInfo; + this.infoRequestFactory = infoRequestFactory; + this.responseFactory = responseFactory; + this.pageFactory = pageFactory; + this.htmlExport = htmlExport; + this.logger = logger; + this.runnableFactory = runnableFactory; + } + + public CacheRequest cacheAnalysisPageRequest(UUID serverUUID, String html) { + return new CacheAnalysisPageRequest(serverUUID, html, config.get(), processing.get(), htmlExport.get(), serverInfo.get().getServerUUID()); + } + + public CacheRequest cacheInspectPageRequest(UUID uuid, String html) { + return new CacheInspectPageRequest(uuid, html, config.get(), processing.get(), serverInfo.get(), htmlExport.get()); + } + + public CacheRequest cacheInspectPluginsTabRequest(UUID uuid, String nav, String html) { + return new CacheInspectPluginsTabRequest(uuid, nav, html, serverInfo.get()); + } + + public CacheRequest cacheNetworkPageContentRequest(UUID serverUUID, String html) { + return new CacheNetworkPageContentRequest(serverUUID, html, serverInfo.get()); + } + + public GenerateRequest generateAnalysisPageRequest(UUID serverUUID) { + return new GenerateAnalysisPageRequest(serverUUID, infoRequestFactory.get(), serverInfo.get(), infoSystem.get(), pageFactory.get()); + } + + public GenerateRequest generateInspectPageRequest(UUID uuid) { + return new GenerateInspectPageRequest(uuid, this, responseFactory.get(), pageFactory.get(), infoSystem.get()); + } + + public GenerateInspectPluginsTabRequest generateInspectPluginsTabRequest(UUID uuid) { + return new GenerateInspectPluginsTabRequest(uuid, infoSystem.get(), this, pageFactory.get()); + } + + public SaveDBSettingsRequest saveDBSettingsRequest() { + return new SaveDBSettingsRequest(plugin.get(), config.get(), logger.get(), runnableFactory.get()); + } + + public SetupRequest sendDBSettingsRequest(String addressOfThisServer) { + return new SendDBSettingsRequest(addressOfThisServer, config.get(), this, connectionSystem.get()); + } + + public CheckConnectionRequest checkConnectionRequest(String webAddress) { + return new CheckConnectionRequest(webAddress, connectionSystem.get()); + } +} \ No newline at end of file diff --git a/Plan/src/main/java/com/djrapitops/plan/system/info/request/InfoRequestHandlerFactory.java b/Plan/src/main/java/com/djrapitops/plan/system/info/request/InfoRequestHandlerFactory.java new file mode 100644 index 000000000..19873915a --- /dev/null +++ b/Plan/src/main/java/com/djrapitops/plan/system/info/request/InfoRequestHandlerFactory.java @@ -0,0 +1,108 @@ +package com.djrapitops.plan.system.info.request; + +import com.djrapitops.plan.PlanPlugin; +import com.djrapitops.plan.system.info.InfoSystem; +import com.djrapitops.plan.system.info.connection.ConnectionSystem; +import com.djrapitops.plan.system.info.server.ServerInfo; +import com.djrapitops.plan.system.processing.Processing; +import com.djrapitops.plan.system.settings.config.PlanConfig; +import com.djrapitops.plan.system.webserver.response.ResponseFactory; +import com.djrapitops.plan.utilities.file.export.HtmlExport; +import com.djrapitops.plan.utilities.html.pages.PageFactory; +import com.djrapitops.plugin.logging.console.PluginLogger; +import com.djrapitops.plugin.task.RunnableFactory; +import dagger.Lazy; + +import javax.inject.Inject; +import javax.inject.Singleton; + +/** + * Factory for {@link InfoRequest} objects that are used for handling received requests. + * + * @author Rsl1122 + */ +@Singleton +public class InfoRequestHandlerFactory { + + private final Lazy plugin; + private final Lazy config; + private final Lazy processing; + private final Lazy infoSystem; + private final Lazy connectionSystem; + private final Lazy serverInfo; + private final Lazy infoRequestFactory; + private final Lazy responseFactory; + private final Lazy pageFactory; + private final Lazy htmlExport; + private final Lazy logger; + private final Lazy runnableFactory; + + @Inject + public InfoRequestHandlerFactory( + Lazy plugin, + Lazy config, + Lazy processing, + Lazy infoSystem, + Lazy connectionSystem, + Lazy serverInfo, + Lazy infoRequestFactory, + Lazy responseFactory, + Lazy pageFactory, + Lazy htmlExport, + Lazy logger, + Lazy runnableFactory + ) { + this.plugin = plugin; + this.config = config; + this.processing = processing; + this.infoSystem = infoSystem; + this.connectionSystem = connectionSystem; + this.serverInfo = serverInfo; + this.infoRequestFactory = infoRequestFactory; + this.responseFactory = responseFactory; + this.pageFactory = pageFactory; + this.htmlExport = htmlExport; + this.logger = logger; + this.runnableFactory = runnableFactory; + } + + CacheRequest cacheAnalysisPageRequest() { + return new CacheAnalysisPageRequest(config.get(), processing.get(), htmlExport.get(), serverInfo.get().getServerUUID()); + } + + CacheRequest cacheInspectPageRequest() { + return new CacheInspectPageRequest(config.get(), processing.get(), serverInfo.get(), htmlExport.get()); + } + + CacheRequest cacheInspectPluginsTabRequest() { + return new CacheInspectPluginsTabRequest(serverInfo.get()); + } + + CacheRequest cacheNetworkPageContentRequest() { + return new CacheNetworkPageContentRequest(serverInfo.get()); + } + + CheckConnectionRequest checkConnectionRequest() { + return new CheckConnectionRequest(connectionSystem.get()); + } + + GenerateRequest generateAnalysisPageRequest() { + return new GenerateAnalysisPageRequest(infoRequestFactory.get(), serverInfo.get(), infoSystem.get(), pageFactory.get()); + } + + GenerateRequest generateInspectPageRequest() { + return new GenerateInspectPageRequest(infoRequestFactory.get(), responseFactory.get(), pageFactory.get(), infoSystem.get()); + } + + GenerateRequest generateInspectPluginsTabRequest() { + return new GenerateInspectPluginsTabRequest(infoSystem.get(), infoRequestFactory.get(), pageFactory.get()); + } + + SetupRequest saveDBSettingsRequest() { + return new SaveDBSettingsRequest(plugin.get(), config.get(), logger.get(), runnableFactory.get()); + } + + SetupRequest sendDBSettingsRequest() { + return new SendDBSettingsRequest(config.get(), infoRequestFactory.get(), connectionSystem.get()); + } +} \ No newline at end of file diff --git a/Plan/src/main/java/com/djrapitops/plan/system/info/request/InfoRequests.java b/Plan/src/main/java/com/djrapitops/plan/system/info/request/InfoRequests.java new file mode 100644 index 000000000..4ef8726b1 --- /dev/null +++ b/Plan/src/main/java/com/djrapitops/plan/system/info/request/InfoRequests.java @@ -0,0 +1,42 @@ +package com.djrapitops.plan.system.info.request; + +import javax.inject.Inject; +import javax.inject.Singleton; +import java.util.HashMap; + +/** + * Map object that holds {@link InfoRequest} objects used for handling incoming requests. + *

+ * Convenience class for Dagger injection. + * + * @author Rsl1122 + */ +@Singleton +public class InfoRequests extends HashMap { + + private final InfoRequestHandlerFactory handlers; + + @Inject + public InfoRequests(InfoRequestHandlerFactory handlers) { + this.handlers = handlers; + } + + public void initializeRequests() { + putRequest(handlers.cacheAnalysisPageRequest()); + putRequest(handlers.cacheInspectPageRequest()); + putRequest(handlers.cacheInspectPluginsTabRequest()); + putRequest(handlers.cacheNetworkPageContentRequest()); + + putRequest(handlers.generateAnalysisPageRequest()); + putRequest(handlers.generateInspectPageRequest()); + putRequest(handlers.generateInspectPluginsTabRequest()); + + putRequest(handlers.saveDBSettingsRequest()); + putRequest(handlers.sendDBSettingsRequest()); + putRequest(handlers.checkConnectionRequest()); + } + + private void putRequest(InfoRequest request) { + put(request.getClass().getSimpleName().toLowerCase(), request); + } +} \ No newline at end of file diff --git a/Plan/src/main/java/com/djrapitops/plan/system/info/request/SaveDBSettingsRequest.java b/Plan/src/main/java/com/djrapitops/plan/system/info/request/SaveDBSettingsRequest.java index 1adb2721c..d02b5428c 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/info/request/SaveDBSettingsRequest.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/info/request/SaveDBSettingsRequest.java @@ -6,19 +6,23 @@ package com.djrapitops.plan.system.info.request; import com.djrapitops.plan.PlanPlugin; import com.djrapitops.plan.api.exceptions.connection.BadRequestException; +import com.djrapitops.plan.api.exceptions.connection.InternalErrorException; import com.djrapitops.plan.api.exceptions.connection.WebException; import com.djrapitops.plan.system.settings.Settings; +import com.djrapitops.plan.system.settings.config.PlanConfig; import com.djrapitops.plan.system.webserver.response.DefaultResponses; import com.djrapitops.plan.system.webserver.response.Response; import com.djrapitops.plan.system.webserver.response.errors.BadRequestResponse; import com.djrapitops.plugin.api.Check; import com.djrapitops.plugin.api.TimeAmount; -import com.djrapitops.plugin.api.utility.log.Log; +import com.djrapitops.plugin.logging.console.PluginLogger; import com.djrapitops.plugin.task.AbsRunnable; import com.djrapitops.plugin.task.RunnableFactory; import com.djrapitops.plugin.utilities.Verify; +import java.io.IOException; import java.util.Map; +import java.util.concurrent.TimeUnit; /** * InfoRequest for sending Database config settings to Bukkit servers. @@ -27,23 +31,28 @@ import java.util.Map; */ public class SaveDBSettingsRequest extends InfoRequestWithVariables implements SetupRequest { - public SaveDBSettingsRequest() { + private final PlanPlugin plugin; + private final PlanConfig config; + private final PluginLogger logger; + private final RunnableFactory runnableFactory; + + SaveDBSettingsRequest( + PlanPlugin plugin, + PlanConfig config, + PluginLogger logger, + RunnableFactory runnableFactory + ) { + this.plugin = plugin; + this.config = config; + this.logger = logger; + this.runnableFactory = runnableFactory; + variables.put("DB_TYPE", "mysql"); // Settings.DB_TYPE - variables.put("DB_HOST", Settings.DB_HOST.toString()); - variables.put("DB_USER", Settings.DB_USER.toString()); - variables.put("DB_PASS", Settings.DB_PASS.toString()); - variables.put("DB_DATABASE", Settings.DB_DATABASE.toString()); - variables.put("DB_PORT", Settings.DB_PORT.toString()); - } - - /** - * Private constructor for creating a handler. - */ - private SaveDBSettingsRequest(boolean b) { - } - - public static SaveDBSettingsRequest createHandler() { - return new SaveDBSettingsRequest(true); + variables.put("DB_HOST", config.getString(Settings.DB_HOST)); + variables.put("DB_USER", config.getString(Settings.DB_USER)); + variables.put("DB_PASS", config.getString(Settings.DB_PASS)); + variables.put("DB_DATABASE", config.getString(Settings.DB_DATABASE)); + variables.put("DB_PORT", config.getString(Settings.DB_PORT)); } @Override @@ -56,27 +65,30 @@ public class SaveDBSettingsRequest extends InfoRequestWithVariables implements S if (Check.isBungeeAvailable()) { return new BadRequestResponse("Not supposed to be called on a Bungee server"); } - if (Settings.BUNGEE_COPY_CONFIG.isFalse() || Settings.BUNGEE_OVERRIDE_STANDALONE_MODE.isTrue()) { + if (Check.isVelocityAvailable()) { + return new BadRequestResponse("Not supposed to be called on a Velocity server"); + } + if (config.isFalse(Settings.BUNGEE_COPY_CONFIG) || config.isTrue(Settings.BUNGEE_OVERRIDE_STANDALONE_MODE)) { return new BadRequestResponse("Bungee config settings overridden on this server."); } try { setSettings(variables); - Log.info("----------------------------------"); - Log.info("The Received Bungee Database Settings, restarting Plan.."); - Log.info("----------------------------------"); + logger.info("----------------------------------"); + logger.info("The Received Bungee Database Settings, restarting Plan.."); + logger.info("----------------------------------"); return DefaultResponses.SUCCESS.get(); } finally { - RunnableFactory.createNew("Bungee Setup Restart Task", new AbsRunnable() { + runnableFactory.create("Bungee Setup Restart Task", new AbsRunnable() { @Override public void run() { - PlanPlugin.getInstance().reloadPlugin(true); + plugin.reloadPlugin(true); } - }).runTaskLater(TimeAmount.SECOND.ticks() * 2L); + }).runTaskLater(TimeAmount.toTicks(2L, TimeUnit.SECONDS)); } } - private void setSettings(Map variables) throws BadRequestException { + private void setSettings(Map variables) throws BadRequestException, InternalErrorException { String type = variables.get("DB_TYPE"); String host = variables.get("DB_HOST"); String user = variables.get("DB_USER"); @@ -92,15 +104,19 @@ public class SaveDBSettingsRequest extends InfoRequestWithVariables implements S Verify.nullCheck(portS, () -> new BadRequestException("DB_PORT not specified in the request.")); try { - Settings.DB_PORT.set(Integer.valueOf(portS)); + config.set(Settings.DB_PORT, Integer.valueOf(portS)); } catch (NumberFormatException e) { throw new BadRequestException("DB_PORT was not a number."); } - Settings.DB_TYPE.set(type); - Settings.DB_HOST.set(host); - Settings.DB_USER.set(user); - Settings.DB_PASS.set(pass); - Settings.DB_DATABASE.set(database); - Settings.save(); + config.set(Settings.DB_TYPE, type); + config.set(Settings.DB_HOST, host); + config.set(Settings.DB_USER, user); + config.set(Settings.DB_PASS, pass); + config.set(Settings.DB_DATABASE, database); + try { + config.save(); + } catch (IOException e) { + throw new InternalErrorException("Failed to Save Config", e); + } } } diff --git a/Plan/src/main/java/com/djrapitops/plan/system/info/request/SendDBSettingsRequest.java b/Plan/src/main/java/com/djrapitops/plan/system/info/request/SendDBSettingsRequest.java index fe95062b0..097cc7883 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/info/request/SendDBSettingsRequest.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/info/request/SendDBSettingsRequest.java @@ -4,19 +4,18 @@ */ package com.djrapitops.plan.system.info.request; -import com.djrapitops.plan.api.exceptions.connection.BadRequestException; -import com.djrapitops.plan.api.exceptions.connection.ConnectionFailException; -import com.djrapitops.plan.api.exceptions.connection.GatewayException; -import com.djrapitops.plan.api.exceptions.connection.WebException; -import com.djrapitops.plan.system.info.InfoSystem; +import com.djrapitops.plan.api.exceptions.connection.*; +import com.djrapitops.plan.system.info.connection.ConnectionSystem; import com.djrapitops.plan.system.info.server.Server; import com.djrapitops.plan.system.settings.Settings; +import com.djrapitops.plan.system.settings.config.PlanConfig; import com.djrapitops.plan.system.webserver.response.DefaultResponses; import com.djrapitops.plan.system.webserver.response.Response; import com.djrapitops.plan.system.webserver.response.errors.BadRequestResponse; import com.djrapitops.plugin.api.Check; import com.djrapitops.plugin.utilities.Verify; +import java.io.IOException; import java.net.SocketException; import java.util.HashMap; import java.util.Map; @@ -29,20 +28,33 @@ import java.util.UUID; */ public class SendDBSettingsRequest extends InfoRequestWithVariables implements SetupRequest { - public SendDBSettingsRequest(String webServerAddress) { + private final PlanConfig config; + private final InfoRequestFactory infoRequestFactory; + private final ConnectionSystem connectionSystem; + + SendDBSettingsRequest( + PlanConfig config, + InfoRequestFactory infoRequestFactory, ConnectionSystem connectionSystem + ) { + this.config = config; + this.infoRequestFactory = infoRequestFactory; + this.connectionSystem = connectionSystem; + } + + SendDBSettingsRequest( + String webServerAddress, + PlanConfig config, + InfoRequestFactory infoRequestFactory, ConnectionSystem connectionSystem + ) { + this.config = config; + this.infoRequestFactory = infoRequestFactory; + this.connectionSystem = connectionSystem; + Verify.nullCheck(webServerAddress, () -> new IllegalArgumentException("webServerAddress can not be null.")); - variables.put("address", webServerAddress); - variables.put("WebServerPort", Integer.toString(Settings.WEBSERVER_PORT.getNumber())); - variables.put("ServerName", Settings.SERVER_NAME.toString().replaceAll("[^a-zA-Z0-9_\\s]", "_")); - variables.put("ThemeBase", Settings.THEME_BASE.toString()); - } - - private SendDBSettingsRequest() { - } - - public static SendDBSettingsRequest createHandler() { - return new SendDBSettingsRequest(); + variables.put("WebServerPort", config.getString(Settings.WEBSERVER_PORT)); + variables.put("ServerName", config.getString(Settings.SERVER_NAME).replaceAll("[^a-zA-Z0-9_\\s]", "_")); + variables.put("ThemeBase", config.getString(Settings.THEME_BASE)); } @Override @@ -76,7 +88,7 @@ public class SendDBSettingsRequest extends InfoRequestWithVariables implements S Server bukkit = new Server(-1, serverUUID, serverName, address, -1); try { - InfoSystem.getInstance().getConnectionSystem().sendInfoRequest(new SaveDBSettingsRequest(), bukkit); + connectionSystem.sendInfoRequest(infoRequestFactory.saveDBSettingsRequest(), bukkit); } catch (ConnectionFailException e) { Throwable cause = e.getCause(); if (!(cause instanceof SocketException) || !cause.getMessage().contains("Unexpected end of file from server")) { @@ -87,12 +99,17 @@ public class SendDBSettingsRequest extends InfoRequestWithVariables implements S return DefaultResponses.SUCCESS.get(); } - private void setOriginalSettings(UUID serverUUID, String webServerPortS, String serverName, String themeBase) { + private void setOriginalSettings(UUID serverUUID, String webServerPortS, String serverName, String themeBase) throws InternalErrorException { Map settings = new HashMap<>(); int webServerPort = Integer.parseInt(webServerPortS); settings.put("WebServerPort", webServerPort); settings.put("ServerName", serverName); settings.put("ThemeBase", themeBase); - Settings.serverSpecific().addOriginalBukkitSettings(serverUUID, settings); + + try { + config.getNetworkSettings().getServerSpecificSettings().addOriginalBukkitSettings(serverUUID, settings); + } catch (IOException e) { + throw new InternalErrorException("Failed to add Bukkit settings to config", e); + } } } diff --git a/Plan/src/main/java/com/djrapitops/plan/system/info/request/UpdateCancelRequest.java b/Plan/src/main/java/com/djrapitops/plan/system/info/request/UpdateCancelRequest.java deleted file mode 100644 index 9fdafcd92..000000000 --- a/Plan/src/main/java/com/djrapitops/plan/system/info/request/UpdateCancelRequest.java +++ /dev/null @@ -1,37 +0,0 @@ -/* - * License is provided in the jar as LICENSE also here: - * https://github.com/Rsl1122/Plan-PlayerAnalytics/blob/master/Plan/src/main/resources/LICENSE - */ -package com.djrapitops.plan.system.info.request; - -import com.djrapitops.plan.system.update.ShutdownUpdateHook; -import com.djrapitops.plan.system.webserver.response.DefaultResponses; -import com.djrapitops.plan.system.webserver.response.Response; - -import java.util.Map; - -/** - * InfoRequest used for Updating the plugin on a network. - * - * @author Rsl1122 - */ -public class UpdateCancelRequest implements InfoRequest { - - public UpdateCancelRequest() { - } - - public static UpdateCancelRequest createHandler() { - return new UpdateCancelRequest(); - } - - @Override - public void runLocally() { - ShutdownUpdateHook.deActivate(); - } - - @Override - public Response handleRequest(Map variables) { - ShutdownUpdateHook.deActivate(); - return DefaultResponses.SUCCESS.get(); - } -} diff --git a/Plan/src/main/java/com/djrapitops/plan/system/info/request/UpdateRequest.java b/Plan/src/main/java/com/djrapitops/plan/system/info/request/UpdateRequest.java deleted file mode 100644 index fd20a666b..000000000 --- a/Plan/src/main/java/com/djrapitops/plan/system/info/request/UpdateRequest.java +++ /dev/null @@ -1,43 +0,0 @@ -/* - * License is provided in the jar as LICENSE also here: - * https://github.com/Rsl1122/Plan-PlayerAnalytics/blob/master/Plan/src/main/resources/LICENSE - */ -package com.djrapitops.plan.system.info.request; - -import com.djrapitops.plan.system.settings.Settings; -import com.djrapitops.plan.system.update.ShutdownUpdateHook; -import com.djrapitops.plan.system.webserver.response.DefaultResponses; -import com.djrapitops.plan.system.webserver.response.Response; -import com.djrapitops.plan.system.webserver.response.errors.BadRequestResponse; - -import java.util.Map; - -/** - * InfoRequest used for Updating the plugin on a network. - * - * @author Rsl1122 - */ -public class UpdateRequest implements InfoRequest { - - public UpdateRequest() { - } - - public static UpdateRequest createHandler() { - return new UpdateRequest(); - } - - @Override - public void runLocally() { - new ShutdownUpdateHook().register(); - } - - @Override - public Response handleRequest(Map variables) { - if (Settings.ALLOW_UPDATE.isTrue()) { - new ShutdownUpdateHook().register(); - return DefaultResponses.SUCCESS.get(); - } else { - return new BadRequestResponse("Update not allowed on this server"); - } - } -} diff --git a/Plan/src/main/java/com/djrapitops/plan/system/info/server/BukkitServerInfo.java b/Plan/src/main/java/com/djrapitops/plan/system/info/server/BukkitServerInfo.java index 0984066f9..50e6ddb2a 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/info/server/BukkitServerInfo.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/info/server/BukkitServerInfo.java @@ -4,16 +4,18 @@ */ package com.djrapitops.plan.system.info.server; -import com.djrapitops.plan.Plan; import com.djrapitops.plan.api.exceptions.EnableException; import com.djrapitops.plan.api.exceptions.database.DBOpException; +import com.djrapitops.plan.system.database.DBSystem; import com.djrapitops.plan.system.database.databases.Database; -import com.djrapitops.plan.system.file.FileSystem; -import com.djrapitops.plan.system.info.server.properties.BukkitServerProperties; import com.djrapitops.plan.system.info.server.properties.ServerProperties; import com.djrapitops.plan.system.settings.Settings; -import com.djrapitops.plan.system.webserver.WebServerSystem; +import com.djrapitops.plan.system.settings.config.PlanConfig; +import com.djrapitops.plan.system.webserver.WebServer; +import dagger.Lazy; +import javax.inject.Inject; +import javax.inject.Singleton; import java.io.IOException; import java.util.Optional; import java.util.UUID; @@ -25,25 +27,33 @@ import java.util.UUID; * * @author Rsl1122 */ +@Singleton public class BukkitServerInfo extends ServerInfo { + private final Lazy webServer; + private final PlanConfig config; private ServerInfoFile serverInfoFile; - private Database database; + private DBSystem dbSystem; - public BukkitServerInfo(Plan plugin) { - this(new BukkitServerProperties(plugin.getServer())); - } - - public BukkitServerInfo(ServerProperties serverProperties) { + @Inject + public BukkitServerInfo( + ServerProperties serverProperties, + ServerInfoFile serverInfoFile, + DBSystem dbSystem, + Lazy webServer, + PlanConfig config + ) { super(serverProperties); + this.serverInfoFile = serverInfoFile; + this.dbSystem = dbSystem; + this.webServer = webServer; + this.config = config; } @Override public void enable() throws EnableException { - database = Database.getActive(); - try { - serverInfoFile = new ServerInfoFile(FileSystem.getDataFolder()); + serverInfoFile.prepare(); } catch (IOException e) { throw new EnableException("Failed to read ServerInfoFile.yml", e); } @@ -64,12 +74,13 @@ public class BukkitServerInfo extends ServerInfo { } private Server updateDbInfo(UUID serverUUID) throws IOException { + Database database = dbSystem.getDatabase(); Optional serverID = database.fetch().getServerID(serverUUID); if (!serverID.isPresent()) { return registerServer(serverUUID); } - String name = Settings.SERVER_NAME.toString().replaceAll("[^a-zA-Z0-9_\\s]", "_"); - String webAddress = WebServerSystem.getInstance().getWebServer().getAccessAddress(); + String name = config.getString(Settings.SERVER_NAME).replaceAll("[^a-zA-Z0-9_\\s]", "_"); + String webAddress = webServer.get().getAccessAddress(); if ("plan".equalsIgnoreCase(name)) { name = "Server " + serverID.get(); } @@ -81,31 +92,34 @@ public class BukkitServerInfo extends ServerInfo { } private Server registerServer() throws IOException { - return registerServer(generateNewUUID(serverProperties)); + return registerServer(generateNewUUID()); } private Server registerServer(UUID serverUUID) throws IOException { - String webAddress = WebServerSystem.getInstance().getWebServer().getAccessAddress(); - String name = Settings.SERVER_NAME.toString().replaceAll("[^a-zA-Z0-9_\\s]", "_"); - int maxPlayers = ServerInfo.getServerProperties().getMaxPlayers(); + String webAddress = webServer.get().getAccessAddress(); + String name = config.getString(Settings.SERVER_NAME).replaceAll("[^a-zA-Z0-9_\\s]", "_"); + int maxPlayers = serverProperties.getMaxPlayers(); Server server = new Server(-1, serverUUID, name, webAddress, maxPlayers); + + Database database = dbSystem.getDatabase(); database.save().serverInfoForThisServer(server); Optional serverID = database.fetch().getServerID(serverUUID); - if (!serverID.isPresent()) { - throw new IllegalStateException("Failed to Register Server (ID not found)"); - } - - int id = serverID.get(); + int id = serverID.orElseThrow(() -> new IllegalStateException("Failed to Register Server (ID not found)")); server.setId(id); serverInfoFile.saveServerUUID(serverUUID); return server; } - private UUID generateNewUUID(ServerProperties serverProperties) { - String seed = serverProperties.getServerId() + serverProperties.getName() + serverProperties.getIp() + serverProperties.getPort() + serverProperties.getVersion() + serverProperties.getImplVersion(); + private UUID generateNewUUID() { + String seed = serverProperties.getServerId() + + serverProperties.getName() + + serverProperties.getIp() + + serverProperties.getPort() + + serverProperties.getVersion() + + serverProperties.getImplVersion(); return UUID.nameUUIDFromBytes(seed.getBytes()); } } \ No newline at end of file diff --git a/Plan/src/main/java/com/djrapitops/plan/system/info/server/BungeeServerInfo.java b/Plan/src/main/java/com/djrapitops/plan/system/info/server/BungeeServerInfo.java index c0658b8fa..7e21a8787 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/info/server/BungeeServerInfo.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/info/server/BungeeServerInfo.java @@ -4,15 +4,17 @@ */ package com.djrapitops.plan.system.info.server; -import com.djrapitops.plan.PlanBungee; import com.djrapitops.plan.api.exceptions.EnableException; import com.djrapitops.plan.api.exceptions.database.DBOpException; +import com.djrapitops.plan.system.database.DBSystem; import com.djrapitops.plan.system.database.databases.Database; -import com.djrapitops.plan.system.info.server.properties.BungeeServerProperties; import com.djrapitops.plan.system.info.server.properties.ServerProperties; -import com.djrapitops.plan.system.webserver.WebServerSystem; -import com.djrapitops.plugin.api.utility.log.Log; +import com.djrapitops.plan.system.webserver.WebServer; +import com.djrapitops.plugin.logging.console.PluginLogger; +import dagger.Lazy; +import javax.inject.Inject; +import javax.inject.Singleton; import java.util.Optional; import java.util.UUID; @@ -21,10 +23,24 @@ import java.util.UUID; * * @author Rsl1122 */ +@Singleton public class BungeeServerInfo extends ServerInfo { - public BungeeServerInfo(PlanBungee plugin) { - super(new BungeeServerProperties(plugin.getProxy())); + private final DBSystem dbSystem; + private final Lazy webServer; + private final PluginLogger logger; + + @Inject + public BungeeServerInfo( + ServerProperties serverProperties, + DBSystem dbSystem, + Lazy webServer, + PluginLogger logger + ) { + super(serverProperties); + this.dbSystem = dbSystem; + this.webServer = webServer; + this.logger = logger; } @Override @@ -32,13 +48,13 @@ public class BungeeServerInfo extends ServerInfo { checkIfDefaultIP(); try { - Database db = Database.getActive(); - Optional bungeeInfo = db.fetch().getBungeeInformation(); + Database database = dbSystem.getDatabase(); + Optional bungeeInfo = database.fetch().getBungeeInformation(); if (bungeeInfo.isPresent()) { server = bungeeInfo.get(); - updateServerInfo(db); + updateServerInfo(database); } else { - server = registerBungeeInfo(db); + server = registerBungeeInfo(database); } } catch (DBOpException e) { throw new EnableException("Failed to read Server information from Database."); @@ -47,7 +63,7 @@ public class BungeeServerInfo extends ServerInfo { } private void updateServerInfo(Database db) { - String accessAddress = WebServerSystem.getInstance().getWebServer().getAccessAddress(); + String accessAddress = webServer.get().getAccessAddress(); if (!accessAddress.equals(server.getWebAddress())) { server.setWebAddress(accessAddress); db.save().serverInfoForThisServer(server); @@ -55,20 +71,19 @@ public class BungeeServerInfo extends ServerInfo { } private void checkIfDefaultIP() throws EnableException { - String ip = ServerInfo.getServerProperties().getIp(); + String ip = serverProperties.getIp(); if ("0.0.0.0".equals(ip)) { - Log.error("IP setting still 0.0.0.0 - Configure AlternativeIP/IP that connects to the Proxy server."); - Log.info("Player Analytics partially enabled (Use /planbungee to reload config)"); + logger.error("IP setting still 0.0.0.0 - Configure AlternativeIP/IP that connects to the Proxy server."); + logger.info("Player Analytics partially enabled (Use /planbungee to reload config)"); throw new EnableException("IP setting still 0.0.0.0 - Configure AlternativeIP/IP that connects to the Proxy server."); } } private Server registerBungeeInfo(Database db) throws EnableException { - ServerProperties properties = ServerInfo.getServerProperties(); - UUID serverUUID = generateNewUUID(properties); - String accessAddress = WebServerSystem.getInstance().getWebServer().getAccessAddress(); + UUID serverUUID = generateNewUUID(); + String accessAddress = webServer.get().getAccessAddress(); - Server bungeeCord = new Server(-1, serverUUID, "BungeeCord", accessAddress, properties.getMaxPlayers()); + Server bungeeCord = new Server(-1, serverUUID, "BungeeCord", accessAddress, serverProperties.getMaxPlayers()); db.save().serverInfoForThisServer(bungeeCord); Optional bungeeInfo = db.fetch().getBungeeInformation(); @@ -78,8 +93,12 @@ public class BungeeServerInfo extends ServerInfo { throw new EnableException("BungeeCord registration failed (DB)"); } - private UUID generateNewUUID(ServerProperties properties) { - String seed = properties.getName() + properties.getIp() + properties.getPort() + properties.getVersion() + properties.getImplVersion(); + private UUID generateNewUUID() { + String seed = serverProperties.getName() + + serverProperties.getIp() + + serverProperties.getPort() + + serverProperties.getVersion() + + serverProperties.getImplVersion(); return UUID.nameUUIDFromBytes(seed.getBytes()); } } diff --git a/Plan/src/main/java/com/djrapitops/plan/system/info/server/ServerInfo.java b/Plan/src/main/java/com/djrapitops/plan/system/info/server/ServerInfo.java index 9ba36b991..aaa6a9586 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/info/server/ServerInfo.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/info/server/ServerInfo.java @@ -5,7 +5,6 @@ package com.djrapitops.plan.system.info.server; import com.djrapitops.plan.api.exceptions.EnableException; -import com.djrapitops.plan.system.PlanSystem; import com.djrapitops.plan.system.SubSystem; import com.djrapitops.plan.system.info.server.properties.ServerProperties; import com.djrapitops.plugin.utilities.Verify; @@ -28,38 +27,22 @@ public abstract class ServerInfo implements SubSystem { this.serverProperties = serverProperties; } - public static ServerInfo getInstance() { - ServerInfo serverInfo = PlanSystem.getInstance().getServerInfo(); - Verify.nullCheck(serverInfo, () -> new IllegalStateException("ServerInfo was not initialized.")); - return serverInfo; + public Server getServer() { + return server; } - public static Server getServer() { - return getInstance().server; - } - - public static ServerProperties getServerProperties() { - return getInstance().serverProperties; - } - - public static UUID getServerUUID() { + public UUID getServerUUID() { return getServer().getUuid(); } - public static String getServerName() { - return getServer().getName(); - } - - public static int getServerID() { - return getServer().getId(); + public ServerProperties getServerProperties() { + return serverProperties; } @Override public void enable() throws EnableException { - // ServerProperties are required when creating Server - Verify.nullCheck(serverProperties, () -> new IllegalStateException("Server Properties did not load!")); server = loadServerInfo(); - Verify.nullCheck(server, () -> new IllegalStateException("Server information did not load!")); + Verify.nullCheck(server, () -> new EnableException("Server information did not load!")); } protected abstract Server loadServerInfo() throws EnableException; diff --git a/Plan/src/main/java/com/djrapitops/plan/system/info/server/ServerInfoFile.java b/Plan/src/main/java/com/djrapitops/plan/system/info/server/ServerInfoFile.java index 69aac5a0b..025f61b96 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/info/server/ServerInfoFile.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/info/server/ServerInfoFile.java @@ -4,11 +4,11 @@ */ package com.djrapitops.plan.system.info.server; -import com.djrapitops.plan.system.file.FileSystem; -import com.djrapitops.plugin.api.config.Config; +import com.djrapitops.plan.system.file.PlanFiles; +import com.djrapitops.plugin.config.Config; import com.djrapitops.plugin.utilities.Verify; -import java.io.File; +import javax.inject.Inject; import java.io.IOException; import java.util.Optional; import java.util.UUID; @@ -22,9 +22,17 @@ import java.util.UUID; * @author Rsl1122 */ public class ServerInfoFile extends Config { - public ServerInfoFile(File dataFolder) throws IOException { - super(new File(dataFolder, "ServerInfoFile.yml")); - copyDefaults(FileSystem.readFromResource("DefaultServerInfoFile.yml")); + + private final PlanFiles files; + + @Inject + public ServerInfoFile(PlanFiles files) { + super(files.getFileFromPluginFolder("ServerInfoFile.yml")); + this.files = files; + } + + public void prepare() throws IOException { + copyDefaults(files.readFromResource("DefaultServerInfoFile.yml")); save(); } diff --git a/Plan/src/main/java/com/djrapitops/plan/system/info/server/SpongeServerInfo.java b/Plan/src/main/java/com/djrapitops/plan/system/info/server/SpongeServerInfo.java index b82b09321..8a97a0498 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/info/server/SpongeServerInfo.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/info/server/SpongeServerInfo.java @@ -1,11 +1,23 @@ package com.djrapitops.plan.system.info.server; -import com.djrapitops.plan.system.info.server.properties.SpongeServerProperties; -import org.spongepowered.api.Sponge; +import com.djrapitops.plan.system.database.DBSystem; +import com.djrapitops.plan.system.info.server.properties.ServerProperties; +import com.djrapitops.plan.system.settings.config.PlanConfig; +import com.djrapitops.plan.system.webserver.WebServer; +import dagger.Lazy; + +import javax.inject.Inject; public class SpongeServerInfo extends BukkitServerInfo { - public SpongeServerInfo() { - super(new SpongeServerProperties(Sponge.getGame())); + @Inject + public SpongeServerInfo( + ServerProperties serverProperties, + ServerInfoFile serverInfoFile, + DBSystem dbSystem, + Lazy webServer, + PlanConfig config + ) { + super(serverProperties, serverInfoFile, dbSystem, webServer, config); } } diff --git a/Plan/src/main/java/com/djrapitops/plan/system/info/server/VelocityServerInfo.java b/Plan/src/main/java/com/djrapitops/plan/system/info/server/VelocityServerInfo.java new file mode 100644 index 000000000..e96f6fce8 --- /dev/null +++ b/Plan/src/main/java/com/djrapitops/plan/system/info/server/VelocityServerInfo.java @@ -0,0 +1,105 @@ +/* + * License is provided in the jar as LICENSE also here: + * https://github.com/Rsl1122/Plan-PlayerAnalytics/blob/master/Plan/src/main/resources/LICENSE + */ +package com.djrapitops.plan.system.info.server; + +import com.djrapitops.plan.api.exceptions.EnableException; +import com.djrapitops.plan.api.exceptions.database.DBOpException; +import com.djrapitops.plan.system.database.DBSystem; +import com.djrapitops.plan.system.database.databases.Database; +import com.djrapitops.plan.system.info.server.properties.ServerProperties; +import com.djrapitops.plan.system.webserver.WebServer; +import com.djrapitops.plugin.logging.console.PluginLogger; +import dagger.Lazy; + +import javax.inject.Inject; +import javax.inject.Singleton; +import java.util.Optional; +import java.util.UUID; + +/** + * Manages Server information on the Bungee instance. + * + * @author Rsl1122 + */ +@Singleton +public class VelocityServerInfo extends ServerInfo { + + private final DBSystem dbSystem; + private final Lazy webServer; + private final PluginLogger logger; + + @Inject + public VelocityServerInfo( + ServerProperties serverProperties, + DBSystem dbSystem, + Lazy webServer, + PluginLogger logger + ) { + super(serverProperties); + this.dbSystem = dbSystem; + this.webServer = webServer; + this.logger = logger; + } + + @Override + public Server loadServerInfo() throws EnableException { + checkIfDefaultIP(); + + try { + Database database = dbSystem.getDatabase(); + Optional bungeeInfo = database.fetch().getBungeeInformation(); + if (bungeeInfo.isPresent()) { + server = bungeeInfo.get(); + updateServerInfo(database); + } else { + server = registerVelocityInfo(database); + } + } catch (DBOpException e) { + throw new EnableException("Failed to read Server information from Database."); + } + return server; + } + + private void updateServerInfo(Database db) { + String accessAddress = webServer.get().getAccessAddress(); + if (!accessAddress.equals(server.getWebAddress())) { + server.setWebAddress(accessAddress); + db.save().serverInfoForThisServer(server); + } + } + + private void checkIfDefaultIP() throws EnableException { + String ip = serverProperties.getIp(); + if ("0.0.0.0".equals(ip)) { + logger.error("IP setting still 0.0.0.0 - Configure AlternativeIP/IP that connects to the Proxy server."); + logger.info("Player Analytics partially enabled (Use /planbungee to reload config)"); + throw new EnableException("IP setting still 0.0.0.0 - Configure AlternativeIP/IP that connects to the Proxy server."); + } + } + + private Server registerVelocityInfo(Database db) throws EnableException { + UUID serverUUID = generateNewUUID(); + String accessAddress = webServer.get().getAccessAddress(); + + // TODO Rework to allow Velocity as name. + Server bungeeCord = new Server(-1, serverUUID, "BungeeCord", accessAddress, serverProperties.getMaxPlayers()); + db.save().serverInfoForThisServer(bungeeCord); + + Optional bungeeInfo = db.fetch().getBungeeInformation(); + if (bungeeInfo.isPresent()) { + return bungeeInfo.get(); + } + throw new EnableException("Velocity registration failed (DB)"); + } + + private UUID generateNewUUID() { + String seed = serverProperties.getName() + + serverProperties.getIp() + + serverProperties.getPort() + + serverProperties.getVersion() + + serverProperties.getImplVersion(); + return UUID.nameUUIDFromBytes(seed.getBytes()); + } +} diff --git a/Plan/src/main/java/com/djrapitops/plan/system/info/server/properties/BungeeServerProperties.java b/Plan/src/main/java/com/djrapitops/plan/system/info/server/properties/BungeeServerProperties.java index 4f6c2cc39..05fa1c18b 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/info/server/properties/BungeeServerProperties.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/info/server/properties/BungeeServerProperties.java @@ -1,6 +1,5 @@ package com.djrapitops.plan.system.info.server.properties; -import com.djrapitops.plan.system.settings.Settings; import net.md_5.bungee.api.ProxyServer; /** @@ -12,14 +11,14 @@ import net.md_5.bungee.api.ProxyServer; */ public class BungeeServerProperties extends ServerProperties { - public BungeeServerProperties(ProxyServer server) { + public BungeeServerProperties(ProxyServer server, String ip) { super( server.getServers().toString(), "BungeeCord", -1, server.getVersion(), server.getVersion(), - Settings.BUNGEE_IP::toString, + () -> ip, server.getConfig().getPlayerLimit(), RedisCheck.isClassAvailable() ? new RedisPlayersOnlineSupplier() : server::getOnlineCount ); diff --git a/Plan/src/main/java/com/djrapitops/plan/system/info/server/properties/VelocityServerProperties.java b/Plan/src/main/java/com/djrapitops/plan/system/info/server/properties/VelocityServerProperties.java new file mode 100644 index 000000000..f96441ddf --- /dev/null +++ b/Plan/src/main/java/com/djrapitops/plan/system/info/server/properties/VelocityServerProperties.java @@ -0,0 +1,27 @@ +package com.djrapitops.plan.system.info.server.properties; + +import com.velocitypowered.api.proxy.ProxyServer; + +/** + * ServerProperties for Velocity. + *

+ * Supports RedisBungee for Players online getting. + * + * @author Rsl1122 + */ +public class VelocityServerProperties extends ServerProperties { + + public VelocityServerProperties(ProxyServer server, String serverIP) { + super( + server.getAllServers().toString(), + "Velocity", + server.getBoundAddress().getPort(), + // not sure how to get these + server.getClass().getPackage().getImplementationVersion(), + server.getClass().getPackage().getImplementationVersion(), + () -> serverIP, + -1, // not sure how to get this + RedisCheck.isClassAvailable() ? new RedisPlayersOnlineSupplier() : server::getPlayerCount + ); + } +} \ No newline at end of file diff --git a/Plan/src/main/java/com/djrapitops/plan/system/listeners/BukkitListenerSystem.java b/Plan/src/main/java/com/djrapitops/plan/system/listeners/BukkitListenerSystem.java index 5a569f154..2ef013f5b 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/listeners/BukkitListenerSystem.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/listeners/BukkitListenerSystem.java @@ -4,24 +4,51 @@ import com.djrapitops.plan.Plan; import com.djrapitops.plan.system.listeners.bukkit.*; import org.bukkit.event.HandlerList; +import javax.inject.Inject; + public class BukkitListenerSystem extends ListenerSystem { private final Plan plugin; - public BukkitListenerSystem(Plan plugin) { + private final PlayerOnlineListener playerOnlineListener; + private final ChatListener chatListener; + private final GameModeChangeListener gamemodeChangeListener; + private final WorldChangeListener worldChangeListener; + private final CommandListener commandListener; + private final DeathEventListener deathEventListener; + private final AFKListener afkListener; + + @Inject + public BukkitListenerSystem(Plan plugin, + PlayerOnlineListener playerOnlineListener, + ChatListener chatListener, + GameModeChangeListener gamemodeChangeListener, + WorldChangeListener worldChangeListener, + CommandListener commandListener, + DeathEventListener deathEventListener, + AFKListener afkListener + ) { this.plugin = plugin; + + this.playerOnlineListener = playerOnlineListener; + this.chatListener = chatListener; + this.gamemodeChangeListener = gamemodeChangeListener; + this.worldChangeListener = worldChangeListener; + this.commandListener = commandListener; + this.deathEventListener = deathEventListener; + this.afkListener = afkListener; } @Override protected void registerListeners() { plugin.registerListener( - new PlayerOnlineListener(), - new ChatListener(), - new GamemodeChangeListener(), - new WorldChangeListener(), - new CommandPreprocessListener(plugin), - new DeathEventListener(), - new AFKListener() + playerOnlineListener, + chatListener, + gamemodeChangeListener, + worldChangeListener, + commandListener, + deathEventListener, + afkListener ); PlayerOnlineListener.setCountKicks(true); } diff --git a/Plan/src/main/java/com/djrapitops/plan/system/listeners/BungeeListenerSystem.java b/Plan/src/main/java/com/djrapitops/plan/system/listeners/BungeeListenerSystem.java index 0b48be733..6ca8c300b 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/listeners/BungeeListenerSystem.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/listeners/BungeeListenerSystem.java @@ -3,17 +3,22 @@ package com.djrapitops.plan.system.listeners; import com.djrapitops.plan.PlanBungee; import com.djrapitops.plan.system.listeners.bungee.PlayerOnlineListener; +import javax.inject.Inject; + public class BungeeListenerSystem extends ListenerSystem { private final PlanBungee plugin; + private PlayerOnlineListener playerOnlineListener; - public BungeeListenerSystem(PlanBungee plugin) { + @Inject + public BungeeListenerSystem(PlanBungee plugin, PlayerOnlineListener playerOnlineListener) { this.plugin = plugin; + this.playerOnlineListener = playerOnlineListener; } @Override protected void registerListeners() { - plugin.registerListener(new PlayerOnlineListener()); + plugin.registerListener(playerOnlineListener); } @Override diff --git a/Plan/src/main/java/com/djrapitops/plan/system/listeners/ListenerSystem.java b/Plan/src/main/java/com/djrapitops/plan/system/listeners/ListenerSystem.java index 4b4e717d1..c2225d1f3 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/listeners/ListenerSystem.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/listeners/ListenerSystem.java @@ -1,15 +1,12 @@ package com.djrapitops.plan.system.listeners; import com.djrapitops.plan.system.SubSystem; -import com.djrapitops.plugin.api.Benchmark; public abstract class ListenerSystem implements SubSystem { @Override public void enable() { - Benchmark.start("Register Listeners"); registerListeners(); - Benchmark.stop("Enable", "Register Listeners"); } @Override @@ -21,5 +18,4 @@ public abstract class ListenerSystem implements SubSystem { protected abstract void unregisterListeners(); - } diff --git a/Plan/src/main/java/com/djrapitops/plan/system/listeners/SpongeListenerSystem.java b/Plan/src/main/java/com/djrapitops/plan/system/listeners/SpongeListenerSystem.java index 27ccc1def..73a89e915 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/listeners/SpongeListenerSystem.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/listeners/SpongeListenerSystem.java @@ -4,24 +4,51 @@ import com.djrapitops.plan.PlanSponge; import com.djrapitops.plan.system.listeners.sponge.*; import org.spongepowered.api.Sponge; +import javax.inject.Inject; + public class SpongeListenerSystem extends ListenerSystem { private final PlanSponge plugin; - public SpongeListenerSystem(PlanSponge plugin) { + private final SpongeAFKListener afkListener; + private final SpongeChatListener chatListener; + private final SpongeCommandListener commandListener; + private final SpongeDeathListener deathListener; + private final SpongeGMChangeListener gmChangeListener; + private final SpongePlayerListener playerListener; + private final SpongeWorldChangeListener worldChangeListener; + + @Inject + public SpongeListenerSystem(PlanSponge plugin, + SpongeAFKListener afkListener, + SpongeChatListener chatListener, + SpongeCommandListener commandListener, + SpongeDeathListener deathListener, + SpongeGMChangeListener gmChangeListener, + SpongePlayerListener playerListener, + SpongeWorldChangeListener worldChangeListener + ) { this.plugin = plugin; + + this.afkListener = afkListener; + this.chatListener = chatListener; + this.commandListener = commandListener; + this.deathListener = deathListener; + this.gmChangeListener = gmChangeListener; + this.playerListener = playerListener; + this.worldChangeListener = worldChangeListener; } @Override protected void registerListeners() { plugin.registerListener( - new SpongeAFKListener(), - new SpongeChatListener(), - new SpongeCommandListener(), - new SpongeDeathListener(), - new SpongeGMChangeListener(), - new SpongePlayerListener(), - new SpongeWorldChangeListener() + afkListener, + chatListener, + commandListener, + deathListener, + playerListener, + gmChangeListener, + worldChangeListener ); } diff --git a/Plan/src/main/java/com/djrapitops/plan/system/listeners/VelocityListenerSystem.java b/Plan/src/main/java/com/djrapitops/plan/system/listeners/VelocityListenerSystem.java new file mode 100644 index 000000000..4aa8da7fc --- /dev/null +++ b/Plan/src/main/java/com/djrapitops/plan/system/listeners/VelocityListenerSystem.java @@ -0,0 +1,34 @@ +package com.djrapitops.plan.system.listeners; + +import com.djrapitops.plan.PlanVelocity; +import com.djrapitops.plan.system.listeners.velocity.PlayerOnlineListener; + +import javax.inject.Inject; +import javax.inject.Singleton; + +@Singleton +public class VelocityListenerSystem extends ListenerSystem { + + private final PlanVelocity plugin; + + private final PlayerOnlineListener playerOnlineListener; + + @Inject + public VelocityListenerSystem( + PlanVelocity plugin, + PlayerOnlineListener playerOnlineListener + ) { + this.plugin = plugin; + this.playerOnlineListener = playerOnlineListener; + } + + @Override + protected void registerListeners() { + plugin.registerListener(playerOnlineListener); + } + + @Override + protected void unregisterListeners() { + plugin.getProxy().getEventManager().unregisterListeners(plugin); + } +} diff --git a/Plan/src/main/java/com/djrapitops/plan/system/listeners/bukkit/AFKListener.java b/Plan/src/main/java/com/djrapitops/plan/system/listeners/bukkit/AFKListener.java index ac7d9ec0d..dd8989307 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/listeners/bukkit/AFKListener.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/listeners/bukkit/AFKListener.java @@ -2,7 +2,9 @@ package com.djrapitops.plan.system.listeners.bukkit; import com.djrapitops.plan.system.afk.AFKTracker; import com.djrapitops.plan.system.settings.Permissions; -import com.djrapitops.plugin.api.utility.log.Log; +import com.djrapitops.plan.system.settings.config.PlanConfig; +import com.djrapitops.plugin.logging.L; +import com.djrapitops.plugin.logging.error.ErrorHandler; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; @@ -12,6 +14,7 @@ import org.bukkit.event.player.PlayerCommandPreprocessEvent; import org.bukkit.event.player.PlayerEvent; import org.bukkit.event.player.PlayerMoveEvent; +import javax.inject.Inject; import java.util.HashMap; import java.util.Map; import java.util.UUID; @@ -27,12 +30,23 @@ import java.util.UUID; public class AFKListener implements Listener { // Static so that /reload does not cause afk tracking to fail. - public static final AFKTracker AFK_TRACKER = new AFKTracker(); + static AFKTracker AFK_TRACKER; private final Map ignorePermissionInfo; + private final ErrorHandler errorHandler; - public AFKListener() { - ignorePermissionInfo = new HashMap<>(); + @Inject + public AFKListener(PlanConfig config, ErrorHandler errorHandler) { + this.errorHandler = errorHandler; + this.ignorePermissionInfo = new HashMap<>(); + + AFKListener.assignAFKTracker(config); + } + + private static void assignAFKTracker(PlanConfig config) { + if (AFK_TRACKER == null) { + AFK_TRACKER = new AFKTracker(config); + } } private void event(PlayerEvent event) { @@ -54,7 +68,7 @@ public class AFKListener implements Listener { AFK_TRACKER.performedAction(uuid, time); } catch (Exception e) { - Log.toLog(this.getClass(), e); + errorHandler.log(L.ERROR, this.getClass(), e); } } diff --git a/Plan/src/main/java/com/djrapitops/plan/system/listeners/bukkit/ChatListener.java b/Plan/src/main/java/com/djrapitops/plan/system/listeners/bukkit/ChatListener.java index e98b53f5a..cd2868417 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/listeners/bukkit/ChatListener.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/listeners/bukkit/ChatListener.java @@ -1,14 +1,16 @@ package com.djrapitops.plan.system.listeners.bukkit; import com.djrapitops.plan.system.processing.Processing; -import com.djrapitops.plan.system.processing.processors.player.NameProcessor; -import com.djrapitops.plugin.api.utility.log.Log; +import com.djrapitops.plan.system.processing.processors.player.PlayerProcessors; +import com.djrapitops.plugin.logging.L; +import com.djrapitops.plugin.logging.error.ErrorHandler; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; import org.bukkit.event.Listener; import org.bukkit.event.player.AsyncPlayerChatEvent; +import javax.inject.Inject; import java.util.UUID; /** @@ -18,11 +20,21 @@ import java.util.UUID; */ public class ChatListener implements Listener { - /** - * ChatEvent listener. - * - * @param event Fired Event - */ + private final PlayerProcessors processorFactory; + private final Processing processing; + private final ErrorHandler errorHandler; + + @Inject + public ChatListener( + PlayerProcessors processorFactory, + Processing processing, + ErrorHandler errorHandler + ) { + this.processorFactory = processorFactory; + this.processing = processing; + this.errorHandler = errorHandler; + } + @EventHandler(priority = EventPriority.MONITOR) public void onChat(AsyncPlayerChatEvent event) { if (event.isCancelled()) { @@ -32,7 +44,7 @@ public class ChatListener implements Listener { try { actOnChatEvent(event); } catch (Exception e) { - Log.toLog(this.getClass(), e); + errorHandler.log(L.ERROR, this.getClass(), e); } } @@ -41,6 +53,6 @@ public class ChatListener implements Listener { UUID uuid = p.getUniqueId(); String name = p.getName(); String displayName = p.getDisplayName(); - Processing.submit(new NameProcessor(uuid, name, displayName)); + processing.submit(processorFactory.nameProcessor(uuid, name, displayName)); } } diff --git a/Plan/src/main/java/com/djrapitops/plan/system/listeners/bukkit/CommandPreprocessListener.java b/Plan/src/main/java/com/djrapitops/plan/system/listeners/bukkit/CommandListener.java similarity index 64% rename from Plan/src/main/java/com/djrapitops/plan/system/listeners/bukkit/CommandPreprocessListener.java rename to Plan/src/main/java/com/djrapitops/plan/system/listeners/bukkit/CommandListener.java index 2757a017c..49855632b 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/listeners/bukkit/CommandPreprocessListener.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/listeners/bukkit/CommandListener.java @@ -2,39 +2,48 @@ package com.djrapitops.plan.system.listeners.bukkit; import com.djrapitops.plan.Plan; import com.djrapitops.plan.system.processing.Processing; -import com.djrapitops.plan.system.processing.processors.CommandProcessor; +import com.djrapitops.plan.system.processing.processors.Processors; import com.djrapitops.plan.system.settings.Permissions; import com.djrapitops.plan.system.settings.Settings; -import com.djrapitops.plugin.api.utility.log.Log; +import com.djrapitops.plan.system.settings.config.PlanConfig; +import com.djrapitops.plugin.logging.L; +import com.djrapitops.plugin.logging.error.ErrorHandler; import org.bukkit.command.Command; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; import org.bukkit.event.Listener; import org.bukkit.event.player.PlayerCommandPreprocessEvent; +import javax.inject.Inject; + /** * Event Listener for PlayerCommandPreprocessEvents. * * @author Rsl1122 */ -public class CommandPreprocessListener implements Listener { +public class CommandListener implements Listener { private final Plan plugin; + private final PlanConfig config; + private final Processors processors; + private final Processing processing; + private final ErrorHandler errorHandler; - /** - * Class Constructor. - * - * @param plugin Current instance of Plan - */ - public CommandPreprocessListener(Plan plugin) { + @Inject + public CommandListener( + Plan plugin, + PlanConfig config, + Processors processors, + Processing processing, + ErrorHandler errorHandler + ) { this.plugin = plugin; + this.config = config; + this.processors = processors; + this.processing = processing; + this.errorHandler = errorHandler; } - /** - * Command use listener. - * - * @param event Fired event. - */ @EventHandler(priority = EventPriority.MONITOR) public void onPlayerCommand(PlayerCommandPreprocessEvent event) { boolean hasIgnorePermission = event.getPlayer().hasPermission(Permissions.IGNORE_COMMAND_USE.getPermission()); @@ -45,15 +54,15 @@ public class CommandPreprocessListener implements Listener { try { actOnCommandEvent(event); } catch (Exception e) { - Log.toLog(this.getClass(), e); + errorHandler.log(L.ERROR, this.getClass(), e); } } private void actOnCommandEvent(PlayerCommandPreprocessEvent event) { String commandName = event.getMessage().substring(1).split(" ")[0].toLowerCase(); - boolean logUnknownCommands = Settings.LOG_UNKNOWN_COMMANDS.isTrue(); - boolean combineCommandAliases = Settings.COMBINE_COMMAND_ALIASES.isTrue(); + boolean logUnknownCommands = config.isTrue(Settings.LOG_UNKNOWN_COMMANDS); + boolean combineCommandAliases = config.isTrue(Settings.COMBINE_COMMAND_ALIASES); if (!logUnknownCommands || combineCommandAliases) { Command command = getBukkitCommand(commandName); @@ -65,7 +74,7 @@ public class CommandPreprocessListener implements Listener { commandName = command.getName(); } } - Processing.submit(new CommandProcessor(commandName)); + processing.submit(processors.commandProcessor(commandName)); } private Command getBukkitCommand(String commandName) { diff --git a/Plan/src/main/java/com/djrapitops/plan/system/listeners/bukkit/DeathEventListener.java b/Plan/src/main/java/com/djrapitops/plan/system/listeners/bukkit/DeathEventListener.java index 2c9f22743..e3b782261 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/listeners/bukkit/DeathEventListener.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/listeners/bukkit/DeathEventListener.java @@ -1,12 +1,14 @@ package com.djrapitops.plan.system.listeners.bukkit; import com.djrapitops.plan.data.container.Session; -import com.djrapitops.plan.data.store.mutators.formatting.Formatters; import com.djrapitops.plan.system.cache.SessionCache; import com.djrapitops.plan.system.processing.Processing; -import com.djrapitops.plan.system.processing.processors.player.KillProcessor; -import com.djrapitops.plugin.api.utility.log.Log; -import com.djrapitops.plugin.utilities.Format; +import com.djrapitops.plan.system.processing.processors.player.MobKillProcessor; +import com.djrapitops.plan.system.processing.processors.player.PlayerKillProcessor; +import com.djrapitops.plan.utilities.formatting.EntityNameFormatter; +import com.djrapitops.plan.utilities.formatting.ItemNameFormatter; +import com.djrapitops.plugin.logging.L; +import com.djrapitops.plugin.logging.error.ErrorHandler; import org.bukkit.Material; import org.bukkit.entity.*; import org.bukkit.event.EventHandler; @@ -17,6 +19,9 @@ import org.bukkit.event.entity.EntityDamageEvent; import org.bukkit.event.entity.EntityDeathEvent; import org.bukkit.projectiles.ProjectileSource; +import javax.inject.Inject; +import java.util.UUID; + /** * Event Listener for EntityDeathEvents. * @@ -24,11 +29,18 @@ import org.bukkit.projectiles.ProjectileSource; */ public class DeathEventListener implements Listener { - /** - * Command use listener. - * - * @param event Fired event. - */ + private final Processing processing; + private final ErrorHandler errorHandler; + + @Inject + public DeathEventListener( + Processing processing, + ErrorHandler errorHandler + ) { + this.processing = processing; + this.errorHandler = errorHandler; + } + @SuppressWarnings("deprecation") @EventHandler(priority = EventPriority.MONITOR) public void onDeath(EntityDeathEvent event) { @@ -37,7 +49,7 @@ public class DeathEventListener implements Listener { if (dead instanceof Player) { // Process Death - Processing.submitCritical(() -> SessionCache.getCachedSession(dead.getUniqueId()).ifPresent(Session::died)); + SessionCache.getCachedSession(dead.getUniqueId()).ifPresent(Session::died); } try { @@ -49,27 +61,28 @@ public class DeathEventListener implements Listener { EntityDamageByEntityEvent entityDamageByEntityEvent = (EntityDamageByEntityEvent) entityDamageEvent; Entity killerEntity = entityDamageByEntityEvent.getDamager(); - handleKill(time, dead, killerEntity); + UUID uuid = dead instanceof Player ? dead.getUniqueId() : null; + handleKill(time, uuid, killerEntity); } catch (Exception e) { - Log.toLog(this.getClass(), e); + errorHandler.log(L.ERROR, this.getClass(), e); } } - private void handleKill(long time, LivingEntity dead, Entity killerEntity) { - KillProcessor processor = null; + private void handleKill(long time, UUID victimUUID, Entity killerEntity) { + Runnable processor = null; if (killerEntity instanceof Player) { - processor = handlePlayerKill(time, dead, (Player) killerEntity); + processor = handlePlayerKill(time, victimUUID, (Player) killerEntity); } else if (killerEntity instanceof Tameable) { - processor = handlePetKill(time, dead, (Tameable) killerEntity); + processor = handlePetKill(time, victimUUID, (Tameable) killerEntity); } else if (killerEntity instanceof Projectile) { - processor = handleProjectileKill(time, dead, (Projectile) killerEntity); + processor = handleProjectileKill(time, victimUUID, (Projectile) killerEntity); } if (processor != null) { - Processing.submit(processor); + processing.submit(processor); } } - private KillProcessor handlePlayerKill(long time, LivingEntity dead, Player killer) { + private Runnable handlePlayerKill(long time, UUID victimUUID, Player killer) { Material itemInHand; try { itemInHand = killer.getInventory().getItemInMainHand().getType(); @@ -81,10 +94,14 @@ public class DeathEventListener implements Listener { } } - return new KillProcessor(killer.getUniqueId(), time, dead, Formatters.itemName().apply(itemInHand.name())); + String weaponName = new ItemNameFormatter().apply(itemInHand.name()); + + return victimUUID != null + ? new PlayerKillProcessor(killer.getUniqueId(), time, victimUUID, weaponName) + : new MobKillProcessor(killer.getUniqueId()); } - private KillProcessor handlePetKill(long time, LivingEntity dead, Tameable tameable) { + private Runnable handlePetKill(long time, UUID victimUUID, Tameable tameable) { if (!tameable.isTamed()) { return null; } @@ -102,22 +119,23 @@ public class DeathEventListener implements Listener { name = tameable.getClass().getSimpleName(); } - return new KillProcessor(owner.getUniqueId(), time, dead, - new Format(name).removeNumbers().removeSymbols().capitalize().toString() - ); + return victimUUID != null + ? new PlayerKillProcessor(owner.getUniqueId(), time, victimUUID, new EntityNameFormatter().apply(name)) + : new MobKillProcessor(owner.getUniqueId()); } - private KillProcessor handleProjectileKill(long time, LivingEntity dead, Projectile projectile) { + private Runnable handleProjectileKill(long time, UUID victimUUID, Projectile projectile) { ProjectileSource source = projectile.getShooter(); if (!(source instanceof Player)) { return null; } Player player = (Player) source; + String projectileName = new EntityNameFormatter().apply(projectile.getType().name()); - return new KillProcessor(player.getUniqueId(), time, dead, - new Format(projectile.getType().name()).capitalize().toString() - ); + return victimUUID != null + ? new PlayerKillProcessor(player.getUniqueId(), time, victimUUID, projectileName) + : new MobKillProcessor(player.getUniqueId()); } } diff --git a/Plan/src/main/java/com/djrapitops/plan/system/listeners/bukkit/GamemodeChangeListener.java b/Plan/src/main/java/com/djrapitops/plan/system/listeners/bukkit/GameModeChangeListener.java similarity index 67% rename from Plan/src/main/java/com/djrapitops/plan/system/listeners/bukkit/GamemodeChangeListener.java rename to Plan/src/main/java/com/djrapitops/plan/system/listeners/bukkit/GameModeChangeListener.java index 8387b9d78..cb8796177 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/listeners/bukkit/GamemodeChangeListener.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/listeners/bukkit/GameModeChangeListener.java @@ -3,13 +3,15 @@ package com.djrapitops.plan.system.listeners.bukkit; import com.djrapitops.plan.data.container.Session; import com.djrapitops.plan.system.cache.SessionCache; import com.djrapitops.plan.system.settings.WorldAliasSettings; -import com.djrapitops.plugin.api.utility.log.Log; +import com.djrapitops.plugin.logging.L; +import com.djrapitops.plugin.logging.error.ErrorHandler; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; import org.bukkit.event.Listener; import org.bukkit.event.player.PlayerGameModeChangeEvent; +import javax.inject.Inject; import java.util.Optional; import java.util.UUID; @@ -18,13 +20,20 @@ import java.util.UUID; * * @author Rsl1122 */ -public class GamemodeChangeListener implements Listener { +public class GameModeChangeListener implements Listener { + + private final WorldAliasSettings worldAliasSettings; + private final ErrorHandler errorHandler; + + @Inject + public GameModeChangeListener( + WorldAliasSettings worldAliasSettings, + ErrorHandler errorHandler + ) { + this.worldAliasSettings = worldAliasSettings; + this.errorHandler = errorHandler; + } - /** - * GM Change Event Listener. - * - * @param event Fired Event. - */ @EventHandler(priority = EventPriority.MONITOR) public void onGameModeChange(PlayerGameModeChangeEvent event) { if (event.isCancelled()) { @@ -33,7 +42,7 @@ public class GamemodeChangeListener implements Listener { try { actOnEvent(event); } catch (Exception e) { - Log.toLog(this.getClass(), e); + errorHandler.log(L.ERROR, this.getClass(), e); } } @@ -44,7 +53,7 @@ public class GamemodeChangeListener implements Listener { String gameMode = event.getNewGameMode().name(); String worldName = player.getWorld().getName(); - WorldAliasSettings.addWorld(worldName); + worldAliasSettings.addWorld(worldName); Optional cachedSession = SessionCache.getCachedSession(uuid); cachedSession.ifPresent(session -> session.changeState(worldName, gameMode, time)); diff --git a/Plan/src/main/java/com/djrapitops/plan/system/listeners/bukkit/PlayerOnlineListener.java b/Plan/src/main/java/com/djrapitops/plan/system/listeners/bukkit/PlayerOnlineListener.java index 5daaf4d84..0d1832b71 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/listeners/bukkit/PlayerOnlineListener.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/listeners/bukkit/PlayerOnlineListener.java @@ -2,12 +2,13 @@ package com.djrapitops.plan.system.listeners.bukkit; import com.djrapitops.plan.data.container.Session; import com.djrapitops.plan.system.cache.SessionCache; +import com.djrapitops.plan.system.info.server.ServerInfo; import com.djrapitops.plan.system.processing.Processing; -import com.djrapitops.plan.system.processing.processors.info.NetworkPageUpdateProcessor; -import com.djrapitops.plan.system.processing.processors.info.PlayerPageUpdateProcessor; -import com.djrapitops.plan.system.processing.processors.player.*; -import com.djrapitops.plugin.api.systems.NotificationCenter; -import com.djrapitops.plugin.api.utility.log.Log; +import com.djrapitops.plan.system.processing.processors.Processors; +import com.djrapitops.plan.system.settings.Settings; +import com.djrapitops.plan.system.settings.config.PlanConfig; +import com.djrapitops.plugin.logging.L; +import com.djrapitops.plugin.logging.error.ErrorHandler; import com.djrapitops.plugin.task.RunnableFactory; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; @@ -18,6 +19,7 @@ import org.bukkit.event.player.PlayerKickEvent; import org.bukkit.event.player.PlayerLoginEvent; import org.bukkit.event.player.PlayerQuitEvent; +import javax.inject.Inject; import java.net.InetAddress; import java.util.UUID; @@ -31,10 +33,37 @@ public class PlayerOnlineListener implements Listener { private static boolean countKicks = true; + private final PlanConfig config; + private final Processors processors; + private final Processing processing; + private final ServerInfo serverInfo; + private final SessionCache sessionCache; + private final ErrorHandler errorHandler; + private final RunnableFactory runnableFactory; + public static void setCountKicks(boolean value) { countKicks = value; } + @Inject + public PlayerOnlineListener( + PlanConfig config, + Processors processors, + Processing processing, + ServerInfo serverInfo, + SessionCache sessionCache, + RunnableFactory runnableFactory, + ErrorHandler errorHandler + ) { + this.config = config; + this.processors = processors; + this.processing = processing; + this.serverInfo = serverInfo; + this.sessionCache = sessionCache; + this.runnableFactory = runnableFactory; + this.errorHandler = errorHandler; + } + @EventHandler(priority = EventPriority.MONITOR) public void onPlayerLogin(PlayerLoginEvent event) { try { @@ -42,9 +71,9 @@ public class PlayerOnlineListener implements Listener { UUID uuid = event.getPlayer().getUniqueId(); boolean op = event.getPlayer().isOp(); boolean banned = result == PlayerLoginEvent.Result.KICK_BANNED; - Processing.submit(new BanAndOpProcessor(uuid, () -> banned, op)); + processing.submit(processors.player().banAndOpProcessor(uuid, () -> banned, op)); } catch (Exception e) { - Log.toLog(this.getClass(), e); + errorHandler.log(L.ERROR, this.getClass(), e); } } @@ -67,9 +96,9 @@ public class PlayerOnlineListener implements Listener { return; } - Processing.submit(new KickProcessor(uuid)); + processing.submit(processors.player().kickProcessor(uuid)); } catch (Exception e) { - Log.toLog(this.getClass(), e); + errorHandler.log(L.ERROR, this.getClass(), e); } } @@ -78,13 +107,13 @@ public class PlayerOnlineListener implements Listener { try { actOnJoinEvent(event); } catch (Exception e) { - Log.toLog(this.getClass(), e); + errorHandler.log(L.ERROR, this.getClass(), e); } } private void actOnJoinEvent(PlayerJoinEvent event) { Player player = event.getPlayer(); - NotificationCenter.checkNotifications(player); + // TODO Move update notification to the website. UUID uuid = player.getUniqueId(); long time = System.currentTimeMillis(); @@ -99,16 +128,16 @@ public class PlayerOnlineListener implements Listener { String playerName = player.getName(); String displayName = player.getDisplayName(); - SessionCache.getInstance().cacheSession(uuid, new Session(uuid, time, world, gm)); + boolean gatheringGeolocations = config.isTrue(Settings.DATA_GEOLOCATIONS); - RunnableFactory.createNew("Player Register: " + uuid, - new RegisterProcessor(uuid, player::getFirstPlayed, playerName, - new IPUpdateProcessor(uuid, address, time), - new NameProcessor(uuid, playerName, displayName), - new PlayerPageUpdateProcessor(uuid) + processing.submitCritical(() -> sessionCache.cacheSession(uuid, new Session(uuid, serverInfo.getServerUUID(), time, world, gm))); + runnableFactory.create("Player Register: " + uuid, + processors.player().registerProcessor(uuid, player::getFirstPlayed, playerName, + gatheringGeolocations ? processors.player().ipUpdateProcessor(uuid, address, time) : null, + processors.player().nameProcessor(uuid, playerName, displayName), + processors.info().playerPageUpdateProcessor(uuid) ) ).runTaskAsynchronously(); - Processing.submit(new NetworkPageUpdateProcessor()); } @EventHandler(priority = EventPriority.MONITOR) @@ -116,7 +145,7 @@ public class PlayerOnlineListener implements Listener { try { actOnQuitEvent(event); } catch (Exception e) { - Log.toLog(this.getClass(), e); + errorHandler.log(L.ERROR, this.getClass(), e); } } @@ -127,9 +156,8 @@ public class PlayerOnlineListener implements Listener { AFKListener.AFK_TRACKER.loggedOut(uuid, time); - Processing.submit(new BanAndOpProcessor(uuid, player::isBanned, player.isOp())); - Processing.submit(new EndSessionProcessor(uuid, time)); - Processing.submit(new NetworkPageUpdateProcessor()); - Processing.submit(new PlayerPageUpdateProcessor(uuid)); + processing.submit(processors.player().banAndOpProcessor(uuid, player::isBanned, player.isOp())); + processing.submit(processors.player().endSessionProcessor(uuid, time)); + processing.submit(processors.info().playerPageUpdateProcessor(uuid)); } } diff --git a/Plan/src/main/java/com/djrapitops/plan/system/listeners/bukkit/WorldChangeListener.java b/Plan/src/main/java/com/djrapitops/plan/system/listeners/bukkit/WorldChangeListener.java index 60ad98cfb..4c0f266d7 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/listeners/bukkit/WorldChangeListener.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/listeners/bukkit/WorldChangeListener.java @@ -3,24 +3,38 @@ package com.djrapitops.plan.system.listeners.bukkit; import com.djrapitops.plan.data.container.Session; import com.djrapitops.plan.system.cache.SessionCache; import com.djrapitops.plan.system.settings.WorldAliasSettings; -import com.djrapitops.plugin.api.utility.log.Log; +import com.djrapitops.plugin.logging.L; +import com.djrapitops.plugin.logging.error.ErrorHandler; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; import org.bukkit.event.Listener; import org.bukkit.event.player.PlayerChangedWorldEvent; +import javax.inject.Inject; import java.util.Optional; import java.util.UUID; public class WorldChangeListener implements Listener { + private final WorldAliasSettings worldAliasSettings; + private final ErrorHandler errorHandler; + + @Inject + public WorldChangeListener( + WorldAliasSettings worldAliasSettings, + ErrorHandler errorHandler + ) { + this.worldAliasSettings = worldAliasSettings; + this.errorHandler = errorHandler; + } + @EventHandler(priority = EventPriority.MONITOR) public void onWorldChange(PlayerChangedWorldEvent event) { try { actOnEvent(event); } catch (Exception e) { - Log.toLog(this.getClass(), e); + errorHandler.log(L.ERROR, this.getClass(), e); } } @@ -33,7 +47,7 @@ public class WorldChangeListener implements Listener { String worldName = player.getWorld().getName(); String gameMode = player.getGameMode().name(); - WorldAliasSettings.addWorld(worldName); + worldAliasSettings.addWorld(worldName); Optional cachedSession = SessionCache.getCachedSession(uuid); cachedSession.ifPresent(session -> session.changeState(worldName, gameMode, time)); diff --git a/Plan/src/main/java/com/djrapitops/plan/system/listeners/bungee/PlayerOnlineListener.java b/Plan/src/main/java/com/djrapitops/plan/system/listeners/bungee/PlayerOnlineListener.java index 1ab692619..d4f9a8a7b 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/listeners/bungee/PlayerOnlineListener.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/listeners/bungee/PlayerOnlineListener.java @@ -8,12 +8,13 @@ import com.djrapitops.plan.data.container.Session; import com.djrapitops.plan.system.cache.SessionCache; import com.djrapitops.plan.system.info.server.ServerInfo; import com.djrapitops.plan.system.processing.Processing; -import com.djrapitops.plan.system.processing.processors.info.PlayerPageUpdateProcessor; -import com.djrapitops.plan.system.processing.processors.player.BungeePlayerRegisterProcessor; -import com.djrapitops.plan.system.processing.processors.player.IPUpdateProcessor; +import com.djrapitops.plan.system.processing.processors.Processors; +import com.djrapitops.plan.system.settings.Settings; +import com.djrapitops.plan.system.settings.config.PlanConfig; import com.djrapitops.plan.system.webserver.cache.PageId; import com.djrapitops.plan.system.webserver.cache.ResponseCache; -import com.djrapitops.plugin.api.utility.log.Log; +import com.djrapitops.plugin.logging.L; +import com.djrapitops.plugin.logging.error.ErrorHandler; import net.md_5.bungee.api.connection.ProxiedPlayer; import net.md_5.bungee.api.event.PlayerDisconnectEvent; import net.md_5.bungee.api.event.PostLoginEvent; @@ -21,6 +22,7 @@ import net.md_5.bungee.api.event.ServerSwitchEvent; import net.md_5.bungee.api.plugin.Listener; import net.md_5.bungee.event.EventHandler; +import javax.inject.Inject; import java.net.InetAddress; import java.util.UUID; @@ -31,6 +33,30 @@ import java.util.UUID; */ public class PlayerOnlineListener implements Listener { + private final PlanConfig config; + private final Processors processors; + private final Processing processing; + private final SessionCache sessionCache; + private final ServerInfo serverInfo; + private final ErrorHandler errorHandler; + + @Inject + public PlayerOnlineListener( + PlanConfig config, + Processors processors, + Processing processing, + SessionCache sessionCache, + ServerInfo serverInfo, + ErrorHandler errorHandler + ) { + this.config = config; + this.processors = processors; + this.processing = processing; + this.sessionCache = sessionCache; + this.serverInfo = serverInfo; + this.errorHandler = errorHandler; + } + @EventHandler public void onPostLogin(PostLoginEvent event) { try { @@ -38,17 +64,19 @@ public class PlayerOnlineListener implements Listener { UUID uuid = player.getUniqueId(); String name = player.getName(); InetAddress address = player.getAddress().getAddress(); - long now = System.currentTimeMillis(); + long time = System.currentTimeMillis(); - SessionCache.getInstance().cacheSession(uuid, new Session(uuid, now, "", "")); + sessionCache.cacheSession(uuid, new Session(uuid, serverInfo.getServerUUID(), time, "", "")); - Processing.submit(new BungeePlayerRegisterProcessor(uuid, name, now, - new IPUpdateProcessor(uuid, address, now)) - ); - Processing.submit(new PlayerPageUpdateProcessor(uuid)); - ResponseCache.clearResponse(PageId.SERVER.of(ServerInfo.getServerUUID())); + boolean gatheringGeolocations = config.isTrue(Settings.DATA_GEOLOCATIONS); + + processing.submit(processors.player().proxyRegisterProcessor(uuid, name, time, + gatheringGeolocations ? processors.player().ipUpdateProcessor(uuid, address, time) : null + )); + processing.submit(processors.info().playerPageUpdateProcessor(uuid)); + ResponseCache.clearResponse(PageId.SERVER.of(serverInfo.getServerUUID())); } catch (Exception e) { - Log.toLog(this.getClass(), e); + errorHandler.log(L.WARN, this.getClass(), e); } } @@ -58,11 +86,11 @@ public class PlayerOnlineListener implements Listener { ProxiedPlayer player = event.getPlayer(); UUID uuid = player.getUniqueId(); - SessionCache.getInstance().endSession(uuid, System.currentTimeMillis()); - Processing.submit(new PlayerPageUpdateProcessor(uuid)); - ResponseCache.clearResponse(PageId.SERVER.of(ServerInfo.getServerUUID())); + sessionCache.endSession(uuid, System.currentTimeMillis()); + processing.submit(processors.info().playerPageUpdateProcessor(uuid)); + ResponseCache.clearResponse(PageId.SERVER.of(serverInfo.getServerUUID())); } catch (Exception e) { - Log.toLog(this.getClass(), e); + errorHandler.log(L.WARN, this.getClass(), e); } } @@ -72,12 +100,12 @@ public class PlayerOnlineListener implements Listener { ProxiedPlayer player = event.getPlayer(); UUID uuid = player.getUniqueId(); - long now = System.currentTimeMillis(); + long time = System.currentTimeMillis(); // Replaces the current session in the cache. - SessionCache.getInstance().cacheSession(uuid, new Session(uuid, now, "", "")); - Processing.submit(new PlayerPageUpdateProcessor(uuid)); + sessionCache.cacheSession(uuid, new Session(uuid, serverInfo.getServerUUID(), time, "", "")); + processing.submit(processors.info().playerPageUpdateProcessor(uuid)); } catch (Exception e) { - Log.toLog(this.getClass(), e); + errorHandler.log(L.WARN, this.getClass(), e); } } } diff --git a/Plan/src/main/java/com/djrapitops/plan/system/listeners/sponge/SpongeAFKListener.java b/Plan/src/main/java/com/djrapitops/plan/system/listeners/sponge/SpongeAFKListener.java index b3a777bec..492b5b22c 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/listeners/sponge/SpongeAFKListener.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/listeners/sponge/SpongeAFKListener.java @@ -2,7 +2,9 @@ package com.djrapitops.plan.system.listeners.sponge; import com.djrapitops.plan.system.afk.AFKTracker; import com.djrapitops.plan.system.settings.Permissions; -import com.djrapitops.plugin.api.utility.log.Log; +import com.djrapitops.plan.system.settings.config.PlanConfig; +import com.djrapitops.plugin.logging.L; +import com.djrapitops.plugin.logging.error.ErrorHandler; import org.spongepowered.api.entity.living.player.Player; import org.spongepowered.api.event.Listener; import org.spongepowered.api.event.Order; @@ -13,6 +15,7 @@ import org.spongepowered.api.event.entity.living.humanoid.player.TargetPlayerEve import org.spongepowered.api.event.filter.cause.First; import org.spongepowered.api.event.message.MessageChannelEvent; +import javax.inject.Inject; import java.util.UUID; /** @@ -26,13 +29,28 @@ import java.util.UUID; public class SpongeAFKListener { // Static so that /reload does not cause afk tracking to fail. - public static final AFKTracker AFK_TRACKER = new AFKTracker(); + static AFKTracker AFK_TRACKER; + + private final ErrorHandler errorHandler; + + @Inject + public SpongeAFKListener(PlanConfig config, ErrorHandler errorHandler) { + this.errorHandler = errorHandler; + + SpongeAFKListener.assignAFKTracker(config); + } + + private static void assignAFKTracker(PlanConfig config) { + if (AFK_TRACKER == null) { + AFK_TRACKER = new AFKTracker(config); + } + } private void event(TargetPlayerEvent event) { try { performedAction(event.getTargetEntity()); } catch (Exception e) { - Log.toLog(this.getClass(), e); + errorHandler.log(L.ERROR, this.getClass(), e); } } @@ -60,7 +78,7 @@ public class SpongeAFKListener { @Listener(order = Order.POST) public void onPlayerCommand(SendCommandEvent event, @First Player player) { performedAction(player); - + boolean isAfkCommand = event.getCommand().toLowerCase().startsWith("afk"); if (isAfkCommand) { AFK_TRACKER.usedAfkCommand(player.getUniqueId(), System.currentTimeMillis()); diff --git a/Plan/src/main/java/com/djrapitops/plan/system/listeners/sponge/SpongeChatListener.java b/Plan/src/main/java/com/djrapitops/plan/system/listeners/sponge/SpongeChatListener.java index cb9e1ff64..05cb6be3c 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/listeners/sponge/SpongeChatListener.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/listeners/sponge/SpongeChatListener.java @@ -1,14 +1,16 @@ package com.djrapitops.plan.system.listeners.sponge; import com.djrapitops.plan.system.processing.Processing; -import com.djrapitops.plan.system.processing.processors.player.NameProcessor; -import com.djrapitops.plugin.api.utility.log.Log; +import com.djrapitops.plan.system.processing.processors.player.PlayerProcessors; +import com.djrapitops.plugin.logging.L; +import com.djrapitops.plugin.logging.error.ErrorHandler; import org.spongepowered.api.entity.living.player.Player; import org.spongepowered.api.event.Listener; import org.spongepowered.api.event.Order; import org.spongepowered.api.event.filter.cause.First; import org.spongepowered.api.event.message.MessageChannelEvent; +import javax.inject.Inject; import java.util.UUID; /** @@ -18,6 +20,21 @@ import java.util.UUID; */ public class SpongeChatListener { + private final PlayerProcessors processorFactory; + private final Processing processing; + private ErrorHandler errorHandler; + + @Inject + public SpongeChatListener( + PlayerProcessors processorFactory, + Processing processing, + ErrorHandler errorHandler + ) { + this.processorFactory = processorFactory; + this.processing = processing; + this.errorHandler = errorHandler; + } + @Listener(order = Order.POST) public void onPlayerChat(MessageChannelEvent.Chat event, @First Player player) { if (event.isCancelled()) { @@ -27,7 +44,7 @@ public class SpongeChatListener { try { actOnChatEvent(player); } catch (Exception e) { - Log.toLog(this.getClass(), e); + errorHandler.log(L.ERROR, this.getClass(), e); } } @@ -35,7 +52,7 @@ public class SpongeChatListener { UUID uuid = player.getUniqueId(); String name = player.getName(); String displayName = player.getDisplayNameData().displayName().get().toPlain(); - Processing.submit(new NameProcessor(uuid, name, displayName)); + processing.submit(processorFactory.nameProcessor(uuid, name, displayName)); } } \ No newline at end of file diff --git a/Plan/src/main/java/com/djrapitops/plan/system/listeners/sponge/SpongeCommandListener.java b/Plan/src/main/java/com/djrapitops/plan/system/listeners/sponge/SpongeCommandListener.java index f752f0ca5..3067f586d 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/listeners/sponge/SpongeCommandListener.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/listeners/sponge/SpongeCommandListener.java @@ -1,10 +1,12 @@ package com.djrapitops.plan.system.listeners.sponge; import com.djrapitops.plan.system.processing.Processing; -import com.djrapitops.plan.system.processing.processors.CommandProcessor; +import com.djrapitops.plan.system.processing.processors.Processors; import com.djrapitops.plan.system.settings.Permissions; import com.djrapitops.plan.system.settings.Settings; -import com.djrapitops.plugin.api.utility.log.Log; +import com.djrapitops.plan.system.settings.config.PlanConfig; +import com.djrapitops.plugin.logging.L; +import com.djrapitops.plugin.logging.error.ErrorHandler; import org.spongepowered.api.Sponge; import org.spongepowered.api.command.CommandMapping; import org.spongepowered.api.entity.living.player.Player; @@ -13,6 +15,7 @@ import org.spongepowered.api.event.Order; import org.spongepowered.api.event.command.SendCommandEvent; import org.spongepowered.api.event.filter.cause.First; +import javax.inject.Inject; import java.util.Optional; /** @@ -22,6 +25,24 @@ import java.util.Optional; */ public class SpongeCommandListener { + private final PlanConfig config; + private final Processors processors; + private final Processing processing; + private ErrorHandler errorHandler; + + @Inject + public SpongeCommandListener( + PlanConfig config, + Processors processors, + Processing processing, + ErrorHandler errorHandler + ) { + this.config = config; + this.processors = processors; + this.processing = processing; + this.errorHandler = errorHandler; + } + @Listener(order = Order.POST) public void onPlayerCommand(SendCommandEvent event, @First Player player) { boolean hasIgnorePermission = player.hasPermission(Permissions.IGNORE_COMMAND_USE.getPermission()); @@ -31,15 +52,15 @@ public class SpongeCommandListener { try { actOnCommandEvent(event); } catch (Exception e) { - Log.toLog(this.getClass(), e); + errorHandler.log(L.ERROR, this.getClass(), e); } } private void actOnCommandEvent(SendCommandEvent event) { String commandName = event.getCommand(); - boolean logUnknownCommands = Settings.LOG_UNKNOWN_COMMANDS.isTrue(); - boolean combineCommandAliases = Settings.COMBINE_COMMAND_ALIASES.isTrue(); + boolean logUnknownCommands = config.isTrue(Settings.LOG_UNKNOWN_COMMANDS); + boolean combineCommandAliases = config.isTrue(Settings.COMBINE_COMMAND_ALIASES); if (!logUnknownCommands || combineCommandAliases) { Optional existingCommand = Sponge.getCommandManager().get(commandName); @@ -51,7 +72,7 @@ public class SpongeCommandListener { commandName = existingCommand.get().getPrimaryAlias(); } } - Processing.submit(new CommandProcessor(commandName)); + processing.submit(processors.commandProcessor(commandName)); } } \ No newline at end of file diff --git a/Plan/src/main/java/com/djrapitops/plan/system/listeners/sponge/SpongeDeathListener.java b/Plan/src/main/java/com/djrapitops/plan/system/listeners/sponge/SpongeDeathListener.java index 568ca0fff..9bdf996b8 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/listeners/sponge/SpongeDeathListener.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/listeners/sponge/SpongeDeathListener.java @@ -1,12 +1,14 @@ package com.djrapitops.plan.system.listeners.sponge; import com.djrapitops.plan.data.container.Session; -import com.djrapitops.plan.data.store.mutators.formatting.Formatters; import com.djrapitops.plan.system.cache.SessionCache; import com.djrapitops.plan.system.processing.Processing; -import com.djrapitops.plan.system.processing.processors.player.SpongeKillProcessor; -import com.djrapitops.plugin.api.utility.log.Log; -import com.djrapitops.plugin.utilities.Format; +import com.djrapitops.plan.system.processing.processors.player.MobKillProcessor; +import com.djrapitops.plan.system.processing.processors.player.PlayerKillProcessor; +import com.djrapitops.plan.utilities.formatting.EntityNameFormatter; +import com.djrapitops.plan.utilities.formatting.ItemNameFormatter; +import com.djrapitops.plugin.logging.L; +import com.djrapitops.plugin.logging.error.ErrorHandler; import org.spongepowered.api.data.key.Keys; import org.spongepowered.api.data.type.HandTypes; import org.spongepowered.api.entity.Entity; @@ -22,6 +24,7 @@ import org.spongepowered.api.item.ItemType; import org.spongepowered.api.item.ItemTypes; import org.spongepowered.api.item.inventory.ItemStack; +import javax.inject.Inject; import java.util.Optional; import java.util.UUID; @@ -32,6 +35,18 @@ import java.util.UUID; */ public class SpongeDeathListener { + private final Processing processing; + private ErrorHandler errorHandler; + + @Inject + public SpongeDeathListener( + Processing processing, + ErrorHandler errorHandler + ) { + this.processing = processing; + this.errorHandler = errorHandler; + } + @Listener public void onEntityDeath(DestructEntityEvent.Death event) { long time = System.currentTimeMillis(); @@ -39,7 +54,7 @@ public class SpongeDeathListener { if (dead instanceof Player) { // Process Death - Processing.submitCritical(() -> SessionCache.getCachedSession(dead.getUniqueId()).ifPresent(Session::died)); + SessionCache.getCachedSession(dead.getUniqueId()).ifPresent(Session::died); } try { @@ -50,31 +65,34 @@ public class SpongeDeathListener { handleKill(time, dead, killerEntity); } } catch (Exception e) { - Log.toLog(this.getClass(), e); + errorHandler.log(L.ERROR, this.getClass(), e); } } private void handleKill(long time, Living dead, Entity killerEntity) { - SpongeKillProcessor processor = null; + Runnable processor = null; + UUID victimUUID = getUUID(dead); if (killerEntity instanceof Player) { - processor = handlePlayerKill(time, dead, (Player) killerEntity); + processor = handlePlayerKill(time, victimUUID, (Player) killerEntity); } else if (killerEntity instanceof Wolf) { - processor = handleWolfKill(time, dead, (Wolf) killerEntity); + processor = handleWolfKill(time, victimUUID, (Wolf) killerEntity); } else if (killerEntity instanceof Projectile) { - processor = handleProjectileKill(time, dead, (Projectile) killerEntity); + processor = handleProjectileKill(time, victimUUID, (Projectile) killerEntity); } if (processor != null) { - Processing.submit(processor); + processing.submit(processor); } } - private SpongeKillProcessor handlePlayerKill(long time, Living dead, Player killer) { + private Runnable handlePlayerKill(long time, UUID victimUUID, Player killer) { Optional inMainHand = killer.getItemInHand(HandTypes.MAIN_HAND); ItemStack inHand = inMainHand.orElse(killer.getItemInHand(HandTypes.OFF_HAND).orElse(ItemStack.empty())); ItemType type = inHand.isEmpty() ? ItemTypes.AIR : inHand.getType(); - return new SpongeKillProcessor(killer.getUniqueId(), time, getUUID(dead), Formatters.itemName().apply(type.getName())); + return victimUUID != null + ? new PlayerKillProcessor(killer.getUniqueId(), time, victimUUID, new ItemNameFormatter().apply(type.getName())) + : new MobKillProcessor(killer.getUniqueId()); } private UUID getUUID(Living dead) { @@ -84,26 +102,33 @@ public class SpongeDeathListener { return null; } - private SpongeKillProcessor handleWolfKill(long time, Living dead, Wolf wolf) { + private Runnable handleWolfKill(long time, UUID victimUUID, Wolf wolf) { Optional> owner = wolf.get(Keys.TAMED_OWNER); - return owner.map(ownerUUID -> ownerUUID.map( - uuid -> new SpongeKillProcessor(uuid, time, getUUID(dead), "Wolf") - ).orElse(null)).orElse(null); + // Has been tamed + return owner.map(ownerUUID -> + // Has tame owner + ownerUUID.map(uuid -> + // Player or mob + victimUUID != null + ? new PlayerKillProcessor(uuid, time, victimUUID, "Wolf") + : new MobKillProcessor(uuid) + ).orElse(null)).orElse(null); } - private SpongeKillProcessor handleProjectileKill(long time, Living dead, Projectile projectile) { + private Runnable handleProjectileKill(long time, UUID victimUUID, Projectile projectile) { ProjectileSource source = projectile.getShooter(); if (!(source instanceof Player)) { return null; } Player player = (Player) source; + String projectileName = new EntityNameFormatter().apply(projectile.getType().getName()); - return new SpongeKillProcessor(player.getUniqueId(), time, getUUID(dead), - new Format(projectile.getType().getName()).capitalize().toString() - ); + return victimUUID != null + ? new PlayerKillProcessor(player.getUniqueId(), time, victimUUID, projectileName) + : new MobKillProcessor(player.getUniqueId()); } } \ No newline at end of file diff --git a/Plan/src/main/java/com/djrapitops/plan/system/listeners/sponge/SpongeGMChangeListener.java b/Plan/src/main/java/com/djrapitops/plan/system/listeners/sponge/SpongeGMChangeListener.java index 490b8ebb1..0afd95df7 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/listeners/sponge/SpongeGMChangeListener.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/listeners/sponge/SpongeGMChangeListener.java @@ -3,12 +3,14 @@ package com.djrapitops.plan.system.listeners.sponge; import com.djrapitops.plan.data.container.Session; import com.djrapitops.plan.system.cache.SessionCache; import com.djrapitops.plan.system.settings.WorldAliasSettings; -import com.djrapitops.plugin.api.utility.log.Log; +import com.djrapitops.plugin.logging.L; +import com.djrapitops.plugin.logging.error.ErrorHandler; import org.spongepowered.api.entity.living.player.Player; import org.spongepowered.api.event.Listener; import org.spongepowered.api.event.Order; import org.spongepowered.api.event.entity.living.humanoid.ChangeGameModeEvent; +import javax.inject.Inject; import java.util.Optional; import java.util.UUID; @@ -19,6 +21,18 @@ import java.util.UUID; */ public class SpongeGMChangeListener { + private final WorldAliasSettings worldAliasSettings; + private ErrorHandler errorHandler; + + @Inject + public SpongeGMChangeListener( + WorldAliasSettings worldAliasSettings, + ErrorHandler errorHandler + ) { + this.worldAliasSettings = worldAliasSettings; + this.errorHandler = errorHandler; + } + @Listener(order = Order.POST) public void onGMChange(ChangeGameModeEvent.TargetPlayer event) { if (event.isCancelled()) { @@ -28,7 +42,7 @@ public class SpongeGMChangeListener { try { actOnGMChangeEvent(event); } catch (Exception e) { - Log.toLog(this.getClass(), e); + errorHandler.log(L.ERROR, this.getClass(), e); } } @@ -40,7 +54,7 @@ public class SpongeGMChangeListener { String gameMode = event.getGameMode().getName().toUpperCase(); String worldName = player.getWorld().getName(); - WorldAliasSettings.addWorld(worldName); + worldAliasSettings.addWorld(worldName); Optional cachedSession = SessionCache.getCachedSession(uuid); cachedSession.ifPresent(session -> session.changeState(worldName, gameMode, time)); diff --git a/Plan/src/main/java/com/djrapitops/plan/system/listeners/sponge/SpongePlayerListener.java b/Plan/src/main/java/com/djrapitops/plan/system/listeners/sponge/SpongePlayerListener.java index c7f5897f5..11ff07dfb 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/listeners/sponge/SpongePlayerListener.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/listeners/sponge/SpongePlayerListener.java @@ -2,13 +2,13 @@ package com.djrapitops.plan.system.listeners.sponge; import com.djrapitops.plan.data.container.Session; import com.djrapitops.plan.system.cache.SessionCache; -import com.djrapitops.plan.system.listeners.bukkit.AFKListener; +import com.djrapitops.plan.system.info.server.ServerInfo; import com.djrapitops.plan.system.processing.Processing; -import com.djrapitops.plan.system.processing.processors.info.NetworkPageUpdateProcessor; -import com.djrapitops.plan.system.processing.processors.info.PlayerPageUpdateProcessor; -import com.djrapitops.plan.system.processing.processors.player.*; -import com.djrapitops.plugin.api.systems.NotificationCenter; -import com.djrapitops.plugin.api.utility.log.Log; +import com.djrapitops.plan.system.processing.processors.Processors; +import com.djrapitops.plan.system.settings.Settings; +import com.djrapitops.plan.system.settings.config.PlanConfig; +import com.djrapitops.plugin.logging.L; +import com.djrapitops.plugin.logging.error.ErrorHandler; import com.djrapitops.plugin.task.RunnableFactory; import org.spongepowered.api.Sponge; import org.spongepowered.api.data.key.Keys; @@ -22,6 +22,7 @@ import org.spongepowered.api.profile.GameProfile; import org.spongepowered.api.service.ProviderRegistration; import org.spongepowered.api.service.ban.BanService; +import javax.inject.Inject; import java.net.InetAddress; import java.util.Optional; import java.util.UUID; @@ -33,12 +34,39 @@ import java.util.UUID; */ public class SpongePlayerListener { + private final PlanConfig config; + private final Processors processors; + private final Processing processing; + private final ServerInfo serverInfo; + private SessionCache sessionCache; + private RunnableFactory runnableFactory; + private ErrorHandler errorHandler; + + @Inject + public SpongePlayerListener( + PlanConfig config, + Processors processors, + Processing processing, + ServerInfo serverInfo, + SessionCache sessionCache, + RunnableFactory runnableFactory, + ErrorHandler errorHandler + ) { + this.config = config; + this.processors = processors; + this.processing = processing; + this.serverInfo = serverInfo; + this.sessionCache = sessionCache; + this.runnableFactory = runnableFactory; + this.errorHandler = errorHandler; + } + @Listener(order = Order.POST) public void onLogin(ClientConnectionEvent.Login event) { try { actOnLoginEvent(event); } catch (Exception e) { - Log.toLog(this.getClass(), e); + errorHandler.log(L.ERROR, this.getClass(), e); } } @@ -46,19 +74,19 @@ public class SpongePlayerListener { GameProfile profile = event.getProfile(); UUID uuid = profile.getUniqueId(); boolean banned = isBanned(profile); - Processing.submit(new BanAndOpProcessor(uuid, () -> banned, false)); + processing.submit(processors.player().banAndOpProcessor(uuid, () -> banned, false)); } @Listener(order = Order.POST) public void onKick(KickPlayerEvent event) { try { UUID uuid = event.getTargetEntity().getUniqueId(); - if (AFKListener.AFK_TRACKER.isAfk(uuid)) { + if (SpongeAFKListener.AFK_TRACKER.isAfk(uuid)) { return; } - Processing.submit(new KickProcessor(uuid)); + processing.submit(processors.player().kickProcessor(uuid)); } catch (Exception e) { - Log.toLog(this.getClass(), e); + errorHandler.log(L.ERROR, this.getClass(), e); } } @@ -76,15 +104,13 @@ public class SpongePlayerListener { try { actOnJoinEvent(event); } catch (Exception e) { - Log.toLog(this.getClass(), e); + errorHandler.log(L.ERROR, this.getClass(), e); } } private void actOnJoinEvent(ClientConnectionEvent.Join event) { Player player = event.getTargetEntity(); - NotificationCenter.checkNotifications(player); - UUID uuid = player.getUniqueId(); long time = System.currentTimeMillis(); @@ -92,26 +118,23 @@ public class SpongePlayerListener { String world = player.getWorld().getName(); Optional gameMode = player.getGameModeData().get(Keys.GAME_MODE); - String gm = "ADVENTURE"; - if (gameMode.isPresent()) { - gm = gameMode.get().getName().toUpperCase(); - } + String gm = gameMode.map(mode -> mode.getName().toUpperCase()).orElse("ADVENTURE"); InetAddress address = player.getConnection().getAddress().getAddress(); String playerName = player.getName(); String displayName = player.getDisplayNameData().displayName().get().toPlain(); - SessionCache.getInstance().cacheSession(uuid, new Session(uuid, time, world, gm)); + boolean gatheringGeolocations = config.isTrue(Settings.DATA_GEOLOCATIONS); - RunnableFactory.createNew("Player Register: " + uuid, - new RegisterProcessor(uuid, () -> time, playerName, - new IPUpdateProcessor(uuid, address, time), - new NameProcessor(uuid, playerName, displayName), - new PlayerPageUpdateProcessor(uuid) + processing.submitCritical(() -> sessionCache.cacheSession(uuid, new Session(uuid, serverInfo.getServerUUID(), time, world, gm))); + runnableFactory.create("Player Register: " + uuid, + processors.player().registerProcessor(uuid, () -> time, playerName, + gatheringGeolocations ? processors.player().ipUpdateProcessor(uuid, address, time) : null, + processors.player().nameProcessor(uuid, playerName, displayName), + processors.info().playerPageUpdateProcessor(uuid) ) ).runTaskAsynchronously(); - Processing.submit(new NetworkPageUpdateProcessor()); } @Listener(order = Order.POST) @@ -119,7 +142,7 @@ public class SpongePlayerListener { try { actOnQuitEvent(event); } catch (Exception e) { - Log.toLog(this.getClass(), e); + errorHandler.log(L.ERROR, this.getClass(), e); } } @@ -131,9 +154,8 @@ public class SpongePlayerListener { SpongeAFKListener.AFK_TRACKER.loggedOut(uuid, time); boolean banned = isBanned(player.getProfile()); - Processing.submit(new BanAndOpProcessor(uuid, () -> banned, false)); - Processing.submit(new EndSessionProcessor(uuid, time)); - Processing.submit(new NetworkPageUpdateProcessor()); - Processing.submit(new PlayerPageUpdateProcessor(uuid)); + processing.submit(processors.player().banAndOpProcessor(uuid, () -> banned, false)); + processing.submit(processors.player().endSessionProcessor(uuid, time)); + processing.submit(processors.info().playerPageUpdateProcessor(uuid)); } } \ No newline at end of file diff --git a/Plan/src/main/java/com/djrapitops/plan/system/listeners/sponge/SpongeWorldChangeListener.java b/Plan/src/main/java/com/djrapitops/plan/system/listeners/sponge/SpongeWorldChangeListener.java index 8d674ef71..c07b71d2b 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/listeners/sponge/SpongeWorldChangeListener.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/listeners/sponge/SpongeWorldChangeListener.java @@ -3,7 +3,8 @@ package com.djrapitops.plan.system.listeners.sponge; import com.djrapitops.plan.data.container.Session; import com.djrapitops.plan.system.cache.SessionCache; import com.djrapitops.plan.system.settings.WorldAliasSettings; -import com.djrapitops.plugin.api.utility.log.Log; +import com.djrapitops.plugin.logging.L; +import com.djrapitops.plugin.logging.error.ErrorHandler; import org.spongepowered.api.data.key.Keys; import org.spongepowered.api.entity.living.player.Player; import org.spongepowered.api.entity.living.player.gamemode.GameMode; @@ -12,6 +13,7 @@ import org.spongepowered.api.event.Order; import org.spongepowered.api.event.entity.MoveEntityEvent; import org.spongepowered.api.event.filter.cause.First; +import javax.inject.Inject; import java.util.Optional; import java.util.UUID; @@ -22,6 +24,18 @@ import java.util.UUID; */ public class SpongeWorldChangeListener { + private final WorldAliasSettings worldAliasSettings; + private ErrorHandler errorHandler; + + @Inject + public SpongeWorldChangeListener( + WorldAliasSettings worldAliasSettings, + ErrorHandler errorHandler + ) { + this.worldAliasSettings = worldAliasSettings; + this.errorHandler = errorHandler; + } + @Listener(order = Order.POST) public void onWorldChange(MoveEntityEvent.Teleport event, @First Player player) { if (event.isCancelled()) { @@ -31,7 +45,7 @@ public class SpongeWorldChangeListener { try { actOnEvent(event, player); } catch (Exception e) { - Log.toLog(this.getClass(), e); + errorHandler.log(L.ERROR, this.getClass(), e); } } @@ -43,7 +57,7 @@ public class SpongeWorldChangeListener { String worldName = event.getToTransform().getExtent().getName(); String gameMode = getGameMode(player); - WorldAliasSettings.addWorld(worldName); + worldAliasSettings.addWorld(worldName); Optional cachedSession = SessionCache.getCachedSession(uuid); cachedSession.ifPresent(session -> session.changeState(worldName, gameMode, time)); diff --git a/Plan/src/main/java/com/djrapitops/plan/system/listeners/velocity/PlayerOnlineListener.java b/Plan/src/main/java/com/djrapitops/plan/system/listeners/velocity/PlayerOnlineListener.java new file mode 100644 index 000000000..95fc1cbc3 --- /dev/null +++ b/Plan/src/main/java/com/djrapitops/plan/system/listeners/velocity/PlayerOnlineListener.java @@ -0,0 +1,114 @@ +/* + * License is provided in the jar as LICENSE also here: + * https://github.com/Rsl1122/Plan-PlayerAnalytics/blob/master/Plan/src/main/resources/LICENSE + */ +package com.djrapitops.plan.system.listeners.velocity; + +import com.djrapitops.plan.data.container.Session; +import com.djrapitops.plan.system.cache.SessionCache; +import com.djrapitops.plan.system.info.server.ServerInfo; +import com.djrapitops.plan.system.processing.Processing; +import com.djrapitops.plan.system.processing.processors.Processors; +import com.djrapitops.plan.system.settings.Settings; +import com.djrapitops.plan.system.settings.config.PlanConfig; +import com.djrapitops.plan.system.webserver.cache.PageId; +import com.djrapitops.plan.system.webserver.cache.ResponseCache; +import com.djrapitops.plugin.logging.L; +import com.djrapitops.plugin.logging.error.ErrorHandler; +import com.velocitypowered.api.event.Subscribe; +import com.velocitypowered.api.event.connection.DisconnectEvent; +import com.velocitypowered.api.event.connection.PostLoginEvent; +import com.velocitypowered.api.event.player.ServerConnectedEvent; +import com.velocitypowered.api.proxy.Player; + +import javax.inject.Inject; +import javax.inject.Singleton; +import java.net.InetAddress; +import java.util.UUID; + +/** + * Player Join listener for Velocity. + *

+ * Based on the bungee version. + * + * @author MicleBrick + */ +@Singleton +public class PlayerOnlineListener { + + private final PlanConfig config; + private final Processors processors; + private final Processing processing; + private final SessionCache sessionCache; + private final ServerInfo serverInfo; + private final ErrorHandler errorHandler; + + @Inject + public PlayerOnlineListener( + PlanConfig config, + Processing processing, + Processors processors, + SessionCache sessionCache, + ServerInfo serverInfo, + ErrorHandler errorHandler + ) { + this.config = config; + this.processing = processing; + this.processors = processors; + this.sessionCache = sessionCache; + this.serverInfo = serverInfo; + this.errorHandler = errorHandler; + } + + @Subscribe + public void onPostLogin(PostLoginEvent event) { + try { + Player player = event.getPlayer(); + UUID uuid = player.getUniqueId(); + String name = player.getUsername(); + InetAddress address = player.getRemoteAddress().getAddress(); + long time = System.currentTimeMillis(); + + sessionCache.cacheSession(uuid, new Session(uuid, serverInfo.getServerUUID(), time, "", "")); + + boolean gatheringGeolocations = config.isTrue(Settings.DATA_GEOLOCATIONS); + + processing.submit(processors.player().proxyRegisterProcessor(uuid, name, time, + gatheringGeolocations ? processors.player().ipUpdateProcessor(uuid, address, time) : null + )); + processing.submit(processors.info().playerPageUpdateProcessor(uuid)); + ResponseCache.clearResponse(PageId.SERVER.of(serverInfo.getServerUUID())); + } catch (Exception e) { + errorHandler.log(L.WARN, this.getClass(), e); + } + } + + @Subscribe + public void onLogout(DisconnectEvent event) { + try { + Player player = event.getPlayer(); + UUID uuid = player.getUniqueId(); + + sessionCache.endSession(uuid, System.currentTimeMillis()); + processing.submit(processors.info().playerPageUpdateProcessor(uuid)); + ResponseCache.clearResponse(PageId.SERVER.of(serverInfo.getServerUUID())); + } catch (Exception e) { + errorHandler.log(L.WARN, this.getClass(), e); + } + } + + @Subscribe + public void onServerSwitch(ServerConnectedEvent event) { + try { + Player player = event.getPlayer(); + UUID uuid = player.getUniqueId(); + + long now = System.currentTimeMillis(); + // Replaces the current session in the cache. + sessionCache.cacheSession(uuid, new Session(uuid, serverInfo.getServerUUID(), now, "", "")); + processing.submit(processors.info().playerPageUpdateProcessor(uuid)); + } catch (Exception e) { + errorHandler.log(L.WARN, this.getClass(), e); + } + } +} diff --git a/Plan/src/main/java/com/djrapitops/plan/system/locale/Locale.java b/Plan/src/main/java/com/djrapitops/plan/system/locale/Locale.java index baa310fc9..e0c950d24 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/locale/Locale.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/locale/Locale.java @@ -2,7 +2,6 @@ package com.djrapitops.plan.system.locale; import com.djrapitops.plan.PlanPlugin; import com.djrapitops.plan.system.locale.lang.*; -import com.djrapitops.plan.system.settings.Settings; import java.io.File; import java.io.IOException; @@ -10,6 +9,7 @@ import java.io.Serializable; import java.util.Arrays; import java.util.HashMap; import java.util.List; +import java.util.Map; import java.util.function.Function; import java.util.stream.Collectors; @@ -20,20 +20,12 @@ import java.util.stream.Collectors; */ public class Locale extends HashMap { - public static Locale fromSetting() throws IOException { - String locale = Settings.LOCALE.toString(); - if (locale.equalsIgnoreCase("default")) { - return new Locale(); - } - return forLangCodeString(locale); + public static Locale forLangCodeString(PlanPlugin plugin, String code) throws IOException { + return forLangCode(LangCode.fromString(code), plugin); } - public static Locale forLangCodeString(String code) throws IOException { - return forLangCode(LangCode.fromString(code)); - } - - public static Locale forLangCode(LangCode code) throws IOException { - return new LocaleFileReader(PlanPlugin.getInstance(), code.getFileName()).load(); + public static Locale forLangCode(LangCode code, PlanPlugin plugin) throws IOException { + return new LocaleFileReader(plugin, code.getFileName()).load(); } public static Locale fromFile(File file) throws IOException { @@ -66,6 +58,10 @@ public class Locale extends HashMap { return get(key).toArray(values); } + public void loadFromAnotherLocale(Map locale) { + putAll(locale); + } + public String replaceMatchingLanguage(String from) { if (isEmpty()) { return from; diff --git a/Plan/src/main/java/com/djrapitops/plan/system/locale/LocaleSystem.java b/Plan/src/main/java/com/djrapitops/plan/system/locale/LocaleSystem.java index 9061a36ed..f344a448a 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/locale/LocaleSystem.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/locale/LocaleSystem.java @@ -1,17 +1,23 @@ package com.djrapitops.plan.system.locale; -import com.djrapitops.plan.api.exceptions.EnableException; +import com.djrapitops.plan.PlanPlugin; import com.djrapitops.plan.system.SubSystem; -import com.djrapitops.plan.system.file.FileSystem; +import com.djrapitops.plan.system.file.PlanFiles; import com.djrapitops.plan.system.locale.lang.*; import com.djrapitops.plan.system.settings.Settings; +import com.djrapitops.plan.system.settings.config.PlanConfig; import com.djrapitops.plan.system.webserver.auth.FailReason; -import com.djrapitops.plugin.api.utility.log.Log; +import com.djrapitops.plugin.logging.L; +import com.djrapitops.plugin.logging.console.PluginLogger; +import com.djrapitops.plugin.logging.error.ErrorHandler; +import javax.inject.Inject; +import javax.inject.Singleton; import java.io.File; import java.io.IOException; import java.util.Arrays; import java.util.Map; +import java.util.Optional; import java.util.function.Function; import java.util.stream.Collectors; @@ -20,11 +26,30 @@ import java.util.stream.Collectors; * * @author Rsl1122 */ +@Singleton public class LocaleSystem implements SubSystem { - private Locale locale; + private final PlanPlugin plugin; + private final PlanFiles files; + private final PlanConfig config; + private final PluginLogger logger; + private final ErrorHandler errorHandler; - public LocaleSystem() { + private final Locale locale; + + @Inject + public LocaleSystem( + PlanPlugin plugin, + PlanFiles files, + PlanConfig config, + PluginLogger logger, + ErrorHandler errorHandler + ) { + this.plugin = plugin; + this.files = files; + this.config = config; + this.logger = logger; + this.errorHandler = errorHandler; this.locale = new Locale(); } @@ -41,7 +66,8 @@ public class LocaleSystem implements SubSystem { ServerPageLang.values(), NetworkPageLang.values(), ErrorPageLang.values(), - FailReason.values() + FailReason.values(), + HealthInfoLang.values() }; return Arrays.stream(lang) @@ -50,45 +76,63 @@ public class LocaleSystem implements SubSystem { } @Override - public void enable() throws EnableException { - File localeFile = FileSystem.getLocaleFile(); + public void enable() { + File localeFile = files.getLocaleFile(); - if (Settings.WRITE_NEW_LOCALE.isTrue()) { + if (config.isTrue(Settings.WRITE_NEW_LOCALE)) { writeNewDefaultLocale(localeFile); } + Optional loaded; if (localeFile.exists()) { - loadFromFile(localeFile); + loaded = loadFromFile(localeFile); } else { - loadSettingLocale(); + loaded = loadSettingLocale(); } + loaded.ifPresent(locale::loadFromAnotherLocale); } private void writeNewDefaultLocale(File localeFile) { try { new LocaleFileWriter(localeFile.exists() ? Locale.fromFile(localeFile) : locale).writeToFile(localeFile); } catch (IOException | IllegalStateException e) { - Log.error("Failed to write new Locale file at " + localeFile.getAbsolutePath()); - Log.toLog(this.getClass().getName(), e); + logger.error("Failed to write new Locale file at " + localeFile.getAbsolutePath()); + errorHandler.log(L.WARN, this.getClass(), e); } - Settings.WRITE_NEW_LOCALE.set(false); - Settings.save(); + resetWriteConfigSetting(); } - private void loadSettingLocale() throws EnableException { + private void resetWriteConfigSetting() { try { - locale = Locale.fromSetting(); - } catch (IOException e) { - throw new EnableException("Failed to read locale from jar: " + Settings.LOCALE.toString(), e); + config.set(Settings.WRITE_NEW_LOCALE, false); + config.save(); + } catch (IOException | IllegalStateException e) { + logger.error("Failed set WriteNewLocaleFileOnEnable back to false"); + errorHandler.log(L.WARN, this.getClass(), e); } } - private void loadFromFile(File localeFile) throws EnableException { + private Optional loadSettingLocale() { try { - locale = Locale.fromFile(localeFile); + String setting = config.getString(Settings.LOCALE); + if (!setting.equalsIgnoreCase("default")) { + return Optional.of(Locale.forLangCodeString(plugin, setting)); + } } catch (IOException e) { - throw new EnableException("Failed to read locale file at " + localeFile.getAbsolutePath(), e); + logger.warn("Failed to read locale from jar: " + config.getString(Settings.LOCALE) + ", " + e.toString()); + logger.warn("Using Default Locale as a fallback (EN)"); } + return Optional.empty(); + } + + private Optional loadFromFile(File localeFile) { + try { + return Optional.of(Locale.fromFile(localeFile)); + } catch (IOException e) { + logger.warn("Failed to read locale file at " + localeFile.getAbsolutePath() + ", " + e.toString()); + logger.warn("Using Default Locale as a fallback (EN)"); + } + return Optional.empty(); } @Override diff --git a/Plan/src/main/java/com/djrapitops/plan/system/locale/lang/CmdHelpLang.java b/Plan/src/main/java/com/djrapitops/plan/system/locale/lang/CmdHelpLang.java index 4a4826f7d..58bb8d167 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/locale/lang/CmdHelpLang.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/locale/lang/CmdHelpLang.java @@ -23,7 +23,6 @@ public enum CmdHelpLang implements Lang { SETUP("Command Help - /planbungee setup", "Toggle set-up mode"), CON("Command Help - /planbungee con", "Debug Bungee-Server connections"), DISABLE("Command Help - /planbungee disable", "Disable the plugin temporarily"), - UPDATE("Command Help - /plan update", "Get change log link or update plugin"), MANAGE_MOVE("Command Help - /plan manage move", "Move data between Databases"), MANAGE_BACKUP("Command Help - /plan manage backup", "Backup a Database"), diff --git a/Plan/src/main/java/com/djrapitops/plan/system/locale/lang/CommandLang.java b/Plan/src/main/java/com/djrapitops/plan/system/locale/lang/CommandLang.java index ec729794e..bbc5c99da 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/locale/lang/CommandLang.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/locale/lang/CommandLang.java @@ -67,17 +67,6 @@ public enum CommandLang implements Lang { DISABLE_DISABLED("Cmd Disable - Disabled", "§aPlan systems are now disabled. You can still use /planbungee reload to restart the plugin."), - UPDATE_WRONG_URL("Cmd Update - Url mismatch", "§cVersion download url did not start with ${0} and might not be trusted. You can download this version manually here (Direct download):"), - UPDATE_CHANGE_LOG("Cmd Update - Change log", "Change Log v${0}:"), - UPDATE_CANCEL_SUCCESS("Cmd Update - Cancel Success", "§aCancel operation performed."), - UPDATE_NOTIFY_CANCEL("Cmd Update - Notify Cancel", "§aYou can cancel the update on servers that haven't rebooted yet with /plan update cancel."), - UPDATE_ONLINE_CHECK("Cmd Update - Online Check", "Checking that all servers are online.."), - UPDATE_FAIL_NOT_ONLINE("Cmd Update - Fail Not Online", "§cNot all servers were online or accessible, you can still update available servers using /plan update -u -force"), - UPDATE_SCHEDULED("Cmd Update - Scheduled", "§a${0} scheduled for update."), - UPDATE_FAIL_FORCED("Cmd Update - Fail Force Notify", "§e${0} failed to update, -force specified, continuing update."), - UPDATE_FAIL_CANCEL("Cmd Update - Fail Cacnel", "§cUpdate failed on a server, cancelling update on all servers.."), - UPDATE_CANCELLED("Cmd Update - Cancelled", "§cUpdate cancelled."), - RELOAD_COMPLETE("Cmd Info - Reload Complete", "§aReload Complete"), RELOAD_FAILED("Cmd Info - Reload Failed", "§cSomething went wrong during reload of the plugin, a restart is recommended."); diff --git a/Plan/src/main/java/com/djrapitops/plan/system/locale/lang/DeepHelpLang.java b/Plan/src/main/java/com/djrapitops/plan/system/locale/lang/DeepHelpLang.java index 04c3564f9..5cee598da 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/locale/lang/DeepHelpLang.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/locale/lang/DeepHelpLang.java @@ -18,7 +18,6 @@ public enum DeepHelpLang implements Lang { QINSPECT("In Depth Help - /plan qinspect ?", "> §2Quick Inspect Command\\ Displays some information about the player in game."), RELOAD("In Depth Help - /plan reload ?", "> §2Reload Command\\ Restarts the plugin using onDisable and onEnable.\\ §bDoes not support swapping jar on the fly"), SEARCH("In Depth Help - /plan search ?", "> §2Search Command\\ Get a list of Player names that match the given argument.\\§7 Example: /plan search 123 - Finds all users with 123 in their name."), - UPDATE("In Depth Help - /plan update ?", "> §2Update Command\\ Used to update the plugin on the next shutdown\\ /plan update - Changelog link\\ /plan update -u - Schedule update to happen on all network servers that are online, next time they reboot.\\ /plan update cancel - Cancel scheduled update on servers that haven't rebooted yet."), WEB("In Depth Help - /plan web ?", "< §2Web User Manage Command.\\ §2/plan web §fList subcommands\\ §2/plan web ? §fIn Depth help"), MANAGE_BACKUP("In Depth Help - /plan manage backup ?", "> §2Backup Subcommand\\ Creates a new SQLite database (.db file) with contents of currently active database in the Plan plugin folder."), diff --git a/Plan/src/main/java/com/djrapitops/plan/system/locale/lang/GenericLang.java b/Plan/src/main/java/com/djrapitops/plan/system/locale/lang/GenericLang.java index b6ef6a87e..634d2296e 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/locale/lang/GenericLang.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/locale/lang/GenericLang.java @@ -8,7 +8,9 @@ package com.djrapitops.plan.system.locale.lang; public enum GenericLang implements Lang { YES("Positive", "Yes"), NO("Negative", "No"), - UNKNOWN("Unknown", "Unknown"); + UNKNOWN("Unknown", "Unknown"), + TODAY("Today", "'Today'"), + YESTERDAY("Yesterday", "'Yesterday'"); private final String identifier; private final String defaultValue; diff --git a/Plan/src/main/java/com/djrapitops/plan/system/locale/lang/HealthInfoLang.java b/Plan/src/main/java/com/djrapitops/plan/system/locale/lang/HealthInfoLang.java new file mode 100644 index 000000000..23d67e5ee --- /dev/null +++ b/Plan/src/main/java/com/djrapitops/plan/system/locale/lang/HealthInfoLang.java @@ -0,0 +1,45 @@ +package com.djrapitops.plan.system.locale.lang; + +/** + * {@link Lang} enum for {@link com.djrapitops.plan.data.store.mutators.health.AbstractHealthInfo} related language. + * + * @author Rsl1122 + */ +public enum HealthInfoLang implements Lang { + REGULAR_ACTIVITY_REMAIN("Regular Activity Remain", " ${0} of regular players have remained active (${1}/${2})"), + REGULAR_CHANGE("Regular Activity Change", " Number of regular players has "), + REGULAR_CHANGE_INCREASE("Regular Activity Change Increase", "increased (+${0})"), + REGULAR_CHANGE_ZERO("Regular Activity Change Zero", "stayed the same (+${0})"), + REGULAR_CHANGE_DECREASE("Regular Activity Change Decrease", "decreased (${0})"), + ACTIVE_PLAY_COMPARISON_INCREASE("Active Playtime Comparison Increase", " Active players seem to have things to do (Played ${0} vs ${1}, last two weeks vs weeks 2-4)"), + ACTIVE_PLAY_COMPARISON_DECREASE("Active Playtime Comparison Decrease", " Active players might be running out of things to do (Played ${0} vs ${1}, last two weeks vs weeks 2-4)"), + NEW_PLAYER_JOIN_PLAYERS_GOOD("New Player Join Players, Yes", " New Players have players to play with when they join (${0} on average)"), + NEW_PLAYER_JOIN_PLAYERS_BAD("New Player Join Players, No", " New Players may not have players to play with when they join (${0} on average)"), + NEW_PLAYER_STICKINESS("New Player Stickiness", " ${0} of new players have stuck around (${1}/${2})"), + TPS_ABOVE_LOW_THERSHOLD("TPS Above Low Threshold", " Average TPS was above Low Threshold ${0} of the time"), + TPS_LOW_DIPS("TPS Low Dips", " Average TPS dropped below Low Threshold (${0}) ${1} times"), + DOWNTIME("Downtime", "Total Server downtime (No Data) was ${0}"), + NO_SERVERS_INACCURACY("No Servers Inaccuracy", " No Bukkit/Sponge servers to gather session data - These measures are inaccurate."), + SINGLE_SERVER_INACCURACY("Single Servers Inaccuracy", " Single Bukkit/Sponge server to gather session data."), + PLAYER_VISIT_PER_SERVER("Player Visit Server", " players visit on servers per day/server on average."), + PLAYER_REGISTER_PER_SERVER("Player Register Server", " players register on servers per day/server on average."), + PLAYER_PLAY_ON_NETWORK("Player Play on Network", " players played on the network:"); + + private final String identifier; + private final String defaultValue; + + HealthInfoLang(String identifier, String defaultValue) { + this.identifier = identifier; + this.defaultValue = defaultValue; + } + + @Override + public String getIdentifier() { + return "Health - " + identifier; + } + + @Override + public String getDefault() { + return defaultValue; + } +} \ No newline at end of file diff --git a/Plan/src/main/java/com/djrapitops/plan/system/locale/lang/ServerPageLang.java b/Plan/src/main/java/com/djrapitops/plan/system/locale/lang/ServerPageLang.java index 435f97f00..a6238f068 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/locale/lang/ServerPageLang.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/locale/lang/ServerPageLang.java @@ -51,7 +51,10 @@ public enum ServerPageLang implements Lang { USED_COMMANDS("Used Commands"), UNIQUE_TEXT("Unique"), COMMAND(" Command"), - TIMES_USED("Times Used"); + TIMES_USED("Times Used"), + FREE_DISK_SPACE("Free Disk Space"), + DISK_SPACE("DISK SPACE"), + ; private final String defaultValue; diff --git a/Plan/src/main/java/com/djrapitops/plan/system/processing/Processing.java b/Plan/src/main/java/com/djrapitops/plan/system/processing/Processing.java index ce9e9df9a..75091b733 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/processing/Processing.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/processing/Processing.java @@ -1,37 +1,44 @@ package com.djrapitops.plan.system.processing; -import com.djrapitops.plan.PlanPlugin; import com.djrapitops.plan.api.exceptions.EnableException; -import com.djrapitops.plan.system.PlanSystem; import com.djrapitops.plan.system.SubSystem; import com.djrapitops.plan.system.locale.Locale; import com.djrapitops.plan.system.locale.lang.PluginLang; -import com.djrapitops.plugin.StaticHolder; -import com.djrapitops.plugin.api.utility.log.Log; -import com.djrapitops.plugin.utilities.Verify; +import com.djrapitops.plugin.logging.L; +import com.djrapitops.plugin.logging.console.PluginLogger; +import com.djrapitops.plugin.logging.error.ErrorHandler; import com.google.common.util.concurrent.ThreadFactoryBuilder; +import dagger.Lazy; +import javax.inject.Inject; +import javax.inject.Singleton; import java.util.List; import java.util.concurrent.*; -import java.util.function.Supplier; +@Singleton public class Processing implements SubSystem { - private final Supplier locale; + private final Lazy locale; + private final PluginLogger logger; + private final ErrorHandler errorHandler; private final ExecutorService nonCriticalExecutor; private final ExecutorService criticalExecutor; - public Processing(Supplier locale) { + @Inject + public Processing( + Lazy locale, + PluginLogger logger, + ErrorHandler errorHandler + ) { this.locale = locale; + this.logger = logger; + this.errorHandler = errorHandler; nonCriticalExecutor = Executors.newFixedThreadPool(6, new ThreadFactoryBuilder().setNameFormat("Plan Non critical-pool-%d").build()); criticalExecutor = Executors.newFixedThreadPool(2, new ThreadFactoryBuilder().setNameFormat("Plan Critical-pool-%d").build()); - saveInstance(nonCriticalExecutor); - saveInstance(criticalExecutor); - saveInstance(this); } - public static void submit(Runnable runnable) { + public void submit(Runnable runnable) { if (runnable instanceof CriticalRunnable) { submitCritical(runnable); return; @@ -39,54 +46,32 @@ public class Processing implements SubSystem { submitNonCritical(runnable); } - public static void saveInstance(Object obj) { - StaticHolder.saveInstance(obj.getClass(), PlanPlugin.getInstance().getClass()); - } - - public static void submitNonCritical(Runnable runnable) { - saveInstance(runnable); - ExecutorService executor = getInstance().nonCriticalExecutor; - if (executor.isShutdown()) { + public void submitNonCritical(Runnable runnable) { + if (nonCriticalExecutor.isShutdown()) { return; } CompletableFuture.supplyAsync(() -> { runnable.run(); return true; - }, executor).handle(Processing::exceptionHandler); + }, nonCriticalExecutor).handle(this::exceptionHandlerNonCritical); } - public static void submitCritical(Runnable runnable) { - saveInstance(runnable); + public void submitCritical(Runnable runnable) { CompletableFuture.supplyAsync(() -> { runnable.run(); return true; - }, getInstance().criticalExecutor).handle(Processing::exceptionHandler); + }, criticalExecutor).handle(this::exceptionHandlerCritical); } - public static void submitNonCritical(Runnable... runnables) { - for (Runnable runnable : runnables) { - submitNonCritical(runnable); - } - } - - public static void submitCritical(Runnable... runnables) { - for (Runnable runnable : runnables) { - submitCritical(runnable); - } - } - - public static Future submit(Callable task) { - saveInstance(task); + public Future submit(Callable task) { if (task instanceof CriticalCallable) { return submitCritical(task); } return submitNonCritical(task); } - public static Future submitNonCritical(Callable task) { - saveInstance(task); - ExecutorService executor = getInstance().nonCriticalExecutor; - if (executor.isShutdown()) { + public Future submitNonCritical(Callable task) { + if (nonCriticalExecutor.isShutdown()) { return null; } return CompletableFuture.supplyAsync(() -> { @@ -95,31 +80,31 @@ public class Processing implements SubSystem { } catch (Exception e) { throw new IllegalStateException(e); } - }, getInstance().nonCriticalExecutor).handle(Processing::exceptionHandler); + }, nonCriticalExecutor).handle(this::exceptionHandlerNonCritical); } - private static T exceptionHandler(T t, Throwable throwable) { + private T exceptionHandlerNonCritical(T t, Throwable throwable) { if (throwable != null) { - Log.toLog(Processing.class, throwable.getCause()); + errorHandler.log(L.WARN, Processing.class, throwable.getCause()); } return t; } - public static Future submitCritical(Callable task) { - saveInstance(task); + private T exceptionHandlerCritical(T t, Throwable throwable) { + if (throwable != null) { + errorHandler.log(L.ERROR, Processing.class, throwable.getCause()); + } + return t; + } + + public Future submitCritical(Callable task) { return CompletableFuture.supplyAsync(() -> { try { return task.call(); } catch (Exception e) { throw new IllegalStateException(e); } - }, getInstance().criticalExecutor).handle(Processing::exceptionHandler); - } - - public static Processing getInstance() { - Processing processing = PlanSystem.getInstance().getProcessing(); - Verify.nullCheck(processing, () -> new IllegalStateException("Processing System has not been initialized.")); - return processing; + }, criticalExecutor).handle(this::exceptionHandlerCritical); } @Override @@ -136,12 +121,12 @@ public class Processing implements SubSystem { public void disable() { nonCriticalExecutor.shutdown(); List criticalTasks = criticalExecutor.shutdownNow(); - Log.info(locale.get().getString(PluginLang.DISABLED_PROCESSING, criticalTasks.size())); + logger.info(locale.get().getString(PluginLang.DISABLED_PROCESSING, criticalTasks.size())); for (Runnable runnable : criticalTasks) { try { runnable.run(); } catch (Exception | NoClassDefFoundError | NoSuchMethodError | NoSuchFieldError e) { - Log.toLog(this.getClass(), e); + errorHandler.log(L.WARN, this.getClass(), e); } } if (!nonCriticalExecutor.isTerminated()) { @@ -154,6 +139,6 @@ public class Processing implements SubSystem { if (!criticalExecutor.isTerminated()) { criticalExecutor.shutdownNow(); } - Log.info(locale.get().getString(PluginLang.DISABLED_PROCESSING_COMPLETE)); + logger.info(locale.get().getString(PluginLang.DISABLED_PROCESSING_COMPLETE)); } } diff --git a/Plan/src/main/java/com/djrapitops/plan/system/processing/importing/ImporterManager.java b/Plan/src/main/java/com/djrapitops/plan/system/processing/importing/ImporterManager.java deleted file mode 100644 index f2dd34b9e..000000000 --- a/Plan/src/main/java/com/djrapitops/plan/system/processing/importing/ImporterManager.java +++ /dev/null @@ -1,58 +0,0 @@ -/* - * License is provided in the jar as LICENSE also here: - * https://github.com/Rsl1122/Plan-PlayerAnalytics/blob/master/Plan/src/main/resources/LICENSE - */ -package com.djrapitops.plan.system.processing.importing; - -import com.djrapitops.plan.system.processing.importing.importers.Importer; - -import java.util.ArrayList; -import java.util.List; - -/** - * @author Fuzzlemann - */ -public class ImporterManager { - - private static final List registry = new ArrayList<>(); - - /** - * Constructor used to hide the public constructor - */ - private ImporterManager() { - throw new IllegalStateException("Utility class"); - } - - public static void registerImporter(Importer importer) { - if (importer == null) { - throw new NullPointerException("Importer cannot be null"); - } - - String firstName = importer.getNames().get(0); - - if (firstName == null) { - throw new IllegalArgumentException("No Importer name given"); - } - - if (getImporter(firstName) != null) { - removeImporter(firstName); - } - - registry.add(importer); - } - - public static List getImporters() { - return registry; - } - - public static Importer getImporter(String name) { - return registry.stream() - .filter(importer -> importer.getNames().contains(name)) - .findAny() - .orElse(null); - } - - public static void removeImporter(String name) { - registry.removeIf(importer -> importer.getNames().contains(name)); - } -} diff --git a/Plan/src/main/java/com/djrapitops/plan/system/processing/processors/CommandProcessor.java b/Plan/src/main/java/com/djrapitops/plan/system/processing/processors/CommandProcessor.java index 4c6b0c468..c4a4bf744 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/processing/processors/CommandProcessor.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/processing/processors/CommandProcessor.java @@ -16,12 +16,15 @@ public class CommandProcessor implements CriticalRunnable { private final String command; - public CommandProcessor(String command) { + private final Database database; + + CommandProcessor(String command, Database database) { this.command = command; + this.database = database; } @Override public void run() { - Database.getActive().save().commandUsed(command); + database.save().commandUsed(command); } } diff --git a/Plan/src/main/java/com/djrapitops/plan/system/processing/processors/Processors.java b/Plan/src/main/java/com/djrapitops/plan/system/processing/processors/Processors.java new file mode 100644 index 000000000..fb0d46dca --- /dev/null +++ b/Plan/src/main/java/com/djrapitops/plan/system/processing/processors/Processors.java @@ -0,0 +1,53 @@ +package com.djrapitops.plan.system.processing.processors; + +import com.djrapitops.plan.data.container.TPS; +import com.djrapitops.plan.system.database.DBSystem; +import com.djrapitops.plan.system.processing.processors.info.InfoProcessors; +import com.djrapitops.plan.system.processing.processors.player.PlayerProcessors; +import dagger.Lazy; + +import javax.inject.Inject; +import javax.inject.Singleton; +import java.util.List; + +/** + * Factory for creating Runnables to run with {@link com.djrapitops.plan.system.processing.Processing}. + * + * @author Rsl1122 + */ +@Singleton +public class Processors { + + private final PlayerProcessors playerProcessors; + private final InfoProcessors infoProcessors; + + private final Lazy dbSystem; + + @Inject + public Processors( + PlayerProcessors playerProcessors, + InfoProcessors infoProcessors, + + Lazy dbSystem + ) { + this.playerProcessors = playerProcessors; + this.infoProcessors = infoProcessors; + this.dbSystem = dbSystem; + } + + public TPSInsertProcessor tpsInsertProcessor(List tpsList) { + return new TPSInsertProcessor(tpsList, dbSystem.get().getDatabase()); + } + + public CommandProcessor commandProcessor(String command) { + return new CommandProcessor(command, dbSystem.get().getDatabase()); + } + + public PlayerProcessors player() { + return playerProcessors; + } + + public InfoProcessors info() { + return infoProcessors; + } +} \ No newline at end of file diff --git a/Plan/src/main/java/com/djrapitops/plan/system/processing/processors/TPSInsertProcessor.java b/Plan/src/main/java/com/djrapitops/plan/system/processing/processors/TPSInsertProcessor.java index 041f24344..828075398 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/processing/processors/TPSInsertProcessor.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/processing/processors/TPSInsertProcessor.java @@ -20,20 +20,24 @@ public class TPSInsertProcessor implements CriticalRunnable { private final List tpsList; - public TPSInsertProcessor(List tpsList) { + private final Database database; + + TPSInsertProcessor(List tpsList, Database database) { this.tpsList = tpsList; + this.database = database; } @Override public void run() { List history = tpsList; - final long lastDate = history.get(history.size() - 1).getDate(); - final double averageTPS = history.stream().mapToDouble(TPS::getTicksPerSecond).average().orElse(0); - final int peakPlayersOnline = history.stream().mapToInt(TPS::getPlayers).max().orElse(0); - final double averageCPUUsage = history.stream().mapToDouble(TPS::getCPUUsage).average().orElse(0); - final long averageUsedMemory = (long) history.stream().mapToLong(TPS::getUsedMemory).average().orElse(0); - final int averageEntityCount = (int) history.stream().mapToInt(TPS::getEntityCount).average().orElse(0); - final int averageChunksLoaded = (int) history.stream().mapToInt(TPS::getChunksLoaded).average().orElse(0); + long lastDate = history.get(history.size() - 1).getDate(); + double averageTPS = history.stream().mapToDouble(TPS::getTicksPerSecond).average().orElse(0); + int peakPlayersOnline = history.stream().mapToInt(TPS::getPlayers).max().orElse(0); + double averageCPUUsage = history.stream().mapToDouble(TPS::getCPUUsage).average().orElse(0); + long averageUsedMemory = (long) history.stream().mapToLong(TPS::getUsedMemory).average().orElse(0); + int averageEntityCount = (int) history.stream().mapToInt(TPS::getEntityCount).average().orElse(0); + int averageChunksLoaded = (int) history.stream().mapToInt(TPS::getChunksLoaded).average().orElse(0); + long freeDiskSpace = (long) history.stream().mapToLong(TPS::getFreeDiskSpace).average().orElse(0); TPS tps = TPSBuilder.get() .date(lastDate) @@ -43,8 +47,9 @@ public class TPSInsertProcessor implements CriticalRunnable { .usedMemory(averageUsedMemory) .entities(averageEntityCount) .chunksLoaded(averageChunksLoaded) + .freeDiskSpace(freeDiskSpace) .toTPS(); - Database.getActive().save().insertTPSforThisServer(tps); + database.save().insertTPSforThisServer(tps); } } diff --git a/Plan/src/main/java/com/djrapitops/plan/system/processing/processors/info/InfoProcessors.java b/Plan/src/main/java/com/djrapitops/plan/system/processing/processors/info/InfoProcessors.java new file mode 100644 index 000000000..d3a21a392 --- /dev/null +++ b/Plan/src/main/java/com/djrapitops/plan/system/processing/processors/info/InfoProcessors.java @@ -0,0 +1,47 @@ +package com.djrapitops.plan.system.processing.processors.info; + +import com.djrapitops.plan.system.info.InfoSystem; +import com.djrapitops.plan.system.info.connection.WebExceptionLogger; +import com.djrapitops.plugin.command.Sender; +import dagger.Lazy; + +import javax.inject.Inject; +import javax.inject.Singleton; +import java.util.UUID; +import java.util.function.BiConsumer; + +/** + * Factory for creating Runnables related to {@link InfoSystem} to run with {@link com.djrapitops.plan.system.processing.Processing}. + * + * @author Rsl1122 + */ +@Singleton +public class InfoProcessors { + + private final Lazy infoSystem; + private final Lazy webExceptionLogger; + + @Inject + public InfoProcessors( + Lazy infoSystem, + Lazy webExceptionLogger + ) { + this.infoSystem = infoSystem; + this.webExceptionLogger = webExceptionLogger; + } + + public InspectCacheRequestProcessor inspectCacheRequestProcessor( + UUID uuid, + Sender sender, + String playerName, + BiConsumer msgSender + ) { + return new InspectCacheRequestProcessor(uuid, sender, playerName, msgSender, + infoSystem.get(), webExceptionLogger.get() + ); + } + + public PlayerPageUpdateProcessor playerPageUpdateProcessor(UUID uuid) { + return new PlayerPageUpdateProcessor(uuid); + } +} \ No newline at end of file diff --git a/Plan/src/main/java/com/djrapitops/plan/system/processing/processors/info/InspectCacheRequestProcessor.java b/Plan/src/main/java/com/djrapitops/plan/system/processing/processors/info/InspectCacheRequestProcessor.java index 5e593a688..ad7db0ccb 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/processing/processors/info/InspectCacheRequestProcessor.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/processing/processors/info/InspectCacheRequestProcessor.java @@ -7,14 +7,11 @@ package com.djrapitops.plan.system.processing.processors.info; import com.djrapitops.plan.api.exceptions.connection.*; import com.djrapitops.plan.system.cache.SessionCache; import com.djrapitops.plan.system.info.InfoSystem; -import com.djrapitops.plan.system.info.connection.ConnectionSystem; -import com.djrapitops.plan.system.locale.Locale; -import com.djrapitops.plan.system.locale.lang.CommandLang; -import com.djrapitops.plugin.api.utility.log.Log; -import com.djrapitops.plugin.command.CommandUtils; -import com.djrapitops.plugin.command.ISender; +import com.djrapitops.plan.system.info.connection.WebExceptionLogger; +import com.djrapitops.plugin.command.Sender; import java.util.UUID; +import java.util.function.BiConsumer; /** * Sends a request to cache players inspect page to the ResponseCache on the appropriate WebServer. @@ -24,45 +21,40 @@ import java.util.UUID; public class InspectCacheRequestProcessor implements Runnable { private final UUID uuid; - private final ISender sender; + private final Sender sender; private final String playerName; - private final Locale locale; + private final BiConsumer msgSender; - public InspectCacheRequestProcessor(UUID uuid, ISender sender, String playerName, Locale locale) { + private final InfoSystem infoSystem; + private final WebExceptionLogger webExceptionLogger; + + InspectCacheRequestProcessor( + UUID uuid, + Sender sender, + String playerName, + BiConsumer msgSender, + InfoSystem infoSystem, + WebExceptionLogger webExceptionLogger + ) { this.uuid = uuid; this.sender = sender; this.playerName = playerName; - this.locale = locale; + this.msgSender = msgSender; + this.infoSystem = infoSystem; + this.webExceptionLogger = webExceptionLogger; } @Override public void run() { SessionCache.refreshActiveSessionsState(); - try { - InfoSystem.getInstance().generateAndCachePlayerPage(uuid); - sendInspectMsg(sender, playerName); - } catch (ConnectionFailException | UnsupportedTransferDatabaseException | UnauthorizedServerException - | NotFoundException | NoServersException e) { - sender.sendMessage("§c" + e.getMessage()); - } catch (WebException e) { - Log.toLog(this.getClass(), e); - } - } - - // TODO Move to InspectCommand somehow. - private void sendInspectMsg(ISender sender, String playerName) { - sender.sendMessage(locale.getString(CommandLang.HEADER_INSPECT, playerName)); - // Link - String url = ConnectionSystem.getInstance().getMainAddress() + "/player/" + playerName; - String linkPrefix = locale.getString(CommandLang.LINK_PREFIX); - boolean console = !CommandUtils.isPlayer(sender); - if (console) { - sender.sendMessage(linkPrefix + url); - } else { - sender.sendMessage(linkPrefix); - sender.sendLink(" ", locale.getString(CommandLang.LINK_CLICK_ME), url); - } - - sender.sendMessage(">"); + webExceptionLogger.logIfOccurs(this.getClass(), () -> { + try { + infoSystem.generateAndCachePlayerPage(uuid); + msgSender.accept(sender, playerName); + } catch (ConnectionFailException | UnsupportedTransferDatabaseException | UnauthorizedServerException + | NotFoundException | NoServersException e) { + sender.sendMessage("§c" + e.getMessage()); + } + }); } } diff --git a/Plan/src/main/java/com/djrapitops/plan/system/processing/processors/info/NetworkPageUpdateProcessor.java b/Plan/src/main/java/com/djrapitops/plan/system/processing/processors/info/NetworkPageUpdateProcessor.java deleted file mode 100644 index 244f70f3d..000000000 --- a/Plan/src/main/java/com/djrapitops/plan/system/processing/processors/info/NetworkPageUpdateProcessor.java +++ /dev/null @@ -1,26 +0,0 @@ -/* - * License is provided in the jar as LICENSE also here: - * https://github.com/Rsl1122/Plan-PlayerAnalytics/blob/master/Plan/src/main/resources/LICENSE - */ -package com.djrapitops.plan.system.processing.processors.info; - -import com.djrapitops.plan.api.exceptions.connection.WebException; -import com.djrapitops.plan.system.info.InfoSystem; -import com.djrapitops.plugin.api.utility.log.Log; - -/** - * Processor for updating the network page. - * - * @author Rsl1122 - */ -public class NetworkPageUpdateProcessor implements Runnable { - - @Override - public void run() { - try { - InfoSystem.getInstance().updateNetworkPage(); - } catch (WebException e) { - Log.toLog(this.getClass(), e); - } - } -} diff --git a/Plan/src/main/java/com/djrapitops/plan/system/processing/processors/info/PlayerPageUpdateProcessor.java b/Plan/src/main/java/com/djrapitops/plan/system/processing/processors/info/PlayerPageUpdateProcessor.java index 8081c66bd..10fa5745d 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/processing/processors/info/PlayerPageUpdateProcessor.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/processing/processors/info/PlayerPageUpdateProcessor.java @@ -9,7 +9,9 @@ public class PlayerPageUpdateProcessor implements Runnable { private final UUID uuid; - public PlayerPageUpdateProcessor(UUID uuid) { + PlayerPageUpdateProcessor( + UUID uuid + ) { this.uuid = uuid; } diff --git a/Plan/src/main/java/com/djrapitops/plan/system/processing/processors/player/BanAndOpProcessor.java b/Plan/src/main/java/com/djrapitops/plan/system/processing/processors/player/BanAndOpProcessor.java index cd5c28777..27d6589c6 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/processing/processors/player/BanAndOpProcessor.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/processing/processors/player/BanAndOpProcessor.java @@ -21,15 +21,21 @@ public class BanAndOpProcessor implements Runnable { private final Supplier banned; private final boolean op; - public BanAndOpProcessor(UUID uuid, Supplier banned, boolean op) { + private final Database database; + + BanAndOpProcessor( + UUID uuid, Supplier banned, boolean op, + Database database + ) { this.uuid = uuid; this.banned = banned; this.op = op; + this.database = database; } @Override public void run() { - SaveOperations save = Database.getActive().save(); + SaveOperations save = database.save(); save.banStatus(uuid, banned.get()); save.opStatus(uuid, op); } diff --git a/Plan/src/main/java/com/djrapitops/plan/system/processing/processors/player/EndSessionProcessor.java b/Plan/src/main/java/com/djrapitops/plan/system/processing/processors/player/EndSessionProcessor.java index 908724914..48d8be5f1 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/processing/processors/player/EndSessionProcessor.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/processing/processors/player/EndSessionProcessor.java @@ -19,13 +19,16 @@ public class EndSessionProcessor implements CriticalRunnable { private final UUID uuid; private final long time; - public EndSessionProcessor(UUID uuid, long time) { + private final SessionCache sessionCache; + + EndSessionProcessor(UUID uuid, long time, SessionCache sessionCache) { this.uuid = uuid; this.time = time; + this.sessionCache = sessionCache; } @Override public void run() { - SessionCache.getInstance().endSession(uuid, time); + sessionCache.endSession(uuid, time); } } diff --git a/Plan/src/main/java/com/djrapitops/plan/system/processing/processors/player/IPUpdateProcessor.java b/Plan/src/main/java/com/djrapitops/plan/system/processing/processors/player/IPUpdateProcessor.java index 895202631..525679f25 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/processing/processors/player/IPUpdateProcessor.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/processing/processors/player/IPUpdateProcessor.java @@ -8,8 +8,6 @@ import com.djrapitops.plan.data.container.GeoInfo; import com.djrapitops.plan.system.cache.GeolocationCache; import com.djrapitops.plan.system.database.databases.Database; import com.djrapitops.plan.system.processing.CriticalRunnable; -import com.djrapitops.plan.system.settings.Settings; -import com.djrapitops.plugin.api.utility.log.Log; import java.net.InetAddress; import java.security.NoSuchAlgorithmException; @@ -26,22 +24,29 @@ public class IPUpdateProcessor implements CriticalRunnable { private final InetAddress ip; private final long time; - public IPUpdateProcessor(UUID uuid, InetAddress ip, long time) { + private final Database database; + private final GeolocationCache geolocationCache; + + IPUpdateProcessor( + UUID uuid, InetAddress ip, long time, + Database database, + GeolocationCache geolocationCache + ) { this.uuid = uuid; this.ip = ip; this.time = time; + this.database = database; + this.geolocationCache = geolocationCache; } @Override public void run() { - if (Settings.DATA_GEOLOCATIONS.isTrue()) { - String country = GeolocationCache.getCountry(ip.getHostAddress()); - try { - GeoInfo geoInfo = new GeoInfo(ip, country, time); - Database.getActive().save().geoInfo(uuid, geoInfo); - } catch (NoSuchAlgorithmException e) { - Log.toLog(this.getClass(), e); - } + try { + String country = geolocationCache.getCountry(ip.getHostAddress()); + GeoInfo geoInfo = new GeoInfo(ip, country, time); + database.save().geoInfo(uuid, geoInfo); + } catch (NoSuchAlgorithmException ignore) { + // Ignored, SHA-256 should be available } } } diff --git a/Plan/src/main/java/com/djrapitops/plan/system/processing/processors/player/KickProcessor.java b/Plan/src/main/java/com/djrapitops/plan/system/processing/processors/player/KickProcessor.java index 587b71cec..67a2a8a8b 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/processing/processors/player/KickProcessor.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/processing/processors/player/KickProcessor.java @@ -18,12 +18,15 @@ public class KickProcessor implements CriticalRunnable { private final UUID uuid; - public KickProcessor(UUID uuid) { + private final Database database; + + KickProcessor(UUID uuid, Database database) { this.uuid = uuid; + this.database = database; } @Override public void run() { - Database.getActive().save().playerWasKicked(uuid); + database.save().playerWasKicked(uuid); } } diff --git a/Plan/src/main/java/com/djrapitops/plan/system/processing/processors/player/KillProcessor.java b/Plan/src/main/java/com/djrapitops/plan/system/processing/processors/player/MobKillProcessor.java similarity index 50% rename from Plan/src/main/java/com/djrapitops/plan/system/processing/processors/player/KillProcessor.java rename to Plan/src/main/java/com/djrapitops/plan/system/processing/processors/player/MobKillProcessor.java index da9b6b737..1cdfc4cf2 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/processing/processors/player/KillProcessor.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/processing/processors/player/MobKillProcessor.java @@ -1,11 +1,8 @@ package com.djrapitops.plan.system.processing.processors.player; -import com.djrapitops.plan.data.container.PlayerKill; import com.djrapitops.plan.data.container.Session; import com.djrapitops.plan.system.cache.SessionCache; import com.djrapitops.plan.system.processing.CriticalRunnable; -import org.bukkit.entity.LivingEntity; -import org.bukkit.entity.Player; import java.util.Optional; import java.util.UUID; @@ -19,26 +16,17 @@ import java.util.UUID; * @author Rsl1122 * @since 4.0.0 */ -public class KillProcessor implements CriticalRunnable { +public class MobKillProcessor implements CriticalRunnable { private final UUID uuid; - private final LivingEntity dead; - private final String weaponName; - private final long time; /** * Constructor. * * @param uuid UUID of the killer. - * @param time Epoch ms the event occurred. - * @param dead Dead entity (Mob or Player) - * @param weaponName Weapon used. */ - public KillProcessor(UUID uuid, long time, LivingEntity dead, String weaponName) { + public MobKillProcessor(UUID uuid) { this.uuid = uuid; - this.time = time; - this.dead = dead; - this.weaponName = weaponName; } @Override @@ -49,11 +37,6 @@ public class KillProcessor implements CriticalRunnable { } Session session = cachedSession.get(); - if (dead instanceof Player) { - Player deadPlayer = (Player) dead; - session.playerKilled(new PlayerKill(deadPlayer.getUniqueId(), weaponName, time)); - } else { - session.mobKilled(); - } + session.mobKilled(); } } diff --git a/Plan/src/main/java/com/djrapitops/plan/system/processing/processors/player/NameProcessor.java b/Plan/src/main/java/com/djrapitops/plan/system/processing/processors/player/NameProcessor.java index b84b4a8fb..a0522f850 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/processing/processors/player/NameProcessor.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/processing/processors/player/NameProcessor.java @@ -7,7 +7,7 @@ package com.djrapitops.plan.system.processing.processors.player; import com.djrapitops.plan.data.store.objects.Nickname; import com.djrapitops.plan.system.cache.DataCache; import com.djrapitops.plan.system.database.databases.Database; -import com.djrapitops.plan.system.info.server.ServerInfo; +import com.djrapitops.plan.system.database.databases.operation.SaveOperations; import com.djrapitops.plan.system.processing.CriticalRunnable; import java.util.UUID; @@ -24,15 +24,23 @@ public class NameProcessor implements CriticalRunnable { private final String playerName; private final Nickname nickname; - public NameProcessor(UUID uuid, String playerName, String displayName) { + private final Database database; + private final DataCache dataCache; + + NameProcessor( + UUID uuid, String playerName, Nickname nickname, + Database database, + DataCache dataCache + ) { this.uuid = uuid; this.playerName = playerName; - this.nickname = new Nickname(displayName, System.currentTimeMillis(), ServerInfo.getServerUUID()); + this.nickname = nickname; + this.database = database; + this.dataCache = dataCache; } @Override public void run() { - DataCache dataCache = DataCache.getInstance(); String cachedName = dataCache.getName(uuid); String cachedDisplayName = dataCache.getDisplayName(uuid); @@ -43,9 +51,8 @@ public class NameProcessor implements CriticalRunnable { dataCache.updateNames(uuid, playerName, nickname.getName()); - Database database = Database.getActive(); - database.save().playerName(uuid, playerName); - - database.save().playerDisplayName(uuid, nickname); + SaveOperations save = database.save(); + save.playerName(uuid, playerName); + save.playerDisplayName(uuid, nickname); } } diff --git a/Plan/src/main/java/com/djrapitops/plan/system/processing/processors/player/PingInsertProcessor.java b/Plan/src/main/java/com/djrapitops/plan/system/processing/processors/player/PingInsertProcessor.java index abc1d6702..077f1afbb 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/processing/processors/player/PingInsertProcessor.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/processing/processors/player/PingInsertProcessor.java @@ -7,7 +7,6 @@ package com.djrapitops.plan.system.processing.processors.player; import com.djrapitops.plan.data.container.Ping; import com.djrapitops.plan.data.store.objects.DateObj; import com.djrapitops.plan.system.database.databases.Database; -import com.djrapitops.plan.system.info.server.ServerInfo; import com.djrapitops.plan.system.processing.CriticalRunnable; import com.djrapitops.plan.utilities.analysis.Median; @@ -26,11 +25,19 @@ import java.util.stream.Collectors; public class PingInsertProcessor implements CriticalRunnable { private final UUID uuid; + private final UUID serverUUID; private final List> pingList; - public PingInsertProcessor(UUID uuid, List> pingList) { + private final Database database; + + PingInsertProcessor( + UUID uuid, UUID serverUUID, List> pingList, + Database database + ) { this.uuid = uuid; + this.serverUUID = serverUUID; this.pingList = pingList; + this.database = database; } @Override @@ -52,12 +59,9 @@ public class PingInsertProcessor implements CriticalRunnable { int maxValue = max.getAsInt(); - Ping ping = new Ping(lastDate, ServerInfo.getServerUUID(), - minValue, - maxValue, - meanValue); + Ping ping = new Ping(lastDate, serverUUID, minValue, maxValue, meanValue); - Database.getActive().save().ping(uuid, ping); + database.save().ping(uuid, ping); } int getMinValue(List> history) { diff --git a/Plan/src/main/java/com/djrapitops/plan/system/processing/processors/player/SpongeKillProcessor.java b/Plan/src/main/java/com/djrapitops/plan/system/processing/processors/player/PlayerKillProcessor.java similarity index 63% rename from Plan/src/main/java/com/djrapitops/plan/system/processing/processors/player/SpongeKillProcessor.java rename to Plan/src/main/java/com/djrapitops/plan/system/processing/processors/player/PlayerKillProcessor.java index c737e6aa6..e9f19a056 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/processing/processors/player/SpongeKillProcessor.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/processing/processors/player/PlayerKillProcessor.java @@ -15,42 +15,38 @@ import java.util.UUID; * Adds PlayerKill or a Mob kill to the active Session. * * @author Rsl1122 - * @since 4.3.0 + * @since 4.0.0 */ -public class SpongeKillProcessor implements CriticalRunnable { +public class PlayerKillProcessor implements CriticalRunnable { - private final UUID uuid; - private final UUID deadUUID; + private final UUID killer; + private final UUID victim; private final String weaponName; private final long time; /** * Constructor. * - * @param uuid UUID of the killer. + * @param killer UUID of the killer. * @param time Epoch ms the event occurred. - * @param deadUUID Dead entity (Mob or Player) + * @param victim Dead entity (Mob or Player) * @param weaponName Weapon used. */ - public SpongeKillProcessor(UUID uuid, long time, UUID deadUUID, String weaponName) { - this.uuid = uuid; + public PlayerKillProcessor(UUID killer, long time, UUID victim, String weaponName) { + this.killer = killer; this.time = time; - this.deadUUID = deadUUID; + this.victim = victim; this.weaponName = weaponName; } @Override public void run() { - Optional cachedSession = SessionCache.getCachedSession(uuid); + Optional cachedSession = SessionCache.getCachedSession(killer); if (!cachedSession.isPresent()) { return; } Session session = cachedSession.get(); - if (deadUUID != null) { - session.playerKilled(new PlayerKill(deadUUID, weaponName, time)); - } else { - session.mobKilled(); - } + session.playerKilled(new PlayerKill(victim, weaponName, time)); } } diff --git a/Plan/src/main/java/com/djrapitops/plan/system/processing/processors/player/PlayerProcessors.java b/Plan/src/main/java/com/djrapitops/plan/system/processing/processors/player/PlayerProcessors.java new file mode 100644 index 000000000..3059fcdae --- /dev/null +++ b/Plan/src/main/java/com/djrapitops/plan/system/processing/processors/player/PlayerProcessors.java @@ -0,0 +1,81 @@ +package com.djrapitops.plan.system.processing.processors.player; + +import com.djrapitops.plan.data.store.objects.DateObj; +import com.djrapitops.plan.data.store.objects.Nickname; +import com.djrapitops.plan.system.cache.DataCache; +import com.djrapitops.plan.system.cache.GeolocationCache; +import com.djrapitops.plan.system.database.DBSystem; +import com.djrapitops.plan.system.info.server.ServerInfo; +import com.djrapitops.plan.system.processing.Processing; +import dagger.Lazy; + +import javax.inject.Inject; +import javax.inject.Singleton; +import java.net.InetAddress; +import java.util.List; +import java.util.UUID; +import java.util.function.Supplier; + +/** + * Factory for creating Runnables related to Player data to run with {@link com.djrapitops.plan.system.processing.Processing}. + * + * @author Rsl1122 + */ +@Singleton +public class PlayerProcessors { + + private final Lazy processing; + private final Lazy serverInfo; + private final Lazy dbSystem; + private final Lazy dataCache; + private final Lazy geolocationCache; + + @Inject + public PlayerProcessors( + Lazy processing, + Lazy serverInfo, + Lazy dbSystem, + Lazy dataCache, + Lazy geolocationCache + ) { + this.processing = processing; + this.serverInfo = serverInfo; + this.dbSystem = dbSystem; + this.dataCache = dataCache; + this.geolocationCache = geolocationCache; + } + + public BanAndOpProcessor banAndOpProcessor(UUID uuid, Supplier banned, boolean op) { + return new BanAndOpProcessor(uuid, banned, op, dbSystem.get().getDatabase()); + } + + public ProxyRegisterProcessor proxyRegisterProcessor(UUID uuid, String name, long registered, Runnable... afterProcess) { + return new ProxyRegisterProcessor(uuid, name, registered, processing.get(), dbSystem.get().getDatabase(), afterProcess); + } + + public EndSessionProcessor endSessionProcessor(UUID uuid, long time) { + return new EndSessionProcessor(uuid, time, dataCache.get()); + } + + public IPUpdateProcessor ipUpdateProcessor(UUID uuid, InetAddress ip, long time) { + return new IPUpdateProcessor(uuid, ip, time, dbSystem.get().getDatabase(), geolocationCache.get()); + } + + public KickProcessor kickProcessor(UUID uuid) { + return new KickProcessor(uuid, dbSystem.get().getDatabase()); + } + + public NameProcessor nameProcessor(UUID uuid, String playerName, String displayName) { + Nickname nickname = new Nickname(displayName, System.currentTimeMillis(), serverInfo.get().getServerUUID()); + return new NameProcessor(uuid, playerName, nickname, dbSystem.get().getDatabase(), dataCache.get()); + } + + public PingInsertProcessor pingInsertProcessor(UUID uuid, List> pingList) { + return new PingInsertProcessor(uuid, serverInfo.get().getServerUUID(), pingList, dbSystem.get().getDatabase()); + } + + public RegisterProcessor registerProcessor(UUID uuid, Supplier registered, String name, Runnable... afterProcess) { + return new RegisterProcessor(uuid, registered, name, processing.get(), dbSystem.get().getDatabase(), afterProcess); + } + +} \ No newline at end of file diff --git a/Plan/src/main/java/com/djrapitops/plan/system/processing/processors/player/BungeePlayerRegisterProcessor.java b/Plan/src/main/java/com/djrapitops/plan/system/processing/processors/player/ProxyRegisterProcessor.java similarity index 71% rename from Plan/src/main/java/com/djrapitops/plan/system/processing/processors/player/BungeePlayerRegisterProcessor.java rename to Plan/src/main/java/com/djrapitops/plan/system/processing/processors/player/ProxyRegisterProcessor.java index 76fbde5bf..8c8aa4b1b 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/processing/processors/player/BungeePlayerRegisterProcessor.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/processing/processors/player/ProxyRegisterProcessor.java @@ -15,23 +15,32 @@ import java.util.UUID; * * @author Rsl1122 */ -public class BungeePlayerRegisterProcessor implements CriticalRunnable { +public class ProxyRegisterProcessor implements CriticalRunnable { private final UUID uuid; private final String name; private final long registered; private final Runnable[] afterProcess; - public BungeePlayerRegisterProcessor(UUID uuid, String name, long registered, Runnable... afterProcess) { + private final Processing processing; + private final Database database; + + ProxyRegisterProcessor( + UUID uuid, String name, long registered, + Processing processing, + Database database, + Runnable... afterProcess + ) { this.uuid = uuid; this.name = name; this.registered = registered; + this.processing = processing; + this.database = database; this.afterProcess = afterProcess; } @Override public void run() { - Database database = Database.getActive(); try { if (database.check().isPlayerRegistered(uuid)) { return; @@ -39,9 +48,8 @@ public class BungeePlayerRegisterProcessor implements CriticalRunnable { database.save().registerNewUser(uuid, registered, name); } finally { for (Runnable process : afterProcess) { - Processing.submit(process); + processing.submit(process); } - } } } diff --git a/Plan/src/main/java/com/djrapitops/plan/system/processing/processors/player/RegisterProcessor.java b/Plan/src/main/java/com/djrapitops/plan/system/processing/processors/player/RegisterProcessor.java index c0487ebee..20789d3da 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/processing/processors/player/RegisterProcessor.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/processing/processors/player/RegisterProcessor.java @@ -5,6 +5,8 @@ package com.djrapitops.plan.system.processing.processors.player; import com.djrapitops.plan.system.database.databases.Database; +import com.djrapitops.plan.system.database.databases.operation.CheckOperations; +import com.djrapitops.plan.system.database.databases.operation.SaveOperations; import com.djrapitops.plan.system.processing.Processing; import com.djrapitops.plugin.task.AbsRunnable; import com.djrapitops.plugin.utilities.Verify; @@ -24,28 +26,38 @@ public class RegisterProcessor extends AbsRunnable { private final String name; private final Runnable[] afterProcess; - public RegisterProcessor(UUID uuid, Supplier registered, String name, Runnable... afterProcess) { - super(RegisterProcessor.class.getSimpleName()); + private final Processing processing; + private final Database database; + + RegisterProcessor( + UUID uuid, Supplier registered, String name, + Processing processing, Database database, + Runnable... afterProcess + ) { this.uuid = uuid; this.registered = registered; this.name = name; + this.processing = processing; + this.database = database; this.afterProcess = afterProcess; } @Override public void run() { - Database db = Database.getActive(); Verify.nullCheck(uuid, () -> new IllegalStateException("UUID was null")); + + CheckOperations check = database.check(); + SaveOperations save = database.save(); try { - if (!db.check().isPlayerRegistered(uuid)) { - db.save().registerNewUser(uuid, registered.get(), name); + if (!check.isPlayerRegistered(uuid)) { + save.registerNewUser(uuid, registered.get(), name); } - if (!db.check().isPlayerRegisteredOnThisServer(uuid)) { - db.save().registerNewUserOnThisServer(uuid, registered.get()); + if (!check.isPlayerRegisteredOnThisServer(uuid)) { + save.registerNewUserOnThisServer(uuid, registered.get()); } } finally { for (Runnable runnable : afterProcess) { - Processing.submit(runnable); + processing.submit(runnable); } cancel(); } diff --git a/Plan/src/main/java/com/djrapitops/plan/system/settings/PlanErrorManager.java b/Plan/src/main/java/com/djrapitops/plan/system/settings/PlanErrorManager.java deleted file mode 100644 index aa7d14141..000000000 --- a/Plan/src/main/java/com/djrapitops/plan/system/settings/PlanErrorManager.java +++ /dev/null @@ -1,55 +0,0 @@ -/* - * License is provided in the jar as LICENSE also here: - * https://github.com/Rsl1122/Plan-PlayerAnalytics/blob/master/Plan/src/main/resources/LICENSE - */ -package com.djrapitops.plan.system.settings; - -import com.djrapitops.plan.system.webserver.WebServer; -import com.djrapitops.plan.system.webserver.WebServerSystem; -import com.djrapitops.plugin.api.Check; -import com.djrapitops.plugin.api.utility.log.ErrorLogger; -import com.djrapitops.plugin.api.utility.log.Log; -import com.djrapitops.plugin.api.utility.log.errormanager.ErrorManager; - -import java.io.File; -import java.util.logging.Level; -import java.util.logging.Logger; - -/** - * Abstract Plugin Framework ErrorManager for logging Errors properly instead of a vague message. - * - * @author Rsl1122 - */ -public class PlanErrorManager implements ErrorManager { - - @Override - public void toLog(String source, Throwable e, Class callingPlugin) { - try { - File logsFolder = Log.getLogsFolder(callingPlugin); - Log.warn(source + " Caught: " + e, callingPlugin); - if (WebServerSystem.isWebServerEnabled()) { - Log.warn("Exception can be viewed at " + WebServer.getInstance().getAccessAddress() + "/debug"); - } else { - Log.warn("It has been logged to ErrorLog.txt"); - } - logGlobally(source, e); - ErrorLogger.logThrowable(e, logsFolder); - } catch (Exception exception) { - System.out.println("Failed to log error to file because of " + exception); - System.out.println("Error:"); - // Fallback - System.out.println("Fail Reason:"); - Logger.getGlobal().log(Level.WARNING, source, e); - } - } - - private void logGlobally(String source, Throwable e) { - try { - if ((Check.isBukkitAvailable() && Check.isBungeeAvailable()) || Settings.DEV_MODE.isTrue()) { - Logger.getGlobal().log(Level.WARNING, source, e); - } - } catch (IllegalStateException ignored) { - /* Config system not initialized */ - } - } -} diff --git a/Plan/src/main/java/com/djrapitops/plan/system/settings/ServerSpecificSettings.java b/Plan/src/main/java/com/djrapitops/plan/system/settings/ServerSpecificSettings.java index 130e19e7e..0d016b231 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/settings/ServerSpecificSettings.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/settings/ServerSpecificSettings.java @@ -5,11 +5,13 @@ package com.djrapitops.plan.system.settings; import com.djrapitops.plan.PlanPlugin; -import com.djrapitops.plan.system.settings.config.ConfigSystem; -import com.djrapitops.plugin.api.config.Config; -import com.djrapitops.plugin.api.utility.log.Log; +import com.djrapitops.plan.system.settings.config.PlanConfig; +import com.djrapitops.plugin.logging.console.PluginLogger; import com.djrapitops.plugin.utilities.Verify; +import dagger.Lazy; +import javax.inject.Inject; +import javax.inject.Singleton; import java.io.IOException; import java.util.Map; import java.util.UUID; @@ -22,13 +24,30 @@ import java.util.UUID; * * @author Rsl1122 */ +@Singleton public class ServerSpecificSettings { - public static void updateSettings(Map settings) { - Log.debug("Checking new settings.."); - Config config = ConfigSystem.getConfig(); + private final Lazy plugin; + private final Lazy config; + + private final PluginLogger logger; + + @Inject + public ServerSpecificSettings( + Lazy plugin, + Lazy config, + PluginLogger logger + ) { + this.plugin = plugin; + this.config = config; + this.logger = logger; + } + + public void updateSettings(Map settings) throws IOException { + logger.debug("Checking new settings.."); boolean changedSomething = false; + PlanConfig planConfig = config.get(); for (Map.Entry setting : settings.entrySet()) { try { String path = setting.getKey(); @@ -37,33 +56,29 @@ public class ServerSpecificSettings { } String stringValue = setting.getValue(); Object value = getValue(stringValue); - String currentValue = config.getString(path); + String currentValue = planConfig.getString(path); if (stringValue.equals(currentValue)) { continue; } - config.set(path, value); - Log.debug(" " + path + ": " + value); + planConfig.set(path, value); + logger.debug(" " + path + ": " + value); } catch (NullPointerException ignored) { } changedSomething = true; } if (changedSomething) { - try { - config.save(); - } catch (IOException e) { - Log.toLog(ServerSpecificSettings.class, e); - } - Log.info("----------------------------------"); - Log.info("The Received Bungee Settings changed the config values, restarting Plan.."); - Log.info("----------------------------------"); - PlanPlugin.getInstance().reloadPlugin(true); + planConfig.save(); + logger.info("----------------------------------"); + logger.info("The Received Bungee Settings changed the config values, restarting Plan.."); + logger.info("----------------------------------"); + plugin.get().reloadPlugin(true); } else { - Log.debug("Settings up to date"); + logger.debug("Settings up to date"); } } - private static Object getValue(String value) { + private Object getValue(String value) { try { return Integer.parseInt(value); } catch (Exception ignored) { @@ -77,19 +92,15 @@ public class ServerSpecificSettings { return value; } - public void addOriginalBukkitSettings(UUID serverUUID, Map settings) { - try { - Config config = ConfigSystem.getConfig(); - if (!Verify.isEmpty(config.getString("Servers." + serverUUID + ".ServerName"))) { - return; - } - for (Map.Entry entry : settings.entrySet()) { - config.set("Servers." + serverUUID + "." + entry.getKey(), entry.getValue()); - } - config.save(); - } catch (IOException e) { - Log.toLog(this.getClass(), e); + public void addOriginalBukkitSettings(UUID serverUUID, Map settings) throws IOException { + PlanConfig planConfig = config.get(); + if (!Verify.isEmpty(planConfig.getString("Servers." + serverUUID + ".ServerName"))) { + return; } + for (Map.Entry entry : settings.entrySet()) { + planConfig.set("Servers." + serverUUID + "." + entry.getKey(), entry.getValue()); + } + planConfig.save(); } private String getPath(UUID serverUUID, Settings setting) { @@ -111,27 +122,24 @@ public class ServerSpecificSettings { } public boolean getBoolean(UUID serverUUID, Settings setting) { - Config config = ConfigSystem.getConfig(); String path = getPath(serverUUID, setting); - return config.getBoolean(path); + return config.get().getBoolean(path); } public String getString(UUID serverUUID, Settings setting) { - Config config = ConfigSystem.getConfig(); String path = getPath(serverUUID, setting); - return config.getString(path); + return config.get().getString(path); } public Integer getInt(UUID serverUUID, Settings setting) { - Config config = ConfigSystem.getConfig(); String path = getPath(serverUUID, setting); - return config.getInt(path); + return config.get().getInt(path); } public void set(UUID serverUUID, Settings setting, Object value) throws IOException { - Config config = ConfigSystem.getConfig(); String path = getPath(serverUUID, setting); - config.set(path, value); - config.save(); + PlanConfig planConfig = config.get(); + planConfig.set(path, value); + planConfig.save(); } } diff --git a/Plan/src/main/java/com/djrapitops/plan/system/settings/Settings.java b/Plan/src/main/java/com/djrapitops/plan/system/settings/Settings.java index 0b283d009..6090a13cf 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/settings/Settings.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/settings/Settings.java @@ -1,13 +1,6 @@ package com.djrapitops.plan.system.settings; -import com.djrapitops.plan.system.settings.config.ConfigSystem; -import com.djrapitops.plugin.api.Check; -import com.djrapitops.plugin.api.config.Config; -import com.djrapitops.plugin.api.utility.log.Log; -import com.djrapitops.plugin.utilities.Verify; - -import java.io.IOException; -import java.util.List; +import com.djrapitops.plan.system.settings.config.Setting; /** * This enum contains all of the config settings used by the plugin for easier @@ -16,7 +9,7 @@ import java.util.List; * @author Rsl1122 * @since 2.3.2 */ -public enum Settings { +public enum Settings implements Setting { // Boolean BUNGEE_COPY_CONFIG("Plugin.Bungee-Override.CopyBungeeConfig"), BUNGEE_OVERRIDE_STANDALONE_MODE("Plugin.Bungee-Override.StandaloneMode"), @@ -37,8 +30,8 @@ public enum Settings { DISPLAY_PLAYER_IPS("Customization.Display.PlayerIPs"), DISPLAY_GAPS_IN_GRAPH_DATA("Customization.Display.GapsInGraphData"), DATA_GEOLOCATIONS("Data.Geolocations"), - ALLOW_UPDATE("Plugin.Allow-Update-Command"), NOTIFY_ABOUT_DEV_RELEASES("Plugin.Notify-About-DEV-Releases"), + CHECK_FOR_UPDATES("Plugin.Check-for-updates"), // Integer WEBSERVER_PORT("WebServer.Port"), @@ -99,6 +92,8 @@ public enum Settings { THEME_BASE("Theme.Base"), THEME_GRAPH_TPS_THRESHOLD_HIGH("Theme.Graphs.TPS.High-Threshold"), THEME_GRAPH_TPS_THRESHOLD_MED("Theme.Graphs.TPS.Medium-Threshold"), + THEME_GRAPH_DISK_THRESHOLD_HIGH("Theme.Graphs.Disk.High-Threshold"), + THEME_GRAPH_DISK_THRESHOLD_MED("Theme.Graphs.Disk.Medium-Threshold"), // StringList HIDE_FACTIONS("Plugins.Factions.HideFactions"), @@ -110,97 +105,24 @@ public enum Settings { BUNGEE_IP("Server.IP"), BUNGEE_NETWORK_NAME("Network.Name"); - private static final ServerSpecificSettings serverSpecificSettings = new ServerSpecificSettings(); - private final String configPath; - private Object tempValue; Settings(String path) { this.configPath = path; } - public static ServerSpecificSettings serverSpecific() { - if (!Check.isBungeeAvailable()) { - throw new IllegalStateException("Not supposed to call this method on Bukkit"); - } - - return serverSpecificSettings; - } - - /** - * If the settings is a boolean, this method should be used. - * - * @return Boolean value of the config setting, false if not boolean. - */ - public boolean isTrue() { - if (tempValue != null) { - return (Boolean) tempValue; - } - return getConfig().getBoolean(configPath); - } - - public boolean isFalse() { - return !isTrue(); - } - - public static void save() { - try { - ConfigSystem.getConfig().save(); - } catch (IOException e) { - Log.toLog(Settings.class, e); - } - } - - /** - * If the settings is a String, this method should be used. - * - * @return String value of the config setting. - */ @Override - public String toString() { - if (tempValue != null) { - return String.valueOf(tempValue); - } - return getConfig().getString(configPath); - } - - /** - * If the settings is a number, this method should be used. - * - * @return Integer value of the config setting - */ - public int getNumber() { - if (tempValue != null) { - return (Integer) tempValue; - } - return getConfig().getInt(configPath); - } - - public List getStringList() { - return getConfig().getStringList(configPath); - } - - /** - * Used to get the String path of a the config setting eg. - * Settings.WebServer.Enabled - * - * @return Path of the config setting. - */ public String getPath() { return configPath; } - public void setTemporaryValue(Object value) { - this.tempValue = value; - } - - public void set(Object value) { - getConfig().set(getPath(), value); - } - - private Config getConfig() { - Config config = ConfigSystem.getConfig(); - Verify.nullCheck(config, () -> new IllegalStateException("Settings are not supposed to be called before ConfigSystem is Enabled!")); - return config; + /** + * @return What getPath returns + * @deprecated Old access method used to return string value in config. Use {@link com.djrapitops.plan.system.settings.config.PlanConfig#getString(Setting)} instead + */ + @Deprecated + @Override + public String toString() { + return getPath(); } } diff --git a/Plan/src/main/java/com/djrapitops/plan/system/settings/WorldAliasSettings.java b/Plan/src/main/java/com/djrapitops/plan/system/settings/WorldAliasSettings.java index 0cbfe4852..e225620b4 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/settings/WorldAliasSettings.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/settings/WorldAliasSettings.java @@ -4,34 +4,65 @@ */ package com.djrapitops.plan.system.settings; +import com.djrapitops.plan.data.container.Session; +import com.djrapitops.plan.data.store.keys.SessionKeys; +import com.djrapitops.plan.data.time.GMTimes; +import com.djrapitops.plan.data.time.WorldTimes; import com.djrapitops.plan.system.processing.Processing; -import com.djrapitops.plan.system.settings.config.ConfigSystem; -import com.djrapitops.plugin.api.config.Config; -import com.djrapitops.plugin.api.config.ConfigNode; -import com.djrapitops.plugin.api.utility.log.Log; +import com.djrapitops.plan.system.settings.config.PlanConfig; +import com.djrapitops.plan.utilities.formatting.Formatter; +import com.djrapitops.plan.utilities.formatting.Formatters; +import com.djrapitops.plugin.config.ConfigNode; +import com.djrapitops.plugin.logging.L; +import com.djrapitops.plugin.logging.error.ErrorHandler; import com.djrapitops.plugin.utilities.Verify; +import dagger.Lazy; +import javax.inject.Inject; +import javax.inject.Singleton; import java.io.IOException; import java.util.HashMap; import java.util.Map; +import java.util.function.Supplier; +import java.util.stream.Collectors; /** - * Class responsible for managing Bukkit side config settings for World Aliases. + * Class responsible for managing config settings for World Aliases. * * @author Rsl1122 */ +@Singleton public class WorldAliasSettings { - private WorldAliasSettings() { - /* Hide Constructor */ + private final Lazy config; + private final Supplier> percentageFormatter; + private final Processing processing; + private final ErrorHandler errorHandler; + + @Inject + public WorldAliasSettings( + Lazy config, + Lazy formatters, + Processing processing, + ErrorHandler errorHandler + ) { + this.config = config; + this.processing = processing; + this.errorHandler = errorHandler; + + percentageFormatter = () -> formatters.get().percentage(); } - + + private ConfigNode getAliasSection() { + return config.get().getConfigNode(Settings.WORLD_ALIASES); + } + /** * Used to get all World aliases in the config * * @return Map: Original name, Alias */ - public static Map getAliases() { + public Map getAliases() { ConfigNode aliasSect = getAliasSection(); Map aliasMap = new HashMap<>(); @@ -41,11 +72,6 @@ public class WorldAliasSettings { return aliasMap; } - private static ConfigNode getAliasSection() { - Config config = ConfigSystem.getConfig(); - return config.getConfigNode(Settings.WORLD_ALIASES.getPath()); - } - /** * Adds a new World to the config section. *

@@ -53,19 +79,110 @@ public class WorldAliasSettings { * * @param world World name */ - public static void addWorld(String world) { + public void addWorld(String world) { ConfigNode aliasSect = getAliasSection(); String previousValue = aliasSect.getConfigNode(world).getValue(); if (Verify.isEmpty(previousValue)) { aliasSect.set(world, world); - Processing.submitNonCritical(() -> { + processing.submitNonCritical(() -> { try { aliasSect.save(); } catch (IOException e) { - Log.toLog(WorldAliasSettings.class, e); + errorHandler.log(L.WARN, WorldAliasSettings.class, e); } }); } } + + public Map getPlaytimePerAlias(WorldTimes worldTimes) { + if (worldTimes.getWorldTimes().isEmpty()) { + return new HashMap<>(); + } + + Map playtimePerWorld = worldTimes.getWorldTimes() // WorldTimes Map + .entrySet().stream() + .collect(Collectors.toMap( + Map.Entry::getKey, + entry -> entry.getValue().getTotal() // GMTimes.getTotal + )); + + Map aliases = getAliases(); + + Map playtimePerAlias = new HashMap<>(); + for (Map.Entry entry : playtimePerWorld.entrySet()) { + String worldName = entry.getKey(); + long playtime = entry.getValue(); + + if (!aliases.containsKey(worldName)) { + aliases.put(worldName, worldName); + addWorld(worldName); + } + + String alias = aliases.get(worldName); + + playtimePerAlias.put(alias, playtimePerAlias.getOrDefault(alias, 0L) + playtime); + } + return playtimePerAlias; + } + + public Map getGMTimesPerAlias(WorldTimes worldTimes) { + Map aliases = getAliases(); + + Map gmTimesPerAlias = new HashMap<>(); + + String[] gms = GMTimes.getGMKeyArray(); + + for (Map.Entry entry : worldTimes.getWorldTimes().entrySet()) { + String worldName = entry.getKey(); + GMTimes gmTimes = entry.getValue(); + + if (!aliases.containsKey(worldName)) { + aliases.put(worldName, worldName); + addWorld(worldName); + } + + String alias = aliases.get(worldName); + + GMTimes aliasGMTimes = gmTimesPerAlias.getOrDefault(alias, new GMTimes()); + for (String gm : gms) { + aliasGMTimes.addTime(gm, gmTimes.getTime(gm)); + } + gmTimesPerAlias.put(alias, aliasGMTimes); + } + return gmTimesPerAlias; + } + + public String getLongestWorldPlayed(Session session) { + Map aliases = getAliases(); + if (!session.supports(SessionKeys.WORLD_TIMES)) { + return "No World Time Data"; + } + WorldTimes worldTimes = session.getUnsafe(SessionKeys.WORLD_TIMES); + if (!session.supports(SessionKeys.END)) { + return "Current: " + aliases.get(worldTimes.getCurrentWorld()); + } + + Map playtimePerAlias = getPlaytimePerAlias(worldTimes); + long total = worldTimes.getTotal(); + // Prevent arithmetic error if 0 + if (total <= 0) { + total = -1; + } + + long longest = 0; + String theWorld = "-"; + for (Map.Entry entry : playtimePerAlias.entrySet()) { + String world = entry.getKey(); + long time = entry.getValue(); + if (time > longest) { + longest = time; + theWorld = world; + } + } + + double quotient = longest * 1.0 / total; + + return theWorld + " (" + percentageFormatter.get().apply(quotient) + ")"; + } } diff --git a/Plan/src/main/java/com/djrapitops/plan/system/settings/config/BukkitConfigSystem.java b/Plan/src/main/java/com/djrapitops/plan/system/settings/config/BukkitConfigSystem.java new file mode 100644 index 000000000..1cb4a207e --- /dev/null +++ b/Plan/src/main/java/com/djrapitops/plan/system/settings/config/BukkitConfigSystem.java @@ -0,0 +1,41 @@ +/* + * License is provided in the jar as LICENSE also here: + * https://github.com/Rsl1122/Plan-PlayerAnalytics/blob/master/Plan/src/main/resources/LICENSE + */ +package com.djrapitops.plan.system.settings.config; + +import com.djrapitops.plan.system.file.PlanFiles; +import com.djrapitops.plan.system.settings.theme.Theme; +import com.djrapitops.plugin.logging.console.PluginLogger; +import com.djrapitops.plugin.logging.error.ErrorHandler; + +import javax.inject.Inject; +import javax.inject.Singleton; +import java.io.IOException; + +/** + * ConfigSystem for Bukkit. + *

+ * Bukkit and Bungee have different default config file inside the jar. + * + * @author Rsl1122 + */ +@Singleton +public class BukkitConfigSystem extends ConfigSystem { + + @Inject + public BukkitConfigSystem( + PlanFiles files, + PlanConfig config, + Theme theme, + PluginLogger logger, + ErrorHandler errorHandler + ) { + super(files, config, theme, logger, errorHandler); + } + + @Override + protected void copyDefaults() throws IOException { + config.copyDefaults(files.readFromResource("config.yml")); + } +} diff --git a/Plan/src/main/java/com/djrapitops/plan/system/settings/config/BungeeConfigSystem.java b/Plan/src/main/java/com/djrapitops/plan/system/settings/config/BungeeConfigSystem.java deleted file mode 100644 index 0738c72c0..000000000 --- a/Plan/src/main/java/com/djrapitops/plan/system/settings/config/BungeeConfigSystem.java +++ /dev/null @@ -1,24 +0,0 @@ -/* - * License is provided in the jar as LICENSE also here: - * https://github.com/Rsl1122/Plan-PlayerAnalytics/blob/master/Plan/src/main/resources/LICENSE - */ -package com.djrapitops.plan.system.settings.config; - -import com.djrapitops.plan.system.file.FileSystem; - -import java.io.IOException; - -/** - * ConfigSystem for Bungee. - *

- * Bukkit and Bungee have different default config file inside the jar. - * - * @author Rsl1122 - */ -public class BungeeConfigSystem extends ConfigSystem { - - @Override - protected void copyDefaults() throws IOException { - config.copyDefaults(FileSystem.readFromResource("bungeeconfig.yml")); - } -} diff --git a/Plan/src/main/java/com/djrapitops/plan/system/settings/config/ConfigSystem.java b/Plan/src/main/java/com/djrapitops/plan/system/settings/config/ConfigSystem.java index 9cb57f7a1..e52c4a4ec 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/settings/config/ConfigSystem.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/settings/config/ConfigSystem.java @@ -5,58 +5,87 @@ package com.djrapitops.plan.system.settings.config; import com.djrapitops.plan.api.exceptions.EnableException; -import com.djrapitops.plan.system.PlanSystem; import com.djrapitops.plan.system.SubSystem; -import com.djrapitops.plan.system.file.FileSystem; +import com.djrapitops.plan.system.file.PlanFiles; import com.djrapitops.plan.system.settings.Settings; import com.djrapitops.plan.system.settings.theme.Theme; -import com.djrapitops.plugin.api.config.Config; -import com.djrapitops.plugin.api.utility.log.Log; +import com.djrapitops.plugin.logging.L; +import com.djrapitops.plugin.logging.console.PluginLogger; +import com.djrapitops.plugin.logging.debug.*; +import com.djrapitops.plugin.logging.error.ErrorHandler; import com.djrapitops.plugin.utilities.Verify; +import javax.inject.Singleton; import java.io.IOException; +import java.util.ArrayList; +import java.util.List; /** * System for Config and other user customizable options. * * @author Rsl1122 */ +@Singleton public abstract class ConfigSystem implements SubSystem { - protected Config config; + protected final PlanFiles files; + protected final PlanConfig config; protected final Theme theme; + protected final PluginLogger logger; + protected final ErrorHandler errorHandler; - public ConfigSystem() { - theme = new Theme(); + public ConfigSystem( + PlanFiles files, + PlanConfig config, + Theme theme, + PluginLogger logger, + ErrorHandler errorHandler + ) { + this.files = files; + this.config = config; + this.theme = theme; + this.logger = logger; + this.errorHandler = errorHandler; } - public static ConfigSystem getInstance() { - ConfigSystem configSystem = PlanSystem.getInstance().getConfigSystem(); - Verify.nullCheck(configSystem, () -> new IllegalStateException("Config System has not been initialized.")); - return configSystem; + public PlanConfig getConfig() { + return config; } - public static Config getConfig() { - return getInstance().config; - } - - public Theme getThemeSystem() { - return getInstance().theme; + public Theme getTheme() { + return theme; } @Override public void enable() throws EnableException { - config = new Config(FileSystem.getConfigFile()); try { copyDefaults(); config.save(); - Log.setDebugMode(Settings.DEBUG.toString()); + + setDebugMode(); } catch (IOException e) { throw new EnableException("Failed to save default config.", e); } theme.enable(); } + private void setDebugMode() { + String debugMode = config.getString(Settings.DEBUG); + + List loggers = new ArrayList<>(); + if (Verify.equalsOne(debugMode, "true", "both", "console")) { + loggers.add(new ConsoleDebugLogger(logger)); + } + if (Verify.equalsOne(debugMode, "true", "both", "file")) { + loggers.add(new FolderTimeStampFileDebugLogger(files.getLogsFolder(), () -> errorHandler)); + } + if (logger.getDebugLogger() instanceof CombineDebugLogger) { + CombineDebugLogger debugLogger = (CombineDebugLogger) logger.getDebugLogger(); + loggers.add(debugLogger.getDebugLogger(MemoryDebugLogger.class).orElse(new MemoryDebugLogger())); + debugLogger.setDebugLoggers(loggers.toArray(new DebugLogger[0])); + } + } + /** * Copies default values from file in jar to Config. * @@ -73,7 +102,7 @@ public abstract class ConfigSystem implements SubSystem { try { config.read(); } catch (IOException e) { - Log.toLog(ConfigSystem.class, e); + errorHandler.log(L.ERROR, this.getClass(), e); } } } diff --git a/Plan/src/main/java/com/djrapitops/plan/system/settings/config/PlanConfig.java b/Plan/src/main/java/com/djrapitops/plan/system/settings/config/PlanConfig.java new file mode 100644 index 000000000..13a2f3bf1 --- /dev/null +++ b/Plan/src/main/java/com/djrapitops/plan/system/settings/config/PlanConfig.java @@ -0,0 +1,102 @@ +package com.djrapitops.plan.system.settings.config; + +import com.djrapitops.plan.data.plugin.PluginsConfigSection; +import com.djrapitops.plan.system.settings.Settings; +import com.djrapitops.plan.system.settings.WorldAliasSettings; +import com.djrapitops.plan.system.settings.network.NetworkSettings; +import com.djrapitops.plugin.config.Config; +import com.djrapitops.plugin.config.ConfigNode; + +import javax.inject.Inject; +import javax.inject.Named; +import javax.inject.Singleton; +import java.io.File; +import java.util.List; +import java.util.TimeZone; +import java.util.concurrent.TimeUnit; + +/** + * Plan configuration file. + * + * @author Rsl1122 + */ +@Singleton +public class PlanConfig extends Config { + + private final PluginsConfigSection pluginsConfigSection; + private final NetworkSettings networkSettings; + private final WorldAliasSettings worldAliasSettings; + + @Inject + public PlanConfig( + @Named("configFile") File file, + NetworkSettings networkSettings, + WorldAliasSettings worldAliasSettings + ) { + super(file); + + this.networkSettings = networkSettings; + this.worldAliasSettings = worldAliasSettings; + + pluginsConfigSection = new PluginsConfigSection(this); + } + + public int getTimeZoneOffsetHours() { + if (isTrue(Settings.USE_SERVER_TIME)) { + int offset = TimeZone.getDefault().getOffset(System.currentTimeMillis()); + int hourMs = (int) TimeUnit.HOURS.toMillis(1L); + return -offset / hourMs; + } + return 0; // UTC + } + + public boolean isTrue(Setting setting) { + return getBoolean(setting.getPath()); + } + + public boolean isFalse(Setting setting) { + return !isTrue(setting); + } + + /** + * If the settings is a String, this method should be used. + * + * @return String value of the config setting. + */ + public String getString(Setting setting) { + return getString(setting.getPath()); + } + + /** + * If the settings is a number, this method should be used. + * + * @return Integer value of the config setting + */ + public int getNumber(Setting setting) { + return getInt(setting.getPath()); + } + + public List getStringList(Setting setting) { + return getStringList(setting.getPath()); + } + + public ConfigNode getConfigNode(Setting setting) { + return getConfigNode(setting.getPath()); + } + + public void set(Setting setting, Object value) { + set(setting.getPath(), value); + } + + public PluginsConfigSection getPluginsConfigSection() { + return pluginsConfigSection; + } + + public NetworkSettings getNetworkSettings() { + return networkSettings; + } + + public WorldAliasSettings getWorldAliasSettings() { + return worldAliasSettings; + } +} \ No newline at end of file diff --git a/Plan/src/main/java/com/djrapitops/plan/system/settings/config/ProxyConfigSystem.java b/Plan/src/main/java/com/djrapitops/plan/system/settings/config/ProxyConfigSystem.java new file mode 100644 index 000000000..39150f5e9 --- /dev/null +++ b/Plan/src/main/java/com/djrapitops/plan/system/settings/config/ProxyConfigSystem.java @@ -0,0 +1,41 @@ +/* + * License is provided in the jar as LICENSE also here: + * https://github.com/Rsl1122/Plan-PlayerAnalytics/blob/master/Plan/src/main/resources/LICENSE + */ +package com.djrapitops.plan.system.settings.config; + +import com.djrapitops.plan.system.file.PlanFiles; +import com.djrapitops.plan.system.settings.theme.Theme; +import com.djrapitops.plugin.logging.console.PluginLogger; +import com.djrapitops.plugin.logging.error.ErrorHandler; + +import javax.inject.Inject; +import javax.inject.Singleton; +import java.io.IOException; + +/** + * ConfigSystem for Bungee. + *

+ * Bukkit and Bungee have different default config file inside the jar. + * + * @author Rsl1122 + */ +@Singleton +public class ProxyConfigSystem extends ConfigSystem { + + @Inject + public ProxyConfigSystem( + PlanFiles files, + PlanConfig config, + Theme theme, + PluginLogger logger, + ErrorHandler errorHandler + ) { + super(files, config, theme, logger, errorHandler); + } + + @Override + protected void copyDefaults() throws IOException { + config.copyDefaults(files.readFromResource("bungeeconfig.yml")); + } +} diff --git a/Plan/src/main/java/com/djrapitops/plan/system/settings/config/ServerConfigSystem.java b/Plan/src/main/java/com/djrapitops/plan/system/settings/config/ServerConfigSystem.java deleted file mode 100644 index 08f352083..000000000 --- a/Plan/src/main/java/com/djrapitops/plan/system/settings/config/ServerConfigSystem.java +++ /dev/null @@ -1,24 +0,0 @@ -/* - * License is provided in the jar as LICENSE also here: - * https://github.com/Rsl1122/Plan-PlayerAnalytics/blob/master/Plan/src/main/resources/LICENSE - */ -package com.djrapitops.plan.system.settings.config; - -import com.djrapitops.plan.system.file.FileSystem; - -import java.io.IOException; - -/** - * ConfigSystem for Bukkit. - *

- * Bukkit and Bungee have different default config file inside the jar. - * - * @author Rsl1122 - */ -public class ServerConfigSystem extends ConfigSystem { - - @Override - protected void copyDefaults() throws IOException { - config.copyDefaults(FileSystem.readFromResource("config.yml")); - } -} diff --git a/Plan/src/main/java/com/djrapitops/plan/system/settings/config/Setting.java b/Plan/src/main/java/com/djrapitops/plan/system/settings/config/Setting.java new file mode 100644 index 000000000..29e544443 --- /dev/null +++ b/Plan/src/main/java/com/djrapitops/plan/system/settings/config/Setting.java @@ -0,0 +1,19 @@ +package com.djrapitops.plan.system.settings.config; + +/** + * Represents a path to a config value. + * + * @author Rsl1122 + */ +public interface Setting { + + /** + * Used to get the String path of a the config setting. + *

+ * Path separates nested levels with a dot. + * + * @return Example: Settings.WebServer.Enabled + */ + String getPath(); + +} diff --git a/Plan/src/main/java/com/djrapitops/plan/system/settings/config/SpongeConfigSystem.java b/Plan/src/main/java/com/djrapitops/plan/system/settings/config/SpongeConfigSystem.java index 477a57ab7..a28cb9108 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/settings/config/SpongeConfigSystem.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/settings/config/SpongeConfigSystem.java @@ -1,10 +1,14 @@ package com.djrapitops.plan.system.settings.config; import com.djrapitops.plan.api.exceptions.EnableException; -import com.djrapitops.plan.system.file.FileSystem; +import com.djrapitops.plan.system.file.PlanFiles; import com.djrapitops.plan.system.settings.Settings; -import com.djrapitops.plugin.api.utility.log.Log; +import com.djrapitops.plan.system.settings.theme.Theme; +import com.djrapitops.plugin.logging.console.PluginLogger; +import com.djrapitops.plugin.logging.error.ErrorHandler; +import javax.inject.Inject; +import javax.inject.Singleton; import java.io.IOException; /** @@ -12,13 +16,25 @@ import java.io.IOException; * * @author Rsl1122 */ -public class SpongeConfigSystem extends ServerConfigSystem { +@Singleton +public class SpongeConfigSystem extends BukkitConfigSystem { private boolean firstInstall; + @Inject + public SpongeConfigSystem( + PlanFiles files, + PlanConfig config, + Theme theme, + PluginLogger logger, + ErrorHandler errorHandler + ) { + super(files, config, theme, logger, errorHandler); + } + @Override public void enable() throws EnableException { - firstInstall = !FileSystem.getConfigFile().exists(); + firstInstall = !files.getConfigFile().exists(); super.enable(); } @@ -26,12 +42,13 @@ public class SpongeConfigSystem extends ServerConfigSystem { protected void copyDefaults() throws IOException { super.copyDefaults(); if (firstInstall) { - Log.info("§eWebServer and Geolocations disabled by default on Sponge servers. You can enable them in the config:"); - Log.info("§e " + Settings.WEBSERVER_DISABLED.getPath()); - Log.info("§e " + Settings.DATA_GEOLOCATIONS.getPath()); - Settings.WEBSERVER_DISABLED.set(true); - Settings.DATA_GEOLOCATIONS.set(false); - Settings.save(); + logger.info("§eWebServer and Geolocations disabled by default on Sponge servers. You can enable them in the config:"); + logger.info("§e " + Settings.WEBSERVER_DISABLED.getPath()); + logger.info("§e " + Settings.DATA_GEOLOCATIONS.getPath()); + + config.set(Settings.WEBSERVER_DISABLED, true); + config.set(Settings.DATA_GEOLOCATIONS, false); + config.save(); } } } \ No newline at end of file diff --git a/Plan/src/main/java/com/djrapitops/plan/system/settings/network/NetworkSettings.java b/Plan/src/main/java/com/djrapitops/plan/system/settings/network/NetworkSettings.java index 985df52c5..eeb52c3bf 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/settings/network/NetworkSettings.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/settings/network/NetworkSettings.java @@ -4,18 +4,23 @@ */ package com.djrapitops.plan.system.settings.network; -import com.djrapitops.plan.api.exceptions.connection.UnsupportedTransferDatabaseException; -import com.djrapitops.plan.api.exceptions.database.DBOpException; -import com.djrapitops.plan.system.database.databases.Database; +import com.djrapitops.plan.system.database.DBSystem; import com.djrapitops.plan.system.info.server.ServerInfo; import com.djrapitops.plan.system.processing.Processing; import com.djrapitops.plan.system.settings.ServerSpecificSettings; import com.djrapitops.plan.system.settings.Settings; +import com.djrapitops.plan.system.settings.config.PlanConfig; import com.djrapitops.plan.utilities.Base64Util; import com.djrapitops.plugin.api.Check; -import com.djrapitops.plugin.api.utility.log.Log; +import com.djrapitops.plugin.logging.L; +import com.djrapitops.plugin.logging.console.PluginLogger; +import com.djrapitops.plugin.logging.error.ErrorHandler; import com.djrapitops.plugin.utilities.Verify; +import dagger.Lazy; +import javax.inject.Inject; +import javax.inject.Singleton; +import java.io.IOException; import java.util.HashMap; import java.util.Map; import java.util.Optional; @@ -28,65 +33,87 @@ import static com.djrapitops.plan.system.settings.Settings.*; * * @author Rsl1122 */ +@Singleton public class NetworkSettings { private static final String SPLIT = ";;SETTING;;"; private static final String VAL_SPLIT = ";;VALUE;;"; - public static void loadSettingsFromDB() { - if (Check.isBungeeAvailable()) { - return; - } + private final Lazy config; + private final ServerSpecificSettings serverSpecificSettings; + private final Processing processing; + private final Lazy dbSystem; + private final Lazy serverInfo; + private final PluginLogger logger; + private final ErrorHandler errorHandler; - if (BUNGEE_OVERRIDE_STANDALONE_MODE.isTrue() || BUNGEE_COPY_CONFIG.isFalse()) { - return; - } - - Processing.submitNonCritical(() -> { - try { - new NetworkSettings().loadFromDatabase(); - } catch (UnsupportedTransferDatabaseException e) { - Log.toLog(NetworkSettings.class, e); - } - }); + @Inject + public NetworkSettings( + Lazy config, + ServerSpecificSettings serverSpecificSettings, + Processing processing, + Lazy dbSystem, + Lazy serverInfo, + PluginLogger logger, + ErrorHandler errorHandler + ) { + this.config = config; + this.serverSpecificSettings = serverSpecificSettings; + this.processing = processing; + this.dbSystem = dbSystem; + this.serverInfo = serverInfo; + this.logger = logger; + this.errorHandler = errorHandler; } - public static void placeSettingsToDB() { - if (!Check.isBungeeAvailable()) { + public void loadSettingsFromDB() { + if (Check.isBungeeAvailable() || Check.isVelocityAvailable()) { return; } - Processing.submitCritical(() -> { - try { - new NetworkSettings().placeToDatabase(); - } catch (DBOpException | UnsupportedTransferDatabaseException e) { - Log.toLog(NetworkSettings.class, e); - } - }); + PlanConfig planConfig = config.get(); + if (planConfig.isTrue(BUNGEE_OVERRIDE_STANDALONE_MODE) || planConfig.isFalse(BUNGEE_COPY_CONFIG)) { + // Don't load settings if they are overridden. + return; + } + + processing.submitNonCritical(this::loadFromDatabase); } - public void loadFromDatabase() throws UnsupportedTransferDatabaseException { - Log.debug("NetworkSettings: Fetch Config settings from database.."); - Optional encodedConfigSettings = Database.getActive().transfer().getEncodedConfigSettings(); + public void placeSettingsToDB() { + if (!Check.isBungeeAvailable() && !Check.isVelocityAvailable()) { + return; + } + + processing.submitNonCritical(this::placeToDatabase); + } + + void loadFromDatabase() { + logger.debug("NetworkSettings: Fetch Config settings from database.."); + Optional encodedConfigSettings = dbSystem.get().getDatabase().transfer().getEncodedConfigSettings(); if (!encodedConfigSettings.isPresent()) { - Log.debug("NetworkSettings: No Config settings in database."); + logger.debug("NetworkSettings: No Config settings in database."); return; } String configSettings = Base64Util.decode(encodedConfigSettings.get()); Map pathValueMap = getPathsAndValues(configSettings); - Log.debug("NetworkSettings: Updating Settings"); - ServerSpecificSettings.updateSettings(pathValueMap); + logger.debug("NetworkSettings: Updating Settings"); + try { + serverSpecificSettings.updateSettings(pathValueMap); + } catch (IOException e) { + errorHandler.log(L.ERROR, this.getClass(), e); + } } private Map getPathsAndValues(String configSettings) { Map pathValueMap = new HashMap<>(); - Log.debug("NetworkSettings: Reading Config String.."); + logger.debug("NetworkSettings: Reading Config String.."); String[] settings = configSettings.split(SPLIT); - UUID thisServerUUID = ServerInfo.getServerUUID(); + UUID thisServerUUID = serverInfo.get().getServerUUID(); for (String settingAndVal : settings) { String[] settingValSplit = settingAndVal.split(VAL_SPLIT); String setting = settingValSplit[0]; @@ -108,10 +135,10 @@ public class NetworkSettings { return pathValueMap; } - public void placeToDatabase() throws UnsupportedTransferDatabaseException { + void placeToDatabase() { Map configValues = getConfigValues(); - Log.debug("NetworkSettings: Building Base64 String.."); + logger.debug("NetworkSettings: Building Base64 String.."); StringBuilder transferBuilder = new StringBuilder(); int size = configValues.size(); int i = 0; @@ -129,12 +156,12 @@ public class NetworkSettings { String base64 = Base64Util.encode(transferBuilder.toString()); - Log.debug("NetworkSettings: Saving Config settings to database.."); - Database.getActive().transfer().storeConfigSettings(base64); + logger.debug("NetworkSettings: Saving Config settings to database.."); + dbSystem.get().getDatabase().transfer().storeConfigSettings(base64); } private Map getConfigValues() { - Log.debug("NetworkSettings: Loading Config Values.."); + logger.debug("NetworkSettings: Loading Config Values.."); Map configValues = new HashMap<>(); addConfigValue(configValues, DB_TYPE, "mysql"); Settings[] sameStrings = new Settings[]{ @@ -178,11 +205,12 @@ public class NetworkSettings { PING_SERVER_ENABLE_DELAY, PING_PLAYER_LOGIN_DELAY }; - Log.debug("NetworkSettings: Adding Config Values.."); + logger.debug("NetworkSettings: Adding Config Values.."); + PlanConfig planConfig = config.get(); for (Settings setting : sameStrings) { - addConfigValue(configValues, setting, setting.toString()); + addConfigValue(configValues, setting, planConfig.getString(setting)); } - addConfigValue(configValues, DB_PORT, DB_PORT.getNumber()); + addConfigValue(configValues, DB_PORT, planConfig.getNumber(DB_PORT)); addServerSpecificValues(configValues); return configValues; } @@ -200,13 +228,12 @@ public class NetworkSettings { } private void addServerSpecificValues(Map configValues) { - Log.debug("NetworkSettings: Adding Server-specific Config Values.."); - ServerSpecificSettings settings = Settings.serverSpecific(); + logger.debug("NetworkSettings: Adding Server-specific Config Values.."); - for (UUID serverUUID : Database.getActive().fetch().getServerUUIDs()) { - String theme = settings.getString(serverUUID, THEME_BASE); - Integer port = settings.getInt(serverUUID, WEBSERVER_PORT); - String name = settings.getString(serverUUID, SERVER_NAME); + for (UUID serverUUID : dbSystem.get().getDatabase().fetch().getServerUUIDs()) { + String theme = serverSpecificSettings.getString(serverUUID, THEME_BASE); + Integer port = serverSpecificSettings.getInt(serverUUID, WEBSERVER_PORT); + String name = serverSpecificSettings.getString(serverUUID, SERVER_NAME); if (!Verify.isEmpty(theme)) { addConfigValue(configValues, serverUUID, THEME_BASE, theme); @@ -219,4 +246,8 @@ public class NetworkSettings { } } } + + public ServerSpecificSettings getServerSpecificSettings() { + return serverSpecificSettings; + } } diff --git a/Plan/src/main/java/com/djrapitops/plan/system/settings/theme/PlanColorScheme.java b/Plan/src/main/java/com/djrapitops/plan/system/settings/theme/PlanColorScheme.java index e5adb4b74..b0408cf84 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/settings/theme/PlanColorScheme.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/settings/theme/PlanColorScheme.java @@ -5,8 +5,10 @@ package com.djrapitops.plan.system.settings.theme; import com.djrapitops.plan.system.settings.Settings; -import com.djrapitops.plugin.api.utility.log.Log; -import com.djrapitops.plugin.settings.ColorScheme; +import com.djrapitops.plan.system.settings.config.PlanConfig; +import com.djrapitops.plugin.command.ColorScheme; +import com.djrapitops.plugin.logging.L; +import com.djrapitops.plugin.logging.console.PluginLogger; /** * ColorScheme that uses values in config settings specific to Plan or PlanBungee. @@ -19,15 +21,15 @@ public class PlanColorScheme extends ColorScheme { super(colors); } - public static PlanColorScheme create() { + public static PlanColorScheme create(PlanConfig config, PluginLogger logger) { try { - String main = "§" + Settings.COLOR_MAIN.toString().charAt(1); - String secondary = "§" + Settings.COLOR_SEC.toString().charAt(1); - String tertiary = "§" + Settings.COLOR_TER.toString().charAt(1); + String main = "§" + config.getString(Settings.COLOR_MAIN).charAt(1); + String secondary = "§" + config.getString(Settings.COLOR_SEC).charAt(1); + String tertiary = "§" + config.getString(Settings.COLOR_TER).charAt(1); return new PlanColorScheme(main, secondary, tertiary); } catch (Exception e) { - Log.infoColor("§cCustomization, Chat colors set-up wrong, using defaults."); + logger.log(L.INFO_COLOR, "§cCustomization, Chat colors set-up wrong, using defaults."); return new PlanColorScheme("§2", "§7", "§f"); } } diff --git a/Plan/src/main/java/com/djrapitops/plan/system/settings/theme/Theme.java b/Plan/src/main/java/com/djrapitops/plan/system/settings/theme/Theme.java index 10e6fe123..ba95584cd 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/settings/theme/Theme.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/settings/theme/Theme.java @@ -4,17 +4,16 @@ */ package com.djrapitops.plan.system.settings.theme; -import com.djrapitops.plan.PlanPlugin; import com.djrapitops.plan.api.exceptions.EnableException; import com.djrapitops.plan.system.SubSystem; -import com.djrapitops.plan.system.settings.Settings; -import com.djrapitops.plan.system.settings.config.ConfigSystem; -import com.djrapitops.plugin.api.utility.EnumUtility; -import com.djrapitops.plugin.api.utility.log.Log; +import com.djrapitops.plugin.logging.console.PluginLogger; import com.djrapitops.plugin.utilities.Verify; +import javax.inject.Inject; +import javax.inject.Singleton; import java.io.IOException; -import java.util.List; + +import static com.djrapitops.plan.system.settings.theme.ThemeVal.*; /** * Enum that contains available themes. @@ -23,35 +22,32 @@ import java.util.List; * * @author Rsl1122 */ +@Singleton public class Theme implements SubSystem { - private ThemeConfig config; + private final ThemeConfig config; + private final PluginLogger logger; - public static Theme getInstance() { - Theme themeSystem = ConfigSystem.getInstance().getThemeSystem(); - Verify.nullCheck(themeSystem, () -> new IllegalStateException("Theme System has not been initialized.")); - return themeSystem; + @Inject + public Theme(ThemeConfig config, PluginLogger logger) { + this.config = config; + this.logger = logger; } - public static String getValue(ThemeVal variable) { + public String getValue(ThemeVal variable) { try { - return getInstance().getThemeValue(variable); + return getThemeValue(variable); } catch (NullPointerException | IllegalStateException e) { return variable.getDefaultValue(); } } - public static String replaceColors(String resourceString) { - return getInstance().replaceThemeColors(resourceString); - } - @Override public void enable() throws EnableException { - String themeName = Settings.THEME_BASE.toString(); try { - config = new ThemeConfig(themeName); + config.save(); } catch (IOException e) { - throw new EnableException("Default theme could not be loaded.", e); + throw new EnableException("theme.yml could not be saved.", e); } } @@ -60,7 +56,7 @@ public class Theme implements SubSystem { } - public String getColor(ThemeVal variable) { + private String getColor(ThemeVal variable) { String path = variable.getThemePath(); try { String value = config.getString(path); @@ -70,24 +66,22 @@ public class Theme implements SubSystem { } else { return value; } - } catch (IllegalStateException e) { - if (!PlanPlugin.getInstance().isReloading()) { - Log.error("Something went wrong with getting variable " + variable.name() + " for: " + path); - } } catch (Exception | NoSuchFieldError e) { - Log.error("Something went wrong with getting variable " + variable.name() + " for: " + path); + logger.error("Something went wrong with getting variable " + variable.name() + " for: " + path); } return variable.getDefaultValue(); } public String replaceThemeColors(String resourceString) { String replaced = resourceString; - List themeVariables = EnumUtility.getSupportedEnumValues(ThemeVal.class, "RED", "PINK", "PURPLE", - "DEEP_PURPLE", "INDIGO", "BLUE", "LIGHT_BLUE", "CYAN", "TEAL", "GREEN", "LIGHT_GREEN", "LIME", - "YELLOW", "AMBER", "ORANGE", "DEEP_ORANGE", "BROWN", "GREY", "BLUE_GREY", "BLACK", "WHITE", - "GRAPH_PUNCHCARD", "GRAPH_PLAYERS_ONLINE", "GRAPH_TPS_HIGH", "GRAPH_TPS_MED", "GRAPH_TPS_LOW", - "GRAPH_CPU", "GRAPH_RAM", "GRAPH_CHUNKS", "GRAPH_ENTITIES", "GRAPH_WORLD_PIE", "GRAPH_GM_PIE", - "GRAPH_ACTIVITY_PIE", "GRAPH_SERVER_PREF_PIE", "FONT_STYLESHEET", "FONT_FAMILY"); + ThemeVal[] themeVariables = new ThemeVal[]{ + RED, PINK, PURPLE, + DEEP_PURPLE, INDIGO, BLUE, LIGHT_BLUE, CYAN, TEAL, GREEN, LIGHT_GREEN, LIME, + YELLOW, AMBER, ORANGE, DEEP_ORANGE, BROWN, GREY, BLUE_GREY, BLACK, WHITE, + GRAPH_PUNCHCARD, GRAPH_PLAYERS_ONLINE, GRAPH_TPS_HIGH, GRAPH_TPS_MED, GRAPH_TPS_LOW, + GRAPH_CPU, GRAPH_RAM, GRAPH_CHUNKS, GRAPH_ENTITIES, GRAPH_WORLD_PIE, GRAPH_GM_PIE, + GRAPH_ACTIVITY_PIE, GRAPH_SERVER_PREF_PIE, FONT_STYLESHEET, FONT_FAMILY + }; for (ThemeVal variable : themeVariables) { String value = getColor(variable); String defaultValue = variable.getDefaultValue(); @@ -105,10 +99,10 @@ public class Theme implements SubSystem { replaced = replaced.replace(defaultValue, value); } } - return replaced; + return replaced.replace("${defaultTheme}", getValue(ThemeVal.THEME_DEFAULT)); } - public String getThemeValue(ThemeVal color) { + private String getThemeValue(ThemeVal color) { return config.getString(color.getThemePath()); } } diff --git a/Plan/src/main/java/com/djrapitops/plan/system/settings/theme/ThemeConfig.java b/Plan/src/main/java/com/djrapitops/plan/system/settings/theme/ThemeConfig.java index ab785faed..bc609c797 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/settings/theme/ThemeConfig.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/settings/theme/ThemeConfig.java @@ -4,14 +4,18 @@ */ package com.djrapitops.plan.system.settings.theme; -import com.djrapitops.plan.PlanPlugin; -import com.djrapitops.plan.utilities.file.FileUtil; -import com.djrapitops.plugin.api.config.Config; -import com.djrapitops.plugin.api.utility.log.Log; +import com.djrapitops.plan.system.file.PlanFiles; +import com.djrapitops.plan.system.settings.Settings; +import com.djrapitops.plan.system.settings.config.PlanConfig; +import com.djrapitops.plugin.config.Config; +import com.djrapitops.plugin.config.ConfigNode; +import com.djrapitops.plugin.logging.console.PluginLogger; +import javax.inject.Inject; +import javax.inject.Singleton; import java.io.File; -import java.io.FileNotFoundException; import java.io.IOException; +import java.util.ArrayList; import java.util.List; /** @@ -19,26 +23,35 @@ import java.util.List; * * @author Rsl1122 */ +@Singleton public class ThemeConfig extends Config { - private ThemeConfig(File file, List defaults) { - super(file, defaults); + @Inject + public ThemeConfig(PlanFiles files, PlanConfig config, PluginLogger logger) { + this(getConfigFile(files), getDefaults(files, config, logger)); } - public ThemeConfig(String fileName) throws IOException { - this(getConfigFile(), getDefaults(fileName)); - save(); + private ThemeConfig(File configFile, List defaults) { + super(configFile, defaults); + + if (defaults.isEmpty()) { + ConfigNode util = new ConfigNode("", null, ""); + for (ThemeVal themeVal : ThemeVal.values()) { + util.set(themeVal.getThemePath(), themeVal.getDefaultValue()); + } + copyDefaults(util); + } } - private static List getDefaults(String fileName) throws IOException { + private static List getDefaults(PlanFiles files, PlanConfig config, PluginLogger logger) { + String fileName = config.getString(Settings.THEME_BASE); String fileLocation = getFileLocation(fileName); - PlanPlugin plugin = PlanPlugin.getInstance(); try { - return FileUtil.lines(plugin, fileLocation); + return files.readFromResource(fileLocation); } catch (IOException e) { - Log.error("Could not find theme " + fileLocation + ". Attempting to use default."); - return FileUtil.lines(plugin, "themes/theme.yml"); + logger.error("Could not find theme " + fileLocation + ". Attempting to use default."); + return new ArrayList<>(); } } @@ -69,15 +82,7 @@ public class ThemeConfig extends Config { } } - private static File getConfigFile() throws IOException { - File folder = PlanPlugin.getInstance().getDataFolder(); - if (!folder.exists()) { - folder.mkdirs(); - } - File themeFile = new File(folder, "theme.yml"); - if (!themeFile.exists() && !themeFile.createNewFile()) { - throw new FileNotFoundException("Failed to create theme.yml"); - } - return themeFile; + private static File getConfigFile(PlanFiles files) { + return files.getFileFromPluginFolder("theme.yml"); } } diff --git a/Plan/src/main/java/com/djrapitops/plan/system/tasks/BukkitTaskSystem.java b/Plan/src/main/java/com/djrapitops/plan/system/tasks/BukkitTaskSystem.java index 1a769c767..0bd0899e8 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/tasks/BukkitTaskSystem.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/tasks/BukkitTaskSystem.java @@ -6,14 +6,20 @@ package com.djrapitops.plan.system.tasks; import com.djrapitops.plan.Plan; import com.djrapitops.plan.system.settings.Settings; -import com.djrapitops.plan.system.tasks.server.BukkitTPSCountTimer; -import com.djrapitops.plan.system.tasks.server.PaperTPSCountTimer; -import com.djrapitops.plan.system.tasks.server.PingCountTimerBukkit; +import com.djrapitops.plan.system.settings.config.PlanConfig; +import com.djrapitops.plan.system.tasks.server.BootAnalysisTask; +import com.djrapitops.plan.system.tasks.server.PeriodicAnalysisTask; +import com.djrapitops.plan.system.tasks.server.bukkit.BukkitTPSCountTimer; +import com.djrapitops.plan.system.tasks.server.bukkit.PaperTPSCountTimer; +import com.djrapitops.plan.system.tasks.server.bukkit.PingCountTimerBukkit; import com.djrapitops.plugin.api.Check; import com.djrapitops.plugin.api.TimeAmount; import com.djrapitops.plugin.task.RunnableFactory; import org.bukkit.Bukkit; +import javax.inject.Inject; +import java.util.concurrent.TimeUnit; + /** * TaskSystem responsible for registering tasks for Bukkit. * @@ -21,23 +27,42 @@ import org.bukkit.Bukkit; */ public class BukkitTaskSystem extends ServerTaskSystem { - public BukkitTaskSystem(Plan plugin) { - super(plugin, - Check.isPaperAvailable() - ? new PaperTPSCountTimer(plugin) - : new BukkitTPSCountTimer(plugin) - ); + private final Plan plugin; + private final PingCountTimerBukkit pingCountTimer; + + @Inject + public BukkitTaskSystem( + Plan plugin, + PlanConfig config, + RunnableFactory runnableFactory, + PaperTPSCountTimer paperTPSCountTimer, + BukkitTPSCountTimer bukkitTPSCountTimer, + BootAnalysisTask bootAnalysisTask, + PeriodicAnalysisTask periodicAnalysisTask, + PingCountTimerBukkit pingCountTimer, + LogsFolderCleanTask logsFolderCleanTask, + PlayersPageRefreshTask playersPageRefreshTask + ) { + super( + runnableFactory, + Check.isPaperAvailable() ? paperTPSCountTimer : bukkitTPSCountTimer, + config, + bootAnalysisTask, + periodicAnalysisTask, + logsFolderCleanTask, + playersPageRefreshTask); + this.plugin = plugin; + this.pingCountTimer = pingCountTimer; } @Override public void enable() { super.enable(); try { - PingCountTimerBukkit pingCountTimer = new PingCountTimerBukkit(); - ((Plan) plugin).registerListener(pingCountTimer); - long startDelay = TimeAmount.SECOND.ticks() * (long) Settings.PING_SERVER_ENABLE_DELAY.getNumber(); - RunnableFactory.createNew("PingCountTimer", pingCountTimer) - .runTaskTimer(startDelay, PingCountTimerBukkit.PING_INTERVAL); + plugin.registerListener(pingCountTimer); + long startDelay = TimeAmount.toTicks(config.getNumber(Settings.PING_SERVER_ENABLE_DELAY), TimeUnit.SECONDS); + registerTask("PingCountTimer", pingCountTimer) + .runTaskTimer(startDelay, 40L); } catch (ExceptionInInitializerError | NoClassDefFoundError ignore) { // Running CraftBukkit } @@ -46,6 +71,6 @@ public class BukkitTaskSystem extends ServerTaskSystem { @Override public void disable() { super.disable(); - Bukkit.getScheduler().cancelTasks((Plan) plugin); + Bukkit.getScheduler().cancelTasks(plugin); } } diff --git a/Plan/src/main/java/com/djrapitops/plan/system/tasks/BungeeTaskSystem.java b/Plan/src/main/java/com/djrapitops/plan/system/tasks/BungeeTaskSystem.java index a5cf91ab2..e209c9fe1 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/tasks/BungeeTaskSystem.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/tasks/BungeeTaskSystem.java @@ -6,14 +6,17 @@ package com.djrapitops.plan.system.tasks; import com.djrapitops.plan.PlanBungee; import com.djrapitops.plan.system.settings.Settings; -import com.djrapitops.plan.system.tasks.bungee.BungeeTPSCountTimer; -import com.djrapitops.plan.system.tasks.bungee.EnableConnectionTask; -import com.djrapitops.plan.system.tasks.server.NetworkPageRefreshTask; -import com.djrapitops.plan.system.tasks.server.PingCountTimerBungee; -import com.djrapitops.plan.utilities.file.export.HtmlExport; +import com.djrapitops.plan.system.settings.config.PlanConfig; +import com.djrapitops.plan.system.tasks.proxy.NetworkPageRefreshTask; +import com.djrapitops.plan.system.tasks.proxy.bungee.BungeeTPSCountTimer; +import com.djrapitops.plan.system.tasks.proxy.bungee.PingCountTimerBungee; import com.djrapitops.plugin.api.TimeAmount; +import com.djrapitops.plugin.task.AbsRunnable; import com.djrapitops.plugin.task.RunnableFactory; +import javax.inject.Inject; +import java.util.concurrent.TimeUnit; + /** * TaskSystem responsible for registering tasks for Bungee. * @@ -22,10 +25,30 @@ import com.djrapitops.plugin.task.RunnableFactory; public class BungeeTaskSystem extends TaskSystem { private final PlanBungee plugin; + private final PlanConfig config; + private final NetworkPageRefreshTask networkPageRefreshTask; + private final PingCountTimerBungee pingCountTimer; + private final LogsFolderCleanTask logsFolderCleanTask; + private final PlayersPageRefreshTask playersPageRefreshTask; - public BungeeTaskSystem(PlanBungee plugin) { - super(new BungeeTPSCountTimer(plugin)); + @Inject + public BungeeTaskSystem( + PlanBungee plugin, + PlanConfig config, + RunnableFactory runnableFactory, + BungeeTPSCountTimer bungeeTPSCountTimer, + NetworkPageRefreshTask networkPageRefreshTask, + PingCountTimerBungee pingCountTimer, + LogsFolderCleanTask logsFolderCleanTask, + PlayersPageRefreshTask playersPageRefreshTask) { + super(runnableFactory, bungeeTPSCountTimer); this.plugin = plugin; + this.config = config; + + this.networkPageRefreshTask = networkPageRefreshTask; + this.pingCountTimer = pingCountTimer; + this.logsFolderCleanTask = logsFolderCleanTask; + this.playersPageRefreshTask = playersPageRefreshTask; } @Override @@ -34,16 +57,21 @@ public class BungeeTaskSystem extends TaskSystem { } private void registerTasks() { - registerTask(new EnableConnectionTask()).runTaskAsynchronously(); - registerTask(tpsCountTimer).runTaskTimerAsynchronously(1000, TimeAmount.SECOND.ticks()); - registerTask(new NetworkPageRefreshTask()).runTaskTimerAsynchronously(1500, TimeAmount.MINUTE.ticks()); - if (Settings.ANALYSIS_EXPORT.isTrue()) { - registerTask(new HtmlExport(plugin)).runTaskAsynchronously(); - } - PingCountTimerBungee pingCountTimer = new PingCountTimerBungee(); + registerTask(tpsCountTimer).runTaskTimerAsynchronously(1000, TimeAmount.toTicks(1L, TimeUnit.SECONDS)); + registerTask(networkPageRefreshTask).runTaskTimerAsynchronously(1500, TimeAmount.toTicks(5L, TimeUnit.MINUTES)); + registerTask(logsFolderCleanTask).runTaskLaterAsynchronously(TimeAmount.toTicks(30L, TimeUnit.SECONDS)); + registerTask("Settings Save", new AbsRunnable() { + @Override + public void run() { + config.getNetworkSettings().placeSettingsToDB(); + } + }).runTaskAsynchronously(); + plugin.registerListener(pingCountTimer); - long startDelay = TimeAmount.SECOND.ticks() * (long) Settings.PING_SERVER_ENABLE_DELAY.getNumber(); - RunnableFactory.createNew("PingCountTimer", pingCountTimer) - .runTaskTimer(startDelay, PingCountTimerBungee.PING_INTERVAL); + long startDelay = TimeAmount.toTicks(config.getNumber(Settings.PING_SERVER_ENABLE_DELAY), TimeUnit.SECONDS); + runnableFactory.create("PingCountTimer", pingCountTimer).runTaskTimer(startDelay, PingCountTimerBungee.PING_INTERVAL); + + registerTask(playersPageRefreshTask) + .runTaskTimerAsynchronously(TimeAmount.toTicks(5L, TimeUnit.MINUTES), TimeAmount.toTicks(5L, TimeUnit.MINUTES)); } } diff --git a/Plan/src/main/java/com/djrapitops/plan/system/tasks/LogsFolderCleanTask.java b/Plan/src/main/java/com/djrapitops/plan/system/tasks/LogsFolderCleanTask.java index a8bf2bbf5..8a88ed171 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/tasks/LogsFolderCleanTask.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/tasks/LogsFolderCleanTask.java @@ -1,27 +1,41 @@ package com.djrapitops.plan.system.tasks; +import com.djrapitops.plan.system.file.PlanFiles; import com.djrapitops.plan.system.settings.Settings; -import com.djrapitops.plugin.api.TimeAmount; -import com.djrapitops.plugin.api.utility.log.Log; +import com.djrapitops.plan.system.settings.config.PlanConfig; +import com.djrapitops.plugin.logging.console.PluginLogger; import com.djrapitops.plugin.task.AbsRunnable; +import javax.inject.Inject; +import javax.inject.Singleton; import java.io.File; import java.io.IOException; import java.nio.file.Files; import java.util.Objects; +import java.util.concurrent.TimeUnit; /** * Task in charge of removing old log files * * @author Rsl1122 */ +@Singleton public class LogsFolderCleanTask extends AbsRunnable { - private final File folder; + private final int keepLogDayThreshold; - public LogsFolderCleanTask(File folder) { - super(LogsFolderCleanTask.class.getSimpleName()); - this.folder = folder; + private final File folder; + private final PluginLogger logger; + + @Inject + public LogsFolderCleanTask( + PlanFiles files, + PlanConfig config, + PluginLogger logger + ) { + this.folder = files.getLogsFolder(); + this.keepLogDayThreshold = config.getNumber(Settings.KEEP_LOGS_DAYS); + this.logger = logger; } @Override @@ -45,12 +59,12 @@ public class LogsFolderCleanTask extends AbsRunnable { private void cleanFolder() { long now = System.currentTimeMillis(); for (File file : Objects.requireNonNull(folder.listFiles())) { - long forDaysMs = Settings.KEEP_LOGS_DAYS.getNumber() * TimeAmount.DAY.ms(); - if (now - file.lastModified() > (forDaysMs > 0 ? forDaysMs : TimeAmount.DAY.ms())) { + long forDaysMs = TimeUnit.DAYS.toMillis(keepLogDayThreshold); + if (now - file.lastModified() > (forDaysMs > 0 ? forDaysMs : TimeUnit.DAYS.toMillis(1L))) { try { Files.delete(file.toPath()); } catch (IOException e) { - Log.warn("Could not delete log file at: " + file.getAbsolutePath() + ", " + e.getMessage()); + logger.warn("Could not delete log file at: " + file.getAbsolutePath() + ", " + e.getMessage()); } } } diff --git a/Plan/src/main/java/com/djrapitops/plan/system/tasks/PlayersPageRefreshTask.java b/Plan/src/main/java/com/djrapitops/plan/system/tasks/PlayersPageRefreshTask.java new file mode 100644 index 000000000..0d87243cd --- /dev/null +++ b/Plan/src/main/java/com/djrapitops/plan/system/tasks/PlayersPageRefreshTask.java @@ -0,0 +1,21 @@ +package com.djrapitops.plan.system.tasks; + +import com.djrapitops.plan.system.webserver.cache.PageId; +import com.djrapitops.plan.system.webserver.cache.ResponseCache; +import com.djrapitops.plugin.task.AbsRunnable; + +import javax.inject.Inject; +import javax.inject.Singleton; + +@Singleton +public class PlayersPageRefreshTask extends AbsRunnable { + + @Inject + public PlayersPageRefreshTask() { + } + + @Override + public void run() { + ResponseCache.clearResponse(PageId.PLAYERS.id()); + } +} diff --git a/Plan/src/main/java/com/djrapitops/plan/system/tasks/ServerTaskSystem.java b/Plan/src/main/java/com/djrapitops/plan/system/tasks/ServerTaskSystem.java index c757da73d..8d2679a52 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/tasks/ServerTaskSystem.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/tasks/ServerTaskSystem.java @@ -1,29 +1,42 @@ package com.djrapitops.plan.system.tasks; -import com.djrapitops.plan.PlanPlugin; import com.djrapitops.plan.system.settings.Settings; +import com.djrapitops.plan.system.settings.config.PlanConfig; import com.djrapitops.plan.system.tasks.server.BootAnalysisTask; -import com.djrapitops.plan.system.tasks.server.NetworkPageRefreshTask; import com.djrapitops.plan.system.tasks.server.PeriodicAnalysisTask; -import com.djrapitops.plan.utilities.file.export.HtmlExport; -import com.djrapitops.plugin.api.Benchmark; import com.djrapitops.plugin.api.TimeAmount; -import com.djrapitops.plugin.task.ITask; +import com.djrapitops.plugin.task.AbsRunnable; import com.djrapitops.plugin.task.RunnableFactory; +import java.util.concurrent.TimeUnit; + /** * Abstracted TaskSystem implementation for both Bukkit and Sponge. * * @author Rsl1122 */ -public class ServerTaskSystem extends TaskSystem { +public abstract class ServerTaskSystem extends TaskSystem { - protected final PlanPlugin plugin; - protected ITask bootAnalysisTask; + protected final PlanConfig config; + private final BootAnalysisTask bootAnalysisTask; + private final PeriodicAnalysisTask periodicAnalysisTask; + private final LogsFolderCleanTask logsFolderCleanTask; + private final PlayersPageRefreshTask playersPageRefreshTask; - public ServerTaskSystem(PlanPlugin plugin, TPSCountTimer tpsCountTimer) { - super(tpsCountTimer); - this.plugin = plugin; + public ServerTaskSystem( + RunnableFactory runnableFactory, + TPSCountTimer tpsCountTimer, + PlanConfig config, + BootAnalysisTask bootAnalysisTask, + PeriodicAnalysisTask periodicAnalysisTask, + LogsFolderCleanTask logsFolderCleanTask, + PlayersPageRefreshTask playersPageRefreshTask) { + super(runnableFactory, tpsCountTimer); + this.config = config; + this.bootAnalysisTask = bootAnalysisTask; + this.periodicAnalysisTask = periodicAnalysisTask; + this.logsFolderCleanTask = logsFolderCleanTask; + this.playersPageRefreshTask = playersPageRefreshTask; } @Override @@ -32,34 +45,26 @@ public class ServerTaskSystem extends TaskSystem { } private void registerTasks() { - Benchmark.start("Task Registration"); - // Analysis refresh settings - int analysisRefreshMinutes = Settings.ANALYSIS_AUTO_REFRESH.getNumber(); + int analysisRefreshMinutes = config.getNumber(Settings.ANALYSIS_AUTO_REFRESH); boolean analysisRefreshTaskIsEnabled = analysisRefreshMinutes > 0; - long analysisPeriod = analysisRefreshMinutes * TimeAmount.MINUTE.ticks(); + long analysisPeriod = TimeAmount.toTicks(analysisRefreshMinutes, TimeUnit.MINUTES); - registerTask(tpsCountTimer).runTaskTimer(1000, TimeAmount.SECOND.ticks()); - registerTask(new NetworkPageRefreshTask()).runTaskTimerAsynchronously(20L, 5L * TimeAmount.MINUTE.ticks()); - bootAnalysisTask = registerTask(new BootAnalysisTask()).runTaskLaterAsynchronously(30L * TimeAmount.SECOND.ticks()); + registerTask(tpsCountTimer).runTaskTimer(1000, TimeAmount.toTicks(1L, TimeUnit.SECONDS)); + registerTask(bootAnalysisTask).runTaskLaterAsynchronously(TimeAmount.toTicks(30L, TimeUnit.SECONDS)); if (analysisRefreshTaskIsEnabled) { - registerTask(new PeriodicAnalysisTask()).runTaskTimerAsynchronously(analysisPeriod, analysisPeriod); + registerTask(periodicAnalysisTask).runTaskTimerAsynchronously(analysisPeriod, analysisPeriod); } - if (Settings.ANALYSIS_EXPORT.isTrue()) { - RunnableFactory.createNew(new HtmlExport(plugin)).runTaskAsynchronously(); - } - Benchmark.stop("Enable", "Task Registration"); - } - public void cancelBootAnalysis() { - try { - if (bootAnalysisTask != null) { - bootAnalysisTask.cancel(); - bootAnalysisTask = null; + registerTask(logsFolderCleanTask).runTaskLaterAsynchronously(TimeAmount.toTicks(30L, TimeUnit.SECONDS)); + registerTask("Settings Load", new AbsRunnable() { + @Override + public void run() { + config.getNetworkSettings().loadSettingsFromDB(); } - } catch (Exception ignored) { - /* Ignored */ - } + }).runTaskAsynchronously(); + registerTask(playersPageRefreshTask) + .runTaskTimerAsynchronously(TimeAmount.toTicks(5L, TimeUnit.MINUTES), TimeAmount.toTicks(5L, TimeUnit.MINUTES)); } } \ No newline at end of file diff --git a/Plan/src/main/java/com/djrapitops/plan/system/tasks/SpongeTaskSystem.java b/Plan/src/main/java/com/djrapitops/plan/system/tasks/SpongeTaskSystem.java index 229e1dc5f..a597813ba 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/tasks/SpongeTaskSystem.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/tasks/SpongeTaskSystem.java @@ -2,36 +2,62 @@ package com.djrapitops.plan.system.tasks; import com.djrapitops.plan.PlanSponge; import com.djrapitops.plan.system.settings.Settings; -import com.djrapitops.plan.system.tasks.server.PingCountTimerSponge; -import com.djrapitops.plan.system.tasks.server.SpongeTPSCountTimer; +import com.djrapitops.plan.system.settings.config.PlanConfig; +import com.djrapitops.plan.system.tasks.server.BootAnalysisTask; +import com.djrapitops.plan.system.tasks.server.PeriodicAnalysisTask; +import com.djrapitops.plan.system.tasks.server.sponge.PingCountTimerSponge; +import com.djrapitops.plan.system.tasks.server.sponge.SpongeTPSCountTimer; import com.djrapitops.plugin.api.TimeAmount; import com.djrapitops.plugin.task.RunnableFactory; import org.spongepowered.api.Sponge; import org.spongepowered.api.scheduler.Task; +import javax.inject.Inject; +import java.util.concurrent.TimeUnit; + public class SpongeTaskSystem extends ServerTaskSystem { - private final PlanSponge planSponge; + private final PlanSponge plugin; + private final PingCountTimerSponge pingCountTimer; - public SpongeTaskSystem(PlanSponge plugin) { - super(plugin, new SpongeTPSCountTimer(plugin)); - this.planSponge = plugin; + @Inject + public SpongeTaskSystem( + PlanSponge plugin, + PlanConfig config, + RunnableFactory runnableFactory, + SpongeTPSCountTimer spongeTPSCountTimer, + BootAnalysisTask bootAnalysisTask, + PeriodicAnalysisTask periodicAnalysisTask, + PingCountTimerSponge pingCountTimer, + LogsFolderCleanTask logsFolderCleanTask, + PlayersPageRefreshTask playersPageRefreshTask + ) { + super( + runnableFactory, + spongeTPSCountTimer, + config, + bootAnalysisTask, + periodicAnalysisTask, + logsFolderCleanTask, + playersPageRefreshTask); + this.plugin = plugin; + this.pingCountTimer = pingCountTimer; } - + @Override public void enable() { super.enable(); - PingCountTimerSponge pingCountTimer = new PingCountTimerSponge(); - planSponge.registerListener(pingCountTimer); - long startDelay = TimeAmount.SECOND.ticks() * (long) Settings.PING_SERVER_ENABLE_DELAY.getNumber(); - RunnableFactory.createNew("PingCountTimer", pingCountTimer) + + plugin.registerListener(pingCountTimer); + long startDelay = TimeAmount.toTicks(config.getNumber(Settings.PING_SERVER_ENABLE_DELAY), TimeUnit.SECONDS); + runnableFactory.create("PingCountTimer", pingCountTimer) .runTaskTimer(startDelay, PingCountTimerSponge.PING_INTERVAL); } @Override public void disable() { super.disable(); - for (Task task : Sponge.getScheduler().getScheduledTasks(planSponge)) { + for (Task task : Sponge.getScheduler().getScheduledTasks(plugin)) { task.cancel(); } } diff --git a/Plan/src/main/java/com/djrapitops/plan/system/tasks/TPSCountTimer.java b/Plan/src/main/java/com/djrapitops/plan/system/tasks/TPSCountTimer.java index 93fe4cd32..100577b0d 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/tasks/TPSCountTimer.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/tasks/TPSCountTimer.java @@ -1,12 +1,14 @@ package com.djrapitops.plan.system.tasks; -import com.djrapitops.plan.PlanPlugin; import com.djrapitops.plan.data.container.TPS; import com.djrapitops.plan.system.processing.Processing; -import com.djrapitops.plan.system.processing.processors.TPSInsertProcessor; -import com.djrapitops.plugin.api.utility.log.Log; +import com.djrapitops.plan.system.processing.processors.Processors; +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.io.File; import java.lang.management.ManagementFactory; import java.lang.management.OperatingSystemMXBean; import java.util.ArrayList; @@ -17,16 +19,29 @@ import java.util.List; * * @author Rsl1122 */ -public abstract class TPSCountTimer extends AbsRunnable { +public abstract class TPSCountTimer extends AbsRunnable { - protected final T plugin; protected final List history; + protected final Processors processors; + protected final Processing processing; + protected final PluginLogger logger; + protected final ErrorHandler errorHandler; + + private boolean diskErrored = false; + protected int latestPlayersOnline = 0; - public TPSCountTimer(T plugin) { - super("TPSCountTimer"); - this.plugin = plugin; + public TPSCountTimer( + Processors processors, + Processing processing, + PluginLogger logger, + ErrorHandler errorHandler + ) { + this.processors = processors; + this.processing = processing; + this.logger = logger; + this.errorHandler = errorHandler; history = new ArrayList<>(); } @@ -39,12 +54,12 @@ public abstract class TPSCountTimer extends AbsRunnable { addNewTPSEntry(nanoTime, now); if (history.size() >= 60) { - Processing.submit(new TPSInsertProcessor(new ArrayList<>(history))); + processing.submit(processors.tpsInsertProcessor(new ArrayList<>(history))); history.clear(); } } catch (Exception | NoClassDefFoundError | NoSuchMethodError | NoSuchFieldError e) { - Log.error("TPS Count Task Disabled due to error, reload Plan to re-enable."); - Log.toLog(this.getClass(), e); + logger.error("TPS Count Task Disabled due to error, reload Plan to re-enable."); + errorHandler.log(L.ERROR, this.getClass(), e); cancel(); } } @@ -77,4 +92,17 @@ public abstract class TPSCountTimer extends AbsRunnable { } return averageCPUUsage * 100.0; } + + protected long getFreeDiskSpace() { + try { + File file = new File(new File("").getAbsolutePath()); + return file.getFreeSpace() / 1000000L; + } catch (SecurityException noPermission) { + if (!diskErrored) { + errorHandler.log(L.WARN, this.getClass(), noPermission); + } + diskErrored = true; + return -1; + } + } } diff --git a/Plan/src/main/java/com/djrapitops/plan/system/tasks/TaskSystem.java b/Plan/src/main/java/com/djrapitops/plan/system/tasks/TaskSystem.java index a35235548..883b17901 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/tasks/TaskSystem.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/tasks/TaskSystem.java @@ -4,11 +4,9 @@ */ package com.djrapitops.plan.system.tasks; -import com.djrapitops.plan.PlanPlugin; import com.djrapitops.plan.system.SubSystem; -import com.djrapitops.plugin.api.systems.TaskCenter; import com.djrapitops.plugin.task.AbsRunnable; -import com.djrapitops.plugin.task.IRunnable; +import com.djrapitops.plugin.task.PluginRunnable; import com.djrapitops.plugin.task.RunnableFactory; /** @@ -20,24 +18,26 @@ import com.djrapitops.plugin.task.RunnableFactory; */ public abstract class TaskSystem implements SubSystem { - protected TPSCountTimer tpsCountTimer; + protected final TPSCountTimer tpsCountTimer; + protected final RunnableFactory runnableFactory; - public TaskSystem(TPSCountTimer tpsCountTimer) { + public TaskSystem(RunnableFactory runnableFactory, TPSCountTimer tpsCountTimer) { this.tpsCountTimer = tpsCountTimer; + this.runnableFactory = runnableFactory; } - protected IRunnable registerTask(AbsRunnable runnable) { - String taskName = runnable.getName(); - return registerTask(taskName != null ? taskName : runnable.getClass().getSimpleName(), runnable); + protected PluginRunnable registerTask(AbsRunnable runnable) { + String taskName = runnable.getClass().getSimpleName(); + return registerTask(taskName, runnable); } - protected IRunnable registerTask(String name, AbsRunnable runnable) { - return RunnableFactory.createNew(name, runnable); + protected PluginRunnable registerTask(String name, AbsRunnable runnable) { + return runnableFactory.create(name, runnable); } @Override public void disable() { - TaskCenter.cancelAllKnownTasks(PlanPlugin.getInstance().getClass()); + runnableFactory.cancelAllKnownTasks(); } } diff --git a/Plan/src/main/java/com/djrapitops/plan/system/tasks/VelocityTaskSystem.java b/Plan/src/main/java/com/djrapitops/plan/system/tasks/VelocityTaskSystem.java new file mode 100644 index 000000000..73890b8c1 --- /dev/null +++ b/Plan/src/main/java/com/djrapitops/plan/system/tasks/VelocityTaskSystem.java @@ -0,0 +1,78 @@ +/* + * License is provided in the jar as LICENSE also here: + * https://github.com/Rsl1122/Plan-PlayerAnalytics/blob/master/Plan/src/main/resources/LICENSE + */ +package com.djrapitops.plan.system.tasks; + +import com.djrapitops.plan.PlanVelocity; +import com.djrapitops.plan.system.settings.Settings; +import com.djrapitops.plan.system.settings.config.PlanConfig; +import com.djrapitops.plan.system.tasks.proxy.NetworkPageRefreshTask; +import com.djrapitops.plan.system.tasks.proxy.bungee.PingCountTimerBungee; +import com.djrapitops.plan.system.tasks.proxy.velocity.PingCountTimerVelocity; +import com.djrapitops.plan.system.tasks.proxy.velocity.VelocityTPSCountTimer; +import com.djrapitops.plugin.api.TimeAmount; +import com.djrapitops.plugin.task.AbsRunnable; +import com.djrapitops.plugin.task.RunnableFactory; + +import javax.inject.Inject; +import java.util.concurrent.TimeUnit; + +/** + * TaskSystem responsible for registering tasks for Velocity. + * + * @author Rsl1122 + */ +public class VelocityTaskSystem extends TaskSystem { + + private final PlanVelocity plugin; + private final PlanConfig config; + private final NetworkPageRefreshTask networkPageRefreshTask; + private final PingCountTimerVelocity pingCountTimer; + private final LogsFolderCleanTask logsFolderCleanTask; + private final PlayersPageRefreshTask playersPageRefreshTask; + + @Inject + public VelocityTaskSystem( + PlanVelocity plugin, + PlanConfig config, + RunnableFactory runnableFactory, + VelocityTPSCountTimer velocityTPSCountTimer, + NetworkPageRefreshTask networkPageRefreshTask, + PingCountTimerVelocity pingCountTimer, + LogsFolderCleanTask logsFolderCleanTask, + PlayersPageRefreshTask playersPageRefreshTask) { + super(runnableFactory, velocityTPSCountTimer); + this.plugin = plugin; + this.config = config; + + this.networkPageRefreshTask = networkPageRefreshTask; + this.pingCountTimer = pingCountTimer; + this.logsFolderCleanTask = logsFolderCleanTask; + this.playersPageRefreshTask = playersPageRefreshTask; + } + + @Override + public void enable() { + registerTasks(); + } + + private void registerTasks() { + registerTask(tpsCountTimer).runTaskTimerAsynchronously(1000, TimeAmount.toTicks(1L, TimeUnit.SECONDS)); + registerTask(networkPageRefreshTask).runTaskTimerAsynchronously(1500, TimeAmount.toTicks(5L, TimeUnit.MINUTES)); + registerTask(logsFolderCleanTask).runTaskLaterAsynchronously(TimeAmount.toTicks(30L, TimeUnit.SECONDS)); + registerTask("Settings Save", new AbsRunnable() { + @Override + public void run() { + config.getNetworkSettings().placeSettingsToDB(); + } + }).runTaskAsynchronously(); + + plugin.registerListener(pingCountTimer); + long startDelay = TimeAmount.toTicks(config.getNumber(Settings.PING_SERVER_ENABLE_DELAY), TimeUnit.SECONDS); + runnableFactory.create("PingCountTimer", pingCountTimer).runTaskTimer(startDelay, PingCountTimerBungee.PING_INTERVAL); + + registerTask(playersPageRefreshTask) + .runTaskTimerAsynchronously(TimeAmount.toTicks(5L, TimeUnit.MINUTES), TimeAmount.toTicks(5L, TimeUnit.MINUTES)); + } +} diff --git a/Plan/src/main/java/com/djrapitops/plan/system/tasks/bungee/BungeeTPSCountTimer.java b/Plan/src/main/java/com/djrapitops/plan/system/tasks/bungee/BungeeTPSCountTimer.java deleted file mode 100644 index dda2d8233..000000000 --- a/Plan/src/main/java/com/djrapitops/plan/system/tasks/bungee/BungeeTPSCountTimer.java +++ /dev/null @@ -1,31 +0,0 @@ -package com.djrapitops.plan.system.tasks.bungee; - -import com.djrapitops.plan.PlanBungee; -import com.djrapitops.plan.data.container.TPS; -import com.djrapitops.plan.data.container.builders.TPSBuilder; -import com.djrapitops.plan.system.info.server.ServerInfo; -import com.djrapitops.plan.system.tasks.TPSCountTimer; - -public class BungeeTPSCountTimer extends TPSCountTimer { - - public BungeeTPSCountTimer(PlanBungee plugin) { - super(plugin); - } - - @Override - public void addNewTPSEntry(long nanoTime, long now) { - int onlineCount = ServerInfo.getServerProperties().getOnlinePlayers(); - TPS tps = TPSBuilder.get() - .date(now) - .skipTPS() - .playersOnline(onlineCount) - .usedCPU(getCPUUsage()) - .usedMemory(getUsedMemory()) - .entities(-1) - .chunksLoaded(-1) - .toTPS(); - - history.add(tps); - latestPlayersOnline = onlineCount; - } -} diff --git a/Plan/src/main/java/com/djrapitops/plan/system/tasks/bungee/EnableConnectionTask.java b/Plan/src/main/java/com/djrapitops/plan/system/tasks/bungee/EnableConnectionTask.java deleted file mode 100644 index 33204938b..000000000 --- a/Plan/src/main/java/com/djrapitops/plan/system/tasks/bungee/EnableConnectionTask.java +++ /dev/null @@ -1,21 +0,0 @@ -package com.djrapitops.plan.system.tasks.bungee; - -import com.djrapitops.plan.system.info.connection.ConnectionSystem; -import com.djrapitops.plan.system.info.connection.WebExceptionLogger; -import com.djrapitops.plan.system.info.request.GenerateNetworkPageContentRequest; -import com.djrapitops.plugin.task.AbsRunnable; - -public class EnableConnectionTask extends AbsRunnable { - - public EnableConnectionTask() { - super(EnableConnectionTask.class.getSimpleName()); - } - - @Override - public void run() { - WebExceptionLogger.logIfOccurs(this.getClass(), - () -> ConnectionSystem.getInstance().sendWideInfoRequest(new GenerateNetworkPageContentRequest()) - ); - cancel(); - } -} diff --git a/Plan/src/main/java/com/djrapitops/plan/system/tasks/proxy/NetworkPageRefreshTask.java b/Plan/src/main/java/com/djrapitops/plan/system/tasks/proxy/NetworkPageRefreshTask.java new file mode 100644 index 000000000..ccb9e46de --- /dev/null +++ b/Plan/src/main/java/com/djrapitops/plan/system/tasks/proxy/NetworkPageRefreshTask.java @@ -0,0 +1,25 @@ +package com.djrapitops.plan.system.tasks.proxy; + +import com.djrapitops.plan.system.info.server.ServerInfo; +import com.djrapitops.plan.system.webserver.cache.PageId; +import com.djrapitops.plan.system.webserver.cache.ResponseCache; +import com.djrapitops.plugin.task.AbsRunnable; + +import javax.inject.Inject; +import javax.inject.Singleton; + +@Singleton +public class NetworkPageRefreshTask extends AbsRunnable { + + private final ServerInfo serverInfo; + + @Inject + public NetworkPageRefreshTask(ServerInfo serverInfo) { + this.serverInfo = serverInfo; + } + + @Override + public void run() { + ResponseCache.clearResponse(PageId.SERVER.of(serverInfo.getServerUUID())); + } +} diff --git a/Plan/src/main/java/com/djrapitops/plan/system/tasks/proxy/bungee/BungeeTPSCountTimer.java b/Plan/src/main/java/com/djrapitops/plan/system/tasks/proxy/bungee/BungeeTPSCountTimer.java new file mode 100644 index 000000000..6a39fc152 --- /dev/null +++ b/Plan/src/main/java/com/djrapitops/plan/system/tasks/proxy/bungee/BungeeTPSCountTimer.java @@ -0,0 +1,49 @@ +package com.djrapitops.plan.system.tasks.proxy.bungee; + +import com.djrapitops.plan.data.container.TPS; +import com.djrapitops.plan.data.container.builders.TPSBuilder; +import com.djrapitops.plan.system.info.server.properties.ServerProperties; +import com.djrapitops.plan.system.processing.Processing; +import com.djrapitops.plan.system.processing.processors.Processors; +import com.djrapitops.plan.system.tasks.TPSCountTimer; +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 BungeeTPSCountTimer extends TPSCountTimer { + + private final ServerProperties serverProperties; + + @Inject + public BungeeTPSCountTimer( + Processors processors, + Processing processing, + ServerProperties serverProperties, + PluginLogger logger, + ErrorHandler errorHandler + ) { + super(processors, processing, logger, errorHandler); + this.serverProperties = serverProperties; + } + + @Override + public void addNewTPSEntry(long nanoTime, long now) { + int onlineCount = serverProperties.getOnlinePlayers(); + TPS tps = TPSBuilder.get() + .date(now) + .skipTPS() + .playersOnline(onlineCount) + .usedCPU(getCPUUsage()) + .usedMemory(getUsedMemory()) + .entities(-1) + .chunksLoaded(-1) + .freeDiskSpace(getFreeDiskSpace()) + .toTPS(); + + history.add(tps); + latestPlayersOnline = onlineCount; + } +} diff --git a/Plan/src/main/java/com/djrapitops/plan/system/tasks/server/PingCountTimerBungee.java b/Plan/src/main/java/com/djrapitops/plan/system/tasks/proxy/bungee/PingCountTimerBungee.java similarity index 68% rename from Plan/src/main/java/com/djrapitops/plan/system/tasks/server/PingCountTimerBungee.java rename to Plan/src/main/java/com/djrapitops/plan/system/tasks/proxy/bungee/PingCountTimerBungee.java index cb24e2aa5..28ab8c190 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/tasks/server/PingCountTimerBungee.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/tasks/proxy/bungee/PingCountTimerBungee.java @@ -21,12 +21,13 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -package com.djrapitops.plan.system.tasks.server; +package com.djrapitops.plan.system.tasks.proxy.bungee; import com.djrapitops.plan.data.store.objects.DateObj; import com.djrapitops.plan.system.processing.Processing; -import com.djrapitops.plan.system.processing.processors.player.PingInsertProcessor; +import com.djrapitops.plan.system.processing.processors.Processors; import com.djrapitops.plan.system.settings.Settings; +import com.djrapitops.plan.system.settings.config.PlanConfig; import com.djrapitops.plugin.api.TimeAmount; import com.djrapitops.plugin.task.AbsRunnable; import com.djrapitops.plugin.task.RunnableFactory; @@ -36,43 +37,70 @@ import net.md_5.bungee.api.event.ServerConnectedEvent; import net.md_5.bungee.api.event.ServerDisconnectEvent; import net.md_5.bungee.api.plugin.Listener; import net.md_5.bungee.event.EventHandler; + +import javax.inject.Inject; +import javax.inject.Singleton; import java.util.*; +import java.util.concurrent.TimeUnit; /** * Task that handles player ping calculation on Bungee based servers. * * @author BrainStone */ +@Singleton public class PingCountTimerBungee extends AbsRunnable implements Listener { //the server is pinging the client every 40 Ticks (2 sec) - so check it then //https://github.com/bergerkiller/CraftSource/blob/master/net.minecraft.server/PlayerConnection.java#L178 public static final int PING_INTERVAL = 2 * 20; - private final Map>> playerHistory = new HashMap<>(); + private final Map>> playerHistory; + + private final PlanConfig config; + private final Processors processors; + private final Processing processing; + private final RunnableFactory runnableFactory; + + @Inject + public PingCountTimerBungee( + PlanConfig config, + Processors processors, + Processing processing, + RunnableFactory runnableFactory + ) { + this.config = config; + this.processors = processors; + this.processing = processing; + this.runnableFactory = runnableFactory; + playerHistory = new HashMap<>(); + } @Override public void run() { - List loggedOut = new ArrayList<>(); long time = System.currentTimeMillis(); - playerHistory.forEach((uuid, history) -> { + Iterator>>> iterator = playerHistory.entrySet().iterator(); + + while (iterator.hasNext()) { + Map.Entry>> entry = iterator.next(); + UUID uuid = entry.getKey(); + List> history = entry.getValue(); ProxiedPlayer player = ProxyServer.getInstance().getPlayer(uuid); if (player != null) { int ping = getPing(player); - if (ping < -1 || ping > TimeAmount.SECOND.ms() * 8L) { + if (ping < -1 || ping > TimeUnit.SECONDS.toMillis(8L)) { // Don't accept bad values - return; + continue; } history.add(new DateObj<>(time, ping)); if (history.size() >= 30) { - Processing.submit(new PingInsertProcessor(uuid, new ArrayList<>(history))); + processing.submit(processors.player().pingInsertProcessor(uuid, new ArrayList<>(history))); history.clear(); } } else { - loggedOut.add(uuid); + iterator.remove(); } - }); - loggedOut.forEach(playerHistory::remove); + } } public void addPlayer(ProxiedPlayer player) { @@ -90,14 +118,14 @@ public class PingCountTimerBungee extends AbsRunnable implements Listener { @EventHandler public void onPlayerJoin(ServerConnectedEvent joinEvent) { ProxiedPlayer player = joinEvent.getPlayer(); - RunnableFactory.createNew("Add Player to Ping list", new AbsRunnable() { + runnableFactory.create("Add Player to Ping list", new AbsRunnable() { @Override public void run() { if (player.isConnected()) { addPlayer(player); } } - }).runTaskLater(TimeAmount.SECOND.ticks() * (long) Settings.PING_PLAYER_LOGIN_DELAY.getNumber()); + }).runTaskLater(TimeAmount.toTicks(config.getNumber(Settings.PING_PLAYER_LOGIN_DELAY), TimeUnit.SECONDS)); } @EventHandler diff --git a/Plan/src/main/java/com/djrapitops/plan/system/tasks/proxy/velocity/PingCountTimerVelocity.java b/Plan/src/main/java/com/djrapitops/plan/system/tasks/proxy/velocity/PingCountTimerVelocity.java new file mode 100644 index 000000000..58d0d535d --- /dev/null +++ b/Plan/src/main/java/com/djrapitops/plan/system/tasks/proxy/velocity/PingCountTimerVelocity.java @@ -0,0 +1,143 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2016-2018 + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package com.djrapitops.plan.system.tasks.proxy.velocity; + +import com.djrapitops.plan.PlanVelocity; +import com.djrapitops.plan.data.store.objects.DateObj; +import com.djrapitops.plan.system.processing.Processing; +import com.djrapitops.plan.system.processing.processors.Processors; +import com.djrapitops.plan.system.settings.Settings; +import com.djrapitops.plan.system.settings.config.PlanConfig; +import com.djrapitops.plugin.api.TimeAmount; +import com.djrapitops.plugin.task.AbsRunnable; +import com.djrapitops.plugin.task.RunnableFactory; +import com.velocitypowered.api.event.Subscribe; +import com.velocitypowered.api.event.connection.DisconnectEvent; +import com.velocitypowered.api.event.player.ServerConnectedEvent; +import com.velocitypowered.api.proxy.Player; + +import javax.inject.Inject; +import javax.inject.Singleton; +import java.util.*; +import java.util.concurrent.TimeUnit; + +/** + * Task that handles player ping calculation on Velocity based servers. + *

+ * Based on PingCountTimerBungee + * + * @author MicleBrick + */ +@Singleton +public class PingCountTimerVelocity extends AbsRunnable { + + //the server is pinging the client every 40 Ticks (2 sec) - so check it then + //https://github.com/bergerkiller/CraftSource/blob/master/net.minecraft.server/PlayerConnection.java#L178 + public static final int PING_INTERVAL = 2 * 20; + + final Map>> playerHistory; + + private final PlanVelocity plugin; + private final PlanConfig config; + private final Processors processors; + private final Processing processing; + private final RunnableFactory runnableFactory; + + @Inject + public PingCountTimerVelocity( + PlanVelocity plugin, + PlanConfig config, + Processors processors, + Processing processing, + RunnableFactory runnableFactory + ) { + this.plugin = plugin; + this.config = config; + this.processors = processors; + this.processing = processing; + this.runnableFactory = runnableFactory; + playerHistory = new HashMap<>(); + } + + @Override + public void run() { + long time = System.currentTimeMillis(); + Iterator>>> iterator = playerHistory.entrySet().iterator(); + + while (iterator.hasNext()) { + Map.Entry>> entry = iterator.next(); + UUID uuid = entry.getKey(); + List> history = entry.getValue(); + Player player = plugin.getProxy().getPlayer(uuid).orElse(null); + if (player != null) { + int ping = getPing(player); + if (ping < -1 || ping > TimeUnit.SECONDS.toMillis(8L)) { + // Don't accept bad values + continue; + } + history.add(new DateObj<>(time, ping)); + if (history.size() >= 30) { + processing.submit(processors.player().pingInsertProcessor(uuid, new ArrayList<>(history))); + history.clear(); + } + } else { + iterator.remove(); + } + } + } + + void addPlayer(Player player) { + playerHistory.put(player.getUniqueId(), new ArrayList<>()); + } + + public void removePlayer(Player player) { + playerHistory.remove(player.getUniqueId()); + } + + private int getPing(Player player) { + return (int) player.getPing(); + } + + @Subscribe + public void onPlayerJoin(ServerConnectedEvent joinEvent) { + Player player = joinEvent.getPlayer(); + runnableFactory.create("Add Player to Ping list", new AbsRunnable() { + @Override + public void run() { + if (player.isActive()) { + addPlayer(player); + } + } + }).runTaskLater(TimeAmount.toTicks(config.getNumber(Settings.PING_PLAYER_LOGIN_DELAY), TimeUnit.SECONDS)); + } + + @Subscribe + public void onPlayerQuit(DisconnectEvent quitEvent) { + removePlayer(quitEvent.getPlayer()); + } + + public void clear() { + playerHistory.clear(); + } +} diff --git a/Plan/src/main/java/com/djrapitops/plan/system/tasks/proxy/velocity/VelocityTPSCountTimer.java b/Plan/src/main/java/com/djrapitops/plan/system/tasks/proxy/velocity/VelocityTPSCountTimer.java new file mode 100644 index 000000000..d0fcbe4ce --- /dev/null +++ b/Plan/src/main/java/com/djrapitops/plan/system/tasks/proxy/velocity/VelocityTPSCountTimer.java @@ -0,0 +1,49 @@ +package com.djrapitops.plan.system.tasks.proxy.velocity; + +import com.djrapitops.plan.data.container.TPS; +import com.djrapitops.plan.data.container.builders.TPSBuilder; +import com.djrapitops.plan.system.info.server.properties.ServerProperties; +import com.djrapitops.plan.system.processing.Processing; +import com.djrapitops.plan.system.processing.processors.Processors; +import com.djrapitops.plan.system.tasks.TPSCountTimer; +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 VelocityTPSCountTimer extends TPSCountTimer { + + private final ServerProperties serverProperties; + + @Inject + public VelocityTPSCountTimer( + Processors processors, + Processing processing, + ServerProperties serverProperties, + PluginLogger logger, + ErrorHandler errorHandler + ) { + super(processors, processing, logger, errorHandler); + this.serverProperties = serverProperties; + } + + @Override + public void addNewTPSEntry(long nanoTime, long now) { + int onlineCount = serverProperties.getOnlinePlayers(); + TPS tps = TPSBuilder.get() + .date(now) + .skipTPS() + .playersOnline(onlineCount) + .usedCPU(getCPUUsage()) + .usedMemory(getUsedMemory()) + .entities(-1) + .chunksLoaded(-1) + .freeDiskSpace(getFreeDiskSpace()) + .toTPS(); + + history.add(tps); + latestPlayersOnline = onlineCount; + } +} diff --git a/Plan/src/main/java/com/djrapitops/plan/system/tasks/server/BootAnalysisTask.java b/Plan/src/main/java/com/djrapitops/plan/system/tasks/server/BootAnalysisTask.java index 7c1277a1c..9b67bf264 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/tasks/server/BootAnalysisTask.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/tasks/server/BootAnalysisTask.java @@ -1,29 +1,43 @@ package com.djrapitops.plan.system.tasks.server; -import com.djrapitops.plan.PlanPlugin; import com.djrapitops.plan.system.info.InfoSystem; import com.djrapitops.plan.system.info.connection.WebExceptionLogger; -import com.djrapitops.plan.system.info.request.GenerateAnalysisPageRequest; +import com.djrapitops.plan.system.info.request.InfoRequestFactory; import com.djrapitops.plan.system.info.server.ServerInfo; -import com.djrapitops.plugin.api.utility.log.Log; import com.djrapitops.plugin.task.AbsRunnable; +import javax.inject.Inject; +import javax.inject.Singleton; + +@Singleton public class BootAnalysisTask extends AbsRunnable { - public BootAnalysisTask() { - super(BootAnalysisTask.class.getSimpleName()); + private final InfoSystem infoSystem; + private final InfoRequestFactory infoRequestFactory; + private final ServerInfo serverInfo; + private final WebExceptionLogger webExceptionLogger; + + @Inject + public BootAnalysisTask( + InfoSystem infoSystem, + InfoRequestFactory infoRequestFactory, + ServerInfo serverInfo, + WebExceptionLogger webExceptionLogger + ) { + this.infoSystem = infoSystem; + this.infoRequestFactory = infoRequestFactory; + this.serverInfo = serverInfo; + this.webExceptionLogger = webExceptionLogger; } @Override public void run() { try { - WebExceptionLogger.logIfOccurs(this.getClass(), () -> - InfoSystem.getInstance().sendRequest(new GenerateAnalysisPageRequest(ServerInfo.getServerUUID())) + webExceptionLogger.logIfOccurs(this.getClass(), () -> + infoSystem.sendRequest(infoRequestFactory.generateAnalysisPageRequest(serverInfo.getServerUUID())) ); - } catch (IllegalStateException e) { - if (!PlanPlugin.getInstance().isReloading()) { - Log.toLog(this.getClass(), e); - } + } catch (IllegalStateException ignore) { + /* Plugin was reloading */ } finally { cancel(); } diff --git a/Plan/src/main/java/com/djrapitops/plan/system/tasks/server/BukkitTPSCountTimer.java b/Plan/src/main/java/com/djrapitops/plan/system/tasks/server/BukkitTPSCountTimer.java deleted file mode 100644 index 1017dea99..000000000 --- a/Plan/src/main/java/com/djrapitops/plan/system/tasks/server/BukkitTPSCountTimer.java +++ /dev/null @@ -1,108 +0,0 @@ -package com.djrapitops.plan.system.tasks.server; - -import com.djrapitops.plan.Plan; -import com.djrapitops.plan.data.container.TPS; -import com.djrapitops.plan.system.tasks.TPSCountTimer; -import com.djrapitops.plugin.api.TimeAmount; -import com.djrapitops.plugin.api.utility.log.Log; -import org.bukkit.World; - -public class BukkitTPSCountTimer extends TPSCountTimer { - - private long lastCheckNano; - - public BukkitTPSCountTimer(Plan plugin) { - super(plugin); - 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. - Log.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 = getUsedMemory(); - - int playersOnline = plugin.getServer().getOnlinePlayers().size(); - latestPlayersOnline = playersOnline; - int loadedChunks = getLoadedChunks(); - int entityCount; - - entityCount = getEntityCount(); - - return getTPS(diff, now, averageCPUUsage, usedMemory, entityCount, loadedChunks, playersOnline); - } - - - /** - * Gets the TPS for Spigot / Bukkit - * - * @param diff The difference between the last run and this run - * @param now The time right now - * @param cpuUsage The usage of the CPU - * @param playersOnline The amount of players that are online - * @return the TPS - */ - protected TPS getTPS(long diff, long now, double cpuUsage, long usedMemory, int entityCount, int chunksLoaded, int playersOnline) { - long difference = diff; - if (difference < TimeAmount.SECOND.ns()) { // No tick count above 20 - difference = TimeAmount.SECOND.ns(); - } - - long twentySeconds = 20L * TimeAmount.SECOND.ns(); - while (difference > twentySeconds) { - // Add 0 TPS since more than 20 ticks has passed. - history.add(new TPS(now, 0, playersOnline, cpuUsage, usedMemory, entityCount, chunksLoaded)); - difference -= twentySeconds; - } - - double tpsN = twentySeconds * 1.0 / difference; - - return new TPS(now, tpsN, playersOnline, cpuUsage, usedMemory, entityCount, chunksLoaded); - } - - /** - * 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/src/main/java/com/djrapitops/plan/system/tasks/server/NetworkPageRefreshTask.java b/Plan/src/main/java/com/djrapitops/plan/system/tasks/server/NetworkPageRefreshTask.java deleted file mode 100644 index 0b598e1dd..000000000 --- a/Plan/src/main/java/com/djrapitops/plan/system/tasks/server/NetworkPageRefreshTask.java +++ /dev/null @@ -1,17 +0,0 @@ -package com.djrapitops.plan.system.tasks.server; - -import com.djrapitops.plan.system.info.InfoSystem; -import com.djrapitops.plan.system.info.connection.WebExceptionLogger; -import com.djrapitops.plugin.task.AbsRunnable; - -public class NetworkPageRefreshTask extends AbsRunnable { - - public NetworkPageRefreshTask() { - super(NetworkPageRefreshTask.class.getSimpleName()); - } - - @Override - public void run() { - WebExceptionLogger.logIfOccurs(this.getClass(), () -> InfoSystem.getInstance().updateNetworkPage()); - } -} diff --git a/Plan/src/main/java/com/djrapitops/plan/system/tasks/server/PaperTPSCountTimer.java b/Plan/src/main/java/com/djrapitops/plan/system/tasks/server/PaperTPSCountTimer.java deleted file mode 100644 index 56930fb94..000000000 --- a/Plan/src/main/java/com/djrapitops/plan/system/tasks/server/PaperTPSCountTimer.java +++ /dev/null @@ -1,37 +0,0 @@ -package com.djrapitops.plan.system.tasks.server; - -import com.djrapitops.plan.Plan; -import com.djrapitops.plan.data.container.TPS; -import org.bukkit.World; - -public class PaperTPSCountTimer extends BukkitTPSCountTimer { - - public PaperTPSCountTimer(Plan plugin) { - super(plugin); - } - - @Override - protected TPS getTPS(long diff, long now, double cpuUsage, long usedMemory, int entityCount, int chunksLoaded, int playersOnline) { - double tps; - try { - tps = plugin.getServer().getTPS()[0]; - } catch (NoSuchMethodError e) { - return super.getTPS(diff, now, cpuUsage, usedMemory, entityCount, chunksLoaded, playersOnline); - } - - if (tps > 20) { - tps = 20; - } - - return new TPS(now, tps, playersOnline, cpuUsage, usedMemory, entityCount, chunksLoaded); - } - - @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/src/main/java/com/djrapitops/plan/system/tasks/server/PeriodicAnalysisTask.java b/Plan/src/main/java/com/djrapitops/plan/system/tasks/server/PeriodicAnalysisTask.java index 9beed5578..00248ce22 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/tasks/server/PeriodicAnalysisTask.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/tasks/server/PeriodicAnalysisTask.java @@ -1,32 +1,54 @@ package com.djrapitops.plan.system.tasks.server; -import com.djrapitops.plan.PlanPlugin; import com.djrapitops.plan.system.info.InfoSystem; import com.djrapitops.plan.system.info.connection.WebExceptionLogger; -import com.djrapitops.plan.system.info.request.GenerateAnalysisPageRequest; +import com.djrapitops.plan.system.info.request.InfoRequestFactory; import com.djrapitops.plan.system.info.server.ServerInfo; -import com.djrapitops.plugin.api.utility.log.Log; +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 javax.inject.Inject; +import javax.inject.Singleton; + +@Singleton public class PeriodicAnalysisTask extends AbsRunnable { - public PeriodicAnalysisTask() { - super(PeriodicAnalysisTask.class.getSimpleName()); + private final InfoSystem infoSystem; + private final InfoRequestFactory infoRequestFactory; + private final ServerInfo serverInfo; + private final PluginLogger logger; + private final ErrorHandler errorHandler; + private final WebExceptionLogger webExceptionLogger; + + @Inject + public PeriodicAnalysisTask( + InfoSystem infoSystem, + InfoRequestFactory infoRequestFactory, ServerInfo serverInfo, + PluginLogger logger, + ErrorHandler errorHandler, + WebExceptionLogger webExceptionLogger + ) { + this.infoSystem = infoSystem; + this.infoRequestFactory = infoRequestFactory; + this.serverInfo = serverInfo; + this.logger = logger; + this.errorHandler = errorHandler; + this.webExceptionLogger = webExceptionLogger; } @Override public void run() { try { - WebExceptionLogger.logIfOccurs(this.getClass(), () -> - InfoSystem.getInstance().sendRequest(new GenerateAnalysisPageRequest(ServerInfo.getServerUUID())) + webExceptionLogger.logIfOccurs(this.getClass(), () -> + infoSystem.sendRequest(infoRequestFactory.generateAnalysisPageRequest(serverInfo.getServerUUID())) ); - } catch (IllegalStateException e) { - if (!PlanPlugin.getInstance().isReloading()) { - Log.toLog(this.getClass(), e); - } + } catch (IllegalStateException ignore) { + /* Plugin was reloading */ } catch (Exception | NoClassDefFoundError | NoSuchMethodError | NoSuchFieldError e) { - Log.error("Periodic Analysis Task Disabled due to error, reload Plan to re-enable."); - Log.toLog(this.getClass(), e); + logger.error("Periodic Analysis Task Disabled due to error, reload Plan to re-enable."); + errorHandler.log(L.ERROR, this.getClass(), e); cancel(); } } diff --git a/Plan/src/main/java/com/djrapitops/plan/system/tasks/server/bukkit/BukkitTPSCountTimer.java b/Plan/src/main/java/com/djrapitops/plan/system/tasks/server/bukkit/BukkitTPSCountTimer.java new file mode 100644 index 000000000..4af7a9cf2 --- /dev/null +++ b/Plan/src/main/java/com/djrapitops/plan/system/tasks/server/bukkit/BukkitTPSCountTimer.java @@ -0,0 +1,138 @@ +package com.djrapitops.plan.system.tasks.server.bukkit; + +import com.djrapitops.plan.Plan; +import com.djrapitops.plan.data.container.TPS; +import com.djrapitops.plan.data.container.builders.TPSBuilder; +import com.djrapitops.plan.system.info.server.properties.ServerProperties; +import com.djrapitops.plan.system.processing.Processing; +import com.djrapitops.plan.system.processing.processors.Processors; +import com.djrapitops.plan.system.tasks.TPSCountTimer; +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 BukkitTPSCountTimer extends TPSCountTimer { + + protected final Plan plugin; + private ServerProperties serverProperties; + private long lastCheckNano; + + @Inject + public BukkitTPSCountTimer( + Plan plugin, + Processors processors, + Processing processing, + ServerProperties serverProperties, + PluginLogger logger, + ErrorHandler errorHandler + ) { + super(processors, processing, 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 = 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(0) + .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/src/main/java/com/djrapitops/plan/system/tasks/server/bukkit/PaperTPSCountTimer.java b/Plan/src/main/java/com/djrapitops/plan/system/tasks/server/bukkit/PaperTPSCountTimer.java new file mode 100644 index 000000000..5dbd6603b --- /dev/null +++ b/Plan/src/main/java/com/djrapitops/plan/system/tasks/server/bukkit/PaperTPSCountTimer.java @@ -0,0 +1,62 @@ +package com.djrapitops.plan.system.tasks.server.bukkit; + +import com.djrapitops.plan.Plan; +import com.djrapitops.plan.data.container.TPS; +import com.djrapitops.plan.data.container.builders.TPSBuilder; +import com.djrapitops.plan.system.info.server.properties.ServerProperties; +import com.djrapitops.plan.system.processing.Processing; +import com.djrapitops.plan.system.processing.processors.Processors; +import com.djrapitops.plugin.logging.console.PluginLogger; +import com.djrapitops.plugin.logging.error.ErrorHandler; +import org.bukkit.World; + +import javax.inject.Inject; + +public class PaperTPSCountTimer extends BukkitTPSCountTimer { + + @Inject + public PaperTPSCountTimer( + Plan plugin, + Processors processors, + Processing processing, + ServerProperties serverProperties, + PluginLogger logger, + ErrorHandler errorHandler + ) { + super(plugin, processors, processing, serverProperties, 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) { + 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/src/main/java/com/djrapitops/plan/system/tasks/server/PingCountTimerBukkit.java b/Plan/src/main/java/com/djrapitops/plan/system/tasks/server/bukkit/PingCountTimerBukkit.java similarity index 72% rename from Plan/src/main/java/com/djrapitops/plan/system/tasks/server/PingCountTimerBukkit.java rename to Plan/src/main/java/com/djrapitops/plan/system/tasks/server/bukkit/PingCountTimerBukkit.java index 2da73a083..345f06719 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/tasks/server/PingCountTimerBukkit.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/tasks/server/bukkit/PingCountTimerBukkit.java @@ -21,15 +21,15 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -package com.djrapitops.plan.system.tasks.server; +package com.djrapitops.plan.system.tasks.server.bukkit; import com.djrapitops.plan.data.store.objects.DateObj; import com.djrapitops.plan.system.processing.Processing; -import com.djrapitops.plan.system.processing.processors.player.PingInsertProcessor; +import com.djrapitops.plan.system.processing.processors.Processors; import com.djrapitops.plan.system.settings.Settings; +import com.djrapitops.plan.system.settings.config.PlanConfig; import com.djrapitops.plan.utilities.java.Reflection; import com.djrapitops.plugin.api.TimeAmount; -import com.djrapitops.plugin.api.utility.log.Log; import com.djrapitops.plugin.task.AbsRunnable; import com.djrapitops.plugin.task.RunnableFactory; import org.bukkit.Bukkit; @@ -39,11 +39,16 @@ import org.bukkit.event.Listener; import org.bukkit.event.player.PlayerJoinEvent; import org.bukkit.event.player.PlayerQuitEvent; +import javax.inject.Inject; +import javax.inject.Singleton; import java.lang.invoke.MethodHandle; import java.lang.invoke.MethodHandles; import java.lang.invoke.MethodHandles.Lookup; import java.lang.reflect.Method; import java.util.*; +import java.util.concurrent.TimeUnit; +import java.util.logging.Level; +import java.util.logging.Logger; /** * Task that handles player ping calculation on Bukkit based servers. @@ -53,6 +58,7 @@ import java.util.*; * * @author games647 */ +@Singleton public class PingCountTimerBukkit extends AbsRunnable implements Listener { //the server is pinging the client every 40 Ticks (2 sec) - so check it then @@ -80,7 +86,11 @@ public class PingCountTimerBukkit extends AbsRunnable implements Listener { localPing = lookup.findGetter(entityPlayer, "ping", Integer.TYPE); } catch (NoSuchMethodException | IllegalAccessException | NoSuchFieldException reflectiveEx) { - Log.toLog(PingCountTimerBukkit.class, reflectiveEx); + Logger.getGlobal().log( + Level.WARNING, + "Reflective exception in static initializer of Plan PingCountTimer", + reflectiveEx + ); } } @@ -88,40 +98,62 @@ public class PingCountTimerBukkit extends AbsRunnable implements Listener { PING_FIELD = localPing; } - private final Map>> playerHistory = new HashMap<>(); + private final Map>> playerHistory; + + private final PlanConfig config; + private final Processors processors; + private final Processing processing; + private final RunnableFactory runnableFactory; + + @Inject + public PingCountTimerBukkit( + PlanConfig config, + Processors processors, + Processing processing, + RunnableFactory runnableFactory + ) { + this.config = config; + this.processors = processors; + this.processing = processing; + this.runnableFactory = runnableFactory; + playerHistory = new HashMap<>(); + } private static boolean isPingMethodAvailable() { try { //Only available in Paper - Player.Spigot.class.getDeclaredMethod("getPing"); + Class.forName("org.bukkit.entity.Player.Spigot").getDeclaredMethod("getPing"); return true; - } catch (NoSuchMethodException noSuchMethodEx) { + } catch (ClassNotFoundException | NoSuchMethodException noSuchMethodEx) { return false; } } @Override public void run() { - List loggedOut = new ArrayList<>(); long time = System.currentTimeMillis(); - playerHistory.forEach((uuid, history) -> { + Iterator>>> iterator = playerHistory.entrySet().iterator(); + + while (iterator.hasNext()) { + Map.Entry>> entry = iterator.next(); + UUID uuid = entry.getKey(); + List> history = entry.getValue(); Player player = Bukkit.getPlayer(uuid); if (player != null) { int ping = getPing(player); - if (ping < -1 || ping > TimeAmount.SECOND.ms() * 8L) { + if (ping < -1 || ping > TimeUnit.SECONDS.toMillis(8L)) { // Don't accept bad values - return; + continue; } history.add(new DateObj<>(time, ping)); if (history.size() >= 30) { - Processing.submit(new PingInsertProcessor(uuid, new ArrayList<>(history))); + processing.submit(processors.player().pingInsertProcessor(uuid, new ArrayList<>(history))); history.clear(); } } else { - loggedOut.add(uuid); + iterator.remove(); } - }); - loggedOut.forEach(playerHistory::remove); + } } public void addPlayer(Player player) { @@ -154,14 +186,14 @@ public class PingCountTimerBukkit extends AbsRunnable implements Listener { @EventHandler public void onPlayerJoin(PlayerJoinEvent joinEvent) { Player player = joinEvent.getPlayer(); - RunnableFactory.createNew("Add Player to Ping list", new AbsRunnable() { + runnableFactory.create("Add Player to Ping list", new AbsRunnable() { @Override public void run() { if (player.isOnline()) { addPlayer(player); } } - }).runTaskLater(TimeAmount.SECOND.ticks() * (long) Settings.PING_PLAYER_LOGIN_DELAY.getNumber()); + }).runTaskLater(TimeAmount.toTicks(config.getNumber(Settings.PING_PLAYER_LOGIN_DELAY), TimeUnit.SECONDS)); } @EventHandler diff --git a/Plan/src/main/java/com/djrapitops/plan/system/tasks/server/PingCountTimerSponge.java b/Plan/src/main/java/com/djrapitops/plan/system/tasks/server/sponge/PingCountTimerSponge.java similarity index 68% rename from Plan/src/main/java/com/djrapitops/plan/system/tasks/server/PingCountTimerSponge.java rename to Plan/src/main/java/com/djrapitops/plan/system/tasks/server/sponge/PingCountTimerSponge.java index cfed96452..5fd889ce1 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/tasks/server/PingCountTimerSponge.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/tasks/server/sponge/PingCountTimerSponge.java @@ -21,12 +21,13 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -package com.djrapitops.plan.system.tasks.server; +package com.djrapitops.plan.system.tasks.server.sponge; import com.djrapitops.plan.data.store.objects.DateObj; import com.djrapitops.plan.system.processing.Processing; -import com.djrapitops.plan.system.processing.processors.player.PingInsertProcessor; +import com.djrapitops.plan.system.processing.processors.Processors; import com.djrapitops.plan.system.settings.Settings; +import com.djrapitops.plan.system.settings.config.PlanConfig; import com.djrapitops.plugin.api.TimeAmount; import com.djrapitops.plugin.task.AbsRunnable; import com.djrapitops.plugin.task.RunnableFactory; @@ -35,7 +36,9 @@ import org.spongepowered.api.entity.living.player.Player; import org.spongepowered.api.event.Listener; import org.spongepowered.api.event.network.ClientConnectionEvent; +import javax.inject.Inject; import java.util.*; +import java.util.concurrent.TimeUnit; /** * Task that handles player ping calculation on Sponge based servers. @@ -48,30 +51,52 @@ public class PingCountTimerSponge extends AbsRunnable { //https://github.com/bergerkiller/CraftSource/blob/master/net.minecraft.server/PlayerConnection.java#L178 public static final int PING_INTERVAL = 2 * 20; - private final Map>> playerHistory = new HashMap<>(); + private final Map>> playerHistory; + + private final PlanConfig config; + private final Processors processors; + private final Processing processing; + private final RunnableFactory runnableFactory; + + @Inject + public PingCountTimerSponge( + PlanConfig config, + Processors processors, + Processing processing, + RunnableFactory runnableFactory + ) { + this.config = config; + this.processors = processors; + this.processing = processing; + this.runnableFactory = runnableFactory; + playerHistory = new HashMap<>(); + } @Override public void run() { - List loggedOut = new ArrayList<>(); long time = System.currentTimeMillis(); - playerHistory.forEach((uuid, history) -> { + Iterator>>> iterator = playerHistory.entrySet().iterator(); + + while (iterator.hasNext()) { + Map.Entry>> entry = iterator.next(); + UUID uuid = entry.getKey(); + List> history = entry.getValue(); Optional player = Sponge.getServer().getPlayer(uuid); if (player.isPresent()) { int ping = getPing(player.get()); - if (ping < -1 || ping > TimeAmount.SECOND.ms() * 8L) { + if (ping < -1 || ping > TimeUnit.SECONDS.toMillis(8L)) { // Don't accept bad values - return; + continue; } history.add(new DateObj<>(time, ping)); if (history.size() >= 30) { - Processing.submit(new PingInsertProcessor(uuid, new ArrayList<>(history))); + processing.submit(processors.player().pingInsertProcessor(uuid, new ArrayList<>(history))); history.clear(); } } else { - loggedOut.add(uuid); + iterator.remove(); } - }); - loggedOut.forEach(playerHistory::remove); + } } public void addPlayer(Player player) { @@ -89,14 +114,14 @@ public class PingCountTimerSponge extends AbsRunnable { @Listener public void onPlayerJoin(ClientConnectionEvent.Join joinEvent) { Player player = joinEvent.getTargetEntity(); - RunnableFactory.createNew("Add Player to Ping list", new AbsRunnable() { + runnableFactory.create("Add Player to Ping list", new AbsRunnable() { @Override public void run() { if (player.isOnline()) { addPlayer(player); } } - }).runTaskLater(TimeAmount.SECOND.ticks() * (long) Settings.PING_PLAYER_LOGIN_DELAY.getNumber()); + }).runTaskLater(TimeAmount.toTicks(config.getNumber(Settings.PING_PLAYER_LOGIN_DELAY), TimeUnit.SECONDS)); } @Listener diff --git a/Plan/src/main/java/com/djrapitops/plan/system/tasks/server/SpongeTPSCountTimer.java b/Plan/src/main/java/com/djrapitops/plan/system/tasks/server/sponge/SpongeTPSCountTimer.java similarity index 55% rename from Plan/src/main/java/com/djrapitops/plan/system/tasks/server/SpongeTPSCountTimer.java rename to Plan/src/main/java/com/djrapitops/plan/system/tasks/server/sponge/SpongeTPSCountTimer.java index a3ce43333..26da8885d 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/tasks/server/SpongeTPSCountTimer.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/tasks/server/sponge/SpongeTPSCountTimer.java @@ -1,20 +1,38 @@ -package com.djrapitops.plan.system.tasks.server; +package com.djrapitops.plan.system.tasks.server.sponge; import com.djrapitops.plan.PlanSponge; import com.djrapitops.plan.data.container.TPS; import com.djrapitops.plan.data.container.builders.TPSBuilder; -import com.djrapitops.plan.system.info.server.ServerInfo; +import com.djrapitops.plan.system.info.server.properties.ServerProperties; +import com.djrapitops.plan.system.processing.Processing; +import com.djrapitops.plan.system.processing.processors.Processors; import com.djrapitops.plan.system.tasks.TPSCountTimer; -import com.djrapitops.plugin.api.utility.log.Log; -import org.spongepowered.api.Sponge; +import com.djrapitops.plugin.logging.console.PluginLogger; +import com.djrapitops.plugin.logging.error.ErrorHandler; import org.spongepowered.api.world.World; -public class SpongeTPSCountTimer extends TPSCountTimer { +import javax.inject.Inject; +import javax.inject.Singleton; + +@Singleton +public class SpongeTPSCountTimer extends TPSCountTimer { private long lastCheckNano; + private final PlanSponge plugin; + private ServerProperties serverProperties; - public SpongeTPSCountTimer(PlanSponge plugin) { - super(plugin); + @Inject + public SpongeTPSCountTimer( + PlanSponge plugin, + Processors processors, + Processing processing, + ServerProperties serverProperties, + PluginLogger logger, + ErrorHandler errorHandler + ) { + super(processors, processing, logger, errorHandler); + this.plugin = plugin; + this.serverProperties = serverProperties; lastCheckNano = -1; } @@ -25,7 +43,7 @@ public class SpongeTPSCountTimer extends TPSCountTimer { lastCheckNano = nanoTime; if (diff > nanoTime) { // First run's diff = nanoTime + 1, no calc possible. - Log.debug("First run of TPSCountTimer Task."); + logger.debug("First run of TPSCountTimer Task."); return; } @@ -35,7 +53,7 @@ public class SpongeTPSCountTimer extends TPSCountTimer { /** * Calculates the TPS * - * @param now The time right now + * @param now The time right now * @return the TPS */ private TPS calculateTPS(long now) { @@ -43,11 +61,12 @@ public class SpongeTPSCountTimer extends TPSCountTimer { long usedMemory = getUsedMemory(); - double tps = Sponge.getGame().getServer().getTicksPerSecond(); - int playersOnline = ServerInfo.getServerProperties().getOnlinePlayers(); + 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) @@ -57,6 +76,7 @@ public class SpongeTPSCountTimer extends TPSCountTimer { .usedMemory(usedMemory) .entities(entityCount) .chunksLoaded(loadedChunks) + .freeDiskSpace(freeDiskSpace) .toTPS(); } @@ -68,7 +88,7 @@ public class SpongeTPSCountTimer extends TPSCountTimer { private int getLoadedChunks() { // DISABLED int loaded = 0; - for (World world : Sponge.getGame().getServer().getWorlds()) { + for (World world : plugin.getGame().getServer().getWorlds()) { loaded += world.getLoadedChunks().spliterator().estimateSize(); } return loaded; @@ -80,6 +100,6 @@ public class SpongeTPSCountTimer extends TPSCountTimer { * @return amount of entities */ private int getEntityCount() { - return Sponge.getGame().getServer().getWorlds().stream().mapToInt(world -> world.getEntities().size()).sum(); + return plugin.getGame().getServer().getWorlds().stream().mapToInt(world -> world.getEntities().size()).sum(); } } diff --git a/Plan/src/main/java/com/djrapitops/plan/system/update/ShutdownUpdateHook.java b/Plan/src/main/java/com/djrapitops/plan/system/update/ShutdownUpdateHook.java deleted file mode 100644 index b75d21531..000000000 --- a/Plan/src/main/java/com/djrapitops/plan/system/update/ShutdownUpdateHook.java +++ /dev/null @@ -1,140 +0,0 @@ -package com.djrapitops.plan.system.update; - -import com.djrapitops.plan.PlanPlugin; -import com.djrapitops.plugin.api.Check; -import com.djrapitops.plugin.api.utility.Version; -import com.djrapitops.plugin.api.utility.log.Log; - -import java.io.*; -import java.net.URL; -import java.net.URLClassLoader; -import java.util.HashSet; -import java.util.Set; - -/** - * Shutdown hook that updates the plugin on server shutdown. - *

- * Does not perform update on force close. - * - * @author Rsl1122 - */ -public class ShutdownUpdateHook extends Thread { - - private static boolean activated = false; - private static File newJar; - - private static Set toDelete = new HashSet<>(); - - private static boolean isActivated() { - return activated; - } - - public static void activate() { - activated = true; - VersionInfo available = VersionCheckSystem.getInstance().getNewVersionAvailable(); - - if (!Version.isNewVersionAvailable(new Version(VersionCheckSystem.getCurrentVersion()), available.getVersion())) { - return; - } - try { - File pluginsFolder = getPluginsFolder(); - newJar = new File(pluginsFolder, "Plan-" + available.getVersion() + ".jar"); - - downloadNewJar(available, newJar); - registerOldJarForDeletion(pluginsFolder, newJar); - } catch (IOException e) { - Log.toLog(ShutdownUpdateHook.class, e); - } - } - - private static File getPluginsFolder() throws FileNotFoundException { - File dataFolder = PlanPlugin.getInstance().getDataFolder(); - File pluginsFolder = Check.isSpongeAvailable() - ? new File(dataFolder.getParentFile().getParentFile().getPath(), "mods") - : new File(dataFolder.getParentFile().getPath()); - if (!pluginsFolder.isDirectory()) { - throw new FileNotFoundException("Could not get plugin folder for Plan."); - } - return pluginsFolder; - } - - public static void deActivate() { - activated = false; - Log.infoColor("§aUpdate has been cancelled."); - - if (newJar != null && newJar.exists()) { - if (!newJar.delete()) { - newJar.deleteOnExit(); - } - } - toDelete.clear(); - } - - public static void registerOldJarForDeletion(File pluginsFolder, File newFileLocation) throws FileNotFoundException { - File[] files = pluginsFolder.listFiles(); - if (files == null) { - throw new FileNotFoundException("Could not delete old jar."); - } - for (File file : files) { - String fileName = file.getName(); - boolean isPlanJar = (fileName.startsWith("Plan-") && fileName.endsWith(".jar")) - || fileName.equals("Plan.jar"); - boolean isNewJar = fileName.equals(newFileLocation.getName()); - if (isPlanJar && !isNewJar) { - toDelete.add(file); - } - } - } - - public static void downloadNewJar(VersionInfo available, File newFileLocation) throws IOException { - URL downloadFrom = new URL(available.getDownloadUrl()); - try ( - BufferedInputStream in = new BufferedInputStream(downloadFrom.openStream()); - FileOutputStream fout = new FileOutputStream(newFileLocation) - ) { - final byte data[] = new byte[1024]; - int count; - while ((count = in.read(data, 0, 1024)) != -1) { - fout.write(data, 0, count); - } - } - } - - public void register() { - if (isActivated()) { - return; - } - Log.infoColor("§aUpdate has been scheduled, Downloading new jar.. Restart server to take effect."); - activate(); - Runtime.getRuntime().addShutdownHook(this); - } - - @Override - public void run() { - if (!(Check.isBukkitAvailable() && Check.isSpongeAvailable() && Check.isBungeeAvailable())) { - unloadJar(); - } - - for (File f : toDelete) { - if (!f.delete()) { - f.deleteOnExit(); - } - } - } - - private void unloadJar() { - ClassLoader classLoader = PlanPlugin.class.getClassLoader(); - - if (classLoader instanceof URLClassLoader) { - try { - ((URLClassLoader) classLoader).close(); - } catch (IOException e) { - // Loggers may be unavailable. - e.printStackTrace(); - } - } - - System.gc(); - } - -} \ No newline at end of file diff --git a/Plan/src/main/java/com/djrapitops/plan/system/update/VersionCheckSystem.java b/Plan/src/main/java/com/djrapitops/plan/system/update/VersionCheckSystem.java index 159b637e7..6ded3e472 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/update/VersionCheckSystem.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/update/VersionCheckSystem.java @@ -4,20 +4,21 @@ */ package com.djrapitops.plan.system.update; -import com.djrapitops.plan.system.PlanSystem; import com.djrapitops.plan.system.SubSystem; import com.djrapitops.plan.system.locale.Locale; import com.djrapitops.plan.system.locale.lang.PluginLang; import com.djrapitops.plan.system.settings.Settings; -import com.djrapitops.plugin.api.Priority; -import com.djrapitops.plugin.api.systems.NotificationCenter; +import com.djrapitops.plan.system.settings.config.PlanConfig; import com.djrapitops.plugin.api.utility.Version; -import com.djrapitops.plugin.api.utility.log.Log; -import com.djrapitops.plugin.utilities.Verify; +import com.djrapitops.plugin.logging.L; +import com.djrapitops.plugin.logging.console.PluginLogger; +import javax.inject.Inject; +import javax.inject.Named; +import javax.inject.Singleton; import java.io.IOException; import java.util.List; -import java.util.function.Supplier; +import java.util.Optional; import java.util.stream.Collectors; /** @@ -25,86 +26,59 @@ import java.util.stream.Collectors; * * @author Rsl1122 */ +@Singleton public class VersionCheckSystem implements SubSystem { private final String currentVersion; - private final Supplier locale; + private final Locale locale; + private final PlanConfig config; + private final PluginLogger logger; + private VersionInfo newVersionAvailable; - public VersionCheckSystem(String currentVersion, Supplier locale) { + @Inject + public VersionCheckSystem( + @Named("currentVersion") String currentVersion, + Locale locale, + PlanConfig config, + PluginLogger logger + ) { this.currentVersion = currentVersion; this.locale = locale; + this.config = config; + this.logger = logger; } - public static VersionCheckSystem getInstance() { - VersionCheckSystem versionCheckSystem = PlanSystem.getInstance().getVersionCheckSystem(); - Verify.nullCheck(versionCheckSystem, () -> new IllegalStateException("Version Check system has not been initialized.")); - return versionCheckSystem; - } - - public static boolean isNewVersionAvailable() { - return getInstance().newVersionAvailable != null; - } - - public static String getCurrentVersion() { - return getInstance().currentVersion; + public boolean isNewVersionAvailable() { + return newVersionAvailable != null; } @Override public void enable() { - if (Settings.ALLOW_UPDATE.isTrue()) { - try { - List versions = VersionInfoLoader.load(); - if (Settings.NOTIFY_ABOUT_DEV_RELEASES.isFalse()) { - versions = versions.stream().filter(VersionInfo::isRelease).collect(Collectors.toList()); - } - VersionInfo newestVersion = versions.get(0); - if (Version.isNewVersionAvailable(new Version(currentVersion), newestVersion.getVersion())) { - newVersionAvailable = newestVersion; - String notification = locale.get().getString( - PluginLang.VERSION_AVAILABLE, - newestVersion.getVersion().toString(), - newestVersion.getChangeLogUrl() - ) + (newestVersion.isRelease() ? "" : locale.get().getString(PluginLang.VERSION_AVAILABLE_DEV)); - Log.infoColor("§a----------------------------------------"); - Log.infoColor("§a" + notification); - Log.infoColor("§a----------------------------------------"); - NotificationCenter.getNotifications().clear(); - NotificationCenter.addNotification(newestVersion.isRelease() ? Priority.HIGH : Priority.MEDIUM, notification); - } else { - Log.info(locale.get().getString(PluginLang.VERSION_NEWEST)); - } - } catch (IOException e) { - Log.error(locale.get().getString(PluginLang.VERSION_FAIL_READ_VERSIONS)); - } - } else { - checkForNewVersion(); + if (config.isFalse(Settings.CHECK_FOR_UPDATES)) { + return; } - } - - private void checkForNewVersion() { - String githubVersionUrl = "https://raw.githubusercontent.com/Rsl1122/Plan-PlayerAnalytics/master/Plan/src/main/resources/plugin.yml"; - String spigotUrl = "https://www.spigotmc.org/resources/plan-player-analytics.32536/"; try { - boolean newVersionAvailable = Version.checkVersion(currentVersion, githubVersionUrl); - if (!newVersionAvailable) { - try { - newVersionAvailable = Version.checkVersion(currentVersion, spigotUrl); - } catch (NoClassDefFoundError ignore) { - /* 1.7.4 Does not have google gson JSONParser */ - } + List versions = VersionInfoLoader.load(); + if (config.isFalse(Settings.NOTIFY_ABOUT_DEV_RELEASES)) { + versions = versions.stream().filter(VersionInfo::isRelease).collect(Collectors.toList()); } - if (newVersionAvailable) { - String newVersionNotification = locale.get().getString(PluginLang.VERSION_AVAILABLE_SPIGOT, spigotUrl); - Log.infoColor("§a----------------------------------------"); - Log.infoColor("§a" + newVersionNotification); - Log.infoColor("§a----------------------------------------"); - NotificationCenter.addNotification(Priority.HIGH, newVersionNotification); + VersionInfo newestVersion = versions.get(0); + if (Version.isNewVersionAvailable(new Version(currentVersion), newestVersion.getVersion())) { + newVersionAvailable = newestVersion; + String notification = locale.getString( + PluginLang.VERSION_AVAILABLE, + newestVersion.getVersion().toString(), + newestVersion.getChangeLogUrl() + ) + (newestVersion.isRelease() ? "" : locale.getString(PluginLang.VERSION_AVAILABLE_DEV)); + logger.log(L.INFO_COLOR, "§a----------------------------------------"); + logger.log(L.INFO_COLOR, "§a" + notification); + logger.log(L.INFO_COLOR, "§a----------------------------------------"); } else { - Log.info(locale.get().getString(PluginLang.VERSION_NEWEST)); + logger.info(locale.getString(PluginLang.VERSION_NEWEST)); } } catch (IOException e) { - Log.error(locale.get().getString(PluginLang.VERSION_FAIL_READ_OLD)); + logger.error(locale.getString(PluginLang.VERSION_FAIL_READ_VERSIONS)); } } @@ -113,7 +87,17 @@ public class VersionCheckSystem implements SubSystem { /* Does not need to be closed */ } - public VersionInfo getNewVersionAvailable() { - return newVersionAvailable; + public Optional getNewVersionAvailable() { + return Optional.ofNullable(newVersionAvailable); + } + + public Optional getUpdateHtml() { + return getNewVersionAvailable() + .map(v -> v.isTrusted() ? "" + + "

Update available!

" : ""); + } + + public String getCurrentVersion() { + return currentVersion; } } diff --git a/Plan/src/main/java/com/djrapitops/plan/system/webserver/Request.java b/Plan/src/main/java/com/djrapitops/plan/system/webserver/Request.java index 47ec0edd7..3563e57aa 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/webserver/Request.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/webserver/Request.java @@ -28,7 +28,7 @@ public class Request { public Request(HttpExchange exchange, Locale locale) { this.requestMethod = exchange.getRequestMethod(); - this.target = exchange.getRequestURI().toString(); + this.target = exchange.getRequestURI().getPath(); remoteAddress = exchange.getRemoteAddress().getAddress().getHostAddress(); diff --git a/Plan/src/main/java/com/djrapitops/plan/system/webserver/RequestHandler.java b/Plan/src/main/java/com/djrapitops/plan/system/webserver/RequestHandler.java index 936d727ca..0c965138b 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/webserver/RequestHandler.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/webserver/RequestHandler.java @@ -4,47 +4,80 @@ */ package com.djrapitops.plan.system.webserver; +import com.djrapitops.plan.system.DebugChannels; +import com.djrapitops.plan.system.database.DBSystem; import com.djrapitops.plan.system.locale.Locale; import com.djrapitops.plan.system.settings.Settings; +import com.djrapitops.plan.system.settings.config.PlanConfig; +import com.djrapitops.plan.system.settings.theme.Theme; import com.djrapitops.plan.system.webserver.auth.Authentication; import com.djrapitops.plan.system.webserver.auth.BasicAuthentication; import com.djrapitops.plan.system.webserver.response.PromptAuthorizationResponse; import com.djrapitops.plan.system.webserver.response.Response; -import com.djrapitops.plugin.api.Benchmark; -import com.djrapitops.plugin.api.utility.log.Log; +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; import com.djrapitops.plugin.utilities.Verify; import com.sun.net.httpserver.Headers; import com.sun.net.httpserver.HttpExchange; import com.sun.net.httpserver.HttpHandler; +import javax.inject.Inject; +import javax.inject.Singleton; import java.util.List; -import java.util.function.Supplier; /** * HttpHandler for WebServer request management. * * @author Rsl1122 */ +@Singleton public class RequestHandler implements HttpHandler { - private final Supplier locale; + private final Locale locale; + private final PlanConfig config; + private final Theme theme; + private final DBSystem dbSystem; private final ResponseHandler responseHandler; + private final Timings timings; + private final PluginLogger logger; + private final ErrorHandler errorHandler; - RequestHandler(WebServer webServer) { - responseHandler = new ResponseHandler(webServer); - locale = webServer.getLocaleSupplier(); + @Inject + RequestHandler( + Locale locale, + PlanConfig config, + Theme theme, + DBSystem dbSystem, + ResponseHandler responseHandler, + Timings timings, + PluginLogger logger, + ErrorHandler errorHandler + ) { + this.locale = locale; + this.config = config; + this.theme = theme; + this.dbSystem = dbSystem; + this.responseHandler = responseHandler; + this.timings = timings; + this.logger = logger; + this.errorHandler = errorHandler; } @Override public void handle(HttpExchange exchange) { Headers requestHeaders = exchange.getRequestHeaders(); Headers responseHeaders = exchange.getResponseHeaders(); - Request request = new Request(exchange, locale.get()); + Request request = new Request(exchange, locale); request.setAuth(getAuthorization(requestHeaders)); String requestString = request.toString(); - Benchmark.start("", requestString); + timings.start(requestString); int responseCode = -1; + + boolean inDevMode = config.isTrue(Settings.DEV_MODE); try { Response response = responseHandler.getResponse(request); responseCode = response.getCode(); @@ -53,16 +86,19 @@ public class RequestHandler implements HttpHandler { } response.setResponseHeaders(responseHeaders); - response.send(exchange, locale.get()); + response.send(exchange, locale, theme); } catch (Exception e) { - if (Settings.DEV_MODE.isTrue()) { - Log.warn("THIS ERROR IS ONLY LOGGED IN DEV MODE:"); - Log.toLog(this.getClass(), e); + if (inDevMode) { + logger.warn("THIS ERROR IS ONLY LOGGED IN DEV MODE:"); + errorHandler.log(L.WARN, this.getClass(), e); } } finally { exchange.close(); - if (Settings.DEV_MODE.isTrue()) { - Log.debug(requestString + " Response code: " + responseCode + " took " + Benchmark.stop("", requestString) + " ms"); + if (inDevMode) { + logger.getDebugLogger().logOn( + DebugChannels.WEB_REQUESTS, + timings.end(requestString).map(Benchmark::toString).orElse("-") + " Code: " + responseCode + ); } } } @@ -75,7 +111,7 @@ public class RequestHandler implements HttpHandler { String authLine = authorization.get(0); if (authLine.contains("Basic ")) { - return new BasicAuthentication(authLine.split(" ")[1]); + return new BasicAuthentication(authLine.split(" ")[1], dbSystem.getDatabase()); } return null; } diff --git a/Plan/src/main/java/com/djrapitops/plan/system/webserver/ResponseHandler.java b/Plan/src/main/java/com/djrapitops/plan/system/webserver/ResponseHandler.java index 280b6de56..6c1fb0be3 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/webserver/ResponseHandler.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/webserver/ResponseHandler.java @@ -7,15 +7,19 @@ package com.djrapitops.plan.system.webserver; import com.djrapitops.plan.api.exceptions.WebUserAuthException; import com.djrapitops.plan.api.exceptions.connection.*; import com.djrapitops.plan.system.info.connection.InfoRequestPageHandler; -import com.djrapitops.plan.system.locale.lang.ErrorPageLang; import com.djrapitops.plan.system.webserver.auth.Authentication; import com.djrapitops.plan.system.webserver.cache.PageId; import com.djrapitops.plan.system.webserver.cache.ResponseCache; import com.djrapitops.plan.system.webserver.pages.*; -import com.djrapitops.plan.system.webserver.response.*; -import com.djrapitops.plan.system.webserver.response.errors.*; -import com.djrapitops.plugin.api.utility.log.Log; +import com.djrapitops.plan.system.webserver.response.Response; +import com.djrapitops.plan.system.webserver.response.ResponseFactory; +import com.djrapitops.plan.system.webserver.response.errors.BadRequestResponse; +import com.djrapitops.plugin.logging.L; +import com.djrapitops.plugin.logging.error.ErrorHandler; +import dagger.Lazy; +import javax.inject.Inject; +import javax.inject.Singleton; import java.util.ArrayList; import java.util.Arrays; import java.util.List; @@ -26,35 +30,56 @@ import java.util.Optional; * * @author Rsl1122 */ +@Singleton public class ResponseHandler extends TreePageHandler { - private final WebServer webServer; + private final DebugPageHandler debugPageHandler; + private final PlayersPageHandler playersPageHandler; + private final PlayerPageHandler playerPageHandler; + private final ServerPageHandler serverPageHandler; + private final InfoRequestPageHandler infoRequestPageHandler; + private final ErrorHandler errorHandler; - public ResponseHandler(WebServer webServer) { + private Lazy webServer; + + @Inject + public ResponseHandler( + ResponseFactory responseFactory, + Lazy webServer, + + DebugPageHandler debugPageHandler, + PlayersPageHandler playersPageHandler, + PlayerPageHandler playerPageHandler, + ServerPageHandler serverPageHandler, + InfoRequestPageHandler infoRequestPageHandler, + + ErrorHandler errorHandler + ) { + super(responseFactory); this.webServer = webServer; + this.debugPageHandler = debugPageHandler; + this.playersPageHandler = playersPageHandler; + this.playerPageHandler = playerPageHandler; + this.serverPageHandler = serverPageHandler; + this.infoRequestPageHandler = infoRequestPageHandler; + this.errorHandler = errorHandler; } - public void registerDefaultPages() { - registerPage("favicon.ico", new RedirectResponse("https://puu.sh/tK0KL/6aa2ba141b.ico"), 5); - registerPage("debug", new DebugPageHandler()); - registerPage("players", new PlayersPageHandler()); - registerPage("player", new PlayerPageHandler()); + public void registerPages() { + registerPage("debug", debugPageHandler); + registerPage("players", playersPageHandler); + registerPage("player", playerPageHandler); - ServerPageHandler serverPageHandler = new ServerPageHandler(); registerPage("network", serverPageHandler); registerPage("server", serverPageHandler); - registerPage("", webServer.isAuthRequired() - ? new RootPageHandler(this) - : new PageHandler() { - @Override - public Response getResponse(Request request, List target) { - return new RedirectResponse("/server"); - } - }); - } - public void registerWebAPIPages() { - registerPage("info", new InfoRequestPageHandler()); + if (webServer.get().isAuthRequired()) { + registerPage("", new RootPageHandler(responseFactory)); + } else { + registerPage("", responseFactory.redirectResponse("/server"), 5); + } + + registerPage("info", infoRequestPageHandler); } public Response getResponse(Request request) { @@ -66,26 +91,26 @@ public class ResponseHandler extends TreePageHandler { try { return getResponse(request, targetString, target); } catch (NoServersException | NotFoundException e) { - return new NotFoundResponse(e.getMessage()); + return responseFactory.notFound404(e.getMessage()); } catch (WebUserAuthException e) { - return PromptAuthorizationResponse.getBasicAuthResponse(e); + return responseFactory.basicAuthFail(e); } catch (ForbiddenException e) { - return new ForbiddenResponse(e.getMessage()); + return responseFactory.forbidden403(e.getMessage()); } catch (BadRequestException e) { return new BadRequestResponse(e.getMessage()); } catch (UnauthorizedServerException e) { - return new UnauthorizedServerResponse(e.getMessage()); + return responseFactory.unauthorizedServer(e.getMessage()); } catch (GatewayException e) { - return new GatewayErrorResponse(e.getMessage()); + return responseFactory.gatewayError504(e.getMessage()); } catch (InternalErrorException e) { if (e.getCause() != null) { - return new InternalErrorResponse(request.getTarget(), e.getCause()); + return responseFactory.internalErrorResponse(e.getCause(), request.getTarget()); } else { - return new InternalErrorResponse(request.getTarget(), e); + return responseFactory.internalErrorResponse(e, request.getTarget()); } } catch (Exception e) { - Log.toLog(this.getClass(), e); - return new InternalErrorResponse(request.getTarget(), e); + errorHandler.log(L.ERROR, this.getClass(), e); + return responseFactory.internalErrorResponse(e, request.getTarget()); } } @@ -93,38 +118,35 @@ public class ResponseHandler extends TreePageHandler { Optional authentication = Optional.empty(); if (targetString.endsWith(".css")) { - return ResponseCache.loadResponse(PageId.CSS.of(targetString), () -> new CSSResponse(targetString)); + return ResponseCache.loadResponse(PageId.CSS.of(targetString), () -> responseFactory.cssResponse(targetString)); } if (targetString.endsWith(".js")) { - return ResponseCache.loadResponse(PageId.JS.of(targetString), () -> new JavaScriptResponse(targetString)); + return ResponseCache.loadResponse(PageId.JS.of(targetString), () -> responseFactory.javaScriptResponse(targetString)); + } + if (targetString.endsWith("favicon.ico")) { + return ResponseCache.loadResponse(PageId.FAVICON.id(), responseFactory::faviconResponse); } boolean isNotInfoRequest = target.isEmpty() || !target.get(0).equals("info"); - boolean isAuthRequired = webServer.isAuthRequired() && isNotInfoRequest; + boolean isAuthRequired = webServer.get().isAuthRequired() && isNotInfoRequest; if (isAuthRequired) { authentication = request.getAuth(); if (!authentication.isPresent()) { - if (webServer.isUsingHTTPS()) { - return DefaultResponses.BASIC_AUTH.get(); + if (webServer.get().isUsingHTTPS()) { + return responseFactory.basicAuth(); } else { - return forbiddenResponse(); + return responseFactory.forbidden403(); } } } PageHandler pageHandler = getPageHandler(target); if (pageHandler == null) { - return new NotFoundResponse(request.getLocale().getString(ErrorPageLang.UNKNOWN_PAGE_404)); + return responseFactory.pageNotFound404(); } else { boolean isAuthorized = authentication.isPresent() && pageHandler.isAuthorized(authentication.get(), target); if (!isAuthRequired || isAuthorized) { return pageHandler.getResponse(request, target); } - return forbiddenResponse(); + return responseFactory.forbidden403(); } } - - public Response forbiddenResponse() { - return ResponseCache.loadResponse(PageId.FORBIDDEN.id(), () -> - new ForbiddenResponse("Your user is not authorized to view this page.
" - + "If you believe this is an error contact staff to change your access level.")); - } } diff --git a/Plan/src/main/java/com/djrapitops/plan/system/webserver/WebServer.java b/Plan/src/main/java/com/djrapitops/plan/system/webserver/WebServer.java index d2b4a4a87..276ef3bfd 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/webserver/WebServer.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/webserver/WebServer.java @@ -1,23 +1,25 @@ package com.djrapitops.plan.system.webserver; -import com.djrapitops.plan.PlanPlugin; import com.djrapitops.plan.api.exceptions.EnableException; import com.djrapitops.plan.system.SubSystem; -import com.djrapitops.plan.system.file.FileSystem; +import com.djrapitops.plan.system.file.PlanFiles; +import com.djrapitops.plan.system.info.server.properties.ServerProperties; import com.djrapitops.plan.system.locale.Locale; import com.djrapitops.plan.system.locale.lang.PluginLang; import com.djrapitops.plan.system.settings.Settings; -import com.djrapitops.plan.utilities.html.HtmlUtils; -import com.djrapitops.plugin.StaticHolder; +import com.djrapitops.plan.system.settings.config.PlanConfig; import com.djrapitops.plugin.api.Check; -import com.djrapitops.plugin.api.utility.log.Log; -import com.djrapitops.plugin.utilities.Verify; +import com.djrapitops.plugin.logging.L; +import com.djrapitops.plugin.logging.console.PluginLogger; +import com.djrapitops.plugin.logging.error.ErrorHandler; import com.google.common.util.concurrent.ThreadFactoryBuilder; import com.sun.net.httpserver.HttpServer; import com.sun.net.httpserver.HttpsConfigurator; import com.sun.net.httpserver.HttpsParameters; import com.sun.net.httpserver.HttpsServer; +import javax.inject.Inject; +import javax.inject.Singleton; import javax.net.ssl.*; import java.io.File; import java.io.FileInputStream; @@ -29,14 +31,22 @@ import java.security.*; import java.security.cert.Certificate; import java.security.cert.CertificateException; import java.util.concurrent.*; -import java.util.function.Supplier; /** * @author Rsl1122 */ +@Singleton public class WebServer implements SubSystem { - private final Supplier locale; + private final Locale locale; + private final PlanFiles files; + private final PlanConfig config; + + private final ServerProperties serverProperties; + private final RequestHandler requestHandler; + + private final PluginLogger logger; + private final ErrorHandler errorHandler; private int port; private boolean enabled = false; @@ -44,66 +54,72 @@ public class WebServer implements SubSystem { private boolean usingHttps = false; - private RequestHandler requestHandler; - private ResponseHandler responseHandler; - - public WebServer(Supplier locale) { + @Inject + public WebServer( + Locale locale, + PlanFiles files, + PlanConfig config, + ServerProperties serverProperties, + PluginLogger logger, + ErrorHandler errorHandler, + RequestHandler requestHandler + ) { this.locale = locale; - } + this.files = files; + this.config = config; + this.serverProperties = serverProperties; - public static WebServer getInstance() { - WebServer webServer = WebServerSystem.getInstance().getWebServer(); - Verify.nullCheck(webServer, () -> new IllegalStateException("WebServer was not initialized.")); - return webServer; + this.requestHandler = requestHandler; + + this.logger = logger; + this.errorHandler = errorHandler; } @Override public void enable() throws EnableException { - this.port = Settings.WEBSERVER_PORT.getNumber(); - - requestHandler = new RequestHandler(this); - responseHandler = requestHandler.getResponseHandler(); - - PlanPlugin plugin = PlanPlugin.getInstance(); - StaticHolder.saveInstance(RequestHandler.class, plugin.getClass()); - StaticHolder.saveInstance(ResponseHandler.class, plugin.getClass()); + this.port = config.getNumber(Settings.WEBSERVER_PORT); initServer(); if (!isEnabled()) { - if (Check.isBungeeAvailable()) { - throw new EnableException(locale.get().getString(PluginLang.ENABLE_FAIL_NO_WEB_SERVER_BUNGEE)); + if (Check.isBungeeAvailable() || Check.isVelocityAvailable()) { + throw new EnableException(locale.getString(PluginLang.ENABLE_FAIL_NO_WEB_SERVER_BUNGEE)); } - if (Settings.WEBSERVER_DISABLED.isTrue()) { - Log.warn(locale.get().getString(PluginLang.ENABLE_NOTIFY_WEB_SERVER_DISABLED)); + if (config.isTrue(Settings.WEBSERVER_DISABLED)) { + logger.warn(locale.getString(PluginLang.ENABLE_NOTIFY_WEB_SERVER_DISABLED)); } else { - Log.error(locale.get().getString(PluginLang.WEB_SERVER_FAIL_PORT_BIND, port)); + logger.error(locale.getString(PluginLang.WEB_SERVER_FAIL_PORT_BIND, port)); } } + + requestHandler.getResponseHandler().registerPages(); } /** * Starts up the WebServer in a new Thread Pool. */ private void initServer() { - // Check if Bukkit WebServer has been disabled. - if (!Check.isBungeeAvailable() && Settings.WEBSERVER_DISABLED.isTrue()) { + if (!(Check.isBungeeAvailable() || Check.isVelocityAvailable()) && config.isTrue(Settings.WEBSERVER_DISABLED)) { + // Bukkit WebServer has been disabled. return; } - // Server is already enabled stop code if (enabled) { + // Server is already enabled stop code return; } try { usingHttps = startHttpsServer(); - Log.debug(usingHttps ? "Https Start Successful." : "Https Start Failed."); + logger.debug(usingHttps ? "Https Start Successful." : "Https Start Failed."); if (!usingHttps) { - Log.infoColor("§e" + locale.get().getString(PluginLang.WEB_SERVER_NOTIFY_HTTP_USER_AUTH)); - server = HttpServer.create(new InetSocketAddress(Settings.WEBSERVER_IP.toString(), port), 10); + logger.log(L.INFO_COLOR, "§e" + locale.getString(PluginLang.WEB_SERVER_NOTIFY_HTTP_USER_AUTH)); + server = HttpServer.create(new InetSocketAddress(config.getString(Settings.WEBSERVER_IP), port), 10); + } else if (server == null) { + logger.log(L.INFO_COLOR, "§eWebServer: Proxy HTTPS Override enabled. HTTP Server in use, make sure that your Proxy webserver is routing with HTTPS and AlternativeIP.Link points to the Proxy"); + server = HttpServer.create(new InetSocketAddress(config.getString(Settings.WEBSERVER_IP), port), 10); } server.createContext("/", requestHandler); @@ -116,22 +132,27 @@ public class WebServer implements SubSystem { enabled = true; - Log.info(locale.get().getString(PluginLang.ENABLED_WEB_SERVER, server.getAddress().getPort(), getAccessAddress())); + logger.info(locale.getString(PluginLang.ENABLED_WEB_SERVER, server.getAddress().getPort(), getAccessAddress())); } catch (IllegalArgumentException | IllegalStateException | IOException e) { - Log.toLog(this.getClass(), e); + errorHandler.log(L.ERROR, this.getClass(), e); enabled = false; } } private boolean startHttpsServer() { - String keyStorePath = Settings.WEBSERVER_CERTIFICATE_PATH.toString(); - if (!Paths.get(keyStorePath).isAbsolute()) { - keyStorePath = FileSystem.getDataFolder() + File.separator + keyStorePath; + String keyStorePath = config.getString(Settings.WEBSERVER_CERTIFICATE_PATH); + + if (keyStorePath.equalsIgnoreCase("proxy")) { + return true; } - char[] storepass = Settings.WEBSERVER_CERTIFICATE_STOREPASS.toString().toCharArray(); - char[] keypass = Settings.WEBSERVER_CERTIFICATE_KEYPASS.toString().toCharArray(); - String alias = Settings.WEBSERVER_CERTIFICATE_ALIAS.toString(); + if (!Paths.get(keyStorePath).isAbsolute()) { + keyStorePath = files.getDataFolder() + File.separator + keyStorePath; + } + + char[] storepass = config.getString(Settings.WEBSERVER_CERTIFICATE_STOREPASS).toCharArray(); + char[] keypass = config.getString(Settings.WEBSERVER_CERTIFICATE_KEYPASS).toCharArray(); + String alias = config.getString(Settings.WEBSERVER_CERTIFICATE_ALIAS); boolean startSuccessful = false; try (FileInputStream fIn = new FileInputStream(keyStorePath)) { @@ -144,7 +165,7 @@ public class WebServer implements SubSystem { throw new IllegalStateException("Certificate with Alias: " + alias + " was not found in the Keystore."); } - Log.info("Certificate: " + cert.getType()); + logger.info("Certificate: " + cert.getType()); KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance("SunX509"); keyManagerFactory.init(keystore, keypass); @@ -152,7 +173,7 @@ public class WebServer implements SubSystem { TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance("SunX509"); trustManagerFactory.init(keystore); - server = HttpsServer.create(new InetSocketAddress(Settings.WEBSERVER_IP.toString(), port), 10); + server = HttpsServer.create(new InetSocketAddress(config.getString(Settings.WEBSERVER_IP), port), 10); SSLContext sslContext = SSLContext.getInstance("TLSv1.2"); sslContext.init(keyManagerFactory.getKeyManagers(), null/*trustManagerFactory.getTrustManagers()*/, null); @@ -171,20 +192,20 @@ public class WebServer implements SubSystem { }); startSuccessful = true; } catch (IllegalStateException e) { - Log.error(e.getMessage()); - Log.toLog(this.getClass(), e); + logger.error(e.getMessage()); + errorHandler.log(L.ERROR, this.getClass(), e); } catch (KeyManagementException | NoSuchAlgorithmException e) { - Log.error(locale.get().getString(PluginLang.WEB_SERVER_FAIL_SSL_CONTEXT)); - Log.toLog(this.getClass(), e); + logger.error(locale.getString(PluginLang.WEB_SERVER_FAIL_SSL_CONTEXT)); + errorHandler.log(L.ERROR, this.getClass(), e); } catch (FileNotFoundException e) { - Log.infoColor("§e" + locale.get().getString(PluginLang.WEB_SERVER_NOTIFY_NO_CERT_FILE, keyStorePath)); - Log.info(locale.get().getString(PluginLang.WEB_SERVER_NOTIFY_HTTP)); + logger.log(L.INFO_COLOR, "§e" + locale.getString(PluginLang.WEB_SERVER_NOTIFY_NO_CERT_FILE, keyStorePath)); + logger.info(locale.getString(PluginLang.WEB_SERVER_NOTIFY_HTTP)); } catch (IOException e) { - Log.error("WebServer: " + e); - Log.toLog(this.getClass(), e); + logger.error("WebServer: " + e); + errorHandler.log(L.ERROR, this.getClass(), e); } catch (KeyStoreException | CertificateException | UnrecoverableKeyException e) { - Log.error(locale.get().getString(PluginLang.WEB_SERVER_FAIL_STORE_LOAD)); - Log.toLog(this.getClass(), e); + logger.error(locale.getString(PluginLang.WEB_SERVER_FAIL_STORE_LOAD)); + errorHandler.log(L.ERROR, this.getClass(), e); } return startSuccessful; } @@ -203,7 +224,7 @@ public class WebServer implements SubSystem { public void disable() { if (server != null) { shutdown(); - Log.info(locale.get().getString(PluginLang.DISABLED_WEB_SERVER)); + logger.info(locale.getString(PluginLang.DISABLED_WEB_SERVER)); } enabled = false; } @@ -235,18 +256,12 @@ public class WebServer implements SubSystem { } public String getAccessAddress() { - return isEnabled() ? getProtocol() + "://" + HtmlUtils.getIP() : Settings.EXTERNAL_WEBSERVER_LINK.toString(); + return isEnabled() ? getProtocol() + "://" + getIP() : config.getString(Settings.EXTERNAL_WEBSERVER_LINK); } - public RequestHandler getRequestHandler() { - return requestHandler; - } - - public ResponseHandler getResponseHandler() { - return responseHandler; - } - - Supplier getLocaleSupplier() { - return locale; + private String getIP() { + return config.isTrue(Settings.SHOW_ALTERNATIVE_IP) + ? config.getString(Settings.ALTERNATIVE_IP).replace("%port%", String.valueOf(port)) + : serverProperties.getIp() + ":" + port; } } diff --git a/Plan/src/main/java/com/djrapitops/plan/system/webserver/WebServerSystem.java b/Plan/src/main/java/com/djrapitops/plan/system/webserver/WebServerSystem.java index 39f6830dd..e1679dfa8 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/webserver/WebServerSystem.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/webserver/WebServerSystem.java @@ -5,44 +5,35 @@ package com.djrapitops.plan.system.webserver; import com.djrapitops.plan.api.exceptions.EnableException; -import com.djrapitops.plan.system.PlanSystem; import com.djrapitops.plan.system.SubSystem; -import com.djrapitops.plan.system.locale.Locale; import com.djrapitops.plan.system.webserver.cache.ResponseCache; -import com.djrapitops.plugin.api.Benchmark; +import com.djrapitops.plugin.benchmarking.Timings; -import java.util.function.Supplier; +import javax.inject.Inject; +import javax.inject.Singleton; /** * WebServer subsystem for managing WebServer initialization. * * @author Rsl1122 */ +@Singleton public class WebServerSystem implements SubSystem { - private WebServer webServer; + private final WebServer webServer; + private Timings timings; - public WebServerSystem(Supplier locale) { - webServer = new WebServer(locale); - } - - public static WebServerSystem getInstance() { - return PlanSystem.getInstance().getWebServerSystem(); - } - - public static boolean isWebServerEnabled() { - WebServer webServer = getInstance().webServer; - return webServer != null && webServer.isEnabled(); + @Inject + public WebServerSystem(WebServer webServer, Timings timings) { + this.webServer = webServer; + this.timings = timings; } @Override public void enable() throws EnableException { - Benchmark.start("WebServer Initialization"); + timings.start("WebServer Initialization"); webServer.enable(); - ResponseHandler responseHandler = webServer.getResponseHandler(); - responseHandler.registerWebAPIPages(); - responseHandler.registerDefaultPages(); - Benchmark.stop("Enable", "WebServer Initialization"); + timings.end("WebServer Initialization"); } @Override diff --git a/Plan/src/main/java/com/djrapitops/plan/system/webserver/auth/BasicAuthentication.java b/Plan/src/main/java/com/djrapitops/plan/system/webserver/auth/BasicAuthentication.java index 225280e9f..5c170ee1f 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/webserver/auth/BasicAuthentication.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/webserver/auth/BasicAuthentication.java @@ -22,10 +22,12 @@ import com.djrapitops.plan.utilities.PassEncryptUtil; */ public class BasicAuthentication implements Authentication { - private String authenticationString; + private final String authenticationString; + private final Database database; - public BasicAuthentication(String authenticationString) { + public BasicAuthentication(String authenticationString, Database database) { this.authenticationString = authenticationString; + this.database = database; } @Override @@ -41,8 +43,6 @@ public class BasicAuthentication implements Authentication { String passwordRaw = userInfo[1]; try { - - Database database = Database.getActive(); if (!database.check().doesWebUserExists(user)) { throw new WebUserAuthException(FailReason.USER_DOES_NOT_EXIST, user); } diff --git a/Plan/src/main/java/com/djrapitops/plan/system/webserver/cache/PageId.java b/Plan/src/main/java/com/djrapitops/plan/system/webserver/cache/PageId.java index 7aa38dd38..e00924ebe 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/webserver/cache/PageId.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/webserver/cache/PageId.java @@ -26,7 +26,7 @@ public enum PageId { JS("js:"), CSS("css:"), - FAVICON_REDIRECT("Redirect:Favicon"), + FAVICON("Favicon"), PLAYER_PLUGINS_TAB("playerPluginsTab:"), NETWORK_CONTENT("networkContent"); diff --git a/Plan/src/main/java/com/djrapitops/plan/system/webserver/pages/DebugPageHandler.java b/Plan/src/main/java/com/djrapitops/plan/system/webserver/pages/DebugPageHandler.java index 1978dd42b..75025a21b 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/webserver/pages/DebugPageHandler.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/webserver/pages/DebugPageHandler.java @@ -9,8 +9,10 @@ import com.djrapitops.plan.data.WebUser; import com.djrapitops.plan.system.webserver.Request; import com.djrapitops.plan.system.webserver.auth.Authentication; import com.djrapitops.plan.system.webserver.response.Response; -import com.djrapitops.plan.system.webserver.response.pages.DebugPageResponse; +import com.djrapitops.plan.system.webserver.response.ResponseFactory; +import javax.inject.Inject; +import javax.inject.Singleton; import java.util.List; /** @@ -18,11 +20,19 @@ import java.util.List; * * @author Rsl1122 */ -public class DebugPageHandler extends PageHandler { +@Singleton +public class DebugPageHandler implements PageHandler { + + private final ResponseFactory responseFactory; + + @Inject + public DebugPageHandler(ResponseFactory responseFactory) { + this.responseFactory = responseFactory; + } @Override public Response getResponse(Request request, List target) { - return new DebugPageResponse(); + return responseFactory.debugPageResponse(); } @Override diff --git a/Plan/src/main/java/com/djrapitops/plan/system/webserver/pages/PageHandler.java b/Plan/src/main/java/com/djrapitops/plan/system/webserver/pages/PageHandler.java index 28cd24d81..3e1a5b6f6 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/webserver/pages/PageHandler.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/webserver/pages/PageHandler.java @@ -17,7 +17,7 @@ import java.util.List; * * @author Rsl1122 */ -public abstract class PageHandler { +public interface PageHandler { /** * Get the Response of a PageHandler. @@ -26,9 +26,9 @@ public abstract class PageHandler { * @param target Rest of the target coordinates after this page has been solved. * @return Response appropriate to the PageHandler. */ - public abstract Response getResponse(Request request, List target) throws WebException; + Response getResponse(Request request, List target) throws WebException; - public boolean isAuthorized(Authentication auth, List target) throws WebUserAuthException { + default boolean isAuthorized(Authentication auth, List target) throws WebUserAuthException { return true; } diff --git a/Plan/src/main/java/com/djrapitops/plan/system/webserver/pages/PlayerPageHandler.java b/Plan/src/main/java/com/djrapitops/plan/system/webserver/pages/PlayerPageHandler.java index f6527455a..37a8ea36f 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/webserver/pages/PlayerPageHandler.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/webserver/pages/PlayerPageHandler.java @@ -8,20 +8,19 @@ import com.djrapitops.plan.api.exceptions.WebUserAuthException; import com.djrapitops.plan.api.exceptions.connection.NoServersException; import com.djrapitops.plan.api.exceptions.connection.WebException; import com.djrapitops.plan.data.WebUser; -import com.djrapitops.plan.system.database.databases.Database; +import com.djrapitops.plan.system.database.DBSystem; import com.djrapitops.plan.system.info.InfoSystem; -import com.djrapitops.plan.system.locale.Locale; -import com.djrapitops.plan.system.locale.lang.ErrorPageLang; import com.djrapitops.plan.system.webserver.Request; import com.djrapitops.plan.system.webserver.auth.Authentication; import com.djrapitops.plan.system.webserver.cache.PageId; import com.djrapitops.plan.system.webserver.cache.ResponseCache; import com.djrapitops.plan.system.webserver.response.Response; -import com.djrapitops.plan.system.webserver.response.errors.NotFoundResponse; +import com.djrapitops.plan.system.webserver.response.ResponseFactory; import com.djrapitops.plan.system.webserver.response.pages.InspectPageResponse; -import com.djrapitops.plan.system.webserver.response.pages.RawPlayerDataResponse; import com.djrapitops.plan.utilities.uuid.UUIDUtility; +import javax.inject.Inject; +import javax.inject.Singleton; import java.util.List; import java.util.UUID; @@ -30,49 +29,64 @@ import java.util.UUID; * * @author Rsl1122 */ -public class PlayerPageHandler extends PageHandler { +@Singleton +public class PlayerPageHandler implements PageHandler { + + private final ResponseFactory responseFactory; + private final DBSystem dbSystem; + private final InfoSystem infoSystem; + private final UUIDUtility uuidUtility; + + @Inject + public PlayerPageHandler( + ResponseFactory responseFactory, + DBSystem dbSystem, + InfoSystem infoSystem, + UUIDUtility uuidUtility + ) { + this.responseFactory = responseFactory; + this.dbSystem = dbSystem; + this.infoSystem = infoSystem; + this.uuidUtility = uuidUtility; + } @Override public Response getResponse(Request request, List target) throws WebException { if (target.isEmpty()) { - return new NotFoundResponse(request.getLocale().getString(ErrorPageLang.UNKNOWN_PAGE_404)); + return responseFactory.pageNotFound404(); } String playerName = target.get(0); - UUID uuid = UUIDUtility.getUUIDOf(playerName); - Locale locale = request.getLocale(); + UUID uuid = uuidUtility.getUUIDOf(playerName); boolean raw = target.size() >= 2 && target.get(1).equalsIgnoreCase("raw"); if (uuid == null) { - return notFound(locale.getString(ErrorPageLang.UUID_404)); + return responseFactory.uuidNotFound404(); } try { - if (Database.getActive().check().isPlayerRegistered(uuid)) { + // TODO Move this Database dependency to PlayerPage generation in PageFactory instead. + if (dbSystem.getDatabase().check().isPlayerRegistered(uuid)) { if (raw) { - return ResponseCache.loadResponse(PageId.RAW_PLAYER.of(uuid), () -> new RawPlayerDataResponse(uuid)); + return ResponseCache.loadResponse(PageId.RAW_PLAYER.of(uuid), () -> responseFactory.rawPlayerPageResponse(uuid)); } - return playerResponseOrNotFound(uuid, locale); + return playerResponseOrNotFound(uuid); } else { - return notFound(locale.getString(ErrorPageLang.NOT_PLAYED_404)); + return responseFactory.playerNotFound404(); } } catch (NoServersException e) { - ResponseCache.loadResponse(PageId.PLAYER.of(uuid), () -> new NotFoundResponse(e.getMessage())); + ResponseCache.loadResponse(PageId.PLAYER.of(uuid), () -> responseFactory.notFound404(e.getMessage())); } - return InspectPageResponse.getRefreshing(); + return responseFactory.serverNotFound404(); } - private Response playerResponseOrNotFound(UUID uuid, Locale locale) throws WebException { + private Response playerResponseOrNotFound(UUID uuid) throws WebException { Response response = ResponseCache.loadResponse(PageId.PLAYER.of(uuid)); if (!(response instanceof InspectPageResponse)) { - InfoSystem.getInstance().generateAndCachePlayerPage(uuid); + infoSystem.generateAndCachePlayerPage(uuid); response = ResponseCache.loadResponse(PageId.PLAYER.of(uuid)); } - return response != null ? response : notFound(locale.getString(ErrorPageLang.NO_SERVERS_404)); - } - - private Response notFound(String error) { - return ResponseCache.loadResponse(PageId.NOT_FOUND.of(error), () -> new NotFoundResponse(error)); + return response != null ? response : responseFactory.serverNotFound404(); } @Override diff --git a/Plan/src/main/java/com/djrapitops/plan/system/webserver/pages/PlayersPageHandler.java b/Plan/src/main/java/com/djrapitops/plan/system/webserver/pages/PlayersPageHandler.java index 7c97a6f75..8341b42d2 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/webserver/pages/PlayersPageHandler.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/webserver/pages/PlayersPageHandler.java @@ -10,8 +10,10 @@ import com.djrapitops.plan.system.webserver.auth.Authentication; import com.djrapitops.plan.system.webserver.cache.PageId; import com.djrapitops.plan.system.webserver.cache.ResponseCache; import com.djrapitops.plan.system.webserver.response.Response; -import com.djrapitops.plan.system.webserver.response.pages.PlayersPageResponse; +import com.djrapitops.plan.system.webserver.response.ResponseFactory; +import javax.inject.Inject; +import javax.inject.Singleton; import java.util.List; /** @@ -19,11 +21,19 @@ import java.util.List; * * @author Rsl1122 */ -public class PlayersPageHandler extends PageHandler { +@Singleton +public class PlayersPageHandler implements PageHandler { + + private final ResponseFactory responseFactory; + + @Inject + public PlayersPageHandler(ResponseFactory responseFactory) { + this.responseFactory = responseFactory; + } @Override public Response getResponse(Request request, List target) { - return ResponseCache.loadResponse(PageId.PLAYERS.id(), PlayersPageResponse::new); + return ResponseCache.loadResponse(PageId.PLAYERS.id(), responseFactory::playersPageResponse); } @Override diff --git a/Plan/src/main/java/com/djrapitops/plan/system/webserver/pages/RootPageHandler.java b/Plan/src/main/java/com/djrapitops/plan/system/webserver/pages/RootPageHandler.java index ed140c925..95bcd5822 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/webserver/pages/RootPageHandler.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/webserver/pages/RootPageHandler.java @@ -7,12 +7,11 @@ package com.djrapitops.plan.system.webserver.pages; import com.djrapitops.plan.api.exceptions.connection.WebException; import com.djrapitops.plan.data.WebUser; import com.djrapitops.plan.system.webserver.Request; -import com.djrapitops.plan.system.webserver.ResponseHandler; import com.djrapitops.plan.system.webserver.auth.Authentication; -import com.djrapitops.plan.system.webserver.response.DefaultResponses; +import com.djrapitops.plan.system.webserver.response.RedirectResponse; import com.djrapitops.plan.system.webserver.response.Response; +import com.djrapitops.plan.system.webserver.response.ResponseFactory; -import java.util.Collections; import java.util.List; import java.util.Optional; @@ -23,19 +22,19 @@ import java.util.Optional; * * @author Rsl1122 */ -public class RootPageHandler extends PageHandler { +public class RootPageHandler implements PageHandler { - private final ResponseHandler responseHandler; + private final ResponseFactory responseFactory; - public RootPageHandler(ResponseHandler responseHandler) { - this.responseHandler = responseHandler; + public RootPageHandler(ResponseFactory responseFactory) { + this.responseFactory = responseFactory; } @Override public Response getResponse(Request request, List target) throws WebException { Optional auth = request.getAuth(); if (!auth.isPresent()) { - return DefaultResponses.BASIC_AUTH.get(); + return responseFactory.basicAuth(); } WebUser webUser = auth.get().getWebUser(); @@ -43,13 +42,13 @@ public class RootPageHandler extends PageHandler { int permLevel = webUser.getPermLevel(); switch (permLevel) { case 0: - return responseHandler.getPageHandler("server").getResponse(request, Collections.emptyList()); + return new RedirectResponse("/server"); case 1: - return responseHandler.getPageHandler("players").getResponse(request, Collections.emptyList()); + return new RedirectResponse("/players"); case 2: - return responseHandler.getPageHandler("player").getResponse(request, Collections.singletonList(webUser.getName())); + return new RedirectResponse("/player/" + webUser.getName()); default: - return responseHandler.forbiddenResponse(); + return responseFactory.forbidden403(); } } diff --git a/Plan/src/main/java/com/djrapitops/plan/system/webserver/pages/ServerPageHandler.java b/Plan/src/main/java/com/djrapitops/plan/system/webserver/pages/ServerPageHandler.java index c7218bb87..ce40973d8 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/webserver/pages/ServerPageHandler.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/webserver/pages/ServerPageHandler.java @@ -5,19 +5,23 @@ package com.djrapitops.plan.system.webserver.pages; import com.djrapitops.plan.api.exceptions.WebUserAuthException; +import com.djrapitops.plan.api.exceptions.connection.ConnectionFailException; +import com.djrapitops.plan.api.exceptions.connection.NoServersException; import com.djrapitops.plan.api.exceptions.connection.WebException; -import com.djrapitops.plan.system.database.databases.Database; +import com.djrapitops.plan.system.database.DBSystem; import com.djrapitops.plan.system.info.InfoSystem; import com.djrapitops.plan.system.info.server.ServerInfo; +import com.djrapitops.plan.system.processing.Processing; import com.djrapitops.plan.system.webserver.Request; import com.djrapitops.plan.system.webserver.auth.Authentication; import com.djrapitops.plan.system.webserver.cache.PageId; import com.djrapitops.plan.system.webserver.cache.ResponseCache; import com.djrapitops.plan.system.webserver.response.Response; -import com.djrapitops.plan.system.webserver.response.pages.AnalysisPageResponse; -import com.djrapitops.plan.system.webserver.response.pages.RawServerDataResponse; +import com.djrapitops.plan.system.webserver.response.ResponseFactory; import com.djrapitops.plugin.api.Check; +import javax.inject.Inject; +import javax.inject.Singleton; import java.util.List; import java.util.Optional; import java.util.UUID; @@ -27,7 +31,29 @@ import java.util.UUID; * * @author Rsl1122 */ -public class ServerPageHandler extends PageHandler { +@Singleton +public class ServerPageHandler implements PageHandler { + + private final Processing processing; + private final ResponseFactory responseFactory; + private final DBSystem dbSystem; + private final ServerInfo serverInfo; + private final InfoSystem infoSystem; + + @Inject + public ServerPageHandler( + Processing processing, + ResponseFactory responseFactory, + DBSystem dbSystem, + ServerInfo serverInfo, + InfoSystem infoSystem + ) { + this.processing = processing; + this.responseFactory = responseFactory; + this.dbSystem = dbSystem; + this.serverInfo = serverInfo; + this.infoSystem = infoSystem; + } @Override public Response getResponse(Request request, List target) { @@ -35,7 +61,7 @@ public class ServerPageHandler extends PageHandler { boolean raw = target.size() >= 2 && target.get(1).equalsIgnoreCase("raw"); if (raw) { - return ResponseCache.loadResponse(PageId.RAW_SERVER.of(serverUUID), () -> new RawServerDataResponse(serverUUID)); + return ResponseCache.loadResponse(PageId.RAW_SERVER.of(serverUUID), () -> responseFactory.rawServerPageResponse(serverUUID)); } Response response = ResponseCache.loadResponse(PageId.SERVER.of(serverUUID)); @@ -43,24 +69,35 @@ public class ServerPageHandler extends PageHandler { if (response != null) { return response; } else { - if (Check.isBungeeAvailable() && ServerInfo.getServerUUID().equals(serverUUID)) { - try { - InfoSystem.getInstance().updateNetworkPage(); - } catch (WebException e) { - /*Ignore, should not occur*/ - } - return ResponseCache.loadResponse(PageId.SERVER.of(serverUUID)); + if ((Check.isBungeeAvailable() || Check.isVelocityAvailable()) && serverInfo.getServerUUID().equals(serverUUID)) { + return ResponseCache.loadResponse(PageId.SERVER.of(serverUUID), responseFactory::networkPageResponse); } - return AnalysisPageResponse.refreshNow(serverUUID); + return refreshNow(serverUUID); } } + // TODO Split responsibility so that this method does not call system to refresh and also render a refresh page. + private Response refreshNow(UUID serverUUID) { + processing.submitNonCritical(() -> { + try { + infoSystem.generateAnalysisPage(serverUUID); + } catch (NoServersException | ConnectionFailException e) { + ResponseCache.cacheResponse(PageId.SERVER.of(serverUUID), () -> responseFactory.notFound404(e.getMessage())); + } catch (WebException e) { + ResponseCache.cacheResponse(PageId.SERVER.of(serverUUID), () -> responseFactory.internalErrorResponse(e, "Failed to generate Analysis Page")); + } + }); + return responseFactory.refreshingAnalysisResponse(); + } + private UUID getServerUUID(List target) { - UUID serverUUID = ServerInfo.getServerUUID(); + // Default to current server's page + UUID serverUUID = serverInfo.getServerUUID(); + if (!target.isEmpty()) { try { - String serverName = target.get(0).replace("%20", " "); - Optional serverUUIDOptional = Database.getActive().fetch().getServerUUID(serverName); + String serverName = target.get(0); + Optional serverUUIDOptional = dbSystem.getDatabase().fetch().getServerUUID(serverName); if (serverUUIDOptional.isPresent()) { serverUUID = serverUUIDOptional.get(); } diff --git a/Plan/src/main/java/com/djrapitops/plan/system/webserver/pages/TreePageHandler.java b/Plan/src/main/java/com/djrapitops/plan/system/webserver/pages/TreePageHandler.java index 1930f809c..46ee9d53b 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/webserver/pages/TreePageHandler.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/webserver/pages/TreePageHandler.java @@ -6,11 +6,10 @@ package com.djrapitops.plan.system.webserver.pages; import com.djrapitops.plan.api.exceptions.WebUserAuthException; import com.djrapitops.plan.api.exceptions.connection.WebException; -import com.djrapitops.plan.system.locale.lang.ErrorPageLang; import com.djrapitops.plan.system.webserver.Request; import com.djrapitops.plan.system.webserver.auth.Authentication; import com.djrapitops.plan.system.webserver.response.Response; -import com.djrapitops.plan.system.webserver.response.errors.NotFoundResponse; +import com.djrapitops.plan.system.webserver.response.ResponseFactory; import java.util.HashMap; import java.util.List; @@ -21,11 +20,14 @@ import java.util.Map; * * @author Rsl1122 */ -public abstract class TreePageHandler extends PageHandler { +public abstract class TreePageHandler implements PageHandler { + + protected final ResponseFactory responseFactory; private Map pages; - public TreePageHandler() { + public TreePageHandler(ResponseFactory responseFactory) { + this.responseFactory = responseFactory; pages = new HashMap<>(); } @@ -52,7 +54,7 @@ public abstract class TreePageHandler extends PageHandler { PageHandler pageHandler = getPageHandler(target); return pageHandler != null ? pageHandler.getResponse(request, target) - : new NotFoundResponse(request.getLocale().getString(ErrorPageLang.UNKNOWN_PAGE_404)); + : responseFactory.pageNotFound404(); } public PageHandler getPageHandler(List target) { diff --git a/Plan/src/main/java/com/djrapitops/plan/system/webserver/response/ByteResponse.java b/Plan/src/main/java/com/djrapitops/plan/system/webserver/response/ByteResponse.java new file mode 100644 index 000000000..b5b7501ba --- /dev/null +++ b/Plan/src/main/java/com/djrapitops/plan/system/webserver/response/ByteResponse.java @@ -0,0 +1,44 @@ +package com.djrapitops.plan.system.webserver.response; + +import com.djrapitops.plan.system.file.PlanFiles; +import com.djrapitops.plan.system.locale.Locale; +import com.djrapitops.plan.system.settings.theme.Theme; +import com.sun.net.httpserver.HttpExchange; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; + +/** + * {@link Response} for raw bytes. + * + * @author Rsl1122 + */ +public class ByteResponse extends Response { + + private final PlanFiles files; + private final String fileName; + + public ByteResponse(ResponseType type, String fileName, PlanFiles files) { + super(type); + this.fileName = fileName; + this.files = files; + + setHeader("HTTP/1.1 200 OK"); + } + + @Override + public void send(HttpExchange exchange, Locale locale, Theme theme) throws IOException { + responseHeaders.set("Accept-Ranges", "bytes"); + exchange.sendResponseHeaders(getCode(), 0); + + try (OutputStream out = exchange.getResponseBody(); + InputStream bis = files.readCustomizableResource(fileName)) { + byte[] buffer = new byte[2048]; + int count; + while ((count = bis.read(buffer)) != -1) { + out.write(buffer, 0, count); + } + } + } +} diff --git a/Plan/src/main/java/com/djrapitops/plan/system/webserver/response/CSSResponse.java b/Plan/src/main/java/com/djrapitops/plan/system/webserver/response/CSSResponse.java index f381dff85..ecfa36cae 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/webserver/response/CSSResponse.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/webserver/response/CSSResponse.java @@ -1,6 +1,8 @@ package com.djrapitops.plan.system.webserver.response; -import com.djrapitops.plan.system.settings.theme.Theme; +import com.djrapitops.plan.system.file.PlanFiles; + +import java.io.IOException; /** * @author Rsl1122 @@ -8,9 +10,9 @@ import com.djrapitops.plan.system.settings.theme.Theme; */ public class CSSResponse extends FileResponse { - public CSSResponse(String fileName) { - super(format(fileName)); + public CSSResponse(String fileName, PlanFiles files) throws IOException { + super(format(fileName), files); super.setType(ResponseType.CSS); - setContent(Theme.replaceColors(getContent())); + setContent(getContent()); } } diff --git a/Plan/src/main/java/com/djrapitops/plan/system/webserver/response/DefaultResponses.java b/Plan/src/main/java/com/djrapitops/plan/system/webserver/response/DefaultResponses.java index 5278d691a..367e73d21 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/webserver/response/DefaultResponses.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/webserver/response/DefaultResponses.java @@ -10,7 +10,6 @@ package com.djrapitops.plan.system.webserver.response; * @author Rsl1122 */ public enum DefaultResponses { - BASIC_AUTH(PromptAuthorizationResponse.getBasicAuthResponse()), SUCCESS(new TextResponse("Success")); private final Response response; diff --git a/Plan/src/main/java/com/djrapitops/plan/system/webserver/response/FileResponse.java b/Plan/src/main/java/com/djrapitops/plan/system/webserver/response/FileResponse.java index ca749b87e..1c07bab5a 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/webserver/response/FileResponse.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/webserver/response/FileResponse.java @@ -4,8 +4,7 @@ */ package com.djrapitops.plan.system.webserver.response; -import com.djrapitops.plan.system.webserver.response.errors.NotFoundResponse; -import com.djrapitops.plan.utilities.file.FileUtil; +import com.djrapitops.plan.system.file.PlanFiles; import com.djrapitops.plugin.utilities.Verify; import java.io.IOException; @@ -20,13 +19,9 @@ import java.io.IOException; */ public class FileResponse extends Response { - public FileResponse(String fileName) { + public FileResponse(String fileName, PlanFiles files) throws IOException { super.setHeader("HTTP/1.1 200 OK"); - try { - super.setContent(FileUtil.getStringFromResource(fileName)); - } catch (IOException e) { - super.setContent(new NotFoundResponse(fileName + " was not found inside the .jar or /plugins/Plan/ folder").getContent()); - } + super.setContent(files.readCustomizableResourceFlat(fileName)); } public static String format(String fileName) { diff --git a/Plan/src/main/java/com/djrapitops/plan/system/webserver/response/JavaScriptResponse.java b/Plan/src/main/java/com/djrapitops/plan/system/webserver/response/JavaScriptResponse.java index bcfba7697..aa31e00fd 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/webserver/response/JavaScriptResponse.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/webserver/response/JavaScriptResponse.java @@ -1,11 +1,8 @@ package com.djrapitops.plan.system.webserver.response; -import com.djrapitops.plan.system.settings.theme.Theme; -import com.djrapitops.plan.system.settings.theme.ThemeVal; -import org.apache.commons.text.StringSubstitutor; +import com.djrapitops.plan.system.file.PlanFiles; -import java.util.HashMap; -import java.util.Map; +import java.io.IOException; /** * @author Rsl1122 @@ -13,11 +10,8 @@ import java.util.Map; */ public class JavaScriptResponse extends FileResponse { - public JavaScriptResponse(String fileName) { - super(format(fileName)); + JavaScriptResponse(String fileName, PlanFiles files) throws IOException { + super(format(fileName), files); super.setType(ResponseType.JAVASCRIPT); - Map replace = new HashMap<>(); - replace.put("defaultTheme", Theme.getValue(ThemeVal.THEME_DEFAULT)); - setContent(StringSubstitutor.replace(Theme.replaceColors(getContent()), replace)); } } diff --git a/Plan/src/main/java/com/djrapitops/plan/system/webserver/response/PromptAuthorizationResponse.java b/Plan/src/main/java/com/djrapitops/plan/system/webserver/response/PromptAuthorizationResponse.java index 08fe60580..95aa49c9b 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/webserver/response/PromptAuthorizationResponse.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/webserver/response/PromptAuthorizationResponse.java @@ -1,11 +1,16 @@ package com.djrapitops.plan.system.webserver.response; import com.djrapitops.plan.api.exceptions.WebUserAuthException; +import com.djrapitops.plan.system.file.PlanFiles; +import com.djrapitops.plan.system.update.VersionCheckSystem; import com.djrapitops.plan.system.webserver.auth.FailReason; import com.djrapitops.plan.system.webserver.response.errors.ErrorResponse; -import com.djrapitops.plan.utilities.FormatUtils; import com.djrapitops.plan.utilities.html.icon.Icon; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; + /** * @author Rsl1122 * @since 3.5.2 @@ -17,12 +22,13 @@ public class PromptAuthorizationResponse extends ErrorResponse { + "- Username and password are case-sensitive
" + "
If you have forgotten your password, ask a staff member to delete your old user and re-register."; - private PromptAuthorizationResponse() { + private PromptAuthorizationResponse(VersionCheckSystem versionCheckSystem, PlanFiles files) throws IOException { + super(versionCheckSystem, files); super.setTitle(Icon.called("lock").build() + " 401 Unauthorized"); } - public static PromptAuthorizationResponse getBasicAuthResponse() { - PromptAuthorizationResponse response = new PromptAuthorizationResponse(); + public static PromptAuthorizationResponse getBasicAuthResponse(VersionCheckSystem versionCheckSystem, PlanFiles files) throws IOException { + PromptAuthorizationResponse response = new PromptAuthorizationResponse(versionCheckSystem, files); response.setHeader("HTTP/1.1 401 Access Denied\r\n" + "WWW-Authenticate: Basic realm=\"/\";"); @@ -31,8 +37,8 @@ public class PromptAuthorizationResponse extends ErrorResponse { return response; } - public static PromptAuthorizationResponse getBasicAuthResponse(WebUserAuthException e) { - PromptAuthorizationResponse response = new PromptAuthorizationResponse(); + public static PromptAuthorizationResponse getBasicAuthResponse(WebUserAuthException e, VersionCheckSystem versionCheckSystem, PlanFiles files) throws IOException { + PromptAuthorizationResponse response = new PromptAuthorizationResponse(versionCheckSystem, files); response.setHeader("HTTP/1.1 401 Access Denied\r\n" + "WWW-Authenticate: Basic realm=\"/\";"); @@ -41,7 +47,7 @@ public class PromptAuthorizationResponse extends ErrorResponse { if (failReason == FailReason.ERROR) { StringBuilder errorBuilder = new StringBuilder("

");
-            for (String line : FormatUtils.getStackTrace(e.getCause())) {
+            for (String line : getStackTrace(e.getCause())) {
                 errorBuilder.append(line);
             }
             errorBuilder.append("
"); @@ -53,4 +59,29 @@ public class PromptAuthorizationResponse extends ErrorResponse { response.replacePlaceholders(); return response; } + + /** + * Gets lines for stack trace recursively. + * + * @param throwable Throwable element + * @return lines of stack trace. + */ + private static List getStackTrace(Throwable throwable) { + List stackTrace = new ArrayList<>(); + stackTrace.add(throwable.toString()); + for (StackTraceElement element : throwable.getStackTrace()) { + stackTrace.add(" " + element.toString()); + } + + Throwable cause = throwable.getCause(); + if (cause != null) { + List causeTrace = getStackTrace(cause); + if (!causeTrace.isEmpty()) { + causeTrace.set(0, "Caused by: " + causeTrace.get(0)); + stackTrace.addAll(causeTrace); + } + } + + return stackTrace; + } } diff --git a/Plan/src/main/java/com/djrapitops/plan/system/webserver/response/RedirectResponse.java b/Plan/src/main/java/com/djrapitops/plan/system/webserver/response/RedirectResponse.java index 86fa225a4..430090c97 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/webserver/response/RedirectResponse.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/webserver/response/RedirectResponse.java @@ -1,6 +1,7 @@ package com.djrapitops.plan.system.webserver.response; import com.djrapitops.plan.system.locale.Locale; +import com.djrapitops.plan.system.settings.theme.Theme; import com.sun.net.httpserver.HttpExchange; import java.io.IOException; @@ -17,8 +18,8 @@ public class RedirectResponse extends Response { } @Override - public void send(HttpExchange exchange, Locale locale) throws IOException { + public void send(HttpExchange exchange, Locale locale, Theme theme) throws IOException { responseHeaders.set("Location", getContent()); - super.send(exchange, locale); + super.send(exchange, locale, theme); } } diff --git a/Plan/src/main/java/com/djrapitops/plan/system/webserver/response/Response.java b/Plan/src/main/java/com/djrapitops/plan/system/webserver/response/Response.java index 349a209c4..afc9ae30d 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/webserver/response/Response.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/webserver/response/Response.java @@ -1,6 +1,7 @@ package com.djrapitops.plan.system.webserver.response; import com.djrapitops.plan.system.locale.Locale; +import com.djrapitops.plan.system.settings.theme.Theme; import com.sun.net.httpserver.Headers; import com.sun.net.httpserver.HttpExchange; @@ -83,14 +84,17 @@ public abstract class Response { this.responseHeaders = responseHeaders; } - public void send(HttpExchange exchange, Locale locale) throws IOException { + public void send(HttpExchange exchange, Locale locale, Theme theme) throws IOException { responseHeaders.set("Content-Type", type); responseHeaders.set("Content-Encoding", "gzip"); exchange.sendResponseHeaders(getCode(), 0); - String sentContent = this instanceof JavaScriptResponse - ? getContent() - : locale.replaceMatchingLanguage(getContent()); + String sentContent = getContent(); + // TODO Smell + if (!(this instanceof JavaScriptResponse)) { + sentContent = locale.replaceMatchingLanguage(sentContent); + } + sentContent = theme.replaceThemeColors(sentContent); try ( GZIPOutputStream out = new GZIPOutputStream(exchange.getResponseBody()); diff --git a/Plan/src/main/java/com/djrapitops/plan/system/webserver/response/ResponseFactory.java b/Plan/src/main/java/com/djrapitops/plan/system/webserver/response/ResponseFactory.java new file mode 100644 index 000000000..9e9137b8e --- /dev/null +++ b/Plan/src/main/java/com/djrapitops/plan/system/webserver/response/ResponseFactory.java @@ -0,0 +1,198 @@ +package com.djrapitops.plan.system.webserver.response; + +import com.djrapitops.plan.api.exceptions.ParseException; +import com.djrapitops.plan.api.exceptions.WebUserAuthException; +import com.djrapitops.plan.system.database.DBSystem; +import com.djrapitops.plan.system.file.PlanFiles; +import com.djrapitops.plan.system.locale.Locale; +import com.djrapitops.plan.system.locale.lang.ErrorPageLang; +import com.djrapitops.plan.system.update.VersionCheckSystem; +import com.djrapitops.plan.system.webserver.response.errors.*; +import com.djrapitops.plan.system.webserver.response.pages.*; +import com.djrapitops.plan.utilities.html.pages.PageFactory; +import com.djrapitops.plugin.logging.L; +import com.djrapitops.plugin.logging.error.ErrorHandler; + +import javax.inject.Inject; +import javax.inject.Singleton; +import java.io.IOException; +import java.util.UUID; + +/** + * Factory for creating different {@link Response} objects. + * + * @author Rsl1122 + */ +@Singleton +public class ResponseFactory { + + private final VersionCheckSystem versionCheckSystem; + private final PlanFiles files; + private final PageFactory pageFactory; + private final Locale locale; + private final DBSystem dbSystem; + private final ErrorHandler errorHandler; + + @Inject + public ResponseFactory( + VersionCheckSystem versionCheckSystem, + PlanFiles files, + PageFactory pageFactory, + Locale locale, + DBSystem dbSystem, + ErrorHandler errorHandler + ) { + this.versionCheckSystem = versionCheckSystem; + this.files = files; + this.pageFactory = pageFactory; + this.locale = locale; + this.dbSystem = dbSystem; + this.errorHandler = errorHandler; + } + + public Response debugPageResponse() { + try { + return new DebugPageResponse(pageFactory.debugPage(), versionCheckSystem, files); + } catch (IOException e) { + return internalErrorResponse(e, "Failed to parse debug page"); + } + } + + public Response playersPageResponse() { + try { + return new PlayersPageResponse(pageFactory.playersPage()); + } catch (ParseException e) { + return internalErrorResponse(e, "Failed to parse players page"); + } + } + + public ErrorResponse internalErrorResponse(Throwable e, String s) { + try { + errorHandler.log(L.WARN, this.getClass(), e); + return new InternalErrorResponse(s, e, versionCheckSystem, files); + } catch (IOException improperRestartException) { + return new ErrorResponse( + "Error occurred: " + e.toString() + + ", additional error occurred when attempting to send error page to user: " + + improperRestartException.toString() + ); + } + } + + public Response networkPageResponse() { + try { + return new NetworkPageResponse(pageFactory.networkPage()); + } catch (ParseException e) { + return internalErrorResponse(e, "Failed to parse network page"); + } + } + + public RawDataResponse rawPlayerPageResponse(UUID uuid) { + return new RawPlayerDataResponse(dbSystem.getDatabase().fetch().getPlayerContainer(uuid)); + } + + public RawDataResponse rawServerPageResponse(UUID serverUUID) { + return new RawServerDataResponse(dbSystem.getDatabase().fetch().getServerContainer(serverUUID)); + } + + public Response javaScriptResponse(String fileName) { + try { + return new JavaScriptResponse(fileName, files); + } catch (IOException e) { + return notFound404("JS File not found from jar: " + fileName + ", " + e.toString()); + } + } + + public Response cssResponse(String fileName) { + try { + return new CSSResponse(fileName, files); + } catch (IOException e) { + return notFound404("CSS File not found from jar: " + fileName + ", " + e.toString()); + } + } + + public Response redirectResponse(String location) { + return new RedirectResponse(location); + } + + public Response faviconResponse() { + return new ByteResponse(ResponseType.X_ICON, "web/favicon.ico", files); + } + + public ErrorResponse pageNotFound404() { + return notFound404(locale.getString(ErrorPageLang.UNKNOWN_PAGE_404)); + } + + public ErrorResponse uuidNotFound404() { + return notFound404(locale.getString(ErrorPageLang.UUID_404)); + } + + public ErrorResponse playerNotFound404() { + return notFound404(locale.getString(ErrorPageLang.NOT_PLAYED_404)); + } + + public ErrorResponse serverNotFound404() { + return notFound404(locale.getString(ErrorPageLang.NO_SERVERS_404)); + } + + public ErrorResponse notFound404(String message) { + try { + return new NotFoundResponse(message, versionCheckSystem, files); + } catch (IOException e) { + return internalErrorResponse(e, "Failed to parse 404 page"); + } + } + + public ErrorResponse basicAuthFail(WebUserAuthException e) { + try { + return PromptAuthorizationResponse.getBasicAuthResponse(e, versionCheckSystem, files); + } catch (IOException e1) { + return internalErrorResponse(e, "Failed to parse PromptAuthorizationResponse"); + } + } + + public ErrorResponse forbidden403() { + return forbidden403("Your user is not authorized to view this page.
" + + "If you believe this is an error contact staff to change your access level."); + } + + public ErrorResponse forbidden403(String message) { + try { + return new ForbiddenResponse(message, versionCheckSystem, files); + } catch (IOException e) { + return internalErrorResponse(e, "Failed to parse ForbiddenResponse"); + } + } + + public ErrorResponse unauthorizedServer(String message) { + try { + return new UnauthorizedServerResponse(message, versionCheckSystem, files); + } catch (IOException e) { + return internalErrorResponse(e, "Failed to parse UnauthorizedServerResponse"); + } + } + + public ErrorResponse gatewayError504(String message) { + try { + return new GatewayErrorResponse(message, versionCheckSystem, files); + } catch (IOException e) { + return internalErrorResponse(e, "Failed to parse GatewayErrorResponse"); + } + } + + public ErrorResponse basicAuth() { + try { + return PromptAuthorizationResponse.getBasicAuthResponse(versionCheckSystem, files); + } catch (IOException e) { + return internalErrorResponse(e, "Failed to parse PromptAuthorizationResponse"); + } + } + + public ErrorResponse refreshingAnalysisResponse() { + try { + return new RefreshingAnalysisResponse(versionCheckSystem, files); + } catch (IOException e) { + return internalErrorResponse(e, "Failed to parse RefreshingAnalysisResponse"); + } + } +} \ No newline at end of file diff --git a/Plan/src/main/java/com/djrapitops/plan/system/webserver/response/ResponseType.java b/Plan/src/main/java/com/djrapitops/plan/system/webserver/response/ResponseType.java index 85ea8b115..85a1f0799 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/webserver/response/ResponseType.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/webserver/response/ResponseType.java @@ -13,7 +13,9 @@ public enum ResponseType { HTML("text/html; charset=utf-8"), CSS("text/css"), JSON("application/json"), - JAVASCRIPT("application/javascript"); + JAVASCRIPT("application/javascript"), + IMAGE("image/gif"), + X_ICON("image/x-icon"); private final String type; diff --git a/Plan/src/main/java/com/djrapitops/plan/system/webserver/response/errors/ErrorResponse.java b/Plan/src/main/java/com/djrapitops/plan/system/webserver/response/errors/ErrorResponse.java index 78aa8810a..d23b7852f 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/webserver/response/errors/ErrorResponse.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/webserver/response/errors/ErrorResponse.java @@ -4,11 +4,9 @@ */ package com.djrapitops.plan.system.webserver.response.errors; -import com.djrapitops.plan.system.settings.theme.Theme; +import com.djrapitops.plan.system.file.PlanFiles; +import com.djrapitops.plan.system.update.VersionCheckSystem; import com.djrapitops.plan.system.webserver.response.pages.PageResponse; -import com.djrapitops.plan.utilities.MiscUtils; -import com.djrapitops.plan.utilities.file.FileUtil; -import com.djrapitops.plugin.api.utility.log.Log; import org.apache.commons.text.StringSubstitutor; import java.io.IOException; @@ -25,12 +23,15 @@ public class ErrorResponse extends PageResponse { private String title; private String paragraph; - public ErrorResponse() { - try { - setContent(Theme.replaceColors(FileUtil.getStringFromResource("web/error.html"))); - } catch (IOException e) { - Log.toLog(this.getClass(), e); - } + private VersionCheckSystem versionCheckSystem; + + public ErrorResponse(VersionCheckSystem versionCheckSystem, PlanFiles files) throws IOException { + this.versionCheckSystem = versionCheckSystem; + setContent(files.readCustomizableResourceFlat("web/error.html")); + } + + public ErrorResponse(String message) { + setContent(message); } public void replacePlaceholders() { @@ -39,7 +40,8 @@ public class ErrorResponse extends PageResponse { String[] split = title.split(">", 3); placeHolders.put("titleText", split.length == 3 ? split[2] : title); placeHolders.put("paragraph", paragraph); - placeHolders.put("version", MiscUtils.getPlanVersion()); + placeHolders.put("version", versionCheckSystem.getCurrentVersion()); + placeHolders.put("update", versionCheckSystem.getUpdateHtml().orElse("")); setContent(StringSubstitutor.replace(getContent(), placeHolders)); } diff --git a/Plan/src/main/java/com/djrapitops/plan/system/webserver/response/errors/ForbiddenResponse.java b/Plan/src/main/java/com/djrapitops/plan/system/webserver/response/errors/ForbiddenResponse.java index 3ac171516..29d41f2b9 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/webserver/response/errors/ForbiddenResponse.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/webserver/response/errors/ForbiddenResponse.java @@ -1,15 +1,19 @@ package com.djrapitops.plan.system.webserver.response.errors; +import com.djrapitops.plan.system.file.PlanFiles; +import com.djrapitops.plan.system.update.VersionCheckSystem; import com.djrapitops.plan.utilities.html.icon.Family; import com.djrapitops.plan.utilities.html.icon.Icon; +import java.io.IOException; + /** * @author Rsl1122 * @since 3.5.2 */ public class ForbiddenResponse extends ErrorResponse { - - public ForbiddenResponse(String msg) { + public ForbiddenResponse(String msg, VersionCheckSystem versionCheckSystem, PlanFiles files) throws IOException { + super(versionCheckSystem, files); super.setHeader("HTTP/1.1 403 Forbidden"); super.setTitle(Icon.called("hand-paper").of(Family.REGULAR) + " 403 Forbidden - Access Denied"); super.setParagraph(msg); diff --git a/Plan/src/main/java/com/djrapitops/plan/system/webserver/response/errors/GatewayErrorResponse.java b/Plan/src/main/java/com/djrapitops/plan/system/webserver/response/errors/GatewayErrorResponse.java index b595e95ff..0215855bd 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/webserver/response/errors/GatewayErrorResponse.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/webserver/response/errors/GatewayErrorResponse.java @@ -4,6 +4,11 @@ */ package com.djrapitops.plan.system.webserver.response.errors; +import com.djrapitops.plan.system.file.PlanFiles; +import com.djrapitops.plan.system.update.VersionCheckSystem; + +import java.io.IOException; + /** * ErrorResponse for GatewayException. * @@ -11,7 +16,8 @@ package com.djrapitops.plan.system.webserver.response.errors; */ public class GatewayErrorResponse extends ErrorResponse { - public GatewayErrorResponse(String message) { + public GatewayErrorResponse(String message, VersionCheckSystem versionCheckSystem, PlanFiles files) throws IOException { + super(versionCheckSystem, files); super.setHeader("HTTP/1.1 504 Gateway Error"); super.setTitle("Failed to Connect (Gateway Error)"); super.setParagraph(message); diff --git a/Plan/src/main/java/com/djrapitops/plan/system/webserver/response/errors/InternalErrorResponse.java b/Plan/src/main/java/com/djrapitops/plan/system/webserver/response/errors/InternalErrorResponse.java index 958857df3..98a022a29 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/webserver/response/errors/InternalErrorResponse.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/webserver/response/errors/InternalErrorResponse.java @@ -1,15 +1,20 @@ package com.djrapitops.plan.system.webserver.response.errors; +import com.djrapitops.plan.system.file.PlanFiles; +import com.djrapitops.plan.system.update.VersionCheckSystem; import com.djrapitops.plan.utilities.html.Html; import com.djrapitops.plan.utilities.html.icon.Icon; +import java.io.IOException; + /** * @author Rsl1122 * @since 3.5.2 */ public class InternalErrorResponse extends ErrorResponse { - public InternalErrorResponse(String cause, Throwable e) { + public InternalErrorResponse(String cause, Throwable e, VersionCheckSystem versionCheckSystem, PlanFiles files) throws IOException { + super(versionCheckSystem, files); super.setHeader("HTTP/1.1 500 Internal Error"); super.setTitle(Icon.called("bug") + " 500 Internal Error occurred"); diff --git a/Plan/src/main/java/com/djrapitops/plan/system/webserver/response/errors/NotFoundResponse.java b/Plan/src/main/java/com/djrapitops/plan/system/webserver/response/errors/NotFoundResponse.java index 35c94faa8..9e3e302f0 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/webserver/response/errors/NotFoundResponse.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/webserver/response/errors/NotFoundResponse.java @@ -1,24 +1,25 @@ package com.djrapitops.plan.system.webserver.response.errors; +import com.djrapitops.plan.system.file.PlanFiles; +import com.djrapitops.plan.system.update.VersionCheckSystem; import com.djrapitops.plan.utilities.html.icon.Icon; +import java.io.IOException; + /** + * Generic 404 response. + * * @author Rsl1122 * @since 3.5.2 */ public class NotFoundResponse extends ErrorResponse { - public NotFoundResponse() { - super.setHeader("HTTP/1.1 404 Not Found"); - super.setTitle(Icon.called("map-signs") + " 404 Not Found"); - super.setParagraph("Page does not exist."); - super.replacePlaceholders(); - } - - public NotFoundResponse(String msg) { + public NotFoundResponse(String msg, VersionCheckSystem versionCheckSystem, PlanFiles files) throws IOException { + super(versionCheckSystem, files); super.setHeader("HTTP/1.1 404 Not Found"); super.setTitle(Icon.called("map-signs") + " 404 Not Found"); super.setParagraph(msg); super.replacePlaceholders(); } + } diff --git a/Plan/src/main/java/com/djrapitops/plan/system/webserver/response/errors/RefreshingAnalysisResponse.java b/Plan/src/main/java/com/djrapitops/plan/system/webserver/response/errors/RefreshingAnalysisResponse.java new file mode 100644 index 000000000..3844b3772 --- /dev/null +++ b/Plan/src/main/java/com/djrapitops/plan/system/webserver/response/errors/RefreshingAnalysisResponse.java @@ -0,0 +1,22 @@ +package com.djrapitops.plan.system.webserver.response.errors; + +import com.djrapitops.plan.system.file.PlanFiles; +import com.djrapitops.plan.system.update.VersionCheckSystem; + +import java.io.IOException; + +/** + * This response is used when Analysis is being refreshed and the user needs some feedback. + * + * @author Rsl1122 + */ +public class RefreshingAnalysisResponse extends ErrorResponse { + + public RefreshingAnalysisResponse(VersionCheckSystem versionCheckSystem, PlanFiles files) throws IOException { + super(versionCheckSystem, files); + + setTitle("Analysis is being refreshed.."); + setParagraph(" Analysis is being run, refresh the page after a few seconds.. (F5)"); + replacePlaceholders(); + } +} \ No newline at end of file diff --git a/Plan/src/main/java/com/djrapitops/plan/system/webserver/response/errors/UnauthorizedServerResponse.java b/Plan/src/main/java/com/djrapitops/plan/system/webserver/response/errors/UnauthorizedServerResponse.java index 0443674fd..cee4863b4 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/webserver/response/errors/UnauthorizedServerResponse.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/webserver/response/errors/UnauthorizedServerResponse.java @@ -4,14 +4,19 @@ */ package com.djrapitops.plan.system.webserver.response.errors; +import com.djrapitops.plan.system.file.PlanFiles; +import com.djrapitops.plan.system.update.VersionCheckSystem; + +import java.io.IOException; + /** * Response when Server is not found in database when attempting to InfoRequest. * * @author Rsl1122 */ public class UnauthorizedServerResponse extends ErrorResponse { - - public UnauthorizedServerResponse(String message) { + public UnauthorizedServerResponse(String message, VersionCheckSystem versionCheckSystem, PlanFiles files) throws IOException { + super(versionCheckSystem, files); super.setHeader("HTTP/1.1 412 Unauthorized"); super.setTitle("Unauthorized Server"); super.setParagraph(message); diff --git a/Plan/src/main/java/com/djrapitops/plan/system/webserver/response/pages/AnalysisPageResponse.java b/Plan/src/main/java/com/djrapitops/plan/system/webserver/response/pages/AnalysisPageResponse.java index 9d3655458..4f240e915 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/webserver/response/pages/AnalysisPageResponse.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/webserver/response/pages/AnalysisPageResponse.java @@ -1,37 +1,11 @@ package com.djrapitops.plan.system.webserver.response.pages; -import com.djrapitops.plan.api.exceptions.connection.ConnectionFailException; -import com.djrapitops.plan.api.exceptions.connection.NoServersException; -import com.djrapitops.plan.api.exceptions.connection.WebException; -import com.djrapitops.plan.system.info.InfoSystem; -import com.djrapitops.plan.system.processing.Processing; -import com.djrapitops.plan.system.webserver.cache.PageId; -import com.djrapitops.plan.system.webserver.cache.ResponseCache; -import com.djrapitops.plan.system.webserver.response.errors.NotFoundResponse; -import com.djrapitops.plan.utilities.html.pages.AnalysisPage; -import com.djrapitops.plugin.api.utility.log.Log; - -import java.util.UUID; - /** * @author Rsl1122 * @since 3.5.2 */ public class AnalysisPageResponse extends PageResponse { - public static AnalysisPageResponse refreshNow(UUID serverUUID) { - Processing.submitNonCritical(() -> { - try { - InfoSystem.getInstance().generateAnalysisPage(serverUUID); - } catch (NoServersException | ConnectionFailException e) { - ResponseCache.cacheResponse(PageId.SERVER.of(serverUUID), () -> new NotFoundResponse(e.getMessage())); - } catch (WebException e) { - Log.toLog(AnalysisPageResponse.class.getName(), e); - } - }); - return new AnalysisPageResponse(AnalysisPage.getRefreshingHtml()); - } - public AnalysisPageResponse(String html) { super.setHeader("HTTP/1.1 200 OK"); super.setContent(html); diff --git a/Plan/src/main/java/com/djrapitops/plan/system/webserver/response/pages/DebugPageResponse.java b/Plan/src/main/java/com/djrapitops/plan/system/webserver/response/pages/DebugPageResponse.java index a263d0d3a..6d5b8a8df 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/webserver/response/pages/DebugPageResponse.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/webserver/response/pages/DebugPageResponse.java @@ -4,10 +4,14 @@ */ package com.djrapitops.plan.system.webserver.response.pages; +import com.djrapitops.plan.system.file.PlanFiles; +import com.djrapitops.plan.system.update.VersionCheckSystem; import com.djrapitops.plan.system.webserver.response.errors.ErrorResponse; import com.djrapitops.plan.utilities.html.icon.Icon; import com.djrapitops.plan.utilities.html.pages.DebugPage; +import java.io.IOException; + /** * WebServer response for /debug-page used for easing issue reporting. * @@ -15,10 +19,11 @@ import com.djrapitops.plan.utilities.html.pages.DebugPage; */ public class DebugPageResponse extends ErrorResponse { - public DebugPageResponse() { + public DebugPageResponse(DebugPage debugPage, VersionCheckSystem versionCheckSystem, PlanFiles files) throws IOException { + super(versionCheckSystem, files); super.setHeader("HTTP/1.1 200 OK"); super.setTitle(Icon.called("bug") + " Debug Information"); - super.setParagraph(new DebugPage().toHtml()); + super.setParagraph(debugPage.toHtml()); replacePlaceholders(); } diff --git a/Plan/src/main/java/com/djrapitops/plan/system/webserver/response/pages/InspectPageResponse.java b/Plan/src/main/java/com/djrapitops/plan/system/webserver/response/pages/InspectPageResponse.java index d201f4657..95d1a8a91 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/webserver/response/pages/InspectPageResponse.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/webserver/response/pages/InspectPageResponse.java @@ -1,9 +1,7 @@ package com.djrapitops.plan.system.webserver.response.pages; -import com.djrapitops.plan.system.settings.theme.Theme; import com.djrapitops.plan.system.webserver.cache.PageId; import com.djrapitops.plan.system.webserver.cache.ResponseCache; -import com.djrapitops.plan.system.webserver.response.errors.ErrorResponse; import com.djrapitops.plan.system.webserver.response.pages.parts.InspectPagePluginsContent; import org.apache.commons.text.StringSubstitutor; @@ -22,7 +20,7 @@ public class InspectPageResponse extends PageResponse { public InspectPageResponse(UUID uuid, String html) { super.setHeader("HTTP/1.1 200 OK"); - super.setContent(Theme.replaceColors(html)); + super.setContent(html); this.uuid = uuid; } @@ -42,14 +40,6 @@ public class InspectPageResponse extends PageResponse { return new String[]{"
  • Calculating...
  • ", ""}; } - public static InspectPageResponse getRefreshing() { - ErrorResponse refreshPage = new ErrorResponse(); - refreshPage.setTitle("Player page request is being processed.."); - refreshPage.setParagraph(" Page will refresh automatically.."); - refreshPage.replacePlaceholders(); - return new InspectPageResponse(null, refreshPage.getContent()); - } - @Override public boolean equals(Object o) { if (this == o) return true; diff --git a/Plan/src/main/java/com/djrapitops/plan/system/webserver/response/pages/NetworkPageResponse.java b/Plan/src/main/java/com/djrapitops/plan/system/webserver/response/pages/NetworkPageResponse.java index e2316491c..bcd5afe66 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/webserver/response/pages/NetworkPageResponse.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/webserver/response/pages/NetworkPageResponse.java @@ -1,8 +1,6 @@ package com.djrapitops.plan.system.webserver.response.pages; import com.djrapitops.plan.api.exceptions.ParseException; -import com.djrapitops.plan.data.store.containers.NetworkContainer; -import com.djrapitops.plan.system.database.databases.Database; import com.djrapitops.plan.utilities.html.pages.NetworkPage; /** @@ -12,9 +10,8 @@ import com.djrapitops.plan.utilities.html.pages.NetworkPage; */ public class NetworkPageResponse extends PageResponse { - public NetworkPageResponse() throws ParseException { - super.setHeader("HTTP/1.1 200 OK"); - NetworkContainer networkContainer = Database.getActive().fetch().getNetworkContainer(); // Not cached, big. - setContent(new NetworkPage(networkContainer).toHtml()); + public NetworkPageResponse(NetworkPage networkPage) throws ParseException { + setHeader("HTTP/1.1 200 OK"); + setContent(networkPage.toHtml()); } } \ No newline at end of file diff --git a/Plan/src/main/java/com/djrapitops/plan/system/webserver/response/pages/PlayersPageResponse.java b/Plan/src/main/java/com/djrapitops/plan/system/webserver/response/pages/PlayersPageResponse.java index d076bb0dd..6322e9a1a 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/webserver/response/pages/PlayersPageResponse.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/webserver/response/pages/PlayersPageResponse.java @@ -1,9 +1,7 @@ package com.djrapitops.plan.system.webserver.response.pages; import com.djrapitops.plan.api.exceptions.ParseException; -import com.djrapitops.plan.system.webserver.response.errors.InternalErrorResponse; import com.djrapitops.plan.utilities.html.pages.PlayersPage; -import com.djrapitops.plugin.api.utility.log.Log; /** * @author Rsl1122 @@ -11,13 +9,8 @@ import com.djrapitops.plugin.api.utility.log.Log; */ public class PlayersPageResponse extends PageResponse { - public PlayersPageResponse() { - super.setHeader("HTTP/1.1 200 OK"); - try { - super.setContent(new PlayersPage().toHtml()); - } catch (ParseException e) { - Log.toLog(this.getClass(), e); - setContent(new InternalErrorResponse("/players", e).getContent()); - } + public PlayersPageResponse(PlayersPage playersPage) throws ParseException { + setHeader("HTTP/1.1 200 OK"); + setContent(playersPage.toHtml()); } } diff --git a/Plan/src/main/java/com/djrapitops/plan/system/webserver/response/pages/RawPlayerDataResponse.java b/Plan/src/main/java/com/djrapitops/plan/system/webserver/response/pages/RawPlayerDataResponse.java index 6a9ee2391..747544886 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/webserver/response/pages/RawPlayerDataResponse.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/webserver/response/pages/RawPlayerDataResponse.java @@ -1,8 +1,6 @@ package com.djrapitops.plan.system.webserver.response.pages; -import com.djrapitops.plan.system.database.databases.Database; - -import java.util.UUID; +import com.djrapitops.plan.data.store.containers.PlayerContainer; /** * Raw Data JSON response for a Player. @@ -11,7 +9,7 @@ import java.util.UUID; */ public class RawPlayerDataResponse extends RawDataResponse { - public RawPlayerDataResponse(UUID uuid) { - super(Database.getActive().fetch().getPlayerContainer(uuid)); + public RawPlayerDataResponse(PlayerContainer playerContainer) { + super(playerContainer); } } \ No newline at end of file diff --git a/Plan/src/main/java/com/djrapitops/plan/system/webserver/response/pages/RawServerDataResponse.java b/Plan/src/main/java/com/djrapitops/plan/system/webserver/response/pages/RawServerDataResponse.java index acb61ba99..3cf31732a 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/webserver/response/pages/RawServerDataResponse.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/webserver/response/pages/RawServerDataResponse.java @@ -1,8 +1,6 @@ package com.djrapitops.plan.system.webserver.response.pages; -import com.djrapitops.plan.system.database.databases.Database; - -import java.util.UUID; +import com.djrapitops.plan.data.store.containers.ServerContainer; /** * Raw Data JSON response for a Server. @@ -11,7 +9,7 @@ import java.util.UUID; */ public class RawServerDataResponse extends RawDataResponse { - public RawServerDataResponse(UUID serverUUID) { - super(Database.getActive().fetch().getServerContainer(serverUUID)); + public RawServerDataResponse(ServerContainer serverContainer) { + super(serverContainer); } } \ No newline at end of file diff --git a/Plan/src/main/java/com/djrapitops/plan/system/webserver/response/pages/parts/InspectPagePluginsContent.java b/Plan/src/main/java/com/djrapitops/plan/system/webserver/response/pages/parts/InspectPagePluginsContent.java index bcba4c45c..be4fee519 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/webserver/response/pages/parts/InspectPagePluginsContent.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/webserver/response/pages/parts/InspectPagePluginsContent.java @@ -37,11 +37,11 @@ public class InspectPagePluginsContent extends PageResponse { addTab(serverUUID, nav, html); } - public static InspectPagePluginsContent generateForThisServer(UUID playerUUID) { - HookHandler hookHandler = HookHandler.getInstance(); + public static InspectPagePluginsContent generateForThisServer(UUID playerUUID, ServerInfo serverInfo, HookHandler hookHandler) { + String serverName = serverInfo.getServer().getName(); + String actualServerName = serverName.equals("Plan") ? "Server " + serverInfo.getServer().getId() : serverName; + Map containers = hookHandler.getInspectContainersFor(playerUUID); - String serverName = ServerInfo.getServerName(); - String actualServerName = serverName.equals("Plan") ? "Server " + ServerInfo.getServerID() : serverName; if (containers.isEmpty()) { return new InspectPagePluginsContent(playerUUID, "
  • " + actualServerName + " (No Data)
  • ", "
    " + @@ -50,7 +50,12 @@ public class InspectPagePluginsContent extends PageResponse { } String nav = "
  • " + actualServerName + "
  • "; + String tab = createTab(containers); + return new InspectPagePluginsContent(serverInfo.getServerUUID(), nav, tab); + } + + private static String createTab(Map containers) { StringBuilder tab = new StringBuilder(); tab.append("
    "); @@ -63,8 +68,7 @@ public class InspectPagePluginsContent extends PageResponse { } tab.append("
    "); - - return new InspectPagePluginsContent(ServerInfo.getServerUUID(), nav, tab.toString()); + return tab.toString(); } public void addTab(UUID serverUUID, String nav, String html) { diff --git a/Plan/src/main/java/com/djrapitops/plan/utilities/FormatUtils.java b/Plan/src/main/java/com/djrapitops/plan/utilities/FormatUtils.java deleted file mode 100644 index 6fe7088c6..000000000 --- a/Plan/src/main/java/com/djrapitops/plan/utilities/FormatUtils.java +++ /dev/null @@ -1,176 +0,0 @@ -package com.djrapitops.plan.utilities; - -import com.djrapitops.plan.system.settings.Settings; -import com.djrapitops.plugin.api.TimeAmount; - -import java.net.Inet6Address; -import java.net.InetAddress; -import java.text.DecimalFormat; -import java.text.SimpleDateFormat; -import java.util.ArrayList; -import java.util.List; -import java.util.Locale; -import java.util.TimeZone; - -/** - * @author Rsl1122 - */ -public class FormatUtils { - - /** - * Constructor used to hide the public constructor - */ - private FormatUtils() { - throw new IllegalStateException("Utility class"); - } - - public static String formatTimeStampISO8601NoClock(long epochMs) { - String format = "yyyy-MM-dd"; - - return format(epochMs, format); - } - - public static String formatTimeStampDay(long epochMs) { - String format = "MMMMM d"; - - if (Settings.FORMAT_DATE_RECENT_DAYS.isTrue()) { - format = replaceRecentDays(epochMs, format, "MMMMM"); - } - - return format(epochMs, format); - } - - public static String formatTimeStampClock(long epochMs) { - String format = Settings.FORMAT_DATE_CLOCK.toString(); - - return format(epochMs, format); - } - - private static String format(long epochMs, String format) { - boolean useServerTime = Settings.USE_SERVER_TIME.isTrue(); - String locale = Settings.LOCALE.toString(); - Locale usedLocale = locale.equalsIgnoreCase("default") ? Locale.ENGLISH : Locale.forLanguageTag(locale); - SimpleDateFormat dateFormat = new SimpleDateFormat(format, usedLocale); - TimeZone timeZone = useServerTime ? TimeZone.getDefault() : TimeZone.getTimeZone("GMT"); - dateFormat.setTimeZone(timeZone); - return dateFormat.format(epochMs); - } - - public static String formatTimeStampSecond(long epochMs) { - String format = Settings.FORMAT_DATE_FULL.toString(); - - if (Settings.FORMAT_DATE_RECENT_DAYS.isTrue()) { - format = replaceRecentDays(epochMs, format); - } - - return format(epochMs, format); - } - - private static String replaceRecentDays(long epochMs, String format) { - return replaceRecentDays(epochMs, format, Settings.FORMAT_DATE_RECENT_DAYS_PATTERN.toString()); - } - - private static String replaceRecentDays(long epochMs, String format, String pattern) { - long now = System.currentTimeMillis(); - - long fromStartOfDay = now % TimeAmount.DAY.ms(); - if (epochMs > now - fromStartOfDay) { - format = format.replace(pattern, "'Today'"); - } else if (epochMs > now - TimeAmount.DAY.ms() - fromStartOfDay) { - format = format.replace(pattern, "'Yesterday'"); - } else if (epochMs > now - TimeAmount.DAY.ms() * 5L) { - format = format.replace(pattern, "EEEE"); - } - return format; - } - - public static String formatTimeStampYear(long epochMs) { - String format = Settings.FORMAT_DATE_NO_SECONDS.toString(); - - if (Settings.FORMAT_DATE_RECENT_DAYS.isTrue()) { - format = replaceRecentDays(epochMs, format); - } - return format(epochMs, format); - } - - /** - * Merges multiple arrays into one. - * - * @param arrays String arrays that need to be combined - * @return One array with contents of the multiple - */ - public static String[] mergeArrays(String[]... arrays) { - return com.djrapitops.plugin.utilities.FormatUtils.mergeArrays(arrays); - } - - /** - * Remove extra decimals from the end of the double. - * - * @param d Double. - * @return String format of the double. - */ - public static String cutDecimals(double d) { - return new DecimalFormat(Settings.FORMAT_DECIMALS.toString()).format(d); - } - - public static String formatIP(InetAddress address) { - String ip = address.getHostAddress(); - if ("localhost".equals(ip)) { - return ip; - } - if (address instanceof Inet6Address) { - StringBuilder b = new StringBuilder(); - int i = 0; - for (String part : ip.split(":")) { - if (i >= 3) { - break; - } - - b.append(part).append(':'); - - i++; - } - - return b.append("xx..").toString(); - } else { - StringBuilder b = new StringBuilder(); - int i = 0; - for (String part : ip.split("\\.")) { - if (i >= 2) { - break; - } - - b.append(part).append('.'); - - i++; - } - - return b.append("xx.xx").toString(); - } - } - - /** - * Gets lines for stack trace recursively. - * - * @param throwable Throwable element - * @return lines of stack trace. - */ - public static List getStackTrace(Throwable throwable) { - List stackTrace = new ArrayList<>(); - stackTrace.add(throwable.toString()); - for (StackTraceElement element : throwable.getStackTrace()) { - stackTrace.add(" " + element.toString()); - } - - Throwable cause = throwable.getCause(); - if (cause != null) { - List causeTrace = getStackTrace(cause); - if (!causeTrace.isEmpty()) { - causeTrace.set(0, "Caused by: " + causeTrace.get(0)); - stackTrace.addAll(causeTrace); - } - } - - return stackTrace; - } -} diff --git a/Plan/src/main/java/com/djrapitops/plan/utilities/MiscUtils.java b/Plan/src/main/java/com/djrapitops/plan/utilities/MiscUtils.java index c16c7a46a..ddfd81998 100644 --- a/Plan/src/main/java/com/djrapitops/plan/utilities/MiscUtils.java +++ b/Plan/src/main/java/com/djrapitops/plan/utilities/MiscUtils.java @@ -1,19 +1,11 @@ package com.djrapitops.plan.utilities; -import com.djrapitops.plan.PlanPlugin; -import com.djrapitops.plan.system.database.databases.Database; import com.djrapitops.plan.system.settings.Permissions; -import com.djrapitops.plan.system.settings.Settings; -import com.djrapitops.plugin.api.TimeAmount; -import com.djrapitops.plugin.api.utility.log.Log; import com.djrapitops.plugin.command.CommandUtils; -import com.djrapitops.plugin.command.ISender; +import com.djrapitops.plugin.command.Sender; import java.io.Closeable; import java.io.IOException; -import java.util.Collections; -import java.util.List; -import java.util.TimeZone; /** * Utility method class containing various static methods. @@ -30,13 +22,6 @@ public class MiscUtils { throw new IllegalStateException("Utility class"); } - public static int getTimeZoneOffsetHours() { - if (Settings.USE_SERVER_TIME.isTrue()) { - return -TimeZone.getDefault().getOffset(System.currentTimeMillis()) / (int) TimeAmount.HOUR.ms(); - } - return 0; - } - /** * Get a players name that matches the given arguments or name of the sender. * @@ -44,7 +29,7 @@ public class MiscUtils { * @param sender Sender of command * @return Player name. */ - public static String getPlayerName(String[] args, ISender sender) { + public static String getPlayerName(String[] args, Sender sender) { return getPlayerName(args, sender, Permissions.INSPECT_OTHER); } @@ -56,7 +41,7 @@ public class MiscUtils { * @param perm Permission to use when checking. * @return The name of the player (first argument or sender) or null if sender has no permission. */ - public static String getPlayerName(String[] args, ISender sender, Permissions perm) { + public static String getPlayerName(String[] args, Sender sender, Permissions perm) { String playerName; boolean isConsole = !CommandUtils.isPlayer(sender); if (isConsole) { @@ -75,29 +60,13 @@ public class MiscUtils { return playerName; } - /** - * Get matching player names from the offline players. - * - * @param search Part of a name to search for. - * @return Alphabetically sorted list of matching player names. - */ - public static List getMatchingPlayerNames(String search) { - Database db = Database.getActive(); - List matches = db.search().matchingPlayers(search); - Collections.sort(matches); - return matches; - } - public static void close(Closeable... close) { for (Closeable c : close) { if (c != null) { try { c.close(); - } catch (IOException e) { - if (Settings.DEV_MODE.isTrue()) { - Log.warn("THIS ERROR IS ONLY LOGGED IN DEV MODE:"); - Log.toLog(MiscUtils.class, e); - } + } catch (IOException ignored) { + // Closing exceptions are ignored. } } } @@ -108,17 +77,10 @@ public class MiscUtils { if (c != null) { try { c.close(); - } catch (Exception e) { - if (Settings.DEV_MODE.isTrue()) { - Log.warn("THIS ERROR IS ONLY LOGGED IN DEV MODE:"); - Log.toLog(MiscUtils.class, e); - } + } catch (Exception ignore) { + // Closing exceptions are ignored. } } } } - - public static String getPlanVersion() { - return PlanPlugin.getInstance().getVersion(); - } } diff --git a/Plan/src/main/java/com/djrapitops/plan/utilities/analysis/ServerBanDataReader.java b/Plan/src/main/java/com/djrapitops/plan/utilities/analysis/ServerBanDataReader.java deleted file mode 100644 index 6d37dc5f4..000000000 --- a/Plan/src/main/java/com/djrapitops/plan/utilities/analysis/ServerBanDataReader.java +++ /dev/null @@ -1,36 +0,0 @@ -package com.djrapitops.plan.utilities.analysis; - -import com.djrapitops.plan.data.plugin.BanData; -import com.djrapitops.plan.data.plugin.HookHandler; -import com.djrapitops.plan.data.store.containers.DataContainer; -import com.djrapitops.plan.data.store.keys.AnalysisKeys; -import com.djrapitops.plan.data.store.mutators.PlayersMutator; -import com.djrapitops.plugin.api.utility.log.Log; - -import java.util.*; - -public class ServerBanDataReader { - - public Set readBanDataForContainer(DataContainer container) { - return readBanData( - container.getValue(AnalysisKeys.PLAYERS_MUTATOR) - .map(PlayersMutator::uuids) - .orElse(new ArrayList<>()) - ); - } - - public Set readBanData(Collection uuids) { - List banPlugins = HookHandler.getInstance().getBanDataSources(); - - Set banned = new HashSet<>(); - for (BanData banPlugin : banPlugins) { - try { - banned.addAll(banPlugin.filterBanned(uuids)); - } catch (Exception | NoSuchMethodError | NoClassDefFoundError | NoSuchFieldError e) { - Log.toLog("PluginData caused exception: " + banPlugin.getClass().getName(), e); - } - } - return banned; - } - -} diff --git a/Plan/src/main/java/com/djrapitops/plan/utilities/comparators/MapComparator.java b/Plan/src/main/java/com/djrapitops/plan/utilities/comparators/MapComparator.java deleted file mode 100644 index b537e44ce..000000000 --- a/Plan/src/main/java/com/djrapitops/plan/utilities/comparators/MapComparator.java +++ /dev/null @@ -1,34 +0,0 @@ -package com.djrapitops.plan.utilities.comparators; - -import java.util.ArrayList; -import java.util.Comparator; -import java.util.List; -import java.util.Map; - -/** - * @author Rsl1122 - */ -public class MapComparator { - - /** - * Constructor used to hide the public constructor - */ - private MapComparator() { - throw new IllegalStateException("Utility class"); - } - - /** - * Sorts a Map of String, Integer by the Values of the Map. - * - * @param map Map to sort - * @return List with String Array, where first value is the value and second - * is the key. - */ - public static List sortByValue(Map map) { - List sortedList = new ArrayList<>(); - map.keySet().forEach(key -> sortedList.add(new String[]{String.valueOf(map.get(key)), key})); - sortedList.sort(Comparator.comparingInt(strings -> Integer.parseInt(strings[0]))); - return sortedList; - } - -} diff --git a/Plan/src/main/java/com/djrapitops/plan/utilities/file/FileUtil.java b/Plan/src/main/java/com/djrapitops/plan/utilities/file/FileUtil.java index dfb176f5c..e50f5c684 100644 --- a/Plan/src/main/java/com/djrapitops/plan/utilities/file/FileUtil.java +++ b/Plan/src/main/java/com/djrapitops/plan/utilities/file/FileUtil.java @@ -2,13 +2,9 @@ package com.djrapitops.plan.utilities.file; import com.djrapitops.plan.PlanPlugin; import com.djrapitops.plan.utilities.MiscUtils; -import com.djrapitops.plugin.api.utility.log.Log; -import com.djrapitops.plugin.utilities.Verify; +import com.djrapitops.plugin.logging.L; -import java.io.File; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.io.InputStream; +import java.io.*; import java.nio.charset.Charset; import java.nio.charset.StandardCharsets; import java.nio.file.Files; @@ -22,15 +18,6 @@ public class FileUtil { throw new IllegalStateException("Utility class"); } - public static String getStringFromResource(String fileName) throws IOException { - StringBuilder html = new StringBuilder(); - PlanPlugin plugin = PlanPlugin.getInstance(); - - lines(PlanPlugin.getInstance(), new File(plugin.getDataFolder(), fileName.replace("/", File.separator)), fileName) - .forEach(line -> html.append(line).append("\r\n")); - return html.toString(); - } - public static List lines(PlanPlugin plugin, File savedFile, String defaults) throws IOException { if (savedFile.exists()) { return lines(savedFile); @@ -44,6 +31,31 @@ public class FileUtil { return lines(plugin, defaults); } + public static InputStream stream(PlanPlugin plugin, File savedFile, String defaults) { + try { + if (savedFile.exists()) { + return stream(savedFile); + } else { + String fileName = savedFile.getName(); + File found = attemptToFind(fileName, new File(plugin.getDataFolder(), "web")); + if (found != null) { + return stream(found); + } + } + } catch (FileNotFoundException ignore) { + // File was not found, use jar version + } + return stream(plugin, defaults); + } + + private static InputStream stream(PlanPlugin plugin, String resource) { + return plugin.getResource(resource); + } + + private static InputStream stream(File savedFile) throws FileNotFoundException { + return new FileInputStream(savedFile); + } + /** * Breadth-First search through the file tree to find the file. * @@ -81,7 +93,7 @@ public class FileUtil { lines.add(scanner.nextLine()); } } catch (NullPointerException e) { - Log.infoColor("§ea Resource was not found inside the jar (" + resource + "), Plan does not support /reload or updates using " + + plugin.getPluginLogger().log(L.INFO_COLOR, "§ea Resource was not found inside the jar (" + resource + "), Plan does not support /reload or updates using " + "Plugin Managers, restart the server and see if the error persists."); throw new FileNotFoundException("File not found inside jar: " + resource); } finally { @@ -96,7 +108,7 @@ public class FileUtil { public static List lines(File file, Charset charset) throws IOException { List lines = new ArrayList<>(); - if (Verify.exists(file)) { + if (file != null && file.exists()) { try (Stream linesStream = Files.lines(file.toPath(), charset)) { lines = linesStream.collect(Collectors.toList()); } diff --git a/Plan/src/main/java/com/djrapitops/plan/utilities/file/export/AnalysisExport.java b/Plan/src/main/java/com/djrapitops/plan/utilities/file/export/AnalysisExport.java deleted file mode 100644 index 16628370d..000000000 --- a/Plan/src/main/java/com/djrapitops/plan/utilities/file/export/AnalysisExport.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * License is provided in the jar as LICENSE also here: - * https://github.com/Rsl1122/Plan-PlayerAnalytics/blob/master/Plan/src/main/resources/LICENSE - */ -package com.djrapitops.plan.utilities.file.export; - -import com.djrapitops.plan.system.info.connection.ConnectionSystem; -import com.djrapitops.plugin.api.Check; -import com.djrapitops.plugin.api.utility.log.Log; - -import java.io.IOException; -import java.util.ConcurrentModificationException; -import java.util.UUID; - -/** - * Task that exports a single Analysis page if it is in ResponseCache. - * - * @author Rsl1122 - */ -public class AnalysisExport extends SpecificExport { - - private final UUID serverUUID; - private final String serverName; - - public AnalysisExport(UUID serverUUID, String serverName) { - super("ServerPageExport:" + serverName); - this.serverUUID = serverUUID; - this.serverName = serverName; - } - - @Override - public void run() { - try { - if (Check.isBukkitAvailable() && ConnectionSystem.getInstance().isServerAvailable()) { - return; - } - - exportAvailableServerPage(serverUUID, serverName); - } catch (IOException e) { - Log.toLog(this.getClass(), e); - } finally { - try { - this.cancel(); - } catch (ConcurrentModificationException | IllegalArgumentException ignore) { - } - } - } -} diff --git a/Plan/src/main/java/com/djrapitops/plan/utilities/file/export/Hastebin.java b/Plan/src/main/java/com/djrapitops/plan/utilities/file/export/Hastebin.java index ea18d957c..189b7257f 100644 --- a/Plan/src/main/java/com/djrapitops/plan/utilities/file/export/Hastebin.java +++ b/Plan/src/main/java/com/djrapitops/plan/utilities/file/export/Hastebin.java @@ -1,6 +1,5 @@ package com.djrapitops.plan.utilities.file.export; -import com.djrapitops.plugin.api.utility.log.Log; import com.google.common.base.Splitter; import com.google.common.collect.ImmutableList; import org.json.simple.JSONObject; @@ -36,7 +35,7 @@ public class Hastebin { * @return The link to the Dump Log * @see #split(String) */ - public static String safeUpload(String content) { + public static String safeUpload(String content) throws ParseException, IOException { List parts = ImmutableList.copyOf(split(content)).reverse(); String lastLink = null; @@ -52,10 +51,7 @@ public class Hastebin { if (e.getMessage().contains("503")) { return "Hastebin unavailable"; } - - Log.toLog("DumpLog.upload", e); - } catch (ParseException e) { - Log.toLog("DumpLog.upload", e); + throw e; } return lastLink; diff --git a/Plan/src/main/java/com/djrapitops/plan/utilities/file/export/HtmlExport.java b/Plan/src/main/java/com/djrapitops/plan/utilities/file/export/HtmlExport.java index 342a9c034..5706e7bf1 100644 --- a/Plan/src/main/java/com/djrapitops/plan/utilities/file/export/HtmlExport.java +++ b/Plan/src/main/java/com/djrapitops/plan/utilities/file/export/HtmlExport.java @@ -5,19 +5,26 @@ package com.djrapitops.plan.utilities.file.export; import com.djrapitops.plan.PlanPlugin; +import com.djrapitops.plan.api.exceptions.ParseException; import com.djrapitops.plan.api.exceptions.database.DBOpException; import com.djrapitops.plan.data.container.UserInfo; -import com.djrapitops.plan.system.database.databases.Database; +import com.djrapitops.plan.system.database.DBSystem; +import com.djrapitops.plan.system.file.PlanFiles; import com.djrapitops.plan.system.info.connection.ConnectionSystem; +import com.djrapitops.plan.system.info.server.ServerInfo; +import com.djrapitops.plan.system.processing.Processing; +import com.djrapitops.plan.system.settings.config.PlanConfig; import com.djrapitops.plan.system.settings.theme.Theme; import com.djrapitops.plan.system.settings.theme.ThemeVal; -import com.djrapitops.plan.system.webserver.response.pages.PlayersPageResponse; import com.djrapitops.plan.utilities.file.FileUtil; +import com.djrapitops.plan.utilities.html.pages.PageFactory; import com.djrapitops.plugin.api.Check; -import com.djrapitops.plugin.api.utility.log.Log; -import com.djrapitops.plugin.task.RunnableFactory; +import com.djrapitops.plugin.logging.L; +import com.djrapitops.plugin.logging.error.ErrorHandler; import com.djrapitops.plugin.utilities.Verify; +import javax.inject.Inject; +import javax.inject.Singleton; import java.io.File; import java.io.FileNotFoundException; import java.io.IOException; @@ -29,31 +36,76 @@ import java.util.*; * * @author Rsl1122 */ +@Singleton public class HtmlExport extends SpecificExport { private final PlanPlugin plugin; + private final Theme theme; + private final Processing processing; + private final PlanFiles files; + private final DBSystem dbSystem; + private final PageFactory pageFactory; + private final ConnectionSystem connectionSystem; + private final ErrorHandler errorHandler; - public HtmlExport(PlanPlugin plugin) { - super("HtmlExportTask"); + @Inject + public HtmlExport( + PlanPlugin plugin, + PlanFiles files, + PlanConfig config, + Theme theme, + Processing processing, + DBSystem dbSystem, + PageFactory pageFactory, + ServerInfo serverInfo, + ConnectionSystem connectionSystem, + ErrorHandler errorHandler + ) { + super(files, config, serverInfo); this.plugin = plugin; + this.theme = theme; + this.processing = processing; + this.files = files; + this.dbSystem = dbSystem; + this.pageFactory = pageFactory; + this.connectionSystem = connectionSystem; + this.errorHandler = errorHandler; } - public static void exportServer(UUID serverUUID) { - Optional serverName = Database.getActive().fetch().getServerName(serverUUID); - serverName.ifPresent(s -> RunnableFactory.createNew(new AnalysisExport(serverUUID, s)).runTaskAsynchronously()); + public void exportServer(UUID serverUUID) { + if (Check.isBukkitAvailable() && connectionSystem.isServerAvailable()) { + return; + } + Optional serverName = dbSystem.getDatabase().fetch().getServerName(serverUUID); + serverName.ifPresent(name -> processing.submitNonCritical(() -> { + try { + exportAvailableServerPage(serverUUID, name); + } catch (IOException e) { + errorHandler.log(L.WARN, this.getClass(), e); + } + })); } - public static void exportPlayer(UUID playerUUID) { - String playerName = Database.getActive().fetch().getPlayerName(playerUUID); + public void exportPlayer(UUID uuid) { + if (Check.isBukkitAvailable() && connectionSystem.isServerAvailable()) { + return; + } + String playerName = dbSystem.getDatabase().fetch().getPlayerName(uuid); if (playerName != null) { - RunnableFactory.createNew(new PlayerExport(playerUUID, playerName)).runTaskAsynchronously(); + processing.submitNonCritical(() -> { + try { + exportAvailablePlayerPage(uuid, playerName); + } catch (IOException e) { + errorHandler.log(L.WARN, this.getClass(), e); + } + }); } } @Override public void run() { try { - if (Check.isBukkitAvailable() && ConnectionSystem.getInstance().isServerAvailable()) { + if (Check.isBukkitAvailable() && connectionSystem.isServerAvailable()) { return; } @@ -64,20 +116,13 @@ public class HtmlExport extends SpecificExport { exportAvailableServerPages(); exportAvailablePlayers(); exportPlayersPage(); - } catch (IOException | DBOpException e) { - Log.toLog(this.getClass(), e); - } finally { - try { - this.cancel(); - } catch (ConcurrentModificationException | IllegalArgumentException ignore) { - } + } catch (IOException | DBOpException | ParseException e) { + errorHandler.log(L.WARN, this.getClass(), e); } } - private void exportPlayersPage() throws IOException { - PlayersPageResponse playersPageResponse = new PlayersPageResponse(); - - String html = playersPageResponse.getContent() + private void exportPlayersPage() throws IOException, ParseException { + String html = pageFactory.playersPage().toHtml() .replace("href=\"plugins/", "href=\"../plugins/") .replace("href=\"css/", "href=\"../css/") .replace("src=\"plugins/", "src=\"../plugins/") @@ -92,13 +137,13 @@ public class HtmlExport extends SpecificExport { } private void exportAvailablePlayers() throws IOException { - for (Map.Entry entry : Database.getActive().fetch().getUsers().entrySet()) { + for (Map.Entry entry : dbSystem.getDatabase().fetch().getUsers().entrySet()) { exportAvailablePlayerPage(entry.getKey(), entry.getValue().getName()); } } private void exportAvailableServerPages() throws IOException { - Map serverNames = Database.getActive().fetch().getServerNames(); + Map serverNames = dbSystem.getDatabase().fetch().getServerNames(); for (Map.Entry entry : serverNames.entrySet()) { exportAvailableServerPage(entry.getKey(), entry.getValue()); @@ -128,6 +173,7 @@ public class HtmlExport extends SpecificExport { "web/js/charts/playerGraph.js", "web/js/charts/playerGraphNoNav.js", "web/js/charts/resourceGraph.js", + "web/js/charts/diskGraph.js", "web/js/charts/tpsGraph.js", "web/js/charts/worldGraph.js", "web/js/charts/worldMap.js", @@ -141,15 +187,15 @@ public class HtmlExport extends SpecificExport { copyFromJar(resources); try { - String demo = FileUtil.getStringFromResource("web/js/demo.js") - .replace("${defaultTheme}", Theme.getValue(ThemeVal.THEME_DEFAULT)); + String demo = files.readFromResourceFlat("web/js/demo.js") + .replace("${defaultTheme}", theme.getValue(ThemeVal.THEME_DEFAULT)); List lines = Arrays.asList(demo.split("\n")); File outputFolder = new File(this.outputFolder, "js"); Verify.isTrue(outputFolder.exists() && outputFolder.isDirectory() || outputFolder.mkdirs(), () -> new FileNotFoundException("Output folder could not be created at" + outputFolder.getAbsolutePath())); export(new File(outputFolder, "demo.js"), lines); } catch (IOException e) { - Log.toLog(this.getClass(), e); + errorHandler.log(L.WARN, this.getClass(), e); } } @@ -176,7 +222,7 @@ public class HtmlExport extends SpecificExport { try { copyFromJar(resource); } catch (IOException e) { - Log.toLog(this.getClass(), e); + errorHandler.log(L.WARN, this.getClass(), e); } } } diff --git a/Plan/src/main/java/com/djrapitops/plan/utilities/file/export/PlayerExport.java b/Plan/src/main/java/com/djrapitops/plan/utilities/file/export/PlayerExport.java deleted file mode 100644 index 804a48a95..000000000 --- a/Plan/src/main/java/com/djrapitops/plan/utilities/file/export/PlayerExport.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * License is provided in the jar as LICENSE also here: - * https://github.com/Rsl1122/Plan-PlayerAnalytics/blob/master/Plan/src/main/resources/LICENSE - */ -package com.djrapitops.plan.utilities.file.export; - -import com.djrapitops.plan.system.info.connection.ConnectionSystem; -import com.djrapitops.plugin.api.Check; -import com.djrapitops.plugin.api.utility.log.Log; - -import java.io.IOException; -import java.util.ConcurrentModificationException; -import java.util.UUID; - -/** - * Task for exporting a single player page. - * - * @author Rsl1122 - */ -public class PlayerExport extends SpecificExport { - - private final UUID uuid; - private final String name; - - public PlayerExport(UUID uuid, String name) { - super("PlayerPageExport:" + name); - this.uuid = uuid; - this.name = name; - } - - @Override - public void run() { - try { - if (Check.isBukkitAvailable() && ConnectionSystem.getInstance().isServerAvailable()) { - return; - } - - exportAvailablePlayerPage(uuid, name); - } catch (IOException e) { - Log.toLog(this.getClass(), e); - } finally { - try { - this.cancel(); - } catch (ConcurrentModificationException | IllegalArgumentException ignore) { - } - } - } -} diff --git a/Plan/src/main/java/com/djrapitops/plan/utilities/file/export/SpecificExport.java b/Plan/src/main/java/com/djrapitops/plan/utilities/file/export/SpecificExport.java index 12ca623a6..32f3b8a58 100644 --- a/Plan/src/main/java/com/djrapitops/plan/utilities/file/export/SpecificExport.java +++ b/Plan/src/main/java/com/djrapitops/plan/utilities/file/export/SpecificExport.java @@ -4,15 +4,14 @@ */ package com.djrapitops.plan.utilities.file.export; -import com.djrapitops.plan.PlanPlugin; +import com.djrapitops.plan.system.file.PlanFiles; import com.djrapitops.plan.system.info.server.ServerInfo; import com.djrapitops.plan.system.settings.Settings; +import com.djrapitops.plan.system.settings.config.PlanConfig; import com.djrapitops.plan.system.webserver.cache.PageId; import com.djrapitops.plan.system.webserver.cache.ResponseCache; import com.djrapitops.plan.system.webserver.response.Response; import com.djrapitops.plugin.api.Check; -import com.djrapitops.plugin.api.utility.log.Log; -import com.djrapitops.plugin.task.AbsRunnable; import java.io.File; import java.io.IOException; @@ -28,33 +27,42 @@ import java.util.UUID; * * @author Rsl1122 */ -public abstract class SpecificExport extends AbsRunnable { +public abstract class SpecificExport implements Runnable { + + private final PlanFiles files; + private final PlanConfig config; + private final ServerInfo serverInfo; protected final File outputFolder; - protected final boolean usingBungee; + private final boolean usingProxy; - protected SpecificExport(String taskName) { - super(taskName); + protected SpecificExport( + PlanFiles files, + PlanConfig config, + ServerInfo serverInfo + ) { + this.files = files; + this.config = config; + this.serverInfo = serverInfo; outputFolder = getFolder(); - usingBungee = Check.isBungeeAvailable(); + usingProxy = Check.isBungeeAvailable() || Check.isVelocityAvailable(); } protected File getFolder() { - String path = Settings.ANALYSIS_EXPORT_PATH.toString(); + File folder; - Log.logDebug("Export", "Path: " + path); + String path = config.getString(Settings.ANALYSIS_EXPORT_PATH); boolean isAbsolute = Paths.get(path).isAbsolute(); - Log.logDebug("Export", "Absolute: " + (isAbsolute ? "Yes" : "No")); if (isAbsolute) { - File folder = new File(path); - if (!folder.exists() || !folder.isDirectory()) { - folder.mkdirs(); - } - return folder; + folder = new File(path); + } else { + File dataFolder = files.getDataFolder(); + folder = new File(dataFolder, path); + } + + if (!folder.exists() || !folder.isDirectory()) { + folder.mkdirs(); } - File dataFolder = PlanPlugin.getInstance().getDataFolder(); - File folder = new File(dataFolder, path); - folder.mkdirs(); return folder; } @@ -104,8 +112,8 @@ public abstract class SpecificExport extends AbsRunnable { .replace("src=\"js/", "src=\"../js/"); File htmlLocation; - if (usingBungee) { - if (serverUUID.equals(ServerInfo.getServerUUID())) { + if (usingProxy) { + if (serverUUID.equals(serverInfo.getServerUUID())) { htmlLocation = new File(outputFolder, "network"); } else { htmlLocation = new File(getServerFolder(), serverName.replace(" ", "%20").replace(".", "%2E")); diff --git a/Plan/src/main/java/com/djrapitops/plan/utilities/formatting/DecimalFormatter.java b/Plan/src/main/java/com/djrapitops/plan/utilities/formatting/DecimalFormatter.java new file mode 100644 index 000000000..f5d7e8286 --- /dev/null +++ b/Plan/src/main/java/com/djrapitops/plan/utilities/formatting/DecimalFormatter.java @@ -0,0 +1,25 @@ +package com.djrapitops.plan.utilities.formatting; + +import com.djrapitops.plan.system.settings.Settings; +import com.djrapitops.plan.system.settings.config.PlanConfig; + +import java.text.DecimalFormat; + +/** + * Formatter for decimal points that depends on settings. + * + * @author Rsl1122 + */ +public class DecimalFormatter implements Formatter { + + private final PlanConfig config; + + public DecimalFormatter(PlanConfig config) { + this.config = config; + } + + @Override + public String apply(Double value) { + return new DecimalFormat(config.getString(Settings.FORMAT_DECIMALS)).format(value); + } +} \ No newline at end of file diff --git a/Plan/src/main/java/com/djrapitops/plan/utilities/formatting/EntityNameFormatter.java b/Plan/src/main/java/com/djrapitops/plan/utilities/formatting/EntityNameFormatter.java new file mode 100644 index 000000000..20ea5daa1 --- /dev/null +++ b/Plan/src/main/java/com/djrapitops/plan/utilities/formatting/EntityNameFormatter.java @@ -0,0 +1,16 @@ +package com.djrapitops.plan.utilities.formatting; + +import com.djrapitops.plugin.utilities.Format; + +/** + * Formatter for entity names, that capitalizes the first word and removes symbols and numbers. + * + * @author Rsl1122 + */ +public class EntityNameFormatter implements Formatter { + + @Override + public String apply(String name) { + return new Format(name).removeNumbers().removeSymbols().capitalize().toString(); + } +} \ No newline at end of file diff --git a/Plan/src/main/java/com/djrapitops/plan/data/store/mutators/formatting/Formatter.java b/Plan/src/main/java/com/djrapitops/plan/utilities/formatting/Formatter.java similarity index 75% rename from Plan/src/main/java/com/djrapitops/plan/data/store/mutators/formatting/Formatter.java rename to Plan/src/main/java/com/djrapitops/plan/utilities/formatting/Formatter.java index 5255d287e..d237a65d5 100644 --- a/Plan/src/main/java/com/djrapitops/plan/data/store/mutators/formatting/Formatter.java +++ b/Plan/src/main/java/com/djrapitops/plan/utilities/formatting/Formatter.java @@ -1,4 +1,4 @@ -package com.djrapitops.plan.data.store.mutators.formatting; +package com.djrapitops.plan.utilities.formatting; import java.util.function.Function; diff --git a/Plan/src/main/java/com/djrapitops/plan/utilities/formatting/Formatters.java b/Plan/src/main/java/com/djrapitops/plan/utilities/formatting/Formatters.java new file mode 100644 index 000000000..787782f15 --- /dev/null +++ b/Plan/src/main/java/com/djrapitops/plan/utilities/formatting/Formatters.java @@ -0,0 +1,108 @@ +package com.djrapitops.plan.utilities.formatting; + +import com.djrapitops.plan.data.store.objects.DateHolder; +import com.djrapitops.plan.system.locale.Locale; +import com.djrapitops.plan.system.settings.config.PlanConfig; +import com.djrapitops.plan.utilities.formatting.time.*; + +import javax.inject.Inject; +import javax.inject.Singleton; + +/** + * Factory for new instances of different {@link Formatter}s. + * + * @author Rsl1122 + */ +@Singleton +public class Formatters { + + private final DateHolderFormatter yearFormatter; + private final DateHolderFormatter dayFormatter; + private final DateHolderFormatter secondFormatter; + private final DateHolderFormatter clockFormatter; + private final DateHolderFormatter iso8601NoClockFormatter; + + private final YearFormatter yearLongFormatter; + private final DayFormatter dayLongFormatter; + private final SecondFormatter secondLongFormatter; + private final ClockFormatter clockLongFormatter; + private final ISO8601NoClockFormatter iso8601NoClockLongFormatter; + + private final TimeAmountFormatter timeAmountFormatter; + + private final DecimalFormatter decimalFormatter; + private final PercentageFormatter percentageFormatter; + + @Inject + public Formatters(PlanConfig config, Locale locale) { + yearLongFormatter = new YearFormatter(config, locale); + dayLongFormatter = new DayFormatter(config, locale); + clockLongFormatter = new ClockFormatter(config, locale); + secondLongFormatter = new SecondFormatter(config, locale); + iso8601NoClockLongFormatter = new ISO8601NoClockFormatter(config, locale); + + yearFormatter = new DateHolderFormatter(yearLongFormatter); + dayFormatter = new DateHolderFormatter(dayLongFormatter); + secondFormatter = new DateHolderFormatter(secondLongFormatter); + clockFormatter = new DateHolderFormatter(clockLongFormatter); + iso8601NoClockFormatter = new DateHolderFormatter(iso8601NoClockLongFormatter); + + timeAmountFormatter = new TimeAmountFormatter(config); + + decimalFormatter = new DecimalFormatter(config); + percentageFormatter = new PercentageFormatter(decimalFormatter); + + } + + public Formatter year() { + return this.yearFormatter; + } + + public Formatter yearLong() { + return yearLongFormatter; + } + + public Formatter day() { + return dayFormatter; + } + + public Formatter dayLong() { + return dayLongFormatter; + } + + public Formatter second() { + return secondFormatter; + } + + public Formatter secondLong() { + return secondLongFormatter; + } + + public Formatter clock() { + return clockFormatter; + } + + public Formatter clockLong() { + return clockLongFormatter; + } + + public Formatter iso8601NoClock() { + return iso8601NoClockFormatter; + } + + public Formatter iso8601NoClockLong() { + return iso8601NoClockLongFormatter; + } + + public Formatter timeAmount() { + return timeAmountFormatter; + } + + public Formatter percentage() { + return percentageFormatter; + } + + public Formatter decimals() { + return decimalFormatter; + } +} \ No newline at end of file diff --git a/Plan/src/main/java/com/djrapitops/plan/utilities/formatting/ItemNameFormatter.java b/Plan/src/main/java/com/djrapitops/plan/utilities/formatting/ItemNameFormatter.java new file mode 100644 index 000000000..4d39be4b7 --- /dev/null +++ b/Plan/src/main/java/com/djrapitops/plan/utilities/formatting/ItemNameFormatter.java @@ -0,0 +1,22 @@ +package com.djrapitops.plan.utilities.formatting; + +import com.djrapitops.plugin.utilities.Format; +import org.apache.commons.text.TextStringBuilder; + +import java.util.Arrays; + +/** + * Formatter for Item names, that capitalizes each part and separates them with spaces instead of underscores. + * + * @author Rsl1122 + */ +public class ItemNameFormatter implements Formatter { + + @Override + public String apply(String name) { + String[] parts = name.split("_"); + TextStringBuilder builder = new TextStringBuilder(); + builder.appendWithSeparators(Arrays.stream(parts).map(part -> new Format(part).capitalize()).iterator(), " "); + return builder.toString(); + } +} \ No newline at end of file diff --git a/Plan/src/main/java/com/djrapitops/plan/utilities/formatting/PercentageFormatter.java b/Plan/src/main/java/com/djrapitops/plan/utilities/formatting/PercentageFormatter.java new file mode 100644 index 000000000..cf68ea88a --- /dev/null +++ b/Plan/src/main/java/com/djrapitops/plan/utilities/formatting/PercentageFormatter.java @@ -0,0 +1,20 @@ +package com.djrapitops.plan.utilities.formatting; + +/** + * Formatter for percentages. + * + * @author Rsl1122 + */ +public class PercentageFormatter implements Formatter { + + private final Formatter formatter; + + public PercentageFormatter(Formatter formatter) { + this.formatter = formatter; + } + + @Override + public String apply(Double value) { + return value >= 0 ? formatter.apply(value * 100.0) + "%" : "-"; + } +} \ No newline at end of file diff --git a/Plan/src/main/java/com/djrapitops/plan/data/store/mutators/formatting/PlaceholderReplacer.java b/Plan/src/main/java/com/djrapitops/plan/utilities/formatting/PlaceholderReplacer.java similarity index 96% rename from Plan/src/main/java/com/djrapitops/plan/data/store/mutators/formatting/PlaceholderReplacer.java rename to Plan/src/main/java/com/djrapitops/plan/utilities/formatting/PlaceholderReplacer.java index 487dc4304..301199af0 100644 --- a/Plan/src/main/java/com/djrapitops/plan/data/store/mutators/formatting/PlaceholderReplacer.java +++ b/Plan/src/main/java/com/djrapitops/plan/utilities/formatting/PlaceholderReplacer.java @@ -1,4 +1,4 @@ -package com.djrapitops.plan.data.store.mutators.formatting; +package com.djrapitops.plan.utilities.formatting; import com.djrapitops.plan.data.store.PlaceholderKey; import com.djrapitops.plan.data.store.containers.DataContainer; diff --git a/Plan/src/main/java/com/djrapitops/plan/utilities/formatting/time/ClockFormatter.java b/Plan/src/main/java/com/djrapitops/plan/utilities/formatting/time/ClockFormatter.java new file mode 100644 index 000000000..84b88b07a --- /dev/null +++ b/Plan/src/main/java/com/djrapitops/plan/utilities/formatting/time/ClockFormatter.java @@ -0,0 +1,29 @@ +package com.djrapitops.plan.utilities.formatting.time; + +import com.djrapitops.plan.system.locale.Locale; +import com.djrapitops.plan.system.settings.Settings; +import com.djrapitops.plan.system.settings.config.PlanConfig; + + +/** + * Formatter for a timestamp that only includes a clock. + * + * @author Rsl1122 + */ +public class ClockFormatter extends DateFormatter { + + public ClockFormatter(PlanConfig config, Locale locale) { + super(config, locale); + } + + @Override + public String apply(Long date) { + return date > 0 ? format(date) : "-"; + } + + private String format(Long date) { + String format = config.getString(Settings.FORMAT_DATE_CLOCK); + + return format(date, format); + } +} \ No newline at end of file diff --git a/Plan/src/main/java/com/djrapitops/plan/utilities/formatting/time/DateFormatter.java b/Plan/src/main/java/com/djrapitops/plan/utilities/formatting/time/DateFormatter.java new file mode 100644 index 000000000..80fbb917f --- /dev/null +++ b/Plan/src/main/java/com/djrapitops/plan/utilities/formatting/time/DateFormatter.java @@ -0,0 +1,61 @@ +package com.djrapitops.plan.utilities.formatting.time; + +import com.djrapitops.plan.system.locale.Locale; +import com.djrapitops.plan.system.locale.lang.GenericLang; +import com.djrapitops.plan.system.settings.Settings; +import com.djrapitops.plan.system.settings.config.PlanConfig; +import com.djrapitops.plan.utilities.formatting.Formatter; + +import java.text.SimpleDateFormat; +import java.util.TimeZone; +import java.util.concurrent.TimeUnit; + +/** + * Abstract formatter for a timestamp. + * + * @author Rsl1122 + */ +public abstract class DateFormatter implements Formatter { + + protected final PlanConfig config; + protected final Locale locale; + + public DateFormatter(PlanConfig config, Locale locale) { + this.config = config; + this.locale = locale; + } + + @Override + public abstract String apply(Long value); + + protected String format(long epochMs, String format) { + boolean useServerTime = config.isTrue(Settings.USE_SERVER_TIME); + String locale = config.getString(Settings.LOCALE); + java.util.Locale usedLocale = locale.equalsIgnoreCase("default") + ? java.util.Locale.ENGLISH + : java.util.Locale.forLanguageTag(locale); + SimpleDateFormat dateFormat = new SimpleDateFormat(format, usedLocale); + TimeZone timeZone = useServerTime ? TimeZone.getDefault() : TimeZone.getTimeZone("GMT"); + dateFormat.setTimeZone(timeZone); + return dateFormat.format(epochMs); + } + + protected String replaceRecentDays(long epochMs, String format) { + return replaceRecentDays(epochMs, format, config.getString(Settings.FORMAT_DATE_RECENT_DAYS_PATTERN)); + } + + protected String replaceRecentDays(long epochMs, String format, String pattern) { + long now = System.currentTimeMillis(); + + long fromStartOfDay = now % TimeUnit.DAYS.toMillis(1L); + if (epochMs > now - fromStartOfDay) { + format = format.replace(pattern, locale.getString(GenericLang.TODAY)); + } else if (epochMs > now - TimeUnit.DAYS.toMillis(1L) - fromStartOfDay) { + format = format.replace(pattern, locale.getString(GenericLang.YESTERDAY)); + } else if (epochMs > now - TimeUnit.DAYS.toMillis(5L)) { + format = format.replace(pattern, "EEEE"); + } + return format; + } + +} \ No newline at end of file diff --git a/Plan/src/main/java/com/djrapitops/plan/utilities/formatting/time/DateHolderFormatter.java b/Plan/src/main/java/com/djrapitops/plan/utilities/formatting/time/DateHolderFormatter.java new file mode 100644 index 000000000..bc19e9d01 --- /dev/null +++ b/Plan/src/main/java/com/djrapitops/plan/utilities/formatting/time/DateHolderFormatter.java @@ -0,0 +1,23 @@ +package com.djrapitops.plan.utilities.formatting.time; + +import com.djrapitops.plan.data.store.objects.DateHolder; +import com.djrapitops.plan.utilities.formatting.Formatter; + +/** + * Formatter for a DateHolder object that uses a different formatter. + * + * @author Rsl1122 + */ +public class DateHolderFormatter implements Formatter { + + private final Formatter formatter; + + public DateHolderFormatter(Formatter formatter) { + this.formatter = formatter; + } + + @Override + public String apply(DateHolder dateHolder) { + return formatter.apply(dateHolder.getDate()); + } +} \ No newline at end of file diff --git a/Plan/src/main/java/com/djrapitops/plan/utilities/formatting/time/DayFormatter.java b/Plan/src/main/java/com/djrapitops/plan/utilities/formatting/time/DayFormatter.java new file mode 100644 index 000000000..ad6add619 --- /dev/null +++ b/Plan/src/main/java/com/djrapitops/plan/utilities/formatting/time/DayFormatter.java @@ -0,0 +1,32 @@ +package com.djrapitops.plan.utilities.formatting.time; + +import com.djrapitops.plan.system.locale.Locale; +import com.djrapitops.plan.system.settings.Settings; +import com.djrapitops.plan.system.settings.config.PlanConfig; + +/** + * Formatter for a timestamp which includes days as the smallest entry. + * + * @author Rsl1122 + */ +public class DayFormatter extends DateFormatter { + + public DayFormatter(PlanConfig config, Locale locale) { + super(config, locale); + } + + @Override + public String apply(Long date) { + return date > 0 ? format(date) : "-"; + } + + private String format(Long date) { + String format = "MMMMM d"; + + if (config.isTrue(Settings.FORMAT_DATE_RECENT_DAYS)) { + format = replaceRecentDays(date, format, "MMMMM"); + } + + return format(date, format); + } +} \ No newline at end of file diff --git a/Plan/src/main/java/com/djrapitops/plan/utilities/formatting/time/ISO8601NoClockFormatter.java b/Plan/src/main/java/com/djrapitops/plan/utilities/formatting/time/ISO8601NoClockFormatter.java new file mode 100644 index 000000000..915d54e94 --- /dev/null +++ b/Plan/src/main/java/com/djrapitops/plan/utilities/formatting/time/ISO8601NoClockFormatter.java @@ -0,0 +1,27 @@ +package com.djrapitops.plan.utilities.formatting.time; + +import com.djrapitops.plan.system.locale.Locale; +import com.djrapitops.plan.system.settings.config.PlanConfig; + +/** + * Formatter for a timestamp in ISO-8601 format without the clock. + * + * @author Rsl1122 + */ +public class ISO8601NoClockFormatter extends DateFormatter { + + public ISO8601NoClockFormatter(PlanConfig config, Locale locale) { + super(config, locale); + } + + @Override + public String apply(Long date) { + return date > 0 ? format(date) : "-"; + } + + private String format(Long date) { + String format = "yyyy-MM-dd"; + + return format(date, format); + } +} \ No newline at end of file diff --git a/Plan/src/main/java/com/djrapitops/plan/utilities/formatting/time/SecondFormatter.java b/Plan/src/main/java/com/djrapitops/plan/utilities/formatting/time/SecondFormatter.java new file mode 100644 index 000000000..56d86ed56 --- /dev/null +++ b/Plan/src/main/java/com/djrapitops/plan/utilities/formatting/time/SecondFormatter.java @@ -0,0 +1,33 @@ +package com.djrapitops.plan.utilities.formatting.time; + +import com.djrapitops.plan.system.locale.Locale; +import com.djrapitops.plan.system.settings.Settings; +import com.djrapitops.plan.system.settings.config.PlanConfig; + + +/** + * Formatter for timestamp which includes seconds as the smallest entry. + * + * @author Rsl1122 + */ +public class SecondFormatter extends DateFormatter { + + public SecondFormatter(PlanConfig config, Locale locale) { + super(config, locale); + } + + @Override + public String apply(Long date) { + return date > 0 ? format(date) : "-"; + } + + private String format(Long date) { + String format = config.getString(Settings.FORMAT_DATE_FULL); + + if (config.isTrue(Settings.FORMAT_DATE_RECENT_DAYS)) { + format = replaceRecentDays(date, format); + } + + return format(date, format); + } +} \ No newline at end of file diff --git a/Plan/src/main/java/com/djrapitops/plan/data/store/mutators/formatting/TimeAmountFormatter.java b/Plan/src/main/java/com/djrapitops/plan/utilities/formatting/time/TimeAmountFormatter.java similarity index 81% rename from Plan/src/main/java/com/djrapitops/plan/data/store/mutators/formatting/TimeAmountFormatter.java rename to Plan/src/main/java/com/djrapitops/plan/utilities/formatting/time/TimeAmountFormatter.java index 014309a7b..872229e08 100644 --- a/Plan/src/main/java/com/djrapitops/plan/data/store/mutators/formatting/TimeAmountFormatter.java +++ b/Plan/src/main/java/com/djrapitops/plan/utilities/formatting/time/TimeAmountFormatter.java @@ -1,6 +1,8 @@ -package com.djrapitops.plan.data.store.mutators.formatting; +package com.djrapitops.plan.utilities.formatting.time; import com.djrapitops.plan.system.settings.Settings; +import com.djrapitops.plan.system.settings.config.PlanConfig; +import com.djrapitops.plan.utilities.formatting.Formatter; import org.apache.commons.lang3.StringUtils; /** @@ -19,6 +21,12 @@ public class TimeAmountFormatter implements Formatter { private static final String MONTHS_PH = "%months%"; private static final String YEARS_PH = "%years%"; + private final PlanConfig config; + + public TimeAmountFormatter(PlanConfig config) { + this.config = config; + } + @Override public String apply(Long ms) { if (ms <= 0) { @@ -42,9 +50,9 @@ public class TimeAmountFormatter implements Formatter { appendMonths(builder, months); appendDays(builder, days); - String hourFormat = Settings.FORMAT_HOURS.toString(); - String minuteFormat = Settings.FORMAT_MINUTES.toString(); - String secondFormat = Settings.FORMAT_SECONDS.toString(); + String hourFormat = config.getString(Settings.FORMAT_HOURS); + String minuteFormat = config.getString(Settings.FORMAT_MINUTES); + String secondFormat = config.getString(Settings.FORMAT_SECONDS); appendHours(builder, hours, hourFormat); appendMinutes(builder, minutes, hours, hourFormat, minuteFormat); @@ -52,7 +60,7 @@ public class TimeAmountFormatter implements Formatter { String formattedTime = StringUtils.remove(builder.toString(), ZERO_PH); if (formattedTime.isEmpty()) { - return Settings.FORMAT_ZERO_SECONDS.toString(); + return config.getString(Settings.FORMAT_ZERO_SECONDS); } return formattedTime; } @@ -100,21 +108,21 @@ public class TimeAmountFormatter implements Formatter { } private void appendDays(StringBuilder builder, long days) { - String singular = Settings.FORMAT_DAY.toString(); - String plural = Settings.FORMAT_DAYS.toString(); + String singular = config.getString(Settings.FORMAT_DAY); + String plural = config.getString(Settings.FORMAT_DAYS); appendValue(builder, days, singular, plural, DAYS_PH); } private void appendMonths(StringBuilder builder, long months) { - String singular = Settings.FORMAT_MONTH.toString(); - String plural = Settings.FORMAT_MONTHS.toString(); + String singular = config.getString(Settings.FORMAT_MONTH); + String plural = config.getString(Settings.FORMAT_MONTHS); appendValue(builder, months, singular, plural, MONTHS_PH); } private void appendYears(StringBuilder builder, long years) { - String singular = Settings.FORMAT_YEAR.toString(); - String plural = Settings.FORMAT_YEARS.toString(); + String singular = config.getString(Settings.FORMAT_YEAR); + String plural = config.getString(Settings.FORMAT_YEARS); appendValue(builder, years, singular, plural, YEARS_PH); } diff --git a/Plan/src/main/java/com/djrapitops/plan/utilities/formatting/time/YearFormatter.java b/Plan/src/main/java/com/djrapitops/plan/utilities/formatting/time/YearFormatter.java new file mode 100644 index 000000000..48379ff96 --- /dev/null +++ b/Plan/src/main/java/com/djrapitops/plan/utilities/formatting/time/YearFormatter.java @@ -0,0 +1,31 @@ +package com.djrapitops.plan.utilities.formatting.time; + +import com.djrapitops.plan.system.locale.Locale; +import com.djrapitops.plan.system.settings.Settings; +import com.djrapitops.plan.system.settings.config.PlanConfig; + +/** + * Formatter for a timestamp which includes year, but not seconds. + * + * @author Rsl1122 + */ +public class YearFormatter extends DateFormatter { + + public YearFormatter(PlanConfig config, Locale locale) { + super(config, locale); + } + + @Override + public String apply(Long date) { + return date > 0 ? format(date) : "-"; + } + + private String format(Long date) { + String format = config.getString(Settings.FORMAT_DATE_NO_SECONDS); + + if (config.isTrue(Settings.FORMAT_DATE_RECENT_DAYS)) { + format = replaceRecentDays(date, format); + } + return format(date, format); + } +} \ No newline at end of file diff --git a/Plan/src/main/java/com/djrapitops/plan/utilities/html/HtmlStructure.java b/Plan/src/main/java/com/djrapitops/plan/utilities/html/HtmlStructure.java index c787fb606..7d22858be 100644 --- a/Plan/src/main/java/com/djrapitops/plan/utilities/html/HtmlStructure.java +++ b/Plan/src/main/java/com/djrapitops/plan/utilities/html/HtmlStructure.java @@ -4,22 +4,11 @@ */ package com.djrapitops.plan.utilities.html; -import com.djrapitops.plan.api.exceptions.database.DBOpException; -import com.djrapitops.plan.system.database.databases.Database; -import com.djrapitops.plan.system.info.server.Server; -import com.djrapitops.plan.system.info.server.ServerInfo; -import com.djrapitops.plan.system.info.server.properties.ServerProperties; -import com.djrapitops.plan.utilities.FormatUtils; -import com.djrapitops.plan.utilities.html.graphs.line.OnlineActivityGraph; import com.djrapitops.plan.utilities.html.icon.Color; import com.djrapitops.plan.utilities.html.icon.Icon; import com.djrapitops.plan.utilities.html.icon.Icons; -import com.djrapitops.plugin.api.utility.log.Log; import org.apache.commons.text.TextStringBuilder; -import java.util.UUID; -import java.util.concurrent.ThreadLocalRandom; - /** * Class for parsing layout components of the websites. * @@ -62,77 +51,6 @@ public class HtmlStructure { return new String[]{"
  • Calculating... Refresh shortly
  • ", tab}; } - // TODO Rework into NetworkPage generation - public static String createServerContainer() { - ServerProperties properties = ServerInfo.getServerProperties(); - int maxPlayers = properties.getMaxPlayers(); - int online = properties.getOnlinePlayers(); - String refresh = FormatUtils.formatTimeStampClock(System.currentTimeMillis()); - - Server server = ServerInfo.getServer(); - - String serverName = server.getName(); - String serverType = properties.getVersion(); - String address = "../server/" + serverName; - - Database db = Database.getActive(); - UUID serverUUID = server.getUuid(); - String id = ThreadLocalRandom.current().nextInt(100) + serverUUID.toString().replace("-", ""); - - int playerCount = 0; - String playerData = "[]"; - try { - playerCount = db.count().getServerPlayerCount(serverUUID); - playerData = new OnlineActivityGraph(db.fetch().getTPSData(serverUUID)).toHighChartsSeries(); - } catch (DBOpException e) { - Log.toLog(HtmlStructure.class, e); - } - - return "
    " + - "
    " + - "
    " + - "
    " + - "
    " + - "

    " + serverName + "

    " + - "
    " + - "
    " + - "
    " + - "
    " + - "
    " + - "
    " + - "
    " + - "
    " + - "
    " + - "

    Registered Players " + - "" + playerCount + "

    " + - "

    Players Online " + - "" + online + " / " + maxPlayers + "

    " + - "

    Type " + - "" + serverType + "

    " + - "
    " + - "

    Last Updated" + - "" + refresh + "

    " + - "
    " + - "
    " + - "" + - ""; - } - public static String playerStatus(boolean online, boolean banned, boolean op) { StringBuilder html = new StringBuilder("

    "); if (online) { diff --git a/Plan/src/main/java/com/djrapitops/plan/utilities/html/HtmlUtils.java b/Plan/src/main/java/com/djrapitops/plan/utilities/html/HtmlUtils.java index c3b1fbbf4..dd63ac367 100644 --- a/Plan/src/main/java/com/djrapitops/plan/utilities/html/HtmlUtils.java +++ b/Plan/src/main/java/com/djrapitops/plan/utilities/html/HtmlUtils.java @@ -1,8 +1,5 @@ package com.djrapitops.plan.utilities.html; -import com.djrapitops.plan.system.info.server.ServerInfo; -import com.djrapitops.plan.system.settings.Settings; - /** * @author Rsl1122 */ @@ -15,22 +12,6 @@ public class HtmlUtils { throw new IllegalStateException("Utility class"); } - /** - * Used to get the WebServer's IP with Port. - * - * @return For example 127.0.0.1:8804 - */ - public static String getIP() { - int port = Settings.WEBSERVER_PORT.getNumber(); - String ip; - if (Settings.SHOW_ALTERNATIVE_IP.isTrue()) { - ip = Settings.ALTERNATIVE_IP.toString().replace("%port%", String.valueOf(port)); - } else { - ip = ServerInfo.getServerProperties().getIp() + ":" + port; - } - return ip; - } - /** * Attempts to remove XSS components. * diff --git a/Plan/src/main/java/com/djrapitops/plan/utilities/html/graphs/Graphs.java b/Plan/src/main/java/com/djrapitops/plan/utilities/html/graphs/Graphs.java new file mode 100644 index 000000000..a6de21f14 --- /dev/null +++ b/Plan/src/main/java/com/djrapitops/plan/utilities/html/graphs/Graphs.java @@ -0,0 +1,68 @@ +package com.djrapitops.plan.utilities.html.graphs; + +import com.djrapitops.plan.utilities.html.graphs.bar.BarGraphFactory; +import com.djrapitops.plan.utilities.html.graphs.calendar.CalendarFactory; +import com.djrapitops.plan.utilities.html.graphs.line.LineGraphFactory; +import com.djrapitops.plan.utilities.html.graphs.pie.PieGraphFactory; +import com.djrapitops.plan.utilities.html.graphs.special.SpecialGraphFactory; +import com.djrapitops.plan.utilities.html.graphs.stack.StackGraphFactory; + +import javax.inject.Inject; +import javax.inject.Singleton; + +/** + * Factory class for different objects representing HTML graphs. + * + * @author Rsl1122 + */ +@Singleton +public class Graphs { + + private final BarGraphFactory barGraphFactory; + private final CalendarFactory calendarFactory; + private final LineGraphFactory lineGraphFactory; + private final PieGraphFactory pieGraphFactory; + private final StackGraphFactory stackGraphFactory; + private final SpecialGraphFactory specialGraphFactory; + + @Inject + public Graphs( + BarGraphFactory barGraphFactory, + CalendarFactory calendarFactory, + LineGraphFactory lineGraphFactory, + PieGraphFactory pieGraphFactory, + StackGraphFactory stackGraphFactory, + SpecialGraphFactory specialGraphFactory + ) { + this.barGraphFactory = barGraphFactory; + this.calendarFactory = calendarFactory; + this.lineGraphFactory = lineGraphFactory; + this.pieGraphFactory = pieGraphFactory; + this.stackGraphFactory = stackGraphFactory; + this.specialGraphFactory = specialGraphFactory; + } + + public BarGraphFactory bar() { + return barGraphFactory; + } + + public CalendarFactory calendar() { + return calendarFactory; + } + + public LineGraphFactory line() { + return lineGraphFactory; + } + + public PieGraphFactory pie() { + return pieGraphFactory; + } + + public StackGraphFactory stack() { + return stackGraphFactory; + } + + public SpecialGraphFactory special() { + return specialGraphFactory; + } +} \ No newline at end of file diff --git a/Plan/src/main/java/com/djrapitops/plan/utilities/html/graphs/ProgressBar.java b/Plan/src/main/java/com/djrapitops/plan/utilities/html/graphs/ProgressBar.java index a29ebc932..043eea01c 100644 --- a/Plan/src/main/java/com/djrapitops/plan/utilities/html/graphs/ProgressBar.java +++ b/Plan/src/main/java/com/djrapitops/plan/utilities/html/graphs/ProgressBar.java @@ -1,9 +1,9 @@ package com.djrapitops.plan.utilities.html.graphs; -import com.djrapitops.plan.data.store.mutators.formatting.Formatters; +import com.djrapitops.plan.utilities.formatting.Formatter; /** - * Utility for creating ProgressBars. + * Utility for creating Progress bars. * * @author Rsl1122 */ @@ -12,16 +12,19 @@ public class ProgressBar { private final int obtained; private final int max; + private final Formatter percentageFormatter; + private final String color; - public ProgressBar(int obtained, int max) { - this(obtained, max, "teal"); + public ProgressBar(int obtained, int max, Formatter percentageFormatter) { + this(obtained, max, "teal", percentageFormatter); } - public ProgressBar(int obtained, int max, String color) { + public ProgressBar(int obtained, int max, String color, Formatter percentageFormatter) { this.obtained = obtained; this.max = max; this.color = color; + this.percentageFormatter = percentageFormatter; } public String toHtml() { @@ -32,7 +35,7 @@ public class ProgressBar { " aria-valuenow=\"" + obtained + "\"" + " aria-valuemin=\"0\" aria-valuemax=\"" + max + "\"" + " style=\"width: " + percentageRounded + "%;\">" + - obtained + " / " + max + " (" + Formatters.percentage().apply(percentage) + ")" + + obtained + " / " + max + " (" + percentageFormatter.apply(percentage) + ")" + "

    "; } diff --git a/Plan/src/main/java/com/djrapitops/plan/utilities/html/graphs/bar/BarGraphFactory.java b/Plan/src/main/java/com/djrapitops/plan/utilities/html/graphs/bar/BarGraphFactory.java new file mode 100644 index 000000000..5527e4089 --- /dev/null +++ b/Plan/src/main/java/com/djrapitops/plan/utilities/html/graphs/bar/BarGraphFactory.java @@ -0,0 +1,23 @@ +package com.djrapitops.plan.utilities.html.graphs.bar; + +import com.djrapitops.plan.data.store.mutators.PlayersMutator; + +import javax.inject.Inject; +import javax.inject.Singleton; + +/** + * Factory class for Bar Graphs. + * + * @author Rsl1122 + */ +@Singleton +public class BarGraphFactory { + @Inject + public BarGraphFactory() { + // Inject Constructor. + } + + public BarGraph geolocationBarGraph(PlayersMutator playersMutator) { + return new GeolocationBarGraph(playersMutator); + } +} \ No newline at end of file diff --git a/Plan/src/main/java/com/djrapitops/plan/utilities/html/graphs/bar/GeolocationBarGraph.java b/Plan/src/main/java/com/djrapitops/plan/utilities/html/graphs/bar/GeolocationBarGraph.java index ba3900acf..b92d5c342 100644 --- a/Plan/src/main/java/com/djrapitops/plan/utilities/html/graphs/bar/GeolocationBarGraph.java +++ b/Plan/src/main/java/com/djrapitops/plan/utilities/html/graphs/bar/GeolocationBarGraph.java @@ -9,11 +9,11 @@ import java.util.stream.Collectors; public class GeolocationBarGraph extends BarGraph { - public GeolocationBarGraph(PlayersMutator mutator) { + GeolocationBarGraph(PlayersMutator mutator) { this(mutator.getGeolocations()); } - public GeolocationBarGraph(List geolocations) { + private GeolocationBarGraph(List geolocations) { super(turnToBars(geolocations)); } diff --git a/Plan/src/main/java/com/djrapitops/plan/utilities/html/graphs/calendar/CalendarFactory.java b/Plan/src/main/java/com/djrapitops/plan/utilities/html/graphs/calendar/CalendarFactory.java new file mode 100644 index 000000000..1f3a5e2c8 --- /dev/null +++ b/Plan/src/main/java/com/djrapitops/plan/utilities/html/graphs/calendar/CalendarFactory.java @@ -0,0 +1,48 @@ +package com.djrapitops.plan.utilities.html.graphs.calendar; + +import com.djrapitops.plan.data.store.containers.PlayerContainer; +import com.djrapitops.plan.data.store.mutators.PlayersMutator; +import com.djrapitops.plan.system.settings.theme.Theme; +import com.djrapitops.plan.utilities.formatting.Formatters; + +import javax.inject.Inject; +import javax.inject.Singleton; +import java.util.TreeMap; + +/** + * Factory class for different objects representing HTML calendars. + * + * @author Rsl1122 + */ +@Singleton +public class CalendarFactory { + private final Theme theme; + private final Formatters formatters; + + @Inject + public CalendarFactory( + Formatters formatters, + Theme theme + ) { + this.formatters = formatters; + this.theme = theme; + } + + public PlayerCalendar playerCalendar(PlayerContainer player) { + return new PlayerCalendar( + player, + formatters.timeAmount(), formatters.yearLong(), formatters.iso8601NoClock(), theme + ); + } + + public ServerCalendar serverCalendar( + PlayersMutator mutator, + TreeMap uniquePerDay, + TreeMap newPerDay + ) { + return new ServerCalendar( + mutator, uniquePerDay, newPerDay, + formatters.iso8601NoClockLong(), formatters.timeAmount(), theme + ); + } +} \ No newline at end of file diff --git a/Plan/src/main/java/com/djrapitops/plan/utilities/html/graphs/calendar/PlayerCalendar.java b/Plan/src/main/java/com/djrapitops/plan/utilities/html/graphs/calendar/PlayerCalendar.java index 972966ca4..a48e5a5d4 100644 --- a/Plan/src/main/java/com/djrapitops/plan/utilities/html/graphs/calendar/PlayerCalendar.java +++ b/Plan/src/main/java/com/djrapitops/plan/utilities/html/graphs/calendar/PlayerCalendar.java @@ -9,17 +9,16 @@ import com.djrapitops.plan.data.container.Session; import com.djrapitops.plan.data.store.containers.PlayerContainer; import com.djrapitops.plan.data.store.keys.PlayerKeys; import com.djrapitops.plan.data.store.keys.SessionKeys; -import com.djrapitops.plan.data.store.mutators.formatting.Formatter; -import com.djrapitops.plan.data.store.mutators.formatting.Formatters; +import com.djrapitops.plan.data.store.objects.DateHolder; import com.djrapitops.plan.system.settings.theme.Theme; import com.djrapitops.plan.system.settings.theme.ThemeVal; -import com.djrapitops.plan.utilities.FormatUtils; -import com.djrapitops.plugin.api.TimeAmount; +import com.djrapitops.plan.utilities.formatting.Formatter; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.concurrent.TimeUnit; /** * Utility for creating FullCalendar calendar event array on Player page. @@ -28,19 +27,28 @@ import java.util.Map; */ public class PlayerCalendar { + private final Formatter timeAmountFormatter; + private final Formatter yearLongFormatter; + private final Formatter iso8601Formatter; + private final Theme theme; + private final List allSessions; private final long registered; - public PlayerCalendar(PlayerContainer container) { - this( - container.getValue(PlayerKeys.SESSIONS).orElse(new ArrayList<>()), - container.getValue(PlayerKeys.REGISTERED).orElse(0L) - ); - } + PlayerCalendar( + PlayerContainer container, + Formatter timeAmountFormatter, + Formatter yearLongFormatter, + Formatter iso8601Formatter, + Theme theme + ) { + this.allSessions = container.getValue(PlayerKeys.SESSIONS).orElse(new ArrayList<>()); + this.registered = container.getValue(PlayerKeys.REGISTERED).orElse(0L); - private PlayerCalendar(List allSessions, long registered) { - this.allSessions = allSessions; - this.registered = registered; + this.timeAmountFormatter = timeAmountFormatter; + this.yearLongFormatter = yearLongFormatter; + this.iso8601Formatter = iso8601Formatter; + this.theme = theme; } public String toCalendarSeries() { @@ -63,9 +71,9 @@ public class PlayerCalendar { int sessionCount = sessions.size(); long playtime = sessions.stream().mapToLong(Session::getLength).sum(); - series.append(",{title: 'Playtime: ").append(Formatters.timeAmount().apply(playtime)) + series.append(",{title: 'Playtime: ").append(timeAmountFormatter.apply(playtime)) .append("',start:'").append(day) - .append("',color: '").append(Theme.getValue(ThemeVal.GREEN)).append("'") + .append("',color: '").append(theme.getValue(ThemeVal.GREEN)).append("'") .append("}"); series.append(",{title: 'Sessions: ").append(sessionCount) @@ -77,7 +85,7 @@ public class PlayerCalendar { private Map> getSessionsByDay() { Map> sessionsByDay = new HashMap<>(); for (Session session : allSessions) { - String day = Formatters.iso8601NoClock().apply(session); + String day = iso8601Formatter.apply(session); List sessionsOfDay = sessionsByDay.getOrDefault(day, new ArrayList<>()); sessionsOfDay.add(session); @@ -87,11 +95,10 @@ public class PlayerCalendar { } private void appendSessionsAndKills(StringBuilder series) { - long fiveMinutes = TimeAmount.MINUTE.ms() * 5L; + long fiveMinutes = TimeUnit.MINUTES.toMillis(5L); - Formatter timeFormatter = Formatters.timeAmount(); for (Session session : allSessions) { - String length = timeFormatter.apply(session.getLength()); + String length = timeAmountFormatter.apply(session.getLength()); series.append(",{title: 'Session: ").append(length) .append("',start:").append(session.getUnsafe(SessionKeys.START)) @@ -105,16 +112,14 @@ public class PlayerCalendar { series.append(",{title: 'Killed: ").append(kill.getVictim()) .append("',start:").append(time) .append(",end:").append(time + fiveMinutes) - .append(",color: '").append(Theme.getValue(ThemeVal.RED)).append("'") + .append(",color: '").append(theme.getValue(ThemeVal.RED)).append("'") .append("}"); } } } private void appendRegister(StringBuilder series) { - String registered = FormatUtils.formatTimeStampYear(this.registered); - - series.append("{title: 'Registered: ").append(registered).append("'," + - "start: ").append(this.registered).append(",color: '").append(Theme.getValue(ThemeVal.LIGHT_GREEN)).append("'}"); + series.append("{title: 'Registered: ").append(yearLongFormatter.apply(registered)).append("'," + + "start: ").append(this.registered).append(",color: '").append(theme.getValue(ThemeVal.LIGHT_GREEN)).append("'}"); } } diff --git a/Plan/src/main/java/com/djrapitops/plan/utilities/html/graphs/calendar/ServerCalendar.java b/Plan/src/main/java/com/djrapitops/plan/utilities/html/graphs/calendar/ServerCalendar.java index 7b1984332..aa6096810 100644 --- a/Plan/src/main/java/com/djrapitops/plan/utilities/html/graphs/calendar/ServerCalendar.java +++ b/Plan/src/main/java/com/djrapitops/plan/utilities/html/graphs/calendar/ServerCalendar.java @@ -7,10 +7,9 @@ package com.djrapitops.plan.utilities.html.graphs.calendar; import com.djrapitops.plan.data.container.Session; import com.djrapitops.plan.data.store.mutators.PlayersMutator; import com.djrapitops.plan.data.store.mutators.SessionsMutator; -import com.djrapitops.plan.data.store.mutators.formatting.Formatters; import com.djrapitops.plan.system.settings.theme.Theme; import com.djrapitops.plan.system.settings.theme.ThemeVal; -import com.djrapitops.plan.utilities.FormatUtils; +import com.djrapitops.plan.utilities.formatting.Formatter; import java.util.*; @@ -25,12 +24,22 @@ public class ServerCalendar { private final TreeMap uniquePerDay; private final TreeMap newPerDay; - public ServerCalendar(PlayersMutator mutator, - TreeMap uniquePerDay, - TreeMap newPerDay) { + private final Formatter iso8601Formatter; + private final Formatter timeAmountFormatter; + private final Theme theme; + + ServerCalendar( + PlayersMutator mutator, TreeMap uniquePerDay, TreeMap newPerDay, + Formatter iso8601Formatter, + Formatter timeAmountFormatter, + Theme theme + ) { this.mutator = mutator; this.uniquePerDay = uniquePerDay; this.newPerDay = newPerDay; + this.iso8601Formatter = iso8601Formatter; + this.timeAmountFormatter = timeAmountFormatter; + this.theme = theme; } public String toCalendarSeries() { @@ -51,12 +60,12 @@ public class ServerCalendar { if (newPlayers <= 0) { continue; } - + String day = entry.getKey(); series.append(",{title: 'New: ").append(newPlayers) .append("',start:'").append(day) - .append("',color: '").append(Theme.getValue(ThemeVal.LIGHT_GREEN)).append("'") + .append("',color: '").append(theme.getValue(ThemeVal.LIGHT_GREEN)).append("'") .append("}"); } @@ -72,7 +81,7 @@ public class ServerCalendar { } Long key = entry.getKey(); - String day = FormatUtils.formatTimeStampISO8601NoClock(key); + String day = iso8601Formatter.apply(key); List sessions = byStartOfDay.getOrDefault(key, new ArrayList<>()); SessionsMutator dayMutator = new SessionsMutator(sessions); @@ -80,14 +89,14 @@ public class ServerCalendar { long playtime = dayMutator.toPlaytime(); long uniquePlayers = entry.getValue(); - series.append(",{title: 'Playtime: ").append(Formatters.timeAmount().apply(playtime)) + series.append(",{title: 'Playtime: ").append(timeAmountFormatter.apply(playtime)) .append("',start:'").append(day) - .append("',color: '").append(Theme.getValue(ThemeVal.GREEN)).append("'") + .append("',color: '").append(theme.getValue(ThemeVal.GREEN)).append("'") .append("}"); series.append(",{title: 'Sessions: ").append(sessionCount) .append("',start:'").append(day) - .append("',color: '").append(Theme.getValue(ThemeVal.TEAL)).append("'") + .append("',color: '").append(theme.getValue(ThemeVal.TEAL)).append("'") .append("}"); series.append(",{title: 'Unique: ").append(uniquePlayers) @@ -99,7 +108,7 @@ public class ServerCalendar { private Map getRegisteredByDay() { Map registeredByDay = new HashMap<>(); for (Map.Entry entry : newPerDay.entrySet()) { - String day = FormatUtils.formatTimeStampISO8601NoClock(entry.getKey()); + String day = iso8601Formatter.apply(entry.getKey()); registeredByDay.put(day, entry.getValue()); } return registeredByDay; diff --git a/Plan/src/main/java/com/djrapitops/plan/utilities/html/graphs/line/AbstractLineGraph.java b/Plan/src/main/java/com/djrapitops/plan/utilities/html/graphs/line/AbstractLineGraph.java deleted file mode 100644 index 94cbbf593..000000000 --- a/Plan/src/main/java/com/djrapitops/plan/utilities/html/graphs/line/AbstractLineGraph.java +++ /dev/null @@ -1,93 +0,0 @@ -/* - * To change this license header, choose License Headers in Project Properties. - * To change this template file, choose Tools | Templates - * and open the template in the editor. - */ -package com.djrapitops.plan.utilities.html.graphs.line; - -import com.djrapitops.plan.system.settings.Settings; -import com.djrapitops.plan.utilities.html.graphs.HighChart; -import com.djrapitops.plan.utilities.html.graphs.line.alg.DouglasPeuckerAlgorithm; -import com.djrapitops.plan.utilities.html.graphs.line.alg.ReduceGapTriangles; -import com.djrapitops.plugin.api.TimeAmount; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; - -/** - * This is a LineGraph for any set of Points, thus it is Abstract. - * - * @author Rsl1122 - * @since 4.2.0 - */ -public class AbstractLineGraph implements HighChart { - - protected List points; - protected boolean reduceGapTriangles = false; - protected boolean reducePoints = false; - - public AbstractLineGraph() { - points = new ArrayList<>(); - } - - public AbstractLineGraph(List points) { - this.points = points; - } - - @Override - public String toHighChartsSeries() { - StringBuilder arrayBuilder = new StringBuilder("["); - - if (reducePoints) { - points = DouglasPeuckerAlgorithm.reducePoints(points, 0); - } - if (reduceGapTriangles) { - points = ReduceGapTriangles.reduce(points); - } - - int size = points.size(); - Long lastX = null; - boolean addMissingPoints = Settings.DISPLAY_GAPS_IN_GRAPH_DATA.isTrue(); - for (int i = 0; i < size; i++) { - Point point = points.get(i); - Double y = point.getY(); - long date = (long) point.getX(); - if (addMissingPoints && lastX != null && date - lastX > TimeAmount.MINUTE.ms() * 3L) { - addMissingPoints(arrayBuilder, lastX, date); - } - lastX = date; - arrayBuilder.append("[").append(date).append(",").append(y).append("]"); - if (i < size - 1) { - arrayBuilder.append(","); - } - } - - arrayBuilder.append("]"); - return arrayBuilder.toString(); - } - - private void addMissingPoints(StringBuilder arrayBuilder, Long lastX, long date) { - long iterate = lastX + TimeAmount.MINUTE.ms(); - while (iterate < date) { - arrayBuilder.append("[").append(iterate).append(",null],"); - iterate += TimeAmount.MINUTE.ms() * 30L; - } - } - - public void reduceGapTriangles() { - this.reduceGapTriangles = true; - } - - public void reducePoints() { - this.reducePoints = true; - } - - public void setPoints(List points) { - this.points = points; - } - - public void addPoints(Collection points) { - this.points.addAll(points); - } -} diff --git a/Plan/src/main/java/com/djrapitops/plan/utilities/html/graphs/line/CPUGraph.java b/Plan/src/main/java/com/djrapitops/plan/utilities/html/graphs/line/CPUGraph.java index e26a24305..86875934e 100644 --- a/Plan/src/main/java/com/djrapitops/plan/utilities/html/graphs/line/CPUGraph.java +++ b/Plan/src/main/java/com/djrapitops/plan/utilities/html/graphs/line/CPUGraph.java @@ -1,10 +1,7 @@ package com.djrapitops.plan.utilities.html.graphs.line; -import com.djrapitops.plan.data.container.TPS; import com.djrapitops.plan.data.store.mutators.TPSMutator; -import java.util.List; - /** * Graph about CPU Usage gathered by TPSCountTimer. * @@ -12,13 +9,9 @@ import java.util.List; * @see com.djrapitops.plan.system.tasks.TPSCountTimer * @since 4.2.0 */ -public class CPUGraph extends AbstractLineGraph { +class CPUGraph extends LineGraph { - public CPUGraph(List tpsData) { - this(new TPSMutator(tpsData)); - } - - public CPUGraph(TPSMutator mutator) { - super(mutator.cpuPoints()); + CPUGraph(TPSMutator mutator, boolean displayGaps) { + super(mutator.cpuPoints(), displayGaps); } } diff --git a/Plan/src/main/java/com/djrapitops/plan/utilities/html/graphs/line/ChunkGraph.java b/Plan/src/main/java/com/djrapitops/plan/utilities/html/graphs/line/ChunkGraph.java index 3ce1d5f0e..4305db54e 100644 --- a/Plan/src/main/java/com/djrapitops/plan/utilities/html/graphs/line/ChunkGraph.java +++ b/Plan/src/main/java/com/djrapitops/plan/utilities/html/graphs/line/ChunkGraph.java @@ -1,10 +1,7 @@ package com.djrapitops.plan.utilities.html.graphs.line; -import com.djrapitops.plan.data.container.TPS; import com.djrapitops.plan.data.store.mutators.TPSMutator; -import java.util.List; - /** * Graph about Chunk Counts gathered by TPSCountTimer. * @@ -12,13 +9,9 @@ import java.util.List; * @see com.djrapitops.plan.system.tasks.TPSCountTimer * @since 4.2.0 */ -public class ChunkGraph extends AbstractLineGraph { +class ChunkGraph extends LineGraph { - public ChunkGraph(List tpsData) { - this(new TPSMutator(tpsData)); - } - - public ChunkGraph(TPSMutator mutator) { - super(mutator.chunkPoints()); + ChunkGraph(TPSMutator mutator, boolean displayGaps) { + super(mutator.chunkPoints(), displayGaps); } } diff --git a/Plan/src/main/java/com/djrapitops/plan/utilities/html/graphs/line/DiskGraph.java b/Plan/src/main/java/com/djrapitops/plan/utilities/html/graphs/line/DiskGraph.java new file mode 100644 index 000000000..52203d747 --- /dev/null +++ b/Plan/src/main/java/com/djrapitops/plan/utilities/html/graphs/line/DiskGraph.java @@ -0,0 +1,17 @@ +package com.djrapitops.plan.utilities.html.graphs.line; + +import com.djrapitops.plan.data.store.mutators.TPSMutator; + +/** + * Graph about Disk Usage gathered by TPSCountTimer. + * + * @author Rsl1122 + * @see com.djrapitops.plan.system.tasks.TPSCountTimer + * @since 4.5.0 + */ +class DiskGraph extends LineGraph { + + DiskGraph(TPSMutator mutator, boolean displayGaps) { + super(mutator.freeDiskPoints(), displayGaps); + } +} diff --git a/Plan/src/main/java/com/djrapitops/plan/utilities/html/graphs/line/EntityGraph.java b/Plan/src/main/java/com/djrapitops/plan/utilities/html/graphs/line/EntityGraph.java index 617612b96..ba00921fd 100644 --- a/Plan/src/main/java/com/djrapitops/plan/utilities/html/graphs/line/EntityGraph.java +++ b/Plan/src/main/java/com/djrapitops/plan/utilities/html/graphs/line/EntityGraph.java @@ -1,10 +1,7 @@ package com.djrapitops.plan.utilities.html.graphs.line; -import com.djrapitops.plan.data.container.TPS; import com.djrapitops.plan.data.store.mutators.TPSMutator; -import java.util.List; - /** * Graph about Entity Counts gathered by TPSCountTimer. * @@ -12,13 +9,9 @@ import java.util.List; * @see com.djrapitops.plan.system.tasks.TPSCountTimer * @since 4.2.0 */ -public class EntityGraph extends AbstractLineGraph { +class EntityGraph extends LineGraph { - public EntityGraph(List tpsData) { - this(new TPSMutator(tpsData)); - } - - public EntityGraph(TPSMutator mutator) { - super(mutator.entityPoints()); + EntityGraph(TPSMutator mutator, boolean displayGaps) { + super(mutator.entityPoints(), displayGaps); } } diff --git a/Plan/src/main/java/com/djrapitops/plan/utilities/html/graphs/line/LineGraph.java b/Plan/src/main/java/com/djrapitops/plan/utilities/html/graphs/line/LineGraph.java new file mode 100644 index 000000000..b84ad26f3 --- /dev/null +++ b/Plan/src/main/java/com/djrapitops/plan/utilities/html/graphs/line/LineGraph.java @@ -0,0 +1,62 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package com.djrapitops.plan.utilities.html.graphs.line; + +import com.djrapitops.plan.utilities.html.graphs.HighChart; + +import java.util.List; +import java.util.concurrent.TimeUnit; + +/** + * This is a LineGraph for any set of Points, thus it is Abstract. + * + * @author Rsl1122 + * @since 4.2.0 + */ +public class LineGraph implements HighChart { + + private final boolean displayGaps; + private List points; + + public LineGraph(List points, boolean displayGaps) { + this.points = points; + this.displayGaps = displayGaps; + } + + @Override + public String toHighChartsSeries() { + StringBuilder arrayBuilder = new StringBuilder("["); + + int size = points.size(); + Long lastX = null; + for (int i = 0; i < size; i++) { + Point point = points.get(i); + Double y = point.getY(); + long date = (long) point.getX(); + + if (displayGaps && lastX != null && date - lastX > TimeUnit.MINUTES.toMillis(3L)) { + addMissingPoints(arrayBuilder, lastX, date); + } + lastX = date; + + arrayBuilder.append("[").append(date).append(",").append(y).append("]"); + if (i < size - 1) { + arrayBuilder.append(","); + } + } + + arrayBuilder.append("]"); + return arrayBuilder.toString(); + } + + private void addMissingPoints(StringBuilder arrayBuilder, Long lastX, long date) { + long iterate = lastX + TimeUnit.MINUTES.toMillis(1L); + while (iterate < date) { + arrayBuilder.append("[").append(iterate).append(",null],"); + iterate += TimeUnit.MINUTES.toMillis(30L); + } + } +} diff --git a/Plan/src/main/java/com/djrapitops/plan/utilities/html/graphs/line/LineGraphFactory.java b/Plan/src/main/java/com/djrapitops/plan/utilities/html/graphs/line/LineGraphFactory.java new file mode 100644 index 000000000..69266bc25 --- /dev/null +++ b/Plan/src/main/java/com/djrapitops/plan/utilities/html/graphs/line/LineGraphFactory.java @@ -0,0 +1,64 @@ +package com.djrapitops.plan.utilities.html.graphs.line; + +import com.djrapitops.plan.data.container.Ping; +import com.djrapitops.plan.data.store.mutators.TPSMutator; +import com.djrapitops.plan.system.settings.Settings; +import com.djrapitops.plan.system.settings.config.PlanConfig; + +import javax.inject.Inject; +import javax.inject.Singleton; +import java.util.List; + +/** + * Factory class for different objects representing HTML line graphs. + * + * @author Rsl1122 + */ +@Singleton +public class LineGraphFactory { + + private final PlanConfig config; + + @Inject + public LineGraphFactory( + PlanConfig config + ) { + this.config = config; + } + + public LineGraph lineGraph(List points) { + return new LineGraph(points, config.isTrue(Settings.DISPLAY_GAPS_IN_GRAPH_DATA)); + } + + public LineGraph chunkGraph(TPSMutator mutator) { + return new ChunkGraph(mutator, config.isTrue(Settings.DISPLAY_GAPS_IN_GRAPH_DATA)); + } + + public LineGraph cpuGraph(TPSMutator mutator) { + return new CPUGraph(mutator, config.isTrue(Settings.DISPLAY_GAPS_IN_GRAPH_DATA)); + } + + public LineGraph entityGraph(TPSMutator mutator) { + return new EntityGraph(mutator, config.isTrue(Settings.DISPLAY_GAPS_IN_GRAPH_DATA)); + } + + public LineGraph playersOnlineGraph(TPSMutator mutator) { + return new PlayersOnlineGraph(mutator, config.isTrue(Settings.DISPLAY_GAPS_IN_GRAPH_DATA)); + } + + public PingGraph pingGraph(List pingList) { + return new PingGraph(pingList, config.isTrue(Settings.DISPLAY_GAPS_IN_GRAPH_DATA)); + } + + public LineGraph ramGraph(TPSMutator mutator) { + return new RamGraph(mutator, config.isTrue(Settings.DISPLAY_GAPS_IN_GRAPH_DATA)); + } + + public LineGraph tpsGraph(TPSMutator mutator) { + return new TPSGraph(mutator, config.isTrue(Settings.DISPLAY_GAPS_IN_GRAPH_DATA)); + } + + public LineGraph diskGraph(TPSMutator mutator) { + return new DiskGraph(mutator, config.isTrue(Settings.DISPLAY_GAPS_IN_GRAPH_DATA)); + } +} \ No newline at end of file diff --git a/Plan/src/main/java/com/djrapitops/plan/utilities/html/graphs/line/OnlineActivityGraph.java b/Plan/src/main/java/com/djrapitops/plan/utilities/html/graphs/line/OnlineActivityGraph.java deleted file mode 100644 index 89fccf3d5..000000000 --- a/Plan/src/main/java/com/djrapitops/plan/utilities/html/graphs/line/OnlineActivityGraph.java +++ /dev/null @@ -1,24 +0,0 @@ -package com.djrapitops.plan.utilities.html.graphs.line; - -import com.djrapitops.plan.data.container.TPS; -import com.djrapitops.plan.data.store.mutators.TPSMutator; - -import java.util.List; - -/** - * Graph about Player Counts gathered by TPSCountTimer. - * - * @author Rsl1122 - * @see com.djrapitops.plan.system.tasks.TPSCountTimer - * @since 4.2.0 - */ -public class OnlineActivityGraph extends AbstractLineGraph { - - public OnlineActivityGraph(List tpsData) { - this(new TPSMutator(tpsData)); - } - - public OnlineActivityGraph(TPSMutator mutator) { - super(mutator.playersOnlinePoints()); - } -} diff --git a/Plan/src/main/java/com/djrapitops/plan/utilities/html/graphs/line/PingGraph.java b/Plan/src/main/java/com/djrapitops/plan/utilities/html/graphs/line/PingGraph.java index 28ad850b2..0960aadfa 100644 --- a/Plan/src/main/java/com/djrapitops/plan/utilities/html/graphs/line/PingGraph.java +++ b/Plan/src/main/java/com/djrapitops/plan/utilities/html/graphs/line/PingGraph.java @@ -7,17 +7,18 @@ import java.util.List; public class PingGraph { - private final AbstractLineGraph maxGraph; - private final AbstractLineGraph minGraph; - private final AbstractLineGraph avgGraph; + private final LineGraph maxGraph; + private final LineGraph minGraph; + private final LineGraph avgGraph; /** * Constructor. * - * @param pings List of Ping values: - * List should be filtered so that only a single entry for each date exists. + * @param pings List of Ping values: + * List should be filtered so that only a single entry for each date exists. + * @param displayGaps Should data gaps be displayed. */ - public PingGraph(List pings) { + PingGraph(List pings, boolean displayGaps) { List max = new ArrayList<>(); List min = new ArrayList<>(); List avg = new ArrayList<>(); @@ -30,9 +31,9 @@ public class PingGraph { avg.add(new Point(date, ping.getAverage())); } - maxGraph = new AbstractLineGraph(max); - minGraph = new AbstractLineGraph(min); - avgGraph = new AbstractLineGraph(avg); + maxGraph = new LineGraph(max, displayGaps); + minGraph = new LineGraph(min, displayGaps); + avgGraph = new LineGraph(avg, displayGaps); } public String toMaxSeries() { diff --git a/Plan/src/main/java/com/djrapitops/plan/utilities/html/graphs/line/PlayersOnlineGraph.java b/Plan/src/main/java/com/djrapitops/plan/utilities/html/graphs/line/PlayersOnlineGraph.java new file mode 100644 index 000000000..7e9f5993c --- /dev/null +++ b/Plan/src/main/java/com/djrapitops/plan/utilities/html/graphs/line/PlayersOnlineGraph.java @@ -0,0 +1,17 @@ +package com.djrapitops.plan.utilities.html.graphs.line; + +import com.djrapitops.plan.data.store.mutators.TPSMutator; + +/** + * Graph about Player Counts gathered by TPSCountTimer. + * + * @author Rsl1122 + * @see com.djrapitops.plan.system.tasks.TPSCountTimer + * @since 4.2.0 + */ +class PlayersOnlineGraph extends LineGraph { + + PlayersOnlineGraph(TPSMutator mutator, boolean displayGaps) { + super(mutator.playersOnlinePoints(), displayGaps); + } +} diff --git a/Plan/src/main/java/com/djrapitops/plan/utilities/html/graphs/line/RamGraph.java b/Plan/src/main/java/com/djrapitops/plan/utilities/html/graphs/line/RamGraph.java index 40b1460d9..833523878 100644 --- a/Plan/src/main/java/com/djrapitops/plan/utilities/html/graphs/line/RamGraph.java +++ b/Plan/src/main/java/com/djrapitops/plan/utilities/html/graphs/line/RamGraph.java @@ -1,10 +1,7 @@ package com.djrapitops.plan.utilities.html.graphs.line; -import com.djrapitops.plan.data.container.TPS; import com.djrapitops.plan.data.store.mutators.TPSMutator; -import java.util.List; - /** * Graph about RAM Usage gathered by TPSCountTimer. * @@ -12,13 +9,9 @@ import java.util.List; * @see com.djrapitops.plan.system.tasks.TPSCountTimer * @since 4.2.0 */ -public class RamGraph extends AbstractLineGraph { +class RamGraph extends LineGraph { - public RamGraph(List tpsData) { - this(new TPSMutator(tpsData)); - } - - public RamGraph(TPSMutator mutator) { - super(mutator.ramUsagePoints()); + RamGraph(TPSMutator mutator, boolean displayGaps) { + super(mutator.ramUsagePoints(), displayGaps); } } diff --git a/Plan/src/main/java/com/djrapitops/plan/utilities/html/graphs/line/TPSGraph.java b/Plan/src/main/java/com/djrapitops/plan/utilities/html/graphs/line/TPSGraph.java index 63d8270dc..5cab30e58 100644 --- a/Plan/src/main/java/com/djrapitops/plan/utilities/html/graphs/line/TPSGraph.java +++ b/Plan/src/main/java/com/djrapitops/plan/utilities/html/graphs/line/TPSGraph.java @@ -1,10 +1,7 @@ package com.djrapitops.plan.utilities.html.graphs.line; -import com.djrapitops.plan.data.container.TPS; import com.djrapitops.plan.data.store.mutators.TPSMutator; -import java.util.List; - /** * Graph about TPS gathered by TPSCountTimer. * @@ -12,13 +9,9 @@ import java.util.List; * @see com.djrapitops.plan.system.tasks.TPSCountTimer * @since 4.2.0 */ -public class TPSGraph extends AbstractLineGraph { +class TPSGraph extends LineGraph { - public TPSGraph(List tpsData) { - this(new TPSMutator(tpsData)); - } - - public TPSGraph(TPSMutator mutator) { - super(mutator.tpsPoints()); + TPSGraph(TPSMutator mutator, boolean displayGaps) { + super(mutator.tpsPoints(), displayGaps); } } diff --git a/Plan/src/main/java/com/djrapitops/plan/utilities/html/graphs/line/alg/ReduceGapTriangles.java b/Plan/src/main/java/com/djrapitops/plan/utilities/html/graphs/line/alg/ReduceGapTriangles.java index 1d0d39700..63714018c 100644 --- a/Plan/src/main/java/com/djrapitops/plan/utilities/html/graphs/line/alg/ReduceGapTriangles.java +++ b/Plan/src/main/java/com/djrapitops/plan/utilities/html/graphs/line/alg/ReduceGapTriangles.java @@ -2,12 +2,12 @@ package com.djrapitops.plan.utilities.html.graphs.line.alg; import com.djrapitops.plan.utilities.comparators.PointComparator; import com.djrapitops.plan.utilities.html.graphs.line.Point; -import com.djrapitops.plugin.api.TimeAmount; import com.djrapitops.plugin.utilities.Verify; import java.util.HashSet; import java.util.List; import java.util.Set; +import java.util.concurrent.TimeUnit; /** * Utility for reducing Points in LineGraphs. @@ -42,7 +42,7 @@ public class ReduceGapTriangles { if (Double.compare(y, lastY) != 0 && Math.abs(lastY - y) > 0.5 - && lastDate < date - TimeAmount.MINUTE.ms() * 10L) { + && lastDate < date - TimeUnit.MINUTES.toMillis(10L)) { toAdd.add(new Point(lastDate + 1, lastY)); toAdd.add(new Point(date - 1, lastY)); } diff --git a/Plan/src/main/java/com/djrapitops/plan/utilities/html/graphs/pie/ActivityPie.java b/Plan/src/main/java/com/djrapitops/plan/utilities/html/graphs/pie/ActivityPie.java index eb7ecf95a..91619d4aa 100644 --- a/Plan/src/main/java/com/djrapitops/plan/utilities/html/graphs/pie/ActivityPie.java +++ b/Plan/src/main/java/com/djrapitops/plan/utilities/html/graphs/pie/ActivityPie.java @@ -5,8 +5,6 @@ package com.djrapitops.plan.utilities.html.graphs.pie; import com.djrapitops.plan.data.store.mutators.ActivityIndex; -import com.djrapitops.plan.system.settings.theme.Theme; -import com.djrapitops.plan.system.settings.theme.ThemeVal; import java.util.*; @@ -17,14 +15,13 @@ import java.util.*; * @see ActivityIndex * @since 4.2.0 */ -public class ActivityPie extends AbstractPieChart { +public class ActivityPie extends Pie { - public ActivityPie(Map> activityData) { - super(turnToSlices(activityData)); + ActivityPie(Map> activityData, String[] colors) { + super(turnToSlices(activityData, colors)); } - private static List turnToSlices(Map> activityData) { - String[] colors = Theme.getValue(ThemeVal.GRAPH_ACTIVITY_PIE).split(", "); + private static List turnToSlices(Map> activityData, String[] colors) { int maxCol = colors.length; List slices = new ArrayList<>(); diff --git a/Plan/src/main/java/com/djrapitops/plan/utilities/html/graphs/pie/AbstractPieChart.java b/Plan/src/main/java/com/djrapitops/plan/utilities/html/graphs/pie/Pie.java similarity index 62% rename from Plan/src/main/java/com/djrapitops/plan/utilities/html/graphs/pie/AbstractPieChart.java rename to Plan/src/main/java/com/djrapitops/plan/utilities/html/graphs/pie/Pie.java index 101c8234d..e60c35a20 100644 --- a/Plan/src/main/java/com/djrapitops/plan/utilities/html/graphs/pie/AbstractPieChart.java +++ b/Plan/src/main/java/com/djrapitops/plan/utilities/html/graphs/pie/Pie.java @@ -7,7 +7,6 @@ package com.djrapitops.plan.utilities.html.graphs.pie; import com.djrapitops.plan.utilities.html.graphs.HighChart; import org.apache.commons.text.TextStringBuilder; -import java.util.ArrayList; import java.util.List; /** @@ -16,15 +15,11 @@ import java.util.List; * @author Rsl1122 * @since 4.2.0 */ -public class AbstractPieChart implements HighChart { +public class Pie implements HighChart { - protected List slices; + protected final List slices; - public AbstractPieChart() { - slices = new ArrayList<>(); - } - - public AbstractPieChart(List slices) { + public Pie(List slices) { this.slices = slices; } @@ -34,12 +29,4 @@ public class AbstractPieChart implements HighChart { series.appendWithSeparators(slices, ","); return series.append("]").toString(); } - - public void setSlices(List slices) { - this.slices = slices; - } - - public void addSlices(List slices) { - this.slices.addAll(slices); - } } diff --git a/Plan/src/main/java/com/djrapitops/plan/utilities/html/graphs/pie/PieGraphFactory.java b/Plan/src/main/java/com/djrapitops/plan/utilities/html/graphs/pie/PieGraphFactory.java new file mode 100644 index 000000000..1875470f5 --- /dev/null +++ b/Plan/src/main/java/com/djrapitops/plan/utilities/html/graphs/pie/PieGraphFactory.java @@ -0,0 +1,54 @@ +package com.djrapitops.plan.utilities.html.graphs.pie; + +import com.djrapitops.plan.data.time.GMTimes; +import com.djrapitops.plan.data.time.WorldTimes; +import com.djrapitops.plan.system.settings.Settings; +import com.djrapitops.plan.system.settings.WorldAliasSettings; +import com.djrapitops.plan.system.settings.config.PlanConfig; +import com.djrapitops.plan.system.settings.theme.Theme; +import com.djrapitops.plan.system.settings.theme.ThemeVal; + +import javax.inject.Inject; +import javax.inject.Singleton; +import java.util.Map; +import java.util.Set; +import java.util.UUID; + +/** + * Factory class for different objects representing HTML pie graphs. + * + * @author Rsl1122 + */ +@Singleton +public class PieGraphFactory { + + private final PlanConfig config; + private final Theme theme; + + @Inject + public PieGraphFactory( + PlanConfig config, + Theme theme + ) { + this.config = config; + this.theme = theme; + } + + public Pie activityPie(Map> activityData) { + String[] colors = theme.getValue(ThemeVal.GRAPH_ACTIVITY_PIE).split(", "); + return new ActivityPie(activityData, colors); + } + + public Pie serverPreferencePie(Map serverNames, Map serverWorldTimes) { + return new ServerPreferencePie(serverNames, serverWorldTimes); + } + + public WorldPie worldPie(WorldTimes worldTimes) { + WorldAliasSettings worldAliasSettings = config.getWorldAliasSettings(); + Map playtimePerAlias = worldAliasSettings.getPlaytimePerAlias(worldTimes); + Map gmTimesPerAlias = worldAliasSettings.getGMTimesPerAlias(worldTimes); + String[] colors = theme.getValue(ThemeVal.GRAPH_WORLD_PIE).split(", "); + boolean orderByPercentage = config.isTrue(Settings.ORDER_WORLD_PIE_BY_PERC); + return new WorldPie(playtimePerAlias, gmTimesPerAlias, colors, orderByPercentage); + } +} \ No newline at end of file diff --git a/Plan/src/main/java/com/djrapitops/plan/utilities/html/graphs/pie/AbstractPieChartWithDrilldown.java b/Plan/src/main/java/com/djrapitops/plan/utilities/html/graphs/pie/PieWithDrilldown.java similarity index 67% rename from Plan/src/main/java/com/djrapitops/plan/utilities/html/graphs/pie/AbstractPieChartWithDrilldown.java rename to Plan/src/main/java/com/djrapitops/plan/utilities/html/graphs/pie/PieWithDrilldown.java index 8c5721d74..a6087f802 100644 --- a/Plan/src/main/java/com/djrapitops/plan/utilities/html/graphs/pie/AbstractPieChartWithDrilldown.java +++ b/Plan/src/main/java/com/djrapitops/plan/utilities/html/graphs/pie/PieWithDrilldown.java @@ -11,12 +11,9 @@ import java.util.List; * * @author Rsl1122 */ -public abstract class AbstractPieChartWithDrilldown extends AbstractPieChart { +public abstract class PieWithDrilldown extends Pie { - public AbstractPieChartWithDrilldown() { - } - - public AbstractPieChartWithDrilldown(List slices) { + public PieWithDrilldown(List slices) { super(slices); } diff --git a/Plan/src/main/java/com/djrapitops/plan/utilities/html/graphs/pie/ServerPreferencePie.java b/Plan/src/main/java/com/djrapitops/plan/utilities/html/graphs/pie/ServerPreferencePie.java index 81791d328..bc9c897ae 100644 --- a/Plan/src/main/java/com/djrapitops/plan/utilities/html/graphs/pie/ServerPreferencePie.java +++ b/Plan/src/main/java/com/djrapitops/plan/utilities/html/graphs/pie/ServerPreferencePie.java @@ -7,9 +7,9 @@ import java.util.List; import java.util.Map; import java.util.UUID; -public class ServerPreferencePie extends AbstractPieChart { +public class ServerPreferencePie extends Pie { - public ServerPreferencePie(Map serverNames, Map serverWorldTimes) { + ServerPreferencePie(Map serverNames, Map serverWorldTimes) { super(turnToSlices(serverNames, serverWorldTimes)); } diff --git a/Plan/src/main/java/com/djrapitops/plan/utilities/html/graphs/pie/WorldPie.java b/Plan/src/main/java/com/djrapitops/plan/utilities/html/graphs/pie/WorldPie.java index 4ca3e0747..87e5b51c5 100644 --- a/Plan/src/main/java/com/djrapitops/plan/utilities/html/graphs/pie/WorldPie.java +++ b/Plan/src/main/java/com/djrapitops/plan/utilities/html/graphs/pie/WorldPie.java @@ -1,35 +1,35 @@ package com.djrapitops.plan.utilities.html.graphs.pie; import com.djrapitops.plan.data.time.GMTimes; -import com.djrapitops.plan.data.time.WorldTimes; -import com.djrapitops.plan.system.settings.Settings; -import com.djrapitops.plan.system.settings.WorldAliasSettings; -import com.djrapitops.plan.system.settings.theme.Theme; -import com.djrapitops.plan.system.settings.theme.ThemeVal; import com.djrapitops.plan.utilities.comparators.PieSliceComparator; -import java.util.*; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Map; -public class WorldPie extends AbstractPieChartWithDrilldown { +public class WorldPie extends PieWithDrilldown { - private WorldTimes worldTimes; + private final Map gmTimesAliasMap; - public WorldPie(WorldTimes worldTimes) { - super(turnIntoSlices(worldTimes)); + WorldPie( + Map playtimePerAlias, + Map gmTimesAliasMap, + String[] colors, + boolean orderByPercentage + ) { + super(turnIntoSlices(playtimePerAlias, colors)); - this.worldTimes = worldTimes; + this.gmTimesAliasMap = gmTimesAliasMap; - if (Settings.ORDER_WORLD_PIE_BY_PERC.isTrue()) { + if (orderByPercentage) { slices.sort(new PieSliceComparator()); } } - private static List turnIntoSlices(WorldTimes worldTimes) { - String[] colors = Theme.getValue(ThemeVal.GRAPH_WORLD_PIE).split(", "); + private static List turnIntoSlices(Map playtimePerAlias, String[] colors) { int colLength = colors.length; - Map playtimePerAlias = worldTimes.getPlaytimePerAlias(); - List worlds = new ArrayList<>(playtimePerAlias.keySet()); Collections.sort(worlds); @@ -46,44 +46,16 @@ public class WorldPie extends AbstractPieChartWithDrilldown { return slices; } - private Map getGMTimesPerAlias() { - Map aliases = WorldAliasSettings.getAliases(); - - Map gmTimesPerAlias = new HashMap<>(); - - String[] gms = GMTimes.getGMKeyArray(); - - for (Map.Entry entry : worldTimes.getWorldTimes().entrySet()) { - String worldName = entry.getKey(); - GMTimes gmTimes = entry.getValue(); - - if (!aliases.containsKey(worldName)) { - aliases.put(worldName, worldName); - WorldAliasSettings.addWorld(worldName); - } - - String alias = aliases.get(worldName); - - GMTimes aliasGMTimes = gmTimesPerAlias.getOrDefault(alias, new GMTimes()); - for (String gm : gms) { - aliasGMTimes.addTime(gm, gmTimes.getTime(gm)); - } - gmTimesPerAlias.put(alias, aliasGMTimes); - } - return gmTimesPerAlias; - } - @Override public String toHighChartsDrilldown() { StringBuilder drilldownBuilder = new StringBuilder(); int i = 0; - Map gmTimesAliasMap = getGMTimesPerAlias(); if (gmTimesAliasMap.isEmpty()) { return "[]"; } int size = gmTimesAliasMap.size(); - + drilldownBuilder.append("["); for (Map.Entry worldAlias : gmTimesAliasMap.entrySet()) { drilldownBuilder.append("{name:'").append(worldAlias.getKey()) diff --git a/Plan/src/main/java/com/djrapitops/plan/utilities/html/graphs/PunchCardGraph.java b/Plan/src/main/java/com/djrapitops/plan/utilities/html/graphs/special/PunchCard.java similarity index 87% rename from Plan/src/main/java/com/djrapitops/plan/utilities/html/graphs/PunchCardGraph.java rename to Plan/src/main/java/com/djrapitops/plan/utilities/html/graphs/special/PunchCard.java index 53b561719..76cf4e599 100644 --- a/Plan/src/main/java/com/djrapitops/plan/utilities/html/graphs/PunchCardGraph.java +++ b/Plan/src/main/java/com/djrapitops/plan/utilities/html/graphs/special/PunchCard.java @@ -3,10 +3,11 @@ * To change this template file, choose Tools | Templates * and open the template in the editor. */ -package com.djrapitops.plan.utilities.html.graphs; +package com.djrapitops.plan.utilities.html.graphs.special; import com.djrapitops.plan.data.container.Session; import com.djrapitops.plan.data.store.keys.SessionKeys; +import com.djrapitops.plan.utilities.html.graphs.HighChart; import java.util.Calendar; import java.util.Collection; @@ -20,16 +21,16 @@ import java.util.stream.Collectors; * @author Rsl1122 * @since 4.2.0 */ -public class PunchCardGraph implements HighChart { +public class PunchCard implements HighChart { private final Collection sessions; /** - * Constuctor for the graph. + * Constructor for the graph. * * @param sessions All sessions of All users this PunchCard represents. */ - public PunchCardGraph(Collection sessions) { + PunchCard(Collection sessions) { this.sessions = sessions; } @@ -37,7 +38,7 @@ public class PunchCardGraph implements HighChart { * First number signifies the Day of Week. (0 = Monday, 6 = Sunday) * Second number signifies the Hour of Day. (0 = 0 AM, 23 = 11 PM) */ - private static List getDaysAndHours(Collection sessionStarts) { + private List getDaysAndHours(Collection sessionStarts) { return sessionStarts.stream().map((Long start) -> { Calendar day = Calendar.getInstance(); day.setTimeInMillis(start); @@ -57,7 +58,7 @@ public class PunchCardGraph implements HighChart { }).collect(Collectors.toList()); } - private static int[][] turnIntoArray(Collection sessionStarts) { + private int[][] turnIntoArray(Collection sessionStarts) { List daysAndHours = getDaysAndHours(sessionStarts); int[][] dataArray = createEmptyArray(); for (int[] dAndH : daysAndHours) { @@ -96,7 +97,7 @@ public class PunchCardGraph implements HighChart { return arrayBuilder.toString(); } - private static List getSessionStarts(Collection data) { + private List getSessionStarts(Collection data) { return data.stream() .filter(Objects::nonNull) .map(s -> s.getUnsafe(SessionKeys.START)) @@ -104,7 +105,7 @@ public class PunchCardGraph implements HighChart { .collect(Collectors.toList()); } - private static int[][] createEmptyArray() { + private int[][] createEmptyArray() { int[][] dataArray = new int[7][24]; for (int i = 0; i < 7; i++) { for (int j = 0; j < 24; j++) { @@ -114,7 +115,7 @@ public class PunchCardGraph implements HighChart { return dataArray; } - private static int findBiggestValue(int[][] dataArray) { + private int findBiggestValue(int[][] dataArray) { int highest = 1; for (int i = 0; i < 7; i++) { for (int j = 0; j < 24; j++) { @@ -127,8 +128,7 @@ public class PunchCardGraph implements HighChart { return highest; } - private static int[][] scale(int[][] dataArray, int big) { - + private int[][] scale(int[][] dataArray, int big) { int[][] scaled = new int[7][24]; for (int i = 0; i < 7; i++) { for (int j = 0; j < 24; j++) { diff --git a/Plan/src/main/java/com/djrapitops/plan/utilities/html/graphs/special/SpecialGraphFactory.java b/Plan/src/main/java/com/djrapitops/plan/utilities/html/graphs/special/SpecialGraphFactory.java new file mode 100644 index 000000000..921651c92 --- /dev/null +++ b/Plan/src/main/java/com/djrapitops/plan/utilities/html/graphs/special/SpecialGraphFactory.java @@ -0,0 +1,31 @@ +package com.djrapitops.plan.utilities.html.graphs.special; + +import com.djrapitops.plan.data.container.Session; +import com.djrapitops.plan.data.store.mutators.PlayersMutator; +import com.djrapitops.plan.utilities.html.graphs.HighChart; + +import javax.inject.Inject; +import javax.inject.Singleton; +import java.util.Collection; + +/** + * Factory class for different objects representing special HTML graphs. + * + * @author Rsl1122 + */ +@Singleton +public class SpecialGraphFactory { + + @Inject + public SpecialGraphFactory() { + // Inject Constructor. + } + + public HighChart punchCard(Collection sessions) { + return new PunchCard(sessions); + } + + public HighChart worldMap(PlayersMutator mutator) { + return new WorldMap(mutator); + } +} \ No newline at end of file diff --git a/Plan/src/main/java/com/djrapitops/plan/utilities/html/graphs/WorldMap.java b/Plan/src/main/java/com/djrapitops/plan/utilities/html/graphs/special/WorldMap.java similarity index 96% rename from Plan/src/main/java/com/djrapitops/plan/utilities/html/graphs/WorldMap.java rename to Plan/src/main/java/com/djrapitops/plan/utilities/html/graphs/special/WorldMap.java index 0fb9d6c4e..c58dedede 100644 --- a/Plan/src/main/java/com/djrapitops/plan/utilities/html/graphs/WorldMap.java +++ b/Plan/src/main/java/com/djrapitops/plan/utilities/html/graphs/special/WorldMap.java @@ -1,6 +1,7 @@ -package com.djrapitops.plan.utilities.html.graphs; +package com.djrapitops.plan.utilities.html.graphs.special; import com.djrapitops.plan.data.store.mutators.PlayersMutator; +import com.djrapitops.plan.utilities.html.graphs.HighChart; import org.apache.commons.text.TextStringBuilder; import java.util.HashMap; @@ -17,12 +18,8 @@ public class WorldMap implements HighChart { private final List geoLocations; - public WorldMap(List geoLocations) { - this.geoLocations = geoLocations; - } - - public WorldMap(PlayersMutator mutator) { - this(mutator.getGeolocations()); + WorldMap(PlayersMutator mutator) { + this.geoLocations = mutator.getGeolocations(); } private static Map getGeoCodes(Map geoCodeCounts) { diff --git a/Plan/src/main/java/com/djrapitops/plan/utilities/html/graphs/ActivityStackGraph.java b/Plan/src/main/java/com/djrapitops/plan/utilities/html/graphs/stack/ActivityStackGraph.java similarity index 55% rename from Plan/src/main/java/com/djrapitops/plan/utilities/html/graphs/ActivityStackGraph.java rename to Plan/src/main/java/com/djrapitops/plan/utilities/html/graphs/stack/ActivityStackGraph.java index eb37a7f3a..c03a5a54a 100644 --- a/Plan/src/main/java/com/djrapitops/plan/utilities/html/graphs/ActivityStackGraph.java +++ b/Plan/src/main/java/com/djrapitops/plan/utilities/html/graphs/stack/ActivityStackGraph.java @@ -2,15 +2,10 @@ * License is provided in the jar as LICENSE also here: * https://github.com/Rsl1122/Plan-PlayerAnalytics/blob/master/Plan/src/main/resources/LICENSE */ -package com.djrapitops.plan.utilities.html.graphs; +package com.djrapitops.plan.utilities.html.graphs.stack; import com.djrapitops.plan.data.store.mutators.ActivityIndex; -import com.djrapitops.plan.data.store.mutators.PlayersMutator; -import com.djrapitops.plan.system.settings.theme.Theme; -import com.djrapitops.plan.system.settings.theme.ThemeVal; -import com.djrapitops.plan.utilities.FormatUtils; -import com.djrapitops.plan.utilities.html.graphs.stack.AbstractStackGraph; -import com.djrapitops.plan.utilities.html.graphs.stack.StackDataSet; +import com.djrapitops.plan.utilities.formatting.Formatter; import java.util.*; @@ -21,25 +16,20 @@ import java.util.*; * @see ActivityIndex * @since 4.2.0 */ -public class ActivityStackGraph extends AbstractStackGraph { +class ActivityStackGraph extends StackGraph { - public ActivityStackGraph(TreeMap>> activityData) { - super(getLabels(activityData.navigableKeySet()), getDataSets(activityData)); + ActivityStackGraph(TreeMap>> activityData, String[] colors, Formatter dayFormatter) { + super(getLabels(activityData.navigableKeySet(), dayFormatter), getDataSets(activityData, colors)); } - public ActivityStackGraph(long date, PlayersMutator mutator) { - this(mutator.toActivityDataMap(date)); - } - - private static String[] getLabels(NavigableSet dates) { + private static String[] getLabels(Collection dates, Formatter dayFormatter) { return dates.stream() - .map(FormatUtils::formatTimeStampDay) + .map(dayFormatter) .toArray(String[]::new); } - private static StackDataSet[] getDataSets(TreeMap>> activityData) { + private static StackDataSet[] getDataSets(TreeMap>> activityData, String[] colors) { String[] groups = ActivityIndex.getGroups(); - String[] colors = Theme.getValue(ThemeVal.GRAPH_ACTIVITY_PIE).split(", "); int maxCol = colors.length; StackDataSet[] dataSets = new StackDataSet[groups.length]; diff --git a/Plan/src/main/java/com/djrapitops/plan/utilities/html/graphs/stack/AbstractStackGraph.java b/Plan/src/main/java/com/djrapitops/plan/utilities/html/graphs/stack/StackGraph.java similarity index 93% rename from Plan/src/main/java/com/djrapitops/plan/utilities/html/graphs/stack/AbstractStackGraph.java rename to Plan/src/main/java/com/djrapitops/plan/utilities/html/graphs/stack/StackGraph.java index ef42b0c8c..bd5f319a6 100644 --- a/Plan/src/main/java/com/djrapitops/plan/utilities/html/graphs/stack/AbstractStackGraph.java +++ b/Plan/src/main/java/com/djrapitops/plan/utilities/html/graphs/stack/StackGraph.java @@ -11,12 +11,12 @@ import com.djrapitops.plan.utilities.html.graphs.HighChart; * * @author Rsl1122 */ -public class AbstractStackGraph implements HighChart { +public class StackGraph implements HighChart { private final StackDataSet[] dataSets; private final String[] labels; - public AbstractStackGraph(String[] labels, StackDataSet... dataSets) { + public StackGraph(String[] labels, StackDataSet... dataSets) { this.dataSets = dataSets; this.labels = labels; } diff --git a/Plan/src/main/java/com/djrapitops/plan/utilities/html/graphs/stack/StackGraphFactory.java b/Plan/src/main/java/com/djrapitops/plan/utilities/html/graphs/stack/StackGraphFactory.java new file mode 100644 index 000000000..9f62dee85 --- /dev/null +++ b/Plan/src/main/java/com/djrapitops/plan/utilities/html/graphs/stack/StackGraphFactory.java @@ -0,0 +1,39 @@ +package com.djrapitops.plan.utilities.html.graphs.stack; + +import com.djrapitops.plan.system.settings.theme.Theme; +import com.djrapitops.plan.system.settings.theme.ThemeVal; +import com.djrapitops.plan.utilities.formatting.Formatter; +import com.djrapitops.plan.utilities.formatting.Formatters; + +import javax.inject.Inject; +import javax.inject.Singleton; +import java.util.Map; +import java.util.Set; +import java.util.TreeMap; +import java.util.UUID; + +/** + * Factory class for different objects representing HTML stack graphs. + * + * @author Rsl1122 + */ +@Singleton +public class StackGraphFactory { + + private final Theme theme; + private final Formatter dayFormatter; + + @Inject + public StackGraphFactory( + Formatters formatters, + Theme theme + ) { + this.theme = theme; + this.dayFormatter = formatters.dayLong(); + } + + public StackGraph activityStackGraph(TreeMap>> activityData) { + String[] colors = theme.getValue(ThemeVal.GRAPH_ACTIVITY_PIE).split(", "); + return new ActivityStackGraph(activityData, colors, dayFormatter); + } +} \ No newline at end of file diff --git a/Plan/src/main/java/com/djrapitops/plan/utilities/html/pages/AnalysisPage.java b/Plan/src/main/java/com/djrapitops/plan/utilities/html/pages/AnalysisPage.java index 071c60eb1..24fa9a9cb 100644 --- a/Plan/src/main/java/com/djrapitops/plan/utilities/html/pages/AnalysisPage.java +++ b/Plan/src/main/java/com/djrapitops/plan/utilities/html/pages/AnalysisPage.java @@ -6,12 +6,12 @@ package com.djrapitops.plan.utilities.html.pages; import com.djrapitops.plan.api.exceptions.ParseException; import com.djrapitops.plan.data.store.containers.AnalysisContainer; -import com.djrapitops.plan.data.store.mutators.formatting.PlaceholderReplacer; -import com.djrapitops.plan.system.webserver.response.errors.ErrorResponse; -import com.djrapitops.plan.utilities.FormatUtils; -import com.djrapitops.plan.utilities.file.FileUtil; -import com.djrapitops.plugin.api.Benchmark; -import com.djrapitops.plugin.api.utility.log.Log; +import com.djrapitops.plan.system.DebugChannels; +import com.djrapitops.plan.system.file.PlanFiles; +import com.djrapitops.plan.system.update.VersionCheckSystem; +import com.djrapitops.plan.utilities.formatting.Formatter; +import com.djrapitops.plan.utilities.formatting.PlaceholderReplacer; +import com.djrapitops.plugin.benchmarking.Timings; import java.io.IOException; @@ -24,28 +24,37 @@ import static com.djrapitops.plan.data.store.keys.AnalysisKeys.*; */ public class AnalysisPage implements Page { + private static final String CHANNEL = DebugChannels.ANALYSIS; + private final AnalysisContainer analysisContainer; - private static final String DEBUG = "Analysis"; - public AnalysisPage(AnalysisContainer analysisContainer) { + private final VersionCheckSystem versionCheckSystem; + private final PlanFiles files; + private final Formatter decimalFormatter; + private final Timings timings; + + AnalysisPage( + AnalysisContainer analysisContainer, + VersionCheckSystem versionCheckSystem, + PlanFiles files, + Formatter decimalFormatter, + Timings timings + ) { this.analysisContainer = analysisContainer; - } - - public static String getRefreshingHtml() { - ErrorResponse refreshPage = new ErrorResponse(); - refreshPage.setTitle("Analysis is being refreshed.."); - refreshPage.setParagraph(" Analysis is being run, refresh the page after a few seconds.. (F5)"); - refreshPage.replacePlaceholders(); - return refreshPage.getContent(); + this.versionCheckSystem = versionCheckSystem; + this.files = files; + this.decimalFormatter = decimalFormatter; + this.timings = timings; } @Override public String toHtml() throws ParseException { - Benchmark.start(DEBUG); + timings.start("Analysis"); PlaceholderReplacer placeholderReplacer = new PlaceholderReplacer(); placeholderReplacer.addAllPlaceholdersFrom(analysisContainer, VERSION, SERVER_NAME, TIME_ZONE, FIRST_DAY, TPS_MEDIUM, TPS_HIGH, + DISK_MEDIUM, DISK_HIGH, PLAYERS_MAX, PLAYERS_ONLINE, PLAYERS_TOTAL, WORLD_PIE_COLORS, GM_PIE_COLORS, ACTIVITY_PIE_COLORS, @@ -53,6 +62,7 @@ public class AnalysisPage implements Page { TPS_LOW_COLOR, WORLD_MAP_HIGH_COLOR, WORLD_MAP_LOW_COLOR, AVG_PING_COLOR, MAX_PING_COLOR, MIN_PING_COLOR ); + placeholderReplacer.put("update", versionCheckSystem.getUpdateHtml().orElse("")); playersTable(placeholderReplacer); sessionStructures(placeholderReplacer); serverHealth(placeholderReplacer); @@ -63,51 +73,50 @@ public class AnalysisPage implements Page { performanceNumbers(placeholderReplacer); try { - return placeholderReplacer.apply(FileUtil.getStringFromResource("web/server.html")); + return placeholderReplacer.apply(files.readCustomizableResourceFlat("web/server.html")); } catch (IOException e) { throw new ParseException(e); } finally { - Benchmark.stop(DEBUG, DEBUG); - Log.logDebug(DEBUG); + timings.end(CHANNEL, "Analysis"); } } private void serverHealth(PlaceholderReplacer placeholderReplacer) { - Benchmark.start(DEBUG + " Server Health"); + timings.start(CHANNEL + " Server Health"); placeholderReplacer.addAllPlaceholdersFrom(analysisContainer, HEALTH_NOTES ); - Benchmark.stop(DEBUG, DEBUG + " Server Health"); + timings.end(CHANNEL, CHANNEL + " Server Health"); } private void sessionStructures(PlaceholderReplacer placeholderReplacer) { - Benchmark.start(DEBUG + " Session Structures"); + timings.start(CHANNEL + " Session Structures"); placeholderReplacer.addAllPlaceholdersFrom(analysisContainer, SESSION_ACCORDION_HTML, SESSION_ACCORDION_FUNCTIONS, SESSION_TABLE, RECENT_LOGINS, COMMAND_USAGE_TABLE, PING_TABLE); - Benchmark.stop(DEBUG, DEBUG + " Session Structures"); + timings.end(CHANNEL, CHANNEL + " Session Structures"); } private void playersTable(PlaceholderReplacer placeholderReplacer) { - Benchmark.start(DEBUG + " Players Table"); + timings.start(CHANNEL + " Players Table"); placeholderReplacer.addAllPlaceholdersFrom(analysisContainer, PLAYERS_TABLE); - Benchmark.stop(DEBUG, DEBUG + " Players Table"); + timings.end(CHANNEL, CHANNEL + " Players Table"); } private void pluginsTabs(PlaceholderReplacer placeholderReplacer) { - Benchmark.start(DEBUG + " 3rd Party"); + timings.start(CHANNEL + " 3rd Party"); placeholderReplacer.addAllPlaceholdersFrom(analysisContainer, PLUGINS_TAB, PLUGINS_TAB_NAV ); - Benchmark.stop(DEBUG, DEBUG + " 3rd Party"); + timings.end(CHANNEL, CHANNEL + " 3rd Party"); } private void miscTotals(PlaceholderReplacer placeholderReplacer) { - Benchmark.start(DEBUG + " Misc. totals"); + timings.start(CHANNEL + " Misc. totals"); placeholderReplacer.addAllPlaceholdersFrom(analysisContainer, - REFRESH_TIME_F, LAST_PEAK_TIME_F, ALL_TIME_PEAK_TIME_F, + REFRESH_TIME_F, REFRESH_TIME_FULL_F, LAST_PEAK_TIME_F, ALL_TIME_PEAK_TIME_F, AVERAGE_SESSION_LENGTH_F, AVERAGE_PLAYTIME_F, PLAYTIME_F, PLAYERS_LAST_PEAK, PLAYERS_ALL_TIME_PEAK, OPERATORS, @@ -115,11 +124,11 @@ public class AnalysisPage implements Page { MOB_KILL_COUNT, PLAYER_KILL_COUNT, HEALTH_INDEX, COMMAND_COUNT, COMMAND_COUNT_UNIQUE ); - Benchmark.stop(DEBUG, DEBUG + " Misc. totals"); + timings.end(CHANNEL, CHANNEL + " Misc. totals"); } private void playerActivityNumbers(PlaceholderReplacer placeholderReplacer) { - Benchmark.start(DEBUG + " Online Activity Numbers"); + timings.start(CHANNEL + " Online Activity Numbers"); placeholderReplacer.addAllPlaceholdersFrom(analysisContainer, PLAYERS_DAY, PLAYERS_WEEK, PLAYERS_MONTH, PLAYERS_NEW_DAY, PLAYERS_NEW_WEEK, PLAYERS_NEW_MONTH, @@ -129,29 +138,29 @@ public class AnalysisPage implements Page { PLAYERS_RETAINED_DAY_PERC, PLAYERS_RETAINED_WEEK, PLAYERS_RETAINED_WEEK_PERC, PLAYERS_RETAINED_MONTH, PLAYERS_RETAINED_MONTH_PERC ); - Benchmark.stop(DEBUG, DEBUG + " Online Activity Numbers"); + timings.end(CHANNEL, CHANNEL + " Online Activity Numbers"); } private void performanceNumbers(PlaceholderReplacer placeholderReplacer) { - Benchmark.start(DEBUG + " Performance Numbers"); + timings.start(CHANNEL + " Performance Numbers"); placeholderReplacer.addAllPlaceholdersFrom(analysisContainer, TPS_SPIKE_MONTH, TPS_SPIKE_WEEK, TPS_SPIKE_DAY ); - placeholderReplacer.addAllPlaceholdersFrom(analysisContainer, FormatUtils::cutDecimals, + placeholderReplacer.addAllPlaceholdersFrom(analysisContainer, decimalFormatter, AVG_TPS_MONTH, AVG_TPS_WEEK, AVG_TPS_DAY, AVG_RAM_MONTH, AVG_RAM_WEEK, AVG_RAM_DAY, AVG_ENTITY_MONTH, AVG_ENTITY_WEEK, AVG_ENTITY_DAY, AVG_CHUNK_MONTH, AVG_CHUNK_WEEK, AVG_CHUNK_DAY ); placeholderReplacer.addAllPlaceholdersFrom(analysisContainer, - value -> value != -1 ? FormatUtils.cutDecimals(value) : "Unavailable", + value -> value != -1 ? decimalFormatter.apply(value) : "Unavailable", AVG_CPU_MONTH, AVG_CPU_WEEK, AVG_CPU_DAY ); - Benchmark.stop(DEBUG, DEBUG + " Performance Numbers"); + timings.end(CHANNEL, CHANNEL + " Performance Numbers"); } private void chartSeries(PlaceholderReplacer placeholderReplacer) { - Benchmark.start(DEBUG + " Chart Series"); + timings.start(CHANNEL + " Chart Series"); placeholderReplacer.addAllPlaceholdersFrom(analysisContainer, WORLD_PIE_SERIES, GM_PIE_SERIES, PLAYERS_ONLINE_SERIES, TPS_SERIES, CPU_SERIES, RAM_SERIES, @@ -160,8 +169,9 @@ public class AnalysisPage implements Page { ACTIVITY_PIE_SERIES, CALENDAR_SERIES, UNIQUE_PLAYERS_SERIES, NEW_PLAYERS_SERIES, COUNTRY_CATEGORIES, COUNTRY_SERIES, - AVG_PING_SERIES, MAX_PING_SERIES, MIN_PING_SERIES + AVG_PING_SERIES, MAX_PING_SERIES, MIN_PING_SERIES, + DISK_SERIES ); - Benchmark.stop(DEBUG, DEBUG + " Chart Series"); + timings.end(CHANNEL, CHANNEL + " Chart Series"); } } \ No newline at end of file diff --git a/Plan/src/main/java/com/djrapitops/plan/utilities/html/pages/DebugPage.java b/Plan/src/main/java/com/djrapitops/plan/utilities/html/pages/DebugPage.java index aaf0c69e2..692c26c28 100644 --- a/Plan/src/main/java/com/djrapitops/plan/utilities/html/pages/DebugPage.java +++ b/Plan/src/main/java/com/djrapitops/plan/utilities/html/pages/DebugPage.java @@ -1,10 +1,7 @@ package com.djrapitops.plan.utilities.html.pages; -import com.djrapitops.plan.PlanPlugin; import com.djrapitops.plan.data.container.Session; import com.djrapitops.plan.data.store.keys.SessionKeys; -import com.djrapitops.plan.data.store.mutators.formatting.Formatter; -import com.djrapitops.plan.data.store.mutators.formatting.Formatters; import com.djrapitops.plan.data.store.objects.DateHolder; import com.djrapitops.plan.system.cache.SessionCache; import com.djrapitops.plan.system.database.databases.Database; @@ -14,17 +11,25 @@ import com.djrapitops.plan.system.info.server.Server; import com.djrapitops.plan.system.info.server.ServerInfo; import com.djrapitops.plan.system.info.server.properties.ServerProperties; import com.djrapitops.plan.system.webserver.cache.ResponseCache; +import com.djrapitops.plan.utilities.file.FileUtil; +import com.djrapitops.plan.utilities.formatting.Formatter; +import com.djrapitops.plan.utilities.formatting.Formatters; import com.djrapitops.plan.utilities.html.Html; import com.djrapitops.plan.utilities.html.HtmlStructure; import com.djrapitops.plan.utilities.html.icon.Icon; import com.djrapitops.plan.utilities.html.structure.TabsElement; -import com.djrapitops.plugin.api.Benchmark; -import com.djrapitops.plugin.api.utility.log.ErrorLogger; -import com.djrapitops.plugin.api.utility.log.Log; +import com.djrapitops.plugin.benchmarking.Benchmark; +import com.djrapitops.plugin.benchmarking.Timings; +import com.djrapitops.plugin.logging.FolderTimeStampFileLogger; +import com.djrapitops.plugin.logging.L; +import com.djrapitops.plugin.logging.debug.CombineDebugLogger; +import com.djrapitops.plugin.logging.debug.DebugLogger; +import com.djrapitops.plugin.logging.debug.MemoryDebugLogger; +import com.djrapitops.plugin.logging.error.DefaultErrorHandler; +import com.djrapitops.plugin.logging.error.ErrorHandler; +import com.djrapitops.plugin.logging.error.FolderTimeStampErrorFileLogger; import java.io.IOException; -import java.lang.management.ManagementFactory; -import java.lang.management.RuntimeMXBean; import java.util.*; /** @@ -34,6 +39,36 @@ import java.util.*; */ public class DebugPage implements Page { + private final Database database; + private final ServerInfo serverInfo; + private final ConnectionSystem connectionSystem; + private final CombineDebugLogger debugLogger; + private final Timings timings; + private final DefaultErrorHandler errorHandler; + + private final Formatter secondFormatter; + private final Formatter yearFormatter; + + DebugPage( + Database database, + ServerInfo serverInfo, + ConnectionSystem connectionSystem, + Formatters formatters, + DebugLogger debugLogger, + Timings timings, + ErrorHandler errorHandler + ) { + this.database = database; + this.serverInfo = serverInfo; + this.connectionSystem = connectionSystem; + this.debugLogger = (CombineDebugLogger) debugLogger; + this.timings = timings; + this.errorHandler = (DefaultErrorHandler) errorHandler; + + this.secondFormatter = formatters.second(); + this.yearFormatter = formatters.yearLong(); + } + @Override public String toHtml() { StringBuilder preContent = new StringBuilder(); @@ -76,7 +111,7 @@ public class DebugPage implements Page { } content.append(""); } catch (Exception e) { - Log.toLog(this.getClass(), e); + errorHandler.log(L.WARN, this.getClass(), e); } } @@ -85,19 +120,18 @@ public class DebugPage implements Page { content.append("
    ### Session Cache:

    "); content.append("UUID | Session Started
    ") .append("-- | --
    "); - Formatter timeStamp = Formatters.yearLongValue(); Set> sessions = SessionCache.getActiveSessions().entrySet(); if (sessions.isEmpty()) { content.append("Empty"); } for (Map.Entry entry : sessions) { UUID uuid = entry.getKey(); - String start = entry.getValue().getValue(SessionKeys.START).map(timeStamp).orElse("Unknown"); + String start = entry.getValue().getValue(SessionKeys.START).map(yearFormatter).orElse("Unknown"); content.append(uuid.toString()).append(" | ").append(start).append("
    "); } content.append("
    "); } catch (Exception e) { - Log.toLog(this.getClass(), e); + errorHandler.log(L.WARN, this.getClass(), e); } } @@ -125,14 +159,12 @@ public class DebugPage implements Page { private void appendConnectionLog(StringBuilder content) { try { - Map> logEntries = ConnectionLog.getLogEntries(); + Map> logEntries = connectionSystem.getConnectionLog().getLogEntries(); content.append("
    ### Connection Log:

    "); content.append("Server Address | Request Type | Response | Sent
    ") .append("-- | -- | -- | --
    "); - Formatter formatter = Formatters.second(); - if (logEntries.isEmpty()) { content.append("**No Connections Logged**
    "); } @@ -146,46 +178,42 @@ public class DebugPage implements Page { content.append(address).append(" | ") .append(infoRequest).append(" | ") .append(logEntry.getResponseCode()).append(" | ") - .append(formatter.apply(logEntry)).append("
    "); + .append(secondFormatter.apply(logEntry)).append("
    "); } } content.append("
    "); content.append("
    ### Servers:

    "); - List servers = ConnectionSystem.getInstance().getBukkitServers(); - content.append("Server Name | Address | UUID
    ") + List servers = connectionSystem.getBukkitServers(); + content.append("Server Name | Address
    ") .append("-- | -- | --
    "); for (Server server : servers) { content.append(server.getName()).append(" | ") - .append(server.getWebAddress()).append(" | ") - .append(server.getUuid()).append("
    "); + .append(server.getWebAddress()).append("
    "); } content.append("
    "); } catch (Exception e) { - Log.toLog(this.getClass(), e); + errorHandler.log(L.WARN, this.getClass(), e); } } private void appendServerInformation(StringBuilder content) { - PlanPlugin plugin = PlanPlugin.getInstance(); - ServerProperties variable = ServerInfo.getServerProperties(); + ServerProperties serverProperties = serverInfo.getServerProperties(); content.append("
    ### Server Information
    ") - .append("**Plan Version:** ").append(plugin.getVersion()).append("
    "); + .append("**Plan Version:** ${version}
    "); content.append("**Server:** "); - content.append(variable.getName()) - .append(" ").append(variable.getImplVersion()) - .append(" ").append(variable.getVersion()); - content.append("
    "); + content.append(serverProperties.getName()) + .append(" ").append(serverProperties.getImplVersion()) + .append(" (").append(serverProperties.getVersion()); + content.append(")
    "); - Database database = Database.getActive(); content.append("**Database:** ").append(database.getName()); content.append("

    "); - RuntimeMXBean runtimeMxBean = ManagementFactory.getRuntimeMXBean(); Properties properties = System.getProperties(); String osName = properties.getProperty("os.name"); @@ -198,7 +226,6 @@ public class DebugPage implements Page { String javaVMVendor = properties.getProperty("java.vm.vendor"); String javaVMName = properties.getProperty("java.vm.name"); String javaVMVersion = properties.getProperty("java.vm.version"); - List javaVMFlags = runtimeMxBean.getInputArguments(); content.append("**Operating SubSystem:** ").append(osName).append(" (").append(osArch) .append(") version ").append(osVersion).append("
    "); @@ -206,7 +233,6 @@ public class DebugPage implements Page { content.append("**Java Version:** ").append(javaVersion).append(", ").append(javaVendor).append("
    "); content.append("**Java VM Version:** ").append(javaVMName).append(" version ").append(javaVMVersion) .append(", ").append(javaVMVendor).append("
    "); - content.append("**Java VM Flags:** ").append(javaVMFlags).append("
    "); content.append("
    "); } @@ -214,52 +240,80 @@ public class DebugPage implements Page { private void appendBenchmarks(StringBuilder content) { content.append("
    ### Benchmarks
    ```
    "); try { - for (String line : Benchmark.getAverages().asStringArray()) { - content.append(line).append("
    "); + for (Benchmark result : timings.getAverageResults()) { + content.append(result.toString()).append("
    "); } } catch (Exception e) { - content.append("Exception on Benchmark.getAverages().asStringArray()"); + content.append("Exception on Timings#getAverageResults"); } content.append("```
    "); } private void appendLoggedErrors(StringBuilder content) { - try { - content.append("
    ### Logged Errors
    "); + content.append("
    ### Logged Errors
    "); - SortedMap> errors = ErrorLogger.getLoggedErrors(PlanPlugin.getInstance()); + List lines = errorHandler.getErrorHandler(FolderTimeStampErrorFileLogger.class) + .flatMap(FolderTimeStampFileLogger::getCurrentFile) + .map(file -> { + try { + return FileUtil.lines(file); + } catch (IOException e) { + errorHandler.log(L.WARN, this.getClass(), e); + return new ArrayList(); + } + }).orElse(new ArrayList<>()); + SortedMap> errors = FolderTimeStampErrorFileLogger.splitByError(lines); - if (!errors.isEmpty()) { - List errorLines = new ArrayList<>(); - for (Map.Entry> entry : errors.entrySet()) { - StringBuilder errorLineBuilder = new StringBuilder(); - for (String line : entry.getValue()) { - errorLineBuilder.append(line).append("
    "); - } - String error = errorLineBuilder.toString(); - if (!errorLines.contains(error)) { - errorLines.add(error); - } + if (!errors.isEmpty()) { + List errorLines = new ArrayList<>(); + for (Map.Entry> entry : errors.entrySet()) { + StringBuilder errorLineBuilder = new StringBuilder(); + for (String line : entry.getValue()) { + errorLineBuilder.append(line).append("
    "); } - for (String error : errorLines) { - content.append("
    ```
    ") - .append(error) - .append("```"); + String error = errorLineBuilder.toString(); + if (!errorLines.contains(error)) { + errorLines.add(error); } - } else { - content.append("**No Errors logged.**
    "); } - content.append("
    "); - } catch (IOException e) { - Log.toLog(this.getClass(), e); + for (String error : errorLines) { + content.append("
    ```
    ") + .append(error) + .append("```"); + } + } else { + content.append("**No Errors logged.**
    "); } + content.append("
    "); } private void appendDebugLog(StringBuilder content) { - content.append("
    ### Debug Log
    ```
    "); - for (String line : Log.getDebugLogInMemory()) { + Optional memoryDebugLogger = this.debugLogger.getDebugLogger(MemoryDebugLogger.class); + Map> channels = memoryDebugLogger.map(MemoryDebugLogger::getChannels).orElse(new HashMap<>()); + + if (channels.isEmpty()) { + content.append("Incompatible Debug Logger in use (No MemoryDebugLogger)"); + return; + } + + TabsElement.Tab[] tabs = channels.entrySet().stream() + .sorted((one, two) -> String.CASE_INSENSITIVE_ORDER.compare(one.getKey(), two.getKey())) + .map(channel -> { + String name = channel.getKey().isEmpty() ? "Default" : channel.getKey(); + return new TabsElement.Tab(name, debugChannelContent(name, channel.getValue())); + }) + .toArray(TabsElement.Tab[]::new); + + content.append(new TabsElement(tabs).toHtmlFull()); + } + + private String debugChannelContent(String channelName, List lines) { + StringBuilder content = new StringBuilder(); + content.append("
    ### Debug (").append(channelName).append(")
    ```
    "); + for (String line : lines) { content.append(line).append("
    "); } content.append("```
    "); + return content.toString(); } } \ No newline at end of file diff --git a/Plan/src/main/java/com/djrapitops/plan/utilities/html/pages/InspectPage.java b/Plan/src/main/java/com/djrapitops/plan/utilities/html/pages/InspectPage.java index 506626182..12d95954f 100644 --- a/Plan/src/main/java/com/djrapitops/plan/utilities/html/pages/InspectPage.java +++ b/Plan/src/main/java/com/djrapitops/plan/utilities/html/pages/InspectPage.java @@ -10,33 +10,33 @@ import com.djrapitops.plan.data.store.containers.PerServerContainer; import com.djrapitops.plan.data.store.containers.PlayerContainer; import com.djrapitops.plan.data.store.keys.PlayerKeys; import com.djrapitops.plan.data.store.mutators.*; -import com.djrapitops.plan.data.store.mutators.formatting.Formatter; -import com.djrapitops.plan.data.store.mutators.formatting.Formatters; -import com.djrapitops.plan.data.store.mutators.formatting.PlaceholderReplacer; import com.djrapitops.plan.data.time.WorldTimes; import com.djrapitops.plan.system.cache.SessionCache; -import com.djrapitops.plan.system.database.databases.Database; +import com.djrapitops.plan.system.file.PlanFiles; import com.djrapitops.plan.system.info.server.ServerInfo; import com.djrapitops.plan.system.settings.Settings; +import com.djrapitops.plan.system.settings.config.PlanConfig; import com.djrapitops.plan.system.settings.theme.Theme; import com.djrapitops.plan.system.settings.theme.ThemeVal; -import com.djrapitops.plan.utilities.FormatUtils; -import com.djrapitops.plan.utilities.MiscUtils; +import com.djrapitops.plan.system.update.VersionCheckSystem; import com.djrapitops.plan.utilities.comparators.SessionStartComparator; -import com.djrapitops.plan.utilities.file.FileUtil; +import com.djrapitops.plan.utilities.formatting.Formatter; +import com.djrapitops.plan.utilities.formatting.Formatters; +import com.djrapitops.plan.utilities.formatting.PlaceholderReplacer; import com.djrapitops.plan.utilities.html.HtmlStructure; -import com.djrapitops.plan.utilities.html.graphs.PunchCardGraph; +import com.djrapitops.plan.utilities.html.graphs.Graphs; import com.djrapitops.plan.utilities.html.graphs.calendar.PlayerCalendar; -import com.djrapitops.plan.utilities.html.graphs.pie.ServerPreferencePie; import com.djrapitops.plan.utilities.html.graphs.pie.WorldPie; +import com.djrapitops.plan.utilities.html.structure.Accordions; import com.djrapitops.plan.utilities.html.structure.ServerAccordion; import com.djrapitops.plan.utilities.html.structure.SessionAccordion; -import com.djrapitops.plan.utilities.html.tables.*; -import com.djrapitops.plugin.api.Benchmark; +import com.djrapitops.plan.utilities.html.tables.HtmlTables; import com.djrapitops.plugin.api.TimeAmount; +import com.djrapitops.plugin.benchmarking.Timings; import java.io.IOException; import java.util.*; +import java.util.concurrent.TimeUnit; /** * Used for parsing Inspect page out of database data and the html. @@ -45,30 +45,70 @@ import java.util.*; */ public class InspectPage implements Page { - private final UUID uuid; + private final PlayerContainer player; + private final Map serverNames; - public InspectPage(UUID uuid) { - this.uuid = uuid; + private final VersionCheckSystem versionCheckSystem; + + private final PlanFiles files; + private final PlanConfig config; + private final Theme theme; + private final Graphs graphs; + private final HtmlTables tables; + private final Accordions accordions; + private final ServerInfo serverInfo; + private final Timings timings; + + private final Formatter timeAmountFormatter; + private final Formatter clockLongFormatter; + private final Formatter secondLongFormatter; + private final Formatter yearLongFormatter; + private final Formatter decimalFormatter; + + InspectPage( + PlayerContainer player, Map serverNames, + VersionCheckSystem versionCheckSystem, + PlanFiles files, + PlanConfig config, + Theme theme, + Graphs graphs, + HtmlTables tables, + Accordions accordions, + Formatters formatters, + ServerInfo serverInfo, + Timings timings + ) { + this.player = player; + this.serverNames = serverNames; + this.versionCheckSystem = versionCheckSystem; + this.files = files; + this.config = config; + this.theme = theme; + this.graphs = graphs; + this.tables = tables; + this.accordions = accordions; + this.serverInfo = serverInfo; + this.timings = timings; + + timeAmountFormatter = formatters.timeAmount(); + clockLongFormatter = formatters.clockLong(); + secondLongFormatter = formatters.secondLong(); + yearLongFormatter = formatters.yearLong(); + decimalFormatter = formatters.decimals(); } @Override public String toHtml() throws ParseException { try { - if (uuid == null) { - throw new IllegalStateException("UUID was null!"); - } - Benchmark.start("Inspect Parse, Fetch"); - Database db = Database.getActive(); - PlayerContainer container = Database.getActive().fetch().getPlayerContainer(uuid); - if (!container.getValue(PlayerKeys.REGISTERED).isPresent()) { + timings.start("Inspect Parse, Fetch"); + if (!player.getValue(PlayerKeys.REGISTERED).isPresent()) { throw new IllegalStateException("Player is not registered"); } - UUID serverUUID = ServerInfo.getServerUUID(); - Map serverNames = db.fetch().getServerNames(); + UUID serverUUID = serverInfo.getServerUUID(); - Benchmark.stop("Inspect Parse, Fetch"); + timings.end("Inspect Parse, Fetch"); - return parse(container, serverUUID, serverNames); + return parse(player, serverUUID, serverNames); } catch (Exception e) { throw new ParseException(e); } @@ -76,12 +116,15 @@ public class InspectPage implements Page { public String parse(PlayerContainer player, UUID serverUUID, Map serverNames) throws IOException { long now = System.currentTimeMillis(); + UUID uuid = player.getUnsafe(PlayerKeys.UUID); PlaceholderReplacer replacer = new PlaceholderReplacer(); - replacer.put("refresh", FormatUtils.formatTimeStampClock(now)); - replacer.put("version", MiscUtils.getPlanVersion()); - replacer.put("timeZone", MiscUtils.getTimeZoneOffsetHours()); + replacer.put("refresh", clockLongFormatter.apply(now)); + replacer.put("refreshFull", secondLongFormatter.apply(now)); + replacer.put("version", versionCheckSystem.getCurrentVersion()); + replacer.put("update", versionCheckSystem.getUpdateHtml().orElse("")); + replacer.put("timeZone", config.getTimeZoneOffsetHours()); boolean online = false; Optional activeSession = SessionCache.getCachedSession(uuid); @@ -95,7 +138,7 @@ public class InspectPage implements Page { String playerName = player.getValue(PlayerKeys.NAME).orElse("Unknown"); int timesKicked = player.getValue(PlayerKeys.KICK_COUNT).orElse(0); - replacer.addAllPlaceholdersFrom(player, Formatters.yearLongValue(), + replacer.addAllPlaceholdersFrom(player, yearLongFormatter, PlayerKeys.REGISTERED, PlayerKeys.LAST_SEEN ); @@ -106,25 +149,25 @@ public class InspectPage implements Page { PerServerMutator perServerMutator = new PerServerMutator(perServerContainer); Map worldTimesPerServer = perServerMutator.worldTimesPerServer(); - replacer.put("serverPieSeries", new ServerPreferencePie(serverNames, worldTimesPerServer).toHighChartsSeries()); - replacer.put("worldPieColors", Theme.getValue(ThemeVal.GRAPH_WORLD_PIE)); - replacer.put("gmPieColors", Theme.getValue(ThemeVal.GRAPH_GM_PIE)); - replacer.put("serverPieColors", Theme.getValue(ThemeVal.GRAPH_SERVER_PREF_PIE)); + replacer.put("serverPieSeries", graphs.pie().serverPreferencePie(serverNames, worldTimesPerServer).toHighChartsSeries()); + replacer.put("worldPieColors", theme.getValue(ThemeVal.GRAPH_WORLD_PIE)); + replacer.put("gmPieColors", theme.getValue(ThemeVal.GRAPH_GM_PIE)); + replacer.put("serverPieColors", theme.getValue(ThemeVal.GRAPH_SERVER_PREF_PIE)); String favoriteServer = serverNames.getOrDefault(perServerMutator.favoriteServer(), "Unknown"); replacer.put("favoriteServer", favoriteServer); - replacer.put("tableBodyNicknames", new NicknameTable( - player.getValue(PlayerKeys.NICKNAMES).orElse(new ArrayList<>()), serverNames) - .parseBody()); - replacer.put("tableBodyIPs", new GeoInfoTable(player.getValue(PlayerKeys.GEO_INFO).orElse(new ArrayList<>())).parseBody()); + replacer.put("tableBodyNicknames", + tables.nicknameTable(player.getValue(PlayerKeys.NICKNAMES).orElse(new ArrayList<>()), serverNames).parseBody() + ); + replacer.put("tableBodyIPs", tables.geoInfoTable(player.getValue(PlayerKeys.GEO_INFO).orElse(new ArrayList<>())).parseBody()); PingMutator pingMutator = PingMutator.forContainer(player); double averagePing = pingMutator.average(); int minPing = pingMutator.min(); int maxPing = pingMutator.max(); String unavailable = "Unavailable"; - replacer.put("avgPing", averagePing != -1 ? FormatUtils.cutDecimals(averagePing) + " ms" : unavailable); + replacer.put("avgPing", averagePing != -1 ? decimalFormatter.apply(averagePing) + " ms" : unavailable); replacer.put("minPing", minPing != -1 ? minPing + " ms" : unavailable); replacer.put("maxPing", maxPing != -1 ? maxPing + " ms" : unavailable); @@ -136,18 +179,18 @@ public class InspectPage implements Page { if (allSessions.isEmpty()) { replacer.put("accordionSessions", "
    " + "

    No Sessions

    " + "
    "); } else { - if (Settings.DISPLAY_SESSIONS_AS_TABLE.isTrue()) { - replacer.put("accordionSessions", new PlayerSessionTable(playerName, allSessions).parseHtml()); + if (config.isTrue(Settings.DISPLAY_SESSIONS_AS_TABLE)) { + replacer.put("accordionSessions", tables.playerSessionTable(playerName, allSessions).parseHtml()); } else { - SessionAccordion sessionAccordion = SessionAccordion.forPlayer(allSessions, () -> serverNames); + SessionAccordion sessionAccordion = accordions.playerSessionAccordion(allSessions, () -> serverNames); replacer.put("accordionSessions", sessionAccordion.toHtml()); sessionAccordionViewScript = sessionAccordion.toViewScript(); } } - ServerAccordion serverAccordion = new ServerAccordion(player, serverNames); + ServerAccordion serverAccordion = accordions.serverAccordion(player, serverNames); - PlayerCalendar playerCalendar = new PlayerCalendar(player); + PlayerCalendar playerCalendar = graphs.calendar().playerCalendar(player); replacer.put("calendarSeries", playerCalendar.toCalendarSeries()); replacer.put("firstDay", 1); @@ -155,9 +198,9 @@ public class InspectPage implements Page { replacer.put("accordionServers", serverAccordion.toHtml()); replacer.put("sessionTabGraphViewFunctions", sessionAccordionViewScript + serverAccordion.toViewScript()); - long dayAgo = now - TimeAmount.DAY.ms(); - long weekAgo = now - TimeAmount.WEEK.ms(); - long monthAgo = now - TimeAmount.MONTH.ms(); + long dayAgo = now - TimeUnit.DAYS.toMillis(1L); + long weekAgo = now - TimeAmount.WEEK.toMillis(1L); + long monthAgo = now - TimeAmount.MONTH.toMillis(1L); SessionsMutator daySessionsMutator = sessionsMutator.filterSessionsBetween(dayAgo, now); SessionsMutator weekSessionsMutator = sessionsMutator.filterSessionsBetween(weekAgo, now); @@ -165,10 +208,10 @@ public class InspectPage implements Page { sessionsAndPlaytime(replacer, sessionsMutator, daySessionsMutator, weekSessionsMutator, monthSessionsMutator); - String punchCardData = new PunchCardGraph(allSessions).toHighChartsSeries(); + String punchCardData = graphs.special().punchCard(allSessions).toHighChartsSeries(); WorldTimes worldTimes = player.getValue(PlayerKeys.WORLD_TIMES).orElse(new WorldTimes(new HashMap<>())); - WorldPie worldPie = new WorldPie(worldTimes); + WorldPie worldPie = graphs.pie().worldPie(worldTimes); replacer.put("worldPieSeries", worldPie.toHighChartsSeries()); replacer.put("gmSeries", worldPie.toHighChartsDrilldown()); @@ -177,9 +220,11 @@ public class InspectPage implements Page { pvpAndPve(replacer, sessionsMutator, weekSessionsMutator, monthSessionsMutator); - ActivityIndex activityIndex = player.getActivityIndex(now); + ActivityIndex activityIndex = player.getActivityIndex( + now, config.getNumber(Settings.ACTIVE_PLAY_THRESHOLD), config.getNumber(Settings.ACTIVE_LOGIN_THRESHOLD) + ); - replacer.put("activityIndexNumber", activityIndex.getFormattedValue()); + replacer.put("activityIndexNumber", activityIndex.getFormattedValue(decimalFormatter)); replacer.put("activityIndexColor", activityIndex.getColor()); replacer.put("activityIndex", activityIndex.getGroup()); @@ -190,11 +235,11 @@ public class InspectPage implements Page { String serverName = serverNames.get(serverUUID); replacer.put("networkName", serverName.equalsIgnoreCase("bungeecord") - ? Settings.BUNGEE_NETWORK_NAME.toString() + ? config.getString(Settings.BUNGEE_NETWORK_NAME) : serverName ); - return replacer.apply(FileUtil.getStringFromResource("web/player.html")); + return replacer.apply(files.readCustomizableResourceFlat("web/player.html")); } private void sessionsAndPlaytime(PlaceholderReplacer replacer, SessionsMutator sessionsMutator, SessionsMutator daySessionsMutator, SessionsMutator weekSessionsMutator, SessionsMutator monthSessionsMutator) { @@ -230,7 +275,7 @@ public class InspectPage implements Page { long sessionAverageWeek = weekSessionsMutator.toAverageSessionLength(); long sessionAverageMonth = monthSessionsMutator.toAverageSessionLength(); - Formatter formatter = Formatters.timeAmount(); + Formatter formatter = timeAmountFormatter; replacer.put("playtimeTotal", formatter.apply(playtime)); replacer.put("playtimeDay", formatter.apply(playtimeDay)); replacer.put("playtimeWeek", formatter.apply(playtimeWeek)); @@ -265,8 +310,8 @@ public class InspectPage implements Page { } private void pvpAndPve(PlaceholderReplacer replacer, SessionsMutator sessionsMutator, SessionsMutator weekSessionsMutator, SessionsMutator monthSessionsMutator) { - String playerKillsTable = new KillsTable(sessionsMutator.toPlayerKillList()).parseHtml(); - String playerDeathTable = new DeathsTable(sessionsMutator.toPlayerDeathList()).parseHtml(); + String playerKillsTable = tables.killsTable(sessionsMutator.toPlayerKillList(), "red").parseHtml(); + String playerDeathTable = tables.deathsTable(sessionsMutator.toPlayerDeathList()).parseHtml(); PvpInfoMutator pvpInfoMutator = PvpInfoMutator.forMutator(sessionsMutator); PvpInfoMutator pvpInfoMutatorMonth = PvpInfoMutator.forMutator(monthSessionsMutator); @@ -280,23 +325,23 @@ public class InspectPage implements Page { replacer.put("playerDeathCount", pvpInfoMutator.playerCausedDeaths()); replacer.put("mobDeathCount", pvpInfoMutator.mobCausedDeaths()); replacer.put("deathCount", pvpInfoMutator.deaths()); - replacer.put("KDR", FormatUtils.cutDecimals(pvpInfoMutator.killDeathRatio())); - replacer.put("mobKDR", FormatUtils.cutDecimals(pvpInfoMutator.mobKillDeathRatio())); + replacer.put("KDR", decimalFormatter.apply(pvpInfoMutator.killDeathRatio())); + replacer.put("mobKDR", decimalFormatter.apply(pvpInfoMutator.mobKillDeathRatio())); replacer.put("playerKillCountMonth", pvpInfoMutatorMonth.playerKills()); replacer.put("mobKillCountMonth", pvpInfoMutatorMonth.mobKills()); replacer.put("playerDeathCountMonth", pvpInfoMutatorMonth.playerCausedDeaths()); replacer.put("mobDeathCountMonth", pvpInfoMutatorMonth.mobCausedDeaths()); replacer.put("deathCountMonth", pvpInfoMutatorMonth.deaths()); - replacer.put("KDRMonth", FormatUtils.cutDecimals(pvpInfoMutatorMonth.killDeathRatio())); - replacer.put("mobKDRMonth", FormatUtils.cutDecimals(pvpInfoMutatorMonth.mobKillDeathRatio())); + replacer.put("KDRMonth", decimalFormatter.apply(pvpInfoMutatorMonth.killDeathRatio())); + replacer.put("mobKDRMonth", decimalFormatter.apply(pvpInfoMutatorMonth.mobKillDeathRatio())); replacer.put("playerKillCountWeek", pvpInfoMutatorWeek.playerKills()); replacer.put("mobKillCountWeek", pvpInfoMutatorWeek.mobKills()); replacer.put("playerDeathCountWeek", pvpInfoMutatorWeek.playerCausedDeaths()); replacer.put("mobDeathCountWeek", pvpInfoMutatorWeek.mobCausedDeaths()); replacer.put("deathCountWeek", pvpInfoMutatorWeek.deaths()); - replacer.put("KDRWeek", FormatUtils.cutDecimals(pvpInfoMutatorWeek.killDeathRatio())); - replacer.put("mobKDRWeek", FormatUtils.cutDecimals(pvpInfoMutatorWeek.mobKillDeathRatio())); + replacer.put("KDRWeek", decimalFormatter.apply(pvpInfoMutatorWeek.killDeathRatio())); + replacer.put("mobKDRWeek", decimalFormatter.apply(pvpInfoMutatorWeek.mobKillDeathRatio())); } } diff --git a/Plan/src/main/java/com/djrapitops/plan/utilities/html/pages/NetworkPage.java b/Plan/src/main/java/com/djrapitops/plan/utilities/html/pages/NetworkPage.java index 073cafbd0..8b223dc0c 100644 --- a/Plan/src/main/java/com/djrapitops/plan/utilities/html/pages/NetworkPage.java +++ b/Plan/src/main/java/com/djrapitops/plan/utilities/html/pages/NetworkPage.java @@ -7,12 +7,10 @@ package com.djrapitops.plan.utilities.html.pages; import com.djrapitops.plan.api.exceptions.ParseException; import com.djrapitops.plan.data.store.containers.NetworkContainer; import com.djrapitops.plan.data.store.keys.NetworkKeys; -import com.djrapitops.plan.data.store.mutators.formatting.PlaceholderReplacer; -import com.djrapitops.plan.system.info.server.ServerInfo; -import com.djrapitops.plan.system.webserver.cache.PageId; -import com.djrapitops.plan.system.webserver.cache.ResponseCache; -import com.djrapitops.plan.system.webserver.response.pages.parts.NetworkPageContent; -import com.djrapitops.plan.utilities.file.FileUtil; +import com.djrapitops.plan.system.file.PlanFiles; +import com.djrapitops.plan.system.info.server.properties.ServerProperties; +import com.djrapitops.plan.system.update.VersionCheckSystem; +import com.djrapitops.plan.utilities.formatting.PlaceholderReplacer; import com.djrapitops.plan.utilities.html.structure.AnalysisPluginsTabContentCreator; import static com.djrapitops.plan.data.store.keys.NetworkKeys.*; @@ -25,15 +23,30 @@ import static com.djrapitops.plan.data.store.keys.NetworkKeys.*; public class NetworkPage implements Page { private final NetworkContainer networkContainer; + private final AnalysisPluginsTabContentCreator analysisPluginsTabContentCreator; - public NetworkPage(NetworkContainer networkContainer) { + private final VersionCheckSystem versionCheckSystem; + private final PlanFiles files; + private final ServerProperties serverProperties; + + NetworkPage( + NetworkContainer networkContainer, + AnalysisPluginsTabContentCreator analysisPluginsTabContentCreator, + VersionCheckSystem versionCheckSystem, + PlanFiles files, + ServerProperties serverProperties + ) { this.networkContainer = networkContainer; + this.analysisPluginsTabContentCreator = analysisPluginsTabContentCreator; + this.versionCheckSystem = versionCheckSystem; + this.files = files; + this.serverProperties = serverProperties; } @Override public String toHtml() throws ParseException { try { - networkContainer.putSupplier(NetworkKeys.PLAYERS_ONLINE, ServerInfo.getServerProperties()::getOnlinePlayers); + networkContainer.putSupplier(NetworkKeys.PLAYERS_ONLINE, serverProperties::getOnlinePlayers); PlaceholderReplacer placeholderReplacer = new PlaceholderReplacer(); placeholderReplacer.addAllPlaceholdersFrom(networkContainer, @@ -46,20 +59,19 @@ public class NetworkPage implements Page { WORLD_MAP_SERIES, WORLD_MAP_HIGH_COLOR, WORLD_MAP_LOW_COLOR, COUNTRY_CATEGORIES, COUNTRY_SERIES, HEALTH_INDEX, HEALTH_NOTES, - ACTIVITY_PIE_SERIES, ACTIVITY_STACK_SERIES, ACTIVITY_STACK_CATEGORIES + ACTIVITY_PIE_SERIES, ACTIVITY_STACK_SERIES, ACTIVITY_STACK_CATEGORIES, + SERVERS_TAB ); - NetworkPageContent networkPageContent = (NetworkPageContent) - ResponseCache.loadResponse(PageId.NETWORK_CONTENT.id(), NetworkPageContent::new); - placeholderReplacer.put("tabContentServers", networkPageContent.getContents()); + placeholderReplacer.put("update", versionCheckSystem.getUpdateHtml().orElse("")); - String[] content = AnalysisPluginsTabContentCreator.createContent(networkContainer.getUnsafe(NetworkKeys.PLAYERS_MUTATOR), null); + String[] content = analysisPluginsTabContentCreator.createContent(null, networkContainer.getUnsafe(NetworkKeys.PLAYERS_MUTATOR)); String nav = content[0]; String tabs = content[1]; placeholderReplacer.put("navPluginsTabs", nav); placeholderReplacer.put("tabsPlugins", tabs); - return placeholderReplacer.apply(FileUtil.getStringFromResource("web/network.html")); + return placeholderReplacer.apply(files.readCustomizableResourceFlat("web/network.html")); } catch (Exception e) { throw new ParseException(e); } diff --git a/Plan/src/main/java/com/djrapitops/plan/utilities/html/pages/PageFactory.java b/Plan/src/main/java/com/djrapitops/plan/utilities/html/pages/PageFactory.java new file mode 100644 index 000000000..2c58123a7 --- /dev/null +++ b/Plan/src/main/java/com/djrapitops/plan/utilities/html/pages/PageFactory.java @@ -0,0 +1,138 @@ +package com.djrapitops.plan.utilities.html.pages; + +import com.djrapitops.plan.data.plugin.HookHandler; +import com.djrapitops.plan.data.store.containers.AnalysisContainer; +import com.djrapitops.plan.data.store.containers.NetworkContainer; +import com.djrapitops.plan.data.store.containers.PlayerContainer; +import com.djrapitops.plan.system.database.DBSystem; +import com.djrapitops.plan.system.database.databases.operation.FetchOperations; +import com.djrapitops.plan.system.file.PlanFiles; +import com.djrapitops.plan.system.info.connection.ConnectionSystem; +import com.djrapitops.plan.system.info.server.ServerInfo; +import com.djrapitops.plan.system.settings.config.PlanConfig; +import com.djrapitops.plan.system.settings.theme.Theme; +import com.djrapitops.plan.system.update.VersionCheckSystem; +import com.djrapitops.plan.system.webserver.response.pages.parts.InspectPagePluginsContent; +import com.djrapitops.plan.utilities.formatting.Formatters; +import com.djrapitops.plan.utilities.html.graphs.Graphs; +import com.djrapitops.plan.utilities.html.structure.Accordions; +import com.djrapitops.plan.utilities.html.structure.AnalysisPluginsTabContentCreator; +import com.djrapitops.plan.utilities.html.tables.HtmlTables; +import com.djrapitops.plugin.benchmarking.Timings; +import com.djrapitops.plugin.logging.debug.DebugLogger; +import com.djrapitops.plugin.logging.error.ErrorHandler; +import dagger.Lazy; + +import javax.inject.Inject; +import javax.inject.Singleton; +import java.util.Map; +import java.util.UUID; + +/** + * Factory for creating different {@link Page} objects. + * + * @author Rsl1122 + */ +@Singleton +public class PageFactory { + + private final Lazy versionCheckSystem; + private final Lazy fileSystem; + private final Lazy config; + private final Lazy theme; + private final Lazy dbSystem; + private final Lazy serverInfo; + private final Lazy connectionSystem; + private final Lazy graphs; + private final Lazy tables; + private final Lazy accordions; + private final Lazy formatters; + private final Lazy analysisContainerFactory; + private final Lazy analysisPluginsTabContentCreator; + private final Lazy hookHandler; + private final Lazy debugLogger; + private final Lazy timings; + private final Lazy errorHandler; + + @Inject + public PageFactory( + Lazy versionCheckSystem, + Lazy fileSystem, + Lazy config, + Lazy theme, + Lazy dbSystem, + Lazy serverInfo, + Lazy connectionSystem, + Lazy graphs, + Lazy tables, + Lazy accordions, + Lazy formatters, + Lazy analysisContainerFactory, + Lazy analysisPluginsTabContentCreator, + Lazy hookHandler, + Lazy debugLogger, + Lazy timings, + Lazy errorHandler + ) { + this.versionCheckSystem = versionCheckSystem; + this.fileSystem = fileSystem; + this.config = config; + this.theme = theme; + this.dbSystem = dbSystem; + this.serverInfo = serverInfo; + this.connectionSystem = connectionSystem; + this.graphs = graphs; + this.tables = tables; + this.accordions = accordions; + this.formatters = formatters; + this.analysisContainerFactory = analysisContainerFactory; + this.analysisPluginsTabContentCreator = analysisPluginsTabContentCreator; + this.hookHandler = hookHandler; + this.debugLogger = debugLogger; + this.timings = timings; + this.errorHandler = errorHandler; + } + + public DebugPage debugPage() { + return new DebugPage( + dbSystem.get().getDatabase(), serverInfo.get(), connectionSystem.get(), formatters.get(), + debugLogger.get(), timings.get(), errorHandler.get() + ); + } + + public PlayersPage playersPage() { + return new PlayersPage(versionCheckSystem.get(), fileSystem.get(), config.get(), + dbSystem.get().getDatabase(), serverInfo.get(), tables.get(), + timings.get()); + } + + public AnalysisPage analysisPage(UUID serverUUID) { + AnalysisContainer analysisContainer = analysisContainerFactory.get() + .forServerContainer(dbSystem.get().getDatabase().fetch().getServerContainer(serverUUID)); + return new AnalysisPage(analysisContainer, versionCheckSystem.get(), fileSystem.get(), formatters.get().decimals(), timings.get()); + } + + public InspectPage inspectPage(UUID uuid) { + FetchOperations fetch = dbSystem.get().getDatabase().fetch(); + PlayerContainer player = fetch.getPlayerContainer(uuid); + Map serverNames = fetch.getServerNames(); + return new InspectPage( + player, serverNames, + versionCheckSystem.get(), + fileSystem.get(), config.get(), theme.get(), + graphs.get(), tables.get(), accordions.get(), formatters.get(), + serverInfo.get(), timings.get() + ); + } + + public InspectPagePluginsContent inspectPagePluginsContent(UUID playerUUID) { + return InspectPagePluginsContent.generateForThisServer(playerUUID, serverInfo.get(), hookHandler.get()); + } + + public NetworkPage networkPage() { + NetworkContainer networkContainer = dbSystem.get().getDatabase().fetch().getNetworkContainer(); // Not cached, big. + return new NetworkPage(networkContainer, + analysisPluginsTabContentCreator.get(), + versionCheckSystem.get(), fileSystem.get(), serverInfo.get().getServerProperties()); + } +} \ No newline at end of file diff --git a/Plan/src/main/java/com/djrapitops/plan/utilities/html/pages/PlayersPage.java b/Plan/src/main/java/com/djrapitops/plan/utilities/html/pages/PlayersPage.java index 020266e82..2d52f1117 100644 --- a/Plan/src/main/java/com/djrapitops/plan/utilities/html/pages/PlayersPage.java +++ b/Plan/src/main/java/com/djrapitops/plan/utilities/html/pages/PlayersPage.java @@ -1,17 +1,17 @@ package com.djrapitops.plan.utilities.html.pages; -import com.djrapitops.plan.PlanPlugin; import com.djrapitops.plan.api.exceptions.ParseException; import com.djrapitops.plan.data.store.containers.PlayerContainer; -import com.djrapitops.plan.data.store.mutators.formatting.PlaceholderReplacer; import com.djrapitops.plan.system.database.databases.Database; +import com.djrapitops.plan.system.file.PlanFiles; import com.djrapitops.plan.system.info.server.ServerInfo; import com.djrapitops.plan.system.settings.Settings; -import com.djrapitops.plan.utilities.file.FileUtil; -import com.djrapitops.plan.utilities.html.tables.PlayersTable; -import com.djrapitops.plugin.api.Benchmark; +import com.djrapitops.plan.system.settings.config.PlanConfig; +import com.djrapitops.plan.system.update.VersionCheckSystem; +import com.djrapitops.plan.utilities.formatting.PlaceholderReplacer; +import com.djrapitops.plan.utilities.html.tables.HtmlTables; import com.djrapitops.plugin.api.Check; -import com.djrapitops.plugin.api.utility.log.Log; +import com.djrapitops.plugin.benchmarking.Timings; import java.util.List; @@ -22,25 +22,53 @@ import java.util.List; */ public class PlayersPage implements Page { + private final VersionCheckSystem versionCheckSystem; + private final PlanFiles files; + private final PlanConfig config; + private final Database database; + private final ServerInfo serverInfo; + + private final HtmlTables tables; + + private final Timings timings; + + PlayersPage( + VersionCheckSystem versionCheckSystem, + PlanFiles files, + PlanConfig config, + Database database, + ServerInfo serverInfo, + HtmlTables tables, + Timings timings + ) { + this.versionCheckSystem = versionCheckSystem; + this.files = files; + this.config = config; + this.database = database; + this.serverInfo = serverInfo; + this.tables = tables; + this.timings = timings; + } + @Override public String toHtml() throws ParseException { try { - Database database = Database.getActive(); PlaceholderReplacer placeholderReplacer = new PlaceholderReplacer(); - placeholderReplacer.put("version", PlanPlugin.getInstance().getVersion()); + placeholderReplacer.put("version", versionCheckSystem.getCurrentVersion()); + placeholderReplacer.put("update", versionCheckSystem.getUpdateHtml().orElse("")); if (Check.isBukkitAvailable()) { - placeholderReplacer.put("networkName", ServerInfo.getServerName()); + placeholderReplacer.put("networkName", serverInfo.getServer().getName()); } else { - placeholderReplacer.put("networkName", Settings.BUNGEE_NETWORK_NAME.toString()); + placeholderReplacer.put("networkName", config.getString(Settings.BUNGEE_NETWORK_NAME)); } - Benchmark.start("Players page players table parsing"); + timings.start("Players page players table parsing"); List playerContainers = database.fetch().getAllPlayerContainers(); - placeholderReplacer.put("playersTable", PlayersTable.forPlayersPage(playerContainers).parseHtml()); - Log.debug(Benchmark.stopAndFormat("Players page players table parsing")); + placeholderReplacer.put("playersTable", tables.playerTableForPlayersPage(playerContainers).parseHtml()); + timings.end("Pages", "Players page players table parsing"); - return placeholderReplacer.apply(FileUtil.getStringFromResource("web/players.html")); + return placeholderReplacer.apply(files.readCustomizableResourceFlat("web/players.html")); } catch (Exception e) { throw new ParseException(e); } diff --git a/Plan/src/main/java/com/djrapitops/plan/utilities/html/structure/AbstractAccordion.java b/Plan/src/main/java/com/djrapitops/plan/utilities/html/structure/Accordion.java similarity index 95% rename from Plan/src/main/java/com/djrapitops/plan/utilities/html/structure/AbstractAccordion.java rename to Plan/src/main/java/com/djrapitops/plan/utilities/html/structure/Accordion.java index 6b47a005f..8bf8b5ddf 100644 --- a/Plan/src/main/java/com/djrapitops/plan/utilities/html/structure/AbstractAccordion.java +++ b/Plan/src/main/java/com/djrapitops/plan/utilities/html/structure/Accordion.java @@ -14,14 +14,14 @@ import java.util.List; * * @author Rsl1122 */ -public class AbstractAccordion { +public class Accordion { private final String id; private final List elements; private String emptyText = "No Data"; - public AbstractAccordion(String id) { + public Accordion(String id) { this.id = new Format(id) .removeSymbols() .removeWhitespace() diff --git a/Plan/src/main/java/com/djrapitops/plan/utilities/html/structure/Accordions.java b/Plan/src/main/java/com/djrapitops/plan/utilities/html/structure/Accordions.java new file mode 100644 index 000000000..b6dee4358 --- /dev/null +++ b/Plan/src/main/java/com/djrapitops/plan/utilities/html/structure/Accordions.java @@ -0,0 +1,109 @@ +package com.djrapitops.plan.utilities.html.structure; + +import com.djrapitops.plan.data.container.Session; +import com.djrapitops.plan.data.store.containers.PlayerContainer; +import com.djrapitops.plan.system.settings.Settings; +import com.djrapitops.plan.system.settings.config.PlanConfig; +import com.djrapitops.plan.system.settings.theme.Theme; +import com.djrapitops.plan.utilities.formatting.Formatters; +import com.djrapitops.plan.utilities.html.graphs.Graphs; +import com.djrapitops.plan.utilities.html.tables.HtmlTables; + +import javax.inject.Inject; +import javax.inject.Singleton; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.UUID; +import java.util.function.Supplier; + +/** + * Factory class for different {@link Accordion} objects. + * + * @author Rsl1122 + */ +@Singleton +public class Accordions { + + private final PlanConfig config; + private final Theme theme; + private final Graphs graphs; + private final HtmlTables tables; + private final Formatters formatters; + + @Inject + public Accordions( + PlanConfig config, + Theme theme, + Graphs graphs, + HtmlTables tables, + Formatters formatters + ) { + this.config = config; + this.theme = theme; + this.graphs = graphs; + this.tables = tables; + this.formatters = formatters; + } + + /** + * Create a new Session accordion for a Player. + * + * @param sessions {@link Session}s of the Player. + * @param serverNamesSupplier Supplier that provides server name map. + * @return a new {@link SessionAccordion}. + */ + public SessionAccordion playerSessionAccordion( + List sessions, + Supplier> serverNamesSupplier + ) { + boolean appendWorldPercentage = config.isTrue(Settings.APPEND_WORLD_PERC); + int maxSessions = config.getNumber(Settings.MAX_SESSIONS); + return new SessionAccordion( + true, sessions, + serverNamesSupplier, HashMap::new, + appendWorldPercentage, maxSessions, + config.getWorldAliasSettings(), theme, graphs, tables, + formatters.year(), formatters.timeAmount() + ); + } + + /** + * Create a new Session accordion for a server. + * + * @param sessions Sessions that have occurred on a server. + * @param serverNamesSupplier Supplier for server names. + * @param playerNamesSupplier Supplier for names of players. + * @return a new {@link SessionAccordion} + */ + public SessionAccordion serverSessionAccordion( + List sessions, + Supplier> serverNamesSupplier, + Supplier> playerNamesSupplier + ) { + boolean appendWorldPercentage = config.isTrue(Settings.APPEND_WORLD_PERC); + int maxSessions = config.getNumber(Settings.MAX_SESSIONS); + return new SessionAccordion( + false, sessions, + serverNamesSupplier, playerNamesSupplier, + appendWorldPercentage, maxSessions, + config.getWorldAliasSettings(), theme, graphs, tables, + formatters.year(), formatters.timeAmount() + ); + } + + /** + * Create a Server breakdown accordion for a player. + * + * @param player PlayerContainer of the Player. + * @param serverNames Names of the servers. + * @return a new {@link ServerAccordion} + */ + public ServerAccordion serverAccordion(PlayerContainer player, Map serverNames) { + return new ServerAccordion( + player, serverNames, + theme, graphs, + formatters.yearLong(), formatters.timeAmount() + ); + } +} diff --git a/Plan/src/main/java/com/djrapitops/plan/utilities/html/structure/AnalysisPluginsTabContentCreator.java b/Plan/src/main/java/com/djrapitops/plan/utilities/html/structure/AnalysisPluginsTabContentCreator.java index 50d6ee6cc..6532f6c08 100644 --- a/Plan/src/main/java/com/djrapitops/plan/utilities/html/structure/AnalysisPluginsTabContentCreator.java +++ b/Plan/src/main/java/com/djrapitops/plan/utilities/html/structure/AnalysisPluginsTabContentCreator.java @@ -4,18 +4,21 @@ */ package com.djrapitops.plan.utilities.html.structure; -import com.djrapitops.plan.PlanPlugin; import com.djrapitops.plan.data.element.AnalysisContainer; import com.djrapitops.plan.data.element.InspectContainer; import com.djrapitops.plan.data.plugin.HookHandler; import com.djrapitops.plan.data.plugin.PluginData; import com.djrapitops.plan.data.store.mutators.PlayersMutator; +import com.djrapitops.plan.system.DebugChannels; import com.djrapitops.plan.utilities.comparators.PluginDataNameComparator; -import com.djrapitops.plan.utilities.html.tables.PluginPlayersTable; -import com.djrapitops.plugin.StaticHolder; -import com.djrapitops.plugin.api.Benchmark; -import com.djrapitops.plugin.api.utility.log.Log; +import com.djrapitops.plan.utilities.html.tables.HtmlTables; +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; +import javax.inject.Inject; +import javax.inject.Singleton; import java.util.*; /** @@ -23,12 +26,35 @@ import java.util.*; * * @author Rsl1122 */ +@Singleton public class AnalysisPluginsTabContentCreator { - public static String[] createContent( - PlayersMutator mutator, - com.djrapitops.plan.data.store.containers.AnalysisContainer analysisContainer + private final HookHandler hookHandler; + private final HtmlTables tables; + private final Timings timings; + private final PluginLogger logger; + private final ErrorHandler errorHandler; + + @Inject + public AnalysisPluginsTabContentCreator( + HookHandler hookHandler, + HtmlTables tables, + Timings timings, + PluginLogger logger, + ErrorHandler errorHandler ) { + this.hookHandler = hookHandler; + this.tables = tables; + this.timings = timings; + this.logger = logger; + this.errorHandler = errorHandler; + } + + public String[] createContent( + com.djrapitops.plan.data.store.containers.AnalysisContainer analysisContainer, + PlayersMutator mutator + ) { + if (mutator.all().isEmpty()) { return new String[]{"
  • No Data
  • ", ""}; } @@ -82,7 +108,7 @@ public class AnalysisPluginsTabContentCreator { "
    " + "

    Plugin Data

    " + "
    " + - new PluginPlayersTable(containers, mutator.all()).parseHtml() + + tables.pluginPlayersTable(containers, mutator.all()).parseHtml() + "
    " + ""; @@ -93,19 +119,17 @@ public class AnalysisPluginsTabContentCreator { }; } - private static Map analyzeAdditionalPluginData( + private Map analyzeAdditionalPluginData( Collection uuids, com.djrapitops.plan.data.store.containers.AnalysisContainer analysisContainer ) { Map containers = new HashMap<>(); - List sources = HookHandler.getInstance().getAdditionalDataSources(); + List sources = hookHandler.getAdditionalDataSources(); sources.parallelStream().forEach(source -> { - PlanPlugin plugin = PlanPlugin.getInstance(); - StaticHolder.saveInstance(AnalysisPluginsTabContentCreator.class, plugin.getClass()); try { - Benchmark.start("Analysis: Source " + source.getSourcePlugin()); + timings.start("Source " + source.getSourcePlugin()); source.setAnalysisData(analysisContainer); AnalysisContainer container = source.getServerData(uuids, new AnalysisContainer()); @@ -114,10 +138,10 @@ public class AnalysisPluginsTabContentCreator { } } catch (Exception | NoClassDefFoundError | NoSuchFieldError | NoSuchMethodError e) { - Log.error("A PluginData-source caused an exception: " + source.getSourcePlugin()); - Log.toLog(AnalysisPluginsTabContentCreator.class, e); + logger.error("A PluginData-source caused an exception: " + source.getSourcePlugin()); + errorHandler.log(L.WARN, this.getClass(), e); } finally { - Benchmark.stop("Analysis", "Analysis: Source " + source.getSourcePlugin()); + timings.end(DebugChannels.ANALYSIS, "Source " + source.getSourcePlugin()); source.setAnalysisData(null); } }); diff --git a/Plan/src/main/java/com/djrapitops/plan/utilities/html/structure/NetworkServerBox.java b/Plan/src/main/java/com/djrapitops/plan/utilities/html/structure/NetworkServerBox.java new file mode 100644 index 000000000..f43c26ee7 --- /dev/null +++ b/Plan/src/main/java/com/djrapitops/plan/utilities/html/structure/NetworkServerBox.java @@ -0,0 +1,101 @@ +package com.djrapitops.plan.utilities.html.structure; + +import com.djrapitops.plan.data.store.mutators.PlayersOnlineResolver; +import com.djrapitops.plan.data.store.mutators.TPSMutator; +import com.djrapitops.plan.system.info.server.Server; +import com.djrapitops.plan.system.webserver.cache.PageId; +import com.djrapitops.plan.system.webserver.cache.ResponseCache; +import com.djrapitops.plan.system.webserver.response.pages.AnalysisPageResponse; +import com.djrapitops.plan.utilities.html.graphs.Graphs; + +import java.util.Optional; +import java.util.UUID; +import java.util.concurrent.ThreadLocalRandom; + +/** + * Html that represents a server box on the network page. + * + * @author Rsl1122 + */ +public class NetworkServerBox { + + private final Server server; + private final int registeredPlayers; + private final TPSMutator tpsMutator; + + private final Graphs graphs; + + public NetworkServerBox( + Server server, + int registeredPlayers, + TPSMutator tpsMutator, + Graphs graphs + ) { + this.server = server; + this.registeredPlayers = registeredPlayers; + this.tpsMutator = tpsMutator; + this.graphs = graphs; + } + + public String toHtml() { + Optional playersOnline = new PlayersOnlineResolver(tpsMutator).getOnlineOn(System.currentTimeMillis()); + int onlineCount = playersOnline.orElse(0); + int maxCount = server.getMaxPlayers(); + + String serverName = server.getName(); + String address = "../server/" + serverName; + UUID serverUUID = server.getUuid(); + String htmlID = ThreadLocalRandom.current().nextInt(100) + serverUUID.toString().replace("-", ""); + + String playersOnlineData = graphs.line().playersOnlineGraph(tpsMutator).toHighChartsSeries(); + + String pageID = PageId.SERVER.of(serverUUID); + boolean isCached = ResponseCache.isCached(pageID); + boolean isOnline = isCached && ResponseCache.loadResponse(pageID) instanceof AnalysisPageResponse; + String cached = isCached ? (isOnline ? "Yes" : "Offline") : "No"; + + return "
    " + + "
    " + + "
    " + + "
    " + + "
    " + + "

    " + serverName + "

    " + + "
    " + + "
    " + + "
    " + + "
    " + + "
    " + + "
    " + + "
    " + + "
    " + + "
    " + + "

    Registered Players " + + "" + registeredPlayers + "

    " + + "

    Players Online " + + "" + onlineCount + " / " + maxCount + "

    " + + "
    " + + "
    " + + "

    Analysis Cached" + + "" + cached + "

    " + + "
    " + + "" + + ""; + } +} \ No newline at end of file diff --git a/Plan/src/main/java/com/djrapitops/plan/utilities/html/structure/RecentLoginList.java b/Plan/src/main/java/com/djrapitops/plan/utilities/html/structure/RecentLoginList.java index 1201cae45..062d07ff6 100644 --- a/Plan/src/main/java/com/djrapitops/plan/utilities/html/structure/RecentLoginList.java +++ b/Plan/src/main/java/com/djrapitops/plan/utilities/html/structure/RecentLoginList.java @@ -5,15 +5,13 @@ import com.djrapitops.plan.data.container.Session; import com.djrapitops.plan.data.store.containers.PlayerContainer; import com.djrapitops.plan.data.store.keys.PlayerKeys; import com.djrapitops.plan.data.store.keys.SessionKeys; -import com.djrapitops.plan.data.store.mutators.formatting.Formatter; -import com.djrapitops.plan.data.store.mutators.formatting.Formatters; -import com.djrapitops.plan.data.store.objects.DateHolder; import com.djrapitops.plan.utilities.comparators.SessionStartComparator; -import com.djrapitops.plugin.api.TimeAmount; +import com.djrapitops.plan.utilities.formatting.Formatter; import java.util.ArrayList; import java.util.List; import java.util.Objects; +import java.util.concurrent.TimeUnit; /** * Utility class for creating recent login list html. @@ -26,15 +24,16 @@ public class RecentLoginList { private final List players; - public RecentLoginList(List players) { + private final Formatter secondLongFormatter; + + public RecentLoginList(List players, Formatter secondLongFormatter) { this.players = players; + this.secondLongFormatter = secondLongFormatter; } public String toHtml() { List recentLogins = getMostRecentLogins(); - Formatter formatter = Formatters.second(); - if (recentLogins.isEmpty()) { return "
  • No Recent Logins
  • "; } @@ -49,7 +48,7 @@ public class RecentLoginList { String name = recentLogin.name; String url = PlanAPI.getInstance().getPlayerInspectPageLink(name); boolean isNew = recentLogin.isNew; - String start = formatter.apply(recentLogin); + String start = secondLongFormatter.apply(recentLogin.date); html.append("
  • ").append(name).append("").append(start).append("
  • "); @@ -81,13 +80,13 @@ public class RecentLoginList { continue; } long mostRecentStart = session.getUnsafe(SessionKeys.START); - boolean isFirstSession = Math.abs(registerDate - mostRecentStart) < TimeAmount.SECOND.ms() * 10L; + boolean isFirstSession = Math.abs(registerDate - mostRecentStart) < TimeUnit.SECONDS.toMillis(10L); recentLogins.add(new RecentLogin(mostRecentStart, isFirstSession, name)); } return recentLogins; } - class RecentLogin implements DateHolder { + class RecentLogin { final long date; final boolean isNew; final String name; @@ -112,11 +111,6 @@ public class RecentLoginList { public int hashCode() { return Objects.hash(date, isNew, name); } - - @Override - public long getDate() { - return date; - } } } \ No newline at end of file diff --git a/Plan/src/main/java/com/djrapitops/plan/utilities/html/structure/ServerAccordion.java b/Plan/src/main/java/com/djrapitops/plan/utilities/html/structure/ServerAccordion.java index 272060804..49a05fc3a 100644 --- a/Plan/src/main/java/com/djrapitops/plan/utilities/html/structure/ServerAccordion.java +++ b/Plan/src/main/java/com/djrapitops/plan/utilities/html/structure/ServerAccordion.java @@ -10,11 +10,11 @@ import com.djrapitops.plan.data.store.containers.PlayerContainer; import com.djrapitops.plan.data.store.keys.PerServerKeys; import com.djrapitops.plan.data.store.keys.PlayerKeys; import com.djrapitops.plan.data.store.mutators.SessionsMutator; -import com.djrapitops.plan.data.store.mutators.formatting.Formatter; -import com.djrapitops.plan.data.store.mutators.formatting.Formatters; import com.djrapitops.plan.data.time.WorldTimes; import com.djrapitops.plan.system.settings.theme.Theme; import com.djrapitops.plan.system.settings.theme.ThemeVal; +import com.djrapitops.plan.utilities.formatting.Formatter; +import com.djrapitops.plan.utilities.html.graphs.Graphs; import com.djrapitops.plan.utilities.html.graphs.pie.WorldPie; import com.djrapitops.plan.utilities.html.icon.Color; import com.djrapitops.plan.utilities.html.icon.Icon; @@ -31,15 +31,30 @@ import java.util.UUID; * * @author Rsl1122 */ -public class ServerAccordion extends AbstractAccordion { +public class ServerAccordion extends Accordion { private final StringBuilder viewScript; private final Map serverNames; private PerServerContainer perServer; - public ServerAccordion(PlayerContainer container, Map serverNames) { + private final Theme theme; + private final Graphs graphs; + private final Formatter yearLongFormatter; + private final Formatter timeAmountFormatter; + + public ServerAccordion( + PlayerContainer container, Map serverNames, + Theme theme, + Graphs graphs, + Formatter yearLongFormatter, + Formatter timeAmountFormatter + ) { super("server_accordion"); + this.theme = theme; + this.graphs = graphs; + this.yearLongFormatter = yearLongFormatter; + this.timeAmountFormatter = timeAmountFormatter; viewScript = new StringBuilder(); @@ -61,8 +76,6 @@ public class ServerAccordion extends AbstractAccordion { private void addElements() { int i = 0; - Formatter timeFormatter = Formatters.timeAmount(); - for (Map.Entry entry : perServer.entrySet()) { UUID serverUUID = entry.getKey(); DataContainer container = entry.getValue(); @@ -84,10 +97,10 @@ public class ServerAccordion extends AbstractAccordion { long playerKills = sessionsMutator.toPlayerKillCount(); long deaths = sessionsMutator.toDeathCount(); - String play = timeFormatter.apply(playtime); - String afk = timeFormatter.apply(afkTime); - String median = timeFormatter.apply(sessionMedian); - String longest = timeFormatter.apply(longestSession); + String play = timeAmountFormatter.apply(playtime); + String afk = timeAmountFormatter.apply(afkTime); + String median = timeAmountFormatter.apply(sessionMedian); + String longest = timeAmountFormatter.apply(longestSession); String sanitizedServerName = new Format(serverName) .removeSymbols() @@ -96,14 +109,14 @@ public class ServerAccordion extends AbstractAccordion { String worldId = "worldPieServer" + sanitizedServerName; - WorldPie worldPie = new WorldPie(worldTimes); + WorldPie worldPie = graphs.pie().worldPie(worldTimes); String title = serverName + "" + play + ""; String leftSide = new AccordionElementContentBuilder() .addRowBold(Icons.OPERATOR, "Operator", operator ? "Yes" : "No") .addRowBold(Icons.BANNED, "Banned", banned ? "Yes" : "No") - .addRowBold(Icon.called("user-plus").of(Color.LIGHT_GREEN), "Registered", Formatters.year().apply(() -> registered)) + .addRowBold(Icon.called("user-plus").of(Color.LIGHT_GREEN), "Registered", yearLongFormatter.apply(registered)) .addBreak() .addRowBold(Icons.SESSION_COUNT, "Sessions", sessionCount) .addRowBold(Icons.PLAYTIME, "Server Playtime", play) @@ -123,7 +136,7 @@ public class ServerAccordion extends AbstractAccordion { ""; addElement(new AccordionElement(htmlID, title) - .setColor(Theme.getValue(ThemeVal.PARSED_SERVER_ACCORDION)) + .setColor(theme.getValue(ThemeVal.PARSED_SERVER_ACCORDION)) .setLeftSide(leftSide) .setRightSide(rightSide)); diff --git a/Plan/src/main/java/com/djrapitops/plan/utilities/html/structure/SessionAccordion.java b/Plan/src/main/java/com/djrapitops/plan/utilities/html/structure/SessionAccordion.java index b50ebd4e4..4a0d3396a 100644 --- a/Plan/src/main/java/com/djrapitops/plan/utilities/html/structure/SessionAccordion.java +++ b/Plan/src/main/java/com/djrapitops/plan/utilities/html/structure/SessionAccordion.java @@ -1,20 +1,21 @@ package com.djrapitops.plan.utilities.html.structure; import com.djrapitops.plan.api.PlanAPI; +import com.djrapitops.plan.data.container.PlayerKill; import com.djrapitops.plan.data.container.Session; import com.djrapitops.plan.data.store.keys.SessionKeys; -import com.djrapitops.plan.data.store.mutators.formatting.Formatter; -import com.djrapitops.plan.data.store.mutators.formatting.Formatters; import com.djrapitops.plan.data.store.objects.DateHolder; import com.djrapitops.plan.data.time.WorldTimes; -import com.djrapitops.plan.system.settings.Settings; +import com.djrapitops.plan.system.settings.WorldAliasSettings; import com.djrapitops.plan.system.settings.theme.Theme; import com.djrapitops.plan.system.settings.theme.ThemeVal; import com.djrapitops.plan.utilities.comparators.DateHolderRecentComparator; +import com.djrapitops.plan.utilities.formatting.Formatter; import com.djrapitops.plan.utilities.html.HtmlStructure; +import com.djrapitops.plan.utilities.html.graphs.Graphs; import com.djrapitops.plan.utilities.html.graphs.pie.WorldPie; import com.djrapitops.plan.utilities.html.icon.Icons; -import com.djrapitops.plan.utilities.html.tables.KillsTable; +import com.djrapitops.plan.utilities.html.tables.HtmlTables; import java.util.*; import java.util.function.Supplier; @@ -25,7 +26,7 @@ import java.util.function.Supplier; * @author Rsl1122 * @see com.djrapitops.plan.data.container.Session for object */ -public class SessionAccordion extends AbstractAccordion { +public class SessionAccordion extends Accordion { private final boolean forPlayer; private final List sessions; @@ -34,37 +35,46 @@ public class SessionAccordion extends AbstractAccordion { private final StringBuilder viewScript; private final boolean appendWorldPercentage; - private int maxSessions; + private final int maxSessions; - private SessionAccordion(boolean forPlayer, List sessions, - Supplier> serverNamesSupplier, - Supplier> playerNamesSupplier) { + private final WorldAliasSettings worldAliasSettings; + private final Theme theme; + private final Graphs graphs; + private final HtmlTables tables; + private final Formatter yearFormatter; + private final Formatter timeAmountFormatter; + + SessionAccordion(boolean forPlayer, List sessions, + Supplier> serverNamesSupplier, + Supplier> playerNamesSupplier, + boolean appendWorldPercentage, + int maxSessions, + WorldAliasSettings worldAliasSettings, + Theme theme, + Graphs graphs, + HtmlTables tables, + Formatter yearFormatter, + Formatter timeAmountFormatter + ) { super("session_accordion"); this.forPlayer = forPlayer; this.sessions = sessions; this.serverNamesSupplier = serverNamesSupplier; this.playerNamesSupplier = playerNamesSupplier; + this.appendWorldPercentage = appendWorldPercentage; + this.maxSessions = maxSessions; + this.worldAliasSettings = worldAliasSettings; + this.theme = theme; + this.graphs = graphs; + this.tables = tables; + this.yearFormatter = yearFormatter; + this.timeAmountFormatter = timeAmountFormatter; viewScript = new StringBuilder(); - maxSessions = Settings.MAX_SESSIONS.getNumber(); - if (maxSessions <= 0) { - maxSessions = 50; - } - appendWorldPercentage = Settings.APPEND_WORLD_PERC.isTrue(); - addElements(); } - public static SessionAccordion forServer(List sessions, Supplier> serverNamesSupplier, - Supplier> playerNamesSupplier) { - return new SessionAccordion(false, sessions, serverNamesSupplier, playerNamesSupplier); - } - - public static SessionAccordion forPlayer(List sessions, Supplier> serverNamesSupplier) { - return new SessionAccordion(true, sessions, serverNamesSupplier, HashMap::new); - } - public String toViewScript() { return viewScript.toString(); } @@ -81,10 +91,8 @@ public class SessionAccordion extends AbstractAccordion { private void addElementsForServer() { Map serverNames = serverNamesSupplier.get(); Map playerNames = playerNamesSupplier.get(); - Formatter timeFormatter = Formatters.timeAmount(); - Formatter timeStampFormatter = Formatters.year(); sessions.sort(new DateHolderRecentComparator()); - + int i = 0; for (Session session : sessions) { if (i >= maxSessions) { @@ -93,17 +101,17 @@ public class SessionAccordion extends AbstractAccordion { String serverName = serverNames.getOrDefault(session.getValue(SessionKeys.SERVER_UUID).orElse(null), "Unknown"); String playerName = playerNames.getOrDefault(session.getValue(SessionKeys.UUID).orElse(null), "Unknown"); - String sessionStart = timeStampFormatter.apply(session); + String sessionStart = yearFormatter.apply(session); WorldTimes worldTimes = session.getValue(SessionKeys.WORLD_TIMES).orElse(new WorldTimes(new HashMap<>())); - WorldPie worldPie = new WorldPie(worldTimes); - String longestWorldPlayed = session.getValue(SessionKeys.LONGEST_WORLD_PLAYED).orElse("Unknown"); + WorldPie worldPie = graphs.pie().worldPie(worldTimes); + String longestWorldPlayed = worldAliasSettings.getLongestWorldPlayed(session); boolean hasEnded = session.supports(SessionKeys.END); - String sessionEnd = hasEnded ? timeStampFormatter.apply(() -> session.getUnsafe(SessionKeys.END)) : "Online"; + String sessionEnd = hasEnded ? yearFormatter.apply(() -> session.getUnsafe(SessionKeys.END)) : "Online"; - String length = (hasEnded ? "" : "(Online) ") + timeFormatter.apply(session.getValue(SessionKeys.LENGTH).orElse(0L)); - String afk = (hasEnded ? "" : "(Inaccurate) ") + timeFormatter.apply(session.getValue(SessionKeys.AFK_TIME).orElse(0L)); + String length = (hasEnded ? "" : "(Online) ") + timeAmountFormatter.apply(session.getValue(SessionKeys.LENGTH).orElse(0L)); + String afk = (hasEnded ? "" : "(Inaccurate) ") + timeAmountFormatter.apply(session.getValue(SessionKeys.AFK_TIME).orElse(0L)); int playerKillCount = session.getValue(SessionKeys.PLAYER_KILL_COUNT).orElse(0); int mobKillCount = session.getValue(SessionKeys.MOB_KILL_COUNT).orElse(0); @@ -138,7 +146,8 @@ public class SessionAccordion extends AbstractAccordion { .append(worldHtmlID).append("gmseries") .append(");"); - String leftBottom = new KillsTable(session.getValue(SessionKeys.PLAYER_KILLS).orElse(new ArrayList<>()), null).parseHtml(); + List kills = session.getValue(SessionKeys.PLAYER_KILLS).orElse(new ArrayList<>()); + String leftBottom = tables.killsTable(kills, null).parseHtml(); String link = PlanAPI.getInstance().getPlayerInspectPageLink(playerName); String rightBottom = ""; addElement(new AccordionElement(htmlID, title) - .setColor(Theme.getValue(ThemeVal.PARSED_SESSION_ACCORDION)) + .setColor(theme.getValue(ThemeVal.PARSED_SESSION_ACCORDION)) .setLeftSide(leftSide + leftBottom) .setRightSide(rightSide + rightBottom)); i++; @@ -155,8 +164,6 @@ public class SessionAccordion extends AbstractAccordion { private void addElementsForPlayer() { Map serverNames = serverNamesSupplier.get(); - Formatter timeFormatter = Formatters.timeAmount(); - Formatter timeStampFormatter = Formatters.year(); sessions.sort(new DateHolderRecentComparator()); int i = 0; @@ -166,17 +173,17 @@ public class SessionAccordion extends AbstractAccordion { } String serverName = serverNames.getOrDefault(session.getValue(SessionKeys.SERVER_UUID).orElse(null), "Unknown"); - String sessionStart = timeStampFormatter.apply(session); + String sessionStart = yearFormatter.apply(session); WorldTimes worldTimes = session.getValue(SessionKeys.WORLD_TIMES).orElse(new WorldTimes(new HashMap<>())); - WorldPie worldPie = new WorldPie(worldTimes); - String longestWorldPlayed = session.getValue(SessionKeys.LONGEST_WORLD_PLAYED).orElse("Unknown"); + WorldPie worldPie = graphs.pie().worldPie(worldTimes); + String longestWorldPlayed = worldAliasSettings.getLongestWorldPlayed(session); boolean hasEnded = session.supports(SessionKeys.END); - String sessionEnd = hasEnded ? timeStampFormatter.apply(() -> session.getValue(SessionKeys.END).orElse(0L)) : "Online"; + String sessionEnd = hasEnded ? yearFormatter.apply(() -> session.getValue(SessionKeys.END).orElse(0L)) : "Online"; - String length = (hasEnded ? "" : "(Online) ") + timeFormatter.apply(session.getValue(SessionKeys.LENGTH).orElse(0L)); - String afk = (hasEnded ? "" : "(Inaccurate) ") + timeFormatter.apply(session.getValue(SessionKeys.AFK_TIME).orElse(0L)); + String length = (hasEnded ? "" : "(Online) ") + timeAmountFormatter.apply(session.getValue(SessionKeys.LENGTH).orElse(0L)); + String afk = (hasEnded ? "" : "(Inaccurate) ") + timeAmountFormatter.apply(session.getValue(SessionKeys.AFK_TIME).orElse(0L)); int playerKillCount = session.getValue(SessionKeys.PLAYER_KILL_COUNT).orElse(0); int mobKillCount = session.getValue(SessionKeys.MOB_KILL_COUNT).orElse(0); @@ -211,10 +218,11 @@ public class SessionAccordion extends AbstractAccordion { .append(worldHtmlID).append("gmseries") .append(");"); - String leftBottom = new KillsTable(session.getValue(SessionKeys.PLAYER_KILLS).orElse(new ArrayList<>()), null).parseHtml(); + List kills = session.getValue(SessionKeys.PLAYER_KILLS).orElse(new ArrayList<>()); + String leftBottom = tables.killsTable(kills, null).parseHtml(); addElement(new AccordionElement(htmlID, title) - .setColor(Theme.getValue(ThemeVal.PARSED_SESSION_ACCORDION)) + .setColor(theme.getValue(ThemeVal.PARSED_SESSION_ACCORDION)) .setLeftSide(leftSide + leftBottom) .setRightSide(rightSide)); diff --git a/Plan/src/main/java/com/djrapitops/plan/utilities/html/tables/CommandUseTable.java b/Plan/src/main/java/com/djrapitops/plan/utilities/html/tables/CommandUseTable.java index ca3a4601c..b41df50f6 100644 --- a/Plan/src/main/java/com/djrapitops/plan/utilities/html/tables/CommandUseTable.java +++ b/Plan/src/main/java/com/djrapitops/plan/utilities/html/tables/CommandUseTable.java @@ -3,27 +3,26 @@ package com.djrapitops.plan.utilities.html.tables; import com.djrapitops.plan.data.element.TableContainer; import com.djrapitops.plan.data.store.containers.DataContainer; import com.djrapitops.plan.data.store.keys.ServerKeys; -import com.djrapitops.plan.utilities.comparators.MapComparator; import com.djrapitops.plan.utilities.html.HtmlUtils; import com.djrapitops.plan.utilities.html.icon.Icon; -import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.stream.Collectors; /** + * Html table that displays how many times each command is used. + * * @author Rsl1122 */ -public class CommandUseTable extends TableContainer { +class CommandUseTable extends TableContainer { - public CommandUseTable(DataContainer container) { - this(container.getValue(ServerKeys.COMMAND_USAGE).orElse(new HashMap<>())); - } - - public CommandUseTable(Map commandUse) { + CommandUseTable(DataContainer container) { super(Icon.called("terminal") + " Command", Icon.called("list-ol") + "Times Used"); + Map commandUse = container.getValue(ServerKeys.COMMAND_USAGE).orElse(new HashMap<>()); + setColor("lime"); if (commandUse.isEmpty()) { addRow("No Commands"); @@ -32,17 +31,22 @@ public class CommandUseTable extends TableContainer { } } + private List> sortByValue(Map map) { + return map.entrySet().stream() + .sorted((one, two) -> Integer.compare(two.getValue(), one.getValue())) + .collect(Collectors.toList()); + } + private void addValues(Map commandUse) { - List sorted = MapComparator.sortByValue(commandUse); - Collections.reverse(sorted); + List> sorted = sortByValue(commandUse); int i = 0; - for (String[] values : sorted) { + for (Map.Entry entry : sorted) { if (i >= 500) { break; } - String command = HtmlUtils.removeXSS(values[1]); - addRow(command, values[0]); + String command = HtmlUtils.removeXSS(entry.getKey()); + addRow(command, entry.getValue()); i++; } diff --git a/Plan/src/main/java/com/djrapitops/plan/utilities/html/tables/DeathsTable.java b/Plan/src/main/java/com/djrapitops/plan/utilities/html/tables/DeathsTable.java index 3c7045e6a..67f3c8277 100644 --- a/Plan/src/main/java/com/djrapitops/plan/utilities/html/tables/DeathsTable.java +++ b/Plan/src/main/java/com/djrapitops/plan/utilities/html/tables/DeathsTable.java @@ -3,11 +3,9 @@ package com.djrapitops.plan.utilities.html.tables; import com.djrapitops.plan.api.PlanAPI; import com.djrapitops.plan.data.container.PlayerDeath; import com.djrapitops.plan.data.element.TableContainer; -import com.djrapitops.plan.data.store.mutators.formatting.Formatter; -import com.djrapitops.plan.data.store.mutators.formatting.Formatters; import com.djrapitops.plan.data.store.objects.DateHolder; -import com.djrapitops.plan.system.cache.DataCache; import com.djrapitops.plan.utilities.comparators.DateHolderRecentComparator; +import com.djrapitops.plan.utilities.formatting.Formatter; import com.djrapitops.plan.utilities.html.Html; import com.djrapitops.plan.utilities.html.icon.Family; import com.djrapitops.plan.utilities.html.icon.Icon; @@ -15,12 +13,17 @@ import com.djrapitops.plan.utilities.html.icon.Icon; import java.util.List; /** + * Html table that displays Deaths of a single player. + * * @author Rsl1122 */ -public class DeathsTable extends TableContainer { +class DeathsTable extends TableContainer { - public DeathsTable(List playerPlayerDeaths) { + private final Formatter yearFormatter; + + DeathsTable(List playerPlayerDeaths, Formatter yearFormatter) { super(Icon.called("clock").of(Family.REGULAR) + " Time", "Killed by", "With"); + this.yearFormatter = yearFormatter; setColor("red"); if (playerPlayerDeaths.isEmpty()) { @@ -32,19 +35,17 @@ public class DeathsTable extends TableContainer { private void addValues(List playerPlayerDeaths) { playerPlayerDeaths.sort(new DateHolderRecentComparator()); - Formatter timestamp = Formatters.year(); int i = 0; - DataCache dataCache = DataCache.getInstance(); for (PlayerDeath death : playerPlayerDeaths) { if (i >= 40) { break; } - String name = dataCache.getName(death.getKiller()); + String killerName = death.getKillerName(); addRow( - timestamp.apply(death), - Html.LINK.parse(PlanAPI.getInstance().getPlayerInspectPageLink(name), name), + yearFormatter.apply(death), + Html.LINK.parse(PlanAPI.getInstance().getPlayerInspectPageLink(killerName), killerName), death.getWeapon() ); diff --git a/Plan/src/main/java/com/djrapitops/plan/utilities/html/tables/GeoInfoTable.java b/Plan/src/main/java/com/djrapitops/plan/utilities/html/tables/GeoInfoTable.java index 7200a5b79..366b36d66 100644 --- a/Plan/src/main/java/com/djrapitops/plan/utilities/html/tables/GeoInfoTable.java +++ b/Plan/src/main/java/com/djrapitops/plan/utilities/html/tables/GeoInfoTable.java @@ -6,11 +6,9 @@ package com.djrapitops.plan.utilities.html.tables; import com.djrapitops.plan.data.container.GeoInfo; import com.djrapitops.plan.data.element.TableContainer; -import com.djrapitops.plan.data.store.mutators.formatting.Formatter; -import com.djrapitops.plan.data.store.mutators.formatting.Formatters; import com.djrapitops.plan.data.store.objects.DateHolder; -import com.djrapitops.plan.system.settings.Settings; import com.djrapitops.plan.utilities.comparators.DateHolderRecentComparator; +import com.djrapitops.plan.utilities.formatting.Formatter; import java.util.List; @@ -19,10 +17,15 @@ import java.util.List; * * @author Rsl1122 */ -public class GeoInfoTable extends TableContainer { +class GeoInfoTable extends TableContainer { - public GeoInfoTable(List geoInfo) { + private final boolean displayIP; + private final Formatter yearFormatter; + + GeoInfoTable(List geoInfo, boolean displayIP, Formatter yearFormatter) { super("IP", "Geolocation", "Last Used"); + this.displayIP = displayIP; + this.yearFormatter = yearFormatter; if (geoInfo.isEmpty()) { addRow("No Connections"); @@ -33,15 +36,12 @@ public class GeoInfoTable extends TableContainer { private void addValues(List geoInfo) { geoInfo.sort(new DateHolderRecentComparator()); - - boolean displayIP = Settings.DISPLAY_PLAYER_IPS.isTrue(); - Formatter formatter = Formatters.year(); for (GeoInfo info : geoInfo) { addRow( displayIP ? info.getIp() : "Hidden (Config)", info.getGeolocation(), - formatter.apply(info) + yearFormatter.apply(info) ); } } diff --git a/Plan/src/main/java/com/djrapitops/plan/utilities/html/tables/HtmlTables.java b/Plan/src/main/java/com/djrapitops/plan/utilities/html/tables/HtmlTables.java new file mode 100644 index 000000000..efbf31485 --- /dev/null +++ b/Plan/src/main/java/com/djrapitops/plan/utilities/html/tables/HtmlTables.java @@ -0,0 +1,170 @@ +package com.djrapitops.plan.utilities.html.tables; + +import com.djrapitops.plan.data.container.*; +import com.djrapitops.plan.data.element.AnalysisContainer; +import com.djrapitops.plan.data.element.TableContainer; +import com.djrapitops.plan.data.plugin.PluginData; +import com.djrapitops.plan.data.store.containers.DataContainer; +import com.djrapitops.plan.data.store.containers.PlayerContainer; +import com.djrapitops.plan.data.store.objects.Nickname; +import com.djrapitops.plan.system.settings.Settings; +import com.djrapitops.plan.system.settings.config.PlanConfig; +import com.djrapitops.plan.utilities.formatting.Formatters; + +import javax.inject.Inject; +import javax.inject.Singleton; +import java.util.Collection; +import java.util.List; +import java.util.Map; +import java.util.UUID; + +/** + * Factory class for objects that represent HTML tables. + * + * @author Rsl1122 + */ +@Singleton +public class HtmlTables { + + private final PlanConfig config; + private final Formatters formatters; + + @Inject + public HtmlTables( + PlanConfig config, + Formatters formatters + ) { + this.config = config; + this.formatters = formatters; + } + + /** + * Create a new Command usage table. + * + * @param container Container that supports ServerKeys.COMMAND_USAGE. + * @return a new {@link CommandUseTable}. + */ + public TableContainer commandUseTable(DataContainer container) { + return new CommandUseTable(container); + } + + /** + * Create a new Deaths table. + * + * @param deaths List of {@link PlayerDeath}s to be added to the table. + * @return a new {@link DeathsTable}. + */ + public TableContainer deathsTable(List deaths) { + return new DeathsTable(deaths, formatters.year()); + } + + /** + * Create a new GeoInfo table. + * + * @param geoInfo List of {@link GeoInfo} to be added to the table. + * @return a new {@link GeoInfoTable}. + */ + public TableContainer geoInfoTable(List geoInfo) { + return new GeoInfoTable(geoInfo, config.isTrue(Settings.DISPLAY_PLAYER_IPS), formatters.year()); + } + + /** + * Create a new Kill table. + * + * @param kills List of {@link PlayerKill]s to be added to the table. + * @param color Color the table header should be. + * @return a new {@link KillsTable}. + */ + public TableContainer killsTable(List kills, String color) { + return new KillsTable(kills, color, formatters.year()); + } + + /** + * Create a new Nickname table. + * + * @param nicknames List of {@link Nickname}s to be added to the table. + * @param serverNames Names of the servers, for the server column. // TODO Move Server names to Nickname object. + * @return a new {@link NicknameTable}. + */ + public TableContainer nicknameTable(List nicknames, Map serverNames) { + return new NicknameTable(nicknames, serverNames, formatters.year()); + } + + /** + * Create a new Country - Ping table. + * + * @param pingPerCountry Map of {@link Ping}s sorted by country names. + * @return a new {@link PingTable}. + */ + public TableContainer pingTable(Map> pingPerCountry) { + return new PingTable(pingPerCountry, formatters.decimals()); + } + + /** + * Create a new Session table for a player. + * + * @param playerName Name of the player. + * @param sessions List of {@link Session}s the player has. + * @return a new {@link PlayerSessionTable}. + */ + public TableContainer playerSessionTable(String playerName, List sessions) { + return new PlayerSessionTable( + playerName, sessions, + config.getNumber(Settings.MAX_SESSIONS), config.getWorldAliasSettings(), formatters.year(), formatters.timeAmount() + ); + } + + /** + * Create a new Session table for a server. + * + * @param playerNames Map of UUID - Name pairs of the players. // TODO Move Player names to Session object. + * @param sessions List of {@link Session}s that occurred on the server. + * @return a new {@link ServerSessionTable}. + */ + public TableContainer serverSessionTable(Map playerNames, List sessions) { + return new ServerSessionTable( + playerNames, sessions, + config.getNumber(Settings.MAX_SESSIONS), config.getWorldAliasSettings(), formatters.year(), formatters.timeAmount() + ); + } + + /** + * Create a Player table for a server. + * + * @param players List of {@link PlayerContainer}s of players who have played on the server. + * @return a new {@link PlayersTable}. + */ + public TableContainer playerTableForServerPage(List players) { + return new PlayersTable( + players, + config.getNumber(Settings.MAX_PLAYERS), + config.getNumber(Settings.ACTIVE_PLAY_THRESHOLD), + config.getNumber(Settings.ACTIVE_LOGIN_THRESHOLD), + formatters.timeAmount(), formatters.yearLong(), formatters.decimals() + ); + } + + /** + * Create a Player table for a players page. + * + * @param players List of {@link PlayerContainer}s of players. + * @return a new {@link PlayersTable}. + */ + public TableContainer playerTableForPlayersPage(List players) { + return new PlayersTable( + players, config.getNumber(Settings.MAX_PLAYERS_PLAYERS_PAGE), + config.getNumber(Settings.ACTIVE_PLAY_THRESHOLD), config.getNumber(Settings.ACTIVE_LOGIN_THRESHOLD), formatters.timeAmount(), formatters.yearLong(), formatters.decimals() + ); + } + + /** + * Create a new Player table that contains Plugin Data. + * + * @param containers PluginData AnalysisContainers. + * @param players List of {@link PlayerContainer}s of players. + * @return a new {@link PluginPlayersTable}. + */ + public TableContainer pluginPlayersTable(Map containers, Collection players) { + return new PluginPlayersTable(containers, players, config.getNumber(Settings.MAX_PLAYERS)); + } +} \ No newline at end of file diff --git a/Plan/src/main/java/com/djrapitops/plan/utilities/html/tables/KillsTable.java b/Plan/src/main/java/com/djrapitops/plan/utilities/html/tables/KillsTable.java index 8e2e1a00e..2f0317219 100644 --- a/Plan/src/main/java/com/djrapitops/plan/utilities/html/tables/KillsTable.java +++ b/Plan/src/main/java/com/djrapitops/plan/utilities/html/tables/KillsTable.java @@ -3,11 +3,9 @@ package com.djrapitops.plan.utilities.html.tables; import com.djrapitops.plan.api.PlanAPI; import com.djrapitops.plan.data.container.PlayerKill; import com.djrapitops.plan.data.element.TableContainer; -import com.djrapitops.plan.data.store.mutators.formatting.Formatter; -import com.djrapitops.plan.data.store.mutators.formatting.Formatters; import com.djrapitops.plan.data.store.objects.DateHolder; -import com.djrapitops.plan.system.cache.DataCache; import com.djrapitops.plan.utilities.comparators.DateHolderRecentComparator; +import com.djrapitops.plan.utilities.formatting.Formatter; import com.djrapitops.plan.utilities.html.Html; import com.djrapitops.plan.utilities.html.icon.Family; import com.djrapitops.plan.utilities.html.icon.Icon; @@ -15,18 +13,20 @@ import com.djrapitops.plan.utilities.html.icon.Icon; import java.util.List; /** + * Html table that displays kills Player has performed. + * * @author Rsl1122 */ -public class KillsTable extends TableContainer { +class KillsTable extends TableContainer { - public KillsTable(List playerKills) { - this(playerKills, "red"); - } + private final Formatter yearFormatter; - public KillsTable(List playerKills, String color) { + KillsTable(List playerKills, String color, Formatter yearFormatter) { super(Icon.called("clock").of(Family.REGULAR) + " Time", "Killed", "With"); setColor(color); + this.yearFormatter = yearFormatter; + if (playerKills.isEmpty()) { addRow("No Kills"); } else { @@ -36,19 +36,17 @@ public class KillsTable extends TableContainer { private void addValues(List playerKills) { playerKills.sort(new DateHolderRecentComparator()); - Formatter timestamp = Formatters.year(); int i = 0; - DataCache dataCache = DataCache.getInstance(); for (PlayerKill kill : playerKills) { if (i >= 40) { break; } - String name = dataCache.getName(kill.getVictim()); + String victimName = kill.getVictimName().orElse("Unknown"); addRow( - timestamp.apply(kill), - Html.LINK.parse(PlanAPI.getInstance().getPlayerInspectPageLink(name), name), + yearFormatter.apply(kill), + Html.LINK.parse(PlanAPI.getInstance().getPlayerInspectPageLink(victimName), victimName), kill.getWeapon() ); diff --git a/Plan/src/main/java/com/djrapitops/plan/utilities/html/tables/NicknameTable.java b/Plan/src/main/java/com/djrapitops/plan/utilities/html/tables/NicknameTable.java index e264a6ba8..95b3dfb0a 100644 --- a/Plan/src/main/java/com/djrapitops/plan/utilities/html/tables/NicknameTable.java +++ b/Plan/src/main/java/com/djrapitops/plan/utilities/html/tables/NicknameTable.java @@ -5,11 +5,10 @@ package com.djrapitops.plan.utilities.html.tables; import com.djrapitops.plan.data.element.TableContainer; -import com.djrapitops.plan.data.store.mutators.formatting.Formatter; -import com.djrapitops.plan.data.store.mutators.formatting.Formatters; import com.djrapitops.plan.data.store.objects.DateHolder; import com.djrapitops.plan.data.store.objects.Nickname; import com.djrapitops.plan.utilities.comparators.DateHolderRecentComparator; +import com.djrapitops.plan.utilities.formatting.Formatter; import com.djrapitops.plan.utilities.html.HtmlUtils; import java.util.List; @@ -17,14 +16,17 @@ import java.util.Map; import java.util.UUID; /** - * Utility Class for creating Nicknames Table for inspect page. + * Html table that displays player's nicknames and where they were seen. * * @author Rsl1122 */ -public class NicknameTable extends TableContainer { +class NicknameTable extends TableContainer { - public NicknameTable(List nicknames, Map serverNames) { + private final Formatter yearFormatter; + + NicknameTable(List nicknames, Map serverNames, Formatter yearFormatter) { super("Nickname", "Server", "Last Seen"); + this.yearFormatter = yearFormatter; if (nicknames.isEmpty()) { addRow("No Nicknames"); @@ -36,14 +38,13 @@ public class NicknameTable extends TableContainer { private void addValues(List nicknames, Map serverNames) { nicknames.sort(new DateHolderRecentComparator()); - Formatter formatter = Formatters.year(); for (Nickname nickname : nicknames) { UUID serverUUID = nickname.getServerUUID(); String serverName = serverNames.getOrDefault(serverUUID, "Unknown"); addRow( HtmlUtils.swapColorsToSpan(HtmlUtils.removeXSS(nickname.getName())), serverName, - formatter.apply(nickname) + yearFormatter.apply(nickname) ); } } diff --git a/Plan/src/main/java/com/djrapitops/plan/utilities/html/tables/PingTable.java b/Plan/src/main/java/com/djrapitops/plan/utilities/html/tables/PingTable.java index 7478d5fcc..e8254e4e9 100644 --- a/Plan/src/main/java/com/djrapitops/plan/utilities/html/tables/PingTable.java +++ b/Plan/src/main/java/com/djrapitops/plan/utilities/html/tables/PingTable.java @@ -3,20 +3,28 @@ package com.djrapitops.plan.utilities.html.tables; import com.djrapitops.plan.data.container.Ping; import com.djrapitops.plan.data.element.TableContainer; import com.djrapitops.plan.data.store.mutators.PingMutator; -import com.djrapitops.plan.utilities.FormatUtils; +import com.djrapitops.plan.utilities.formatting.Formatter; import com.djrapitops.plan.utilities.html.icon.Icon; import java.util.*; -public class PingTable extends TableContainer { +/** + * Html table that displays countries and their average, worst and best pings. + * + * @author Rsl1122 + */ +class PingTable extends TableContainer { - public PingTable(Map> pingPerCountry) { + private final Formatter decimalFormatter; + + PingTable(Map> pingPerCountry, Formatter decimalFormatter) { super( Icon.called("globe") + " Country", Icon.called("signal") + " Average Ping", Icon.called("signal") + " Worst Ping", Icon.called("signal") + " Best Ping" ); + this.decimalFormatter = decimalFormatter; setColor("amber"); addRows(pingPerCountry); @@ -44,7 +52,7 @@ public class PingTable extends TableContainer { Integer minimum = min.get(country); addRow( country, - average >= 0 ? FormatUtils.cutDecimals(average) + " ms" : "-", + average >= 0 ? decimalFormatter.apply(average) + " ms" : "-", maximum >= 0 ? maximum + " ms" : "-", minimum >= 0 ? minimum + " ms" : "-" ); diff --git a/Plan/src/main/java/com/djrapitops/plan/utilities/html/tables/PlayerSessionTable.java b/Plan/src/main/java/com/djrapitops/plan/utilities/html/tables/PlayerSessionTable.java index 916788100..966d0cdda 100644 --- a/Plan/src/main/java/com/djrapitops/plan/utilities/html/tables/PlayerSessionTable.java +++ b/Plan/src/main/java/com/djrapitops/plan/utilities/html/tables/PlayerSessionTable.java @@ -3,47 +3,47 @@ package com.djrapitops.plan.utilities.html.tables; import com.djrapitops.plan.api.PlanAPI; import com.djrapitops.plan.data.container.Session; import com.djrapitops.plan.data.element.TableContainer; -import com.djrapitops.plan.data.store.containers.DataContainer; -import com.djrapitops.plan.data.store.keys.PlayerKeys; import com.djrapitops.plan.data.store.keys.SessionKeys; -import com.djrapitops.plan.data.store.mutators.formatting.Formatters; -import com.djrapitops.plan.system.settings.Settings; +import com.djrapitops.plan.data.store.objects.DateHolder; +import com.djrapitops.plan.system.settings.WorldAliasSettings; +import com.djrapitops.plan.utilities.formatting.Formatter; import com.djrapitops.plan.utilities.html.Html; -import java.util.ArrayList; import java.util.List; /** - * TableContainer for a Session table for a single player. + * Html table that can be used to replace a {@link com.djrapitops.plan.utilities.html.structure.SessionAccordion}. * * @author Rsl1122 */ -public class PlayerSessionTable extends TableContainer { +class PlayerSessionTable extends TableContainer { + + private final int maxSessions; + private final WorldAliasSettings worldAliasSettings; + private final Formatter yearFormatter; + private final Formatter timeAmountFormatter; private final String playerName; private final List sessions; - public static PlayerSessionTable forContainer(DataContainer container) { - return new PlayerSessionTable( - container.getValue(PlayerKeys.NAME).orElse("Unknown"), - container.getValue(PlayerKeys.SESSIONS).orElse(new ArrayList<>()) - ); - } - - public PlayerSessionTable(String playerName, List sessions) { + PlayerSessionTable(String playerName, List sessions, + int maxSessions, + WorldAliasSettings worldAliasSettings, + Formatter yearFormatter, + Formatter timeAmountFormatter + ) { super("Player", "Start", "Length", "World"); this.playerName = playerName; this.sessions = sessions; + this.maxSessions = maxSessions; + this.worldAliasSettings = worldAliasSettings; + this.yearFormatter = yearFormatter; + this.timeAmountFormatter = timeAmountFormatter; addRows(); } private void addRows() { - int maxSessions = Settings.MAX_SESSIONS.getNumber(); - if (maxSessions <= 0) { - maxSessions = 50; - } - String inspectUrl = PlanAPI.getInstance().getPlayerInspectPageLink(playerName); int i = 0; @@ -52,11 +52,11 @@ public class PlayerSessionTable extends TableContainer { break; } - String start = Formatters.year().apply(session); + String start = yearFormatter.apply(session); String length = session.supports(SessionKeys.END) - ? Formatters.timeAmount().apply(session.getValue(SessionKeys.LENGTH).orElse(0L)) + ? timeAmountFormatter.apply(session.getValue(SessionKeys.LENGTH).orElse(0L)) : "Online"; - String world = session.getValue(SessionKeys.LONGEST_WORLD_PLAYED).orElse("Unknown"); + String world = worldAliasSettings.getLongestWorldPlayed(session); String toolTip = "Session ID: " + session.getValue(SessionKeys.DB_ID) .map(id -> Integer.toString(id)) diff --git a/Plan/src/main/java/com/djrapitops/plan/utilities/html/tables/PlayersTable.java b/Plan/src/main/java/com/djrapitops/plan/utilities/html/tables/PlayersTable.java index ac4975fe4..732c5fbd4 100644 --- a/Plan/src/main/java/com/djrapitops/plan/utilities/html/tables/PlayersTable.java +++ b/Plan/src/main/java/com/djrapitops/plan/utilities/html/tables/PlayersTable.java @@ -8,9 +8,8 @@ import com.djrapitops.plan.data.store.keys.PlayerKeys; import com.djrapitops.plan.data.store.mutators.ActivityIndex; import com.djrapitops.plan.data.store.mutators.GeoInfoMutator; import com.djrapitops.plan.data.store.mutators.SessionsMutator; -import com.djrapitops.plan.data.store.mutators.formatting.Formatters; -import com.djrapitops.plan.system.settings.Settings; import com.djrapitops.plan.utilities.comparators.PlayerContainerLastPlayedComparator; +import com.djrapitops.plan.utilities.formatting.Formatter; import com.djrapitops.plan.utilities.html.Html; import com.djrapitops.plan.utilities.html.icon.Family; import com.djrapitops.plan.utilities.html.icon.Icon; @@ -18,16 +17,28 @@ import com.djrapitops.plan.utilities.html.icon.Icon; import java.util.List; /** - * Utility for creating Players table html. + * Html table that displays a lot of information about players. * * @author Rsl1122 */ -public class PlayersTable extends TableContainer { +class PlayersTable extends TableContainer { private final List players; private final int maxPlayers; + private final int activeMinuteThreshold; + private final int activeLoginThreshold; - private PlayersTable(List players, int maxPlayers) { + private final Formatter decimalFormatter; + + PlayersTable( + List players, + int maxPlayers, + int activeMinuteThreshold, + int activeLoginThreshold, + Formatter timeAmountFormatter, + Formatter yearLongFormatter, + Formatter decimalFormatter + ) { super( Icon.called("user") + " Name", Icon.called("check") + " Activity Index", @@ -39,22 +50,17 @@ public class PlayersTable extends TableContainer { ); this.players = players; this.maxPlayers = maxPlayers; + this.activeMinuteThreshold = activeMinuteThreshold; + this.activeLoginThreshold = activeLoginThreshold; + this.decimalFormatter = decimalFormatter; useJqueryDataTables("player-table"); - setFormatter(2, Formatters.timeAmount()); - setFormatter(4, Formatters.yearLongValue()); - setFormatter(5, Formatters.yearLongValue()); + setFormatter(2, timeAmountFormatter); + setFormatter(4, yearLongFormatter); + setFormatter(5, yearLongFormatter); addRows(); } - public static PlayersTable forServerPage(List players) { - return new PlayersTable(players, Settings.MAX_PLAYERS.getNumber()); - } - - public static PlayersTable forPlayersPage(List players) { - return new PlayersTable(players, Settings.MAX_PLAYERS_PLAYERS_PAGE.getNumber()); - } - private void addRows() { PlanAPI planAPI = PlanAPI.getInstance(); long now = System.currentTimeMillis(); @@ -75,9 +81,9 @@ public class PlayersTable extends TableContainer { long registered = player.getValue(PlayerKeys.REGISTERED).orElse(0L); long lastSeen = sessionsMutator.toLastSeen(); - ActivityIndex activityIndex = player.getActivityIndex(now); + ActivityIndex activityIndex = player.getActivityIndex(now, activeMinuteThreshold, activeLoginThreshold); boolean isBanned = player.getValue(PlayerKeys.BANNED).orElse(false); - String activityString = activityIndex.getFormattedValue() + String activityString = activityIndex.getFormattedValue(decimalFormatter) + (isBanned ? " (Banned)" : " (" + activityIndex.getGroup() + ")"); String geolocation = GeoInfoMutator.forContainer(player).mostRecent().map(GeoInfo::getGeolocation).orElse("-"); diff --git a/Plan/src/main/java/com/djrapitops/plan/utilities/html/tables/PluginPlayersTable.java b/Plan/src/main/java/com/djrapitops/plan/utilities/html/tables/PluginPlayersTable.java index 558de9b3e..6bbe3c95f 100644 --- a/Plan/src/main/java/com/djrapitops/plan/utilities/html/tables/PluginPlayersTable.java +++ b/Plan/src/main/java/com/djrapitops/plan/utilities/html/tables/PluginPlayersTable.java @@ -6,31 +6,41 @@ import com.djrapitops.plan.data.element.TableContainer; import com.djrapitops.plan.data.plugin.PluginData; import com.djrapitops.plan.data.store.containers.PlayerContainer; import com.djrapitops.plan.data.store.keys.PlayerKeys; -import com.djrapitops.plan.system.settings.Settings; -import com.djrapitops.plan.utilities.FormatUtils; import com.djrapitops.plan.utilities.html.Html; +import com.djrapitops.plugin.utilities.ArrayUtil; import org.apache.commons.lang3.ArrayUtils; import java.io.Serializable; import java.util.*; /** - * TableContainer that creates the html table for per player plugins values. + * Html table that displays players data in various plugins. * * @author Rsl1122 */ -public class PluginPlayersTable extends TableContainer { +class PluginPlayersTable extends TableContainer { private Collection players; - public PluginPlayersTable(Map containers, Collection players) { - this(getPluginDataSet(containers), players); + private final int maxPlayers; + + PluginPlayersTable( + Map containers, + Collection players, + int maxPlayers + ) { + this(getPluginDataSet(containers), players, maxPlayers); } - private PluginPlayersTable(TreeMap> pluginDataSet, Collection players) { + private PluginPlayersTable( + TreeMap> pluginDataSet, + Collection players, + int maxPlayers + ) { super(true, getHeaders(pluginDataSet.keySet())); this.players = players; + this.maxPlayers = maxPlayers; useJqueryDataTables("player-plugin-table"); @@ -61,10 +71,6 @@ public class PluginPlayersTable extends TableContainer { private void addValues(Map rows) { int i = 0; - int maxPlayers = Settings.MAX_PLAYERS.getNumber(); - if (maxPlayers <= 0) { - maxPlayers = 2000; - } for (PlayerContainer profile : players) { if (i >= maxPlayers) { break; @@ -73,7 +79,7 @@ public class PluginPlayersTable extends TableContainer { String name = profile.getValue(PlayerKeys.NAME).orElse("Unknown"); String link = Html.LINK_EXTERNAL.parse(PlanAPI.getInstance().getPlayerInspectPageLink(name), name); - String[] playerData = FormatUtils.mergeArrays(new String[]{link}, rows.getOrDefault(uuid, new String[]{})); + String[] playerData = ArrayUtil.merge(new String[]{link}, rows.getOrDefault(uuid, new String[]{})); addRow(ArrayUtils.addAll(playerData)); i++; diff --git a/Plan/src/main/java/com/djrapitops/plan/utilities/html/tables/ServerSessionTable.java b/Plan/src/main/java/com/djrapitops/plan/utilities/html/tables/ServerSessionTable.java index a4f2fbfc3..ded4fa860 100644 --- a/Plan/src/main/java/com/djrapitops/plan/utilities/html/tables/ServerSessionTable.java +++ b/Plan/src/main/java/com/djrapitops/plan/utilities/html/tables/ServerSessionTable.java @@ -4,8 +4,9 @@ import com.djrapitops.plan.api.PlanAPI; import com.djrapitops.plan.data.container.Session; import com.djrapitops.plan.data.element.TableContainer; import com.djrapitops.plan.data.store.keys.SessionKeys; -import com.djrapitops.plan.data.store.mutators.formatting.Formatters; -import com.djrapitops.plan.system.settings.Settings; +import com.djrapitops.plan.data.store.objects.DateHolder; +import com.djrapitops.plan.system.settings.WorldAliasSettings; +import com.djrapitops.plan.utilities.formatting.Formatter; import com.djrapitops.plan.utilities.html.Html; import java.util.List; @@ -13,40 +14,50 @@ import java.util.Map; import java.util.UUID; /** - * TableContainer for a Session table for a single player. + * Html table that can be used to replace a {@link com.djrapitops.plan.utilities.html.structure.SessionAccordion}. * * @author Rsl1122 */ -public class ServerSessionTable extends TableContainer { +class ServerSessionTable extends TableContainer { + + private final int maxSessions; + private final WorldAliasSettings worldAliasSettings; + private final Formatter yearFormatter; + private final Formatter timeAmountFormatter; private final List sessions; private Map playerNames; - public ServerSessionTable(Map playerNames, List sessions) { + ServerSessionTable( + Map playerNames, List sessions, + int maxSessions, + WorldAliasSettings worldAliasSettings, + Formatter yearFormatter, + Formatter timeAmountFormatter + ) { super("Player", "Start", "Length", "World"); this.playerNames = playerNames; this.sessions = sessions; + this.maxSessions = maxSessions; + this.worldAliasSettings = worldAliasSettings; + this.yearFormatter = yearFormatter; + this.timeAmountFormatter = timeAmountFormatter; addRows(); } private void addRows() { - int maxSessions = Settings.MAX_SESSIONS.getNumber(); - if (maxSessions <= 0) { - maxSessions = 50; - } - int i = 0; for (Session session : sessions) { if (i >= maxSessions) { break; } - String start = Formatters.year().apply(session); + String start = yearFormatter.apply(session); String length = session.supports(SessionKeys.END) - ? Formatters.timeAmount().apply(session.getValue(SessionKeys.LENGTH).orElse(0L)) + ? timeAmountFormatter.apply(session.getValue(SessionKeys.LENGTH).orElse(0L)) : "Online"; - String world = session.getValue(SessionKeys.LONGEST_WORLD_PLAYED).orElse("Unknown"); + String world = worldAliasSettings.getLongestWorldPlayed(session); String toolTip = "Session ID: " + session.getValue(SessionKeys.DB_ID) .map(id -> Integer.toString(id)) diff --git a/Plan/src/main/java/com/djrapitops/plan/utilities/metrics/BStatsBukkit.java b/Plan/src/main/java/com/djrapitops/plan/utilities/metrics/BStatsBukkit.java index 2b3e3a7a3..1ac0f7de9 100644 --- a/Plan/src/main/java/com/djrapitops/plan/utilities/metrics/BStatsBukkit.java +++ b/Plan/src/main/java/com/djrapitops/plan/utilities/metrics/BStatsBukkit.java @@ -1,9 +1,7 @@ package com.djrapitops.plan.utilities.metrics; import com.djrapitops.plan.Plan; -import com.djrapitops.plan.system.database.databases.Database; import com.djrapitops.plugin.api.Check; -import com.djrapitops.plugin.api.utility.log.Log; import org.bstats.bukkit.Metrics; public class BStatsBukkit { @@ -16,7 +14,6 @@ public class BStatsBukkit { } public void registerMetrics() { - Log.logDebug("Enable", "Enabling bStats Metrics."); if (metrics == null) { metrics = new Metrics(plugin); } @@ -28,7 +25,7 @@ public class BStatsBukkit { if ("CraftBukkit".equals(serverType) && Check.isSpigotAvailable()) { serverType = "Spigot"; } - String databaseType = Database.getActive().getName(); + String databaseType = plugin.getSystem().getDatabaseSystem().getDatabase().getName(); addStringSettingPie("server_type", serverType); addStringSettingPie("database_type", databaseType); diff --git a/Plan/src/main/java/com/djrapitops/plan/utilities/metrics/BStatsBungee.java b/Plan/src/main/java/com/djrapitops/plan/utilities/metrics/BStatsBungee.java index 42a4af38b..21c7fbdb9 100644 --- a/Plan/src/main/java/com/djrapitops/plan/utilities/metrics/BStatsBungee.java +++ b/Plan/src/main/java/com/djrapitops/plan/utilities/metrics/BStatsBungee.java @@ -3,7 +3,6 @@ package com.djrapitops.plan.utilities.metrics; import com.djrapitops.plan.PlanBungee; import com.djrapitops.plan.system.database.databases.Database; import com.djrapitops.plan.system.info.connection.ConnectionSystem; -import com.djrapitops.plugin.api.utility.log.Log; import org.bstats.bungeecord.Metrics; import java.io.Serializable; @@ -11,14 +10,18 @@ import java.io.Serializable; public class BStatsBungee { private final PlanBungee plugin; + private final Database database; + private final ConnectionSystem connectionSystem; + private Metrics metrics; - public BStatsBungee(PlanBungee plugin) { + public BStatsBungee(PlanBungee plugin, Database database, ConnectionSystem connectionSystem) { this.plugin = plugin; + this.database = database; + this.connectionSystem = connectionSystem; } public void registerMetrics() { - Log.logDebug("Enable", "Enabling bStats Metrics."); if (metrics == null) { metrics = new Metrics(plugin); } @@ -27,11 +30,11 @@ public class BStatsBungee { private void registerConfigSettingGraphs() { String serverType = plugin.getProxy().getName(); - String databaseType = Database.getActive().getName(); + String databaseType = database.getName(); addStringSettingPie("server_type", serverType); addStringSettingPie("database_type", databaseType); - addStringSettingPie("network_servers", ConnectionSystem.getInstance().getBukkitServers().size()); + addStringSettingPie("network_servers", connectionSystem.getBukkitServers().size()); } protected void addStringSettingPie(String id, Serializable setting) { diff --git a/Plan/src/main/java/com/djrapitops/plan/utilities/metrics/BStatsSponge.java b/Plan/src/main/java/com/djrapitops/plan/utilities/metrics/BStatsSponge.java index 15c2cd6c3..bae02213d 100644 --- a/Plan/src/main/java/com/djrapitops/plan/utilities/metrics/BStatsSponge.java +++ b/Plan/src/main/java/com/djrapitops/plan/utilities/metrics/BStatsSponge.java @@ -1,8 +1,6 @@ package com.djrapitops.plan.utilities.metrics; import com.djrapitops.plan.system.database.databases.Database; -import com.djrapitops.plan.system.info.connection.ConnectionSystem; -import com.djrapitops.plugin.api.utility.log.Log; import org.bstats.sponge.Metrics; import java.io.Serializable; @@ -10,27 +8,25 @@ import java.io.Serializable; public class BStatsSponge { private final Metrics metrics; + private final Database database; - public BStatsSponge(Metrics metrics) { + public BStatsSponge(Metrics metrics, Database database) { this.metrics = metrics; + this.database = database; } public void registerMetrics() { - Log.logDebug("Enable", "Enabling bStats Metrics."); if (metrics != null) { registerConfigSettingGraphs(); - } else { - Log.debug("Metrics not injected properly."); } } private void registerConfigSettingGraphs() { String serverType = "Sponge"; - String databaseType = Database.getActive().getName(); + String databaseType = database.getName(); addStringSettingPie("server_type", serverType); addStringSettingPie("database_type", databaseType); - addStringSettingPie("network_servers", ConnectionSystem.getInstance().getBukkitServers().size()); } protected void addStringSettingPie(String id, Serializable setting) { diff --git a/Plan/src/main/java/com/djrapitops/plan/utilities/uuid/UUIDUtility.java b/Plan/src/main/java/com/djrapitops/plan/utilities/uuid/UUIDUtility.java index c52d4cfc5..958768918 100644 --- a/Plan/src/main/java/com/djrapitops/plan/utilities/uuid/UUIDUtility.java +++ b/Plan/src/main/java/com/djrapitops/plan/utilities/uuid/UUIDUtility.java @@ -7,58 +7,48 @@ package com.djrapitops.plan.utilities.uuid; import com.djrapitops.plan.api.exceptions.database.DBOpException; import com.djrapitops.plan.system.cache.DataCache; -import com.djrapitops.plan.system.database.databases.Database; -import com.djrapitops.plugin.api.Check; +import com.djrapitops.plan.system.database.DBSystem; import com.djrapitops.plugin.api.utility.UUIDFetcher; -import com.djrapitops.plugin.api.utility.log.Log; +import com.djrapitops.plugin.logging.L; +import com.djrapitops.plugin.logging.error.ErrorHandler; +import javax.inject.Inject; +import javax.inject.Singleton; import java.util.UUID; /** * @author Rsl1122 */ +@Singleton public class UUIDUtility { - /** - * Constructor used to hide the public constructor - */ - private UUIDUtility() { - throw new IllegalStateException("Utility class"); + private final DataCache dataCache; + private final DBSystem dbSystem; + private final ErrorHandler errorHandler; + + @Inject + public UUIDUtility(DataCache dataCache, DBSystem dbSystem, ErrorHandler errorHandler) { + this.dataCache = dataCache; + this.dbSystem = dbSystem; + this.errorHandler = errorHandler; } /** * Get UUID of a player. * * @param playerName Player's name - * @return UUID of the player. - */ - public static UUID getUUIDOf(String playerName) { - try { - return getUUIDOf(playerName, Database.getActive()); - } catch (Exception e) { - return null; - } - } - - /** - * Get UUID of a player. - * - * @param playerName Player's name - * @param db Database to check from. * @return UUID of the player */ - private static UUID getUUIDOf(String playerName, Database db) { + public UUID getUUIDOf(String playerName) { UUID uuid = null; - if (Check.isBukkitAvailable()) { - UUID uuidOf = DataCache.getInstance().getUUIDof(playerName); - if (uuidOf != null) { - return uuidOf; - } + UUID uuidOf = dataCache.getUUIDof(playerName); + if (uuidOf != null) { + return uuidOf; } try { - uuid = db.fetch().getUuidOf(playerName); + uuid = dbSystem.getDatabase().fetch().getUuidOf(playerName); } catch (DBOpException e) { - Log.toLog(UUIDUtility.class, e); + errorHandler.log(L.ERROR, UUIDUtility.class, e); } try { if (uuid == null) { diff --git a/Plan/src/main/resources/bungee.yml b/Plan/src/main/resources/bungee.yml index b165e7633..06db99042 100644 --- a/Plan/src/main/resources/bungee.yml +++ b/Plan/src/main/resources/bungee.yml @@ -1,7 +1,7 @@ name: Plan author: Rsl1122 main: com.djrapitops.plan.PlanBungee -version: 4.4.7 +version: 4.5.0 softdepend: - AdvancedBan - LiteBans diff --git a/Plan/src/main/resources/bungeeconfig.yml b/Plan/src/main/resources/bungeeconfig.yml index 0a659ed81..2b1595155 100644 --- a/Plan/src/main/resources/bungeeconfig.yml +++ b/Plan/src/main/resources/bungeeconfig.yml @@ -12,7 +12,7 @@ Network: Plugin: Debug: 'false' Locale: default - Allow-Update-Command: true + Check-for-updates: true Notify-About-DEV-Releases: false KeepLogsForXDays: 7 @@ -116,33 +116,6 @@ Theme: Font: FontStyleSheet: https://fonts.googleapis.com/css?family=Quicksand:300,400 FontFamily: "'Quicksand', sans-serif" - Color: - Dark: Base - Light: Base - Colors: - Main: Base - Main-Dark: Base - Secondary: Base - Secondary-Dark: Base - Tertiary: Base - Background: Base - Table-Light: Base - Table-Dark: Base - Graphs: - PunchCard: Base - PlayersOnline: Base - TPS: - High: Base - Medium: Base - Low: Base - CPU: Base - RAM: Base - Chunks: Base - Entities: Base - WorldPie: '"#438c99", "#639A67", "#D8EBB5", "#D9BF77", "#0099C6", "#66AA00", "#316395", "#994499", "#22AA99", "#AAAA11", "#6633CC", "#E67300", "#329262", "#5574A6"' - ActivityPie: '"#228B22", "#A9A9A9", "#808080", "#951800"' - ServerPreferencePie: '"#0099C6", "#66AA00", "#316395", "#994499", "#22AA99", "#AAAA11", "#6633CC", "#E67300", "#329262", "#5574A6"' - # ----------------------------------------------------- Servers: Example: diff --git a/Plan/src/main/resources/config.yml b/Plan/src/main/resources/config.yml index 266672566..03e9018b6 100644 --- a/Plan/src/main/resources/config.yml +++ b/Plan/src/main/resources/config.yml @@ -17,7 +17,7 @@ Plugin: Bungee-Override: StandaloneMode: false CopyBungeeConfig: true - Allow-Update-Command: true + Check-for-updates: true Notify-About-DEV-Releases: false KeepLogsForXDays: 7 @@ -138,6 +138,10 @@ Theme: TPS: High-Threshold: 18 Medium-Threshold: 10 + # Free Disk space thresholds, in megabytes. + Disk: + High-Threshold: 500 + Medium-Threshold: 100 # ----------------------------------------------------- Plugins: Factions: diff --git a/Plan/src/main/resources/locale/locale_CN.txt b/Plan/src/main/resources/locale/locale_CN.txt index d7c7c33eb..5d2c3e14c 100644 --- a/Plan/src/main/resources/locale/locale_CN.txt +++ b/Plan/src/main/resources/locale/locale_CN.txt @@ -312,4 +312,26 @@ WebServer - Notify HTTP User Auth || 网页服务器:已禁用 WebServer - Notify no Cert file || 网页服务器:未找到证书密钥存储文件:${0} WebServer FAIL - Port Bind || 未成功初始化网页服务器。端口(${0})是否被占用? WebServer FAIL - SSL Context || 网页服务器:SSL 环境初始化失败。 -WebServer FAIL - Store Load || 网页服务器:SSL 证书载入失败。 \ No newline at end of file +WebServer FAIL - Store Load || 网页服务器:SSL 证书载入失败。 +Yesterday || 'Yesterday' +Today || 'Today' +Health - Active Playtime Comparison Decrease || Active players might be running out of things to do (Played ${0} vs ${1}, last two weeks vs weeks 2-4) +Health - Active Playtime Comparison Increase || Active players seem to have things to do (Played ${0} vs ${1}, last two weeks vs weeks 2-4) +Health - Downtime || Total Server downtime (No Data) was ${0} +Health - New Player Join Players, No || New Players may not have players to play with when they join (${0} on average) +Health - New Player Join Players, Yes || New Players have players to play with when they join (${0} on average) +Health - New Player Stickiness || ${0} of new players have stuck around (${1}/${2}) +Health - No Servers Inaccuracy || No Bukkit/Sponge servers to gather session data - These measures are inaccurate. +Health - Player Play on Network || players played on the network: +Health - Player Register Server || players register on servers per day/server on average. +Health - Player Visit Server || players visit on servers per day/server on average. +Health - Regular Activity Change || Number of regular players has +Health - Regular Activity Change Decrease || decreased (${0}) +Health - Regular Activity Change Increase || increased (+${0}) +Health - Regular Activity Change Zero || stayed the same (+${0}) +Health - Regular Activity Remain || ${0} of regular players have remained active (${1}/${2}) +Health - Single Servers Inaccuracy || Single Bukkit/Sponge server to gather session data. +Health - TPS Above Low Threshold || Average TPS was above Low Threshold ${0} of the time +Health - TPS Low Dips || Average TPS dropped below Low Threshold (${0}) ${1} times +HTML - FREE_DISK_SPACE || Free Disk Space +HTML - DISK_SPACE || DISK SPACE \ No newline at end of file diff --git a/Plan/src/main/resources/locale/locale_CZ.txt b/Plan/src/main/resources/locale/locale_CZ.txt index 29f63a3f2..5edf5c68f 100644 --- a/Plan/src/main/resources/locale/locale_CZ.txt +++ b/Plan/src/main/resources/locale/locale_CZ.txt @@ -312,3 +312,25 @@ WebServer - Notify no Cert file || WebServer: Certificate KeySto WebServer FAIL - Port Bind || WebServer was not initialized successfully. Is the port (${0}) in use? WebServer FAIL - SSL Context || WebServer: SSL Context Initialization Failed. WebServer FAIL - Store Load || WebServer: SSL Certificate loading Failed. +Yesterday || 'Yesterday' +Today || 'Today' +Health - Active Playtime Comparison Decrease || Active players might be running out of things to do (Played ${0} vs ${1}, last two weeks vs weeks 2-4) +Health - Active Playtime Comparison Increase || Active players seem to have things to do (Played ${0} vs ${1}, last two weeks vs weeks 2-4) +Health - Downtime || Total Server downtime (No Data) was ${0} +Health - New Player Join Players, No || New Players may not have players to play with when they join (${0} on average) +Health - New Player Join Players, Yes || New Players have players to play with when they join (${0} on average) +Health - New Player Stickiness || ${0} of new players have stuck around (${1}/${2}) +Health - No Servers Inaccuracy || No Bukkit/Sponge servers to gather session data - These measures are inaccurate. +Health - Player Play on Network || players played on the network: +Health - Player Register Server || players register on servers per day/server on average. +Health - Player Visit Server || players visit on servers per day/server on average. +Health - Regular Activity Change || Number of regular players has +Health - Regular Activity Change Decrease || decreased (${0}) +Health - Regular Activity Change Increase || increased (+${0}) +Health - Regular Activity Change Zero || stayed the same (+${0}) +Health - Regular Activity Remain || ${0} of regular players have remained active (${1}/${2}) +Health - Single Servers Inaccuracy || Single Bukkit/Sponge server to gather session data. +Health - TPS Above Low Threshold || Average TPS was above Low Threshold ${0} of the time +Health - TPS Low Dips || Average TPS dropped below Low Threshold (${0}) ${1} times +HTML - FREE_DISK_SPACE || Free Disk Space +HTML - DISK_SPACE || DISK SPACE \ No newline at end of file diff --git a/Plan/src/main/resources/locale/locale_DE.txt b/Plan/src/main/resources/locale/locale_DE.txt index 26a694b20..08f6d484a 100644 --- a/Plan/src/main/resources/locale/locale_DE.txt +++ b/Plan/src/main/resources/locale/locale_DE.txt @@ -101,7 +101,7 @@ Disable || Player Analytics ausgeschalte Disable - Processing || Verarbeite kritische unverarbeitete Aufgaben. (${0}) Disable - Processing Complete || Verarbeitung komplett. Disable - WebServer || Webserver deaktiviert. -Enable || Player Analytics angeschaltet. +Enable || Player Analytics eingeschaltet. Enable - Database || ${0}-dDatenbankverbindung hergestellt. Enable - Notify Address Confirmation || Versichere dich, dass die Adresse auf DIESEN Server verweist: ${0} Enable - Notify Empty IP || IP in der server.properties ist leer & AlternativeIP ist nicht in Verwendung. Es werden falsche Links verwendet! @@ -243,7 +243,7 @@ HTML - WORLD_PLAYTIME || Spielzeit in der Welt HTML - WORST_PING || Schlechtester Ping HTML ERRORS - ACCESS_DENIED_403 || Zugriff verweigert HTML ERRORS - ANALYSIS_REFRESH || Plan wird aktualisiert... -HTML ERRORS - ANALYSIS_REFRESH_LONG || Plan wird ausgeführt, lade in ein paar Sekunden neu +HTML ERRORS - ANALYSIS_REFRESH_LONG || Plan wird ausgeführt. Es wird in ein paar Sekunden neu geladen. HTML ERRORS - AUTH_FAIL_TIPS_401 || - Stelle sicher, dass du einen Account mit /plan register hinzugefügt hast.
    - Überprüfe, ob Passwort und Benutzername korrekt sind
    - Bei Benutzername und Passwort auf Groß- und Kleinschreibung achten!

    - Wenn du dein Passwort vergessen hast, bitte ein Teammitglied deinen Account zu löschen und neu zu erstellen. HTML ERRORS - AUTHENTICATION_FAIlED_401 || Authentifizierung fehlgeschlagen. HTML ERRORS - FORBIDDEN_403 || Verboten @@ -292,8 +292,8 @@ Manage - Fail, Old version || §eFehlgeschlagen: Veraltete Manage - Fail, Unauthorized || §eFehlgeschlagen: Zugriff verweigert. Server verwendet möglicherweise eine andere Datenbank. Manage - Fail, Unexpected Exception || §eUnerwartete Ausnahme: ${0} Manage - List Importers || Importer: -Manage - Notify External Url || §eNicht-lokale Adresse, ist der Port offen? -Manage - Remind HotSwap || §eDenk dran, zur neuen Datenbank zu wechseln (/plan m hotswap ${0}) und das Plugin neu zu laden. +Manage - Notify External Url || §eNicht-lokale Adresse. Ist der Port offen? +Manage - Remind HotSwap || §eDenk dran, zur neuen Datenbank zu wechseln (/plan m hotswap ${0}) und um das Plugin neu zu laden. Manage - Start || > §2Verarbeite Daten... Manage - Success || > §aErfolgreich! Negative || Nein @@ -312,3 +312,25 @@ WebServer - Notify no Cert file || WebServer: Zertifikat KeyStor WebServer FAIL - Port Bind || WebServer wurde nicht erfolgreich initalisiert. Ist der Port (${0}) schon benutzt? WebServer FAIL - SSL Context || WebServer: SSL Context Initialisierung fehlgeschlagen. WebServer FAIL - Store Load || WebServer: SSL Zertifikat konnte nicht geladen werden. +Yesterday || 'Gestern' +Today || 'Heute' +Health - Active Playtime Comparison Decrease || Aktive Spieler haben möglicherweise nichts mehr zu tun (Gespielt ${0} vs ${1}. Das zeigt der Vergleich der letzten zwei Wochen zu den vorherigen 2 Wochen) +Health - Active Playtime Comparison Increase || Aktive Spieler haben möglicherweise etwas zu tun (Gespielt ${0} vs ${1}. Das zeigt der Vergleich der letzten zwei Wochen zu den vorherigen 2 Wochen) +Health - Downtime || Gesamte Serverdowntime (Keine Daten) war ${0} +Health - New Player Join Players, No || Neue Spieler haben möglicherweise keine anderen Spielern, mit denen sie spielen können. (${0} im Durchschnitt) +Health - New Player Join Players, Yes || Neue Spieler haben andere Spieler, mit denen Spielen können. (${0} im Durchschnitt) +Health - New Player Stickiness || ${0} von den neuen Spieler sind geblieben (${1}/${2}) +Health - No Servers Inaccuracy || Es sind keine Bukkit/Sponge-Server verfügbar um Sessiondaten zu sammeln - Diese Messungen sind ungenau. +Health - Player Play on Network || Spieler spieltn im Netzwerk: +Health - Player Register Server || Spieler wurden auf dem Server pro Tag/Server im Durchschnitt registriert. +Health - Player Visit Server || Spieler haben den Server am Tag/Server im Durchschnitt besucht. +Health - Regular Activity Change || Anzahl an regelmässigen Spielern beträgt +Health - Regular Activity Change Decrease || verringert um (${0}) +Health - Regular Activity Change Increase || Erhöht um (+${0}) +Health - Regular Activity Change Zero || Bleibt gleich (+${0}) +Health - Regular Activity Remain || ${0} von den regelmässigen Spielern sind aktiv geblieben (${1}/${2}) +Health - Single Servers Inaccuracy || Einzelner Bukkit/Sponge um Sessiondaten zu sammelnm. +Health - TPS Above Low Threshold || Durchschnittliche TPS war über der unteren Grenze ${0} in der Zeit. +Health - TPS Low Dips || Durchschnittliche TPS war unter der unteren Grenze. (${0}) ${1} male. +HTML - FREE_DISK_SPACE || Freier Festplattenspeicher +HTML - DISK_SPACE || Festplattenspeicher diff --git a/Plan/src/main/resources/locale/locale_EN.txt b/Plan/src/main/resources/locale/locale_EN.txt index 29f63a3f2..5edf5c68f 100644 --- a/Plan/src/main/resources/locale/locale_EN.txt +++ b/Plan/src/main/resources/locale/locale_EN.txt @@ -312,3 +312,25 @@ WebServer - Notify no Cert file || WebServer: Certificate KeySto WebServer FAIL - Port Bind || WebServer was not initialized successfully. Is the port (${0}) in use? WebServer FAIL - SSL Context || WebServer: SSL Context Initialization Failed. WebServer FAIL - Store Load || WebServer: SSL Certificate loading Failed. +Yesterday || 'Yesterday' +Today || 'Today' +Health - Active Playtime Comparison Decrease || Active players might be running out of things to do (Played ${0} vs ${1}, last two weeks vs weeks 2-4) +Health - Active Playtime Comparison Increase || Active players seem to have things to do (Played ${0} vs ${1}, last two weeks vs weeks 2-4) +Health - Downtime || Total Server downtime (No Data) was ${0} +Health - New Player Join Players, No || New Players may not have players to play with when they join (${0} on average) +Health - New Player Join Players, Yes || New Players have players to play with when they join (${0} on average) +Health - New Player Stickiness || ${0} of new players have stuck around (${1}/${2}) +Health - No Servers Inaccuracy || No Bukkit/Sponge servers to gather session data - These measures are inaccurate. +Health - Player Play on Network || players played on the network: +Health - Player Register Server || players register on servers per day/server on average. +Health - Player Visit Server || players visit on servers per day/server on average. +Health - Regular Activity Change || Number of regular players has +Health - Regular Activity Change Decrease || decreased (${0}) +Health - Regular Activity Change Increase || increased (+${0}) +Health - Regular Activity Change Zero || stayed the same (+${0}) +Health - Regular Activity Remain || ${0} of regular players have remained active (${1}/${2}) +Health - Single Servers Inaccuracy || Single Bukkit/Sponge server to gather session data. +Health - TPS Above Low Threshold || Average TPS was above Low Threshold ${0} of the time +Health - TPS Low Dips || Average TPS dropped below Low Threshold (${0}) ${1} times +HTML - FREE_DISK_SPACE || Free Disk Space +HTML - DISK_SPACE || DISK SPACE \ No newline at end of file diff --git a/Plan/src/main/resources/locale/locale_FI.txt b/Plan/src/main/resources/locale/locale_FI.txt index 806e94a76..8aed76a3c 100644 --- a/Plan/src/main/resources/locale/locale_FI.txt +++ b/Plan/src/main/resources/locale/locale_FI.txt @@ -311,3 +311,25 @@ WebServer - Notify no Cert file || Web Palvelin: Sertifikaatti A WebServer FAIL - Port Bind || Web Palvelin ei käynnistynyt. Onko portti (${0}) käytössä? WebServer FAIL - SSL Context || Web Palvelin: SSL Kontekstin käynnistys ei onnistunut. WebServer FAIL - Store Load || Web Palvelin: SSL Sertifikaatin lataus ei onnistunut. +Yesterday || 'Eilen' +Today || 'Tänään' +Health - Active Playtime Comparison Decrease || Aktiivisilta pelaajilta voi olla loppumassa tekeminen (Pelasivat ${0} vs ${1}, viimeisen kahden viikon vs viikot 2-4) +Health - Active Playtime Comparison Increase || Aktiivisilta pelaajilta vaikuttaa olevan tekemistä (Pelasivat ${0} vs ${1}, viimeisen kahden viikon vs viikot 2-4) +Health - Downtime || Palvelimen downtime (Ei Dataa) oli ${0} +Health - New Player Join Players, No || Uusilla pelaajilla voi olla yksinäistä (${0} paikalla keskimäärin) +Health - New Player Join Players, Yes || Uusilla pelaajilla on kavereita liittyessä (${0} paikalla keskimäärin) +Health - New Player Stickiness || ${0} uusista pelaajista jäi pelaamaan (${1}/${2}) +Health - No Servers Inaccuracy || Ei Bukkit/Sponge palvelimia sessio tietojen keräykseen - Nämä arviot ovat epätarkkoja. +Health - Player Play on Network || pelaajaa pelasi verkossa: +Health - Player Register Server || pelaajaa rekisteröityi palvelimille per päivä/palvelin keskimäärin. +Health - Player Visit Server || pelaajaa käy palvelimilla per päivä/palvelin keskimäärin. +Health - Regular Activity Change || Kestopelaajien määrä on +Health - Regular Activity Change Decrease || pienentynyt (${0}) +Health - Regular Activity Change Increase || kasvanut (+${0}) +Health - Regular Activity Change Zero || pysynyt samana (+${0}) +Health - Regular Activity Remain || ${0} kestopelaajista on pysynyt aktiivisena (${1}/${2}) +Health - Single Servers Inaccuracy || Yksi Bukkit/Sponge palvelin sessio tietojen keräykseen. +Health - TPS Above Low Threshold || Keskimääräinen TPS oli alarajan yläpuolella ${0} ajasta +Health - TPS Low Dips || Keskimääräinen TPS putosi alarajan alapuolelle (${0}) ${1} kertaa +HTML - FREE_DISK_SPACE || Vapaa Levytila +HTML - DISK_SPACE || LEVYTILA \ No newline at end of file diff --git a/Plan/src/main/resources/locale/locale_FR.txt b/Plan/src/main/resources/locale/locale_FR.txt index 29f63a3f2..5edf5c68f 100644 --- a/Plan/src/main/resources/locale/locale_FR.txt +++ b/Plan/src/main/resources/locale/locale_FR.txt @@ -312,3 +312,25 @@ WebServer - Notify no Cert file || WebServer: Certificate KeySto WebServer FAIL - Port Bind || WebServer was not initialized successfully. Is the port (${0}) in use? WebServer FAIL - SSL Context || WebServer: SSL Context Initialization Failed. WebServer FAIL - Store Load || WebServer: SSL Certificate loading Failed. +Yesterday || 'Yesterday' +Today || 'Today' +Health - Active Playtime Comparison Decrease || Active players might be running out of things to do (Played ${0} vs ${1}, last two weeks vs weeks 2-4) +Health - Active Playtime Comparison Increase || Active players seem to have things to do (Played ${0} vs ${1}, last two weeks vs weeks 2-4) +Health - Downtime || Total Server downtime (No Data) was ${0} +Health - New Player Join Players, No || New Players may not have players to play with when they join (${0} on average) +Health - New Player Join Players, Yes || New Players have players to play with when they join (${0} on average) +Health - New Player Stickiness || ${0} of new players have stuck around (${1}/${2}) +Health - No Servers Inaccuracy || No Bukkit/Sponge servers to gather session data - These measures are inaccurate. +Health - Player Play on Network || players played on the network: +Health - Player Register Server || players register on servers per day/server on average. +Health - Player Visit Server || players visit on servers per day/server on average. +Health - Regular Activity Change || Number of regular players has +Health - Regular Activity Change Decrease || decreased (${0}) +Health - Regular Activity Change Increase || increased (+${0}) +Health - Regular Activity Change Zero || stayed the same (+${0}) +Health - Regular Activity Remain || ${0} of regular players have remained active (${1}/${2}) +Health - Single Servers Inaccuracy || Single Bukkit/Sponge server to gather session data. +Health - TPS Above Low Threshold || Average TPS was above Low Threshold ${0} of the time +Health - TPS Low Dips || Average TPS dropped below Low Threshold (${0}) ${1} times +HTML - FREE_DISK_SPACE || Free Disk Space +HTML - DISK_SPACE || DISK SPACE \ No newline at end of file diff --git a/Plan/src/main/resources/locale/locale_GA.txt b/Plan/src/main/resources/locale/locale_GA.txt index 29f63a3f2..5edf5c68f 100644 --- a/Plan/src/main/resources/locale/locale_GA.txt +++ b/Plan/src/main/resources/locale/locale_GA.txt @@ -312,3 +312,25 @@ WebServer - Notify no Cert file || WebServer: Certificate KeySto WebServer FAIL - Port Bind || WebServer was not initialized successfully. Is the port (${0}) in use? WebServer FAIL - SSL Context || WebServer: SSL Context Initialization Failed. WebServer FAIL - Store Load || WebServer: SSL Certificate loading Failed. +Yesterday || 'Yesterday' +Today || 'Today' +Health - Active Playtime Comparison Decrease || Active players might be running out of things to do (Played ${0} vs ${1}, last two weeks vs weeks 2-4) +Health - Active Playtime Comparison Increase || Active players seem to have things to do (Played ${0} vs ${1}, last two weeks vs weeks 2-4) +Health - Downtime || Total Server downtime (No Data) was ${0} +Health - New Player Join Players, No || New Players may not have players to play with when they join (${0} on average) +Health - New Player Join Players, Yes || New Players have players to play with when they join (${0} on average) +Health - New Player Stickiness || ${0} of new players have stuck around (${1}/${2}) +Health - No Servers Inaccuracy || No Bukkit/Sponge servers to gather session data - These measures are inaccurate. +Health - Player Play on Network || players played on the network: +Health - Player Register Server || players register on servers per day/server on average. +Health - Player Visit Server || players visit on servers per day/server on average. +Health - Regular Activity Change || Number of regular players has +Health - Regular Activity Change Decrease || decreased (${0}) +Health - Regular Activity Change Increase || increased (+${0}) +Health - Regular Activity Change Zero || stayed the same (+${0}) +Health - Regular Activity Remain || ${0} of regular players have remained active (${1}/${2}) +Health - Single Servers Inaccuracy || Single Bukkit/Sponge server to gather session data. +Health - TPS Above Low Threshold || Average TPS was above Low Threshold ${0} of the time +Health - TPS Low Dips || Average TPS dropped below Low Threshold (${0}) ${1} times +HTML - FREE_DISK_SPACE || Free Disk Space +HTML - DISK_SPACE || DISK SPACE \ No newline at end of file diff --git a/Plan/src/main/resources/locale/locale_IT.txt b/Plan/src/main/resources/locale/locale_IT.txt index 29f63a3f2..5edf5c68f 100644 --- a/Plan/src/main/resources/locale/locale_IT.txt +++ b/Plan/src/main/resources/locale/locale_IT.txt @@ -312,3 +312,25 @@ WebServer - Notify no Cert file || WebServer: Certificate KeySto WebServer FAIL - Port Bind || WebServer was not initialized successfully. Is the port (${0}) in use? WebServer FAIL - SSL Context || WebServer: SSL Context Initialization Failed. WebServer FAIL - Store Load || WebServer: SSL Certificate loading Failed. +Yesterday || 'Yesterday' +Today || 'Today' +Health - Active Playtime Comparison Decrease || Active players might be running out of things to do (Played ${0} vs ${1}, last two weeks vs weeks 2-4) +Health - Active Playtime Comparison Increase || Active players seem to have things to do (Played ${0} vs ${1}, last two weeks vs weeks 2-4) +Health - Downtime || Total Server downtime (No Data) was ${0} +Health - New Player Join Players, No || New Players may not have players to play with when they join (${0} on average) +Health - New Player Join Players, Yes || New Players have players to play with when they join (${0} on average) +Health - New Player Stickiness || ${0} of new players have stuck around (${1}/${2}) +Health - No Servers Inaccuracy || No Bukkit/Sponge servers to gather session data - These measures are inaccurate. +Health - Player Play on Network || players played on the network: +Health - Player Register Server || players register on servers per day/server on average. +Health - Player Visit Server || players visit on servers per day/server on average. +Health - Regular Activity Change || Number of regular players has +Health - Regular Activity Change Decrease || decreased (${0}) +Health - Regular Activity Change Increase || increased (+${0}) +Health - Regular Activity Change Zero || stayed the same (+${0}) +Health - Regular Activity Remain || ${0} of regular players have remained active (${1}/${2}) +Health - Single Servers Inaccuracy || Single Bukkit/Sponge server to gather session data. +Health - TPS Above Low Threshold || Average TPS was above Low Threshold ${0} of the time +Health - TPS Low Dips || Average TPS dropped below Low Threshold (${0}) ${1} times +HTML - FREE_DISK_SPACE || Free Disk Space +HTML - DISK_SPACE || DISK SPACE \ No newline at end of file diff --git a/Plan/src/main/resources/locale/locale_NL.txt b/Plan/src/main/resources/locale/locale_NL.txt index 29f63a3f2..5edf5c68f 100644 --- a/Plan/src/main/resources/locale/locale_NL.txt +++ b/Plan/src/main/resources/locale/locale_NL.txt @@ -312,3 +312,25 @@ WebServer - Notify no Cert file || WebServer: Certificate KeySto WebServer FAIL - Port Bind || WebServer was not initialized successfully. Is the port (${0}) in use? WebServer FAIL - SSL Context || WebServer: SSL Context Initialization Failed. WebServer FAIL - Store Load || WebServer: SSL Certificate loading Failed. +Yesterday || 'Yesterday' +Today || 'Today' +Health - Active Playtime Comparison Decrease || Active players might be running out of things to do (Played ${0} vs ${1}, last two weeks vs weeks 2-4) +Health - Active Playtime Comparison Increase || Active players seem to have things to do (Played ${0} vs ${1}, last two weeks vs weeks 2-4) +Health - Downtime || Total Server downtime (No Data) was ${0} +Health - New Player Join Players, No || New Players may not have players to play with when they join (${0} on average) +Health - New Player Join Players, Yes || New Players have players to play with when they join (${0} on average) +Health - New Player Stickiness || ${0} of new players have stuck around (${1}/${2}) +Health - No Servers Inaccuracy || No Bukkit/Sponge servers to gather session data - These measures are inaccurate. +Health - Player Play on Network || players played on the network: +Health - Player Register Server || players register on servers per day/server on average. +Health - Player Visit Server || players visit on servers per day/server on average. +Health - Regular Activity Change || Number of regular players has +Health - Regular Activity Change Decrease || decreased (${0}) +Health - Regular Activity Change Increase || increased (+${0}) +Health - Regular Activity Change Zero || stayed the same (+${0}) +Health - Regular Activity Remain || ${0} of regular players have remained active (${1}/${2}) +Health - Single Servers Inaccuracy || Single Bukkit/Sponge server to gather session data. +Health - TPS Above Low Threshold || Average TPS was above Low Threshold ${0} of the time +Health - TPS Low Dips || Average TPS dropped below Low Threshold (${0}) ${1} times +HTML - FREE_DISK_SPACE || Free Disk Space +HTML - DISK_SPACE || DISK SPACE \ No newline at end of file diff --git a/Plan/src/main/resources/locale/locale_NO.txt b/Plan/src/main/resources/locale/locale_NO.txt index 29f63a3f2..5edf5c68f 100644 --- a/Plan/src/main/resources/locale/locale_NO.txt +++ b/Plan/src/main/resources/locale/locale_NO.txt @@ -312,3 +312,25 @@ WebServer - Notify no Cert file || WebServer: Certificate KeySto WebServer FAIL - Port Bind || WebServer was not initialized successfully. Is the port (${0}) in use? WebServer FAIL - SSL Context || WebServer: SSL Context Initialization Failed. WebServer FAIL - Store Load || WebServer: SSL Certificate loading Failed. +Yesterday || 'Yesterday' +Today || 'Today' +Health - Active Playtime Comparison Decrease || Active players might be running out of things to do (Played ${0} vs ${1}, last two weeks vs weeks 2-4) +Health - Active Playtime Comparison Increase || Active players seem to have things to do (Played ${0} vs ${1}, last two weeks vs weeks 2-4) +Health - Downtime || Total Server downtime (No Data) was ${0} +Health - New Player Join Players, No || New Players may not have players to play with when they join (${0} on average) +Health - New Player Join Players, Yes || New Players have players to play with when they join (${0} on average) +Health - New Player Stickiness || ${0} of new players have stuck around (${1}/${2}) +Health - No Servers Inaccuracy || No Bukkit/Sponge servers to gather session data - These measures are inaccurate. +Health - Player Play on Network || players played on the network: +Health - Player Register Server || players register on servers per day/server on average. +Health - Player Visit Server || players visit on servers per day/server on average. +Health - Regular Activity Change || Number of regular players has +Health - Regular Activity Change Decrease || decreased (${0}) +Health - Regular Activity Change Increase || increased (+${0}) +Health - Regular Activity Change Zero || stayed the same (+${0}) +Health - Regular Activity Remain || ${0} of regular players have remained active (${1}/${2}) +Health - Single Servers Inaccuracy || Single Bukkit/Sponge server to gather session data. +Health - TPS Above Low Threshold || Average TPS was above Low Threshold ${0} of the time +Health - TPS Low Dips || Average TPS dropped below Low Threshold (${0}) ${1} times +HTML - FREE_DISK_SPACE || Free Disk Space +HTML - DISK_SPACE || DISK SPACE \ No newline at end of file diff --git a/Plan/src/main/resources/locale/locale_PL.txt b/Plan/src/main/resources/locale/locale_PL.txt index 29f63a3f2..5edf5c68f 100644 --- a/Plan/src/main/resources/locale/locale_PL.txt +++ b/Plan/src/main/resources/locale/locale_PL.txt @@ -312,3 +312,25 @@ WebServer - Notify no Cert file || WebServer: Certificate KeySto WebServer FAIL - Port Bind || WebServer was not initialized successfully. Is the port (${0}) in use? WebServer FAIL - SSL Context || WebServer: SSL Context Initialization Failed. WebServer FAIL - Store Load || WebServer: SSL Certificate loading Failed. +Yesterday || 'Yesterday' +Today || 'Today' +Health - Active Playtime Comparison Decrease || Active players might be running out of things to do (Played ${0} vs ${1}, last two weeks vs weeks 2-4) +Health - Active Playtime Comparison Increase || Active players seem to have things to do (Played ${0} vs ${1}, last two weeks vs weeks 2-4) +Health - Downtime || Total Server downtime (No Data) was ${0} +Health - New Player Join Players, No || New Players may not have players to play with when they join (${0} on average) +Health - New Player Join Players, Yes || New Players have players to play with when they join (${0} on average) +Health - New Player Stickiness || ${0} of new players have stuck around (${1}/${2}) +Health - No Servers Inaccuracy || No Bukkit/Sponge servers to gather session data - These measures are inaccurate. +Health - Player Play on Network || players played on the network: +Health - Player Register Server || players register on servers per day/server on average. +Health - Player Visit Server || players visit on servers per day/server on average. +Health - Regular Activity Change || Number of regular players has +Health - Regular Activity Change Decrease || decreased (${0}) +Health - Regular Activity Change Increase || increased (+${0}) +Health - Regular Activity Change Zero || stayed the same (+${0}) +Health - Regular Activity Remain || ${0} of regular players have remained active (${1}/${2}) +Health - Single Servers Inaccuracy || Single Bukkit/Sponge server to gather session data. +Health - TPS Above Low Threshold || Average TPS was above Low Threshold ${0} of the time +Health - TPS Low Dips || Average TPS dropped below Low Threshold (${0}) ${1} times +HTML - FREE_DISK_SPACE || Free Disk Space +HTML - DISK_SPACE || DISK SPACE \ No newline at end of file diff --git a/Plan/src/main/resources/locale/locale_PT.txt b/Plan/src/main/resources/locale/locale_PT.txt index 29f63a3f2..5edf5c68f 100644 --- a/Plan/src/main/resources/locale/locale_PT.txt +++ b/Plan/src/main/resources/locale/locale_PT.txt @@ -312,3 +312,25 @@ WebServer - Notify no Cert file || WebServer: Certificate KeySto WebServer FAIL - Port Bind || WebServer was not initialized successfully. Is the port (${0}) in use? WebServer FAIL - SSL Context || WebServer: SSL Context Initialization Failed. WebServer FAIL - Store Load || WebServer: SSL Certificate loading Failed. +Yesterday || 'Yesterday' +Today || 'Today' +Health - Active Playtime Comparison Decrease || Active players might be running out of things to do (Played ${0} vs ${1}, last two weeks vs weeks 2-4) +Health - Active Playtime Comparison Increase || Active players seem to have things to do (Played ${0} vs ${1}, last two weeks vs weeks 2-4) +Health - Downtime || Total Server downtime (No Data) was ${0} +Health - New Player Join Players, No || New Players may not have players to play with when they join (${0} on average) +Health - New Player Join Players, Yes || New Players have players to play with when they join (${0} on average) +Health - New Player Stickiness || ${0} of new players have stuck around (${1}/${2}) +Health - No Servers Inaccuracy || No Bukkit/Sponge servers to gather session data - These measures are inaccurate. +Health - Player Play on Network || players played on the network: +Health - Player Register Server || players register on servers per day/server on average. +Health - Player Visit Server || players visit on servers per day/server on average. +Health - Regular Activity Change || Number of regular players has +Health - Regular Activity Change Decrease || decreased (${0}) +Health - Regular Activity Change Increase || increased (+${0}) +Health - Regular Activity Change Zero || stayed the same (+${0}) +Health - Regular Activity Remain || ${0} of regular players have remained active (${1}/${2}) +Health - Single Servers Inaccuracy || Single Bukkit/Sponge server to gather session data. +Health - TPS Above Low Threshold || Average TPS was above Low Threshold ${0} of the time +Health - TPS Low Dips || Average TPS dropped below Low Threshold (${0}) ${1} times +HTML - FREE_DISK_SPACE || Free Disk Space +HTML - DISK_SPACE || DISK SPACE \ No newline at end of file diff --git a/Plan/src/main/resources/plugin.yml b/Plan/src/main/resources/plugin.yml index f83a18fa4..a9f9380e0 100644 --- a/Plan/src/main/resources/plugin.yml +++ b/Plan/src/main/resources/plugin.yml @@ -1,7 +1,7 @@ name: Plan author: Rsl1122 main: com.djrapitops.plan.Plan -version: 4.4.7 +version: 4.5.0 softdepend: - EssentialsX - Towny @@ -95,7 +95,7 @@ permissions: plan.basic: children: plan.?: true - plan.inspect.base: true + plan.inspect.base: true plan.qinspect.base: true plan.advanced: childer: diff --git a/Plan/src/main/resources/web/error.html b/Plan/src/main/resources/web/error.html index 332d19e45..e55ef5672 100644 --- a/Plan/src/main/resources/web/error.html +++ b/Plan/src/main/resources/web/error.html @@ -111,6 +111,7 @@
    Player Analytics: v${version} + ${update}
    diff --git a/Plan/src/main/resources/web/favicon.ico b/Plan/src/main/resources/web/favicon.ico new file mode 100644 index 000000000..cea02dd44 Binary files /dev/null and b/Plan/src/main/resources/web/favicon.ico differ diff --git a/Plan/src/main/resources/web/js/charts/diskGraph.js b/Plan/src/main/resources/web/js/charts/diskGraph.js new file mode 100644 index 000000000..93a9d27a6 --- /dev/null +++ b/Plan/src/main/resources/web/js/charts/diskGraph.js @@ -0,0 +1,41 @@ +function diskChart(id, series) { + Highcharts.stockChart(id, { + rangeSelector: { + selected: 2, + buttons: [{ + type: 'hour', + count: 12, + text: '12h' + }, { + type: 'hour', + count: 24, + text: '24h' + }, { + type: 'day', + count: 7, + text: '7d' + }, { + type: 'month', + count: 1, + text: '30d' + }, { + type: 'all', + text: 'All' + }] + }, + yAxis: { + labels: { + formatter: function () { + return this.value + ' Mb'; + } + }, + softMax: 2, + softMin: 0 + }, + title: {text: ''}, + legend: { + enabled: true + }, + series: series + }); +} \ No newline at end of file diff --git a/Plan/src/main/resources/web/js/charts/resourceGraph.js b/Plan/src/main/resources/web/js/charts/resourceGraph.js index 6d411fa63..723bb00f7 100644 --- a/Plan/src/main/resources/web/js/charts/resourceGraph.js +++ b/Plan/src/main/resources/web/js/charts/resourceGraph.js @@ -48,7 +48,7 @@ function resourceChart(id, cpuSeries, ramSeries, playersOnlineSeries) { }, { labels: { formatter: function () { - return this.value + ' MB'; + return this.value + ' Mb'; } } }], diff --git a/Plan/src/main/resources/web/network.html b/Plan/src/main/resources/web/network.html index 869b50233..4fe271323 100644 --- a/Plan/src/main/resources/web/network.html +++ b/Plan/src/main/resources/web/network.html @@ -148,6 +148,7 @@
    Player Analytics: v${version} + ${update}
    diff --git a/Plan/src/main/resources/web/player.html b/Plan/src/main/resources/web/player.html index 152d3e586..ff432cca5 100644 --- a/Plan/src/main/resources/web/player.html +++ b/Plan/src/main/resources/web/player.html @@ -143,6 +143,7 @@
    Player Analytics: v${version} + ${update}
    diff --git a/Plan/src/main/resources/web/players.html b/Plan/src/main/resources/web/players.html index f6fc6abc8..ab35092c1 100644 --- a/Plan/src/main/resources/web/players.html +++ b/Plan/src/main/resources/web/players.html @@ -117,6 +117,7 @@
    Player Analytics: v${version} + ${update}
    diff --git a/Plan/src/main/resources/web/server.html b/Plan/src/main/resources/web/server.html index 5438fa41a..8e75c014e 100644 --- a/Plan/src/main/resources/web/server.html +++ b/Plan/src/main/resources/web/server.html @@ -170,6 +170,7 @@
    Player Analytics: v${version} + ${update}
    @@ -838,6 +839,9 @@
  • PING
  • +
  • + DISK SPACE
  • @@ -859,6 +863,9 @@
    +
    +
    +
    @@ -1163,6 +1170,7 @@ + @@ -1199,6 +1207,8 @@ values: { tpsMed: ${tpsMedium}, tpsHigh: ${tpsHigh}, + diskMed: ${diskMedium}, + diskHigh: ${diskHigh}, firstDay: ${firstDay} }, data: { @@ -1223,7 +1233,8 @@ country: ${countrySeries}, avgPing: ${avgPingSeries}, maxPing: ${maxPingSeries}, - minPing: ${minPingSeries} + minPing: ${minPingSeries}, + disk: ${diskSeries} } }; @@ -1235,12 +1246,13 @@ newPlayers: 'New Players', tps: 'TPS', cpu: 'CPU Usage (%)', - ram: 'RAM Usage (MB)', + ram: 'RAM Usage (Mb)', entities: 'Loaded Entities', chunks: 'Loaded Chunks', maxPing: 'Worst Ping', minPing: 'Best Ping', - avgPing: 'Average Ping' + avgPing: 'Average Ping', + disk: 'Free Disk Space (Mb)' }, tooltip: { twoDecimals: { @@ -1264,6 +1276,16 @@ }, { value: 30, color: v.colors.tpsHigh + }], + disk: [{ + value: v.values.diskMed, + color: v.colors.tpsLow + }, { + value: v.values.diskHigh, + color: v.colors.tpsMed + }, { + value: Number.MAX_VALUE, + color: v.colors.tpsHigh }] } }; @@ -1383,6 +1405,13 @@ color: v.colors.chunks, yAxis: 2 }, + disk: { + name: s.name.disk, + type: s.type.spline, + zones: s.zones.disk, + tooltip: s.tooltip.zeroDecimals, + data: v.data.disk + }, activityPie: { name: 'Players', colorByPoint: true, @@ -1461,6 +1490,7 @@ onlineActivityCalendar('#calendar', v.data.calendar, v.values.firstDay); horizontalBarChart('countryBarChart', v.data.countryCategories, [series.country], 'Players'); lineChart('pingGraph', [series.avgPing, series.maxPing, series.minPing]); + diskChart('diskGraph', [series.disk]); ${sessionTabGraphViewFunctions} /**/ diff --git a/Plan/src/test/java/com/djrapitops/plan/system/BukkitSystemTest.java b/Plan/src/test/java/com/djrapitops/plan/BukkitSystemTest.java similarity index 61% rename from Plan/src/test/java/com/djrapitops/plan/system/BukkitSystemTest.java rename to Plan/src/test/java/com/djrapitops/plan/BukkitSystemTest.java index 07b1ce3b7..fd2b47a48 100644 --- a/Plan/src/test/java/com/djrapitops/plan/system/BukkitSystemTest.java +++ b/Plan/src/test/java/com/djrapitops/plan/BukkitSystemTest.java @@ -2,20 +2,20 @@ * License is provided in the jar as LICENSE also here: * https://github.com/Rsl1122/Plan-PlayerAnalytics/blob/master/Plan/src/main/resources/LICENSE */ -package com.djrapitops.plan.system; +package com.djrapitops.plan; -import com.djrapitops.plan.Plan; import com.djrapitops.plan.api.exceptions.EnableException; +import com.djrapitops.plan.system.PlanSystem; import com.djrapitops.plan.system.settings.Settings; +import com.djrapitops.plan.system.settings.config.PlanConfig; import org.junit.*; import org.junit.rules.TemporaryFolder; import org.junit.runner.RunWith; import org.mockito.junit.MockitoJUnitRunner; -import utilities.Teardown; -import utilities.mocks.BukkitMockUtil; +import utilities.mocks.PlanBukkitMocker; /** - * Test for BukkitSystem. + * Test for Bukkit PlanSystem. * * @author Rsl1122 */ @@ -24,38 +24,35 @@ public class BukkitSystemTest { @ClassRule public static TemporaryFolder temporaryFolder = new TemporaryFolder(); - private static Plan planMock; - private BukkitSystem bukkitSystem; + private PlanSystem bukkitSystem; + private static PlanBukkitComponent COMPONENT; @BeforeClass public static void setUpClass() throws Exception { - BukkitMockUtil mockUtil = BukkitMockUtil.setUp() - .withDataFolder(temporaryFolder.getRoot()) - .withLogging() + PlanBukkitMocker mockUtil = PlanBukkitMocker.setUp() + .withDataFolder(temporaryFolder.newFolder()) .withPluginDescription() .withResourceFetchingFromJar() .withServer(); - planMock = mockUtil.getPlanMock(); + COMPONENT = DaggerPlanBukkitComponent.builder().plan(mockUtil.getPlanMock()).build(); } @Before public void setUp() { - Teardown.resetSettingsTempValues(); + bukkitSystem = COMPONENT.system(); } - + @After public void tearDown() { if (bukkitSystem != null) { bukkitSystem.disable(); } - Teardown.resetSettingsTempValues(); } @Test public void testEnable() throws EnableException { - Settings.WEBSERVER_PORT.setTemporaryValue(9005); - - bukkitSystem = new BukkitSystem(planMock); + PlanConfig config = bukkitSystem.getConfigSystem().getConfig(); + config.set(Settings.WEBSERVER_PORT, 9005); bukkitSystem.enable(); } } diff --git a/Plan/src/test/java/com/djrapitops/plan/BungeeBukkitConnectionTest.java b/Plan/src/test/java/com/djrapitops/plan/BungeeBukkitConnectionTest.java new file mode 100644 index 000000000..993321ecb --- /dev/null +++ b/Plan/src/test/java/com/djrapitops/plan/BungeeBukkitConnectionTest.java @@ -0,0 +1,101 @@ +/* + * License is provided in the jar as LICENSE also here: + * https://github.com/Rsl1122/Plan-PlayerAnalytics/blob/master/Plan/src/main/resources/LICENSE + */ +package com.djrapitops.plan; + +import com.djrapitops.plan.system.PlanSystem; +import com.djrapitops.plan.system.database.DBSystem; +import com.djrapitops.plan.system.settings.Settings; +import org.junit.*; +import org.junit.rules.ExpectedException; +import org.junit.rules.TemporaryFolder; +import org.junit.runner.RunWith; +import org.mockito.junit.MockitoJUnitRunner; +import utilities.mocks.PlanBukkitMocker; +import utilities.mocks.PlanBungeeMocker; + +import java.util.UUID; + +/** + * @author Rsl1122 + */ +@RunWith(MockitoJUnitRunner.Silent.class) +public class BungeeBukkitConnectionTest { + + @ClassRule + public static TemporaryFolder temporaryFolder = new TemporaryFolder(); + private static PlanBukkitComponent BUKKIT_COMPONENT; + private static PlanBungeeComponent BUNGEE_COMPONENT; + + @Rule + public ExpectedException thrown = ExpectedException.none(); + + private PlanSystem bukkitSystem; + private PlanSystem bungeeSystem; + + private UUID bukkitUUID; + private UUID bungeeUUID; + + @BeforeClass + public static void setUpClass() throws Exception { + PlanBukkitMocker planBukkitMocker = PlanBukkitMocker.setUp() + .withDataFolder(temporaryFolder.getRoot()) + .withPluginDescription() + .withResourceFetchingFromJar() + .withServer(); + BUKKIT_COMPONENT = DaggerPlanBukkitComponent.builder().plan(planBukkitMocker.getPlanMock()).build(); + + PlanBungeeMocker planBungeeMocker = PlanBungeeMocker.setUp() + .withDataFolder(temporaryFolder.getRoot()) + .withPluginDescription() + .withResourceFetchingFromJar() + .withProxy(); + BUNGEE_COMPONENT = DaggerPlanBungeeComponent.builder().plan(planBungeeMocker.getPlanMock()).build(); + } + + @After + public void tearDown() { + System.out.println("------------------------------"); + System.out.println("Disable"); + System.out.println("------------------------------"); + if (bukkitSystem != null) { + bukkitSystem.disable(); + } + if (bungeeSystem != null) { + bungeeSystem.disable(); + } + } + + public void enable() throws Exception { + bukkitSystem = BUKKIT_COMPONENT.system(); + bungeeSystem = BUNGEE_COMPONENT.system(); + + bukkitSystem.getConfigSystem().getConfig().set(Settings.WEBSERVER_PORT, 9005); + bungeeSystem.getConfigSystem().getConfig().set(Settings.WEBSERVER_PORT, 9250); + + DBSystem dbSystem = bungeeSystem.getDatabaseSystem(); + dbSystem.setActiveDatabase(dbSystem.getSqLiteFactory().usingDefaultFile()); + + bukkitSystem.enable(); + bungeeSystem.enable(); + + bukkitUUID = bukkitSystem.getServerInfo().getServerUUID(); + bungeeUUID = bungeeSystem.getServerInfo().getServerUUID(); + + System.out.println("------------------------------"); + System.out.println("Enable Complete"); + System.out.println("Bukkit: " + bukkitUUID); + System.out.println("Bungee: " + bungeeUUID); + System.out.println("------------------------------"); + } + + @Test + @Ignore("Causes next BungeeSystem test to fail") + public void testRequest() throws Exception { + enable(); + + System.out.println("Sending request"); +// bungeeSystem.getInfoSystem().getConnectionSystem().sendWideInfoRequest(new GenerateInspectPluginsTabRequest(infoSystem, infoRequestFactory, TestConstants.PLAYER_ONE_UUID)); + } +} diff --git a/Plan/src/test/java/com/djrapitops/plan/BungeeSystemTest.java b/Plan/src/test/java/com/djrapitops/plan/BungeeSystemTest.java new file mode 100644 index 000000000..4b83276da --- /dev/null +++ b/Plan/src/test/java/com/djrapitops/plan/BungeeSystemTest.java @@ -0,0 +1,104 @@ +/* + * License is provided in the jar as LICENSE also here: + * https://github.com/Rsl1122/Plan-PlayerAnalytics/blob/master/Plan/src/main/resources/LICENSE + */ +package com.djrapitops.plan; + +import com.djrapitops.plan.api.exceptions.EnableException; +import com.djrapitops.plan.system.PlanSystem; +import com.djrapitops.plan.system.database.DBSystem; +import com.djrapitops.plan.system.settings.Settings; +import com.djrapitops.plan.system.settings.config.PlanConfig; +import org.junit.*; +import org.junit.rules.ExpectedException; +import org.junit.rules.TemporaryFolder; +import org.junit.runner.RunWith; +import org.mockito.junit.MockitoJUnitRunner; +import utilities.mocks.PlanBungeeMocker; + +/** + * Test for Bungee PlanSystem. + * + * @author Rsl1122 + */ +@RunWith(MockitoJUnitRunner.Silent.class) +public class BungeeSystemTest { + + @ClassRule + public static TemporaryFolder temporaryFolder = new TemporaryFolder(); + private static PlanBungee PLUGIN_MOCK; + @Rule + public ExpectedException thrown = ExpectedException.none(); + + private PlanBungeeComponent component; + private PlanSystem bungeeSystem; + + @BeforeClass + public static void setUpClass() throws Exception { + PlanBungeeMocker mocker = PlanBungeeMocker.setUp() + .withDataFolder(temporaryFolder.newFolder()) + .withPluginDescription() + .withResourceFetchingFromJar() + .withProxy(); + PLUGIN_MOCK = mocker.getPlanMock(); + } + + @Before + public void setUp() { + component = DaggerPlanBungeeComponent.builder().plan(PLUGIN_MOCK).build(); + } + + @After + public void tearDown() { + if (bungeeSystem != null) { + bungeeSystem.disable(); + } + } + + @Test + public void bungeeEnables() throws Exception { + bungeeSystem = component.system(); + + PlanConfig config = bungeeSystem.getConfigSystem().getConfig(); + config.set(Settings.WEBSERVER_PORT, 9005); + config.set(Settings.BUNGEE_IP, "8.8.8.8"); + + DBSystem dbSystem = bungeeSystem.getDatabaseSystem(); + dbSystem.setActiveDatabase(dbSystem.getSqLiteFactory().usingDefaultFile()); + + bungeeSystem.enable(); + } + + @Test + @Ignore("First test causes config settings to be wrong") + public void bungeeDoesNotEnableWithDefaultIP() throws Exception { + thrown.expect(EnableException.class); + thrown.expectMessage("IP setting still 0.0.0.0 - Configure AlternativeIP/IP that connects to the Proxy server."); + + bungeeSystem = component.system(); + + PlanConfig config = bungeeSystem.getConfigSystem().getConfig(); + config.set(Settings.WEBSERVER_PORT, 9005); + config.set(Settings.BUNGEE_IP, "0.0.0.0"); + + DBSystem dbSystem = bungeeSystem.getDatabaseSystem(); + dbSystem.setActiveDatabase(dbSystem.getSqLiteFactory().usingDefaultFile()); + + bungeeSystem.enable(); + } + + @Test + @Ignore("MySQL Driver unavailable for some reason.") + public void testEnableNoMySQL() throws EnableException { + thrown.expect(EnableException.class); + thrown.expectMessage("Database failed to initialize"); + + bungeeSystem = component.system(); + + PlanConfig config = bungeeSystem.getConfigSystem().getConfig(); + config.set(Settings.WEBSERVER_PORT, 9005); + config.set(Settings.BUNGEE_IP, "8.8.8.8"); + + bungeeSystem.enable(); + } +} diff --git a/Plan/src/test/java/com/djrapitops/plan/system/SpongeSystemTest.java b/Plan/src/test/java/com/djrapitops/plan/SpongeSystemTest.java similarity index 65% rename from Plan/src/test/java/com/djrapitops/plan/system/SpongeSystemTest.java rename to Plan/src/test/java/com/djrapitops/plan/SpongeSystemTest.java index 84a2a86d0..7e84b618a 100644 --- a/Plan/src/test/java/com/djrapitops/plan/system/SpongeSystemTest.java +++ b/Plan/src/test/java/com/djrapitops/plan/SpongeSystemTest.java @@ -2,20 +2,19 @@ * License is provided in the jar as LICENSE also here: * https://github.com/Rsl1122/Plan-PlayerAnalytics/blob/master/Plan/src/main/resources/LICENSE */ -package com.djrapitops.plan.system; +package com.djrapitops.plan; -import com.djrapitops.plan.PlanSponge; import com.djrapitops.plan.api.exceptions.EnableException; +import com.djrapitops.plan.system.PlanSystem; import com.djrapitops.plan.system.settings.Settings; import org.junit.*; import org.junit.rules.TemporaryFolder; import org.junit.runner.RunWith; import org.mockito.junit.MockitoJUnitRunner; -import utilities.Teardown; -import utilities.mocks.SpongeMockUtil; +import utilities.mocks.PlanSpongeMocker; /** - * Test for BukkitSystem. + * Test for Sponge PlanSystem. * * @author Rsl1122 */ @@ -25,20 +24,21 @@ public class SpongeSystemTest { @ClassRule public static TemporaryFolder temporaryFolder = new TemporaryFolder(); private static PlanSponge planMock; - private SpongeSystem spongeSystem; + private PlanSystem spongeSystem; + private PlanSpongeComponent component; @BeforeClass public static void setUpClass() throws Exception { - SpongeMockUtil mockUtil = SpongeMockUtil.setUp() + PlanSpongeMocker mockUtil = PlanSpongeMocker.setUp() .withDataFolder(temporaryFolder.getRoot()) - .withLogging() - .withResourceFetchingFromJar(); + .withResourceFetchingFromJar() + .withGame(); planMock = mockUtil.getPlanMock(); } @Before public void setUp() { - Teardown.resetSettingsTempValues(); + component = DaggerPlanSpongeComponent.builder().plan(planMock).build(); } @After @@ -46,15 +46,13 @@ public class SpongeSystemTest { if (spongeSystem != null) { spongeSystem.disable(); } - Teardown.resetSettingsTempValues(); } @Test - @Ignore("Sponge mock required") public void testEnable() throws EnableException { - Settings.WEBSERVER_PORT.setTemporaryValue(9005); + spongeSystem = component.system(); + spongeSystem.getConfigSystem().getConfig().set(Settings.WEBSERVER_PORT, 9005); - spongeSystem = new SpongeSystem(planMock); spongeSystem.enable(); } } diff --git a/Plan/src/test/java/com/djrapitops/plan/VelocitySystemTest.java b/Plan/src/test/java/com/djrapitops/plan/VelocitySystemTest.java new file mode 100644 index 000000000..a84ab2d4e --- /dev/null +++ b/Plan/src/test/java/com/djrapitops/plan/VelocitySystemTest.java @@ -0,0 +1,69 @@ +/* + * License is provided in the jar as LICENSE also here: + * https://github.com/Rsl1122/Plan-PlayerAnalytics/blob/master/Plan/src/main/resources/LICENSE + */ +package com.djrapitops.plan; + +import com.djrapitops.plan.system.PlanSystem; +import com.djrapitops.plan.system.database.DBSystem; +import com.djrapitops.plan.system.settings.Settings; +import com.djrapitops.plan.system.settings.config.PlanConfig; +import org.junit.*; +import org.junit.rules.ExpectedException; +import org.junit.rules.TemporaryFolder; +import org.junit.runner.RunWith; +import org.mockito.junit.MockitoJUnitRunner; +import utilities.mocks.PlanVelocityMocker; + +/** + * Test for Velocity PlanSystem. + * + * @author Rsl1122 + */ +@RunWith(MockitoJUnitRunner.Silent.class) +public class VelocitySystemTest { + + @ClassRule + public static TemporaryFolder temporaryFolder = new TemporaryFolder(); + private static PlanVelocity PLUGIN_MOCK; + @Rule + public ExpectedException thrown = ExpectedException.none(); + + private PlanVelocityComponent component; + private PlanSystem velocitySystem; + + @BeforeClass + public static void setUpClass() throws Exception { + PlanVelocityMocker mocker = PlanVelocityMocker.setUp() + .withDataFolder(temporaryFolder.newFolder()) + .withResourceFetchingFromJar() + .withProxy(); + PLUGIN_MOCK = mocker.getPlanMock(); + } + + @Before + public void setUp() { + component = DaggerPlanVelocityComponent.builder().plan(PLUGIN_MOCK).build(); + } + + @After + public void tearDown() { + if (velocitySystem != null) { + velocitySystem.disable(); + } + } + + @Test + public void velocityEnables() throws Exception { + velocitySystem = component.system(); + + PlanConfig config = velocitySystem.getConfigSystem().getConfig(); + config.set(Settings.WEBSERVER_PORT, 9005); + config.set(Settings.BUNGEE_IP, "8.8.8.8"); + + DBSystem dbSystem = velocitySystem.getDatabaseSystem(); + dbSystem.setActiveDatabase(dbSystem.getSqLiteFactory().usingDefaultFile()); + + velocitySystem.enable(); + } +} diff --git a/Plan/src/test/java/com/djrapitops/plan/data/PlayerKillTest.java b/Plan/src/test/java/com/djrapitops/plan/data/PlayerKillTest.java index 1537e4b9c..d1d252fa2 100644 --- a/Plan/src/test/java/com/djrapitops/plan/data/PlayerKillTest.java +++ b/Plan/src/test/java/com/djrapitops/plan/data/PlayerKillTest.java @@ -12,28 +12,43 @@ import utilities.RandomData; import java.util.UUID; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; /** + * Tests for {@link PlayerKill}. + * * @author Rsl1122 */ public class PlayerKillTest { - private String randomString = RandomData.randomString(10); + private String weapon = RandomData.randomString(10); private UUID testUUID = UUID.randomUUID(); - private PlayerKill playerKill = new PlayerKill(testUUID, randomString, 100L); + private PlayerKill underTest = new PlayerKill(testUUID, weapon, 100L); @Test - public void testGetVictim() { - assertEquals(playerKill.getVictim(), testUUID); + public void victimUUIDIsReturned() { + assertEquals(testUUID, underTest.getVictim()); } @Test - public void testGetDate() { - assertEquals(playerKill.getDate(), 100L); + public void dateIsReturned() { + assertEquals(100L, underTest.getDate()); } @Test - public void testGetWeapon() { - assertEquals(playerKill.getWeapon(), randomString); + public void weaponIsReturned() { + assertEquals(weapon, underTest.getWeapon()); + } + + @Test + public void noVictimFound() { + assertFalse(underTest.getVictimName().isPresent()); + } + + @Test + public void victimFound() { + String expectedName = "Test Victim"; + PlayerKill underTest = new PlayerKill(testUUID, weapon, 100L, expectedName); + assertEquals("Test Victim", underTest.getVictimName().orElse("Unknown")); } } diff --git a/Plan/src/test/java/com/djrapitops/plan/data/cache/GeolocationCacheTest.java b/Plan/src/test/java/com/djrapitops/plan/data/cache/GeolocationCacheTest.java deleted file mode 100644 index 9e7771bad..000000000 --- a/Plan/src/test/java/com/djrapitops/plan/data/cache/GeolocationCacheTest.java +++ /dev/null @@ -1,80 +0,0 @@ -package com.djrapitops.plan.data.cache; - -import com.djrapitops.plan.system.cache.CacheSystem; -import com.djrapitops.plan.system.cache.GeolocationCache; -import org.junit.Before; -import org.junit.BeforeClass; -import org.junit.ClassRule; -import org.junit.Test; -import org.junit.rules.TemporaryFolder; -import org.junit.runner.RunWith; -import org.mockito.junit.MockitoJUnitRunner; -import utilities.mocks.SystemMockUtil; - -import java.util.HashMap; -import java.util.Map; - -import static junit.framework.TestCase.*; - -/** - * @author Fuzzlemann - */ -@RunWith(MockitoJUnitRunner.Silent.class) -public class GeolocationCacheTest { - - private final Map ipsToCountries = new HashMap<>(); - - @ClassRule - public static TemporaryFolder temporaryFolder = new TemporaryFolder(); - - @BeforeClass - public static void setUpClass() throws Exception { - SystemMockUtil.setUp(temporaryFolder.getRoot()) - .enableConfigSystem() - .enableCacheSystem(); - } - - @Before - public void setUp() { - CacheSystem.getInstance().getGeolocationCache().clearCache(); - - ipsToCountries.put("8.8.8.8", "United States"); - ipsToCountries.put("8.8.4.4", "United States"); - ipsToCountries.put("4.4.2.2", "United States"); - ipsToCountries.put("208.67.222.222", "United States"); - ipsToCountries.put("208.67.220.220", "United States"); - ipsToCountries.put("205.210.42.205", "Canada"); - ipsToCountries.put("64.68.200.200", "Canada"); - ipsToCountries.put("0.0.0.0", "Not Known"); - ipsToCountries.put("127.0.0.1", "Local Machine"); - } - - @Test - public void testCountryGetting() { - for (Map.Entry entry : ipsToCountries.entrySet()) { - String ip = entry.getKey(); - String expCountry = entry.getValue(); - - String country = GeolocationCache.getCountry(ip); - - assertEquals(country, expCountry); - } - } - - @Test - public void testCaching() { - for (Map.Entry entry : ipsToCountries.entrySet()) { - String ip = entry.getKey(); - String expIp = entry.getValue(); - - assertFalse(GeolocationCache.isCached(ip)); - String countrySecondCall = GeolocationCache.getCountry(ip); - assertTrue(GeolocationCache.isCached(ip)); - - String countryThirdCall = GeolocationCache.getCountry(ip); - - assertEquals(countrySecondCall, countryThirdCall); - assertEquals(countryThirdCall, expIp); - } - } -} diff --git a/Plan/src/test/java/com/djrapitops/plan/data/calculation/ActivityIndexTest.java b/Plan/src/test/java/com/djrapitops/plan/data/calculation/ActivityIndexTest.java deleted file mode 100644 index 59fa7f226..000000000 --- a/Plan/src/test/java/com/djrapitops/plan/data/calculation/ActivityIndexTest.java +++ /dev/null @@ -1,125 +0,0 @@ -package com.djrapitops.plan.data.calculation; - -import com.djrapitops.plan.data.container.Session; -import com.djrapitops.plan.data.store.containers.PlayerContainer; -import com.djrapitops.plan.data.store.keys.PlayerKeys; -import com.djrapitops.plan.data.store.mutators.ActivityIndex; -import com.djrapitops.plan.system.settings.Settings; -import com.djrapitops.plugin.api.TimeAmount; -import org.junit.BeforeClass; -import org.junit.ClassRule; -import org.junit.Test; -import org.junit.rules.TemporaryFolder; -import utilities.TestConstants; -import utilities.mocks.SystemMockUtil; - -import java.util.ArrayList; -import java.util.List; -import java.util.UUID; - -import static junit.framework.TestCase.assertEquals; -import static org.junit.Assert.assertTrue; - -/** - * Test for ActivityIndex. - * - * @author Rsl1122 - */ -public class ActivityIndexTest { - @ClassRule - public static TemporaryFolder temporaryFolder = new TemporaryFolder(); - private static final UUID UUID = TestConstants.PLAYER_ONE_UUID; - private static final UUID SERVER_UUID = TestConstants.SERVER_UUID; - - @BeforeClass - public static void setUpClass() throws Exception { - SystemMockUtil.setUp(temporaryFolder.getRoot()).enableConfigSystem(); - } - - @Test - public void testMaxActivityIndex() { - PlayerContainer container = new PlayerContainer(); - List sessions = new ArrayList<>(); - - long date = System.currentTimeMillis(); - long week = TimeAmount.WEEK.ms(); - long weekAgo = date - week; - long twoWeeksAgo = date - 2L * week; - long threeWeeksAgo = date - 3L * week; - - long requiredPlaytime = Settings.ACTIVE_PLAY_THRESHOLD.getNumber() * TimeAmount.MINUTE.ms(); - int requiredLogins = Settings.ACTIVE_LOGIN_THRESHOLD.getNumber(); - - for (int i = 0; i < requiredLogins; i++) { - sessions.add(new Session(0, UUID, SERVER_UUID, weekAgo, weekAgo + requiredPlaytime * 4L, 0, 0, 0)); - sessions.add(new Session(0, UUID, SERVER_UUID, twoWeeksAgo, twoWeeksAgo + requiredPlaytime * 4L, 0, 0, 0)); - sessions.add(new Session(0, UUID, SERVER_UUID, threeWeeksAgo, threeWeeksAgo + requiredPlaytime * 4L, 0, 0, 0)); - } - container.putRawData(PlayerKeys.SESSIONS, sessions); - - assertEquals(5.0, new ActivityIndex(container, date).getValue()); - } - - @Test - public void testMaxActivityIndex2() { - PlayerContainer container = new PlayerContainer(); - List sessions = new ArrayList<>(); - - long date = System.currentTimeMillis(); - long week = TimeAmount.WEEK.ms(); - long weekAgo = date - week; - long twoWeeksAgo = date - 2L * week; - long threeWeeksAgo = date - 3L * week; - - long requiredPlaytime = Settings.ACTIVE_PLAY_THRESHOLD.getNumber() * TimeAmount.MINUTE.ms(); - int requiredLogins = Settings.ACTIVE_LOGIN_THRESHOLD.getNumber(); - - for (int i = 0; i < requiredLogins * 2; i++) { - sessions.add(new Session(0, UUID, SERVER_UUID, weekAgo, weekAgo + requiredPlaytime * 3L, 0, 0, 0)); - sessions.add(new Session(0, UUID, SERVER_UUID, twoWeeksAgo, twoWeeksAgo + requiredPlaytime * 3L, 0, 0, 0)); - sessions.add(new Session(0, UUID, SERVER_UUID, threeWeeksAgo, threeWeeksAgo + requiredPlaytime * 3L, 0, 0, 0)); - } - container.putRawData(PlayerKeys.SESSIONS, sessions); - assertTrue(container.supports(PlayerKeys.SESSIONS)); - assertTrue(container.getValue(PlayerKeys.SESSIONS).isPresent()); - - assertEquals(5.0, new ActivityIndex(container, date).getValue()); - } - - @Test - public void testActivityIndexOne() { - PlayerContainer container = new PlayerContainer(); - List sessions = new ArrayList<>(); - - long date = System.currentTimeMillis(); - long week = TimeAmount.WEEK.ms(); - long weekAgo = date - week; - long twoWeeksAgo = date - 2L * week; - long threeWeeksAgo = date - 3L * week; - - int requiredLogins = Settings.ACTIVE_LOGIN_THRESHOLD.getNumber(); - long requiredPlaytime = Settings.ACTIVE_PLAY_THRESHOLD.getNumber() * TimeAmount.MINUTE.ms() / requiredLogins; - - for (int i = 0; i < requiredLogins; i++) { - sessions.add(new Session(i, UUID, SERVER_UUID, weekAgo, weekAgo + requiredPlaytime, 0, 0, 0)); - sessions.add(new Session(i * 2, UUID, SERVER_UUID, twoWeeksAgo, twoWeeksAgo + requiredPlaytime, 0, 0, 0)); - sessions.add(new Session(i * 3, UUID, SERVER_UUID, threeWeeksAgo, threeWeeksAgo + requiredPlaytime, 0, 0, 0)); - } - container.putRawData(PlayerKeys.SESSIONS, sessions); - - assertTrue(2.0 <= new ActivityIndex(container, date).getValue()); - } - - @Test(timeout = 500) - public void testTimeout() { - PlayerContainer container = new PlayerContainer(); - List sessions = new ArrayList<>(); - - for (int i = 0; i < 5000; i++) { - sessions.add(new Session(0, UUID, SERVER_UUID, 0, 0, 0, 0, 0)); - } - container.putRawData(PlayerKeys.SESSIONS, sessions); - - new ActivityIndex(container, 0).getValue(); - } -} \ No newline at end of file diff --git a/Plan/src/test/java/com/djrapitops/plan/data/container/GeoInfoTest.java b/Plan/src/test/java/com/djrapitops/plan/data/container/GeoInfoTest.java index 6e382eacf..7b7c19871 100644 --- a/Plan/src/test/java/com/djrapitops/plan/data/container/GeoInfoTest.java +++ b/Plan/src/test/java/com/djrapitops/plan/data/container/GeoInfoTest.java @@ -24,4 +24,24 @@ public class GeoInfoTest { assertEquals(expected, result); } + @Test + public void testFormatIP() throws UnknownHostException { + InetAddress ip = InetAddress.getByName("1.2.3.4"); + InetAddress ip2 = InetAddress.getByName("1.2.3.26"); + InetAddress ip3 = InetAddress.getByName("1.2.3.235"); + String expected = "1.2.xx.xx"; + + assertEquals(expected, GeoInfo.formatIP(ip)); + assertEquals(expected, GeoInfo.formatIP(ip2)); + assertEquals(expected, GeoInfo.formatIP(ip3)); + } + + @Test + public void testFormatIPv6() throws UnknownHostException { + InetAddress ip = InetAddress.getByName("1234:1234:1234:1234:1234:1234:1234:1234%0"); + String expected = "1234:1234:1234:xx.."; + + assertEquals(expected, GeoInfo.formatIP(ip)); + } + } \ No newline at end of file diff --git a/Plan/src/test/java/com/djrapitops/plan/data/container/SessionTest.java b/Plan/src/test/java/com/djrapitops/plan/data/container/SessionTest.java index d58898680..37870eed7 100644 --- a/Plan/src/test/java/com/djrapitops/plan/data/container/SessionTest.java +++ b/Plan/src/test/java/com/djrapitops/plan/data/container/SessionTest.java @@ -7,6 +7,7 @@ import utilities.TestConstants; import java.util.List; import java.util.Optional; +import java.util.UUID; import static org.junit.Assert.*; @@ -17,10 +18,12 @@ import static org.junit.Assert.*; */ public class SessionTest { + private final UUID serverUUID = TestConstants.SERVER_UUID; + @Test public void safeStartKeyConstructor() { for (int i = 0; i < 10000; i++) { - Session session = new Session(null, System.currentTimeMillis(), null, null); + Session session = new Session(null, serverUUID, System.currentTimeMillis(), null, null); // Should not throw session.getUnsafe(SessionKeys.START); @@ -40,7 +43,7 @@ public class SessionTest { @Test public void killsAreAdded() { - Session session = new Session(null, System.currentTimeMillis(), "", ""); + Session session = new Session(null, serverUUID, System.currentTimeMillis(), "", ""); Optional> beforeOptional = session.getValue(SessionKeys.PLAYER_KILLS); assertTrue(beforeOptional.isPresent()); @@ -59,7 +62,7 @@ public class SessionTest { @Test public void killsAreAdded2() { - Session session = new Session(null, System.currentTimeMillis(), "", ""); + Session session = new Session(null, serverUUID, System.currentTimeMillis(), "", ""); session.playerKilled(new PlayerKill(TestConstants.PLAYER_TWO_UUID, "Weapon", System.currentTimeMillis())); @@ -73,7 +76,7 @@ public class SessionTest { @Test public void worldTimesWorks() { long time = System.currentTimeMillis(); - Session session = new Session(null, time, "One", "Survival"); + Session session = new Session(null, serverUUID, time, "One", "Survival"); session.changeState("Two", "Three", time + 5L); Optional optional = session.getValue(SessionKeys.WORLD_TIMES); diff --git a/Plan/src/test/java/com/djrapitops/plan/data/store/containers/DataContainerTest.java b/Plan/src/test/java/com/djrapitops/plan/data/store/containers/DataContainerTest.java index 3f0a8c1b4..3c121c573 100644 --- a/Plan/src/test/java/com/djrapitops/plan/data/store/containers/DataContainerTest.java +++ b/Plan/src/test/java/com/djrapitops/plan/data/store/containers/DataContainerTest.java @@ -20,8 +20,6 @@ public class DataContainerTest { DataContainer container = new DataContainer(); container.putSupplier(TEST_KEY, () -> "Success"); - // Test twice for CachingSupplier - assertEquals("Success", container.getUnsafe(TEST_KEY)); assertEquals("Success", container.getUnsafe(TEST_KEY)); } @@ -30,8 +28,6 @@ public class DataContainerTest { DataContainer container = new DataContainer(); container.putSupplier(TEST_KEY, () -> "Success"); - // Test twice for CachingSupplier - assertEquals("Success", container.getUnsafe(TEST_KEY_COPY)); assertEquals("Success", container.getUnsafe(TEST_KEY_COPY)); } @@ -40,8 +36,6 @@ public class DataContainerTest { DataContainer container = new DataContainer(); container.putRawData(TEST_KEY, "Success"); - // Test twice for CachingSupplier - assertEquals("Success", container.getUnsafe(TEST_KEY)); assertEquals("Success", container.getUnsafe(TEST_KEY)); } @@ -50,8 +44,6 @@ public class DataContainerTest { DataContainer container = new DataContainer(); container.putRawData(TEST_KEY, "Success"); - // Test twice for CachingSupplier - assertEquals("Success", container.getUnsafe(TEST_KEY_COPY)); assertEquals("Success", container.getUnsafe(TEST_KEY_COPY)); } @@ -60,10 +52,8 @@ public class DataContainerTest { DataContainer container = new DataContainer(); container.putRawData(TEST_KEY, null); - // Test twice for CachingSupplier assertTrue(container.supports(TEST_KEY)); assertNull(container.getUnsafe(TEST_KEY)); - assertNull(container.getUnsafe(TEST_KEY)); } @Test @@ -79,10 +69,27 @@ public class DataContainerTest { DataContainer container = new DataContainer(); container.putSupplier(TEST_KEY, () -> null); - // Test twice for CachingSupplier assertTrue(container.supports(TEST_KEY)); assertNull(container.getUnsafe(TEST_KEY)); - assertNull(container.getUnsafe(TEST_KEY)); + } + + @Test + public void cachingSupplier() { + DataContainer container = new DataContainer(); + String firstObj = "First"; + String secondObj = "Second"; + + assertNotSame(firstObj, secondObj); + + container.putCachingSupplier(TEST_KEY, () -> firstObj); + + String found = container.getUnsafe(TEST_KEY); + assertEquals(firstObj, found); + assertSame(firstObj, found); + assertNotSame(secondObj, found); + + String secondCall = container.getUnsafe(TEST_KEY); + assertSame(found, secondCall); } } \ No newline at end of file diff --git a/Plan/src/test/java/com/djrapitops/plan/data/store/mutators/FormattersTest.java b/Plan/src/test/java/com/djrapitops/plan/data/store/mutators/FormattersTest.java deleted file mode 100644 index dcd226989..000000000 --- a/Plan/src/test/java/com/djrapitops/plan/data/store/mutators/FormattersTest.java +++ /dev/null @@ -1,44 +0,0 @@ -package com.djrapitops.plan.data.store.mutators; - -import com.djrapitops.plan.data.store.mutators.formatting.Formatters; -import com.djrapitops.plugin.api.TimeAmount; -import org.junit.BeforeClass; -import org.junit.ClassRule; -import org.junit.Test; -import org.junit.rules.TemporaryFolder; -import utilities.Teardown; -import utilities.mocks.SystemMockUtil; - -import static org.junit.Assert.assertEquals; - -/** - * Test for the Formatters class. - * - * @author Rsl1122 - */ -public class FormattersTest { - @ClassRule - public static TemporaryFolder temporaryFolder = new TemporaryFolder(); - - @BeforeClass - public static void setUpClass() throws Exception { - SystemMockUtil.setUp(temporaryFolder.getRoot()) - .enableConfigSystem(); - Teardown.resetSettingsTempValues(); - } - - @Test - public void formatTimeAmount() { - String expResult = "1s"; - String result = Formatters.timeAmount().apply(TimeAmount.SECOND.ms()); - - assertEquals(expResult, result); - } - - @Test - public void formatTimeAmountMonths() { - long time = TimeAmount.DAY.ms() * 40L; - assertEquals("1 month, 10d ", Formatters.timeAmount().apply(time)); - } - -} \ No newline at end of file diff --git a/Plan/src/test/java/com/djrapitops/plan/data/store/mutators/TPSMutatorTest.java b/Plan/src/test/java/com/djrapitops/plan/data/store/mutators/TPSMutatorTest.java index 33d93c5e8..42d156ac7 100644 --- a/Plan/src/test/java/com/djrapitops/plan/data/store/mutators/TPSMutatorTest.java +++ b/Plan/src/test/java/com/djrapitops/plan/data/store/mutators/TPSMutatorTest.java @@ -9,6 +9,7 @@ import org.junit.Test; import java.util.ArrayList; import java.util.Collections; import java.util.List; +import java.util.concurrent.TimeUnit; import java.util.stream.Collectors; import static org.junit.Assert.*; @@ -28,9 +29,9 @@ public class TPSMutatorTest { testData = new ArrayList<>(); time = System.currentTimeMillis(); - long twoMonthsAgo = time - TimeAmount.MONTH.ms() * 2L; + long twoMonthsAgo = time - TimeAmount.MONTH.toMillis(2L); - for (long date = twoMonthsAgo; date < time; date += TimeAmount.MINUTE.ms()) { + for (long date = twoMonthsAgo; date < time; date += TimeUnit.MINUTES.toMillis(1L)) { testData.add( TPSBuilder.get().date(date) .tps(0.0) @@ -39,6 +40,7 @@ public class TPSMutatorTest { .usedMemory(0) .entities(0) .chunksLoaded(0) + .freeDiskSpace(0) .toTPS() ); } @@ -55,13 +57,14 @@ public class TPSMutatorTest { public void noDownTimeOnSingleEntry() { long expected = 0; long result = new TPSMutator(Collections.singletonList( - TPSBuilder.get().date(time - TimeAmount.DAY.ms()) + TPSBuilder.get().date(time - TimeUnit.DAYS.toMillis(1L)) .tps(0.0) .playersOnline(0) .usedCPU(0.0) .usedMemory(0) .entities(0) .chunksLoaded(0) + .freeDiskSpace(0) .toTPS() )).serverDownTime(); assertEquals(expected, result); @@ -69,8 +72,8 @@ public class TPSMutatorTest { @Test public void fullDownTime() { - long periodLength = TimeAmount.MINUTE.ms() * 5L; - long expected = TimeAmount.MONTH.ms() * 2L - periodLength; + long periodLength = TimeUnit.MINUTES.toMillis(5L); + long expected = TimeAmount.MONTH.toMillis(2L) - periodLength; TPSMutator tpsMutator = new TPSMutator(testData.stream() .filter(tps -> (tps.getDate() - time) % (periodLength) == 0) @@ -84,10 +87,10 @@ public class TPSMutatorTest { @Test public void filteredFullMonthDownTime() { - long periodLength = TimeAmount.MINUTE.ms() * 5L; - long expected = TimeAmount.MONTH.ms() - periodLength; + long periodLength = TimeUnit.MINUTES.toMillis(5L); + long expected = TimeAmount.MONTH.toMillis(1L) - periodLength; - long monthAgo = time - TimeAmount.MONTH.ms(); + long monthAgo = time - TimeAmount.MONTH.toMillis(1L); TPSMutator tpsMutator = new TPSMutator(testData.stream() .filter(tps -> (tps.getDate() - time) % (periodLength) == 0) .collect(Collectors.toList())) @@ -102,12 +105,12 @@ public class TPSMutatorTest { @Test public void filteredFullMonthDownTimeWhenRandomOrder() { - long periodLength = TimeAmount.MINUTE.ms() * 5L; - long expected = TimeAmount.MONTH.ms() - periodLength; + long periodLength = TimeUnit.MINUTES.toMillis(5L); + long expected = TimeAmount.MONTH.toMillis(1L) - periodLength; - List randomOrder = testData; + List randomOrder = new ArrayList<>(testData); Collections.shuffle(randomOrder); - long monthAgo = time - TimeAmount.MONTH.ms(); + long monthAgo = time - TimeAmount.MONTH.toMillis(1L); TPSMutator tpsMutator = new TPSMutator(randomOrder.stream() .filter(tps -> (tps.getDate() - time) % (periodLength) == 0) .collect(Collectors.toList())) @@ -122,7 +125,7 @@ public class TPSMutatorTest { @Test public void filterWorksCorrectly() { - long monthAgo = time - TimeAmount.MONTH.ms(); + long monthAgo = time - TimeAmount.MONTH.toMillis(1L); List filtered = new TPSMutator(testData).filterDataBetween(monthAgo, time).all(); for (TPS tps : filtered) { diff --git a/Plan/src/test/java/com/djrapitops/plan/data/store/mutators/formatting/DecimalFormatterTest.java b/Plan/src/test/java/com/djrapitops/plan/data/store/mutators/formatting/DecimalFormatterTest.java new file mode 100644 index 000000000..93985d8bb --- /dev/null +++ b/Plan/src/test/java/com/djrapitops/plan/data/store/mutators/formatting/DecimalFormatterTest.java @@ -0,0 +1,48 @@ +package com.djrapitops.plan.data.store.mutators.formatting; + +import com.djrapitops.plan.system.settings.Settings; +import com.djrapitops.plan.system.settings.config.PlanConfig; +import com.djrapitops.plan.utilities.formatting.DecimalFormatter; +import org.junit.Before; +import org.junit.Test; +import org.mockito.Mockito; + +import static org.junit.Assert.assertTrue; +import static org.mockito.Mockito.when; + +/** + * Test for {@link DecimalFormatter} class. + * + * @author Rsl1122 + */ +public class DecimalFormatterTest { + + private DecimalFormatter underTest; + + @Before + public void setUp() { + PlanConfig config = Mockito.mock(PlanConfig.class); + when(config.getString(Settings.FORMAT_DECIMALS)).thenReturn("#.##"); + + underTest = new DecimalFormatter(config); + } + + @Test + public void testCutDecimalsWhichIsRoundedDown() { + double d = 0.05234; + + String result = underTest.apply(d); + + assertTrue("0.05".equals(result) || "0,05".equals(result)); + } + + @Test + public void testCutDecimalsWhichIsRoundedUp() { + double d = 0.05634; + + String result = underTest.apply(d); + + assertTrue("0.06".equals(result) || "0,06".equals(result)); + } + +} \ No newline at end of file diff --git a/Plan/src/test/java/com/djrapitops/plan/data/store/mutators/formatting/TimeAmountFormatterDefaultTest.java b/Plan/src/test/java/com/djrapitops/plan/data/store/mutators/formatting/TimeAmountFormatterDefaultTest.java index 236388d4d..98cea0aa6 100644 --- a/Plan/src/test/java/com/djrapitops/plan/data/store/mutators/formatting/TimeAmountFormatterDefaultTest.java +++ b/Plan/src/test/java/com/djrapitops/plan/data/store/mutators/formatting/TimeAmountFormatterDefaultTest.java @@ -1,14 +1,16 @@ package com.djrapitops.plan.data.store.mutators.formatting; import com.djrapitops.plan.system.settings.Settings; -import com.djrapitops.plugin.api.TimeAmount; -import org.junit.AfterClass; -import org.junit.Before; +import com.djrapitops.plan.system.settings.config.PlanConfig; +import com.djrapitops.plan.utilities.formatting.time.TimeAmountFormatter; import org.junit.BeforeClass; import org.junit.Test; -import utilities.Teardown; +import org.mockito.Mockito; + +import java.util.concurrent.TimeUnit; import static org.junit.Assert.assertEquals; +import static org.mockito.Mockito.when; /** * Test class for {@link TimeAmountFormatter} that checks extra zeros config example. @@ -17,41 +19,35 @@ import static org.junit.Assert.assertEquals; */ public class TimeAmountFormatterDefaultTest { - private TimeAmountFormatter timeAmountFormatter; + private static TimeAmountFormatter underTest; @BeforeClass public static void setUpClass() { - Settings.FORMAT_YEAR.setTemporaryValue("1 year, "); - Settings.FORMAT_YEARS.setTemporaryValue("%years% years, "); - Settings.FORMAT_MONTH.setTemporaryValue("1 month, "); - Settings.FORMAT_MONTHS.setTemporaryValue("%months% months, "); - Settings.FORMAT_DAY.setTemporaryValue("1d "); - Settings.FORMAT_DAYS.setTemporaryValue("%days%d "); - Settings.FORMAT_HOURS.setTemporaryValue("%hours%h "); - Settings.FORMAT_MINUTES.setTemporaryValue("%minutes%m "); - Settings.FORMAT_SECONDS.setTemporaryValue("%seconds%s"); - Settings.FORMAT_ZERO_SECONDS.setTemporaryValue("0s"); - } - - @AfterClass - public static void tearDownClass() { - Teardown.resetSettingsTempValues(); - } - - @Before - public void setUp() { - timeAmountFormatter = new TimeAmountFormatter(); + PlanConfig config = Mockito.mock(PlanConfig.class); + when(config.getString(Settings.FORMAT_YEAR)).thenReturn("1 year, "); + when(config.getString(Settings.FORMAT_YEARS)).thenReturn("%years% years, "); + when(config.getString(Settings.FORMAT_MONTH)).thenReturn("1 month, "); + when(config.getString(Settings.FORMAT_YEAR)).thenReturn("1 year, "); + when(config.getString(Settings.FORMAT_MONTH)).thenReturn("1 month, "); + when(config.getString(Settings.FORMAT_MONTHS)).thenReturn("%months% months, "); + when(config.getString(Settings.FORMAT_DAY)).thenReturn("1d "); + when(config.getString(Settings.FORMAT_DAYS)).thenReturn("%days%d "); + when(config.getString(Settings.FORMAT_HOURS)).thenReturn("%hours%h "); + when(config.getString(Settings.FORMAT_MINUTES)).thenReturn("%minutes%m "); + when(config.getString(Settings.FORMAT_SECONDS)).thenReturn("%seconds%s"); + when(config.getString(Settings.FORMAT_ZERO_SECONDS)).thenReturn("0s"); + underTest = new TimeAmountFormatter(config); } @Test public void exampleOne() { String expected = "1 year, 1 month, 5d 12h 30m 20s"; - long ms = TimeAmount.DAY.ms() * 400L + - TimeAmount.HOUR.ms() * 12L + - TimeAmount.MINUTE.ms() * 30L + - TimeAmount.SECOND.ms() * 20L; - String result = timeAmountFormatter.apply(ms); + long ms = TimeUnit.DAYS.toMillis(400L) + + TimeUnit.HOURS.toMillis(12L) + + TimeUnit.MINUTES.toMillis(30L) + + TimeUnit.SECONDS.toMillis(20L); + String result = underTest.apply(ms); assertEquals(expected, result); } @@ -60,8 +56,8 @@ public class TimeAmountFormatterDefaultTest { public void exampleTwo() { String expected = "1 year, 1 month, 5d "; - long ms = TimeAmount.DAY.ms() * 400L; - String result = timeAmountFormatter.apply(ms); + long ms = TimeUnit.DAYS.toMillis(400L); + String result = underTest.apply(ms); assertEquals(expected, result); } @@ -70,9 +66,9 @@ public class TimeAmountFormatterDefaultTest { public void exampleThree() { String expected = "12h 20s"; - long ms = TimeAmount.HOUR.ms() * 12L + - TimeAmount.SECOND.ms() * 20L; - String result = timeAmountFormatter.apply(ms); + long ms = TimeUnit.HOURS.toMillis(12L) + + TimeUnit.SECONDS.toMillis(20L); + String result = underTest.apply(ms); assertEquals(expected, result); } @@ -81,8 +77,8 @@ public class TimeAmountFormatterDefaultTest { public void exampleFour() { String expected = "30m "; - long ms = TimeAmount.MINUTE.ms() * 30L; - String result = timeAmountFormatter.apply(ms); + long ms = TimeUnit.MINUTES.toMillis(30L); + String result = underTest.apply(ms); assertEquals(expected, result); } @@ -91,8 +87,8 @@ public class TimeAmountFormatterDefaultTest { public void exampleFive() { String expected = "20s"; - long ms = TimeAmount.SECOND.ms() * 20L; - String result = timeAmountFormatter.apply(ms); + long ms = TimeUnit.SECONDS.toMillis(20L); + String result = underTest.apply(ms); assertEquals(expected, result); } @@ -102,7 +98,7 @@ public class TimeAmountFormatterDefaultTest { String expected = "-"; long ms = 0L; - String result = timeAmountFormatter.apply(ms); + String result = underTest.apply(ms); assertEquals(expected, result); } @@ -111,8 +107,8 @@ public class TimeAmountFormatterDefaultTest { public void exampleOneSecond() { String expected = "1s"; - long ms = TimeAmount.SECOND.ms(); - String result = timeAmountFormatter.apply(ms); + long ms = TimeUnit.SECONDS.toMillis(1L); + String result = underTest.apply(ms); assertEquals(expected, result); } @@ -121,8 +117,8 @@ public class TimeAmountFormatterDefaultTest { public void exampleOneMinute() { String expected = "1m "; - long ms = TimeAmount.MINUTE.ms(); - String result = timeAmountFormatter.apply(ms); + long ms = TimeUnit.MINUTES.toMillis(1L); + String result = underTest.apply(ms); assertEquals(expected, result); } diff --git a/Plan/src/test/java/com/djrapitops/plan/data/store/mutators/formatting/TimeAmountFormatterExtraZerosTest.java b/Plan/src/test/java/com/djrapitops/plan/data/store/mutators/formatting/TimeAmountFormatterExtraZerosTest.java index 7971d5d9f..ace314cc1 100644 --- a/Plan/src/test/java/com/djrapitops/plan/data/store/mutators/formatting/TimeAmountFormatterExtraZerosTest.java +++ b/Plan/src/test/java/com/djrapitops/plan/data/store/mutators/formatting/TimeAmountFormatterExtraZerosTest.java @@ -1,14 +1,16 @@ package com.djrapitops.plan.data.store.mutators.formatting; import com.djrapitops.plan.system.settings.Settings; -import com.djrapitops.plugin.api.TimeAmount; -import org.junit.AfterClass; -import org.junit.Before; +import com.djrapitops.plan.system.settings.config.PlanConfig; +import com.djrapitops.plan.utilities.formatting.time.TimeAmountFormatter; import org.junit.BeforeClass; import org.junit.Test; -import utilities.Teardown; +import org.mockito.Mockito; + +import java.util.concurrent.TimeUnit; import static org.junit.Assert.assertEquals; +import static org.mockito.Mockito.when; /** * Test class for {@link TimeAmountFormatter} that checks extra zeros config example. @@ -17,41 +19,33 @@ import static org.junit.Assert.assertEquals; */ public class TimeAmountFormatterExtraZerosTest { - private TimeAmountFormatter timeAmountFormatter; + private static TimeAmountFormatter underTest; @BeforeClass public static void setUpClass() { - Settings.FORMAT_YEAR.setTemporaryValue("1 year, "); - Settings.FORMAT_YEARS.setTemporaryValue("%years% years, "); - Settings.FORMAT_MONTH.setTemporaryValue("1 month, "); - Settings.FORMAT_MONTHS.setTemporaryValue("%months% months, "); - Settings.FORMAT_DAY.setTemporaryValue("1d "); - Settings.FORMAT_DAYS.setTemporaryValue("%days%d "); - Settings.FORMAT_HOURS.setTemporaryValue("%zero%%hours%:"); - Settings.FORMAT_MINUTES.setTemporaryValue("%hours%%zero%%minutes%:"); - Settings.FORMAT_SECONDS.setTemporaryValue("%minutes%%zero%%seconds%"); - Settings.FORMAT_ZERO_SECONDS.setTemporaryValue("00:00:00"); - } - - @AfterClass - public static void tearDownClass() { - Teardown.resetSettingsTempValues(); - } - - @Before - public void setUp() { - timeAmountFormatter = new TimeAmountFormatter(); + PlanConfig config = Mockito.mock(PlanConfig.class); + when(config.getString(Settings.FORMAT_YEAR)).thenReturn("1 year, "); + when(config.getString(Settings.FORMAT_YEARS)).thenReturn("%years% years, "); + when(config.getString(Settings.FORMAT_MONTH)).thenReturn("1 month, "); + when(config.getString(Settings.FORMAT_MONTHS)).thenReturn("%months% months, "); + when(config.getString(Settings.FORMAT_DAY)).thenReturn("1d "); + when(config.getString(Settings.FORMAT_DAYS)).thenReturn("%days%d "); + when(config.getString(Settings.FORMAT_HOURS)).thenReturn("%zero%%hours%:"); + when(config.getString(Settings.FORMAT_MINUTES)).thenReturn("%hours%%zero%%minutes%:"); + when(config.getString(Settings.FORMAT_SECONDS)).thenReturn("%minutes%%zero%%seconds%"); + when(config.getString(Settings.FORMAT_ZERO_SECONDS)).thenReturn("00:00:00"); + underTest = new TimeAmountFormatter(config); } @Test public void exampleOne() { String expected = "1 year, 1 month, 5d 12:30:20"; - long ms = TimeAmount.DAY.ms() * 400L + - TimeAmount.HOUR.ms() * 12L + - TimeAmount.MINUTE.ms() * 30L + - TimeAmount.SECOND.ms() * 20L; - String result = timeAmountFormatter.apply(ms); + long ms = TimeUnit.DAYS.toMillis(400L) + + TimeUnit.HOURS.toMillis(12L) + + TimeUnit.MINUTES.toMillis(30L) + + TimeUnit.SECONDS.toMillis(20L); + String result = underTest.apply(ms); assertEquals(expected, result); } @@ -60,8 +54,8 @@ public class TimeAmountFormatterExtraZerosTest { public void exampleTwo() { String expected = "1 year, 1 month, 5d 00:00:00"; - long ms = TimeAmount.DAY.ms() * 400L; - String result = timeAmountFormatter.apply(ms); + long ms = TimeUnit.DAYS.toMillis(400L); + String result = underTest.apply(ms); assertEquals(expected, result); } @@ -70,9 +64,9 @@ public class TimeAmountFormatterExtraZerosTest { public void exampleThree() { String expected = "12:00:20"; - long ms = TimeAmount.HOUR.ms() * 12L + - TimeAmount.SECOND.ms() * 20L; - String result = timeAmountFormatter.apply(ms); + long ms = TimeUnit.HOURS.toMillis(12L) + + TimeUnit.SECONDS.toMillis(20L); + String result = underTest.apply(ms); assertEquals(expected, result); } @@ -81,8 +75,8 @@ public class TimeAmountFormatterExtraZerosTest { public void exampleFour() { String expected = "00:30:00"; - long ms = TimeAmount.MINUTE.ms() * 30L; - String result = timeAmountFormatter.apply(ms); + long ms = TimeUnit.MINUTES.toMillis(30L); + String result = underTest.apply(ms); assertEquals(expected, result); } @@ -91,8 +85,8 @@ public class TimeAmountFormatterExtraZerosTest { public void exampleFive() { String expected = "00:00:20"; - long ms = TimeAmount.SECOND.ms() * 20L; - String result = timeAmountFormatter.apply(ms); + long ms = TimeUnit.SECONDS.toMillis(20L); + String result = underTest.apply(ms); assertEquals(expected, result); } @@ -102,7 +96,7 @@ public class TimeAmountFormatterExtraZerosTest { String expected = "-"; long ms = 0L; - String result = timeAmountFormatter.apply(ms); + String result = underTest.apply(ms); assertEquals(expected, result); } @@ -111,8 +105,8 @@ public class TimeAmountFormatterExtraZerosTest { public void exampleOneSecond() { String expected = "00:00:01"; - long ms = TimeAmount.SECOND.ms(); - String result = timeAmountFormatter.apply(ms); + long ms = TimeUnit.SECONDS.toMillis(1L); + String result = underTest.apply(ms); assertEquals(expected, result); } @@ -121,8 +115,8 @@ public class TimeAmountFormatterExtraZerosTest { public void exampleOneMinute() { String expected = "00:01:00"; - long ms = TimeAmount.MINUTE.ms(); - String result = timeAmountFormatter.apply(ms); + long ms = TimeUnit.MINUTES.toMillis(1L); + String result = underTest.apply(ms); assertEquals(expected, result); } diff --git a/Plan/src/test/java/com/djrapitops/plan/data/time/GMTimesTest.java b/Plan/src/test/java/com/djrapitops/plan/data/time/GMTimesTest.java index 4879c616f..f862f9c52 100644 --- a/Plan/src/test/java/com/djrapitops/plan/data/time/GMTimesTest.java +++ b/Plan/src/test/java/com/djrapitops/plan/data/time/GMTimesTest.java @@ -3,123 +3,117 @@ package com.djrapitops.plan.data.time; import org.junit.Test; import java.util.HashMap; -import java.util.Map; import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; +/** + * Tests for {@link GMTimes}. + * + * @author Rsl1122 + */ public class GMTimesTest { @Test - public void testSetAllGMTimes() { - GMTimes gmTimes = new GMTimes(); - gmTimes.setAllGMTimes(1L, 2L, 3L, 4L); + public void allGMTimesAreSet() { + GMTimes times = new GMTimes(); + times.setAllGMTimes(1L, 2L, 3L, 4L); - Map times = gmTimes.getTimes(); - - assertEquals(times.size(), 4); - assertTrue(times.get("SURVIVAL") == 1L); - assertTrue(times.get("CREATIVE") == 2L); - assertTrue(times.get("ADVENTURE") == 3L); - assertTrue(times.get("SPECTATOR") == 4L); + assertEquals(1L, times.getTime("SURVIVAL")); + assertEquals(2L, times.getTime("CREATIVE")); + assertEquals(3L, times.getTime("ADVENTURE")); + assertEquals(4L, times.getTime("SPECTATOR")); } @Test - public void testSetAllGMTimesTooFew() { - GMTimes gmTimes = new GMTimes(); - gmTimes.setAllGMTimes(1L, 2L); + public void allGMTimesAreSetWithTooFewArguments() { + GMTimes times = new GMTimes(); + times.setAllGMTimes(1L, 2L); - Map times = gmTimes.getTimes(); - - assertEquals(times.size(), 4); - assertTrue(times.get("SURVIVAL") == 1L); - assertTrue(times.get("CREATIVE") == 2L); - assertTrue(times.get("ADVENTURE") == 0L); - assertTrue(times.get("SPECTATOR") == 0L); + assertEquals(1L, times.getTime("SURVIVAL")); + assertEquals(2L, times.getTime("CREATIVE")); + assertEquals(0L, times.getTime("ADVENTURE")); + assertEquals(0L, times.getTime("SPECTATOR")); } @Test - public void testSetAllGMTimesTooMany() { - GMTimes gmTimes = new GMTimes(); - gmTimes.setAllGMTimes(1L, 2L, 3L, 4L, 5L, 6L); + public void allGMTimesAreSetWithTooManyArguments() { + GMTimes times = new GMTimes(); + times.setAllGMTimes(1L, 2L, 3L, 4L, 5L, 6L); - Map times = gmTimes.getTimes(); - - assertEquals(times.size(), 4); - assertTrue(times.get("SURVIVAL") == 1L); - assertTrue(times.get("CREATIVE") == 2L); - assertTrue(times.get("ADVENTURE") == 3L); - assertTrue(times.get("SPECTATOR") == 4L); + assertEquals(1L, times.getTime("SURVIVAL")); + assertEquals(2L, times.getTime("CREATIVE")); + assertEquals(3L, times.getTime("ADVENTURE")); + assertEquals(4L, times.getTime("SPECTATOR")); } @Test - public void testResetTimes() { + public void timesAreReset() { GMTimes gmTimes = new GMTimes(); gmTimes.setAllGMTimes(4, 3, 2, 1); - gmTimes.resetTimes(10); + gmTimes.resetTimes(10L); - assertTrue(gmTimes.getTotal() == 10L); - assertTrue(gmTimes.getTime("SURVIVAL") == 10L); - assertTrue(gmTimes.getTime("ADVENTURE") == 0L); + assertEquals(10L, gmTimes.getTotal()); + assertEquals(10L, gmTimes.getTime("SURVIVAL")); + assertEquals(0L, gmTimes.getTime("ADVENTURE")); } @Test - public void testSetTime() { + public void timeIsSet() { GMTimes gmTimes = new GMTimes(); gmTimes.setTime("SURVIVAL", 5L); - assertTrue(gmTimes.getTime("SURVIVAL") == 5L); + assertEquals(5L, gmTimes.getTime("SURVIVAL")); } @Test - public void testRenameState() { + public void stateIsRenamed() { GMTimes gmTimes = new GMTimes(); gmTimes.setAllGMTimes(5L); gmTimes.renameState("SURVIVAL", "Survival"); - assertTrue(gmTimes.getTime("SURVIVAL") == 0L); - assertTrue(gmTimes.getTime("Survival") == 5L); + assertEquals(0L, gmTimes.getTime("SURVIVAL")); + assertEquals(5L, gmTimes.getTime("Survival")); } @Test - public void testChangeStateNormal() { + public void stateIsChangedAppropriately() { GMTimes gmTimes = new GMTimes(new HashMap<>(), "SURVIVAL", 0); gmTimes.changeState("CREATIVE", 5L); - assertTrue(gmTimes.getTime("SURVIVAL") == 5L); - assertTrue(gmTimes.getTime("CREATIVE") == 0L); + assertEquals(5L, gmTimes.getTime("SURVIVAL")); + assertEquals(0L, gmTimes.getTime("CREATIVE")); gmTimes.changeState("ADVENTURE", 20L); - assertTrue(gmTimes.getTime("SURVIVAL") == 5L); - assertTrue(gmTimes.getTime("CREATIVE") == 15L); - assertTrue(gmTimes.getTime("ADVENTURE") == 0L); + assertEquals(5L, gmTimes.getTime("SURVIVAL")); + assertEquals(15L, gmTimes.getTime("CREATIVE")); + assertEquals(0L, gmTimes.getTime("ADVENTURE")); } @Test - public void testChangeStateMissingStartTime() { + public void stateIsChangedWhenStartTimeIsDefault() { GMTimes gmTimes = new GMTimes("SURVIVAL"); gmTimes.changeState("CREATIVE", 5L); - assertTrue(5L == gmTimes.getTime("SURVIVAL")); - assertTrue(0L == gmTimes.getTime("CREATIVE")); + assertEquals(5L, gmTimes.getTime("SURVIVAL")); + assertEquals(0L, gmTimes.getTime("CREATIVE")); gmTimes.changeState("ADVENTURE", 20L); - assertTrue(5L == gmTimes.getTime("SURVIVAL")); - assertTrue(15L == gmTimes.getTime("CREATIVE")); - assertTrue(0L == gmTimes.getTime("ADVENTURE")); + assertEquals(5L, gmTimes.getTime("SURVIVAL")); + assertEquals(15L, gmTimes.getTime("CREATIVE")); + assertEquals(0L, gmTimes.getTime("ADVENTURE")); } @Test - public void testChangeStateMissingStartState() { + public void stateIsChangedWhenBeginStateIsDefault() { GMTimes test = new GMTimes(); test.changeState("CREATIVE", 5L); - assertTrue(5L == test.getTime("CREATIVE")); + assertEquals(5L, test.getTime("CREATIVE")); test.changeState("ADVENTURE", 20L); - assertTrue(20L == test.getTime("CREATIVE")); - assertTrue(0L == test.getTime("ADVENTURE")); + assertEquals(20L, test.getTime("CREATIVE")); + assertEquals(0L, test.getTime("ADVENTURE")); } } \ No newline at end of file diff --git a/Plan/src/test/java/com/djrapitops/plan/data/time/WorldTimesTest.java b/Plan/src/test/java/com/djrapitops/plan/data/time/WorldTimesTest.java index d85dca4c4..74187b1fb 100644 --- a/Plan/src/test/java/com/djrapitops/plan/data/time/WorldTimesTest.java +++ b/Plan/src/test/java/com/djrapitops/plan/data/time/WorldTimesTest.java @@ -22,7 +22,7 @@ public class WorldTimesTest { private WorldTimes worldTimes = new WorldTimes(worldOne, gms[0], time); @Test - public void testWorldChange() { + public void stateAffectedByWorldChange() { long changeTime = time + 1000L; worldTimes.updateState(worldTwo, gms[0], changeTime); @@ -31,7 +31,7 @@ public class WorldTimesTest { } @Test - public void testGMChange() { + public void stateAffectedByGamemodeChange() { long changeTime = time + 1000L; worldTimes.updateState(worldOne, gms[0], changeTime); @@ -40,7 +40,7 @@ public class WorldTimesTest { } @Test - public void testBothTwiceChange() { + public void stateAffectedByTwoChangesAtOnce() { long changeTime = time + 1000L; long changeTime2 = changeTime + 1000L; @@ -57,7 +57,7 @@ public class WorldTimesTest { } @Test - public void testLotOfChangesWorldTime() { + public void stateAffectedByManyWorldChanges() { long amount = 1000L; String[] worlds = new String[]{worldOne, worldTwo}; @@ -95,7 +95,7 @@ public class WorldTimesTest { } @Test - public void testGMTrackingSingleWorld() { + public void gamemodeTrackingWorksForASingleWorld() { long changeTime = time + 1000L; long changeTime2 = changeTime + 1000L; @@ -114,7 +114,7 @@ public class WorldTimesTest { } @Test - public void testGMTrackingTwoWorlds() { + public void gamemodeTrackingWorksForTwoWorlds() { long changeTime = time + 1000L; long changeTime2 = time + 2000L; diff --git a/Plan/src/test/java/com/djrapitops/plan/system/BungeeBukkitConnectionTest.java b/Plan/src/test/java/com/djrapitops/plan/system/BungeeBukkitConnectionTest.java deleted file mode 100644 index c0c2d06a4..000000000 --- a/Plan/src/test/java/com/djrapitops/plan/system/BungeeBukkitConnectionTest.java +++ /dev/null @@ -1,122 +0,0 @@ -/* - * License is provided in the jar as LICENSE also here: - * https://github.com/Rsl1122/Plan-PlayerAnalytics/blob/master/Plan/src/main/resources/LICENSE - */ -package com.djrapitops.plan.system; - -import com.djrapitops.plan.Plan; -import com.djrapitops.plan.PlanBungee; -import com.djrapitops.plan.api.exceptions.EnableException; -import com.djrapitops.plan.api.exceptions.connection.WebException; -import com.djrapitops.plan.system.database.ServerDBSystem; -import com.djrapitops.plan.system.info.request.GenerateInspectPluginsTabRequest; -import com.djrapitops.plan.system.info.server.ServerInfo; -import com.djrapitops.plan.system.locale.Locale; -import com.djrapitops.plan.system.settings.Settings; -import org.junit.*; -import org.junit.rules.ExpectedException; -import org.junit.rules.TemporaryFolder; -import org.junit.runner.RunWith; -import org.mockito.junit.MockitoJUnitRunner; -import utilities.Teardown; -import utilities.TestConstants; -import utilities.mocks.BukkitMockUtil; -import utilities.mocks.BungeeMockUtil; - -import java.util.UUID; - -/** - * @author Rsl1122 - */ -@RunWith(MockitoJUnitRunner.Silent.class) -public class BungeeBukkitConnectionTest { - - @ClassRule - public static TemporaryFolder temporaryFolder = new TemporaryFolder(); - private static Plan bukkitMock; - private static PlanBungee bungeeMock; - - @Rule - public ExpectedException thrown = ExpectedException.none(); - - private BukkitSystem bukkitSystem; - private BungeeSystem bungeeSystem; - - private UUID bukkitUUID; - private UUID bungeeUUID; - - @BeforeClass - public static void setUpClass() throws Exception { - BukkitMockUtil bukkitMockUtil = BukkitMockUtil.setUp() - .withDataFolder(temporaryFolder.getRoot()) - .withLogging() - .withPluginDescription() - .withResourceFetchingFromJar() - .withServer(); - bukkitMock = bukkitMockUtil.getPlanMock(); - - BungeeMockUtil bungeeMockUtil = BungeeMockUtil.setUp() - .withDataFolder(temporaryFolder.getRoot()) - .withLogging() - .withPluginDescription() - .withResourceFetchingFromJar() - .withProxy(); - bungeeMock = bungeeMockUtil.getPlanMock(); - } - - @Before - public void setUp() { - Teardown.resetSettingsTempValues(); - Settings.DEBUG.setTemporaryValue("console"); - Settings.DEV_MODE.setTemporaryValue(true); - } - - @After - public void tearDown() { - System.out.println("------------------------------"); - System.out.println("Disable"); - System.out.println("------------------------------"); - if (bukkitSystem != null) { - bukkitSystem.disable(); - } - if (bungeeSystem != null) { - bungeeSystem.disable(); - } - Teardown.resetSettingsTempValues(); - } - - public void enable() throws EnableException { - Settings.WEBSERVER_PORT.setTemporaryValue(9005); - - bukkitSystem = new BukkitSystem(bukkitMock); - bukkitSystem.enable(); - - bukkitUUID = ServerInfo.getServerUUID(); - - bungeeSystem = new BungeeSystem(bungeeMock); - - Settings.WEBSERVER_PORT.setTemporaryValue(9250); - Settings.BUNGEE_IP.setTemporaryValue("localhost"); - Settings.DB_TYPE.setTemporaryValue("sqlite"); - bungeeSystem.setDatabaseSystem(new ServerDBSystem(Locale::new)); - - bungeeSystem.enable(); - - bungeeUUID = ServerInfo.getServerUUID(); - - System.out.println("------------------------------"); - System.out.println("Enable Complete"); - System.out.println("Bukkit: " + bukkitUUID); - System.out.println("Bungee: " + bungeeUUID); - System.out.println("------------------------------"); - } - - @Test - @Ignore("Causes next BungeeSystem test to fail") - public void testRequest() throws EnableException, WebException { - enable(); - - System.out.println("Sending request"); - bungeeSystem.getInfoSystem().getConnectionSystem().sendWideInfoRequest(new GenerateInspectPluginsTabRequest(TestConstants.PLAYER_ONE_UUID)); - } -} diff --git a/Plan/src/test/java/com/djrapitops/plan/system/BungeeSystemTest.java b/Plan/src/test/java/com/djrapitops/plan/system/BungeeSystemTest.java deleted file mode 100644 index 7b8bb705f..000000000 --- a/Plan/src/test/java/com/djrapitops/plan/system/BungeeSystemTest.java +++ /dev/null @@ -1,95 +0,0 @@ -/* - * License is provided in the jar as LICENSE also here: - * https://github.com/Rsl1122/Plan-PlayerAnalytics/blob/master/Plan/src/main/resources/LICENSE - */ -package com.djrapitops.plan.system; - -import com.djrapitops.plan.PlanBungee; -import com.djrapitops.plan.api.exceptions.EnableException; -import com.djrapitops.plan.system.database.ServerDBSystem; -import com.djrapitops.plan.system.locale.Locale; -import com.djrapitops.plan.system.settings.Settings; -import org.junit.*; -import org.junit.rules.ExpectedException; -import org.junit.rules.TemporaryFolder; -import org.junit.runner.RunWith; -import org.mockito.junit.MockitoJUnitRunner; -import utilities.Teardown; -import utilities.mocks.BungeeMockUtil; - -/** - * Test for BukkitSystem. - * - * @author Rsl1122 - */ -@RunWith(MockitoJUnitRunner.Silent.class) -public class BungeeSystemTest { - - @ClassRule - public static TemporaryFolder temporaryFolder = new TemporaryFolder(); - private static PlanBungee planMock; - @Rule - public ExpectedException thrown = ExpectedException.none(); - private BungeeSystem bungeeSystem; - - @BeforeClass - public static void setUpClass() throws Exception { - BungeeMockUtil mockUtil = BungeeMockUtil.setUp() - .withDataFolder(temporaryFolder.getRoot()) - .withLogging() - .withPluginDescription() - .withResourceFetchingFromJar() - .withProxy(); - planMock = mockUtil.getPlanMock(); - } - - - @Before - public void setUp() { - Teardown.resetSettingsTempValues(); - } - - @After - public void tearDown() { - if (bungeeSystem != null) { - bungeeSystem.disable(); - } - Teardown.resetSettingsTempValues(); - } - - @Test - public void testEnable() throws EnableException { - bungeeSystem = new BungeeSystem(planMock); - - Settings.WEBSERVER_PORT.setTemporaryValue(9005); - Settings.BUNGEE_IP.setTemporaryValue("8.8.8.8"); - Settings.DB_TYPE.setTemporaryValue("sqlite"); - bungeeSystem.setDatabaseSystem(new ServerDBSystem(Locale::new)); - - bungeeSystem.enable(); - } - - @Test - public void testEnableDefaultIP() throws EnableException { - thrown.expect(EnableException.class); - thrown.expectMessage("IP setting still 0.0.0.0 - Configure AlternativeIP/IP that connects to the Proxy server."); - - bungeeSystem = new BungeeSystem(planMock); - - Settings.WEBSERVER_PORT.setTemporaryValue(9005); - Settings.DB_TYPE.setTemporaryValue("sqlite"); - bungeeSystem.setDatabaseSystem(new ServerDBSystem(Locale::new)); - - bungeeSystem.enable(); - } - - @Test - @Ignore("MySQL Driver unavailable for some reason.") - public void testEnableNoMySQL() throws EnableException { - thrown.expect(EnableException.class); - thrown.expectMessage("Database failed to initialize"); - - bungeeSystem = new BungeeSystem(planMock); - bungeeSystem.enable(); - } -} diff --git a/Plan/src/test/java/com/djrapitops/plan/system/cache/GeolocationCacheTest.java b/Plan/src/test/java/com/djrapitops/plan/system/cache/GeolocationCacheTest.java index 3e5339806..8835552c3 100644 --- a/Plan/src/test/java/com/djrapitops/plan/system/cache/GeolocationCacheTest.java +++ b/Plan/src/test/java/com/djrapitops/plan/system/cache/GeolocationCacheTest.java @@ -1,62 +1,103 @@ package com.djrapitops.plan.system.cache; -import com.djrapitops.plan.Plan; import com.djrapitops.plan.api.exceptions.EnableException; -import com.djrapitops.plan.system.BukkitSystem; +import com.djrapitops.plan.system.file.PlanFiles; +import com.djrapitops.plan.system.locale.Locale; import com.djrapitops.plan.system.settings.Settings; -import com.djrapitops.plugin.StaticHolder; -import org.junit.AfterClass; +import com.djrapitops.plan.system.settings.config.PlanConfig; +import com.djrapitops.plugin.logging.console.TestPluginLogger; +import org.junit.Before; import org.junit.BeforeClass; import org.junit.ClassRule; import org.junit.Test; import org.junit.rules.TemporaryFolder; -import utilities.Teardown; -import utilities.mocks.BukkitMockUtil; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.junit.MockitoJUnitRunner; -import static org.junit.Assert.assertEquals; +import java.io.File; +import java.io.IOException; +import java.nio.file.Files; +import java.util.HashMap; +import java.util.Map; + +import static org.junit.Assert.*; +import static org.mockito.Mockito.when; /** - * Test for GeolocationCache. + * Tests for {@link GeolocationCache}. * - * @author Rsl1122 + * @author Fuzzlemann */ +@RunWith(MockitoJUnitRunner.Silent.class) public class GeolocationCacheTest { + private static final Map TEST_DATA = new HashMap<>(); + private static File IP_STORE; + @Mock + public PlanFiles files; + @Mock + public PlanConfig config; + @ClassRule public static TemporaryFolder temporaryFolder = new TemporaryFolder(); - private static Plan planMock; + private GeolocationCache underTest; @BeforeClass - public static void setUpClass() throws Exception { - Teardown.resetSettingsTempValues(); - BukkitMockUtil mockUtil = BukkitMockUtil.setUp() - .withDataFolder(temporaryFolder.getRoot()) - .withLogging() - .withPluginDescription() - .withResourceFetchingFromJar() - .withServer(); - planMock = mockUtil.getPlanMock(); - StaticHolder.saveInstance(GeolocationCacheTest.class, planMock.getClass()); + public static void setUpClass() throws IOException { + IP_STORE = temporaryFolder.newFile("GeoIP.dat"); + // TemporaryFolder creates the file, which prevents cache from downloading the GeoIP database from the internet. + // This is why the file needs to be removed first. + Files.delete(IP_STORE.toPath()); + + TEST_DATA.put("8.8.8.8", "United States"); + TEST_DATA.put("8.8.4.4", "United States"); + TEST_DATA.put("4.4.2.2", "United States"); + TEST_DATA.put("208.67.222.222", "United States"); + TEST_DATA.put("208.67.220.220", "United States"); + TEST_DATA.put("205.210.42.205", "Canada"); + TEST_DATA.put("64.68.200.200", "Canada"); + TEST_DATA.put("0.0.0.0", "Not Known"); + TEST_DATA.put("127.0.0.1", "Local Machine"); } - @AfterClass - public static void tearDownClass() { - Teardown.resetSettingsTempValues(); + @Before + public void setUp() throws EnableException { + when(config.isTrue(Settings.DATA_GEOLOCATIONS)).thenReturn(true); + when(files.getFileFromPluginFolder("GeoIP.dat")).thenReturn(IP_STORE); + + assertTrue(config.isTrue(Settings.DATA_GEOLOCATIONS)); + + underTest = new GeolocationCache(new Locale(), files, config, new TestPluginLogger()); + underTest.enable(); } @Test - public void testGeolocationCache() throws EnableException { - Settings.WEBSERVER_PORT.setTemporaryValue(9005); - BukkitSystem system = new BukkitSystem(planMock); - try { - system.enable(); + public void countryIsFetched() { + for (Map.Entry entry : TEST_DATA.entrySet()) { + String ip = entry.getKey(); + String expCountry = entry.getValue(); - String expected = "Germany"; - String result = GeolocationCache.getCountry("141.52.255.1"); - assertEquals(expected, result); - } finally { - system.disable(); + String country = underTest.getCountry(ip); + + assertEquals(expCountry, country); } } -} \ No newline at end of file + @Test + public void callsToCachedIPsReturnCachedEntries() { + for (Map.Entry entry : TEST_DATA.entrySet()) { + String ip = entry.getKey(); + String expIp = entry.getValue(); + + assertFalse(underTest.isCached(ip)); + String countrySecondCall = underTest.getCountry(ip); + assertTrue(underTest.isCached(ip)); + + String countryThirdCall = underTest.getCountry(ip); + + assertSame(countrySecondCall, countryThirdCall); + assertEquals(expIp, countryThirdCall); + } + } +} diff --git a/Plan/src/test/java/com/djrapitops/plan/system/cache/SessionCacheTest.java b/Plan/src/test/java/com/djrapitops/plan/system/cache/SessionCacheTest.java index 7316387ab..b12cf3120 100644 --- a/Plan/src/test/java/com/djrapitops/plan/system/cache/SessionCacheTest.java +++ b/Plan/src/test/java/com/djrapitops/plan/system/cache/SessionCacheTest.java @@ -1,10 +1,10 @@ package com.djrapitops.plan.system.cache; import com.djrapitops.plan.data.container.Session; -import org.junit.*; -import org.junit.rules.TemporaryFolder; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; import utilities.TestConstants; -import utilities.mocks.SystemMockUtil; import java.util.Optional; import java.util.UUID; @@ -14,22 +14,15 @@ import static org.junit.Assert.assertTrue; public class SessionCacheTest { - @ClassRule - public static TemporaryFolder temporaryFolder = new TemporaryFolder(); - private SessionCache sessionCache; private Session session; private final UUID uuid = TestConstants.PLAYER_ONE_UUID; - - @BeforeClass - public static void setUpClass() throws Exception { - SystemMockUtil.setUp(temporaryFolder.getRoot()) - .enableProcessing(); - } + private final UUID serverUUID = TestConstants.SERVER_UUID; @Before public void setUp() { - sessionCache = new SessionCache(null); - session = new Session(uuid, 12345L, "World1", "SURVIVAL"); + session = new Session(uuid, serverUUID, 12345L, "World1", "SURVIVAL"); + + SessionCache sessionCache = new SessionCache(null); sessionCache.cacheSession(uuid, session); } @@ -40,7 +33,6 @@ public class SessionCacheTest { @Test public void testAtomity() { - SessionCache reloaded = new SessionCache(null); Optional cachedSession = SessionCache.getCachedSession(uuid); assertTrue(cachedSession.isPresent()); assertEquals(session, cachedSession.get()); @@ -48,9 +40,9 @@ public class SessionCacheTest { @Test public void testBungeeReCaching() { - SessionCache cache = new BungeeDataCache(null); + SessionCache cache = new ProxyDataCache(null, null); cache.cacheSession(uuid, session); - Session expected = new Session(uuid, 0, "", ""); + Session expected = new Session(uuid, serverUUID, 0, "", ""); cache.cacheSession(uuid, expected); Optional result = SessionCache.getCachedSession(uuid); diff --git a/Plan/src/test/java/com/djrapitops/plan/system/database/databases/MySQLTest.java b/Plan/src/test/java/com/djrapitops/plan/system/database/databases/MySQLTest.java deleted file mode 100644 index 855d869aa..000000000 --- a/Plan/src/test/java/com/djrapitops/plan/system/database/databases/MySQLTest.java +++ /dev/null @@ -1,30 +0,0 @@ -/* - * License is provided in the jar as LICENSE also here: - * https://github.com/Rsl1122/Plan-PlayerAnalytics/blob/master/Plan/src/main/resources/LICENSE - */ -package com.djrapitops.plan.system.database.databases; - -import com.djrapitops.plan.system.database.databases.sql.MySQLDB; -import com.djrapitops.plan.system.locale.Locale; -import org.junit.Test; - -import static org.junit.Assert.assertEquals; - -/** - * Tests MySQLDB. - * - * @author Rsl1122 - */ -public class MySQLTest { - - @Test - public void testMySQLGetConfigName() { - assertEquals("mysql", new MySQLDB(Locale::new).getConfigName()); - } - - @Test - public void testMySQLGetName() { - assertEquals("MySQL", new MySQLDB(Locale::new).getName()); - } - -} diff --git a/Plan/src/test/java/com/djrapitops/plan/system/database/databases/SQLiteTest.java b/Plan/src/test/java/com/djrapitops/plan/system/database/databases/SQLiteTest.java index 7026f96be..ed866437c 100644 --- a/Plan/src/test/java/com/djrapitops/plan/system/database/databases/SQLiteTest.java +++ b/Plan/src/test/java/com/djrapitops/plan/system/database/databases/SQLiteTest.java @@ -5,8 +5,8 @@ */ package com.djrapitops.plan.system.database.databases; -import com.djrapitops.plan.Plan; -import com.djrapitops.plan.api.exceptions.database.DBException; +import com.djrapitops.plan.DaggerPlanBukkitComponent; +import com.djrapitops.plan.PlanBukkitComponent; import com.djrapitops.plan.api.exceptions.database.DBInitException; import com.djrapitops.plan.data.WebUser; import com.djrapitops.plan.data.container.*; @@ -19,33 +19,33 @@ import com.djrapitops.plan.data.store.keys.*; import com.djrapitops.plan.data.store.objects.Nickname; import com.djrapitops.plan.data.time.GMTimes; import com.djrapitops.plan.data.time.WorldTimes; +import com.djrapitops.plan.system.PlanSystem; +import com.djrapitops.plan.system.database.DBSystem; import com.djrapitops.plan.system.database.databases.sql.SQLDB; import com.djrapitops.plan.system.database.databases.sql.SQLiteDB; import com.djrapitops.plan.system.database.databases.sql.tables.*; import com.djrapitops.plan.system.info.server.Server; -import com.djrapitops.plan.system.info.server.ServerInfo; -import com.djrapitops.plan.system.locale.Locale; -import com.djrapitops.plan.system.processing.processors.player.RegisterProcessor; +import com.djrapitops.plan.system.settings.Settings; import com.djrapitops.plan.utilities.Base64Util; import com.djrapitops.plan.utilities.SHA256Hash; -import com.djrapitops.plugin.StaticHolder; -import com.djrapitops.plugin.api.TimeAmount; -import com.djrapitops.plugin.api.utility.log.Log; import org.junit.*; import org.junit.rules.TemporaryFolder; import org.junit.rules.Timeout; import org.junit.runner.RunWith; import org.mockito.junit.MockitoJUnitRunner; -import utilities.*; -import utilities.mocks.SystemMockUtil; +import utilities.OptionalAssert; +import utilities.RandomData; +import utilities.TestConstants; +import utilities.mocks.PlanBukkitMocker; -import java.io.UnsupportedEncodingException; +import java.io.File; import java.lang.management.ManagementFactory; import java.lang.management.OperatingSystemMXBean; import java.lang.reflect.Field; import java.lang.reflect.Modifier; import java.security.NoSuchAlgorithmException; import java.util.*; +import java.util.concurrent.TimeUnit; import static org.junit.Assert.*; @@ -55,50 +55,49 @@ import static org.junit.Assert.*; @RunWith(MockitoJUnitRunner.Silent.class) public class SQLiteTest { - private final List worlds = Arrays.asList("TestWorld", "TestWorld2"); @ClassRule public static TemporaryFolder temporaryFolder = new TemporaryFolder(); + private static DBSystem dbSystem; private static SQLDB db; + private static PlanSystem system; + + private final List worlds = Arrays.asList("TestWorld", "TestWorld2"); private final UUID playerUUID = TestConstants.PLAYER_ONE_UUID; private final UUID player2UUID = TestConstants.PLAYER_TWO_UUID; + private final UUID serverUUID = TestConstants.SERVER_UUID; @Rule public Timeout globalTimeout = Timeout.seconds(5); @BeforeClass public static void setUpClass() throws Exception { System.out.println("--- Test Class Setup ---"); - SystemMockUtil mockUtil = SystemMockUtil.setUp(temporaryFolder.getRoot()) - .enableConfigSystem(); - db = new SQLiteDB(Locale::new); - mockUtil.enableDatabaseSystem(db) - .enableServerInfoSystem(); - StaticHolder.saveInstance(SQLDB.class, Plan.class); - StaticHolder.saveInstance(SQLiteTest.class, Plan.class); + PlanBukkitMocker mockUtil = PlanBukkitMocker.setUp() + .withDataFolder(temporaryFolder.newFolder()) + .withPluginDescription() + .withResourceFetchingFromJar() + .withServer(); + PlanBukkitComponent component = DaggerPlanBukkitComponent.builder().plan(mockUtil.getPlanMock()).build(); + system = component.system(); + system.getConfigSystem().getConfig().set(Settings.WEBSERVER_PORT, 9005); + system.enable(); - Log.setErrorManager(new TestErrorManager()); - Log.setDebugMode("console"); -// Settings.DEV_MODE.setTemporaryValue(true); - - db.init(); + dbSystem = system.getDatabaseSystem(); + db = (SQLDB) dbSystem.getDatabase(); System.out.println("--- Class Setup Complete ---\n"); } @AfterClass public static void tearDownClass() { - if (db != null) { - db.close(); - } - Teardown.resetSettingsTempValues(); + system.disable(); } @Before public void setUp() { - assertEquals(db, Database.getActive()); System.out.println("\n-- Clearing Test Database --"); db.remove().everything(); ServerTable serverTable = db.getServerTable(); serverTable.saveCurrentServerInfo(new Server(-1, TestConstants.SERVER_UUID, "ServerName", "", 20)); - assertEquals(ServerInfo.getServerUUID(), TestConstants.SERVER_UUID); + assertEquals(db.getServerUUIDSupplier().get(), TestConstants.SERVER_UUID); System.out.println("-- Clear Complete --\n"); } @@ -213,7 +212,7 @@ public class SQLiteTest { List expected = new ArrayList<>(); for (int i = 0; i < RandomData.randomInt(1, 5); i++) { - expected.add(new TPS(r.nextLong(), r.nextDouble(), r.nextInt(100000000), r.nextDouble(), r.nextLong(), r.nextInt(), r.nextInt())); + expected.add(new TPS(r.nextLong(), r.nextDouble(), r.nextInt(100000000), r.nextDouble(), r.nextLong(), r.nextInt(), r.nextInt(), r.nextLong())); } for (TPS tps : expected) { @@ -350,7 +349,7 @@ public class SQLiteTest { saveTwoWorlds(); saveUserOne(); saveUserTwo(); - Session session = new Session(TestConstants.PLAYER_ONE_UUID, 12345L, "", ""); + Session session = new Session(TestConstants.PLAYER_ONE_UUID, serverUUID, 12345L, "", ""); session.endSession(22345L); session.setWorldTimes(createWorldTimes()); session.setPlayerKills(createKills()); @@ -381,7 +380,7 @@ public class SQLiteTest { saveUserOne(); saveUserTwo(); - Session session = new Session(TestConstants.PLAYER_ONE_UUID, 12345L, "", ""); + Session session = new Session(TestConstants.PLAYER_ONE_UUID, serverUUID, 12345L, "", ""); session.endSession(22345L); session.setWorldTimes(createWorldTimes()); session.setPlayerKills(createKills()); @@ -403,7 +402,7 @@ public class SQLiteTest { System.out.println(" " + entry.getValue()); } - List savedSessions = sessions.get(ServerInfo.getServerUUID()); + List savedSessions = sessions.get(serverUUID); assertNotNull(savedSessions); assertEquals(1, savedSessions.size()); @@ -435,7 +434,7 @@ public class SQLiteTest { assertEquals(playerUUID, userInfo.getUuid()); assertEquals(123456789L, (long) usersTable.getRegisterDates().get(0)); assertEquals(123456789L, userInfo.getRegistered()); - assertEquals(1, userInfoTable.getServerUserCount(ServerInfo.getServerUUID())); + assertEquals(1, userInfoTable.getServerUserCount(serverUUID)); assertEquals("Waiting for Update..", userInfo.getName()); assertFalse(userInfo.isBanned()); assertFalse(userInfo.isOperator()); @@ -545,7 +544,7 @@ public class SQLiteTest { userInfoTable.registerUserInfo(playerUUID, 223456789L); saveTwoWorlds(); - Session session = new Session(TestConstants.PLAYER_ONE_UUID, 12345L, "", ""); + Session session = new Session(TestConstants.PLAYER_ONE_UUID, serverUUID, 12345L, "", ""); session.endSession(22345L); session.setWorldTimes(createWorldTimes()); session.setPlayerKills(createKills()); @@ -566,7 +565,7 @@ public class SQLiteTest { } @Test - public void testRemovalEverything() throws UnsupportedEncodingException, NoSuchAlgorithmException { + public void testRemovalEverything() throws NoSuchAlgorithmException { UserInfoTable userInfoTable = db.getUserInfoTable(); UsersTable usersTable = db.getUsersTable(); SessionsTable sessionsTable = db.getSessionsTable(); @@ -611,7 +610,7 @@ public class SQLiteTest { userInfoTable.registerUserInfo(playerUUID, 223456789L); saveTwoWorlds(database); - Session session = new Session(TestConstants.PLAYER_ONE_UUID, 12345L, "", ""); + Session session = new Session(TestConstants.PLAYER_ONE_UUID, serverUUID, 12345L, "", ""); session.endSession(22345L); session.setWorldTimes(createWorldTimes()); session.setPlayerKills(createKills()); @@ -635,14 +634,15 @@ public class SQLiteTest { Random r = new Random(); OperatingSystemMXBean operatingSystemMXBean = ManagementFactory.getOperatingSystemMXBean(); int availableProcessors = ManagementFactory.getOperatingSystemMXBean().getAvailableProcessors(); - final double averageCPUUsage = operatingSystemMXBean.getSystemLoadAverage() / availableProcessors * 100.0; - final long usedMemory = 51231251254L; - final int entityCount = 6123; - final int chunksLoaded = 2134; - expected.add(new TPS(r.nextLong(), r.nextDouble(), r.nextInt(100000000), averageCPUUsage, usedMemory, entityCount, chunksLoaded)); - expected.add(new TPS(r.nextLong(), r.nextDouble(), r.nextInt(100000000), averageCPUUsage, usedMemory, entityCount, chunksLoaded)); - expected.add(new TPS(r.nextLong(), r.nextDouble(), r.nextInt(100000000), averageCPUUsage, usedMemory, entityCount, chunksLoaded)); - expected.add(new TPS(r.nextLong(), r.nextDouble(), r.nextInt(100000000), averageCPUUsage, usedMemory, entityCount, chunksLoaded)); + double averageCPUUsage = operatingSystemMXBean.getSystemLoadAverage() / availableProcessors * 100.0; + long usedMemory = 51231251254L; + int entityCount = 6123; + int chunksLoaded = 2134; + long freeDiskSpace = new File("").getUsableSpace(); + expected.add(new TPS(r.nextLong(), r.nextDouble(), r.nextInt(100000000), averageCPUUsage, usedMemory, entityCount, chunksLoaded, freeDiskSpace)); + expected.add(new TPS(r.nextLong(), r.nextDouble(), r.nextInt(100000000), averageCPUUsage, usedMemory, entityCount, chunksLoaded, freeDiskSpace)); + expected.add(new TPS(r.nextLong(), r.nextDouble(), r.nextInt(100000000), averageCPUUsage, usedMemory, entityCount, chunksLoaded, freeDiskSpace)); + expected.add(new TPS(r.nextLong(), r.nextDouble(), r.nextInt(100000000), averageCPUUsage, usedMemory, entityCount, chunksLoaded, freeDiskSpace)); for (TPS tps : expected) { tpsTable.insertTPS(tps); } @@ -705,7 +705,7 @@ public class SQLiteTest { saveUserOne(); saveUserTwo(); - Session session = new Session(TestConstants.PLAYER_ONE_UUID, 12345L, "", ""); + Session session = new Session(TestConstants.PLAYER_ONE_UUID, serverUUID, 12345L, "", ""); session.endSession(22345L); session.setWorldTimes(createWorldTimes()); session.setPlayerKills(createKills()); @@ -747,9 +747,9 @@ public class SQLiteTest { } @Test - public void testBackupAndRestore() throws DBException, UnsupportedEncodingException, NoSuchAlgorithmException { + public void testBackupAndRestore() throws Exception { System.out.println("- Creating Backup Database -"); - SQLiteDB backup = new SQLiteDB("debug-backup" + System.currentTimeMillis(), Locale::new); + SQLiteDB backup = dbSystem.getSqLiteFactory().usingFile(temporaryFolder.newFile("backup.db")); backup.init(); System.out.println("- Backup Database Created -"); @@ -810,7 +810,7 @@ public class SQLiteTest { List sessions = new ArrayList<>(); sessions.add(session); sessionMap.put(playerUUID, sessions); - map.put(ServerInfo.getServerUUID(), sessionMap); + map.put(serverUUID, sessionMap); worldTimesTable.saveWorldTimes(map); @@ -833,7 +833,6 @@ public class SQLiteTest { List sessions = new ArrayList<>(); sessions.add(session); sessionMap.put(playerUUID, sessions); - UUID serverUUID = ServerInfo.getServerUUID(); map.put(serverUUID, sessionMap); sessionsTable.insertSessions(map, true); @@ -857,23 +856,6 @@ public class SQLiteTest { assertEquals(createWorldTimes(), worldTimesOfServer); } - @Test - public void testRegisterProcessorRegisterException() { - assertFalse(db.getUsersTable().isRegistered(playerUUID)); - assertFalse(db.getUserInfoTable().isRegistered(playerUUID)); - System.out.println("\n- Running RegisterProcessors -"); - List processors = new ArrayList<>(); - for (int i = 0; i < 200; i++) { - processors.add(new RegisterProcessor(playerUUID, () -> 500L, "name")); - } - for (RegisterProcessor processor : processors) { - processor.run(); - } - System.out.println("- RegisterProcessors Run -\n"); - assertTrue(db.getUsersTable().isRegistered(playerUUID)); - assertTrue(db.getUserInfoTable().isRegistered(playerUUID)); - } - @Test public void testRegister() { assertFalse(db.check().isPlayerRegistered(playerUUID)); @@ -885,7 +867,7 @@ public class SQLiteTest { } @Test - public void testWorldTableGetWorldNamesNoException() throws UnsupportedEncodingException, NoSuchAlgorithmException { + public void testWorldTableGetWorldNamesNoException() throws NoSuchAlgorithmException { saveAllData(db); Set worldNames = db.getWorldTable().getWorldNames(TestConstants.SERVER_UUID); assertEquals(new HashSet<>(worlds), worldNames); @@ -931,7 +913,7 @@ public class SQLiteTest { } @Test - public void testNewContainerForPlayer() throws UnsupportedEncodingException, NoSuchAlgorithmException { + public void testNewContainerForPlayer() throws NoSuchAlgorithmException { saveAllData(db); long start = System.nanoTime(); @@ -960,12 +942,12 @@ public class SQLiteTest { assertTrue(container.supports(PlayerKeys.PLAYER_KILL_COUNT)); assertFalse(container.supports(PlayerKeys.ACTIVE_SESSION)); - container.putRawData(PlayerKeys.ACTIVE_SESSION, new Session(TestConstants.PLAYER_ONE_UUID, System.currentTimeMillis(), "TestWorld", "SURVIVAL")); + container.putRawData(PlayerKeys.ACTIVE_SESSION, new Session(TestConstants.PLAYER_ONE_UUID, serverUUID, System.currentTimeMillis(), "TestWorld", "SURVIVAL")); assertTrue(container.supports(PlayerKeys.ACTIVE_SESSION)); long end = System.nanoTime(); - assertFalse("Took too long: " + ((end - start) / 1000000.0) + "ms", end - start > TimeAmount.SECOND.ns()); + assertFalse("Took too long: " + ((end - start) / 1000000.0) + "ms", end - start > TimeUnit.SECONDS.toNanos(1L)); OptionalAssert.equals(playerUUID, container.getValue(PlayerKeys.UUID)); OptionalAssert.equals(123456789L, container.getValue(PlayerKeys.REGISTERED)); @@ -986,7 +968,7 @@ public class SQLiteTest { } @Test - public void playerContainerSupportsAllPlayerKeys() throws UnsupportedEncodingException, NoSuchAlgorithmException, IllegalAccessException { + public void playerContainerSupportsAllPlayerKeys() throws NoSuchAlgorithmException, IllegalAccessException { saveAllData(db); PlayerContainer playerContainer = db.fetch().getPlayerContainer(TestConstants.PLAYER_ONE_UUID); @@ -1008,7 +990,7 @@ public class SQLiteTest { } @Test - public void serverContainerSupportsAllServerKeys() throws UnsupportedEncodingException, NoSuchAlgorithmException, IllegalAccessException { + public void serverContainerSupportsAllServerKeys() throws NoSuchAlgorithmException, IllegalAccessException { saveAllData(db); ServerContainer serverContainer = db.fetch().getServerContainer(TestConstants.SERVER_UUID); @@ -1028,10 +1010,13 @@ public class SQLiteTest { } @Test - public void analysisContainerSupportsAllAnalysisKeys() throws IllegalAccessException, UnsupportedEncodingException, NoSuchAlgorithmException { + @Ignore + public void analysisContainerSupportsAllAnalysisKeys() throws IllegalAccessException, NoSuchAlgorithmException { serverContainerSupportsAllServerKeys(); - AnalysisContainer analysisContainer = new AnalysisContainer(db.fetch().getServerContainer(TestConstants.SERVER_UUID)); - + AnalysisContainer.Factory factory = null; + AnalysisContainer analysisContainer = factory.forServerContainer( + db.fetch().getServerContainer(TestConstants.SERVER_UUID) + ); List unsupported = new ArrayList<>(); for (Field field : AnalysisKeys.class.getDeclaredFields()) { if (!Modifier.isPublic(field.getModifiers())) { @@ -1047,7 +1032,7 @@ public class SQLiteTest { } @Test - public void networkContainerSupportsAllNetworkKeys() throws IllegalAccessException, UnsupportedEncodingException, NoSuchAlgorithmException { + public void networkContainerSupportsAllNetworkKeys() throws IllegalAccessException, NoSuchAlgorithmException { serverContainerSupportsAllServerKeys(); NetworkContainer networkContainer = db.fetch().getNetworkContainer(); @@ -1064,4 +1049,44 @@ public class SQLiteTest { assertTrue("Some keys are not supported by NetworkContainer: NetworkKeys." + unsupported.toString(), unsupported.isEmpty()); } + + @Test + public void testGetMatchingNames() { + String exp1 = "TestName"; + String exp2 = "TestName2"; + + UsersTable usersTable = db.getUsersTable(); + UUID uuid1 = UUID.randomUUID(); + usersTable.registerUser(uuid1, 0L, exp1); + usersTable.registerUser(UUID.randomUUID(), 0L, exp2); + + String search = "testname"; + + List result = db.search().matchingPlayers(search); + + assertNotNull(result); + assertEquals(2, result.size()); + assertEquals(exp1, result.get(0)); + assertEquals(exp2, result.get(1)); + } + + @Test + public void testGetMatchingNickNames() { + UUID uuid = UUID.randomUUID(); + String userName = RandomData.randomString(10); + db.getUsersTable().registerUser(uuid, 0L, userName); + db.getUsersTable().registerUser(TestConstants.PLAYER_ONE_UUID, 1L, "Not random"); + + String nickname = "2" + RandomData.randomString(10); + db.getNicknamesTable().saveUserName(uuid, new Nickname(nickname, System.currentTimeMillis(), TestConstants.SERVER_UUID)); + db.getNicknamesTable().saveUserName(TestConstants.PLAYER_ONE_UUID, new Nickname("No nick", System.currentTimeMillis(), TestConstants.SERVER_UUID)); + + String search = "2"; + + List result = db.search().matchingPlayers(search); + + assertNotNull(result); + assertEquals(1, result.size()); + assertEquals(userName, result.get(0)); + } } diff --git a/Plan/src/test/java/com/djrapitops/plan/data/additional/importer/ImportBuilderTest.java b/Plan/src/test/java/com/djrapitops/plan/system/importing/data/ImportBuilderTest.java similarity index 75% rename from Plan/src/test/java/com/djrapitops/plan/data/additional/importer/ImportBuilderTest.java rename to Plan/src/test/java/com/djrapitops/plan/system/importing/data/ImportBuilderTest.java index e68ec84a4..000a51dd0 100644 --- a/Plan/src/test/java/com/djrapitops/plan/data/additional/importer/ImportBuilderTest.java +++ b/Plan/src/test/java/com/djrapitops/plan/system/importing/data/ImportBuilderTest.java @@ -2,28 +2,16 @@ * License is provided in the jar as LICENSE also here: * https://github.com/Rsl1122/Plan-PlayerAnalytics/blob/master/Plan/src/main/resources/LICENSE */ -package com.djrapitops.plan.data.additional.importer; +package com.djrapitops.plan.system.importing.data; -import com.djrapitops.plan.Plan; import com.djrapitops.plan.data.container.PlayerKill; import com.djrapitops.plan.data.container.TPS; import com.djrapitops.plan.data.store.objects.Nickname; import com.djrapitops.plan.data.time.GMTimes; -import com.djrapitops.plan.system.database.databases.SQLiteTest; -import com.djrapitops.plan.system.database.databases.sql.SQLDB; -import com.djrapitops.plan.system.processing.importing.ServerImportData; -import com.djrapitops.plan.system.processing.importing.UserImportData; -import com.djrapitops.plugin.StaticHolder; -import com.djrapitops.plugin.api.utility.log.Log; import com.google.common.collect.ImmutableMap; -import org.junit.BeforeClass; -import org.junit.ClassRule; import org.junit.Test; -import org.junit.rules.TemporaryFolder; import utilities.RandomData; import utilities.TestConstants; -import utilities.TestErrorManager; -import utilities.mocks.SystemMockUtil; import java.util.Arrays; import java.util.Collections; @@ -35,33 +23,17 @@ import static junit.framework.TestCase.assertTrue; import static org.junit.Assert.*; /** + * Tests for various {@link com.djrapitops.plan.system.importing.importers.Importer}s. + * * @author Fuzzlemann */ public class ImportBuilderTest { - @ClassRule - public static TemporaryFolder temporaryFolder = new TemporaryFolder(); - private int randomInt = RandomData.randomInt(0, 10); private String randomString = RandomData.randomString(randomInt); - @BeforeClass - public static void setUpClass() throws Exception { - System.out.println("--- Test Class Setup ---"); - SystemMockUtil.setUp(temporaryFolder.getRoot()) - .enableConfigSystem() - .enableDatabaseSystem() - .enableServerInfoSystem(); - StaticHolder.saveInstance(SQLDB.class, Plan.class); - StaticHolder.saveInstance(SQLiteTest.class, Plan.class); - - Log.setErrorManager(new TestErrorManager()); - - System.out.println("--- Class Setup Complete ---\n"); - } - @Test - public void testEmptyServerBuilder() { + public void emptyServerBuilderInitializesCollections() { ServerImportData data = ServerImportData.builder().build(); assertNotNull(data.getCommandUsages()); @@ -69,8 +41,8 @@ public class ImportBuilderTest { } @Test - public void testEmptyUserBuilder() { - UserImportData data = UserImportData.builder().build(); + public void emptyUserBuilderInitializesSomeVariables() { + UserImportData data = UserImportData.builder(TestConstants.SERVER_UUID).build(); assertEquals(0, data.getRegistered()); assertEquals(0, data.getTimesKicked()); @@ -95,10 +67,10 @@ public class ImportBuilderTest { } @Test - public void testServerDataBuilder() { + public void serverDataBuilderConstructsCorrectItem() { ServerImportData.ServerImportDataBuilder builder = ServerImportData.builder(); - TPS tps = new TPS(randomInt, randomInt, randomInt, randomInt, randomInt, randomInt, randomInt); + TPS tps = new TPS(randomInt, randomInt, randomInt, randomInt, randomInt, randomInt, randomInt, randomInt); ServerImportData data = builder.tpsData(tps) .tpsData(tps) @@ -123,8 +95,8 @@ public class ImportBuilderTest { } @Test - public void testUserDataBuilder() { - UserImportData.UserImportDataBuilder builder = UserImportData.builder(); + public void userDataBuilderConstructsCorrectItem() { + UserImportData.UserImportDataBuilder builder = UserImportData.builder(TestConstants.SERVER_UUID); UUID uuid = UUID.randomUUID(); PlayerKill playerKill = new PlayerKill(uuid, randomString, 1); diff --git a/Plan/src/test/java/com/djrapitops/plan/system/listeners/bukkit/AFKListenerTest.java b/Plan/src/test/java/com/djrapitops/plan/system/listeners/bukkit/AFKListenerTest.java index 3461abcf4..bd8660f3c 100644 --- a/Plan/src/test/java/com/djrapitops/plan/system/listeners/bukkit/AFKListenerTest.java +++ b/Plan/src/test/java/com/djrapitops/plan/system/listeners/bukkit/AFKListenerTest.java @@ -1,21 +1,21 @@ package com.djrapitops.plan.system.listeners.bukkit; import com.djrapitops.plan.system.settings.Settings; +import com.djrapitops.plan.system.settings.config.PlanConfig; +import com.djrapitops.plugin.logging.console.TestPluginLogger; +import com.djrapitops.plugin.logging.error.ConsoleErrorLogger; import org.bukkit.entity.Player; import org.bukkit.event.player.PlayerMoveEvent; -import org.junit.AfterClass; -import org.junit.BeforeClass; +import org.junit.Before; import org.junit.Test; import org.mockito.Mockito; -import utilities.Teardown; import utilities.TestConstants; import java.util.ArrayList; import java.util.Collection; import static org.junit.Assert.assertEquals; -import static org.mockito.Mockito.doAnswer; -import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.*; /** * Test for {@link AFKListener} @@ -24,27 +24,25 @@ import static org.mockito.Mockito.doReturn; */ public class AFKListenerTest { - @BeforeClass - public static void setUpClass() { - Settings.AFK_THRESHOLD_MINUTES.setTemporaryValue(3); - } + private AFKListener underTest; - @AfterClass - public static void tearDownClass() { - Teardown.resetSettingsTempValues(); + @Before + public void setUp() { + PlanConfig config = Mockito.mock(PlanConfig.class); + when(config.getNumber(Settings.AFK_THRESHOLD_MINUTES)).thenReturn(3); + underTest = new AFKListener(config, new ConsoleErrorLogger(new TestPluginLogger())); } @Test - public void testAfkPermissionCallCaching() { - AFKListener afkListener = new AFKListener(); + public void afkPermissionIsNotCalledMoreThanOnce() { Collection calls = new ArrayList<>(); Player player = mockPlayer(calls); PlayerMoveEvent event = mockMoveEvent(player); - afkListener.onMove(event); + underTest.onMove(event); assertEquals(1, calls.size()); - afkListener.onMove(event); + underTest.onMove(event); assertEquals(1, calls.size()); } diff --git a/Plan/src/test/java/com/djrapitops/plan/system/processing/processors/player/PingInsertProcessorTest.java b/Plan/src/test/java/com/djrapitops/plan/system/processing/processors/player/PingInsertProcessorTest.java index ba7c40523..050bdc182 100644 --- a/Plan/src/test/java/com/djrapitops/plan/system/processing/processors/player/PingInsertProcessorTest.java +++ b/Plan/src/test/java/com/djrapitops/plan/system/processing/processors/player/PingInsertProcessorTest.java @@ -2,7 +2,6 @@ package com.djrapitops.plan.system.processing.processors.player; import com.djrapitops.plan.data.store.objects.DateObj; import com.djrapitops.plan.utilities.analysis.Median; -import com.djrapitops.plugin.api.TimeAmount; import org.junit.Before; import org.junit.Test; import utilities.RandomData; @@ -11,6 +10,7 @@ import utilities.TestConstants; import java.util.ArrayList; import java.util.Collections; import java.util.List; +import java.util.concurrent.TimeUnit; import java.util.stream.Collectors; import static org.junit.Assert.assertEquals; @@ -28,38 +28,36 @@ public class PingInsertProcessorTest { public void setUp() { testPing = new ArrayList<>(); - for (int i = 0; i < TimeAmount.MINUTE.ms(); i += TimeAmount.SECOND.ms() * 2L) { + for (int i = 0; i < TimeUnit.MINUTES.toMillis(1L); i += TimeUnit.SECONDS.toMillis(2L)) { testPing.add(new DateObj<>(i, RandomData.randomInt(1, 4000))); } } @Test - public void testMedian() { + public void medianCalculation() { List collect = testPing.stream().map(DateObj::getValue).sorted().collect(Collectors.toList()); - System.out.println(collect); + int expected = (int) Median.forInt(collect).calculate(); - int result = new PingInsertProcessor(TestConstants.PLAYER_ONE_UUID, new ArrayList<>()).getMeanValue(testPing); - System.out.println(result); + int result = new PingInsertProcessor(TestConstants.PLAYER_ONE_UUID, TestConstants.SERVER_UUID, new ArrayList<>(), null) + .getMeanValue(testPing); assertEquals(expected, result); } @Test - public void testMedianSingleEntry() { + public void medianCalculationForSingleEntry() { int expected = 50; - int result = new PingInsertProcessor(TestConstants.PLAYER_ONE_UUID, new ArrayList<>()).getMeanValue( - Collections.singletonList(new DateObj<>(0, expected)) - ); + int result = new PingInsertProcessor(TestConstants.PLAYER_ONE_UUID, TestConstants.SERVER_UUID, new ArrayList<>(), null) + .getMeanValue(Collections.singletonList(new DateObj<>(0, expected))); assertEquals(expected, result); } @Test - public void testMedianEmpty() { + public void medianCalculationForNoEntries() { int expected = -1; - int result = new PingInsertProcessor(TestConstants.PLAYER_ONE_UUID, new ArrayList<>()).getMeanValue( - Collections.emptyList() - ); + int result = new PingInsertProcessor(TestConstants.PLAYER_ONE_UUID, TestConstants.SERVER_UUID, new ArrayList<>(), null) + .getMeanValue(Collections.emptyList()); assertEquals(expected, result); } diff --git a/Plan/src/test/java/com/djrapitops/plan/system/settings/network/NetworkSettingsTest.java b/Plan/src/test/java/com/djrapitops/plan/system/settings/network/NetworkSettingsTest.java index 6504005b5..c7b902617 100644 --- a/Plan/src/test/java/com/djrapitops/plan/system/settings/network/NetworkSettingsTest.java +++ b/Plan/src/test/java/com/djrapitops/plan/system/settings/network/NetworkSettingsTest.java @@ -1,67 +1,45 @@ package com.djrapitops.plan.system.settings.network; -import com.djrapitops.plan.Plan; -import com.djrapitops.plan.api.exceptions.connection.UnsupportedTransferDatabaseException; -import com.djrapitops.plan.api.exceptions.database.DBException; -import com.djrapitops.plan.system.database.databases.sql.SQLDB; -import com.djrapitops.plan.system.database.databases.sql.SQLiteDB; -import com.djrapitops.plan.system.database.databases.sql.tables.ServerTable; -import com.djrapitops.plan.system.info.server.Server; -import com.djrapitops.plan.system.info.server.ServerInfo; -import com.djrapitops.plan.system.locale.Locale; +import com.djrapitops.plan.DaggerPlanBukkitComponent; +import com.djrapitops.plan.PlanBukkitComponent; +import com.djrapitops.plan.api.exceptions.EnableException; +import com.djrapitops.plan.system.PlanSystem; import com.djrapitops.plan.system.settings.Settings; -import com.djrapitops.plugin.StaticHolder; -import com.djrapitops.plugin.api.utility.log.Log; -import org.junit.*; +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.ClassRule; +import org.junit.Test; import org.junit.rules.TemporaryFolder; -import utilities.Teardown; -import utilities.TestConstants; -import utilities.TestErrorManager; -import utilities.mocks.SystemMockUtil; - -import static org.junit.Assert.assertEquals; +import utilities.mocks.PlanBukkitMocker; public class NetworkSettingsTest { @ClassRule public static TemporaryFolder temporaryFolder = new TemporaryFolder(); - private static SQLDB db; + private static PlanBukkitComponent COMPONENT; @BeforeClass public static void setUpClass() throws Exception { - Teardown.resetSettingsTempValues(); - StaticHolder.saveInstance(NetworkSettingsTest.class, Plan.class); - - SystemMockUtil mockUtil = SystemMockUtil.setUp(temporaryFolder.getRoot()) - .enableConfigSystem(); - db = new SQLiteDB(Locale::new); - mockUtil.enableDatabaseSystem(db) - .enableServerInfoSystem(); - - Log.setErrorManager(new TestErrorManager()); - Log.setDebugMode("console"); - Settings.DEV_MODE.setTemporaryValue(true); + PlanBukkitMocker mocker = PlanBukkitMocker.setUp() + .withDataFolder(temporaryFolder.getRoot()) + .withPluginDescription() + .withResourceFetchingFromJar() + .withServer(); + COMPONENT = DaggerPlanBukkitComponent.builder().plan(mocker.getPlanMock()).build(); } @AfterClass public static void tearDownClass() { - if (db != null) { - db.close(); - } - Teardown.resetSettingsTempValues(); - } - - @Before - public void setUp() { - db.remove().everything(); - ServerTable serverTable = db.getServerTable(); - serverTable.saveCurrentServerInfo(new Server(-1, TestConstants.SERVER_UUID, "ServerName", "", 20)); - assertEquals(ServerInfo.getServerUUID(), TestConstants.SERVER_UUID); + COMPONENT.system().disable(); } @Test - public void testTransfer() throws DBException, UnsupportedTransferDatabaseException { - NetworkSettings networkSettings = new NetworkSettings(); + public void transferDoesNotProduceException() throws EnableException { + PlanSystem system = COMPONENT.system(); + system.getConfigSystem().getConfig().set(Settings.WEBSERVER_PORT, 9005); + system.enable(); + + NetworkSettings networkSettings = system.getConfigSystem().getConfig().getNetworkSettings(); networkSettings.placeToDatabase(); networkSettings.loadFromDatabase(); } diff --git a/Plan/src/test/java/com/djrapitops/plan/system/tasks/proxy/velocity/PingCountTimerVelocityTest.java b/Plan/src/test/java/com/djrapitops/plan/system/tasks/proxy/velocity/PingCountTimerVelocityTest.java new file mode 100644 index 000000000..e7d928771 --- /dev/null +++ b/Plan/src/test/java/com/djrapitops/plan/system/tasks/proxy/velocity/PingCountTimerVelocityTest.java @@ -0,0 +1,54 @@ +package com.djrapitops.plan.system.tasks.proxy.velocity; + +import com.djrapitops.plan.PlanVelocity; +import com.velocitypowered.api.proxy.Player; +import com.velocitypowered.api.proxy.ProxyServer; +import org.junit.Before; +import org.junit.Test; +import org.mockito.Mockito; +import utilities.TestConstants; +import utilities.mocks.PlanVelocityMocker; + +import java.util.Optional; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; +import static org.mockito.Mockito.when; + +/** + * Tests for {@link PingCountTimerVelocity}. + * + * @author Rsl1122 + */ +public class PingCountTimerVelocityTest { + + private PlanVelocity plugin; + private Player player; + + @Before + public void setUp() { + PlanVelocityMocker mocker = PlanVelocityMocker.setUp() + .withProxy(); + plugin = mocker.getPlanMock(); + + player = Mockito.mock(Player.class); + when(player.getPing()).thenReturn(5L); + when(player.getUniqueId()).thenReturn(TestConstants.PLAYER_ONE_UUID); + + ProxyServer proxy = plugin.getProxy(); + when(proxy.getPlayer(TestConstants.PLAYER_ONE_UUID)).thenReturn(Optional.empty()); + } + + @Test + public void offlinePlayerIsRemovedFromPlayerHistory() { + PingCountTimerVelocity counter = new PingCountTimerVelocity(plugin, null, null, null, null); + + assertTrue(counter.playerHistory.isEmpty()); + counter.addPlayer(player); + assertFalse(counter.playerHistory.isEmpty()); + + counter.run(); + assertTrue(counter.playerHistory.isEmpty()); + } + +} \ No newline at end of file diff --git a/Plan/src/test/java/com/djrapitops/plan/system/update/ShutdownUpdateHookTest.java b/Plan/src/test/java/com/djrapitops/plan/system/update/ShutdownUpdateHookTest.java deleted file mode 100644 index 825ae3a47..000000000 --- a/Plan/src/test/java/com/djrapitops/plan/system/update/ShutdownUpdateHookTest.java +++ /dev/null @@ -1,57 +0,0 @@ -package com.djrapitops.plan.system.update; - -import com.djrapitops.plugin.api.utility.Version; -import org.junit.ClassRule; -import org.junit.Test; -import org.junit.rules.TemporaryFolder; - -import java.io.File; -import java.io.IOException; -import java.util.Arrays; - -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; - -/** - * Test for ShutdownUpdateHook functionality. - * - * @author Rsl1122 - * @see ShutdownUpdateHook - */ -public class ShutdownUpdateHookTest { - - @ClassRule - public static TemporaryFolder temporaryFolder = new TemporaryFolder(); - - @Test - public void downloadNewJar() throws IOException { - File newJar = new File(temporaryFolder.getRoot(), "Plan-4.2.0.jar"); - ShutdownUpdateHook.downloadNewJar(new VersionInfo( - true, - new Version("4.2.0"), - "https://github.com/Rsl1122/Plan-PlayerAnalytics/releases/download/4.2.0/Plan-4.2.0.jar", - "" - ), newJar - ); - - assertTrue(newJar.exists()); - } - - @Test - public void deleteOldJarAndKeepNewJar() throws IOException { - File newJar = new File(temporaryFolder.getRoot(), "Plan-4.2.0.jar"); - File oldJar = new File(temporaryFolder.getRoot(), "Plan.jar"); - - assertTrue(newJar.createNewFile()); - assertTrue(oldJar.createNewFile()); - - System.out.println(Arrays.toString(temporaryFolder.getRoot().listFiles())); - ShutdownUpdateHook.registerOldJarForDeletion(temporaryFolder.getRoot(), new File(temporaryFolder.getRoot(), "Plan-4.2.0.jar")); - - new ShutdownUpdateHook().run(); - - System.out.println(Arrays.toString(temporaryFolder.getRoot().listFiles())); - assertTrue(newJar.exists()); - assertFalse(oldJar.exists()); - } -} \ No newline at end of file diff --git a/Plan/src/test/java/com/djrapitops/plan/system/webserver/HTTPSWebServerAuthTest.java b/Plan/src/test/java/com/djrapitops/plan/system/webserver/HTTPSWebServerAuthTest.java index 52f05e4af..a30e7fff0 100644 --- a/Plan/src/test/java/com/djrapitops/plan/system/webserver/HTTPSWebServerAuthTest.java +++ b/Plan/src/test/java/com/djrapitops/plan/system/webserver/HTTPSWebServerAuthTest.java @@ -1,18 +1,22 @@ package com.djrapitops.plan.system.webserver; -import com.djrapitops.plan.Plan; +import com.djrapitops.plan.DaggerPlanBukkitComponent; +import com.djrapitops.plan.PlanBukkitComponent; import com.djrapitops.plan.api.exceptions.connection.*; import com.djrapitops.plan.data.WebUser; -import com.djrapitops.plan.system.BukkitSystem; +import com.djrapitops.plan.system.PlanSystem; import com.djrapitops.plan.system.settings.Settings; +import com.djrapitops.plan.system.settings.config.PlanConfig; import com.djrapitops.plan.utilities.Base64Util; import com.djrapitops.plan.utilities.PassEncryptUtil; -import org.junit.*; +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.ClassRule; +import org.junit.Test; import org.junit.rules.TemporaryFolder; import org.junit.runner.RunWith; import org.mockito.junit.MockitoJUnitRunner; -import utilities.Teardown; -import utilities.mocks.BukkitMockUtil; +import utilities.mocks.PlanBukkitMocker; import javax.net.ssl.*; import java.io.File; @@ -27,53 +31,43 @@ public class HTTPSWebServerAuthTest { @ClassRule public static TemporaryFolder temporaryFolder = new TemporaryFolder(); - private static BukkitSystem bukkitSystem; + private static PlanSystem bukkitSystem; @BeforeClass public static void setUpClass() throws Exception { - BukkitMockUtil mockUtil = BukkitMockUtil.setUp() + PlanBukkitMocker mocker = PlanBukkitMocker.setUp() .withDataFolder(temporaryFolder.getRoot()) - .withLogging() .withPluginDescription() .withResourceFetchingFromJar() .withServer(); - Plan planMock = mockUtil.getPlanMock(); + PlanBukkitComponent component = DaggerPlanBukkitComponent.builder().plan(mocker.getPlanMock()).build(); URL resource = HTTPSWebServerAuthTest.class.getResource("/Cert.keystore"); String keyStore = resource.getPath(); String absolutePath = new File(keyStore).getAbsolutePath(); - Settings.WEBSERVER_CERTIFICATE_PATH.setTemporaryValue(absolutePath); - Settings.WEBSERVER_CERTIFICATE_KEYPASS.setTemporaryValue("MnD3bU5HpmPXag0e"); - Settings.WEBSERVER_CERTIFICATE_STOREPASS.setTemporaryValue("wDwwf663NLTm73gL"); - Settings.WEBSERVER_CERTIFICATE_ALIAS.setTemporaryValue("DefaultPlanCert"); + bukkitSystem = component.system(); - Settings.WEBSERVER_PORT.setTemporaryValue(9005); + PlanConfig config = bukkitSystem.getConfigSystem().getConfig(); + + config.set(Settings.WEBSERVER_CERTIFICATE_PATH, absolutePath); + config.set(Settings.WEBSERVER_CERTIFICATE_KEYPASS, "MnD3bU5HpmPXag0e"); + config.set(Settings.WEBSERVER_CERTIFICATE_STOREPASS, "wDwwf663NLTm73gL"); + config.set(Settings.WEBSERVER_CERTIFICATE_ALIAS, "DefaultPlanCert"); + + config.set(Settings.WEBSERVER_PORT, 9005); - bukkitSystem = new BukkitSystem(planMock); bukkitSystem.enable(); - bukkitSystem.getDatabaseSystem().getActiveDatabase().save() + bukkitSystem.getDatabaseSystem().getDatabase().save() .webUser(new WebUser("test", PassEncryptUtil.createHash("testPass"), 0)); } - @Before - public void setUp() { - Teardown.resetSettingsTempValues(); - } - - @After - public void tearDown() { - Teardown.resetSettingsTempValues(); - } - @AfterClass public static void tearDownClass() { if (bukkitSystem != null) { bukkitSystem.disable(); } - bukkitSystem.disable(); - } private static final TrustManager[] trustAllCerts = new TrustManager[]{ @@ -129,6 +123,7 @@ public class HTTPSWebServerAuthTest { switch (responseCode) { case 200: + case 302: return; case 400: throw new BadRequestException("Bad Request: " + url.toString()); diff --git a/Plan/src/test/java/com/djrapitops/plan/utilities/FormatUtilsTest.java b/Plan/src/test/java/com/djrapitops/plan/utilities/FormatUtilsTest.java deleted file mode 100644 index f0a0c8385..000000000 --- a/Plan/src/test/java/com/djrapitops/plan/utilities/FormatUtilsTest.java +++ /dev/null @@ -1,88 +0,0 @@ -package com.djrapitops.plan.utilities; - -import org.junit.BeforeClass; -import org.junit.ClassRule; -import org.junit.Test; -import org.junit.rules.TemporaryFolder; -import org.junit.runner.RunWith; -import org.mockito.junit.MockitoJUnitRunner; -import utilities.RandomData; -import utilities.Teardown; -import utilities.mocks.SystemMockUtil; - -import java.net.InetAddress; -import java.net.UnknownHostException; - -import static org.junit.Assert.*; - -/** - * @author Rsl1122 - */ -@RunWith(MockitoJUnitRunner.Silent.class) -public class FormatUtilsTest { - - @ClassRule - public static TemporaryFolder temporaryFolder = new TemporaryFolder(); - - @BeforeClass - public static void setUpClass() throws Exception { - SystemMockUtil.setUp(temporaryFolder.getRoot()) - .enableConfigSystem(); - Teardown.resetSettingsTempValues(); - } - - @Test - public void testMergeArrays() { - String randomString1 = RandomData.randomString(10); - String randomString2 = RandomData.randomString(10); - String randomString3 = RandomData.randomString(10); - String randomString4 = RandomData.randomString(10); - - String[][] arrays = new String[][]{new String[]{randomString1, randomString2}, new String[]{randomString3, randomString4}}; - String[] expResult = new String[]{randomString1, randomString2, randomString3, randomString4}; - - String[] result = FormatUtils.mergeArrays(arrays); - - assertArrayEquals(expResult, result); - } - - @Test - public void testCutDecimalsWhichIsRoundedDown() { - double d = 0.05234; - - String result = FormatUtils.cutDecimals(d); - - assertTrue("0.05".equals(result) || "0,05".equals(result)); - } - - @Test - public void testCutDecimalsWhichIsRoundedUp() { - double d = 0.05634; - - String result = FormatUtils.cutDecimals(d); - - assertTrue("0.06".equals(result) || "0,06".equals(result)); - } - - @Test - public void testFormatIP() throws UnknownHostException { - InetAddress ip = InetAddress.getByName("1.2.3.4"); - InetAddress ip2 = InetAddress.getByName("1.2.3.26"); - InetAddress ip3 = InetAddress.getByName("1.2.3.235"); - String expected = "1.2.xx.xx"; - - assertEquals(expected, FormatUtils.formatIP(ip)); - assertEquals(expected, FormatUtils.formatIP(ip2)); - assertEquals(expected, FormatUtils.formatIP(ip3)); - } - - @Test - public void testFormatIPv6() throws UnknownHostException { - InetAddress ip = InetAddress.getByName("1234:1234:1234:1234:1234:1234:1234:1234%0"); - String expected = "1234:1234:1234:xx.."; - - assertEquals(expected, FormatUtils.formatIP(ip)); - } - - -} diff --git a/Plan/src/test/java/com/djrapitops/plan/utilities/MiscUtilsTest.java b/Plan/src/test/java/com/djrapitops/plan/utilities/MiscUtilsTest.java index a841b6f89..310fcae12 100644 --- a/Plan/src/test/java/com/djrapitops/plan/utilities/MiscUtilsTest.java +++ b/Plan/src/test/java/com/djrapitops/plan/utilities/MiscUtilsTest.java @@ -5,63 +5,35 @@ */ package com.djrapitops.plan.utilities; -import com.djrapitops.plan.Plan; -import com.djrapitops.plan.data.store.objects.Nickname; -import com.djrapitops.plan.system.database.databases.Database; -import com.djrapitops.plan.system.database.databases.sql.SQLDB; -import com.djrapitops.plan.system.database.databases.sql.tables.UsersTable; -import com.djrapitops.plan.system.info.server.Server; -import com.djrapitops.plugin.StaticHolder; -import com.djrapitops.plugin.command.ISender; -import com.djrapitops.plugin.command.bukkit.BukkitCMDSender; -import org.junit.Before; -import org.junit.BeforeClass; -import org.junit.ClassRule; +import com.djrapitops.plan.system.settings.Permissions; +import com.djrapitops.plugin.command.Sender; +import com.djrapitops.plugin.command.SenderType; import org.junit.Test; -import org.junit.rules.TemporaryFolder; -import org.junit.runner.RunWith; -import org.mockito.junit.MockitoJUnitRunner; -import utilities.RandomData; -import utilities.TestConstants; -import utilities.mocks.SystemMockUtil; -import utilities.mocks.objects.MockUtils; +import org.mockito.Mockito; -import java.util.List; -import java.util.UUID; - -import static org.junit.Assert.*; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; +import static org.mockito.Mockito.when; /** + * Tests for various {@link MiscUtils} methods. + * * @author Rsl1122 */ -@RunWith(MockitoJUnitRunner.Silent.class) public class MiscUtilsTest { - private SQLDB db; - - @ClassRule - public static TemporaryFolder temporaryFolder = new TemporaryFolder(); - - @BeforeClass - public static void setUpClass() throws Exception { - StaticHolder.saveInstance(MiscUtils.class, Plan.class); - SystemMockUtil.setUp(temporaryFolder.getRoot()) - .enableConfigSystem() - .enableDatabaseSystem() - .enableServerInfoSystem(); - - Database.getActive().save().serverInfoForThisServer(new Server(-1, TestConstants.SERVER_UUID, "ServerName", "", 20)); - } - - @Before - public void setUp() { - db = (SQLDB) Database.getActive(); + private Sender mockAPlayerSender(String name, boolean hasPermission) { + Sender sender = Mockito.mock(Sender.class); + when(sender.hasPermission(Permissions.INSPECT_OTHER.getPermission())).thenReturn(hasPermission); + when(sender.getName()).thenReturn(name); + when(sender.getSenderType()).thenReturn(SenderType.PLAYER); + return sender; } @Test - public void testGetPlayerDisplayNameArgsPerm() { + public void getNameShouldReturnNameWithPermission() { String[] args = new String[]{"Rsl1122", "Test"}; - ISender sender = new BukkitCMDSender(MockUtils.mockPlayer()); + Sender sender = mockAPlayerSender("TestName", true); String expResult = "Rsl1122"; String result = MiscUtils.getPlayerName(args, sender); @@ -70,9 +42,9 @@ public class MiscUtilsTest { } @Test - public void testGetPlayerDisplayNameArgsNoPerm() { + public void getNameShouldReturnNullWithoutPermission() { String[] args = new String[]{"Rsl1122", "Test"}; - ISender sender = new BukkitCMDSender(MockUtils.mockPlayer2()); + Sender sender = mockAPlayerSender("TestName", false); String result = MiscUtils.getPlayerName(args, sender); @@ -80,86 +52,48 @@ public class MiscUtilsTest { } @Test - public void testGetPlayerDisplayNameNoArgsPerm() { + public void getNameShouldReturnPlayerNameWithoutArgs() { String[] args = new String[]{}; - ISender sender = new BukkitCMDSender(MockUtils.mockPlayer()); + String expected = "TestName"; + Sender sender = mockAPlayerSender(expected, true); - String expResult = "TestName"; String result = MiscUtils.getPlayerName(args, sender); - assertEquals(expResult, result); + assertEquals(expected, result); } @Test - public void testGetPlayerDisplayNameNoArgsNoPerm() { + public void getNameShouldReturnPlayerNameWithoutArgsOrPermission() { String[] args = new String[]{}; - ISender sender = new BukkitCMDSender(MockUtils.mockPlayer2()); + String expected = "TestName2"; + Sender sender = mockAPlayerSender(expected, false); - String expResult = "TestName2"; String result = MiscUtils.getPlayerName(args, sender); - assertEquals(expResult, result); + assertEquals(expected, result); } @Test - public void testGetPlayerDisplayNameOwnNameNoPerm() { + public void getNameShouldReturnPlayerNameWithoutPermissionForOwnName() { String[] args = new String[]{"testname2"}; - ISender sender = new BukkitCMDSender(MockUtils.mockPlayer2()); + String expected = "TestName2"; + Sender sender = mockAPlayerSender(expected, false); - String expResult = "TestName2"; String result = MiscUtils.getPlayerName(args, sender); - assertEquals(expResult, result); + assertEquals(expected, result); } @Test - public void testGetPlayerDisplayNameConsole() { + public void getNameShouldReturnArgumentForConsole() { String[] args = new String[]{"TestConsoleSender"}; - ISender sender = new BukkitCMDSender(MockUtils.mockConsoleSender()); + String expected = "TestConsoleSender"; + + Sender sender = Mockito.mock(Sender.class); + when(sender.getSenderType()).thenReturn(SenderType.CONSOLE); - String expResult = "TestConsoleSender"; String result = MiscUtils.getPlayerName(args, sender); - assertEquals(expResult, result); - } - - @Test - public void testGetMatchingNames() { - String exp1 = "TestName"; - String exp2 = "TestName2"; - - UsersTable usersTable = db.getUsersTable(); - UUID uuid1 = UUID.randomUUID(); - usersTable.registerUser(uuid1, 0L, exp1); - usersTable.registerUser(UUID.randomUUID(), 0L, exp2); - - String search = "testname"; - - List result = MiscUtils.getMatchingPlayerNames(search); - - assertNotNull(result); - assertEquals(2, result.size()); - assertEquals(exp1, result.get(0)); - assertEquals(exp2, result.get(1)); - } - - @Test - public void testGetMatchingNickNames() { - UUID uuid = UUID.randomUUID(); - String userName = RandomData.randomString(10); - db.getUsersTable().registerUser(uuid, 0L, userName); - db.getUsersTable().registerUser(TestConstants.PLAYER_ONE_UUID, 1L, "Not random"); - - String nickname = "2" + RandomData.randomString(10); - db.getNicknamesTable().saveUserName(uuid, new Nickname(nickname, System.currentTimeMillis(), TestConstants.SERVER_UUID)); - db.getNicknamesTable().saveUserName(TestConstants.PLAYER_ONE_UUID, new Nickname("No nick", System.currentTimeMillis(), TestConstants.SERVER_UUID)); - - String search = "2"; - - List result = MiscUtils.getMatchingPlayerNames(search); - - assertNotNull(result); - assertEquals(1, result.size()); - assertEquals(userName, result.get(0)); + assertEquals(expected, result); } } diff --git a/Plan/src/test/java/com/djrapitops/plan/utilities/export/HastebinTest.java b/Plan/src/test/java/com/djrapitops/plan/utilities/export/HastebinTest.java index 6069be9c3..e38068f36 100644 --- a/Plan/src/test/java/com/djrapitops/plan/utilities/export/HastebinTest.java +++ b/Plan/src/test/java/com/djrapitops/plan/utilities/export/HastebinTest.java @@ -1,75 +1,17 @@ package com.djrapitops.plan.utilities.export; -import com.djrapitops.plan.PlanPlugin; import com.djrapitops.plan.utilities.file.export.Hastebin; -import com.djrapitops.plugin.StaticHolder; -import com.djrapitops.plugin.api.utility.log.Log; import com.google.common.collect.Iterables; -import org.json.simple.parser.ParseException; -import org.junit.Before; -import org.junit.BeforeClass; -import org.junit.ClassRule; import org.junit.Test; -import org.junit.rules.TemporaryFolder; -import org.junit.runner.RunWith; -import org.mockito.junit.MockitoJUnitRunner; import utilities.RandomData; -import utilities.mocks.SystemMockUtil; - -import java.io.IOException; -import java.util.concurrent.atomic.AtomicBoolean; import static junit.framework.TestCase.assertEquals; -import static junit.framework.TestCase.assertNotNull; /** * @author Fuzzlemann */ -@RunWith(MockitoJUnitRunner.Silent.class) public class HastebinTest { - private final AtomicBoolean testLink = new AtomicBoolean(false); - - @ClassRule - public static TemporaryFolder temporaryFolder = new TemporaryFolder(); - - @BeforeClass - public static void setUpClass() throws Exception { - SystemMockUtil.setUp(temporaryFolder.getRoot()) - .enableConfigSystem() - .enableDatabaseSystem(); - } - - @Before - public void checkAvailability() { - Thread thread = new Thread(() -> { - StaticHolder.saveInstance(this.getClass(), PlanPlugin.getInstance().getClass()); - try { - Hastebin.upload(RandomData.randomString(10)); - } catch (IOException e) { - if (e.getMessage().contains("503")) { - return; - } - - Log.toLog("checkAvailability()", e); - } catch (ParseException e) { - /* Ignored */ - } - - testLink.set(true); - }); - - thread.start(); - - try { - thread.join(5000); - } catch (InterruptedException e) { - Log.info("Hastebin timed out"); - } - - Log.info("Hastebin Available: " + testLink.get()); - } - @Test public void testSplitting() { Iterable parts = Hastebin.split(RandomData.randomString(500000)); @@ -79,17 +21,4 @@ public class HastebinTest { assertEquals(expPartCount, partCount); } - - @Test - public void testUpload() { - if (!testLink.get()) { - Log.info("Hastebin not available, skipping testUpload()"); - return; - } - - String link = Hastebin.safeUpload(RandomData.randomString(10)); - assertNotNull(link); - - Log.info("Hastebin Link: " + link); - } } diff --git a/Plan/src/test/java/com/djrapitops/plan/utilities/html/graphs/GraphTest.java b/Plan/src/test/java/com/djrapitops/plan/utilities/html/graphs/GraphTest.java deleted file mode 100644 index 5da2f8d2c..000000000 --- a/Plan/src/test/java/com/djrapitops/plan/utilities/html/graphs/GraphTest.java +++ /dev/null @@ -1,118 +0,0 @@ -/* - * License is provided in the jar as LICENSE also here: - * https://github.com/Rsl1122/Plan-PlayerAnalytics/blob/master/Plan/src/main/resources/LICENSE - */ -package com.djrapitops.plan.utilities.html.graphs; - -import com.djrapitops.plan.data.container.TPS; -import com.djrapitops.plan.data.store.mutators.ActivityIndex; -import com.djrapitops.plan.system.settings.Settings; -import com.djrapitops.plan.utilities.html.graphs.line.*; -import com.djrapitops.plan.utilities.html.graphs.stack.AbstractStackGraph; -import org.junit.Before; -import org.junit.Test; -import utilities.RandomData; - -import java.util.*; - -import static org.junit.Assert.assertTrue; - -/** - * Tests various Graphs. - * - * @author Rsl1122 - */ -public class GraphTest { - - private final List tpsList = new ArrayList<>(); - private final TreeMap>> activityData = new TreeMap<>(); - - @Before - public void setUp() { - String[] groups = ActivityIndex.getGroups(); - for (int i = 0; i < 10; i++) { - tpsList.add(new TPS(i, i, i, i, i, i, i)); - Map> gData = new HashMap<>(); - for (String group : groups) { - Set uuids = new HashSet<>(); - for (int j = 0; j < RandomData.randomInt(1, 20); j++) { - uuids.add(UUID.randomUUID()); - } - gData.put(group, uuids); - } - activityData.put((long) i, gData); - } - } - - @Test - public void testLineGraphsForBracketErrors() { - AbstractLineGraph[] graphs = new AbstractLineGraph[]{ - new CPUGraph(tpsList), - new OnlineActivityGraph(tpsList), - new RamGraph(tpsList), - new TPSGraph(tpsList), - new EntityGraph(tpsList), - new ChunkGraph(tpsList) - }; - - for (AbstractLineGraph graph : graphs) { - System.out.print("Bracket Test: " + graph.getClass().getSimpleName() + " | "); - String series = graph.toHighChartsSeries(); - - System.out.println(series); - - char[] chars = series.toCharArray(); - assertBracketMatch(chars); - } - } - - @Test - public void testStackGraphsForBracketErrors() { - Settings.FORMAT_DECIMALS.setTemporaryValue("#.##"); - - AbstractStackGraph[] graphs = new AbstractStackGraph[]{ - new ActivityStackGraph(activityData) - }; - - for (AbstractStackGraph graph : graphs) { - System.out.print("Bracket Test: " + graph.getClass().getSimpleName() + " | "); - String series = graph.toHighChartsSeries(); - System.out.println(series); - char[] chars = series.toCharArray(); - assertBracketMatch(chars); - - String labels = graph.toHighChartsLabels(); - System.out.println(labels); - chars = labels.toCharArray(); - assertBracketMatch(chars); - } - } - - private void assertBracketMatch(char[] chars) { - Stack bracketStack = new Stack<>(); - for (int i = 0; i < chars.length; i++) { - char c = chars[i]; - switch (c) { - case '{': - case '[': - case '(': - bracketStack.push(c); - break; - case ')': - Character pop = bracketStack.pop(); - assertTrue("Bracket mismatch at char: " + i + " Expected (, got " + pop, '(' == pop); - break; - case ']': - Character pop1 = bracketStack.pop(); - assertTrue("Bracket mismatch at char: " + i + " Expected [, got " + pop1, '[' == pop1); - break; - case '}': - Character pop2 = bracketStack.pop(); - assertTrue("Bracket mismatch at char: " + i + " Expected {, got " + pop2, '{' == pop2); - break; - default: - break; - } - } - } -} diff --git a/Plan/src/test/java/com/djrapitops/plan/utilities/html/graphs/line/LineGraphTest.java b/Plan/src/test/java/com/djrapitops/plan/utilities/html/graphs/line/LineGraphTest.java new file mode 100644 index 000000000..bc78ebd56 --- /dev/null +++ b/Plan/src/test/java/com/djrapitops/plan/utilities/html/graphs/line/LineGraphTest.java @@ -0,0 +1,81 @@ +package com.djrapitops.plan.utilities.html.graphs.line; + +import com.djrapitops.plan.data.container.TPS; +import com.djrapitops.plan.data.store.mutators.TPSMutator; +import org.junit.Before; +import org.junit.Test; + +import java.util.ArrayList; +import java.util.List; +import java.util.Stack; + +import static org.junit.Assert.assertEquals; + +/** + * Test class for {@link LineGraph}. + * + * @author Rsl1122 + */ +public class LineGraphTest { + + private final List tpsList = new ArrayList<>(); + + @Before + public void setUp() { + for (int i = 0; i < 10; i++) { + tpsList.add(new TPS(i, i, i, i, i, i, i, i)); + } + } + + @Test + public void testLineGraphsForBracketErrors() { + TPSMutator mutator = new TPSMutator(tpsList); + LineGraph[] graphs = new LineGraph[]{ + new CPUGraph(mutator, true), + new PlayersOnlineGraph(mutator, false), + new RamGraph(mutator, true), + new TPSGraph(mutator, false), + new EntityGraph(mutator, true), + new ChunkGraph(mutator, false), + new DiskGraph(mutator, false) + }; + + for (LineGraph graph : graphs) { + System.out.print("Bracket Test: " + graph.getClass().getSimpleName() + " | "); + String series = graph.toHighChartsSeries(); + + System.out.println(series); + + char[] chars = series.toCharArray(); + assertBracketMatch(chars); + } + } + + private void assertBracketMatch(char[] chars) { + Stack bracketStack = new Stack<>(); + for (int i = 0; i < chars.length; i++) { + char c = chars[i]; + switch (c) { + case '{': + case '[': + case '(': + bracketStack.push(c); + break; + case ')': + Character pop = bracketStack.pop(); + assertEquals("Bracket mismatch at char: " + i + " Expected (, got " + pop, '(', (char) pop); + break; + case ']': + Character pop1 = bracketStack.pop(); + assertEquals("Bracket mismatch at char: " + i + " Expected [, got " + pop1, '[', (char) pop1); + break; + case '}': + Character pop2 = bracketStack.pop(); + assertEquals("Bracket mismatch at char: " + i + " Expected {, got " + pop2, '{', (char) pop2); + break; + default: + break; + } + } + } +} \ No newline at end of file diff --git a/Plan/src/test/java/com/djrapitops/plan/utilities/html/tables/PlayersTableTest.java b/Plan/src/test/java/com/djrapitops/plan/utilities/html/tables/PlayersTableTest.java index d57d13535..f07eb11be 100644 --- a/Plan/src/test/java/com/djrapitops/plan/utilities/html/tables/PlayersTableTest.java +++ b/Plan/src/test/java/com/djrapitops/plan/utilities/html/tables/PlayersTableTest.java @@ -1,13 +1,16 @@ package com.djrapitops.plan.utilities.html.tables; +import com.djrapitops.plan.api.ServerAPI; +import com.djrapitops.plan.data.plugin.HookHandler; import com.djrapitops.plan.data.store.containers.PlayerContainer; import com.djrapitops.plan.data.store.keys.PlayerKeys; +import com.djrapitops.plan.system.database.DBSystem; +import com.djrapitops.plan.utilities.uuid.UUIDUtility; +import com.djrapitops.plugin.logging.console.TestPluginLogger; +import com.djrapitops.plugin.logging.error.ConsoleErrorLogger; import org.junit.BeforeClass; -import org.junit.ClassRule; import org.junit.Test; -import org.junit.rules.TemporaryFolder; -import utilities.Teardown; -import utilities.mocks.SystemMockUtil; +import org.mockito.Mockito; import java.util.ArrayList; import java.util.Collections; @@ -23,14 +26,14 @@ import static org.junit.Assert.assertTrue; */ public class PlayersTableTest { - @ClassRule - public static TemporaryFolder temporaryFolder = new TemporaryFolder(); - @BeforeClass - public static void setUpClass() throws Exception { - SystemMockUtil.setUp(temporaryFolder.getRoot()) - .enableConfigSystem(); - Teardown.resetSettingsTempValues(); + public static void setUpClass() { + new ServerAPI( + Mockito.mock(UUIDUtility.class), + Mockito.mock(HookHandler.class), + Mockito.mock(DBSystem.class), + new ConsoleErrorLogger(new TestPluginLogger()) + ); } @Test @@ -38,7 +41,15 @@ public class PlayersTableTest { PlayerContainer container = new PlayerContainer(); container.putRawData(PlayerKeys.SESSIONS, new ArrayList<>()); List players = Collections.singletonList(container); - String html = PlayersTable.forServerPage(players).parseHtml(); + String html = new PlayersTable( + players, + 50, // maxPlayers + 60, // activeMinuteThreshold + 5, // activeLoginThreshold + l -> "", + l -> "", + d -> "" + ).parseHtml(); testHtmlValidity(html); } diff --git a/Plan/src/test/java/utilities/RandomData.java b/Plan/src/test/java/utilities/RandomData.java index 2e90abf8f..27a36b591 100644 --- a/Plan/src/test/java/utilities/RandomData.java +++ b/Plan/src/test/java/utilities/RandomData.java @@ -40,7 +40,7 @@ public class RandomData { for (int i = 0; i < 20; i++) { int randInt = r.nextInt(); long randLong = r.nextLong(); - test.add(new TPS(randLong, randLong, randInt, randLong, randLong, randInt, randInt)); + test.add(new TPS(randLong, randLong, randInt, randLong, randLong, randInt, randInt, randLong)); } return test; } diff --git a/Plan/src/test/java/utilities/Teardown.java b/Plan/src/test/java/utilities/Teardown.java deleted file mode 100644 index 562caae73..000000000 --- a/Plan/src/test/java/utilities/Teardown.java +++ /dev/null @@ -1,21 +0,0 @@ -/* - * License is provided in the jar as LICENSE also here: - * https://github.com/Rsl1122/Plan-PlayerAnalytics/blob/master/Plan/src/main/resources/LICENSE - */ -package utilities; - -import com.djrapitops.plan.system.settings.Settings; - -/** - * Test utility for {@code @Teardown} tags. - * - * @author Rsl1122 - */ -public class Teardown { - - public static void resetSettingsTempValues() { - for (Settings settings : Settings.values()) { - settings.setTemporaryValue(null); - } - } -} diff --git a/Plan/src/test/java/utilities/TestDatabaseCreator.java b/Plan/src/test/java/utilities/TestDatabaseCreator.java index 5f4bbcc4e..199bbf610 100644 --- a/Plan/src/test/java/utilities/TestDatabaseCreator.java +++ b/Plan/src/test/java/utilities/TestDatabaseCreator.java @@ -1,17 +1,14 @@ package utilities; -import com.djrapitops.plan.api.exceptions.database.DBInitException; import com.djrapitops.plan.data.container.Session; import com.djrapitops.plan.data.time.GMTimes; import com.djrapitops.plan.data.time.WorldTimes; import com.djrapitops.plan.system.database.databases.sql.SQLDB; -import com.djrapitops.plan.system.database.databases.sql.SQLiteDB; import com.djrapitops.plan.system.info.server.Server; -import com.djrapitops.plan.system.locale.Locale; -import com.djrapitops.plugin.api.TimeAmount; import java.io.File; import java.util.*; +import java.util.concurrent.TimeUnit; import java.util.stream.Collectors; public class TestDatabaseCreator { @@ -29,17 +26,17 @@ public class TestDatabaseCreator { "840b0c0e-a65c-4269-8d5c-d3e1de349557" }).map(UUID::fromString).collect(Collectors.toList()); private static final String[] gms = GMTimes.getGMKeyArray(); - private final SQLDB db; + private final SQLDB db = null; // TODO private final Random r; private Map> worlds; - public TestDatabaseCreator() throws DBInitException { + public TestDatabaseCreator() { File testDB = new File("src/test/resources/testDB.db".replace("/", File.separator)); boolean oldDB = testDB.exists(); - db = new SQLiteDB(testDB, Locale::new); - db.init(); +// db = new SQLiteDB(testDB, Locale::new); +// db.init(); r = new Random(); @@ -87,7 +84,7 @@ public class TestDatabaseCreator { String world = worldNames.get(r.nextInt(worldNames.size())); String gm = gms[r.nextInt(gms.length)]; - long end = date + (long) r.nextInt((int) TimeAmount.DAY.ms()); + long end = date + (long) r.nextInt((int) TimeUnit.DAYS.toMillis(1L)); Session session = new Session(-1, uuid, serverUUID, date, end, diff --git a/Plan/src/test/java/utilities/TestErrorManager.java b/Plan/src/test/java/utilities/TestErrorManager.java deleted file mode 100644 index 1ec22a380..000000000 --- a/Plan/src/test/java/utilities/TestErrorManager.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * License is provided in the jar as LICENSE also here: - * https://github.com/Rsl1122/Plan-PlayerAnalytics/blob/master/Plan/src/main/resources/LICENSE - */ -package utilities; - -import com.djrapitops.plugin.api.utility.log.errormanager.ErrorManager; - -/** - * ErrorManager for tests that should throw the exceptions that occur. - * - * @author Rsl1122 - */ -public class TestErrorManager implements ErrorManager { - - @Override - public void toLog(String s, Throwable throwable, Class aClass) { - throw new RuntimeException("Error During Test.", throwable); - } -} diff --git a/Plan/src/test/java/utilities/mocks/MockUtil.java b/Plan/src/test/java/utilities/mocks/Mocker.java similarity index 93% rename from Plan/src/test/java/utilities/mocks/MockUtil.java rename to Plan/src/test/java/utilities/mocks/Mocker.java index f62f0fc9a..d4b302620 100644 --- a/Plan/src/test/java/utilities/mocks/MockUtil.java +++ b/Plan/src/test/java/utilities/mocks/Mocker.java @@ -12,11 +12,11 @@ import java.io.FileInputStream; import static org.mockito.Mockito.doReturn; /** - * Abstract MockUtil for methods that can be used for both Bungee and Bukkit. + * Abstract Mocker for methods that can be used for both Bungee and Bukkit. * * @author Rsl1122 */ -abstract class MockUtil { +abstract class Mocker { PlanPlugin planMock; diff --git a/Plan/src/test/java/utilities/mocks/BukkitMockUtil.java b/Plan/src/test/java/utilities/mocks/PlanBukkitMocker.java similarity index 53% rename from Plan/src/test/java/utilities/mocks/BukkitMockUtil.java rename to Plan/src/test/java/utilities/mocks/PlanBukkitMocker.java index 34ef6dc04..3fee8477e 100644 --- a/Plan/src/test/java/utilities/mocks/BukkitMockUtil.java +++ b/Plan/src/test/java/utilities/mocks/PlanBukkitMocker.java @@ -5,25 +5,29 @@ package utilities.mocks; import com.djrapitops.plan.Plan; -import com.djrapitops.plugin.StaticHolder; -import com.djrapitops.plugin.task.RunnableFactory; -import com.djrapitops.plugin.task.ThreadRunnable; +import com.djrapitops.plugin.benchmarking.Timings; +import com.djrapitops.plugin.command.ColorScheme; +import com.djrapitops.plugin.logging.console.PluginLogger; +import com.djrapitops.plugin.logging.console.TestPluginLogger; +import com.djrapitops.plugin.logging.debug.CombineDebugLogger; +import com.djrapitops.plugin.logging.debug.DebugLogger; +import com.djrapitops.plugin.logging.debug.MemoryDebugLogger; +import com.djrapitops.plugin.logging.error.ConsoleErrorLogger; +import com.djrapitops.plugin.logging.error.ErrorHandler; +import com.djrapitops.plugin.task.thread.ThreadRunnableFactory; import org.bukkit.Server; +import org.bukkit.command.ConsoleCommandSender; import org.bukkit.plugin.InvalidDescriptionException; import org.bukkit.plugin.PluginDescriptionFile; import org.bukkit.scheduler.BukkitScheduler; import org.mockito.Mockito; -import org.mockito.junit.MockitoJUnitRunner; -import utilities.Teardown; import utilities.TestConstants; -import utilities.mocks.objects.FakeConsoleCmdSender; import utilities.mocks.objects.TestLogger; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; -import static org.mockito.Mockito.doCallRealMethod; import static org.mockito.Mockito.doReturn; /** @@ -31,48 +35,52 @@ import static org.mockito.Mockito.doReturn; * * @author Rsl1122 */ -public class BukkitMockUtil extends MockUtil { +public class PlanBukkitMocker extends Mocker { private Plan planMock; - private BukkitMockUtil() { + private PlanBukkitMocker() { } - public static BukkitMockUtil setUp() { - RunnableFactory.activateTestMode(); - Teardown.resetSettingsTempValues(); - return new BukkitMockUtil().mockPlugin(); + public static PlanBukkitMocker setUp() { + return new PlanBukkitMocker().mockPlugin(); } - private BukkitMockUtil mockPlugin() { + private PlanBukkitMocker mockPlugin() { planMock = Mockito.mock(Plan.class); super.planMock = planMock; - StaticHolder.register(Plan.class, planMock); - StaticHolder.register(planMock); - StaticHolder.saveInstance(MockitoJUnitRunner.class, Plan.class); - StaticHolder.saveInstance(ThreadRunnable.class, Plan.class); + doReturn(new ColorScheme("§1", "§2", "§3")).when(planMock).getColorScheme(); + doReturn("1.0.0").when(planMock).getVersion(); - doCallRealMethod().when(planMock).getVersion(); - doCallRealMethod().when(planMock).getColorScheme(); + TestLogger testLogger = new TestLogger(); + ThreadRunnableFactory runnableFactory = new ThreadRunnableFactory(); + PluginLogger testPluginLogger = new TestPluginLogger(); + DebugLogger debugLogger = new CombineDebugLogger(new MemoryDebugLogger()); + ErrorHandler consoleErrorLogger = new ConsoleErrorLogger(testPluginLogger); + Timings timings = new Timings(debugLogger); + + doReturn(testLogger).when(planMock).getLogger(); + doReturn(runnableFactory).when(planMock).getRunnableFactory(); + doReturn(testPluginLogger).when(planMock).getPluginLogger(); + doReturn(debugLogger).when(planMock).getDebugLogger(); + doReturn(consoleErrorLogger).when(planMock).getErrorHandler(); + doReturn(timings).when(planMock).getTimings(); return this; } - public BukkitMockUtil withDataFolder(File tempFolder) { + public PlanBukkitMocker withDataFolder(File tempFolder) { doReturn(tempFolder).when(planMock).getDataFolder(); return this; } - public BukkitMockUtil withLogging() { - Mockito.doCallRealMethod().when(planMock).log(Mockito.anyString(), Mockito.anyString()); - TestLogger testLogger = new TestLogger(); - doReturn(testLogger).when(planMock).getLogger(); + @Deprecated + public PlanBukkitMocker withLogging() { return this; } - - public BukkitMockUtil withPluginDescription() { + public PlanBukkitMocker withPluginDescription() { try { File pluginYml = getFile("/plugin.yml"); PluginDescriptionFile description = new PluginDescriptionFile(new FileInputStream(pluginYml)); @@ -83,12 +91,12 @@ public class BukkitMockUtil extends MockUtil { return this; } - public BukkitMockUtil withResourceFetchingFromJar() throws Exception { + public PlanBukkitMocker withResourceFetchingFromJar() throws Exception { withPluginFiles(); return this; } - public BukkitMockUtil withServer() { + public PlanBukkitMocker withServer() { Server serverMock = Mockito.mock(Server.class); doReturn("").when(serverMock).getIp(); doReturn("Bukkit").when(serverMock).getName(); @@ -97,7 +105,7 @@ public class BukkitMockUtil extends MockUtil { doReturn("1.12.2").when(serverMock).getVersion(); doReturn("32423").when(serverMock).getBukkitVersion(); doReturn(TestConstants.BUKKIT_MAX_PLAYERS).when(serverMock).getMaxPlayers(); - FakeConsoleCmdSender sender = new FakeConsoleCmdSender(); + ConsoleCommandSender sender = Mockito.mock(ConsoleCommandSender.class); doReturn(sender).when(serverMock).getConsoleSender(); BukkitScheduler bukkitScheduler = Mockito.mock(BukkitScheduler.class); diff --git a/Plan/src/test/java/utilities/mocks/BungeeMockUtil.java b/Plan/src/test/java/utilities/mocks/PlanBungeeMocker.java similarity index 50% rename from Plan/src/test/java/utilities/mocks/BungeeMockUtil.java rename to Plan/src/test/java/utilities/mocks/PlanBungeeMocker.java index 38e3cd019..17636156f 100644 --- a/Plan/src/test/java/utilities/mocks/BungeeMockUtil.java +++ b/Plan/src/test/java/utilities/mocks/PlanBungeeMocker.java @@ -5,82 +5,91 @@ package utilities.mocks; import com.djrapitops.plan.PlanBungee; -import com.djrapitops.plugin.StaticHolder; -import com.djrapitops.plugin.task.RunnableFactory; -import com.djrapitops.plugin.task.ThreadRunnable; +import com.djrapitops.plugin.benchmarking.Timings; +import com.djrapitops.plugin.command.ColorScheme; +import com.djrapitops.plugin.logging.console.PluginLogger; +import com.djrapitops.plugin.logging.console.TestPluginLogger; +import com.djrapitops.plugin.logging.debug.CombineDebugLogger; +import com.djrapitops.plugin.logging.debug.DebugLogger; +import com.djrapitops.plugin.logging.debug.MemoryDebugLogger; +import com.djrapitops.plugin.logging.error.ConsoleErrorLogger; +import com.djrapitops.plugin.logging.error.ErrorHandler; +import com.djrapitops.plugin.task.thread.ThreadRunnableFactory; import net.md_5.bungee.api.CommandSender; import net.md_5.bungee.api.ProxyConfig; import net.md_5.bungee.api.ProxyServer; import net.md_5.bungee.api.plugin.PluginDescription; import net.md_5.bungee.api.plugin.PluginManager; import org.mockito.Mockito; -import org.mockito.junit.MockitoJUnitRunner; -import utilities.Teardown; import utilities.TestConstants; -import utilities.mocks.objects.FakeBungeeConsole; import utilities.mocks.objects.TestLogger; import java.io.File; import java.util.HashSet; -import static org.mockito.Mockito.*; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.when; /** * Mocking Utility for Bungee version of Plan (PlanBungee). * * @author Rsl1122 */ -public class BungeeMockUtil extends MockUtil { +public class PlanBungeeMocker extends Mocker { private PlanBungee planMock; - private BungeeMockUtil() { + private PlanBungeeMocker() { } - public static BungeeMockUtil setUp() { - RunnableFactory.activateTestMode(); - Teardown.resetSettingsTempValues(); - return new BungeeMockUtil().mockPlugin(); + public static PlanBungeeMocker setUp() { + return new PlanBungeeMocker().mockPlugin(); } - private BungeeMockUtil mockPlugin() { + private PlanBungeeMocker mockPlugin() { planMock = Mockito.mock(PlanBungee.class); super.planMock = planMock; - StaticHolder.register(PlanBungee.class, planMock); - StaticHolder.register(planMock); - StaticHolder.saveInstance(MockitoJUnitRunner.class, PlanBungee.class); - StaticHolder.saveInstance(ThreadRunnable.class, PlanBungee.class); + doReturn(new ColorScheme("§1", "§2", "§3")).when(planMock).getColorScheme(); + doReturn("1.0.0").when(planMock).getVersion(); + + TestLogger testLogger = new TestLogger(); + ThreadRunnableFactory runnableFactory = new ThreadRunnableFactory(); + PluginLogger testPluginLogger = new TestPluginLogger(); + DebugLogger debugLogger = new CombineDebugLogger(new MemoryDebugLogger()); + ErrorHandler consoleErrorLogger = new ConsoleErrorLogger(testPluginLogger); + Timings timings = new Timings(debugLogger); + + doReturn(testLogger).when(planMock).getLogger(); + doReturn(runnableFactory).when(planMock).getRunnableFactory(); + doReturn(testPluginLogger).when(planMock).getPluginLogger(); + doReturn(debugLogger).when(planMock).getDebugLogger(); + doReturn(consoleErrorLogger).when(planMock).getErrorHandler(); + doReturn(timings).when(planMock).getTimings(); - when(planMock.getVersion()).thenCallRealMethod(); - when(planMock.getColorScheme()).thenCallRealMethod(); -// doCallRealMethod().when(planMock).getVersion(); -// doCallRealMethod().when(planMock).getColorScheme(); return this; } - public BungeeMockUtil withDataFolder(File tempFolder) { + public PlanBungeeMocker withDataFolder(File tempFolder) { when(planMock.getDataFolder()).thenReturn(tempFolder); return this; } - public BungeeMockUtil withResourceFetchingFromJar() throws Exception { + public PlanBungeeMocker withResourceFetchingFromJar() throws Exception { withPluginFiles(); return this; } - public BungeeMockUtil withLogging() { - doCallRealMethod().when(planMock).log(Mockito.anyString(), Mockito.anyString()); - TestLogger testLogger = new TestLogger(); - doReturn(testLogger).when(planMock).getLogger(); + @Deprecated + public PlanBungeeMocker withLogging() { return this; } - public BungeeMockUtil withProxy() { + public PlanBungeeMocker withProxy() { ProxyServer proxyMock = Mockito.mock(ProxyServer.class); doReturn("1.12.2").when(proxyMock).getVersion(); - CommandSender console = new FakeBungeeConsole(); + CommandSender console = Mockito.mock(CommandSender.class); doReturn(console).when(proxyMock).getConsole(); ProxyConfig proxyConfig = Mockito.mock(ProxyConfig.class); @@ -94,7 +103,7 @@ public class BungeeMockUtil extends MockUtil { return this; } - public BungeeMockUtil withPluginDescription() { + public PlanBungeeMocker withPluginDescription() { File pluginYml = getFile("/bungee.yml"); HashSet empty = new HashSet<>(); PluginDescription pluginDescription = new PluginDescription("Plan", "", "9.9.9", "Rsl1122", empty, empty, pluginYml, ""); diff --git a/Plan/src/test/java/utilities/mocks/PlanPluginMocker.java b/Plan/src/test/java/utilities/mocks/PlanPluginMocker.java new file mode 100644 index 000000000..8509b51b5 --- /dev/null +++ b/Plan/src/test/java/utilities/mocks/PlanPluginMocker.java @@ -0,0 +1,69 @@ +/* + * License is provided in the jar as LICENSE also here: + * https://github.com/Rsl1122/Plan-PlayerAnalytics/blob/master/Plan/src/main/resources/LICENSE + */ +package utilities.mocks; + +import com.djrapitops.plan.Plan; +import com.djrapitops.plan.PlanPlugin; +import com.djrapitops.plugin.command.ColorScheme; +import com.djrapitops.plugin.logging.console.TestPluginLogger; +import com.djrapitops.plugin.logging.error.ConsoleErrorLogger; +import com.djrapitops.plugin.task.thread.ThreadRunnableFactory; +import org.mockito.Mockito; + +import java.io.File; + +import static org.mockito.Mockito.doReturn; + +/** + * Mocking Utility for Bukkit version of Plan. + * + * @author Rsl1122 + */ +public class PlanPluginMocker extends Mocker { + + private PlanPlugin planMock; + + private PlanPluginMocker() { + } + + public static PlanPluginMocker setUp() { + return new PlanPluginMocker().mockPlugin(); + } + + private PlanPluginMocker mockPlugin() { + planMock = Mockito.mock(Plan.class); + super.planMock = planMock; + + doReturn(new ColorScheme("§1", "§2", "§3")).when(planMock).getColorScheme(); + doReturn("1.0.0").when(planMock).getVersion(); + + ThreadRunnableFactory runnableFactory = new ThreadRunnableFactory(); + doReturn(runnableFactory).when(planMock).getRunnableFactory(); + + return this; + } + + public PlanPluginMocker withDataFolder(File tempFolder) { + doReturn(tempFolder).when(planMock).getDataFolder(); + return this; + } + + public PlanPluginMocker withLogging() { + TestPluginLogger testPluginLogger = new TestPluginLogger(); + doReturn(testPluginLogger).when(planMock).getPluginLogger(); + ConsoleErrorLogger consoleErrorLogger = new ConsoleErrorLogger(testPluginLogger); + doReturn(consoleErrorLogger).when(planMock).getErrorHandler(); + return this; + } + + public PlanPluginMocker withResourceFetchingFromJar() throws Exception { + withPluginFiles(); + return this; + } + + public PlanPlugin getPlanMock() { + return planMock; + } +} diff --git a/Plan/src/test/java/utilities/mocks/PlanSpongeMocker.java b/Plan/src/test/java/utilities/mocks/PlanSpongeMocker.java new file mode 100644 index 000000000..c1364fa69 --- /dev/null +++ b/Plan/src/test/java/utilities/mocks/PlanSpongeMocker.java @@ -0,0 +1,128 @@ +/* + * License is provided in the jar as LICENSE also here: + * https://github.com/Rsl1122/Plan-PlayerAnalytics/blob/master/Plan/src/main/resources/LICENSE + */ +package utilities.mocks; + +import com.djrapitops.plan.PlanSponge; +import com.djrapitops.plugin.benchmarking.Timings; +import com.djrapitops.plugin.command.ColorScheme; +import com.djrapitops.plugin.logging.console.PluginLogger; +import com.djrapitops.plugin.logging.console.TestPluginLogger; +import com.djrapitops.plugin.logging.debug.CombineDebugLogger; +import com.djrapitops.plugin.logging.debug.DebugLogger; +import com.djrapitops.plugin.logging.debug.MemoryDebugLogger; +import com.djrapitops.plugin.logging.error.ConsoleErrorLogger; +import com.djrapitops.plugin.logging.error.ErrorHandler; +import com.djrapitops.plugin.task.thread.ThreadRunnableFactory; +import org.mockito.Mockito; +import org.slf4j.Logger; +import org.spongepowered.api.Game; +import org.spongepowered.api.MinecraftVersion; +import org.spongepowered.api.Platform; +import org.spongepowered.api.Server; +import org.spongepowered.api.entity.living.player.Player; +import org.spongepowered.api.text.Text; + +import java.io.File; +import java.net.InetSocketAddress; +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; + +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.when; + +/** + * Mocking Utility for Sponge version of Plan. + * + * @author Rsl1122 + */ +public class PlanSpongeMocker extends Mocker { + + private PlanSponge planMock; + + private PlanSpongeMocker() { + } + + public static PlanSpongeMocker setUp() { + return new PlanSpongeMocker().mockPlugin(); + } + + private PlanSpongeMocker mockPlugin() { + planMock = Mockito.mock(PlanSponge.class); + super.planMock = planMock; + + doReturn(new ColorScheme("§1", "§2", "§3")).when(planMock).getColorScheme(); + doReturn("1.0.0").when(planMock).getVersion(); + + Logger logger = Mockito.mock(Logger.class); + ThreadRunnableFactory runnableFactory = new ThreadRunnableFactory(); + PluginLogger testPluginLogger = new TestPluginLogger(); + DebugLogger debugLogger = new CombineDebugLogger(new MemoryDebugLogger()); + ErrorHandler consoleErrorLogger = new ConsoleErrorLogger(testPluginLogger); + Timings timings = new Timings(debugLogger); + + doReturn(logger).when(planMock).getLogger(); + doReturn(runnableFactory).when(planMock).getRunnableFactory(); + doReturn(testPluginLogger).when(planMock).getPluginLogger(); + doReturn(debugLogger).when(planMock).getDebugLogger(); + doReturn(consoleErrorLogger).when(planMock).getErrorHandler(); + doReturn(timings).when(planMock).getTimings(); + + return this; + } + + public PlanSpongeMocker withDataFolder(File tempFolder) { + when(planMock.getDataFolder()).thenReturn(tempFolder); + return this; + } + + public PlanSpongeMocker withGame() { + Game game = Mockito.mock(Game.class); + + Platform platform = mockPlatform(); + Server server = mockServer(); + doReturn(platform).when(game).getPlatform(); + doReturn(server).when(game).getServer(); + + doReturn(game).when(planMock).getGame(); + return this; + } + + private Platform mockPlatform() { + Platform platform = Mockito.mock(Platform.class); + + MinecraftVersion version = Mockito.mock(MinecraftVersion.class); + doReturn("1.12").when(version).getName(); + doReturn(version).when(platform).getMinecraftVersion(); + + return platform; + } + + private Server mockServer() { + Server server = Mockito.mock(Server.class); + + Text motd = Mockito.mock(Text.class); + doReturn("Motd").when(motd).toPlain(); + Optional ip = Optional.of(new InetSocketAddress(25565)); + int maxPlayers = 20; + List online = new ArrayList<>(); + + doReturn(motd).when(server).getMotd(); + doReturn(ip).when(server).getBoundAddress(); + doReturn(maxPlayers).when(server).getMaxPlayers(); + doReturn(online).when(server).getOnlinePlayers(); + + return server; + } + + public PlanSpongeMocker withResourceFetchingFromJar() throws Exception { + withPluginFiles(); + return this; + } + + public PlanSponge getPlanMock() { + return planMock; + } +} diff --git a/Plan/src/test/java/utilities/mocks/PlanVelocityMocker.java b/Plan/src/test/java/utilities/mocks/PlanVelocityMocker.java new file mode 100644 index 000000000..d81afe4d4 --- /dev/null +++ b/Plan/src/test/java/utilities/mocks/PlanVelocityMocker.java @@ -0,0 +1,96 @@ +/* + * License is provided in the jar as LICENSE also here: + * https://github.com/Rsl1122/Plan-PlayerAnalytics/blob/master/Plan/src/main/resources/LICENSE + */ +package utilities.mocks; + +import com.djrapitops.plan.PlanVelocity; +import com.djrapitops.plugin.benchmarking.Timings; +import com.djrapitops.plugin.command.ColorScheme; +import com.djrapitops.plugin.logging.console.PluginLogger; +import com.djrapitops.plugin.logging.console.TestPluginLogger; +import com.djrapitops.plugin.logging.debug.CombineDebugLogger; +import com.djrapitops.plugin.logging.debug.DebugLogger; +import com.djrapitops.plugin.logging.debug.MemoryDebugLogger; +import com.djrapitops.plugin.logging.error.ConsoleErrorLogger; +import com.djrapitops.plugin.logging.error.ErrorHandler; +import com.djrapitops.plugin.task.thread.ThreadRunnableFactory; +import com.velocitypowered.api.proxy.ProxyServer; +import org.mockito.Mockito; + +import java.io.File; +import java.net.InetSocketAddress; +import java.util.ArrayList; + +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.when; + +/** + * Mocking Utility for Velocity version of Plan (PlanVelocity). + * + * @author Rsl1122 + */ +public class PlanVelocityMocker extends Mocker { + + private PlanVelocity planMock; + + private PlanVelocityMocker() { + } + + public static PlanVelocityMocker setUp() { + return new PlanVelocityMocker().mockPlugin(); + } + + private PlanVelocityMocker mockPlugin() { + planMock = Mockito.mock(PlanVelocity.class); + super.planMock = planMock; + + doReturn(new ColorScheme("§1", "§2", "§3")).when(planMock).getColorScheme(); + doReturn("1.0.0").when(planMock).getVersion(); + + ThreadRunnableFactory runnableFactory = new ThreadRunnableFactory(); + PluginLogger testPluginLogger = new TestPluginLogger(); + DebugLogger debugLogger = new CombineDebugLogger(new MemoryDebugLogger()); + ErrorHandler consoleErrorLogger = new ConsoleErrorLogger(testPluginLogger); + Timings timings = new Timings(debugLogger); + + doReturn(runnableFactory).when(planMock).getRunnableFactory(); + doReturn(testPluginLogger).when(planMock).getPluginLogger(); + doReturn(debugLogger).when(planMock).getDebugLogger(); + doReturn(consoleErrorLogger).when(planMock).getErrorHandler(); + doReturn(timings).when(planMock).getTimings(); + + return this; + } + + public PlanVelocityMocker withDataFolder(File tempFolder) { + when(planMock.getDataFolder()).thenReturn(tempFolder); + return this; + } + + public PlanVelocityMocker withResourceFetchingFromJar() throws Exception { + withPluginFiles(); + return this; + } + + @Deprecated + public PlanVelocityMocker withLogging() { + return this; + } + + public PlanVelocityMocker withProxy() { + ProxyServer server = Mockito.mock(ProxyServer.class); + + InetSocketAddress ip = new InetSocketAddress(25565); + + doReturn(new ArrayList<>()).when(server).getAllServers(); + doReturn(ip).when(server).getBoundAddress(); + + doReturn(server).when(planMock).getProxy(); + return this; + } + + public PlanVelocity getPlanMock() { + return planMock; + } +} diff --git a/Plan/src/test/java/utilities/mocks/SpongeMockUtil.java b/Plan/src/test/java/utilities/mocks/SpongeMockUtil.java deleted file mode 100644 index bfdca4bf5..000000000 --- a/Plan/src/test/java/utilities/mocks/SpongeMockUtil.java +++ /dev/null @@ -1,73 +0,0 @@ -/* - * License is provided in the jar as LICENSE also here: - * https://github.com/Rsl1122/Plan-PlayerAnalytics/blob/master/Plan/src/main/resources/LICENSE - */ -package utilities.mocks; - -import com.djrapitops.plan.PlanSponge; -import com.djrapitops.plugin.StaticHolder; -import com.djrapitops.plugin.task.RunnableFactory; -import com.djrapitops.plugin.task.ThreadRunnable; -import org.mockito.Mockito; -import org.mockito.junit.MockitoJUnitRunner; -import utilities.Teardown; - -import java.io.File; - -import static org.mockito.Mockito.*; - -/** - * Mocking Utility for Sponge version of Plan. - * - * @author Rsl1122 - */ -public class SpongeMockUtil extends MockUtil { - - private PlanSponge planMock; - - private SpongeMockUtil() { - } - - public static SpongeMockUtil setUp() { - RunnableFactory.activateTestMode(); - Teardown.resetSettingsTempValues(); - return new SpongeMockUtil().mockPlugin(); - } - - private SpongeMockUtil mockPlugin() { - planMock = Mockito.mock(PlanSponge.class); - super.planMock = planMock; - StaticHolder.register(PlanSponge.class, planMock); - StaticHolder.register(planMock); - - StaticHolder.saveInstance(MockitoJUnitRunner.class, PlanSponge.class); - StaticHolder.saveInstance(ThreadRunnable.class, PlanSponge.class); - - doReturn("4.2.0").when(planMock).getVersion(); - doCallRealMethod().when(planMock).getColorScheme(); - - return this; - } - - public SpongeMockUtil withDataFolder(File tempFolder) { - when(planMock.getDataFolder()).thenReturn(tempFolder); - return this; - } - - public SpongeMockUtil withLogging() { - doNothing().when(planMock).log(Mockito.anyString(), Mockito.anyString()); -// TestLogger testLogger = new TestLogger(); -// doReturn(testLogger).when(planMock).(); - return this; - } - - - public SpongeMockUtil withResourceFetchingFromJar() throws Exception { - withPluginFiles(); - return this; - } - - public PlanSponge getPlanMock() { - return planMock; - } -} diff --git a/Plan/src/test/java/utilities/mocks/SystemMockUtil.java b/Plan/src/test/java/utilities/mocks/SystemMockUtil.java deleted file mode 100644 index 49522d102..000000000 --- a/Plan/src/test/java/utilities/mocks/SystemMockUtil.java +++ /dev/null @@ -1,75 +0,0 @@ -/* - * License is provided in the jar as LICENSE also here: - * https://github.com/Rsl1122/Plan-PlayerAnalytics/blob/master/Plan/src/main/resources/LICENSE - */ -package utilities.mocks; - -import com.djrapitops.plan.Plan; -import com.djrapitops.plan.api.exceptions.EnableException; -import com.djrapitops.plan.api.exceptions.database.DBException; -import com.djrapitops.plan.system.BukkitSystem; -import com.djrapitops.plan.system.database.DBSystem; -import com.djrapitops.plan.system.database.databases.sql.SQLDB; -import com.djrapitops.plugin.StaticHolder; - -import java.io.File; - -/** - * Utility for mocking only certain parts of systems. - * - * @author Rsl1122 - */ -public class SystemMockUtil { - - private BukkitSystem bukkitSystem; - - public static SystemMockUtil setUp(File dataFolder) throws Exception { - StaticHolder.saveInstance(SystemMockUtil.class, Plan.class); - return new SystemMockUtil().initializeBukkitSystem(dataFolder); - } - - public SystemMockUtil enableConfigSystem() throws Exception { - bukkitSystem.getFileSystem().enable(); - bukkitSystem.getConfigSystem().enable(); - return this; - } - - public SystemMockUtil enableCacheSystem() throws Exception { - bukkitSystem.getCacheSystem().enable(); - return this; - } - - private SystemMockUtil initializeBukkitSystem(File dataFolder) throws Exception { - Plan planMock = BukkitMockUtil.setUp() - .withDataFolder(dataFolder) - .withLogging() - .withResourceFetchingFromJar() - .withPluginDescription() - .withServer() - .getPlanMock(); - bukkitSystem = new BukkitSystem(planMock); - return this; - } - - public SystemMockUtil enableProcessing() throws EnableException { - bukkitSystem.getProcessing().enable(); - return this; - } - - public SystemMockUtil enableDatabaseSystem() throws EnableException { - bukkitSystem.getDatabaseSystem().enable(); - return this; - } - - public SystemMockUtil enableServerInfoSystem() throws EnableException { - bukkitSystem.getServerInfo().enable(); - return this; - } - - public SystemMockUtil enableDatabaseSystem(SQLDB db) throws EnableException, DBException { - DBSystem dbSystem = bukkitSystem.getDatabaseSystem(); - dbSystem.enable(); - dbSystem.setActiveDatabase(db); - return this; - } -} diff --git a/Plan/src/test/java/utilities/mocks/objects/FakeBungeeConsole.java b/Plan/src/test/java/utilities/mocks/objects/FakeBungeeConsole.java deleted file mode 100644 index 2ec6a0fda..000000000 --- a/Plan/src/test/java/utilities/mocks/objects/FakeBungeeConsole.java +++ /dev/null @@ -1,79 +0,0 @@ -/* - * License is provided in the jar as LICENSE also here: - * https://github.com/Rsl1122/Plan-PlayerAnalytics/blob/master/Plan/src/main/resources/LICENSE - */ -package utilities.mocks.objects; - -import net.md_5.bungee.api.CommandSender; -import net.md_5.bungee.api.chat.BaseComponent; - -import java.util.Collection; - -/** - * Fake console to return as mock for Bungee. - *

    - * Logs with System.out.print. - * - * @author Rsl1122 - */ -public class FakeBungeeConsole implements CommandSender { - - @Override - public String getName() { - return null; - } - - @Override - public void sendMessage(String s) { - System.out.println(s); - } - - @Override - public void sendMessages(String... strings) { - for (String string : strings) { - sendMessage(string); - } - } - - @Override - public void sendMessage(BaseComponent... baseComponents) { - for (BaseComponent baseComponent : baseComponents) { - sendMessage(baseComponent); - } - } - - @Override - public void sendMessage(BaseComponent baseComponent) { - sendMessage(baseComponent.toPlainText()); - } - - @Override - public Collection getGroups() { - return null; - } - - @Override - public void addGroups(String... strings) { - - } - - @Override - public void removeGroups(String... strings) { - - } - - @Override - public boolean hasPermission(String s) { - return true; - } - - @Override - public void setPermission(String s, boolean b) { - - } - - @Override - public Collection getPermissions() { - return null; - } -} diff --git a/Plan/src/test/java/utilities/mocks/objects/FakeConsoleCmdSender.java b/Plan/src/test/java/utilities/mocks/objects/FakeConsoleCmdSender.java deleted file mode 100644 index 82cfb9d10..000000000 --- a/Plan/src/test/java/utilities/mocks/objects/FakeConsoleCmdSender.java +++ /dev/null @@ -1,147 +0,0 @@ -/* - * License is provided in the jar as LICENSE also here: - * https://github.com/Rsl1122/Plan-PlayerAnalytics/blob/master/Plan/src/main/resources/LICENSE - */ -package utilities.mocks.objects; - -import org.bukkit.Server; -import org.bukkit.command.ConsoleCommandSender; -import org.bukkit.conversations.Conversation; -import org.bukkit.conversations.ConversationAbandonedEvent; -import org.bukkit.permissions.Permission; -import org.bukkit.permissions.PermissionAttachment; -import org.bukkit.permissions.PermissionAttachmentInfo; -import org.bukkit.plugin.Plugin; - -import java.util.Set; - -/** - * Fake ConsoleCommandSender - * - * @author Rsl1122 - */ -public class FakeConsoleCmdSender implements ConsoleCommandSender { - - @Override - public void sendMessage(String s) { - System.out.println("Log: " + s); - } - - @Override - public void sendMessage(String[] strings) { - for (String string : strings) { - sendMessage(string); - } - } - - @Override - public Server getServer() { - return null; - } - - @Override - public String getName() { - return null; - } - - @Override - public Spigot spigot() { - return null; - } - - @Override - public boolean isConversing() { - return false; - } - - @Override - public void acceptConversationInput(String s) { - - } - - @Override - public boolean beginConversation(Conversation conversation) { - return false; - } - - @Override - public void abandonConversation(Conversation conversation) { - - } - - @Override - public void abandonConversation(Conversation conversation, ConversationAbandonedEvent conversationAbandonedEvent) { - - } - - @Override - public void sendRawMessage(String s) { - - } - - @Override - public boolean isPermissionSet(String s) { - return false; - } - - @Override - public boolean isPermissionSet(Permission permission) { - return false; - } - - @Override - public boolean hasPermission(String s) { - return false; - } - - @Override - public boolean hasPermission(Permission permission) { - return false; - } - - @Override - public PermissionAttachment addAttachment(Plugin plugin, String s, boolean b) { - return null; - } - - @Override - public PermissionAttachment addAttachment(Plugin plugin) { - return null; - } - - @Override - public PermissionAttachment addAttachment(Plugin plugin, String s, boolean b, int i) { - return null; - } - - @Override - public PermissionAttachment addAttachment(Plugin plugin, int i) { - return null; - } - - @Override - public void removeAttachment(PermissionAttachment permissionAttachment) { - - } - - @Override - public void recalculatePermissions() { - - } - - @Override - public Set getEffectivePermissions() { - return null; - } - - @Override - public boolean isOp() { - return false; - } - - @Override - public void setOp(boolean b) { - - } - -} diff --git a/Plan/src/test/java/utilities/mocks/objects/MockUtils.java b/Plan/src/test/java/utilities/mocks/objects/MockPlayers.java similarity index 74% rename from Plan/src/test/java/utilities/mocks/objects/MockUtils.java rename to Plan/src/test/java/utilities/mocks/objects/MockPlayers.java index 8b209a141..1968742fe 100644 --- a/Plan/src/test/java/utilities/mocks/objects/MockUtils.java +++ b/Plan/src/test/java/utilities/mocks/objects/MockPlayers.java @@ -3,31 +3,17 @@ package utilities.mocks.objects; import org.bukkit.GameMode; import org.bukkit.Location; import org.bukkit.World; -import org.bukkit.command.CommandSender; import org.bukkit.entity.Player; import org.mockito.Mockito; - -import java.util.UUID; +import utilities.TestConstants; import static org.mockito.Mockito.when; -/** - * @author Rsl1122 - * @deprecated To Be Refactored into multiple classes. - */ -@Deprecated -public class MockUtils { - - public static World mockWorld() { - World mockWorld = Mockito.mock(World.class); - when(mockWorld.toString()).thenReturn("World"); - return mockWorld; - } - +public class MockPlayers { public static Player mockPlayer() { Player p = Mockito.mock(Player.class); when(p.getGameMode()).thenReturn(GameMode.SURVIVAL); - when(p.getUniqueId()).thenReturn(UUID.fromString("45b0dfdb-f71d-4cf3-8c21-27c9d4c651db")); + when(p.getUniqueId()).thenReturn(TestConstants.PLAYER_ONE_UUID); when(p.getFirstPlayed()).thenReturn(1234567L); World mockWorld = mockWorld(); when(p.getLocation()).thenReturn(new Location(mockWorld, 0, 0, 0)); @@ -42,7 +28,7 @@ public class MockUtils { public static Player mockPlayer2() { Player p = Mockito.mock(Player.class); when(p.getGameMode()).thenReturn(GameMode.SPECTATOR); - when(p.getUniqueId()).thenReturn(UUID.fromString("ec94a954-1fa1-445b-b09b-9b698519af80")); + when(p.getUniqueId()).thenReturn(TestConstants.PLAYER_TWO_UUID); when(p.getFirstPlayed()).thenReturn(3423434L); World mockWorld = mockWorld(); when(p.getLocation()).thenReturn(new Location(mockWorld, 1, 0, 1)); @@ -54,8 +40,9 @@ public class MockUtils { return p; } - public static CommandSender mockConsoleSender() { - return Mockito.mock(CommandSender.class); + private static World mockWorld() { + World mockWorld = Mockito.mock(World.class); + when(mockWorld.toString()).thenReturn("World"); + return mockWorld; } - } diff --git a/PlanPluginBridge/PlanPluginBridge-4.4.0.jar b/PlanPluginBridge/PlanPluginBridge-4.4.0.jar deleted file mode 100644 index 6e1a2c5da..000000000 Binary files a/PlanPluginBridge/PlanPluginBridge-4.4.0.jar and /dev/null differ diff --git a/PlanPluginBridge/PlanPluginBridge-4.5.0.jar b/PlanPluginBridge/PlanPluginBridge-4.5.0.jar new file mode 100644 index 000000000..94ca2ae22 Binary files /dev/null and b/PlanPluginBridge/PlanPluginBridge-4.5.0.jar differ diff --git a/PlanPluginBridge/pom.xml b/PlanPluginBridge/pom.xml index 329b230d8..c64c72f15 100644 --- a/PlanPluginBridge/pom.xml +++ b/PlanPluginBridge/pom.xml @@ -4,7 +4,7 @@ 4.0.0 com.djrapitops PlanPluginBridge - 4.3.0-SNAPSHOT + 4.5.0-SNAPSHOT jar ${project.groupId}:${project.artifactId} @@ -87,7 +87,7 @@ discordsrv-repo - https://ci.scarsz.me/plugin/repository/everything/ + https://nexus.scarsz.me/content/groups/public/ @@ -95,7 +95,7 @@ com.djrapitops Plan - 4.3.0-SNAPSHOT + 4.5.0-SNAPSHOT provided @@ -104,7 +104,6 @@ 1.3 - com.destroystokyo.paper @@ -184,8 +183,8 @@ provided - github.scarsz.discordsrv - DiscordSRV + com.discordsrv + discordsrv 1.16.4 provided @@ -292,6 +291,21 @@ ${project.artifactId} + + maven-compiler-plugin + 3.7.0 + + 1.8 + 1.8 + + + com.google.dagger + dagger-compiler + 2.16 + + + + org.apache.maven.plugins maven-install-plugin diff --git a/PlanPluginBridge/src/main/java/com/djrapitops/pluginbridge/plan/Bridge.java b/PlanPluginBridge/src/main/java/com/djrapitops/pluginbridge/plan/Bridge.java index 4ac01895d..509ddca78 100644 --- a/PlanPluginBridge/src/main/java/com/djrapitops/pluginbridge/plan/Bridge.java +++ b/PlanPluginBridge/src/main/java/com/djrapitops/pluginbridge/plan/Bridge.java @@ -2,123 +2,45 @@ package com.djrapitops.pluginbridge.plan; import com.djrapitops.plan.data.plugin.HookHandler; import com.djrapitops.plan.system.settings.Settings; -import com.djrapitops.plugin.api.Check; -import com.djrapitops.plugin.api.utility.log.Log; -import com.djrapitops.pluginbridge.plan.aac.AdvancedAntiCheatHook; -import com.djrapitops.pluginbridge.plan.advancedachievements.AdvancedAchievementsHook; -import com.djrapitops.pluginbridge.plan.advancedban.AdvancedBanHook; -import com.djrapitops.pluginbridge.plan.askyblock.ASkyBlockHook; -import com.djrapitops.pluginbridge.plan.banmanager.BanManagerHook; -import com.djrapitops.pluginbridge.plan.buycraft.BuyCraftHook; -import com.djrapitops.pluginbridge.plan.discordsrv.DiscordSRVHook; -import com.djrapitops.pluginbridge.plan.essentials.EssentialsHook; -import com.djrapitops.pluginbridge.plan.factions.FactionsHook; -import com.djrapitops.pluginbridge.plan.griefprevention.GriefPreventionHook; -import com.djrapitops.pluginbridge.plan.griefprevention.plus.GriefPreventionPlusHook; -import com.djrapitops.pluginbridge.plan.jobs.JobsHook; -import com.djrapitops.pluginbridge.plan.kingdoms.KingdomsHook; -import com.djrapitops.pluginbridge.plan.litebans.LiteBansBukkitHook; -import com.djrapitops.pluginbridge.plan.litebans.LiteBansBungeeHook; -import com.djrapitops.pluginbridge.plan.luckperms.LuckPermsHook; -import com.djrapitops.pluginbridge.plan.mcmmo.McmmoHook; -import com.djrapitops.pluginbridge.plan.nucleus.NucleusHook; -import com.djrapitops.pluginbridge.plan.protocolsupport.ProtocolSupportHook; -import com.djrapitops.pluginbridge.plan.redprotect.RedProtectHook; -import com.djrapitops.pluginbridge.plan.sponge.SpongeEconomyHook; -import com.djrapitops.pluginbridge.plan.superbvote.SuperbVoteHook; -import com.djrapitops.pluginbridge.plan.towny.TownyHook; -import com.djrapitops.pluginbridge.plan.vault.VaultHook; -import com.djrapitops.pluginbridge.plan.viaversion.ViaVersionBukkitHook; -import com.djrapitops.pluginbridge.plan.viaversion.ViaVersionBungeeHook; +import com.djrapitops.plan.system.settings.config.PlanConfig; +import com.djrapitops.plugin.logging.L; +import com.djrapitops.plugin.logging.error.ErrorHandler; /** * Manages connection to other plugins. * * @author Rsl1122 */ -@SuppressWarnings("WeakerAccess") -public class Bridge { +public abstract class Bridge { - private Bridge() { - throw new IllegalStateException("Utility class"); + private final PlanConfig config; + private final ErrorHandler errorHandler; + + Bridge( + PlanConfig config, + ErrorHandler errorHandler + ) { + this.config = config; + this.errorHandler = errorHandler; } - public static void hook(HookHandler h) { - Hook[] hooks = getHooks(h); - hookInto(hooks); + public void hook(HookHandler handler) { + Hook[] hooks = getHooks(); + hookInto(handler, hooks); } - private static void hookInto(Hook[] hooks) { + private void hookInto(HookHandler handler, Hook[] hooks) { + boolean devMode = config.isTrue(Settings.DEV_MODE); for (Hook hook : hooks) { try { - hook.hook(); + hook.hook(handler); } catch (Exception | NoClassDefFoundError e) { - if (Settings.DEV_MODE.isTrue()) { - Log.toLog("PluginBridge", e); + if (devMode) { + errorHandler.log(L.WARN, this.getClass(), e); } } } } - private static Hook[] getHooks(HookHandler h) { - Hook[] hooks; - if (Check.isBungeeAvailable()) { - hooks = getBungeeHooks(h); - } else if (Check.isBukkitAvailable()) { - hooks = getBukkitHooks(h); - } else if (Check.isSpongeAvailable()) { - hooks = getSpongeHooks(h); - } else { - return new Hook[0]; - } - return hooks; - } - - private static Hook[] getSpongeHooks(HookHandler h) { - return new Hook[]{ - new BuyCraftHook(h), - new LuckPermsHook(h), - new SpongeEconomyHook(h), - new NucleusHook(h) - }; - } - - private static Hook[] getBungeeHooks(HookHandler h) { - return new Hook[]{ - new AdvancedBanHook(h), - new BuyCraftHook(h), - new LiteBansBungeeHook(h), - new LuckPermsHook(h), - new ViaVersionBungeeHook(h) - }; - } - - private static Hook[] getBukkitHooks(HookHandler h) { - return new Hook[]{ - new AdvancedAntiCheatHook(h), - new AdvancedAchievementsHook(h), - new AdvancedBanHook(h), - new ASkyBlockHook(h), - new BanManagerHook(h), - new BuyCraftHook(h), - new DiscordSRVHook(h), - new EssentialsHook(h), - new FactionsHook(h), - new GriefPreventionHook(h), - new GriefPreventionPlusHook(h), - new JobsHook(h), - new KingdomsHook(h), - new LiteBansBukkitHook(h), - new LuckPermsHook(h), - new McmmoHook(h), - new SuperbVoteHook(h), - new ProtocolSupportHook(h), - // new ReactHook(h), - new RedProtectHook(h), - new TownyHook(h), - new VaultHook(h), - new ViaVersionBukkitHook(h)//, - // new PlaceholderAPIHook(h) - }; - } + abstract Hook[] getHooks(); } diff --git a/PlanPluginBridge/src/main/java/com/djrapitops/pluginbridge/plan/BukkitBridge.java b/PlanPluginBridge/src/main/java/com/djrapitops/pluginbridge/plan/BukkitBridge.java new file mode 100644 index 000000000..2b01c3a82 --- /dev/null +++ b/PlanPluginBridge/src/main/java/com/djrapitops/pluginbridge/plan/BukkitBridge.java @@ -0,0 +1,147 @@ +package com.djrapitops.pluginbridge.plan; + +import com.djrapitops.plan.system.settings.config.PlanConfig; +import com.djrapitops.plugin.logging.error.ErrorHandler; +import com.djrapitops.pluginbridge.plan.aac.AdvancedAntiCheatHook; +import com.djrapitops.pluginbridge.plan.advancedachievements.AdvancedAchievementsHook; +import com.djrapitops.pluginbridge.plan.advancedban.AdvancedBanHook; +import com.djrapitops.pluginbridge.plan.askyblock.ASkyBlockHook; +import com.djrapitops.pluginbridge.plan.banmanager.BanManagerHook; +import com.djrapitops.pluginbridge.plan.buycraft.BuyCraftHook; +import com.djrapitops.pluginbridge.plan.discordsrv.DiscordSRVHook; +import com.djrapitops.pluginbridge.plan.essentials.EssentialsHook; +import com.djrapitops.pluginbridge.plan.factions.FactionsHook; +import com.djrapitops.pluginbridge.plan.griefprevention.GriefPreventionHook; +import com.djrapitops.pluginbridge.plan.griefprevention.plus.GriefPreventionPlusHook; +import com.djrapitops.pluginbridge.plan.jobs.JobsHook; +import com.djrapitops.pluginbridge.plan.kingdoms.KingdomsHook; +import com.djrapitops.pluginbridge.plan.litebans.LiteBansBukkitHook; +import com.djrapitops.pluginbridge.plan.luckperms.LuckPermsHook; +import com.djrapitops.pluginbridge.plan.mcmmo.McmmoHook; +import com.djrapitops.pluginbridge.plan.protocolsupport.ProtocolSupportHook; +import com.djrapitops.pluginbridge.plan.redprotect.RedProtectHook; +import com.djrapitops.pluginbridge.plan.superbvote.SuperbVoteHook; +import com.djrapitops.pluginbridge.plan.towny.TownyHook; +import com.djrapitops.pluginbridge.plan.vault.VaultHook; +import com.djrapitops.pluginbridge.plan.viaversion.ViaVersionBukkitHook; + +import javax.inject.Inject; +import javax.inject.Singleton; + +/** + * Plugin bridge for Bukkit plugins. + * + * @author Rsl1122 + */ +@Singleton +public class BukkitBridge extends Bridge { + + private final AdvancedAntiCheatHook advancedAntiCheatHook; + private final AdvancedAchievementsHook advancedAchievementsHook; + private final AdvancedBanHook advancedBanHook; + private final ASkyBlockHook aSkyBlockHook; + private final BanManagerHook banManagerHook; + private final BuyCraftHook buyCraftHook; + private final DiscordSRVHook discordSRVHook; + private final EssentialsHook essentialsHook; + private final FactionsHook factionsHook; + private final GriefPreventionHook griefPreventionHook; + private final GriefPreventionPlusHook griefPreventionPlusHook; + private final JobsHook jobsHook; + private final KingdomsHook kingdomsHook; + private final LiteBansBukkitHook liteBansHook; + private final LuckPermsHook luckPermsHook; + private final McmmoHook mcmmoHook; +// private final PlaceholderAPIHook placeholderAPIHook; + private final ProtocolSupportHook protocolSupportHook; + private final RedProtectHook redProtectHook; + private final SuperbVoteHook superbVoteHook; + private final TownyHook townyHook; + private final VaultHook vaultHook; + private final ViaVersionBukkitHook viaVersionHook; + + @Inject + public BukkitBridge( + PlanConfig config, + ErrorHandler errorHandler, + + AdvancedAntiCheatHook advancedAntiCheatHook, + AdvancedAchievementsHook advancedAchievementsHook, + AdvancedBanHook advancedBanHook, + ASkyBlockHook aSkyBlockHook, + BanManagerHook banManagerHook, + BuyCraftHook buyCraftHook, + DiscordSRVHook discordSRVHook, + EssentialsHook essentialsHook, + FactionsHook factionsHook, + GriefPreventionHook griefPreventionHook, + GriefPreventionPlusHook griefPreventionPlusHook, + JobsHook jobsHook, + KingdomsHook kingdomsHook, + LiteBansBukkitHook liteBansHook, + LuckPermsHook luckPermsHook, + McmmoHook mcmmoHook, +// PlaceholderAPIHook placeholderAPIHook, + ProtocolSupportHook protocolSupportHook, + RedProtectHook redProtectHook, + SuperbVoteHook superbVoteHook, + TownyHook townyHook, + VaultHook vaultHook, + ViaVersionBukkitHook viaVersionHook + ) { + super(config, errorHandler); + this.advancedAntiCheatHook = advancedAntiCheatHook; + this.advancedAchievementsHook = advancedAchievementsHook; + this.advancedBanHook = advancedBanHook; + this.aSkyBlockHook = aSkyBlockHook; + this.banManagerHook = banManagerHook; + this.buyCraftHook = buyCraftHook; + this.discordSRVHook = discordSRVHook; + this.essentialsHook = essentialsHook; + this.factionsHook = factionsHook; + this.griefPreventionHook = griefPreventionHook; + this.griefPreventionPlusHook = griefPreventionPlusHook; + this.jobsHook = jobsHook; + this.kingdomsHook = kingdomsHook; + this.liteBansHook = liteBansHook; + this.luckPermsHook = luckPermsHook; + this.mcmmoHook = mcmmoHook; +// this.placeholderAPIHook = placeholderAPIHook; + this.protocolSupportHook = protocolSupportHook; + this.redProtectHook = redProtectHook; + this.superbVoteHook = superbVoteHook; + this.townyHook = townyHook; + this.vaultHook = vaultHook; + this.viaVersionHook = viaVersionHook; + } + + @Override + Hook[] getHooks() { + return new Hook[]{ + advancedAntiCheatHook, + advancedAchievementsHook, + advancedBanHook, + aSkyBlockHook, + banManagerHook, + buyCraftHook, + discordSRVHook, + essentialsHook, + factionsHook, + griefPreventionHook, + griefPreventionPlusHook, + jobsHook, + kingdomsHook, + liteBansHook, + luckPermsHook, + mcmmoHook, +// placeholderAPIHook, + protocolSupportHook, + // new ReactHook(), + redProtectHook, + superbVoteHook, + townyHook, + vaultHook, + viaVersionHook + }; + } +} \ No newline at end of file diff --git a/PlanPluginBridge/src/main/java/com/djrapitops/pluginbridge/plan/BungeeBridge.java b/PlanPluginBridge/src/main/java/com/djrapitops/pluginbridge/plan/BungeeBridge.java new file mode 100644 index 000000000..5c4b69002 --- /dev/null +++ b/PlanPluginBridge/src/main/java/com/djrapitops/pluginbridge/plan/BungeeBridge.java @@ -0,0 +1,57 @@ +package com.djrapitops.pluginbridge.plan; + +import com.djrapitops.plan.system.settings.config.PlanConfig; +import com.djrapitops.plugin.logging.error.ErrorHandler; +import com.djrapitops.pluginbridge.plan.advancedban.AdvancedBanHook; +import com.djrapitops.pluginbridge.plan.buycraft.BuyCraftHook; +import com.djrapitops.pluginbridge.plan.litebans.LiteBansBungeeHook; +import com.djrapitops.pluginbridge.plan.luckperms.LuckPermsHook; +import com.djrapitops.pluginbridge.plan.viaversion.ViaVersionBungeeHook; + +import javax.inject.Inject; +import javax.inject.Singleton; + +/** + * Plugin bridge for BungeeCord plugins. + * + * @author Rsl1122 + */ +@Singleton +public class BungeeBridge extends Bridge { + + private final AdvancedBanHook advancedBanHook; + private final BuyCraftHook buyCraftHook; + private final LiteBansBungeeHook liteBansHook; + private final LuckPermsHook luckPermsHook; + private final ViaVersionBungeeHook viaVersionHook; + + @Inject + public BungeeBridge( + PlanConfig config, + ErrorHandler errorHandler, + + AdvancedBanHook advancedBanHook, + BuyCraftHook buyCraftHook, + LiteBansBungeeHook liteBansHook, + LuckPermsHook luckPermsHook, + ViaVersionBungeeHook viaVersionHook + ) { + super(config, errorHandler); + this.advancedBanHook = advancedBanHook; + this.buyCraftHook = buyCraftHook; + this.liteBansHook = liteBansHook; + this.luckPermsHook = luckPermsHook; + this.viaVersionHook = viaVersionHook; + } + + @Override + Hook[] getHooks() { + return new Hook[]{ + advancedBanHook, + buyCraftHook, + liteBansHook, + luckPermsHook, + viaVersionHook + }; + } +} \ No newline at end of file diff --git a/PlanPluginBridge/src/main/java/com/djrapitops/pluginbridge/plan/Hook.java b/PlanPluginBridge/src/main/java/com/djrapitops/pluginbridge/plan/Hook.java index 16f600f53..091e821b3 100644 --- a/PlanPluginBridge/src/main/java/com/djrapitops/pluginbridge/plan/Hook.java +++ b/PlanPluginBridge/src/main/java/com/djrapitops/pluginbridge/plan/Hook.java @@ -1,7 +1,7 @@ package com.djrapitops.pluginbridge.plan; import com.djrapitops.plan.data.plugin.HookHandler; -import com.djrapitops.plan.data.plugin.PluginData; +import com.djrapitops.plugin.api.Check; /** * Abstract class for easy hooking of plugins. @@ -16,40 +16,23 @@ public abstract class Hook { */ protected boolean enabled; - protected HookHandler hookHandler; - - private Hook() { - throw new IllegalStateException(); - } - /** * Class constructor. *

    * Checks if the given plugin (class path) is enabled. * - * @param plugin Class path string of the plugin's main JavaPlugin class. + * @param pluginClass Class path string of the plugin's main JavaPlugin class. */ - public Hook(String plugin, HookHandler hookHandler) { - this.hookHandler = hookHandler; - try { - Class.forName(plugin); - enabled = true; - } catch (Exception e) { - enabled = false; - } + public Hook(String pluginClass) { + enabled = Check.isAvailable(pluginClass); } - public abstract void hook() throws NoClassDefFoundError; + public abstract void hook(HookHandler handler) throws NoClassDefFoundError; /** * Constructor to set enabled to false. */ - public Hook(HookHandler hookHandler) { + public Hook() { enabled = false; - this.hookHandler = hookHandler; - } - - protected void addPluginDataSource(PluginData pluginData) { - hookHandler.addPluginDataSource(pluginData); } } diff --git a/PlanPluginBridge/src/main/java/com/djrapitops/pluginbridge/plan/PluginBridgeModule.java b/PlanPluginBridge/src/main/java/com/djrapitops/pluginbridge/plan/PluginBridgeModule.java new file mode 100644 index 000000000..d9058072e --- /dev/null +++ b/PlanPluginBridge/src/main/java/com/djrapitops/pluginbridge/plan/PluginBridgeModule.java @@ -0,0 +1,50 @@ +package com.djrapitops.pluginbridge.plan; + +import dagger.Module; +import dagger.Provides; + +import javax.inject.Singleton; + +/** + * Dagger modules for different plugin bridges. + * + * @author Rsl1122 + */ +public class PluginBridgeModule { + + @Module + public static class Bukkit { + @Provides + @Singleton + public Bridge provideBridge(BukkitBridge bridge) { + return bridge; + } + } + + @Module + public static class Bungee { + @Provides + @Singleton + public Bridge provideBridge(BungeeBridge bridge) { + return bridge; + } + } + + @Module + public static class Sponge { + @Provides + @Singleton + public Bridge provideBridge(SpongeBridge bridge) { + return bridge; + } + } + + @Module + public static class Velocity { + @Provides + @Singleton + public Bridge provideBridge(VelocityBridge bridge) { + return bridge; + } + } +} \ No newline at end of file diff --git a/PlanPluginBridge/src/main/java/com/djrapitops/pluginbridge/plan/SpongeBridge.java b/PlanPluginBridge/src/main/java/com/djrapitops/pluginbridge/plan/SpongeBridge.java new file mode 100644 index 000000000..0933e3d99 --- /dev/null +++ b/PlanPluginBridge/src/main/java/com/djrapitops/pluginbridge/plan/SpongeBridge.java @@ -0,0 +1,52 @@ +package com.djrapitops.pluginbridge.plan; + +import com.djrapitops.plan.system.settings.config.PlanConfig; +import com.djrapitops.plugin.logging.error.ErrorHandler; +import com.djrapitops.pluginbridge.plan.buycraft.BuyCraftHook; +import com.djrapitops.pluginbridge.plan.luckperms.LuckPermsHook; +import com.djrapitops.pluginbridge.plan.nucleus.NucleusHook; +import com.djrapitops.pluginbridge.plan.sponge.SpongeEconomyHook; + +import javax.inject.Inject; +import javax.inject.Singleton; + +/** + * Plugin bridge for Sponge plugins. + * + * @author Rsl1122 + */ +@Singleton +public class SpongeBridge extends Bridge { + + private final BuyCraftHook buyCraftHook; + private final LuckPermsHook luckPermsHook; + private final NucleusHook nucleusHook; + private final SpongeEconomyHook spongeEconomyHook; + + @Inject + public SpongeBridge( + PlanConfig config, + ErrorHandler errorHandler, + + BuyCraftHook buyCraftHook, + LuckPermsHook luckPermsHook, + NucleusHook nucleusHook, + SpongeEconomyHook spongeEconomyHook + ) { + super(config, errorHandler); + this.buyCraftHook = buyCraftHook; + this.luckPermsHook = luckPermsHook; + this.nucleusHook = nucleusHook; + this.spongeEconomyHook = spongeEconomyHook; + } + + @Override + Hook[] getHooks() { + return new Hook[]{ + buyCraftHook, + luckPermsHook, + nucleusHook, + spongeEconomyHook + }; + } +} \ No newline at end of file diff --git a/PlanPluginBridge/src/main/java/com/djrapitops/pluginbridge/plan/VelocityBridge.java b/PlanPluginBridge/src/main/java/com/djrapitops/pluginbridge/plan/VelocityBridge.java new file mode 100644 index 000000000..224827bd8 --- /dev/null +++ b/PlanPluginBridge/src/main/java/com/djrapitops/pluginbridge/plan/VelocityBridge.java @@ -0,0 +1,37 @@ +package com.djrapitops.pluginbridge.plan; + +import com.djrapitops.plan.system.settings.config.PlanConfig; +import com.djrapitops.plugin.logging.error.ErrorHandler; +import com.djrapitops.pluginbridge.plan.buycraft.BuyCraftHook; + +import javax.inject.Inject; +import javax.inject.Singleton; + +/** + * Plugin bridge for Velocity plugins. + * + * @author Rsl1122 + */ +@Singleton +public class VelocityBridge extends Bridge { + + private final BuyCraftHook buyCraftHook; + + @Inject + public VelocityBridge( + PlanConfig config, + ErrorHandler errorHandler, + + BuyCraftHook buyCraftHook + ) { + super(config, errorHandler); + this.buyCraftHook = buyCraftHook; + } + + @Override + Hook[] getHooks() { + return new Hook[]{ + buyCraftHook + }; + } +} \ No newline at end of file diff --git a/PlanPluginBridge/src/main/java/com/djrapitops/pluginbridge/plan/aac/AdvancedAntiCheatData.java b/PlanPluginBridge/src/main/java/com/djrapitops/pluginbridge/plan/aac/AdvancedAntiCheatData.java index 441e55965..674130e5b 100644 --- a/PlanPluginBridge/src/main/java/com/djrapitops/pluginbridge/plan/aac/AdvancedAntiCheatData.java +++ b/PlanPluginBridge/src/main/java/com/djrapitops/pluginbridge/plan/aac/AdvancedAntiCheatData.java @@ -9,7 +9,7 @@ import com.djrapitops.plan.data.element.InspectContainer; import com.djrapitops.plan.data.element.TableContainer; import com.djrapitops.plan.data.plugin.ContainerSize; import com.djrapitops.plan.data.plugin.PluginData; -import com.djrapitops.plan.utilities.FormatUtils; +import com.djrapitops.plan.utilities.formatting.Formatter; import com.djrapitops.plan.utilities.html.icon.Color; import com.djrapitops.plan.utilities.html.icon.Family; import com.djrapitops.plan.utilities.html.icon.Icon; @@ -26,18 +26,20 @@ import java.util.stream.Collectors; * * @author Rsl1122 */ -public class AdvancedAntiCheatData extends PluginData { +class AdvancedAntiCheatData extends PluginData { private final HackerTable table; + private final Formatter timestampFormatter; - public AdvancedAntiCheatData(HackerTable table) { + AdvancedAntiCheatData(HackerTable table, Formatter timestampFormatter) { super(ContainerSize.THIRD, "AdvancedAntiCheat"); + this.timestampFormatter = timestampFormatter; super.setPluginIcon(Icon.called("heart").of(Color.RED).build()); this.table = table; } @Override - public InspectContainer getPlayerData(UUID uuid, InspectContainer inspectContainer) throws Exception { + public InspectContainer getPlayerData(UUID uuid, InspectContainer inspectContainer) { List hackObjects = table.getHackObjects(uuid); inspectContainer.addValue( @@ -53,8 +55,8 @@ public class AdvancedAntiCheatData extends PluginData { hackTable.setColor("red"); for (HackObject hackObject : hackObjects) { - String date = FormatUtils.formatTimeStampYear(hackObject.getDate()); - String hack = Format.create(hackObject.getHackType().getName()).capitalize().toString(); + String date = timestampFormatter.apply(hackObject.getDate()); + String hack = new Format(hackObject.getHackType()).capitalize().toString(); hackTable.addRow(date, hack, hackObject.getViolationLevel()); } inspectContainer.addTable("hackTable", hackTable); @@ -63,7 +65,7 @@ public class AdvancedAntiCheatData extends PluginData { } @Override - public AnalysisContainer getServerData(Collection collection, AnalysisContainer analysisContainer) throws Exception { + public AnalysisContainer getServerData(Collection collection, AnalysisContainer analysisContainer) { Map> hackObjects = table.getHackObjects(); Map violations = hackObjects.entrySet().stream() diff --git a/PlanPluginBridge/src/main/java/com/djrapitops/pluginbridge/plan/aac/AdvancedAntiCheatHook.java b/PlanPluginBridge/src/main/java/com/djrapitops/pluginbridge/plan/aac/AdvancedAntiCheatHook.java index b89d07442..d083ae103 100644 --- a/PlanPluginBridge/src/main/java/com/djrapitops/pluginbridge/plan/aac/AdvancedAntiCheatHook.java +++ b/PlanPluginBridge/src/main/java/com/djrapitops/pluginbridge/plan/aac/AdvancedAntiCheatHook.java @@ -5,40 +5,59 @@ package com.djrapitops.pluginbridge.plan.aac; import com.djrapitops.plan.Plan; -import com.djrapitops.plan.api.exceptions.database.DBException; +import com.djrapitops.plan.api.exceptions.database.DBInitException; +import com.djrapitops.plan.api.exceptions.database.DBOpException; import com.djrapitops.plan.data.plugin.HookHandler; -import com.djrapitops.plan.system.database.databases.Database; +import com.djrapitops.plan.system.database.DBSystem; import com.djrapitops.plan.system.database.databases.sql.SQLDB; -import com.djrapitops.plugin.api.utility.log.Log; +import com.djrapitops.plan.system.processing.Processing; +import com.djrapitops.plan.utilities.formatting.Formatters; import com.djrapitops.pluginbridge.plan.Hook; +import javax.inject.Inject; +import javax.inject.Singleton; + /** * Hook for AAC plugin. * * @author Rsl1122 */ +@Singleton public class AdvancedAntiCheatHook extends Hook { - public AdvancedAntiCheatHook(HookHandler hookHandler) { - super("me.konsolas.aac.AAC", hookHandler); + private final Plan plugin; + private final Processing processing; + private final DBSystem dbSystem; + private final Formatters formatters; + + @Inject + public AdvancedAntiCheatHook( + Plan plugin, + Processing processing, + DBSystem dbSystem, + Formatters formatters + ) { + super("me.konsolas.aac.AAC"); + this.plugin = plugin; + this.processing = processing; + this.dbSystem = dbSystem; + this.formatters = formatters; } @Override - public void hook() throws NoClassDefFoundError { + public void hook(HookHandler hookHandler) throws NoClassDefFoundError { if (!enabled) { return; } - Plan plugin = Plan.getInstance(); - HackerTable table = new HackerTable((SQLDB) Database.getActive()); + HackerTable hackerTable = new HackerTable((SQLDB) dbSystem.getDatabase()); try { - table.createTable(); - } catch (DBException e) { - Log.toLog(this.getClass().getName(), e); - return; + hackerTable.createTable(); + } catch (DBInitException e) { + throw new DBOpException("Failed to create AAC database table", e); } - plugin.registerListener(new PlayerHackKickListener()); - addPluginDataSource(new AdvancedAntiCheatData(table)); + plugin.registerListener(new PlayerHackKickListener(hackerTable, processing)); + hookHandler.addPluginDataSource(new AdvancedAntiCheatData(hackerTable, formatters.yearLong())); } } \ No newline at end of file diff --git a/PlanPluginBridge/src/main/java/com/djrapitops/pluginbridge/plan/aac/HackObject.java b/PlanPluginBridge/src/main/java/com/djrapitops/pluginbridge/plan/aac/HackObject.java index 89103f048..2042671b7 100644 --- a/PlanPluginBridge/src/main/java/com/djrapitops/pluginbridge/plan/aac/HackObject.java +++ b/PlanPluginBridge/src/main/java/com/djrapitops/pluginbridge/plan/aac/HackObject.java @@ -4,8 +4,6 @@ */ package com.djrapitops.pluginbridge.plan.aac; -import me.konsolas.aac.api.HackType; - import java.util.UUID; /** @@ -17,10 +15,10 @@ public class HackObject { private final UUID uuid; private final long date; - private final HackType hackType; + private final String hackType; private final int violationLevel; - public HackObject(UUID uuid, long date, HackType hackType, int violationLevel) { + public HackObject(UUID uuid, long date, String hackType, int violationLevel) { this.uuid = uuid; this.date = date; this.hackType = hackType; @@ -35,7 +33,7 @@ public class HackObject { return date; } - public HackType getHackType() { + public String getHackType() { return hackType; } diff --git a/PlanPluginBridge/src/main/java/com/djrapitops/pluginbridge/plan/aac/HackerTable.java b/PlanPluginBridge/src/main/java/com/djrapitops/pluginbridge/plan/aac/HackerTable.java index 35a6eb97a..9fc0aefc2 100644 --- a/PlanPluginBridge/src/main/java/com/djrapitops/pluginbridge/plan/aac/HackerTable.java +++ b/PlanPluginBridge/src/main/java/com/djrapitops/pluginbridge/plan/aac/HackerTable.java @@ -12,7 +12,6 @@ import com.djrapitops.plan.system.database.databases.sql.processing.QueryAllStat import com.djrapitops.plan.system.database.databases.sql.processing.QueryStatement; import com.djrapitops.plan.system.database.databases.sql.statements.Select; import com.djrapitops.plan.system.database.databases.sql.tables.Table; -import me.konsolas.aac.api.HackType; import java.sql.PreparedStatement; import java.sql.ResultSet; @@ -51,7 +50,7 @@ public class HackerTable extends Table { ); } - public List getHackObjects(UUID uuid) throws SQLException { + public List getHackObjects(UUID uuid) { String sql = "SELECT * FROM " + tableName + " WHERE " + columnUUID + "=?"; return query(new QueryStatement>(sql) { @@ -66,7 +65,7 @@ public class HackerTable extends Table { while (set.next()) { UUID uuid = UUID.fromString(set.getString(columnUUID)); long date = set.getLong(columnDate); - HackType hackType = HackType.valueOf(set.getString(columnHackType)); + String hackType = set.getString(columnHackType); int violationLevel = set.getInt(columnViolations); hackObjects.add(new HackObject(uuid, date, hackType, violationLevel)); } @@ -75,7 +74,7 @@ public class HackerTable extends Table { }); } - public Map> getHackObjects() throws SQLException { + public Map> getHackObjects() { return query(new QueryAllStatement>>(Select.all(tableName).toString(), 5000) { @Override public Map> processResults(ResultSet set) throws SQLException { @@ -83,7 +82,7 @@ public class HackerTable extends Table { while (set.next()) { UUID uuid = UUID.fromString(set.getString(columnUUID)); long date = set.getLong(columnDate); - HackType hackType = HackType.valueOf(set.getString(columnHackType)); + String hackType = set.getString(columnHackType); int violationLevel = set.getInt(columnViolations); List list = hackObjects.getOrDefault(uuid, new ArrayList<>()); list.add(new HackObject(uuid, date, hackType, violationLevel)); @@ -94,7 +93,7 @@ public class HackerTable extends Table { }); } - public void insertHackRow(HackObject hackObject) throws SQLException { + public void insertHackRow(HackObject hackObject) { String sql = "INSERT INTO " + tableName + " (" + columnUUID + ", " + columnDate + ", " @@ -107,7 +106,7 @@ public class HackerTable extends Table { public void prepare(PreparedStatement statement) throws SQLException { statement.setString(1, hackObject.getUuid().toString()); statement.setLong(2, hackObject.getDate()); - statement.setString(3, hackObject.getHackType().name()); + statement.setString(3, hackObject.getHackType()); statement.setInt(4, hackObject.getViolationLevel()); } }); diff --git a/PlanPluginBridge/src/main/java/com/djrapitops/pluginbridge/plan/aac/PlayerHackKickListener.java b/PlanPluginBridge/src/main/java/com/djrapitops/pluginbridge/plan/aac/PlayerHackKickListener.java index 57cf95f85..287815a4e 100644 --- a/PlanPluginBridge/src/main/java/com/djrapitops/pluginbridge/plan/aac/PlayerHackKickListener.java +++ b/PlanPluginBridge/src/main/java/com/djrapitops/pluginbridge/plan/aac/PlayerHackKickListener.java @@ -5,10 +5,7 @@ */ package com.djrapitops.pluginbridge.plan.aac; -import com.djrapitops.plan.system.database.databases.Database; -import com.djrapitops.plan.system.database.databases.sql.SQLDB; import com.djrapitops.plan.system.processing.Processing; -import com.djrapitops.plugin.api.utility.log.Log; import me.konsolas.aac.api.AACAPIProvider; import me.konsolas.aac.api.HackType; import me.konsolas.aac.api.PlayerViolationCommandEvent; @@ -17,7 +14,6 @@ import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; import org.bukkit.event.Listener; -import java.sql.SQLException; import java.util.UUID; /** @@ -26,7 +22,15 @@ import java.util.UUID; * @author Rsl1122 * @since 4.1.0 */ -public class PlayerHackKickListener implements Listener { +class PlayerHackKickListener implements Listener { + + private final HackerTable hackerTable; + private final Processing processing; + + PlayerHackKickListener(HackerTable hackerTable, Processing processing) { + this.hackerTable = hackerTable; + this.processing = processing; + } @EventHandler(priority = EventPriority.MONITOR) public void onKick(PlayerViolationCommandEvent event) { @@ -37,17 +41,12 @@ public class PlayerHackKickListener implements Listener { Player player = event.getPlayer(); UUID uuid = player.getUniqueId(); HackType hackType = event.getHackType(); + String hackTypeName = hackType.getName(); long time = System.currentTimeMillis(); int violations = AACAPIProvider.getAPI().getViolationLevel(player, hackType); - HackObject hackObject = new HackObject(uuid, time, hackType, violations); + HackObject hackObject = new HackObject(uuid, time, hackTypeName, violations); - Processing.submitNonCritical(() -> { - try { - new HackerTable((SQLDB) Database.getActive()).insertHackRow(hackObject); - } catch (SQLException e) { - Log.toLog(this.getClass().getName(), e); - } - }); + processing.submitNonCritical(() -> hackerTable.insertHackRow(hackObject)); } } diff --git a/PlanPluginBridge/src/main/java/com/djrapitops/pluginbridge/plan/advancedachievements/AdvancedAchievementsData.java b/PlanPluginBridge/src/main/java/com/djrapitops/pluginbridge/plan/advancedachievements/AdvancedAchievementsData.java index 6b028071f..736117d4e 100644 --- a/PlanPluginBridge/src/main/java/com/djrapitops/pluginbridge/plan/advancedachievements/AdvancedAchievementsData.java +++ b/PlanPluginBridge/src/main/java/com/djrapitops/pluginbridge/plan/advancedachievements/AdvancedAchievementsData.java @@ -8,30 +8,36 @@ import com.djrapitops.plan.data.element.AnalysisContainer; import com.djrapitops.plan.data.element.InspectContainer; import com.djrapitops.plan.data.plugin.ContainerSize; import com.djrapitops.plan.data.plugin.PluginData; -import com.djrapitops.plan.utilities.FormatUtils; +import com.djrapitops.plan.utilities.formatting.Formatter; import com.djrapitops.plan.utilities.html.icon.Color; import com.djrapitops.plan.utilities.html.icon.Family; import com.djrapitops.plan.utilities.html.icon.Icon; -import com.djrapitops.plugin.api.TimeAmount; import com.hm.achievement.api.AdvancedAchievementsAPI; import java.util.Collection; import java.util.Map; import java.util.UUID; +import java.util.concurrent.TimeUnit; /** * PluginData class for AdvancedAchievements. * * @author Rsl1122 */ -public class AdvancedAchievementsData extends PluginData { +class AdvancedAchievementsData extends PluginData { private final AdvancedAchievementsAPI aaAPI; + private final Formatter decimalFormatter; + private long lastRefresh; private Map totalAchievements; - public AdvancedAchievementsData(AdvancedAchievementsAPI aaAPI) { + AdvancedAchievementsData( + AdvancedAchievementsAPI aaAPI, + Formatter decimalFormatter + ) { super(ContainerSize.THIRD, "AdvancedAchievements"); + this.decimalFormatter = decimalFormatter; setPluginIcon(Icon.called("star").of(Color.GREEN).build()); this.aaAPI = aaAPI; refreshTotalAchievements(); @@ -47,12 +53,12 @@ public class AdvancedAchievementsData extends PluginData { @Override public AnalysisContainer getServerData(Collection collection, AnalysisContainer analysisContainer) { - if (System.currentTimeMillis() - lastRefresh > TimeAmount.MINUTE.ms() * 5L) { + if (System.currentTimeMillis() - lastRefresh > TimeUnit.MINUTES.toMillis(5L)) { refreshTotalAchievements(); } long total = getTotal(totalAchievements); int size = totalAchievements.size(); - String average = size != 0 ? FormatUtils.cutDecimals(total * 1.0 / size) : "-"; + String average = size != 0 ? decimalFormatter.apply(total * 1.0 / size) : "-"; analysisContainer.addValue(getWithIcon("Total Achievements", Icon.called("check-circle").of(Family.REGULAR).of(Color.GREEN)), total); analysisContainer.addValue(getWithIcon("Average Achievements", Icon.called("check-circle").of(Family.REGULAR).of(Color.GREEN)), average); diff --git a/PlanPluginBridge/src/main/java/com/djrapitops/pluginbridge/plan/advancedachievements/AdvancedAchievementsHook.java b/PlanPluginBridge/src/main/java/com/djrapitops/pluginbridge/plan/advancedachievements/AdvancedAchievementsHook.java index 37dfd8795..44e32233b 100644 --- a/PlanPluginBridge/src/main/java/com/djrapitops/pluginbridge/plan/advancedachievements/AdvancedAchievementsHook.java +++ b/PlanPluginBridge/src/main/java/com/djrapitops/pluginbridge/plan/advancedachievements/AdvancedAchievementsHook.java @@ -1,10 +1,14 @@ package com.djrapitops.pluginbridge.plan.advancedachievements; import com.djrapitops.plan.data.plugin.HookHandler; +import com.djrapitops.plan.utilities.formatting.Formatter; +import com.djrapitops.plan.utilities.formatting.Formatters; import com.djrapitops.pluginbridge.plan.Hook; import com.hm.achievement.api.AdvancedAchievementsAPI; import com.hm.achievement.api.AdvancedAchievementsAPIFetcher; +import javax.inject.Inject; +import javax.inject.Singleton; import java.util.Optional; /** @@ -14,26 +18,25 @@ import java.util.Optional; * @author Rsl1122 * @since 3.1.0 */ +@Singleton public class AdvancedAchievementsHook extends Hook { - /** - * Hooks the plugin and registers it's PluginData objects. - *

    - * API#addPluginDataSource uses the same method from HookHandler. - * - * @param hookH HookHandler instance for registering the data sources. - * @throws NoClassDefFoundError when the plugin class can not be found. - */ - public AdvancedAchievementsHook(HookHandler hookH) { - super("com.hm.achievement.AdvancedAchievements", hookH); + private final Formatter decimalFormatter; + + @Inject + public AdvancedAchievementsHook( + Formatters formatters + ) { + super("com.hm.achievement.AdvancedAchievements"); + decimalFormatter = formatters.decimals(); } @Override - public void hook() throws NoClassDefFoundError { + public void hook(HookHandler handler) throws NoClassDefFoundError { if (enabled) { Optional aaAPI = AdvancedAchievementsAPIFetcher.fetchInstance(); if (aaAPI.isPresent()) { - addPluginDataSource(new AdvancedAchievementsData(aaAPI.get())); + handler.addPluginDataSource(new AdvancedAchievementsData(aaAPI.get(), decimalFormatter)); } else { enabled = false; } diff --git a/PlanPluginBridge/src/main/java/com/djrapitops/pluginbridge/plan/advancedban/AdvancedBanData.java b/PlanPluginBridge/src/main/java/com/djrapitops/pluginbridge/plan/advancedban/AdvancedBanData.java index 377083f1a..ca3857e08 100644 --- a/PlanPluginBridge/src/main/java/com/djrapitops/pluginbridge/plan/advancedban/AdvancedBanData.java +++ b/PlanPluginBridge/src/main/java/com/djrapitops/pluginbridge/plan/advancedban/AdvancedBanData.java @@ -9,7 +9,7 @@ import com.djrapitops.plan.data.element.AnalysisContainer; import com.djrapitops.plan.data.element.InspectContainer; import com.djrapitops.plan.data.plugin.ContainerSize; import com.djrapitops.plan.data.plugin.PluginData; -import com.djrapitops.plan.utilities.FormatUtils; +import com.djrapitops.plan.utilities.formatting.Formatter; import com.djrapitops.plan.utilities.html.Html; import com.djrapitops.plan.utilities.html.HtmlUtils; import com.djrapitops.plan.utilities.html.icon.Color; @@ -28,9 +28,15 @@ import java.util.UUID; * * @author Vankka */ -public class AdvancedBanData extends PluginData { - public AdvancedBanData() { +class AdvancedBanData extends PluginData { + + private final Formatter timestampFormatter; + + AdvancedBanData( + Formatter timestampFormatter + ) { super(ContainerSize.THIRD, "AdvancedBan"); + this.timestampFormatter = timestampFormatter; setPluginIcon(Icons.BANNED); } @@ -66,8 +72,8 @@ public class AdvancedBanData extends PluginData { String operator = punishment.getOperator(); String link = Html.LINK.parse(PlanAPI.getInstance().getPlayerInspectPageLink(operator), operator); String reason = HtmlUtils.swapColorsToSpan(punishment.getReason()); - String start = FormatUtils.formatTimeStampYear(punishment.getStart()); - String end = FormatUtils.formatTimeStampYear(punishment.getEnd()); + String start = timestampFormatter.apply(punishment.getStart()); + String end = timestampFormatter.apply(punishment.getEnd()); PunishmentType type = punishment.getType(); // Permanent diff --git a/PlanPluginBridge/src/main/java/com/djrapitops/pluginbridge/plan/advancedban/AdvancedBanHook.java b/PlanPluginBridge/src/main/java/com/djrapitops/pluginbridge/plan/advancedban/AdvancedBanHook.java index b118ce1f4..3e310f31e 100644 --- a/PlanPluginBridge/src/main/java/com/djrapitops/pluginbridge/plan/advancedban/AdvancedBanHook.java +++ b/PlanPluginBridge/src/main/java/com/djrapitops/pluginbridge/plan/advancedban/AdvancedBanHook.java @@ -4,23 +4,37 @@ */ package com.djrapitops.pluginbridge.plan.advancedban; -import com.djrapitops.pluginbridge.plan.Hook; import com.djrapitops.plan.data.plugin.HookHandler; +import com.djrapitops.plan.utilities.formatting.Formatter; +import com.djrapitops.plan.utilities.formatting.Formatters; +import com.djrapitops.pluginbridge.plan.Hook; + +import javax.inject.Inject; +import javax.inject.Singleton; /** * Hook for AdvancedBan plugin. * * @author Vankka */ +@Singleton public class AdvancedBanHook extends Hook { - public AdvancedBanHook(HookHandler hookHandler) { - super("me.leoko.advancedban.Universal", hookHandler); + + private final Formatter timestampFormatter; + + @Inject + public AdvancedBanHook( + Formatters formatters + ) { + super("me.leoko.advancedban.Universal"); + + timestampFormatter = formatters.yearLong(); } @Override - public void hook() throws NoClassDefFoundError { + public void hook(HookHandler handler) throws NoClassDefFoundError { if (enabled) { - addPluginDataSource(new AdvancedBanData()); + handler.addPluginDataSource(new AdvancedBanData(timestampFormatter)); } } } diff --git a/PlanPluginBridge/src/main/java/com/djrapitops/pluginbridge/plan/askyblock/ASkyBlockData.java b/PlanPluginBridge/src/main/java/com/djrapitops/pluginbridge/plan/askyblock/ASkyBlockData.java index fc3640f07..241bf3384 100644 --- a/PlanPluginBridge/src/main/java/com/djrapitops/pluginbridge/plan/askyblock/ASkyBlockData.java +++ b/PlanPluginBridge/src/main/java/com/djrapitops/pluginbridge/plan/askyblock/ASkyBlockData.java @@ -9,6 +9,7 @@ import com.djrapitops.plan.data.element.InspectContainer; import com.djrapitops.plan.data.element.TableContainer; import com.djrapitops.plan.data.plugin.ContainerSize; import com.djrapitops.plan.data.plugin.PluginData; +import com.djrapitops.plan.utilities.formatting.Formatter; import com.djrapitops.plan.utilities.html.graphs.ProgressBar; import com.djrapitops.plan.utilities.html.icon.Color; import com.djrapitops.plan.utilities.html.icon.Family; @@ -25,12 +26,15 @@ import java.util.UUID; * * @author Rsl1122 */ -public class ASkyBlockData extends PluginData { +class ASkyBlockData extends PluginData { private final ASkyBlockAPI api; - public ASkyBlockData(ASkyBlockAPI api) { + private final Formatter percentageFormatter; + + ASkyBlockData(ASkyBlockAPI api, Formatter percentageFormatter) { super(ContainerSize.THIRD, "ASkyBlock"); + this.percentageFormatter = percentageFormatter; setPluginIcon(Icon.called("street-view").of(Color.LIGHT_BLUE).build()); this.api = api; } @@ -54,7 +58,7 @@ public class ASkyBlockData extends PluginData { int max = challengeCompletion.size(); inspectContainer.addValue(getWithIcon("Challenge Progress", Icon.called("bookmark").of(Color.LIGHT_BLUE)), obtained + " / " + max); - ProgressBar challengeProgress = new ProgressBar(obtained, max, "light-blue"); + ProgressBar challengeProgress = new ProgressBar(obtained, max, "light-blue", percentageFormatter); inspectContainer.addHtml("challenge-progress", challengeProgress.toHtml()); addTable(inspectContainer, challengeCompletion); diff --git a/PlanPluginBridge/src/main/java/com/djrapitops/pluginbridge/plan/askyblock/ASkyBlockHook.java b/PlanPluginBridge/src/main/java/com/djrapitops/pluginbridge/plan/askyblock/ASkyBlockHook.java index 784ec0dc0..0626f1e05 100644 --- a/PlanPluginBridge/src/main/java/com/djrapitops/pluginbridge/plan/askyblock/ASkyBlockHook.java +++ b/PlanPluginBridge/src/main/java/com/djrapitops/pluginbridge/plan/askyblock/ASkyBlockHook.java @@ -1,33 +1,39 @@ package com.djrapitops.pluginbridge.plan.askyblock; import com.djrapitops.plan.data.plugin.HookHandler; +import com.djrapitops.plan.utilities.formatting.Formatter; +import com.djrapitops.plan.utilities.formatting.Formatters; import com.djrapitops.pluginbridge.plan.Hook; import com.wasteofplastic.askyblock.ASkyBlockAPI; +import javax.inject.Inject; +import javax.inject.Singleton; + /** * A Class responsible for hooking to ASkyBlock and registering data sources. * * @author Rsl1122 * @since 3.5.0 */ +@Singleton public class ASkyBlockHook extends Hook { - /** - * Hooks the plugin and registers it's PluginData objects. - *

    - * API#addPluginDataSource uses the same method from HookHandler. - * - * @param hookH HookHandler instance for registering the data sources. - * @throws NoClassDefFoundError when the plugin class can not be found. - */ - public ASkyBlockHook(HookHandler hookH) throws NoClassDefFoundError { - super("com.wasteofplastic.askyblock.ASkyBlock", hookH); + private final Formatter percentageFormatter; + + @Inject + public ASkyBlockHook( + Formatters formatters + ) throws NoClassDefFoundError { + super("com.wasteofplastic.askyblock.ASkyBlock"); + + percentageFormatter = formatters.percentage(); } - public void hook() throws NoClassDefFoundError { + @Override + public void hook(HookHandler handler) throws NoClassDefFoundError { if (enabled) { ASkyBlockAPI api = ASkyBlockAPI.getInstance(); - addPluginDataSource(new ASkyBlockData(api)); + handler.addPluginDataSource(new ASkyBlockData(api, percentageFormatter)); } } } diff --git a/PlanPluginBridge/src/main/java/com/djrapitops/pluginbridge/plan/banmanager/BanManagerData.java b/PlanPluginBridge/src/main/java/com/djrapitops/pluginbridge/plan/banmanager/BanManagerData.java index acb5b0180..ed6bb7f6e 100644 --- a/PlanPluginBridge/src/main/java/com/djrapitops/pluginbridge/plan/banmanager/BanManagerData.java +++ b/PlanPluginBridge/src/main/java/com/djrapitops/pluginbridge/plan/banmanager/BanManagerData.java @@ -10,7 +10,7 @@ import com.djrapitops.plan.data.element.InspectContainer; import com.djrapitops.plan.data.plugin.BanData; import com.djrapitops.plan.data.plugin.ContainerSize; import com.djrapitops.plan.data.plugin.PluginData; -import com.djrapitops.plan.utilities.FormatUtils; +import com.djrapitops.plan.utilities.formatting.Formatter; import com.djrapitops.plan.utilities.html.Html; import com.djrapitops.plan.utilities.html.icon.Color; import com.djrapitops.plan.utilities.html.icon.Family; @@ -29,10 +29,13 @@ import java.util.stream.Collectors; * * @author Rsl1122 */ -public class BanManagerData extends PluginData implements BanData { +class BanManagerData extends PluginData implements BanData { - public BanManagerData() { + private final Formatter timestampFormatter; + + BanManagerData(Formatter timestampFormatter) { super(ContainerSize.THIRD, "BanManager"); + this.timestampFormatter = timestampFormatter; setPluginIcon(Icons.BANNED); } @@ -42,38 +45,46 @@ public class BanManagerData extends PluginData implements BanData { boolean muted = BmAPI.isMuted(uuid); inspectContainer.addValue(getWithIcon("Banned", Icons.BANNED), banned ? "Yes" : "No"); - if (banned) { - PlayerBanData currentBan = BmAPI.getCurrentBan(uuid); - String bannedBy = currentBan.getActor().getName(); - String link = Html.LINK.parse(PlanAPI.getInstance().getPlayerInspectPageLink(bannedBy), bannedBy); - long date = currentBan.getCreated(); - long ends = currentBan.getExpires(); - String reason = currentBan.getReason(); - - inspectContainer.addValue(" " + getWithIcon("Banned by", Icon.called("user").of(Color.RED)), link); - inspectContainer.addValue(" " + getWithIcon("Date", Icon.called("calendar").of(Color.RED).of(Family.REGULAR)), FormatUtils.formatTimeStampYear(date)); - inspectContainer.addValue(" " + getWithIcon("Ends", Icon.called("calendar-check").of(Color.RED).of(Family.REGULAR)), FormatUtils.formatTimeStampYear(ends)); - inspectContainer.addValue(" " + getWithIcon("Reason", Icon.called("comment").of(Color.RED).of(Family.REGULAR)), reason); + addBanInformation(uuid, inspectContainer); } + inspectContainer.addValue(getWithIcon("Muted", Icon.called("bell-slash").of(Color.DEEP_ORANGE)), muted ? "Yes" : "No"); if (muted) { - PlayerMuteData currentMute = BmAPI.getCurrentMute(uuid); - String mutedBy = currentMute.getActor().getName(); - String link = Html.LINK.parse(PlanAPI.getInstance().getPlayerInspectPageLink(mutedBy), mutedBy); - long date = currentMute.getCreated(); - long ends = currentMute.getExpires(); - String reason = currentMute.getReason(); - - inspectContainer.addValue(" " + getWithIcon("Muted by", Icon.called("user").of(Color.DEEP_ORANGE)), link); - inspectContainer.addValue(" " + getWithIcon("Date", Icon.called("calendar").of(Color.DEEP_ORANGE).of(Family.REGULAR)), FormatUtils.formatTimeStampYear(date)); - inspectContainer.addValue(" " + getWithIcon("Ends", Icon.called("calendar-check").of(Color.DEEP_ORANGE).of(Family.REGULAR)), FormatUtils.formatTimeStampYear(ends)); - inspectContainer.addValue(" " + getWithIcon("Reason", Icon.called("comment").of(Color.DEEP_ORANGE).of(Family.REGULAR)), reason); + addMuteInformation(uuid, inspectContainer); } return inspectContainer; } + private void addBanInformation(UUID uuid, InspectContainer inspectContainer) { + PlayerBanData currentBan = BmAPI.getCurrentBan(uuid); + String bannedBy = currentBan.getActor().getName(); + String link = Html.LINK.parse(PlanAPI.getInstance().getPlayerInspectPageLink(bannedBy), bannedBy); + long date = currentBan.getCreated(); + long ends = currentBan.getExpires(); + String reason = currentBan.getReason(); + + inspectContainer.addValue(" " + getWithIcon("Banned by", Icon.called("user").of(Color.RED)), link); + inspectContainer.addValue(" " + getWithIcon("Date", Icon.called("calendar").of(Color.RED).of(Family.REGULAR)), timestampFormatter.apply(date)); + inspectContainer.addValue(" " + getWithIcon("Ends", Icon.called("calendar-check").of(Color.RED).of(Family.REGULAR)), timestampFormatter.apply(ends)); + inspectContainer.addValue(" " + getWithIcon("Reason", Icon.called("comment").of(Color.RED).of(Family.REGULAR)), reason); + } + + private void addMuteInformation(UUID uuid, InspectContainer inspectContainer) { + PlayerMuteData currentMute = BmAPI.getCurrentMute(uuid); + String mutedBy = currentMute.getActor().getName(); + String link = Html.LINK.parse(PlanAPI.getInstance().getPlayerInspectPageLink(mutedBy), mutedBy); + long date = currentMute.getCreated(); + long ends = currentMute.getExpires(); + String reason = currentMute.getReason(); + + inspectContainer.addValue(" " + getWithIcon("Muted by", Icon.called("user").of(Color.DEEP_ORANGE)), link); + inspectContainer.addValue(" " + getWithIcon("Date", Icon.called("calendar").of(Color.DEEP_ORANGE).of(Family.REGULAR)), timestampFormatter.apply(date)); + inspectContainer.addValue(" " + getWithIcon("Ends", Icon.called("calendar-check").of(Color.DEEP_ORANGE).of(Family.REGULAR)), timestampFormatter.apply(ends)); + inspectContainer.addValue(" " + getWithIcon("Reason", Icon.called("comment").of(Color.DEEP_ORANGE).of(Family.REGULAR)), reason); + } + @Override public AnalysisContainer getServerData(Collection collection, AnalysisContainer analysisContainer) { return analysisContainer; diff --git a/PlanPluginBridge/src/main/java/com/djrapitops/pluginbridge/plan/banmanager/BanManagerHook.java b/PlanPluginBridge/src/main/java/com/djrapitops/pluginbridge/plan/banmanager/BanManagerHook.java index e6cc68aea..a277b94ed 100644 --- a/PlanPluginBridge/src/main/java/com/djrapitops/pluginbridge/plan/banmanager/BanManagerHook.java +++ b/PlanPluginBridge/src/main/java/com/djrapitops/pluginbridge/plan/banmanager/BanManagerHook.java @@ -1,29 +1,39 @@ -/* +/* * Licence is provided in the jar as license.yml also here: * https://github.com/Rsl1122/Plan-PlayerAnalytics/blob/master/Plan/src/main/resources/license.yml */ package com.djrapitops.pluginbridge.plan.banmanager; -import com.djrapitops.pluginbridge.plan.Hook; import com.djrapitops.plan.data.plugin.HookHandler; +import com.djrapitops.plan.utilities.formatting.Formatter; +import com.djrapitops.plan.utilities.formatting.Formatters; +import com.djrapitops.pluginbridge.plan.Hook; + +import javax.inject.Inject; +import javax.inject.Singleton; /** * Hook for BanManager plugin. * * @author Rsl1122 */ +@Singleton public class BanManagerHook extends Hook { - public BanManagerHook(HookHandler hookHandler) { - super("me.confuser.banmanager.BanManager", hookHandler); + private final Formatter timestampFormatter; + + @Inject + public BanManagerHook(Formatters formatters) { + super("me.confuser.banmanager.BanManager"); + timestampFormatter = formatters.yearLong(); } @Override - public void hook() throws NoClassDefFoundError { + public void hook(HookHandler handler) throws NoClassDefFoundError { if (!enabled) { return; } - addPluginDataSource(new BanManagerData()); + handler.addPluginDataSource(new BanManagerData(timestampFormatter)); } } \ No newline at end of file diff --git a/PlanPluginBridge/src/main/java/com/djrapitops/pluginbridge/plan/buycraft/BuyCraftData.java b/PlanPluginBridge/src/main/java/com/djrapitops/pluginbridge/plan/buycraft/BuyCraftData.java index fe9266355..326cbb6a0 100644 --- a/PlanPluginBridge/src/main/java/com/djrapitops/pluginbridge/plan/buycraft/BuyCraftData.java +++ b/PlanPluginBridge/src/main/java/com/djrapitops/pluginbridge/plan/buycraft/BuyCraftData.java @@ -11,7 +11,8 @@ import com.djrapitops.plan.data.element.InspectContainer; import com.djrapitops.plan.data.element.TableContainer; import com.djrapitops.plan.data.plugin.ContainerSize; import com.djrapitops.plan.data.plugin.PluginData; -import com.djrapitops.plan.utilities.FormatUtils; +import com.djrapitops.plan.system.settings.config.PlanConfig; +import com.djrapitops.plan.utilities.formatting.Formatter; import com.djrapitops.plan.utilities.html.Html; import com.djrapitops.plan.utilities.html.icon.Color; import com.djrapitops.plan.utilities.html.icon.Family; @@ -24,12 +25,23 @@ import java.util.*; * * @author Rsl1122 */ -public class BuyCraftData extends PluginData { +class BuyCraftData extends PluginData { private final String secret; - public BuyCraftData(String secret) { + private final PlanConfig config; + private final Formatter timestampFormatter; + private final Formatter decimalFormatter; + + BuyCraftData( + String secret, + PlanConfig config, Formatter timestampFormatter, + Formatter decimalFormatter + ) { super(ContainerSize.TAB, "BuyCraft"); + this.config = config; + this.timestampFormatter = timestampFormatter; + this.decimalFormatter = decimalFormatter; setPluginIcon(Icon.called("shopping-bag").of(Color.BLUE).build()); this.secret = secret; @@ -68,14 +80,14 @@ public class BuyCraftData extends PluginData { String name = payment.getPlayerName(); payTable.addRow( Html.LINK.parse(PlanAPI.getInstance().getPlayerInspectPageLink(name), name), - FormatUtils.formatTimeStampYear(payment.getDate()), - FormatUtils.cutDecimals(payment.getAmount()) + " " + payment.getCurrency(), + timestampFormatter.apply(payment.getDate()), + decimalFormatter.apply(payment.getAmount()) + " " + payment.getCurrency(), payment.getPackages() ); } analysisContainer.addTable("payTable", payTable); - MoneyStackGraph moneyStackGraph = MoneyStackGraph.create(payments); + MoneyStackGraph moneyStackGraph = new MoneyStackGraph(payments, config); String graphHtml = Html.PANEL_BODY.parse("

    ") + "