Merge pull request #558 from Rsl1122/4.2.0

Pull Request for 4.2.0
This commit is contained in:
Rsl1122 2018-04-07 14:06:56 +03:00 committed by GitHub
commit e40c63bc0e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
162 changed files with 2852 additions and 1329 deletions

26
.travis.yml Normal file
View File

@ -0,0 +1,26 @@
language: java
sudo: false
install: true
before_install:
- pwd
- cd PlanPluginBridge
- ls
- mvn install:install-file -Dfile=/home/travis/build/Rsl1122/Plan-PlayerAnalytics/PlanPluginBridge/PlanPluginBridge-4.2.0.jar -DpomFile=/home/travis/build/Rsl1122/Plan-PlayerAnalytics/PlanPluginBridge/pom.xml
- cd ../Plan
- ls
install:
- mvn install -DskipTests
addons:
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
script:
- pwd
- mvn clean org.jacoco:jacoco-maven-plugin:prepare-agent package sonar:sonar
cache:
directories:
- '$HOME/.m2/repository'
- '$HOME/.sonar/cache'

View File

@ -115,6 +115,10 @@
<id>paper-repo</id>
<url>https://repo.destroystokyo.com/repository/maven-public/</url>
</repository>
<repository>
<id>sponge-repo</id>
<url>https://repo.spongepowered.org/maven</url>
</repository>
</repositories>
<dependencies>
<dependency>
@ -253,6 +257,74 @@
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.spongepowered</groupId>
<artifactId>spongeapi</artifactId>
<version>7.0.0</version>
<scope>provided</scope>
<exclusions>
<exclusion>
<artifactId>error_prone_annotations</artifactId>
<groupId>com.google.errorprone</groupId>
</exclusion>
<exclusion>
<artifactId>guice</artifactId>
<groupId>com.google.inject</groupId>
</exclusion>
<exclusion>
<artifactId>caffeine</artifactId>
<groupId>com.github.ben-manes.caffeine</groupId>
</exclusion>
<exclusion>
<artifactId>guava</artifactId>
<groupId>com.github.ben-manes.caffeine</groupId>
</exclusion>
<exclusion>
<artifactId>plugin-meta</artifactId>
<groupId>org.spongepowered</groupId>
</exclusion>
<exclusion>
<artifactId>configurate-hocon</artifactId>
<groupId>ninja.leaping.configurate</groupId>
</exclusion>
<exclusion>
<artifactId>configurate-gson</artifactId>
<groupId>ninja.leaping.configurate</groupId>
</exclusion>
<exclusion>
<artifactId>configurate-yaml</artifactId>
<groupId>ninja.leaping.configurate</groupId>
</exclusion>
<exclusion>
<artifactId>flow-math</artifactId>
<groupId>com.flowpowered</groupId>
</exclusion>
<exclusion>
<artifactId>flow-noise</artifactId>
<groupId>com.flowpowered</groupId>
</exclusion>
<exclusion>
<artifactId>asm</artifactId>
<groupId>org.ow2.asm</groupId>
</exclusion>
<exclusion>
<artifactId>slf4j-api</artifactId>
<groupId>org.slf4j</groupId>
</exclusion>
<exclusion>
<artifactId>jsr305</artifactId>
<groupId>com.google.code.findbugs</groupId>
</exclusion>
<exclusion>
<artifactId>gson</artifactId>
<groupId>com.google.code.gson</groupId>
</exclusion>
<exclusion>
<artifactId>guava</artifactId>
<groupId>com.google.guava</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>

View File

@ -19,6 +19,10 @@
<id>paper-repo</id>
<url>https://repo.destroystokyo.com/repository/maven-public/</url>
</repository>
<repository>
<id>sponge-repo</id>
<url>https://repo.spongepowered.org/maven</url>
</repository>
</repositories>
<dependencies>
<!-- Framework for easier plugin development -->
@ -62,6 +66,14 @@
<type>jar</type>
<scope>provided</scope>
</dependency>
<!-- SpongePowered -->
<dependency>
<groupId>org.spongepowered</groupId>
<artifactId>spongeapi</artifactId>
<version>7.0.0</version>
<type>jar</type>
<scope>provided</scope>
</dependency>
<!-- StringUtils lang3 -->
<dependency>
<groupId>org.apache.commons</groupId>

View File

@ -19,6 +19,7 @@
*/
package com.djrapitops.plan;
import com.djrapitops.plan.api.exceptions.EnableException;
import com.djrapitops.plan.command.PlanCommand;
import com.djrapitops.plan.system.BukkitSystem;
import com.djrapitops.plan.system.processing.importing.ImporterManager;
@ -35,6 +36,9 @@ import com.djrapitops.plugin.api.utility.log.Log;
import com.djrapitops.plugin.settings.ColorScheme;
import org.bukkit.configuration.file.FileConfiguration;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
* Main class for Bukkit that manages the plugin.
*
@ -76,9 +80,18 @@ public class Plan extends BukkitPlugin implements PlanPlugin {
Benchmark.stop("Enable", "Enable");
Log.logDebug("Enable");
Log.info(Locale.get(Msg.ENABLED).toString());
} catch (Exception e) {
} catch (AbstractMethodError e) {
Log.error("Plugin ran into AbstractMethodError - Server restart is required. Likely cause is updating the jar without a restart.");
} catch (EnableException e) {
Log.error("----------------------------------------");
Log.error("Error: " + e.getMessage());
Log.error("----------------------------------------");
Log.error("Plugin Failed to Initialize Correctly. If this issue is caused by config settings you can use /plan reload");
Log.toLog(this.getClass(), e);
onDisable();
} catch (Exception e) {
Logger.getGlobal().log(Level.SEVERE, this.getClass().getSimpleName() + "-v" + getVersion(), e);
Log.error("Plugin Failed to Initialize Correctly. If this issue is caused by config settings you can use /plan reload");
Log.error("This error should be reported at https://github.com/Rsl1122/Plan-PlayerAnalytics/issues");
onDisable();
}
registerCommand("plan", new PlanCommand(this));

View File

@ -4,6 +4,7 @@
*/
package com.djrapitops.plan;
import com.djrapitops.plan.api.exceptions.EnableException;
import com.djrapitops.plan.command.PlanBungeeCommand;
import com.djrapitops.plan.system.BungeeSystem;
import com.djrapitops.plan.system.settings.locale.Locale;
@ -17,6 +18,8 @@ import com.djrapitops.plugin.api.utility.log.Log;
import com.djrapitops.plugin.settings.ColorScheme;
import java.io.InputStream;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
* Bungee Main class.
@ -39,9 +42,19 @@ public class PlanBungee extends BungeePlugin implements PlanPlugin {
system.enable();
Log.info(Locale.get(Msg.ENABLED).toString());
} catch (AbstractMethodError e) {
Log.error("Plugin ran into AbstractMethodError - Server restart is required. Likely cause is updating the jar without a restart.");
} catch (EnableException e) {
Log.error("----------------------------------------");
Log.error("Error: " + e.getMessage());
Log.error("----------------------------------------");
Log.error("Plugin Failed to Initialize Correctly. If this issue is caused by config settings you can use /planbungee reload");
onDisable();
} catch (Exception e) {
Log.error("Plugin Failed to Initialize Correctly:");
Log.toLog(this.getClass(), e);
Logger.getGlobal().log(Level.SEVERE, this.getClass().getSimpleName() + "-v" + getVersion(), e);
Log.error("Plugin Failed to Initialize Correctly. If this issue is caused by config settings you can use /planbungee reload");
Log.error("This error should be reported at https://github.com/Rsl1122/Plan-PlayerAnalytics/issues");
onDisable();
}
registerCommand("planbungee", new PlanBungeeCommand(this));
}

View File

@ -20,6 +20,7 @@ public interface PlanPlugin extends IPlugin {
static PlanPlugin getInstance() {
boolean bukkitAvailable = Check.isBukkitAvailable();
boolean bungeeAvailable = Check.isBungeeAvailable();
boolean spongeAvailable = Check.isSpongeAvailable();
if (bukkitAvailable) {
try {
Plan instance = Plan.getInstance();
@ -38,6 +39,15 @@ public interface PlanPlugin extends IPlugin {
} catch (IllegalStateException ignored) {
}
}
if (spongeAvailable) {
try {
PlanSponge instance = PlanSponge.getInstance();
if (instance != null) {
return instance;
}
} catch (IllegalStateException ignored) {
}
}
throw new IllegalAccessError("Plugin instance not available");
}

View File

@ -0,0 +1,143 @@
package com.djrapitops.plan;
import com.djrapitops.plan.api.exceptions.EnableException;
import com.djrapitops.plan.system.SpongeSystem;
import com.djrapitops.plan.system.settings.locale.Locale;
import com.djrapitops.plan.system.settings.locale.Msg;
import com.djrapitops.plan.system.settings.theme.PlanColorScheme;
import com.djrapitops.plugin.SpongePlugin;
import com.djrapitops.plugin.StaticHolder;
import com.djrapitops.plugin.api.Benchmark;
import com.djrapitops.plugin.api.utility.log.DebugLog;
import com.djrapitops.plugin.api.utility.log.Log;
import com.djrapitops.plugin.settings.ColorScheme;
import com.google.inject.Inject;
import org.slf4j.Logger;
import org.spongepowered.api.config.ConfigDir;
import org.spongepowered.api.event.Listener;
import org.spongepowered.api.event.game.state.GameStartedServerEvent;
import org.spongepowered.api.event.game.state.GameStoppingServerEvent;
import org.spongepowered.api.plugin.Plugin;
import java.io.File;
import java.io.InputStream;
@Plugin(id = "plan", name = "Plan", version = "4.2.0")
public class PlanSponge extends SpongePlugin implements PlanPlugin {
@Inject
private Logger logger;
@Inject
@ConfigDir(sharedRoot = false)
private File dataFolder;
private SpongeSystem system;
@Listener
public void onServerStart(GameStartedServerEvent event) {
onEnable();
}
@Listener
public void onServerStop(GameStoppingServerEvent event) {
onDisable();
}
public static PlanSponge getInstance() {
return (PlanSponge) StaticHolder.getInstance(PlanSponge.class);
}
@Override
public void onEnable() {
super.onEnable();
system = new SpongeSystem(this);
try {
system.enable();
} catch (AbstractMethodError e) {
Log.error("Plugin ran into AbstractMethodError - Server restart is required. Likely cause is updating the jar without a restart.");
} catch (EnableException e) {
Log.error("----------------------------------------");
Log.error("Error: " + e.getMessage());
Log.error("----------------------------------------");
Log.error("Plugin Failed to Initialize Correctly. If this issue is caused by config settings you can use /plan reload");
onDisable();
} catch (Exception e) {
Log.toLog(this.getClass().getSimpleName() + "-v" + getVersion(), e);
Log.error("Plugin Failed to Initialize Correctly. If this issue is caused by config settings you can use /plan reload");
Log.error("This error should be reported at https://github.com/Rsl1122/Plan-PlayerAnalytics/issues");
onDisable();
}
}
@Override
public void onDisable() {
if (system != null) {
system.disable();
}
Log.info(Locale.get(Msg.DISABLED).toString());
Benchmark.pluginDisabled(PlanSponge.class);
DebugLog.pluginDisabled(PlanSponge.class);
}
@Override
public InputStream getResource(String resource) {
return getClass().getResourceAsStream("/" + resource);
}
@Override
public ColorScheme getColorScheme() {
return PlanColorScheme.create();
}
@Override
public void onReload() {
}
@Override
public boolean isReloading() {
return false;
}
@Override
public void log(String level, String msg) {
switch (level.toUpperCase()) {
case "INFO_COLOR":
case "INFO":
case "I":
logger.info(msg);
break;
case "W":
case "WARN":
case "WARNING":
logger.warn(msg);
break;
case "E":
case "ERR":
case "ERROR":
case "SEVERE":
logger.error(msg);
break;
default:
logger.info(msg);
break;
}
}
@Override
public File getDataFolder() {
return dataFolder;
}
@Override
public String getVersion() {
return "4.2.0";
}
public SpongeSystem getSystem() {
return system;
}
}

View File

@ -14,7 +14,6 @@ import com.djrapitops.plan.system.cache.DataCache;
import com.djrapitops.plan.system.cache.SessionCache;
import com.djrapitops.plan.system.database.databases.Database;
import com.djrapitops.plan.utilities.MiscUtils;
import com.djrapitops.plugin.StaticHolder;
import com.djrapitops.plugin.api.utility.log.Log;
import java.util.Map;
@ -56,10 +55,6 @@ public class ShutdownHook extends Thread {
Map<UUID, Session> activeSessions = SessionCache.getActiveSessions();
long now = MiscUtils.getTime();
db = Database.getActive();
if (!db.isOpen()) {
db.init();
}
saveFirstSessionInformation(db, now);
saveActiveSessions(db, activeSessions, now);
} catch (IllegalStateException ignored) {
@ -74,13 +69,15 @@ public class ShutdownHook extends Thread {
Log.toLog(this.getClass(), e);
}
}
StaticHolder.unRegister(Plan.class);
}
}
private void saveFirstSessionInformation(Database db, long now) {
private void saveFirstSessionInformation(Database db, long now) throws DBInitException {
DataCache dataCache = CacheSystem.getInstance().getDataCache();
for (Map.Entry<UUID, Integer> entry : dataCache.getFirstSessionMsgCounts().entrySet()) {
if (!db.isOpen()) {
db.init();
}
try {
UUID uuid = entry.getKey();
int messagesSent = entry.getValue();
@ -91,7 +88,7 @@ public class ShutdownHook extends Thread {
}
}
private void saveActiveSessions(Database db, Map<UUID, Session> activeSessions, long now) {
private void saveActiveSessions(Database db, Map<UUID, Session> activeSessions, long now) throws DBInitException {
for (Map.Entry<UUID, Session> entry : activeSessions.entrySet()) {
UUID uuid = entry.getKey();
Session session = entry.getValue();
@ -99,6 +96,9 @@ public class ShutdownHook extends Thread {
if (sessionEnd == -1) {
session.endSession(now);
}
if (!db.isOpen()) {
db.init();
}
try {
Log.debug("Shutdown: Saving a session: " + session.getSessionStart());
db.save().session(uuid, session);

View File

@ -5,7 +5,7 @@
package com.djrapitops.plan.api;
import com.djrapitops.plan.data.plugin.PluginData;
import com.djrapitops.plan.system.BukkitSystem;
import com.djrapitops.plan.system.ServerSystem;
import com.djrapitops.plan.system.database.databases.operation.FetchOperations;
import java.util.UUID;
@ -15,26 +15,26 @@ import java.util.UUID;
*
* @author Rsl1122
*/
public class BukkitAPI extends CommonAPI {
public class ServerAPI extends CommonAPI {
private final BukkitSystem bukkitSystem;
private final ServerSystem serverSystem;
public BukkitAPI(BukkitSystem bukkitSystem) {
this.bukkitSystem = bukkitSystem;
public ServerAPI(ServerSystem serverSystem) {
this.serverSystem = serverSystem;
}
@Override
public void addPluginDataSource(PluginData pluginData) {
bukkitSystem.getHookHandler().addPluginDataSource(pluginData);
serverSystem.getHookHandler().addPluginDataSource(pluginData);
}
@Override
public String getPlayerName(UUID uuid) {
return bukkitSystem.getCacheSystem().getDataCache().getName(uuid);
return serverSystem.getCacheSystem().getDataCache().getName(uuid);
}
@Override
public FetchOperations fetchFromPlanDB() {
return bukkitSystem.getDatabaseSystem().getActiveDatabase().fetch();
return serverSystem.getDatabaseSystem().getActiveDatabase().fetch();
}
}

View File

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

View File

@ -7,7 +7,7 @@ import com.djrapitops.plan.system.info.InfoSystem;
import com.djrapitops.plan.system.info.connection.ConnectionSystem;
import com.djrapitops.plan.system.info.server.Server;
import com.djrapitops.plan.system.info.server.ServerInfo;
import com.djrapitops.plan.system.processing.Processor;
import com.djrapitops.plan.system.processing.Processing;
import com.djrapitops.plan.system.settings.Permissions;
import com.djrapitops.plan.system.settings.locale.Locale;
import com.djrapitops.plan.system.settings.locale.Msg;
@ -49,7 +49,7 @@ public class AnalyzeCommand extends SubCommand {
public boolean onCommand(ISender sender, String commandLabel, String[] args) {
sender.sendMessage(Locale.get(Msg.CMD_INFO_FETCH_DATA).toString());
Processor.queue(() -> {
Processing.submitNonCritical(() -> {
try {
Server server = getServer(args).orElseGet(ServerInfo::getServer);
UUID serverUUID = server.getUuid();
@ -59,7 +59,6 @@ public class AnalyzeCommand extends SubCommand {
sendWebUserNotificationIfNecessary(sender);
sendLink(server, sender);
} catch (DBException | WebException e) {
// TODO Exception handling
sender.sendMessage(ChatColor.RED + " Error occurred: " + e.toString());
Log.toLog(this.getClass(), e);
}

View File

@ -3,6 +3,7 @@ package com.djrapitops.plan.command.commands;
import com.djrapitops.plan.api.exceptions.database.DBException;
import com.djrapitops.plan.api.exceptions.database.FatalDBException;
import com.djrapitops.plan.system.database.databases.Database;
import com.djrapitops.plan.system.processing.Processing;
import com.djrapitops.plan.system.processing.processors.info.InspectCacheRequestProcessor;
import com.djrapitops.plan.system.settings.Permissions;
import com.djrapitops.plan.system.settings.locale.Locale;
@ -72,7 +73,7 @@ public class InspectCommand extends SubCommand {
sender.sendMessage(ChatColor.YELLOW + "[Plan] You might not have a web user, use /plan register <password>");
}
}
new InspectCacheRequestProcessor(uuid, sender, playerName).queue();
Processing.submit(new InspectCacheRequestProcessor(uuid, sender, playerName));
} catch (FatalDBException ex) {
Log.toLog(this.getClass(), ex);
sender.sendMessage(ChatColor.RED + "Fatal database exception occurred: " + ex.getMessage());

View File

@ -8,7 +8,7 @@ import com.djrapitops.plan.system.info.InfoSystem;
import com.djrapitops.plan.system.info.request.CheckConnectionRequest;
import com.djrapitops.plan.system.info.server.Server;
import com.djrapitops.plan.system.info.server.ServerInfo;
import com.djrapitops.plan.system.processing.Processor;
import com.djrapitops.plan.system.processing.Processing;
import com.djrapitops.plan.system.settings.Permissions;
import com.djrapitops.plan.system.settings.locale.Locale;
import com.djrapitops.plan.system.settings.locale.Msg;
@ -54,9 +54,7 @@ public class ManageConDebugCommand extends SubCommand {
return true;
}
Processor.queue(() -> {
testServers(sender);
});
Processing.submitNonCritical(() -> testServers(sender));
return true;
}

View File

@ -1,6 +1,7 @@
package com.djrapitops.plan.command.commands.manage;
import com.djrapitops.plan.system.processing.importing.ImporterManager;
import com.djrapitops.plan.system.processing.importing.importers.Importer;
import com.djrapitops.plan.system.settings.Permissions;
import com.djrapitops.plan.system.settings.locale.Locale;
import com.djrapitops.plan.system.settings.locale.Msg;
@ -38,20 +39,33 @@ public class ManageImportCommand extends SubCommand {
return true;
}
runImport("offlineimporter");
String importArg = args[0];
if (importArg.equals("list")) {
sender.sendMessage("Importers: ");
ImporterManager.getImporters().stream()
.map(Importer::getNames)
.map(list -> list.get(0))
.forEach(name -> sender.sendMessage("- " + name));
return true;
}
private void runImport(String importer) {
RunnableFactory.createNew("Import", new AbsRunnable() {
Importer importer = ImporterManager.getImporter(importArg);
if (importer == null) {
sender.sendMessage("§eImporter '" + importArg + "' doesn't exist");
return true;
}
RunnableFactory.createNew("Import:" + importArg, new AbsRunnable() {
@Override
public void run() {
try {
ImporterManager.getImporter(importer).processImport();
importer.processImport();
} finally {
this.cancel();
cancel();
}
}
}).runTaskAsynchronously();
return true;
}
}

View File

@ -2,7 +2,7 @@ package com.djrapitops.plan.command.commands.manage;
import com.djrapitops.plan.api.exceptions.connection.*;
import com.djrapitops.plan.system.info.InfoSystem;
import com.djrapitops.plan.system.processing.Processor;
import com.djrapitops.plan.system.processing.Processing;
import com.djrapitops.plan.system.settings.Permissions;
import com.djrapitops.plan.system.settings.Settings;
import com.djrapitops.plan.system.settings.locale.Locale;
@ -59,7 +59,7 @@ public class ManageSetupCommand extends SubCommand {
}
private void requestSetup(ISender sender, String address) {
Processor.queue(() -> {
Processing.submitNonCritical(() -> {
try {
Settings.BUNGEE_OVERRIDE_STANDALONE_MODE.set(false);
Settings.BUNGEE_COPY_CONFIG.set(true);

View File

@ -14,10 +14,6 @@ import com.djrapitops.plan.system.info.server.ServerInfo;
import com.djrapitops.plan.utilities.MiscUtils;
import com.djrapitops.plan.utilities.comparators.ActionComparator;
import com.djrapitops.plan.utilities.comparators.GeoInfoComparator;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.OfflinePlayer;
import org.bukkit.entity.Player;
import java.io.Serializable;
import java.util.*;
@ -31,7 +27,7 @@ import java.util.stream.Stream;
*
* @author Rsl1122
*/
public class PlayerProfile implements OfflinePlayer {
public class PlayerProfile {
// Identification
private final UUID uuid;
@ -172,10 +168,6 @@ public class PlayerProfile implements OfflinePlayer {
return getLastSeen(getAllSessions());
}
public long getLastSeen(UUID serverUUID) {
return getLastSeen(getSessions(serverUUID).stream());
}
public long getLastSeen(Stream<Session> s) {
OptionalLong max = s.mapToLong(session -> Math.max(session.getSessionStart(), session.getSessionEnd())).max();
if (max.isPresent()) {
@ -387,7 +379,6 @@ public class PlayerProfile implements OfflinePlayer {
return uuid;
}
@Override
public String getName() {
return name;
}
@ -435,70 +426,20 @@ public class PlayerProfile implements OfflinePlayer {
// OfflinePlayer methods for possible PluginData analysis
@Override
public boolean isOnline() {
Player p = getPlayer();
return p != null && p.isOnline();
}
@Override
public UUID getUniqueId() {
return uuid;
}
@Override
public boolean isBanned() {
return bannedOnServers.size() != 0;
}
@Override
public boolean isWhitelisted() {
return true;
}
@Override
public void setWhitelisted(boolean b) {
/* Do nothing */
}
@Override
public Player getPlayer() {
return Bukkit.getPlayer(uuid);
}
@Override
public long getFirstPlayed() {
return registered;
}
@Override
public long getLastPlayed() {
return getLastSeen(ServerInfo.getServerUUID());
}
@Override
public boolean hasPlayedBefore() {
return true;
}
@Override
public Location getBedSpawnLocation() {
return null;
}
@Override
public Map<String, Object> serialize() {
return new HashMap<>();
}
@Override
public boolean isOp() {
return oppedOnServers.contains(ServerInfo.getServerUUID());
}
@Override
public void setOp(boolean b) {
/* Do nothing */
public static long getAFKTime(Stream<Session> sessions) {
return sessions.mapToLong(Session::getAfkLength).sum();
}
public static long getActivePlaytime(Stream<Session> sessions) {
return sessions.mapToLong(Session::getActiveLength).sum();
}
public void calculateWorldTimesPerServer() {

View File

@ -45,17 +45,17 @@ public class ActivityIndex {
// Playtime per week multipliers, max out to avoid too high values.
double max = 4.0;
long playtimeWeek = PlayerProfile.getPlaytime(sessionsWeek.stream());
long playtimeWeek = PlayerProfile.getActivePlaytime(sessionsWeek.stream());
double weekPlay = (playtimeWeek * 1.0 / activePlayThreshold);
if (weekPlay > max) {
weekPlay = max;
}
long playtimeWeek2 = PlayerProfile.getPlaytime(sessionsWeek2.stream());
long playtimeWeek2 = PlayerProfile.getActivePlaytime(sessionsWeek2.stream());
double week2Play = (playtimeWeek2 * 1.0 / activePlayThreshold);
if (week2Play > max) {
week2Play = max;
}
long playtimeWeek3 = PlayerProfile.getPlaytime(sessionsWeek3.stream());
long playtimeWeek3 = PlayerProfile.getActivePlaytime(sessionsWeek3.stream());
double week3Play = (playtimeWeek3 * 1.0 / activePlayThreshold);
if (week3Play > max) {
week3Play = max;

View File

@ -23,6 +23,7 @@ import com.djrapitops.plan.utilities.html.Html;
import com.djrapitops.plan.utilities.html.graphs.ActivityStackGraph;
import com.djrapitops.plan.utilities.html.graphs.PunchCardGraph;
import com.djrapitops.plan.utilities.html.graphs.WorldMap;
import com.djrapitops.plan.utilities.html.graphs.calendar.ServerCalendar;
import com.djrapitops.plan.utilities.html.graphs.line.*;
import com.djrapitops.plan.utilities.html.graphs.pie.ActivityPie;
import com.djrapitops.plan.utilities.html.graphs.pie.WorldPie;
@ -128,6 +129,11 @@ public class AnalysisData extends RawData {
geolocationsTab(geoLocations);
commandUsage(commandUsage);
List<Long> registered = profile.getPlayers().stream().map(PlayerProfile::getRegistered).collect(Collectors.toList());
ServerCalendar serverCalendar = new ServerCalendar(registered, sessions);
addValue("calendarSeries", serverCalendar.toCalendarSeries());
addValue("firstDay", 1);
addValue("ops", ops.size());
addValue("playersTotal", playersTotal);

View File

@ -36,6 +36,8 @@ public class Session {
private int mobKills;
private int deaths;
private long afkTime;
/**
* Creates a new session with given start and end of -1.
*
@ -48,15 +50,10 @@ public class Session {
playerKills = new ArrayList<>();
mobKills = 0;
deaths = 0;
afkTime = 0;
}
/**
* Re-Creates a session data object for viewing.
*
* @param sessionStart Epoch millisecond the session was started.
* @param sessionEnd Epoch millisecond the session ended.
*/
public Session(int id, long sessionStart, long sessionEnd, int mobKills, int deaths) {
public Session(int id, long sessionStart, long sessionEnd, int mobKills, int deaths, long afkTime) {
this.sessionID = id;
this.sessionStart = sessionStart;
this.sessionEnd = sessionEnd;
@ -64,6 +61,7 @@ public class Session {
this.playerKills = new ArrayList<>();
this.mobKills = mobKills;
this.deaths = deaths;
this.afkTime = afkTime;
}
/**
@ -159,6 +157,18 @@ public class Session {
return sessionID != null;
}
public void addAFKTime(long timeAFK) {
afkTime += timeAFK;
}
public long getAfkLength() {
return afkTime;
}
public long getActiveLength() {
return getLength() - getAfkLength();
}
/**
* Used to get the ID of the session in the Database.
*

View File

@ -26,6 +26,8 @@ public abstract class PluginData {
private String pluginIcon;
private String iconColor;
private String helpText;
public PluginData(ContainerSize size, String sourcePlugin) {
this.size = size;
this.sourcePlugin = sourcePlugin;
@ -43,6 +45,10 @@ public abstract class PluginData {
this.iconColor = iconColor;
}
public final String getHelpText() {
return helpText;
}
public final String parsePluginIcon() {
return pluginIcon != null ? Html.FA_COLORED_ICON.parse((iconColor != null ? iconColor : "black"), pluginIcon) : Html.FONT_AWESOME_ICON.parse("cube");
}
@ -55,6 +61,10 @@ public abstract class PluginData {
return sourcePlugin;
}
protected final void setHelpText(String html) {
helpText = Html.HELP_BUBBLE.parse(sourcePlugin, html);
}
@Override
public final boolean equals(Object o) {
if (this == o) return true;

View File

@ -6,7 +6,7 @@ package com.djrapitops.plan.system;
import com.djrapitops.plan.Plan;
import com.djrapitops.plan.ShutdownHook;
import com.djrapitops.plan.api.BukkitAPI;
import com.djrapitops.plan.api.ServerAPI;
import com.djrapitops.plan.api.exceptions.EnableException;
import com.djrapitops.plan.data.plugin.HookHandler;
import com.djrapitops.plan.system.database.BukkitDBSystem;
@ -27,9 +27,10 @@ import com.djrapitops.plugin.api.utility.log.Log;
*
* @author Rsl1122
*/
public class BukkitSystem extends PlanSystem {
public class BukkitSystem extends PlanSystem implements ServerSystem {
public BukkitSystem(Plan plugin) {
testSystem = this;
Log.setErrorManager(new PlanErrorManager());
@ -45,7 +46,7 @@ public class BukkitSystem extends PlanSystem {
serverInfo = new BukkitServerInfo(plugin);
hookHandler = new HookHandler();
planAPI = new BukkitAPI(this);
planAPI = new ServerAPI(this);
StaticHolder.saveInstance(ShutdownHook.class, plugin.getClass());
new ShutdownHook().register();

View File

@ -13,7 +13,7 @@ import com.djrapitops.plan.system.file.FileSystem;
import com.djrapitops.plan.system.info.InfoSystem;
import com.djrapitops.plan.system.info.server.ServerInfo;
import com.djrapitops.plan.system.listeners.ListenerSystem;
import com.djrapitops.plan.system.processing.ProcessingQueue;
import com.djrapitops.plan.system.processing.Processing;
import com.djrapitops.plan.system.settings.config.ConfigSystem;
import com.djrapitops.plan.system.tasks.TaskSystem;
import com.djrapitops.plan.system.update.VersionCheckSystem;
@ -34,7 +34,7 @@ public abstract class PlanSystem implements SubSystem {
protected static PlanSystem testSystem;
// Initialized in this class
protected final ProcessingQueue processingQueue;
private Processing processing;
protected final WebServerSystem webServerSystem;
protected final CacheSystem cacheSystem;
@ -55,7 +55,7 @@ public abstract class PlanSystem implements SubSystem {
protected PlanAPI planAPI;
public PlanSystem() {
processingQueue = new ProcessingQueue();
processing = new Processing();
webServerSystem = new WebServerSystem();
cacheSystem = new CacheSystem(this);
}
@ -63,12 +63,15 @@ public abstract class PlanSystem implements SubSystem {
public static PlanSystem getInstance() {
boolean bukkitAvailable = Check.isBukkitAvailable();
boolean bungeeAvailable = Check.isBungeeAvailable();
boolean spongeAvailable = Check.isSpongeAvailable();
if (bukkitAvailable && bungeeAvailable) {
return testSystem;
} else if (bungeeAvailable) {
return BungeeSystem.getInstance();
} else if (bukkitAvailable) {
return BukkitSystem.getInstance();
} else if (spongeAvailable) {
return SpongeSystem.getInstance();
}
throw new IllegalAccessError("PlanSystem is not available on this platform.");
}
@ -83,7 +86,7 @@ public abstract class PlanSystem implements SubSystem {
configSystem,
databaseSystem,
webServerSystem,
processingQueue,
processing,
serverInfo,
infoSystem,
cacheSystem,
@ -103,7 +106,7 @@ public abstract class PlanSystem implements SubSystem {
hookHandler,
cacheSystem,
listenerSystem,
processingQueue,
processing,
databaseSystem,
webServerSystem,
infoSystem,
@ -136,16 +139,12 @@ public abstract class PlanSystem implements SubSystem {
Verify.nullCheck(hookHandler, () -> new IllegalStateException("Plugin Hooks were not initialized."));
Verify.nullCheck(planAPI, () -> new IllegalStateException("Plan API was not initialized."));
} catch (Exception e) {
throw new EnableException("One of the subsystems is not initialized on enable for " + this.getClass().getSimpleName() + ".", e);
throw new EnableException("One of the subsystems is not initialized on enable for " + this.getClass().getSimpleName() + ": " + e.getMessage());
}
}
// Accessor methods.
public ProcessingQueue getProcessingQueue() {
return processingQueue;
}
public VersionCheckSystem getVersionCheckSystem() {
return versionCheckSystem;
}
@ -193,4 +192,8 @@ public abstract class PlanSystem implements SubSystem {
public PlanAPI getPlanAPI() {
return planAPI;
}
public Processing getProcessing() {
return processing;
}
}

View File

@ -0,0 +1,14 @@
package com.djrapitops.plan.system;
import com.djrapitops.plan.data.plugin.HookHandler;
import com.djrapitops.plan.system.cache.CacheSystem;
import com.djrapitops.plan.system.database.DBSystem;
public interface ServerSystem {
HookHandler getHookHandler();
CacheSystem getCacheSystem();
DBSystem getDatabaseSystem();
}

View File

@ -0,0 +1,63 @@
/*
* Licence is provided in the jar as license.yml also here:
* https://github.com/Rsl1122/Plan-PlayerAnalytics/blob/master/Plan/src/main/resources/license.yml
*/
package com.djrapitops.plan.system;
import com.djrapitops.plan.PlanSponge;
import com.djrapitops.plan.ShutdownHook;
import com.djrapitops.plan.api.ServerAPI;
import com.djrapitops.plan.api.exceptions.EnableException;
import com.djrapitops.plan.data.plugin.HookHandler;
import com.djrapitops.plan.system.database.BukkitDBSystem;
import com.djrapitops.plan.system.file.FileSystem;
import com.djrapitops.plan.system.info.BukkitInfoSystem;
import com.djrapitops.plan.system.info.server.SpongeServerInfo;
import com.djrapitops.plan.system.listeners.SpongeListenerSystem;
import com.djrapitops.plan.system.settings.PlanErrorManager;
import com.djrapitops.plan.system.settings.config.BukkitConfigSystem;
import com.djrapitops.plan.system.settings.network.NetworkSettings;
import com.djrapitops.plan.system.tasks.SpongeTaskSystem;
import com.djrapitops.plan.system.update.VersionCheckSystem;
import com.djrapitops.plugin.StaticHolder;
import com.djrapitops.plugin.api.utility.log.Log;
/**
* Represents PlanSystem for PlanSponge.
*
* @author Rsl1122
*/
public class SpongeSystem extends PlanSystem implements ServerSystem {
public SpongeSystem(PlanSponge plugin) {
testSystem = this;
Log.setErrorManager(new PlanErrorManager());
versionCheckSystem = new VersionCheckSystem(plugin.getVersion());
fileSystem = new FileSystem(plugin);
configSystem = new BukkitConfigSystem();
databaseSystem = new BukkitDBSystem();
listenerSystem = new SpongeListenerSystem();
taskSystem = new SpongeTaskSystem();
infoSystem = new BukkitInfoSystem();
serverInfo = new SpongeServerInfo();
hookHandler = new HookHandler();
planAPI = new ServerAPI(this);
StaticHolder.saveInstance(ShutdownHook.class, plugin.getClass());
new ShutdownHook().register();
}
public static SpongeSystem getInstance() {
return PlanSponge.getInstance().getSystem();
}
@Override
public void enable() throws EnableException {
super.enable();
NetworkSettings.loadSettingsFromDB();
}
}

View File

@ -0,0 +1,51 @@
package com.djrapitops.plan.system.afk;
import com.djrapitops.plan.data.container.Session;
import com.djrapitops.plan.system.cache.SessionCache;
import com.djrapitops.plan.system.settings.Settings;
import com.djrapitops.plugin.api.TimeAmount;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
import java.util.UUID;
/**
* Keeps track how long player has been afk during a session
*
* @author Rsl1122
*/
public class AFKTracker {
private final Map<UUID, Long> lastMovement;
private final long afkThresholdMs;
public AFKTracker() {
lastMovement = new HashMap<>();
afkThresholdMs = Settings.AFK_THRESHOLD_MINUTES.getNumber() * TimeAmount.MINUTE.ms();
}
public void performedAction(UUID uuid, long time) {
Long lastMoved = lastMovement.getOrDefault(uuid, time);
lastMovement.put(uuid, time);
if (time - lastMoved < afkThresholdMs) {
// Threshold not crossed, no action required.
return;
}
long timeAFK = time - lastMoved;
Optional<Session> cachedSession = SessionCache.getCachedSession(uuid);
if (!cachedSession.isPresent()) {
return;
}
Session session = cachedSession.get();
session.addAFKTime(timeAFK);
}
public void loggedOut(UUID uuid, long time) {
performedAction(uuid, time);
lastMovement.remove(uuid);
}
}

View File

@ -4,8 +4,6 @@ import com.djrapitops.plan.api.exceptions.database.DBException;
import com.djrapitops.plan.data.container.Session;
import com.djrapitops.plan.system.PlanSystem;
import com.djrapitops.plan.system.database.databases.Database;
import com.djrapitops.plan.system.info.connection.WebExceptionLogger;
import com.djrapitops.plan.system.processing.Processor;
import com.djrapitops.plan.utilities.MiscUtils;
import com.djrapitops.plugin.api.utility.log.Log;
import com.djrapitops.plugin.utilities.Verify;
@ -54,9 +52,6 @@ public class SessionCache {
public void cacheSession(UUID uuid, Session session) {
activeSessions.put(uuid, session);
Processor.queue(() -> WebExceptionLogger.logIfOccurs(this.getClass(), () ->
system.getInfoSystem().generateAndCachePlayerPage(uuid))
);
}
public void endSession(UUID uuid, long time) {
@ -71,8 +66,6 @@ public class SessionCache {
Log.toLog(this.getClass(), e);
} finally {
activeSessions.remove(uuid);
WebExceptionLogger.logIfOccurs(this.getClass(), () -> system.getInfoSystem().generateAndCachePlayerPage(uuid));
}
}

View File

@ -49,7 +49,8 @@ public abstract class DBSystem implements SubSystem {
Log.info(Locale.get(Msg.ENABLE_DB_INFO).parse(db.getConfigName()));
Benchmark.stop("Enable", "Init Database");
} catch (DBInitException e) {
throw new EnableException("Database failed to initialize", e);
Throwable cause = e.getCause();
throw new EnableException(db.getName() + " init failure: " + cause.getMessage(), cause);
}
}

View File

@ -88,4 +88,6 @@ public interface FetchOperations {
List<Server> getServers() throws DBException;
List<UUID> getServerUUIDs() throws DBException;
List<String> getNetworkGeolocations() throws DBException;
}

View File

@ -6,7 +6,6 @@ package com.djrapitops.plan.system.database.databases.operation;
import com.djrapitops.plan.api.exceptions.database.DBException;
import java.util.Map;
import java.util.Optional;
import java.util.UUID;
@ -21,31 +20,12 @@ public interface TransferOperations {
// Save
void storePlayerHtml(UUID player, String encodedHtml) throws DBException;
void storeServerHtml(UUID serverUUID, String encodedHtml) throws DBException;
void storeNetworkPageContent(UUID serverUUID, String encodedHtml) throws DBException;
void storePlayerPluginsTab(UUID player, String encodedHtml) throws DBException;
void storeConfigSettings(String encodedSettingString) throws DBException;
@Deprecated
void playerOnline(UUID playerUUID) throws DBException;
// Get
Map<UUID, String> getEncodedPlayerHtml() throws DBException;
Map<UUID, String> getEncodedNetworkPageContent() throws DBException;
Map<UUID, String> getEncodedServerHtml() throws DBException;
@Deprecated
Optional<UUID> getServerPlayerIsOnlineOn(UUID playerUUID) throws DBException;
Map<UUID, String> getEncodedPlayerPluginsTabs(UUID playerUUID) throws DBException;
Optional<String> getEncodedConfigSettings() throws DBException;
}

View File

@ -111,7 +111,6 @@ public abstract class SQLDB extends Database {
}
} catch (SQLException e) {
Log.toLog(this.getClass(), e);
} finally {
cancel();
}
}
@ -134,7 +133,7 @@ public abstract class SQLDB extends Database {
if (newDatabase) {
Log.info("New Database created.");
versionTable.setVersion(14);
versionTable.setVersion(16);
}
int version = versionTable.getVersion();
@ -169,6 +168,15 @@ public abstract class SQLDB extends Database {
transferTable.alterTableV14();
versionTable.setVersion(14);
}
if (version < 15) {
sessionsTable.alterTableV15();
versionTable.setVersion(15);
}
if (version < 16) {
killsTable.alterTableV16();
worldTimesTable.alterTableV16();
versionTable.setVersion(16);
}
} catch (SQLException e) {
throw new DBInitException("Failed to set-up Database", e);
}

View File

@ -416,4 +416,13 @@ public class SQLFetchOps extends SQLOps implements FetchOperations {
throw SQLErrorUtil.getExceptionFor(e);
}
}
@Override
public List<String> getNetworkGeolocations() throws DBException {
try {
return geoInfoTable.getNetworkGeolocations();
} catch (SQLException e) {
throw SQLErrorUtil.getExceptionFor(e);
}
}
}

View File

@ -9,7 +9,6 @@ import com.djrapitops.plan.system.database.databases.operation.TransferOperation
import com.djrapitops.plan.system.database.databases.sql.SQLDB;
import java.sql.SQLException;
import java.util.Map;
import java.util.Optional;
import java.util.UUID;
@ -24,69 +23,6 @@ public class SQLTransferOps extends SQLOps implements TransferOperations {
super(db);
}
@Override
public void storePlayerHtml(UUID player, String encodedHtml) throws DBException {
try {
transferTable.storePlayerHtml(player, encodedHtml);
} catch (SQLException e) {
throw SQLErrorUtil.getExceptionFor(e);
}
}
@Override
public void storeServerHtml(UUID serverUUID, String encodedHtml) throws DBException {
try {
transferTable.storeServerHtml(serverUUID, encodedHtml);
} catch (SQLException e) {
throw SQLErrorUtil.getExceptionFor(e);
}
}
@Override
public void storeNetworkPageContent(UUID serverUUID, String encodedHtml) throws DBException {
try {
transferTable.storeNetworkPageContent(serverUUID, encodedHtml);
} catch (SQLException e) {
throw SQLErrorUtil.getExceptionFor(e);
}
}
@Override
public Map<UUID, String> getEncodedPlayerHtml() throws DBException {
try {
return transferTable.getPlayerHtml();
} catch (SQLException e) {
throw SQLErrorUtil.getExceptionFor(e);
}
}
@Override
public Map<UUID, String> getEncodedNetworkPageContent() throws DBException {
try {
return transferTable.getNetworkPageContent();
} catch (SQLException e) {
throw SQLErrorUtil.getExceptionFor(e);
}
}
@Override
public Map<UUID, String> getEncodedServerHtml() throws DBException {
try {
return transferTable.getServerHtml();
} catch (SQLException e) {
throw SQLErrorUtil.getExceptionFor(e);
}
}
@Override
public void storePlayerPluginsTab(UUID player, String encodedHtml) throws DBException {
try {
transferTable.storePlayerPluginsTab(player, encodedHtml);
} catch (SQLException e) {
throw SQLErrorUtil.getExceptionFor(e);
}
}
@Override
public Optional<UUID> getServerPlayerIsOnlineOn(UUID playerUUID) throws DBException {
try {
@ -96,15 +32,6 @@ public class SQLTransferOps extends SQLOps implements TransferOperations {
}
}
@Override
public Map<UUID, String> getEncodedPlayerPluginsTabs(UUID playerUUID) throws DBException {
try {
return transferTable.getPlayerPluginsTabs(playerUUID);
} catch (SQLException e) {
throw SQLErrorUtil.getExceptionFor(e);
}
}
@Override
public void storeConfigSettings(String encodedSettingString) throws DBException {
try {
@ -123,12 +50,4 @@ public class SQLTransferOps extends SQLOps implements TransferOperations {
}
}
@Override
public void playerOnline(UUID playerUUID) throws DBException {
try {
transferTable.storePlayerOnlineOnThisServer(playerUUID);
} catch (SQLException e) {
throw SQLErrorUtil.getExceptionFor(e);
}
}
}

View File

@ -179,6 +179,30 @@ public class GeoInfoTable extends UserIDTable {
});
}
public List<String> getNetworkGeolocations() throws SQLException {
String subQuery = "SELECT " +
Col.USER_ID + ", " +
"MAX(" + Col.LAST_USED + ") as max" +
" FROM " + tableName +
" GROUP BY " + Col.USER_ID;
String sql = "SELECT " +
"f." + Col.GEOLOCATION +
" FROM (" + subQuery + ") as x" +
" INNER JOIN " + tableName + " AS f ON f." + Col.USER_ID + "=x." + Col.USER_ID +
" AND f." + Col.LAST_USED + "=x.max";
return query(new QueryAllStatement<List<String>>(sql) {
@Override
public List<String> processResults(ResultSet set) throws SQLException {
List<String> geolocations = new ArrayList<>();
while (set.next()) {
geolocations.add(set.getString(Col.GEOLOCATION.get()));
}
return geolocations;
}
});
}
public enum Col implements Column {
USER_ID(UserIDTable.Col.USER_ID.get()),
IP("ip"),

View File

@ -10,6 +10,7 @@ import com.djrapitops.plan.system.database.databases.sql.processing.QueryStateme
import com.djrapitops.plan.system.database.databases.sql.statements.Column;
import com.djrapitops.plan.system.database.databases.sql.statements.Sql;
import com.djrapitops.plan.system.database.databases.sql.statements.TableSqlParser;
import com.djrapitops.plan.system.info.server.ServerInfo;
import com.djrapitops.plugin.utilities.Verify;
import java.sql.PreparedStatement;
@ -28,18 +29,23 @@ import java.util.*;
*/
public class KillsTable extends UserIDTable {
private final ServerTable serverTable;
public KillsTable(SQLDB db) {
super("plan_kills", db);
sessionsTable = db.getSessionsTable();
serverTable = db.getServerTable();
insertStatement = "INSERT INTO " + tableName + " ("
+ Col.KILLER_ID + ", "
+ Col.VICTIM_ID + ", "
+ Col.SERVER_ID + ", "
+ Col.SESSION_ID + ", "
+ Col.DATE + ", "
+ Col.WEAPON
+ ") VALUES ("
+ usersTable.statementSelectID + ", "
+ usersTable.statementSelectID + ", "
+ serverTable.statementSelectServerID + ", "
+ "?, ?, ?)";
}
@ -51,12 +57,14 @@ public class KillsTable extends UserIDTable {
createTable(TableSqlParser.createTable(tableName)
.column(Col.KILLER_ID, Sql.INT).notNull()
.column(Col.VICTIM_ID, Sql.INT).notNull()
.column(Col.SERVER_ID, Sql.INT).notNull()
.column(Col.WEAPON, Sql.varchar(30)).notNull()
.column(Col.DATE, Sql.LONG).notNull()
.column(Col.SESSION_ID, Sql.INT).notNull()
.foreignKey(Col.KILLER_ID, usersTable.getTableName(), UsersTable.Col.ID)
.foreignKey(Col.VICTIM_ID, usersTable.getTableName(), UsersTable.Col.ID)
.foreignKey(Col.SESSION_ID, sessionsTable.getTableName(), SessionsTable.Col.ID)
.foreignKey(Col.SERVER_ID, serverTable.getTableName(), ServerTable.Col.SERVER_ID)
.toString()
);
}
@ -131,9 +139,10 @@ public class KillsTable extends UserIDTable {
statement.setString(1, uuid.toString());
statement.setString(2, victim.toString());
statement.setInt(3, sessionID);
statement.setLong(4, date);
statement.setString(5, weapon);
statement.setString(3, ServerInfo.getServerUUID().toString());
statement.setInt(4, sessionID);
statement.setLong(5, date);
statement.setString(6, weapon);
statement.addBatch();
}
}
@ -243,9 +252,10 @@ public class KillsTable extends UserIDTable {
String weapon = kill.getWeapon();
statement.setString(1, killer.toString());
statement.setString(2, victim.toString());
statement.setInt(3, sessionID);
statement.setLong(4, date);
statement.setString(5, weapon);
statement.setString(3, serverUUID.toString());
statement.setInt(4, sessionID);
statement.setLong(5, date);
statement.setString(6, weapon);
statement.addBatch();
}
}
@ -255,9 +265,33 @@ public class KillsTable extends UserIDTable {
});
}
public void alterTableV16() throws SQLException {
addColumns(Col.SERVER_ID + " integer NOT NULL DEFAULT 0");
Map<Integer, Integer> sessionIDServerIDRelation = sessionsTable.getIDServerIDRelation();
String sql = "UPDATE " + tableName + " SET " +
Col.SERVER_ID + "=?" +
" WHERE " + Col.SESSION_ID + "=?";
executeBatch(new ExecStatement(sql) {
@Override
public void prepare(PreparedStatement statement) throws SQLException {
for (Map.Entry<Integer, Integer> entry : sessionIDServerIDRelation.entrySet()) {
Integer sessionID = entry.getKey();
Integer serverID = entry.getValue();
statement.setInt(1, serverID);
statement.setInt(2, sessionID);
statement.addBatch();
}
}
});
}
public enum Col implements Column {
KILLER_ID("killer_id"),
VICTIM_ID("victim_id"),
SERVER_ID("server_id"),
SESSION_ID("session_id"),
WEAPON("weapon"),
DATE("date");

View File

@ -30,8 +30,10 @@ import java.util.*;
*/
public class ServerTable extends Table {
public static final String TABLE_NAME = "plan_servers";
public ServerTable(SQLDB db) {
super("plan_servers", db);
super(TABLE_NAME, db);
statementSelectServerID = "(" + Select.from(tableName, tableName + "." + Col.SERVER_ID).where(tableName + "." + Col.SERVER_UUID + "=?").toString() + " LIMIT 1)";
statementSelectServerNameID = "(" + Select.from(tableName, tableName + "." + Col.NAME).where(tableName + "." + Col.SERVER_ID + "=?").toString() + " LIMIT 1)";
insertStatement = Insert.values(tableName,

View File

@ -27,8 +27,10 @@ import java.util.stream.Collectors;
*/
public class SessionsTable extends UserIDTable {
public static final String TABLE_NAME = "plan_sessions";
public SessionsTable(SQLDB db) {
super("plan_sessions", db);
super(TABLE_NAME, db);
serverTable = db.getServerTable();
insertStatement = "INSERT INTO " + tableName + " ("
+ Col.USER_ID + ", "
@ -36,10 +38,11 @@ public class SessionsTable extends UserIDTable {
+ Col.SESSION_END + ", "
+ Col.DEATHS + ", "
+ Col.MOB_KILLS + ", "
+ Col.AFK_TIME + ", "
+ Col.SERVER_ID
+ ") VALUES ("
+ usersTable.statementSelectID + ", "
+ "?, ?, ?, ?, "
+ "?, ?, ?, ?, ?, "
+ serverTable.statementSelectServerID + ")";
}
@ -56,6 +59,7 @@ public class SessionsTable extends UserIDTable {
.column(Col.SESSION_END, Sql.LONG).notNull()
.column(Col.MOB_KILLS, Sql.INT).notNull()
.column(Col.DEATHS, Sql.INT).notNull()
.column(Col.AFK_TIME, Sql.LONG).notNull()
.foreignKey(Col.USER_ID, usersTable.getTableName(), UsersTable.Col.ID)
.foreignKey(Col.SERVER_ID, serverTable.getTableName(), ServerTable.Col.SERVER_ID)
.primaryKey(usingMySQL, Col.ID)
@ -132,7 +136,8 @@ public class SessionsTable extends UserIDTable {
statement.setLong(3, session.getSessionEnd());
statement.setInt(4, session.getDeaths());
statement.setInt(5, session.getMobKills());
statement.setString(6, ServerInfo.getServerUUID().toString());
statement.setLong(6, session.getAfkLength());
statement.setString(7, ServerInfo.getServerUUID().toString());
}
});
}
@ -172,10 +177,12 @@ public class SessionsTable extends UserIDTable {
throw new IllegalStateException("Server not present");
}
long timeAFK = set.getLong(Col.AFK_TIME.get());
int deaths = set.getInt(Col.DEATHS.get());
int mobKills = set.getInt(Col.MOB_KILLS.get());
List<Session> sessions = sessionsByServer.getOrDefault(serverUUID, new ArrayList<>());
sessions.add(new Session(id, start, end, mobKills, deaths));
sessions.add(new Session(id, start, end, mobKills, deaths, timeAFK));
sessionsByServer.put(serverUUID, sessions);
}
return sessionsByServer;
@ -458,6 +465,7 @@ public class SessionsTable extends UserIDTable {
Col.SESSION_END + ", " +
Col.DEATHS + ", " +
Col.MOB_KILLS + ", " +
Col.AFK_TIME + ", " +
usersUUIDColumn +
" FROM " + tableName +
" INNER JOIN " + usersTable + " on " + usersIDColumn + "=" + Col.USER_ID +
@ -479,8 +487,11 @@ public class SessionsTable extends UserIDTable {
int deaths = set.getInt(Col.DEATHS.get());
int mobKills = set.getInt(Col.MOB_KILLS.get());
long timeAFK = set.getLong(Col.AFK_TIME.get());
List<Session> sessions = sessionsByUser.getOrDefault(uuid, new ArrayList<>());
sessions.add(new Session(set.getInt(Col.ID.get()), start, end, mobKills, deaths));
sessions.add(new Session(set.getInt(Col.ID.get()), start, end, mobKills, deaths, timeAFK));
sessionsByUser.put(uuid, sessions);
}
return sessionsByUser;
@ -515,7 +526,6 @@ public class SessionsTable extends UserIDTable {
});
}
// TODO Write tests for this method
public Map<UUID, Long> getLastSeenForAllPlayers() throws SQLException {
String usersIDColumn = usersTable + "." + UsersTable.Col.ID;
String usersUUIDColumn = usersTable + "." + UsersTable.Col.UUID + " as uuid";
@ -551,7 +561,8 @@ public class SessionsTable extends UserIDTable {
Col.SESSION_START + ", " +
Col.SESSION_END + ", " +
Col.DEATHS + ", " +
Col.MOB_KILLS +
Col.MOB_KILLS + ", " +
Col.AFK_TIME +
" FROM " + tableName;
return query(new QueryAllStatement<Map<UUID, Map<UUID, List<Session>>>>(sql, 20000) {
@ -572,7 +583,9 @@ public class SessionsTable extends UserIDTable {
int mobKills = set.getInt(Col.MOB_KILLS.get());
int id = set.getInt(Col.ID.get());
Session session = new Session(id, start, end, mobKills, deaths);
long timeAFK = set.getLong(Col.AFK_TIME.get());
Session session = new Session(id, start, end, mobKills, deaths, timeAFK);
sessions.add(session);
sessionsByUser.put(uuid, sessions);
@ -598,7 +611,8 @@ public class SessionsTable extends UserIDTable {
Col.SESSION_START + ", " +
Col.SESSION_END + ", " +
Col.DEATHS + ", " +
Col.MOB_KILLS +
Col.MOB_KILLS + ", " +
Col.AFK_TIME +
" FROM " + tableName +
" WHERE " + Col.SESSION_START + ">?";
@ -625,7 +639,9 @@ public class SessionsTable extends UserIDTable {
int mobKills = set.getInt(Col.MOB_KILLS.get());
int id = set.getInt(Col.ID.get());
Session session = new Session(id, start, end, mobKills, deaths);
long timeAFK = set.getLong(Col.AFK_TIME.get());
Session session = new Session(id, start, end, mobKills, deaths, timeAFK);
sessions.add(session);
sessionsByUser.put(uuid, sessions);
@ -655,7 +671,8 @@ public class SessionsTable extends UserIDTable {
statement.setLong(3, session.getSessionEnd());
statement.setInt(4, session.getDeaths());
statement.setInt(5, session.getMobKills());
statement.setString(6, serverUUID.toString());
statement.setLong(6, session.getAfkLength());
statement.setString(7, serverUUID.toString());
statement.addBatch();
}
}
@ -718,6 +735,28 @@ public class SessionsTable extends UserIDTable {
}
}
public void alterTableV15() {
addColumns(Col.AFK_TIME + " bigint NOT NULL DEFAULT 0");
}
public Map<Integer, Integer> getIDServerIDRelation() throws SQLException {
String sql = "SELECT " +
Col.ID + ", " +
Col.SERVER_ID +
" FROM " + tableName;
return query(new QueryAllStatement<Map<Integer, Integer>>(sql, 10000) {
@Override
public Map<Integer, Integer> processResults(ResultSet set) throws SQLException {
HashMap<Integer, Integer> idServerIdMap = new HashMap<>();
while (set.next()) {
idServerIdMap.put(set.getInt(Col.ID.get()), set.getInt(Col.SERVER_ID.get()));
}
return idServerIdMap;
}
});
}
public enum Col implements Column {
USER_ID(UserIDTable.Col.USER_ID.get()),
ID("id"),
@ -725,7 +764,8 @@ public class SessionsTable extends UserIDTable {
SESSION_START("session_start"),
SESSION_END("session_end"),
MOB_KILLS("mob_kills"),
DEATHS("deaths");
DEATHS("deaths"),
AFK_TIME("afk_time");
private final String column;

View File

@ -43,6 +43,13 @@ public abstract class Table {
}
}
protected void renameTable(String to) throws SQLException {
String sql = usingMySQL ?
"RENAME TABLE " + tableName + " TO " + to :
"ALTER TABLE " + tableName + " RENAME TO " + to;
execute(sql);
}
/**
* Used to get a new Connection to the Database.
*

View File

@ -11,19 +11,15 @@ import com.djrapitops.plan.system.database.databases.sql.processing.QueryStateme
import com.djrapitops.plan.system.database.databases.sql.statements.Column;
import com.djrapitops.plan.system.database.databases.sql.statements.Sql;
import com.djrapitops.plan.system.database.databases.sql.statements.TableSqlParser;
import com.djrapitops.plan.system.info.request.CacheAnalysisPageRequest;
import com.djrapitops.plan.system.info.request.CacheInspectPageRequest;
import com.djrapitops.plan.system.info.request.CacheInspectPluginsTabRequest;
import com.djrapitops.plan.system.info.request.CacheNetworkPageContentRequest;
import com.djrapitops.plan.system.info.server.ServerInfo;
import com.djrapitops.plan.utilities.Base64Util;
import com.djrapitops.plan.utilities.MiscUtils;
import com.djrapitops.plugin.api.TimeAmount;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.*;
import java.util.Optional;
import java.util.UUID;
/**
* Table that is in charge of transferring data between network servers.
@ -39,23 +35,12 @@ public class TransferTable extends Table {
private final String insertStatementNoParts;
private final ServerTable serverTable;
private final String insertStatementParts;
private final String selectStatement;
public TransferTable(SQLDB db) {
super("plan_transfer", db);
serverTable = db.getServerTable();
insertStatementParts = "REPLACE INTO " + tableName + " (" +
Col.SENDER_ID + ", " +
Col.EXPIRY + ", " +
Col.INFO_TYPE + ", " +
Col.EXTRA_VARIABLES + ", " +
Col.CONTENT + ", " +
Col.PART +
") VALUES (" +
serverTable.statementSelectServerID + ", " +
"?, ?, ?, ?, ?)";
insertStatementNoParts = "REPLACE INTO " + tableName + " (" +
Col.SENDER_ID + ", " +
Col.EXPIRY + ", " +
@ -116,142 +101,6 @@ public class TransferTable extends Table {
});
}
public void storePlayerHtml(UUID player, String encodedHtml) throws SQLException {
execute(new ExecStatement(insertStatementNoParts) {
@Override
public void prepare(PreparedStatement statement) throws SQLException {
statement.setString(1, ServerInfo.getServerUUID().toString());
statement.setLong(2, MiscUtils.getTime() + TimeAmount.MINUTE.ms());
statement.setString(3, CacheInspectPageRequest.class.getSimpleName().toLowerCase());
statement.setString(4, player.toString());
statement.setString(5, encodedHtml);
}
});
}
public void storeServerHtml(UUID serverUUID, String encodedHtml) throws SQLException {
List<String> split = Base64Util.split(encodedHtml, 500000L);
int i = 0;
long expires = MiscUtils.getTime() + TimeAmount.MINUTE.ms();
for (String part : split) {
final int partNumber = i;
execute(new ExecStatement(insertStatementParts) {
@Override
public void prepare(PreparedStatement statement) throws SQLException {
statement.setString(1, ServerInfo.getServerUUID().toString());
statement.setLong(2, expires);
statement.setString(3, CacheAnalysisPageRequest.class.getSimpleName().toLowerCase());
statement.setString(4, serverUUID.toString());
statement.setString(5, part);
statement.setInt(6, partNumber);
}
});
i++;
}
}
public void storeNetworkPageContent(UUID serverUUID, String encodedHtml) throws SQLException {
execute(new ExecStatement(insertStatementNoParts) {
@Override
public void prepare(PreparedStatement statement) throws SQLException {
statement.setString(1, ServerInfo.getServerUUID().toString());
statement.setLong(2, MiscUtils.getTime() + TimeAmount.MINUTE.ms());
statement.setString(3, CacheNetworkPageContentRequest.class.getSimpleName().toLowerCase());
statement.setString(4, serverUUID.toString());
statement.setString(5, encodedHtml);
}
});
}
private Map<UUID, String> getHtmlPerUUIDForCacheRequest(Class c) throws SQLException {
return query(new QueryStatement<Map<UUID, String>>(selectStatement, 250) {
@Override
public void prepare(PreparedStatement statement) throws SQLException {
statement.setString(1, c.getSimpleName().toLowerCase());
statement.setLong(2, MiscUtils.getTime());
}
@Override
public Map<UUID, String> processResults(ResultSet set) throws SQLException {
Map<UUID, String> htmlPerUUID = new HashMap<>();
Map<UUID, Long> expiry = new HashMap<>();
while (set.next()) {
String uuidString = set.getString(Col.EXTRA_VARIABLES.get());
UUID uuid = UUID.fromString(uuidString);
long expires = set.getLong(Col.EXPIRY.get());
long correctExpiry = expiry.getOrDefault(uuid, expires);
if (expires == correctExpiry) {
htmlPerUUID.put(uuid, htmlPerUUID.getOrDefault(uuid, "") + set.getString(Col.CONTENT.get()));
expiry.put(uuid, correctExpiry);
}
}
return htmlPerUUID;
}
});
}
public void storePlayerPluginsTab(UUID player, String encodedHtml) throws SQLException {
execute(new ExecStatement(insertStatementNoParts) {
@Override
public void prepare(PreparedStatement statement) throws SQLException {
statement.setString(1, ServerInfo.getServerUUID().toString());
statement.setLong(2, MiscUtils.getTime() + TimeAmount.MINUTE.ms());
statement.setString(3, CacheInspectPluginsTabRequest.class.getSimpleName().toLowerCase());
statement.setString(4, player.toString());
statement.setString(5, encodedHtml);
}
});
}
public Map<UUID, String> getPlayerHtml() throws SQLException {
return getHtmlPerUUIDForCacheRequest(CacheInspectPageRequest.class);
}
public Map<UUID, String> getNetworkPageContent() throws SQLException {
return getHtmlPerUUIDForCacheRequest(CacheNetworkPageContentRequest.class);
}
public Map<UUID, String> getServerHtml() throws SQLException {
return getHtmlPerUUIDForCacheRequest(CacheAnalysisPageRequest.class);
}
public Map<UUID, String> getPlayerPluginsTabs(UUID playerUUID) throws SQLException {
String serverIDColumn = serverTable + "." + ServerTable.Col.SERVER_ID;
String serverUUIDColumn = serverTable + "." + ServerTable.Col.SERVER_UUID + " as s_uuid";
String sql = "SELECT " +
Col.CONTENT + ", " +
serverUUIDColumn +
" FROM " + tableName +
" INNER JOIN " + serverTable + " on " + serverIDColumn + "=" + Col.SENDER_ID +
" WHERE " + Col.INFO_TYPE + "= ?" +
" AND " + Col.EXPIRY + "> ?" +
" AND " + Col.EXTRA_VARIABLES + "=?";
return query(new QueryStatement<Map<UUID, String>>(sql, 250) {
@Override
public void prepare(PreparedStatement statement) throws SQLException {
statement.setString(1, CacheInspectPluginsTabRequest.class.getSimpleName().toLowerCase());
statement.setLong(2, MiscUtils.getTime());
statement.setString(3, playerUUID.toString());
}
@Override
public Map<UUID, String> processResults(ResultSet set) throws SQLException {
Map<UUID, String> htmlPerUUID = new HashMap<>();
while (set.next()) {
UUID serverUUID = UUID.fromString(set.getString("s_uuid"));
String html64 = set.getString(Col.CONTENT.get());
htmlPerUUID.put(serverUUID, html64);
}
return htmlPerUUID;
}
});
}
@Deprecated
public Optional<UUID> getServerPlayerIsOnline(UUID playerUUID) throws SQLException {
String serverIDColumn = serverTable + "." + ServerTable.Col.SERVER_ID;
@ -279,20 +128,6 @@ public class TransferTable extends Table {
});
}
@Deprecated
public void storePlayerOnlineOnThisServer(UUID playerUUID) throws SQLException {
execute(new ExecStatement(insertStatementNoParts) {
@Override
public void prepare(PreparedStatement statement) throws SQLException {
statement.setString(1, ServerInfo.getServerUUID().toString());
statement.setLong(2, MiscUtils.getTime() + TimeAmount.MINUTE.ms());
statement.setString(3, "onlineStatus");
statement.setString(4, playerUUID.toString());
statement.setString(5, null);
}
});
}
public void storeConfigSettings(String encodedSettingString) throws SQLException {
execute(new ExecStatement(insertStatementNoParts) {
@Override

View File

@ -16,9 +16,6 @@ import java.util.UUID;
*/
public abstract class UserIDTable extends Table {
@Deprecated
protected final String columnUserID = "user_id";
public enum Col implements Column {
USER_ID("user_id");
@ -46,7 +43,7 @@ public abstract class UserIDTable extends Table {
}
public void removeUser(UUID uuid) throws SQLException {
String sql = "DELETE FROM " + tableName + " WHERE (" + columnUserID + "=" + usersTable.statementSelectID + ")";
String sql = "DELETE FROM " + tableName + " WHERE (" + Col.USER_ID + "=" + usersTable.statementSelectID + ")";
execute(new ExecStatement(sql) {
@Override

View File

@ -10,11 +10,14 @@ import com.djrapitops.plan.system.database.databases.sql.statements.Sql;
import com.djrapitops.plan.system.database.databases.sql.statements.TableSqlParser;
import com.djrapitops.plan.system.info.server.ServerInfo;
import com.djrapitops.plugin.utilities.Verify;
import com.google.common.base.Objects;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;
/**
* Table class representing database table plan_worlds.
@ -26,19 +29,27 @@ import java.util.*;
*/
public class WorldTable extends Table {
public WorldTable(SQLDB db) {
super("plan_worlds", db);
statementSelectID = "(SELECT " + Col.ID + " FROM " + tableName + " WHERE (" + Col.NAME + "=?) LIMIT 1)";
}
public static final String TABLE_NAME = "plan_worlds";
public final String statementSelectID;
private final ServerTable serverTable;
public WorldTable(SQLDB db) {
super(TABLE_NAME, db);
serverTable = db.getServerTable();
statementSelectID = "(SELECT " + Col.ID + " FROM " + tableName +
" WHERE (" + Col.NAME + "=?)" +
" AND (" + Col.SERVER_ID + "=" + serverTable.statementSelectServerID + ")" +
" LIMIT 1)";
}
@Override
public void createTable() throws DBInitException {
createTable(TableSqlParser.createTable(tableName)
.primaryKeyIDColumn(usingMySQL, Col.ID)
.column(Col.NAME, Sql.varchar(100)).notNull()
.column(Col.SERVER_ID, Sql.INT).notNull()
.primaryKey(usingMySQL, Col.ID)
.foreignKey(Col.SERVER_ID, ServerTable.TABLE_NAME, ServerTable.Col.SERVER_ID)
.toString()
);
}
@ -49,7 +60,7 @@ public class WorldTable extends Table {
* @return List of all world names in the database.
* @throws SQLException Database error occurs.
*/
public List<String> getWorlds() throws SQLException {
public List<String> getAllWorlds() throws SQLException {
String sql = "SELECT * FROM " + tableName;
return query(new QueryAllStatement<List<String>>(sql) {
@ -65,6 +76,78 @@ public class WorldTable extends Table {
});
}
public Map<UUID, List<String>> getWorldsPerServer() throws SQLException {
Map<Integer, UUID> serverUUIDsByID = serverTable.getServerUUIDsByID();
String sql = "SELECT * FROM " + tableName;
return query(new QueryAllStatement<Map<UUID, List<String>>>(sql, 1000) {
@Override
public Map<UUID, List<String>> processResults(ResultSet set) throws SQLException {
Map<UUID, List<String>> worldsPerServer = new HashMap<>();
while (set.next()) {
UUID serverUUID = serverUUIDsByID.get(set.getInt(Col.SERVER_ID.get()));
String worldName = set.getString(Col.NAME.get());
List<String> worlds = worldsPerServer.getOrDefault(serverUUID, new ArrayList<>());
worlds.add(worldName);
worldsPerServer.put(serverUUID, worlds);
}
return worldsPerServer;
}
});
}
public Map<Integer, UUID> getServerUUIDByWorldID() throws SQLException {
Map<Integer, UUID> serverUUIDsByID = serverTable.getServerUUIDsByID();
String sql = "SELECT DISTINCT " +
Col.ID + ", " +
Col.SERVER_ID +
" FROM " + tableName;
return query(new QueryAllStatement<Map<Integer, UUID>>(sql, 100) {
@Override
public Map<Integer, UUID> processResults(ResultSet set) throws SQLException {
Map<Integer, UUID> idMap = new HashMap<>();
while (set.next()) {
int worldId = set.getInt(Col.ID.get());
int serverId = set.getInt(Col.SERVER_ID.get());
UUID serverUUID = serverUUIDsByID.getOrDefault(serverId, ServerInfo.getServerUUID());
idMap.put(worldId, serverUUID);
}
return idMap;
}
});
}
public List<String> getWorlds() throws SQLException {
return getWorlds(ServerInfo.getServerUUID());
}
public List<String> getWorlds(UUID serverUUID) throws SQLException {
String sql = "SELECT * FROM " + tableName +
" WHERE " + Col.SERVER_ID + "=" + serverTable.statementSelectServerID;
return query(new QueryStatement<List<String>>(sql) {
@Override
public void prepare(PreparedStatement statement) throws SQLException {
statement.setString(1, serverUUID.toString());
}
@Override
public List<String> processResults(ResultSet set) throws SQLException {
List<String> worldNames = new ArrayList<>();
while (set.next()) {
String worldName = set.getString(Col.NAME.get());
worldNames.add(worldName);
}
return worldNames;
}
});
}
public void saveWorlds(Collection<String> worlds) throws SQLException {
saveWorlds(worlds, ServerInfo.getServerUUID());
}
/**
* Used to save a list of world names.
* <p>
@ -73,25 +156,27 @@ public class WorldTable extends Table {
* @param worlds List of world names.
* @throws SQLException Database error occurs.
*/
public void saveWorlds(Collection<String> worlds) throws SQLException {
public void saveWorlds(Collection<String> worlds, UUID serverUUID) throws SQLException {
Verify.nullCheck(worlds);
Set<String> worldsToSave = new HashSet<>(worlds);
List<String> saved = getWorlds();
List<String> saved = getWorlds(serverUUID);
worldsToSave.removeAll(saved);
if (Verify.isEmpty(worlds)) {
return;
}
String sql = "INSERT INTO " + tableName + " ("
+ Col.NAME
+ ") VALUES (?)";
+ Col.NAME + ", "
+ Col.SERVER_ID
+ ") VALUES (?, " + serverTable.statementSelectServerID + ")";
executeBatch(new ExecStatement(sql) {
@Override
public void prepare(PreparedStatement statement) throws SQLException {
for (String world : worldsToSave) {
statement.setString(1, world);
statement.setString(2, serverUUID.toString());
statement.addBatch();
}
}
@ -99,9 +184,37 @@ public class WorldTable extends Table {
}
public Set<String> getWorldNames(UUID serverUUID) throws SQLException {
String sql = "SELECT DISTINCT " + Col.NAME + " FROM " + tableName +
" WHERE " + Col.SERVER_ID + "=" + serverTable.statementSelectServerID;
return query(new QueryStatement<Set<String>>(sql, 100) {
@Override
public void prepare(PreparedStatement statement) throws SQLException {
statement.setString(1, serverUUID.toString());
}
@Override
public Set<String> processResults(ResultSet set) throws SQLException {
Set<String> worldNames = new HashSet<>();
while (set.next()) {
worldNames.add(set.getString(Col.NAME.get()));
}
return worldNames;
}
});
}
/**
* Used to get world names for this server.
*
* @param serverUUID UUID of the Server
* @return World names known for that server
* @throws SQLException If DB Error occurs
* @deprecated Use getWorldNames instead, this method is slower.
*/
@Deprecated
public Set<String> getWorldNamesOld(UUID serverUUID) throws SQLException {
WorldTimesTable worldTimesTable = db.getWorldTimesTable();
SessionsTable sessionsTable = db.getSessionsTable();
ServerTable serverTable = db.getServerTable();
String statementSelectServerID = serverTable.statementSelectServerID;
@ -134,32 +247,103 @@ public class WorldTable extends Table {
});
}
public Set<String> getWorldNames() throws SQLException {
return getWorldNames(ServerInfo.getServerUUID());
public void alterTableV16() throws SQLException {
addColumns(Col.SERVER_ID + " integer NOT NULL DEFAULT 0");
List<UUID> serverUUIDs = serverTable.getServerUUIDs();
Map<UUID, Set<String>> worldsPerServer = new HashMap<>();
for (UUID serverUUID : serverUUIDs) {
worldsPerServer.put(serverUUID, getWorldNamesOld(serverUUID));
}
public Map<String, Integer> getWorldIds() throws SQLException {
String sql = "SELECT DISTINCT " +
Col.NAME + ", " +
Col.ID + " FROM " +
tableName;
for (Map.Entry<UUID, Set<String>> entry : worldsPerServer.entrySet()) {
UUID serverUUID = entry.getKey();
Set<String> worlds = entry.getValue();
return query(new QueryAllStatement<Map<String, Integer>>(sql, 200) {
saveWorlds(worlds, serverUUID);
}
updateWorldTimesTableWorldIDs();
execute("DELETE FROM " + tableName + " WHERE " + Col.SERVER_ID + "=0");
}
private void updateWorldTimesTableWorldIDs() throws SQLException {
List<WorldObj> worldObjects = getWorldObjects();
Map<WorldObj, List<WorldObj>> oldToNewMap =
worldObjects.stream()
.filter(worldObj -> worldObj.serverId == 0)
.collect(Collectors.toMap(
Function.identity(),
oldWorld -> worldObjects.stream()
.filter(worldObj -> worldObj.serverId != 0)
.filter(worldObj -> worldObj.equals(oldWorld))
.collect(Collectors.toList()
)));
WorldTimesTable worldTimesTable = db.getWorldTimesTable();
String sql = "UPDATE " + worldTimesTable + " SET " +
WorldTimesTable.Col.WORLD_ID + "=?" +
" WHERE " + WorldTimesTable.Col.WORLD_ID + "=?" +
" AND " + WorldTimesTable.Col.SERVER_ID + "=?";
executeBatch(new ExecStatement(sql) {
@Override
public Map<String, Integer> processResults(ResultSet set) throws SQLException {
Map<String, Integer> worldIds = new HashMap<>();
while (set.next()) {
String worldName = set.getString(Col.NAME.get());
int worldId = set.getInt(Col.ID.get());
worldIds.put(worldName, worldId);
public void prepare(PreparedStatement statement) throws SQLException {
for (Map.Entry<WorldObj, List<WorldObj>> entry : oldToNewMap.entrySet()) {
WorldObj old = entry.getKey();
for (WorldObj newWorld : entry.getValue()) {
statement.setInt(1, newWorld.id);
statement.setInt(2, old.id);
statement.setInt(3, newWorld.serverId);
statement.addBatch();
}
return worldIds;
}
}
});
}
public Map<Integer, List<Integer>> getWorldIDsByServerIDs() throws SQLException {
String sql = "SELECT " +
Col.ID + ", " +
Col.SERVER_ID +
" FROM " + tableName;
return query(new QueryAllStatement<Map<Integer, List<Integer>>>(sql, 100) {
@Override
public Map<Integer, List<Integer>> processResults(ResultSet set) throws SQLException {
HashMap<Integer, List<Integer>> map = new HashMap<>();
while (set.next()) {
int serverID = set.getInt(Col.SERVER_ID.get());
int worldID = set.getInt(Col.ID.get());
List<Integer> worldIDs = map.getOrDefault(serverID, new ArrayList<>());
worldIDs.add(worldID);
map.put(serverID, worldIDs);
}
return map;
}
});
}
public List<WorldObj> getWorldObjects() throws SQLException {
String sql = "SELECT * FROM " + tableName;
return query(new QueryAllStatement<List<WorldObj>>(sql, 100) {
@Override
public List<WorldObj> processResults(ResultSet set) throws SQLException {
List<WorldObj> objects = new ArrayList<>();
while (set.next()) {
int worldID = set.getInt(Col.ID.get());
int serverID = set.getInt(Col.SERVER_ID.get());
String worldName = set.getString(Col.NAME.get());
objects.add(new WorldObj(worldID, serverID, worldName));
}
return objects;
}
});
}
public enum Col implements Column {
ID("id"),
SERVER_ID("server_id"),
NAME("world_name");
private final String column;
@ -179,3 +363,37 @@ public class WorldTable extends Table {
}
}
}
class WorldObj {
final int id;
final int serverId;
final String name;
public WorldObj(int id, int serverId, String name) {
this.id = id;
this.serverId = serverId;
this.name = name;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
WorldObj worldObj = (WorldObj) o;
return Objects.equal(name, worldObj.name);
}
@Override
public int hashCode() {
return Objects.hashCode(name);
}
@Override
public String toString() {
return "{" +
"id=" + id +
", serverId=" + serverId +
", name='" + name + '\'' +
'}';
}
}

View File

@ -12,6 +12,10 @@ import com.djrapitops.plan.system.database.databases.sql.statements.Column;
import com.djrapitops.plan.system.database.databases.sql.statements.Sql;
import com.djrapitops.plan.system.database.databases.sql.statements.TableSqlParser;
import com.djrapitops.plan.system.info.server.ServerInfo;
import com.djrapitops.plugin.api.TimeAmount;
import com.djrapitops.plugin.api.utility.log.Log;
import com.djrapitops.plugin.task.AbsRunnable;
import com.djrapitops.plugin.task.RunnableFactory;
import com.djrapitops.plugin.utilities.Verify;
import java.sql.PreparedStatement;
@ -31,13 +35,21 @@ import java.util.stream.Collectors;
*/
public class WorldTimesTable extends UserIDTable {
public static final String TABLE_NAME = "plan_world_times";
private final ServerTable serverTable;
private final WorldTable worldTable;
private final SessionsTable sessionsTable;
private String insertStatement;
public WorldTimesTable(SQLDB db) {
super("plan_world_times", db);
super(TABLE_NAME, db);
worldTable = db.getWorldTable();
sessionsTable = db.getSessionsTable();
serverTable = db.getServerTable();
insertStatement = "INSERT INTO " + tableName + " (" +
Col.USER_ID + ", " +
Col.WORLD_ID + ", " +
Col.SERVER_ID + ", " +
Col.SESSION_ID + ", " +
Col.SURVIVAL + ", " +
Col.CREATIVE + ", " +
@ -46,18 +58,16 @@ public class WorldTimesTable extends UserIDTable {
") VALUES (" +
usersTable.statementSelectID + ", " +
worldTable.statementSelectID + ", " +
serverTable.statementSelectServerID + ", " +
"?, ?, ?, ?, ?)";
}
private final WorldTable worldTable;
private final SessionsTable sessionsTable;
private String insertStatement;
@Override
public void createTable() throws DBInitException {
createTable(TableSqlParser.createTable(tableName)
.column(Col.USER_ID, Sql.INT).notNull()
.column(Col.WORLD_ID, Sql.INT).notNull()
.column(Col.SERVER_ID, Sql.INT).notNull()
.column(Col.SESSION_ID, Sql.INT).notNull()
.column(Col.SURVIVAL, Sql.LONG).notNull().defaultValue("0")
.column(Col.CREATIVE, Sql.LONG).notNull().defaultValue("0")
@ -65,6 +75,7 @@ public class WorldTimesTable extends UserIDTable {
.column(Col.SPECTATOR, Sql.LONG).notNull().defaultValue("0")
.foreignKey(Col.USER_ID, usersTable.getTableName(), UsersTable.Col.ID)
.foreignKey(Col.WORLD_ID, worldTable.getTableName(), WorldTable.Col.ID)
.foreignKey(Col.SERVER_ID, serverTable.getTableName(), ServerTable.Col.SERVER_ID)
.foreignKey(Col.SESSION_ID, sessionsTable.getTableName(), SessionsTable.Col.ID)
.toString()
);
@ -135,13 +146,16 @@ public class WorldTimesTable extends UserIDTable {
GMTimes gmTimes = entry.getValue();
statement.setString(1, uuid.toString());
statement.setString(2, worldName);
statement.setInt(3, sessionID);
String serverUUID = ServerInfo.getServerUUID().toString();
statement.setString(3, serverUUID);
statement.setString(4, serverUUID);
statement.setInt(5, sessionID);
String[] gms = GMTimes.getGMKeyArray();
statement.setLong(4, gmTimes.getTime(gms[0]));
statement.setLong(5, gmTimes.getTime(gms[1]));
statement.setLong(6, gmTimes.getTime(gms[2]));
statement.setLong(7, gmTimes.getTime(gms[3]));
statement.setLong(6, gmTimes.getTime(gms[0]));
statement.setLong(7, gmTimes.getTime(gms[1]));
statement.setLong(8, gmTimes.getTime(gms[2]));
statement.setLong(9, gmTimes.getTime(gms[3]));
statement.addBatch();
}
}
@ -151,8 +165,6 @@ public class WorldTimesTable extends UserIDTable {
public WorldTimes getWorldTimesOfServer(UUID serverUUID) throws SQLException {
String worldIDColumn = worldTable + "." + WorldTable.Col.ID;
String worldNameColumn = worldTable + "." + WorldTable.Col.NAME + " as world_name";
String sessionIDColumn = sessionsTable + "." + SessionsTable.Col.ID;
String sessionServerIDColumn = sessionsTable + ".server_id";
String sql = "SELECT " +
"SUM(" + Col.SURVIVAL + ") as survival, " +
"SUM(" + Col.CREATIVE + ") as creative, " +
@ -161,8 +173,7 @@ public class WorldTimesTable extends UserIDTable {
worldNameColumn +
" FROM " + tableName +
" INNER JOIN " + worldTable + " on " + worldIDColumn + "=" + Col.WORLD_ID +
" INNER JOIN " + sessionsTable + " on " + sessionIDColumn + "=" + Col.SESSION_ID +
" WHERE " + sessionServerIDColumn + "=" + db.getServerTable().statementSelectServerID +
" WHERE " + tableName + "." + Col.SERVER_ID + "=" + db.getServerTable().statementSelectServerID +
" GROUP BY " + Col.WORLD_ID;
return query(new QueryStatement<WorldTimes>(sql, 1000) {
@ -193,10 +204,6 @@ public class WorldTimesTable extends UserIDTable {
});
}
public WorldTimes getWorldTimesOfServer() throws SQLException {
return getWorldTimesOfServer(ServerInfo.getServerUUID());
}
public WorldTimes getWorldTimesOfUser(UUID uuid) throws SQLException {
String worldIDColumn = worldTable + "." + WorldTable.Col.ID;
String worldNameColumn = worldTable + "." + WorldTable.Col.NAME + " as world_name";
@ -315,9 +322,10 @@ public class WorldTimesTable extends UserIDTable {
public void prepare(PreparedStatement statement) throws SQLException {
String[] gms = GMTimes.getGMKeyArray();
// Every Server
for (Map<UUID, List<Session>> serverSessions : allSessions.values()) {
for (Map.Entry<UUID, Map<UUID, List<Session>>> serverSessions : allSessions.entrySet()) {
UUID serverUUID = serverSessions.getKey();
// Every User
for (Map.Entry<UUID, List<Session>> entry : serverSessions.entrySet()) {
for (Map.Entry<UUID, List<Session>> entry : serverSessions.getValue().entrySet()) {
UUID uuid = entry.getKey();
List<Session> sessions = entry.getValue();
// Every Session
@ -329,11 +337,13 @@ public class WorldTimesTable extends UserIDTable {
GMTimes gmTimes = worldTimesEntry.getValue();
statement.setString(1, uuid.toString());
statement.setString(2, worldName);
statement.setInt(3, sessionID);
statement.setLong(4, gmTimes.getTime(gms[0]));
statement.setLong(5, gmTimes.getTime(gms[1]));
statement.setLong(6, gmTimes.getTime(gms[2]));
statement.setLong(7, gmTimes.getTime(gms[3]));
statement.setString(3, serverUUID.toString());
statement.setString(4, serverUUID.toString());
statement.setInt(5, sessionID);
statement.setLong(6, gmTimes.getTime(gms[0]));
statement.setLong(7, gmTimes.getTime(gms[1]));
statement.setLong(8, gmTimes.getTime(gms[2]));
statement.setLong(9, gmTimes.getTime(gms[3]));
statement.addBatch();
}
}
@ -343,8 +353,45 @@ public class WorldTimesTable extends UserIDTable {
});
}
public void alterTableV16() {
addColumns(Col.SERVER_ID + " integer NOT NULL DEFAULT 0");
RunnableFactory.createNew("DB version -> 16", new AbsRunnable() {
@Override
public void run() {
try {
Map<Integer, Integer> sessionIDServerIDRelation = sessionsTable.getIDServerIDRelation();
String sql = "UPDATE " + tableName + " SET " +
Col.SERVER_ID + "=?" +
" WHERE " + Col.SESSION_ID + "=?";
executeBatch(new ExecStatement(sql) {
@Override
public void prepare(PreparedStatement statement) throws SQLException {
for (Map.Entry<Integer, Integer> entry : sessionIDServerIDRelation.entrySet()) {
Integer sessionID = entry.getKey();
Integer serverID = entry.getValue();
statement.setInt(1, serverID);
statement.setInt(2, sessionID);
statement.addBatch();
}
}
});
worldTable.alterTableV16();
} catch (SQLException e) {
Log.toLog(this.getClass().getName(), e);
} finally {
cancel();
}
}
}).runTaskLaterAsynchronously(TimeAmount.SECOND.ticks() * 2);
}
public enum Col implements Column {
USER_ID(UserIDTable.Col.USER_ID.get()),
SERVER_ID("server_id"),
SESSION_ID("session_id"),
WORLD_ID("world_id"),
SURVIVAL("survival_time"),

View File

@ -169,7 +169,7 @@ public class BatchOperationTable extends Table {
return;
}
Log.debug("Batch Copy Worlds");
toDB.getDb().getWorldTable().saveWorlds(db.getWorldTable().getWorlds());
toDB.getDb().getWorldTable().saveWorlds(db.getWorldTable().getAllWorlds());
}
public void copyUsers(BatchOperationTable toDB) throws SQLException {

View File

@ -38,14 +38,16 @@ public class Version8TransferTable extends Table {
throw new IllegalStateException("Method not supposed to be used on this table.");
}
private String tableRenameSql(String from, String to) {
return usingMySQL ?
private void renameTable(String from, String to) throws SQLException {
String sql = usingMySQL ?
"RENAME TABLE " + from + " TO " + to :
"ALTER TABLE " + from + " RENAME TO " + to;
execute(sql);
}
private String dropTableSql(String name) {
return "DROP TABLE " + name;
private void dropTable(String name) throws SQLException {
String sql = "DROP TABLE " + name;
execute(sql);
}
public void alterTablesToV10() throws SQLException, DBInitException {
@ -54,23 +56,23 @@ public class Version8TransferTable extends Table {
copyTPS();
execute(dropTableSql("plan_user_info"));
dropTable("plan_user_info");
copyUsers();
execute(dropTableSql("plan_ips"));
dropTable("plan_ips");
db.getGeoInfoTable().createTable();
execute(dropTableSql("plan_world_times"));
execute(dropTableSql("plan_worlds"));
dropTable("plan_world_times");
dropTable("plan_worlds");
db.getWorldTable().createTable();
db.getWorldTimesTable().createTable();
execute(dropTableSql("plan_actions"));
dropTable("plan_actions");
db.getActionsTable().createTable();
execute(dropTableSql("plan_gamemodetimes"));
execute(dropTableSql("temp_nicks"));
execute(dropTableSql("temp_kills"));
execute(dropTableSql("temp_users"));
dropTable("plan_gamemodetimes");
dropTable("temp_nicks");
dropTable("temp_kills");
dropTable("temp_users");
db.setVersion(10);
Benchmark.stop("Schema copy from 8 to 10");
@ -79,19 +81,19 @@ public class Version8TransferTable extends Table {
private void copyUsers() throws SQLException, DBInitException {
String tempTableName = "temp_users";
UsersTable usersTable = db.getUsersTable();
execute(tableRenameSql("plan_users", tempTableName));
renameTable("plan_users", tempTableName);
String tempNickTableName = "temp_nicks";
NicknamesTable nicknamesTable = db.getNicknamesTable();
execute(tableRenameSql(nicknamesTable.toString(), tempNickTableName));
renameTable(nicknamesTable.toString(), tempNickTableName);
String tempKillsTableName = "temp_kills";
KillsTable killsTable = db.getKillsTable();
execute(tableRenameSql(killsTable.toString(), tempKillsTableName));
renameTable(killsTable.toString(), tempKillsTableName);
usersTable.createTable();
nicknamesTable.createTable();
execute(dropTableSql("plan_sessions"));
dropTable("plan_sessions");
db.getSessionsTable().createTable();
killsTable.createTable();
@ -141,7 +143,7 @@ public class Version8TransferTable extends Table {
String tempTableName = "temp_cmdusg";
CommandUseTable commandUseTable = db.getCommandUseTable();
execute(tableRenameSql("plan_commandusages", tempTableName));
renameTable("plan_commandusages", tempTableName);
commandUseTable.createTable();
@ -153,14 +155,14 @@ public class Version8TransferTable extends Table {
" FROM " + tempTableName;
execute(statement);
execute(dropTableSql(tempTableName));
dropTable(tempTableName);
}
private void copyTPS() throws SQLException, DBInitException {
String tempTableName = "temp_tps";
TPSTable tpsTable = db.getTpsTable();
execute(tableRenameSql(tpsTable.toString(), tempTableName));
renameTable(tpsTable.toString(), tempTableName);
tpsTable.createTable();
@ -172,6 +174,6 @@ public class Version8TransferTable extends Table {
" FROM " + tempTableName;
execute(statement);
execute(dropTableSql(tempTableName));
dropTable(tempTableName);
}
}

View File

@ -11,7 +11,7 @@ import com.djrapitops.plan.system.database.databases.Database;
import com.djrapitops.plan.system.info.request.*;
import com.djrapitops.plan.system.info.server.Server;
import com.djrapitops.plan.system.info.server.ServerInfo;
import com.djrapitops.plan.system.processing.Processor;
import com.djrapitops.plan.system.processing.Processing;
import com.djrapitops.plan.system.settings.Settings;
import com.djrapitops.plan.system.settings.locale.Locale;
import com.djrapitops.plan.system.settings.locale.Msg;
@ -39,7 +39,7 @@ public class BukkitConnectionSystem extends ConnectionSystem {
}
private void refreshServerMap() {
Processor.queue(() -> {
Processing.submitNonCritical(() -> {
if (latestServerMapRefresh < MiscUtils.getTime() - TimeAmount.SECOND.ms() * 15L) {
try {
Database database = Database.getActive();

View File

@ -82,8 +82,8 @@ public class ConnectionLog {
/**
* Most recent first.
*
* @param o
* @return
* @param o object
* @return -1 or 1
*/
@Override
public int compareTo(Entry o) {

View File

@ -106,7 +106,6 @@ public class ConnectionOut {
connection.setRequestProperty("charset", "UTF-8");
String parameters = parseVariables();
infoRequest.placeDataToDatabase();
connection.setRequestProperty("Content-Length", Integer.toString(parameters.length()));

View File

@ -4,11 +4,9 @@
*/
package com.djrapitops.plan.system.info.request;
import com.djrapitops.plan.api.exceptions.connection.TransferDatabaseException;
import com.djrapitops.plan.api.exceptions.connection.BadRequestException;
import com.djrapitops.plan.api.exceptions.connection.WebException;
import com.djrapitops.plan.api.exceptions.database.DBException;
import com.djrapitops.plan.system.database.databases.Database;
import com.djrapitops.plan.system.processing.Processor;
import com.djrapitops.plan.system.processing.Processing;
import com.djrapitops.plan.system.settings.Settings;
import com.djrapitops.plan.system.webserver.response.DefaultResponses;
import com.djrapitops.plan.system.webserver.response.Response;
@ -27,7 +25,7 @@ import java.util.UUID;
*
* @author Rsl1122
*/
public class CacheAnalysisPageRequest implements CacheRequest {
public class CacheAnalysisPageRequest extends InfoRequestWithVariables implements CacheRequest {
private final UUID serverUUID;
private final String html;
@ -40,6 +38,7 @@ public class CacheAnalysisPageRequest implements CacheRequest {
public CacheAnalysisPageRequest(UUID serverUUID, String html) {
Verify.nullCheck(serverUUID, html);
this.serverUUID = serverUUID;
variables.put("html", Base64Util.encode(html));
this.html = html;
}
@ -47,42 +46,24 @@ public class CacheAnalysisPageRequest implements CacheRequest {
return new CacheAnalysisPageRequest();
}
@Override
public void placeDataToDatabase() throws WebException {
Verify.nullCheck(serverUUID, html);
String encodedHtml = Base64Util.encode(html);
try {
Database.getActive().transfer().storeServerHtml(serverUUID, encodedHtml);
} catch (DBException e) {
throw new TransferDatabaseException(e);
}
}
@Override
public Response handleRequest(Map<String, String> variables) throws WebException {
// Available variables: sender
// Available variables: sender, html (Base64)
try {
Map<UUID, String> pages = Database.getActive().transfer().getEncodedServerHtml();
UUID serverUUID = UUID.fromString(variables.get("sender"));
String html = variables.get("html");
Verify.nullCheck(html, () -> new BadRequestException("HTML 'html' variable not supplied in the request"));
boolean export = Settings.ANALYSIS_EXPORT.isTrue();
for (Map.Entry<UUID, String> entry : pages.entrySet()) {
UUID serverUUID = entry.getKey();
String html = Base64Util.decode(entry.getValue());
cache(export, serverUUID, html);
}
} catch (DBException e) {
throw new TransferDatabaseException(e);
}
cache(export, serverUUID, Base64Util.decode(html));
return DefaultResponses.SUCCESS.get();
}
private void cache(boolean export, UUID serverUUID, String html) {
ResponseCache.cacheResponse(PageId.SERVER.of(serverUUID), () -> new AnalysisPageResponse(html));
if (export) {
Processor.queue(() -> HtmlExport.exportServer(serverUUID));
Processing.submitNonCritical(() -> HtmlExport.exportServer(serverUUID));
}
}

View File

@ -4,12 +4,10 @@
*/
package com.djrapitops.plan.system.info.request;
import com.djrapitops.plan.api.exceptions.connection.TransferDatabaseException;
import com.djrapitops.plan.api.exceptions.connection.BadRequestException;
import com.djrapitops.plan.api.exceptions.connection.WebException;
import com.djrapitops.plan.api.exceptions.database.DBException;
import com.djrapitops.plan.system.database.databases.Database;
import com.djrapitops.plan.system.info.server.ServerInfo;
import com.djrapitops.plan.system.processing.Processor;
import com.djrapitops.plan.system.processing.Processing;
import com.djrapitops.plan.system.settings.Settings;
import com.djrapitops.plan.system.webserver.response.DefaultResponses;
import com.djrapitops.plan.system.webserver.response.Response;
@ -30,7 +28,7 @@ import java.util.UUID;
*
* @author Rsl1122
*/
public class CacheInspectPageRequest implements CacheRequest {
public class CacheInspectPageRequest extends InfoRequestWithVariables implements CacheRequest {
private final UUID player;
private final String html;
@ -42,6 +40,8 @@ public class CacheInspectPageRequest implements CacheRequest {
public CacheInspectPageRequest(UUID player, String html) {
Verify.nullCheck(player, html);
variables.put("player", player.toString());
variables.put("html", Base64Util.encode(html));
this.player = player;
this.html = html;
}
@ -50,44 +50,28 @@ public class CacheInspectPageRequest implements CacheRequest {
return new CacheInspectPageRequest();
}
@Override
public void placeDataToDatabase() throws WebException {
Verify.nullCheck(player, html);
String encodedHtml = Base64Util.encode(html);
try {
Database.getActive().transfer().storePlayerHtml(player, encodedHtml);
} catch (DBException e) {
throw new TransferDatabaseException(e);
}
}
@Override
public Response handleRequest(Map<String, String> variables) throws WebException {
// Available variables: sender
// Available variables: sender, player, html (Base64)
try {
Map<UUID, String> pages = Database.getActive().transfer().getEncodedPlayerHtml();
String player = variables.get("player");
Verify.nullCheck(player, () -> new BadRequestException("Player UUID 'player' variable not supplied in the request."));
UUID uuid = UUID.fromString(player);
boolean export = Settings.ANALYSIS_EXPORT.isTrue();
for (Map.Entry<UUID, String> entry : pages.entrySet()) {
UUID uuid = entry.getKey();
String html = Base64Util.decode(entry.getValue());
String html = variables.get("html");
Verify.nullCheck(html, () -> new BadRequestException("HTML 'html' variable not supplied in the request"));
Map<String, String> replace = Collections.singletonMap("networkName", ServerInfo.getServerName());
boolean export = Settings.ANALYSIS_EXPORT.isTrue();
cache(export, uuid, StrSubstitutor.replace(Base64Util.decode(html), replace));
cache(export, uuid, StrSubstitutor.replace(html, replace));
}
} catch (DBException e) {
throw new TransferDatabaseException(e);
}
return DefaultResponses.SUCCESS.get();
}
private void cache(boolean export, UUID uuid, String html) {
ResponseCache.cacheResponse(PageId.PLAYER.of(uuid), () -> new InspectPageResponse(uuid, html));
if (export) {
Processor.queue(() -> HtmlExport.exportPlayer(uuid));
Processing.submitNonCritical(() -> HtmlExport.exportPlayer(uuid));
}
}

View File

@ -5,10 +5,7 @@
package com.djrapitops.plan.system.info.request;
import com.djrapitops.plan.api.exceptions.connection.BadRequestException;
import com.djrapitops.plan.api.exceptions.connection.TransferDatabaseException;
import com.djrapitops.plan.api.exceptions.connection.WebException;
import com.djrapitops.plan.api.exceptions.database.DBException;
import com.djrapitops.plan.system.database.databases.Database;
import com.djrapitops.plan.system.info.server.ServerInfo;
import com.djrapitops.plan.system.webserver.response.DefaultResponses;
import com.djrapitops.plan.system.webserver.response.Response;
@ -28,23 +25,20 @@ import java.util.UUID;
*/
public class CacheInspectPluginsTabRequest extends InfoRequestWithVariables implements CacheRequest {
private static final String SPLIT = "AASPLITAA";
private final UUID player;
private final String nav;
private final String html;
private CacheInspectPluginsTabRequest() {
player = null;
nav = null;
html = null;
}
public CacheInspectPluginsTabRequest(UUID player, String nav, String html) {
Verify.nullCheck(player, nav);
variables.put("player", player.toString());
variables.put("nav", nav);
variables.put("html", Base64Util.encode(html));
this.player = player;
this.nav = nav;
this.html = html;
}
@ -52,44 +46,23 @@ public class CacheInspectPluginsTabRequest extends InfoRequestWithVariables impl
return new CacheInspectPluginsTabRequest();
}
@Override
public void placeDataToDatabase() throws WebException {
Verify.nullCheck(player, nav);
String encodedHtml = Base64Util.encode(nav + SPLIT + html);
try {
Database.getActive().transfer().storePlayerPluginsTab(player, encodedHtml);
} catch (DBException e) {
throw new TransferDatabaseException(e);
}
}
@Override
public Response handleRequest(Map<String, String> variables) throws WebException {
// Available variables: sender, player
// Available variables: sender, player, nav, html
String player = variables.get("player");
Verify.nullCheck(player, () -> new BadRequestException("Player UUID 'player' variable not supplied in the request."));
UUID uuid = UUID.fromString(player);
UUID serverUUID = UUID.fromString(variables.get("sender"));
String nav = variables.get("nav");
String html = variables.get("html");
Verify.nullCheck(nav, () -> new BadRequestException("Nav HTML 'nav' variable not supplied in the request"));
Verify.nullCheck(html, () -> new BadRequestException("HTML 'html' variable not supplied in the request"));
try {
InspectPagePluginsContent pluginsTab = getPluginsTab(uuid);
Map<UUID, String> pages = Database.getActive().transfer().getEncodedPlayerPluginsTabs(uuid);
for (Map.Entry<UUID, String> entry : pages.entrySet()) {
UUID serverUUID = entry.getKey();
String[] navAndHtml = Base64Util.decode(entry.getValue()).split(SPLIT);
if (navAndHtml.length <= 1) {
continue;
}
pluginsTab.addTab(serverUUID, navAndHtml[0], navAndHtml[1]);
}
} catch (DBException e) {
throw new TransferDatabaseException(e);
}
pluginsTab.addTab(serverUUID, nav, Base64Util.decode(html));
return DefaultResponses.SUCCESS.get();
}
@ -99,6 +72,6 @@ public class CacheInspectPluginsTabRequest extends InfoRequestWithVariables impl
@Override
public void runLocally() {
getPluginsTab(player).addTab(ServerInfo.getServerUUID(), nav, html);
getPluginsTab(player).addTab(ServerInfo.getServerUUID(), variables.get("nav"), html);
}
}

View File

@ -4,10 +4,8 @@
*/
package com.djrapitops.plan.system.info.request;
import com.djrapitops.plan.api.exceptions.connection.TransferDatabaseException;
import com.djrapitops.plan.api.exceptions.connection.BadRequestException;
import com.djrapitops.plan.api.exceptions.connection.WebException;
import com.djrapitops.plan.api.exceptions.database.DBException;
import com.djrapitops.plan.system.database.databases.Database;
import com.djrapitops.plan.system.info.InfoSystem;
import com.djrapitops.plan.system.info.server.ServerInfo;
import com.djrapitops.plan.system.webserver.response.DefaultResponses;
@ -15,6 +13,7 @@ import com.djrapitops.plan.system.webserver.response.Response;
import com.djrapitops.plan.system.webserver.response.cache.PageId;
import com.djrapitops.plan.system.webserver.response.cache.ResponseCache;
import com.djrapitops.plan.system.webserver.response.pages.parts.NetworkPageContent;
import com.djrapitops.plan.utilities.Base64Util;
import com.djrapitops.plugin.utilities.Verify;
import java.util.Map;
@ -23,57 +22,36 @@ import java.util.UUID;
/**
* InfoRequest for caching Network page parts to ResponseCache of receiving server.
* <p>
* SHOULD NOT BE SENT TO BUKKIT
* SHOULD NOT BE SENT TO BUKKIT.
*
* @author Rsl1122
*/
public class CacheNetworkPageContentRequest implements CacheRequest {
public class CacheNetworkPageContentRequest extends InfoRequestWithVariables implements CacheRequest {
private final UUID serverUUID;
private final String html;
public CacheNetworkPageContentRequest(UUID serverUUID, String html) {
Verify.nullCheck(serverUUID, html);
this.serverUUID = serverUUID;
variables.put("serverName", ServerInfo.getServerName());
variables.put("html", Base64Util.encode(html));
this.html = html;
}
private CacheNetworkPageContentRequest() {
serverUUID = null;
html = null;
}
@Override
public void placeDataToDatabase() throws WebException {
try {
Database.getActive().transfer().storeNetworkPageContent(serverUUID, html);
} catch (DBException e) {
throw new TransferDatabaseException(e);
}
}
@Override
public Response handleRequest(Map<String, String> variables) throws WebException {
// Available variables: sender
// Available variables: sender, serverName, html (Base64)
Map<UUID, String> networkPageHtml;
Map<UUID, String> serverNames;
try {
Database database = Database.getActive();
networkPageHtml = database.transfer().getEncodedNetworkPageContent();
serverNames = database.fetch().getServerNames();
} catch (DBException e) {
throw new TransferDatabaseException(e);
}
String serverName = variables.get("serverName");
Verify.nullCheck(serverName, () -> new BadRequestException("Server name 'serverName' variable not supplied in the request"));
String html = variables.get("html");
Verify.nullCheck(html, () -> new BadRequestException("HTML 'html' variable not supplied in the request"));
for (Map.Entry<UUID, String> entry : networkPageHtml.entrySet()) {
UUID serverUUID = entry.getKey();
String serverName = serverNames.getOrDefault(serverUUID, "Unknown");
String html = entry.getValue();
NetworkPageContent networkPage = getNetworkPageContent();
networkPage.addElement(serverName, html);
}
NetworkPageContent serversTab = getNetworkPageContent();
serversTab.addElement(serverName, Base64Util.decode(html));
InfoSystem.getInstance().updateNetworkPage();

View File

@ -39,11 +39,6 @@ public class CheckConnectionRequest extends InfoRequestWithVariables {
return new CheckConnectionRequest();
}
@Override
public void placeDataToDatabase() {
/* Not necessary */
}
@Override
public void runLocally() {
/* Won't be run */

View File

@ -16,12 +16,14 @@ import com.djrapitops.plan.system.info.server.ServerInfo;
import com.djrapitops.plan.system.webserver.pages.parsing.AnalysisPage;
import com.djrapitops.plan.system.webserver.response.DefaultResponses;
import com.djrapitops.plan.system.webserver.response.Response;
import com.djrapitops.plan.system.webserver.response.errors.InternalErrorResponse;
import com.djrapitops.plan.utilities.analysis.Analysis;
import com.djrapitops.plugin.api.utility.log.Log;
import com.djrapitops.plugin.utilities.Verify;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.ExecutionException;
/**
* InfoRequest to generate Analysis page HTML at the receiving end.
@ -42,11 +44,6 @@ public class GenerateAnalysisPageRequest extends InfoRequestWithVariables implem
serverUUID = null;
}
@Override
public void placeDataToDatabase() {
// No data required in a Generate request
}
@Override
public Response handleRequest(Map<String, String> variables) throws WebException {
// Variables available: sender, server
@ -59,7 +56,9 @@ public class GenerateAnalysisPageRequest extends InfoRequestWithVariables implem
throw new BadRequestException("Requested Analysis page from wrong server.");
}
if (!Analysis.isAnalysisBeingRun()) {
generateAndCache(serverUUID);
}
return DefaultResponses.SUCCESS.get();
}
@ -88,6 +87,9 @@ public class GenerateAnalysisPageRequest extends InfoRequestWithVariables implem
Log.toLog(this.getClass(), e);
}
throw new InternalErrorException("Analysis failed due to exception", e);
} catch (InterruptedException | ExecutionException e) {
/* Plugin is shutting down, exceptions ignored */
return new InternalErrorResponse("Plugin may be shutting down", e).getContent();
} catch (Exception e) {
Log.toLog(this.getClass(), e);
throw new InternalErrorException("Analysis failed due to exception", e);

View File

@ -40,11 +40,6 @@ public class GenerateInspectPageRequest extends InfoRequestWithVariables impleme
return new GenerateInspectPageRequest();
}
@Override
public void placeDataToDatabase() {
// No data required in a Generate request
}
@Override
public Response handleRequest(Map<String, String> variables) throws WebException {
// Available variables: sender, player

View File

@ -38,11 +38,6 @@ public class GenerateInspectPluginsTabRequest extends InfoRequestWithVariables i
return new GenerateInspectPluginsTabRequest();
}
@Override
public void placeDataToDatabase() {
// No data required in a Generate request
}
@Override
public Response handleRequest(Map<String, String> variables) throws WebException {
// Available variables: sender, player

View File

@ -22,11 +22,6 @@ public class GenerateNetworkPageContentRequest implements WideRequest, GenerateR
return new GenerateNetworkPageContentRequest();
}
@Override
public void placeDataToDatabase() {
/* No Data needed on a GenerateRequest.*/
}
@Override
public Response handleRequest(Map<String, String> variables) throws WebException {
InfoSystem.getInstance().updateNetworkPage();

View File

@ -16,8 +16,6 @@ import java.util.Map;
*/
public interface InfoRequest {
void placeDataToDatabase() throws WebException;
Response handleRequest(Map<String, String> variables) throws WebException;
void runLocally() throws WebException;

View File

@ -43,11 +43,6 @@ public class SaveDBSettingsRequest extends InfoRequestWithVariables implements S
return new SaveDBSettingsRequest(true);
}
@Override
public void placeDataToDatabase() {
/* Not necessary */
}
@Override
public void runLocally() {
/* Won't be run */

View File

@ -45,11 +45,6 @@ public class SendDBSettingsRequest extends InfoRequestWithVariables implements S
return new SendDBSettingsRequest();
}
@Override
public void placeDataToDatabase() {
/* Not necessary */
}
@Override
public void runLocally() {
/* Won't be run */

View File

@ -29,6 +29,9 @@ public class BukkitServerInfo extends ServerInfo {
private ServerInfoFile serverInfoFile;
private Database database;
BukkitServerInfo() {
}
public BukkitServerInfo(Plan plugin) {
serverProperties = new ServerProperties(plugin.getServer());
}
@ -51,7 +54,8 @@ public class BukkitServerInfo extends ServerInfo {
try {
return serverUUID.isPresent() ? updateDbInfo(serverUUID.get()) : registerServer();
} catch (DBException e) {
throw new EnableException("Failed to read Server information from Database", e);
String causeMsg = e.getCause().getMessage();
throw new EnableException("Failed to read Server information from Database: " + causeMsg, e);
} catch (IOException e) {
throw new EnableException("Failed to read ServerInfoFile.yml", e);
}

View File

@ -39,7 +39,7 @@ public class BungeeServerInfo extends ServerInfo {
server = registerBungeeInfo(db);
}
} catch (DBException e) {
throw new EnableException("Failed to read Database for Server");
throw new EnableException("Failed to read Server information from Database.");
}
return server;
}

View File

@ -3,6 +3,9 @@ package com.djrapitops.plan.system.info.server;
import com.djrapitops.plan.system.settings.Settings;
import net.md_5.bungee.api.ProxyServer;
import org.bukkit.Server;
import org.spongepowered.api.Game;
import java.net.InetSocketAddress;
/**
* Class responsible for holding server variable values that do not change
@ -49,6 +52,24 @@ public class ServerProperties {
onlinePlayers = server::getOnlineCount;
}
public ServerProperties(Game game) {
if (game == null) {
throw new IllegalStateException("Game did not inject.");
}
version = game.getPlatform().getMinecraftVersion().getName();
ip = () -> game.getServer().getBoundAddress()
.orElseGet(() -> new InetSocketAddress(25565))
.getAddress().getHostAddress();
name = "Sponge";
port = game.getServer().getBoundAddress().orElseGet(() -> new InetSocketAddress(25565)).getPort();
implVersion = version;
id = game.getServer().getMotd().toPlain();
maxPlayers = game.getServer().getMaxPlayers();
onlinePlayers = () -> game.getServer().getOnlinePlayers().size();
}
/**
* Ip string in server.properties.
*

View File

@ -0,0 +1,10 @@
package com.djrapitops.plan.system.info.server;
import org.spongepowered.api.Sponge;
public class SpongeServerInfo extends BukkitServerInfo {
public SpongeServerInfo() {
serverProperties = new ServerProperties(Sponge.getGame());
}
}

View File

@ -20,7 +20,8 @@ public class BukkitListenerSystem extends ListenerSystem {
new GamemodeChangeListener(),
new WorldChangeListener(),
new CommandPreprocessListener(plugin),
new DeathEventListener()
new DeathEventListener(),
new AFKListener()
);
PlayerOnlineListener.setCountKicks(true);
}

View File

@ -13,7 +13,7 @@ public class BungeeListenerSystem extends ListenerSystem {
@Override
protected void registerListeners() {
plugin.registerListener(new PlayerOnlineListener(plugin));
plugin.registerListener(new PlayerOnlineListener());
}
@Override

View File

@ -0,0 +1,14 @@
package com.djrapitops.plan.system.listeners;
public class SpongeListenerSystem extends ListenerSystem {
@Override
protected void registerListeners() {
}
@Override
protected void unregisterListeners() {
}
}

View File

@ -0,0 +1,55 @@
package com.djrapitops.plan.system.listeners.bukkit;
import com.djrapitops.plan.system.afk.AFKTracker;
import com.djrapitops.plan.utilities.MiscUtils;
import com.djrapitops.plugin.api.utility.log.Log;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.player.AsyncPlayerChatEvent;
import org.bukkit.event.player.PlayerCommandPreprocessEvent;
import org.bukkit.event.player.PlayerEvent;
import org.bukkit.event.player.PlayerMoveEvent;
import java.util.UUID;
/**
* Listener that keeps track of actions that are not considered being AFK.
* <p>
* Additional Listener calls in PlayerOnlineListener to avoid having HIGHEST priority listeners.
*
* @author Rsl1122
* @see PlayerOnlineListener
*/
public class AFKListener implements Listener {
// Static so that /reload does not cause afk tracking to fail.
public static final AFKTracker AFK_TRACKER = new AFKTracker();
private void event(PlayerEvent event) {
try {
UUID uuid = event.getPlayer().getUniqueId();
long time = MiscUtils.getTime();
AFK_TRACKER.performedAction(uuid, time);
} catch (Exception e) {
Log.toLog(this.getClass(), e);
}
}
@EventHandler(priority = EventPriority.MONITOR)
public void onMove(PlayerMoveEvent event) {
event(event);
}
@EventHandler(priority = EventPriority.MONITOR)
public void onPlayerChat(AsyncPlayerChatEvent event) {
event(event);
}
@EventHandler(priority = EventPriority.MONITOR)
public void onPlayerCommand(PlayerCommandPreprocessEvent event) {
event(event);
}
}

View File

@ -1,6 +1,7 @@
package com.djrapitops.plan.system.listeners.bukkit;
import com.djrapitops.plan.system.cache.SessionCache;
import com.djrapitops.plan.system.processing.Processing;
import com.djrapitops.plan.system.processing.processors.player.NameProcessor;
import com.djrapitops.plugin.api.utility.log.Log;
import org.bukkit.entity.Player;
@ -40,7 +41,7 @@ public class ChatListener implements Listener {
sessionCache.firstSessionMessageSent(uuid);
}
new NameProcessor(uuid, name, displayName).queue();
Processing.submit(new NameProcessor(uuid, name, displayName));
} catch (Exception e) {
Log.toLog(this.getClass(), e);
}

View File

@ -1,6 +1,7 @@
package com.djrapitops.plan.system.listeners.bukkit;
import com.djrapitops.plan.Plan;
import com.djrapitops.plan.system.processing.Processing;
import com.djrapitops.plan.system.processing.processors.CommandProcessor;
import com.djrapitops.plan.system.settings.Permissions;
import com.djrapitops.plan.system.settings.Settings;
@ -57,7 +58,7 @@ public class CommandPreprocessListener implements Listener {
commandName = command.getName();
}
}
new CommandProcessor(commandName).queue();
Processing.submit(new CommandProcessor(commandName));
} catch (Exception e) {
Log.toLog(this.getClass(), e);
}

View File

@ -2,7 +2,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.processing.Processor;
import com.djrapitops.plan.system.processing.Processing;
import com.djrapitops.plan.system.processing.processors.player.KillProcessor;
import com.djrapitops.plan.utilities.MiscUtils;
import com.djrapitops.plugin.api.utility.log.Log;
@ -37,7 +37,7 @@ public class DeathEventListener implements Listener {
if (dead instanceof Player) {
// Process Death
Processor.queue(() -> SessionCache.getCachedSession(dead.getUniqueId()).ifPresent(Session::died));
Processing.submitCritical(() -> SessionCache.getCachedSession(dead.getUniqueId()).ifPresent(Session::died));
}
try {
@ -65,7 +65,7 @@ public class DeathEventListener implements Listener {
processor = handleArrowKill(time, dead, (Arrow) killerEntity);
}
if (processor != null) {
processor.queue();
Processing.submit(processor);
}
}

View File

@ -27,23 +27,27 @@ public class GamemodeChangeListener implements Listener {
* @param event Fired Event.
*/
@EventHandler(priority = EventPriority.MONITOR)
public void onGamemodeChange(PlayerGameModeChangeEvent event) {
public void onGameModeChange(PlayerGameModeChangeEvent event) {
if (event.isCancelled()) {
return;
}
try {
Player p = event.getPlayer();
UUID uuid = p.getUniqueId();
long time = MiscUtils.getTime();
String gameMode = event.getNewGameMode().name();
String worldName = p.getWorld().getName();
new WorldAliasSettings().addWorld(worldName);
Optional<Session> cachedSession = SessionCache.getCachedSession(uuid);
cachedSession.ifPresent(session -> session.changeState(worldName, gameMode, time));
actOnEvent(event);
} catch (Exception e) {
Log.toLog(this.getClass(), e);
}
}
private void actOnEvent(PlayerGameModeChangeEvent event) {
Player player = event.getPlayer();
UUID uuid = player.getUniqueId();
long time = MiscUtils.getTime();
String gameMode = event.getNewGameMode().name();
String worldName = player.getWorld().getName();
WorldAliasSettings.addWorld(worldName);
Optional<Session> cachedSession = SessionCache.getCachedSession(uuid);
cachedSession.ifPresent(session -> session.changeState(worldName, gameMode, time));
}
}

View File

@ -2,8 +2,9 @@ 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.processing.Processor;
import com.djrapitops.plan.system.processing.Processing;
import com.djrapitops.plan.system.processing.processors.info.NetworkPageUpdateProcessor;
import com.djrapitops.plan.system.processing.processors.info.PlayerPageUpdateProcessor;
import com.djrapitops.plan.system.processing.processors.player.*;
import com.djrapitops.plan.system.tasks.TaskSystem;
import com.djrapitops.plan.utilities.MiscUtils;
@ -41,7 +42,7 @@ public class PlayerOnlineListener implements Listener {
UUID uuid = event.getPlayer().getUniqueId();
boolean op = event.getPlayer().isOp();
boolean banned = result == PlayerLoginEvent.Result.KICK_BANNED;
new BanAndOpProcessor(uuid, banned, op).queue();
Processing.submit(new BanAndOpProcessor(uuid, banned, op));
} catch (Exception e) {
Log.toLog(this.getClass(), e);
}
@ -62,19 +63,12 @@ public class PlayerOnlineListener implements Listener {
return;
}
UUID uuid = event.getPlayer().getUniqueId();
new KickProcessor(uuid).queue();
Processing.submit(new KickProcessor(uuid));
} catch (Exception e) {
Log.toLog(this.getClass(), e);
}
}
/**
* PlayerJoinEvent Listener.
* <p>
* Adds processing information to the ProcessingQueue.
*
* @param event The Fired event.
*/
@EventHandler(priority = EventPriority.MONITOR)
public void onPlayerJoin(PlayerJoinEvent event) {
try {
@ -84,6 +78,8 @@ public class PlayerOnlineListener implements Listener {
UUID uuid = player.getUniqueId();
long time = MiscUtils.getTime();
AFKListener.AFK_TRACKER.performedAction(uuid, time);
String world = player.getWorld().getName();
String gm = player.getGameMode().name();
@ -96,25 +92,19 @@ public class PlayerOnlineListener implements Listener {
SessionCache.getInstance().cacheSession(uuid, new Session(time, world, gm));
Processor.queueMany(
Processing.submit(
new RegisterProcessor(uuid, player.getFirstPlayed(), time, playerName, playersOnline,
new IPUpdateProcessor(uuid, ip, time),
new NameProcessor(uuid, playerName, displayName)
),
new NetworkPageUpdateProcessor()
new NameProcessor(uuid, playerName, displayName),
new PlayerPageUpdateProcessor(uuid)
)
);
Processing.submit(new NetworkPageUpdateProcessor());
} catch (Exception e) {
Log.toLog(this.getClass(), e);
}
}
/**
* PlayerQuitEvent Listener.
* <p>
* Adds processing information to the ProcessingQueue.
*
* @param event Fired event
*/
@EventHandler(priority = EventPriority.MONITOR)
public void onPlayerQuit(PlayerQuitEvent event) {
try {
@ -122,17 +112,19 @@ public class PlayerOnlineListener implements Listener {
Player player = event.getPlayer();
UUID uuid = player.getUniqueId();
Processor.queueMany(
new BanAndOpProcessor(uuid, player.isBanned(), player.isOp()),
new EndSessionProcessor(uuid, time),
new NetworkPageUpdateProcessor()
);
AFKListener.AFK_TRACKER.loggedOut(uuid, time);
Processing.submit(new BanAndOpProcessor(uuid, player.isBanned(), player.isOp()));
Processing.submit(new EndSessionProcessor(uuid, time));
Processing.submit(new NetworkPageUpdateProcessor());
SessionCache sessionCache = SessionCache.getInstance();
if (sessionCache.isFirstSession(uuid)) {
int messagesSent = sessionCache.getFirstSessionMsgCount(uuid);
new FirstLeaveProcessor(uuid, time, messagesSent).queue();
Processing.submit(new FirstLeaveProcessor(uuid, time, messagesSent));
}
Processing.submit(new PlayerPageUpdateProcessor(uuid));
} catch (Exception e) {
Log.toLog(this.getClass(), e);
}

View File

@ -19,19 +19,24 @@ public class WorldChangeListener implements Listener {
@EventHandler(priority = EventPriority.MONITOR)
public void onWorldChange(PlayerChangedWorldEvent event) {
try {
Player p = event.getPlayer();
String worldName = p.getWorld().getName();
UUID uuid = p.getUniqueId();
String gameMode = p.getGameMode().name();
long time = MiscUtils.getTime();
new WorldAliasSettings().addWorld(worldName);
Optional<Session> cachedSession = SessionCache.getCachedSession(uuid);
cachedSession.ifPresent(session -> session.changeState(worldName, gameMode, time));
actOnEvent(event);
} catch (Exception e) {
Log.toLog(this.getClass(), e);
}
}
private void actOnEvent(PlayerChangedWorldEvent event) {
long time = MiscUtils.getTime();
Player player = event.getPlayer();
UUID uuid = player.getUniqueId();
String worldName = player.getWorld().getName();
String gameMode = player.getGameMode().name();
WorldAliasSettings.addWorld(worldName);
Optional<Session> cachedSession = SessionCache.getCachedSession(uuid);
cachedSession.ifPresent(session -> session.changeState(worldName, gameMode, time));
}
}

View File

@ -4,7 +4,7 @@
*/
package com.djrapitops.plan.system.listeners.bungee;
import com.djrapitops.plan.PlanBungee;
import com.djrapitops.plan.system.processing.Processing;
import com.djrapitops.plan.system.processing.processors.player.BungeePlayerRegisterProcessor;
import com.djrapitops.plan.utilities.MiscUtils;
import com.djrapitops.plugin.api.utility.log.Log;
@ -22,12 +22,6 @@ import java.util.UUID;
*/
public class PlayerOnlineListener implements Listener {
private final PlanBungee plugin;
public PlayerOnlineListener(PlanBungee plugin) {
this.plugin = plugin;
}
@EventHandler
public void onPostLogin(PostLoginEvent event) {
try {
@ -36,7 +30,7 @@ public class PlayerOnlineListener implements Listener {
String name = player.getName();
long now = MiscUtils.getTime();
plugin.getSystem().getProcessingQueue().queue(new BungeePlayerRegisterProcessor(uuid, name, now));
Processing.submit(new BungeePlayerRegisterProcessor(uuid, name, now));
} catch (Exception e) {
Log.toLog(this.getClass(), e);
}

View File

@ -0,0 +1,6 @@
package com.djrapitops.plan.system.processing;
import java.util.concurrent.Callable;
public interface CriticalCallable<T> extends Callable<T> {
}

View File

@ -0,0 +1,4 @@
package com.djrapitops.plan.system.processing;
public interface CriticalRunnable extends Runnable {
}

View File

@ -0,0 +1,113 @@
package com.djrapitops.plan.system.processing;
import com.djrapitops.plan.PlanPlugin;
import com.djrapitops.plan.api.exceptions.EnableException;
import com.djrapitops.plan.system.PlanSystem;
import com.djrapitops.plan.system.SubSystem;
import com.djrapitops.plugin.StaticHolder;
import com.djrapitops.plugin.api.utility.log.Log;
import com.djrapitops.plugin.utilities.Verify;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
public class Processing implements SubSystem {
private final ExecutorService nonCriticalExecutor;
private final ExecutorService criticalExecutor;
public Processing() {
nonCriticalExecutor = Executors.newFixedThreadPool(6);
criticalExecutor = Executors.newFixedThreadPool(2);
}
public static void submit(Runnable runnable) {
if (runnable instanceof CriticalRunnable) {
submitCritical(runnable);
return;
}
submitNonCritical(runnable);
}
public static void saveInstance(Object obj) {
StaticHolder.saveInstance(obj.getClass(), PlanPlugin.getInstance().getClass());
}
public static void submitNonCritical(Runnable runnable) {
saveInstance(runnable);
getInstance().nonCriticalExecutor.submit(runnable);
}
public static void submitCritical(Runnable runnable) {
saveInstance(runnable);
getInstance().criticalExecutor.submit(runnable);
}
public static void submitNonCritical(Runnable... runnables) {
ExecutorService nonCriticalExecutor = getInstance().nonCriticalExecutor;
for (Runnable runnable : runnables) {
saveInstance(runnable);
nonCriticalExecutor.submit(runnable);
}
}
public static void submitCritical(Runnable... runnables) {
ExecutorService criticalExecutor = getInstance().criticalExecutor;
for (Runnable runnable : runnables) {
saveInstance(runnable);
criticalExecutor.submit(runnable);
}
}
public static <T> Future<T> submit(Callable<T> task) {
saveInstance(task);
if (task instanceof CriticalCallable) {
return submitCritical(task);
}
return submitNonCritical(task);
}
public static <T> Future<T> submitNonCritical(Callable<T> task) {
saveInstance(task);
return getInstance().nonCriticalExecutor.submit(task);
}
public static <T> Future<T> submitCritical(Callable<T> task) {
saveInstance(task);
return getInstance().criticalExecutor.submit(task);
}
public static Processing getInstance() {
Processing processing = PlanSystem.getInstance().getProcessing();
Verify.nullCheck(processing, () -> new IllegalStateException("Processing System has not been initialized."));
return processing;
}
@Override
public void enable() throws EnableException {
if (nonCriticalExecutor.isShutdown()) {
throw new EnableException("Non Critical ExecutorService was shut down on enable");
}
if (criticalExecutor.isShutdown()) {
throw new EnableException("Critical ExecutorService was shut down on enable");
}
}
@Override
public void disable() {
nonCriticalExecutor.shutdown();
List<Runnable> criticalTasks = criticalExecutor.shutdownNow();
Log.info("Processing critical unprocessed tasks. (" + criticalTasks.size() + ")");
for (Runnable runnable : criticalTasks) {
try {
runnable.run();
} catch (Exception | NoClassDefFoundError | NoSuchMethodError | NoSuchFieldError e) {
Log.toLog(this.getClass(), e);
}
}
Log.info("Processing complete.");
}
}

View File

@ -1,102 +0,0 @@
package com.djrapitops.plan.system.processing;
import com.djrapitops.plan.system.PlanSystem;
import com.djrapitops.plan.system.SubSystem;
import com.djrapitops.plan.utilities.queue.Consumer;
import com.djrapitops.plan.utilities.queue.Queue;
import com.djrapitops.plan.utilities.queue.Setup;
import com.djrapitops.plugin.api.Benchmark;
import com.djrapitops.plugin.api.utility.log.Log;
import com.djrapitops.plugin.utilities.Verify;
import java.util.List;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
/**
* This Class is starts the Process Queue Thread, that processes Processor
* objects.
*
* @author Rsl1122
* @since 3.0.0
*/
public class ProcessingQueue extends Queue<Processor> implements SubSystem {
public ProcessingQueue() {
super(new ArrayBlockingQueue<>(20000));
setup = new ProcessSetup(queue);
}
public static ProcessingQueue getInstance() {
ProcessingQueue processingQueue = PlanSystem.getInstance().getProcessingQueue();
Verify.nullCheck(processingQueue, () -> new IllegalStateException("ProcessingQueue has not been initialized."));
return processingQueue;
}
@Override
public void enable() {
setup.go();
}
@Override
public void disable() {
List<Processor> processors = stopAndReturnLeftovers();
Log.info("Processing unprocessed processors. (" + processors.size() + ")");
for (Processor processor : processors) {
try {
processor.process();
} catch (Exception e) {
Log.toLog(this.getClass(), e);
}
}
}
/**
* Used to add Processor object to be processed.
*
* @param processor processing object.
*/
public void queue(Processor processor) {
if (!queue.offer(processor)) {
Log.toLog(Processor.class, new IllegalStateException("Processor was not added to Queue"));
}
}
}
class ProcessConsumer extends Consumer<Processor> {
ProcessConsumer(BlockingQueue<Processor> q) {
super(q, "ProcessQueueConsumer");
}
@Override
protected void consume(Processor process) {
if (process == null) {
return;
}
try {
String benchName = "Processed " + process.getClass().getSimpleName() + ".";
Benchmark.start(benchName);
process.process();
Benchmark.stop(benchName);
} catch (Exception | NoClassDefFoundError | NoSuchFieldError | NoSuchMethodError e) {
Log.toLog(process.getClass(), e);
}
}
}
class ProcessSetup extends Setup<Processor> {
ProcessSetup(BlockingQueue<Processor> q) {
super(
new ProcessConsumer(q),
new ProcessConsumer(q),
new ProcessConsumer(q),
new ProcessConsumer(q),
new ProcessConsumer(q),
new ProcessConsumer(q),
new ProcessConsumer(q),
new ProcessConsumer(q)
);
}
}

View File

@ -1,36 +0,0 @@
/*
* Licence is provided in the jar as license.yml also here:
* https://github.com/Rsl1122/Plan-PlayerAnalytics/blob/master/Plan/src/main/resources/license.yml
*/
package com.djrapitops.plan.system.processing;
/**
* Interface for ProcessingQueue.
* <p>
* Allows lambda Processor creation.
*
* @author Rsl1122
*/
public interface Processor {
static void queueMany(Processor... processors) {
ProcessingQueue processingQueue = ProcessingQueue.getInstance();
for (Processor processor : processors) {
processingQueue.queue(processor);
}
}
/**
* A way to run code Async in ProcessingQueue.
* <p>
* Good for lambdas.
*
* @param processor Processor.
*/
static void queue(Processor processor) {
ProcessingQueue.getInstance().queue(processor);
}
void process();
}

View File

@ -214,7 +214,7 @@ public abstract class Importer {
int mobKills = userImportData.getMobKills();
int deaths = userImportData.getDeaths();
Session session = new Session(0, 0L, 0L, mobKills, deaths);
Session session = new Session(0, 0L, 0L, mobKills, deaths, 0);
session.setPlayerKills(userImportData.getKills());
session.setWorldTimes(new WorldTimes(userImportData.getWorldTimes()));

View File

@ -6,6 +6,7 @@ package com.djrapitops.plan.system.processing.processors;
import com.djrapitops.plan.api.exceptions.database.DBException;
import com.djrapitops.plan.system.database.databases.Database;
import com.djrapitops.plan.system.processing.CriticalRunnable;
import com.djrapitops.plugin.api.utility.log.Log;
/**
@ -13,16 +14,18 @@ import com.djrapitops.plugin.api.utility.log.Log;
*
* @author Rsl1122
*/
public class CommandProcessor extends ObjectProcessor<String> {
public class CommandProcessor implements CriticalRunnable {
public CommandProcessor(String object) {
super(object);
private final String command;
public CommandProcessor(String command) {
this.command = command;
}
@Override
public void process() {
public void run() {
try {
Database.getActive().save().commandUsed(object);
Database.getActive().save().commandUsed(command);
} catch (DBException e) {
Log.toLog(this.getClass(), e);
}

View File

@ -1,31 +0,0 @@
/*
* Licence is provided in the jar as license.yml also here:
* https://github.com/Rsl1122/Plan-PlayerAnalytics/blob/master/Plan/src/main/resources/license.yml
*/
package com.djrapitops.plan.system.processing.processors;
import com.djrapitops.plan.system.processing.Processor;
/**
* Abstract class for processing different objects using Generics.
*
* @author Rsl1122
*/
public abstract class ObjectProcessor<T> implements Processor {
protected final T object;
public ObjectProcessor(T object) {
this.object = object;
}
@Override
public abstract void process();
protected T getObject() {
return object;
}
public void queue() {
Processor.queue(this);
}
}

View File

@ -8,6 +8,7 @@ import com.djrapitops.plan.api.exceptions.database.DBException;
import com.djrapitops.plan.data.container.TPS;
import com.djrapitops.plan.data.container.builders.TPSBuilder;
import com.djrapitops.plan.system.database.databases.Database;
import com.djrapitops.plan.system.processing.CriticalRunnable;
import com.djrapitops.plan.utilities.analysis.MathUtils;
import com.djrapitops.plugin.api.utility.log.Log;
@ -18,15 +19,17 @@ import java.util.List;
*
* @author Rsl1122
*/
public class TPSInsertProcessor extends ObjectProcessor<List<TPS>> {
public class TPSInsertProcessor implements CriticalRunnable {
public TPSInsertProcessor(List<TPS> object) {
super(object);
private final List<TPS> tpsList;
public TPSInsertProcessor(List<TPS> tpsList) {
this.tpsList = tpsList;
}
@Override
public void process() {
List<TPS> history = object;
public void run() {
List<TPS> history = tpsList;
final long lastDate = history.get(history.size() - 1).getDate();
final double averageTPS = MathUtils.round(MathUtils.averageDouble(history.stream().map(TPS::getTicksPerSecond)));
final int peakPlayersOnline = history.stream().mapToInt(TPS::getPlayers).max().orElse(0);

View File

@ -8,7 +8,6 @@ import com.djrapitops.plan.api.exceptions.connection.*;
import com.djrapitops.plan.system.cache.SessionCache;
import com.djrapitops.plan.system.info.InfoSystem;
import com.djrapitops.plan.system.info.connection.ConnectionSystem;
import com.djrapitops.plan.system.processing.processors.player.PlayerProcessor;
import com.djrapitops.plan.system.settings.locale.Locale;
import com.djrapitops.plan.system.settings.locale.Msg;
import com.djrapitops.plugin.api.utility.log.Log;
@ -22,26 +21,26 @@ import java.util.UUID;
*
* @author Rsl1122
*/
public class InspectCacheRequestProcessor extends PlayerProcessor {
public class InspectCacheRequestProcessor implements Runnable {
private final UUID uuid;
private final ISender sender;
private final String playerName;
public InspectCacheRequestProcessor(UUID uuid, ISender sender, String playerName) {
super(uuid);
this.playerName = playerName;
this.uuid = uuid;
this.sender = sender;
this.playerName = playerName;
}
@Override
public void process() {
public void run() {
SessionCache.refreshActiveSessionsState();
try {
InfoSystem.getInstance().generateAndCachePlayerPage(getUUID());
InfoSystem.getInstance().generateAndCachePlayerPage(uuid);
sendInspectMsg(sender, playerName);
} catch (ConnectionFailException | UnsupportedTransferDatabaseException | UnauthorizedServerException
| NotFoundException | NoServersException e) {
// TODO Test if this is appropriate
sender.sendMessage("§c" + e.getMessage());
} catch (WebException e) {
Log.toLog(this.getClass(), e);

View File

@ -6,7 +6,6 @@ package com.djrapitops.plan.system.processing.processors.info;
import com.djrapitops.plan.api.exceptions.connection.WebException;
import com.djrapitops.plan.system.info.InfoSystem;
import com.djrapitops.plan.system.processing.Processor;
import com.djrapitops.plugin.api.utility.log.Log;
/**
@ -14,10 +13,10 @@ import com.djrapitops.plugin.api.utility.log.Log;
*
* @author Rsl1122
*/
public class NetworkPageUpdateProcessor implements Processor {
public class NetworkPageUpdateProcessor implements Runnable {
@Override
public void process() {
public void run() {
try {
InfoSystem.getInstance().updateNetworkPage();
} catch (WebException e) {

View File

@ -0,0 +1,22 @@
package com.djrapitops.plan.system.processing.processors.info;
import com.djrapitops.plan.system.info.InfoSystem;
import com.djrapitops.plan.system.info.connection.WebExceptionLogger;
import java.util.UUID;
public class PlayerPageUpdateProcessor implements Runnable {
private final UUID uuid;
public PlayerPageUpdateProcessor(UUID uuid) {
this.uuid = uuid;
}
@Override
public void run() {
WebExceptionLogger.logIfOccurs(this.getClass(),
() -> InfoSystem.getInstance().generateAndCachePlayerPage(uuid)
);
}
}

View File

@ -16,24 +16,24 @@ import java.util.UUID;
*
* @author Rsl1122
*/
public class BanAndOpProcessor extends PlayerProcessor {
public class BanAndOpProcessor implements Runnable {
private final UUID uuid;
private final boolean banned;
private final boolean opped;
private final boolean op;
public BanAndOpProcessor(UUID uuid, boolean banned, boolean op) {
super(uuid);
this.uuid = uuid;
this.banned = banned;
opped = op;
this.op = op;
}
@Override
public void process() {
UUID uuid = getUUID();
public void run() {
try {
SaveOperations save = Database.getActive().save();
save.banStatus(uuid, banned);
save.opStatus(uuid, opped);
save.opStatus(uuid, op);
} catch (DBException e) {
Log.toLog(this.getClass(), e);
}

View File

@ -6,6 +6,7 @@ package com.djrapitops.plan.system.processing.processors.player;
import com.djrapitops.plan.api.exceptions.database.DBException;
import com.djrapitops.plan.system.database.databases.Database;
import com.djrapitops.plan.system.processing.CriticalRunnable;
import com.djrapitops.plugin.api.utility.log.Log;
import java.util.UUID;
@ -15,20 +16,20 @@ import java.util.UUID;
*
* @author Rsl1122
*/
public class BungeePlayerRegisterProcessor extends PlayerProcessor {
public class BungeePlayerRegisterProcessor implements CriticalRunnable {
private final UUID uuid;
private final String name;
private final long registered;
public BungeePlayerRegisterProcessor(UUID uuid, String name, long registered) {
super(uuid);
this.uuid = uuid;
this.name = name;
this.registered = registered;
}
@Override
public void process() {
UUID uuid = getUUID();
public void run() {
Database database = Database.getActive();
try {
if (database.check().isPlayerRegistered(uuid)) {

View File

@ -5,6 +5,7 @@
package com.djrapitops.plan.system.processing.processors.player;
import com.djrapitops.plan.system.cache.SessionCache;
import com.djrapitops.plan.system.processing.CriticalRunnable;
import java.util.UUID;
@ -13,18 +14,18 @@ import java.util.UUID;
*
* @author Rsl1122
*/
public class EndSessionProcessor extends PlayerProcessor {
public class EndSessionProcessor implements CriticalRunnable {
private final UUID uuid;
private final long time;
public EndSessionProcessor(UUID uuid, long time) {
super(uuid);
this.uuid = uuid;
this.time = time;
}
@Override
public void process() {
UUID uuid = getUUID();
public void run() {
SessionCache.getInstance().endSession(uuid, time);
}
}

View File

@ -9,6 +9,7 @@ import com.djrapitops.plan.data.Actions;
import com.djrapitops.plan.data.container.Action;
import com.djrapitops.plan.system.cache.SessionCache;
import com.djrapitops.plan.system.database.databases.Database;
import com.djrapitops.plan.system.processing.CriticalRunnable;
import com.djrapitops.plugin.api.utility.log.Log;
import java.util.UUID;
@ -19,18 +20,18 @@ import java.util.UUID;
* @author Rsl1122
* @since 4.0.0
*/
public class FirstLeaveProcessor extends PlayerProcessor {
public class FirstLeaveProcessor implements CriticalRunnable {
private final UUID uuid;
private final Action leaveAction;
public FirstLeaveProcessor(UUID uuid, long time, int messagesSent) {
super(uuid);
this.uuid = uuid;
leaveAction = new Action(time, Actions.FIRST_LOGOUT, "Messages sent: " + messagesSent);
}
@Override
public void process() {
UUID uuid = getUUID();
public void run() {
try {
Database.getActive().save().action(uuid, leaveAction);
} catch (DBException e) {

View File

@ -8,6 +8,7 @@ import com.djrapitops.plan.api.exceptions.database.DBException;
import com.djrapitops.plan.data.container.GeoInfo;
import com.djrapitops.plan.system.cache.GeolocationCache;
import com.djrapitops.plan.system.database.databases.Database;
import com.djrapitops.plan.system.processing.CriticalRunnable;
import com.djrapitops.plugin.api.utility.log.Log;
import java.util.UUID;
@ -17,20 +18,20 @@ import java.util.UUID;
*
* @author Rsl1122
*/
public class IPUpdateProcessor extends PlayerProcessor {
public class IPUpdateProcessor implements CriticalRunnable {
private final UUID uuid;
private final String ip;
private final long time;
public IPUpdateProcessor(UUID uuid, String ip, long time) {
super(uuid);
this.uuid = uuid;
this.ip = ip;
this.time = time;
}
@Override
public void process() {
UUID uuid = getUUID();
public void run() {
String country = GeolocationCache.getCountry(ip);
try {
Database.getActive().save().geoInfo(uuid, new GeoInfo(ip, country, time));

View File

@ -6,6 +6,7 @@ package com.djrapitops.plan.system.processing.processors.player;
import com.djrapitops.plan.api.exceptions.database.DBException;
import com.djrapitops.plan.system.database.databases.Database;
import com.djrapitops.plan.system.processing.CriticalRunnable;
import com.djrapitops.plugin.api.utility.log.Log;
import java.util.UUID;
@ -15,14 +16,16 @@ import java.util.UUID;
*
* @author Rsl1122
*/
public class KickProcessor extends PlayerProcessor {
public class KickProcessor implements CriticalRunnable {
private final UUID uuid;
public KickProcessor(UUID uuid) {
super(uuid);
this.uuid = uuid;
}
@Override
public void process() {
UUID uuid = getUUID();
public void run() {
try {
Database.getActive().save().playerWasKicked(uuid);
} catch (DBException e) {

View File

@ -3,6 +3,7 @@ package com.djrapitops.plan.system.processing.processors.player;
import com.djrapitops.plan.data.container.PlayerKill;
import com.djrapitops.plan.data.container.Session;
import com.djrapitops.plan.system.cache.SessionCache;
import com.djrapitops.plan.system.processing.CriticalRunnable;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
@ -18,8 +19,9 @@ import java.util.UUID;
* @author Rsl1122
* @since 4.0.0
*/
public class KillProcessor extends PlayerProcessor {
public class KillProcessor implements CriticalRunnable {
private final UUID uuid;
private final LivingEntity dead;
private final String weaponName;
private final long time;
@ -33,16 +35,14 @@ public class KillProcessor extends PlayerProcessor {
* @param weaponName Weapon used.
*/
public KillProcessor(UUID uuid, long time, LivingEntity dead, String weaponName) {
super(uuid);
this.uuid = uuid;
this.time = time;
this.dead = dead;
this.weaponName = weaponName;
}
@Override
public void process() {
UUID uuid = getUUID();
public void run() {
Optional<Session> cachedSession = SessionCache.getCachedSession(uuid);
if (!cachedSession.isPresent()) {
return;

View File

@ -10,7 +10,8 @@ import com.djrapitops.plan.data.container.Action;
import com.djrapitops.plan.system.cache.DataCache;
import com.djrapitops.plan.system.database.databases.Database;
import com.djrapitops.plan.system.info.server.ServerInfo;
import com.djrapitops.plan.system.processing.Processor;
import com.djrapitops.plan.system.processing.CriticalRunnable;
import com.djrapitops.plan.system.processing.Processing;
import com.djrapitops.plan.utilities.MiscUtils;
import com.djrapitops.plan.utilities.html.HtmlUtils;
import com.djrapitops.plugin.api.utility.log.Log;
@ -24,20 +25,20 @@ import java.util.UUID;
* @author Rsl1122
* @since 4.0.0
*/
public class NameProcessor extends PlayerProcessor {
public class NameProcessor implements CriticalRunnable {
private final UUID uuid;
private final String playerName;
private final String displayName;
public NameProcessor(UUID uuid, String playerName, String displayName) {
super(uuid);
this.uuid = uuid;
this.playerName = playerName;
this.displayName = displayName;
}
@Override
public void process() {
UUID uuid = getUUID();
public void run() {
DataCache dataCache = DataCache.getInstance();
String cachedName = dataCache.getName(uuid);
String cachedDisplayName = dataCache.getDisplayName(uuid);
@ -68,7 +69,7 @@ public class NameProcessor extends PlayerProcessor {
long time = MiscUtils.getTime();
Processor.queue(() -> {
Processing.submitCritical(() -> {
String info = HtmlUtils.removeXSS(displayName);
Action action = new Action(time, Actions.NEW_NICKNAME, info);

View File

@ -1,30 +0,0 @@
/*
* Licence is provided in the jar as license.yml also here:
* https://github.com/Rsl1122/Plan-PlayerAnalytics/blob/master/Plan/src/main/resources/license.yml
*/
package com.djrapitops.plan.system.processing.processors.player;
import com.djrapitops.plan.system.processing.processors.ObjectProcessor;
import java.util.UUID;
/**
* Abstract Processor that takes UUID as a parameter.
* <p>
* Created to allow extending processors to use Generics.
*
* @author Rsl1122
*/
public abstract class PlayerProcessor extends ObjectProcessor<UUID> {
public PlayerProcessor(UUID uuid) {
super(uuid);
}
protected UUID getUUID() {
return object;
}
@Override
public abstract void process();
}

View File

@ -9,8 +9,8 @@ import com.djrapitops.plan.data.Actions;
import com.djrapitops.plan.data.container.Action;
import com.djrapitops.plan.system.cache.SessionCache;
import com.djrapitops.plan.system.database.databases.Database;
import com.djrapitops.plan.system.processing.Processor;
import com.djrapitops.plan.system.processing.processors.ObjectProcessor;
import com.djrapitops.plan.system.processing.CriticalRunnable;
import com.djrapitops.plan.system.processing.Processing;
import com.djrapitops.plugin.api.utility.log.Log;
import com.djrapitops.plugin.utilities.Verify;
@ -21,16 +21,17 @@ import java.util.UUID;
*
* @author Rsl1122
*/
public class RegisterProcessor extends PlayerProcessor {
public class RegisterProcessor implements CriticalRunnable {
private final UUID uuid;
private final long registered;
private final long time;
private final int playersOnline;
private final String name;
private final ObjectProcessor[] afterProcess;
private final Runnable[] afterProcess;
public RegisterProcessor(UUID uuid, long registered, long time, String name, int playersOnline, ObjectProcessor... afterProcess) {
super(uuid);
public RegisterProcessor(UUID uuid, long registered, long time, String name, int playersOnline, Runnable... afterProcess) {
this.uuid = uuid;
this.registered = registered;
this.time = time;
this.playersOnline = playersOnline;
@ -39,8 +40,7 @@ public class RegisterProcessor extends PlayerProcessor {
}
@Override
public void process() {
UUID uuid = getUUID();
public void run() {
Database db = Database.getActive();
Verify.nullCheck(uuid, () -> new IllegalStateException("UUID was null"));
try {
@ -58,7 +58,9 @@ public class RegisterProcessor extends PlayerProcessor {
} catch (DBException e) {
Log.toLog(this.getClass(), e);
} finally {
Processor.queueMany(afterProcess);
for (Runnable runnable : afterProcess) {
Processing.submit(runnable);
}
}
}
}

View File

@ -35,6 +35,7 @@ public enum Settings {
WEBSERVER_DISABLED("WebServer.DisableWebServer"),
FORMAT_DATE_RECENT_DAYS("Customization.Formatting.Dates.RecentDays"),
DISPLAY_PLAYER_IPS("Customization.Display.PlayerIPs"),
DISPLAY_GAPS_IN_GRAPH_DATA("Customization.Display.GapsInGraphData"),
// Integer
WEBSERVER_PORT("WebServer.Port"),
@ -45,6 +46,7 @@ public enum Settings {
MAX_SESSIONS("Customization.Display.MaxSessions"),
MAX_PLAYERS("Customization.Display.MaxPlayers"),
MAX_PLAYERS_PLAYERS_PAGE("Customization.Display.MaxPlayersPlayersPage"),
AFK_THRESHOLD_MINUTES("Data.AFKThresholdMinutes"),
// String
DEBUG("Plugin.Debug"),

View File

@ -4,7 +4,7 @@
*/
package com.djrapitops.plan.system.settings;
import com.djrapitops.plan.system.processing.Processor;
import com.djrapitops.plan.system.processing.Processing;
import com.djrapitops.plan.system.settings.config.ConfigSystem;
import com.djrapitops.plugin.api.config.Config;
import com.djrapitops.plugin.api.config.ConfigNode;
@ -22,12 +22,16 @@ import java.util.Map;
*/
public class WorldAliasSettings {
private WorldAliasSettings() {
/* Hide Constructor */
}
/**
* Used to get all World aliases in the config
*
* @return Map: Original name, Alias
*/
public Map<String, String> getAliases() {
public static Map<String, String> getAliases() {
ConfigNode aliasSect = getAliasSection();
Map<String, String> aliasMap = new HashMap<>();
@ -37,7 +41,7 @@ public class WorldAliasSettings {
return aliasMap;
}
private ConfigNode getAliasSection() {
private static ConfigNode getAliasSection() {
Config config = ConfigSystem.getConfig();
return config.getConfigNode(Settings.WORLD_ALIASES.getPath());
}
@ -49,29 +53,19 @@ public class WorldAliasSettings {
*
* @param world World name
*/
public void addWorld(String world) {
public static void addWorld(String world) {
ConfigNode aliasSect = getAliasSection();
String previousValue = aliasSect.getConfigNode(world).getValue();
if (Verify.isEmpty(previousValue)) {
aliasSect.set(world, world);
Processor.queue(() -> {
Processing.submitNonCritical(() -> {
try {
aliasSect.save();
} catch (IOException e) {
Log.toLog(this.getClass(), e);
Log.toLog(WorldAliasSettings.class, e);
}
});
}
}
/**
* Used to get alias of a single world.
*
* @param world World name.
* @return Alias.
*/
public String getAlias(String world) {
return getAliasSection().getString(world);
}
}

View File

@ -8,7 +8,7 @@ import com.djrapitops.plan.api.exceptions.connection.UnsupportedTransferDatabase
import com.djrapitops.plan.api.exceptions.database.DBException;
import com.djrapitops.plan.system.database.databases.Database;
import com.djrapitops.plan.system.info.server.ServerInfo;
import com.djrapitops.plan.system.processing.Processor;
import com.djrapitops.plan.system.processing.Processing;
import com.djrapitops.plan.system.settings.ServerSpecificSettings;
import com.djrapitops.plan.system.settings.Settings;
import com.djrapitops.plan.utilities.Base64Util;
@ -40,7 +40,7 @@ public class NetworkSettings {
return;
}
Processor.queue(() -> {
Processing.submitNonCritical(() -> {
try {
new NetworkSettings().loadFromDatabase();
} catch (DBException | UnsupportedTransferDatabaseException e) {
@ -54,7 +54,7 @@ public class NetworkSettings {
return;
}
Processor.queue(() -> {
Processing.submitCritical(() -> {
try {
new NetworkSettings().placeToDatabase();
} catch (DBException | UnsupportedTransferDatabaseException e) {
@ -147,7 +147,7 @@ public class NetworkSettings {
Settings.MAX_PLAYERS_PLAYERS_PAGE, Settings.PLAYERTABLE_FOOTER, Settings.FORMAT_DATE_RECENT_DAYS,
Settings.FORMAT_DATE_RECENT_DAYS_PATTERN, Settings.FORMAT_DATE_CLOCK, Settings.FORMAT_DATE_NO_SECONDS,
Settings.FORMAT_DATE_FULL, Settings.DISPLAY_PLAYER_IPS, Settings.ACTIVE_LOGIN_THRESHOLD,
Settings.ACTIVE_PLAY_THRESHOLD
Settings.ACTIVE_PLAY_THRESHOLD, Settings.DISPLAY_GAPS_IN_GRAPH_DATA, Settings.AFK_THRESHOLD_MINUTES
};
Log.debug("NetworkSettings: Adding Config Values..");
for (Settings setting : sameStrings) {

View File

@ -0,0 +1,9 @@
package com.djrapitops.plan.system.tasks;
public class SpongeTaskSystem extends TaskSystem {
@Override
public void enable() {
}
}

View File

@ -2,7 +2,7 @@ package com.djrapitops.plan.system.tasks;
import com.djrapitops.plan.PlanPlugin;
import com.djrapitops.plan.data.container.TPS;
import com.djrapitops.plan.system.processing.Processor;
import com.djrapitops.plan.system.processing.Processing;
import com.djrapitops.plan.system.processing.processors.TPSInsertProcessor;
import com.djrapitops.plan.utilities.MiscUtils;
import com.djrapitops.plugin.api.utility.log.Log;
@ -38,7 +38,7 @@ public abstract class TPSCountTimer<T extends PlanPlugin> extends AbsRunnable {
addNewTPSEntry(nanoTime, now);
if (history.size() >= 60) {
Processor.queue(new TPSInsertProcessor(new ArrayList<>(history)));
Processing.submit(new TPSInsertProcessor(new ArrayList<>(history)));
history.clear();
}
} catch (Exception | NoClassDefFoundError | NoSuchMethodError | NoSuchFieldError e) {

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