[Merge] Version 4.6.0 (#882)

This commit is contained in:
Risto Lahtela 2019-01-17 13:44:20 +02:00 committed by GitHub
commit 46c460955b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
415 changed files with 9866 additions and 4211 deletions

4
.gitignore vendored
View File

@ -2,9 +2,13 @@ temporaryTestFolder/
Plan.iml
PlanPluginBridge.iml
.sonar/
builds/
*.db
**/.gradle
out/
# Created by https://www.gitignore.io/api/maven,eclipse,intellij,netbeans,osx,windows,notepadpp,windows,java
### Maven ###

View File

@ -1,20 +1,28 @@
language: java
sudo: false
sudo: true
install: false
addons:
chrome: stable
sonarcloud:
organization: "player-analytics-plan"
token:
secure: "bTqGEUlfpVGgXgwC9UiIwYN+LsUtXFHTbWkAjnNJcCKTLDvHzUfDzY8/M7YIpIlcS7EWggNgJhskkg/WBglESx/0KcVl4NukMgbylqvp7y1F7eOkYLuriWBpuwMaSCHTWjmyq1iWNJ26i569PETbKiS+sNYnx9lPIpXI4ph0M9EKK3nQpTLr1aeVHi+XilJu6UNY7whipoW1fEwn02s2SvIXUMJN1fS0tmUjMavlOnlxt0lCU/oayMVG7vFKE2wWDJ5Ucd6lLGLPA1at4ypy6nJVcl8Bn547qoXBoIyMbtAhpcLUzkkFLK8BxuSsQ5neK71GLlmbiU+bIU5dpfRgsS3XLOXSSgide0ly/Za4zQVUBfu36F5xJOFGGdALGfMBhWdCzW1j0oDcINauUhjK/VB9v8M8qpxBCV6Q570FH2CQdNotfUWvHHGVZf1+yqXnC5iUcIh4cuxNCrOgp3uql8cpLGtMfqScV4l7GkcYGXLZlLUhGPK5K8UhwPym31CJU8If6ExMiKttxvpCtcGsXx2bRl7gRl3+xdjlY0PzIfbBbgYY6uu5v6cK8RHxp/+sLsBDfPtVvRZnnOVACLUFzTRSr6nP0Cm8rr+91S3rTmf4Qug+IN32xMDVcs6Sm68v/KTn2QoA2XyXOMLbIR39/0ani00xCd3FPF9Ae115YHg="
jdk:
- oraclejdk8
services:
- mysql
jobs:
include:
- stage: "Tests"
name: "Checkstyle"
script: bash scripts/runCheckstyle.sh
- stage: "Tests"
name: "Unit tests"
before_script: bash scripts/prepareTestEnv.sh
script: bash scripts/runTests.sh
after_success: bash scripts/sonar.sh
- stage: "System Tests"
name: "Test environment setup"
script: bash scripts/prepareServerJars.sh
@ -22,4 +30,6 @@ cache:
directories:
- '$HOME/.m2/repository'
- '$HOME/.sonar/cache'
- '$HOME/.gradle'
- '.gradle'
- '$HOME/servers/'

143
Plan/build.gradle Normal file
View File

@ -0,0 +1,143 @@
plugins {
id "java"
id "jacoco"
id "checkstyle"
id "org.sonarqube" version "2.6.2"
id "net.ltgt.apt" version "0.19"
id "net.ltgt.apt-idea" version "0.19"
id "com.github.johnrengelman.shadow" version "4.0.2"
}
allprojects {
wrapper.gradleVersion = "5.0"
group "com.djrapitops"
version "4.6.0-SNAPSHOT"
test {
testLogging {
events "passed", "failed"
exceptionFormat "full"
}
}
// Fix for UTF-8 files showing with wrong encoding when compiled on Windows machines.
tasks.withType(JavaCompile) {
options.encoding = 'UTF-8'
}
}
subprojects {
// Build plugins
apply plugin: "java"
apply plugin: "maven"
apply plugin: "net.ltgt.apt" // Annotation processing plugin
apply plugin: "net.ltgt.apt-idea" // Annotation processing IntelliJ IDEA configuration plugin
apply plugin: "com.github.johnrengelman.shadow"
// Report plugins
apply plugin: "checkstyle"
apply plugin: "jacoco"
sourceCompatibility = 1.8
targetCompatibility = 1.8
ext.daggerVersion = "2.20"
ext.daggerCompilerVersion = "2.20"
ext.abstractPluginFrameworkVersion = "3.4.1"
ext.planPluginBridgeVersion = "4.6.0-1"
ext.bukkitVersion = "1.12.2-R0.1-SNAPSHOT"
ext.spigotVersion = "1.12.2-R0.1-SNAPSHOT"
ext.paperVersion = "1.12.2-R0.1-SNAPSHOT"
ext.spongeVersion = "7.1.0"
ext.bungeeVersion = "1.12-SNAPSHOT"
ext.velocityVersion = "1.0-SNAPSHOT"
ext.redisBungeeVersion = "0.3.8-SNAPSHOT"
ext.httpClientVersion = "4.5.6"
ext.commonsTextVersion = "1.6"
ext.htmlCompressorVersion = "1.5.2"
ext.caffeineVersion = "2.6.2"
ext.h2Version = "1.4.196"
ext.hikariVersion = "3.3.0"
ext.slf4jVersion = "1.7.25"
ext.geoIpVersion = "2.12.0"
ext.guavaVersion = "26.0-jre"
ext.bstatsVersion = "1.2"
repositories {
mavenCentral()
maven { // Spigot Repository
url = "https://hub.spigotmc.org/nexus/content/repositories/snapshots/"
}
maven { // Paper Repository
url = "https://papermc.io/repo/repository/maven-public/"
}
maven { // Sponge Repository
url = "https://repo.spongepowered.org/maven"
}
maven { // BungeeCord Repository
url = "https://oss.sonatype.org/content/repositories/snapshots"
}
maven { // RedisBungee Repository
url = "http://repo.md-5.net/content/repositories/snapshots/"
}
maven { // Velocity Repository
url = "https://repo.velocitypowered.com/snapshots/"
}
maven { // bStats Repository
url = "http://repo.bstats.org/content/repositories/releases/"
}
maven { // PlanPluginBridge Repository
url = "https://dl.bintray.com/rsl1122/Plan-repository"
}
}
dependencies {
// Dependency Injection used across the project
compile "com.google.dagger:dagger:$daggerVersion"
annotationProcessor "com.google.dagger:dagger-compiler:$daggerCompilerVersion"
testAnnotationProcessor "com.google.dagger:dagger-compiler:$daggerCompilerVersion"
// Test Tooling Dependencies
testCompile "org.junit.jupiter:junit-jupiter-engine:5.3.2" // JUnit 5
testCompile "org.junit.platform:junit-platform-runner:1.3.2" // JUnit 4 runner for JUnit 5 tests
testCompile "org.junit.vintage:junit-vintage-engine:5.3.2" // JUnit 4 compatibility for JUnit 5
testCompile "org.junit.jupiter:junit-jupiter-params:5.3.2" // JUnit 5, parameterized tests
testCompile "org.junit-pioneer:junit-pioneer:0.3.0" // TempDirectory TODO REMOVE W/ JUNIT 5.4
testCompile "org.mockito:mockito-core:2.23.4" // Mockito Core
testCompile "org.mockito:mockito-junit-jupiter:2.23.4" // Mockito JUnit 5 Extension
testCompile "org.seleniumhq.selenium:selenium-java:3.141.59" // Selenium (Browser tests)
testCompile "com.jayway.awaitility:awaitility:1.7.0" // Awaitility (Concurrent wait conditions)
// Testing dependencies required by Plan
testCompile "org.xerial:sqlite-jdbc:3.25.2" // SQLite
testCompile "mysql:mysql-connector-java:8.0.13" // MySQL
}
configurations {
testArtifacts.extendsFrom testRuntime
}
// Test classes available to other modules
task testJar(type: Jar) {
classifier "test"
from sourceSets.test.output
}
artifacts {
testArtifacts testJar
}
checkstyle {
configFile rootProject.file('config/checkstyle/checkstyle.xml')
}
}
sonarqube {
properties {
property "sonar.projectName", "Player Analytics"
property "sonar.projectKey", "com.djrapitops:Plan"
}
}

23
Plan/bukkit/build.gradle Normal file
View File

@ -0,0 +1,23 @@
dependencies {
compile project(path: ":common", configuration: 'shadow')
compile "com.djrapitops:AbstractPluginFramework-bukkit:$abstractPluginFrameworkVersion"
compile "org.bstats:bstats-bukkit:$bstatsVersion"
compileOnly "com.destroystokyo.paper:paper-api:$paperVersion"
compileOnly "org.spigotmc:spigot-api:$spigotVersion"
compileOnly "org.bukkit:bukkit:$bukkitVersion"
testCompile "com.destroystokyo.paper:paper-api:$paperVersion"
testCompile "org.spigotmc:spigot-api:$spigotVersion"
testCompile "org.bukkit:bukkit:$bukkitVersion"
testCompile project(path: ":common", configuration: 'testArtifacts')
}
shadowJar {
configurations = [project.configurations.compile]
relocate 'org.bstats', 'com.djrapitops.plan.utilities.metrics'
relocate 'org.slf4j', 'plan.org.slf4j'
}

View File

@ -1,99 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>Plan</artifactId>
<groupId>com.djrapitops</groupId>
<version>4.5.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>Plan-bukkit</artifactId>
<build>
<defaultGoal>clean package install</defaultGoal>
<finalName>${project.artifactId}-${project.parent.version}</finalName>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.2.1</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
</execution>
</executions>
<configuration>
<artifactSet>
<includes>
<include>com.djrapitops:AbstractPluginFramework-bukkit</include>
<include>org.bstats:bstats-bukkit</include>
</includes>
</artifactSet>
<relocations>
<relocation>
<pattern>org.bstats</pattern>
<shadedPattern>com.djrapitops.plan.utilities.metrics</shadedPattern>
</relocation>
<relocation>
<pattern>org.slf4j</pattern>
<shadedPattern>plan.org.slf4j</shadedPattern>
</relocation>
</relocations>
<createDependencyReducedPom>false</createDependencyReducedPom>
</configuration>
</plugin>
</plugins>
</build>
<dependencies>
<dependency> <!-- Plan Common classes -->
<groupId>com.djrapitops</groupId>
<artifactId>Plan-common</artifactId>
<version>${project.parent.version}</version>
<scope>compile</scope>
</dependency>
<dependency> <!-- Plan Common test classes -->
<groupId>com.djrapitops</groupId>
<artifactId>Plan-common</artifactId>
<version>${project.parent.version}</version>
<type>test-jar</type>
<scope>test</scope>
</dependency>
<dependency> <!-- Bukkit part of Abstract Plugin Framework -->
<groupId>com.djrapitops</groupId>
<artifactId>AbstractPluginFramework-bukkit</artifactId>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
</dependency>
<dependency> <!-- Metrics -->
<groupId>org.bstats</groupId>
<artifactId>bstats-bukkit</artifactId>
</dependency>
<dependency> <!-- Paper API -->
<groupId>com.destroystokyo.paper</groupId>
<artifactId>paper-api</artifactId>
<scope>provided</scope>
</dependency>
<dependency> <!-- Spigot API -->
<groupId>org.spigotmc</groupId>
<artifactId>spigot-api</artifactId>
<scope>provided</scope>
</dependency>
<dependency> <!-- Bukkit API -->
<groupId>org.bukkit</groupId>
<artifactId>bukkit</artifactId>
<scope>provided</scope>
</dependency>
</dependencies>
</project>

View File

@ -35,7 +35,6 @@ import java.util.logging.Logger;
* Main class for Bukkit that manages the plugin.
*
* @author Rsl1122
* @since 1.0.0
*/
public class Plan extends BukkitPlugin implements PlanPlugin {
@ -74,6 +73,9 @@ public class Plan extends BukkitPlugin implements PlanPlugin {
command.registerCommands();
registerCommand("plan", command);
new RegisterCommandFilter().registerFilter();
if (system != null) {
system.getProcessing().submitNonCritical(() -> system.getListenerSystem().callEnableEvent(this));
}
}
@Override

View File

@ -0,0 +1,58 @@
/*
* This file is part of Player Analytics (Plan).
*
* Plan is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License v3 as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Plan is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Plan. If not, see <https://www.gnu.org/licenses/>.
*/
package com.djrapitops.plan.api.events;
import org.bukkit.event.Event;
import org.bukkit.event.HandlerList;
/**
* Event that is called when Plan is enabled.
* <p>
* This includes, but might not be limited to:
* - First time the plugin enables successfully
* - Plan is reloaded
* - Bukkit-BungeeCord setup updates settings
* - Plan is enabled after it was disabled
* <p>
* {@code event.isPlanSystemEnabled()} can be called to determine if the enable was successful.
* It is not guaranteed that this event is called when the plugin fails to enable properly.
*
* @author Rsl1122
*/
public class PlanBukkitEnableEvent extends Event {
private static final HandlerList handlers = new HandlerList();
private final boolean enabled;
public PlanBukkitEnableEvent(boolean enabled) {
super(true);
this.enabled = enabled;
}
public static HandlerList getHandlerList() {
return handlers;
}
public boolean isPlanSystemEnabled() {
return enabled;
}
@Override
public HandlerList getHandlers() {
return PlanBukkitEnableEvent.getHandlerList();
}
}

View File

@ -31,7 +31,6 @@ import java.util.Set;
* Filters out WebUser registration command logs.
*
* @author Rsl1122
* @since 3.5.2
*/
public class RegisterCommandFilter extends AbstractFilter {

View File

@ -24,8 +24,8 @@ import com.djrapitops.plan.system.info.server.ServerInfo;
import com.djrapitops.plan.system.info.server.ServerServerInfo;
import com.djrapitops.plan.system.listeners.BukkitListenerSystem;
import com.djrapitops.plan.system.listeners.ListenerSystem;
import com.djrapitops.plan.system.settings.config.BukkitConfigSystem;
import com.djrapitops.plan.system.settings.config.ConfigSystem;
import com.djrapitops.plan.system.settings.BukkitConfigSystem;
import com.djrapitops.plan.system.settings.ConfigSystem;
import com.djrapitops.plan.system.tasks.BukkitTaskSystem;
import com.djrapitops.plan.system.tasks.TaskSystem;
import dagger.Binds;

View File

@ -21,8 +21,8 @@ import com.djrapitops.plan.system.database.databases.sql.H2DB;
import com.djrapitops.plan.system.database.databases.sql.MySQLDB;
import com.djrapitops.plan.system.database.databases.sql.SQLiteDB;
import com.djrapitops.plan.system.locale.Locale;
import com.djrapitops.plan.system.settings.Settings;
import com.djrapitops.plan.system.settings.config.PlanConfig;
import com.djrapitops.plan.system.settings.paths.DatabaseSettings;
import com.djrapitops.plugin.benchmarking.Timings;
import com.djrapitops.plugin.logging.console.PluginLogger;
import com.djrapitops.plugin.logging.error.ErrorHandler;
@ -61,7 +61,7 @@ public class BukkitDBSystem extends DBSystem {
@Override
public void enable() throws EnableException {
String dbType = config.getString(Settings.DB_TYPE).toLowerCase().trim();
String dbType = config.get(DatabaseSettings.TYPE).toLowerCase().trim();
db = getActiveDatabaseByName(dbType);
super.enable();
}

View File

@ -32,7 +32,6 @@ import java.util.stream.Collectors;
* It also removes invalid data.
*
* @author Fuzzlemann
* @since 4.0.0
*/
public class UserImportRefiner {

View File

@ -46,7 +46,6 @@ import java.util.stream.Collectors;
/**
* @author Fuzzlemann
* @since 4.0.0
*/
public abstract class BukkitImporter implements Importer {

View File

@ -34,7 +34,6 @@ import java.util.Set;
/**
* @author Fuzzlemann
* @since 4.0.0
*/
@Singleton
public class OfflinePlayerImporter extends BukkitImporter {

View File

@ -17,8 +17,11 @@
package com.djrapitops.plan.system.listeners;
import com.djrapitops.plan.Plan;
import com.djrapitops.plan.PlanPlugin;
import com.djrapitops.plan.api.events.PlanBukkitEnableEvent;
import com.djrapitops.plan.system.listeners.bukkit.*;
import com.djrapitops.plan.system.status.Status;
import org.bukkit.Bukkit;
import org.bukkit.event.HandlerList;
import javax.inject.Inject;
@ -77,4 +80,10 @@ public class BukkitListenerSystem extends ListenerSystem {
protected void unregisterListeners() {
HandlerList.unregisterAll(plugin);
}
@Override
public void callEnableEvent(PlanPlugin plugin) {
PlanBukkitEnableEvent event = new PlanBukkitEnableEvent(plugin.isSystemEnabled());
Bukkit.getServer().getPluginManager().callEvent(event);
}
}

View File

@ -20,8 +20,8 @@ import com.djrapitops.plan.Plan;
import com.djrapitops.plan.system.processing.Processing;
import com.djrapitops.plan.system.processing.processors.Processors;
import com.djrapitops.plan.system.settings.Permissions;
import com.djrapitops.plan.system.settings.Settings;
import com.djrapitops.plan.system.settings.config.PlanConfig;
import com.djrapitops.plan.system.settings.paths.DataGatheringSettings;
import com.djrapitops.plugin.logging.L;
import com.djrapitops.plugin.logging.error.ErrorHandler;
import org.bukkit.command.Command;
@ -77,8 +77,8 @@ public class CommandListener implements Listener {
private void actOnCommandEvent(PlayerCommandPreprocessEvent event) {
String commandName = event.getMessage().substring(1).split(" ")[0].toLowerCase();
boolean logUnknownCommands = config.isTrue(Settings.LOG_UNKNOWN_COMMANDS);
boolean combineCommandAliases = config.isTrue(Settings.COMBINE_COMMAND_ALIASES);
boolean logUnknownCommands = config.isTrue(DataGatheringSettings.LOG_UNKNOWN_COMMANDS);
boolean combineCommandAliases = config.isTrue(DataGatheringSettings.COMBINE_COMMAND_ALIASES);
if (!logUnknownCommands || combineCommandAliases) {
Command command = getBukkitCommand(commandName);

View File

@ -18,7 +18,7 @@ package com.djrapitops.plan.system.listeners.bukkit;
import com.djrapitops.plan.data.container.Session;
import com.djrapitops.plan.system.cache.SessionCache;
import com.djrapitops.plan.system.settings.WorldAliasSettings;
import com.djrapitops.plan.system.settings.config.WorldAliasSettings;
import com.djrapitops.plugin.logging.L;
import com.djrapitops.plugin.logging.error.ErrorHandler;
import org.bukkit.entity.Player;

View File

@ -21,8 +21,8 @@ import com.djrapitops.plan.system.cache.SessionCache;
import com.djrapitops.plan.system.info.server.ServerInfo;
import com.djrapitops.plan.system.processing.Processing;
import com.djrapitops.plan.system.processing.processors.Processors;
import com.djrapitops.plan.system.settings.Settings;
import com.djrapitops.plan.system.settings.config.PlanConfig;
import com.djrapitops.plan.system.settings.paths.DataGatheringSettings;
import com.djrapitops.plan.system.status.Status;
import com.djrapitops.plugin.logging.L;
import com.djrapitops.plugin.logging.error.ErrorHandler;
@ -44,7 +44,6 @@ import java.util.UUID;
* Event Listener for PlayerJoin, PlayerQuit and PlayerKickEvents.
*
* @author Rsl1122
* @since 2.0.0
*/
public class PlayerOnlineListener implements Listener {
@ -142,7 +141,7 @@ public class PlayerOnlineListener implements Listener {
String playerName = player.getName();
String displayName = player.getDisplayName();
boolean gatheringGeolocations = config.isTrue(Settings.DATA_GEOLOCATIONS);
boolean gatheringGeolocations = config.isTrue(DataGatheringSettings.GEOLOCATIONS);
processing.submitCritical(() -> sessionCache.cacheSession(uuid, new Session(uuid, serverInfo.getServerUUID(), time, world, gm)));
runnableFactory.create("Player Register: " + uuid,

View File

@ -18,7 +18,7 @@ package com.djrapitops.plan.system.listeners.bukkit;
import com.djrapitops.plan.data.container.Session;
import com.djrapitops.plan.system.cache.SessionCache;
import com.djrapitops.plan.system.settings.WorldAliasSettings;
import com.djrapitops.plan.system.settings.config.WorldAliasSettings;
import com.djrapitops.plugin.logging.L;
import com.djrapitops.plugin.logging.error.ErrorHandler;
import org.bukkit.entity.Player;

View File

@ -18,12 +18,13 @@ package com.djrapitops.plan.system.tasks;
import com.djrapitops.plan.Plan;
import com.djrapitops.plan.ShutdownHook;
import com.djrapitops.plan.system.settings.Settings;
import com.djrapitops.plan.system.settings.config.PlanConfig;
import com.djrapitops.plan.system.settings.paths.TimeSettings;
import com.djrapitops.plan.system.tasks.bukkit.BukkitTPSCountTimer;
import com.djrapitops.plan.system.tasks.bukkit.PaperTPSCountTimer;
import com.djrapitops.plan.system.tasks.bukkit.PingCountTimerBukkit;
import com.djrapitops.plan.system.tasks.server.BootAnalysisTask;
import com.djrapitops.plan.system.tasks.server.ConfigStoreTask;
import com.djrapitops.plan.system.tasks.server.PeriodicAnalysisTask;
import com.djrapitops.plugin.api.Check;
import com.djrapitops.plugin.api.TimeAmount;
@ -44,6 +45,7 @@ public class BukkitTaskSystem extends ServerTaskSystem {
private final Plan plugin;
private final ShutdownHook shutdownHook;
private final PingCountTimerBukkit pingCountTimer;
private final ConfigStoreTask configStoreTask;
@Inject
public BukkitTaskSystem(
@ -57,7 +59,8 @@ public class BukkitTaskSystem extends ServerTaskSystem {
PeriodicAnalysisTask periodicAnalysisTask,
PingCountTimerBukkit pingCountTimer,
LogsFolderCleanTask logsFolderCleanTask,
PlayersPageRefreshTask playersPageRefreshTask
PlayersPageRefreshTask playersPageRefreshTask,
ConfigStoreTask configStoreTask
) {
super(
runnableFactory,
@ -70,6 +73,7 @@ public class BukkitTaskSystem extends ServerTaskSystem {
this.plugin = plugin;
this.shutdownHook = shutdownHook;
this.pingCountTimer = pingCountTimer;
this.configStoreTask = configStoreTask;
}
@Override
@ -77,9 +81,13 @@ public class BukkitTaskSystem extends ServerTaskSystem {
super.enable();
try {
plugin.registerListener(pingCountTimer);
long startDelay = TimeAmount.toTicks(config.getNumber(Settings.PING_SERVER_ENABLE_DELAY), TimeUnit.SECONDS);
long startDelay = TimeAmount.toTicks(config.get(TimeSettings.PING_SERVER_ENABLE_DELAY), TimeUnit.MILLISECONDS);
registerTask("PingCountTimer", pingCountTimer)
.runTaskTimer(startDelay, 40L);
// +40 ticks / 2 seconds so that update check task runs first.
long storeDelay = TimeAmount.toTicks(config.get(TimeSettings.CONFIG_UPDATE_INTERVAL), TimeUnit.MILLISECONDS) + 40;
registerTask("Config Store Task", configStoreTask).runTaskLaterAsynchronously(storeDelay);
} catch (ExceptionInInitializerError | NoClassDefFoundError ignore) {
// Running CraftBukkit
}

View File

@ -26,8 +26,8 @@ package com.djrapitops.plan.system.tasks.bukkit;
import com.djrapitops.plan.data.store.objects.DateObj;
import com.djrapitops.plan.system.processing.Processing;
import com.djrapitops.plan.system.processing.processors.Processors;
import com.djrapitops.plan.system.settings.Settings;
import com.djrapitops.plan.system.settings.config.PlanConfig;
import com.djrapitops.plan.system.settings.paths.TimeSettings;
import com.djrapitops.plan.utilities.java.Reflection;
import com.djrapitops.plugin.api.TimeAmount;
import com.djrapitops.plugin.task.AbsRunnable;
@ -199,7 +199,7 @@ public class PingCountTimerBukkit extends AbsRunnable implements Listener {
addPlayer(player);
}
}
}).runTaskLater(TimeAmount.toTicks(config.getNumber(Settings.PING_PLAYER_LOGIN_DELAY), TimeUnit.SECONDS));
}).runTaskLater(TimeAmount.toTicks(config.get(TimeSettings.PING_PLAYER_LOGIN_DELAY), TimeUnit.MILLISECONDS));
}
@EventHandler

View File

@ -270,7 +270,7 @@ public final class Reflection {
* <p>
* Strings enclosed with curly brackets - such as {TEXT} - will be replaced according to the following table:
* </p>
* <table border="1">
* <table border="1" summary="Variables and description">
* <tr>
* <th>Variable</th>
* <th>Content</th>

View File

@ -1,20 +1,41 @@
/*
* License is provided in the jar as LICENSE also here:
* https://github.com/Rsl1122/Plan-PlayerAnalytics/blob/master/Plan/src/main/resources/LICENSE
* This file is part of Player Analytics (Plan).
*
* Plan is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License v3 as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Plan is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Plan. If not, see <https://www.gnu.org/licenses/>.
*/
package com.djrapitops.plan;
import com.djrapitops.plan.api.exceptions.EnableException;
import com.djrapitops.plan.system.PlanSystem;
import com.djrapitops.plan.system.settings.Settings;
import com.djrapitops.plan.system.settings.ConfigSettingKeyTest;
import com.djrapitops.plan.system.settings.config.PlanConfig;
import com.djrapitops.plan.system.settings.paths.WebserverSettings;
import com.djrapitops.plan.system.settings.paths.key.Setting;
import org.junit.Before;
import org.junit.ClassRule;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
import org.junit.runner.RunWith;
import org.mockito.junit.MockitoJUnitRunner;
import rules.BukkitComponentMocker;
import rules.ComponentMocker;
import utilities.RandomData;
import java.util.Collection;
import static org.junit.Assert.assertTrue;
/**
* Test for Bukkit PlanSystem.
@ -26,18 +47,40 @@ public class BukkitSystemTest {
@ClassRule
public static TemporaryFolder temporaryFolder = new TemporaryFolder();
@ClassRule
public static ComponentMocker component = new BukkitComponentMocker(temporaryFolder);
@Rule
public ComponentMocker component = new BukkitComponentMocker(temporaryFolder);
private final int TEST_PORT_NUMBER = RandomData.randomInt(9005, 9500);
private PlanSystem system;
@Before
public void prepareSystem() {
system = component.getPlanSystem();
system.getConfigSystem().getConfig()
.set(WebserverSettings.PORT, TEST_PORT_NUMBER);
}
@Test
public void testEnable() throws EnableException {
PlanSystem bukkitSystem = component.getPlanSystem();
public void bukkitSystemEnables() throws EnableException {
try {
PlanConfig config = bukkitSystem.getConfigSystem().getConfig();
config.set(Settings.WEBSERVER_PORT, 9005);
bukkitSystem.enable();
system.enable();
assertTrue(system.isEnabled());
} finally {
bukkitSystem.disable();
system.disable();
}
}
@Test
public void bukkitSystemHasDefaultConfigValuesAfterEnable() throws EnableException, IllegalAccessException {
try {
system.enable();
PlanConfig config = system.getConfigSystem().getConfig();
Collection<Setting> serverSettings = ConfigSettingKeyTest.getServerSettings();
ConfigSettingKeyTest.assertValidDefaultValuesForAllSettings(config, serverSettings);
} finally {
system.disable();
}
}
}

View File

@ -1,8 +1,24 @@
/*
* This file is part of Player Analytics (Plan).
*
* Plan is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License v3 as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Plan is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Plan. If not, see <https://www.gnu.org/licenses/>.
*/
package com.djrapitops.plan.system.listeners;
import com.djrapitops.plan.system.listeners.bukkit.AFKListener;
import com.djrapitops.plan.system.settings.Settings;
import com.djrapitops.plan.system.settings.config.PlanConfig;
import com.djrapitops.plan.system.settings.paths.TimeSettings;
import com.djrapitops.plugin.logging.console.TestPluginLogger;
import com.djrapitops.plugin.logging.error.ConsoleErrorLogger;
import org.bukkit.entity.Player;
@ -12,6 +28,8 @@ import org.junit.Test;
import org.mockito.Mockito;
import utilities.TestConstants;
import java.util.concurrent.TimeUnit;
import static org.mockito.Mockito.*;
/**
@ -26,7 +44,7 @@ public class AFKListenerTest {
@Before
public void setUp() {
PlanConfig config = Mockito.mock(PlanConfig.class);
when(config.getNumber(Settings.AFK_THRESHOLD_MINUTES)).thenReturn(3);
when(config.get(TimeSettings.AFK_THRESHOLD)).thenReturn(TimeUnit.MINUTES.toMillis(3));
underTest = new AFKListener(config, new ConsoleErrorLogger(new TestPluginLogger()));
}

View File

@ -1,6 +1,18 @@
/*
* License is provided in the jar as LICENSE also here:
* https://github.com/Rsl1122/Plan-PlayerAnalytics/blob/master/Plan/src/main/resources/LICENSE
* This file is part of Player Analytics (Plan).
*
* Plan is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License v3 as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Plan is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Plan. If not, see <https://www.gnu.org/licenses/>.
*/
package utilities.mocks;

View File

@ -0,0 +1,20 @@
dependencies {
compile project(path: ":common", configuration: 'shadow')
compile "com.djrapitops:AbstractPluginFramework-bungeecord:$abstractPluginFrameworkVersion"
compile "org.bstats:bstats-bungeecord:$bstatsVersion"
compileOnly "net.md-5:bungeecord-api:$bungeeVersion"
compileOnly "com.imaginarycode.minecraft:RedisBungee:$redisBungeeVersion"
testCompile "net.md-5:bungeecord-api:$bungeeVersion"
testCompile "com.imaginarycode.minecraft:RedisBungee:$redisBungeeVersion"
testCompile project(path: ":common", configuration: 'testArtifacts')
}
shadowJar {
configurations = [project.configurations.compile]
relocate 'org.bstats', 'com.djrapitops.plan.utilities.metrics'
relocate 'org.slf4j', 'plan.org.slf4j'
}

View File

@ -1,90 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>Plan</artifactId>
<groupId>com.djrapitops</groupId>
<version>4.5.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>Plan-bungeecord</artifactId>
<build>
<defaultGoal>clean package install</defaultGoal>
<finalName>${project.artifactId}-${project.parent.version}</finalName>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.2.1</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
</execution>
</executions>
<configuration>
<artifactSet>
<includes>
<include>com.djrapitops:AbstractPluginFramework-bungeecord</include>
<include>org.bstats:bstats-bungeecord</include>
</includes>
</artifactSet>
<relocations>
<relocation>
<pattern>org.bstats</pattern>
<shadedPattern>com.djrapitops.plan.utilities.metrics</shadedPattern>
</relocation>
<relocation>
<pattern>org.slf4j</pattern>
<shadedPattern>plan.org.slf4j</shadedPattern>
</relocation>
</relocations>
<createDependencyReducedPom>false</createDependencyReducedPom>
</configuration>
</plugin>
</plugins>
</build>
<dependencies>
<dependency> <!-- Plan Common classes -->
<groupId>com.djrapitops</groupId>
<artifactId>Plan-common</artifactId>
<version>${project.parent.version}</version>
<scope>compile</scope>
</dependency>
<dependency> <!-- Plan Common test classes -->
<groupId>com.djrapitops</groupId>
<artifactId>Plan-common</artifactId>
<version>${project.parent.version}</version>
<type>test-jar</type>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.djrapitops</groupId>
<artifactId>AbstractPluginFramework-bungeecord</artifactId>
</dependency>
<dependency>
<groupId>net.md-5</groupId>
<artifactId>bungeecord-api</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.imaginarycode.minecraft</groupId>
<artifactId>RedisBungee</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.bstats</groupId>
<artifactId>bstats-bungeecord</artifactId>
</dependency>
</dependencies>
</project>

View File

@ -70,11 +70,14 @@ public class PlanBungee extends BungeePlugin implements PlanPlugin {
PlanProxyCommand command = component.planCommand();
command.registerCommands();
registerCommand("planbungee", command);
if (system != null) {
system.getProcessing().submitNonCritical(() -> system.getListenerSystem().callEnableEvent(this));
}
}
@Override
public void onDisable() {
system.disable();
if (system != null) system.disable();
logger.info(locale.getString(PluginLang.DISABLED));
}

View File

@ -0,0 +1,46 @@
/*
* This file is part of Player Analytics (Plan).
*
* Plan is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License v3 as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Plan is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Plan. If not, see <https://www.gnu.org/licenses/>.
*/
package com.djrapitops.plan.api.events;
import net.md_5.bungee.api.plugin.Event;
/**
* Event that is called when Plan is enabled.
* <p>
* This includes, but might not be limited to:
* - First time the plugin enables successfully
* - Plan is reloaded
* - Plan is enabled after it was disabled
* <p>
* {@code event.isPlanSystemEnabled()} can be called to determine if the enable was successful.
* It is not guaranteed that this event is called when the plugin fails to enable properly.
*
* @author Rsl1122
*/
public class PlanBungeeEnableEvent extends Event {
private final boolean enabled;
public PlanBungeeEnableEvent(boolean enabled) {
this.enabled = enabled;
}
public boolean isPlanSystemEnabled() {
return enabled;
}
}

View File

@ -19,7 +19,6 @@ package com.djrapitops.plan.modules.bungee;
import com.djrapitops.plan.PlanBungee;
import com.djrapitops.plan.system.info.server.properties.BungeeServerProperties;
import com.djrapitops.plan.system.info.server.properties.ServerProperties;
import com.djrapitops.plan.system.settings.Settings;
import com.djrapitops.plan.system.settings.config.PlanConfig;
import dagger.Module;
import dagger.Provides;
@ -37,6 +36,6 @@ public class BungeeServerPropertiesModule {
@Provides
@Singleton
ServerProperties provideServerProperties(PlanBungee plugin, PlanConfig config) {
return new BungeeServerProperties(plugin.getProxy(), config.getString(Settings.BUNGEE_IP));
return new BungeeServerProperties(plugin.getProxy(), config);
}
}

View File

@ -16,6 +16,8 @@
*/
package com.djrapitops.plan.system.info.server.properties;
import com.djrapitops.plan.system.settings.config.PlanConfig;
import com.djrapitops.plan.system.settings.paths.ProxySettings;
import net.md_5.bungee.api.ProxyServer;
/**
@ -27,14 +29,14 @@ import net.md_5.bungee.api.ProxyServer;
*/
public class BungeeServerProperties extends ServerProperties {
public BungeeServerProperties(ProxyServer server, String ip) {
public BungeeServerProperties(ProxyServer server, PlanConfig config) {
super(
server.getServers().toString(),
"BungeeCord",
-1,
server.getVersion(),
server.getVersion(),
() -> ip,
() -> config.get(ProxySettings.IP),
server.getConfig().getPlayerLimit(),
RedisCheck.isClassAvailable() ? new RedisPlayersOnlineSupplier() : server::getOnlineCount
);

View File

@ -17,6 +17,8 @@
package com.djrapitops.plan.system.listeners;
import com.djrapitops.plan.PlanBungee;
import com.djrapitops.plan.PlanPlugin;
import com.djrapitops.plan.api.events.PlanBungeeEnableEvent;
import com.djrapitops.plan.system.listeners.bungee.PlayerOnlineListener;
import javax.inject.Inject;
@ -41,4 +43,10 @@ public class BungeeListenerSystem extends ListenerSystem {
protected void unregisterListeners() {
plugin.getProxy().getPluginManager().unregisterListeners(plugin);
}
@Override
public void callEnableEvent(PlanPlugin plugin) {
PlanBungeeEnableEvent event = new PlanBungeeEnableEvent(plugin.isSystemEnabled());
((PlanBungee) plugin).getProxy().getPluginManager().callEvent(event);
}
}

View File

@ -21,8 +21,8 @@ import com.djrapitops.plan.system.cache.SessionCache;
import com.djrapitops.plan.system.info.server.ServerInfo;
import com.djrapitops.plan.system.processing.Processing;
import com.djrapitops.plan.system.processing.processors.Processors;
import com.djrapitops.plan.system.settings.Settings;
import com.djrapitops.plan.system.settings.config.PlanConfig;
import com.djrapitops.plan.system.settings.paths.DataGatheringSettings;
import com.djrapitops.plan.system.webserver.cache.PageId;
import com.djrapitops.plan.system.webserver.cache.ResponseCache;
import com.djrapitops.plugin.logging.L;
@ -80,7 +80,7 @@ public class PlayerOnlineListener implements Listener {
sessionCache.cacheSession(uuid, new Session(uuid, serverInfo.getServerUUID(), time, "", ""));
boolean gatheringGeolocations = config.isTrue(Settings.DATA_GEOLOCATIONS);
boolean gatheringGeolocations = config.isTrue(DataGatheringSettings.GEOLOCATIONS);
processing.submit(processors.player().proxyRegisterProcessor(uuid, name, time,
gatheringGeolocations ? processors.player().ipUpdateProcessor(uuid, address, time) : null

View File

@ -17,13 +17,13 @@
package com.djrapitops.plan.system.tasks;
import com.djrapitops.plan.PlanBungee;
import com.djrapitops.plan.system.settings.Settings;
import com.djrapitops.plan.system.settings.config.PlanConfig;
import com.djrapitops.plan.system.settings.paths.TimeSettings;
import com.djrapitops.plan.system.tasks.bungee.BungeeTPSCountTimer;
import com.djrapitops.plan.system.tasks.bungee.PingCountTimerBungee;
import com.djrapitops.plan.system.tasks.proxy.NetworkConfigStoreTask;
import com.djrapitops.plan.system.tasks.proxy.NetworkPageRefreshTask;
import com.djrapitops.plugin.api.TimeAmount;
import com.djrapitops.plugin.task.AbsRunnable;
import com.djrapitops.plugin.task.RunnableFactory;
import javax.inject.Inject;
@ -42,6 +42,7 @@ public class BungeeTaskSystem extends TaskSystem {
private final PingCountTimerBungee pingCountTimer;
private final LogsFolderCleanTask logsFolderCleanTask;
private final PlayersPageRefreshTask playersPageRefreshTask;
private final NetworkConfigStoreTask networkConfigStoreTask;
@Inject
public BungeeTaskSystem(
@ -52,7 +53,9 @@ public class BungeeTaskSystem extends TaskSystem {
NetworkPageRefreshTask networkPageRefreshTask,
PingCountTimerBungee pingCountTimer,
LogsFolderCleanTask logsFolderCleanTask,
PlayersPageRefreshTask playersPageRefreshTask) {
PlayersPageRefreshTask playersPageRefreshTask,
NetworkConfigStoreTask networkConfigStoreTask
) {
super(runnableFactory, bungeeTPSCountTimer);
this.plugin = plugin;
this.config = config;
@ -61,6 +64,7 @@ public class BungeeTaskSystem extends TaskSystem {
this.pingCountTimer = pingCountTimer;
this.logsFolderCleanTask = logsFolderCleanTask;
this.playersPageRefreshTask = playersPageRefreshTask;
this.networkConfigStoreTask = networkConfigStoreTask;
}
@Override
@ -72,18 +76,16 @@ public class BungeeTaskSystem extends TaskSystem {
registerTask(tpsCountTimer).runTaskTimerAsynchronously(1000, TimeAmount.toTicks(1L, TimeUnit.SECONDS));
registerTask(networkPageRefreshTask).runTaskTimerAsynchronously(1500, TimeAmount.toTicks(5L, TimeUnit.MINUTES));
registerTask(logsFolderCleanTask).runTaskLaterAsynchronously(TimeAmount.toTicks(30L, TimeUnit.SECONDS));
registerTask("Settings Save", new AbsRunnable() {
@Override
public void run() {
config.getNetworkSettings().placeSettingsToDB();
}
}).runTaskAsynchronously();
plugin.registerListener(pingCountTimer);
long startDelay = TimeAmount.toTicks(config.getNumber(Settings.PING_SERVER_ENABLE_DELAY), TimeUnit.SECONDS);
long startDelay = TimeAmount.toTicks(config.get(TimeSettings.PING_SERVER_ENABLE_DELAY), TimeUnit.MILLISECONDS);
runnableFactory.create("PingCountTimer", pingCountTimer).runTaskTimer(startDelay, PingCountTimerBungee.PING_INTERVAL);
registerTask(playersPageRefreshTask)
.runTaskTimerAsynchronously(TimeAmount.toTicks(5L, TimeUnit.MINUTES), TimeAmount.toTicks(5L, TimeUnit.MINUTES));
// +40 ticks / 2 seconds so that update check task runs first.
long storeDelay = TimeAmount.toTicks(config.get(TimeSettings.CONFIG_UPDATE_INTERVAL), TimeUnit.MILLISECONDS) + 40;
registerTask("Config Store Task", networkConfigStoreTask).runTaskLaterAsynchronously(storeDelay);
}
}

View File

@ -26,8 +26,8 @@ package com.djrapitops.plan.system.tasks.bungee;
import com.djrapitops.plan.data.store.objects.DateObj;
import com.djrapitops.plan.system.processing.Processing;
import com.djrapitops.plan.system.processing.processors.Processors;
import com.djrapitops.plan.system.settings.Settings;
import com.djrapitops.plan.system.settings.config.PlanConfig;
import com.djrapitops.plan.system.settings.paths.TimeSettings;
import com.djrapitops.plugin.api.TimeAmount;
import com.djrapitops.plugin.task.AbsRunnable;
import com.djrapitops.plugin.task.RunnableFactory;
@ -125,7 +125,7 @@ public class PingCountTimerBungee extends AbsRunnable implements Listener {
addPlayer(player);
}
}
}).runTaskLater(TimeAmount.toTicks(config.getNumber(Settings.PING_PLAYER_LOGIN_DELAY), TimeUnit.SECONDS));
}).runTaskLater(TimeAmount.toTicks(config.get(TimeSettings.PING_PLAYER_LOGIN_DELAY), TimeUnit.MILLISECONDS));
}
@EventHandler

View File

@ -1,16 +1,28 @@
/*
* License is provided in the jar as LICENSE also here:
* https://github.com/Rsl1122/Plan-PlayerAnalytics/blob/master/Plan/src/main/resources/LICENSE
* This file is part of Player Analytics (Plan).
*
* Plan is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License v3 as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Plan is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Plan. If not, see <https://www.gnu.org/licenses/>.
*/
package com.djrapitops.plan;
import com.djrapitops.plan.api.exceptions.EnableException;
import com.djrapitops.plan.system.PlanSystem;
import com.djrapitops.plan.system.database.DBSystem;
import com.djrapitops.plan.system.settings.Settings;
import com.djrapitops.plan.system.settings.config.PlanConfig;
import com.djrapitops.plan.system.settings.paths.ProxySettings;
import com.djrapitops.plan.system.settings.paths.WebserverSettings;
import org.junit.ClassRule;
import org.junit.Ignore;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
@ -19,6 +31,9 @@ import org.junit.runner.RunWith;
import org.mockito.junit.MockitoJUnitRunner;
import rules.BungeeComponentMocker;
import rules.ComponentMocker;
import utilities.RandomData;
import static org.junit.Assert.assertTrue;
/**
* Test for Bungee PlanSystem.
@ -30,9 +45,11 @@ public class BungeeSystemTest {
@ClassRule
public static TemporaryFolder temporaryFolder = new TemporaryFolder();
@ClassRule
public static ComponentMocker component = new BungeeComponentMocker(temporaryFolder);
private final int TEST_PORT_NUMBER = RandomData.randomInt(9005, 9500);
@Rule
public ComponentMocker component = new BungeeComponentMocker(temporaryFolder);
@Rule
public ExpectedException thrown = ExpectedException.none();
@ -41,8 +58,8 @@ public class BungeeSystemTest {
PlanSystem bungeeSystem = component.getPlanSystem();
try {
PlanConfig config = bungeeSystem.getConfigSystem().getConfig();
config.set(Settings.WEBSERVER_PORT, 9005);
config.set(Settings.BUNGEE_IP, "8.8.8.8");
config.set(WebserverSettings.PORT, TEST_PORT_NUMBER);
config.set(ProxySettings.IP, "8.8.8.8");
DBSystem dbSystem = bungeeSystem.getDatabaseSystem();
dbSystem.setActiveDatabase(dbSystem.getSqLiteFactory().usingDefaultFile());
@ -54,7 +71,6 @@ public class BungeeSystemTest {
}
@Test
@Ignore("First test causes config settings to be wrong")
public void bungeeDoesNotEnableWithDefaultIP() throws Exception {
thrown.expect(EnableException.class);
thrown.expectMessage("IP setting still 0.0.0.0 - Configure AlternativeIP/IP that connects to the Proxy server.");
@ -62,29 +78,28 @@ public class BungeeSystemTest {
PlanSystem bungeeSystem = component.getPlanSystem();
try {
PlanConfig config = bungeeSystem.getConfigSystem().getConfig();
config.set(Settings.WEBSERVER_PORT, 9005);
config.set(Settings.BUNGEE_IP, "0.0.0.0");
config.set(WebserverSettings.PORT, TEST_PORT_NUMBER);
config.set(ProxySettings.IP, "0.0.0.0");
DBSystem dbSystem = bungeeSystem.getDatabaseSystem();
dbSystem.setActiveDatabase(dbSystem.getSqLiteFactory().usingDefaultFile());
bungeeSystem.enable();
assertTrue(bungeeSystem.isEnabled());
} finally {
bungeeSystem.disable();
}
}
@Test
@Ignore("MySQL Driver unavailable for some reason.")
public void testEnableNoMySQL() throws EnableException {
thrown.expect(EnableException.class);
thrown.expectMessage("Database failed to initialize");
PlanSystem bungeeSystem = component.getPlanSystem();
try {
PlanConfig config = bungeeSystem.getConfigSystem().getConfig();
config.set(Settings.WEBSERVER_PORT, 9005);
config.set(Settings.BUNGEE_IP, "8.8.8.8");
config.set(WebserverSettings.PORT, TEST_PORT_NUMBER);
config.set(ProxySettings.IP, "8.8.8.8");
bungeeSystem.enable();
} finally {

View File

@ -1,6 +1,18 @@
/*
* License is provided in the jar as LICENSE also here:
* https://github.com/Rsl1122/Plan-PlayerAnalytics/blob/master/Plan/src/main/resources/LICENSE
* This file is part of Player Analytics (Plan).
*
* Plan is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License v3 as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Plan is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Plan. If not, see <https://www.gnu.org/licenses/>.
*/
package utilities.mocks;
@ -14,7 +26,7 @@ import com.djrapitops.plugin.logging.debug.DebugLogger;
import com.djrapitops.plugin.logging.debug.MemoryDebugLogger;
import com.djrapitops.plugin.logging.error.ConsoleErrorLogger;
import com.djrapitops.plugin.logging.error.ErrorHandler;
import com.djrapitops.plugin.task.thread.ThreadRunnableFactory;
import com.djrapitops.plugin.task.RunnableFactory;
import net.md_5.bungee.api.CommandSender;
import net.md_5.bungee.api.ProxyConfig;
import net.md_5.bungee.api.ProxyServer;
@ -23,6 +35,7 @@ import net.md_5.bungee.api.plugin.PluginManager;
import org.mockito.Mockito;
import utilities.TestConstants;
import utilities.mocks.objects.TestLogger;
import utilities.mocks.objects.TestRunnableFactory;
import java.io.File;
import java.util.HashSet;
@ -54,7 +67,7 @@ public class PlanBungeeMocker extends Mocker {
doReturn("1.0.0").when(planMock).getVersion();
TestLogger testLogger = new TestLogger();
ThreadRunnableFactory runnableFactory = new ThreadRunnableFactory();
RunnableFactory runnableFactory = new TestRunnableFactory();
PluginLogger testPluginLogger = new TestPluginLogger();
DebugLogger debugLogger = new CombineDebugLogger(new MemoryDebugLogger());
ErrorHandler consoleErrorLogger = new ConsoleErrorLogger(testPluginLogger);
@ -85,6 +98,7 @@ public class PlanBungeeMocker extends Mocker {
return this;
}
@SuppressWarnings("deprecation")
public PlanBungeeMocker withProxy() {
ProxyServer proxyMock = Mockito.mock(ProxyServer.class);
doReturn("1.12.2").when(proxyMock).getVersion();

38
Plan/common/build.gradle Normal file
View File

@ -0,0 +1,38 @@
dependencies {
compile "com.djrapitops:AbstractPluginFramework-api:$abstractPluginFrameworkVersion"
compile "com.djrapitops:PlanPluginBridge:$planPluginBridgeVersion"
compile "org.apache.httpcomponents:httpclient:$httpClientVersion"
compile "org.apache.commons:commons-text:$commonsTextVersion"
compile "com.googlecode.htmlcompressor:htmlcompressor:$htmlCompressorVersion"
compile "com.github.ben-manes.caffeine:caffeine:$caffeineVersion"
compile "com.h2database:h2:$h2Version"
compile "com.zaxxer:HikariCP:$hikariVersion"
compile "org.slf4j:slf4j-nop:$slf4jVersion"
compile "org.slf4j:slf4j-api:$slf4jVersion"
compile "com.maxmind.geoip2:geoip2:$geoIpVersion"
compileOnly "com.google.guava:guava:$guavaVersion"
}
shadowJar {
configurations = [project.configurations.compile]
// Exclude these files
exclude "org/json/**/*"
exclude "**/*.svg"
exclude "**/*.ttf"
exclude "**/*.woff"
exclude "**/*.eot"
exclude "**/*.woff2"
exclude "**/*.psd"
relocate('org.apache', 'plan.org.apache') {
exclude 'org/apache/logging/**'
}
relocate 'com.maxmind', 'plan.com.maxmind'
relocate 'com.fasterxml', 'plan.com.fasterxml'
relocate 'com.zaxxer', 'plan.com.zaxxer'
relocate 'org.h2', 'plan.org.h2'
relocate 'org.bstats', 'plan.org.bstats'
relocate 'org.slf4j', 'plan.org.slf4j'
relocate 'com.google.dagger', 'plan.com.google.dagger'
}

View File

@ -1,181 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>Plan</artifactId>
<groupId>com.djrapitops</groupId>
<version>4.5.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>Plan-common</artifactId>
<description>
Module that includes common functionality between all platforms.
- Contains functionality related dependencies.
- Contains abstractions and interfaces
</description>
<dependencies>
<!-- Framework for easier plugin development -->
<dependency>
<groupId>com.djrapitops</groupId>
<artifactId>AbstractPluginFramework-api</artifactId>
</dependency>
<dependency> <!-- SoftDepended Plugins -->
<groupId>com.djrapitops</groupId>
<artifactId>PlanPluginBridge</artifactId>
</dependency>
<dependency> <!-- HttpClient -->
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
</dependency>
<dependency> <!-- String Replacer -->
<groupId>org.apache.commons</groupId>
<artifactId>commons-text</artifactId>
</dependency>
<dependency> <!-- HTML Compression -->
<groupId>com.googlecode.htmlcompressor</groupId>
<artifactId>htmlcompressor</artifactId>
</dependency>
<dependency> <!-- Cache with invalidation -->
<groupId>com.github.ben-manes.caffeine</groupId>
<artifactId>caffeine</artifactId>
</dependency>
<dependency> <!-- H2 -->
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
</dependency>
<dependency> <!-- MySQL Connection Pool -->
<groupId>com.zaxxer</groupId>
<artifactId>HikariCP</artifactId>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-nop</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
</dependency>
<dependency> <!-- Geo IP -->
<groupId>com.maxmind.geoip2</groupId>
<artifactId>geoip2</artifactId>
</dependency>
<dependency> <!-- Guava -->
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<scope>provided</scope>
</dependency>
</dependencies>
<build>
<defaultGoal>clean package install</defaultGoal>
<finalName>${project.name}</finalName>
<sourceDirectory>${basedir}/src/main/java</sourceDirectory>
<testSourceDirectory>${basedir}/src/test/java</testSourceDirectory>
<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>locale/*.txt</include>
<include>**/*.ico</include>
</includes>
</resource>
</resources>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.2.1</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
</execution>
</executions>
<configuration>
<artifactSet>
<includes>
<include>com.djrapitops:*</include>
<include>org.apache.httpcomponents:*</include>
<include>commons-logging:*</include>
<include>commons-codec:*</include>
<include>org.apache.commons:commons-text</include>
<include>org.apache.commons:commons-lang3</include>
<include>com.zaxxer:HikariCP</include>
<include>org.slf4j:slf4j-api</include>
<include>org.slf4j:slf4j-nop</include>
<include>com.maxmind.geoip2:*</include>
<include>com.maxmind.db:*</include>
<include>com.fasterxml.jackson.core:*</include>
<include>com.google.dagger:*</include>
<include>javax.inject:*</include>
<include>com.github.ben-manes.caffeine:caffeine</include>
<include>com.googlecode.htmlcompressor:htmlcompressor</include>
<include>com.h2database:h2</include>
</includes>
</artifactSet>
<relocations>
<relocation>
<pattern>org.apache</pattern>
<shadedPattern>plan.org.apache</shadedPattern>
<excludes>
<exclude>org.apache.logging.**</exclude>
</excludes>
</relocation>
<relocation>
<pattern>com.maxmind</pattern>
<shadedPattern>plan.com.maxmind</shadedPattern>
</relocation>
<relocation>
<pattern>com.fasterxml</pattern>
<shadedPattern>plan.com.fasterxml</shadedPattern>
</relocation>
<relocation>
<pattern>com.zaxxer</pattern>
<shadedPattern>plan.com.zaxxer</shadedPattern>
</relocation>
<relocation>
<pattern>org.h2</pattern>
<shadedPattern>plan.org.h2</shadedPattern>
</relocation>
<relocation>
<pattern>org.bstats</pattern>
<shadedPattern>com.djrapitops.plan.utilities.metrics</shadedPattern>
</relocation>
<relocation>
<pattern>org.slf4j</pattern>
<shadedPattern>plan.org.slf4j</shadedPattern>
</relocation>
</relocations>
<createDependencyReducedPom>false</createDependencyReducedPom>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>3.0.1</version>
<configuration>
<excludePackageNames>test.*</excludePackageNames>
</configuration>
</plugin>
</plugins>
</build>
</project>

View File

@ -41,4 +41,8 @@ public interface PlanPlugin extends IPlugin {
boolean isReloading();
PlanSystem getSystem();
default boolean isSystemEnabled() {
return getSystem().isEnabled();
}
}

View File

@ -16,9 +16,12 @@
*/
package com.djrapitops.plan.api;
import com.djrapitops.plan.api.data.PlayerContainer;
import com.djrapitops.plan.api.data.ServerContainer;
import com.djrapitops.plan.data.plugin.PluginData;
import com.djrapitops.plan.system.database.databases.operation.FetchOperations;
import java.util.Collection;
import java.util.Map;
import java.util.Optional;
import java.util.UUID;
@ -41,6 +44,10 @@ public interface PlanAPI {
static void set(PlanAPI api) {
PlanAPIHolder.API = api;
}
private PlanAPIHolder() {
/* Static variable holder */
}
}
void addPluginDataSource(PluginData pluginData);
@ -55,5 +62,45 @@ public interface PlanAPI {
Map<UUID, String> getKnownPlayerNames();
/**
* Fetch things from the database.
*
* @return FetchOperations object.
* @deprecated FetchOperations interface is going to removed since it is too rigid.
*/
@Deprecated
FetchOperations fetchFromPlanDB();
/**
* Fetch PlayerContainer from the database.
* <p>
* Blocking operation.
*
* @param uuid UUID of the player.
* @return a {@link PlayerContainer}.
*/
default PlayerContainer fetchPlayerContainer(UUID uuid) {
return new PlayerContainer(fetchFromPlanDB().getPlayerContainer(uuid));
}
/**
* Fetch a ServerContainer from the database.
* <p>
* Blocking operation.
*
* @param serverUUID UUID of the server.
* @return a {@link ServerContainer}.
*/
default ServerContainer fetchServerContainer(UUID serverUUID) {
return new ServerContainer(fetchFromPlanDB().getServerContainer(serverUUID));
}
/**
* Fetch server UUIDs.
*
* @return All Plan server UUIDs.
*/
default Collection<UUID> fetchServerUUIDs() {
return fetchFromPlanDB().getServerUUIDs();
}
}

View File

@ -0,0 +1,52 @@
/*
* This file is part of Player Analytics (Plan).
*
* Plan is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License v3 as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Plan is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Plan. If not, see <https://www.gnu.org/licenses/>.
*/
package com.djrapitops.plan.api.data;
import com.djrapitops.plan.data.store.Key;
import java.util.Optional;
/**
* Wrapper for a PlayerContainer.
* <p>
* The actual object is wrapped to avoid exposing too much API that might change.
* See {@link com.djrapitops.plan.data.store.keys.PlayerKeys} for Key objects.
* <p>
* The Keys might change in the future, but the Optional API should help dealing with those cases.
*
* @author Rsl1122
*/
public class PlayerContainer {
private final com.djrapitops.plan.data.store.containers.PlayerContainer container;
public PlayerContainer(com.djrapitops.plan.data.store.containers.PlayerContainer container) {
this.container = container;
}
public double getActivityIndex(long date, long playtimeMsThreshold, int loginThreshold) {
return container.getActivityIndex(date, playtimeMsThreshold, loginThreshold).getValue();
}
public boolean playedBetween(long after, long before) {
return container.playedBetween(after, before);
}
public <T> Optional<T> getValue(Key<T> key) {
return container.getValue(key);
}
}

View File

@ -0,0 +1,44 @@
/*
* This file is part of Player Analytics (Plan).
*
* Plan is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License v3 as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Plan is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Plan. If not, see <https://www.gnu.org/licenses/>.
*/
package com.djrapitops.plan.api.data;
import com.djrapitops.plan.data.store.Key;
import java.util.Optional;
/**
* Wrapper for a ServerContainer.
* <p>
* The actual object is wrapped to avoid exposing too much API that might change.
* See {@link com.djrapitops.plan.data.store.keys.ServerKeys} for Key objects.
* <p>
* The Keys might change in the future, but the Optional API should help dealing with those cases.
*
* @author Rsl1122
*/
public class ServerContainer {
private final com.djrapitops.plan.data.store.containers.ServerContainer container;
public ServerContainer(com.djrapitops.plan.data.store.containers.ServerContainer container) {
this.container = container;
}
public <T> Optional<T> getValue(Key<T> key) {
return container.getValue(key);
}
}

View File

@ -20,8 +20,8 @@ import com.djrapitops.plan.command.commands.*;
import com.djrapitops.plan.system.locale.Locale;
import com.djrapitops.plan.system.locale.lang.DeepHelpLang;
import com.djrapitops.plan.system.settings.Permissions;
import com.djrapitops.plan.system.settings.Settings;
import com.djrapitops.plan.system.settings.config.PlanConfig;
import com.djrapitops.plan.system.settings.paths.PluginSettings;
import com.djrapitops.plugin.command.ColorScheme;
import com.djrapitops.plugin.command.CommandNode;
import com.djrapitops.plugin.command.CommandType;
@ -37,7 +37,6 @@ import javax.inject.Singleton;
* Uses the Abstract Plugin Framework for easier command management.
*
* @author Rsl1122
* @since 1.0.0
*/
@Singleton
public class PlanCommand extends TreeCmdNode {
@ -128,7 +127,7 @@ public class PlanCommand extends TreeCmdNode {
infoCommand,
reloadCommand,
manageCommand.get(),
config.isTrue(Settings.DEV_MODE) ? devCommand : null
config.isTrue(PluginSettings.DEV_MODE) ? devCommand : null
};
setNodeGroups(analyticsGroup, webGroup, manageGroup);
commandsRegistered = true;

View File

@ -39,7 +39,6 @@ import javax.inject.Singleton;
* Uses the Abstract Plugin Framework for easier command management.
*
* @author Rsl1122
* @since 1.0.0
*/
@Singleton
public class PlanProxyCommand extends TreeCmdNode {

View File

@ -48,7 +48,6 @@ import java.util.UUID;
* This SubCommand is used to run the analysis and access the /server link.
*
* @author Rsl1122
* @since 2.0.0
*/
@Singleton
public class AnalyzeCommand extends CommandNode {

View File

@ -59,7 +59,7 @@ public class BungeeSetupToggleCommand extends CommandNode {
connectionSystem.setSetupAllowed(true);
}
String msg = locale.getString(connectionSystem.isSetupAllowed() ? CommandLang.SETUP_ALLOWED : CommandLang.CONNECT_FORBIDDEN);
String msg = locale.getString(connectionSystem.isSetupAllowed() ? CommandLang.SETUP_ALLOWED : CommandLang.SETUP_FORBIDDEN);
sender.sendMessage(msg);
}
}

View File

@ -35,7 +35,6 @@ import javax.inject.Inject;
* This SubCommand is used to view the version and the database type in use.
*
* @author Rsl1122
* @since 2.0.0
*/
public class InfoCommand extends CommandNode {

View File

@ -43,7 +43,6 @@ import java.util.UUID;
* This command is used to refresh Inspect page and display link.
*
* @author Rsl1122
* @since 1.0.0
*/
public class InspectCommand extends CommandNode {

View File

@ -33,7 +33,6 @@ import javax.inject.Inject;
* Command used to display url to the player list page.
*
* @author Rsl1122
* @since 3.5.2
*/
public class ListPlayersCommand extends CommandNode {

View File

@ -34,7 +34,6 @@ import javax.inject.Named;
* This SubCommand is used to manage the the plugin's database and components.
*
* @author Rsl1122
* @since 2.3.0
*/
public class ManageCommand extends TreeCmdNode {

View File

@ -32,8 +32,8 @@ import com.djrapitops.plan.system.locale.lang.DeepHelpLang;
import com.djrapitops.plan.system.locale.lang.GenericLang;
import com.djrapitops.plan.system.processing.Processing;
import com.djrapitops.plan.system.settings.Permissions;
import com.djrapitops.plan.system.settings.Settings;
import com.djrapitops.plan.system.settings.config.PlanConfig;
import com.djrapitops.plan.system.settings.paths.TimeSettings;
import com.djrapitops.plan.utilities.MiscUtils;
import com.djrapitops.plan.utilities.formatting.Formatter;
import com.djrapitops.plan.utilities.formatting.Formatters;
@ -55,7 +55,6 @@ import java.util.UUID;
* This command is used to cache UserInfo to InspectCache and display the link.
*
* @author Rsl1122
* @since 1.0.0
*/
@Singleton
public class QInspectCommand extends CommandNode {
@ -138,8 +137,8 @@ public class QInspectCommand extends CommandNode {
ActivityIndex activityIndex = player.getActivityIndex(
now,
config.getNumber(Settings.ACTIVE_PLAY_THRESHOLD),
config.getNumber(Settings.ACTIVE_LOGIN_THRESHOLD)
config.get(TimeSettings.ACTIVE_PLAY_THRESHOLD),
config.get(TimeSettings.ACTIVE_LOGIN_THRESHOLD)
);
Long registered = player.getValue(PlayerKeys.REGISTERED).orElse(0L);
Long lastSeen = player.getValue(PlayerKeys.LAST_SEEN).orElse(0L);

View File

@ -48,7 +48,6 @@ import java.util.Arrays;
* {@code Permissions.MANAGE_WEB} required for registering other users.
*
* @author Rsl1122
* @since 3.5.2
*/
@Singleton
public class RegisterCommand extends CommandNode {
@ -97,6 +96,8 @@ public class RegisterCommand extends CommandNode {
sender.sendMessage("§cPassword hash error.");
} catch (NumberFormatException e) {
throw new NumberFormatException(args[2]);
} catch (IllegalArgumentException e) {
throw e;
} catch (Exception e) {
errorHandler.log(L.WARN, this.getClass(), e);
}
@ -152,7 +153,7 @@ public class RegisterCommand extends CommandNode {
return;
}
database.save().webUser(webUser);
sender.sendMessage(locale.getString(CommandLang.WEB_USER_REGISTER_SUCCESS));
sender.sendMessage(locale.getString(CommandLang.WEB_USER_REGISTER_SUCCESS, userName));
logger.info(locale.getString(CommandLang.WEB_USER_REGISTER_NOTIFY, userName, webUser.getPermLevel()));
} catch (Exception e) {
errorHandler.log(L.WARN, this.getClass(), e);

View File

@ -36,7 +36,6 @@ import javax.inject.Inject;
* This SubCommand is used to reload the plugin.
*
* @author Rsl1122
* @since 2.0.0
*/
public class ReloadCommand extends CommandNode {

View File

@ -42,7 +42,6 @@ import java.util.List;
* This SubCommand is used to search for a user.
*
* @author Rsl1122
* @since 2.0.0
*/
@Singleton
public class SearchCommand extends CommandNode {

View File

@ -37,7 +37,6 @@ import javax.inject.Named;
* Web subcommand used to manage Web users.
*
* @author Rsl1122
* @since 3.5.2
*/
public class WebUserCommand extends TreeCmdNode {

View File

@ -48,7 +48,6 @@ import java.util.UUID;
* This command is used to backup a database to a .db file.
*
* @author Rsl1122
* @since 2.3.0
*/
@Singleton
public class ManageBackupCommand extends CommandNode {

View File

@ -43,7 +43,6 @@ import java.util.Arrays;
* This manage SubCommand is used to clear a database of all data.
*
* @author Rsl1122
* @since 2.3.0
*/
@Singleton
public class ManageClearCommand extends CommandNode {

View File

@ -45,7 +45,6 @@ import java.util.UUID;
* This manage SubCommand is used to request settings from Bungee so that connection can be established.
*
* @author Rsl1122
* @since 2.3.0
*/
@Singleton
public class ManageConDebugCommand extends CommandNode {
@ -85,7 +84,7 @@ public class ManageConDebugCommand extends CommandNode {
setInDepthHelp(locale.getArray(DeepHelpLang.MANAGE_CON));
}
private void testServer(Sender sender, String accessAddress, Server server, Locale locale) {
private void testServer(Sender sender, Server server, Locale locale) {
String address = server.getWebAddress().toLowerCase();
boolean usingHttps = address.startsWith("https");
boolean local = address.contains("localhost")
@ -96,9 +95,6 @@ public class ManageConDebugCommand extends CommandNode {
try {
connectionSystem.sendInfoRequest(infoRequestFactory.checkConnectionRequest(address), server);
sender.sendMessage(getMsgFor(address, usingHttps, local, true, true));
} catch (ForbiddenException | BadRequestException | InternalErrorException e) {
sender.sendMessage(getMsgFor(address, usingHttps, local, false, false));
sender.sendMessage(locale.getString(ManageLang.CON_EXCEPTION, e.getClass().getSimpleName()));
} catch (UnauthorizedServerException e) {
sender.sendMessage(getMsgFor(address, usingHttps, local, true, false));
sender.sendMessage(locale.getString(ManageLang.CON_UNAUTHORIZED));
@ -142,7 +138,7 @@ public class ManageConDebugCommand extends CommandNode {
if (thisServer.equals(server.getUuid())) {
continue;
}
testServer(sender, accessAddress, server, locale);
testServer(sender, server, locale);
}
}

View File

@ -34,7 +34,6 @@ import java.util.Arrays;
* This manage SubCommand is used to disable some features of the plugin temporarily.
*
* @author Rsl1122
* @since 4.0.4
*/
public class ManageDisableCommand extends CommandNode {
@ -61,13 +60,11 @@ public class ManageDisableCommand extends CommandNode {
Verify.isTrue(args.length >= 1,
() -> new IllegalArgumentException(locale.getString(CommandLang.FAIL_REQ_ONE_ARG, Arrays.toString(this.getArguments()))));
switch (args[0].toLowerCase()) {
case "kickcount":
status.setCountKicks(false);
sender.sendMessage(locale.getString(CommandLang.FEATURE_DISABLED, "Kick Counting"));
break;
default:
sender.sendMessage(locale.getString(CommandLang.FAIL_NO_SUCH_FEATURE, "'kickcount'"));
if ("kickcount".equals(args[0].toLowerCase())) {
status.setCountKicks(false);
sender.sendMessage(locale.getString(CommandLang.FEATURE_DISABLED, "Kick Counting"));
} else {
sender.sendMessage(locale.getString(CommandLang.FAIL_NO_SUCH_FEATURE, "'kickcount'"));
}
}
}

View File

@ -25,8 +25,8 @@ import com.djrapitops.plan.system.locale.lang.CmdHelpLang;
import com.djrapitops.plan.system.locale.lang.CommandLang;
import com.djrapitops.plan.system.locale.lang.ManageLang;
import com.djrapitops.plan.system.settings.Permissions;
import com.djrapitops.plan.system.settings.Settings;
import com.djrapitops.plan.system.settings.config.PlanConfig;
import com.djrapitops.plan.system.settings.paths.DatabaseSettings;
import com.djrapitops.plugin.command.CommandNode;
import com.djrapitops.plugin.command.CommandType;
import com.djrapitops.plugin.command.Sender;
@ -43,7 +43,6 @@ import java.util.Arrays;
* plugin if the connection to the new database can be established.
*
* @author Rsl1122
* @since 2.3.0
*/
public class ManageHotSwapCommand extends CommandNode {
@ -95,7 +94,7 @@ public class ManageHotSwapCommand extends CommandNode {
}
try {
config.set(Settings.DB_TYPE, dbName);
config.set(DatabaseSettings.TYPE, dbName);
config.save();
} catch (IOException e) {
errorHandler.log(L.ERROR, this.getClass(), e);

View File

@ -39,7 +39,6 @@ import java.util.Optional;
* This manage SubCommand is used to import data from 3rd party plugins.
*
* @author Rsl1122
* @since 2.3.0
*/
@Singleton
public class ManageImportCommand extends CommandNode {
@ -72,20 +71,24 @@ public class ManageImportCommand extends CommandNode {
String importArg = args[0];
if (importArg.equals("list")) {
if ("list".equals(importArg)) {
sender.sendMessage(locale.getString(ManageLang.IMPORTERS));
importSystem.getImporterNames().forEach(name -> sender.sendMessage("- " + name));
return;
}
findImporter(sender, importArg);
findAndProcessImporter(sender, importArg);
}
private void findImporter(Sender sender, String importArg) {
private void findAndProcessImporter(Sender sender, String importArg) {
Optional<Importer> foundImporter = importSystem.getImporter(importArg);
if (foundImporter.isPresent()) {
Importer importer = foundImporter.get();
processing.submitNonCritical(importer::processImport);
processing.submitNonCritical(() -> {
sender.sendMessage(locale.getString(ManageLang.PROGRESS_START));
importer.processImport();
sender.sendMessage(locale.getString(ManageLang.PROGRESS_SUCCESS));
});
} else {
sender.sendMessage(locale.getString(ManageLang.FAIL_IMPORTER_NOT_FOUND, importArg));
}

View File

@ -43,7 +43,6 @@ import java.util.Arrays;
* Destination database will be cleared.
*
* @author Rsl1122
* @since 2.3.0
*/
@Singleton
public class ManageMoveCommand extends CommandNode {

View File

@ -110,20 +110,14 @@ public class ManageRestoreCommand extends CommandNode {
private void runRestoreTask(String backupDbName, Sender sender, Database database) {
processing.submitCritical(() -> {
try {
String backupDBName = backupDbName;
boolean containsDBFileExtension = backupDBName.endsWith(".db");
File backupDBFile = files.getFileFromPluginFolder(backupDBName + (containsDBFileExtension ? "" : ".db"));
boolean containsDBFileExtension = backupDbName.endsWith(".db");
File backupDBFile = files.getFileFromPluginFolder(backupDbName + (containsDBFileExtension ? "" : ".db"));
if (!backupDBFile.exists()) {
sender.sendMessage(locale.getString(ManageLang.FAIL_FILE_NOT_FOUND, backupDBFile.getAbsolutePath()));
return;
}
if (containsDBFileExtension) {
backupDBName = backupDBName.substring(0, backupDBName.length() - 3);
}
SQLiteDB backupDB = sqliteFactory.usingFile(backupDBFile);
backupDB.init();

View File

@ -24,8 +24,8 @@ import com.djrapitops.plan.system.locale.lang.CommandLang;
import com.djrapitops.plan.system.locale.lang.DeepHelpLang;
import com.djrapitops.plan.system.processing.Processing;
import com.djrapitops.plan.system.settings.Permissions;
import com.djrapitops.plan.system.settings.Settings;
import com.djrapitops.plan.system.settings.config.PlanConfig;
import com.djrapitops.plan.system.settings.paths.PluginSettings;
import com.djrapitops.plan.system.webserver.WebServer;
import com.djrapitops.plugin.command.CommandNode;
import com.djrapitops.plugin.command.CommandType;
@ -42,7 +42,6 @@ import java.util.Arrays;
* This manage SubCommand is used to request settings from Bungee so that connection can be established.
*
* @author Rsl1122
* @since 2.3.0
*/
@Singleton
public class ManageSetupCommand extends CommandNode {
@ -101,8 +100,7 @@ public class ManageSetupCommand extends CommandNode {
private void requestSetup(Sender sender, String address) {
processing.submitNonCritical(() -> {
try {
config.set(Settings.BUNGEE_OVERRIDE_STANDALONE_MODE, false);
config.set(Settings.BUNGEE_COPY_CONFIG, true);
config.set(PluginSettings.BUNGEE_COPY_CONFIG, true);
infoSystem.requestSetUp(address);

View File

@ -42,7 +42,6 @@ import java.util.UUID;
* This SubCommand is used to set a server as uninstalled on Plan.
*
* @author Rsl1122
* @since 2.0.0
*/
@Singleton
public class ManageUninstalledCommand extends CommandNode {

View File

@ -40,7 +40,6 @@ import java.util.Arrays;
* Subcommand for checking WebUser permission level.
*
* @author Rsl1122
* @since 3.5.2
*/
@Singleton
public class WebCheckCommand extends CommandNode {

View File

@ -39,7 +39,6 @@ import java.util.Arrays;
* Subcommand for deleting a WebUser.
*
* @author Rsl1122
* @since 3.5.2
*/
@Singleton
public class WebDeleteCommand extends CommandNode {

View File

@ -30,7 +30,6 @@ import javax.inject.Inject;
* Subcommand for info about permission levels.
*
* @author Rsl1122
* @since 3.5.2
*/
public class WebLevelCommand extends CommandNode {

View File

@ -39,7 +39,6 @@ import java.util.List;
* Subcommand for checking WebUser list.
*
* @author Rsl1122
* @since 3.5.2
*/
@Singleton
public class WebListUsersCommand extends CommandNode {

View File

@ -22,7 +22,6 @@ import java.util.Objects;
* Object containing webserver security user information.
*
* @author Rsl1122
* @since 3.5.2
*/
public class WebUser {

View File

@ -24,7 +24,6 @@ import java.util.Objects;
* Class containing single datapoint of TPS / Players online / CPU Usage / Used Memory / Entity Count / Chunks loaded.
*
* @author Rsl1122
* @since 3.5.0
*/
public class TPS implements DateHolder {

View File

@ -38,7 +38,6 @@ import java.util.UUID;
* @author Rsl1122
* @see TableContainer
* @see InspectContainer
* @since 4.1.0
*/
public final class AnalysisContainer extends InspectContainer {

View File

@ -35,7 +35,6 @@ import java.util.TreeMap;
*
* @author Rsl1122
* @see TableContainer
* @since 4.1.0
*/
public class InspectContainer {
@ -93,7 +92,7 @@ public class InspectContainer {
}
public boolean isEmpty() {
return values.isEmpty() && html.isEmpty() && tables.isEmpty();
return values.isEmpty() && hasOnlyValues();
}
public final boolean hasValues() {

View File

@ -26,14 +26,12 @@ import com.djrapitops.pluginbridge.plan.Bridge;
import javax.inject.Inject;
import javax.inject.Singleton;
import java.util.*;
import java.util.stream.Collectors;
/**
* Class responsible for hooking to other plugins and managing the %plugins%
* placeholder on Analysis and Inspect pages.
*
* @author Rsl1122
* @since 2.6.0
*/
@Singleton
public class HookHandler implements SubSystem {
@ -94,6 +92,10 @@ public class HookHandler implements SubSystem {
configHandler.createSection(dataSource);
}
if (configHandler.isEnabled(dataSource)) {
additionalDataSources.stream()
.filter(pluginData -> pluginData.getSourcePlugin().equals(dataSource.getSourcePlugin()))
.findAny()
.ifPresent(additionalDataSources::remove);
logger.debug("Registered a new datasource: " + dataSource.getSourcePlugin());
additionalDataSources.add(dataSource);
}
@ -112,13 +114,6 @@ public class HookHandler implements SubSystem {
return additionalDataSources;
}
public List<BanData> getBanDataSources() {
return additionalDataSources.stream()
.filter(p -> p instanceof BanData)
.map(p -> (BanData) p)
.collect(Collectors.toList());
}
public Map<PluginData, InspectContainer> getInspectContainersFor(UUID uuid) {
List<PluginData> plugins = getAdditionalDataSources();
Map<PluginData, InspectContainer> containers = new HashMap<>();

View File

@ -34,7 +34,6 @@ import java.util.UUID;
* to register objects extending this class.
*
* @author Rsl1122
* @since 4.1.0
*/
public abstract class PluginData {

View File

@ -16,8 +16,8 @@
*/
package com.djrapitops.plan.data.plugin;
import com.djrapitops.plan.system.settings.config.ConfigNode;
import com.djrapitops.plan.system.settings.config.PlanConfig;
import com.djrapitops.plugin.config.ConfigNode;
import java.io.IOException;
@ -26,7 +26,6 @@ import java.io.IOException;
* objects to the config.
*
* @author Rsl1122
* @since 3.5.0
*/
public class PluginsConfigSection {
@ -41,12 +40,12 @@ public class PluginsConfigSection {
public boolean hasSection(PluginData dataSource) {
ConfigNode section = getPluginsSection();
String pluginName = dataSource.getSourcePlugin();
return section.getChildren().containsKey(pluginName)
&& section.getConfigNode(pluginName).getChildren().containsKey("Enabled");
return section.getNode(pluginName + ".Enabled").isPresent();
}
private ConfigNode getPluginsSection() {
return config.getConfigNode("Plugins");
return config.getNode("Plugins")
.orElse(config.addNode("Plugins"));
}
public void createSection(PluginData dataSource) throws IOException {

View File

@ -27,8 +27,9 @@ import com.djrapitops.plan.data.time.WorldTimes;
import com.djrapitops.plan.system.database.DBSystem;
import com.djrapitops.plan.system.info.server.properties.ServerProperties;
import com.djrapitops.plan.system.locale.Locale;
import com.djrapitops.plan.system.settings.Settings;
import com.djrapitops.plan.system.settings.config.PlanConfig;
import com.djrapitops.plan.system.settings.paths.DisplaySettings;
import com.djrapitops.plan.system.settings.paths.TimeSettings;
import com.djrapitops.plan.system.settings.theme.Theme;
import com.djrapitops.plan.system.settings.theme.ThemeVal;
import com.djrapitops.plan.utilities.formatting.Formatters;
@ -137,10 +138,10 @@ public class AnalysisContainer extends DataContainer {
putRawData(AnalysisKeys.VERSION, version);
putSupplier(AnalysisKeys.TIME_ZONE, config::getTimeZoneOffsetHours);
putRawData(AnalysisKeys.FIRST_DAY, 1);
putRawData(AnalysisKeys.TPS_MEDIUM, config.getNumber(Settings.THEME_GRAPH_TPS_THRESHOLD_MED));
putRawData(AnalysisKeys.TPS_HIGH, config.getNumber(Settings.THEME_GRAPH_TPS_THRESHOLD_HIGH));
putRawData(AnalysisKeys.DISK_MEDIUM, config.getNumber(Settings.THEME_GRAPH_DISK_THRESHOLD_MED));
putRawData(AnalysisKeys.DISK_HIGH, config.getNumber(Settings.THEME_GRAPH_DISK_THRESHOLD_HIGH));
putRawData(AnalysisKeys.TPS_MEDIUM, config.get(DisplaySettings.GRAPH_TPS_THRESHOLD_MED));
putRawData(AnalysisKeys.TPS_HIGH, config.get(DisplaySettings.GRAPH_TPS_THRESHOLD_HIGH));
putRawData(AnalysisKeys.DISK_MEDIUM, config.get(DisplaySettings.GRAPH_DISK_THRESHOLD_MED));
putRawData(AnalysisKeys.DISK_HIGH, config.get(DisplaySettings.GRAPH_DISK_THRESHOLD_HIGH));
addServerProperties();
addThemeColors();
@ -258,8 +259,8 @@ public class AnalysisContainer extends DataContainer {
putCachingSupplier(retentionDay, () -> getUnsafe(AnalysisKeys.PLAYERS_MUTATOR).compareAndFindThoseLikelyToBeRetained(
getUnsafe(newDay).all(), getUnsafe(AnalysisKeys.ANALYSIS_TIME_MONTH_AGO),
getUnsafe(AnalysisKeys.PLAYERS_ONLINE_RESOLVER),
config.getNumber(Settings.ACTIVE_PLAY_THRESHOLD),
config.getNumber(Settings.ACTIVE_LOGIN_THRESHOLD)
config.get(TimeSettings.ACTIVE_PLAY_THRESHOLD),
config.get(TimeSettings.ACTIVE_LOGIN_THRESHOLD)
).count()
);
putSupplier(AnalysisKeys.PLAYERS_RETAINED_DAY, () -> {
@ -404,7 +405,7 @@ public class AnalysisContainer extends DataContainer {
getUnsafe(AnalysisKeys.NEW_PLAYERS_PER_DAY)
).toCalendarSeries());
putCachingSupplier(AnalysisKeys.ACTIVITY_DATA, () -> getUnsafe(AnalysisKeys.PLAYERS_MUTATOR).toActivityDataMap(getUnsafe(AnalysisKeys.ANALYSIS_TIME), config.getNumber(Settings.ACTIVE_PLAY_THRESHOLD), config.getNumber(Settings.ACTIVE_LOGIN_THRESHOLD)));
putCachingSupplier(AnalysisKeys.ACTIVITY_DATA, () -> getUnsafe(AnalysisKeys.PLAYERS_MUTATOR).toActivityDataMap(getUnsafe(AnalysisKeys.ANALYSIS_TIME), config.get(TimeSettings.ACTIVE_PLAY_THRESHOLD), config.get(TimeSettings.ACTIVE_LOGIN_THRESHOLD)));
Key<StackGraph> activityStackGraph = new Key<>(StackGraph.class, "ACTIVITY_STACK_GRAPH");
putCachingSupplier(activityStackGraph, () -> graphs.stack().activityStackGraph(getUnsafe(AnalysisKeys.ACTIVITY_DATA)));
putSupplier(AnalysisKeys.ACTIVITY_STACK_CATEGORIES, () -> getUnsafe(activityStackGraph).toHighChartsLabels());
@ -439,7 +440,7 @@ public class AnalysisContainer extends DataContainer {
putCachingSupplier(AnalysisKeys.PLAYERS_ONLINE_RESOLVER, () -> new PlayersOnlineResolver(getUnsafe(AnalysisKeys.TPS_MUTATOR)));
int threshold = config.getNumber(Settings.THEME_GRAPH_TPS_THRESHOLD_MED);
int threshold = config.get(DisplaySettings.GRAPH_TPS_THRESHOLD_MED);
putSupplier(AnalysisKeys.TPS_SPIKE_MONTH, () -> getUnsafe(tpsMonth).lowTpsSpikeCount(threshold));
putSupplier(AnalysisKeys.AVG_TPS_MONTH, () -> getUnsafe(tpsMonth).averageTPS());
@ -483,9 +484,9 @@ public class AnalysisContainer extends DataContainer {
putCachingSupplier(healthInformation, () -> new HealthInformation(
this,
locale,
config.getNumber(Settings.THEME_GRAPH_TPS_THRESHOLD_MED),
config.getNumber(Settings.ACTIVE_PLAY_THRESHOLD),
config.getNumber(Settings.ACTIVE_LOGIN_THRESHOLD),
config.get(DisplaySettings.GRAPH_TPS_THRESHOLD_MED),
config.get(TimeSettings.ACTIVE_PLAY_THRESHOLD),
config.get(TimeSettings.ACTIVE_LOGIN_THRESHOLD),
formatters.timeAmount(), formatters.decimals(), formatters.percentage()
));
putSupplier(AnalysisKeys.HEALTH_INDEX, () -> getUnsafe(healthInformation).getServerHealth());

View File

@ -24,10 +24,12 @@ import com.djrapitops.plan.data.store.mutators.PlayersMutator;
import com.djrapitops.plan.data.store.mutators.TPSMutator;
import com.djrapitops.plan.data.store.mutators.health.NetworkHealthInformation;
import com.djrapitops.plan.system.database.DBSystem;
import com.djrapitops.plan.system.info.server.Server;
import com.djrapitops.plan.system.info.server.properties.ServerProperties;
import com.djrapitops.plan.system.locale.Locale;
import com.djrapitops.plan.system.settings.Settings;
import com.djrapitops.plan.system.settings.config.PlanConfig;
import com.djrapitops.plan.system.settings.paths.ProxySettings;
import com.djrapitops.plan.system.settings.paths.TimeSettings;
import com.djrapitops.plan.system.settings.theme.Theme;
import com.djrapitops.plan.system.settings.theme.ThemeVal;
import com.djrapitops.plan.utilities.formatting.Formatters;
@ -42,10 +44,7 @@ import dagger.Lazy;
import javax.inject.Inject;
import javax.inject.Named;
import javax.inject.Singleton;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.*;
import java.util.concurrent.TimeUnit;
/**
@ -107,17 +106,28 @@ public class NetworkContainer extends DataContainer {
putSupplier(NetworkKeys.SERVERS_TAB, () -> {
StringBuilder serverBoxes = new StringBuilder();
Map<Integer, List<TPS>> playersOnlineData = getValue(NetworkKeys.NETWORK_PLAYER_ONLINE_DATA).orElse(new HashMap<>());
Map<Integer, Integer> registerData = getValue(NetworkKeys.SERVER_REGISTER_DATA).orElse(new HashMap<>());
getValue(NetworkKeys.BUKKIT_SERVERS).orElse(new ArrayList<>())
.stream()
Map<UUID, Integer> registerData = getValue(NetworkKeys.SERVER_REGISTER_DATA).orElse(new HashMap<>());
Collection<Server> servers = getValue(NetworkKeys.BUKKIT_SERVERS).orElse(new ArrayList<>());
servers.stream()
.sorted((one, two) -> String.CASE_INSENSITIVE_ORDER.compare(one.getName(), two.getName()))
.forEach(server -> {
int serverId = server.getId();
TPSMutator tpsMutator = new TPSMutator(playersOnlineData.getOrDefault(serverId, new ArrayList<>()));
int registered = registerData.getOrDefault(serverId, 0);
TPSMutator tpsMutator = new TPSMutator(playersOnlineData.getOrDefault(server.getId(), new ArrayList<>()));
int registered = registerData.getOrDefault(server.getUuid(), 0);
NetworkServerBox serverBox = new NetworkServerBox(server, registered, tpsMutator, graphs);
serverBoxes.append(serverBox.toHtml());
});
if (servers.isEmpty()) {
serverBoxes.append("<div class=\"row clearfix\">" +
"<div class=\"col-xs-12 col-sm-12 col-md-12 col-lg-12\">" +
"<div class=\"card\">" +
"<div class=\"header\">" +
"<div class=\"row clearfix\">" +
"<div class=\"col-xs-6 col-sm-6 col-lg-6\">" +
"<h2><i class=\"col-light-green fa fa-servers\"></i> No Servers</h2>" +
"</div><div class=\"body\">" +
"<p>No Bukkit/Sponge servers connected to Plan.</p>" +
"</div></div></div></div>");
}
return serverBoxes.toString();
});
}
@ -127,8 +137,8 @@ public class NetworkContainer extends DataContainer {
putCachingSupplier(healthInformation, () -> new NetworkHealthInformation(
this,
locale,
config.getNumber(Settings.ACTIVE_PLAY_THRESHOLD),
config.getNumber(Settings.ACTIVE_LOGIN_THRESHOLD),
config.get(TimeSettings.ACTIVE_PLAY_THRESHOLD),
config.get(TimeSettings.ACTIVE_LOGIN_THRESHOLD),
formatters.timeAmount(), formatters.decimals(), formatters.percentage()
));
putCachingSupplier(NetworkKeys.HEALTH_INDEX, () -> getUnsafe(healthInformation).getServerHealth());
@ -148,7 +158,7 @@ public class NetworkContainer extends DataContainer {
putCachingSupplier(NetworkKeys.NETWORK_NAME, () ->
Check.isBungeeAvailable() || Check.isVelocityAvailable() ?
config.getString(Settings.BUNGEE_NETWORK_NAME) :
config.get(ProxySettings.NETWORK_NAME) :
bungeeContainer.getValue(ServerKeys.NAME).orElse("Plan")
);
putSupplier(NetworkKeys.PLAYERS_ONLINE, serverProperties::getOnlinePlayers);
@ -171,7 +181,7 @@ public class NetworkContainer extends DataContainer {
graphs.line().playersOnlineGraph(TPSMutator.forContainer(bungeeContainer)).toHighChartsSeries()
);
Key<StackGraph> activityStackGraph = new Key<>(StackGraph.class, "ACTIVITY_STACK_GRAPH");
putSupplier(NetworkKeys.ACTIVITY_DATA, () -> getUnsafe(NetworkKeys.PLAYERS_MUTATOR).toActivityDataMap(getUnsafe(NetworkKeys.REFRESH_TIME), config.getNumber(Settings.ACTIVE_PLAY_THRESHOLD), config.getNumber(Settings.ACTIVE_LOGIN_THRESHOLD)));
putSupplier(NetworkKeys.ACTIVITY_DATA, () -> getUnsafe(NetworkKeys.PLAYERS_MUTATOR).toActivityDataMap(getUnsafe(NetworkKeys.REFRESH_TIME), config.get(TimeSettings.ACTIVE_PLAY_THRESHOLD), config.get(TimeSettings.ACTIVE_LOGIN_THRESHOLD)));
putSupplier(activityStackGraph, () -> graphs.stack().activityStackGraph(getUnsafe(NetworkKeys.ACTIVITY_DATA)));
putSupplier(NetworkKeys.ACTIVITY_STACK_CATEGORIES, () -> getUnsafe(activityStackGraph).toHighChartsLabels());
putSupplier(NetworkKeys.ACTIVITY_STACK_SERIES, () -> getUnsafe(activityStackGraph).toHighChartsSeries());

View File

@ -38,8 +38,8 @@ public class PlayerContainer extends DataContainer {
activityIndexCache = new HashMap<>();
}
public ActivityIndex getActivityIndex(long date, int minuteThreshold, int loginThreshold) {
return activityIndexCache.computeIfAbsent(date, time -> new ActivityIndex(this, time, minuteThreshold, loginThreshold));
public ActivityIndex getActivityIndex(long date, long playtimeMsThreshold, int loginThreshold) {
return activityIndexCache.computeIfAbsent(date, time -> new ActivityIndex(this, time, playtimeMsThreshold, loginThreshold));
}
public boolean playedBetween(long after, long before) {

View File

@ -74,7 +74,7 @@ public class NetworkKeys {
public static final Key<Collection<Server>> BUKKIT_SERVERS = new Key<>(new Type<Collection<Server>>() {}, "BUKKIT_SERVERS");
public static final Key<TreeMap<Long, Map<String, Set<UUID>>>> ACTIVITY_DATA = CommonKeys.ACTIVITY_DATA;
public static final Key<Map<Integer, List<TPS>>> NETWORK_PLAYER_ONLINE_DATA = new Key<>(new Type<Map<Integer, List<TPS>>>() {}, "NETWORK_PLAYER_ONLINE_DATA");
public static final Key<Map<Integer, Integer>> SERVER_REGISTER_DATA = new Key<>(new Type<Map<Integer, Integer>>() {}, "SERVER_REGISTER_DATA");
public static final Key<Map<UUID, Integer>> SERVER_REGISTER_DATA = new Key<>(new Type<Map<UUID, Integer>>() {}, "SERVER_REGISTER_DATA");
private NetworkKeys() {
/* static variable class */

View File

@ -24,20 +24,19 @@ import com.djrapitops.plugin.api.TimeAmount;
import java.util.List;
import java.util.Optional;
import java.util.concurrent.TimeUnit;
public class ActivityIndex {
private final double value;
private final int playThreshold;
private final long playtimeMsThreshold;
private final int loginThreshold;
public ActivityIndex(
DataContainer container, long date,
int minuteThreshold, int loginThreshold
long playtimeMsThreshold, int loginThreshold
) {
this.playThreshold = minuteThreshold;
this.playtimeMsThreshold = playtimeMsThreshold;
this.loginThreshold = loginThreshold;
value = calculate(container, date);
@ -53,7 +52,7 @@ public class ActivityIndex {
long twoWeeksAgo = date - 2L * week;
long threeWeeksAgo = date - 3L * week;
long activePlayThreshold = TimeUnit.MINUTES.toMillis(playThreshold);
long activePlayThreshold = playtimeMsThreshold;
int activeLoginThreshold = loginThreshold;
Optional<List<Session>> sessionsValue = container.getValue(PlayerKeys.SESSIONS);

View File

@ -86,8 +86,8 @@ public class PlayersMutator {
);
}
public PlayersMutator filterActive(long date, int minuteThreshold, int loginThreshold, double limit) {
return filterBy(player -> player.getActivityIndex(date, minuteThreshold, loginThreshold).getValue() >= limit);
public PlayersMutator filterActive(long date, long msThreshold, int loginThreshold, double limit) {
return filterBy(player -> player.getActivityIndex(date, msThreshold, loginThreshold).getValue() >= limit);
}
public PlayersMutator filterPlayedOnServer(UUID serverUUID) {
@ -139,7 +139,7 @@ public class PlayersMutator {
return pingPerCountry;
}
public TreeMap<Long, Map<String, Set<UUID>>> toActivityDataMap(long date, int minuteThreshold, int loginThreshold) {
public TreeMap<Long, Map<String, Set<UUID>>> toActivityDataMap(long date, long msThreshold, int loginThreshold) {
TreeMap<Long, Map<String, Set<UUID>>> activityData = new TreeMap<>();
for (long time = date; time >= date - TimeAmount.MONTH.toMillis(2L); time -= TimeAmount.WEEK.toMillis(1L)) {
Map<String, Set<UUID>> map = activityData.getOrDefault(time, new HashMap<>());
@ -148,7 +148,7 @@ public class PlayersMutator {
if (player.getValue(PlayerKeys.REGISTERED).orElse(0L) > time) {
continue;
}
ActivityIndex activityIndex = player.getActivityIndex(time, minuteThreshold, loginThreshold);
ActivityIndex activityIndex = player.getActivityIndex(time, msThreshold, loginThreshold);
String activityGroup = activityIndex.getGroup();
Set<UUID> uuids = map.getOrDefault(activityGroup, new HashSet<>());
@ -195,7 +195,7 @@ public class PlayersMutator {
Iterable<PlayerContainer> compareTo,
long dateLimit,
PlayersOnlineResolver onlineResolver,
int activityMinuteThreshold,
long activityMsThreshold,
int activityLoginThreshold
) {
Collection<PlayerContainer> retainedAfterMonth = new ArrayList<>();
@ -223,10 +223,10 @@ public class PlayersMutator {
}
List<RetentionData> retained = retainedAfterMonth.stream()
.map(player -> new RetentionData(player, onlineResolver, activityMinuteThreshold, activityLoginThreshold))
.map(player -> new RetentionData(player, onlineResolver, activityMsThreshold, activityLoginThreshold))
.collect(Collectors.toList());
List<RetentionData> notRetained = notRetainedAfterMonth.stream()
.map(player -> new RetentionData(player, onlineResolver, activityMinuteThreshold, activityLoginThreshold))
.map(player -> new RetentionData(player, onlineResolver, activityMsThreshold, activityLoginThreshold))
.collect(Collectors.toList());
RetentionData avgRetained = RetentionData.average(retained);
@ -234,7 +234,7 @@ public class PlayersMutator {
List<PlayerContainer> toBeRetained = new ArrayList<>();
for (PlayerContainer player : compareTo) {
RetentionData retentionData = new RetentionData(player, onlineResolver, activityMinuteThreshold, activityLoginThreshold);
RetentionData retentionData = new RetentionData(player, onlineResolver, activityMsThreshold, activityLoginThreshold);
if (retentionData.distance(avgRetained) < retentionData.distance(avgNotRetained)) {
toBeRetained.add(player);
}

View File

@ -60,7 +60,7 @@ public class RetentionData {
public RetentionData(
PlayerContainer player,
PlayersOnlineResolver onlineOnJoin,
int activityMinuteThreshold,
long activityMsThreshold,
int activityLoginThreshold
) {
Optional<Long> registeredValue = player.getValue(PlayerKeys.REGISTERED);
@ -68,7 +68,7 @@ public class RetentionData {
.map(registered -> new ActivityIndex(
player,
registered + TimeUnit.DAYS.toMillis(1L),
activityMinuteThreshold,
activityMsThreshold,
activityLoginThreshold
).getValue())
.orElse(0.0);

View File

@ -38,7 +38,7 @@ public abstract class AbstractHealthInfo {
protected double serverHealth;
protected final Locale locale;
protected final int activeMinuteThreshold;
protected final long activeMsThreshold;
protected final int activeLoginThreshold;
protected final Formatter<Long> timeAmountFormatter;
protected final Formatter<Double> decimalFormatter;
@ -46,7 +46,8 @@ public abstract class AbstractHealthInfo {
public AbstractHealthInfo(
long now, long monthAgo,
Locale locale, int activeMinuteThreshold,
Locale locale,
long activeMsThreshold,
int activeLoginThreshold,
Formatter<Long> timeAmountFormatter,
Formatter<Double> decimalFormatter,
@ -55,7 +56,7 @@ public abstract class AbstractHealthInfo {
this.now = now;
this.monthAgo = monthAgo;
this.locale = locale;
this.activeMinuteThreshold = activeMinuteThreshold;
this.activeMsThreshold = activeMsThreshold;
this.activeLoginThreshold = activeLoginThreshold;
this.timeAmountFormatter = timeAmountFormatter;
this.decimalFormatter = decimalFormatter;
@ -139,7 +140,7 @@ public abstract class AbstractHealthInfo {
}
protected void activePlayerPlaytimeChange(PlayersMutator playersMutator) {
PlayersMutator currentlyActive = playersMutator.filterActive(now, activeMinuteThreshold, activeLoginThreshold, 1.75);
PlayersMutator currentlyActive = playersMutator.filterActive(now, activeMsThreshold, activeLoginThreshold, 1.75);
long twoWeeksAgo = now - ((now - monthAgo) / 2L);
long totalFourToTwoWeeks = 0;
@ -156,13 +157,17 @@ public abstract class AbstractHealthInfo {
long avgLastTwoWeeks = totalLastTwoWeeks / (long) activeCount;
String avgLastTwoWeeksString = timeAmountFormatter.apply(avgLastTwoWeeks);
String avgFourToTwoWeeksString = timeAmountFormatter.apply(avgFourToTwoWeeks);
if (avgFourToTwoWeeks >= avgLastTwoWeeks) {
// Played more or equal amount than 2 weeks ago
if (avgLastTwoWeeks >= avgFourToTwoWeeks) {
addNote(Icons.GREEN_THUMB + locale.getString(HealthInfoLang.ACTIVE_PLAY_COMPARISON_INCREASE,
avgLastTwoWeeksString, avgFourToTwoWeeksString));
// Played more than 2 hours less, than 2 weeks ago
} else if (avgFourToTwoWeeks - avgLastTwoWeeks > TimeUnit.HOURS.toMillis(2L)) {
addNote(Icons.RED_WARN + locale.getString(HealthInfoLang.ACTIVE_PLAY_COMPARISON_DECREASE,
avgLastTwoWeeksString, avgFourToTwoWeeksString));
serverHealth -= 5;
// Played less than two weeks ago
} else {
addNote(Icons.YELLOW_FLAG + locale.getString(HealthInfoLang.ACTIVE_PLAY_COMPARISON_DECREASE,
avgLastTwoWeeksString, avgFourToTwoWeeksString));

View File

@ -47,7 +47,7 @@ public class HealthInformation extends AbstractHealthInfo {
AnalysisContainer analysisContainer,
Locale locale,
int lowTPSThreshold,
int activeMinuteThreshold,
long activeMsThreshold,
int activeLoginThreshold,
Formatter<Long> timeAmountFormatter,
Formatter<Double> decimalFormatter,
@ -57,7 +57,7 @@ public class HealthInformation extends AbstractHealthInfo {
analysisContainer.getUnsafe(AnalysisKeys.ANALYSIS_TIME),
analysisContainer.getUnsafe(AnalysisKeys.ANALYSIS_TIME_MONTH_AGO),
locale,
activeMinuteThreshold, activeLoginThreshold,
activeMsThreshold, activeLoginThreshold,
timeAmountFormatter, decimalFormatter, percentageFormatter
);
this.analysisContainer = analysisContainer;

View File

@ -39,7 +39,7 @@ public class NetworkHealthInformation extends AbstractHealthInfo {
public NetworkHealthInformation(
NetworkContainer container,
Locale locale,
int activeMinuteThreshold,
long activeMsThreshold,
int activeLoginThreshold,
Formatter<Long> timeAmountFormatter,
Formatter<Double> decimalFormatter,
@ -49,7 +49,7 @@ public class NetworkHealthInformation extends AbstractHealthInfo {
container.getUnsafe(NetworkKeys.REFRESH_TIME),
container.getUnsafe(NetworkKeys.REFRESH_TIME_MONTH_AGO),
locale,
activeMinuteThreshold, activeLoginThreshold,
activeMsThreshold, activeLoginThreshold,
timeAmountFormatter, decimalFormatter, percentageFormatter
);
this.container = container;

View File

@ -24,7 +24,6 @@ import java.util.Map;
* TimeKeeper class that tracks the time spent in each GameMode based on Playtime.
*
* @author Rsl1122
* @since 3.6.0
*/
public class GMTimes extends TimeKeeper {

View File

@ -24,7 +24,6 @@ import java.util.Objects;
* Class that tracks the time spent in each World based on GMTimes.
*
* @author Rsl1122
* @since 4.0.0
*/
public class WorldTimes {
@ -78,7 +77,7 @@ public class WorldTimes {
*/
public void updateState(String worldName, String gameMode, long changeTime) {
GMTimes currentGMTimes = times.get(currentWorld);
if (worldName.equals(currentWorld)) {
if (currentWorld.equals(worldName)) {
currentGMTimes.changeState(gameMode, changeTime);
} else {
GMTimes newGMTimes = times.get(worldName);

View File

@ -28,8 +28,8 @@ import com.djrapitops.plan.system.info.InfoSystem;
import com.djrapitops.plan.system.info.ProxyInfoSystem;
import com.djrapitops.plan.system.info.connection.ConnectionSystem;
import com.djrapitops.plan.system.info.connection.ProxyConnectionSystem;
import com.djrapitops.plan.system.settings.config.ConfigSystem;
import com.djrapitops.plan.system.settings.config.ProxyConfigSystem;
import com.djrapitops.plan.system.settings.ConfigSystem;
import com.djrapitops.plan.system.settings.ProxyConfigSystem;
import dagger.Binds;
import dagger.Module;

View File

@ -29,7 +29,7 @@ import com.djrapitops.plan.system.info.server.ServerInfo;
import com.djrapitops.plan.system.listeners.ListenerSystem;
import com.djrapitops.plan.system.locale.LocaleSystem;
import com.djrapitops.plan.system.processing.Processing;
import com.djrapitops.plan.system.settings.config.ConfigSystem;
import com.djrapitops.plan.system.settings.ConfigSystem;
import com.djrapitops.plan.system.tasks.TaskSystem;
import com.djrapitops.plan.system.update.VersionCheckSystem;
import com.djrapitops.plan.system.webserver.WebServerSystem;
@ -49,6 +49,8 @@ import javax.inject.Singleton;
@Singleton
public class PlanSystem implements SubSystem {
private boolean enabled = false;
private final PlanFiles files;
private final ConfigSystem configSystem;
private final VersionCheckSystem versionCheckSystem;
@ -130,6 +132,7 @@ public class PlanSystem implements SubSystem {
taskSystem,
hookHandler
);
enabled = true;
}
private void enableSystems(SubSystem... systems) throws EnableException {
@ -140,6 +143,7 @@ public class PlanSystem implements SubSystem {
@Override
public void disable() {
enabled = false;
disableSystems(
taskSystem,
hookHandler,
@ -240,4 +244,8 @@ public class PlanSystem implements SubSystem {
public HtmlUtilities getHtmlUtilities() {
return htmlUtilities;
}
public boolean isEnabled() {
return enabled;
}
}

View File

@ -18,11 +18,10 @@ package com.djrapitops.plan.system.afk;
import com.djrapitops.plan.data.container.Session;
import com.djrapitops.plan.system.cache.SessionCache;
import com.djrapitops.plan.system.settings.Settings;
import com.djrapitops.plan.system.settings.config.PlanConfig;
import com.djrapitops.plan.system.settings.paths.TimeSettings;
import java.util.*;
import java.util.concurrent.TimeUnit;
/**
* Keeps track how long player has been afk during a session
@ -33,12 +32,12 @@ public class AFKTracker {
private final Set<UUID> usedAFKCommand;
private final Map<UUID, Long> lastMovement;
private final long afkThresholdMs;
private final PlanConfig config;
public AFKTracker(PlanConfig config) {
this.config = config;
usedAFKCommand = new HashSet<>();
lastMovement = new HashMap<>();
afkThresholdMs = TimeUnit.MINUTES.toMillis(config.getNumber(Settings.AFK_THRESHOLD_MINUTES));
}
public void hasIgnorePermission(UUID uuid) {
@ -47,7 +46,7 @@ public class AFKTracker {
public void usedAfkCommand(UUID uuid, long time) {
usedAFKCommand.add(uuid);
lastMovement.put(uuid, time - afkThresholdMs);
lastMovement.put(uuid, time - config.get(TimeSettings.AFK_THRESHOLD));
}
public void performedAction(UUID uuid, long time) {
@ -58,12 +57,12 @@ public class AFKTracker {
lastMovement.put(uuid, time);
try {
if (time - lastMoved < afkThresholdMs) {
if (time - lastMoved < config.get(TimeSettings.AFK_THRESHOLD)) {
// Threshold not crossed, no action required.
return;
}
long removeAfkCommandEffect = usedAFKCommand.contains(uuid) ? afkThresholdMs : 0;
long removeAfkCommandEffect = usedAFKCommand.contains(uuid) ? config.get(TimeSettings.AFK_THRESHOLD) : 0;
long timeAFK = time - lastMoved - removeAfkCommandEffect;
Optional<Session> cachedSession = SessionCache.getCachedSession(uuid);
@ -90,6 +89,6 @@ public class AFKTracker {
if (lastMoved == null || lastMoved == -1) {
return false;
}
return time - lastMoved > afkThresholdMs;
return time - lastMoved > config.get(TimeSettings.AFK_THRESHOLD);
}
}

View File

@ -39,7 +39,6 @@ import java.util.UUID;
* </ul>
*
* @author Rsl1122
* @since 4.0.0
*/
@Singleton
public class DataCache extends SessionCache implements SubSystem {

View File

@ -21,8 +21,8 @@ import com.djrapitops.plan.system.SubSystem;
import com.djrapitops.plan.system.file.PlanFiles;
import com.djrapitops.plan.system.locale.Locale;
import com.djrapitops.plan.system.locale.lang.PluginLang;
import com.djrapitops.plan.system.settings.Settings;
import com.djrapitops.plan.system.settings.config.PlanConfig;
import com.djrapitops.plan.system.settings.paths.DataGatheringSettings;
import com.djrapitops.plugin.logging.L;
import com.djrapitops.plugin.logging.console.PluginLogger;
import com.maxmind.geoip2.DatabaseReader;
@ -51,7 +51,6 @@ import java.util.zip.GZIPInputStream;
* It caches all IPs with their matching country.
*
* @author Fuzzlemann
* @since 3.5.5
*/
@Singleton
public class GeolocationCache implements SubSystem {
@ -82,7 +81,7 @@ public class GeolocationCache implements SubSystem {
@Override
public void enable() throws EnableException {
geolocationDB = files.getFileFromPluginFolder("GeoIP.dat");
if (config.isTrue(Settings.DATA_GEOLOCATIONS)) {
if (config.isTrue(DataGatheringSettings.GEOLOCATIONS)) {
try {
checkDB();
} catch (UnknownHostException e) {

View File

@ -29,7 +29,6 @@ import java.util.UUID;
* This class is used to store active sessions of players in memory.
*
* @author Rsl1122
* @since 3.0.0
*/
public class SessionCache {

View File

@ -22,7 +22,6 @@ import java.util.Optional;
* An enum which stores the name, the config name and if the Database supports MySQL Queries
*
* @author Fuzzlemann
* @since 4.5.1
*/
public enum DBType {

View File

@ -63,5 +63,4 @@ public abstract class Database {
public abstract void scheduleClean(long delay);
public abstract TransferOperations transfer();
}

View File

@ -25,6 +25,7 @@ import com.djrapitops.plan.data.store.containers.NetworkContainer;
import com.djrapitops.plan.data.store.containers.PlayerContainer;
import com.djrapitops.plan.data.store.containers.ServerContainer;
import com.djrapitops.plan.system.info.server.Server;
import com.djrapitops.plan.system.settings.config.Config;
import java.util.*;
@ -134,5 +135,7 @@ public interface FetchOperations {
Map<Integer, List<TPS>> getPlayersOnlineForServers(Collection<Server> servers);
Map<Integer, Integer> getPlayersRegisteredForServers(Collection<Server> servers);
Map<UUID, Integer> getPlayersRegisteredForServers(Collection<Server> servers);
Optional<Config> getNewConfig(long updatedAfter, UUID serverUUID);
}

View File

@ -20,6 +20,7 @@ import com.djrapitops.plan.data.WebUser;
import com.djrapitops.plan.data.container.*;
import com.djrapitops.plan.data.store.objects.Nickname;
import com.djrapitops.plan.system.info.server.Server;
import com.djrapitops.plan.system.settings.config.Config;
import java.util.List;
import java.util.Map;
@ -83,4 +84,6 @@ public interface SaveOperations {
void ping(UUID uuid, Ping ping);
void setAsUninstalled(UUID serverUUID);
void saveConfig(UUID serverUUID, Config config, long lastModified);
}

View File

@ -0,0 +1,97 @@
/*
* This file is part of Player Analytics (Plan).
*
* Plan is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License v3 as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Plan is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Plan. If not, see <https://www.gnu.org/licenses/>.
*/
package com.djrapitops.plan.system.database.databases.sql;
import com.djrapitops.plan.system.database.databases.DBType;
import com.djrapitops.plan.system.database.databases.sql.operation.Queries;
import com.djrapitops.plan.system.database.databases.sql.statements.Column;
import com.djrapitops.plan.system.database.databases.sql.tables.*;
import com.djrapitops.plugin.task.AbsRunnable;
import org.apache.commons.text.TextStringBuilder;
public class CreateIndexTask extends AbsRunnable {
private final SQLDB db;
public CreateIndexTask(SQLDB db) {
this.db = db;
}
@Override
public void run() {
createIndex(UsersTable.TABLE_NAME, "plan_users_uuid_index",
UsersTable.Col.UUID
);
createIndex(UserInfoTable.TABLE_NAME, "plan_user_info_uuid_index",
UserInfoTable.Col.UUID,
UserInfoTable.Col.SERVER_UUID
);
createIndex(SessionsTable.TABLE_NAME, "plan_sessions_uuid_index",
SessionsTable.Col.UUID,
SessionsTable.Col.SERVER_UUID
);
createIndex(SessionsTable.TABLE_NAME, "plan_sessions_date_index",
SessionsTable.Col.SESSION_START
);
createIndex(WorldTimesTable.TABLE_NAME, "plan_world_times_uuid_index",
WorldTimesTable.Col.UUID,
WorldTimesTable.Col.SERVER_UUID
);
createIndex(KillsTable.TABLE_NAME, "plan_kills_uuid_index",
KillsTable.Col.KILLER_UUID,
KillsTable.Col.VICTIM_UUID,
KillsTable.Col.SERVER_UUID
);
createIndex(KillsTable.TABLE_NAME, "plan_kills_date_index",
KillsTable.Col.DATE
);
createIndex(PingTable.TABLE_NAME, "plan_ping_uuid_index",
PingTable.Col.UUID,
PingTable.Col.SERVER_UUID
);
createIndex(PingTable.TABLE_NAME, "plan_ping_date_index",
PingTable.Col.DATE
);
createIndex(TPSTable.TABLE_NAME, "plan_tps_date_index",
TPSTable.Col.DATE
);
}
private void createIndex(String tableName, String indexName, Column... indexedColumns) {
if (indexedColumns.length == 0) {
throw new IllegalArgumentException("Can not create index without columns");
}
boolean isMySQL = db.getType() == DBType.MYSQL;
if (isMySQL) {
boolean indexExists = db.query(Queries.doesIndexExist(indexName, tableName));
if (indexExists) return;
}
TextStringBuilder sql = new TextStringBuilder("CREATE INDEX ");
if (!isMySQL) {
sql.append("IF NOT EXISTS ");
}
sql.append(indexName).append(" ON ").append(tableName);
sql.append(" (");
sql.appendWithSeparators(indexedColumns, ",");
sql.append(")");
db.execute(sql.toString());
}
}

View File

@ -22,8 +22,8 @@ import com.djrapitops.plan.system.database.databases.DBType;
import com.djrapitops.plan.system.file.PlanFiles;
import com.djrapitops.plan.system.info.server.ServerInfo;
import com.djrapitops.plan.system.locale.Locale;
import com.djrapitops.plan.system.settings.Settings;
import com.djrapitops.plan.system.settings.config.PlanConfig;
import com.djrapitops.plan.system.settings.paths.DatabaseSettings;
import com.djrapitops.plan.utilities.MiscUtils;
import com.djrapitops.plugin.benchmarking.Timings;
import com.djrapitops.plugin.logging.L;
@ -45,7 +45,6 @@ import java.util.Objects;
* Implementation of the H2 database
*
* @author Fuzzlemann
* @since 4.5.1
*/
public class H2DB extends SQLDB {
@ -92,8 +91,8 @@ public class H2DB extends SQLDB {
}
private Connection getConnectionFor(String dbFilePath) throws SQLException {
String username = config.getString(Settings.DB_USER);
String password = config.getString(Settings.DB_PASS);
String username = config.get(DatabaseSettings.MYSQL_USER);
String password = config.get(DatabaseSettings.MYSQL_PASS);
JdbcDataSource jdbcDataSource = new JdbcDataSource();
jdbcDataSource.setURL("jdbc:h2:file:" + dbFilePath + ";mode=MySQL");
@ -105,10 +104,14 @@ public class H2DB extends SQLDB {
private void startConnectionPingTask() {
stopConnectionPingTask();
// Maintains Connection.
connectionPingTask = runnableFactory.create("DBConnectionPingTask " + getType().getName(),
new KeepAliveTask(connection, () -> getNewConnection(databaseFile), logger, errorHandler)
).runTaskTimerAsynchronously(60L * 20L, 60L * 20L);
try {
// Maintains Connection.
connectionPingTask = runnableFactory.create("DBConnectionPingTask " + getType().getName(),
new KeepAliveTask(connection, () -> getNewConnection(databaseFile), logger, errorHandler)
).runTaskTimerAsynchronously(60L * 20L, 60L * 20L);
} catch (Exception ignored) {
// Task failed to register because plugin is being disabled
}
}
private void stopConnectionPingTask() {

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