Merge pull request #500 from Rsl1122/4.2.0-refactoring

PR for Refactoring branch
This commit is contained in:
Rsl1122 2018-02-12 14:49:33 +02:00 committed by GitHub
commit 15ade849df
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
558 changed files with 16764 additions and 13597 deletions

3
.gitignore vendored
View File

@ -3,6 +3,9 @@ Plan.iml
PlanPluginBridge.iml
.sonar/
# Shell files
*.sh
# Created by https://www.gitignore.io/api/maven,eclipse,intellij,netbeans,osx,windows,notepadpp,windows,java
### Maven ###

View File

@ -3,22 +3,22 @@
<modelVersion>4.0.0</modelVersion>
<groupId>com.djrapitops</groupId>
<artifactId>Plan</artifactId>
<version>4.2.0-SNAPSHOT</version>
<version>4.2.0-SNAPSHOT</version>
<build>
<sourceDirectory>${basedir}/src</sourceDirectory>
<testSourceDirectory>${basedir}/test</testSourceDirectory>
<sourceDirectory>${basedir}/src/main/java</sourceDirectory>
<testSourceDirectory>${basedir}/src/test/java</testSourceDirectory>
<defaultGoal>clean package install</defaultGoal>
<resources>
<resource>
<targetPath>.</targetPath>
<directory>${basedir}/src/main/resources</directory>
<includes>
<include>**/*.keystore</include>
<include>**/*.css</include>
<include>**/*.yml</include>
<include>**/*.html</include>
<include>**/*.js</include>
<include>**/*.css</include>
<include>**/*.keystore</include>
<include>**/*.css</include>
<include>**/*.yml</include>
<include>**/*.html</include>
<include>**/*.js</include>
<include>**/*.css</include>
</includes>
<excludes>
<exclude>licence.yml</exclude>
@ -47,7 +47,6 @@
</execution>
</executions>
<configuration>
<minimizeJar>true</minimizeJar>
<artifactSet>
<excludes>
<exclude>org.powermock:*</exclude>
@ -65,6 +64,10 @@
</artifactSet>
</configuration>
</plugin>
<plugin>
<artifactId>maven-install-plugin</artifactId>
<version>2.5.2</version>
</plugin>
<plugin>
<artifactId>maven-jar-plugin</artifactId>
<version>2.6</version>
@ -104,206 +107,183 @@
<id>bungeecord-repo</id>
<url>https://oss.sonatype.org/content/repositories/snapshots</url>
</repository>
<repository>
<id>spigot-repo</id>
<url>https://hub.spigotmc.org/nexus/content/repositories/snapshots/</url>
</repository>
<repository>
<id>paper-repo</id>
<url>https://repo.destroystokyo.com/repository/maven-public/</url>
</repository>
<repository>
<id>spigot-repo</id>
<url>https://hub.spigotmc.org/nexus/content/repositories/snapshots/</url>
</repository>
<repository>
<id>paper-repo</id>
<url>https://repo.destroystokyo.com/repository/maven-public/</url>
</repository>
</repositories>
<dependencies>
<dependency>
<groupId>com.destroystokyo.paper</groupId>
<artifactId>paper-api</artifactId>
<version>1.12.2-R0.1-SNAPSHOT</version>
<scope>provided</scope>
<exclusions>
<exclusion>
<artifactId>authlib</artifactId>
<groupId>com.mojang</groupId>
</exclusion>
<exclusion>
<artifactId>commons-lang</artifactId>
<groupId>commons-lang</groupId>
</exclusion>
<exclusion>
<artifactId>json-simple</artifactId>
<groupId>com.googlecode.json-simple</groupId>
</exclusion>
<exclusion>
<artifactId>jsr305</artifactId>
<groupId>com.google.code.findbugs</groupId>
</exclusion>
<exclusion>
<artifactId>guava</artifactId>
<groupId>com.google.guava</groupId>
</exclusion>
<exclusion>
<artifactId>gson</artifactId>
<groupId>com.google.code.gson</groupId>
</exclusion>
<exclusion>
<artifactId>snakeyaml</artifactId>
<groupId>org.yaml</groupId>
</exclusion>
<exclusion>
<artifactId>bungeecord-chat</artifactId>
<groupId>net.md-5</groupId>
</exclusion>
<exclusion>
<artifactId>slf4j-api</artifactId>
<groupId>org.slf4j</groupId>
</exclusion>
<exclusion>
<artifactId>asm-all</artifactId>
<groupId>org.ow2.asm</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.spigotmc</groupId>
<artifactId>spigot-api</artifactId>
<version>1.12-R0.1-SNAPSHOT</version>
<artifactId>paper-api</artifactId>
<version>1.12.2-R0.1-SNAPSHOT</version>
<scope>provided</scope>
<exclusions>
<exclusion>
<artifactId>commons-lang</artifactId>
<groupId>commons-lang</groupId>
<artifactId>authlib</artifactId>
<groupId>com.mojang</groupId>
</exclusion>
<exclusion>
<artifactId>commons-lang</artifactId>
<groupId>commons-lang</groupId>
</exclusion>
<exclusion>
<artifactId>json-simple</artifactId>
<groupId>com.googlecode.json-simple</groupId>
</exclusion>
<exclusion>
<artifactId>jsr305</artifactId>
<groupId>com.google.code.findbugs</groupId>
</exclusion>
<exclusion>
<artifactId>guava</artifactId>
<groupId>com.google.guava</groupId>
</exclusion>
<exclusion>
<artifactId>gson</artifactId>
<groupId>com.google.code.gson</groupId>
</exclusion>
<exclusion>
<artifactId>snakeyaml</artifactId>
<groupId>org.yaml</groupId>
</exclusion>
<exclusion>
<artifactId>bungeecord-chat</artifactId>
<groupId>net.md-5</groupId>
</exclusion>
<exclusion>
<artifactId>slf4j-api</artifactId>
<groupId>org.slf4j</groupId>
</exclusion>
<exclusion>
<artifactId>asm-all</artifactId>
<groupId>org.ow2.asm</groupId>
</exclusion>
<exclusion>
<artifactId>json-simple</artifactId>
<groupId>com.googlecode.json-simple</groupId>
</exclusion>
<exclusion>
<artifactId>guava</artifactId>
<groupId>com.google.guava</groupId>
</exclusion>
<exclusion>
<artifactId>gson</artifactId>
<groupId>com.google.code.gson</groupId>
</exclusion>
<exclusion>
<artifactId>snakeyaml</artifactId>
<groupId>org.yaml</groupId>
</exclusion>
<exclusion>
<artifactId>bungeecord-chat</artifactId>
<groupId>net.md-5</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.bukkit</groupId>
<artifactId>bukkit</artifactId>
<version>1.12.2-R0.1-SNAPSHOT</version>
<scope>provided</scope>
<exclusions>
<exclusion>
<artifactId>commons-lang</artifactId>
<groupId>commons-lang</groupId>
</exclusion>
<exclusion>
<artifactId>json-simple</artifactId>
<groupId>com.googlecode.json-simple</groupId>
</exclusion>
<exclusion>
<artifactId>guava</artifactId>
<groupId>com.google.guava</groupId>
</exclusion>
<exclusion>
<artifactId>gson</artifactId>
<groupId>com.google.code.gson</groupId>
</exclusion>
<exclusion>
<artifactId>snakeyaml</artifactId>
<groupId>org.yaml</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<dependency>
<groupId>org.spigotmc</groupId>
<artifactId>spigot-api</artifactId>
<version>1.12-R0.1-SNAPSHOT</version>
<scope>provided</scope>
<exclusions>
<exclusion>
<artifactId>commons-lang</artifactId>
<groupId>commons-lang</groupId>
</exclusion>
<exclusion>
<artifactId>json-simple</artifactId>
<groupId>com.googlecode.json-simple</groupId>
</exclusion>
<exclusion>
<artifactId>guava</artifactId>
<groupId>com.google.guava</groupId>
</exclusion>
<exclusion>
<artifactId>gson</artifactId>
<groupId>com.google.code.gson</groupId>
</exclusion>
<exclusion>
<artifactId>snakeyaml</artifactId>
<groupId>org.yaml</groupId>
</exclusion>
<exclusion>
<artifactId>bungeecord-chat</artifactId>
<groupId>net.md-5</groupId>
<artifactId>bungeecord-api</artifactId>
<version>1.12-SNAPSHOT</version>
<scope>provided</scope>
<exclusions>
<exclusion>
<artifactId>bungeecord-config</artifactId>
<groupId>net.md-5</groupId>
</exclusion>
<exclusion>
<artifactId>bungeecord-event</artifactId>
<groupId>net.md-5</groupId>
</exclusion>
<exclusion>
<artifactId>bungeecord-protocol</artifactId>
<groupId>net.md-5</groupId>
</exclusion>
<exclusion>
<artifactId>bungeecord-chat</artifactId>
<groupId>net.md-5</groupId>
</exclusion>
<exclusion>
<artifactId>guava</artifactId>
<groupId>com.google.guava</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock</artifactId>
<version>1.6.6</version>
<type>pom</type>
<scope>compile</scope>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-api-mockito</artifactId>
<version>1.6.6</version>
<scope>compile</scope>
<groupId>org.bukkit</groupId>
<artifactId>bukkit</artifactId>
<version>1.12.2-R0.1-SNAPSHOT</version>
<scope>provided</scope>
<exclusions>
<exclusion>
<artifactId>commons-lang</artifactId>
<groupId>commons-lang</groupId>
</exclusion>
<exclusion>
<artifactId>json-simple</artifactId>
<groupId>com.googlecode.json-simple</groupId>
</exclusion>
<exclusion>
<artifactId>guava</artifactId>
<groupId>com.google.guava</groupId>
</exclusion>
<exclusion>
<artifactId>gson</artifactId>
<groupId>com.google.code.gson</groupId>
</exclusion>
<exclusion>
<artifactId>snakeyaml</artifactId>
<groupId>org.yaml</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-module-junit4</artifactId>
<version>1.6.6</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-module-junit4-rule</artifactId>
<version>1.6.6</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-classloading-xstream</artifactId>
<version>1.6.6</version>
<scope>compile</scope>
<groupId>net.md-5</groupId>
<artifactId>bungeecord-api</artifactId>
<version>1.12-SNAPSHOT</version>
<scope>provided</scope>
<exclusions>
<exclusion>
<artifactId>bungeecord-config</artifactId>
<groupId>net.md-5</groupId>
</exclusion>
<exclusion>
<artifactId>bungeecord-event</artifactId>
<groupId>net.md-5</groupId>
</exclusion>
<exclusion>
<artifactId>bungeecord-protocol</artifactId>
<groupId>net.md-5</groupId>
</exclusion>
<exclusion>
<artifactId>bungeecord-chat</artifactId>
<groupId>net.md-5</groupId>
</exclusion>
<exclusion>
<artifactId>guava</artifactId>
<groupId>com.google.guava</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<version>1.10.19</version>
<scope>compile</scope>
<version>2.13.0</version>
<scope>test</scope>
<exclusions>
<exclusion>
<artifactId>byte-buddy</artifactId>
<groupId>net.bytebuddy</groupId>
</exclusion>
<exclusion>
<artifactId>byte-buddy-agent</artifactId>
<groupId>net.bytebuddy</groupId>
</exclusion>
<exclusion>
<artifactId>objenesis</artifactId>
<groupId>org.objenesis</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-api-easymock</artifactId>
<version>1.6.6</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.easymock</groupId>
<artifactId>easymock</artifactId>
<version>3.4</version>
<scope>compile</scope>
<groupId>org.xerial</groupId>
<artifactId>sqlite-jdbc</artifactId>
<version>3.21.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>compile</scope>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.hamcrest</groupId>

View File

@ -25,15 +25,13 @@
<dependency>
<groupId>com.djrapitops</groupId>
<artifactId>AbstractPluginFramework</artifactId>
<version>3.0.1</version>
<scope>compile</scope>
<version>3.1.1</version>
</dependency>
<!-- SoftDepended Plugins -->
<dependency>
<groupId>com.djrapitops</groupId>
<artifactId>PlanPluginBridge</artifactId>
<version>4.2.0-SNAPSHOT</version>
<scope>compile</scope>
</dependency>
<!-- Paper API -->
<dependency>
@ -69,7 +67,6 @@
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.6</version>
<scope>compile</scope>
</dependency>
<!-- Geo IP -->
<dependency>
@ -82,69 +79,39 @@
<groupId>org.apache.commons</groupId>
<artifactId>commons-dbcp2</artifactId>
<version>2.1.1</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-pool2</artifactId>
<version>2.4.2</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>1.2</version>
<scope>compile</scope>
</dependency>
<!-- Testing -->
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock</artifactId>
<version>1.6.6</version>
<type>pom</type>
</dependency>
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-api-mockito</artifactId>
<version>1.6.6</version>
</dependency>
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-module-junit4</artifactId>
<version>1.6.6</version>
</dependency>
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-module-junit4-rule</artifactId>
<version>1.6.6</version>
</dependency>
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-classloading-xstream</artifactId>
<version>1.6.6</version>
</dependency>
<!-- Mockito (Test Dependency) -->
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<version>1.10.19</version>
<version>2.13.0</version>
<type>jar</type>
<scope>test</scope>
</dependency>
<!-- SQLite (Test Dependency) -->
<!-- https://mvnrepository.com/artifact/org.xerial/sqlite-jdbc -->
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-api-easymock</artifactId>
<version>1.6.6</version>
<type>jar</type>
</dependency>
<dependency>
<groupId>org.easymock</groupId>
<artifactId>easymock</artifactId>
<version>3.4</version>
<groupId>org.xerial</groupId>
<artifactId>sqlite-jdbc</artifactId>
<version>3.21.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.hamcrest</groupId>
@ -158,7 +125,7 @@
<defaultGoal>clean package install</defaultGoal>
<finalName>${project.name}</finalName>
<sourceDirectory>${basedir}/src/main/java</sourceDirectory>
<testSourceDirectory>${basedir}/test/main/java</testSourceDirectory>
<testSourceDirectory>${basedir}/src/test/java</testSourceDirectory>
<resources>
<resource>
<targetPath>.</targetPath>
@ -198,7 +165,6 @@
</execution>
</executions>
<configuration>
<minimizeJar>true</minimizeJar>
<artifactSet>
<excludes>
<exclude>org.powermock:*</exclude>

View File

@ -19,94 +19,31 @@
*/
package com.djrapitops.plan;
import com.djrapitops.plan.api.API;
import com.djrapitops.plan.api.IPlan;
import com.djrapitops.plan.api.exceptions.PlanEnableException;
import com.djrapitops.plan.command.PlanCommand;
import com.djrapitops.plan.data.plugin.HookHandler;
import com.djrapitops.plan.database.Database;
import com.djrapitops.plan.settings.Settings;
import com.djrapitops.plan.settings.locale.Locale;
import com.djrapitops.plan.settings.locale.Msg;
import com.djrapitops.plan.settings.theme.PlanColorScheme;
import com.djrapitops.plan.settings.theme.Theme;
import com.djrapitops.plan.systems.Systems;
import com.djrapitops.plan.systems.cache.DataCache;
import com.djrapitops.plan.systems.cache.GeolocationCache;
import com.djrapitops.plan.systems.file.FileSystem;
import com.djrapitops.plan.systems.file.config.ConfigSystem;
import com.djrapitops.plan.systems.file.database.DBSystem;
import com.djrapitops.plan.systems.info.BukkitInformationManager;
import com.djrapitops.plan.systems.info.ImporterManager;
import com.djrapitops.plan.systems.info.InformationManager;
import com.djrapitops.plan.systems.info.server.BukkitServerInfoManager;
import com.djrapitops.plan.systems.listeners.*;
import com.djrapitops.plan.systems.processing.Processor;
import com.djrapitops.plan.systems.processing.importing.importers.OfflinePlayerImporter;
import com.djrapitops.plan.systems.queue.ProcessingQueue;
import com.djrapitops.plan.systems.tasks.TaskSystem;
import com.djrapitops.plan.systems.update.VersionCheckSystem;
import com.djrapitops.plan.systems.webserver.WebServer;
import com.djrapitops.plan.systems.webserver.WebServerSystem;
import com.djrapitops.plan.systems.webserver.pagecache.PageCache;
import com.djrapitops.plan.utilities.file.export.HtmlExport;
import com.djrapitops.plan.system.BukkitSystem;
import com.djrapitops.plan.system.processing.importing.ImporterManager;
import com.djrapitops.plan.system.processing.importing.importers.OfflinePlayerImporter;
import com.djrapitops.plan.system.settings.locale.Locale;
import com.djrapitops.plan.system.settings.locale.Msg;
import com.djrapitops.plan.system.settings.theme.PlanColorScheme;
import com.djrapitops.plan.utilities.metrics.BStats;
import com.djrapitops.plugin.BukkitPlugin;
import com.djrapitops.plugin.StaticHolder;
import com.djrapitops.plugin.api.Benchmark;
import com.djrapitops.plugin.api.TimeAmount;
import com.djrapitops.plugin.api.config.Config;
import com.djrapitops.plugin.api.systems.TaskCenter;
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.task.AbsRunnable;
import com.djrapitops.plugin.task.RunnableFactory;
import org.bukkit.configuration.file.FileConfiguration;
import java.io.IOException;
import java.net.UnknownHostException;
import java.util.List;
import java.util.UUID;
/**
* Main class for Bukkit that manages the plugin.
* <p>
* Everything can be accessed through this class. Use Plan.getInstance() to get
* the initialised instance of Plan.
*
* @author Rsl1122
* @since 1.0.0
*/
public class Plan extends BukkitPlugin implements IPlan {
public class Plan extends BukkitPlugin implements PlanPlugin {
private API api;
private Systems systems;
private ProcessingQueue processingQueue;
private HookHandler hookHandler; // Manages 3rd party data sources
private BukkitInformationManager infoManager;
private BukkitServerInfoManager serverInfoManager;
private ServerVariableHolder serverVariableHolder;
/**
* Used to get the PlanAPI. @see API
*
* @return API of the current instance of Plan.
* @throws IllegalStateException If onEnable method has not been called on
* Plan and the instance is null.
* @throws NoClassDefFoundError If Plan is not installed.
*/
public static API getPlanAPI() throws NoClassDefFoundError {
Plan instance = getInstance();
if (instance == null) {
throw new IllegalStateException("Plugin not enabled properly, Singleton instance is null.");
}
return instance.getApi();
}
private BukkitSystem system;
/**
* Used to get the plugin-instance singleton.
@ -117,14 +54,6 @@ public class Plan extends BukkitPlugin implements IPlan {
return (Plan) StaticHolder.getInstance(Plan.class);
}
public static UUID getServerUUID() {
return getInstance().getServerUuid();
}
public UUID getServerUuid() {
return serverInfoManager.getServerUUID();
}
/**
* OnEnable method.
* <p>
@ -134,77 +63,9 @@ public class Plan extends BukkitPlugin implements IPlan {
public void onEnable() {
super.onEnable();
try {
systems = new Systems(this);
FileSystem.getInstance().init();
ConfigSystem.getInstance().init();
Log.setDebugMode(Settings.DEBUG.toString());
VersionCheckSystem.getInstance().init();
Benchmark.start("Enable");
try {
GeolocationCache.checkDB();
} catch (UnknownHostException e) {
Log.error("Plan Requires internet access on first run to download GeoLite2 Geolocation database.");
} catch (IOException e) {
throw new PlanEnableException("Something went wrong saving the downloaded GeoLite2 Geolocation database", e);
}
new Locale().loadLocale();
Theme.getInstance().init();
Benchmark.start("Reading server variables");
serverVariableHolder = new ServerVariableHolder(getServer());
Benchmark.stop("Enable", "Reading server variables");
DBSystem.getInstance().init();
Benchmark.start("WebServer Initialization");
processingQueue = new ProcessingQueue();
serverInfoManager = new BukkitServerInfoManager(this);
infoManager = new BukkitInformationManager(this);
WebServerSystem.getInstance().init();
if (!WebServerSystem.isWebServerEnabled()) {
if (Settings.WEBSERVER_DISABLED.isTrue()) {
Log.warn("WebServer was not initialized. (WebServer.DisableWebServer: true)");
} else {
Log.error("WebServer was not initialized successfully. Is the port (" + Settings.WEBSERVER_PORT.getNumber() + ") in use?");
}
}
serverInfoManager.updateServerInfo();
infoManager.updateConnection();
Benchmark.stop("Enable", "WebServer Initialization");
if (!reloading) {
registerListeners();
}
PlanPlayerListener.setCountKicks(true);
TaskSystem.getInstance().init();
this.api = new API(this);
boolean usingBungeeWebServer = infoManager.isUsingAnotherWebServer();
boolean usingAlternativeIP = Settings.SHOW_ALTERNATIVE_IP.isTrue();
if (!usingAlternativeIP && serverVariableHolder.getIp().isEmpty()) {
Log.infoColor(Locale.get(Msg.ENABLE_NOTIFY_EMPTY_IP).toString());
}
if (usingBungeeWebServer && usingAlternativeIP) {
Log.info("Make sure that the alternative IP points to the Bukkit Server: " + Settings.ALTERNATIVE_IP.toString());
}
registerCommand("plan", new PlanCommand(this));
Benchmark.start("Hook to 3rd party plugins");
hookHandler = new HookHandler(this);
Benchmark.stop("Enable", "Hook to 3rd party plugins");
system = new BukkitSystem(this);
system.enable();
ImporterManager.registerImporter(new OfflinePlayerImporter());
@ -215,16 +76,12 @@ public class Plan extends BukkitPlugin implements IPlan {
Benchmark.stop("Enable", "Enable");
Log.logDebug("Enable");
Log.info(Locale.get(Msg.ENABLED).toString());
StaticHolder.saveInstance(ShutdownHook.class, this.getClass());
new ShutdownHook(this);
if (Settings.ANALYSIS_EXPORT.isTrue()) {
RunnableFactory.createNew(new HtmlExport(this)).runTaskAsynchronously();
}
} catch (Exception e) {
Log.error("Plugin Failed to Initialize Correctly.");
Log.toLog(this.getClass().getName(), e);
Log.error("Plugin Failed to Initialize Correctly. If this issue is caused by config settings you can use /plan reload");
Log.toLog(this.getClass(), e);
onDisable();
}
registerCommand("plan", new PlanCommand(this));
}
@Override
@ -237,34 +94,11 @@ public class Plan extends BukkitPlugin implements IPlan {
*/
@Override
public void onDisable() {
//Clears the page cache
PageCache.clearCache();
// Processes unprocessed processors
if (processingQueue != null) {
List<Processor> processors = processingQueue.stopAndReturnLeftovers();
if (!reloading) {
Log.info("Processing unprocessed processors. (" + processors.size() + ")"); // TODO Move to Locale
for (Processor processor : processors) {
processor.process();
}
} else {
RunnableFactory.createNew("Re-Add processors", new AbsRunnable() {
@Override
public void run() {
addToProcessQueue(processors.toArray(new Processor[processors.size()]));
cancel();
}
}).runTaskLaterAsynchronously(TimeAmount.SECOND.ticks() * 5L);
}
}
systems.close();
system.disable();
Log.info(Locale.get(Msg.DISABLED).toString());
Benchmark.pluginDisabled(Plan.class);
DebugLog.pluginDisabled(Plan.class);
TaskCenter.cancelAllKnownTasks(Plan.class);
}
@Override
@ -274,110 +108,10 @@ public class Plan extends BukkitPlugin implements IPlan {
@Override
public void onReload() {
ConfigSystem.reload();
}
private void registerListeners() {
Benchmark.start("Register Listeners");
registerListener(new PlanPlayerListener(this));
registerListener(new PlanChatListener(this));
registerListener(new PlanGamemodeChangeListener(this));
registerListener(new PlanWorldChangeListener(this));
registerListener(new PlanCommandPreprocessListener(this));
registerListener(new PlanDeathEventListener(this));
Benchmark.stop("Enable", "Register Listeners");
}
/**
* Used to access Cache.
*
* @return Current instance of the DataCache
*/
public DataCache getDataCache() {
return getInfoManager().getDataCache();
}
/**
* Used to access active Database.
*
* @return the Current Database
*/
@Deprecated
public Database getDB() {
return DBSystem.getInstance().getActiveDatabase();
}
/**
* Used to access WebServer.
*
* @return the WebServer
*/
public WebServer getWebServer() {
return WebServerSystem.getInstance().getWebServer();
}
/**
* Used to access HookHandler.
*
* @return HookHandler that manages Hooks to other plugins.
*/
public HookHandler getHookHandler() {
return hookHandler;
}
/**
* Used to get the object storing server variables that are constant after
* boot.
*
* @return ServerVariableHolder
* @see ServerVariableHolder
*/
public ServerVariableHolder getVariable() {
return serverVariableHolder;
}
/**
* Used to get the object storing server info
*
* @return BukkitServerInfoManager
* @see BukkitServerInfoManager
*/
public BukkitServerInfoManager getServerInfoManager() {
return serverInfoManager;
}
public ProcessingQueue getProcessingQueue() {
return processingQueue;
}
public void addToProcessQueue(Processor... processors) {
if (!reloading) {
for (Processor processor : processors) {
if (processor == null) {
continue;
}
processingQueue.addToQueue(processor);
}
} else {
RunnableFactory.createNew("Re-Add processors", new AbsRunnable() {
@Override
public void run() {
addToProcessQueue(processors);
cancel();
}
}).runTaskLaterAsynchronously(TimeAmount.SECOND.ticks() * 5L);
}
}
@Override
public Config getMainConfig() {
return ConfigSystem.getInstance().getConfig();
}
public InformationManager getInfoManager() {
return infoManager;
}
public boolean isReloading() {
return reloading;
}
@ -418,21 +152,7 @@ public class Plan extends BukkitPlugin implements IPlan {
throw new IllegalStateException("This method should be used on this plugin.");
}
/**
* Method for getting the API.
* <p>
* Created due to necessity for testing, but can be used.
* For direct API getter use {@code Plan.getPlanAPI()}.
* <p>
* If Plan is reloaded a new API instance is created.
*
* @return Plan API instance.
*/
public API getApi() {
return api;
}
public Systems getSystems() {
return systems;
public BukkitSystem getSystem() {
return system;
}
}

View File

@ -4,129 +4,55 @@
*/
package com.djrapitops.plan;
import com.djrapitops.plan.api.IPlan;
import com.djrapitops.plan.command.PlanBungeeCommand;
import com.djrapitops.plan.database.Database;
import com.djrapitops.plan.settings.Settings;
import com.djrapitops.plan.settings.locale.Locale;
import com.djrapitops.plan.settings.locale.Msg;
import com.djrapitops.plan.settings.theme.PlanColorScheme;
import com.djrapitops.plan.settings.theme.Theme;
import com.djrapitops.plan.systems.Systems;
import com.djrapitops.plan.systems.file.FileSystem;
import com.djrapitops.plan.systems.file.config.ConfigSystem;
import com.djrapitops.plan.systems.file.database.DBSystem;
import com.djrapitops.plan.systems.info.BungeeInformationManager;
import com.djrapitops.plan.systems.info.InformationManager;
import com.djrapitops.plan.systems.info.server.BungeeServerInfoManager;
import com.djrapitops.plan.systems.listeners.BungeePlayerListener;
import com.djrapitops.plan.systems.processing.Processor;
import com.djrapitops.plan.systems.queue.ProcessingQueue;
import com.djrapitops.plan.systems.tasks.TaskSystem;
import com.djrapitops.plan.systems.update.VersionCheckSystem;
import com.djrapitops.plan.systems.webserver.WebServer;
import com.djrapitops.plan.systems.webserver.WebServerSystem;
import com.djrapitops.plan.utilities.file.export.HtmlExport;
import com.djrapitops.plan.system.BungeeSystem;
import com.djrapitops.plan.system.settings.locale.Locale;
import com.djrapitops.plan.system.settings.locale.Msg;
import com.djrapitops.plan.system.settings.theme.PlanColorScheme;
import com.djrapitops.plugin.BungeePlugin;
import com.djrapitops.plugin.StaticHolder;
import com.djrapitops.plugin.api.Benchmark;
import com.djrapitops.plugin.api.config.Config;
import com.djrapitops.plugin.api.systems.TaskCenter;
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.task.RunnableFactory;
import java.io.InputStream;
import java.util.UUID;
/**
* Bungee Main class.
*
* @author Rsl1122
*/
public class PlanBungee extends BungeePlugin implements IPlan {
public class PlanBungee extends BungeePlugin implements PlanPlugin {
private Systems systems;
private BungeeServerInfoManager serverInfoManager;
private BungeeInformationManager infoManager;
private com.djrapitops.plan.ServerVariableHolder variableHolder;
private ProcessingQueue processingQueue;
private boolean setupAllowed = false;
@Override
public void onEnable() {
super.onEnable();
try {
systems = new Systems(this);
FileSystem.getInstance().init();
ConfigSystem.getInstance().init();
Log.setDebugMode(Settings.DEBUG.toString());
VersionCheckSystem.getInstance().init();
variableHolder = new com.djrapitops.plan.ServerVariableHolder(getProxy());
new Locale().loadLocale();
Theme.getInstance().init();
DBSystem.getInstance().init();
String ip = variableHolder.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)");
return;
}
Benchmark.start("WebServer Initialization");
serverInfoManager = new BungeeServerInfoManager(this);
infoManager = new BungeeInformationManager(this);
WebServerSystem.getInstance().init();
serverInfoManager.loadServerInfo();
TaskSystem.getInstance().init();
processingQueue = new ProcessingQueue();
registerListener(new BungeePlayerListener(this));
Log.logDebug("Enable", "WebServer Initialization");
Log.info(Locale.get(Msg.ENABLED).toString());
if (Settings.ANALYSIS_EXPORT.isTrue()) {
RunnableFactory.createNew(new HtmlExport(this)).runTaskAsynchronously();
}
} catch (Exception e) {
Log.error("Plugin Failed to Initialize Correctly.");
Log.toLog(this.getClass().getName(), e);
}
registerCommand("planbungee", new PlanBungeeCommand(this));
}
private BungeeSystem system;
public static PlanBungee getInstance() {
return (PlanBungee) StaticHolder.getInstance(PlanBungee.class);
}
@Override
public void onDisable() {
if (processingQueue != null) {
try {
processingQueue.stop();
} catch (IllegalArgumentException ignored) {
/*ignored*/
}
public void onEnable() {
super.onEnable();
try {
system = new BungeeSystem(this);
system.enable();
Log.info(Locale.get(Msg.ENABLED).toString());
} catch (Exception e) {
Log.error("Plugin Failed to Initialize Correctly:");
Log.toLog(this.getClass(), e);
}
systems.close();
registerCommand("planbungee", new PlanBungeeCommand(this));
}
@Override
public void onDisable() {
system.disable();
Log.info(Locale.get(Msg.DISABLED).toString());
Benchmark.pluginDisabled(PlanBungee.class);
DebugLog.pluginDisabled(PlanBungee.class);
TaskCenter.cancelAllKnownTasks(PlanBungee.class);
}
@Override
@ -136,40 +62,6 @@ public class PlanBungee extends BungeePlugin implements IPlan {
@Override
public void onReload() {
ConfigSystem.reload();
}
@Override
@Deprecated
public Database getDB() {
return DBSystem.getInstance().getActiveDatabase();
}
public BungeeServerInfoManager getServerInfoManager() {
return serverInfoManager;
}
@Override
public InformationManager getInfoManager() {
return infoManager;
}
@Override
public WebServer getWebServer() {
return WebServerSystem.getInstance().getWebServer();
}
@Override
public ProcessingQueue getProcessingQueue() {
return processingQueue;
}
@Override
public void addToProcessQueue(Processor... processors) {
for (Processor processor : processors) {
processingQueue.addToQueue(processor);
}
}
@Override
@ -177,39 +69,17 @@ public class PlanBungee extends BungeePlugin implements IPlan {
return getResourceAsStream(resource);
}
@Override
public Config getMainConfig() {
return ConfigSystem.getInstance().getConfig();
}
@Override
public ColorScheme getColorScheme() {
return PlanColorScheme.create();
}
@Override
public com.djrapitops.plan.ServerVariableHolder getVariable() {
return variableHolder;
}
public static UUID getServerUUID() {
return getInstance().getServerUuid();
}
public UUID getServerUuid() {
return serverInfoManager.getServerUUID();
public BungeeSystem getSystem() {
return system;
}
@Override
public Systems getSystems() {
return systems;
}
public boolean isSetupAllowed() {
return setupAllowed;
}
public void setSetupAllowed(boolean setupAllowed) {
this.setupAllowed = setupAllowed;
public boolean isReloading() {
return reloading;
}
}

View File

@ -0,0 +1,53 @@
/*
* 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.plan;
import com.djrapitops.plugin.IPlugin;
import com.djrapitops.plugin.api.Check;
import com.djrapitops.plugin.settings.ColorScheme;
import java.io.File;
import java.io.InputStream;
/**
* Abstraction interface for both Plan and PlanBungee.
*
* @author Rsl1122
*/
public interface PlanPlugin extends IPlugin {
static PlanPlugin getInstance() {
boolean bukkitAvailable = Check.isBukkitAvailable();
boolean bungeeAvailable = Check.isBungeeAvailable();
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) {
}
}
throw new IllegalAccessError("Plugin instance not available");
}
@Override
File getDataFolder();
InputStream getResource(String resource);
ColorScheme getColorScheme();
@Override
boolean isReloading();
}

View File

@ -1,22 +1,22 @@
/*
/*
* 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.plan;
import com.djrapitops.plan.api.exceptions.DatabaseInitException;
import com.djrapitops.plan.api.exceptions.database.DBException;
import com.djrapitops.plan.api.exceptions.database.DBInitException;
import com.djrapitops.plan.data.Actions;
import com.djrapitops.plan.data.container.Action;
import com.djrapitops.plan.data.container.Session;
import com.djrapitops.plan.database.databases.SQLDB;
import com.djrapitops.plan.database.tables.Actions;
import com.djrapitops.plan.database.tables.SessionsTable;
import com.djrapitops.plan.systems.cache.DataCache;
import com.djrapitops.plan.systems.cache.SessionCache;
import com.djrapitops.plan.system.cache.CacheSystem;
import com.djrapitops.plan.system.cache.DataCache;
import com.djrapitops.plan.system.cache.SessionCache;
import com.djrapitops.plan.system.database.databases.Database;
import com.djrapitops.plan.utilities.MiscUtils;
import com.djrapitops.plugin.StaticHolder;
import com.djrapitops.plugin.api.utility.log.Log;
import java.sql.SQLException;
import java.util.Map;
import java.util.UUID;
@ -29,78 +29,81 @@ import java.util.UUID;
*/
public class ShutdownHook extends Thread {
private static boolean active = false;
private static DataCache dataCache;
private static SQLDB db;
private static boolean activated = false;
public ShutdownHook(Plan plugin) {
if (!active) {
Runtime.getRuntime().addShutdownHook(this);
private static boolean isActivated() {
return activated;
}
private static void activate(ShutdownHook hook) {
activated = true;
Runtime.getRuntime().addShutdownHook(hook);
}
public void register() {
if (isActivated()) {
return;
}
active = true;
db = (SQLDB) plugin.getDB();
dataCache = plugin.getDataCache();
activate(this);
}
@Override
public void run() {
Log.debug("Shutdown hook triggered.");
Database db = null;
try {
Map<UUID, Session> activeSessions = SessionCache.getActiveSessions();
long now = MiscUtils.getTime();
if (db == null) {
return;
}
db = Database.getActive();
if (!db.isOpen()) {
db.init();
}
saveFirstSessionInformation(now);
saveActiveSessions(activeSessions, now);
} catch (DatabaseInitException e) {
Log.toLog(this.getClass().getName(), e);
saveFirstSessionInformation(db, now);
saveActiveSessions(db, activeSessions, now);
} catch (IllegalStateException ignored) {
/* Database is not initialized */
} catch (DBInitException e) {
Log.toLog(this.getClass(), e);
} finally {
if (db != null) {
try {
db.close();
} catch (SQLException e) {
Log.toLog(this.getClass().getName(), e);
} catch (DBException e) {
Log.toLog(this.getClass(), e);
}
}
db = null;
dataCache = null;
StaticHolder.unRegister(Plan.class);
}
}
private void saveFirstSessionInformation(long now) {
private void saveFirstSessionInformation(Database db, long now) {
DataCache dataCache = CacheSystem.getInstance().getDataCache();
for (Map.Entry<UUID, Integer> entry : dataCache.getFirstSessionMsgCounts().entrySet()) {
try {
UUID uuid = entry.getKey();
int messagesSent = entry.getValue();
db.getActionsTable().insertAction(uuid, new Action(now, Actions.FIRST_LOGOUT, "Messages sent: " + messagesSent));
} catch (SQLException e) {
Log.toLog(this.getClass().getName(), e);
db.save().action(uuid, new Action(now, Actions.FIRST_LOGOUT, "Messages sent: " + messagesSent));
} catch (DBException e) {
Log.toLog(this.getClass(), e);
}
}
}
private void saveActiveSessions(Map<UUID, Session> activeSessions, long now) {
SessionsTable sessionsTable = db.getSessionsTable();
private void saveActiveSessions(Database db, Map<UUID, Session> activeSessions, long now) {
for (Map.Entry<UUID, Session> entry : activeSessions.entrySet()) {
UUID uuid = entry.getKey();
Session session = entry.getValue();
long sessionEnd = session.getSessionEnd();
if (sessionEnd != -1) {
continue;
if (sessionEnd == -1) {
session.endSession(now);
}
session.endSession(now);
try {
Log.debug("Shutdown: Saving a session: " + session.getSessionStart());
sessionsTable.saveSession(uuid, session);
} catch (SQLException e) {
Log.toLog(this.getClass().getName(), e);
db.save().session(uuid, session);
} catch (DBException e) {
Log.toLog(this.getClass(), e);
}
}
activeSessions.clear();

View File

@ -1,254 +0,0 @@
package com.djrapitops.plan.api;
import com.djrapitops.plan.Plan;
import com.djrapitops.plan.api.exceptions.ParseException;
import com.djrapitops.plan.data.AnalysisData;
import com.djrapitops.plan.data.plugin.PluginData;
import com.djrapitops.plan.systems.info.BukkitInformationManager;
import com.djrapitops.plan.utilities.uuid.UUIDUtility;
import com.djrapitops.plugin.utilities.Verify;
import org.bukkit.OfflinePlayer;
import java.sql.SQLException;
import java.util.Collection;
import java.util.UUID;
import static org.bukkit.Bukkit.getOfflinePlayer;
/**
* This class contains the API methods for Bukkit version of the plugin.
* <p>
* Methods can be called from Asynchronous task and are thread safe unless
* otherwise stated.
* <p>
* Use Plan.getPlanAPI() to get the API.
* <p>
* More information about API methods can be found on GitHub.
*
* @author Rsl1122
* @see PluginData
* @see AnalysisType
* @since 4.0.0
*/
public class API {
private final Plan plugin;
/**
* Creates a new API instance - not supposed to be called outside {@code Plan.onEnable}.
*
* @param plugin Current instance of Plan
*/
public API(Plan plugin) {
this.plugin = plugin;
}
/**
* Condition whether or not the plugin enabled successfully.
*
* @return true if plugin is enabled correctly.
*/
public boolean isEnabled() {
return plugin.isEnabled();
}
/**
* Add a source of plugin data to the Plugins tab on Analysis and/or Inspect
* page.
* <p>
* Refer to documentation on GitHub or Javadoc of PluginData to set-up a
* data source that extends PluginData correctly.
*
* @param dataSource an object that extends PluginData-object, thus allowing
* Analysis and Inspect to manage the data of a plugin correctly.
* @see PluginData
*/
public void addPluginDataSource(PluginData dataSource) {
if (isEnabled()) {
plugin.getHookHandler().addPluginDataSource(dataSource);
}
}
/**
* Used to get a relative link to InspectPage of a player.
* <p>
* This method is useful if you have a table and want to link to the inspect
* page.
* <p>
* Html.LINK.parse("Link", "PlayerName") can be used to get a link
* {@code <a href="Link">PlayerName</a>}
*
* @param name Name of the player
* @return {@code ../player/PlayerName}
*/
public String getPlayerInspectPageLink(String name) {
if (name == null) {
return "#";
}
return "../player/" + name.replace(" ", "%20").replace(".", "%2E");
}
/**
* Condition if Players's Inspect page is cached to PageCache.
*
* @param uuid UUID of the player.
* @return true/false
* @deprecated use {@code isPlayerHtmlCached}
*/
@Deprecated
public boolean isPlayersDataInspectCached(UUID uuid) {
return isPlayerHtmlCached(uuid);
}
/**
* Condition if Players's Inspect page is cached to PageCache of the providing WebServer.
* <p>
* Using BungeeCord: Will send a {@code IsCachedWebAPI} request to check if the page is in Bungee's PageCache.
* Only Bukkit: Checks PageCache for page.
*
* @param uuid UUID of the player.
* @return true/false
*/
public boolean isPlayerHtmlCached(UUID uuid) {
return plugin.getInfoManager().isCached(uuid);
}
/**
* Cache Players's Inspect page to the PageCache of the providing WebServer.
*
* @param uuid UUID of the player.
* @deprecated use {@code cachePlayerHtml}
*/
@Deprecated
public void cacheUserDataToInspectCache(UUID uuid) {
cachePlayerHtml(uuid);
}
/**
* Cache Players's Inspect page to the PageCache of the providing WebServer.
* <p>
* Using BungeeCord: Will send a {@code PostHtmlWebAPI} request after calculating the inspect page.
* Only Bukkit: Calculates inspect page and places it in the PageCache.
*
* @param uuid UUID of the player.
* @deprecated use {@code cachePlayerHtml}
*/
public void cachePlayerHtml(UUID uuid) {
plugin.getInfoManager().cachePlayer(uuid);
}
/**
* Used to get the full Html of the Inspect page as a string.
* <p>
* Re-calculates the inspect html on this server.
*
* @param uuid UUID of the player.
* @return player.html with all placeholders replaced.
*/
public String getPlayerHtmlAsString(UUID uuid) throws ParseException {
return plugin.getInfoManager().getPlayerHtml(uuid);
}
/**
* Condition if the Analysis has been run and is cached to the AnalysisCache.
*
* @return true/false
*/
public boolean isAnalysisCached() {
return plugin.getInfoManager().isAnalysisCached(Plan.getServerUUID());
}
/**
* Run the analysis.
*/
public void updateAnalysisCache() {
plugin.getInfoManager().refreshAnalysis(plugin.getServerUuid());
}
/**
* Used to get the full HTML of the Analysis page as a string.
* <p>
* Condition if the data is cached to AnalysisCache before calling this.
*
* @return server.html with all placeholders replaced.
* @throws NullPointerException if AnalysisData has not been cached.
*/
public String getAnalysisHtmlAsString() {
return plugin.getInfoManager().getAnalysisHtml();
}
/**
* Used to get the AnalysisData object.
* <p>
* Condition if the data is cached to AnalysisCache before calling this.
*
* @return AnalysisData object.
* @see AnalysisData
*/
public AnalysisData getAnalysisDataFromCache() {
return ((BukkitInformationManager) plugin.getInfoManager()).getAnalysisData();
}
/**
* Used to get the PlayerName of a player who has played on the server.
* Should be called from an Async thread.
*
* @param uuid UUID of the player.
* @return PlayerName, eg "Rsl1122"
* @throws IllegalArgumentException If uuid is null.
* @throws IllegalStateException If the player has not played on the server before.
*/
public String getPlayerName(UUID uuid) throws SQLException {
Verify.nullCheck(uuid);
String playerName = plugin.getDB().getUsersTable().getPlayerName(uuid);
if (playerName != null) {
return playerName;
}
OfflinePlayer offlinePlayer = getOfflinePlayer(uuid);
if (offlinePlayer != null) {
return offlinePlayer.getName();
}
throw new IllegalStateException("Player has not played on this server before.");
}
/**
* Uses UUIDUtility to turn PlayerName to UUID.
*
* @param playerName Player's name
* @return UUID of the Player
* @throws Exception if player's name is not registered at Mojang
* @deprecated Typo in method name, use playerNameToUUID instead
*/
@Deprecated
public UUID PlayerNameToUUID(String playerName) {
return playerNameToUUID(playerName);
}
/**
* Uses UUIDUtility to turn PlayerName to UUID.
*
* @param playerName Player's name
* @return UUID of the Player
* @throws IllegalArgumentException if player's name is not registered at Mojang
*/
public UUID playerNameToUUID(String playerName) {
UUID uuid = UUIDUtility.getUUIDOf(playerName);
if (uuid == null) {
throw new IllegalArgumentException("UUID did not get a match");
}
return uuid;
}
/**
* Get the saved UUIDs in the database.
* <p>
* Should be called from async thread.
*
* @return Collection of UUIDs that can be found in the database.
* @throws SQLException If database error occurs.
* @since 3.4.2
*/
public Collection<UUID> getSavedUUIDs() throws SQLException {
return plugin.getDB().getSavedUUIDs();
}
}

View File

@ -0,0 +1,40 @@
/*
* 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.plan.api;
import com.djrapitops.plan.data.plugin.PluginData;
import com.djrapitops.plan.system.BukkitSystem;
import com.djrapitops.plan.system.database.databases.operation.FetchOperations;
import java.util.UUID;
/**
* PlanAPI extension for Bukkit
*
* @author Rsl1122
*/
public class BukkitAPI extends CommonAPI {
private final BukkitSystem bukkitSystem;
public BukkitAPI(BukkitSystem bukkitSystem) {
this.bukkitSystem = bukkitSystem;
}
@Override
public void addPluginDataSource(PluginData pluginData) {
bukkitSystem.getHookHandler().addPluginDataSource(pluginData);
}
@Override
public String getPlayerName(UUID uuid) {
return bukkitSystem.getCacheSystem().getDataCache().getName(uuid);
}
@Override
public FetchOperations fetchFromPlanDB() {
return bukkitSystem.getDatabaseSystem().getActiveDatabase().fetch();
}
}

View File

@ -0,0 +1,40 @@
/*
* 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.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();
}
}

View File

@ -0,0 +1,47 @@
/*
* 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.plan.api;
import com.djrapitops.plan.api.exceptions.database.DBException;
import com.djrapitops.plan.utilities.uuid.UUIDUtility;
import com.djrapitops.plugin.api.utility.log.Log;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
/**
* PlanAPI extension for all implementations.
*
* @author Rsl1122
*/
public abstract class CommonAPI implements PlanAPI {
@Override
public String getPlayerInspectPageLink(UUID uuid) {
return getPlayerInspectPageLink(getPlayerName(uuid));
}
@Override
public String getPlayerInspectPageLink(String playerName) {
return "../player/" + playerName;
}
@Override
public UUID playerNameToUUID(String playerName) {
return UUIDUtility.getUUIDOf(playerName);
}
@Override
public Map<UUID, String> getKnownPlayerNames() {
try {
return fetchFromPlanDB().getPlayerNames();
} catch (DBException e) {
Log.toLog(this.getClass(), e);
return new HashMap<>();
}
}
}

View File

@ -1,51 +0,0 @@
/*
* 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.plan.api;
import com.djrapitops.plan.ServerVariableHolder;
import com.djrapitops.plan.database.Database;
import com.djrapitops.plan.systems.Systems;
import com.djrapitops.plan.systems.info.InformationManager;
import com.djrapitops.plan.systems.processing.Processor;
import com.djrapitops.plan.systems.queue.ProcessingQueue;
import com.djrapitops.plan.systems.webserver.WebServer;
import com.djrapitops.plugin.IPlugin;
import com.djrapitops.plugin.api.config.Config;
import com.djrapitops.plugin.settings.ColorScheme;
import java.io.File;
import java.io.InputStream;
import java.util.UUID;
/**
* Abstraction interface for both Plan and PlanBungee.
*
* @author Rsl1122
*/
public interface IPlan extends IPlugin {
Database getDB();
ServerVariableHolder getVariable();
UUID getServerUuid();
InformationManager getInfoManager();
WebServer getWebServer();
File getDataFolder();
ProcessingQueue getProcessingQueue();
void addToProcessQueue(Processor... processors);
InputStream getResource(String resource);
Config getMainConfig();
ColorScheme getColorScheme();
Systems getSystems();
}

View File

@ -0,0 +1,38 @@
/*
* 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.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.UUID;
/**
* Interface for PlanAPI methods.
*
* @author Rsl1122
*/
public interface PlanAPI {
static PlanAPI getInstance() {
return PlanSystem.getInstance().getPlanAPI();
}
void addPluginDataSource(PluginData pluginData);
String getPlayerInspectPageLink(UUID uuid);
String getPlayerInspectPageLink(String playerName);
String getPlayerName(UUID uuid);
UUID playerNameToUUID(String playerName);
Map<UUID, String> getKnownPlayerNames();
FetchOperations fetchFromPlanDB();
}

View File

@ -1,21 +0,0 @@
/*
* 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.plan.api.exceptions;
/**
* Thrown when something goes wrong with creating tables with {@code Table#createTable}.
*
* @author Rsl1122
*/
public class DBCreateTableException extends DatabaseInitException {
public DBCreateTableException(String tableName, String message, Throwable cause) {
super(tableName + ": " + message, cause);
}
public DBCreateTableException(Throwable cause) {
super(cause);
}
}

View File

@ -1,4 +1,4 @@
/*
/*
* 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
*/
@ -9,13 +9,13 @@ package com.djrapitops.plan.api.exceptions;
*
* @author Rsl1122
*/
public class PlanEnableException extends Exception {
public class EnableException extends Exception {
public PlanEnableException(String message, Throwable cause) {
public EnableException(String message, Throwable cause) {
super(message, cause);
}
public PlanEnableException(String message) {
public EnableException(String message) {
super(message);
}
}

View File

@ -1,11 +1,11 @@
/*
/*
* 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.plan.api.exceptions;
/**
* Exception thrown when PageParser encounters an Exception.
* Exception thrown when Page encounters an Exception.
*
* @author Rsl1122
*/

View File

@ -0,0 +1,13 @@
package com.djrapitops.plan.api.exceptions;
public class PassEncryptException extends Exception {
public PassEncryptException(String s) {
super(s);
}
public PassEncryptException(String s, Throwable throwable) {
super(s, throwable);
}
}

View File

@ -1,21 +0,0 @@
/*
* 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.plan.api.exceptions;
/**
* Thrown when WebAPI fails to connect to an address.
*
* @author Rsl1122
*/
public class WebAPIConnectionFailException extends WebAPIException {
public WebAPIConnectionFailException(String message, Throwable cause) {
super(message, cause);
}
public WebAPIConnectionFailException(Throwable cause) {
super(cause);
}
}

View File

@ -1,28 +0,0 @@
/*
* 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.plan.api.exceptions;
/**
* Thrown when WebAPI POST-request fails, general Exception.
*
* @author Rsl1122
*/
public class WebAPIException extends Exception {
public WebAPIException() {
}
public WebAPIException(String message) {
super(message);
}
public WebAPIException(String message, Throwable cause) {
super(message, cause);
}
public WebAPIException(Throwable cause) {
super(cause);
}
}

View File

@ -1,28 +0,0 @@
/*
* 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.plan.api.exceptions;
/**
* Group of WebAPIExceptions that can be considered a failed connection state on some occasions.
*
* @author Rsl1122
*/
public class WebAPIFailException extends WebAPIException {
public WebAPIFailException() {
}
public WebAPIFailException(String message) {
super(message);
}
public WebAPIFailException(String message, Throwable cause) {
super(message, cause);
}
public WebAPIFailException(Throwable cause) {
super(cause);
}
}

View File

@ -1,16 +0,0 @@
/*
* 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.plan.api.exceptions;
/**
* Thrown when WebAPI returns 404, usually when response is supposed to be false.
*
* @author Rsl1122
*/
public class WebAPIInternalErrorException extends WebAPIFailException {
public WebAPIInternalErrorException() {
super("Internal Error occurred on receiving server");
}
}

View File

@ -1,16 +0,0 @@
/*
* 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.plan.api.exceptions;
/**
* Thrown when WebAPI returns 404, usually when response is supposed to be false.
*
* @author Rsl1122
*/
public class WebAPINotFoundException extends WebAPIFailException {
public WebAPINotFoundException() {
super("Not Found");
}
}

View File

@ -1,27 +1,37 @@
/*
/*
* 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.plan.api.exceptions;
import com.djrapitops.plan.api.exceptions.connection.WebException;
import com.djrapitops.plan.system.webserver.auth.FailReason;
/**
* Thrown when WebUser can not be authorized (WebServer).
*
* @author Rsl1122
*/
public class WebUserAuthException extends Exception {
public WebUserAuthException() {
public class WebUserAuthException extends WebException {
private final FailReason failReason;
public WebUserAuthException(FailReason failReason) {
super(failReason.getReason());
this.failReason = failReason;
}
public WebUserAuthException(String message) {
super(message);
}
public WebUserAuthException(String message, Throwable cause) {
super(message, cause);
public WebUserAuthException(FailReason failReason, String additionalInfo) {
super(failReason.getReason() + ": " + additionalInfo);
this.failReason = failReason;
}
public WebUserAuthException(Throwable cause) {
super(cause);
super(FailReason.ERROR.getReason(), cause);
this.failReason = FailReason.ERROR;
}
public FailReason getFailReason() {
return failReason;
}
}

View File

@ -0,0 +1,17 @@
/*
* 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.plan.api.exceptions.connection;
/**
* Thrown when connection is returned 401 Bad Request.
*
* @author Rsl1122
*/
public class BadRequestException extends WebException {
public BadRequestException(String message) {
super(message);
}
}

View File

@ -0,0 +1,21 @@
/*
* 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.plan.api.exceptions.connection;
/**
* Thrown when Connection fails to connect to an address.
*
* @author Rsl1122
*/
public class ConnectionFailException extends WebException {
public ConnectionFailException(String message, Throwable cause) {
super(message, cause);
}
public ConnectionFailException(Throwable cause) {
super(cause);
}
}

View File

@ -1,16 +1,16 @@
/*
/*
* 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.plan.api.exceptions;
package com.djrapitops.plan.api.exceptions.connection;
/**
* Thrown when WebAPI gets a 403 response.
* Thrown when Connection gets a 403 response.
*
* @author Rsl1122
*/
public class WebAPIForbiddenException extends WebAPIFailException {
public WebAPIForbiddenException(String url) {
public class ForbiddenException extends WebFailException {
public ForbiddenException(String url) {
super("Forbidden: " + url);
}
}

View File

@ -0,0 +1,20 @@
/*
* 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.plan.api.exceptions.connection;
/**
* Thrown when Connection returns 500.
*
* @author Rsl1122
*/
public class InternalErrorException extends WebFailException {
public InternalErrorException() {
super("Internal Error occurred on receiving server");
}
public InternalErrorException(String message, Throwable cause) {
super(message, cause);
}
}

View File

@ -0,0 +1,25 @@
/*
* 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.plan.api.exceptions.connection;
/**
* Thrown when ConnectionSystem can not find any servers to send request to.
*
* @author Rsl1122
*/
public class NoServersException extends WebException {
public NoServersException(String message) {
super(message);
}
public NoServersException(String message, Throwable cause) {
super(message, cause);
}
public NoServersException(Throwable cause) {
super(cause);
}
}

View File

@ -0,0 +1,16 @@
/*
* 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.plan.api.exceptions.connection;
/**
* Thrown when Connection returns 404, when page is not found.
*
* @author Rsl1122
*/
public class NotFoundException extends WebFailException {
public NotFoundException(String message) {
super(message);
}
}

View File

@ -0,0 +1,19 @@
/*
* 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.plan.api.exceptions.connection;
import com.djrapitops.plan.api.exceptions.database.DBException;
/**
* Thrown when DBException occurs during InfoRequest#placeIntoDatabase.
*
* @author Rsl1122
*/
public class TransferDatabaseException extends WebException {
public TransferDatabaseException(DBException cause) {
super(cause);
}
}

View File

@ -0,0 +1,25 @@
/*
* 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.plan.api.exceptions.connection;
/**
* Thrown when Connection gets a 412 response due to ServerUUID not being in the database.
*
* @author Rsl1122
*/
public class UnauthorizedServerException extends WebFailException {
public UnauthorizedServerException(String message) {
super(message);
}
public UnauthorizedServerException(String message, Throwable cause) {
super(message, cause);
}
public UnauthorizedServerException(Throwable cause) {
super(cause);
}
}

View File

@ -0,0 +1,19 @@
/*
* 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.plan.api.exceptions.connection;
import com.djrapitops.plan.system.database.databases.Database;
/**
* Exception thrown when calling Database#transfer and Database implementation doesn't support it.
*
* @author Rsl1122
*/
public class UnsupportedTransferDatabaseException extends WebException {
public UnsupportedTransferDatabaseException(Database db) {
super(db.getName() + " does not support Transfer operations!");
}
}

View File

@ -0,0 +1,28 @@
/*
* 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.plan.api.exceptions.connection;
/**
* Thrown when Connection POST-request fails, general Exception.
*
* @author Rsl1122
*/
public class WebException extends Exception {
public WebException() {
}
public WebException(String message) {
super(message);
}
public WebException(String message, Throwable cause) {
super(message, cause);
}
public WebException(Throwable cause) {
super(cause);
}
}

View File

@ -0,0 +1,28 @@
/*
* 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.plan.api.exceptions.connection;
/**
* Group of WebExceptions that can be considered a failed connection state on some occasions.
*
* @author Rsl1122
*/
public class WebFailException extends WebException {
public WebFailException() {
}
public WebFailException(String message) {
super(message);
}
public WebFailException(String message, Throwable cause) {
super(message, cause);
}
public WebFailException(Throwable cause) {
super(cause);
}
}

View File

@ -1,25 +1,25 @@
/*
/*
* 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.plan.api.exceptions;
package com.djrapitops.plan.api.exceptions.database;
/**
* Thrown when something goes wrong with the Database, generic exception.
*
* @author Rsl1122
*/
public class DatabaseException extends Exception {
public class DBException extends Exception {
public DatabaseException(String message, Throwable cause) {
public DBException(String message, Throwable cause) {
super(message, cause);
}
public DatabaseException(Throwable cause) {
public DBException(Throwable cause) {
super(cause);
}
public DatabaseException(String message) {
public DBException(String message) {
super(message);
}
}

View File

@ -1,25 +1,25 @@
/*
/*
* 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.plan.api.exceptions;
package com.djrapitops.plan.api.exceptions.database;
/**
* Thrown when something goes wrong with {@code Database#init}.
*
* @author Rsl1122
*/
public class DatabaseInitException extends DatabaseException {
public class DBInitException extends FatalDBException {
public DatabaseInitException(String message, Throwable cause) {
public DBInitException(String message, Throwable cause) {
super(message, cause);
}
public DatabaseInitException(Throwable cause) {
public DBInitException(Throwable cause) {
super(cause);
}
public DatabaseInitException(String message) {
public DBInitException(String message) {
super(message);
}
}

View File

@ -0,0 +1,16 @@
package com.djrapitops.plan.api.exceptions.database;
public class DBNoDataException extends DBException {
public DBNoDataException(String message, Throwable cause) {
super(message, cause);
}
public DBNoDataException(Throwable cause) {
super(cause);
}
public DBNoDataException(String message) {
super(message);
}
}

View File

@ -0,0 +1,16 @@
package com.djrapitops.plan.api.exceptions.database;
public class FatalDBException extends DBException {
public FatalDBException(String message, Throwable cause) {
super(message, cause);
}
public FatalDBException(Throwable cause) {
super(cause);
}
public FatalDBException(String message) {
super(message);
}
}

View File

@ -1,43 +0,0 @@
package com.djrapitops.plan.command;
import com.djrapitops.plan.Plan;
import com.djrapitops.plan.PlanBungee;
import com.djrapitops.plugin.api.Check;
import com.djrapitops.plugin.utilities.Verify;
import java.util.UUID;
/**
* This class contains methods used by commands
*
* @author Rsl1122
* @since 3.5.0
*/
public class ConditionUtils {
/**
* Constructor used to hide the public constructor
*/
private ConditionUtils() {
throw new IllegalStateException("Utility class");
}
/**
* Condition if the player has played.
*
* @param uuid UUID of player
* @return has the player played before, false if uuid is null.
*/
public static boolean playerHasPlayed(UUID uuid) {
if ( Verify.containsNull(uuid)) {
return false;
}
boolean hasPlayed;
if (Check.isBukkitAvailable()) {
hasPlayed = Plan.getInstance().getServer().getOfflinePlayer(uuid).hasPlayedBefore();
} else {
hasPlayed = PlanBungee.getInstance().getDB().wasSeenBefore(uuid);
}
return hasPlayed;
}
}

View File

@ -2,9 +2,9 @@ package com.djrapitops.plan.command;
import com.djrapitops.plan.PlanBungee;
import com.djrapitops.plan.command.commands.*;
import com.djrapitops.plan.settings.Permissions;
import com.djrapitops.plan.settings.locale.Locale;
import com.djrapitops.plan.settings.locale.Msg;
import com.djrapitops.plan.system.settings.Permissions;
import com.djrapitops.plan.system.settings.locale.Locale;
import com.djrapitops.plan.system.settings.locale.Msg;
import com.djrapitops.plugin.command.CommandType;
import com.djrapitops.plugin.command.TreeCommand;
import com.djrapitops.plugin.command.defaultcmds.StatusCommand;
@ -43,13 +43,13 @@ public class PlanBungeeCommand extends TreeCommand<PlanBungee> {
new ReloadCommand(plugin),
new StatusCommand<>(plugin, Permissions.MANAGE.getPermission(), plugin.getColorScheme()),
new ListCommand(),
new BungeeSetupToggleCommand(plugin)
new BungeeSetupToggleCommand()
);
RegisterCommand registerCommand = new RegisterCommand(plugin);
RegisterCommand registerCommand = new RegisterCommand();
add(
registerCommand,
new WebUserCommand(plugin, registerCommand),
new NetworkCommand(plugin),
new NetworkCommand(),
new ListServersCommand(plugin)
);
}

View File

@ -2,16 +2,16 @@ package com.djrapitops.plan.command;
import com.djrapitops.plan.Plan;
import com.djrapitops.plan.command.commands.*;
import com.djrapitops.plan.settings.Permissions;
import com.djrapitops.plan.settings.Settings;
import com.djrapitops.plan.settings.locale.Locale;
import com.djrapitops.plan.settings.locale.Msg;
import com.djrapitops.plan.system.settings.Permissions;
import com.djrapitops.plan.system.settings.Settings;
import com.djrapitops.plan.system.settings.locale.Locale;
import com.djrapitops.plan.system.settings.locale.Msg;
import com.djrapitops.plugin.command.CommandType;
import com.djrapitops.plugin.command.TreeCommand;
import com.djrapitops.plugin.command.defaultcmds.StatusCommand;
/**
* TreeCommand for the /plan command, and all subcommands.
* TreeCommand for the /plan command, and all SubCommands.
* <p>
* Uses the Abstract Plugin Framework for easier command management.
*
@ -20,13 +20,6 @@ import com.djrapitops.plugin.command.defaultcmds.StatusCommand;
*/
public class PlanCommand extends TreeCommand<Plan> {
/**
* CommandExecutor class Constructor.
* <p>
* Initializes Subcommands
*
* @param plugin Current instance of Plan
*/
public PlanCommand(Plan plugin) {
super(plugin, "plan", CommandType.CONSOLE, "", "", "plan");
super.setDefaultCommand("inspect");
@ -41,25 +34,25 @@ public class PlanCommand extends TreeCommand<Plan> {
@Override
public void addCommands() {
add(
new InspectCommand(plugin),
new InspectCommand(),
new QInspectCommand(plugin),
new AnalyzeCommand(plugin),
new SearchCommand(plugin),
new AnalyzeCommand(),
new SearchCommand(),
new InfoCommand(plugin),
new ReloadCommand(plugin),
new ManageCommand(plugin),
new StatusCommand<>(plugin, Permissions.MANAGE.getPermission(), plugin.getColorScheme()),
new ListCommand()
);
RegisterCommand registerCommand = new RegisterCommand(plugin);
RegisterCommand registerCommand = new RegisterCommand();
add(
registerCommand,
new WebUserCommand(plugin, registerCommand),
new NetworkCommand(plugin),
new NetworkCommand(),
new ListServersCommand(plugin));
if (Settings.DEV_MODE.isTrue()) {
add(new DevCommand(plugin));
add(new DevCommand());
}
}
}

View File

@ -1,77 +1,43 @@
package com.djrapitops.plan.command.commands;
import com.djrapitops.plan.Plan;
import com.djrapitops.plan.settings.Permissions;
import com.djrapitops.plan.settings.locale.Locale;
import com.djrapitops.plan.settings.locale.Msg;
import com.djrapitops.plan.systems.info.InformationManager;
import com.djrapitops.plan.systems.info.server.ServerInfo;
import com.djrapitops.plan.api.exceptions.connection.WebException;
import com.djrapitops.plan.api.exceptions.database.DBException;
import com.djrapitops.plan.system.database.databases.Database;
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.info.server.ServerInfo;
import com.djrapitops.plan.system.processing.Processor;
import com.djrapitops.plan.system.settings.Permissions;
import com.djrapitops.plan.system.settings.locale.Locale;
import com.djrapitops.plan.system.settings.locale.Msg;
import com.djrapitops.plan.system.webserver.WebServerSystem;
import com.djrapitops.plan.utilities.analysis.Analysis;
import com.djrapitops.plugin.api.utility.log.Log;
import com.djrapitops.plugin.command.CommandType;
import com.djrapitops.plugin.command.CommandUtils;
import com.djrapitops.plugin.command.ISender;
import com.djrapitops.plugin.command.SubCommand;
import com.djrapitops.plugin.task.AbsRunnable;
import com.djrapitops.plugin.task.RunnableFactory;
import com.djrapitops.plugin.utilities.Verify;
import org.bukkit.ChatColor;
import java.sql.SQLException;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.UUID;
/**
* This subcommand is used to run the analysis and access the /server link.
* This SubCommand is used to run the analysis and access the /server link.
*
* @author Rsl1122
* @since 2.0.0
*/
public class AnalyzeCommand extends SubCommand {
private final Plan plugin;
private final InformationManager infoManager;
/**
* Subcommand Constructor.
*
* @param plugin Current instance of Plan
*/
public AnalyzeCommand(Plan plugin) {
public AnalyzeCommand() {
super("analyze, analyse, analysis, a",
CommandType.CONSOLE,
Permissions.ANALYZE.getPermission(),
Locale.get(Msg.CMD_USG_ANALYZE).parse(),
"[ServerName or ID]");
this.plugin = plugin;
infoManager = plugin.getInfoManager();
}
public static void sendAnalysisMessage(Collection<ISender> senders, UUID serverUUID) throws SQLException {
if (Verify.isEmpty(senders)) {
return;
}
Plan plugin = Plan.getInstance();
Optional<String> serverName = plugin.getDB().getServerTable().getServerName(serverUUID);
serverName.ifPresent(name -> {
String target = "/server/" + name;
String url = plugin.getInfoManager().getLinkTo(target);
String message = Locale.get(Msg.CMD_INFO_LINK).toString();
for (ISender sender : senders) {
sender.sendMessage(Locale.get(Msg.CMD_HEADER_ANALYZE).toString());
// Link
boolean console = !CommandUtils.isPlayer(sender);
if (console) {
sender.sendMessage(message + url);
} else {
sender.sendMessage(message);
sender.sendLink(" ", Locale.get(Msg.CMD_INFO_CLICK_ME).toString(), url);
}
sender.sendMessage(Locale.get(Msg.CMD_CONSTANT_FOOTER).toString());
}
});
}
@Override
@ -81,57 +47,75 @@ public class AnalyzeCommand extends SubCommand {
@Override
public boolean onCommand(ISender sender, String commandLabel, String[] args) {
// TODO Write a command for listing servers.
UUID serverUUID = Plan.getServerUUID();
if (args.length >= 1 && plugin.getInfoManager().isUsingAnotherWebServer()) {
try {
List<ServerInfo> bukkitServers = plugin.getDB().getServerTable().getBukkitServers();
Optional<ServerInfo> server = bukkitServers.stream().filter(info -> {
StringBuilder idBuilder = new StringBuilder(args[0]);
if (args.length > 1) {
for (int i = 1; i < args.length; i++) {
idBuilder.append(" ").append(args[i]);
}
}
String serverIdentifier = idBuilder.toString();
return Integer.toString(info.getId()).equals(serverIdentifier) || info.getName().equalsIgnoreCase(serverIdentifier);
}).findFirst();
if (server.isPresent()) {
serverUUID = server.get().getUuid();
}
} catch (SQLException e) {
Log.toLog(this.getClass().getName(), e);
return true;
}
}
updateCache(sender, serverUUID);
sender.sendMessage(Locale.get(Msg.CMD_INFO_FETCH_DATA).toString());
if (plugin.getInfoManager().isAuthRequired() && CommandUtils.isPlayer(sender)) {
RunnableFactory.createNew(new AbsRunnable("WebUser exist check task") {
@Override
public void run() {
try {
boolean senderHasWebUser = plugin.getDB().getSecurityTable().userExists(sender.getName());
if (!senderHasWebUser) {
sender.sendMessage(ChatColor.YELLOW + "[Plan] You might not have a web user, use /plan register <password>");
}
} catch (Exception e) {
Log.toLog(this.getClass().getName() + getName(), e);
} finally {
this.cancel();
}
Processor.queue(() -> {
try {
Server server = getServer(args).orElseGet(ServerInfo::getServer);
UUID serverUUID = server.getUuid();
if (!ServerInfo.getServerUUID().equals(serverUUID) || !Analysis.isAnalysisBeingRun()) {
InfoSystem.getInstance().generateAnalysisPage(serverUUID);
}
}).runTaskAsynchronously();
}
sendWebUserNotificationIfNecessary(sender);
sendLink(server, sender);
} catch (DBException | WebException e) {
// TODO Exception handling
sender.sendMessage(ChatColor.RED + " Error occurred: " + e.toString());
Log.toLog(this.getClass(), e);
}
});
return true;
}
private void updateCache(ISender sender, UUID serverUUID) {
infoManager.addAnalysisNotification(sender, serverUUID);
infoManager.refreshAnalysis(serverUUID);
private void sendLink(Server server, ISender sender) {
String target = "/server/" + server.getName();
String url = ConnectionSystem.getAddress() + target;
String message = Locale.get(Msg.CMD_INFO_LINK).toString();
sender.sendMessage(Locale.get(Msg.CMD_HEADER_ANALYZE).toString());
// Link
boolean console = !CommandUtils.isPlayer(sender);
if (console) {
sender.sendMessage(message + url);
} else {
sender.sendMessage(message);
sender.sendLink(" ", Locale.get(Msg.CMD_INFO_CLICK_ME).toString(), url);
}
sender.sendMessage(Locale.get(Msg.CMD_CONSTANT_FOOTER).toString());
}
private void sendWebUserNotificationIfNecessary(ISender sender) throws DBException {
if (WebServerSystem.getInstance().getWebServer().isAuthRequired() && CommandUtils.isPlayer(sender)) {
boolean senderHasWebUser = Database.getActive().check().doesWebUserExists(sender.getName());
if (!senderHasWebUser) {
sender.sendMessage(ChatColor.YELLOW + "[Plan] You might not have a web user, use /plan register <password>");
}
}
}
private Optional<Server> getServer(String[] args) throws DBException {
if (args.length >= 1 && ConnectionSystem.getInstance().isServerAvailable()) {
Map<UUID, Server> bukkitServers = Database.getActive().fetch().getBukkitServers();
String serverIdentifier = getGivenIdentifier(args);
for (Map.Entry<UUID, Server> entry : bukkitServers.entrySet()) {
Server server = entry.getValue();
if (Integer.toString(server.getId()).equals(serverIdentifier)
|| server.getName().equalsIgnoreCase(serverIdentifier)) {
return Optional.of(server);
}
}
}
return Optional.empty();
}
private String getGivenIdentifier(String[] args) {
StringBuilder idBuilder = new StringBuilder(args[0]);
if (args.length > 1) {
for (int i = 1; i < args.length; i++) {
idBuilder.append(" ").append(args[i]);
}
}
return idBuilder.toString();
}
}

View File

@ -4,33 +4,34 @@
*/
package com.djrapitops.plan.command.commands;
import com.djrapitops.plan.PlanBungee;
import com.djrapitops.plan.settings.Permissions;
import com.djrapitops.plan.system.info.connection.ConnectionSystem;
import com.djrapitops.plan.system.settings.Permissions;
import com.djrapitops.plugin.command.CommandType;
import com.djrapitops.plugin.command.ISender;
import com.djrapitops.plugin.command.SubCommand;
/**
* //TODO Class Javadoc Comment
* Command for Toggling whether or not BungeeCord accepts set up requests.
*
* This was added as a security measure against unwanted MySQL snooping.
*
* @author Rsl1122
*/
public class BungeeSetupToggleCommand extends SubCommand {
private final PlanBungee plugin;
public BungeeSetupToggleCommand(PlanBungee plugin) {
public BungeeSetupToggleCommand() {
super("setup", CommandType.ALL, Permissions.MANAGE.getPermission(), "Toggle Setup mode for Bungee");
this.plugin = plugin;
}
@Override
public boolean onCommand(ISender sender, String s, String[] strings) {
boolean setupAllowed = plugin.isSetupAllowed();
boolean setupAllowed = ConnectionSystem.isSetupAllowed();
ConnectionSystem connectionSystem = ConnectionSystem.getInstance();
if (setupAllowed) {
plugin.setSetupAllowed(false);
connectionSystem.setSetupAllowed(false);
} else {
plugin.setSetupAllowed(true);
connectionSystem.setSetupAllowed(true);
}
String msg = !setupAllowed ? "§aSet-up is now Allowed" : "§cSet-up is now Forbidden";
sender.sendMessage(msg);

View File

@ -1,23 +1,17 @@
/*
/*
* 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.plan.command.commands;
import com.djrapitops.plan.Plan;
import com.djrapitops.plan.api.exceptions.WebAPIException;
import com.djrapitops.plan.settings.locale.Locale;
import com.djrapitops.plan.settings.locale.Msg;
import com.djrapitops.plan.systems.webserver.webapi.WebAPI;
import com.djrapitops.plan.systems.webserver.webapi.bukkit.InspectWebAPI;
import com.djrapitops.plan.system.info.connection.ConnectionSystem;
import com.djrapitops.plan.system.settings.locale.Locale;
import com.djrapitops.plan.system.settings.locale.Msg;
import com.djrapitops.plan.utilities.Condition;
import com.djrapitops.plugin.command.CommandType;
import com.djrapitops.plugin.command.ISender;
import com.djrapitops.plugin.command.SubCommand;
import java.util.Optional;
import java.util.UUID;
/**
* Command used for testing functions that are too difficult to unit test.
*
@ -25,11 +19,8 @@ import java.util.UUID;
*/
public class DevCommand extends SubCommand {
private final Plan plugin;
public DevCommand(Plan plugin) {
public DevCommand() {
super("dev", CommandType.PLAYER_OR_ARGS, "plan.*", "Test Plugin functions not testable with unit tests.", "<feature to test>");
this.plugin = plugin;
}
@Override
@ -39,48 +30,21 @@ public class DevCommand extends SubCommand {
}
String feature = args[0];
switch (feature) {
case "webapi":
case "connection":
if (!Condition.isTrue(args.length >= 2, Locale.get(Msg.CMD_FAIL_REQ_ONE_ARG).toString(), sender)) {
break;
}
if (!webapi(args[1] + "webapi", args.length >= 3)) {
sender.sendMessage("[Plan] No such API / Exception occurred.");
}
sender.sendMessage("[Plan] No implementation.");
break;
case "web":
Optional<String> bungeeConnectionAddress = plugin.getServerInfoManager().getBungeeConnectionAddress();
String accessAddress = plugin.getWebServer().getAccessAddress();
sender.sendMessage((plugin.getInfoManager().isUsingAnotherWebServer() && bungeeConnectionAddress.isPresent())
? "Bungee: " + bungeeConnectionAddress.get() : "Local: " + accessAddress);
ConnectionSystem connectionSystem = ConnectionSystem.getInstance();
String accessAddress = connectionSystem.getMainAddress();
sender.sendMessage((connectionSystem.isServerAvailable())
? "Bungee: " + accessAddress : "Local: " + accessAddress);
break;
default:
break;
}
return true;
}
private boolean webapi(String method, boolean connectToBungee) {
WebAPI api = plugin.getWebServer().getWebAPI().getAPI(method);
if (api == null) {
return false;
}
try {
String address = plugin.getWebServer().getAccessAddress();
if (connectToBungee) {
Optional<String> bungeeConnectionAddress = plugin.getServerInfoManager().getBungeeConnectionAddress();
if (bungeeConnectionAddress.isPresent()) {
address = bungeeConnectionAddress.get();
}
}
if (api instanceof InspectWebAPI) {
((InspectWebAPI) api).sendRequest(address, UUID.randomUUID());
} else {
api.sendRequest(address);
}
return true;
} catch (WebAPIException e) {
e.printStackTrace();
}
return false;
}
}

View File

@ -1,16 +1,18 @@
package com.djrapitops.plan.command.commands;
import com.djrapitops.plan.Plan;
import com.djrapitops.plan.settings.Permissions;
import com.djrapitops.plan.settings.locale.Locale;
import com.djrapitops.plan.settings.locale.Msg;
import com.djrapitops.plan.system.database.databases.Database;
import com.djrapitops.plan.system.settings.Permissions;
import com.djrapitops.plan.system.settings.locale.Locale;
import com.djrapitops.plan.system.settings.locale.Msg;
import com.djrapitops.plan.system.update.VersionCheckSystem;
import com.djrapitops.plugin.command.CommandType;
import com.djrapitops.plugin.command.ISender;
import com.djrapitops.plugin.command.SubCommand;
import com.djrapitops.plugin.settings.ColorScheme;
/**
* This subcommand is used to view the version and the database type in use.
* This SubCommand is used to view the version and the database type in use.
*
* @author Rsl1122
* @since 2.0.0
@ -19,11 +21,6 @@ public class InfoCommand extends SubCommand {
private final Plan plugin;
/**
* Subcommand Constructor.
*
* @param plugin Current instance of Plan
*/
public InfoCommand(Plan plugin) {
super("info",
CommandType.CONSOLE,
@ -40,10 +37,13 @@ public class InfoCommand extends SubCommand {
String sColor = cs.getSecondaryColor();
String tColor = cs.getTertiaryColor();
String ball = Locale.get(Msg.CMD_CONSTANT_LIST_BALL).toString();
String upToDate = VersionCheckSystem.isNewVersionAvailable() ? "Update Available" : "Up to date";
String[] messages = {
Locale.get(Msg.CMD_HEADER_INFO).toString(),
ball + mColor + " Version: " + sColor + plugin.getDescription().getVersion(),
ball + mColor + " Active Database: " + tColor + plugin.getDB().getConfigName(),
ball + mColor + " Up to date: " + sColor + upToDate,
ball + mColor + " Active Database: " + tColor + Database.getActive().getConfigName(),
Locale.get(Msg.CMD_CONSTANT_FOOTER).toString()
};
sender.sendMessage(messages);

View File

@ -1,11 +1,13 @@
package com.djrapitops.plan.command.commands;
import com.djrapitops.plan.Plan;
import com.djrapitops.plan.command.ConditionUtils;
import com.djrapitops.plan.settings.Permissions;
import com.djrapitops.plan.settings.locale.Locale;
import com.djrapitops.plan.settings.locale.Msg;
import com.djrapitops.plan.systems.processing.info.InspectCacheRequestProcessor;
import com.djrapitops.plan.api.exceptions.database.DBException;
import com.djrapitops.plan.api.exceptions.database.FatalDBException;
import com.djrapitops.plan.system.database.databases.Database;
import com.djrapitops.plan.system.processing.processors.info.InspectCacheRequestProcessor;
import com.djrapitops.plan.system.settings.Permissions;
import com.djrapitops.plan.system.settings.locale.Locale;
import com.djrapitops.plan.system.settings.locale.Msg;
import com.djrapitops.plan.system.webserver.WebServer;
import com.djrapitops.plan.utilities.Condition;
import com.djrapitops.plan.utilities.MiscUtils;
import com.djrapitops.plan.utilities.uuid.UUIDUtility;
@ -19,33 +21,22 @@ import com.djrapitops.plugin.task.RunnableFactory;
import com.djrapitops.plugin.utilities.Verify;
import org.bukkit.ChatColor;
import java.sql.SQLException;
import java.util.UUID;
/**
* This command is used to cache UserInfo to InspectCache and display the link.
* This command is used to refresh Inspect page and display link.
*
* @author Rsl1122
* @since 1.0.0
*/
public class InspectCommand extends SubCommand {
private final Plan plugin;
/**
* Class Constructor.
*
* @param plugin Current instance of Plan
*/
public InspectCommand(Plan plugin) {
public InspectCommand() {
super("inspect",
CommandType.PLAYER_OR_ARGS,
Permissions.INSPECT.getPermission(),
Locale.get(Msg.CMD_USG_INSPECT).toString(),
"<player>");
this.plugin = plugin;
}
@Override
@ -66,26 +57,28 @@ public class InspectCommand extends SubCommand {
@Override
public void run() {
try {
Database activeDB = Database.getActive();
UUID uuid = UUIDUtility.getUUIDOf(playerName);
if (!Condition.isTrue(Verify.notNull(uuid), Locale.get(Msg.CMD_FAIL_USERNAME_NOT_VALID).toString(), sender)) {
return;
}
if (!Condition.isTrue(ConditionUtils.playerHasPlayed(uuid), Locale.get(Msg.CMD_FAIL_USERNAME_NOT_SEEN).toString(), sender)) {
if (!Condition.isTrue(activeDB.check().isPlayerRegistered(uuid), Locale.get(Msg.CMD_FAIL_USERNAME_NOT_KNOWN).toString(), sender)) {
return;
}
if (!Condition.isTrue(plugin.getDB().wasSeenBefore(uuid), Locale.get(Msg.CMD_FAIL_USERNAME_NOT_KNOWN).toString(), sender)) {
return;
}
if (CommandUtils.isPlayer(sender) && plugin.getWebServer().isAuthRequired()) {
boolean senderHasWebUser = plugin.getDB().getSecurityTable().userExists(sender.getName());
if (CommandUtils.isPlayer(sender) && WebServer.getInstance().isAuthRequired()) {
boolean senderHasWebUser = activeDB.check().doesWebUserExists(sender.getName());
if (!senderHasWebUser) {
sender.sendMessage(ChatColor.YELLOW + "[Plan] You might not have a web user, use /plan register <password>");
}
}
plugin.addToProcessQueue(new InspectCacheRequestProcessor(uuid, sender, playerName));
} catch (SQLException ex) {
Log.toLog(this.getClass().getName(), ex);
new InspectCacheRequestProcessor(uuid, sender, playerName).queue();
} catch (FatalDBException ex) {
Log.toLog(this.getClass(), ex);
sender.sendMessage(ChatColor.RED + "Fatal database exception occurred: " + ex.getMessage());
} catch (DBException ex) {
Log.toLog(this.getClass(), ex);
sender.sendMessage(ChatColor.YELLOW + "Non-Fatal database exception occurred: " + ex.getMessage());
} finally {
this.cancel();
}

View File

@ -1,30 +1,24 @@
package com.djrapitops.plan.command.commands;
import com.djrapitops.plan.settings.Permissions;
import com.djrapitops.plan.settings.locale.Locale;
import com.djrapitops.plan.settings.locale.Msg;
import com.djrapitops.plan.utilities.MiscUtils;
import com.djrapitops.plan.system.info.connection.ConnectionSystem;
import com.djrapitops.plan.system.settings.Permissions;
import com.djrapitops.plan.system.settings.locale.Locale;
import com.djrapitops.plan.system.settings.locale.Msg;
import com.djrapitops.plugin.command.CommandType;
import com.djrapitops.plugin.command.CommandUtils;
import com.djrapitops.plugin.command.ISender;
import com.djrapitops.plugin.command.SubCommand;
/**
* Command used to display link to the player list webpage.
* <p>
* Subcommand is not registered if Webserver is not enabled.
* Command used to display url to the player list page.
*
* @author Rsl1122
* @since 3.5.2
*/
public class ListCommand extends SubCommand {
/**
* Class Constructor.
*/
public ListCommand() {
super("list, pl", CommandType.CONSOLE, Permissions.INSPECT_OTHER.getPermission(), Locale.get(Msg.CMD_USG_LIST).toString(), "");
super("list, pl, playerlist, players", CommandType.CONSOLE, Permissions.INSPECT_OTHER.getPermission(), Locale.get(Msg.CMD_USG_LIST).toString(), "");
}
@Override
@ -43,7 +37,7 @@ public class ListCommand extends SubCommand {
sender.sendMessage(Locale.get(Msg.CMD_CONSTANT_FOOTER).parse());
// Link
String url = MiscUtils.getIPlan().getInfoManager().getLinkTo("/players/");
String url = ConnectionSystem.getAddress() + "/players/";
String message = Locale.get(Msg.CMD_INFO_LINK).toString();
boolean console = !CommandUtils.isPlayer(sender);
if (console) {

View File

@ -1,34 +1,30 @@
package com.djrapitops.plan.command.commands;
import com.djrapitops.plan.api.IPlan;
import com.djrapitops.plan.settings.Permissions;
import com.djrapitops.plan.settings.locale.Locale;
import com.djrapitops.plan.settings.locale.Msg;
import com.djrapitops.plan.PlanPlugin;
import com.djrapitops.plan.api.exceptions.database.DBException;
import com.djrapitops.plan.system.database.databases.Database;
import com.djrapitops.plan.system.info.server.Server;
import com.djrapitops.plan.system.settings.Permissions;
import com.djrapitops.plan.system.settings.locale.Locale;
import com.djrapitops.plan.system.settings.locale.Msg;
import com.djrapitops.plugin.api.utility.log.Log;
import com.djrapitops.plugin.command.CommandType;
import com.djrapitops.plugin.command.ISender;
import com.djrapitops.plugin.command.SubCommand;
import com.djrapitops.plugin.settings.ColorScheme;
import java.sql.SQLException;
import java.util.Map;
import java.util.List;
/**
* This subcommand is used to reload the plugin.
* This SubCommand is used to list all servers found in the database.
*
* @author Rsl1122
* @since 2.0.0
*/
public class ListServersCommand extends SubCommand {
private final IPlan plugin;
private final PlanPlugin plugin;
/**
* Subcommand constructor.
*
* @param plugin Current instance of Plan
*/
public ListServersCommand(IPlan plugin) {
public ListServersCommand(PlanPlugin plugin) {
super("servers, serverlist, listservers, sl",
CommandType.CONSOLE,
Permissions.MANAGE.getPermission(),
@ -45,14 +41,14 @@ public class ListServersCommand extends SubCommand {
String tCol = colorScheme.getTertiaryColor();
try {
sender.sendMessage(Locale.get(Msg.CMD_CONSTANT_FOOTER).toString() + mCol + " Servers");
Map<Integer, String> serverNames = plugin.getDB().getServerTable().getServerNamesByID();
for (Map.Entry<Integer, String> entry : serverNames.entrySet()) {
sender.sendMessage(" " + tCol + entry.getKey() + sCol + " : " + entry.getValue());
List<Server> servers = Database.getActive().fetch().getServers();
for (Server server : servers) {
sender.sendMessage(" " + tCol + server.getId() + sCol + " : " + server.getName() + " : " + server.getWebAddress());
}
sender.sendMessage(Locale.get(Msg.CMD_CONSTANT_FOOTER).toString());
} catch (SQLException e) {
sender.sendMessage("§cSQLException occurred.");
Log.toLog(this.getClass().getName(), e);
} catch (DBException e) {
sender.sendMessage("§cDatabase Exception occurred.");
Log.toLog(this.getClass(), e);
}
return true;
}

View File

@ -2,27 +2,20 @@ package com.djrapitops.plan.command.commands;
import com.djrapitops.plan.Plan;
import com.djrapitops.plan.command.commands.manage.*;
import com.djrapitops.plan.settings.Permissions;
import com.djrapitops.plan.settings.locale.Locale;
import com.djrapitops.plan.settings.locale.Msg;
import com.djrapitops.plan.system.settings.Permissions;
import com.djrapitops.plan.system.settings.locale.Locale;
import com.djrapitops.plan.system.settings.locale.Msg;
import com.djrapitops.plugin.command.CommandType;
import com.djrapitops.plugin.command.TreeCommand;
/**
* This command is used to manage the database of the plugin.
* <p>
* No arguments will run ManageHelpCommand. Contains subcommands.
* This SubCommand is used to manage the the plugin's database and components.
*
* @author Rsl1122
* @since 2.3.0
*/
public class ManageCommand extends TreeCommand<Plan> {
/**
* Subcommand Constructor.
*
* @param plugin Current instance of Plan
*/
public ManageCommand(Plan plugin) {
super(plugin, "manage,m", CommandType.CONSOLE, Permissions.MANAGE.getPermission(), Locale.get(Msg.CMD_USG_MANAGE).toString(), "plan m");
super.setColorScheme(plugin.getColorScheme());
@ -36,14 +29,14 @@ public class ManageCommand extends TreeCommand<Plan> {
@Override
public void addCommands() {
add(
new ManageMoveCommand(plugin),
new ManageMoveCommand(),
new ManageHotswapCommand(plugin),
new ManageBackupCommand(plugin),
new ManageBackupCommand(),
new ManageRestoreCommand(plugin),
new ManageImportCommand(plugin),
new ManageRemoveCommand(plugin),
new ManageImportCommand(),
new ManageRemoveCommand(),
new ManageClearCommand(plugin),
new ManageSetupCommand(plugin),
new ManageSetupCommand(),
new ManageDisableCommand()
);
}

View File

@ -1,35 +1,26 @@
package com.djrapitops.plan.command.commands;
import com.djrapitops.plan.api.IPlan;
import com.djrapitops.plan.settings.Permissions;
import com.djrapitops.plan.settings.locale.Locale;
import com.djrapitops.plan.settings.locale.Msg;
import com.djrapitops.plan.system.info.connection.ConnectionSystem;
import com.djrapitops.plan.system.settings.Permissions;
import com.djrapitops.plan.system.settings.locale.Locale;
import com.djrapitops.plan.system.settings.locale.Msg;
import com.djrapitops.plugin.command.CommandType;
import com.djrapitops.plugin.command.CommandUtils;
import com.djrapitops.plugin.command.ISender;
import com.djrapitops.plugin.command.SubCommand;
/**
* Command used to display link to the player list webpage.
* <p>
* Subcommand is not registered if Webserver is not enabled.
* Command used to display url to the network page.
*
* @author Rsl1122
* @since 3.5.2
*/
public class NetworkCommand extends SubCommand {
private final IPlan plugin;
/**
* Class Constructor.
*/
public NetworkCommand(IPlan plugin) {
public NetworkCommand() {
super("network, n, netw",
CommandType.CONSOLE,
Permissions.ANALYZE.getPermission(),
"Get the link to the network page");
this.plugin = plugin;
}
@Override
@ -42,7 +33,7 @@ public class NetworkCommand extends SubCommand {
sender.sendMessage(Locale.get(Msg.CMD_CONSTANT_FOOTER).parse());
// Link
String url = plugin.getInfoManager().getLinkTo("/network/");
String url = ConnectionSystem.getAddress() + "/network/";
String message = Locale.get(Msg.CMD_INFO_LINK).toString();
boolean console = !CommandUtils.isPlayer(sender);
if (console) {

View File

@ -1,10 +1,13 @@
package com.djrapitops.plan.command.commands;
import com.djrapitops.plan.api.IPlan;
import com.djrapitops.plan.PlanPlugin;
import com.djrapitops.plan.api.exceptions.database.DBException;
import com.djrapitops.plan.data.PlayerProfile;
import com.djrapitops.plan.settings.Permissions;
import com.djrapitops.plan.settings.locale.Locale;
import com.djrapitops.plan.settings.locale.Msg;
import com.djrapitops.plan.data.calculation.ActivityIndex;
import com.djrapitops.plan.system.database.databases.Database;
import com.djrapitops.plan.system.settings.Permissions;
import com.djrapitops.plan.system.settings.locale.Locale;
import com.djrapitops.plan.system.settings.locale.Msg;
import com.djrapitops.plan.utilities.Condition;
import com.djrapitops.plan.utilities.FormatUtils;
import com.djrapitops.plan.utilities.MiscUtils;
@ -19,7 +22,6 @@ import com.djrapitops.plugin.task.AbsRunnable;
import com.djrapitops.plugin.task.RunnableFactory;
import com.djrapitops.plugin.utilities.Verify;
import java.sql.SQLException;
import java.util.UUID;
/**
@ -30,14 +32,14 @@ import java.util.UUID;
*/
public class QInspectCommand extends SubCommand {
private final IPlan plugin;
private final PlanPlugin plugin;
/**
* Class Constructor.
*
* @param plugin Current instance of Plan
*/
public QInspectCommand(IPlan plugin) {
public QInspectCommand(PlanPlugin plugin) {
super("qinspect",
CommandType.PLAYER_OR_ARGS,
Permissions.QUICK_INSPECT.getPermission(),
@ -70,16 +72,17 @@ public class QInspectCommand extends SubCommand {
if (!Condition.isTrue(Verify.notNull(uuid), Locale.get(Msg.CMD_FAIL_USERNAME_NOT_VALID).toString(), sender)) {
return;
}
if (!Condition.isTrue(plugin.getDB().wasSeenBefore(uuid), Locale.get(Msg.CMD_FAIL_USERNAME_NOT_KNOWN).toString(), sender)) {
Database database = Database.getActive();
if (!Condition.isTrue(database.check().isPlayerRegistered(uuid), Locale.get(Msg.CMD_FAIL_USERNAME_NOT_KNOWN).toString(), sender)) {
return;
}
PlayerProfile playerProfile = plugin.getDB().getPlayerProfile(uuid);
PlayerProfile playerProfile = database.fetch().getPlayerProfile(uuid);
sendMsgs(sender, playerProfile);
} catch (SQLException ex) {
Log.toLog(this.getClass().getName(), ex);
} catch (DBException ex) {
Log.toLog(this.getClass(), ex);
} finally {
this.cancel();
}
@ -100,9 +103,9 @@ public class QInspectCommand extends SubCommand {
sender.sendMessage(Locale.get(Msg.CMD_HEADER_INSPECT).toString() + ": " + colT + profile.getName());
double activityIndex = profile.getActivityIndex(now);
ActivityIndex activityIndex = profile.getActivityIndex(now);
sender.sendMessage(colT + ball + " " + colM + " Activity Index: " + colS + FormatUtils.cutDecimals(activityIndex) + " | " + FormatUtils.readableActivityIndex(activityIndex)[1]);
sender.sendMessage(colT + ball + " " + colM + " Activity Index: " + colS + activityIndex.getFormattedValue() + " | " + activityIndex.getColor());
sender.sendMessage(colT + ball + " " + colM + " Registered: " + colS + FormatUtils.formatTimeStampYear(profile.getRegistered()));
sender.sendMessage(colT + ball + " " + colM + " Last Seen: " + colS + FormatUtils.formatTimeStampYear(profile.getLastSeen()));
sender.sendMessage(colT + ball + " " + colM + " Logged in from: " + colS + profile.getMostRecentGeoInfo().getGeolocation());

View File

@ -1,11 +1,10 @@
package com.djrapitops.plan.command.commands;
import com.djrapitops.plan.api.IPlan;
import com.djrapitops.plan.data.WebUser;
import com.djrapitops.plan.database.tables.SecurityTable;
import com.djrapitops.plan.settings.Permissions;
import com.djrapitops.plan.settings.locale.Locale;
import com.djrapitops.plan.settings.locale.Msg;
import com.djrapitops.plan.system.database.databases.Database;
import com.djrapitops.plan.system.settings.Permissions;
import com.djrapitops.plan.system.settings.locale.Locale;
import com.djrapitops.plan.system.settings.locale.Msg;
import com.djrapitops.plan.utilities.Condition;
import com.djrapitops.plan.utilities.PassEncryptUtil;
import com.djrapitops.plugin.api.Check;
@ -20,26 +19,22 @@ import com.djrapitops.plugin.task.RunnableFactory;
/**
* Command for registering web users.
* <p>
* Registers a new webuser to the database.
* Registers a new WebUser to the database.
* <p>
* No permission required for self registration. (Constructor string is empty)
* <p>
* plan.webmanage required for registering other users.
* No permission required for self registration. (Super constructor string is empty).
* {@code Permissions.MANAGE_WEB} required for registering other users.
*
* @author Rsl1122
* @since 3.5.2
*/
public class RegisterCommand extends SubCommand {
private final IPlan plugin;
public RegisterCommand(IPlan plugin) {
public RegisterCommand() {
super("register",
CommandType.PLAYER_OR_ARGS,
"", // No Permission Requirement
Locale.get(Msg.CMD_USG_WEB_REGISTER).toString(),
"<password> [name] [access lvl]");
this.plugin = plugin;
if (Check.isBukkitAvailable()) {
setupFilter();
}
@ -121,16 +116,16 @@ public class RegisterCommand extends SubCommand {
final String userName = webUser.getName();
final String successMsg = "§aAdded a new user (" + userName + ") successfully!";
try {
SecurityTable securityTable = plugin.getDB().getSecurityTable();
boolean userExists = securityTable.userExists(userName);
Database database = Database.getActive();
boolean userExists = database.check().doesWebUserExists(userName);
if (!Condition.isTrue(!userExists, existsMsg, sender)) {
return;
}
securityTable.addNewUser(webUser);
database.save().webUser(webUser);
sender.sendMessage(successMsg);
Log.info("Registered new user: " + userName + " Perm level: " + webUser.getPermLevel());
} catch (Exception e) {
Log.toLog(this.getClass().getName(), e);
Log.toLog(this.getClass(), e);
} finally {
this.cancel();
}

View File

@ -1,30 +1,25 @@
package com.djrapitops.plan.command.commands;
import com.djrapitops.plan.api.IPlan;
import com.djrapitops.plan.settings.Permissions;
import com.djrapitops.plan.settings.locale.Locale;
import com.djrapitops.plan.settings.locale.Msg;
import com.djrapitops.plan.PlanPlugin;
import com.djrapitops.plan.system.settings.Permissions;
import com.djrapitops.plan.system.settings.locale.Locale;
import com.djrapitops.plan.system.settings.locale.Msg;
import com.djrapitops.plugin.api.utility.log.Log;
import com.djrapitops.plugin.command.CommandType;
import com.djrapitops.plugin.command.ISender;
import com.djrapitops.plugin.command.SubCommand;
/**
* This subcommand is used to reload the plugin.
* This SubCommand is used to reload the plugin.
*
* @author Rsl1122
* @since 2.0.0
*/
public class ReloadCommand extends SubCommand {
private final IPlan plugin;
private final PlanPlugin plugin;
/**
* Subcommand constructor.
*
* @param plugin Current instance of Plan
*/
public ReloadCommand(IPlan plugin) {
public ReloadCommand(PlanPlugin plugin) {
super("reload",
CommandType.CONSOLE,
Permissions.MANAGE.getPermission(),
@ -38,7 +33,7 @@ public class ReloadCommand extends SubCommand {
try {
plugin.reloadPlugin(true);
} catch (Exception e) {
Log.toLog(this.getClass().getName(), e);
Log.toLog(this.getClass(), e);
sender.sendMessage("§cSomething went wrong during reload of the plugin, a restart is recommended.");
}
sender.sendMessage(Locale.get(Msg.CMD_INFO_RELOAD_COMPLETE).toString());

View File

@ -1,9 +1,8 @@
package com.djrapitops.plan.command.commands;
import com.djrapitops.plan.Plan;
import com.djrapitops.plan.settings.Permissions;
import com.djrapitops.plan.settings.locale.Locale;
import com.djrapitops.plan.settings.locale.Msg;
import com.djrapitops.plan.system.settings.Permissions;
import com.djrapitops.plan.system.settings.locale.Locale;
import com.djrapitops.plan.system.settings.locale.Msg;
import com.djrapitops.plan.utilities.Condition;
import com.djrapitops.plan.utilities.MiscUtils;
import com.djrapitops.plugin.command.CommandType;
@ -18,19 +17,14 @@ import java.util.Arrays;
import java.util.List;
/**
* This subcommand is used to search for a user, and to view all matches' data.
* This SubCommand is used to search for a user.
*
* @author Rsl1122
* @since 2.0.0
*/
public class SearchCommand extends SubCommand {
/**
* Class Constructor.
*
* @param plugin Current instance of Plan
*/
public SearchCommand(Plan plugin) {
public SearchCommand() {
super("search",
CommandType.PLAYER_OR_ARGS,
Permissions.SEARCH.getPermission(),

View File

@ -2,14 +2,14 @@ package com.djrapitops.plan.command.commands;
import com.djrapitops.plan.Plan;
import com.djrapitops.plan.PlanBungee;
import com.djrapitops.plan.api.IPlan;
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;
import com.djrapitops.plan.command.commands.webuser.WebListUsersCommand;
import com.djrapitops.plan.settings.Permissions;
import com.djrapitops.plan.settings.locale.Locale;
import com.djrapitops.plan.settings.locale.Msg;
import com.djrapitops.plan.system.settings.Permissions;
import com.djrapitops.plan.system.settings.locale.Locale;
import com.djrapitops.plan.system.settings.locale.Msg;
import com.djrapitops.plugin.command.CommandType;
import com.djrapitops.plugin.command.TreeCommand;
@ -19,7 +19,7 @@ import com.djrapitops.plugin.command.TreeCommand;
* @author Rsl1122
* @since 3.5.2
*/
public class WebUserCommand extends TreeCommand<IPlan> {
public class WebUserCommand extends TreeCommand<PlanPlugin> {
public WebUserCommand(Plan plugin, RegisterCommand register) {
super(plugin, "webuser, web",
@ -50,8 +50,8 @@ public class WebUserCommand extends TreeCommand<IPlan> {
add(
new WebLevelCommand(plugin),
new WebListUsersCommand(plugin),
new WebCheckCommand(plugin),
new WebDeleteCommand(plugin)
new WebCheckCommand(),
new WebDeleteCommand()
);
}
}

View File

@ -1,11 +1,11 @@
package com.djrapitops.plan.command.commands.manage;
import com.djrapitops.plan.Plan;
import com.djrapitops.plan.api.exceptions.DatabaseInitException;
import com.djrapitops.plan.database.Database;
import com.djrapitops.plan.settings.Permissions;
import com.djrapitops.plan.settings.locale.Locale;
import com.djrapitops.plan.settings.locale.Msg;
import com.djrapitops.plan.api.exceptions.database.DBInitException;
import com.djrapitops.plan.system.database.DBSystem;
import com.djrapitops.plan.system.database.databases.Database;
import com.djrapitops.plan.system.settings.Permissions;
import com.djrapitops.plan.system.settings.locale.Locale;
import com.djrapitops.plan.system.settings.locale.Msg;
import com.djrapitops.plan.utilities.Condition;
import com.djrapitops.plan.utilities.ManageUtils;
import com.djrapitops.plugin.api.utility.log.Log;
@ -24,21 +24,13 @@ import com.djrapitops.plugin.utilities.Verify;
*/
public class ManageBackupCommand extends SubCommand {
private final Plan plugin;
/**
* Class Constructor.
*
* @param plugin Current instance of Plan
*/
public ManageBackupCommand(Plan plugin) {
public ManageBackupCommand() {
super("backup",
CommandType.CONSOLE,
Permissions.MANAGE.getPermission(),
Locale.get(Msg.CMD_USG_MANAGE_BACKUP).toString(),
"<DB>");
this.plugin = plugin;
}
@Override
@ -54,7 +46,7 @@ public class ManageBackupCommand extends SubCommand {
return true;
}
final Database database = ManageUtils.getDB(dbName);
final Database database = DBSystem.getActiveDatabaseByName(dbName);
// If DB is null return
if (!Condition.isTrue(Verify.notNull(database), Locale.get(Msg.MANAGE_FAIL_FAULTY_DB).toString(), sender)) {
@ -63,7 +55,7 @@ public class ManageBackupCommand extends SubCommand {
}
Log.debug("Backup", "Start");
runBackupTask(sender, args, database);
} catch (DatabaseInitException | NullPointerException e) {
} catch (DBInitException | NullPointerException e) {
sender.sendMessage(Locale.get(Msg.MANAGE_FAIL_FAULTY_DB).toString());
} finally {
Log.logDebug("Backup");
@ -80,7 +72,7 @@ public class ManageBackupCommand extends SubCommand {
ManageUtils.backup(args[0], database);
sender.sendMessage(Locale.get(Msg.MANAGE_INFO_COPY_SUCCESS).toString());
} catch (Exception e) {
Log.toLog(this.getClass().getName() + " " + getTaskName(), e);
Log.toLog(this.getClass(), e);
sender.sendMessage(Locale.get(Msg.MANAGE_INFO_FAIL).toString());
} finally {
this.cancel();

View File

@ -1,16 +1,17 @@
package com.djrapitops.plan.command.commands.manage;
import com.djrapitops.plan.Plan;
import com.djrapitops.plan.api.exceptions.DatabaseInitException;
import com.djrapitops.plan.api.exceptions.database.DBException;
import com.djrapitops.plan.api.exceptions.database.DBInitException;
import com.djrapitops.plan.api.exceptions.database.FatalDBException;
import com.djrapitops.plan.data.container.Session;
import com.djrapitops.plan.database.Database;
import com.djrapitops.plan.settings.Permissions;
import com.djrapitops.plan.settings.locale.Locale;
import com.djrapitops.plan.settings.locale.Msg;
import com.djrapitops.plan.systems.cache.DataCache;
import com.djrapitops.plan.systems.cache.SessionCache;
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.plan.system.settings.Permissions;
import com.djrapitops.plan.system.settings.locale.Locale;
import com.djrapitops.plan.system.settings.locale.Msg;
import com.djrapitops.plan.utilities.Condition;
import com.djrapitops.plan.utilities.ManageUtils;
import com.djrapitops.plan.utilities.MiscUtils;
import com.djrapitops.plugin.api.utility.log.Log;
import com.djrapitops.plugin.command.CommandType;
@ -20,10 +21,8 @@ import com.djrapitops.plugin.task.AbsRunnable;
import com.djrapitops.plugin.task.RunnableFactory;
import com.djrapitops.plugin.utilities.Verify;
import java.sql.SQLException;
/**
* This manage subcommand is used to clear a database of all data.
* This manage SubCommand is used to clear a database of all data.
*
* @author Rsl1122
* @since 2.3.0
@ -32,11 +31,6 @@ public class ManageClearCommand extends SubCommand {
private final Plan plugin;
/**
* Class Constructor.
*
* @param plugin Current instance of Plan
*/
public ManageClearCommand(Plan plugin) {
super("clear",
CommandType.PLAYER_OR_ARGS,
@ -71,9 +65,9 @@ public class ManageClearCommand extends SubCommand {
}
try {
Database database = ManageUtils.getDB(dbName);
Database database = DBSystem.getActiveDatabaseByName(dbName);
runClearTask(sender, database);
} catch (DatabaseInitException e) {
} catch (DBInitException e) {
sender.sendMessage(Locale.get(Msg.MANAGE_FAIL_FAULTY_DB).toString());
}
return true;
@ -86,19 +80,22 @@ public class ManageClearCommand extends SubCommand {
try {
sender.sendMessage(Locale.get(Msg.MANAGE_INFO_START).parse());
database.removeAllData();
database.remove().everything();
DataCache dataCache = plugin.getDataCache();
long now = MiscUtils.getTime();
SessionCache.clear();
plugin.getServer().getOnlinePlayers().forEach(
player -> dataCache.cacheSession(player.getUniqueId(),
player -> SessionCache.getInstance().cacheSession(player.getUniqueId(),
new Session(now, player.getWorld().getName(), player.getGameMode().name()))
);
sender.sendMessage(Locale.get(Msg.MANAGE_INFO_CLEAR_SUCCESS).toString());
} catch (SQLException e) {
} catch (FatalDBException e) {
sender.sendMessage(Locale.get(Msg.MANAGE_INFO_FAIL).toString()
+ " Error was fatal, so all information may not have been removed.");
Log.toLog(this.getClass(), e);
} catch (DBException e) {
sender.sendMessage(Locale.get(Msg.MANAGE_INFO_FAIL).toString());
Log.toLog(this.getClass().getSimpleName() + "/" + this.getTaskName(), e);
Log.toLog(this.getClass(), e);
} finally {
this.cancel();
}

View File

@ -1,9 +1,9 @@
package com.djrapitops.plan.command.commands.manage;
import com.djrapitops.plan.settings.Permissions;
import com.djrapitops.plan.settings.locale.Locale;
import com.djrapitops.plan.settings.locale.Msg;
import com.djrapitops.plan.systems.listeners.PlanPlayerListener;
import com.djrapitops.plan.system.listeners.bukkit.PlayerOnlineListener;
import com.djrapitops.plan.system.settings.Permissions;
import com.djrapitops.plan.system.settings.locale.Locale;
import com.djrapitops.plan.system.settings.locale.Msg;
import com.djrapitops.plan.utilities.Condition;
import com.djrapitops.plugin.command.CommandType;
import com.djrapitops.plugin.command.ISender;
@ -34,7 +34,7 @@ public class ManageDisableCommand extends SubCommand {
}
switch (args[0].toLowerCase()) {
case "kickcount":
PlanPlayerListener.setCountKicks(false);
PlayerOnlineListener.setCountKicks(false);
sender.sendMessage("§aDisabled Kick Counting temporarily until next plugin reload.");
break;
default:

View File

@ -1,24 +1,21 @@
package com.djrapitops.plan.command.commands.manage;
import com.djrapitops.plan.Plan;
import com.djrapitops.plan.database.Database;
import com.djrapitops.plan.settings.Permissions;
import com.djrapitops.plan.settings.Settings;
import com.djrapitops.plan.settings.locale.Locale;
import com.djrapitops.plan.settings.locale.Msg;
import com.djrapitops.plan.system.database.DBSystem;
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.plan.system.settings.locale.Locale;
import com.djrapitops.plan.system.settings.locale.Msg;
import com.djrapitops.plan.utilities.Condition;
import com.djrapitops.plan.utilities.ManageUtils;
import com.djrapitops.plugin.api.config.Config;
import com.djrapitops.plugin.api.utility.log.Log;
import com.djrapitops.plugin.command.CommandType;
import com.djrapitops.plugin.command.ISender;
import com.djrapitops.plugin.command.SubCommand;
import com.djrapitops.plugin.utilities.Verify;
import java.io.IOException;
/**
* This manage subcommand is used to swap to a different database and reload the
* This manage SubCommand is used to swap to a different database and reload the
* plugin if the connection to the new database can be established.
*
* @author Rsl1122
@ -28,11 +25,6 @@ public class ManageHotswapCommand extends SubCommand {
private final Plan plugin;
/**
* Class Constructor.
*
* @param plugin Current instance of Plan
*/
public ManageHotswapCommand(Plan plugin) {
super("hotswap",
CommandType.PLAYER_OR_ARGS,
@ -61,12 +53,12 @@ public class ManageHotswapCommand extends SubCommand {
return true;
}
if (Condition.isTrue(dbName.equals(plugin.getDB().getConfigName()), Locale.get(Msg.MANAGE_FAIL_SAME_DB).toString(), sender)) {
if (Condition.isTrue(dbName.equals(Database.getActive().getConfigName()), Locale.get(Msg.MANAGE_FAIL_SAME_DB).toString(), sender)) {
return true;
}
try {
final Database database = ManageUtils.getDB(dbName);
final Database database = DBSystem.getActiveDatabaseByName(dbName);
// If DB is null return
if (!Condition.isTrue(Verify.notNull(database), Locale.get(Msg.MANAGE_FAIL_FAULTY_DB).toString(), sender)) {
@ -74,24 +66,19 @@ public class ManageHotswapCommand extends SubCommand {
return true;
}
assert database != null;
database.getVersion(); //Test db connection
if (!database.isOpen()) {
return true;
}
} catch (Exception e) {
Log.toLog(this.getClass().getName(), e);
Log.toLog(this.getClass(), e);
sender.sendMessage(Locale.get(Msg.MANAGE_FAIL_FAULTY_DB).toString());
return true;
}
Config config = plugin.getMainConfig();
config.set(Settings.DB_TYPE.getPath(), dbName);
try {
config.save();
plugin.reloadPlugin(true);
} catch (IOException e) {
Log.toLog(this.getClass().getName(), e);
}
Settings.DB_TYPE.set(dbName);
Settings.save();
plugin.reloadPlugin(true);
return true;
}
}

View File

@ -1,10 +1,9 @@
package com.djrapitops.plan.command.commands.manage;
import com.djrapitops.plan.Plan;
import com.djrapitops.plan.settings.Permissions;
import com.djrapitops.plan.settings.locale.Locale;
import com.djrapitops.plan.settings.locale.Msg;
import com.djrapitops.plan.systems.info.ImporterManager;
import com.djrapitops.plan.system.processing.importing.ImporterManager;
import com.djrapitops.plan.system.settings.Permissions;
import com.djrapitops.plan.system.settings.locale.Locale;
import com.djrapitops.plan.system.settings.locale.Msg;
import com.djrapitops.plan.utilities.Condition;
import com.djrapitops.plugin.command.CommandType;
import com.djrapitops.plugin.command.ISender;
@ -13,21 +12,14 @@ import com.djrapitops.plugin.task.AbsRunnable;
import com.djrapitops.plugin.task.RunnableFactory;
/**
* This manage subcommand is used to import data from 3rd party plugins.
* <p>
* Supported plugins (v3.0.0) : OnTime
* This manage SubCommand is used to import data from 3rd party plugins.
*
* @author Rsl1122
* @since 2.3.0
*/
public class ManageImportCommand extends SubCommand {
/**
* Class Constructor.
*
* @param plugin Current instance of Plan
*/
public ManageImportCommand(Plan plugin) {
public ManageImportCommand() {
super("import",
CommandType.CONSOLE,
Permissions.MANAGE.getPermission(),

View File

@ -1,10 +1,10 @@
package com.djrapitops.plan.command.commands.manage;
import com.djrapitops.plan.Plan;
import com.djrapitops.plan.database.Database;
import com.djrapitops.plan.settings.Permissions;
import com.djrapitops.plan.settings.locale.Locale;
import com.djrapitops.plan.settings.locale.Msg;
import com.djrapitops.plan.system.database.DBSystem;
import com.djrapitops.plan.system.database.databases.Database;
import com.djrapitops.plan.system.settings.Permissions;
import com.djrapitops.plan.system.settings.locale.Locale;
import com.djrapitops.plan.system.settings.locale.Msg;
import com.djrapitops.plan.utilities.Condition;
import com.djrapitops.plan.utilities.ManageUtils;
import com.djrapitops.plugin.api.utility.log.Log;
@ -16,7 +16,7 @@ import com.djrapitops.plugin.task.RunnableFactory;
import com.djrapitops.plugin.utilities.Verify;
/**
* This manage subcommand is used to move all data from one database to another.
* This manage SubCommand is used to move all data from one database to another.
* <p>
* Destination database will be cleared.
*
@ -25,21 +25,12 @@ import com.djrapitops.plugin.utilities.Verify;
*/
public class ManageMoveCommand extends SubCommand {
private final Plan plugin;
/**
* Class Constructor.
*
* @param plugin Current instance of Plan
*/
public ManageMoveCommand(Plan plugin) {
public ManageMoveCommand() {
super("move",
CommandType.PLAYER_OR_ARGS,
Permissions.MANAGE.getPermission(),
Locale.get(Msg.CMD_USG_MANAGE_MOVE).toString(),
"<fromDB> <toDB> [-a]");
this.plugin = plugin;
}
@Override
@ -71,8 +62,8 @@ public class ManageMoveCommand extends SubCommand {
}
try {
final Database fromDatabase = ManageUtils.getDB(fromDB);
final Database toDatabase = ManageUtils.getDB(toDB);
final Database fromDatabase = DBSystem.getActiveDatabaseByName(fromDB);
final Database toDatabase = DBSystem.getActiveDatabaseByName(toDB);
runMoveTask(fromDatabase, toDatabase, sender);
} catch (Exception e) {
@ -90,10 +81,10 @@ public class ManageMoveCommand extends SubCommand {
ManageUtils.clearAndCopy(toDatabase, fromDatabase);
sender.sendMessage(Locale.get(Msg.MANAGE_INFO_MOVE_SUCCESS).toString());
boolean movedToCurrentDatabase = Verify.equalsIgnoreCase(toDatabase.getConfigName(), plugin.getDB().getConfigName());
boolean movedToCurrentDatabase = Verify.equalsIgnoreCase(toDatabase.getConfigName(), Database.getActive().getConfigName());
Condition.isTrue(!movedToCurrentDatabase, Locale.get(Msg.MANAGE_INFO_CONFIG_REMINDER).toString(), sender);
} catch (Exception e) {
Log.toLog(this.getClass().getName() + " " + getTaskName(), e);
Log.toLog(this.getClass(), e);
sender.sendMessage(Locale.get(Msg.MANAGE_INFO_FAIL).toString());
} finally {
this.cancel();

View File

@ -1,12 +1,12 @@
package com.djrapitops.plan.command.commands.manage;
import com.djrapitops.plan.Plan;
import com.djrapitops.plan.api.exceptions.database.DBException;
import com.djrapitops.plan.data.container.Session;
import com.djrapitops.plan.settings.Permissions;
import com.djrapitops.plan.settings.locale.Locale;
import com.djrapitops.plan.settings.locale.Msg;
import com.djrapitops.plan.systems.cache.DataCache;
import com.djrapitops.plan.systems.cache.SessionCache;
import com.djrapitops.plan.system.cache.SessionCache;
import com.djrapitops.plan.system.database.databases.Database;
import com.djrapitops.plan.system.settings.Permissions;
import com.djrapitops.plan.system.settings.locale.Locale;
import com.djrapitops.plan.system.settings.locale.Msg;
import com.djrapitops.plan.utilities.Condition;
import com.djrapitops.plan.utilities.MiscUtils;
import com.djrapitops.plan.utilities.uuid.UUIDUtility;
@ -19,7 +19,6 @@ import com.djrapitops.plugin.task.RunnableFactory;
import com.djrapitops.plugin.utilities.Verify;
import org.bukkit.entity.Player;
import java.sql.SQLException;
import java.util.UUID;
import static org.bukkit.Bukkit.getPlayer;
@ -32,22 +31,12 @@ import static org.bukkit.Bukkit.getPlayer;
*/
public class ManageRemoveCommand extends SubCommand {
private final Plan plugin;
/**
* Class Constructor.
*
* @param plugin Current instance of Plan
*/
public ManageRemoveCommand(Plan plugin) {
public ManageRemoveCommand() {
super("remove",
CommandType.PLAYER_OR_ARGS,
Permissions.MANAGE.getPermission(),
Locale.get(Msg.CMD_USG_MANAGE_REMOVE).toString(),
"<player> [-a]");
this.plugin = plugin;
}
@Override
@ -80,30 +69,29 @@ public class ManageRemoveCommand extends SubCommand {
}
message = Locale.get(Msg.CMD_FAIL_USERNAME_NOT_KNOWN).toString();
if (!Condition.isTrue(plugin.getDB().wasSeenBefore(uuid), message, sender)) {
Database database = Database.getActive();
if (!Condition.isTrue(database.check().isPlayerRegistered(uuid), message, sender)) {
return;
}
message = Locale.get(Msg.MANAGE_FAIL_CONFIRM).parse(Locale.get(Msg.MANAGE_NOTIFY_REMOVE).parse(plugin.getDB().getConfigName()));
message = Locale.get(Msg.MANAGE_FAIL_CONFIRM).parse(Locale.get(Msg.MANAGE_NOTIFY_REMOVE).parse(Database.getActive().getConfigName()));
if (!Condition.isTrue(Verify.contains("-a", args), message, sender)) {
return;
}
sender.sendMessage(Locale.get(Msg.MANAGE_INFO_START).parse());
try {
plugin.getDB().removeAccount(uuid);
DataCache dataCache = plugin.getDataCache();
Player player = getPlayer(uuid);
if (player != null) {
SessionCache.getActiveSessions().remove(uuid);
dataCache.cacheSession(uuid, new Session(MiscUtils.getTime(), player.getWorld().getName(), player.getGameMode().name()));
}
sender.sendMessage(Locale.get(Msg.MANAGE_INFO_REMOVE_SUCCESS).parse(playerName, plugin.getDB().getConfigName()));
} catch (SQLException e) {
Log.toLog(this.getClass().getName(), e);
sender.sendMessage(Locale.get(Msg.MANAGE_INFO_FAIL).toString());
database.remove().player(uuid);
Player player = getPlayer(uuid);
if (player != null) {
SessionCache.getActiveSessions().remove(uuid);
SessionCache.getInstance().cacheSession(uuid, new Session(MiscUtils.getTime(), player.getWorld().getName(), player.getGameMode().name()));
}
sender.sendMessage(Locale.get(Msg.MANAGE_INFO_REMOVE_SUCCESS).parse(playerName, Database.getActive().getConfigName()));
} catch (DBException e) {
Log.toLog(this.getClass(), e);
sender.sendMessage(Locale.get(Msg.MANAGE_INFO_FAIL).toString());
} finally {
this.cancel();
}

View File

@ -1,11 +1,12 @@
package com.djrapitops.plan.command.commands.manage;
import com.djrapitops.plan.Plan;
import com.djrapitops.plan.database.Database;
import com.djrapitops.plan.database.databases.SQLiteDB;
import com.djrapitops.plan.settings.Permissions;
import com.djrapitops.plan.settings.locale.Locale;
import com.djrapitops.plan.settings.locale.Msg;
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.settings.Permissions;
import com.djrapitops.plan.system.settings.locale.Locale;
import com.djrapitops.plan.system.settings.locale.Msg;
import com.djrapitops.plan.utilities.Condition;
import com.djrapitops.plan.utilities.ManageUtils;
import com.djrapitops.plugin.api.utility.log.Log;
@ -19,7 +20,7 @@ import com.djrapitops.plugin.utilities.Verify;
import java.io.File;
/**
* This manage subcommand is used to restore a backup.db file in the
* This manage SubCommand is used to restore a backup.db file in the
* /plugins/Plan folder.
*
* @author Rsl1122
@ -28,11 +29,6 @@ public class ManageRestoreCommand extends SubCommand {
private final Plan plugin;
/**
* Class Constructor.
*
* @param plugin Current instance of Plan
*/
public ManageRestoreCommand(Plan plugin) {
super("restore",
CommandType.CONSOLE,
@ -61,7 +57,7 @@ public class ManageRestoreCommand extends SubCommand {
}
try {
final Database database = ManageUtils.getDB(db);
final Database database = DBSystem.getActiveDatabaseByName(db);
runRestoreTask(args, sender, database);
} catch (Exception e) {
@ -93,13 +89,10 @@ public class ManageRestoreCommand extends SubCommand {
sender.sendMessage(Locale.get(Msg.MANAGE_INFO_START).parse());
ManageUtils.clearAndCopy(database, backupDB);
if (database.getConfigName().equals(plugin.getDB().getConfigName())) {
// plugin.getDataCache().getCommandUseFromDb();
}
sender.sendMessage(Locale.get(Msg.MANAGE_INFO_COPY_SUCCESS).toString());
} catch (Exception e) {
Log.toLog(this.getClass().getName() + " " + getTaskName(), e);
Log.toLog(this.getClass(), e);
sender.sendMessage(Locale.get(Msg.MANAGE_INFO_FAIL).toString());
} finally {
this.cancel();

View File

@ -1,45 +1,33 @@
package com.djrapitops.plan.command.commands.manage;
import com.djrapitops.plan.Plan;
import com.djrapitops.plan.api.exceptions.WebAPIException;
import com.djrapitops.plan.api.exceptions.WebAPIForbiddenException;
import com.djrapitops.plan.settings.Permissions;
import com.djrapitops.plan.settings.Settings;
import com.djrapitops.plan.settings.locale.Locale;
import com.djrapitops.plan.settings.locale.Msg;
import com.djrapitops.plan.systems.webserver.webapi.bungee.RequestSetupWebAPI;
import com.djrapitops.plan.api.exceptions.connection.*;
import com.djrapitops.plan.system.info.InfoSystem;
import com.djrapitops.plan.system.processing.Processor;
import com.djrapitops.plan.system.settings.Permissions;
import com.djrapitops.plan.system.settings.Settings;
import com.djrapitops.plan.system.settings.locale.Locale;
import com.djrapitops.plan.system.settings.locale.Msg;
import com.djrapitops.plan.system.webserver.WebServerSystem;
import com.djrapitops.plan.utilities.Condition;
import com.djrapitops.plugin.api.config.Config;
import com.djrapitops.plugin.api.utility.log.Log;
import com.djrapitops.plugin.command.CommandType;
import com.djrapitops.plugin.command.ISender;
import com.djrapitops.plugin.command.SubCommand;
/**
* This manage subcommand is used to swap to a different database and reload the
* plugin if the connection to the new database can be established.
* This manage SubCommand is used to request settings from Bungee so that connection can be established.
*
* @author Rsl1122
* @since 2.3.0
*/
public class ManageSetupCommand extends SubCommand {
private final Plan plugin;
/**
* Class Constructor.
*
* @param plugin Current instance of Plan
*/
public ManageSetupCommand(Plan plugin) {
public ManageSetupCommand() {
super("setup",
CommandType.PLAYER_OR_ARGS,
Permissions.MANAGE.getPermission(),
"Set-Up Bungee WebServer connection",
"<Bungee WebServer address>");
this.plugin = plugin;
}
@Override
@ -52,31 +40,47 @@ public class ManageSetupCommand extends SubCommand {
if (!Condition.isTrue(args.length >= 1, Locale.get(Msg.CMD_FAIL_REQ_ONE_ARG).toString(), sender)) {
return true;
}
if (!plugin.getWebServer().isEnabled()) {
if (!WebServerSystem.isWebServerEnabled()) {
sender.sendMessage("§cWebServer is not enabled on this server! Make sure it enables on boot!");
return true;
}
String address = args[0].toLowerCase();
if (!address.startsWith("http")) {
if (!address.startsWith("http") || address.endsWith("://")) {
sender.sendMessage("§cMake sure you're using the full address (Starts with http:// or https://) - Check Bungee enable log for the full address.");
return true;
}
if (address.endsWith("/")) {
address = address.substring(0, address.length() - 1);
}
try {
Config config = plugin.getMainConfig();
config.set(Settings.BUNGEE_OVERRIDE_STANDALONE_MODE.getPath(), false);
config.set(Settings.BUNGEE_COPY_CONFIG.getPath(), true);
// plugin.getWebServer().getWebAPI().getAPI(PingWebAPI.class).sendRequest(address);
plugin.getWebServer().getWebAPI().getAPI(RequestSetupWebAPI.class).sendRequest(address);
sender.sendMessage("§eConnection successful, Plan may restart in a few seconds, if it doesn't something has gone wrong.");
} catch (WebAPIForbiddenException e) {
sender.sendMessage("§eConnection succeeded, but Bungee has set-up mode disabled - use '/planbungee setup' to enable it.");
} catch (WebAPIException e) {
Log.toLog(this.getClass().getName(), e);
sender.sendMessage("§cConnection to Bungee WebServer failed: More info on console");
}
requestSetup(sender, address);
return true;
}
private void requestSetup(ISender sender, String address) {
Processor.queue(() -> {
try {
Settings.BUNGEE_OVERRIDE_STANDALONE_MODE.set(false);
Settings.BUNGEE_COPY_CONFIG.set(true);
InfoSystem.getInstance().requestSetUp(address);
sender.sendMessage("§aConnection successful, Plan may restart in a few seconds..");
} catch (ForbiddenException e) {
sender.sendMessage("§eConnection succeeded, but Bungee has set-up mode disabled - use '/planbungee setup' to enable it.");
} catch (BadRequestException e) {
sender.sendMessage("§eConnection succeeded, but Receiving server was a Bukkit server. Use Bungee address instead.");
} catch (UnauthorizedServerException e) {
sender.sendMessage("§eConnection succeeded, but Receiving server didn't authorize this server. Contact Discord for support");
} catch (ConnectionFailException e) {
sender.sendMessage("§eConnection failed: " + e.getMessage());
} catch (InternalErrorException e) {
sender.sendMessage("§eConnection succeeded. " + e.getMessage() + ", check possible ErrorLog on receiving server's debug page.");
} catch (WebException e) {
Log.toLog(this.getClass(), e);
sender.sendMessage("§cConnection to Bungee WebServer failed: More info in the error log.");
}
});
}
}

View File

@ -1,11 +1,10 @@
package com.djrapitops.plan.command.commands.webuser;
import com.djrapitops.plan.api.IPlan;
import com.djrapitops.plan.data.WebUser;
import com.djrapitops.plan.database.tables.SecurityTable;
import com.djrapitops.plan.settings.Permissions;
import com.djrapitops.plan.settings.locale.Locale;
import com.djrapitops.plan.settings.locale.Msg;
import com.djrapitops.plan.system.database.databases.Database;
import com.djrapitops.plan.system.settings.Permissions;
import com.djrapitops.plan.system.settings.locale.Locale;
import com.djrapitops.plan.system.settings.locale.Msg;
import com.djrapitops.plan.utilities.Condition;
import com.djrapitops.plugin.api.utility.log.Log;
import com.djrapitops.plugin.command.CommandType;
@ -23,15 +22,12 @@ import org.bukkit.ChatColor;
*/
public class WebCheckCommand extends SubCommand {
private final IPlan plugin;
public WebCheckCommand(IPlan plugin) {
public WebCheckCommand() {
super("check",
CommandType.PLAYER_OR_ARGS,
Permissions.MANAGE_WEB.getPerm(),
Locale.get(Msg.CMD_USG_WEB_CHECK).toString(),
"<username>");
this.plugin = plugin;
}
@Override
@ -39,20 +35,20 @@ public class WebCheckCommand extends SubCommand {
if (!Condition.isTrue(args.length >= 1, Locale.get(Msg.CMD_FAIL_REQ_ONE_ARG).parse() + " <username>", sender)) {
return true;
}
SecurityTable table = plugin.getDB().getSecurityTable();
Database database = Database.getActive();
String user = args[0];
RunnableFactory.createNew(new AbsRunnable("Webuser Check Task: " + user) {
@Override
public void run() {
try {
if (!Condition.isTrue(table.userExists(user), ChatColor.RED + "[Plan] User Doesn't exist.", sender)) {
if (!Condition.isTrue(database.check().doesWebUserExists(user), ChatColor.RED + "[Plan] User Doesn't exist.", sender)) {
return;
}
WebUser info = table.getWebUser(user);
WebUser info = database.fetch().getWebUser(user);
sender.sendMessage(info.getName() + ": Permission level: " + info.getPermLevel());
} catch (Exception ex) {
Log.toLog(this.getClass().getName(), ex);
Log.toLog(this.getClass(), ex);
sender.sendMessage(Locale.get(Msg.MANAGE_INFO_FAIL).parse());
} finally {
this.cancel();

View File

@ -1,10 +1,9 @@
package com.djrapitops.plan.command.commands.webuser;
import com.djrapitops.plan.api.IPlan;
import com.djrapitops.plan.database.tables.SecurityTable;
import com.djrapitops.plan.settings.Permissions;
import com.djrapitops.plan.settings.locale.Locale;
import com.djrapitops.plan.settings.locale.Msg;
import com.djrapitops.plan.system.database.databases.Database;
import com.djrapitops.plan.system.settings.Permissions;
import com.djrapitops.plan.system.settings.locale.Locale;
import com.djrapitops.plan.system.settings.locale.Msg;
import com.djrapitops.plan.utilities.Condition;
import com.djrapitops.plugin.api.utility.log.Log;
import com.djrapitops.plugin.command.CommandType;
@ -22,15 +21,12 @@ import net.md_5.bungee.api.ChatColor;
*/
public class WebDeleteCommand extends SubCommand {
private final IPlan plugin;
public WebDeleteCommand(IPlan plugin) {
public WebDeleteCommand() {
super("delete, remove",
CommandType.PLAYER_OR_ARGS,
Permissions.MANAGE_WEB.getPerm(),
Locale.get(Msg.CMD_USG_WEB_DELETE).toString(),
"<username>");
this.plugin = plugin;
}
@Override
@ -38,20 +34,20 @@ public class WebDeleteCommand extends SubCommand {
if (!Condition.isTrue(args.length >= 1, Locale.get(Msg.CMD_FAIL_REQ_ONE_ARG).parse() + " <username>", sender)) {
return true;
}
SecurityTable table = plugin.getDB().getSecurityTable();
Database database = Database.getActive();
String user = args[0];
RunnableFactory.createNew(new AbsRunnable("Webuser Delete Task: " + user) {
@Override
public void run() {
try {
if (!Condition.isTrue(table.userExists(user), ChatColor.RED + "[Plan] User Doesn't exist.", sender)) {
if (!Condition.isTrue(database.check().doesWebUserExists(user), ChatColor.RED + "[Plan] User Doesn't exist.", sender)) {
return;
}
table.removeUser(user);
database.remove().webUser(user);
sender.sendMessage(Locale.get(Msg.MANAGE_INFO_SUCCESS).parse());
} catch (Exception ex) {
Log.toLog(this.getClass().getName(), ex);
Log.toLog(this.getClass(), ex);
sender.sendMessage(Locale.get(Msg.MANAGE_INFO_FAIL).parse());
} finally {
this.cancel();

View File

@ -1,9 +1,9 @@
package com.djrapitops.plan.command.commands.webuser;
import com.djrapitops.plan.api.IPlan;
import com.djrapitops.plan.settings.Permissions;
import com.djrapitops.plan.settings.locale.Locale;
import com.djrapitops.plan.settings.locale.Msg;
import com.djrapitops.plan.PlanPlugin;
import com.djrapitops.plan.system.settings.Permissions;
import com.djrapitops.plan.system.settings.locale.Locale;
import com.djrapitops.plan.system.settings.locale.Msg;
import com.djrapitops.plugin.command.CommandType;
import com.djrapitops.plugin.command.ISender;
import com.djrapitops.plugin.command.SubCommand;
@ -17,9 +17,9 @@ import com.djrapitops.plugin.settings.ColorScheme;
*/
public class WebLevelCommand extends SubCommand {
private final IPlan plugin;
private final PlanPlugin plugin;
public WebLevelCommand(IPlan plugin) {
public WebLevelCommand(PlanPlugin plugin) {
super("level",
CommandType.CONSOLE,
Permissions.MANAGE_WEB.getPerm(),

View File

@ -1,10 +1,11 @@
package com.djrapitops.plan.command.commands.webuser;
import com.djrapitops.plan.api.IPlan;
import com.djrapitops.plan.PlanPlugin;
import com.djrapitops.plan.data.WebUser;
import com.djrapitops.plan.settings.Permissions;
import com.djrapitops.plan.settings.locale.Locale;
import com.djrapitops.plan.settings.locale.Msg;
import com.djrapitops.plan.system.database.databases.Database;
import com.djrapitops.plan.system.settings.Permissions;
import com.djrapitops.plan.system.settings.locale.Locale;
import com.djrapitops.plan.system.settings.locale.Msg;
import com.djrapitops.plan.utilities.comparators.WebUserComparator;
import com.djrapitops.plugin.api.utility.log.Log;
import com.djrapitops.plugin.command.CommandType;
@ -24,9 +25,9 @@ import java.util.List;
*/
public class WebListUsersCommand extends SubCommand {
private final IPlan plugin;
private final PlanPlugin plugin;
public WebListUsersCommand(IPlan plugin) {
public WebListUsersCommand(PlanPlugin plugin) {
super("list", CommandType.CONSOLE, Permissions.MANAGE_WEB.getPerm(), "List registered web users & permission levels.");
this.plugin = plugin;
}
@ -39,7 +40,7 @@ public class WebListUsersCommand extends SubCommand {
try {
ColorScheme cs = plugin.getColorScheme();
String mCol = cs.getMainColor();
List<WebUser> users = plugin.getDB().getSecurityTable().getUsers();
List<WebUser> users = Database.getActive().fetch().getWebUsers();
users.sort(new WebUserComparator());
sender.sendMessage(Locale.get(Msg.CMD_CONSTANT_FOOTER).parse() + mCol + " WebUsers (" + users.size() + ")");
for (WebUser user : users) {
@ -47,7 +48,7 @@ public class WebListUsersCommand extends SubCommand {
}
sender.sendMessage(Locale.get(Msg.CMD_CONSTANT_FOOTER).parse());
} catch (Exception ex) {
Log.toLog(this.getClass().getName(), ex);
Log.toLog(this.getClass(), ex);
sender.sendMessage(Locale.get(Msg.MANAGE_INFO_FAIL).parse());
} finally {
this.cancel();

View File

@ -1,8 +1,8 @@
/*
/*
* 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.plan.database.tables;
package com.djrapitops.plan.data;
import org.apache.commons.lang3.text.WordUtils;

View File

@ -1,19 +1,19 @@
/*
/*
* 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.plan.data;
import com.djrapitops.plan.data.calculation.ActivityIndex;
import com.djrapitops.plan.data.container.Action;
import com.djrapitops.plan.data.container.GeoInfo;
import com.djrapitops.plan.data.container.PlayerKill;
import com.djrapitops.plan.data.container.Session;
import com.djrapitops.plan.data.time.WorldTimes;
import com.djrapitops.plan.settings.Settings;
import com.djrapitops.plan.system.info.server.ServerInfo;
import com.djrapitops.plan.utilities.MiscUtils;
import com.djrapitops.plan.utilities.comparators.ActionComparator;
import com.djrapitops.plan.utilities.comparators.GeoInfoComparator;
import com.djrapitops.plugin.api.TimeAmount;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.OfflinePlayer;
@ -57,7 +57,7 @@ public class PlayerProfile implements OfflinePlayer {
private Map<String, String> pluginReplaceMap;
// Value that requires lot of processing
private Map<Long, Double> activityIndex;
private Map<Long, ActivityIndex> activityIndexCache;
public PlayerProfile(UUID uuid, String name, long registered) {
this.uuid = uuid;
@ -76,88 +76,59 @@ public class PlayerProfile implements OfflinePlayer {
geoInformation = new ArrayList<>();
pluginReplaceMap = new HashMap<>();
activityIndex = new HashMap<>();
activityIndexCache = new HashMap<>();
}
public static long getPlaytime(Stream<Session> s) {
return s.mapToLong(Session::getLength).sum();
}
public static long getLongestSession(Stream<Session> s) {
OptionalLong longestSession = s.mapToLong(Session::getLength).max();
if (longestSession.isPresent()) {
return longestSession.getAsLong();
}
return -1;
}
public static long getSessionMedian(Stream<Session> s) {
List<Long> sessionLenghts = s.map(Session::getLength)
.sorted()
.collect(Collectors.toList());
if (sessionLenghts.isEmpty()) {
return 0;
}
return sessionLenghts.get(sessionLenghts.size() / 2);
}
public static long getSessionAverage(Stream<Session> s) {
OptionalDouble average = s.map(Session::getLength)
.mapToLong(i -> i)
.average();
if (average.isPresent()) {
return (long) average.getAsDouble();
}
return 0L;
}
public static Stream<PlayerKill> getPlayerKills(Stream<Session> s) {
return s.map(Session::getPlayerKills)
.flatMap(Collection::stream);
}
public static long getDeathCount(Stream<Session> s) {
return s.mapToLong(Session::getDeaths)
.sum();
}
public static long getMobKillCount(Stream<Session> s) {
return s.mapToLong(Session::getMobKills)
.sum();
}
// Calculating Getters
public double getActivityIndex(long date) {
Double activityIndx = activityIndex.get(date);
if (activityIndx != null) {
return activityIndx;
}
long week = TimeAmount.WEEK.ms();
long weekAgo = date - week;
long twoWeeksAgo = date - 2L * week;
long threeWeeksAgo = date - 3L * week;
long activePlayThreshold = Settings.ACTIVE_PLAY_THRESHOLD.getNumber() * TimeAmount.MINUTE.ms();
if (activePlayThreshold <= 0) {
activePlayThreshold = 1;
}
int activeLoginThreshold = Settings.ACTIVE_LOGIN_THRESHOLD.getNumber();
if (activeLoginThreshold <= 0) {
activeLoginThreshold = 1;
}
List<Session> sessionsWeek = getSessions(weekAgo, date).collect(Collectors.toList());
List<Session> sessionsWeek2 = getSessions(twoWeeksAgo, weekAgo).collect(Collectors.toList());
List<Session> sessionsWeek3 = getSessions(threeWeeksAgo, twoWeeksAgo).collect(Collectors.toList());
// Playtime per week multipliers, max out to avoid too high values.
double max = 4.0;
long playtimeWeek = PlayerProfile.getPlaytime(sessionsWeek.stream());
double weekPlay = (playtimeWeek * 1.0 / activePlayThreshold);
if (weekPlay > max) {
weekPlay = max;
}
long playtimeWeek2 = PlayerProfile.getPlaytime(sessionsWeek2.stream());
double week2Play = (playtimeWeek2 * 1.0 / activePlayThreshold);
if (week2Play > max) {
week2Play = max;
}
long playtimeWeek3 = PlayerProfile.getPlaytime(sessionsWeek3.stream());
double week3Play = (playtimeWeek3 * 1.0 / activePlayThreshold);
if (week3Play > max) {
week3Play = max;
}
double playtimeMultiplier = 1.0;
if (playtimeWeek + playtimeWeek2 + playtimeWeek3 > activeLoginThreshold * 3.0) {
playtimeMultiplier = 1.25;
}
// Reduce the harshness for new players and players who have had a vacation
if (weekPlay > 1 && week3Play > 1 && week2Play == 0.0) {
week2Play = 0.5;
}
if (weekPlay > 1 && week2Play == 0.0) {
week2Play = 0.6;
}
if (weekPlay > 1 && week3Play == 0.0) {
week3Play = 0.75;
}
double playAvg = (weekPlay + week2Play + week3Play) / 3.0;
double weekLogin = sessionsWeek.size() >= activeLoginThreshold ? 1.0 : 0.5;
double week2Login = sessionsWeek2.size() >= activeLoginThreshold ? 1.0 : 0.5;
double week3Login = sessionsWeek3.size() >= activeLoginThreshold ? 1.0 : 0.5;
double loginMultiplier = 1.0;
double loginTotal = weekLogin + week2Login + week3Login;
double loginAvg = loginTotal / 3.0;
if (loginTotal <= 2.0) {
// Reduce index for players that have not logged in the threshold amount for 2 weeks
loginMultiplier = 0.75;
}
activityIndx = playAvg * loginAvg * loginMultiplier * playtimeMultiplier;
activityIndex.put(date, activityIndx);
return activityIndx;
public ActivityIndex getActivityIndex(long date) {
return activityIndexCache.computeIfAbsent(date, dateValue -> new ActivityIndex(this, dateValue));
}
/**
@ -169,6 +140,10 @@ public class PlayerProfile implements OfflinePlayer {
return worldTimesMap.getOrDefault(null, new WorldTimes(new HashMap<>()));
}
public void setWorldTimes(Map<UUID, WorldTimes> worldTimes) {
worldTimesMap.putAll(worldTimes);
}
/**
* Get world times per server for this player.
*
@ -202,8 +177,7 @@ public class PlayerProfile implements OfflinePlayer {
}
public long getLastSeen(Stream<Session> s) {
OptionalLong max = s.mapToLong(Session::getSessionEnd)
.max();
OptionalLong max = s.mapToLong(session -> Math.max(session.getSessionStart(), session.getSessionEnd())).max();
if (max.isPresent()) {
return max.getAsLong();
}
@ -222,12 +196,6 @@ public class PlayerProfile implements OfflinePlayer {
return getPlaytime(getSessions(serverUUID).stream());
}
public static long getPlaytime(Stream<Session> s) {
return s.map(Session::getLength)
.mapToLong(i -> i)
.sum();
}
public long getLongestSession() {
return getLongestSession(-1, MiscUtils.getTime() + 1L);
}
@ -240,16 +208,6 @@ public class PlayerProfile implements OfflinePlayer {
return getLongestSession(getSessions(serverUUID).stream());
}
public static long getLongestSession(Stream<Session> s) {
OptionalLong longestSession = s.map(Session::getLength)
.mapToLong(i -> i)
.max();
if (longestSession.isPresent()) {
return longestSession.getAsLong();
}
return -1;
}
public long getSessionMedian() {
return getSessionMedian(-1, MiscUtils.getTime() + 1L);
}
@ -262,15 +220,7 @@ public class PlayerProfile implements OfflinePlayer {
return getSessionMedian(getSessions(serverUUID).stream());
}
public static long getSessionMedian(Stream<Session> s) {
List<Long> sessionLenghts = s.map(Session::getLength)
.sorted()
.collect(Collectors.toList());
if (sessionLenghts.isEmpty()) {
return 0;
}
return sessionLenghts.get(sessionLenghts.size() / 2);
}
// Special Getters
public long getSessionAverage() {
return getSessionAverage(-1, MiscUtils.getTime() + 1L);
@ -284,22 +234,10 @@ public class PlayerProfile implements OfflinePlayer {
return getSessionAverage(getSessions(serverUUID).stream());
}
public static long getSessionAverage(Stream<Session> s) {
OptionalDouble average = s.map(Session::getLength)
.mapToLong(i -> i)
.average();
if (average.isPresent()) {
return (long) average.getAsDouble();
}
return 0L;
}
public boolean playedBetween(long after, long before) {
return getSessions(after, before).findFirst().isPresent();
}
// Special Getters
public Stream<Session> getAllSessions() {
return sessions.values().stream().flatMap(Collection::stream);
}
@ -332,11 +270,6 @@ public class PlayerProfile implements OfflinePlayer {
return getPlayerKills(getSessions(serverUUID).stream());
}
public static Stream<PlayerKill> getPlayerKills(Stream<Session> s) {
return s.map(Session::getPlayerKills)
.flatMap(Collection::stream);
}
public long getPlayerKillCount() {
return getPlayerKills().count();
}
@ -353,11 +286,6 @@ public class PlayerProfile implements OfflinePlayer {
return getDeathCount(getSessions(serverUUID).stream());
}
public static long getDeathCount(Stream<Session> s) {
return s.mapToLong(Session::getDeaths)
.sum();
}
public long getMobKillCount() {
return getMobKillCount(getAllSessions());
}
@ -366,11 +294,6 @@ public class PlayerProfile implements OfflinePlayer {
return getMobKillCount(getSessions(serverUUID).stream());
}
public static long getMobKillCount(Stream<Session> s) {
return s.mapToLong(Session::getMobKills)
.sum();
}
public long getSessionCount() {
return getAllSessions().count();
}
@ -379,12 +302,12 @@ public class PlayerProfile implements OfflinePlayer {
return getSessions(serverUUID).size();
}
// Setters & Adders
public long getRegistered(UUID serverUUID) {
return registeredMap.getOrDefault(serverUUID, -1L);
}
// Setters & Adders
public void bannedOnServer(UUID serverUUID) {
bannedOnServers.add(serverUUID);
}
@ -405,12 +328,8 @@ public class PlayerProfile implements OfflinePlayer {
this.sessions.put(serverUUID, sessions);
}
public void setSessions(Map<UUID, List<Session>> sessions) {
this.sessions.putAll(sessions);
}
public void addActiveSession(Session activeSession) {
UUID serverUUID = MiscUtils.getIPlan().getServerUuid();
UUID serverUUID = ServerInfo.getServerUUID();
List<Session> sessions = getSessions(serverUUID);
sessions.add(activeSession);
this.sessions.put(serverUUID, sessions);
@ -428,10 +347,6 @@ public class PlayerProfile implements OfflinePlayer {
worldTimesMap.put(serverUUID, worldTimes);
}
public void setWorldTimes(Map<UUID, WorldTimes> worldTimes) {
worldTimesMap.putAll(worldTimes);
}
public void setTotalWorldTimes(WorldTimes worldTimes) {
worldTimesMap.put(null, worldTimes);
}
@ -440,42 +355,39 @@ public class PlayerProfile implements OfflinePlayer {
registeredMap.put(serverUUID, registered);
}
public int getTimesKicked() {
return timesKicked;
}
// Default Setters
public void setActions(List<Action> actions) {
this.actions = actions;
}
public void setNicknames(Map<UUID, List<String>> nicknames) {
this.nicknames = nicknames;
}
public void setGeoInformation(List<GeoInfo> geoInformation) {
this.geoInformation = geoInformation;
}
public void setTimesKicked(int timesKicked) {
this.timesKicked = timesKicked;
}
// Default Getters
public int getTimesKicked() {
return timesKicked;
}
public Map<UUID, List<String>> getNicknames() {
return nicknames;
}
public void setNicknames(Map<UUID, List<String>> nicknames) {
this.nicknames = nicknames;
}
public List<GeoInfo> getGeoInformation() {
return geoInformation;
}
// Default Getters
public void setGeoInformation(List<GeoInfo> geoInformation) {
this.geoInformation = geoInformation;
}
public UUID getUuid() {
return uuid;
}
@Override
public String getName() {
return name;
}
@ -496,10 +408,18 @@ public class PlayerProfile implements OfflinePlayer {
return sessions;
}
public void setSessions(Map<UUID, List<Session>> sessions) {
this.sessions.putAll(sessions);
}
public List<Action> getActions() {
return actions;
}
public void setActions(List<Action> actions) {
this.actions = actions;
}
public Map<String, String> getPluginReplaceMap() {
return pluginReplaceMap;
}
@ -553,7 +473,7 @@ public class PlayerProfile implements OfflinePlayer {
@Override
public long getLastPlayed() {
return getLastSeen(MiscUtils.getIPlan().getServerUuid());
return getLastSeen(ServerInfo.getServerUUID());
}
@Override
@ -573,7 +493,7 @@ public class PlayerProfile implements OfflinePlayer {
@Override
public boolean isOp() {
return oppedOnServers.contains(MiscUtils.getIPlan().getServerUuid());
return oppedOnServers.contains(ServerInfo.getServerUUID());
}
@Override
@ -582,7 +502,7 @@ public class PlayerProfile implements OfflinePlayer {
}
public void calculateWorldTimesPerServer() {
if (worldTimesMap.containsKey(MiscUtils.getIPlan().getServerUuid())) {
if (worldTimesMap.containsKey(ServerInfo.getServerUUID())) {
return;
}

View File

@ -1,24 +1,20 @@
/*
/*
* 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.plan.data;
import com.djrapitops.plan.Plan;
import com.djrapitops.plan.PlanBungee;
import com.djrapitops.plan.data.container.GeoInfo;
import com.djrapitops.plan.data.container.PlayerKill;
import com.djrapitops.plan.data.container.Session;
import com.djrapitops.plan.data.container.TPS;
import com.djrapitops.plan.data.time.WorldTimes;
import com.djrapitops.plan.settings.Settings;
import com.djrapitops.plan.utilities.MiscUtils;
import com.djrapitops.plan.system.settings.Settings;
import com.djrapitops.plan.utilities.analysis.AnalysisUtils;
import com.djrapitops.plan.utilities.analysis.MathUtils;
import com.djrapitops.plan.utilities.comparators.PlayerProfileLastPlayedComparator;
import com.djrapitops.plan.utilities.comparators.TPSComparator;
import com.djrapitops.plan.utilities.html.tables.PlayersTableCreator;
import com.djrapitops.plugin.api.Check;
import com.djrapitops.plugin.api.TimeAmount;
import java.util.*;
@ -64,6 +60,113 @@ public class ServerProfile {
lastPeakPlayers = -1;
}
public static long getLowSpikeCount(List<TPS> tpsData) {
int mediumThreshold = Settings.THEME_GRAPH_TPS_THRESHOLD_MED.getNumber();
boolean wasLow = false;
long spikeCount = 0L;
for (TPS tpsObj : tpsData) {
double tps = tpsObj.getTicksPerSecond();
if (tps < mediumThreshold) {
if (!wasLow) {
spikeCount++;
wasLow = true;
}
} else {
wasLow = false;
}
}
return spikeCount;
}
public static List<PlayerKill> getPlayerKills(List<Session> s) {
List<PlayerKill> kills = new ArrayList<>();
for (Session session : s) {
kills.addAll(session.getPlayerKills());
}
return kills;
}
public static long getMobKillCount(List<Session> s) {
long total = 0;
for (Session session : s) {
total += session.getMobKills();
}
return total;
}
public static long getDeathCount(List<Session> s) {
long total = 0;
for (Session session : s) {
total += session.getDeaths();
}
return total;
}
public static long serverDownTime(List<TPS> tpsData) {
long lastDate = -1;
long downTime = 0;
for (TPS tps : tpsData) {
long date = tps.getDate();
if (lastDate == -1) {
lastDate = date;
continue;
}
long diff = date - lastDate;
if (diff > TimeAmount.MINUTE.ms() * 3L) {
downTime += diff;
}
lastDate = date;
}
return downTime;
}
public static long serverIdleTime(List<TPS> tpsData) {
long lastDate = -1;
int lastPlayers = 0;
long idleTime = 0;
for (TPS tps : tpsData) {
long date = tps.getDate();
int players = tps.getPlayers();
if (lastDate == -1) {
lastDate = date;
lastPlayers = players;
continue;
}
long diff = date - lastDate;
if (lastPlayers == 0 && players == 0) {
idleTime += diff;
}
lastDate = date;
lastPlayers = players;
}
return idleTime;
}
public static double aboveLowThreshold(List<TPS> tpsData) {
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) {
count++;
}
}
return count * 1.0 / tpsData.size();
}
public List<PlayerProfile> getPlayers() {
return players;
}
@ -88,27 +191,6 @@ public class ServerProfile {
this.commandUsage = commandUsage;
}
public static long getLowSpikeCount(List<TPS> tpsData) {
int mediumThreshold = Settings.THEME_GRAPH_TPS_THRESHOLD_MED.getNumber();
boolean wasLow = false;
long spikeCount = 0L;
for (TPS tpsObj : tpsData) {
double tps = tpsObj.getTicksPerSecond();
if (tps < mediumThreshold) {
if (!wasLow) {
spikeCount++;
wasLow = true;
}
} else {
wasLow = false;
}
}
return spikeCount;
}
public double getAverageTPS(long after, long before) {
OptionalDouble average = getTPSData(after, before)
.mapToDouble(TPS::getTicksPerSecond)
@ -200,6 +282,8 @@ public class ServerProfile {
.collect(Collectors.toList());
}
// Default setters & getters
public long getTotalPlaytime() {
return serverWorldtimes.getTotal();
}
@ -220,32 +304,6 @@ public class ServerProfile {
return players.stream().map(p -> p.getSessions(serverUUID)).flatMap(Collection::stream).collect(Collectors.toList());
}
public static List<PlayerKill> getPlayerKills(List<Session> s) {
List<PlayerKill> kills = new ArrayList<>();
for (Session session : s) {
kills.addAll(session.getPlayerKills());
}
return kills;
}
public static long getMobKillCount(List<Session> s) {
long total = 0;
for (Session session : s) {
total += session.getMobKills();
}
return total;
}
public static long getDeathCount(List<Session> s) {
long total = 0;
for (Session session : s) {
total += session.getDeaths();
}
return total;
}
// Default setters & getters
public WorldTimes getServerWorldtimes() {
return serverWorldtimes;
}
@ -286,18 +344,6 @@ public class ServerProfile {
this.allTimePeakPlayers = allTimePeakPlayers;
}
public static int getPlayersOnline() {
if (Check.isBungeeAvailable()) {
return PlanBungee.getInstance().getProxy().getOnlineCount();
} else {
return Plan.getInstance().getServer().getOnlinePlayers().size();
}
}
public static int getPlayersMax() {
return MiscUtils.getIPlan().getVariable().getMaxPlayers();
}
public Stream<PlayerProfile> getOps() {
return players.stream().filter(PlayerProfile::isOp);
}
@ -316,74 +362,12 @@ public class ServerProfile {
.collect(Collectors.toList()));
}
public static long serverDownTime(List<TPS> tpsData) {
long lastDate = -1;
long downTime = 0;
for (TPS tps : tpsData) {
long date = tps.getDate();
if (lastDate == -1) {
lastDate = date;
continue;
}
long diff = date - lastDate;
if (diff > TimeAmount.MINUTE.ms() * 3L) {
downTime += diff;
}
lastDate = date;
}
return downTime;
}
public long serverIdleTime(long after, long before) {
return serverIdleTime(getTPSData(after, before)
.sorted(new TPSComparator())
.collect(Collectors.toList()));
}
public static long serverIdleTime(List<TPS> tpsData) {
long lastDate = -1;
int lastPlayers = 0;
long idleTime = 0;
for (TPS tps : tpsData) {
long date = tps.getDate();
int players = tps.getPlayers();
if (lastDate == -1) {
lastDate = date;
lastPlayers = players;
continue;
}
long diff = date - lastDate;
if (lastPlayers == 0 && players == 0) {
idleTime += diff;
}
lastDate = date;
lastPlayers = players;
}
return idleTime;
}
public static double aboveLowThreshold(List<TPS> tpsData) {
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) {
count++;
}
}
return count * 1.0 / tpsData.size();
}
public PlayerProfile getPlayer(UUID uuid) {
if (playerMap == null) {
playerMap = players.stream().collect(Collectors.toMap(PlayerProfile::getUuid, Function.identity()));

View File

@ -0,0 +1,133 @@
package com.djrapitops.plan.data.calculation;
import com.djrapitops.plan.data.PlayerProfile;
import com.djrapitops.plan.data.container.Session;
import com.djrapitops.plan.system.settings.Settings;
import com.djrapitops.plan.utilities.FormatUtils;
import com.djrapitops.plugin.api.TimeAmount;
import java.util.List;
import java.util.stream.Collectors;
public class ActivityIndex {
private final double value;
public ActivityIndex(PlayerProfile player, long date) {
value = calculate(player, date);
}
public static String[] getGroups() {
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(PlayerProfile player, long date) {
long week = TimeAmount.WEEK.ms();
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());
List<Session> sessionsWeek = player.getSessions(weekAgo, date).collect(Collectors.toList());
List<Session> sessionsWeek2 = player.getSessions(twoWeeksAgo, weekAgo).collect(Collectors.toList());
List<Session> sessionsWeek3 = player.getSessions(threeWeeksAgo, twoWeeksAgo).collect(Collectors.toList());
// Playtime per week multipliers, max out to avoid too high values.
double max = 4.0;
long playtimeWeek = PlayerProfile.getPlaytime(sessionsWeek.stream());
double weekPlay = (playtimeWeek * 1.0 / activePlayThreshold);
if (weekPlay > max) {
weekPlay = max;
}
long playtimeWeek2 = PlayerProfile.getPlaytime(sessionsWeek2.stream());
double week2Play = (playtimeWeek2 * 1.0 / activePlayThreshold);
if (week2Play > max) {
week2Play = max;
}
long playtimeWeek3 = PlayerProfile.getPlaytime(sessionsWeek3.stream());
double week3Play = (playtimeWeek3 * 1.0 / activePlayThreshold);
if (week3Play > max) {
week3Play = max;
}
double playtimeMultiplier = 1.0;
if (playtimeWeek + playtimeWeek2 + playtimeWeek3 > activePlayThreshold * 3.0) {
playtimeMultiplier = 1.25;
}
// Reduce the harshness for new players and players who have had a vacation
if (weekPlay > 1 && week3Play > 1 && week2Play == 0.0) {
week2Play = 0.5;
}
if (weekPlay > 1 && week2Play == 0.0) {
week2Play = 0.6;
}
if (weekPlay > 1 && week3Play == 0.0) {
week3Play = 0.75;
}
double playAvg = (weekPlay + week2Play + week3Play) / 3.0;
double weekLogin = sessionsWeek.size() >= activeLoginThreshold ? 1.0 : 0.5;
double week2Login = sessionsWeek2.size() >= activeLoginThreshold ? 1.0 : 0.5;
double week3Login = sessionsWeek3.size() >= activeLoginThreshold ? 1.0 : 0.5;
double loginMultiplier = 1.0;
double loginTotal = weekLogin + week2Login + week3Login;
double loginAvg = loginTotal / 3.0;
if (loginTotal <= 2.0) {
// Reduce index for players that have not logged in the threshold amount for 2 weeks
loginMultiplier = 0.75;
}
return playAvg * loginAvg * loginMultiplier * playtimeMultiplier;
}
public double getValue() {
return value;
}
public String getFormattedValue() {
return FormatUtils.cutDecimals(value);
}
public String getGroup() {
if (value >= 3.5) {
return "Very Active";
} else if (value >= 1.75) {
return "Active";
} else if (value >= 1.0) {
return "Regular";
} else if (value >= 0.5) {
return "Irregular";
} else {
return "Inactive";
}
}
public String getColor() {
if (value >= 3.5) {
return "green";
} else if (value >= 1.75) {
return "green";
} else if (value >= 1.0) {
return "lime";
} else if (value >= 0.5) {
return "amber";
} else {
return "blue-gray";
}
}
}

View File

@ -1,22 +1,25 @@
package com.djrapitops.plan.data;
package com.djrapitops.plan.data.calculation;
import com.djrapitops.plan.PlanPlugin;
import com.djrapitops.plan.data.PlayerProfile;
import com.djrapitops.plan.data.ServerProfile;
import com.djrapitops.plan.data.container.Session;
import com.djrapitops.plan.data.container.StickyData;
import com.djrapitops.plan.data.container.TPS;
import com.djrapitops.plan.data.element.AnalysisContainer;
import com.djrapitops.plan.data.element.HealthNotes;
import com.djrapitops.plan.data.plugin.PluginData;
import com.djrapitops.plan.data.time.WorldTimes;
import com.djrapitops.plan.settings.Settings;
import com.djrapitops.plan.settings.theme.Theme;
import com.djrapitops.plan.settings.theme.ThemeVal;
import com.djrapitops.plan.system.info.server.ServerInfo;
import com.djrapitops.plan.system.info.server.ServerProperties;
import com.djrapitops.plan.system.settings.Settings;
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.utilities.analysis.AnalysisUtils;
import com.djrapitops.plan.utilities.analysis.MathUtils;
import com.djrapitops.plan.utilities.comparators.SessionStartComparator;
import com.djrapitops.plan.utilities.html.Html;
import com.djrapitops.plan.utilities.html.HtmlUtils;
import com.djrapitops.plan.utilities.html.graphs.ActivityStackGraph;
import com.djrapitops.plan.utilities.html.graphs.PunchCardGraph;
import com.djrapitops.plan.utilities.html.graphs.WorldMap;
@ -25,7 +28,7 @@ import com.djrapitops.plan.utilities.html.graphs.pie.ActivityPie;
import com.djrapitops.plan.utilities.html.graphs.pie.WorldPie;
import com.djrapitops.plan.utilities.html.structure.AnalysisPluginsTabContentCreator;
import com.djrapitops.plan.utilities.html.structure.SessionTabStructureCreator;
import com.djrapitops.plan.utilities.html.tables.CommandUseTableCreator;
import com.djrapitops.plan.utilities.html.tables.CommandUseTable;
import com.djrapitops.plan.utilities.html.tables.SessionsTableCreator;
import com.djrapitops.plugin.api.TimeAmount;
@ -66,12 +69,12 @@ public class AnalysisData extends RawData {
}
private void addConstants() {
addValue("version", MiscUtils.getIPlan().getVersion());
addValue("version", PlanPlugin.getInstance().getVersion());
addValue("worldPieColors", Theme.getValue(ThemeVal.GRAPH_WORLD_PIE));
addValue("gmPieColors", Theme.getValue(ThemeVal.GRAPH_GM_PIE));
addValue("serverName", Settings.SERVER_NAME.toString().replaceAll("[^a-zA-Z0-9_\\s]", "_"));
addValue("timeZone", MiscUtils.getTimeZoneOffsetHours());
addValue("refresh", FormatUtils.formatTimeStamp(refreshDate));
addValue("refresh", FormatUtils.formatTimeStampClock(refreshDate));
addValue("activityPieColors", Theme.getValue(ThemeVal.GRAPH_ACTIVITY_PIE));
addValue("playersGraphColor", Theme.getValue(ThemeVal.GRAPH_PLAYERS_ONLINE));
@ -83,12 +86,9 @@ public class AnalysisData extends RawData {
addValue("tpsMedium", Settings.THEME_GRAPH_TPS_THRESHOLD_MED.getNumber());
addValue("tpsHigh", Settings.THEME_GRAPH_TPS_THRESHOLD_HIGH.getNumber());
addValue("playersMax", ServerProfile.getPlayersMax());
addValue("playersOnline", ServerProfile.getPlayersOnline());
}
public long getRefreshDate() {
return refreshDate;
ServerProperties serverProperties = ServerInfo.getServerProperties();
addValue("playersMax", serverProperties.getMaxPlayers());
addValue("playersOnline", serverProperties.getOnlinePlayers());
}
public void analyze(ServerProfile profile) {
@ -143,11 +143,11 @@ public class AnalysisData extends RawData {
Map<String, Set<UUID>> activityNow = activityData.getOrDefault(now, new HashMap<>());
String[] activityStackSeries = ActivityStackGraph.createSeries(activityData);
String activityPieSeries = ActivityPie.createSeries(activityNow);
ActivityStackGraph activityStackGraph = new ActivityStackGraph(activityData);
String activityPieSeries = new ActivityPie(activityNow).toHighChartsSeries();
addValue("activityStackCategories", activityStackSeries[0]);
addValue("activityStackSeries", activityStackSeries[1]);
addValue("activityStackCategories", activityStackGraph.toHighChartsLabels());
addValue("activityStackSeries", activityStackGraph.toHighChartsSeries());
addValue("activityPieSeries", activityPieSeries);
Set<UUID> veryActiveNow = activityNow.getOrDefault("Very Active", new HashSet<>());
@ -166,11 +166,11 @@ public class AnalysisData extends RawData {
private void commandUsage(Map<String, Integer> commandUsage) {
addValue("commandUniqueCount", String.valueOf(commandUsage.size()));
addValue("commandCount", MathUtils.sumInt(commandUsage.values().stream().map(i -> (int) i)));
addValue("tableBodyCommands", HtmlUtils.removeXSS(CommandUseTableCreator.createTable(commandUsage)));
addValue("tableBodyCommands", new CommandUseTable(commandUsage).parseBody());
}
private void geolocationsTab(List<String> geoLocations) {
addValue("geoMapSeries", WorldMap.createSeries(geoLocations));
addValue("geoMapSeries", new WorldMap(geoLocations).toHighChartsSeries());
}
private void onlineActivityNumbers(ServerProfile profile, Map<UUID, List<Session>> sessions, List<PlayerProfile> players) {
@ -285,7 +285,7 @@ public class AnalysisData extends RawData {
addValue("tableBodySessions", tables[0]);
addValue("listRecentLogins", tables[1]);
addValue("sessionAverage", FormatUtils.formatTimeAmount(MathUtils.averageLong(allSessions.stream().map(Session::getLength))));
addValue("punchCardSeries", PunchCardGraph.createSeries(sessionsMonth));
addValue("punchCardSeries", new PunchCardGraph(sessionsMonth).toHighChartsSeries());
addValue("deaths", ServerProfile.getDeathCount(allSessions));
addValue("mobKillCount", ServerProfile.getMobKillCount(allSessions));
@ -302,9 +302,9 @@ public class AnalysisData extends RawData {
Html.TABLE_PLAYERS_FOOTER.parse(playersTableBody)
: Html.TABLE_PLAYERS.parse(playersTableBody));
addValue("worldTotal", FormatUtils.formatTimeAmount(worldTimes.getTotal()));
String[] seriesData = WorldPie.createSeries(worldTimes);
addValue("worldSeries", seriesData[0]);
addValue("gmSeries", seriesData[1]);
WorldPie worldPie = new WorldPie(worldTimes);
addValue("worldSeries", worldPie.toHighChartsSeries());
addValue("gmSeries", worldPie.toHighChartsDrilldown());
addValue("lastPeakTime", lastPeak != -1 ? FormatUtils.formatTimeStampYear(lastPeak) : "No Data");
addValue("playersLastPeak", lastPeak != -1 ? profile.getLastPeakPlayers() : "-");
addValue("bestPeakTime", allTimePeak != -1 ? FormatUtils.formatTimeStampYear(allTimePeak) : "No Data");
@ -319,12 +319,12 @@ public class AnalysisData extends RawData {
addValue("tpsSpikeWeek", value("tpsSpikeWeek"));
addValue("tpsSpikeDay", value("tpsSpikeDay"));
addValue("playersOnlineSeries", PlayerActivityGraph.createSeries(tpsData));
addValue("tpsSeries", TPSGraph.createSeries(tpsData));
addValue("cpuSeries", CPUGraph.createSeries(tpsData));
addValue("ramSeries", RamGraph.createSeries(tpsData));
addValue("entitySeries", WorldLoadGraph.createSeriesEntities(tpsData));
addValue("chunkSeries", WorldLoadGraph.createSeriesChunks(tpsData));
addValue("playersOnlineSeries", new OnlineActivityGraph(tpsData).toHighChartsSeries());
addValue("tpsSeries", new TPSGraph(tpsData).toHighChartsSeries());
addValue("cpuSeries", new CPUGraph(tpsData).toHighChartsSeries());
addValue("ramSeries", new RamGraph(tpsData).toHighChartsSeries());
addValue("entitySeries", new EntityGraph(tpsData).toHighChartsSeries());
addValue("chunkSeries", new ChunkGraph(tpsData).toHighChartsSeries());
double averageCPUMonth = MathUtils.averageDouble(tpsDataMonth.stream().map(TPS::getCPUUsage).filter(i -> i != 0));
double averageCPUWeek = MathUtils.averageDouble(tpsDataWeek.stream().map(TPS::getCPUUsage).filter(i -> i != 0));

View File

@ -2,14 +2,13 @@
* 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.plan.data.element;
package com.djrapitops.plan.data.calculation;
import com.djrapitops.plan.data.AnalysisData;
import com.djrapitops.plan.data.PlayerProfile;
import com.djrapitops.plan.data.ServerProfile;
import com.djrapitops.plan.data.container.StickyData;
import com.djrapitops.plan.data.container.TPS;
import com.djrapitops.plan.settings.Settings;
import com.djrapitops.plan.system.settings.Settings;
import com.djrapitops.plan.utilities.FormatUtils;
import com.djrapitops.plan.utilities.analysis.MathUtils;
import com.djrapitops.plan.utilities.html.Html;
@ -25,17 +24,16 @@ import java.util.stream.Collectors;
*/
public class HealthNotes {
private final List<String> healthNotes;
private double serverHealth;
private final List<String> notes;
private final AnalysisData analysisData;
private final TreeMap<Long, Map<String, Set<UUID>>> activityData;
private final SortedMap<Long, Map<String, Set<UUID>>> activityData;
private final List<TPS> tpsDataMonth;
private final long now;
private final long fourWeeksAgo;
private double serverHealth;
public HealthNotes(AnalysisData analysisData, TreeMap<Long, Map<String, Set<UUID>>> activityData, List<TPS> tpsDataMonth, long now) {
this.healthNotes = new ArrayList<>();
public HealthNotes(AnalysisData analysisData, SortedMap<Long, Map<String, Set<UUID>>> activityData, List<TPS> tpsDataMonth, long now) {
this.notes = new ArrayList<>();
serverHealth = 100.0;
this.analysisData = analysisData;
@ -54,7 +52,7 @@ public class HealthNotes {
public String parse() {
StringBuilder healthNoteBuilder = new StringBuilder();
for (String healthNote : healthNotes) {
for (String healthNote : notes) {
healthNoteBuilder.append(healthNote);
}
return healthNoteBuilder.toString();
@ -107,20 +105,20 @@ public class HealthNotes {
+ remain + "/" + activeFWAGNum + ")";
}
if (change > 0) {
healthNotes.add(
notes.add(
"<p>" + Html.GREEN_THUMB.parse() + " Number of regular players has increased (+" + change + ")<br>" +
remainNote + "</p>");
} else if (change == 0) {
healthNotes.add(
notes.add(
"<p>" + Html.GREEN_THUMB.parse() + " Number of regular players has stayed the same (+" + change + ")<br>" +
remainNote + "</p>");
} else if (change > -20) {
healthNotes.add(
notes.add(
"<p>" + Html.YELLOW_FLAG.parse() + " Number of regular players has decreased (" + change + ")<br>" +
remainNote + "</p>");
serverHealth -= 5;
} else {
healthNotes.add(
notes.add(
"<p>" + Html.RED_WARN.parse() + " Number of regular players has decreased (" + change + ")<br>" +
remainNote + "</p>");
serverHealth -= 10;
@ -130,10 +128,10 @@ public class HealthNotes {
private void newPlayerNote() {
double avgOnlineOnRegister = MathUtils.averageInt(analysisData.getStickyMonthData().stream().map(StickyData::getOnlineOnJoin));
if (avgOnlineOnRegister >= 1) {
healthNotes.add("<p>" + Html.GREEN_THUMB.parse() + " New Players have players to play with when they join ("
notes.add("<p>" + Html.GREEN_THUMB.parse() + " New Players have players to play with when they join ("
+ FormatUtils.cutDecimals(avgOnlineOnRegister) + " on average)</p>");
} else {
healthNotes.add("<p>" + Html.YELLOW_FLAG.parse() + " New Players may not have players to play with when they join ("
notes.add("<p>" + Html.YELLOW_FLAG.parse() + " New Players may not have players to play with when they join ("
+ FormatUtils.cutDecimals(avgOnlineOnRegister) + " on average)</p>");
serverHealth -= 5;
}
@ -144,10 +142,10 @@ public class HealthNotes {
if (newM != 0) {
double stuckPerc = MathUtils.averageDouble(stuckPerM, newM) * 100;
if (stuckPerc >= 25) {
healthNotes.add("<p>" + Html.GREEN_THUMB.parse() + " " + FormatUtils.cutDecimals(stuckPerc)
notes.add("<p>" + Html.GREEN_THUMB.parse() + " " + FormatUtils.cutDecimals(stuckPerc)
+ "% of new players have stuck around (" + stuckPerM + "/" + newM + ")</p>");
} else {
healthNotes.add("<p>" + Html.YELLOW_FLAG.parse() + " " + FormatUtils.cutDecimals(stuckPerc)
notes.add("<p>" + Html.YELLOW_FLAG.parse() + " " + FormatUtils.cutDecimals(stuckPerc)
+ "% of new players have stuck around (" + stuckPerM + "/" + newM + ")</p>");
}
}
@ -155,7 +153,7 @@ public class HealthNotes {
private void activePlayerPlaytimeChange() {
List<PlayerProfile> currentActivePlayers = analysisData.getPlayers().stream()
.filter(player -> player.getActivityIndex(now) >= 1.75)
.filter(player -> player.getActivityIndex(now).getValue() >= 1.75)
.collect(Collectors.toList());
long twoWeeksAgo = now - TimeAmount.WEEK.ms() * 2L;
@ -173,16 +171,16 @@ public class HealthNotes {
String avgLastTwoWeeksString = FormatUtils.formatTimeAmount(avgLastTwoWeeks);
String avgFourToTwoWeeksString = FormatUtils.formatTimeAmount(avgFourToTwoWeeks);
if (avgFourToTwoWeeks >= avgLastTwoWeeks) {
healthNotes.add("<p>" + Html.GREEN_THUMB.parse() + " Active players seem to have things to do (Played "
notes.add("<p>" + Html.GREEN_THUMB.parse() + " Active players seem to have things to do (Played "
+ avgLastTwoWeeksString + " vs " + avgFourToTwoWeeksString
+ ", last two weeks vs weeks 2-4)</p>");
} else if (avgFourToTwoWeeks - avgLastTwoWeeks > TimeAmount.HOUR.ms() * 2L) {
healthNotes.add("<p>" + Html.RED_WARN.parse() + " Active players might be running out of things to do (Played "
notes.add("<p>" + Html.RED_WARN.parse() + " Active players might be running out of things to do (Played "
+ avgLastTwoWeeksString + " vs " + avgFourToTwoWeeksString
+ ", last two weeks vs weeks 2-4)</p>");
serverHealth -= 5;
} else {
healthNotes.add("<p>" + Html.YELLOW_FLAG.parse() + " Active players might be running out of things to do (Played "
notes.add("<p>" + Html.YELLOW_FLAG.parse() + " Active players might be running out of things to do (Played "
+ avgLastTwoWeeksString + " vs " + avgFourToTwoWeeksString
+ ", last two weeks vs weeks 2-4)</p>");
}
@ -208,18 +206,18 @@ public class HealthNotes {
+ FormatUtils.cutDecimals(aboveThreshold * 100.0) + "% of the time";
if (tpsSpikeMonth <= 5) {
healthNotes.add("<p>" + Html.GREEN_THUMB.parse()
notes.add("<p>" + Html.GREEN_THUMB.parse()
+ " Average TPS dropped below Low Threshold (" + Settings.THEME_GRAPH_TPS_THRESHOLD_MED.getNumber() + ")" +
" " + tpsSpikeMonth + " times<br>" +
avgLowThresholdString + "</p>");
} else if (tpsSpikeMonth <= 25) {
healthNotes.add("<p>" + Html.YELLOW_FLAG.parse()
notes.add("<p>" + Html.YELLOW_FLAG.parse()
+ " Average TPS dropped below Low Threshold (" + Settings.THEME_GRAPH_TPS_THRESHOLD_MED.getNumber() + ")" +
" " + tpsSpikeMonth + " times<br>" +
avgLowThresholdString + "</p>");
serverHealth *= 0.95;
} else {
healthNotes.add("<p>" + Html.RED_WARN.parse()
notes.add("<p>" + Html.RED_WARN.parse()
+ " Average TPS dropped below Low Threshold (" + Settings.THEME_GRAPH_TPS_THRESHOLD_MED.getNumber() + ")" +
" " + tpsSpikeMonth + " times<br>" +
avgLowThresholdString + "</p>");
@ -227,14 +225,14 @@ public class HealthNotes {
}
if (serverDownTime <= TimeAmount.DAY.ms()) {
healthNotes.add("<p>" + Html.GREEN_THUMB.parse() + " Total Server downtime (No Data) was "
notes.add("<p>" + Html.GREEN_THUMB.parse() + " Total Server downtime (No Data) was "
+ FormatUtils.formatTimeAmount(serverDownTime) + "</p>");
} else if (serverDownTime <= TimeAmount.WEEK.ms()) {
healthNotes.add("<p>" + Html.YELLOW_FLAG.parse() + " Total Server downtime (No Data) was "
notes.add("<p>" + Html.YELLOW_FLAG.parse() + " Total Server downtime (No Data) was "
+ FormatUtils.formatTimeAmount(serverDownTime) + "</p>");
serverHealth *= (TimeAmount.WEEK.ms() - serverDownTime) * 1.0 / TimeAmount.WEEK.ms();
} else {
healthNotes.add("<p>" + Html.RED_WARN.parse() + " Total Server downtime (No Data) was "
notes.add("<p>" + Html.RED_WARN.parse() + " Total Server downtime (No Data) was "
+ FormatUtils.formatTimeAmount(serverDownTime) + "</p>");
serverHealth *= (TimeAmount.MONTH.ms() - serverDownTime) * 1.0 / TimeAmount.MONTH.ms();
}

View File

@ -1,4 +1,4 @@
package com.djrapitops.plan.data;
package com.djrapitops.plan.data.calculation;
import com.djrapitops.plugin.utilities.Verify;

View File

@ -1,11 +1,10 @@
/*
/*
* 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.plan.data.container;
import com.djrapitops.plan.data.HasDate;
import com.djrapitops.plan.database.tables.Actions;
import com.djrapitops.plan.data.Actions;
import com.djrapitops.plan.utilities.FormatUtils;
import com.djrapitops.plan.utilities.html.Html;
@ -16,7 +15,7 @@ import java.util.Objects;
*
* @author Rsl1122
*/
public class Action implements HasDate {
public class Action {
private final long date;
private final Actions doneAction;
private final String additionalInfo;

View File

@ -1,10 +1,9 @@
/*
/*
* 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.plan.data.container;
import com.djrapitops.plan.data.HasDate;
import com.google.common.base.Objects;
/**
@ -12,7 +11,7 @@ import com.google.common.base.Objects;
*
* @author Rsl1122
*/
public class GeoInfo implements HasDate {
public class GeoInfo {
private final String ip;
private final String geolocation;
@ -36,11 +35,6 @@ public class GeoInfo implements HasDate {
return lastUsed;
}
@Override
public long getDate() {
return getLastUsed();
}
@Override
public boolean equals(Object o) {
if (this == o) return true;

View File

@ -1,9 +1,7 @@
package com.djrapitops.plan.data.container;
import com.djrapitops.plan.Plan;
import com.djrapitops.plan.data.HasDate;
import com.djrapitops.plan.database.tables.Actions;
import org.apache.commons.lang3.builder.ToStringBuilder;
import com.djrapitops.plan.data.Actions;
import com.djrapitops.plan.system.cache.DataCache;
import java.util.Objects;
import java.util.UUID;
@ -14,7 +12,7 @@ import java.util.UUID;
*
* @author Rsl1122
*/
public class PlayerKill implements HasDate {
public class PlayerKill {
private final UUID victim;
private final long time;
@ -51,11 +49,6 @@ public class PlayerKill implements HasDate {
return time;
}
@Override
public long getDate() {
return getTime();
}
/**
* Get the Weapon used as string.
*
@ -66,7 +59,7 @@ public class PlayerKill implements HasDate {
}
public Action convertToAction() {
String name = Plan.getInstance().getDataCache().getName(victim);
String name = DataCache.getInstance().getName(victim);
return new Action(time, Actions.KILLED, name + " with " + weapon);
}
@ -87,10 +80,9 @@ public class PlayerKill implements HasDate {
@Override
public String toString() {
return new ToStringBuilder(this)
.append("victim", victim)
.append("time", time)
.append("weapon", weapon)
.toString();
return "PlayerKill{" +
"victim=" + victim + ", " +
"time=" + time + ", " +
"weapon='" + weapon + "'}";
}
}

View File

@ -1,9 +1,7 @@
package com.djrapitops.plan.data.container;
import com.djrapitops.plan.data.HasDate;
import com.djrapitops.plan.data.time.WorldTimes;
import com.djrapitops.plan.utilities.MiscUtils;
import org.apache.commons.lang3.builder.ToStringBuilder;
import java.util.ArrayList;
import java.util.HashMap;
@ -28,7 +26,7 @@ import java.util.Objects;
*
* @author Rsl1122
*/
public class Session implements HasDate {
public class Session {
private final long sessionStart;
private Integer sessionID;
@ -68,18 +66,6 @@ public class Session implements HasDate {
this.deaths = deaths;
}
/**
* Starts a new Session.
*
* @param time Time the session started.
* @param world World the session started in.
* @param gm GameMode the session started in.
* @return a new Session object.
*/
public static Session start(long time, String world, String gm) {
return new Session(time, world, gm);
}
/**
* Ends the session with given end point.
* <p>
@ -207,19 +193,13 @@ public class Session implements HasDate {
@Override
public String toString() {
return new ToStringBuilder(this)
.append("sessionStart", sessionStart)
.append("sessionID", sessionID)
.append("worldTimes", worldTimes)
.append("sessionEnd", sessionEnd)
.append("playerKills", playerKills)
.append("mobKills", mobKills)
.append("deaths", deaths)
.toString();
}
@Override
public long getDate() {
return getSessionStart();
return "Session{" +
"sessionStart=" + sessionStart + ", " +
"sessionID=" + sessionID + ", " +
"worldTimes=" + worldTimes + ", " +
"sessionEnd=" + sessionEnd + ", " +
"playerKills=" + playerKills + ", " +
"mobKills=" + mobKills + ", " +
"deaths=" + deaths + '}';
}
}

View File

@ -4,40 +4,40 @@
*/
package com.djrapitops.plan.data.container;
import com.djrapitops.plan.data.Actions;
import com.djrapitops.plan.data.PlayerProfile;
import com.djrapitops.plan.database.tables.Actions;
import com.djrapitops.plugin.api.TimeAmount;
import com.google.common.base.Objects;
import java.util.List;
public class StickyData {
private final double activityIndex;
private Integer messagesSent;
private Integer onlineOnJoin;
public StickyData(PlayerProfile player) {
activityIndex = player.getActivityIndex(player.getRegistered() + TimeAmount.DAY.ms());
for (Action action : player.getActions()) {
if (messagesSent == null && action.getDoneAction() == Actions.FIRST_LOGOUT) {
String additionalInfo = action.getAdditionalInfo();
String[] split = additionalInfo.split(": ");
if (split.length == 2) {
try {
messagesSent = Integer.parseInt(split[1]);
} catch (NumberFormatException ignored) {
}
activityIndex = player.getActivityIndex(player.getRegistered() + TimeAmount.DAY.ms()).getValue();
loadActionVariables(player.getActions());
}
private void loadActionVariables(List<Action> actions) {
for (Action action : actions) {
try {
if (messagesSent == null && action.getDoneAction() == Actions.FIRST_LOGOUT) {
messagesSent = loadSentMessages(action);
}
}
if (onlineOnJoin == null && action.getDoneAction() == Actions.FIRST_SESSION) {
String additionalInfo = action.getAdditionalInfo();
String[] split = additionalInfo.split(" ");
if (split.length == 3) {
try {
onlineOnJoin = Integer.parseInt(split[1]);
} catch (NumberFormatException ignored) {
}
if (onlineOnJoin == null && action.getDoneAction() == Actions.FIRST_SESSION) {
onlineOnJoin = loadOnlineOnJoin(action);
}
} catch (IllegalArgumentException ignore) {
/* continue */
}
}
setDefaultValuesIfNull();
}
private void setDefaultValuesIfNull() {
if (messagesSent == null) {
messagesSent = 0;
}
@ -46,6 +46,24 @@ public class StickyData {
}
}
private int loadOnlineOnJoin(Action action) {
String additionalInfo = action.getAdditionalInfo();
String[] split = additionalInfo.split(" ");
if (split.length == 3) {
return Integer.parseInt(split[1]);
}
throw new IllegalArgumentException("Improper Action");
}
private int loadSentMessages(Action action) {
String additionalInfo = action.getAdditionalInfo();
String[] split = additionalInfo.split(": ");
if (split.length == 2) {
return Integer.parseInt(split[1]);
}
throw new IllegalArgumentException("Improper Action");
}
public double distance(StickyData data) {
double num = 0;
num += Math.abs(data.activityIndex - activityIndex) * 2.0;

View File

@ -5,9 +5,6 @@
*/
package com.djrapitops.plan.data.container;
import com.djrapitops.plan.data.HasDate;
import org.apache.commons.lang3.builder.ToStringBuilder;
import java.util.Objects;
/**
@ -16,7 +13,7 @@ import java.util.Objects;
* @author Rsl1122
* @since 3.5.0
*/
public class TPS implements HasDate {
public class TPS {
private final long date;
private final double ticksPerSecond;
@ -131,14 +128,13 @@ public class TPS implements HasDate {
@Override
public String toString() {
return new ToStringBuilder(this)
.append("date", date)
.append("ticksPerSecond", ticksPerSecond)
.append("players", players)
.append("cpuUsage", cpuUsage)
.append("usedMemory", usedMemory)
.append("entityCount", entityCount)
.append("chunksLoaded", chunksLoaded)
.toString();
return "TPS{" +
"date=" + date + ", " +
"ticksPerSecond=" + ticksPerSecond + ", " +
"players=" + players + ", " +
"cpuUsage=" + cpuUsage + ", " +
"usedMemory=" + usedMemory + ", " +
"entityCount=" + entityCount + ", " +
"chunksLoaded=" + chunksLoaded + '}';
}
}

View File

@ -38,18 +38,10 @@ public class UserInfo {
return name;
}
public void setName(String name) {
this.name = name;
}
public long getRegistered() {
return registered;
}
public void setRegistered(long registered) {
this.registered = registered;
}
public long getLastSeen() {
return lastSeen;
}
@ -62,10 +54,6 @@ public class UserInfo {
return banned;
}
public void setBanned(boolean banned) {
this.banned = banned;
}
public boolean isOpped() {
return opped;
}

View File

@ -0,0 +1,97 @@
/*
* 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.plan.data.container.builders;
import com.djrapitops.plan.data.container.TPS;
/**
* Builder for TPS to make it easier to manage.
*
* @author Rsl1122
*/
public class TPSBuilder {
protected long date = 0;
protected double ticksPerSecond = -1;
protected int players = -1;
protected double cpuUsage = -1;
protected long usedMemory = -1;
protected int entityCount = -1;
protected int chunksLoaded = -1;
/**
* Hides constructor.
*/
private TPSBuilder() {
}
public static TPSBuilder.Date get() {
return new TPSBuilder.Chunks();
}
public TPS toTPS() {
return new TPS(date, ticksPerSecond, players, cpuUsage, usedMemory, entityCount, chunksLoaded);
}
public static class Date extends TPSBuilder {
public Ticks date(long date) {
this.date = date;
return (Ticks) this;
}
}
public static class Ticks extends Date {
public Players tps(double tps) {
ticksPerSecond = tps;
return (Players) this;
}
public Players skipTPS() {
return (Players) this;
}
}
public static class Players extends Ticks {
public CPU playersOnline(int online) {
players = online;
return (CPU) this;
}
}
public static class CPU extends Players {
public Memory usedCPU(double cpu) {
cpuUsage = cpu;
return (Memory) this;
}
}
public static class Memory extends CPU {
public Entities usedMemory(long ram) {
usedMemory = ram;
return (Entities) this;
}
}
public static class Entities extends Memory {
public Chunks entities(int count) {
entityCount = count;
return (Chunks) this;
}
}
public static class Chunks extends Entities {
public TPSBuilder chunksLoaded(int chunksLoaded) {
this.chunksLoaded = chunksLoaded;
return this;
}
}
}

View File

@ -1,4 +1,4 @@
/*
/*
* 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
*/

View File

@ -1,4 +1,4 @@
/*
/*
* 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
*/
@ -69,6 +69,11 @@ public class InspectContainer {
return html.toString();
}
/**
* Check if InspectContainer has only values, and not HTML or Tables.
*
* @return true/false
*/
public final boolean hasOnlyValues() {
return html.isEmpty() && tables.isEmpty();
}

View File

@ -1,4 +1,4 @@
/*
/*
* 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
*/
@ -16,11 +16,13 @@ import java.util.List;
*
* @author Rsl1122
*/
public final class TableContainer {
public class TableContainer {
private final String[] header;
private List<Serializable[]> values;
private boolean jqueryDatatable;
private String color;
/**
@ -38,18 +40,18 @@ public final class TableContainer {
values = new ArrayList<>();
}
public void addRow(Serializable... values) {
public final void addRow(Serializable... values) {
this.values.add(values);
}
public String parseHtml() {
return Html.TABLE_SCROLL.parse() +
public final String parseHtml() {
return getTableHeader() +
parseHeader() +
parseBody() +
"</table>";
}
private String parseBody() {
public final String parseBody() {
StringBuilder body = new StringBuilder();
if (values.isEmpty()) {
@ -73,11 +75,11 @@ public final class TableContainer {
return Html.TABLE_BODY.parse(body.toString());
}
public void setColor(String color) {
public final void setColor(String color) {
this.color = color;
}
public String parseHeader() {
public final String parseHeader() {
StringBuilder header = new StringBuilder("<thead" + (color != null ? " class=\"bg-" + color + "\"" : "") + "><tr>");
for (String title : this.header) {
header.append("<th>").append(title).append("</th>");
@ -85,4 +87,21 @@ public final class TableContainer {
header.append("</tr></thead>");
return header.toString();
}
/**
* Make use of JQuery Datatables plugin.
* <p>
* If this is called, result of {@code parseHtml()} should be wrapped with {@code Html.PANEL.parse(Html.PANEL_BODY.parse(result))}
*/
public void useJqueryDataTables() {
this.jqueryDatatable = true;
}
private String getTableHeader() {
if (jqueryDatatable) {
return "<div class=\"table-responsive\">" + Html.TABLE_JQUERY.parse() + "</div>";
} else {
return Html.TABLE_SCROLL.parse();
}
}
}

View File

@ -1,4 +1,4 @@
/*
/*
* 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
*/

View File

@ -1,4 +1,4 @@
/*
/*
* 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
*/

View File

@ -1,12 +1,15 @@
package com.djrapitops.plan.data.plugin;
import com.djrapitops.plan.Plan;
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.pluginbridge.plan.Bridge;
import java.util.ArrayList;
import java.util.List;
import java.util.*;
/**
* Class responsible for hooking to other plugins and managing the %plugins%
@ -15,27 +18,37 @@ import java.util.List;
* @author Rsl1122
* @since 2.6.0
*/
public class HookHandler {
public class HookHandler implements SubSystem {
private final List<PluginData> additionalDataSources;
private final PluginsConfigSection configHandler;
private PluginsConfigSection configHandler;
/**
* Class constructor, hooks to plugins.
*
* @param plugin Current instance of plan.
*/
public HookHandler(Plan plugin) {
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);
} catch (Exception e) {
Log.toLog(this.getClass().getName(), e);
Log.toLog(this.getClass(), e);
Log.error("Plan Plugin Bridge not included in the plugin jar.");
}
}
@Override
public void disable() {
}
/**
* Adds a new PluginData source to the list.
* <p>
@ -60,7 +73,7 @@ public class HookHandler {
additionalDataSources.add(dataSource);
}
} catch (Exception e) {
Log.toLog(this.getClass().getName(), e);
Log.toLog(this.getClass(), e);
Log.error("Attempting to register PluginDataSource caused an exception.");
}
}
@ -73,4 +86,23 @@ public class HookHandler {
public List<PluginData> getAdditionalDataSources() {
return additionalDataSources;
}
public Map<PluginData, InspectContainer> getInspectContainersFor(UUID uuid) {
List<PluginData> plugins = getAdditionalDataSources();
Map<PluginData, InspectContainer> containers = new HashMap<>();
for (PluginData pluginData : plugins) {
InspectContainer inspectContainer = new InspectContainer();
try {
InspectContainer container = pluginData.getPlayerData(uuid, inspectContainer);
if (container != null && !container.isEmpty()) {
containers.put(pluginData, container);
}
} catch (Exception | NoClassDefFoundError | NoSuchFieldError | NoSuchMethodError e) {
String sourcePlugin = pluginData.getSourcePlugin();
Log.error("PluginData caused exception: " + sourcePlugin);
Log.toLog(this.getClass().getName() + " " + sourcePlugin, e);
}
}
return containers;
}
}

View File

@ -1,6 +1,6 @@
package com.djrapitops.plan.data.plugin;
import com.djrapitops.plan.systems.file.config.ConfigSystem;
import com.djrapitops.plan.system.settings.config.ConfigSystem;
import com.djrapitops.plugin.api.config.ConfigNode;
import com.djrapitops.plugin.api.utility.log.Log;
@ -23,7 +23,7 @@ public class PluginsConfigSection {
}
private ConfigNode getPluginsSection() {
return ConfigSystem.getInstance().getConfig().getConfigNode("Plugins");
return ConfigSystem.getConfig().getConfigNode("Plugins");
}
public void createSection(PluginData dataSource) {
@ -35,7 +35,7 @@ public class PluginsConfigSection {
section.sort();
section.save();
} catch (IOException e) {
Log.toLog(this.getClass().getName(), e);
Log.toLog(this.getClass(), e);
}
}

View File

@ -1,7 +1,6 @@
package com.djrapitops.plan.data.time;
import com.djrapitops.plugin.utilities.Verify;
import org.apache.commons.lang3.builder.ToStringBuilder;
import java.util.HashMap;
import java.util.Map;
@ -155,10 +154,7 @@ public abstract class TimeKeeper {
@Override
public String toString() {
return new ToStringBuilder(this)
.append("times", times)
.append("state", state)
.append("lastStateChange", lastStateChange)
.toString();
return "TimeKeeper{" + "times=" + times +
", state='" + state + "', lastStateChange=" + lastStateChange + '}';
}
}

View File

@ -1,43 +0,0 @@
package com.djrapitops.plan.database;
/**
* Class to contain objects in the batches.
*
* @param <T> Object stored.
* @author Rsl1122
* @since 3.4.3
*/
public class Container<T> {
private final T object;
private final int id;
/**
* Constructor for the object.
*
* @param object Object to place inside the container.
* @param id UserID related to the object.
*/
public Container(T object, int id) {
this.object = object;
this.id = id;
}
/**
* Get the object in the container.
*
* @return object.
*/
public T getObject() {
return object;
}
/**
* Get the UserID related to the object.
*
* @return userID
*/
public int getId() {
return id;
}
}

View File

@ -1,110 +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.database;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
/**
* Class containing static utility methods used by the Database classes.
*
* @author Rsl1122
* @since 3.4.3
*/
public class DBUtils {
private static final int BATCH_SIZE = 10192;
/**
* Constructor used to hide the public constructor
*/
private DBUtils() {
throw new IllegalStateException("Utility class");
}
/**
* Splits a collection of objects into lists with the size defined by
* BATCH_SIZE.
*
* @param <T> Object type
* @param objects Collection of the objects
* @return Lists with max size of BATCH_SIZE
*/
public static <T> List<List<T>> splitIntoBatches(Collection<T> objects) {
List<List<T>> batches = new ArrayList<>();
int i = 0;
int j = 0;
for (T obj : objects) {
if (batches.size() <= j) {
batches.add(new ArrayList<>());
}
batches.get(j).add(obj);
i++;
if (i % BATCH_SIZE == 0) {
j++;
}
}
return batches;
}
/**
* @param <T> Object type
* @param objects Collection of the objects
* @return Lists with max size of BATCH_SIZE
*/
public static <T> List<List<Container<T>>> splitIntoBatchesId(Map<Integer, List<T>> objects) {
List<List<Container<T>>> wrappedBatches = new ArrayList<>();
int i = 0;
int j = 0;
for (Entry<Integer, List<T>> entry : objects.entrySet()) {
for (T object : entry.getValue()) {
if (wrappedBatches.size() <= j) {
wrappedBatches.add(new ArrayList<>());
}
wrappedBatches.get(j).add(new Container<>(object, entry.getKey()));
i++;
if (i % BATCH_SIZE == 0) {
j++;
}
}
}
return wrappedBatches;
}
/**
* @param <T> Object type
* @param objects Collection of the objects
* @return Lists with max size of BATCH_SIZE
*/
public static <T> List<List<Container<T>>> splitIntoBatchesWithID(Map<Integer, T> objects) {
List<List<Container<T>>> wrappedBatches = new ArrayList<>();
int i = 0;
int j = 0;
for (Entry<Integer, T> entry : objects.entrySet()) {
T object = entry.getValue();
if (wrappedBatches.size() <= j) {
wrappedBatches.add(new ArrayList<>());
}
wrappedBatches.get(j).add(new Container<>(object, entry.getKey()));
i++;
if (i % BATCH_SIZE == 0) {
j++;
}
}
return wrappedBatches;
}
}

View File

@ -1,269 +0,0 @@
package com.djrapitops.plan.database;
import com.djrapitops.plan.api.exceptions.DatabaseInitException;
import com.djrapitops.plan.data.PlayerProfile;
import com.djrapitops.plan.data.ServerProfile;
import com.djrapitops.plan.database.tables.*;
import org.apache.commons.lang3.StringUtils;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
/**
* Abstract class representing a Database.
* <p>
* All methods should be only called from an asynchronous thread, unless stated
* otherwise.
*
* @author Rsl1122
*/
public abstract class Database {
protected UsersTable usersTable;
protected UserInfoTable userInfoTable;
protected ActionsTable actionsTable;
protected KillsTable killsTable;
protected NicknamesTable nicknamesTable;
protected SessionsTable sessionsTable;
protected IPsTable ipsTable;
protected CommandUseTable commandUseTable;
protected TPSTable tpsTable;
protected VersionTable versionTable;
protected SecurityTable securityTable;
protected WorldTable worldTable;
protected WorldTimesTable worldTimesTable;
protected ServerTable serverTable;
/**
* Super constructor.
*/
public Database() {
}
/**
* Initiates the database.
*
* @throws DatabaseInitException if SQLException or other exception occurs.
*/
public void init() throws DatabaseInitException {
}
/**
* Condition if the user is saved in the database.
*
* @param uuid UUID of the user.
* @return true/false
*/
public abstract boolean wasSeenBefore(UUID uuid);
/**
* Used to get the name of the database type.
* <p>
* Thread safe.
*
* @return SQLite/MySQL
*/
public abstract String getName();
/**
* Used to get the config name of the database type.
* <p>
* Thread safe.
*
* @return sqlite/mysql
*/
public String getConfigName() {
return StringUtils.remove(getName().toLowerCase(), ' ');
}
public abstract boolean isNewDatabase() throws SQLException;
/**
* Used to get the database schema version.
*
* @return Integer starting from 0, incremented by one when schema is
* updated.
* @throws SQLException If a database error occurs.
*/
public abstract int getVersion() throws SQLException;
/**
* Used to set the database schema version.
*
* @param version Integer starting from 0, incremented by one when schema is
* updated.
* @throws SQLException If a database error occurs.
*/
public abstract void setVersion(int version) throws SQLException;
/**
* Closes the database and it's resources.
*
* @throws SQLException If a database error occurs.
*/
public abstract void close() throws SQLException;
/**
* Returns a connection to the MySQL connection pool.
* <p>
* On SQLite does nothing.
*
* @param connection Connection to return.
* @throws SQLException DB Error
*/
public abstract void returnToPool(Connection connection) throws SQLException;
/**
* Removes all data related to an account from the database.
*
* @param uuid UUID of the account.
* @throws SQLException If a database error occurs.
*/
public abstract void removeAccount(UUID uuid) throws SQLException;
/**
* Used to clear all data from the database.
* <p>
* Uses DELETE * FROM table.
*
* @throws SQLException if remove fails.
*/
public abstract void removeAllData() throws SQLException;
/**
* Used to fetch the saved UUIDs in the users table.
*
* @return Set of saved UUIDs
* @throws SQLException If a database error occurs.
*/
public Set<UUID> getSavedUUIDs() throws SQLException {
return usersTable.getSavedUUIDs();
}
/**
* Used to get the Command usage mep.
*
* @return String command (key), Integer times used
* @throws SQLException If a database error occurs.
*/
public Map<String, Integer> getCommandUse() throws SQLException {
return commandUseTable.getCommandUse();
}
/**
* Used to get the users table.
*
* @return Table representing plan_users
*/
public UsersTable getUsersTable() {
return usersTable;
}
/**
* Used to get the users table.
*
* @return Table representing plan_sessions
*/
public SessionsTable getSessionsTable() {
return sessionsTable;
}
/**
* Used to get the kills table.
*
* @return Table representing plan_kills
*/
public KillsTable getKillsTable() {
return killsTable;
}
/**
* Used to get the ips table.
*
* @return Table representing plan_ips
*/
public IPsTable getIpsTable() {
return ipsTable;
}
/**
* Used to get the nicknames table.
*
* @return Table representing plan_nicknames
*/
public NicknamesTable getNicknamesTable() {
return nicknamesTable;
}
/**
* Used to get the command usage table.
*
* @return Table representing plan_commandusages
*/
public CommandUseTable getCommandUseTable() {
return commandUseTable;
}
/**
* Used to get the tps table.
*
* @return Table representing plan_tps
*/
public TPSTable getTpsTable() {
return tpsTable;
}
/**
* Used to get the security table.
*
* @return Table representing plan_security
*/
public SecurityTable getSecurityTable() {
return securityTable;
}
/**
* Used to get the worlds table.
*
* @return Table representing plan_worlds
*/
public WorldTable getWorldTable() {
return worldTable;
}
/**
* Used to get the world times table.
*
* @return Table representing plan_world_times
*/
public WorldTimesTable getWorldTimesTable() {
return worldTimesTable;
}
public ServerTable getServerTable() {
return serverTable;
}
public ActionsTable getActionsTable() {
return actionsTable;
}
public UserInfoTable getUserInfoTable() {
return userInfoTable;
}
public abstract void commit(Connection connection) throws SQLException;
public boolean isUsingMySQL() {
return "mysql".equals(getConfigName());
}
public abstract PlayerProfile getPlayerProfile(UUID uuid) throws SQLException;
public abstract ServerProfile getServerProfile(UUID serverUUID) throws SQLException;
}

View File

@ -1,445 +0,0 @@
package com.djrapitops.plan.database.databases;
import com.djrapitops.plan.api.exceptions.DatabaseInitException;
import com.djrapitops.plan.data.PlayerProfile;
import com.djrapitops.plan.data.ServerProfile;
import com.djrapitops.plan.data.container.*;
import com.djrapitops.plan.database.Database;
import com.djrapitops.plan.database.tables.*;
import com.djrapitops.plan.database.tables.move.Version8TransferTable;
import com.djrapitops.plan.utilities.MiscUtils;
import com.djrapitops.plugin.api.Benchmark;
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.ITask;
import com.djrapitops.plugin.task.RunnableFactory;
import org.apache.commons.dbcp2.BasicDataSource;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.*;
/**
* Class containing main logic for different data related save and load functionality.
*
* @author Rsl1122
* @since 2.0.0
*/
public abstract class SQLDB extends Database {
private final boolean usingMySQL;
private boolean open = false;
private ITask dbCleanTask;
public SQLDB() {
usingMySQL = getName().equals("MySQL");
versionTable = new VersionTable(this, usingMySQL);
serverTable = new ServerTable(this, usingMySQL);
securityTable = new SecurityTable(this, usingMySQL);
commandUseTable = new CommandUseTable(this, usingMySQL);
tpsTable = new TPSTable(this, usingMySQL);
usersTable = new UsersTable(this, usingMySQL);
userInfoTable = new UserInfoTable(this, usingMySQL);
actionsTable = new ActionsTable(this, usingMySQL);
ipsTable = new IPsTable(this, usingMySQL);
nicknamesTable = new NicknamesTable(this, usingMySQL);
sessionsTable = new SessionsTable(this, usingMySQL);
killsTable = new KillsTable(this, usingMySQL);
worldTable = new WorldTable(this, usingMySQL);
worldTimesTable = new WorldTimesTable(this, usingMySQL);
}
/**
* Initializes the Database.
* <p>
* All tables exist in the database after call to this.
* Updates Schema to latest version.
* Converts Unsaved Bukkit player files to database data.
* Cleans the database.
*
* @throws DatabaseInitException if Database fails to initiate.
*/
@Override
public void init() throws DatabaseInitException {
setStatus("Init");
String benchName = "Init " + getConfigName();
Benchmark.start("Database", benchName);
try {
setupDataSource();
setupDatabase();
open = true;
} finally {
Benchmark.stop("Database", benchName);
Log.logDebug("Database");
}
}
public void scheduleClean(long secondsDelay) {
dbCleanTask = RunnableFactory.createNew("DB Clean Task", new AbsRunnable() {
@Override
public void run() {
try {
if (isOpen()) {
clean();
}
} catch (SQLException e) {
Log.toLog(this.getClass().getName(), e);
} finally {
cancel();
}
}
}).runTaskLaterAsynchronously(TimeAmount.SECOND.ticks() * secondsDelay);
}
/**
* Ensures connection functions correctly and all tables exist.
* <p>
* Updates to latest schema.
*
* @throws DatabaseInitException if something goes wrong.
*/
public void setupDatabase() throws DatabaseInitException {
try {
boolean newDatabase = isNewDatabase();
versionTable.createTable();
createTables();
if (newDatabase) {
Log.info("New Database created.");
setVersion(13);
}
int version = getVersion();
final SQLDB db = this;
if (version < 10) {
RunnableFactory.createNew("DB v8 -> v10 Task", new AbsRunnable() {
@Override
public void run() {
try {
new Version8TransferTable(db, isUsingMySQL()).alterTablesToV10();
} catch (DatabaseInitException | SQLException e) {
Log.toLog(this.getClass().getName(), e);
}
}
}).runTaskLaterAsynchronously(TimeAmount.SECOND.ticks() * 5L);
}
if (version < 11) {
serverTable.alterTableV11();
setVersion(11);
}
if (version < 12) {
actionsTable.alterTableV12();
ipsTable.alterTableV12();
setVersion(12);
}
if (version < 13) {
ipsTable.alterTableV13();
setVersion(13);
}
} catch (SQLException e) {
throw new DatabaseInitException("Failed to set-up Database", e);
}
}
/**
* Creates the tables that contain data.
* <p>
* Updates table columns to latest schema.
*/
private void createTables() throws DatabaseInitException {
Benchmark.start("Database", "Create tables");
for (Table table : getAllTables()) {
table.createTable();
}
Benchmark.stop("Database", "Create tables");
}
/**
* Get all tables in a create order.
*
* @return Table array.
*/
public Table[] getAllTables() {
return new Table[]{
serverTable, usersTable, userInfoTable, ipsTable,
nicknamesTable, sessionsTable, killsTable,
commandUseTable, actionsTable, tpsTable,
worldTable, worldTimesTable, securityTable
};
}
/**
* Get all tables for removal of data.
*
* @return Tables in the order the data should be removed in.
*/
public Table[] getAllTablesInRemoveOrder() {
return new Table[]{
ipsTable, nicknamesTable, killsTable,
worldTimesTable, sessionsTable, actionsTable,
worldTable, userInfoTable, usersTable,
commandUseTable, tpsTable, securityTable,
serverTable
};
}
/**
* Setups the {@link BasicDataSource}
*/
public abstract void setupDataSource() throws DatabaseInitException;
/**
* Closes the SQLDB
*
* @throws SQLException DB Error
*/
@Override
public void close() throws SQLException {
setStatus("Closed");
open = false;
Log.logDebug("Database"); // Log remaining Debug info if present
if (dbCleanTask != null) {
dbCleanTask.cancel();
}
}
/**
* @return @throws SQLException
*/
@Override
public int getVersion() throws SQLException {
return versionTable.getVersion();
}
@Override
public void setVersion(int version) throws SQLException {
versionTable.setVersion(version);
}
@Override
public boolean isNewDatabase() throws SQLException {
return versionTable.isNewDatabase();
}
@Override
public PlayerProfile getPlayerProfile(UUID uuid) throws SQLException {
if (!wasSeenBefore(uuid)) {
return null;
}
String playerName = usersTable.getPlayerName(uuid);
Optional<Long> registerDate = usersTable.getRegisterDate(uuid);
if (!registerDate.isPresent()) {
throw new IllegalStateException("User has been saved with null register date to a NOT NULL column");
}
PlayerProfile profile = new PlayerProfile(uuid, playerName, registerDate.get());
profile.setTimesKicked(usersTable.getTimesKicked(uuid));
Map<UUID, UserInfo> userInfo = userInfoTable.getAllUserInfo(uuid);
addUserInfoToProfile(profile, userInfo);
profile.setActions(actionsTable.getActions(uuid));
profile.setNicknames(nicknamesTable.getAllNicknames(uuid));
profile.setGeoInformation(ipsTable.getGeoInfo(uuid));
Map<UUID, List<Session>> sessions = sessionsTable.getSessions(uuid);
profile.setSessions(sessions);
profile.calculateWorldTimesPerServer();
profile.setTotalWorldTimes(worldTimesTable.getWorldTimesOfUser(uuid));
return profile;
}
private void addUserInfoToProfile(PlayerProfile profile, Map<UUID, UserInfo> userInfo) {
for (Map.Entry<UUID, UserInfo> entry : userInfo.entrySet()) {
UUID serverUUID = entry.getKey();
UserInfo info = entry.getValue();
profile.setRegistered(serverUUID, info.getRegistered());
if (info.isBanned()) {
profile.bannedOnServer(serverUUID);
}
if (info.isOpped()) {
profile.oppedOnServer(serverUUID);
}
}
}
@Override
public ServerProfile getServerProfile(UUID serverUUID) throws SQLException {
ServerProfile profile = new ServerProfile(serverUUID);
profile.setPlayers(getPlayers(serverUUID));
profile.setTps(tpsTable.getTPSData(serverUUID));
Optional<TPS> allTimePeak = tpsTable.getAllTimePeak(serverUUID);
if (allTimePeak.isPresent()) {
TPS peak = allTimePeak.get();
profile.setAllTimePeak(peak.getDate());
profile.setAllTimePeakPlayers(peak.getPlayers());
}
Optional<TPS> lastPeak = tpsTable.getPeakPlayerCount(serverUUID, MiscUtils.getTime() - (TimeAmount.DAY.ms() * 2L));
if (lastPeak.isPresent()) {
TPS peak = lastPeak.get();
profile.setLastPeakDate(peak.getDate());
profile.setLastPeakPlayers(peak.getPlayers());
}
profile.setCommandUsage(commandUseTable.getCommandUse(serverUUID));
profile.setServerWorldtimes(worldTimesTable.getWorldTimesOfServer(serverUUID));
return profile;
}
private List<PlayerProfile> getPlayers(UUID serverUUID) throws SQLException {
List<UserInfo> serverUserInfo = userInfoTable.getServerUserInfo(serverUUID);
Map<UUID, Integer> timesKicked = usersTable.getAllTimesKicked();
Map<UUID, List<Action>> actions = actionsTable.getServerActions(serverUUID);
Map<UUID, List<GeoInfo>> geoInfo = ipsTable.getAllGeoInfo();
Map<UUID, List<Session>> sessions = sessionsTable.getSessionInfoOfServer(serverUUID);
Map<UUID, Map<UUID, List<Session>>> map = new HashMap<>();
map.put(serverUUID, sessions);
killsTable.addKillsToSessions(map);
worldTimesTable.addWorldTimesToSessions(map);
List<PlayerProfile> players = new ArrayList<>();
for (UserInfo userInfo : serverUserInfo) {
UUID uuid = userInfo.getUuid();
PlayerProfile profile = new PlayerProfile(uuid, userInfo.getName(), userInfo.getRegistered());
profile.setTimesKicked(timesKicked.getOrDefault(uuid, 0));
if (userInfo.isBanned()) {
profile.bannedOnServer(serverUUID);
}
if (userInfo.isOpped()) {
profile.oppedOnServer(serverUUID);
}
profile.setActions(actions.getOrDefault(uuid, new ArrayList<>()));
profile.setGeoInformation(geoInfo.getOrDefault(uuid, new ArrayList<>()));
profile.setSessions(serverUUID, sessions.getOrDefault(uuid, new ArrayList<>()));
players.add(profile);
}
return players;
}
@Override
public boolean wasSeenBefore(UUID uuid) {
if (uuid == null) {
return false;
}
try {
return usersTable.isRegistered(uuid);
} catch (SQLException e) {
Log.toLog(this.getClass().getName(), e);
return false;
} finally {
setAvailable();
}
}
public void removeAccount(UUID uuid) throws SQLException {
if (uuid == null) {
return;
}
try {
Log.logDebug("Database", "Removing Account: " + uuid);
Benchmark.start("Database", "Remove Account");
for (Table t : getAllTablesInRemoveOrder()) {
if (!(t instanceof UserIDTable)) {
continue;
}
UserIDTable table = (UserIDTable) t;
table.removeUser(uuid);
}
} finally {
Benchmark.stop("Database", "Remove Account");
setAvailable();
}
}
private void clean() throws SQLException {
Log.info("Cleaning the database.");
tpsTable.clean();
Log.info("Clean complete.");
}
@Override
public void removeAllData() throws SQLException {
setStatus("Clearing all data");
try {
for (Table table : getAllTablesInRemoveOrder()) {
table.removeAllData();
}
} finally {
setAvailable();
}
}
private void setStatus(String status) {
Log.logDebug("Database", status);
}
public void setAvailable() {
Log.logDebug("Database");
}
public abstract Connection getConnection() throws SQLException;
/**
* Commits changes to the .db file when using SQLite Database.
* <p>
* MySQL has Auto Commit enabled.
*/
@Override
public void commit(Connection connection) throws SQLException {
try {
if (!usingMySQL) {
connection.commit();
}
} catch (SQLException e) {
if (!e.getMessage().contains("cannot commit")) {
Log.toLog(this.getClass().getName(), e);
}
} finally {
returnToPool(connection);
}
}
@Override
public void returnToPool(Connection connection) throws SQLException {
if (usingMySQL && connection != null) {
connection.close();
}
}
/**
* Reverts transaction when using SQLite Database.
* <p>
* MySQL has Auto Commit enabled.
*/
public void rollback(Connection connection) throws SQLException {
try {
if (!usingMySQL) {
connection.rollback();
}
} finally {
returnToPool(connection);
}
}
public boolean isOpen() {
return open;
}
}

View File

@ -1,140 +0,0 @@
package com.djrapitops.plan.database.databases;
import com.djrapitops.plan.api.exceptions.DatabaseInitException;
import com.djrapitops.plan.utilities.MiscUtils;
import com.djrapitops.plugin.api.utility.log.Log;
import com.djrapitops.plugin.task.AbsRunnable;
import com.djrapitops.plugin.task.ITask;
import com.djrapitops.plugin.task.RunnableFactory;
import org.apache.commons.dbcp2.BasicDataSource;
import java.io.File;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;
/**
* @author Rsl1122
*/
public class SQLiteDB extends SQLDB {
private final String dbName;
private Connection connection;
private ITask connectionPingTask;
/**
* Class Constructor.
*/
public SQLiteDB() {
this("database");
}
public SQLiteDB(String dbName) {
this.dbName = dbName;
}
/**
* Setups the {@link BasicDataSource}
*/
@Override
public void setupDataSource() throws DatabaseInitException {
try {
connection = getNewConnection(dbName);
} catch (SQLException e) {
throw new DatabaseInitException(e);
}
startConnectionPingTask();
}
public Connection getNewConnection(String dbName) throws SQLException {
try {
Class.forName("org.sqlite.JDBC");
} catch (ClassNotFoundException e) {
Log.toLog(this.getClass().getName(), e);
return null; // Should never happen.
}
String dbFilePath = new File(MiscUtils.getIPlan().getDataFolder(), dbName + ".db").getAbsolutePath();
Connection connection;
try {
connection = DriverManager.getConnection("jdbc:sqlite:" + dbFilePath + "?journal_mode=WAL");
} catch (SQLException ignored) {
connection = DriverManager.getConnection("jdbc:sqlite:" + dbFilePath);
Log.info("SQLite WAL mode not supported on this server version, using default. This may or may not affect performance.");
}
connection.setAutoCommit(false);
// connection.
// setJournalMode(connection);
return connection;
}
private void setJournalMode(Connection connection) throws SQLException {
try (Statement statement = connection.createStatement()) {
statement.execute("");
}
}
private void startConnectionPingTask() {
stopConnectionPingTask();
// Maintains Connection.
connectionPingTask = RunnableFactory.createNew(new AbsRunnable("DBConnectionPingTask " + getName()) {
@Override
public void run() {
Statement statement = null;
try {
if (connection != null && !connection.isClosed()) {
statement = connection.createStatement();
statement.execute("/* ping */ SELECT 1");
}
} catch (SQLException e) {
try {
connection = getNewConnection(dbName);
} catch (SQLException e1) {
Log.toLog(this.getClass().getName(), e1);
Log.error("SQLite connection maintaining task had to be closed due to exception.");
this.cancel();
}
} finally {
MiscUtils.close(statement);
}
}
}).runTaskTimerAsynchronously(60L * 20L, 60L * 20L);
}
private void stopConnectionPingTask() {
if (connectionPingTask != null) {
try {
connectionPingTask.cancel();
} catch (Exception ignored) {
}
}
}
/**
* @return the name of the Database
*/
@Override
public String getName() {
return "SQLite";
}
@Override
public Connection getConnection() throws SQLException {
if (connection == null) {
connection = getNewConnection(dbName);
}
return connection;
}
@Override
public void close() throws SQLException {
stopConnectionPingTask();
MiscUtils.close(connection);
super.close();
}
}

View File

@ -0,0 +1,63 @@
/*
* 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.plan.system;
import com.djrapitops.plan.Plan;
import com.djrapitops.plan.ShutdownHook;
import com.djrapitops.plan.api.BukkitAPI;
import com.djrapitops.plan.api.exceptions.EnableException;
import com.djrapitops.plan.data.plugin.HookHandler;
import com.djrapitops.plan.system.database.BukkitDBSystem;
import com.djrapitops.plan.system.file.FileSystem;
import com.djrapitops.plan.system.info.BukkitInfoSystem;
import com.djrapitops.plan.system.info.server.BukkitServerInfo;
import com.djrapitops.plan.system.listeners.BukkitListenerSystem;
import com.djrapitops.plan.system.settings.PlanErrorManager;
import com.djrapitops.plan.system.settings.config.BukkitConfigSystem;
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;
/**
* Represents PlanSystem for Plan.
*
* @author Rsl1122
*/
public class BukkitSystem extends PlanSystem {
public BukkitSystem(Plan plugin) {
testSystem = this;
Log.setErrorManager(new PlanErrorManager());
versionCheckSystem = new VersionCheckSystem(plugin.getVersion());
fileSystem = new FileSystem(plugin);
configSystem = new BukkitConfigSystem();
databaseSystem = new BukkitDBSystem();
listenerSystem = new BukkitListenerSystem(plugin);
taskSystem = new BukkitTaskSystem(plugin);
infoSystem = new BukkitInfoSystem();
serverInfo = new BukkitServerInfo(plugin);
hookHandler = new HookHandler();
planAPI = new BukkitAPI(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();
}
}

View File

@ -0,0 +1,63 @@
/*
* 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.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.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.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;
/**
* Represents PlanSystem for PlanBungee.
*
* @author Rsl1122
*/
public class BungeeSystem extends PlanSystem {
public BungeeSystem(PlanBungee plugin) {
testSystem = this;
Log.setErrorManager(new PlanErrorManager());
versionCheckSystem = new VersionCheckSystem(plugin.getVersion());
fileSystem = new FileSystem(plugin);
configSystem = new BungeeConfigSystem();
databaseSystem = new BungeeDBSystem();
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();
}
}

View File

@ -0,0 +1,196 @@
/*
* 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.plan.system;
import com.djrapitops.plan.api.PlanAPI;
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.info.InfoSystem;
import com.djrapitops.plan.system.info.server.ServerInfo;
import com.djrapitops.plan.system.listeners.ListenerSystem;
import com.djrapitops.plan.system.processing.ProcessingQueue;
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;
/**
* PlanSystem contains everything Plan needs to run.
* <p>
* This is an abstraction layer on top of Plugin instances so that tests can be run with less mocks.
*
* @author Rsl1122
*/
public abstract class PlanSystem implements SubSystem {
protected static PlanSystem testSystem;
// Initialized in this class
protected final ProcessingQueue processingQueue;
protected final WebServerSystem webServerSystem;
protected final CacheSystem cacheSystem;
// These need to be initialized in the sub class.
protected VersionCheckSystem versionCheckSystem;
protected FileSystem fileSystem;
protected ConfigSystem configSystem;
protected DBSystem databaseSystem;
protected InfoSystem infoSystem;
protected ListenerSystem listenerSystem;
protected TaskSystem taskSystem;
protected ServerInfo serverInfo;
protected HookHandler hookHandler;
// Not a SubSystem.
protected PlanAPI planAPI;
public PlanSystem() {
processingQueue = new ProcessingQueue();
webServerSystem = new WebServerSystem();
cacheSystem = new CacheSystem(this);
}
public static PlanSystem getInstance() {
boolean bukkitAvailable = Check.isBukkitAvailable();
boolean bungeeAvailable = Check.isBungeeAvailable();
if (bukkitAvailable && bungeeAvailable) {
return testSystem;
} else if (bungeeAvailable) {
return BungeeSystem.getInstance();
} else if (bukkitAvailable) {
return BukkitSystem.getInstance();
}
throw new IllegalAccessError("PlanSystem is not available on this platform.");
}
@Override
public void enable() throws EnableException {
checkSubSystemInitialization();
SubSystem[] systems = new SubSystem[]{
versionCheckSystem,
fileSystem,
configSystem,
databaseSystem,
webServerSystem,
processingQueue,
serverInfo,
infoSystem,
cacheSystem,
listenerSystem,
taskSystem,
hookHandler
};
for (SubSystem system : systems) {
system.enable();
}
}
@Override
public void disable() {
SubSystem[] systems = new SubSystem[]{
taskSystem,
hookHandler,
cacheSystem,
listenerSystem,
processingQueue,
databaseSystem,
webServerSystem,
infoSystem,
serverInfo,
configSystem,
fileSystem,
versionCheckSystem
};
for (SubSystem system : systems) {
try {
if (system != null) {
system.disable();
}
} catch (Exception e) {
Log.toLog(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(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);
}
}
// Accessor methods.
public ProcessingQueue getProcessingQueue() {
return processingQueue;
}
public VersionCheckSystem getVersionCheckSystem() {
return versionCheckSystem;
}
public ConfigSystem getConfigSystem() {
return configSystem;
}
public FileSystem getFileSystem() {
return fileSystem;
}
public DBSystem getDatabaseSystem() {
return databaseSystem;
}
public ListenerSystem getListenerSystem() {
return listenerSystem;
}
public TaskSystem getTaskSystem() {
return taskSystem;
}
public WebServerSystem getWebServerSystem() {
return webServerSystem;
}
public ServerInfo getServerInfo() {
return serverInfo;
}
public CacheSystem getCacheSystem() {
return cacheSystem;
}
public InfoSystem getInfoSystem() {
return infoSystem;
}
public HookHandler getHookHandler() {
return hookHandler;
}
public PlanAPI getPlanAPI() {
return planAPI;
}
}

View File

@ -0,0 +1,28 @@
/*
* 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.plan.system;
import com.djrapitops.plan.api.exceptions.EnableException;
/**
* Represents a system that can be enabled and disabled.
*
* @author Rsl1122
*/
public interface SubSystem {
/**
* Performs enable actions for the subsystem.
*
* @throws EnableException If an error occurred during enable and it is fatal to the subsystem.
*/
void enable() throws EnableException;
/**
* Performs disable actions for the subsystem
*/
void disable();
}

Some files were not shown because too many files have changed in this diff Show More