mirror of
https://github.com/plan-player-analytics/Plan.git
synced 2025-03-27 14:09:20 +01:00
Merge branch 'data-refactoring' into data-refactoring-bridge-fixes
This commit is contained in:
commit
02f3aa21de
@ -35,7 +35,7 @@
|
||||
</plugin>
|
||||
<plugin>
|
||||
<artifactId>maven-shade-plugin</artifactId>
|
||||
<version>3.1.1</version>
|
||||
<version>3.1.1</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<phase>package</phase>
|
||||
@ -65,21 +65,21 @@
|
||||
<pattern>org.apache</pattern>
|
||||
<shadedPattern>plan.org.apache</shadedPattern>
|
||||
<excludes>
|
||||
<exclude>org.apache.logging.**</exclude>
|
||||
<exclude>org.apache.logging.**</exclude>
|
||||
</excludes>
|
||||
</relocation>
|
||||
<relocation>
|
||||
<pattern>com.maxmind</pattern>
|
||||
<shadedPattern>plan.com.maxmind</shadedPattern>
|
||||
<excludes>
|
||||
<exclude>org.apache.logging.**</exclude>
|
||||
<exclude>org.apache.logging.**</exclude>
|
||||
</excludes>
|
||||
</relocation>
|
||||
<relocation>
|
||||
<pattern>com.fasterxml</pattern>
|
||||
<shadedPattern>plan.com.fasterxml</shadedPattern>
|
||||
<excludes>
|
||||
<exclude>org.apache.logging.**</exclude>
|
||||
<exclude>org.apache.logging.**</exclude>
|
||||
</excludes>
|
||||
</relocation>
|
||||
</relocations>
|
||||
|
@ -6,16 +6,15 @@ package com.djrapitops.plan;
|
||||
|
||||
import com.djrapitops.plan.api.exceptions.database.DBException;
|
||||
import com.djrapitops.plan.api.exceptions.database.DBInitException;
|
||||
import com.djrapitops.plan.data.Actions;
|
||||
import com.djrapitops.plan.data.container.Action;
|
||||
import com.djrapitops.plan.api.exceptions.database.DBOpException;
|
||||
import com.djrapitops.plan.data.container.Session;
|
||||
import com.djrapitops.plan.system.cache.CacheSystem;
|
||||
import com.djrapitops.plan.system.cache.DataCache;
|
||||
import com.djrapitops.plan.data.store.keys.SessionKeys;
|
||||
import com.djrapitops.plan.system.cache.SessionCache;
|
||||
import com.djrapitops.plan.system.database.databases.Database;
|
||||
import com.djrapitops.plugin.api.utility.log.Log;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
@ -54,7 +53,6 @@ public class ShutdownHook extends Thread {
|
||||
Map<UUID, Session> activeSessions = SessionCache.getActiveSessions();
|
||||
long now = System.currentTimeMillis();
|
||||
db = Database.getActive();
|
||||
saveFirstSessionInformation(db, now);
|
||||
saveActiveSessions(db, activeSessions, now);
|
||||
} catch (IllegalStateException ignored) {
|
||||
/* Database is not initialized */
|
||||
@ -71,28 +69,12 @@ public class ShutdownHook extends Thread {
|
||||
}
|
||||
}
|
||||
|
||||
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();
|
||||
db.save().action(uuid, new Action(now, Actions.FIRST_LOGOUT, "Messages sent: " + messagesSent));
|
||||
} catch (DBException e) {
|
||||
Log.toLog(this.getClass(), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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();
|
||||
long sessionEnd = session.getSessionEnd();
|
||||
if (sessionEnd == -1) {
|
||||
Optional<Long> end = session.getValue(SessionKeys.END);
|
||||
if (!end.isPresent()) {
|
||||
session.endSession(now);
|
||||
}
|
||||
if (!db.isOpen()) {
|
||||
@ -101,7 +83,7 @@ public class ShutdownHook extends Thread {
|
||||
try {
|
||||
Log.debug("Shutdown: Saving a session: " + session.getSessionStart());
|
||||
db.save().session(uuid, session);
|
||||
} catch (DBException e) {
|
||||
} catch (DBOpException e) {
|
||||
Log.toLog(this.getClass(), e);
|
||||
}
|
||||
}
|
||||
|
@ -4,7 +4,7 @@
|
||||
*/
|
||||
package com.djrapitops.plan.api;
|
||||
|
||||
import com.djrapitops.plan.api.exceptions.database.DBException;
|
||||
import com.djrapitops.plan.api.exceptions.database.DBOpException;
|
||||
import com.djrapitops.plan.utilities.uuid.UUIDUtility;
|
||||
import com.djrapitops.plugin.api.utility.log.Log;
|
||||
|
||||
@ -38,7 +38,7 @@ public abstract class CommonAPI implements PlanAPI {
|
||||
public Map<UUID, String> getKnownPlayerNames() {
|
||||
try {
|
||||
return fetchFromPlanDB().getPlayerNames();
|
||||
} catch (DBException e) {
|
||||
} catch (DBOpException e) {
|
||||
Log.toLog(this.getClass(), e);
|
||||
return new HashMap<>();
|
||||
}
|
||||
|
@ -4,8 +4,6 @@
|
||||
*/
|
||||
package com.djrapitops.plan.api.exceptions.connection;
|
||||
|
||||
import com.djrapitops.plan.api.exceptions.database.DBException;
|
||||
|
||||
/**
|
||||
* Thrown when DBException occurs during InfoRequest#placeIntoDatabase.
|
||||
*
|
||||
@ -13,7 +11,7 @@ import com.djrapitops.plan.api.exceptions.database.DBException;
|
||||
*/
|
||||
public class TransferDatabaseException extends WebException {
|
||||
|
||||
public TransferDatabaseException(DBException cause) {
|
||||
public TransferDatabaseException(Exception cause) {
|
||||
super(cause);
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,33 @@
|
||||
package com.djrapitops.plan.api.exceptions.database;
|
||||
|
||||
import java.sql.SQLException;
|
||||
|
||||
/**
|
||||
* Runtime exception for wrapping database errors.
|
||||
*
|
||||
* @author Rsl1122
|
||||
*/
|
||||
public class DBOpException extends RuntimeException {
|
||||
|
||||
private boolean fatal = false;
|
||||
|
||||
public DBOpException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
public DBOpException(String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
}
|
||||
|
||||
public static DBOpException forCause(String sql, SQLException e) {
|
||||
return new DBOpException("SQL Failed: " + sql + "; " + e.getMessage(), e);
|
||||
}
|
||||
|
||||
public boolean isFatal() {
|
||||
return fatal;
|
||||
}
|
||||
|
||||
public void setFatal(boolean fatal) {
|
||||
this.fatal = fatal;
|
||||
}
|
||||
}
|
@ -1,7 +1,7 @@
|
||||
package com.djrapitops.plan.command.commands;
|
||||
|
||||
import com.djrapitops.plan.api.exceptions.connection.WebException;
|
||||
import com.djrapitops.plan.api.exceptions.database.DBException;
|
||||
import com.djrapitops.plan.api.exceptions.database.DBOpException;
|
||||
import com.djrapitops.plan.system.database.databases.Database;
|
||||
import com.djrapitops.plan.system.info.InfoSystem;
|
||||
import com.djrapitops.plan.system.info.connection.ConnectionSystem;
|
||||
@ -12,7 +12,6 @@ import com.djrapitops.plan.system.settings.Permissions;
|
||||
import com.djrapitops.plan.system.settings.locale.Locale;
|
||||
import com.djrapitops.plan.system.settings.locale.Msg;
|
||||
import com.djrapitops.plan.system.webserver.WebServerSystem;
|
||||
import com.djrapitops.plan.utilities.analysis.Analysis;
|
||||
import com.djrapitops.plugin.api.utility.log.Log;
|
||||
import com.djrapitops.plugin.command.CommandNode;
|
||||
import com.djrapitops.plugin.command.CommandType;
|
||||
@ -46,12 +45,12 @@ public class AnalyzeCommand extends CommandNode {
|
||||
try {
|
||||
Server server = getServer(args).orElseGet(ServerInfo::getServer);
|
||||
UUID serverUUID = server.getUuid();
|
||||
if (!ServerInfo.getServerUUID().equals(serverUUID) || !Analysis.isAnalysisBeingRun()) {
|
||||
InfoSystem.getInstance().generateAnalysisPage(serverUUID);
|
||||
}
|
||||
|
||||
|
||||
InfoSystem.getInstance().generateAnalysisPage(serverUUID);
|
||||
sendWebUserNotificationIfNecessary(sender);
|
||||
sendLink(server, sender);
|
||||
} catch (DBException | WebException e) {
|
||||
} catch (DBOpException | WebException e) {
|
||||
sender.sendMessage("§cError occurred: " + e.toString());
|
||||
Log.toLog(this.getClass(), e);
|
||||
}
|
||||
@ -74,7 +73,7 @@ public class AnalyzeCommand extends CommandNode {
|
||||
sender.sendMessage(Locale.get(Msg.CMD_CONSTANT_FOOTER).toString());
|
||||
}
|
||||
|
||||
private void sendWebUserNotificationIfNecessary(ISender sender) throws DBException {
|
||||
private void sendWebUserNotificationIfNecessary(ISender sender) {
|
||||
if (WebServerSystem.getInstance().getWebServer().isAuthRequired() && CommandUtils.isPlayer(sender)) {
|
||||
|
||||
boolean senderHasWebUser = Database.getActive().check().doesWebUserExists(sender.getName());
|
||||
@ -84,7 +83,7 @@ public class AnalyzeCommand extends CommandNode {
|
||||
}
|
||||
}
|
||||
|
||||
private Optional<Server> getServer(String[] args) throws DBException {
|
||||
private Optional<Server> getServer(String[] args) {
|
||||
if (args.length >= 1 && ConnectionSystem.getInstance().isServerAvailable()) {
|
||||
Map<UUID, Server> bukkitServers = Database.getActive().fetch().getBukkitServers();
|
||||
String serverIdentifier = getGivenIdentifier(args);
|
||||
|
@ -1,7 +1,6 @@
|
||||
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.api.exceptions.database.DBOpException;
|
||||
import com.djrapitops.plan.system.database.databases.Database;
|
||||
import com.djrapitops.plan.system.processing.Processing;
|
||||
import com.djrapitops.plan.system.processing.processors.info.InspectCacheRequestProcessor;
|
||||
@ -60,24 +59,29 @@ public class InspectCommand extends CommandNode {
|
||||
return;
|
||||
}
|
||||
|
||||
if (CommandUtils.isPlayer(sender) && WebServer.getInstance().isAuthRequired()) {
|
||||
boolean senderHasWebUser = activeDB.check().doesWebUserExists(sender.getName());
|
||||
|
||||
if (!senderHasWebUser) {
|
||||
sender.sendMessage("§e[Plan] You might not have a web user, use /plan register <password>");
|
||||
}
|
||||
}
|
||||
checkWebUserAndNotify(activeDB, sender);
|
||||
Processing.submit(new InspectCacheRequestProcessor(uuid, sender, playerName));
|
||||
} catch (FatalDBException ex) {
|
||||
Log.toLog(this.getClass(), ex);
|
||||
sender.sendMessage("§cFatal database exception occurred: " + ex.getMessage());
|
||||
} catch (DBException ex) {
|
||||
Log.toLog(this.getClass(), ex);
|
||||
sender.sendMessage("§eNon-Fatal database exception occurred: " + ex.getMessage());
|
||||
} catch (DBOpException e) {
|
||||
if (e.isFatal()) {
|
||||
sender.sendMessage("§cFatal database exception occurred: " + e.getMessage());
|
||||
} else {
|
||||
sender.sendMessage("§eNon-Fatal database exception occurred: " + e.getMessage());
|
||||
}
|
||||
Log.toLog(this.getClass(), e);
|
||||
} finally {
|
||||
this.cancel();
|
||||
}
|
||||
}
|
||||
}).runTaskAsynchronously();
|
||||
}
|
||||
|
||||
private void checkWebUserAndNotify(Database activeDB, ISender sender) {
|
||||
if (CommandUtils.isPlayer(sender) && WebServer.getInstance().isAuthRequired()) {
|
||||
boolean senderHasWebUser = activeDB.check().doesWebUserExists(sender.getName());
|
||||
|
||||
if (!senderHasWebUser) {
|
||||
sender.sendMessage("§e[Plan] You might not have a web user, use /plan register <password>");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,7 +1,7 @@
|
||||
package com.djrapitops.plan.command.commands;
|
||||
|
||||
import com.djrapitops.plan.PlanPlugin;
|
||||
import com.djrapitops.plan.api.exceptions.database.DBException;
|
||||
import com.djrapitops.plan.api.exceptions.database.DBOpException;
|
||||
import com.djrapitops.plan.system.database.databases.Database;
|
||||
import com.djrapitops.plan.system.info.server.Server;
|
||||
import com.djrapitops.plan.system.settings.Permissions;
|
||||
@ -44,7 +44,7 @@ public class ListServersCommand extends CommandNode {
|
||||
sender.sendMessage(" " + tCol + server.getId() + sCol + " : " + server.getName() + " : " + server.getWebAddress());
|
||||
}
|
||||
sender.sendMessage(Locale.get(Msg.CMD_CONSTANT_FOOTER).toString());
|
||||
} catch (DBException e) {
|
||||
} catch (DBOpException e) {
|
||||
sender.sendMessage("§cDatabase Exception occurred.");
|
||||
Log.toLog(this.getClass(), e);
|
||||
}
|
||||
|
@ -1,14 +1,20 @@
|
||||
package com.djrapitops.plan.command.commands;
|
||||
|
||||
import com.djrapitops.plan.PlanPlugin;
|
||||
import com.djrapitops.plan.api.exceptions.database.DBException;
|
||||
import com.djrapitops.plan.data.PlayerProfile;
|
||||
import com.djrapitops.plan.data.calculation.ActivityIndex;
|
||||
import com.djrapitops.plan.api.exceptions.database.DBOpException;
|
||||
import com.djrapitops.plan.data.container.GeoInfo;
|
||||
import com.djrapitops.plan.data.store.containers.PlayerContainer;
|
||||
import com.djrapitops.plan.data.store.keys.PlayerKeys;
|
||||
import com.djrapitops.plan.data.store.mutators.ActivityIndex;
|
||||
import com.djrapitops.plan.data.store.mutators.GeoInfoMutator;
|
||||
import com.djrapitops.plan.data.store.mutators.SessionsMutator;
|
||||
import com.djrapitops.plan.data.store.mutators.formatting.Formatter;
|
||||
import com.djrapitops.plan.data.store.mutators.formatting.Formatters;
|
||||
import com.djrapitops.plan.data.store.objects.DateHolder;
|
||||
import com.djrapitops.plan.system.database.databases.Database;
|
||||
import com.djrapitops.plan.system.settings.Permissions;
|
||||
import com.djrapitops.plan.system.settings.locale.Locale;
|
||||
import com.djrapitops.plan.system.settings.locale.Msg;
|
||||
import com.djrapitops.plan.utilities.FormatUtils;
|
||||
import com.djrapitops.plan.utilities.MiscUtils;
|
||||
import com.djrapitops.plan.utilities.uuid.UUIDUtility;
|
||||
import com.djrapitops.plugin.api.utility.log.Log;
|
||||
@ -16,10 +22,12 @@ import com.djrapitops.plugin.command.CommandNode;
|
||||
import com.djrapitops.plugin.command.CommandType;
|
||||
import com.djrapitops.plugin.command.ISender;
|
||||
import com.djrapitops.plugin.settings.ColorScheme;
|
||||
import com.djrapitops.plugin.settings.DefaultMessages;
|
||||
import com.djrapitops.plugin.task.AbsRunnable;
|
||||
import com.djrapitops.plugin.task.RunnableFactory;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
@ -64,17 +72,20 @@ public class QInspectCommand extends CommandNode {
|
||||
return;
|
||||
}
|
||||
|
||||
Database database = Database.getActive();
|
||||
if (!database.check().isPlayerRegistered(uuid)) {
|
||||
PlayerContainer container = Database.getActive().fetch().getPlayerContainer(uuid);
|
||||
if (!container.getValue(PlayerKeys.REGISTERED).isPresent()) {
|
||||
sender.sendMessage(Locale.get(Msg.CMD_FAIL_USERNAME_NOT_KNOWN).toString());
|
||||
return;
|
||||
}
|
||||
|
||||
PlayerProfile playerProfile = database.fetch().getPlayerProfile(uuid);
|
||||
|
||||
sendMessages(sender, playerProfile);
|
||||
} catch (DBException ex) {
|
||||
Log.toLog(this.getClass(), ex);
|
||||
sendMessages(sender, container);
|
||||
} catch (DBOpException e) {
|
||||
if (e.isFatal()) {
|
||||
sender.sendMessage("§cFatal database exception occurred: " + e.getMessage());
|
||||
} else {
|
||||
sender.sendMessage("§eNon-Fatal database exception occurred: " + e.getMessage());
|
||||
}
|
||||
Log.toLog(this.getClass(), e);
|
||||
} finally {
|
||||
this.cancel();
|
||||
}
|
||||
@ -82,7 +93,7 @@ public class QInspectCommand extends CommandNode {
|
||||
}).runTaskAsynchronously();
|
||||
}
|
||||
|
||||
private void sendMessages(ISender sender, PlayerProfile profile) {
|
||||
private void sendMessages(ISender sender, PlayerContainer container) {
|
||||
long now = System.currentTimeMillis();
|
||||
|
||||
ColorScheme colorScheme = plugin.getColorScheme();
|
||||
@ -90,24 +101,30 @@ public class QInspectCommand extends CommandNode {
|
||||
String colM = colorScheme.getMainColor();
|
||||
String colS = colorScheme.getSecondaryColor();
|
||||
String colT = colorScheme.getTertiaryColor();
|
||||
Formatter<DateHolder> timestamp = Formatters.year();
|
||||
Formatter<Long> length = Formatters.timeAmount();
|
||||
|
||||
String ball = DefaultMessages.BALL.parse();
|
||||
sender.sendMessage(Locale.get(Msg.CMD_HEADER_INSPECT).toString() + ": " + colT + container.getValue(PlayerKeys.NAME).orElse("Unknown"));
|
||||
|
||||
sender.sendMessage(Locale.get(Msg.CMD_HEADER_INSPECT).toString() + ": " + colT + profile.getName());
|
||||
ActivityIndex activityIndex = container.getActivityIndex(now);
|
||||
Long registered = container.getValue(PlayerKeys.REGISTERED).orElse(0L);
|
||||
Long lastSeen = container.getValue(PlayerKeys.LAST_SEEN).orElse(0L);
|
||||
List<GeoInfo> geoInfo = container.getValue(PlayerKeys.GEO_INFO).orElse(new ArrayList<>());
|
||||
Optional<GeoInfo> mostRecentGeoInfo = new GeoInfoMutator(geoInfo).mostRecent();
|
||||
String loginLocation = mostRecentGeoInfo.isPresent() ? mostRecentGeoInfo.get().getGeolocation() : "-";
|
||||
SessionsMutator sessionsMutator = SessionsMutator.forContainer(container);
|
||||
|
||||
ActivityIndex activityIndex = profile.getActivityIndex(now);
|
||||
|
||||
sender.sendMessage(colT + ball + " " + colM + " Activity Index: " + colS + activityIndex.getFormattedValue() + " | " + activityIndex.getGroup());
|
||||
sender.sendMessage(colT + ball + " " + colM + " Registered: " + colS + FormatUtils.formatTimeStampYear(profile.getRegistered()));
|
||||
sender.sendMessage(colT + ball + " " + colM + " Last Seen: " + colS + FormatUtils.formatTimeStampYear(profile.getLastSeen()));
|
||||
sender.sendMessage(colT + ball + " " + colM + " Logged in from: " + colS + profile.getMostRecentGeoInfo().getGeolocation());
|
||||
sender.sendMessage(colT + ball + " " + colM + " Playtime: " + colS + FormatUtils.formatTimeAmount(profile.getTotalPlaytime()));
|
||||
sender.sendMessage(colT + ball + " " + colM + " Longest Session: " + colS + FormatUtils.formatTimeAmount(profile.getLongestSession(0, now)));
|
||||
sender.sendMessage(colT + ball + " " + colM + " Times Kicked: " + colS + profile.getTimesKicked());
|
||||
sender.sendMessage(colM + " Activity Index: " + colS + activityIndex.getFormattedValue() + " | " + activityIndex.getGroup());
|
||||
sender.sendMessage(colM + " Registered: " + colS + timestamp.apply(() -> registered));
|
||||
sender.sendMessage(colM + " Last Seen: " + colS + timestamp.apply(() -> lastSeen));
|
||||
sender.sendMessage(colM + " Logged in from: " + colS + loginLocation);
|
||||
sender.sendMessage(colM + " Playtime: " + colS + length.apply(sessionsMutator.toPlaytime()));
|
||||
sender.sendMessage(colM + " Longest Session: " + colS + length.apply(sessionsMutator.toLongestSessionLength()));
|
||||
sender.sendMessage(colM + " Times Kicked: " + colS + container.getValue(PlayerKeys.KICK_COUNT).orElse(0));
|
||||
sender.sendMessage("");
|
||||
sender.sendMessage(colT + ball + " " + colM + " Player Kills : " + colS + profile.getPlayerKills().count());
|
||||
sender.sendMessage(colT + ball + " " + colM + " Mob Kills : " + colS + profile.getMobKillCount());
|
||||
sender.sendMessage(colT + ball + " " + colM + " Deaths : " + colS + profile.getDeathCount());
|
||||
sender.sendMessage(colM + " Player Kills : " + colS + sessionsMutator.toPlayerKillCount());
|
||||
sender.sendMessage(colM + " Mob Kills : " + colS + sessionsMutator.toMobKillCount());
|
||||
sender.sendMessage(colM + " Deaths : " + colS + sessionsMutator.toDeathCount());
|
||||
|
||||
sender.sendMessage(Locale.get(Msg.CMD_CONSTANT_FOOTER).toString());
|
||||
}
|
||||
|
@ -1,9 +1,11 @@
|
||||
package com.djrapitops.plan.command.commands;
|
||||
|
||||
import com.djrapitops.plan.api.exceptions.database.DBOpException;
|
||||
import com.djrapitops.plan.system.settings.Permissions;
|
||||
import com.djrapitops.plan.system.settings.locale.Locale;
|
||||
import com.djrapitops.plan.system.settings.locale.Msg;
|
||||
import com.djrapitops.plan.utilities.MiscUtils;
|
||||
import com.djrapitops.plugin.api.utility.log.Log;
|
||||
import com.djrapitops.plugin.command.CommandNode;
|
||||
import com.djrapitops.plugin.command.CommandType;
|
||||
import com.djrapitops.plugin.command.ISender;
|
||||
@ -57,6 +59,9 @@ public class SearchCommand extends CommandNode {
|
||||
}
|
||||
|
||||
sender.sendMessage(Locale.get(Msg.CMD_CONSTANT_FOOTER).toString());
|
||||
} catch (DBOpException e) {
|
||||
sender.sendMessage("§cDatabase error occurred: " + e.getMessage());
|
||||
Log.toLog(this.getClass(), e);
|
||||
} finally {
|
||||
this.cancel();
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
package com.djrapitops.plan.command.commands;
|
||||
|
||||
import com.djrapitops.plan.api.exceptions.connection.*;
|
||||
import com.djrapitops.plan.api.exceptions.database.DBException;
|
||||
import com.djrapitops.plan.api.exceptions.database.DBOpException;
|
||||
import com.djrapitops.plan.command.commands.manage.ManageConDebugCommand;
|
||||
import com.djrapitops.plan.system.database.databases.Database;
|
||||
import com.djrapitops.plan.system.database.databases.operation.FetchOperations;
|
||||
@ -101,7 +101,7 @@ public class UpdateCommand extends CommandNode {
|
||||
try {
|
||||
cancel(sender, Database.getActive().fetch().getServers());
|
||||
sender.sendMessage("§aCancel operation performed.");
|
||||
} catch (DBException e) {
|
||||
} catch (DBOpException e) {
|
||||
sender.sendMessage("§cDatabase error occurred, cancel could not be performed.");
|
||||
Log.toLog(this.getClass().getName(), e);
|
||||
}
|
||||
@ -120,7 +120,7 @@ public class UpdateCommand extends CommandNode {
|
||||
try {
|
||||
List<Server> servers = Database.getActive().fetch().getServers();
|
||||
update(sender, servers, args);
|
||||
} catch (DBException e) {
|
||||
} catch (DBOpException e) {
|
||||
Log.toLog(this.getClass().getName(), e);
|
||||
}
|
||||
}
|
||||
@ -228,7 +228,7 @@ public class UpdateCommand extends CommandNode {
|
||||
success = false;
|
||||
}
|
||||
return success;
|
||||
} catch (DBException e) {
|
||||
} catch (DBOpException e) {
|
||||
sender.sendMessage("§cDatabase error occurred, update has been cancelled.");
|
||||
Log.toLog(this.getClass().getName(), e);
|
||||
return false;
|
||||
|
@ -2,13 +2,13 @@ package com.djrapitops.plan.command.commands.manage;
|
||||
|
||||
import com.djrapitops.plan.api.exceptions.database.DBException;
|
||||
import com.djrapitops.plan.api.exceptions.database.DBInitException;
|
||||
import com.djrapitops.plan.data.store.mutators.formatting.Formatters;
|
||||
import com.djrapitops.plan.system.database.DBSystem;
|
||||
import com.djrapitops.plan.system.database.databases.Database;
|
||||
import com.djrapitops.plan.system.database.databases.sql.SQLiteDB;
|
||||
import com.djrapitops.plan.system.settings.Permissions;
|
||||
import com.djrapitops.plan.system.settings.locale.Locale;
|
||||
import com.djrapitops.plan.system.settings.locale.Msg;
|
||||
import com.djrapitops.plan.utilities.FormatUtils;
|
||||
import com.djrapitops.plugin.api.utility.log.Log;
|
||||
import com.djrapitops.plugin.command.CommandNode;
|
||||
import com.djrapitops.plugin.command.CommandType;
|
||||
@ -17,7 +17,6 @@ import com.djrapitops.plugin.task.AbsRunnable;
|
||||
import com.djrapitops.plugin.task.RunnableFactory;
|
||||
import com.djrapitops.plugin.utilities.Verify;
|
||||
|
||||
import java.sql.SQLException;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.UUID;
|
||||
@ -85,10 +84,10 @@ public class ManageBackupCommand extends CommandNode {
|
||||
* @param dbName Name of database (mysql/sqlite)
|
||||
* @param copyFromDB Database you want to backup.
|
||||
*/
|
||||
private void createNewBackup(String dbName, Database copyFromDB) throws SQLException {
|
||||
private void createNewBackup(String dbName, Database copyFromDB) {
|
||||
SQLiteDB backupDB = null;
|
||||
try {
|
||||
String timeStamp = FormatUtils.formatTimeStampISO8601NoClock(System.currentTimeMillis());
|
||||
String timeStamp = Formatters.iso8601NoClock().apply(System::currentTimeMillis);
|
||||
String fileName = dbName + "-backup-" + timeStamp;
|
||||
backupDB = new SQLiteDB(fileName);
|
||||
Collection<UUID> uuids = copyFromDB.fetch().getSavedUUIDs();
|
||||
|
@ -1,8 +1,7 @@
|
||||
package com.djrapitops.plan.command.commands.manage;
|
||||
|
||||
import com.djrapitops.plan.api.exceptions.database.DBException;
|
||||
import com.djrapitops.plan.api.exceptions.database.DBInitException;
|
||||
import com.djrapitops.plan.api.exceptions.database.FatalDBException;
|
||||
import com.djrapitops.plan.api.exceptions.database.DBOpException;
|
||||
import com.djrapitops.plan.system.database.DBSystem;
|
||||
import com.djrapitops.plan.system.database.databases.Database;
|
||||
import com.djrapitops.plan.system.settings.Permissions;
|
||||
@ -66,12 +65,13 @@ public class ManageClearCommand extends CommandNode {
|
||||
database.remove().everything();
|
||||
|
||||
sender.sendMessage(Locale.get(Msg.MANAGE_INFO_CLEAR_SUCCESS).toString());
|
||||
} catch (FatalDBException e) {
|
||||
sender.sendMessage(Locale.get(Msg.MANAGE_INFO_FAIL).toString()
|
||||
+ " Error was fatal, so all information may not have been removed.");
|
||||
Log.toLog(this.getClass(), e);
|
||||
} catch (DBException e) {
|
||||
sender.sendMessage(Locale.get(Msg.MANAGE_INFO_FAIL).toString());
|
||||
} catch (DBOpException e) {
|
||||
if (e.isFatal()) {
|
||||
sender.sendMessage(Locale.get(Msg.MANAGE_INFO_FAIL).toString()
|
||||
+ " Error was fatal, so all information may not have been removed.");
|
||||
} else {
|
||||
sender.sendMessage(Locale.get(Msg.MANAGE_INFO_FAIL).toString());
|
||||
}
|
||||
Log.toLog(this.getClass(), e);
|
||||
} finally {
|
||||
this.cancel();
|
||||
|
@ -2,7 +2,6 @@ package com.djrapitops.plan.command.commands.manage;
|
||||
|
||||
import com.djrapitops.plan.PlanPlugin;
|
||||
import com.djrapitops.plan.api.exceptions.connection.*;
|
||||
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.request.CheckConnectionRequest;
|
||||
@ -11,7 +10,6 @@ import com.djrapitops.plan.system.info.server.ServerInfo;
|
||||
import com.djrapitops.plan.system.processing.Processing;
|
||||
import com.djrapitops.plan.system.settings.Permissions;
|
||||
import com.djrapitops.plan.system.webserver.WebServerSystem;
|
||||
import com.djrapitops.plugin.api.utility.log.Log;
|
||||
import com.djrapitops.plugin.command.CommandNode;
|
||||
import com.djrapitops.plugin.command.CommandType;
|
||||
import com.djrapitops.plugin.command.ISender;
|
||||
@ -44,24 +42,19 @@ public class ManageConDebugCommand extends CommandNode {
|
||||
}
|
||||
|
||||
private void testServers(ISender sender) {
|
||||
try {
|
||||
List<Server> servers = Database.getActive().fetch().getServers();
|
||||
List<Server> servers = Database.getActive().fetch().getServers();
|
||||
|
||||
if (servers.isEmpty()) {
|
||||
sender.sendMessage("§cNo Servers found in the database.");
|
||||
if (servers.isEmpty()) {
|
||||
sender.sendMessage("§cNo Servers found in the database.");
|
||||
}
|
||||
|
||||
String accessAddress = WebServerSystem.getInstance().getWebServer().getAccessAddress();
|
||||
UUID thisServer = ServerInfo.getServerUUID();
|
||||
for (Server server : servers) {
|
||||
if (thisServer.equals(server.getUuid())) {
|
||||
continue;
|
||||
}
|
||||
|
||||
String accessAddress = WebServerSystem.getInstance().getWebServer().getAccessAddress();
|
||||
UUID thisServer = ServerInfo.getServerUUID();
|
||||
for (Server server : servers) {
|
||||
if (thisServer.equals(server.getUuid())) {
|
||||
continue;
|
||||
}
|
||||
testServer(sender, accessAddress, server);
|
||||
}
|
||||
|
||||
} catch (DBException e) {
|
||||
Log.toLog(this.getClass().getName(), e);
|
||||
testServer(sender, accessAddress, server);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
package com.djrapitops.plan.command.commands.manage;
|
||||
|
||||
import com.djrapitops.plan.api.exceptions.database.DBException;
|
||||
import com.djrapitops.plan.api.exceptions.database.DBOpException;
|
||||
import com.djrapitops.plan.system.database.databases.Database;
|
||||
import com.djrapitops.plan.system.settings.Permissions;
|
||||
import com.djrapitops.plan.system.settings.locale.Locale;
|
||||
@ -70,7 +70,7 @@ public class ManageRemoveCommand extends CommandNode {
|
||||
database.remove().player(uuid);
|
||||
|
||||
sender.sendMessage(Locale.get(Msg.MANAGE_INFO_REMOVE_SUCCESS).parse(playerName, Database.getActive().getConfigName()));
|
||||
} catch (DBException e) {
|
||||
} catch (DBOpException e) {
|
||||
Log.toLog(this.getClass(), e);
|
||||
sender.sendMessage(Locale.get(Msg.MANAGE_INFO_FAIL).toString());
|
||||
} finally {
|
||||
|
@ -1,44 +0,0 @@
|
||||
/*
|
||||
* License is provided in the jar as LICENSE also here:
|
||||
* https://github.com/Rsl1122/Plan-PlayerAnalytics/blob/master/Plan/src/main/resources/LICENSE
|
||||
*/
|
||||
package com.djrapitops.plan.data;
|
||||
|
||||
import org.apache.commons.text.WordUtils;
|
||||
|
||||
/**
|
||||
* IDs of various actions
|
||||
*
|
||||
* @author Rsl1122
|
||||
*/
|
||||
public enum Actions {
|
||||
UNKNOWN(-1),
|
||||
FIRST_SESSION(1),
|
||||
FIRST_LOGOUT(2),
|
||||
NEW_NICKNAME(3),
|
||||
KILLED(-2); // Not stored in ActionsTable.
|
||||
|
||||
private final int id;
|
||||
|
||||
Actions(int id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public static Actions getById(int id) {
|
||||
for (Actions a : values()) {
|
||||
if (a.getId() == id) {
|
||||
return a;
|
||||
}
|
||||
}
|
||||
return UNKNOWN;
|
||||
}
|
||||
|
||||
public int getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return WordUtils.capitalizeFully(name(), '_').replace('_', ' ');
|
||||
}
|
||||
}
|
@ -1,462 +0,0 @@
|
||||
/*
|
||||
* License is provided in the jar as LICENSE also here:
|
||||
* https://github.com/Rsl1122/Plan-PlayerAnalytics/blob/master/Plan/src/main/resources/LICENSE
|
||||
*/
|
||||
package com.djrapitops.plan.data;
|
||||
|
||||
import com.djrapitops.plan.data.calculation.ActivityIndex;
|
||||
import com.djrapitops.plan.data.container.Action;
|
||||
import com.djrapitops.plan.data.container.GeoInfo;
|
||||
import com.djrapitops.plan.data.container.PlayerKill;
|
||||
import com.djrapitops.plan.data.container.Session;
|
||||
import com.djrapitops.plan.data.time.WorldTimes;
|
||||
import com.djrapitops.plan.system.info.server.ServerInfo;
|
||||
import com.djrapitops.plan.utilities.comparators.ActionComparator;
|
||||
import com.djrapitops.plan.utilities.comparators.GeoInfoComparator;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
/**
|
||||
* Data container object for a single player.
|
||||
* <p>
|
||||
* Created to streamline analysis and to make it easier to understand.
|
||||
*
|
||||
* @author Rsl1122
|
||||
*/
|
||||
public class PlayerProfile {
|
||||
|
||||
// Identification
|
||||
private final UUID uuid;
|
||||
private final String name;
|
||||
|
||||
// Basic information
|
||||
private final long registered;
|
||||
private Map<UUID, Long> registeredMap;
|
||||
private Set<UUID> bannedOnServers;
|
||||
private Set<UUID> oppedOnServers;
|
||||
private int timesKicked;
|
||||
|
||||
// Activity related information
|
||||
private Map<UUID, List<Session>> sessions;
|
||||
private List<Action> actions;
|
||||
private Map<UUID, WorldTimes> worldTimesMap;
|
||||
|
||||
// Extra information
|
||||
private Map<UUID, List<String>> nicknames;
|
||||
private List<GeoInfo> geoInformation;
|
||||
|
||||
// Plugin data
|
||||
private Map<String, String> pluginReplaceMap;
|
||||
|
||||
// Value that requires lot of processing
|
||||
private Map<Long, ActivityIndex> activityIndexCache;
|
||||
|
||||
public PlayerProfile(UUID uuid, String name, long registered) {
|
||||
this.uuid = uuid;
|
||||
this.name = name;
|
||||
this.registered = registered;
|
||||
registeredMap = new HashMap<>();
|
||||
|
||||
bannedOnServers = new HashSet<>();
|
||||
oppedOnServers = new HashSet<>();
|
||||
|
||||
sessions = new HashMap<>();
|
||||
actions = new ArrayList<>();
|
||||
worldTimesMap = new HashMap<>();
|
||||
|
||||
nicknames = new HashMap<>();
|
||||
geoInformation = new ArrayList<>();
|
||||
|
||||
pluginReplaceMap = new HashMap<>();
|
||||
activityIndexCache = new HashMap<>();
|
||||
}
|
||||
|
||||
public static long getPlaytime(Stream<Session> s) {
|
||||
return s.mapToLong(Session::getLength).sum();
|
||||
}
|
||||
|
||||
public static long getLongestSession(Stream<Session> s) {
|
||||
OptionalLong longestSession = s.mapToLong(Session::getLength).max();
|
||||
if (longestSession.isPresent()) {
|
||||
return longestSession.getAsLong();
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
public static long getSessionMedian(Stream<Session> s) {
|
||||
List<Long> sessionLenghts = s.map(Session::getLength)
|
||||
.sorted()
|
||||
.collect(Collectors.toList());
|
||||
if (sessionLenghts.isEmpty()) {
|
||||
return 0;
|
||||
}
|
||||
return sessionLenghts.get(sessionLenghts.size() / 2);
|
||||
}
|
||||
|
||||
public static long getSessionAverage(Stream<Session> s) {
|
||||
OptionalDouble average = s.map(Session::getLength)
|
||||
.mapToLong(i -> i)
|
||||
.average();
|
||||
if (average.isPresent()) {
|
||||
return (long) average.getAsDouble();
|
||||
}
|
||||
return 0L;
|
||||
}
|
||||
|
||||
public static Stream<PlayerKill> getPlayerKills(Stream<Session> s) {
|
||||
return s.map(Session::getPlayerKills)
|
||||
.flatMap(Collection::stream);
|
||||
}
|
||||
|
||||
public static long getDeathCount(Stream<Session> s) {
|
||||
return s.mapToLong(Session::getDeaths)
|
||||
.sum();
|
||||
}
|
||||
|
||||
public static long getMobKillCount(Stream<Session> s) {
|
||||
return s.mapToLong(Session::getMobKills)
|
||||
.sum();
|
||||
}
|
||||
|
||||
// Calculating Getters
|
||||
public ActivityIndex getActivityIndex(long date) {
|
||||
return activityIndexCache.computeIfAbsent(date, dateValue -> new ActivityIndex(this, dateValue));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the total world times of the player.
|
||||
*
|
||||
* @return returns the WorldTimes in the "null" key of the map.
|
||||
*/
|
||||
public WorldTimes getWorldTimes() {
|
||||
return worldTimesMap.getOrDefault(null, new WorldTimes(new HashMap<>()));
|
||||
}
|
||||
|
||||
public void setWorldTimes(Map<UUID, WorldTimes> worldTimes) {
|
||||
worldTimesMap.putAll(worldTimes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get world times per server for this player.
|
||||
*
|
||||
* @return a copy of the WorldTimes Map without the "null" key.
|
||||
*/
|
||||
public Map<UUID, WorldTimes> getWorldTimesPerServer() {
|
||||
Map<UUID, WorldTimes> map = new HashMap<>(worldTimesMap);
|
||||
map.remove(null);
|
||||
return map;
|
||||
}
|
||||
|
||||
public UUID getFavoriteServer() {
|
||||
long max = 0L;
|
||||
UUID maxServer = null;
|
||||
for (Map.Entry<UUID, WorldTimes> entry : getWorldTimesPerServer().entrySet()) {
|
||||
long playTime = entry.getValue().getTotal();
|
||||
if (playTime > max) {
|
||||
max = playTime;
|
||||
maxServer = entry.getKey();
|
||||
}
|
||||
}
|
||||
return maxServer;
|
||||
}
|
||||
|
||||
public long getLastSeen() {
|
||||
return getLastSeen(getAllSessions());
|
||||
}
|
||||
|
||||
public long getLastSeen(Stream<Session> s) {
|
||||
OptionalLong max = s.mapToLong(session -> Math.max(session.getSessionStart(), session.getSessionEnd())).max();
|
||||
if (max.isPresent()) {
|
||||
return max.getAsLong();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
public long getTotalPlaytime() {
|
||||
return getPlaytime(-1, System.currentTimeMillis() + 1L);
|
||||
}
|
||||
|
||||
public long getPlaytime(long after, long before) {
|
||||
return getPlaytime(getSessions(after, before));
|
||||
}
|
||||
|
||||
public long getPlaytime(UUID serverUUID) {
|
||||
return getPlaytime(getSessions(serverUUID).stream());
|
||||
}
|
||||
|
||||
public long getLongestSession() {
|
||||
return getLongestSession(-1, System.currentTimeMillis() + 1L);
|
||||
}
|
||||
|
||||
public long getLongestSession(int after, long before) {
|
||||
return getLongestSession(getSessions(after, before));
|
||||
}
|
||||
|
||||
public long getLongestSession(UUID serverUUID) {
|
||||
return getLongestSession(getSessions(serverUUID).stream());
|
||||
}
|
||||
|
||||
public long getSessionMedian() {
|
||||
return getSessionMedian(-1, System.currentTimeMillis() + 1L);
|
||||
}
|
||||
|
||||
public long getSessionMedian(int after, long before) {
|
||||
return getSessionMedian(getSessions(after, before));
|
||||
}
|
||||
|
||||
public long getSessionMedian(UUID serverUUID) {
|
||||
return getSessionMedian(getSessions(serverUUID).stream());
|
||||
}
|
||||
|
||||
// Special Getters
|
||||
|
||||
public long getSessionAverage() {
|
||||
return getSessionAverage(-1, System.currentTimeMillis() + 1L);
|
||||
}
|
||||
|
||||
public long getSessionAverage(int after, long before) {
|
||||
return getSessionAverage(getSessions(after, before));
|
||||
}
|
||||
|
||||
public long getSessionAverage(UUID serverUUID) {
|
||||
return getSessionAverage(getSessions(serverUUID).stream());
|
||||
}
|
||||
|
||||
public boolean playedBetween(long after, long before) {
|
||||
return getSessions(after, before).findFirst().isPresent();
|
||||
}
|
||||
|
||||
public Stream<Session> getAllSessions() {
|
||||
return sessions.values().stream().flatMap(Collection::stream);
|
||||
}
|
||||
|
||||
public Stream<Session> getSessions(long after, long before) {
|
||||
return getAllSessions()
|
||||
.filter(session -> session.getSessionStart() >= after && session.getSessionStart() <= before);
|
||||
}
|
||||
|
||||
public GeoInfo getMostRecentGeoInfo() {
|
||||
if (geoInformation.isEmpty()) {
|
||||
return new GeoInfo("-", "Not Known", System.currentTimeMillis(), "");
|
||||
}
|
||||
geoInformation.sort(new GeoInfoComparator());
|
||||
return geoInformation.get(0);
|
||||
}
|
||||
|
||||
public List<Action> getAllActions() {
|
||||
List<Action> actions = new ArrayList<>(this.actions);
|
||||
getPlayerKills().map(PlayerKill::convertToAction).forEach(actions::add);
|
||||
actions.sort(new ActionComparator());
|
||||
return actions;
|
||||
}
|
||||
|
||||
public Stream<PlayerKill> getPlayerKills() {
|
||||
return getPlayerKills(getAllSessions());
|
||||
}
|
||||
|
||||
public Stream<PlayerKill> getPlayerKills(UUID serverUUID) {
|
||||
return getPlayerKills(getSessions(serverUUID).stream());
|
||||
}
|
||||
|
||||
public long getPlayerKillCount() {
|
||||
return getPlayerKills().count();
|
||||
}
|
||||
|
||||
public long getPlayerKillCount(UUID serverUUID) {
|
||||
return getPlayerKills(serverUUID).count();
|
||||
}
|
||||
|
||||
public long getDeathCount() {
|
||||
return getDeathCount(getAllSessions());
|
||||
}
|
||||
|
||||
public long getDeathCount(UUID serverUUID) {
|
||||
return getDeathCount(getSessions(serverUUID).stream());
|
||||
}
|
||||
|
||||
public long getMobKillCount() {
|
||||
return getMobKillCount(getAllSessions());
|
||||
}
|
||||
|
||||
public long getMobKillCount(UUID serverUUID) {
|
||||
return getMobKillCount(getSessions(serverUUID).stream());
|
||||
}
|
||||
|
||||
public long getSessionCount() {
|
||||
return getAllSessions().count();
|
||||
}
|
||||
|
||||
public long getSessionCount(UUID serverUUID) {
|
||||
return getSessions(serverUUID).size();
|
||||
}
|
||||
|
||||
// Setters & Adders
|
||||
|
||||
public long getRegistered(UUID serverUUID) {
|
||||
return registeredMap.getOrDefault(serverUUID, -1L);
|
||||
}
|
||||
|
||||
public void bannedOnServer(UUID serverUUID) {
|
||||
bannedOnServers.add(serverUUID);
|
||||
}
|
||||
|
||||
public void oppedOnServer(UUID serverUUID) {
|
||||
oppedOnServers.add(serverUUID);
|
||||
}
|
||||
|
||||
public void bannedOnServer(Collection<UUID> serverUUIDs) {
|
||||
bannedOnServers.addAll(serverUUIDs);
|
||||
}
|
||||
|
||||
public void oppedOnServer(Collection<UUID> serverUUIDs) {
|
||||
oppedOnServers.addAll(serverUUIDs);
|
||||
}
|
||||
|
||||
public void setSessions(UUID serverUUID, List<Session> sessions) {
|
||||
this.sessions.put(serverUUID, sessions);
|
||||
}
|
||||
|
||||
public void addActiveSession(Session activeSession) {
|
||||
UUID serverUUID = ServerInfo.getServerUUID();
|
||||
List<Session> sessions = getSessions(serverUUID);
|
||||
sessions.add(activeSession);
|
||||
this.sessions.put(serverUUID, sessions);
|
||||
}
|
||||
|
||||
public List<Session> getSessions(UUID serverUUID) {
|
||||
return this.sessions.getOrDefault(serverUUID, new ArrayList<>());
|
||||
}
|
||||
|
||||
public void addReplaceValue(String placeholder, Serializable value) {
|
||||
pluginReplaceMap.put(placeholder, value.toString());
|
||||
}
|
||||
|
||||
public void setWorldTimes(UUID serverUUID, WorldTimes worldTimes) {
|
||||
worldTimesMap.put(serverUUID, worldTimes);
|
||||
}
|
||||
|
||||
public void setTotalWorldTimes(WorldTimes worldTimes) {
|
||||
worldTimesMap.put(null, worldTimes);
|
||||
}
|
||||
|
||||
public void setRegistered(UUID serverUUID, long registered) {
|
||||
registeredMap.put(serverUUID, registered);
|
||||
}
|
||||
|
||||
public int getTimesKicked() {
|
||||
return timesKicked;
|
||||
}
|
||||
|
||||
// Default Setters
|
||||
|
||||
public void setTimesKicked(int timesKicked) {
|
||||
this.timesKicked = timesKicked;
|
||||
}
|
||||
|
||||
public Map<UUID, List<String>> getNicknames() {
|
||||
return nicknames;
|
||||
}
|
||||
|
||||
public void setNicknames(Map<UUID, List<String>> nicknames) {
|
||||
this.nicknames = nicknames;
|
||||
}
|
||||
|
||||
public List<GeoInfo> getGeoInformation() {
|
||||
return geoInformation;
|
||||
}
|
||||
|
||||
// Default Getters
|
||||
|
||||
public void setGeoInformation(List<GeoInfo> geoInformation) {
|
||||
this.geoInformation = geoInformation;
|
||||
}
|
||||
|
||||
public UUID getUuid() {
|
||||
return uuid;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public long getRegistered() {
|
||||
return registered;
|
||||
}
|
||||
|
||||
public Set<UUID> getBannedOnServers() {
|
||||
return bannedOnServers;
|
||||
}
|
||||
|
||||
public Set<UUID> getOppedOnServers() {
|
||||
return oppedOnServers;
|
||||
}
|
||||
|
||||
public Map<UUID, List<Session>> getSessions() {
|
||||
return sessions;
|
||||
}
|
||||
|
||||
public void setSessions(Map<UUID, List<Session>> sessions) {
|
||||
this.sessions.putAll(sessions);
|
||||
}
|
||||
|
||||
public List<Action> getActions() {
|
||||
return actions;
|
||||
}
|
||||
|
||||
public void setActions(List<Action> actions) {
|
||||
this.actions = actions;
|
||||
}
|
||||
|
||||
public Map<String, String> getPluginReplaceMap() {
|
||||
return pluginReplaceMap;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the WorldTimes map.
|
||||
*
|
||||
* @return Map that contains WorldTimes for each server and a total in the "null" key.
|
||||
*/
|
||||
public Map<UUID, WorldTimes> getWorldTimesMap() {
|
||||
return worldTimesMap;
|
||||
}
|
||||
|
||||
// OfflinePlayer methods for possible PluginData analysis
|
||||
|
||||
public boolean isBanned() {
|
||||
return bannedOnServers.size() != 0;
|
||||
}
|
||||
|
||||
public boolean isOp() {
|
||||
return oppedOnServers.contains(ServerInfo.getServerUUID());
|
||||
}
|
||||
|
||||
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() {
|
||||
if (worldTimesMap.containsKey(ServerInfo.getServerUUID())) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (Map.Entry<UUID, List<Session>> entry : sessions.entrySet()) {
|
||||
UUID serverUUID = entry.getKey();
|
||||
List<Session> sessions = entry.getValue();
|
||||
|
||||
WorldTimes times = worldTimesMap.getOrDefault(serverUUID, new WorldTimes(new HashMap<>()));
|
||||
for (Session session : sessions) {
|
||||
WorldTimes worldTimes = session.getWorldTimes();
|
||||
times.add(worldTimes);
|
||||
}
|
||||
worldTimesMap.put(serverUUID, times);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@ -1,391 +0,0 @@
|
||||
/*
|
||||
* License is provided in the jar as LICENSE also here:
|
||||
* https://github.com/Rsl1122/Plan-PlayerAnalytics/blob/master/Plan/src/main/resources/LICENSE
|
||||
*/
|
||||
package com.djrapitops.plan.data;
|
||||
|
||||
import com.djrapitops.plan.data.container.GeoInfo;
|
||||
import com.djrapitops.plan.data.container.PlayerKill;
|
||||
import com.djrapitops.plan.data.container.Session;
|
||||
import com.djrapitops.plan.data.container.TPS;
|
||||
import com.djrapitops.plan.data.time.WorldTimes;
|
||||
import com.djrapitops.plan.system.settings.Settings;
|
||||
import com.djrapitops.plan.utilities.analysis.AnalysisUtils;
|
||||
import com.djrapitops.plan.utilities.analysis.MathUtils;
|
||||
import com.djrapitops.plan.utilities.comparators.PlayerProfileLastPlayedComparator;
|
||||
import com.djrapitops.plan.utilities.comparators.TPSComparator;
|
||||
import com.djrapitops.plan.utilities.html.tables.PlayersTableCreator;
|
||||
import com.djrapitops.plugin.api.TimeAmount;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
/**
|
||||
* Data class for streamlining Analysis data.
|
||||
* <p>
|
||||
* Most of the methods are not the most efficient when multiple of them are used.
|
||||
*
|
||||
* @author Rsl1122
|
||||
*/
|
||||
public class ServerProfile {
|
||||
|
||||
private final UUID serverUUID;
|
||||
|
||||
// Database information
|
||||
private List<PlayerProfile> players;
|
||||
private List<TPS> tps;
|
||||
private Map<String, Integer> commandUsage;
|
||||
|
||||
// Information calculated with SQL
|
||||
private WorldTimes serverWorldtimes;
|
||||
private long lastPeakDate;
|
||||
private int lastPeakPlayers;
|
||||
private long allTimePeak;
|
||||
private int allTimePeakPlayers;
|
||||
|
||||
// Calculated once
|
||||
private Map<UUID, PlayerProfile> playerMap;
|
||||
|
||||
public ServerProfile(UUID serverUUID) {
|
||||
this.serverUUID = serverUUID;
|
||||
players = new ArrayList<>();
|
||||
tps = new ArrayList<>();
|
||||
commandUsage = new HashMap<>();
|
||||
|
||||
allTimePeak = -1;
|
||||
allTimePeakPlayers = -1;
|
||||
lastPeakDate = -1;
|
||||
lastPeakPlayers = -1;
|
||||
}
|
||||
|
||||
public static long getLowSpikeCount(List<TPS> tpsData) {
|
||||
int mediumThreshold = Settings.THEME_GRAPH_TPS_THRESHOLD_MED.getNumber();
|
||||
|
||||
boolean wasLow = false;
|
||||
long spikeCount = 0L;
|
||||
|
||||
for (TPS tpsObj : tpsData) {
|
||||
double tps = tpsObj.getTicksPerSecond();
|
||||
if (tps < mediumThreshold) {
|
||||
if (!wasLow) {
|
||||
spikeCount++;
|
||||
wasLow = true;
|
||||
}
|
||||
} else {
|
||||
wasLow = false;
|
||||
}
|
||||
}
|
||||
|
||||
return spikeCount;
|
||||
}
|
||||
|
||||
public static List<PlayerKill> getPlayerKills(List<Session> s) {
|
||||
List<PlayerKill> kills = new ArrayList<>();
|
||||
for (Session session : s) {
|
||||
kills.addAll(session.getPlayerKills());
|
||||
}
|
||||
return kills;
|
||||
}
|
||||
|
||||
public static long getMobKillCount(List<Session> s) {
|
||||
long total = 0;
|
||||
for (Session session : s) {
|
||||
total += session.getMobKills();
|
||||
}
|
||||
return total;
|
||||
}
|
||||
|
||||
public static long getDeathCount(List<Session> s) {
|
||||
long total = 0;
|
||||
for (Session session : s) {
|
||||
total += session.getDeaths();
|
||||
}
|
||||
return total;
|
||||
}
|
||||
|
||||
public static long serverDownTime(List<TPS> tpsData) {
|
||||
long lastDate = -1;
|
||||
long downTime = 0;
|
||||
for (TPS tps : tpsData) {
|
||||
long date = tps.getDate();
|
||||
if (lastDate == -1) {
|
||||
lastDate = date;
|
||||
continue;
|
||||
}
|
||||
|
||||
long diff = date - lastDate;
|
||||
if (diff > TimeAmount.MINUTE.ms() * 3L) {
|
||||
downTime += diff;
|
||||
}
|
||||
lastDate = date;
|
||||
}
|
||||
|
||||
return downTime;
|
||||
}
|
||||
|
||||
public static long serverIdleTime(List<TPS> tpsData) {
|
||||
long lastDate = -1;
|
||||
int lastPlayers = 0;
|
||||
long idleTime = 0;
|
||||
for (TPS tps : tpsData) {
|
||||
long date = tps.getDate();
|
||||
int players = tps.getPlayers();
|
||||
if (lastDate == -1) {
|
||||
lastDate = date;
|
||||
lastPlayers = players;
|
||||
continue;
|
||||
}
|
||||
|
||||
long diff = date - lastDate;
|
||||
if (lastPlayers == 0 && players == 0) {
|
||||
idleTime += diff;
|
||||
}
|
||||
|
||||
lastDate = date;
|
||||
lastPlayers = players;
|
||||
}
|
||||
|
||||
return idleTime;
|
||||
}
|
||||
|
||||
public static double aboveLowThreshold(List<TPS> tpsData) {
|
||||
if (tpsData.isEmpty()) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
int threshold = Settings.THEME_GRAPH_TPS_THRESHOLD_MED.getNumber();
|
||||
|
||||
long count = 0;
|
||||
for (TPS tps : tpsData) {
|
||||
if (tps.getTicksPerSecond() >= threshold) {
|
||||
count++;
|
||||
}
|
||||
}
|
||||
|
||||
return count * 1.0 / tpsData.size();
|
||||
}
|
||||
|
||||
public List<PlayerProfile> getPlayers() {
|
||||
return players;
|
||||
}
|
||||
|
||||
public void setPlayers(List<PlayerProfile> players) {
|
||||
this.players = players;
|
||||
}
|
||||
|
||||
public List<TPS> getTps() {
|
||||
return tps;
|
||||
}
|
||||
|
||||
public void setTps(List<TPS> tps) {
|
||||
this.tps = tps;
|
||||
}
|
||||
|
||||
public Map<String, Integer> getCommandUsage() {
|
||||
return commandUsage;
|
||||
}
|
||||
|
||||
public void setCommandUsage(Map<String, Integer> commandUsage) {
|
||||
this.commandUsage = commandUsage;
|
||||
}
|
||||
|
||||
public double getAverageTPS(long after, long before) {
|
||||
OptionalDouble average = getTPSData(after, before)
|
||||
.mapToDouble(TPS::getTicksPerSecond)
|
||||
.average();
|
||||
if (average.isPresent()) {
|
||||
return average.getAsDouble();
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
public double getAverageCPU(long after, long before) {
|
||||
OptionalDouble average = getTPSData(after, before)
|
||||
.mapToDouble(TPS::getCPUUsage)
|
||||
.filter(num -> num >= 0)
|
||||
.average();
|
||||
if (average.isPresent()) {
|
||||
return average.getAsDouble();
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
public double getAverageRAM(long after, long before) {
|
||||
OptionalDouble average = getTPSData(after, before)
|
||||
.mapToDouble(TPS::getUsedMemory)
|
||||
.average();
|
||||
if (average.isPresent()) {
|
||||
return average.getAsDouble();
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
public double getAverageEntities(long after, long before) {
|
||||
OptionalDouble average = getTPSData(after, before)
|
||||
.mapToDouble(TPS::getEntityCount)
|
||||
.average();
|
||||
if (average.isPresent()) {
|
||||
return average.getAsDouble();
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
public double getAverageChunks(long after, long before) {
|
||||
OptionalDouble average = getTPSData(after, before)
|
||||
.mapToDouble(TPS::getChunksLoaded)
|
||||
.average();
|
||||
if (average.isPresent()) {
|
||||
return average.getAsDouble();
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
public long getNewPlayers(long after, long before) {
|
||||
return getPlayersWhoRegistered(after, before).count();
|
||||
}
|
||||
|
||||
public long getUniquePlayers(long after, long before) {
|
||||
return getPlayersWhoPlayedBetween(after, before).count();
|
||||
}
|
||||
|
||||
public double getNewPlayersPerDay(long after, long before) {
|
||||
long days = AnalysisUtils.getNumberOfDaysBetween(after, before);
|
||||
long newPlayers = getNewPlayers(after, before);
|
||||
return days == 0 ? newPlayers : newPlayers * 1.0 / days;
|
||||
}
|
||||
|
||||
public Stream<PlayerProfile> getPlayersWhoPlayedBetween(long after, long before) {
|
||||
return players.stream()
|
||||
.filter(player -> player.playedBetween(after, before));
|
||||
}
|
||||
|
||||
public Stream<PlayerProfile> getPlayersWhoRegistered(long after, long before) {
|
||||
return players.stream()
|
||||
.filter(player -> player.getRegistered() >= after && player.getRegistered() <= before);
|
||||
}
|
||||
|
||||
public Stream<TPS> getTPSData(long after, long before) {
|
||||
return tps.stream().filter(tps -> tps.getDate() >= after && tps.getDate() <= before);
|
||||
}
|
||||
|
||||
public String createPlayersTableBody() {
|
||||
players.sort(new PlayerProfileLastPlayedComparator());
|
||||
return PlayersTableCreator.createTable(players);
|
||||
}
|
||||
|
||||
public List<String> getGeoLocations() {
|
||||
return players.stream()
|
||||
.map(PlayerProfile::getMostRecentGeoInfo)
|
||||
.map(GeoInfo::getGeolocation)
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
// Default setters & getters
|
||||
|
||||
public long getTotalPlaytime() {
|
||||
return serverWorldtimes.getTotal();
|
||||
}
|
||||
|
||||
public long getAveragePlayTime() {
|
||||
return MathUtils.averageLong(getTotalPlaytime(), getPlayerCount());
|
||||
}
|
||||
|
||||
public long getPlayerCount() {
|
||||
return players.size();
|
||||
}
|
||||
|
||||
public Map<UUID, List<Session>> getSessions() {
|
||||
return players.stream().collect(Collectors.toMap(PlayerProfile::getUuid, p -> p.getSessions(serverUUID)));
|
||||
}
|
||||
|
||||
public List<Session> getAllSessions() {
|
||||
return players.stream().map(p -> p.getSessions(serverUUID)).flatMap(Collection::stream).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
public WorldTimes getServerWorldtimes() {
|
||||
return serverWorldtimes;
|
||||
}
|
||||
|
||||
public void setServerWorldtimes(WorldTimes serverWorldtimes) {
|
||||
this.serverWorldtimes = serverWorldtimes;
|
||||
}
|
||||
|
||||
public long getLastPeakDate() {
|
||||
return lastPeakDate;
|
||||
}
|
||||
|
||||
public void setLastPeakDate(long lastPeakDate) {
|
||||
this.lastPeakDate = lastPeakDate;
|
||||
}
|
||||
|
||||
public int getLastPeakPlayers() {
|
||||
return lastPeakPlayers;
|
||||
}
|
||||
|
||||
public void setLastPeakPlayers(int lastPeakPlayers) {
|
||||
this.lastPeakPlayers = lastPeakPlayers;
|
||||
}
|
||||
|
||||
public long getAllTimePeak() {
|
||||
return allTimePeak;
|
||||
}
|
||||
|
||||
public void setAllTimePeak(long allTimePeak) {
|
||||
this.allTimePeak = allTimePeak;
|
||||
}
|
||||
|
||||
public int getAllTimePeakPlayers() {
|
||||
return allTimePeakPlayers;
|
||||
}
|
||||
|
||||
public void setAllTimePeakPlayers(int allTimePeakPlayers) {
|
||||
this.allTimePeakPlayers = allTimePeakPlayers;
|
||||
}
|
||||
|
||||
public Stream<PlayerProfile> getOps() {
|
||||
return players.stream().filter(PlayerProfile::isOp);
|
||||
}
|
||||
|
||||
public Set<UUID> getUuids() {
|
||||
Set<UUID> uuids = new HashSet<>();
|
||||
for (PlayerProfile player : players) {
|
||||
uuids.add(player.getUuid());
|
||||
}
|
||||
return uuids;
|
||||
}
|
||||
|
||||
public long serverDownTime(long after, long before) {
|
||||
return serverDownTime(getTPSData(after, before)
|
||||
.sorted(new TPSComparator())
|
||||
.collect(Collectors.toList()));
|
||||
}
|
||||
|
||||
public long serverIdleTime(long after, long before) {
|
||||
return serverIdleTime(getTPSData(after, before)
|
||||
.sorted(new TPSComparator())
|
||||
.collect(Collectors.toList()));
|
||||
}
|
||||
|
||||
public PlayerProfile getPlayer(UUID uuid) {
|
||||
if (playerMap == null) {
|
||||
playerMap = players.stream().collect(Collectors.toMap(PlayerProfile::getUuid, Function.identity()));
|
||||
}
|
||||
|
||||
return playerMap.get(uuid);
|
||||
}
|
||||
|
||||
public void addActiveSessions(Map<UUID, Session> activeSessions) {
|
||||
for (Map.Entry<UUID, Session> entry : activeSessions.entrySet()) {
|
||||
UUID uuid = entry.getKey();
|
||||
Session session = entry.getValue();
|
||||
session.setSessionID((int) session.getSessionStart());
|
||||
|
||||
PlayerProfile player = getPlayer(uuid);
|
||||
if (player != null) {
|
||||
player.addActiveSession(session);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,407 +0,0 @@
|
||||
package com.djrapitops.plan.data.calculation;
|
||||
|
||||
import com.djrapitops.plan.PlanPlugin;
|
||||
import com.djrapitops.plan.data.PlayerProfile;
|
||||
import com.djrapitops.plan.data.ServerProfile;
|
||||
import com.djrapitops.plan.data.container.Session;
|
||||
import com.djrapitops.plan.data.container.StickyData;
|
||||
import com.djrapitops.plan.data.container.TPS;
|
||||
import com.djrapitops.plan.data.element.AnalysisContainer;
|
||||
import com.djrapitops.plan.data.plugin.PluginData;
|
||||
import com.djrapitops.plan.data.time.WorldTimes;
|
||||
import com.djrapitops.plan.system.info.server.ServerInfo;
|
||||
import com.djrapitops.plan.system.info.server.ServerProperties;
|
||||
import com.djrapitops.plan.system.settings.Settings;
|
||||
import com.djrapitops.plan.system.settings.theme.Theme;
|
||||
import com.djrapitops.plan.system.settings.theme.ThemeVal;
|
||||
import com.djrapitops.plan.utilities.FormatUtils;
|
||||
import com.djrapitops.plan.utilities.MiscUtils;
|
||||
import com.djrapitops.plan.utilities.analysis.AnalysisUtils;
|
||||
import com.djrapitops.plan.utilities.analysis.MathUtils;
|
||||
import com.djrapitops.plan.utilities.comparators.SessionStartComparator;
|
||||
import com.djrapitops.plan.utilities.html.Html;
|
||||
import com.djrapitops.plan.utilities.html.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;
|
||||
import com.djrapitops.plan.utilities.html.structure.AnalysisPluginsTabContentCreator;
|
||||
import com.djrapitops.plan.utilities.html.structure.SessionTabStructureCreator;
|
||||
import com.djrapitops.plan.utilities.html.tables.CommandUseTable;
|
||||
import com.djrapitops.plan.utilities.html.tables.SessionsTableCreator;
|
||||
import com.djrapitops.plugin.api.TimeAmount;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* Big container object for Data.
|
||||
* <p>
|
||||
* Contains parts that can be analysed. Each part has their own purpose.
|
||||
* <p>
|
||||
* Parts contain variables that can be added to. These variables are then
|
||||
* analysed using the analysis method.
|
||||
* <p>
|
||||
* After being analysed the ReplaceMap can be retrieved for replacing
|
||||
* placeholders on the server.html file.
|
||||
*
|
||||
* @author Rsl1122
|
||||
* @since 3.5.2
|
||||
*/
|
||||
public class AnalysisData extends RawData {
|
||||
|
||||
private long refreshDate;
|
||||
|
||||
private Map<String, Long> analyzedValues;
|
||||
private Set<StickyData> stickyMonthData;
|
||||
private List<PlayerProfile> players;
|
||||
|
||||
public AnalysisData() {
|
||||
analyzedValues = new HashMap<>();
|
||||
stickyMonthData = new HashSet<>();
|
||||
}
|
||||
|
||||
public void parsePluginsSection(Map<PluginData, AnalysisContainer> containers) {
|
||||
String[] navAndTabs = AnalysisPluginsTabContentCreator.createContent(containers);
|
||||
addValue("navPluginsTabs", navAndTabs[0]);
|
||||
addValue("tabsPlugins", navAndTabs[1]);
|
||||
}
|
||||
|
||||
private void addConstants() {
|
||||
addValue("version", PlanPlugin.getInstance().getVersion());
|
||||
addValue("worldPieColors", Theme.getValue(ThemeVal.GRAPH_WORLD_PIE));
|
||||
addValue("gmPieColors", Theme.getValue(ThemeVal.GRAPH_GM_PIE));
|
||||
addValue("serverName", Settings.SERVER_NAME.toString().replaceAll("[^a-zA-Z0-9_\\s]", "_"));
|
||||
addValue("timeZone", MiscUtils.getTimeZoneOffsetHours());
|
||||
addValue("refresh", FormatUtils.formatTimeStampClock(refreshDate));
|
||||
|
||||
addValue("activityPieColors", Theme.getValue(ThemeVal.GRAPH_ACTIVITY_PIE));
|
||||
addValue("playersGraphColor", Theme.getValue(ThemeVal.GRAPH_PLAYERS_ONLINE));
|
||||
addValue("tpsHighColor", Theme.getValue(ThemeVal.GRAPH_TPS_HIGH));
|
||||
addValue("tpsMediumColor", Theme.getValue(ThemeVal.GRAPH_TPS_MED));
|
||||
addValue("tpsLowColor", Theme.getValue(ThemeVal.GRAPH_TPS_LOW));
|
||||
addValue("worldMapColLow", Theme.getValue(ThemeVal.WORLD_MAP_LOW));
|
||||
addValue("worldMapColHigh", Theme.getValue(ThemeVal.WORLD_MAP_HIGH));
|
||||
addValue("tpsMedium", Settings.THEME_GRAPH_TPS_THRESHOLD_MED.getNumber());
|
||||
addValue("tpsHigh", Settings.THEME_GRAPH_TPS_THRESHOLD_HIGH.getNumber());
|
||||
|
||||
ServerProperties serverProperties = ServerInfo.getServerProperties();
|
||||
addValue("playersMax", serverProperties.getMaxPlayers());
|
||||
addValue("playersOnline", serverProperties.getOnlinePlayers());
|
||||
}
|
||||
|
||||
public void analyze(ServerProfile profile) {
|
||||
long now = System.currentTimeMillis();
|
||||
refreshDate = now;
|
||||
long dayAgo = now - TimeAmount.DAY.ms();
|
||||
long weekAgo = now - TimeAmount.WEEK.ms();
|
||||
long monthAgo = now - TimeAmount.MONTH.ms();
|
||||
|
||||
addConstants();
|
||||
|
||||
got("now", now);
|
||||
got("dayAgo", dayAgo);
|
||||
got("weekAgo", weekAgo);
|
||||
got("monthAgo", monthAgo);
|
||||
|
||||
Map<UUID, List<Session>> sessions = profile.getSessions();
|
||||
List<Session> allSessions = profile.getAllSessions();
|
||||
allSessions.sort(new SessionStartComparator());
|
||||
|
||||
players = profile.getPlayers();
|
||||
List<PlayerProfile> ops = profile.getOps().collect(Collectors.toList());
|
||||
long playersTotal = got("playersTotal", players.size());
|
||||
|
||||
List<TPS> tpsData = profile.getTPSData(0, now).collect(Collectors.toList());
|
||||
List<TPS> tpsDataDay = profile.getTPSData(dayAgo, now).collect(Collectors.toList());
|
||||
List<TPS> tpsDataWeek = profile.getTPSData(weekAgo, now).collect(Collectors.toList());
|
||||
List<TPS> tpsDataMonth = profile.getTPSData(monthAgo, now).collect(Collectors.toList());
|
||||
|
||||
List<String> geoLocations = profile.getGeoLocations();
|
||||
Map<String, Integer> commandUsage = profile.getCommandUsage();
|
||||
|
||||
directProfileVariables(profile);
|
||||
performanceTab(tpsData, tpsDataDay, tpsDataWeek, tpsDataMonth);
|
||||
sessionData(monthAgo, sessions, allSessions);
|
||||
onlineActivityNumbers(profile, sessions, players);
|
||||
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);
|
||||
|
||||
healthTab(now, players, tpsDataMonth);
|
||||
|
||||
long totalPlaytime = profile.getTotalPlaytime();
|
||||
addValue("playtimeTotal", playersTotal != 0 ? FormatUtils.formatTimeAmount(totalPlaytime) : "No Players");
|
||||
addValue("playtimeAverage", playersTotal != 0 ? FormatUtils.formatTimeAmount(MathUtils.averageLong(totalPlaytime, playersTotal)) : "-");
|
||||
}
|
||||
|
||||
private void healthTab(long now, List<PlayerProfile> players, List<TPS> tpsDataMonth) {
|
||||
TreeMap<Long, Map<String, Set<UUID>>> activityData = AnalysisUtils.turnToActivityDataMap(now, players);
|
||||
|
||||
Map<String, Set<UUID>> activityNow = activityData.getOrDefault(now, new HashMap<>());
|
||||
|
||||
ActivityStackGraph activityStackGraph = new ActivityStackGraph(activityData);
|
||||
String activityPieSeries = new ActivityPie(activityNow).toHighChartsSeries();
|
||||
|
||||
addValue("activityStackCategories", activityStackGraph.toHighChartsLabels());
|
||||
addValue("activityStackSeries", activityStackGraph.toHighChartsSeries());
|
||||
addValue("activityPieSeries", activityPieSeries);
|
||||
|
||||
Set<UUID> veryActiveNow = activityNow.getOrDefault("Very Active", new HashSet<>());
|
||||
Set<UUID> activeNow = activityNow.getOrDefault("Active", new HashSet<>());
|
||||
Set<UUID> regularNow = activityNow.getOrDefault("Regular", new HashSet<>());
|
||||
|
||||
addValue("playersRegular", (veryActiveNow.size() + activeNow.size() + regularNow.size()));
|
||||
|
||||
HealthNotes healthNotes = new HealthNotes(this, activityData, tpsDataMonth, now);
|
||||
healthNotes.analyzeHealth();
|
||||
|
||||
addValue("healthNotes", healthNotes.parse());
|
||||
addValue("healthIndex", healthNotes.getServerHealth());
|
||||
}
|
||||
|
||||
private void commandUsage(Map<String, Integer> commandUsage) {
|
||||
addValue("commandUniqueCount", String.valueOf(commandUsage.size()));
|
||||
addValue("commandCount", MathUtils.sumInt(commandUsage.values().stream().map(i -> (int) i)));
|
||||
addValue("tableBodyCommands", new CommandUseTable(commandUsage).parseBody());
|
||||
}
|
||||
|
||||
private void geolocationsTab(List<String> geoLocations) {
|
||||
addValue("geoMapSeries", new WorldMap(geoLocations).toHighChartsSeries());
|
||||
}
|
||||
|
||||
private void onlineActivityNumbers(ServerProfile profile, Map<UUID, List<Session>> sessions, List<PlayerProfile> players) {
|
||||
long now = value("now");
|
||||
long dayAgo = value("dayAgo");
|
||||
long weekAgo = value("weekAgo");
|
||||
long monthAgo = value("monthAgo");
|
||||
|
||||
List<PlayerProfile> newDay = profile.getPlayersWhoRegistered(dayAgo, now).collect(Collectors.toList());
|
||||
List<PlayerProfile> newWeek = profile.getPlayersWhoRegistered(weekAgo, now).collect(Collectors.toList());
|
||||
List<PlayerProfile> newMonth = profile.getPlayersWhoRegistered(monthAgo, now).collect(Collectors.toList());
|
||||
List<PlayerProfile> uniqueDay = profile.getPlayersWhoPlayedBetween(dayAgo, now).collect(Collectors.toList());
|
||||
List<PlayerProfile> uniqueWeek = profile.getPlayersWhoPlayedBetween(weekAgo, now).collect(Collectors.toList());
|
||||
List<PlayerProfile> uniqueMonth = profile.getPlayersWhoPlayedBetween(monthAgo, now).collect(Collectors.toList());
|
||||
|
||||
int uniqD = uniqueDay.size();
|
||||
int uniqW = uniqueWeek.size();
|
||||
int uniqM = uniqueMonth.size();
|
||||
long newD = got("newD", newDay.size());
|
||||
long newW = got("newW", newWeek.size());
|
||||
long newM = got("newM", newMonth.size());
|
||||
long playersTotal = value("playersTotal");
|
||||
|
||||
addValue("playersDay", uniqD);
|
||||
addValue("playersWeek", uniqW);
|
||||
addValue("playersMonth", uniqM);
|
||||
addValue("playersNewDay", newD);
|
||||
addValue("playersNewWeek", newW);
|
||||
addValue("playersNewMonth", newM);
|
||||
|
||||
addValue("playersAverage", AnalysisUtils.getUniqueJoinsPerDay(sessions, -1));
|
||||
addValue("playersAverageDay", AnalysisUtils.getUniqueJoinsPerDay(sessions, dayAgo));
|
||||
addValue("playersAverageWeek", AnalysisUtils.getUniqueJoinsPerDay(sessions, weekAgo));
|
||||
addValue("playersAverageMonth", AnalysisUtils.getUniqueJoinsPerDay(sessions, monthAgo));
|
||||
addValue("playersNewAverage", AnalysisUtils.getNewUsersPerDay(toRegistered(players), -1, playersTotal));
|
||||
addValue("playersNewAverageDay", AnalysisUtils.getNewUsersPerDay(toRegistered(newDay), -1, newD));
|
||||
addValue("playersNewAverageWeek", AnalysisUtils.getNewUsersPerDay(toRegistered(newWeek), -1, newW));
|
||||
addValue("playersNewAverageMonth", AnalysisUtils.getNewUsersPerDay(toRegistered(newMonth), -1, newM));
|
||||
|
||||
stickiness(now, weekAgo, monthAgo, newDay, newWeek, newMonth);
|
||||
}
|
||||
|
||||
private void stickiness(long now, long weekAgo, long monthAgo,
|
||||
List<PlayerProfile> newDay, List<PlayerProfile> newWeek, List<PlayerProfile> newMonth) {
|
||||
long newD = value("newD");
|
||||
long newW = value("newW");
|
||||
long newM = value("newM");
|
||||
|
||||
List<PlayerProfile> playersStuckPerMonth = newMonth.stream()
|
||||
.filter(p -> {
|
||||
long backLimit = Math.max(monthAgo, p.getRegistered());
|
||||
long half = backLimit + ((now - backLimit) / 2L);
|
||||
return p.playedBetween(backLimit, half) && p.playedBetween(half, now);
|
||||
})
|
||||
.collect(Collectors.toList());
|
||||
List<PlayerProfile> playersStuckPerWeek = newWeek.stream()
|
||||
.filter(p -> {
|
||||
long backLimit = Math.max(weekAgo, p.getRegistered());
|
||||
long half = backLimit + ((now - backLimit) / 2L);
|
||||
return p.playedBetween(backLimit, half) && p.playedBetween(half, now);
|
||||
})
|
||||
.collect(Collectors.toList());
|
||||
|
||||
int stuckPerM = playersStuckPerMonth.size();
|
||||
int stuckPerW = playersStuckPerWeek.size();
|
||||
got("stuckPerM", stuckPerM);
|
||||
got("stuckPerW", stuckPerW);
|
||||
|
||||
stickyMonthData = newMonth.stream().map(StickyData::new).distinct().collect(Collectors.toSet());
|
||||
|
||||
addValue("playersStuckMonth", stuckPerM);
|
||||
addValue("playersStuckWeek", stuckPerW);
|
||||
addValue("playersStuckPercMonth", newM != 0 ? FormatUtils.cutDecimals(MathUtils.averageDouble(stuckPerM, newM) * 100.0) + "%" : "-");
|
||||
addValue("playersStuckPercWeek", newW != 0 ? FormatUtils.cutDecimals(MathUtils.averageDouble(stuckPerW, newW) * 100.0) + "%" : "-");
|
||||
|
||||
stuckPerDay(newDay, newD, monthAgo);
|
||||
}
|
||||
|
||||
private void stuckPerDay(List<PlayerProfile> newDay, long newD, long monthAgo) {
|
||||
if (newD != 0) {
|
||||
List<PlayerProfile> stuckAfterMonth = new ArrayList<>();
|
||||
List<PlayerProfile> notStuckAfterMonth = new ArrayList<>();
|
||||
|
||||
for (PlayerProfile player : players) {
|
||||
long registered = player.getRegistered();
|
||||
|
||||
// Discard uncertain data
|
||||
if (registered > monthAgo) {
|
||||
continue;
|
||||
}
|
||||
|
||||
long monthAfterRegister = registered + TimeAmount.MONTH.ms();
|
||||
long half = registered + (TimeAmount.MONTH.ms() / 2L);
|
||||
if (player.playedBetween(registered, half) && player.playedBetween(half, monthAfterRegister)) {
|
||||
stuckAfterMonth.add(player);
|
||||
} else {
|
||||
notStuckAfterMonth.add(player);
|
||||
}
|
||||
}
|
||||
|
||||
if (stuckAfterMonth.isEmpty() || notStuckAfterMonth.isEmpty()) {
|
||||
addValue("playersStuckDay", 0);
|
||||
addValue("playersStuckPercDay", "Not enough data");
|
||||
return;
|
||||
}
|
||||
|
||||
List<StickyData> stuck = stuckAfterMonth.stream().map(StickyData::new).collect(Collectors.toList());
|
||||
List<StickyData> nonStuck = notStuckAfterMonth.stream().map(StickyData::new).collect(Collectors.toList());
|
||||
|
||||
StickyData avgStuck = AnalysisUtils.average(stuck);
|
||||
StickyData avgNonStuck = AnalysisUtils.average(nonStuck);
|
||||
|
||||
int stuckPerD = 0;
|
||||
for (PlayerProfile player : newDay) {
|
||||
StickyData stickyData = new StickyData(player);
|
||||
if (stickyData.distance(avgStuck) < stickyData.distance(avgNonStuck)) {
|
||||
stuckPerD++;
|
||||
}
|
||||
}
|
||||
|
||||
addValue("playersStuckDay", stuckPerD);
|
||||
addValue("playersStuckPercDay", FormatUtils.cutDecimals(MathUtils.averageDouble(stuckPerD, newD) * 100.0) + "%");
|
||||
} else {
|
||||
addValue("playersStuckDay", 0);
|
||||
addValue("playersStuckPercDay", "-");
|
||||
}
|
||||
}
|
||||
|
||||
private List<Long> toRegistered(List<PlayerProfile> players) {
|
||||
return players.stream().map(PlayerProfile::getRegistered).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
private void sessionData(long monthAgo, Map<UUID, List<Session>> sessions, List<Session> allSessions) {
|
||||
List<Session> sessionsMonth = allSessions.stream()
|
||||
.filter(s -> s.getSessionStart() >= monthAgo)
|
||||
.collect(Collectors.toList());
|
||||
String[] tables = SessionsTableCreator.createTable(sessions, allSessions);
|
||||
String[] sessionContent = SessionTabStructureCreator.createStructure(sessions, allSessions);
|
||||
|
||||
addValue("sessionCount", allSessions.size());
|
||||
addValue("accordionSessions", sessionContent[0]);
|
||||
addValue("sessionTabGraphViewFunctions", sessionContent[1]);
|
||||
addValue("tableBodySessions", tables[0]);
|
||||
addValue("listRecentLogins", tables[1]);
|
||||
addValue("sessionAverage", FormatUtils.formatTimeAmount(MathUtils.averageLong(allSessions.stream().map(Session::getLength))));
|
||||
addValue("punchCardSeries", new PunchCardGraph(sessionsMonth).toHighChartsSeries());
|
||||
|
||||
addValue("deaths", ServerProfile.getDeathCount(allSessions));
|
||||
addValue("mobKillCount", ServerProfile.getMobKillCount(allSessions));
|
||||
addValue("killCount", ServerProfile.getPlayerKills(allSessions).size());
|
||||
}
|
||||
|
||||
private void directProfileVariables(ServerProfile profile) {
|
||||
WorldTimes worldTimes = profile.getServerWorldtimes();
|
||||
long allTimePeak = profile.getAllTimePeak();
|
||||
long lastPeak = profile.getLastPeakDate();
|
||||
|
||||
String playersTableBody = profile.createPlayersTableBody();
|
||||
addValue("tablePlayerlist", Settings.PLAYERTABLE_FOOTER.isTrue() ?
|
||||
Html.TABLE_PLAYERS_FOOTER.parse(playersTableBody)
|
||||
: Html.TABLE_PLAYERS.parse(playersTableBody));
|
||||
addValue("worldTotal", FormatUtils.formatTimeAmount(worldTimes.getTotal()));
|
||||
WorldPie worldPie = new WorldPie(worldTimes);
|
||||
addValue("worldSeries", worldPie.toHighChartsSeries());
|
||||
addValue("gmSeries", worldPie.toHighChartsDrilldown());
|
||||
addValue("lastPeakTime", lastPeak != -1 ? FormatUtils.formatTimeStampYear(lastPeak) : "No Data");
|
||||
addValue("playersLastPeak", lastPeak != -1 ? profile.getLastPeakPlayers() : "-");
|
||||
addValue("bestPeakTime", allTimePeak != -1 ? FormatUtils.formatTimeStampYear(allTimePeak) : "No Data");
|
||||
addValue("playersBestPeak", allTimePeak != -1 ? profile.getAllTimePeakPlayers() : "-");
|
||||
}
|
||||
|
||||
private void performanceTab(List<TPS> tpsData, List<TPS> tpsDataDay, List<TPS> tpsDataWeek, List<TPS> tpsDataMonth) {
|
||||
got("tpsSpikeMonth", ServerProfile.getLowSpikeCount(tpsDataMonth));
|
||||
got("tpsSpikeWeek", ServerProfile.getLowSpikeCount(tpsDataWeek));
|
||||
got("tpsSpikeDay", ServerProfile.getLowSpikeCount(tpsDataDay));
|
||||
addValue("tpsSpikeMonth", value("tpsSpikeMonth"));
|
||||
addValue("tpsSpikeWeek", value("tpsSpikeWeek"));
|
||||
addValue("tpsSpikeDay", value("tpsSpikeDay"));
|
||||
|
||||
addValue("playersOnlineSeries", new OnlineActivityGraph(tpsData).toHighChartsSeries());
|
||||
addValue("tpsSeries", new TPSGraph(tpsData).toHighChartsSeries());
|
||||
addValue("cpuSeries", new CPUGraph(tpsData).toHighChartsSeries());
|
||||
addValue("ramSeries", new RamGraph(tpsData).toHighChartsSeries());
|
||||
addValue("entitySeries", new EntityGraph(tpsData).toHighChartsSeries());
|
||||
addValue("chunkSeries", new ChunkGraph(tpsData).toHighChartsSeries());
|
||||
|
||||
double averageCPUMonth = MathUtils.averageDouble(tpsDataMonth.stream().map(TPS::getCPUUsage).filter(i -> i != 0));
|
||||
double averageCPUWeek = MathUtils.averageDouble(tpsDataWeek.stream().map(TPS::getCPUUsage).filter(i -> i != 0));
|
||||
double averageCPUDay = MathUtils.averageDouble(tpsDataDay.stream().map(TPS::getCPUUsage).filter(i -> i != 0));
|
||||
|
||||
addValue("tpsAverageMonth", FormatUtils.cutDecimals(MathUtils.averageDouble(tpsDataMonth.stream().map(TPS::getTicksPerSecond))));
|
||||
addValue("tpsAverageWeek", FormatUtils.cutDecimals(MathUtils.averageDouble(tpsDataWeek.stream().map(TPS::getTicksPerSecond))));
|
||||
addValue("tpsAverageDay", FormatUtils.cutDecimals(MathUtils.averageDouble(tpsDataDay.stream().map(TPS::getTicksPerSecond))));
|
||||
|
||||
addValue("cpuAverageMonth", averageCPUMonth >= 0 ? FormatUtils.cutDecimals(averageCPUMonth) + "%" : "Unavailable");
|
||||
addValue("cpuAverageWeek", averageCPUWeek >= 0 ? FormatUtils.cutDecimals(averageCPUWeek) + "%" : "Unavailable");
|
||||
addValue("cpuAverageDay", averageCPUDay >= 0 ? FormatUtils.cutDecimals(averageCPUDay) + "%" : "Unavailable");
|
||||
|
||||
addValue("ramAverageMonth", FormatUtils.cutDecimals(MathUtils.averageLong(tpsDataMonth.stream().map(TPS::getUsedMemory).filter(i -> i != 0))));
|
||||
addValue("ramAverageWeek", FormatUtils.cutDecimals(MathUtils.averageLong(tpsDataWeek.stream().map(TPS::getUsedMemory).filter(i -> i != 0))));
|
||||
addValue("ramAverageDay", FormatUtils.cutDecimals(MathUtils.averageLong(tpsDataDay.stream().map(TPS::getUsedMemory).filter(i -> i != 0))));
|
||||
|
||||
addValue("entityAverageMonth", FormatUtils.cutDecimals(MathUtils.averageInt(tpsDataMonth.stream().map(TPS::getEntityCount).filter(i -> i != 0))));
|
||||
addValue("entityAverageWeek", FormatUtils.cutDecimals(MathUtils.averageInt(tpsDataWeek.stream().map(TPS::getEntityCount).filter(i -> i != 0))));
|
||||
addValue("entityAverageDay", FormatUtils.cutDecimals(MathUtils.averageInt(tpsDataDay.stream().map(TPS::getEntityCount).filter(i -> i != 0))));
|
||||
|
||||
addValue("chunkAverageMonth", FormatUtils.cutDecimals(MathUtils.averageInt(tpsDataMonth.stream().map(TPS::getChunksLoaded).filter(i -> i != 0))));
|
||||
addValue("chunkAverageWeek", FormatUtils.cutDecimals(MathUtils.averageInt(tpsDataWeek.stream().map(TPS::getChunksLoaded).filter(i -> i != 0))));
|
||||
addValue("chunkAverageDay", FormatUtils.cutDecimals(MathUtils.averageInt(tpsDataDay.stream().map(TPS::getChunksLoaded).filter(i -> i != 0))));
|
||||
}
|
||||
|
||||
private long got(String key, long v) {
|
||||
analyzedValues.put(key, v);
|
||||
return v;
|
||||
}
|
||||
|
||||
public long value(String key) {
|
||||
return analyzedValues.getOrDefault(key, 0L);
|
||||
}
|
||||
|
||||
public Set<StickyData> getStickyMonthData() {
|
||||
return stickyMonthData;
|
||||
}
|
||||
|
||||
public List<PlayerProfile> getPlayers() {
|
||||
return players;
|
||||
}
|
||||
}
|
@ -1,64 +0,0 @@
|
||||
package com.djrapitops.plan.data.calculation;
|
||||
|
||||
import com.djrapitops.plugin.utilities.Verify;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Extending objects should represent, add together and analyse data.
|
||||
*
|
||||
* @author Rsl1122
|
||||
* @since 3.5.2
|
||||
*/
|
||||
public abstract class RawData {
|
||||
|
||||
private final Map<String, Serializable> replaceMap;
|
||||
|
||||
/**
|
||||
* Only used by subclasses.
|
||||
*/
|
||||
public RawData() {
|
||||
replaceMap = new HashMap<>();
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds values from an existing replaceMap.
|
||||
*
|
||||
* @param values Map that contains place-holders.
|
||||
*/
|
||||
public void addValues(Map<String, Serializable> values) {
|
||||
Verify.nullCheck(values);
|
||||
replaceMap.putAll(values);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a placeholder to the replaceMap.
|
||||
*
|
||||
* @param placeholder placeholder, without prefix and suffix
|
||||
* @param value Any value the placeholder should be replaced with.
|
||||
*/
|
||||
public void addValue(String placeholder, Serializable value) {
|
||||
replaceMap.put(placeholder, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to get the placeholders and values.
|
||||
*
|
||||
* @return Map containing the placeholders and values.
|
||||
*/
|
||||
public Map<String, Serializable> getReplaceMap() {
|
||||
return replaceMap;
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to get the value for a placeholder without the placeholder prefix and suffix.
|
||||
*
|
||||
* @param key placeholder name without ${ and }
|
||||
* @return Value the placeholder should be replaced with or null.
|
||||
*/
|
||||
public Serializable get(String key) {
|
||||
return replaceMap.get(key);
|
||||
}
|
||||
}
|
@ -1,78 +0,0 @@
|
||||
/*
|
||||
* License is provided in the jar as LICENSE also here:
|
||||
* https://github.com/Rsl1122/Plan-PlayerAnalytics/blob/master/Plan/src/main/resources/LICENSE
|
||||
*/
|
||||
package com.djrapitops.plan.data.container;
|
||||
|
||||
import com.djrapitops.plan.data.Actions;
|
||||
import com.djrapitops.plan.utilities.FormatUtils;
|
||||
import com.djrapitops.plan.utilities.html.Html;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* Class that represents an action made by a player.
|
||||
*
|
||||
* @author Rsl1122
|
||||
*/
|
||||
public class Action {
|
||||
private final long date;
|
||||
private final Actions doneAction;
|
||||
private final String additionalInfo;
|
||||
private int serverID;
|
||||
|
||||
public Action(long date, Actions doneAction, String additionalInfo) {
|
||||
this.date = date;
|
||||
this.doneAction = doneAction;
|
||||
this.additionalInfo = additionalInfo;
|
||||
}
|
||||
|
||||
public Action(long date, Actions doneAction, String additionalInfo, int serverID) {
|
||||
this.date = date;
|
||||
this.doneAction = doneAction;
|
||||
this.additionalInfo = additionalInfo;
|
||||
this.serverID = serverID;
|
||||
}
|
||||
|
||||
public long getDate() {
|
||||
return date;
|
||||
}
|
||||
|
||||
public Actions getDoneAction() {
|
||||
return doneAction;
|
||||
}
|
||||
|
||||
public String getAdditionalInfo() {
|
||||
return additionalInfo;
|
||||
}
|
||||
|
||||
/**
|
||||
* Can only be used on Action classes returned by the ActionsTable.
|
||||
*
|
||||
* @return ID of the server the action occurred on.
|
||||
*/
|
||||
public int getServerID() {
|
||||
return serverID;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
Action action = (Action) o;
|
||||
return date == action.date &&
|
||||
serverID == action.serverID &&
|
||||
doneAction == action.doneAction &&
|
||||
Objects.equals(additionalInfo, action.additionalInfo);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(date, doneAction, additionalInfo, serverID);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return Html.TABLELINE_3.parse(FormatUtils.formatTimeStampYear(date), doneAction.toString(), additionalInfo);
|
||||
}
|
||||
}
|
@ -4,6 +4,8 @@
|
||||
*/
|
||||
package com.djrapitops.plan.data.container;
|
||||
|
||||
import com.djrapitops.plan.data.store.objects.DateHolder;
|
||||
import com.djrapitops.plan.data.store.objects.DateMap;
|
||||
import com.djrapitops.plan.utilities.FormatUtils;
|
||||
import com.djrapitops.plan.utilities.SHA256Hash;
|
||||
import com.google.common.base.Objects;
|
||||
@ -17,25 +19,33 @@ import java.security.NoSuchAlgorithmException;
|
||||
*
|
||||
* @author Rsl1122
|
||||
*/
|
||||
public class GeoInfo {
|
||||
public class GeoInfo implements DateHolder {
|
||||
|
||||
private final String ip;
|
||||
private final String geolocation;
|
||||
private final String ipHash;
|
||||
private final long lastUsed;
|
||||
private final long date;
|
||||
|
||||
public GeoInfo(InetAddress address, String geolocation, long lastUsed)
|
||||
throws UnsupportedEncodingException, NoSuchAlgorithmException {
|
||||
this(FormatUtils.formatIP(address), geolocation, lastUsed, new SHA256Hash(address.getHostAddress()).create());
|
||||
}
|
||||
|
||||
public GeoInfo(String ip, String geolocation, long lastUsed, String ipHash) {
|
||||
public GeoInfo(String ip, String geolocation, long date, String ipHash) {
|
||||
this.ip = ip;
|
||||
this.geolocation = geolocation;
|
||||
this.lastUsed = lastUsed;
|
||||
this.date = date;
|
||||
this.ipHash = ipHash;
|
||||
}
|
||||
|
||||
public static DateMap<GeoInfo> intoDateMap(Iterable<GeoInfo> geoInfo) {
|
||||
DateMap<GeoInfo> map = new DateMap<>();
|
||||
for (GeoInfo info : geoInfo) {
|
||||
map.put(info.date, info);
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
public String getIp() {
|
||||
return ip;
|
||||
}
|
||||
@ -44,8 +54,9 @@ public class GeoInfo {
|
||||
return geolocation;
|
||||
}
|
||||
|
||||
public long getLastUsed() {
|
||||
return lastUsed;
|
||||
@Override
|
||||
public long getDate() {
|
||||
return date;
|
||||
}
|
||||
|
||||
public String getIpHash() {
|
||||
@ -58,11 +69,22 @@ public class GeoInfo {
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
GeoInfo geoInfo = (GeoInfo) o;
|
||||
return Objects.equal(ip, geoInfo.ip) &&
|
||||
Objects.equal(geolocation, geoInfo.geolocation);
|
||||
Objects.equal(geolocation, geoInfo.geolocation) &&
|
||||
Objects.equal(ipHash, geoInfo.ipHash);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hashCode(ip, geolocation);
|
||||
return Objects.hashCode(ip, geolocation, ipHash);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "GeoInfo{" +
|
||||
"ip='" + ip + '\'' +
|
||||
", geolocation='" + geolocation + '\'' +
|
||||
", ipHash='" + ipHash + '\'' +
|
||||
", date=" + date +
|
||||
'}';
|
||||
}
|
||||
}
|
@ -1,7 +1,6 @@
|
||||
package com.djrapitops.plan.data.container;
|
||||
|
||||
import com.djrapitops.plan.data.Actions;
|
||||
import com.djrapitops.plan.system.cache.DataCache;
|
||||
import com.djrapitops.plan.data.store.objects.DateHolder;
|
||||
|
||||
import java.util.Objects;
|
||||
import java.util.UUID;
|
||||
@ -12,10 +11,10 @@ import java.util.UUID;
|
||||
*
|
||||
* @author Rsl1122
|
||||
*/
|
||||
public class PlayerKill {
|
||||
public class PlayerKill implements DateHolder {
|
||||
|
||||
private final UUID victim;
|
||||
private final long time;
|
||||
private final long date;
|
||||
private final String weapon;
|
||||
|
||||
/**
|
||||
@ -23,12 +22,12 @@ public class PlayerKill {
|
||||
*
|
||||
* @param victim UUID of the victim.
|
||||
* @param weapon Weapon used.
|
||||
* @param time Epoch millisecond at which the kill occurred.
|
||||
* @param date Epoch millisecond at which the kill occurred.
|
||||
*/
|
||||
public PlayerKill(UUID victim, String weapon, long time) {
|
||||
public PlayerKill(UUID victim, String weapon, long date) {
|
||||
this.victim = victim;
|
||||
this.weapon = weapon;
|
||||
this.time = time;
|
||||
this.date = date;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -40,13 +39,9 @@ public class PlayerKill {
|
||||
return victim;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the Epoch millisecond the kill occurred.
|
||||
*
|
||||
* @return long in ms.
|
||||
*/
|
||||
public long getTime() {
|
||||
return time;
|
||||
@Override
|
||||
public long getDate() {
|
||||
return date;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -58,31 +53,26 @@ public class PlayerKill {
|
||||
return weapon;
|
||||
}
|
||||
|
||||
public Action convertToAction() {
|
||||
String name = DataCache.getInstance().getName(victim);
|
||||
return new Action(time, Actions.KILLED, name + " with " + weapon);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
PlayerKill that = (PlayerKill) o;
|
||||
return time == that.time &&
|
||||
return date == that.date &&
|
||||
Objects.equals(victim, that.victim) &&
|
||||
Objects.equals(weapon, that.weapon);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(victim, time, weapon);
|
||||
return Objects.hash(victim, date, weapon);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "PlayerKill{" +
|
||||
"victim=" + victim + ", " +
|
||||
"time=" + time + ", " +
|
||||
"date=" + date + ", " +
|
||||
"weapon='" + weapon + "'}";
|
||||
}
|
||||
}
|
||||
|
@ -1,77 +1,100 @@
|
||||
package com.djrapitops.plan.data.container;
|
||||
|
||||
import com.djrapitops.plan.data.store.containers.DataContainer;
|
||||
import com.djrapitops.plan.data.store.keys.SessionKeys;
|
||||
import com.djrapitops.plan.data.store.objects.DateHolder;
|
||||
import com.djrapitops.plan.data.time.WorldTimes;
|
||||
import com.djrapitops.plan.system.info.server.ServerInfo;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* Object for storing various information about a player's play session.
|
||||
* <p>
|
||||
* Includes:
|
||||
* <ul>
|
||||
* <li>World and GameMode playtimes</li>
|
||||
* <li>Player and Mob kills</li>
|
||||
* <li>Deaths</li>
|
||||
* </ul>
|
||||
* <p>
|
||||
* Following data can be derived from Sessions in the database (Between any time span):
|
||||
* <ul>
|
||||
* <li>Playtime</li>
|
||||
* <li>LoginTimes</li>
|
||||
* </ul>
|
||||
* DataContainer for information about a player's play session.
|
||||
*
|
||||
* @author Rsl1122
|
||||
* @see SessionKeys for Key objects.
|
||||
*/
|
||||
public class Session {
|
||||
public class Session extends DataContainer implements DateHolder {
|
||||
|
||||
private final long sessionStart;
|
||||
private Integer sessionID;
|
||||
private WorldTimes worldTimes;
|
||||
private long sessionEnd;
|
||||
private List<PlayerKill> playerKills;
|
||||
private int mobKills;
|
||||
private int deaths;
|
||||
|
||||
private long afkTime;
|
||||
|
||||
/**
|
||||
* Creates a new session with given start and end of -1.
|
||||
* Creates a new session.
|
||||
*
|
||||
* @param sessionStart Epoch millisecond the session was started.
|
||||
* @param uuid UUID of the Player.
|
||||
* @param sessionStart Epoch ms the session started.
|
||||
* @param world Starting world.
|
||||
* @param gm Starting GameMode.
|
||||
*/
|
||||
public Session(long sessionStart, String world, String gm) {
|
||||
this.worldTimes = new WorldTimes(world, gm);
|
||||
this.sessionStart = sessionStart;
|
||||
this.sessionEnd = -1;
|
||||
playerKills = new ArrayList<>();
|
||||
public Session(UUID uuid, long sessionStart, String world, String gm) {
|
||||
mobKills = 0;
|
||||
deaths = 0;
|
||||
afkTime = 0;
|
||||
|
||||
putRawData(SessionKeys.UUID, uuid);
|
||||
putRawData(SessionKeys.START, sessionStart);
|
||||
putRawData(SessionKeys.WORLD_TIMES, new WorldTimes(world, gm));
|
||||
putRawData(SessionKeys.PLAYER_KILLS, new ArrayList<>());
|
||||
putSupplier(SessionKeys.MOB_KILL_COUNT, () -> mobKills);
|
||||
putSupplier(SessionKeys.DEATH_COUNT, () -> deaths);
|
||||
putSupplier(SessionKeys.AFK_TIME, () -> afkTime);
|
||||
|
||||
putSupplier(SessionKeys.PLAYER_KILL_COUNT, getUnsafe(SessionKeys.PLAYER_KILLS)::size);
|
||||
putSupplier(SessionKeys.LENGTH, () ->
|
||||
getValue(SessionKeys.END).orElse(System.currentTimeMillis()) - getUnsafe(SessionKeys.START));
|
||||
putSupplier(SessionKeys.ACTIVE_TIME, () -> getUnsafe(SessionKeys.LENGTH) - getUnsafe(SessionKeys.AFK_TIME));
|
||||
putSupplier(SessionKeys.SERVER_UUID, ServerInfo::getServerUUID);
|
||||
}
|
||||
|
||||
public Session(int id, long sessionStart, long sessionEnd, int mobKills, int deaths, long afkTime) {
|
||||
this.sessionID = id;
|
||||
this.sessionStart = sessionStart;
|
||||
this.sessionEnd = sessionEnd;
|
||||
this.worldTimes = new WorldTimes(new HashMap<>());
|
||||
this.playerKills = new ArrayList<>();
|
||||
/**
|
||||
* Recreates a Session found in the database.
|
||||
* <p>
|
||||
* WorldTimes and Player kills need to be set separately.
|
||||
*
|
||||
* @param id ID in the database (Used for fetching world times and player kills.
|
||||
* @param uuid UUID of the Player.
|
||||
* @param serverUUID UUID of the Server.
|
||||
* @param sessionStart Epoch ms the session started.
|
||||
* @param sessionEnd Epoch ms the session ended.
|
||||
* @param mobKills Mobs killed during the session.
|
||||
* @param deaths Death count during the session.
|
||||
* @param afkTime Time spent AFK during the session.
|
||||
*/
|
||||
public Session(int id, UUID uuid, UUID serverUUID, long sessionStart, long sessionEnd, int mobKills, int deaths, long afkTime) {
|
||||
putRawData(SessionKeys.DB_ID, id);
|
||||
putRawData(SessionKeys.UUID, uuid);
|
||||
putRawData(SessionKeys.SERVER_UUID, serverUUID);
|
||||
putRawData(SessionKeys.START, sessionStart);
|
||||
putRawData(SessionKeys.END, sessionEnd);
|
||||
putRawData(SessionKeys.WORLD_TIMES, new WorldTimes(new HashMap<>()));
|
||||
putRawData(SessionKeys.PLAYER_KILLS, new ArrayList<>());
|
||||
putSupplier(SessionKeys.MOB_KILL_COUNT, () -> mobKills);
|
||||
putSupplier(SessionKeys.DEATH_COUNT, () -> deaths);
|
||||
putSupplier(SessionKeys.AFK_TIME, () -> afkTime);
|
||||
|
||||
this.mobKills = mobKills;
|
||||
this.deaths = deaths;
|
||||
this.afkTime = afkTime;
|
||||
|
||||
putSupplier(SessionKeys.PLAYER_KILL_COUNT, () -> getUnsafe(SessionKeys.PLAYER_KILLS).size());
|
||||
putSupplier(SessionKeys.LENGTH, () ->
|
||||
getValue(SessionKeys.END).orElse(System.currentTimeMillis()) - getUnsafe(SessionKeys.START));
|
||||
putSupplier(SessionKeys.ACTIVE_TIME, () -> getUnsafe(SessionKeys.LENGTH) - getUnsafe(SessionKeys.AFK_TIME));
|
||||
}
|
||||
|
||||
/**
|
||||
* Ends the session with given end point.
|
||||
* <p>
|
||||
* (Changes the end to the parameter.).
|
||||
* Updates world times to the latest value.
|
||||
*
|
||||
* @param endOfSession Epoch millisecond the session ended.
|
||||
*/
|
||||
public void endSession(long endOfSession) {
|
||||
sessionEnd = endOfSession;
|
||||
putRawData(SessionKeys.END, endOfSession);
|
||||
WorldTimes worldTimes = getValue(SessionKeys.WORLD_TIMES)
|
||||
.orElseThrow(() -> new IllegalStateException("World times have not been defined"));
|
||||
worldTimes.updateState(endOfSession);
|
||||
}
|
||||
|
||||
@ -83,10 +106,14 @@ public class Session {
|
||||
* @param time Epoch ms of the event.
|
||||
*/
|
||||
public void changeState(String world, String gm, long time) {
|
||||
WorldTimes worldTimes = getValue(SessionKeys.WORLD_TIMES)
|
||||
.orElseThrow(() -> new IllegalStateException("World times is not defined"));
|
||||
worldTimes.updateState(world, gm, time);
|
||||
}
|
||||
|
||||
public void playerKilled(PlayerKill kill) {
|
||||
List<PlayerKill> playerKills = getValue(SessionKeys.PLAYER_KILLS)
|
||||
.orElseThrow(() -> new IllegalStateException("Player kills is not defined."));
|
||||
playerKills.add(kill);
|
||||
}
|
||||
|
||||
@ -104,10 +131,12 @@ public class Session {
|
||||
* @return Long in ms.
|
||||
*/
|
||||
public long getLength() {
|
||||
if (sessionEnd == -1) {
|
||||
return System.currentTimeMillis() - sessionStart;
|
||||
}
|
||||
return sessionEnd - sessionStart;
|
||||
return getValue(SessionKeys.LENGTH).orElse(0L);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getDate() {
|
||||
return getUnsafe(SessionKeys.START);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -115,8 +144,9 @@ public class Session {
|
||||
*
|
||||
* @return Epoch millisecond the session started.
|
||||
*/
|
||||
@Deprecated
|
||||
public long getSessionStart() {
|
||||
return sessionStart;
|
||||
return getUnsafe(SessionKeys.START);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -124,46 +154,53 @@ public class Session {
|
||||
*
|
||||
* @return Epoch millisecond the session ended.
|
||||
*/
|
||||
@Deprecated
|
||||
public long getSessionEnd() {
|
||||
return sessionEnd;
|
||||
return getValue(SessionKeys.END).orElse(-1L);
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public WorldTimes getWorldTimes() {
|
||||
return worldTimes;
|
||||
return getValue(SessionKeys.WORLD_TIMES).orElse(null);
|
||||
}
|
||||
|
||||
public void setWorldTimes(WorldTimes worldTimes) {
|
||||
this.worldTimes = worldTimes;
|
||||
putRawData(SessionKeys.WORLD_TIMES, worldTimes);
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public List<PlayerKill> getPlayerKills() {
|
||||
return playerKills;
|
||||
return getValue(SessionKeys.PLAYER_KILLS).orElse(new ArrayList<>());
|
||||
}
|
||||
|
||||
public void setPlayerKills(List<PlayerKill> playerKills) {
|
||||
this.playerKills = playerKills;
|
||||
putRawData(SessionKeys.PLAYER_KILLS, playerKills);
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public int getMobKills() {
|
||||
return mobKills;
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public int getDeaths() {
|
||||
return deaths;
|
||||
}
|
||||
|
||||
public boolean isFetchedFromDB() {
|
||||
return sessionID != null;
|
||||
return supports(SessionKeys.DB_ID);
|
||||
}
|
||||
|
||||
public void addAFKTime(long timeAFK) {
|
||||
afkTime += timeAFK;
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public long getAfkLength() {
|
||||
return afkTime;
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public long getActiveLength() {
|
||||
return getLength() - getAfkLength();
|
||||
}
|
||||
@ -174,12 +211,13 @@ public class Session {
|
||||
* @return ID if present.
|
||||
* @throws NullPointerException if Session was not fetched from DB. Check {@code isFetchedFromDB} first.
|
||||
*/
|
||||
@Deprecated
|
||||
public int getSessionID() {
|
||||
return sessionID != null ? sessionID : -1;
|
||||
return getValue(SessionKeys.DB_ID).orElseThrow(() -> new NullPointerException("Session not fetched from DB."));
|
||||
}
|
||||
|
||||
public void setSessionID(int sessionID) {
|
||||
this.sessionID = sessionID;
|
||||
putRawData(SessionKeys.DB_ID, sessionID);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -187,28 +225,17 @@ public class Session {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
Session session = (Session) o;
|
||||
return sessionStart == session.sessionStart &&
|
||||
sessionEnd == session.sessionEnd &&
|
||||
return getUnsafe(SessionKeys.START).equals(session.getUnsafe(SessionKeys.START)) &&
|
||||
getValue(SessionKeys.END).orElse(-1L).equals(session.getValue(SessionKeys.END).orElse(-1L)) &&
|
||||
mobKills == session.mobKills &&
|
||||
deaths == session.deaths &&
|
||||
Objects.equals(worldTimes, session.worldTimes) &&
|
||||
Objects.equals(playerKills, session.playerKills);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(sessionStart, sessionID, worldTimes, sessionEnd, playerKills, mobKills, deaths);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Session{" +
|
||||
"sessionStart=" + sessionStart + ", " +
|
||||
"sessionID=" + sessionID + ", " +
|
||||
"worldTimes=" + worldTimes + ", " +
|
||||
"sessionEnd=" + sessionEnd + ", " +
|
||||
"playerKills=" + playerKills + ", " +
|
||||
"mobKills=" + mobKills + ", " +
|
||||
"deaths=" + deaths + '}';
|
||||
Objects.equals(
|
||||
getValue(SessionKeys.WORLD_TIMES).orElse(null),
|
||||
session.getValue(SessionKeys.WORLD_TIMES).orElse(null)
|
||||
) &&
|
||||
Objects.equals(
|
||||
getValue(SessionKeys.PLAYER_KILLS).orElse(new ArrayList<>()),
|
||||
session.getValue(SessionKeys.PLAYER_KILLS).orElse(new ArrayList<>())
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -1,108 +0,0 @@
|
||||
/*
|
||||
* License is provided in the jar as LICENSE also here:
|
||||
* https://github.com/Rsl1122/Plan-PlayerAnalytics/blob/master/Plan/src/main/resources/LICENSE
|
||||
*/
|
||||
package com.djrapitops.plan.data.container;
|
||||
|
||||
import com.djrapitops.plan.data.Actions;
|
||||
import com.djrapitops.plan.data.PlayerProfile;
|
||||
import com.djrapitops.plugin.api.TimeAmount;
|
||||
import com.google.common.base.Objects;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class StickyData {
|
||||
private final double activityIndex;
|
||||
private Double messagesSent;
|
||||
private Double onlineOnJoin;
|
||||
|
||||
public StickyData(PlayerProfile player) {
|
||||
activityIndex = player.getActivityIndex(player.getRegistered() + TimeAmount.DAY.ms()).getValue();
|
||||
loadActionVariables(player.getActions());
|
||||
}
|
||||
|
||||
public StickyData(double activityIndex, Double messagesSent, Double onlineOnJoin) {
|
||||
this.activityIndex = activityIndex;
|
||||
this.messagesSent = messagesSent;
|
||||
this.onlineOnJoin = onlineOnJoin;
|
||||
}
|
||||
|
||||
private void loadActionVariables(List<Action> actions) {
|
||||
for (Action action : actions) {
|
||||
try {
|
||||
if (messagesSent == null && action.getDoneAction() == Actions.FIRST_LOGOUT) {
|
||||
messagesSent = (double) loadSentMessages(action);
|
||||
}
|
||||
if (onlineOnJoin == null && action.getDoneAction() == Actions.FIRST_SESSION) {
|
||||
onlineOnJoin = (double) loadOnlineOnJoin(action);
|
||||
}
|
||||
} catch (IllegalArgumentException ignore) {
|
||||
/* continue */
|
||||
}
|
||||
}
|
||||
setDefaultValuesIfNull();
|
||||
}
|
||||
|
||||
private void setDefaultValuesIfNull() {
|
||||
if (messagesSent == null) {
|
||||
messagesSent = 0.0;
|
||||
}
|
||||
if (onlineOnJoin == null) {
|
||||
onlineOnJoin = 0.0;
|
||||
}
|
||||
}
|
||||
|
||||
private int loadOnlineOnJoin(Action action) {
|
||||
String additionalInfo = action.getAdditionalInfo();
|
||||
String[] split = additionalInfo.split(" ");
|
||||
if (split.length == 3) {
|
||||
return Integer.parseInt(split[1]);
|
||||
}
|
||||
throw new IllegalArgumentException("Improper Action");
|
||||
}
|
||||
|
||||
private int loadSentMessages(Action action) {
|
||||
String additionalInfo = action.getAdditionalInfo();
|
||||
String[] split = additionalInfo.split(": ");
|
||||
if (split.length == 2) {
|
||||
return Integer.parseInt(split[1]);
|
||||
}
|
||||
throw new IllegalArgumentException("Improper Action");
|
||||
}
|
||||
|
||||
public double distance(StickyData data) {
|
||||
double num = 0;
|
||||
num += Math.abs(data.activityIndex - activityIndex) * 2.0;
|
||||
num += Math.abs(data.onlineOnJoin - onlineOnJoin) / 10.0;
|
||||
num += Math.abs(data.messagesSent - messagesSent) / 10.0;
|
||||
|
||||
return num;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
StickyData that = (StickyData) o;
|
||||
return Double.compare(that.activityIndex, activityIndex) == 0 &&
|
||||
Objects.equal(messagesSent, that.messagesSent) &&
|
||||
Objects.equal(onlineOnJoin, that.onlineOnJoin);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hashCode(activityIndex, messagesSent, onlineOnJoin);
|
||||
}
|
||||
|
||||
public double getOnlineOnJoin() {
|
||||
return onlineOnJoin;
|
||||
}
|
||||
|
||||
public double getActivityIndex() {
|
||||
return activityIndex;
|
||||
}
|
||||
|
||||
public Double getMessagesSent() {
|
||||
return messagesSent;
|
||||
}
|
||||
}
|
@ -5,6 +5,8 @@
|
||||
*/
|
||||
package com.djrapitops.plan.data.container;
|
||||
|
||||
import com.djrapitops.plan.data.store.objects.DateHolder;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
@ -13,7 +15,7 @@ import java.util.Objects;
|
||||
* @author Rsl1122
|
||||
* @since 3.5.0
|
||||
*/
|
||||
public class TPS {
|
||||
public class TPS implements DateHolder {
|
||||
|
||||
private final long date;
|
||||
private final double ticksPerSecond;
|
||||
@ -44,11 +46,7 @@ public class TPS {
|
||||
this.chunksLoaded = chunksLoaded;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the time of the average calculation.
|
||||
*
|
||||
* @return epoch ms.
|
||||
*/
|
||||
@Override
|
||||
public long getDate() {
|
||||
return date;
|
||||
}
|
||||
|
@ -54,7 +54,7 @@ public class UserInfo {
|
||||
return banned;
|
||||
}
|
||||
|
||||
public boolean isOpped() {
|
||||
public boolean isOperator() {
|
||||
return opped;
|
||||
}
|
||||
|
||||
|
@ -10,7 +10,7 @@ import java.util.TreeMap;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* Container used to parse data for Analysis page.
|
||||
* Container used to parse data for Server page.
|
||||
* <p>
|
||||
* Similar to InspectContainer, but can contain data for each player for a bigger Player data table.
|
||||
* <p>
|
||||
|
@ -4,6 +4,7 @@
|
||||
*/
|
||||
package com.djrapitops.plan.data.element;
|
||||
|
||||
import com.djrapitops.plan.data.store.mutators.formatting.Formatter;
|
||||
import com.djrapitops.plan.utilities.FormatUtils;
|
||||
import com.djrapitops.plan.utilities.html.Html;
|
||||
|
||||
@ -19,6 +20,7 @@ import java.util.List;
|
||||
public class TableContainer {
|
||||
|
||||
protected final String[] header;
|
||||
protected final Formatter[] formatters;
|
||||
private List<Serializable[]> values;
|
||||
|
||||
private boolean jqueryDatatable;
|
||||
@ -32,11 +34,13 @@ public class TableContainer {
|
||||
*/
|
||||
public TableContainer(String... header) {
|
||||
this.header = header;
|
||||
this.formatters = new Formatter[this.header.length];
|
||||
values = new ArrayList<>();
|
||||
}
|
||||
|
||||
public TableContainer(boolean players, String... header) {
|
||||
this.header = FormatUtils.mergeArrays(new String[]{Html.FONT_AWESOME_ICON.parse("user") + " Player"}, header);
|
||||
this.formatters = new Formatter[this.header.length];
|
||||
values = new ArrayList<>();
|
||||
}
|
||||
|
||||
@ -48,7 +52,7 @@ public class TableContainer {
|
||||
return getTableHeader() +
|
||||
parseHeader() +
|
||||
parseBody() +
|
||||
"</table>";
|
||||
"</table>" + (jqueryDatatable ? "</div>" : "");
|
||||
}
|
||||
|
||||
public final String parseBody() {
|
||||
@ -58,21 +62,30 @@ public class TableContainer {
|
||||
addRow("No Data");
|
||||
}
|
||||
for (Serializable[] row : values) {
|
||||
|
||||
int maxIndex = row.length - 1;
|
||||
body.append("<tr>");
|
||||
for (int i = 0; i < header.length; i++) {
|
||||
body.append("<td>");
|
||||
if (i > maxIndex) {
|
||||
body.append("-");
|
||||
} else {
|
||||
body.append(row[i]);
|
||||
try {
|
||||
if (i > maxIndex) {
|
||||
body.append("<td>-");
|
||||
} else {
|
||||
Serializable value = row[i];
|
||||
Formatter formatter = formatters[i];
|
||||
body.append("<td").append(formatter != null ? " data-order=\"" + value + "\">" : ">");
|
||||
body.append(formatter != null ? formatter.apply(value) : value);
|
||||
}
|
||||
body.append("</td>");
|
||||
} catch (ClassCastException | ArrayIndexOutOfBoundsException e) {
|
||||
throw new IllegalStateException("Invalid formatter given at index " + i + ": " + e.getMessage(), e);
|
||||
}
|
||||
body.append("</td>");
|
||||
}
|
||||
body.append("</tr>");
|
||||
|
||||
}
|
||||
|
||||
return Html.TABLE_BODY.parse(body.toString());
|
||||
|
||||
}
|
||||
|
||||
public final void setColor(String color) {
|
||||
@ -88,6 +101,12 @@ public class TableContainer {
|
||||
return header.toString();
|
||||
}
|
||||
|
||||
public final void setFormatter(int index, Formatter formatter) {
|
||||
if (index < formatters.length) {
|
||||
formatters[index] = formatter;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Make use of JQuery Datatables plugin.
|
||||
* <p>
|
||||
@ -99,7 +118,7 @@ public class TableContainer {
|
||||
|
||||
private String getTableHeader() {
|
||||
if (jqueryDatatable) {
|
||||
return "<div class=\"table-responsive\">" + Html.TABLE_JQUERY.parse() + "</div>";
|
||||
return "<div class=\"table-responsive\">" + Html.TABLE_JQUERY.parse();
|
||||
} else {
|
||||
return Html.TABLE_SCROLL.parse();
|
||||
}
|
||||
|
@ -11,7 +11,9 @@ import java.util.UUID;
|
||||
* Interface for PluginData objects that affect Ban state of players.
|
||||
*
|
||||
* @author Rsl1122
|
||||
* @deprecated As of 4.3.2+ BanData has been deprecated as a way to display bans. Use Key integration instead.
|
||||
*/
|
||||
@Deprecated
|
||||
public interface BanData {
|
||||
|
||||
boolean isBanned(UUID uuid);
|
||||
|
@ -0,0 +1,33 @@
|
||||
package com.djrapitops.plan.data.store;
|
||||
|
||||
import com.djrapitops.plugin.api.TimeAmount;
|
||||
|
||||
import java.util.function.Supplier;
|
||||
|
||||
/**
|
||||
* Caching layer between Supplier and caller.
|
||||
*
|
||||
* Refreshes the value if 30 seconds have passed since the last call.
|
||||
*
|
||||
* @author Rsl1122
|
||||
*/
|
||||
public class CachingSupplier<T> implements Supplier<T> {
|
||||
|
||||
private final Supplier<T> original;
|
||||
private T cachedValue;
|
||||
private long cacheTime;
|
||||
|
||||
public CachingSupplier(Supplier<T> original) {
|
||||
this.original = original;
|
||||
cacheTime = 0L;
|
||||
}
|
||||
|
||||
@Override
|
||||
public T get() {
|
||||
if (cachedValue == null || System.currentTimeMillis() - cacheTime > TimeAmount.SECOND.ms() * 30L) {
|
||||
cachedValue = original.get();
|
||||
cacheTime = System.currentTimeMillis();
|
||||
}
|
||||
return cachedValue;
|
||||
}
|
||||
}
|
68
Plan/src/main/java/com/djrapitops/plan/data/store/Key.java
Normal file
68
Plan/src/main/java/com/djrapitops/plan/data/store/Key.java
Normal file
@ -0,0 +1,68 @@
|
||||
package com.djrapitops.plan.data.store;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* Identifier used for storing and fetching data from DataContainers.
|
||||
*
|
||||
* @param <T> Type of the object returned by the Value identified by this Key.
|
||||
* @author Rsl1122
|
||||
*/
|
||||
public class Key<T> {
|
||||
|
||||
private final Type<T> type;
|
||||
private final String keyName;
|
||||
|
||||
/**
|
||||
* Create a new key.
|
||||
* <p>
|
||||
* Example usage:
|
||||
* {@code Key<String> key = new Key(String.class, "identifier");}
|
||||
* <p>
|
||||
* (In Keys class) {@code public static final Key<String> IDENTIFIER = new Key(String.class, "identifier");}
|
||||
* {@code Key<String> key = Keys.IDENTIFIER;}
|
||||
*
|
||||
* @param type Class with type of the Object returned by the Value identified by this Key.
|
||||
* @param keyName Name (identifier) of the Key.
|
||||
*/
|
||||
public Key(Class<T> type, String keyName) {
|
||||
this(Type.ofClass(type), keyName);
|
||||
}
|
||||
|
||||
public Key(Type<T> type, String keyName) {
|
||||
this.type = type;
|
||||
this.keyName = keyName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the type of the key.
|
||||
*
|
||||
* @return specified in constructor.
|
||||
*/
|
||||
public Type<T> getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the name (identifier) of the Key.
|
||||
*
|
||||
* @return For example "nickname"
|
||||
*/
|
||||
public String getKeyName() {
|
||||
return keyName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
Key<?> key = (Key<?>) o;
|
||||
return Objects.equals(type, key.type) &&
|
||||
Objects.equals(keyName, key.keyName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(type, keyName);
|
||||
}
|
||||
}
|
@ -0,0 +1,25 @@
|
||||
package com.djrapitops.plan.data.store;
|
||||
|
||||
/**
|
||||
* Special Key object that can be used for placeholders when replacing values in html files.
|
||||
*
|
||||
* @author Rsl1122
|
||||
*/
|
||||
public class PlaceholderKey<T> extends Key<T> {
|
||||
|
||||
private final String placeholder;
|
||||
|
||||
public PlaceholderKey(Class<T> type, String placeholder) {
|
||||
super(type, placeholder);
|
||||
this.placeholder = placeholder;
|
||||
}
|
||||
|
||||
public PlaceholderKey(Type<T> type, String placeholder) {
|
||||
super(type, placeholder);
|
||||
this.placeholder = placeholder;
|
||||
}
|
||||
|
||||
public String getPlaceholder() {
|
||||
return placeholder;
|
||||
}
|
||||
}
|
45
Plan/src/main/java/com/djrapitops/plan/data/store/Type.java
Normal file
45
Plan/src/main/java/com/djrapitops/plan/data/store/Type.java
Normal file
@ -0,0 +1,45 @@
|
||||
package com.djrapitops.plan.data.store;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* Similar to Google's TypeToken but without requiring whole gson package.
|
||||
* <p>
|
||||
* Create new instance with {@code new Type<YourObject>() {}}.
|
||||
*
|
||||
* @author Rsl1122
|
||||
*/
|
||||
public abstract class Type<T> {
|
||||
|
||||
private final String genericsSuperClass;
|
||||
|
||||
public Type() {
|
||||
genericsSuperClass = getGenericsClass().getGenericSuperclass().getTypeName();
|
||||
}
|
||||
|
||||
public static <K> Type<K> ofClass(Class<K> of) {
|
||||
return new Type<K>() {};
|
||||
}
|
||||
|
||||
public static <K> Type<K> of(K object) {
|
||||
return new Type<K>() {};
|
||||
}
|
||||
|
||||
public Class<Type<T>> getGenericsClass() {
|
||||
return (Class<Type<T>>) getClass();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (!(o instanceof Type)) return false;
|
||||
Type<?> type = (Type<?>) o;
|
||||
return Objects.equals(genericsSuperClass, type.genericsSuperClass);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
|
||||
return Objects.hash(genericsSuperClass);
|
||||
}
|
||||
}
|
@ -0,0 +1,385 @@
|
||||
package com.djrapitops.plan.data.store.containers;
|
||||
|
||||
import com.djrapitops.plan.PlanPlugin;
|
||||
import com.djrapitops.plan.data.store.Key;
|
||||
import com.djrapitops.plan.data.store.Type;
|
||||
import com.djrapitops.plan.data.store.keys.AnalysisKeys;
|
||||
import com.djrapitops.plan.data.store.keys.PlayerKeys;
|
||||
import com.djrapitops.plan.data.store.keys.ServerKeys;
|
||||
import com.djrapitops.plan.data.store.mutators.*;
|
||||
import com.djrapitops.plan.data.store.mutators.formatting.Formatters;
|
||||
import com.djrapitops.plan.data.time.WorldTimes;
|
||||
import com.djrapitops.plan.system.database.databases.Database;
|
||||
import com.djrapitops.plan.system.info.server.ServerInfo;
|
||||
import com.djrapitops.plan.system.info.server.ServerProperties;
|
||||
import com.djrapitops.plan.system.settings.Settings;
|
||||
import com.djrapitops.plan.system.settings.theme.Theme;
|
||||
import com.djrapitops.plan.system.settings.theme.ThemeVal;
|
||||
import com.djrapitops.plan.utilities.MiscUtils;
|
||||
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;
|
||||
import com.djrapitops.plan.utilities.html.structure.AnalysisPluginsTabContentCreator;
|
||||
import com.djrapitops.plan.utilities.html.structure.RecentLoginList;
|
||||
import com.djrapitops.plan.utilities.html.structure.SessionAccordion;
|
||||
import com.djrapitops.plan.utilities.html.tables.CommandUseTable;
|
||||
import com.djrapitops.plan.utilities.html.tables.PlayersTable;
|
||||
import com.djrapitops.plan.utilities.html.tables.ServerSessionTable;
|
||||
import com.djrapitops.plugin.api.TimeAmount;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* Container used for analysis.
|
||||
*
|
||||
* @author Rsl1122
|
||||
* @see com.djrapitops.plan.data.store.keys.AnalysisKeys for Key objects
|
||||
* @see com.djrapitops.plan.data.store.PlaceholderKey for placeholder information
|
||||
*/
|
||||
public class AnalysisContainer extends DataContainer {
|
||||
|
||||
private final ServerContainer serverContainer;
|
||||
|
||||
private static final Key<Map<UUID, String>> serverNames = new Key<>(new Type<Map<UUID, String>>() {}, "SERVER_NAMES");
|
||||
|
||||
public AnalysisContainer(ServerContainer serverContainer) {
|
||||
this.serverContainer = serverContainer;
|
||||
addAnalysisSuppliers();
|
||||
}
|
||||
|
||||
public ServerContainer getServerContainer() {
|
||||
return serverContainer;
|
||||
}
|
||||
|
||||
private void addAnalysisSuppliers() {
|
||||
putSupplier(AnalysisKeys.SESSIONS_MUTATOR, () -> SessionsMutator.forContainer(serverContainer));
|
||||
putSupplier(AnalysisKeys.TPS_MUTATOR, () -> TPSMutator.forContainer(serverContainer));
|
||||
putSupplier(AnalysisKeys.PLAYERS_MUTATOR, () -> PlayersMutator.forContainer(serverContainer));
|
||||
|
||||
addConstants();
|
||||
addPlayerSuppliers();
|
||||
addSessionSuppliers();
|
||||
addGraphSuppliers();
|
||||
addTPSAverageSuppliers();
|
||||
addCommandSuppliers();
|
||||
addServerHealth();
|
||||
addPluginSuppliers();
|
||||
}
|
||||
|
||||
private void addConstants() {
|
||||
long now = System.currentTimeMillis();
|
||||
putRawData(AnalysisKeys.ANALYSIS_TIME, now);
|
||||
putRawData(AnalysisKeys.ANALYSIS_TIME_DAY_AGO, now - TimeAmount.DAY.ms());
|
||||
putRawData(AnalysisKeys.ANALYSIS_TIME_WEEK_AGO, now - TimeAmount.WEEK.ms());
|
||||
putRawData(AnalysisKeys.ANALYSIS_TIME_MONTH_AGO, now - TimeAmount.MONTH.ms());
|
||||
putSupplier(AnalysisKeys.REFRESH_TIME_F, () -> Formatters.second().apply(() -> getUnsafe(AnalysisKeys.ANALYSIS_TIME)));
|
||||
|
||||
putRawData(AnalysisKeys.VERSION, PlanPlugin.getInstance().getVersion());
|
||||
putSupplier(AnalysisKeys.TIME_ZONE, MiscUtils::getTimeZoneOffsetHours);
|
||||
putRawData(AnalysisKeys.FIRST_DAY, 1);
|
||||
putRawData(AnalysisKeys.TPS_MEDIUM, Settings.THEME_GRAPH_TPS_THRESHOLD_MED.getNumber());
|
||||
putRawData(AnalysisKeys.TPS_HIGH, Settings.THEME_GRAPH_TPS_THRESHOLD_HIGH.getNumber());
|
||||
|
||||
addServerProperties();
|
||||
addThemeColors();
|
||||
}
|
||||
|
||||
private void addServerProperties() {
|
||||
putSupplier(AnalysisKeys.SERVER_NAME, () ->
|
||||
getUnsafe(serverNames).getOrDefault(serverContainer.getUnsafe(ServerKeys.SERVER_UUID), "Plan")
|
||||
);
|
||||
|
||||
ServerProperties serverProperties = ServerInfo.getServerProperties();
|
||||
putRawData(AnalysisKeys.PLAYERS_MAX, serverProperties.getMaxPlayers());
|
||||
putRawData(AnalysisKeys.PLAYERS_ONLINE, serverProperties.getOnlinePlayers());
|
||||
}
|
||||
|
||||
private void addThemeColors() {
|
||||
putRawData(AnalysisKeys.ACTIVITY_PIE_COLORS, Theme.getValue(ThemeVal.GRAPH_ACTIVITY_PIE));
|
||||
putRawData(AnalysisKeys.GM_PIE_COLORS, Theme.getValue(ThemeVal.GRAPH_GM_PIE));
|
||||
putRawData(AnalysisKeys.PLAYERS_GRAPH_COLOR, Theme.getValue(ThemeVal.GRAPH_PLAYERS_ONLINE));
|
||||
putRawData(AnalysisKeys.TPS_LOW_COLOR, Theme.getValue(ThemeVal.GRAPH_TPS_LOW));
|
||||
putRawData(AnalysisKeys.TPS_MEDIUM_COLOR, Theme.getValue(ThemeVal.GRAPH_TPS_MED));
|
||||
putRawData(AnalysisKeys.TPS_HIGH_COLOR, Theme.getValue(ThemeVal.GRAPH_TPS_HIGH));
|
||||
putRawData(AnalysisKeys.WORLD_MAP_LOW_COLOR, Theme.getValue(ThemeVal.WORLD_MAP_LOW));
|
||||
putRawData(AnalysisKeys.WORLD_MAP_HIGH_COLOR, Theme.getValue(ThemeVal.WORLD_MAP_HIGH));
|
||||
putRawData(AnalysisKeys.WORLD_PIE_COLORS, Theme.getValue(ThemeVal.GRAPH_WORLD_PIE));
|
||||
}
|
||||
|
||||
private void addPlayerSuppliers() {
|
||||
putSupplier(AnalysisKeys.PLAYER_NAMES, () -> serverContainer.getValue(ServerKeys.PLAYERS).orElse(new ArrayList<>())
|
||||
.stream().collect(Collectors.toMap(
|
||||
p -> p.getUnsafe(PlayerKeys.UUID), p -> p.getValue(PlayerKeys.NAME).orElse("?"))
|
||||
)
|
||||
);
|
||||
putSupplier(AnalysisKeys.PLAYERS_TOTAL, () -> serverContainer.getValue(ServerKeys.PLAYER_COUNT).orElse(0));
|
||||
putSupplier(AnalysisKeys.PLAYERS_LAST_PEAK, () ->
|
||||
serverContainer.getValue(ServerKeys.RECENT_PEAK_PLAYERS)
|
||||
.map(dateObj -> Integer.toString(dateObj.getValue())).orElse("-")
|
||||
);
|
||||
putSupplier(AnalysisKeys.PLAYERS_ALL_TIME_PEAK, () ->
|
||||
serverContainer.getValue(ServerKeys.ALL_TIME_PEAK_PLAYERS)
|
||||
.map(dateObj -> Integer.toString(dateObj.getValue())).orElse("-")
|
||||
);
|
||||
putSupplier(AnalysisKeys.LAST_PEAK_TIME_F, () ->
|
||||
serverContainer.getValue(ServerKeys.RECENT_PEAK_PLAYERS)
|
||||
.map(dateObj -> Formatters.year().apply(dateObj)).orElse("-")
|
||||
);
|
||||
putSupplier(AnalysisKeys.ALL_TIME_PEAK_TIME_F, () ->
|
||||
serverContainer.getValue(ServerKeys.ALL_TIME_PEAK_PLAYERS)
|
||||
.map(dateObj -> Formatters.year().apply(dateObj)).orElse("-")
|
||||
);
|
||||
putSupplier(AnalysisKeys.OPERATORS, () -> serverContainer.getValue(ServerKeys.OPERATORS).map(List::size).orElse(0));
|
||||
putSupplier(AnalysisKeys.PLAYERS_TABLE, () ->
|
||||
PlayersTable.forServerPage(getUnsafe(AnalysisKeys.PLAYERS_MUTATOR).all()).parseHtml()
|
||||
);
|
||||
|
||||
newAndUniquePlayerCounts();
|
||||
}
|
||||
|
||||
private void newAndUniquePlayerCounts() {
|
||||
Key<PlayersMutator> newDay = new Key<>(PlayersMutator.class, "NEW_DAY");
|
||||
Key<PlayersMutator> newWeek = new Key<>(PlayersMutator.class, "NEW_WEEK");
|
||||
Key<PlayersMutator> newMonth = new Key<>(PlayersMutator.class, "NEW_MONTH");
|
||||
Key<PlayersMutator> uniqueDay = new Key<>(PlayersMutator.class, "UNIQUE_DAY");
|
||||
Key<PlayersMutator> uniqueWeek = new Key<>(PlayersMutator.class, "UNIQUE_WEEK");
|
||||
Key<PlayersMutator> uniqueMonth = new Key<>(PlayersMutator.class, "UNIQUE_MONTH");
|
||||
putSupplier(newDay, () -> getUnsafe(AnalysisKeys.PLAYERS_MUTATOR)
|
||||
.filterRegisteredBetween(getUnsafe(AnalysisKeys.ANALYSIS_TIME_DAY_AGO), getUnsafe(AnalysisKeys.ANALYSIS_TIME))
|
||||
);
|
||||
putSupplier(newWeek, () -> getUnsafe(AnalysisKeys.PLAYERS_MUTATOR)
|
||||
.filterRegisteredBetween(getUnsafe(AnalysisKeys.ANALYSIS_TIME_WEEK_AGO), getUnsafe(AnalysisKeys.ANALYSIS_TIME))
|
||||
);
|
||||
putSupplier(newMonth, () -> getUnsafe(AnalysisKeys.PLAYERS_MUTATOR)
|
||||
.filterRegisteredBetween(getUnsafe(AnalysisKeys.ANALYSIS_TIME_MONTH_AGO), getUnsafe(AnalysisKeys.ANALYSIS_TIME))
|
||||
);
|
||||
putSupplier(uniqueDay, () -> getUnsafe(AnalysisKeys.PLAYERS_MUTATOR)
|
||||
.filterRegisteredBetween(getUnsafe(AnalysisKeys.ANALYSIS_TIME_DAY_AGO), getUnsafe(AnalysisKeys.ANALYSIS_TIME))
|
||||
);
|
||||
putSupplier(uniqueWeek, () -> getUnsafe(AnalysisKeys.PLAYERS_MUTATOR)
|
||||
.filterRegisteredBetween(getUnsafe(AnalysisKeys.ANALYSIS_TIME_WEEK_AGO), getUnsafe(AnalysisKeys.ANALYSIS_TIME))
|
||||
);
|
||||
putSupplier(uniqueMonth, () -> getUnsafe(AnalysisKeys.PLAYERS_MUTATOR)
|
||||
.filterRegisteredBetween(getUnsafe(AnalysisKeys.ANALYSIS_TIME_MONTH_AGO), getUnsafe(AnalysisKeys.ANALYSIS_TIME))
|
||||
);
|
||||
|
||||
putSupplier(AnalysisKeys.PLAYERS_NEW_DAY, () -> getUnsafe(newDay).count());
|
||||
putSupplier(AnalysisKeys.PLAYERS_NEW_WEEK, () -> getUnsafe(newWeek).count());
|
||||
putSupplier(AnalysisKeys.PLAYERS_NEW_MONTH, () -> getUnsafe(newMonth).count());
|
||||
putSupplier(AnalysisKeys.PLAYERS_DAY, () -> getUnsafe(uniqueDay).count());
|
||||
putSupplier(AnalysisKeys.PLAYERS_WEEK, () -> getUnsafe(uniqueWeek).count());
|
||||
putSupplier(AnalysisKeys.PLAYERS_MONTH, () -> getUnsafe(uniqueMonth).count());
|
||||
putSupplier(AnalysisKeys.AVG_PLAYERS_NEW, () -> getUnsafe(AnalysisKeys.PLAYERS_MUTATOR).newPerDay());
|
||||
putSupplier(AnalysisKeys.AVG_PLAYERS_NEW_DAY, () -> getUnsafe(uniqueDay).newPerDay());
|
||||
putSupplier(AnalysisKeys.AVG_PLAYERS_NEW_WEEK, () -> getUnsafe(uniqueWeek).newPerDay());
|
||||
putSupplier(AnalysisKeys.AVG_PLAYERS_NEW_MONTH, () -> getUnsafe(uniqueMonth).newPerDay());
|
||||
|
||||
Key<Integer> retentionDay = new Key<>(Integer.class, "RETENTION_DAY");
|
||||
// compareAndFindThoseLikelyToBeRetained can throw exception.
|
||||
putSupplier(retentionDay, () -> getUnsafe(AnalysisKeys.PLAYERS_MUTATOR).compareAndFindThoseLikelyToBeRetained(
|
||||
getUnsafe(newDay).all(), getUnsafe(AnalysisKeys.ANALYSIS_TIME_MONTH_AGO),
|
||||
getUnsafe(AnalysisKeys.PLAYERS_ONLINE_RESOLVER)
|
||||
).count()
|
||||
);
|
||||
putSupplier(AnalysisKeys.PLAYERS_RETAINED_DAY, () -> {
|
||||
try {
|
||||
return getUnsafe(retentionDay);
|
||||
} catch (IllegalStateException noPlayersAfterDateFiltering) {
|
||||
return 0;
|
||||
}
|
||||
});
|
||||
putSupplier(AnalysisKeys.PLAYERS_RETAINED_DAY_PERC, () -> {
|
||||
try {
|
||||
Integer playersNewDay = getUnsafe(AnalysisKeys.PLAYERS_NEW_DAY);
|
||||
return playersNewDay != 0 ? Formatters.percentage().apply(1.0 * getUnsafe(retentionDay) / playersNewDay) : "-";
|
||||
} catch (IllegalStateException noPlayersAfterDateFiltering) {
|
||||
return "Not enough data";
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void addSessionSuppliers() {
|
||||
Key<SessionAccordion> sessionAccordion = new Key<>(SessionAccordion.class, "SESSION_ACCORDION");
|
||||
putSupplier(serverNames, () -> Database.getActive().fetch().getServerNames());
|
||||
putSupplier(sessionAccordion, () -> SessionAccordion.forServer(
|
||||
getUnsafe(AnalysisKeys.SESSIONS_MUTATOR).all(),
|
||||
getSupplier(serverNames),
|
||||
() -> getUnsafe(AnalysisKeys.PLAYER_NAMES)
|
||||
));
|
||||
putSupplier(AnalysisKeys.SESSION_ACCORDION_HTML, () -> getUnsafe(sessionAccordion).toHtml());
|
||||
putSupplier(AnalysisKeys.SESSION_ACCORDION_FUNCTIONS, () -> getUnsafe(sessionAccordion).toViewScript());
|
||||
|
||||
putSupplier(AnalysisKeys.RECENT_LOGINS, () -> new RecentLoginList(
|
||||
serverContainer.getValue(ServerKeys.PLAYERS).orElse(new ArrayList<>())
|
||||
).toHtml()
|
||||
);
|
||||
putSupplier(AnalysisKeys.SESSION_TABLE, () -> new ServerSessionTable(
|
||||
getUnsafe(AnalysisKeys.PLAYER_NAMES), getUnsafe(AnalysisKeys.SESSIONS_MUTATOR).all()).parseHtml()
|
||||
);
|
||||
|
||||
putSupplier(AnalysisKeys.AVERAGE_SESSION_LENGTH_F, () -> Formatters.timeAmount()
|
||||
.apply(getUnsafe(AnalysisKeys.SESSIONS_MUTATOR).toAverageSessionLength())
|
||||
);
|
||||
putSupplier(AnalysisKeys.SESSION_COUNT, () -> getUnsafe(AnalysisKeys.SESSIONS_MUTATOR).count());
|
||||
putSupplier(AnalysisKeys.PLAYTIME_TOTAL, () -> getUnsafe(AnalysisKeys.SESSIONS_MUTATOR).toPlaytime());
|
||||
putSupplier(AnalysisKeys.DEATHS, () -> getUnsafe(AnalysisKeys.SESSIONS_MUTATOR).toDeathCount());
|
||||
putSupplier(AnalysisKeys.MOB_KILL_COUNT, () -> getUnsafe(AnalysisKeys.SESSIONS_MUTATOR).toMobKillCount());
|
||||
putSupplier(AnalysisKeys.PLAYER_KILL_COUNT, () -> getUnsafe(AnalysisKeys.SESSIONS_MUTATOR).toPlayerKillCount());
|
||||
putSupplier(AnalysisKeys.PLAYTIME_F, () -> Formatters.timeAmount()
|
||||
.apply(getUnsafe(AnalysisKeys.PLAYTIME_TOTAL))
|
||||
);
|
||||
putSupplier(AnalysisKeys.AVERAGE_PLAYTIME_F, () -> {
|
||||
long players = getUnsafe(AnalysisKeys.PLAYERS_TOTAL);
|
||||
return players != 0 ? Formatters.timeAmount()
|
||||
.apply(getUnsafe(AnalysisKeys.PLAYTIME_TOTAL) / players) : "-";
|
||||
}
|
||||
);
|
||||
putSupplier(AnalysisKeys.AVERAGE_SESSION_LENGTH_F, () -> Formatters.timeAmount()
|
||||
.apply(getUnsafe(AnalysisKeys.SESSIONS_MUTATOR).toAverageSessionLength())
|
||||
);
|
||||
|
||||
Key<SessionsMutator> sessionsDay = new Key<>(SessionsMutator.class, "SESSIONS_DAY");
|
||||
Key<SessionsMutator> sessionsWeek = new Key<>(SessionsMutator.class, "SESSIONS_WEEK");
|
||||
Key<SessionsMutator> sessionsMonth = new Key<>(SessionsMutator.class, "SESSIONS_MONTH");
|
||||
putSupplier(sessionsDay, () -> getUnsafe(AnalysisKeys.SESSIONS_MUTATOR)
|
||||
.filterSessionsBetween(getUnsafe(AnalysisKeys.ANALYSIS_TIME_DAY_AGO), getUnsafe(AnalysisKeys.ANALYSIS_TIME))
|
||||
);
|
||||
putSupplier(sessionsWeek, () -> getUnsafe(AnalysisKeys.SESSIONS_MUTATOR)
|
||||
.filterSessionsBetween(getUnsafe(AnalysisKeys.ANALYSIS_TIME_WEEK_AGO), getUnsafe(AnalysisKeys.ANALYSIS_TIME))
|
||||
);
|
||||
putSupplier(sessionsMonth, () -> getUnsafe(AnalysisKeys.SESSIONS_MUTATOR)
|
||||
.filterSessionsBetween(getUnsafe(AnalysisKeys.ANALYSIS_TIME_MONTH_AGO), getUnsafe(AnalysisKeys.ANALYSIS_TIME))
|
||||
);
|
||||
|
||||
putSupplier(AnalysisKeys.PUNCHCARD_SERIES, () -> new PunchCardGraph(getUnsafe(sessionsMonth).all()).toHighChartsSeries());
|
||||
putSupplier(AnalysisKeys.AVG_PLAYERS, () -> getUnsafe(AnalysisKeys.SESSIONS_MUTATOR).toUniqueJoinsPerDay());
|
||||
putSupplier(AnalysisKeys.AVG_PLAYERS_DAY, () -> getUnsafe(sessionsDay).toUniqueJoinsPerDay());
|
||||
putSupplier(AnalysisKeys.AVG_PLAYERS_WEEK, () -> getUnsafe(sessionsWeek).toUniqueJoinsPerDay());
|
||||
putSupplier(AnalysisKeys.AVG_PLAYERS_MONTH, () -> getUnsafe(sessionsMonth).toUniqueJoinsPerDay());
|
||||
putSupplier(AnalysisKeys.PLAYERS_RETAINED_WEEK, () ->
|
||||
getUnsafe(AnalysisKeys.PLAYERS_MUTATOR).filterRetained(
|
||||
getUnsafe(AnalysisKeys.ANALYSIS_TIME_WEEK_AGO),
|
||||
getUnsafe(AnalysisKeys.ANALYSIS_TIME)
|
||||
).count()
|
||||
);
|
||||
putSupplier(AnalysisKeys.PLAYERS_RETAINED_MONTH, () ->
|
||||
getUnsafe(AnalysisKeys.PLAYERS_MUTATOR).filterRetained(
|
||||
getUnsafe(AnalysisKeys.ANALYSIS_TIME_MONTH_AGO),
|
||||
getUnsafe(AnalysisKeys.ANALYSIS_TIME)
|
||||
).count()
|
||||
);
|
||||
putSupplier(AnalysisKeys.PLAYERS_RETAINED_WEEK_PERC, () -> {
|
||||
Integer playersNewWeek = getUnsafe(AnalysisKeys.PLAYERS_NEW_WEEK);
|
||||
return playersNewWeek != 0 ? Formatters.percentage().apply(
|
||||
1.0 * getUnsafe(AnalysisKeys.PLAYERS_RETAINED_WEEK) / playersNewWeek) : "-";
|
||||
}
|
||||
);
|
||||
putSupplier(AnalysisKeys.PLAYERS_RETAINED_MONTH_PERC, () -> {
|
||||
Integer playersNewMonth = getUnsafe(AnalysisKeys.PLAYERS_NEW_MONTH);
|
||||
return playersNewMonth != 0 ? Formatters.percentage().apply(
|
||||
1.0 * getUnsafe(AnalysisKeys.PLAYERS_RETAINED_MONTH) / playersNewMonth) : "-";
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
private void addGraphSuppliers() {
|
||||
Key<WorldPie> worldPie = new Key<>(WorldPie.class, "WORLD_PIE");
|
||||
putSupplier(worldPie, () -> new WorldPie(serverContainer.getValue(ServerKeys.WORLD_TIMES).orElse(new WorldTimes(new HashMap<>()))));
|
||||
putSupplier(AnalysisKeys.WORLD_PIE_SERIES, () -> getUnsafe(worldPie).toHighChartsSeries());
|
||||
putSupplier(AnalysisKeys.GM_PIE_SERIES, () -> getUnsafe(worldPie).toHighChartsDrilldown());
|
||||
putSupplier(AnalysisKeys.PLAYERS_ONLINE_SERIES, () ->
|
||||
new OnlineActivityGraph(getUnsafe(AnalysisKeys.TPS_MUTATOR)).toHighChartsSeries()
|
||||
);
|
||||
putSupplier(AnalysisKeys.TPS_SERIES, () -> new TPSGraph(getUnsafe(AnalysisKeys.TPS_MUTATOR)).toHighChartsSeries());
|
||||
putSupplier(AnalysisKeys.CPU_SERIES, () -> new CPUGraph(getUnsafe(AnalysisKeys.TPS_MUTATOR)).toHighChartsSeries());
|
||||
putSupplier(AnalysisKeys.RAM_SERIES, () -> new RamGraph(getUnsafe(AnalysisKeys.TPS_MUTATOR)).toHighChartsSeries());
|
||||
putSupplier(AnalysisKeys.ENTITY_SERIES, () -> new EntityGraph(getUnsafe(AnalysisKeys.TPS_MUTATOR)).toHighChartsSeries());
|
||||
putSupplier(AnalysisKeys.CHUNK_SERIES, () -> new ChunkGraph(getUnsafe(AnalysisKeys.TPS_MUTATOR)).toHighChartsSeries());
|
||||
putSupplier(AnalysisKeys.WORLD_MAP_SERIES, () ->
|
||||
new WorldMap(getUnsafe(AnalysisKeys.PLAYERS_MUTATOR).getGeolocations()).toHighChartsSeries()
|
||||
);
|
||||
putSupplier(AnalysisKeys.CALENDAR_SERIES, () -> new ServerCalendar(getUnsafe(AnalysisKeys.PLAYERS_MUTATOR)).toCalendarSeries());
|
||||
|
||||
putSupplier(AnalysisKeys.ACTIVITY_DATA, () -> getUnsafe(AnalysisKeys.PLAYERS_MUTATOR).toActivityDataMap(getUnsafe(AnalysisKeys.ANALYSIS_TIME)));
|
||||
Key<ActivityStackGraph> activityStackGraph = new Key<>(ActivityStackGraph.class, "ACTIVITY_STACK_GRAPH");
|
||||
putSupplier(activityStackGraph, () -> new ActivityStackGraph(getUnsafe(AnalysisKeys.ACTIVITY_DATA)));
|
||||
putSupplier(AnalysisKeys.ACTIVITY_STACK_CATEGORIES, () -> getUnsafe(activityStackGraph).toHighChartsLabels());
|
||||
putSupplier(AnalysisKeys.ACTIVITY_STACK_SERIES, () -> getUnsafe(activityStackGraph).toHighChartsSeries());
|
||||
putSupplier(AnalysisKeys.ACTIVITY_PIE_SERIES, () ->
|
||||
new ActivityPie(getUnsafe(AnalysisKeys.ACTIVITY_DATA).get(getUnsafe(AnalysisKeys.ANALYSIS_TIME))).toHighChartsSeries()
|
||||
);
|
||||
putSupplier(AnalysisKeys.PLAYERS_REGULAR, () -> {
|
||||
Map<String, Set<UUID>> activityNow = getUnsafe(AnalysisKeys.ACTIVITY_DATA)
|
||||
.floorEntry(getUnsafe(AnalysisKeys.ANALYSIS_TIME)).getValue();
|
||||
Set<UUID> veryActiveNow = activityNow.getOrDefault("Very Active", new HashSet<>());
|
||||
Set<UUID> activeNow = activityNow.getOrDefault("Active", new HashSet<>());
|
||||
Set<UUID> regularNow = activityNow.getOrDefault("Regular", new HashSet<>());
|
||||
return veryActiveNow.size() + activeNow.size() + regularNow.size();
|
||||
});
|
||||
}
|
||||
|
||||
private void addTPSAverageSuppliers() {
|
||||
Key<TPSMutator> tpsMonth = new Key<>(TPSMutator.class, "TPS_MONTH");
|
||||
Key<TPSMutator> tpsWeek = new Key<>(TPSMutator.class, "TPS_WEEK");
|
||||
Key<TPSMutator> tpsDay = new Key<>(TPSMutator.class, "TPS_DAY");
|
||||
|
||||
putSupplier(tpsMonth, () -> getUnsafe(AnalysisKeys.TPS_MUTATOR)
|
||||
.filterDataBetween(getUnsafe(AnalysisKeys.ANALYSIS_TIME_MONTH_AGO), getUnsafe(AnalysisKeys.ANALYSIS_TIME))
|
||||
);
|
||||
putSupplier(tpsWeek, () -> getUnsafe(AnalysisKeys.TPS_MUTATOR)
|
||||
.filterDataBetween(getUnsafe(AnalysisKeys.ANALYSIS_TIME_WEEK_AGO), getUnsafe(AnalysisKeys.ANALYSIS_TIME))
|
||||
);
|
||||
putSupplier(tpsDay, () -> getUnsafe(AnalysisKeys.TPS_MUTATOR)
|
||||
.filterDataBetween(getUnsafe(AnalysisKeys.ANALYSIS_TIME_DAY_AGO), getUnsafe(AnalysisKeys.ANALYSIS_TIME))
|
||||
);
|
||||
|
||||
putSupplier(AnalysisKeys.PLAYERS_ONLINE_RESOLVER, () -> new PlayersOnlineResolver(getUnsafe(AnalysisKeys.TPS_MUTATOR)));
|
||||
|
||||
putSupplier(AnalysisKeys.TPS_SPIKE_MONTH, () -> getUnsafe(tpsMonth).lowTpsSpikeCount());
|
||||
putSupplier(AnalysisKeys.AVG_TPS_MONTH, () -> getUnsafe(tpsMonth).averageTPS());
|
||||
putSupplier(AnalysisKeys.AVG_CPU_MONTH, () -> getUnsafe(tpsMonth).averageCPU());
|
||||
putSupplier(AnalysisKeys.AVG_RAM_MONTH, () -> getUnsafe(tpsMonth).averageRAM());
|
||||
putSupplier(AnalysisKeys.AVG_ENTITY_MONTH, () -> getUnsafe(tpsMonth).averageEntities());
|
||||
putSupplier(AnalysisKeys.AVG_CHUNK_MONTH, () -> getUnsafe(tpsMonth).averageChunks());
|
||||
putSupplier(AnalysisKeys.TPS_SPIKE_WEEK, () -> getUnsafe(tpsWeek).lowTpsSpikeCount());
|
||||
putSupplier(AnalysisKeys.AVG_TPS_WEEK, () -> getUnsafe(tpsWeek).averageTPS());
|
||||
putSupplier(AnalysisKeys.AVG_CPU_WEEK, () -> getUnsafe(tpsWeek).averageCPU());
|
||||
putSupplier(AnalysisKeys.AVG_RAM_WEEK, () -> getUnsafe(tpsWeek).averageRAM());
|
||||
putSupplier(AnalysisKeys.AVG_ENTITY_WEEK, () -> getUnsafe(tpsWeek).averageEntities());
|
||||
putSupplier(AnalysisKeys.AVG_CHUNK_WEEK, () -> getUnsafe(tpsWeek).averageChunks());
|
||||
putSupplier(AnalysisKeys.TPS_SPIKE_DAY, () -> getUnsafe(tpsDay).lowTpsSpikeCount());
|
||||
putSupplier(AnalysisKeys.AVG_TPS_DAY, () -> getUnsafe(tpsDay).averageTPS());
|
||||
putSupplier(AnalysisKeys.AVG_CPU_DAY, () -> getUnsafe(tpsDay).averageCPU());
|
||||
putSupplier(AnalysisKeys.AVG_RAM_DAY, () -> getUnsafe(tpsDay).averageRAM());
|
||||
putSupplier(AnalysisKeys.AVG_ENTITY_DAY, () -> getUnsafe(tpsDay).averageEntities());
|
||||
putSupplier(AnalysisKeys.AVG_CHUNK_DAY, () -> getUnsafe(tpsDay).averageChunks());
|
||||
}
|
||||
|
||||
private void addCommandSuppliers() {
|
||||
putSupplier(AnalysisKeys.COMMAND_USAGE_TABLE, () -> new CommandUseTable(serverContainer).parseHtml());
|
||||
putSupplier(AnalysisKeys.COMMAND_COUNT_UNIQUE, () -> serverContainer.getValue(ServerKeys.COMMAND_USAGE).map(Map::size).orElse(0));
|
||||
putSupplier(AnalysisKeys.COMMAND_COUNT, () -> CommandUseMutator.forContainer(serverContainer).commandUsageCount());
|
||||
}
|
||||
|
||||
private void addServerHealth() {
|
||||
Key<HealthInformation> healthInformation = new Key<>(HealthInformation.class, "HEALTH_INFORMATION");
|
||||
putSupplier(healthInformation, () -> new HealthInformation(this));
|
||||
putSupplier(AnalysisKeys.HEALTH_INDEX, () -> getUnsafe(healthInformation).getServerHealth());
|
||||
putSupplier(AnalysisKeys.HEALTH_NOTES, () -> getUnsafe(healthInformation).toHtml());
|
||||
}
|
||||
|
||||
private void addPluginSuppliers() {
|
||||
// TODO Refactor into a system that supports running the analysis on Bungee
|
||||
Key<String[]> navAndTabs = new Key<>(new Type<String[]>() {}, "NAV_AND_TABS");
|
||||
putSupplier(navAndTabs, () ->
|
||||
AnalysisPluginsTabContentCreator.createContent(getUnsafe(AnalysisKeys.PLAYERS_MUTATOR))
|
||||
);
|
||||
putSupplier(AnalysisKeys.PLUGINS_TAB_NAV, () -> getUnsafe(navAndTabs)[0]);
|
||||
putSupplier(AnalysisKeys.PLUGINS_TAB, () -> getUnsafe(navAndTabs)[1]);
|
||||
}
|
||||
}
|
@ -0,0 +1,119 @@
|
||||
package com.djrapitops.plan.data.store.containers;
|
||||
|
||||
import com.djrapitops.plan.data.store.CachingSupplier;
|
||||
import com.djrapitops.plan.data.store.Key;
|
||||
import com.djrapitops.plan.data.store.mutators.formatting.Formatter;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Optional;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
/**
|
||||
* Abstract representation of an object that holds the Values for different Keys.
|
||||
* <p>
|
||||
* The methods in this object are used for placing and fetching the data from the container.
|
||||
* Methods to use depend on your use case.
|
||||
*
|
||||
* @author Rsl1122
|
||||
*/
|
||||
public class DataContainer extends HashMap<Key, Supplier> {
|
||||
|
||||
/**
|
||||
* Place your data inside the container.
|
||||
*
|
||||
* @param key Key of type T that identifies the data and will be used later when the data needs to be fetched.
|
||||
* @param obj object to store
|
||||
* @param <T> Type of the object
|
||||
*/
|
||||
public <T> void putRawData(Key<T> key, T obj) {
|
||||
putSupplier(key, () -> obj);
|
||||
}
|
||||
|
||||
public <T> void putSupplier(Key<T> key, Supplier<T> supplier) {
|
||||
super.put(key, new CachingSupplier<>(supplier));
|
||||
}
|
||||
|
||||
public <T> Supplier<T> getSupplier(Key<T> key) {
|
||||
return (Supplier<T>) super.get(key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a Value with the given Key has been placed into the container.
|
||||
*
|
||||
* @param key Key that identifies the data.
|
||||
* @param <T> Type of the object returned by the Value if it is present.
|
||||
* @return true if found, false if not.
|
||||
*/
|
||||
public <T> boolean supports(Key<T> key) {
|
||||
return containsKey(key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an Optional of the data identified by the Key.
|
||||
* <p>
|
||||
* Since Value is a functional interface, its method may call blocking methods via Value implementations,
|
||||
* It is therefore recommended to not call this method on the server thread.
|
||||
* <p>
|
||||
* It is recommended to check if the Optional is present as null values returned by plugins will be empty.
|
||||
*
|
||||
* @param key Key that identifies the Value
|
||||
* @param <T> Type of the object returned by Value
|
||||
* @return Optional of the object if the key is registered and key matches the type of the object. Otherwise empty.
|
||||
*/
|
||||
public <T> Optional<T> getValue(Key<T> key) {
|
||||
Supplier<T> supplier = getSupplier(key);
|
||||
if (supplier == null) {
|
||||
return Optional.empty();
|
||||
}
|
||||
try {
|
||||
return Optional.ofNullable(supplier.get());
|
||||
} catch (ClassCastException e) {
|
||||
return Optional.empty();
|
||||
}
|
||||
}
|
||||
|
||||
public <T> T getUnsafe(Key<T> key) {
|
||||
Supplier supplier = get(key);
|
||||
if (supplier == null) {
|
||||
throw new IllegalArgumentException("Unsupported Key: " + key.getKeyName());
|
||||
}
|
||||
return (T) supplier.get();
|
||||
}
|
||||
|
||||
public <T> String getFormatted(Key<T> key, Formatter<Optional<T>> formatter) {
|
||||
Optional<T> value = getValue(key);
|
||||
return formatter.apply(value);
|
||||
}
|
||||
|
||||
public <T> String getFormattedUnsafe(Key<T> key, Formatter<T> formatter) {
|
||||
T value = getUnsafe(key);
|
||||
return formatter.apply(value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Normal put method.
|
||||
*
|
||||
* @param key Key.
|
||||
* @param value Supplier
|
||||
* @return the previous value.
|
||||
* @deprecated Use putSupplier instead for type safety.
|
||||
*/
|
||||
@Override
|
||||
@Deprecated
|
||||
public Supplier put(Key key, Supplier value) {
|
||||
return super.put(key, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Normal get method.
|
||||
*
|
||||
* @param key Key.
|
||||
* @return Supplier
|
||||
* @deprecated Use getSupplier instead for types.
|
||||
*/
|
||||
@Override
|
||||
@Deprecated
|
||||
public Supplier get(Object key) {
|
||||
return super.get(key);
|
||||
}
|
||||
}
|
@ -0,0 +1,144 @@
|
||||
package com.djrapitops.plan.data.store.containers;
|
||||
|
||||
import com.djrapitops.plan.PlanPlugin;
|
||||
import com.djrapitops.plan.api.exceptions.database.DBOpException;
|
||||
import com.djrapitops.plan.data.store.Key;
|
||||
import com.djrapitops.plan.data.store.keys.NetworkKeys;
|
||||
import com.djrapitops.plan.data.store.keys.ServerKeys;
|
||||
import com.djrapitops.plan.data.store.mutators.PlayersMutator;
|
||||
import com.djrapitops.plan.data.store.mutators.TPSMutator;
|
||||
import com.djrapitops.plan.data.store.mutators.formatting.Formatters;
|
||||
import com.djrapitops.plan.system.database.databases.Database;
|
||||
import com.djrapitops.plan.system.info.server.ServerInfo;
|
||||
import com.djrapitops.plan.system.settings.theme.Theme;
|
||||
import com.djrapitops.plan.system.settings.theme.ThemeVal;
|
||||
import com.djrapitops.plan.utilities.MiscUtils;
|
||||
import com.djrapitops.plan.utilities.html.graphs.WorldMap;
|
||||
import com.djrapitops.plan.utilities.html.graphs.line.OnlineActivityGraph;
|
||||
import com.djrapitops.plugin.api.TimeAmount;
|
||||
import com.djrapitops.plugin.api.utility.log.Log;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* DataContainer for the whole network.
|
||||
*
|
||||
* @author Rsl1122
|
||||
* @see com.djrapitops.plan.data.store.keys.NetworkKeys for Key objects
|
||||
* @see com.djrapitops.plan.data.store.PlaceholderKey for placeholder information
|
||||
*/
|
||||
public class NetworkContainer extends DataContainer {
|
||||
|
||||
private final ServerContainer bungeeContainer;
|
||||
|
||||
private final Map<UUID, AnalysisContainer> serverContainers;
|
||||
|
||||
public NetworkContainer(ServerContainer bungeeContainer) {
|
||||
this.bungeeContainer = bungeeContainer;
|
||||
serverContainers = new HashMap<>();
|
||||
|
||||
putSupplier(NetworkKeys.PLAYERS_MUTATOR, () -> PlayersMutator.forContainer(bungeeContainer));
|
||||
|
||||
addConstants();
|
||||
addPlayerInformation();
|
||||
}
|
||||
|
||||
public void putAnalysisContainer(AnalysisContainer analysisContainer) {
|
||||
serverContainers.put(analysisContainer.getServerContainer().getUnsafe(ServerKeys.SERVER_UUID), analysisContainer);
|
||||
}
|
||||
|
||||
public Optional<AnalysisContainer> getAnalysisContainer(UUID serverUUID) {
|
||||
AnalysisContainer container = serverContainers.get(serverUUID);
|
||||
if (container != null) {
|
||||
return Optional.of(container);
|
||||
}
|
||||
try {
|
||||
AnalysisContainer analysisContainer = new AnalysisContainer(Database.getActive().fetch().getServerContainer(serverUUID));
|
||||
serverContainers.put(serverUUID, analysisContainer);
|
||||
return Optional.of(analysisContainer);
|
||||
} catch (DBOpException e) {
|
||||
Log.toLog(this.getClass(), e);
|
||||
}
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
private void addConstants() {
|
||||
long now = System.currentTimeMillis();
|
||||
putRawData(NetworkKeys.REFRESH_TIME, now);
|
||||
putRawData(NetworkKeys.REFRESH_TIME_DAY_AGO, getUnsafe(NetworkKeys.REFRESH_TIME) - TimeAmount.DAY.ms());
|
||||
putRawData(NetworkKeys.REFRESH_TIME_WEEK_AGO, getUnsafe(NetworkKeys.REFRESH_TIME) - TimeAmount.WEEK.ms());
|
||||
putRawData(NetworkKeys.REFRESH_TIME_MONTH_AGO, getUnsafe(NetworkKeys.REFRESH_TIME) - TimeAmount.MONTH.ms());
|
||||
putSupplier(NetworkKeys.REFRESH_TIME_F, () -> Formatters.second().apply(() -> getUnsafe(NetworkKeys.REFRESH_TIME)));
|
||||
|
||||
putRawData(NetworkKeys.VERSION, PlanPlugin.getInstance().getVersion());
|
||||
putSupplier(NetworkKeys.TIME_ZONE, MiscUtils::getTimeZoneOffsetHours);
|
||||
|
||||
putSupplier(NetworkKeys.NETWORK_NAME, () -> bungeeContainer.getValue(ServerKeys.NAME).orElse("Plan"));
|
||||
putSupplier(NetworkKeys.PLAYERS_ONLINE, ServerInfo.getServerProperties()::getOnlinePlayers);
|
||||
putRawData(NetworkKeys.WORLD_MAP_LOW_COLOR, Theme.getValue(ThemeVal.WORLD_MAP_LOW));
|
||||
putRawData(NetworkKeys.WORLD_MAP_HIGH_COLOR, Theme.getValue(ThemeVal.WORLD_MAP_HIGH));
|
||||
putRawData(NetworkKeys.PLAYERS_GRAPH_COLOR, Theme.getValue(ThemeVal.GRAPH_PLAYERS_ONLINE));
|
||||
}
|
||||
|
||||
private void addPlayerInformation() {
|
||||
putSupplier(NetworkKeys.PLAYERS_TOTAL, () -> getUnsafe(NetworkKeys.PLAYERS_MUTATOR).count());
|
||||
putSupplier(NetworkKeys.WORLD_MAP_SERIES, () ->
|
||||
new WorldMap(PlayersMutator.forContainer(bungeeContainer)).toHighChartsSeries()
|
||||
);
|
||||
putSupplier(NetworkKeys.PLAYERS_ONLINE_SERIES, () ->
|
||||
new OnlineActivityGraph(TPSMutator.forContainer(bungeeContainer)).toHighChartsSeries()
|
||||
);
|
||||
putSupplier(NetworkKeys.ALL_TIME_PEAK_TIME_F, () ->
|
||||
bungeeContainer.getValue(ServerKeys.ALL_TIME_PEAK_PLAYERS).map(Formatters.year()::apply).orElse("No data")
|
||||
);
|
||||
putSupplier(NetworkKeys.RECENT_PEAK_TIME_F, () ->
|
||||
bungeeContainer.getValue(ServerKeys.RECENT_PEAK_PLAYERS).map(Formatters.year()::apply).orElse("No data")
|
||||
);
|
||||
putSupplier(NetworkKeys.PLAYERS_ALL_TIME_PEAK, () ->
|
||||
bungeeContainer.getValue(ServerKeys.ALL_TIME_PEAK_PLAYERS).map(dateObj -> "" + dateObj.getValue()).orElse("-")
|
||||
);
|
||||
putSupplier(NetworkKeys.PLAYERS_RECENT_PEAK, () ->
|
||||
bungeeContainer.getValue(ServerKeys.RECENT_PEAK_PLAYERS).map(dateObj -> "" + dateObj.getValue()).orElse("-")
|
||||
);
|
||||
|
||||
addPlayerCounts();
|
||||
}
|
||||
|
||||
private void addPlayerCounts() {
|
||||
Key<PlayersMutator> newDay = new Key<>(PlayersMutator.class, "NEW_DAY");
|
||||
Key<PlayersMutator> newWeek = new Key<>(PlayersMutator.class, "NEW_WEEK");
|
||||
Key<PlayersMutator> newMonth = new Key<>(PlayersMutator.class, "NEW_MONTH");
|
||||
Key<PlayersMutator> uniqueDay = new Key<>(PlayersMutator.class, "UNIQUE_DAY");
|
||||
Key<PlayersMutator> uniqueWeek = new Key<>(PlayersMutator.class, "UNIQUE_WEEK");
|
||||
Key<PlayersMutator> uniqueMonth = new Key<>(PlayersMutator.class, "UNIQUE_MONTH");
|
||||
putSupplier(newDay, () -> getUnsafe(NetworkKeys.PLAYERS_MUTATOR)
|
||||
.filterRegisteredBetween(getUnsafe(NetworkKeys.REFRESH_TIME_DAY_AGO), getUnsafe(NetworkKeys.REFRESH_TIME))
|
||||
);
|
||||
putSupplier(newWeek, () -> getUnsafe(NetworkKeys.PLAYERS_MUTATOR)
|
||||
.filterRegisteredBetween(getUnsafe(NetworkKeys.REFRESH_TIME_WEEK_AGO), getUnsafe(NetworkKeys.REFRESH_TIME))
|
||||
);
|
||||
putSupplier(newMonth, () -> getUnsafe(NetworkKeys.PLAYERS_MUTATOR)
|
||||
.filterRegisteredBetween(getUnsafe(NetworkKeys.REFRESH_TIME_MONTH_AGO), getUnsafe(NetworkKeys.REFRESH_TIME))
|
||||
);
|
||||
putSupplier(uniqueDay, () -> getUnsafe(NetworkKeys.PLAYERS_MUTATOR)
|
||||
.filterPlayedBetween(getUnsafe(NetworkKeys.REFRESH_TIME_DAY_AGO), getUnsafe(NetworkKeys.REFRESH_TIME))
|
||||
);
|
||||
putSupplier(uniqueWeek, () -> getUnsafe(NetworkKeys.PLAYERS_MUTATOR)
|
||||
.filterPlayedBetween(getUnsafe(NetworkKeys.REFRESH_TIME_WEEK_AGO), getUnsafe(NetworkKeys.REFRESH_TIME))
|
||||
);
|
||||
putSupplier(uniqueMonth, () -> getUnsafe(NetworkKeys.PLAYERS_MUTATOR)
|
||||
.filterPlayedBetween(getUnsafe(NetworkKeys.REFRESH_TIME_MONTH_AGO), getUnsafe(NetworkKeys.REFRESH_TIME))
|
||||
);
|
||||
|
||||
putSupplier(NetworkKeys.PLAYERS_NEW_DAY, () -> getUnsafe(newDay).count());
|
||||
putSupplier(NetworkKeys.PLAYERS_NEW_WEEK, () -> getUnsafe(newWeek).count());
|
||||
putSupplier(NetworkKeys.PLAYERS_NEW_MONTH, () -> getUnsafe(newMonth).count());
|
||||
putSupplier(NetworkKeys.PLAYERS_DAY, () -> getUnsafe(uniqueDay).count());
|
||||
putSupplier(NetworkKeys.PLAYERS_WEEK, () -> getUnsafe(uniqueWeek).count());
|
||||
putSupplier(NetworkKeys.PLAYERS_MONTH, () -> getUnsafe(uniqueMonth).count());
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,13 @@
|
||||
package com.djrapitops.plan.data.store.containers;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* Container for data about a player linked to a single server.
|
||||
*
|
||||
* @author Rsl1122
|
||||
* @see com.djrapitops.plan.data.store.keys.PerServerKeys For Key objects.
|
||||
*/
|
||||
public class PerServerContainer extends HashMap<UUID, DataContainer> {
|
||||
}
|
@ -0,0 +1,38 @@
|
||||
package com.djrapitops.plan.data.store.containers;
|
||||
|
||||
import com.djrapitops.plan.data.store.mutators.ActivityIndex;
|
||||
import com.djrapitops.plan.data.store.mutators.SessionsMutator;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* DataContainer about a Player.
|
||||
* <p>
|
||||
* Use {@code getValue(PlayerKeys.REGISTERED).isPresent()} to determine if Plan has data about the player.
|
||||
*
|
||||
* @author Rsl1122
|
||||
* @see com.djrapitops.plan.data.store.keys.PlayerKeys For Key objects.
|
||||
*/
|
||||
public class PlayerContainer extends DataContainer {
|
||||
|
||||
private Map<Long, ActivityIndex> activityIndexCache;
|
||||
|
||||
public PlayerContainer() {
|
||||
activityIndexCache = new HashMap<>();
|
||||
}
|
||||
|
||||
public ActivityIndex getActivityIndex(long date) {
|
||||
ActivityIndex index = activityIndexCache.get(date);
|
||||
if (index == null) {
|
||||
index = new ActivityIndex(this, date);
|
||||
activityIndexCache.put(date, index);
|
||||
}
|
||||
return index;
|
||||
}
|
||||
|
||||
public boolean playedBetween(long after, long before) {
|
||||
return SessionsMutator.forContainer(this).playedBetween(after, before);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,10 @@
|
||||
package com.djrapitops.plan.data.store.containers;
|
||||
|
||||
/**
|
||||
* DataContainer for a single server.
|
||||
*
|
||||
* @author Rsl1122
|
||||
* @see com.djrapitops.plan.data.store.keys.ServerKeys For Key objects.
|
||||
*/
|
||||
public class ServerContainer extends DataContainer {
|
||||
}
|
@ -0,0 +1,146 @@
|
||||
package com.djrapitops.plan.data.store.keys;
|
||||
|
||||
import com.djrapitops.plan.data.store.Key;
|
||||
import com.djrapitops.plan.data.store.PlaceholderKey;
|
||||
import com.djrapitops.plan.data.store.Type;
|
||||
import com.djrapitops.plan.data.store.mutators.PlayersMutator;
|
||||
import com.djrapitops.plan.data.store.mutators.PlayersOnlineResolver;
|
||||
import com.djrapitops.plan.data.store.mutators.SessionsMutator;
|
||||
import com.djrapitops.plan.data.store.mutators.TPSMutator;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.TreeMap;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* Key objects used for Analysis.
|
||||
* <p>
|
||||
* PlaceholderKey objects can be used for directly replacing a value on the html.
|
||||
*
|
||||
* @author Rsl1122
|
||||
* @see com.djrapitops.plan.data.store.containers.AnalysisContainer for Suppliers for each Key.
|
||||
*/
|
||||
public class AnalysisKeys {
|
||||
|
||||
// Constants (Affected only by config settings)
|
||||
public static final PlaceholderKey<String> VERSION = CommonPlaceholderKeys.VERSION;
|
||||
public static final PlaceholderKey<String> SERVER_NAME = new PlaceholderKey<>(String.class, "serverName");
|
||||
public static final PlaceholderKey<Integer> TIME_ZONE = CommonPlaceholderKeys.TIME_ZONE;
|
||||
public static final PlaceholderKey<Integer> FIRST_DAY = new PlaceholderKey<>(Integer.class, "firstDay");
|
||||
public static final PlaceholderKey<Integer> TPS_MEDIUM = new PlaceholderKey<>(Integer.class, "tpsMedium");
|
||||
public static final PlaceholderKey<Integer> TPS_HIGH = new PlaceholderKey<>(Integer.class, "tpsHigh");
|
||||
public static final PlaceholderKey<Integer> PLAYERS_MAX = new PlaceholderKey<>(Integer.class, "playersMax");
|
||||
public static final PlaceholderKey<Integer> PLAYERS_ONLINE = CommonPlaceholderKeys.PLAYERS_ONLINE;
|
||||
public static final PlaceholderKey<Integer> PLAYERS_TOTAL = CommonPlaceholderKeys.PLAYERS_TOTAL;
|
||||
//
|
||||
public static final PlaceholderKey<String> WORLD_PIE_COLORS = new PlaceholderKey<>(String.class, "worldPieColors");
|
||||
public static final PlaceholderKey<String> GM_PIE_COLORS = new PlaceholderKey<>(String.class, "gmPieColors");
|
||||
public static final PlaceholderKey<String> ACTIVITY_PIE_COLORS = new PlaceholderKey<>(String.class, "activityPieColors");
|
||||
public static final PlaceholderKey<String> PLAYERS_GRAPH_COLOR = CommonPlaceholderKeys.PLAYERS_GRAPH_COLOR;
|
||||
public static final PlaceholderKey<String> TPS_HIGH_COLOR = new PlaceholderKey<>(String.class, "tpsHighColor");
|
||||
public static final PlaceholderKey<String> TPS_MEDIUM_COLOR = new PlaceholderKey<>(String.class, "tpsMediumColor");
|
||||
public static final PlaceholderKey<String> TPS_LOW_COLOR = new PlaceholderKey<>(String.class, "tpsLowColor");
|
||||
public static final PlaceholderKey<String> WORLD_MAP_HIGH_COLOR = CommonPlaceholderKeys.WORLD_MAP_HIGH_COLOR;
|
||||
public static final PlaceholderKey<String> WORLD_MAP_LOW_COLOR = CommonPlaceholderKeys.WORLD_MAP_LOW_COLOR;
|
||||
// Tables & other structures
|
||||
public static final PlaceholderKey<String> PLAYERS_TABLE = new PlaceholderKey<>(String.class, "tablePlayerlist");
|
||||
public static final PlaceholderKey<String> SESSION_ACCORDION_HTML = new PlaceholderKey<>(String.class, "accordionSessions");
|
||||
public static final PlaceholderKey<String> SESSION_ACCORDION_FUNCTIONS = new PlaceholderKey<>(String.class, "sessionTabGraphViewFunctions");
|
||||
public static final PlaceholderKey<String> SESSION_TABLE = new PlaceholderKey<>(String.class, "tableBodySessions");
|
||||
public static final PlaceholderKey<String> RECENT_LOGINS = new PlaceholderKey<>(String.class, "listRecentLogins");
|
||||
public static final PlaceholderKey<String> COMMAND_USAGE_TABLE = new PlaceholderKey<>(String.class, "tableCommandUsage");
|
||||
public static final PlaceholderKey<String> HEALTH_NOTES = new PlaceholderKey<>(String.class, "healthNotes");
|
||||
public static final PlaceholderKey<String> PLUGINS_TAB = new PlaceholderKey<>(String.class, "tabsPlugins");
|
||||
public static final PlaceholderKey<String> PLUGINS_TAB_NAV = new PlaceholderKey<>(String.class, "navPluginsTabs");
|
||||
// Formatted time values
|
||||
public static final PlaceholderKey<String> REFRESH_TIME_F = CommonPlaceholderKeys.REFRESH_TIME_F;
|
||||
public static final PlaceholderKey<String> LAST_PEAK_TIME_F = CommonPlaceholderKeys.LAST_PEAK_TIME_F;
|
||||
public static final PlaceholderKey<String> ALL_TIME_PEAK_TIME_F = CommonPlaceholderKeys.ALL_TIME_PEAK_TIME_F;
|
||||
public static final PlaceholderKey<String> AVERAGE_SESSION_LENGTH_F = new PlaceholderKey<>(String.class, "sessionAverage");
|
||||
public static final PlaceholderKey<String> AVERAGE_PLAYTIME_F = new PlaceholderKey<>(String.class, "playtimeAverage");
|
||||
public static final PlaceholderKey<String> PLAYTIME_F = new PlaceholderKey<>(String.class, "playtimeTotal");
|
||||
// Direct values, possibly formatted
|
||||
public static final PlaceholderKey<String> PLAYERS_LAST_PEAK = CommonPlaceholderKeys.PLAYERS_LAST_PEAK;
|
||||
public static final PlaceholderKey<String> PLAYERS_ALL_TIME_PEAK = CommonPlaceholderKeys.PLAYERS_ALL_TIME_PEAK;
|
||||
public static final PlaceholderKey<Integer> OPERATORS = new PlaceholderKey<>(Integer.class, "ops");
|
||||
public static final PlaceholderKey<Integer> PLAYERS_REGULAR = new PlaceholderKey<>(Integer.class, "playersRegular");
|
||||
public static final PlaceholderKey<Integer> SESSION_COUNT = new PlaceholderKey<>(Integer.class, "sessionCount");
|
||||
public static final PlaceholderKey<Integer> DEATHS = new PlaceholderKey<>(Integer.class, "deaths");
|
||||
public static final PlaceholderKey<Integer> MOB_KILL_COUNT = new PlaceholderKey<>(Integer.class, "mobKillCount");
|
||||
public static final PlaceholderKey<Integer> PLAYER_KILL_COUNT = new PlaceholderKey<>(Integer.class, "killCount");
|
||||
public static final PlaceholderKey<Double> HEALTH_INDEX = new PlaceholderKey<>(Double.class, "healthIndex");
|
||||
public static final PlaceholderKey<Integer> COMMAND_COUNT = new PlaceholderKey<>(Integer.class, "commandCount");
|
||||
public static final PlaceholderKey<Integer> COMMAND_COUNT_UNIQUE = new PlaceholderKey<>(Integer.class, "commandUniqueCount");
|
||||
//
|
||||
public static final PlaceholderKey<Integer> PLAYERS_DAY = CommonPlaceholderKeys.PLAYERS_DAY;
|
||||
public static final PlaceholderKey<Integer> PLAYERS_WEEK = CommonPlaceholderKeys.PLAYERS_WEEK;
|
||||
public static final PlaceholderKey<Integer> PLAYERS_MONTH = CommonPlaceholderKeys.PLAYERS_MONTH;
|
||||
public static final PlaceholderKey<Integer> PLAYERS_NEW_DAY = CommonPlaceholderKeys.PLAYERS_NEW_DAY;
|
||||
public static final PlaceholderKey<Integer> PLAYERS_NEW_WEEK = CommonPlaceholderKeys.PLAYERS_NEW_WEEK;
|
||||
public static final PlaceholderKey<Integer> PLAYERS_NEW_MONTH = CommonPlaceholderKeys.PLAYERS_NEW_MONTH;
|
||||
public static final PlaceholderKey<Integer> AVG_PLAYERS = new PlaceholderKey<>(Integer.class, "playersAverage");
|
||||
public static final PlaceholderKey<Integer> AVG_PLAYERS_DAY = new PlaceholderKey<>(Integer.class, "playersAverageDay");
|
||||
public static final PlaceholderKey<Integer> AVG_PLAYERS_WEEK = new PlaceholderKey<>(Integer.class, "playersAverageWeek");
|
||||
public static final PlaceholderKey<Integer> AVG_PLAYERS_MONTH = new PlaceholderKey<>(Integer.class, "playersAverageMonth");
|
||||
public static final PlaceholderKey<Integer> AVG_PLAYERS_NEW = new PlaceholderKey<>(Integer.class, "playersNewAverage");
|
||||
public static final PlaceholderKey<Integer> AVG_PLAYERS_NEW_DAY = new PlaceholderKey<>(Integer.class, "playersNewAverageDay");
|
||||
public static final PlaceholderKey<Integer> AVG_PLAYERS_NEW_WEEK = new PlaceholderKey<>(Integer.class, "playersNewAverageWeek");
|
||||
public static final PlaceholderKey<Integer> AVG_PLAYERS_NEW_MONTH = new PlaceholderKey<>(Integer.class, "playersNewAverageMonth");
|
||||
public static final PlaceholderKey<Integer> PLAYERS_RETAINED_DAY = new PlaceholderKey<>(Integer.class, "playersStuckDay");
|
||||
public static final PlaceholderKey<String> PLAYERS_RETAINED_DAY_PERC = new PlaceholderKey<>(String.class, "playersStuckPercDay");
|
||||
public static final PlaceholderKey<Integer> PLAYERS_RETAINED_WEEK = new PlaceholderKey<>(Integer.class, "playersStuckWeek");
|
||||
public static final PlaceholderKey<String> PLAYERS_RETAINED_WEEK_PERC = new PlaceholderKey<>(String.class, "playersStuckPercWeek");
|
||||
public static final PlaceholderKey<Integer> PLAYERS_RETAINED_MONTH = new PlaceholderKey<>(Integer.class, "playersStuckMonth");
|
||||
public static final PlaceholderKey<String> PLAYERS_RETAINED_MONTH_PERC = new PlaceholderKey<>(String.class, "playersStuckPercMonth");
|
||||
//
|
||||
public static final PlaceholderKey<Integer> TPS_SPIKE_MONTH = new PlaceholderKey<>(Integer.class, "tpsSpikeMonth");
|
||||
public static final PlaceholderKey<Integer> TPS_SPIKE_WEEK = new PlaceholderKey<>(Integer.class, "tpsSpikeWeek");
|
||||
public static final PlaceholderKey<Integer> TPS_SPIKE_DAY = new PlaceholderKey<>(Integer.class, "tpsSpikeDay");
|
||||
public static final PlaceholderKey<Double> AVG_TPS_MONTH = new PlaceholderKey<>(Double.class, "tpsAverageMonth");
|
||||
public static final PlaceholderKey<Double> AVG_TPS_WEEK = new PlaceholderKey<>(Double.class, "tpsAverageWeek");
|
||||
public static final PlaceholderKey<Double> AVG_TPS_DAY = new PlaceholderKey<>(Double.class, "tpsAverageDay");
|
||||
public static final PlaceholderKey<Double> AVG_CPU_MONTH = new PlaceholderKey<>(Double.class, "cpuAverageMonth");
|
||||
public static final PlaceholderKey<Double> AVG_CPU_WEEK = new PlaceholderKey<>(Double.class, "cpuAverageWeek");
|
||||
public static final PlaceholderKey<Double> AVG_CPU_DAY = new PlaceholderKey<>(Double.class, "cpuAverageDay");
|
||||
public static final PlaceholderKey<Double> AVG_RAM_MONTH = new PlaceholderKey<>(Double.class, "ramAverageMonth");
|
||||
public static final PlaceholderKey<Double> AVG_RAM_WEEK = new PlaceholderKey<>(Double.class, "ramAverageWeek");
|
||||
public static final PlaceholderKey<Double> AVG_RAM_DAY = new PlaceholderKey<>(Double.class, "ramAverageDay");
|
||||
public static final PlaceholderKey<Double> AVG_ENTITY_MONTH = new PlaceholderKey<>(Double.class, "entityAverageMonth");
|
||||
public static final PlaceholderKey<Double> AVG_ENTITY_WEEK = new PlaceholderKey<>(Double.class, "entityAverageWeek");
|
||||
public static final PlaceholderKey<Double> AVG_ENTITY_DAY = new PlaceholderKey<>(Double.class, "entityAverageDay");
|
||||
public static final PlaceholderKey<Double> AVG_CHUNK_MONTH = new PlaceholderKey<>(Double.class, "chunkAverageMonth");
|
||||
public static final PlaceholderKey<Double> AVG_CHUNK_WEEK = new PlaceholderKey<>(Double.class, "chunkAverageWeek");
|
||||
public static final PlaceholderKey<Double> AVG_CHUNK_DAY = new PlaceholderKey<>(Double.class, "chunkAverageDay");
|
||||
// Data for Charts
|
||||
public static final PlaceholderKey<String> WORLD_PIE_SERIES = new PlaceholderKey<>(String.class, "worldSeries");
|
||||
public static final PlaceholderKey<String> GM_PIE_SERIES = new PlaceholderKey<>(String.class, "gmSeries");
|
||||
public static final PlaceholderKey<String> PLAYERS_ONLINE_SERIES = CommonPlaceholderKeys.PLAYERS_ONLINE_SERIES;
|
||||
public static final PlaceholderKey<String> TPS_SERIES = new PlaceholderKey<>(String.class, "tpsSeries");
|
||||
public static final PlaceholderKey<String> CPU_SERIES = new PlaceholderKey<>(String.class, "cpuSeries");
|
||||
public static final PlaceholderKey<String> RAM_SERIES = new PlaceholderKey<>(String.class, "ramSeries");
|
||||
public static final PlaceholderKey<String> ENTITY_SERIES = new PlaceholderKey<>(String.class, "entitySeries");
|
||||
public static final PlaceholderKey<String> CHUNK_SERIES = new PlaceholderKey<>(String.class, "chunkSeries");
|
||||
public static final PlaceholderKey<String> PUNCHCARD_SERIES = new PlaceholderKey<>(String.class, "punchCardSeries");
|
||||
public static final PlaceholderKey<String> WORLD_MAP_SERIES = CommonPlaceholderKeys.WORLD_MAP_SERIES;
|
||||
public static final PlaceholderKey<String> ACTIVITY_STACK_SERIES = new PlaceholderKey<>(String.class, "activityStackSeries");
|
||||
public static final PlaceholderKey<String> ACTIVITY_STACK_CATEGORIES = new PlaceholderKey<>(String.class, "activityStackCategories");
|
||||
public static final PlaceholderKey<String> ACTIVITY_PIE_SERIES = new PlaceholderKey<>(String.class, "activityPieSeries");
|
||||
public static final PlaceholderKey<String> CALENDAR_SERIES = new PlaceholderKey<>(String.class, "calendarSeries");
|
||||
// Variables used only during analysis
|
||||
public static final Key<SessionsMutator> SESSIONS_MUTATOR = CommonKeys.SESSIONS_MUTATOR;
|
||||
public static final Key<TPSMutator> TPS_MUTATOR = CommonKeys.TPS_MUTATOR;
|
||||
public static final Key<PlayersMutator> PLAYERS_MUTATOR = CommonKeys.PLAYERS_MUTATOR;
|
||||
public static final Key<PlayersOnlineResolver> PLAYERS_ONLINE_RESOLVER = new Key<>(PlayersOnlineResolver.class, "PLAYERS_ONLINE_RESOLVER");
|
||||
public static final Key<Long> PLAYTIME_TOTAL = new Key<>(Long.class, "PLAYTIME_TOTAL");
|
||||
public static final Key<Long> ANALYSIS_TIME = new Key<>(Long.class, "ANALYSIS_TIME");
|
||||
public static final Key<Long> ANALYSIS_TIME_DAY_AGO = new Key<>(Long.class, "ANALYSIS_TIME_DAY_AGO");
|
||||
public static final Key<Long> ANALYSIS_TIME_WEEK_AGO = new Key<>(Long.class, "ANALYSIS_TIME_WEEK_AGO");
|
||||
public static final Key<Long> ANALYSIS_TIME_MONTH_AGO = new Key<>(Long.class, "ANALYSIS_TIME_MONTH_AGO");
|
||||
public static final Key<Map<UUID, String>> PLAYER_NAMES = new Key<>(new Type<Map<UUID, String>>() {}, "PLAYER_NAMES");
|
||||
public static final Key<TreeMap<Long, Map<String, Set<UUID>>>> ACTIVITY_DATA = new Key<>(new Type<TreeMap<Long, Map<String, Set<UUID>>>>() {}, "ACTIVITY_DATA");
|
||||
|
||||
private AnalysisKeys() {
|
||||
/* Static variable class */
|
||||
}
|
||||
}
|
@ -0,0 +1,48 @@
|
||||
package com.djrapitops.plan.data.store.keys;
|
||||
|
||||
import com.djrapitops.plan.data.container.PlayerKill;
|
||||
import com.djrapitops.plan.data.container.Session;
|
||||
import com.djrapitops.plan.data.store.Key;
|
||||
import com.djrapitops.plan.data.store.PlaceholderKey;
|
||||
import com.djrapitops.plan.data.store.Type;
|
||||
import com.djrapitops.plan.data.store.mutators.PlayersMutator;
|
||||
import com.djrapitops.plan.data.store.mutators.SessionsMutator;
|
||||
import com.djrapitops.plan.data.store.mutators.TPSMutator;
|
||||
import com.djrapitops.plan.data.time.WorldTimes;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* Class holding Key objects that are commonly used across multiple DataContainers.
|
||||
*
|
||||
* @author Rsl1122
|
||||
*/
|
||||
public class CommonKeys {
|
||||
|
||||
private CommonKeys() {
|
||||
/* Static variable class */
|
||||
}
|
||||
|
||||
public static final Key<UUID> UUID = new Key<>(UUID.class, "uuid");
|
||||
public static final Key<UUID> SERVER_UUID = new Key<>(UUID.class, "server_uuid");
|
||||
public static final Key<String> NAME = new Key<>(String.class, "name");
|
||||
public static final PlaceholderKey<Long> REGISTERED = new PlaceholderKey<>(Long.class, "registered");
|
||||
|
||||
public static final Key<List<Session>> SESSIONS = new Key<>(new Type<List<Session>>() {}, "sessions");
|
||||
public static final Key<WorldTimes> WORLD_TIMES = new Key<>(WorldTimes.class, "world_times");
|
||||
public static final PlaceholderKey<Long> LAST_SEEN = new PlaceholderKey<>(Long.class, "lastSeen");
|
||||
|
||||
public static final Key<List<PlayerKill>> PLAYER_KILLS = new Key<>(new Type<List<PlayerKill>>() {}, "player_kills");
|
||||
public static final Key<Integer> PLAYER_KILL_COUNT = new Key<>(Integer.class, "player_kill_count");
|
||||
public static final Key<Integer> MOB_KILL_COUNT = new Key<>(Integer.class, "mob_kill_count");
|
||||
public static final Key<Integer> DEATH_COUNT = new Key<>(Integer.class, "death_count");
|
||||
|
||||
public static final Key<Boolean> BANNED = new Key<>(Boolean.class, "banned");
|
||||
public static final Key<Boolean> OPERATOR = new Key<>(Boolean.class, "operator");
|
||||
|
||||
public static final Key<SessionsMutator> SESSIONS_MUTATOR = new Key<>(SessionsMutator.class, "SESSIONS_MUTATOR");
|
||||
public static final Key<TPSMutator> TPS_MUTATOR = new Key<>(TPSMutator.class, "TPS_MUTATOR");
|
||||
public static final Key<PlayersMutator> PLAYERS_MUTATOR = new Key<>(PlayersMutator.class, "PLAYERS_MUTATOR");
|
||||
|
||||
}
|
@ -0,0 +1,40 @@
|
||||
package com.djrapitops.plan.data.store.keys;
|
||||
|
||||
import com.djrapitops.plan.data.store.PlaceholderKey;
|
||||
|
||||
/**
|
||||
* Similar to {@link CommonKeys}, but for {@link com.djrapitops.plan.data.store.PlaceholderKey}s.
|
||||
*
|
||||
* @author Rsl1122
|
||||
* @see com.djrapitops.plan.data.store.PlaceholderKey for placeholder information
|
||||
*/
|
||||
class CommonPlaceholderKeys {
|
||||
|
||||
static final PlaceholderKey<String> VERSION = new PlaceholderKey<>(String.class, "version");
|
||||
static final PlaceholderKey<Integer> TIME_ZONE = new PlaceholderKey<>(Integer.class, "timeZone");
|
||||
static final PlaceholderKey<String> PLAYERS_GRAPH_COLOR = new PlaceholderKey<>(String.class, "playersGraphColor");
|
||||
static final PlaceholderKey<String> PLAYERS_ONLINE_SERIES = new PlaceholderKey<>(String.class, "playersOnlineSeries");
|
||||
static final PlaceholderKey<String> WORLD_MAP_HIGH_COLOR = new PlaceholderKey<>(String.class, "worldMapColHigh");
|
||||
static final PlaceholderKey<String> WORLD_MAP_LOW_COLOR = new PlaceholderKey<>(String.class, "worldMapColLow");
|
||||
static final PlaceholderKey<Integer> PLAYERS_ONLINE = new PlaceholderKey<>(Integer.class, "playersOnline");
|
||||
static final PlaceholderKey<Integer> PLAYERS_TOTAL = new PlaceholderKey<>(Integer.class, "playersTotal");
|
||||
static final PlaceholderKey<String> WORLD_MAP_SERIES = new PlaceholderKey<>(String.class, "geoMapSeries");
|
||||
|
||||
static final PlaceholderKey<Integer> PLAYERS_DAY = new PlaceholderKey<>(Integer.class, "playersDay");
|
||||
static final PlaceholderKey<Integer> PLAYERS_WEEK = new PlaceholderKey<>(Integer.class, "playersWeek");
|
||||
static final PlaceholderKey<Integer> PLAYERS_MONTH = new PlaceholderKey<>(Integer.class, "playersMonth");
|
||||
static final PlaceholderKey<Integer> PLAYERS_NEW_DAY = new PlaceholderKey<>(Integer.class, "playersNewDay");
|
||||
static final PlaceholderKey<Integer> PLAYERS_NEW_WEEK = new PlaceholderKey<>(Integer.class, "playersNewWeek");
|
||||
static final PlaceholderKey<Integer> PLAYERS_NEW_MONTH = new PlaceholderKey<>(Integer.class, "playersNewMonth");
|
||||
|
||||
static final PlaceholderKey<String> REFRESH_TIME_F = new PlaceholderKey<>(String.class, "refresh");
|
||||
static final PlaceholderKey<String> LAST_PEAK_TIME_F = new PlaceholderKey<>(String.class, "lastPeakTime");
|
||||
static final PlaceholderKey<String> ALL_TIME_PEAK_TIME_F = new PlaceholderKey<>(String.class, "bestPeakTime");
|
||||
static final PlaceholderKey<String> PLAYERS_LAST_PEAK = new PlaceholderKey<>(String.class, "playersLastPeak");
|
||||
static final PlaceholderKey<String> PLAYERS_ALL_TIME_PEAK = new PlaceholderKey<>(String.class, "playersBestPeak");
|
||||
|
||||
private CommonPlaceholderKeys() {
|
||||
/* static variable class */
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,49 @@
|
||||
package com.djrapitops.plan.data.store.keys;
|
||||
|
||||
import com.djrapitops.plan.data.store.Key;
|
||||
import com.djrapitops.plan.data.store.PlaceholderKey;
|
||||
import com.djrapitops.plan.data.store.mutators.PlayersMutator;
|
||||
|
||||
/**
|
||||
* Key objects for {@link com.djrapitops.plan.data.store.containers.NetworkContainer}.
|
||||
*
|
||||
* @author Rsl1122
|
||||
* @see com.djrapitops.plan.data.store.containers.NetworkContainer for DataContainer.
|
||||
*/
|
||||
public class NetworkKeys {
|
||||
|
||||
public static final PlaceholderKey<String> VERSION = CommonPlaceholderKeys.VERSION;
|
||||
public static final PlaceholderKey<String> NETWORK_NAME = new PlaceholderKey<>(String.class, "networkName");
|
||||
public static final PlaceholderKey<Integer> TIME_ZONE = CommonPlaceholderKeys.TIME_ZONE;
|
||||
public static final PlaceholderKey<Integer> PLAYERS_ONLINE = CommonPlaceholderKeys.PLAYERS_ONLINE;
|
||||
public static final PlaceholderKey<Integer> PLAYERS_TOTAL = CommonPlaceholderKeys.PLAYERS_TOTAL;
|
||||
public static final PlaceholderKey<String> PLAYERS_GRAPH_COLOR = CommonPlaceholderKeys.PLAYERS_GRAPH_COLOR;
|
||||
public static final PlaceholderKey<String> WORLD_MAP_HIGH_COLOR = CommonPlaceholderKeys.WORLD_MAP_HIGH_COLOR;
|
||||
public static final PlaceholderKey<String> WORLD_MAP_LOW_COLOR = CommonPlaceholderKeys.WORLD_MAP_LOW_COLOR;
|
||||
|
||||
public static final PlaceholderKey<String> REFRESH_TIME_F = CommonPlaceholderKeys.REFRESH_TIME_F;
|
||||
public static final PlaceholderKey<String> RECENT_PEAK_TIME_F = CommonPlaceholderKeys.LAST_PEAK_TIME_F;
|
||||
public static final PlaceholderKey<String> ALL_TIME_PEAK_TIME_F = CommonPlaceholderKeys.ALL_TIME_PEAK_TIME_F;
|
||||
public static final PlaceholderKey<String> PLAYERS_RECENT_PEAK = CommonPlaceholderKeys.PLAYERS_LAST_PEAK;
|
||||
public static final PlaceholderKey<String> PLAYERS_ALL_TIME_PEAK = CommonPlaceholderKeys.PLAYERS_ALL_TIME_PEAK;
|
||||
public static final PlaceholderKey<Integer> PLAYERS_DAY = CommonPlaceholderKeys.PLAYERS_DAY;
|
||||
public static final PlaceholderKey<Integer> PLAYERS_WEEK = CommonPlaceholderKeys.PLAYERS_WEEK;
|
||||
public static final PlaceholderKey<Integer> PLAYERS_MONTH = CommonPlaceholderKeys.PLAYERS_MONTH;
|
||||
public static final PlaceholderKey<Integer> PLAYERS_NEW_DAY = CommonPlaceholderKeys.PLAYERS_NEW_DAY;
|
||||
public static final PlaceholderKey<Integer> PLAYERS_NEW_WEEK = CommonPlaceholderKeys.PLAYERS_NEW_WEEK;
|
||||
public static final PlaceholderKey<Integer> PLAYERS_NEW_MONTH = CommonPlaceholderKeys.PLAYERS_NEW_MONTH;
|
||||
|
||||
public static final PlaceholderKey<String> WORLD_MAP_SERIES = CommonPlaceholderKeys.WORLD_MAP_SERIES;
|
||||
public static final PlaceholderKey<String> PLAYERS_ONLINE_SERIES = CommonPlaceholderKeys.PLAYERS_ONLINE_SERIES;
|
||||
|
||||
public static final Key<Long> REFRESH_TIME = new Key<>(Long.class, "REFRESH_TIME");
|
||||
public static final Key<Long> REFRESH_TIME_DAY_AGO = new Key<>(Long.class, "REFRESH_TIME_DAY_AGO");
|
||||
public static final Key<Long> REFRESH_TIME_WEEK_AGO = new Key<>(Long.class, "REFRESH_TIME_WEEK_AGO");
|
||||
public static final Key<Long> REFRESH_TIME_MONTH_AGO = new Key<>(Long.class, "REFRESH_TIME_MONTH_AGO");
|
||||
public static final Key<PlayersMutator> PLAYERS_MUTATOR = CommonKeys.PLAYERS_MUTATOR;
|
||||
|
||||
private NetworkKeys() {
|
||||
/* static variable class */
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,38 @@
|
||||
package com.djrapitops.plan.data.store.keys;
|
||||
|
||||
import com.djrapitops.plan.data.container.PlayerKill;
|
||||
import com.djrapitops.plan.data.container.Session;
|
||||
import com.djrapitops.plan.data.store.Key;
|
||||
import com.djrapitops.plan.data.store.containers.PerServerContainer;
|
||||
import com.djrapitops.plan.data.time.WorldTimes;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Key objects for PerServerContainer container.
|
||||
*
|
||||
* @author Rsl1122
|
||||
* @see com.djrapitops.plan.system.database.databases.sql.operation.SQLFetchOps For Suppliers for each key
|
||||
* @see PerServerContainer For the DataContainer.
|
||||
*/
|
||||
public class PerServerKeys {
|
||||
|
||||
private PerServerKeys() {
|
||||
/* Static variable class */
|
||||
}
|
||||
|
||||
public static final Key<Long> REGISTERED = CommonKeys.REGISTERED;
|
||||
|
||||
public static final Key<List<Session>> SESSIONS = CommonKeys.SESSIONS;
|
||||
public static final Key<WorldTimes> WORLD_TIMES = CommonKeys.WORLD_TIMES;
|
||||
|
||||
public static final Key<List<PlayerKill>> PLAYER_KILLS = CommonKeys.PLAYER_KILLS;
|
||||
public static final Key<Integer> PLAYER_KILL_COUNT = CommonKeys.PLAYER_KILL_COUNT;
|
||||
public static final Key<Integer> MOB_KILL_COUNT = CommonKeys.MOB_KILL_COUNT;
|
||||
public static final Key<Integer> DEATH_COUNT = CommonKeys.DEATH_COUNT;
|
||||
public static final Key<Long> LAST_SEEN = CommonKeys.LAST_SEEN;
|
||||
|
||||
public static final Key<Boolean> BANNED = CommonKeys.BANNED;
|
||||
public static final Key<Boolean> OPERATOR = CommonKeys.OPERATOR;
|
||||
|
||||
}
|
@ -0,0 +1,52 @@
|
||||
package com.djrapitops.plan.data.store.keys;
|
||||
|
||||
import com.djrapitops.plan.data.container.GeoInfo;
|
||||
import com.djrapitops.plan.data.container.PlayerKill;
|
||||
import com.djrapitops.plan.data.container.Session;
|
||||
import com.djrapitops.plan.data.store.Key;
|
||||
import com.djrapitops.plan.data.store.PlaceholderKey;
|
||||
import com.djrapitops.plan.data.store.Type;
|
||||
import com.djrapitops.plan.data.store.containers.PerServerContainer;
|
||||
import com.djrapitops.plan.data.store.objects.Nickname;
|
||||
import com.djrapitops.plan.data.time.WorldTimes;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* Class that holds Key objects for PlayerContainer.
|
||||
*
|
||||
* @author Rsl1122
|
||||
* @see com.djrapitops.plan.system.database.databases.sql.operation.SQLFetchOps For Suppliers for each key
|
||||
* @see com.djrapitops.plan.data.store.containers.PlayerContainer For DataContainer.
|
||||
*/
|
||||
public class PlayerKeys {
|
||||
|
||||
private PlayerKeys() {
|
||||
/* Static variable class */
|
||||
}
|
||||
|
||||
public static final Key<UUID> UUID = CommonKeys.UUID;
|
||||
public static final Key<String> NAME = CommonKeys.NAME;
|
||||
public static final Key<List<Nickname>> NICKNAMES = new Key<>(new Type<List<Nickname>>() {}, "nicknames");
|
||||
|
||||
public static final PlaceholderKey<Long> REGISTERED = CommonKeys.REGISTERED;
|
||||
|
||||
public static final Key<Integer> KICK_COUNT = new Key<>(Integer.class, "kick_count");
|
||||
public static final Key<List<GeoInfo>> GEO_INFO = new Key<>(new Type<List<GeoInfo>>() {}, "geo_info");
|
||||
|
||||
public static final Key<Session> ACTIVE_SESSION = new Key<>(Session.class, "active_session");
|
||||
public static final Key<List<Session>> SESSIONS = CommonKeys.SESSIONS;
|
||||
public static final Key<WorldTimes> WORLD_TIMES = CommonKeys.WORLD_TIMES;
|
||||
|
||||
public static final Key<List<PlayerKill>> PLAYER_KILLS = CommonKeys.PLAYER_KILLS;
|
||||
public static final Key<Integer> PLAYER_KILL_COUNT = CommonKeys.PLAYER_KILL_COUNT;
|
||||
public static final Key<Integer> MOB_KILL_COUNT = CommonKeys.MOB_KILL_COUNT;
|
||||
public static final Key<Integer> DEATH_COUNT = CommonKeys.DEATH_COUNT;
|
||||
public static final Key<PerServerContainer> PER_SERVER = new Key<>(PerServerContainer.class, "per_server_data");
|
||||
public static final PlaceholderKey<Long> LAST_SEEN = CommonKeys.LAST_SEEN;
|
||||
|
||||
public static final Key<Boolean> BANNED = CommonKeys.BANNED;
|
||||
public static final Key<Boolean> OPERATOR = CommonKeys.OPERATOR;
|
||||
|
||||
}
|
@ -0,0 +1,48 @@
|
||||
package com.djrapitops.plan.data.store.keys;
|
||||
|
||||
import com.djrapitops.plan.data.container.PlayerKill;
|
||||
import com.djrapitops.plan.data.container.Session;
|
||||
import com.djrapitops.plan.data.container.TPS;
|
||||
import com.djrapitops.plan.data.store.Key;
|
||||
import com.djrapitops.plan.data.store.Type;
|
||||
import com.djrapitops.plan.data.store.containers.PlayerContainer;
|
||||
import com.djrapitops.plan.data.store.objects.DateObj;
|
||||
import com.djrapitops.plan.data.time.WorldTimes;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* Keys for the ServerContainer.
|
||||
*
|
||||
* @author Rsl1122
|
||||
* @see com.djrapitops.plan.system.database.databases.sql.operation.SQLFetchOps For Suppliers for each key
|
||||
* @see com.djrapitops.plan.data.store.containers.ServerContainer For DataContainer.
|
||||
*/
|
||||
public class ServerKeys {
|
||||
|
||||
private ServerKeys() {
|
||||
/* Static variable class */
|
||||
}
|
||||
|
||||
public static final Key<UUID> SERVER_UUID = CommonKeys.SERVER_UUID;
|
||||
public static final Key<String> NAME = CommonKeys.NAME;
|
||||
|
||||
public static final Key<List<PlayerContainer>> PLAYERS = new Key<>(new Type<List<PlayerContainer>>() {}, "players");
|
||||
public static final Key<List<PlayerContainer>> OPERATORS = new Key<>(new Type<List<PlayerContainer>>() {}, "operators");
|
||||
public static final Key<Integer> PLAYER_COUNT = new Key<>(Integer.class, "player_count");
|
||||
|
||||
public static final Key<List<Session>> SESSIONS = CommonKeys.SESSIONS;
|
||||
public static final Key<WorldTimes> WORLD_TIMES = CommonKeys.WORLD_TIMES;
|
||||
|
||||
public static final Key<List<PlayerKill>> PLAYER_KILLS = CommonKeys.PLAYER_KILLS;
|
||||
public static final Key<Integer> PLAYER_KILL_COUNT = CommonKeys.PLAYER_KILL_COUNT;
|
||||
public static final Key<Integer> MOB_KILL_COUNT = CommonKeys.MOB_KILL_COUNT;
|
||||
public static final Key<Integer> DEATH_COUNT = CommonKeys.DEATH_COUNT;
|
||||
|
||||
public static final Key<List<TPS>> TPS = new Key<>(new Type<List<TPS>>() {}, "tps");
|
||||
public static final Key<DateObj<Integer>> ALL_TIME_PEAK_PLAYERS = new Key<>(new Type<DateObj<Integer>>() {}, "all_time_peak_players");
|
||||
public static final Key<DateObj<Integer>> RECENT_PEAK_PLAYERS = new Key<>(new Type<DateObj<Integer>>() {}, "recent_peak_players");
|
||||
public static final Key<Map<String, Integer>> COMMAND_USAGE = new Key<>(new Type<Map<String, Integer>>() {}, "command_usage");
|
||||
}
|
@ -0,0 +1,37 @@
|
||||
package com.djrapitops.plan.data.store.keys;
|
||||
|
||||
import com.djrapitops.plan.data.container.PlayerKill;
|
||||
import com.djrapitops.plan.data.store.Key;
|
||||
import com.djrapitops.plan.data.time.WorldTimes;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* Class holding Key objects for Session (DataContainer).
|
||||
*
|
||||
* @author Rsl1122
|
||||
* @see com.djrapitops.plan.data.container.Session for DataContainer.
|
||||
*/
|
||||
public class SessionKeys {
|
||||
|
||||
public static final Key<Integer> DB_ID = new Key<>(Integer.class, "db_id");
|
||||
public static final Key<UUID> UUID = CommonKeys.UUID;
|
||||
public static final Key<UUID> SERVER_UUID = CommonKeys.SERVER_UUID;
|
||||
|
||||
public static final Key<Long> START = new Key<>(Long.class, "start");
|
||||
public static final Key<Long> END = new Key<>(Long.class, "end");
|
||||
public static final Key<Long> LENGTH = new Key<>(Long.class, "length");
|
||||
public static final Key<Long> AFK_TIME = new Key<>(Long.class, "afk_time");
|
||||
public static final Key<Long> ACTIVE_TIME = new Key<>(Long.class, "active_time");
|
||||
public static final Key<WorldTimes> WORLD_TIMES = CommonKeys.WORLD_TIMES;
|
||||
public static final Key<List<PlayerKill>> PLAYER_KILLS = CommonKeys.PLAYER_KILLS;
|
||||
public static final Key<Integer> PLAYER_KILL_COUNT = CommonKeys.PLAYER_KILL_COUNT;
|
||||
public static final Key<Integer> MOB_KILL_COUNT = CommonKeys.MOB_KILL_COUNT;
|
||||
public static final Key<Integer> DEATH_COUNT = CommonKeys.DEATH_COUNT;
|
||||
|
||||
private SessionKeys() {
|
||||
/* Static variable class */
|
||||
}
|
||||
|
||||
}
|
@ -1,20 +1,21 @@
|
||||
package com.djrapitops.plan.data.calculation;
|
||||
package com.djrapitops.plan.data.store.mutators;
|
||||
|
||||
import com.djrapitops.plan.data.PlayerProfile;
|
||||
import com.djrapitops.plan.data.container.Session;
|
||||
import com.djrapitops.plan.data.store.containers.DataContainer;
|
||||
import com.djrapitops.plan.data.store.keys.PlayerKeys;
|
||||
import com.djrapitops.plan.system.settings.Settings;
|
||||
import com.djrapitops.plan.utilities.FormatUtils;
|
||||
import com.djrapitops.plugin.api.TimeAmount;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.Optional;
|
||||
|
||||
public class ActivityIndex {
|
||||
|
||||
private final double value;
|
||||
|
||||
public ActivityIndex(PlayerProfile player, long date) {
|
||||
value = calculate(player, date);
|
||||
public ActivityIndex(DataContainer container, long date) {
|
||||
value = calculate(container, date);
|
||||
}
|
||||
|
||||
public static String[] getGroups() {
|
||||
@ -29,7 +30,7 @@ public class ActivityIndex {
|
||||
return value <= 0 ? 1 : value;
|
||||
}
|
||||
|
||||
private double calculate(PlayerProfile player, long date) {
|
||||
private double calculate(DataContainer container, long date) {
|
||||
long week = TimeAmount.WEEK.ms();
|
||||
long weekAgo = date - week;
|
||||
long twoWeeksAgo = date - 2L * week;
|
||||
@ -38,24 +39,33 @@ public class ActivityIndex {
|
||||
long activePlayThreshold = loadSetting(Settings.ACTIVE_PLAY_THRESHOLD.getNumber() * TimeAmount.MINUTE.ms());
|
||||
int activeLoginThreshold = loadSetting(Settings.ACTIVE_LOGIN_THRESHOLD.getNumber());
|
||||
|
||||
List<Session> sessionsWeek = player.getSessions(weekAgo, date).collect(Collectors.toList());
|
||||
List<Session> sessionsWeek2 = player.getSessions(twoWeeksAgo, weekAgo).collect(Collectors.toList());
|
||||
List<Session> sessionsWeek3 = player.getSessions(threeWeeksAgo, twoWeeksAgo).collect(Collectors.toList());
|
||||
Optional<List<Session>> sessionsValue = container.getValue(PlayerKeys.SESSIONS);
|
||||
if (!sessionsValue.isPresent()) {
|
||||
return 0.0;
|
||||
}
|
||||
SessionsMutator sessionsMutator = new SessionsMutator(sessionsValue.get());
|
||||
if (sessionsMutator.all().isEmpty()) {
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
SessionsMutator weekOne = sessionsMutator.filterSessionsBetween(weekAgo, date);
|
||||
SessionsMutator weekTwo = sessionsMutator.filterSessionsBetween(twoWeeksAgo, weekAgo);
|
||||
SessionsMutator weekThree = sessionsMutator.filterSessionsBetween(threeWeeksAgo, twoWeeksAgo);
|
||||
|
||||
// Playtime per week multipliers, max out to avoid too high values.
|
||||
double max = 4.0;
|
||||
|
||||
long playtimeWeek = PlayerProfile.getActivePlaytime(sessionsWeek.stream());
|
||||
long playtimeWeek = weekOne.toActivePlaytime();
|
||||
double weekPlay = (playtimeWeek * 1.0 / activePlayThreshold);
|
||||
if (weekPlay > max) {
|
||||
weekPlay = max;
|
||||
}
|
||||
long playtimeWeek2 = PlayerProfile.getActivePlaytime(sessionsWeek2.stream());
|
||||
long playtimeWeek2 = weekTwo.toActivePlaytime();
|
||||
double week2Play = (playtimeWeek2 * 1.0 / activePlayThreshold);
|
||||
if (week2Play > max) {
|
||||
week2Play = max;
|
||||
}
|
||||
long playtimeWeek3 = PlayerProfile.getActivePlaytime(sessionsWeek3.stream());
|
||||
long playtimeWeek3 = weekThree.toActivePlaytime();
|
||||
double week3Play = (playtimeWeek3 * 1.0 / activePlayThreshold);
|
||||
if (week3Play > max) {
|
||||
week3Play = max;
|
||||
@ -79,9 +89,9 @@ public class ActivityIndex {
|
||||
|
||||
double playAvg = (weekPlay + week2Play + week3Play) / 3.0;
|
||||
|
||||
double weekLogin = sessionsWeek.size() >= activeLoginThreshold ? 1.0 : 0.5;
|
||||
double week2Login = sessionsWeek2.size() >= activeLoginThreshold ? 1.0 : 0.5;
|
||||
double week3Login = sessionsWeek3.size() >= activeLoginThreshold ? 1.0 : 0.5;
|
||||
double weekLogin = weekOne.count() >= activeLoginThreshold ? 1.0 : 0.5;
|
||||
double week2Login = weekTwo.count() >= activeLoginThreshold ? 1.0 : 0.5;
|
||||
double week3Login = weekThree.count() >= activeLoginThreshold ? 1.0 : 0.5;
|
||||
|
||||
double loginMultiplier = 1.0;
|
||||
double loginTotal = weekLogin + week2Login + week3Login;
|
@ -0,0 +1,35 @@
|
||||
package com.djrapitops.plan.data.store.mutators;
|
||||
|
||||
import com.djrapitops.plan.data.store.containers.DataContainer;
|
||||
import com.djrapitops.plan.data.store.keys.ServerKeys;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Mutator for Command Usage Map objects.
|
||||
* <p>
|
||||
* Can be used to easily get different values about the map.
|
||||
*
|
||||
* @author Rsl1122
|
||||
*/
|
||||
public class CommandUseMutator {
|
||||
|
||||
private Map<String, Integer> commandUsage;
|
||||
|
||||
public CommandUseMutator(Map<String, Integer> commandUsage) {
|
||||
this.commandUsage = commandUsage;
|
||||
}
|
||||
|
||||
public static CommandUseMutator forContainer(DataContainer container) {
|
||||
return new CommandUseMutator(container.getValue(ServerKeys.COMMAND_USAGE).orElse(new HashMap<>()));
|
||||
}
|
||||
|
||||
public int commandUsageCount() {
|
||||
int total = 0;
|
||||
for (Integer value : commandUsage.values()) {
|
||||
total += value;
|
||||
}
|
||||
return total;
|
||||
}
|
||||
}
|
@ -0,0 +1,42 @@
|
||||
package com.djrapitops.plan.data.store.mutators;
|
||||
|
||||
import com.djrapitops.plan.data.container.GeoInfo;
|
||||
import com.djrapitops.plan.data.store.containers.DataContainer;
|
||||
import com.djrapitops.plan.data.store.keys.PlayerKeys;
|
||||
import com.djrapitops.plan.utilities.comparators.GeoInfoComparator;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
/**
|
||||
* Mutator for lists of GeoInfo objects.
|
||||
*
|
||||
* @author Rsl1122
|
||||
* @see GeoInfo for the object.
|
||||
*/
|
||||
public class GeoInfoMutator {
|
||||
|
||||
private final List<GeoInfo> geoInfo;
|
||||
|
||||
public static GeoInfoMutator forContainer(DataContainer container) {
|
||||
return new GeoInfoMutator(container.getValue(PlayerKeys.GEO_INFO).orElse(new ArrayList<>()));
|
||||
}
|
||||
|
||||
public GeoInfoMutator(List<GeoInfo> geoInfo) {
|
||||
this.geoInfo = geoInfo;
|
||||
}
|
||||
|
||||
public GeoInfoMutator forCollection(Collection<GeoInfo> collection) {
|
||||
return new GeoInfoMutator(new ArrayList<>(collection));
|
||||
}
|
||||
|
||||
public Optional<GeoInfo> mostRecent() {
|
||||
if (geoInfo.isEmpty()) {
|
||||
return Optional.empty();
|
||||
}
|
||||
geoInfo.sort(new GeoInfoComparator());
|
||||
return Optional.of(geoInfo.get(0));
|
||||
}
|
||||
}
|
@ -2,55 +2,46 @@
|
||||
* License is provided in the jar as LICENSE also here:
|
||||
* https://github.com/Rsl1122/Plan-PlayerAnalytics/blob/master/Plan/src/main/resources/LICENSE
|
||||
*/
|
||||
package com.djrapitops.plan.data.calculation;
|
||||
package com.djrapitops.plan.data.store.mutators;
|
||||
|
||||
import com.djrapitops.plan.data.PlayerProfile;
|
||||
import com.djrapitops.plan.data.ServerProfile;
|
||||
import com.djrapitops.plan.data.container.StickyData;
|
||||
import com.djrapitops.plan.data.container.TPS;
|
||||
import com.djrapitops.plan.data.store.Key;
|
||||
import com.djrapitops.plan.data.store.containers.AnalysisContainer;
|
||||
import com.djrapitops.plan.data.store.containers.PlayerContainer;
|
||||
import com.djrapitops.plan.data.store.keys.AnalysisKeys;
|
||||
import com.djrapitops.plan.data.store.mutators.formatting.Formatter;
|
||||
import com.djrapitops.plan.data.store.mutators.formatting.Formatters;
|
||||
import com.djrapitops.plan.system.settings.Settings;
|
||||
import com.djrapitops.plan.utilities.FormatUtils;
|
||||
import com.djrapitops.plan.utilities.analysis.MathUtils;
|
||||
import com.djrapitops.plan.utilities.html.Html;
|
||||
import com.djrapitops.plugin.api.TimeAmount;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* Class in charge of Server health analysis.
|
||||
* Server Health analysis mutator.
|
||||
*
|
||||
* @author Rsl1122
|
||||
*/
|
||||
public class HealthNotes {
|
||||
public class HealthInformation {
|
||||
|
||||
private final AnalysisContainer analysisContainer;
|
||||
private final List<String> notes;
|
||||
private final AnalysisData analysisData;
|
||||
private final SortedMap<Long, Map<String, Set<UUID>>> activityData;
|
||||
private final List<TPS> tpsDataMonth;
|
||||
private final long now;
|
||||
private final long fourWeeksAgo;
|
||||
private double serverHealth;
|
||||
private long fourWeeksAgo;
|
||||
|
||||
public HealthNotes(AnalysisData analysisData, SortedMap<Long, Map<String, Set<UUID>>> activityData, List<TPS> tpsDataMonth, long now) {
|
||||
public HealthInformation(AnalysisContainer analysisContainer) {
|
||||
this.analysisContainer = analysisContainer;
|
||||
this.notes = new ArrayList<>();
|
||||
|
||||
now = analysisContainer.getUnsafe(AnalysisKeys.ANALYSIS_TIME);
|
||||
fourWeeksAgo = analysisContainer.getUnsafe(AnalysisKeys.ANALYSIS_TIME_MONTH_AGO);
|
||||
|
||||
serverHealth = 100.0;
|
||||
|
||||
this.analysisData = analysisData;
|
||||
this.activityData = activityData;
|
||||
this.tpsDataMonth = tpsDataMonth;
|
||||
this.now = now;
|
||||
this.fourWeeksAgo = now - TimeAmount.WEEK.ms() * 4L;
|
||||
calculate();
|
||||
}
|
||||
|
||||
public void analyzeHealth() {
|
||||
activityChangeNote();
|
||||
newPlayerNote();
|
||||
activePlayerPlaytimeChange();
|
||||
lowPerformance();
|
||||
}
|
||||
|
||||
public String parse() {
|
||||
public String toHtml() {
|
||||
StringBuilder healthNoteBuilder = new StringBuilder();
|
||||
for (String healthNote : notes) {
|
||||
healthNoteBuilder.append(healthNote);
|
||||
@ -58,11 +49,20 @@ public class HealthNotes {
|
||||
return healthNoteBuilder.toString();
|
||||
}
|
||||
|
||||
private void calculate() {
|
||||
activityChangeNote();
|
||||
newPlayerNote();
|
||||
activePlayerPlaytimeChange();
|
||||
lowPerformance();
|
||||
}
|
||||
|
||||
public double getServerHealth() {
|
||||
return serverHealth;
|
||||
}
|
||||
|
||||
private void activityChangeNote() {
|
||||
TreeMap<Long, Map<String, Set<UUID>>> activityData = analysisContainer.getUnsafe(AnalysisKeys.ACTIVITY_DATA);
|
||||
|
||||
Map<String, Set<UUID>> activityNow = activityData.getOrDefault(now, new HashMap<>());
|
||||
Set<UUID> veryActiveNow = activityNow.getOrDefault("Very Active", new HashSet<>());
|
||||
Set<UUID> activeNow = activityNow.getOrDefault("Active", new HashSet<>());
|
||||
@ -126,7 +126,14 @@ public class HealthNotes {
|
||||
}
|
||||
|
||||
private void newPlayerNote() {
|
||||
double avgOnlineOnRegister = MathUtils.averageDouble(analysisData.getStickyMonthData().stream().map(StickyData::getOnlineOnJoin));
|
||||
Key<PlayersMutator> newMonth = new Key<>(PlayersMutator.class, "NEW_MONTH");
|
||||
PlayersMutator newPlayersMonth = analysisContainer.getValue(newMonth).orElse(new PlayersMutator(new ArrayList<>()));
|
||||
PlayersOnlineResolver onlineResolver = analysisContainer.getUnsafe(AnalysisKeys.PLAYERS_ONLINE_RESOLVER);
|
||||
|
||||
double avgOnlineOnRegister = newPlayersMonth.registerDates().stream()
|
||||
.mapToInt(date -> onlineResolver.getOnlineOn(date).orElse(-1))
|
||||
.filter(value -> value != -1)
|
||||
.average().orElse(0);
|
||||
if (avgOnlineOnRegister >= 1) {
|
||||
notes.add("<p>" + Html.GREEN_THUMB.parse() + " New Players have players to play with when they join ("
|
||||
+ FormatUtils.cutDecimals(avgOnlineOnRegister) + " on average)</p>");
|
||||
@ -136,40 +143,39 @@ public class HealthNotes {
|
||||
serverHealth -= 5;
|
||||
}
|
||||
|
||||
long newM = analysisData.value("newM");
|
||||
long stuckPerM = analysisData.value("stuckPerM");
|
||||
long playersNewMonth = analysisContainer.getValue(AnalysisKeys.PLAYERS_NEW_MONTH).orElse(0);
|
||||
long playersRetainedMonth = analysisContainer.getValue(AnalysisKeys.PLAYERS_RETAINED_MONTH).orElse(0);
|
||||
|
||||
if (newM != 0) {
|
||||
double stuckPerc = MathUtils.averageDouble(stuckPerM, newM) * 100;
|
||||
if (stuckPerc >= 25) {
|
||||
notes.add("<p>" + Html.GREEN_THUMB.parse() + " " + FormatUtils.cutDecimals(stuckPerc)
|
||||
+ "% of new players have stuck around (" + stuckPerM + "/" + newM + ")</p>");
|
||||
if (playersNewMonth != 0) {
|
||||
double retainPercentage = playersRetainedMonth / playersNewMonth;
|
||||
if (retainPercentage >= 0.25) {
|
||||
notes.add("<p>" + Html.GREEN_THUMB.parse() + " " + Formatters.percentage().apply(retainPercentage)
|
||||
+ " of new players have stuck around (" + playersRetainedMonth + "/" + playersNewMonth + ")</p>");
|
||||
} else {
|
||||
notes.add("<p>" + Html.YELLOW_FLAG.parse() + " " + FormatUtils.cutDecimals(stuckPerc)
|
||||
+ "% of new players have stuck around (" + stuckPerM + "/" + newM + ")</p>");
|
||||
notes.add("<p>" + Html.YELLOW_FLAG.parse() + " " + Formatters.percentage().apply(retainPercentage)
|
||||
+ "% of new players have stuck around (" + playersRetainedMonth + "/" + playersNewMonth + ")</p>");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void activePlayerPlaytimeChange() {
|
||||
List<PlayerProfile> currentActivePlayers = analysisData.getPlayers().stream()
|
||||
.filter(player -> player.getActivityIndex(now).getValue() >= 1.75)
|
||||
.collect(Collectors.toList());
|
||||
|
||||
long twoWeeksAgo = now - TimeAmount.WEEK.ms() * 2L;
|
||||
PlayersMutator currentlyActive = analysisContainer.getUnsafe(AnalysisKeys.PLAYERS_MUTATOR).filterActive(now, 1.75);
|
||||
long twoWeeksAgo = (now - (now - fourWeeksAgo)) / 2L;
|
||||
|
||||
long totalFourToTwoWeeks = 0;
|
||||
long totalLastTwoWeeks = 0;
|
||||
for (PlayerProfile activePlayer : currentActivePlayers) {
|
||||
totalFourToTwoWeeks += activePlayer.getPlaytime(analysisData.value("monthAgo"), twoWeeksAgo);
|
||||
totalLastTwoWeeks += activePlayer.getPlaytime(twoWeeksAgo, now);
|
||||
for (PlayerContainer activePlayer : currentlyActive.all()) {
|
||||
totalFourToTwoWeeks += SessionsMutator.forContainer(activePlayer)
|
||||
.filterSessionsBetween(fourWeeksAgo, twoWeeksAgo).toActivePlaytime();
|
||||
totalLastTwoWeeks += SessionsMutator.forContainer(activePlayer)
|
||||
.filterSessionsBetween(twoWeeksAgo, now).toActivePlaytime();
|
||||
}
|
||||
int currentlyActive = currentActivePlayers.size();
|
||||
if (currentlyActive != 0) {
|
||||
long avgFourToTwoWeeks = MathUtils.averageLong(totalFourToTwoWeeks, currentlyActive);
|
||||
long avgLastTwoWeeks = MathUtils.averageLong(totalLastTwoWeeks, currentlyActive);
|
||||
String avgLastTwoWeeksString = FormatUtils.formatTimeAmount(avgLastTwoWeeks);
|
||||
String avgFourToTwoWeeksString = FormatUtils.formatTimeAmount(avgFourToTwoWeeks);
|
||||
int activeCount = currentlyActive.count();
|
||||
if (activeCount != 0) {
|
||||
long avgFourToTwoWeeks = totalFourToTwoWeeks / (long) activeCount;
|
||||
long avgLastTwoWeeks = totalLastTwoWeeks / (long) activeCount;
|
||||
String avgLastTwoWeeksString = Formatters.timeAmount().apply(avgLastTwoWeeks);
|
||||
String avgFourToTwoWeeksString = Formatters.timeAmount().apply(avgFourToTwoWeeks);
|
||||
if (avgFourToTwoWeeks >= avgLastTwoWeeks) {
|
||||
notes.add("<p>" + Html.GREEN_THUMB.parse() + " Active players seem to have things to do (Played "
|
||||
+ avgLastTwoWeeksString + " vs " + avgFourToTwoWeeksString
|
||||
@ -188,9 +194,11 @@ public class HealthNotes {
|
||||
}
|
||||
|
||||
private void lowPerformance() {
|
||||
long serverDownTime = ServerProfile.serverDownTime(tpsDataMonth);
|
||||
double aboveThreshold = ServerProfile.aboveLowThreshold(tpsDataMonth);
|
||||
long tpsSpikeMonth = analysisData.value("tpsSpikeMonth");
|
||||
Key<TPSMutator> tpsMonth = new Key<>(TPSMutator.class, "TPS_MONTH");
|
||||
TPSMutator tpsMutator = analysisContainer.getUnsafe(tpsMonth);
|
||||
long serverDownTime = tpsMutator.serverDownTime();
|
||||
double aboveThreshold = tpsMutator.percentageTPSAboveLowThreshold();
|
||||
long tpsSpikeMonth = analysisContainer.getValue(AnalysisKeys.TPS_SPIKE_MONTH).orElse(0);
|
||||
|
||||
String avgLowThresholdString = " ";
|
||||
if (aboveThreshold >= 0.96) {
|
||||
@ -224,16 +232,17 @@ public class HealthNotes {
|
||||
serverHealth *= 0.8;
|
||||
}
|
||||
|
||||
Formatter<Long> formatter = Formatters.timeAmount();
|
||||
if (serverDownTime <= TimeAmount.DAY.ms()) {
|
||||
notes.add("<p>" + Html.GREEN_THUMB.parse() + " Total Server downtime (No Data) was "
|
||||
+ FormatUtils.formatTimeAmount(serverDownTime) + "</p>");
|
||||
+ formatter.apply(serverDownTime) + "</p>");
|
||||
} else if (serverDownTime <= TimeAmount.WEEK.ms()) {
|
||||
notes.add("<p>" + Html.YELLOW_FLAG.parse() + " Total Server downtime (No Data) was "
|
||||
+ FormatUtils.formatTimeAmount(serverDownTime) + "</p>");
|
||||
+ formatter.apply(serverDownTime) + "</p>");
|
||||
serverHealth *= (TimeAmount.WEEK.ms() - serverDownTime) * 1.0 / TimeAmount.WEEK.ms();
|
||||
} else {
|
||||
notes.add("<p>" + Html.RED_WARN.parse() + " Total Server downtime (No Data) was "
|
||||
+ FormatUtils.formatTimeAmount(serverDownTime) + "</p>");
|
||||
+ formatter.apply(serverDownTime) + "</p>");
|
||||
serverHealth *= (TimeAmount.MONTH.ms() - serverDownTime) * 1.0 / TimeAmount.MONTH.ms();
|
||||
}
|
||||
}
|
||||
@ -247,4 +256,4 @@ public class HealthNotes {
|
||||
regularNewCompareSet.removeAll(veryActiveFWAG);
|
||||
return regularNewCompareSet.size();
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,100 @@
|
||||
package com.djrapitops.plan.data.store.mutators;
|
||||
|
||||
import com.djrapitops.plan.data.container.Session;
|
||||
import com.djrapitops.plan.data.store.containers.DataContainer;
|
||||
import com.djrapitops.plan.data.store.containers.PerServerContainer;
|
||||
import com.djrapitops.plan.data.store.keys.PerServerKeys;
|
||||
import com.djrapitops.plan.data.store.keys.PlayerKeys;
|
||||
import com.djrapitops.plan.data.time.WorldTimes;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* Mutator for PerServerContainer object.
|
||||
*
|
||||
* @author Rsl1122
|
||||
*/
|
||||
public class PerServerDataMutator {
|
||||
|
||||
private final PerServerContainer data;
|
||||
|
||||
public PerServerDataMutator(PerServerContainer data) {
|
||||
this.data = data;
|
||||
}
|
||||
|
||||
public static PerServerDataMutator forContainer(DataContainer container) {
|
||||
return new PerServerDataMutator(container.getValue(PlayerKeys.PER_SERVER).orElse(new PerServerContainer()));
|
||||
}
|
||||
|
||||
public List<Session> flatMapSessions() {
|
||||
return data.values().stream()
|
||||
.filter(container -> container.supports(PerServerKeys.SESSIONS))
|
||||
.map(container -> container.getUnsafe(PerServerKeys.SESSIONS))
|
||||
.flatMap(Collection::stream)
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
public WorldTimes flatMapWorldTimes() {
|
||||
WorldTimes total = new WorldTimes(new HashMap<>());
|
||||
|
||||
for (DataContainer container : data.values()) {
|
||||
if (container.supports(PerServerKeys.WORLD_TIMES)) {
|
||||
WorldTimes worldTimes = container.getUnsafe(PerServerKeys.WORLD_TIMES);
|
||||
total.add(worldTimes);
|
||||
}
|
||||
}
|
||||
|
||||
return total;
|
||||
}
|
||||
|
||||
public Map<UUID, WorldTimes> worldTimesPerServer() {
|
||||
Map<UUID, WorldTimes> timesMap = new HashMap<>();
|
||||
for (Map.Entry<UUID, DataContainer> entry : data.entrySet()) {
|
||||
DataContainer container = entry.getValue();
|
||||
timesMap.put(entry.getKey(), container.getValue(PerServerKeys.WORLD_TIMES).orElse(new WorldTimes(new HashMap<>())));
|
||||
}
|
||||
return timesMap;
|
||||
}
|
||||
|
||||
public UUID favoriteServer() {
|
||||
long max = 0;
|
||||
UUID maxServer = null;
|
||||
|
||||
for (Map.Entry<UUID, DataContainer> entry : data.entrySet()) {
|
||||
long total = SessionsMutator.forContainer(entry.getValue()).toPlaytime();
|
||||
if (total > max) {
|
||||
max = total;
|
||||
maxServer = entry.getKey();
|
||||
}
|
||||
}
|
||||
|
||||
return maxServer;
|
||||
}
|
||||
|
||||
public Map<UUID, List<Session>> sessionsPerServer() {
|
||||
Map<UUID, List<Session>> sessionMap = new HashMap<>();
|
||||
for (Map.Entry<UUID, DataContainer> entry : data.entrySet()) {
|
||||
sessionMap.put(entry.getKey(), entry.getValue().getValue(PerServerKeys.SESSIONS).orElse(new ArrayList<>()));
|
||||
}
|
||||
return sessionMap;
|
||||
}
|
||||
|
||||
public boolean isBanned() {
|
||||
for (DataContainer container : data.values()) {
|
||||
if (container.getValue(PlayerKeys.BANNED).orElse(false)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean isOperator() {
|
||||
for (DataContainer container : data.values()) {
|
||||
if (container.getValue(PlayerKeys.OPERATOR).orElse(false)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
@ -0,0 +1,216 @@
|
||||
package com.djrapitops.plan.data.store.mutators;
|
||||
|
||||
import com.djrapitops.plan.data.container.GeoInfo;
|
||||
import com.djrapitops.plan.data.container.Session;
|
||||
import com.djrapitops.plan.data.store.containers.DataContainer;
|
||||
import com.djrapitops.plan.data.store.containers.PlayerContainer;
|
||||
import com.djrapitops.plan.data.store.keys.PlayerKeys;
|
||||
import com.djrapitops.plan.data.store.keys.ServerKeys;
|
||||
import com.djrapitops.plan.data.store.keys.SessionKeys;
|
||||
import com.djrapitops.plan.data.store.mutators.formatting.Formatters;
|
||||
import com.djrapitops.plan.utilities.analysis.AnalysisUtils;
|
||||
import com.djrapitops.plugin.api.TimeAmount;
|
||||
import com.djrapitops.plugin.api.utility.log.Log;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* Mutator for a bunch of {@link com.djrapitops.plan.data.store.containers.PlayerContainer}s.
|
||||
*
|
||||
* @author Rsl1122
|
||||
*/
|
||||
public class PlayersMutator {
|
||||
|
||||
private List<PlayerContainer> players;
|
||||
|
||||
public PlayersMutator(List<PlayerContainer> players) {
|
||||
this.players = players;
|
||||
}
|
||||
|
||||
public static PlayersMutator copyOf(PlayersMutator mutator) {
|
||||
return new PlayersMutator(new ArrayList<>(mutator.players));
|
||||
}
|
||||
|
||||
public static PlayersMutator forContainer(DataContainer container) {
|
||||
if (!container.supports(ServerKeys.PLAYERS)) {
|
||||
Log.warn(container.getClass().getSimpleName() + " does not support PLAYERS key.");
|
||||
}
|
||||
return new PlayersMutator(container.getValue(ServerKeys.PLAYERS).orElse(new ArrayList<>()));
|
||||
}
|
||||
|
||||
public PlayersMutator filterPlayedBetween(long after, long before) {
|
||||
return new PlayersMutator(players.stream().filter(player ->
|
||||
player.getValue(PlayerKeys.SESSIONS)
|
||||
.map(sessions -> sessions.stream().anyMatch(session -> {
|
||||
long start = session.getValue(SessionKeys.START).orElse(-1L);
|
||||
long end = session.getValue(SessionKeys.END).orElse(-1L);
|
||||
return (after <= start && start <= before) || (after <= end && end <= before);
|
||||
})).orElse(false)
|
||||
).collect(Collectors.toList()));
|
||||
}
|
||||
|
||||
public PlayersMutator filterRegisteredBetween(long after, long before) {
|
||||
return new PlayersMutator(players.stream().filter(player ->
|
||||
player.getValue(PlayerKeys.REGISTERED).map(date -> after <= date && date <= before).orElse(false)
|
||||
).collect(Collectors.toList()));
|
||||
}
|
||||
|
||||
public PlayersMutator filterRetained(long after, long before) {
|
||||
return new PlayersMutator(players.stream()
|
||||
.filter(player -> {
|
||||
long backLimit = Math.max(after, player.getValue(PlayerKeys.REGISTERED).orElse(0L));
|
||||
long half = backLimit + ((before - backLimit) / 2L);
|
||||
SessionsMutator sessionsMutator = SessionsMutator.forContainer(player);
|
||||
return !sessionsMutator.playedBetween(backLimit, half) && !sessionsMutator.playedBetween(half, before);
|
||||
})
|
||||
.collect(Collectors.toList()));
|
||||
}
|
||||
|
||||
public PlayersMutator filterActive(long date, double limit) {
|
||||
return new PlayersMutator(players.stream()
|
||||
.filter(player -> player.getActivityIndex(date).getValue() >= limit)
|
||||
.collect(Collectors.toList()));
|
||||
}
|
||||
|
||||
public List<PlayerContainer> all() {
|
||||
return players;
|
||||
}
|
||||
|
||||
public List<Long> registerDates() {
|
||||
List<Long> registerDates = new ArrayList<>();
|
||||
for (PlayerContainer player : players) {
|
||||
registerDates.add(player.getValue(PlayerKeys.REGISTERED).orElse(-1L));
|
||||
}
|
||||
return registerDates;
|
||||
}
|
||||
|
||||
public List<String> getGeolocations() {
|
||||
List<String> geolocations = new ArrayList<>();
|
||||
|
||||
for (PlayerContainer player : players) {
|
||||
Optional<GeoInfo> mostRecent = GeoInfoMutator.forContainer(player).mostRecent();
|
||||
mostRecent.ifPresent(geoInfo -> geolocations.add(geoInfo.getGeolocation()));
|
||||
}
|
||||
|
||||
return geolocations;
|
||||
}
|
||||
|
||||
public TreeMap<Long, Map<String, Set<UUID>>> toActivityDataMap(long date) {
|
||||
TreeMap<Long, Map<String, Set<UUID>>> activityData = new TreeMap<>();
|
||||
if (!players.isEmpty()) {
|
||||
for (PlayerContainer player : players) {
|
||||
for (long time = date; time >= date - TimeAmount.MONTH.ms() * 2L; time -= TimeAmount.WEEK.ms()) {
|
||||
ActivityIndex activityIndex = player.getActivityIndex(time);
|
||||
String activityGroup = activityIndex.getGroup();
|
||||
|
||||
Map<String, Set<UUID>> map = activityData.getOrDefault(time, new HashMap<>());
|
||||
Set<UUID> uuids = map.getOrDefault(activityGroup, new HashSet<>());
|
||||
uuids.add(player.getUnsafe(PlayerKeys.UUID));
|
||||
map.put(activityGroup, uuids);
|
||||
activityData.put(time, map);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
activityData.put(date, Collections.emptyMap());
|
||||
}
|
||||
return activityData;
|
||||
}
|
||||
|
||||
public int count() {
|
||||
return players.size();
|
||||
}
|
||||
|
||||
public int newPerDay() {
|
||||
List<Long> registerDates = registerDates();
|
||||
int total = 0;
|
||||
Function<Long, Integer> formatter = Formatters.dayOfYear();
|
||||
Set<Integer> days = new HashSet<>();
|
||||
for (Long date : registerDates) {
|
||||
int day = formatter.apply(date);
|
||||
days.add(day);
|
||||
total++;
|
||||
}
|
||||
int numberOfDays = days.size();
|
||||
|
||||
if (numberOfDays == 0) {
|
||||
return 0;
|
||||
}
|
||||
return total / numberOfDays;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compares players in the mutator to other players in terms of player retention.
|
||||
*
|
||||
* @param compareTo Players to compare to.
|
||||
* @param dateLimit Epoch ms back limit, if the player registered after this their value is not used.
|
||||
* @return Mutator containing the players that are considered to be retained.
|
||||
* @throws IllegalStateException If all players are rejected due to dateLimit.
|
||||
*/
|
||||
public PlayersMutator compareAndFindThoseLikelyToBeRetained(Iterable<PlayerContainer> compareTo,
|
||||
long dateLimit,
|
||||
PlayersOnlineResolver onlineResolver) {
|
||||
Collection<PlayerContainer> retainedAfterMonth = new ArrayList<>();
|
||||
Collection<PlayerContainer> notRetainedAfterMonth = new ArrayList<>();
|
||||
|
||||
for (PlayerContainer player : players) {
|
||||
long registered = player.getValue(PlayerKeys.REGISTERED).orElse(System.currentTimeMillis());
|
||||
|
||||
// Discard uncertain data
|
||||
if (registered > dateLimit) {
|
||||
continue;
|
||||
}
|
||||
|
||||
long monthAfterRegister = registered + TimeAmount.MONTH.ms();
|
||||
long half = registered + (TimeAmount.MONTH.ms() / 2L);
|
||||
if (player.playedBetween(registered, half) && player.playedBetween(half, monthAfterRegister)) {
|
||||
retainedAfterMonth.add(player);
|
||||
} else {
|
||||
notRetainedAfterMonth.add(player);
|
||||
}
|
||||
}
|
||||
|
||||
if (retainedAfterMonth.isEmpty() || notRetainedAfterMonth.isEmpty()) {
|
||||
throw new IllegalStateException("No players to compare to after rejecting with dateLimit");
|
||||
}
|
||||
|
||||
List<RetentionData> retained = retainedAfterMonth.stream()
|
||||
.map(player -> new RetentionData(player, onlineResolver))
|
||||
.collect(Collectors.toList());
|
||||
List<RetentionData> notRetained = notRetainedAfterMonth.stream()
|
||||
.map(player -> new RetentionData(player, onlineResolver))
|
||||
.collect(Collectors.toList());
|
||||
|
||||
RetentionData avgRetained = AnalysisUtils.average(retained);
|
||||
RetentionData avgNotRetained = AnalysisUtils.average(notRetained);
|
||||
|
||||
List<PlayerContainer> toBeRetained = new ArrayList<>();
|
||||
for (PlayerContainer player : compareTo) {
|
||||
RetentionData retentionData = new RetentionData(player, onlineResolver);
|
||||
if (retentionData.distance(avgRetained) < retentionData.distance(avgNotRetained)) {
|
||||
toBeRetained.add(player);
|
||||
}
|
||||
}
|
||||
return new PlayersMutator(toBeRetained);
|
||||
}
|
||||
|
||||
public List<Session> getSessions() {
|
||||
return players.stream()
|
||||
.map(player -> player.getValue(PlayerKeys.SESSIONS).orElse(new ArrayList<>()))
|
||||
.flatMap(Collection::stream)
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
public List<UUID> uuids() {
|
||||
return players.stream()
|
||||
.map(player -> player.getValue(PlayerKeys.UUID).orElse(null))
|
||||
.filter(Objects::nonNull)
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
public List<PlayerContainer> operators() {
|
||||
return players.stream()
|
||||
.filter(player -> player.getValue(PlayerKeys.OPERATOR).orElse(false)).collect(Collectors.toList());
|
||||
}
|
||||
}
|
@ -0,0 +1,40 @@
|
||||
package com.djrapitops.plan.data.store.mutators;
|
||||
|
||||
import com.djrapitops.plan.utilities.html.graphs.line.Point;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* Resolves dates into players online numbers with a help of a NavigableMap.
|
||||
* <p>
|
||||
* Time Complexity of O(n / 2) with the use of TreeMap.
|
||||
*
|
||||
* @author Rsl1122
|
||||
*/
|
||||
public class PlayersOnlineResolver {
|
||||
|
||||
private final NavigableMap<Long, Integer> onlineNumberMap;
|
||||
|
||||
public PlayersOnlineResolver(TPSMutator mutator) {
|
||||
List<Point> points = mutator.playersOnlinePoints();
|
||||
onlineNumberMap = new TreeMap<>();
|
||||
for (Point point : points) {
|
||||
double date = point.getX();
|
||||
double value = point.getY();
|
||||
onlineNumberMap.put((long) date, (int) value);
|
||||
}
|
||||
}
|
||||
|
||||
public Optional<Integer> getOnlineOn(long date) {
|
||||
Map.Entry<Long, Integer> entry = onlineNumberMap.floorEntry(date);
|
||||
if (entry == null) {
|
||||
return Optional.empty();
|
||||
}
|
||||
return Optional.of(entry.getValue());
|
||||
}
|
||||
|
||||
public boolean isServerOnline(long date, long timeLimit) {
|
||||
Long lastEntry = onlineNumberMap.floorKey(date);
|
||||
return date - lastEntry < timeLimit;
|
||||
}
|
||||
}
|
@ -0,0 +1,71 @@
|
||||
/*
|
||||
* Licence is provided in the jar as license.yml also here:
|
||||
* https://github.com/Rsl1122/Plan-PlayerAnalytics/blob/master/Plan/src/main/resources/license.yml
|
||||
*/
|
||||
package com.djrapitops.plan.data.store.mutators;
|
||||
|
||||
import com.djrapitops.plan.data.store.containers.PlayerContainer;
|
||||
import com.djrapitops.plan.data.store.keys.PlayerKeys;
|
||||
import com.djrapitops.plugin.api.TimeAmount;
|
||||
import com.google.common.base.Objects;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
/**
|
||||
* Utility class for player retention calculations.
|
||||
* <p>
|
||||
* Previously known as StickyData.
|
||||
*
|
||||
* @author Rsl1122
|
||||
*/
|
||||
public class RetentionData {
|
||||
private final double activityIndex;
|
||||
private double onlineOnJoin;
|
||||
|
||||
public RetentionData(double activityIndex, double onlineOnJoin) {
|
||||
this.activityIndex = activityIndex;
|
||||
this.onlineOnJoin = onlineOnJoin;
|
||||
}
|
||||
|
||||
public RetentionData(PlayerContainer player, PlayersOnlineResolver onlineOnJoin) {
|
||||
Optional<Long> registeredValue = player.getValue(PlayerKeys.REGISTERED);
|
||||
activityIndex = registeredValue
|
||||
.map(registered -> new ActivityIndex(player, registered + TimeAmount.DAY.ms()).getValue())
|
||||
.orElse(0.0);
|
||||
this.onlineOnJoin = registeredValue
|
||||
.map(registered -> onlineOnJoin.getOnlineOn(registered).orElse(-1))
|
||||
.orElse(0);
|
||||
}
|
||||
|
||||
public double distance(RetentionData data) {
|
||||
double num = 0;
|
||||
num += Math.abs(data.activityIndex - activityIndex) * 2.0;
|
||||
num += data.onlineOnJoin != -1 && onlineOnJoin != -1
|
||||
? Math.abs(data.onlineOnJoin - onlineOnJoin) / 10.0
|
||||
: 0;
|
||||
|
||||
return num;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
RetentionData that = (RetentionData) o;
|
||||
return Double.compare(that.activityIndex, activityIndex) == 0 &&
|
||||
Objects.equal(onlineOnJoin, that.onlineOnJoin);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hashCode(activityIndex, onlineOnJoin);
|
||||
}
|
||||
|
||||
public double getOnlineOnJoin() {
|
||||
return onlineOnJoin;
|
||||
}
|
||||
|
||||
public double getActivityIndex() {
|
||||
return activityIndex;
|
||||
}
|
||||
}
|
@ -0,0 +1,181 @@
|
||||
package com.djrapitops.plan.data.store.mutators;
|
||||
|
||||
import com.djrapitops.plan.data.container.PlayerKill;
|
||||
import com.djrapitops.plan.data.container.Session;
|
||||
import com.djrapitops.plan.data.store.containers.DataContainer;
|
||||
import com.djrapitops.plan.data.store.keys.CommonKeys;
|
||||
import com.djrapitops.plan.data.store.keys.SessionKeys;
|
||||
import com.djrapitops.plan.data.store.mutators.formatting.Formatters;
|
||||
import com.djrapitops.plan.data.time.WorldTimes;
|
||||
import com.djrapitops.plugin.api.utility.log.Log;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* Mutator for a list of Sessions.
|
||||
* <p>
|
||||
* Can be used to get properties of a large number of sessions easily.
|
||||
*
|
||||
* @author Rsl1122
|
||||
*/
|
||||
public class SessionsMutator {
|
||||
|
||||
private List<Session> sessions;
|
||||
|
||||
public static SessionsMutator forContainer(DataContainer container) {
|
||||
if (!container.supports(CommonKeys.SESSIONS)) {
|
||||
Log.warn(container.getClass().getSimpleName() + " does not support SESSIONS key.");
|
||||
}
|
||||
return new SessionsMutator(container.getValue(CommonKeys.SESSIONS).orElse(new ArrayList<>()));
|
||||
}
|
||||
|
||||
public static SessionsMutator copyOf(SessionsMutator mutator) {
|
||||
return new SessionsMutator(new ArrayList<>(mutator.sessions));
|
||||
}
|
||||
|
||||
public SessionsMutator(List<Session> sessions) {
|
||||
this.sessions = sessions;
|
||||
}
|
||||
|
||||
public List<Session> all() {
|
||||
return sessions;
|
||||
}
|
||||
|
||||
public SessionsMutator filterSessionsBetween(long after, long before) {
|
||||
return new SessionsMutator(sessions.stream()
|
||||
.filter(getBetweenPredicate(after, before))
|
||||
.collect(Collectors.toList()));
|
||||
}
|
||||
|
||||
public WorldTimes toTotalWorldTimes() {
|
||||
WorldTimes total = new WorldTimes(new HashMap<>());
|
||||
|
||||
for (Session session : sessions) {
|
||||
session.getValue(SessionKeys.WORLD_TIMES).ifPresent(total::add);
|
||||
}
|
||||
|
||||
return total;
|
||||
}
|
||||
|
||||
public List<PlayerKill> toPlayerKillList() {
|
||||
return sessions.stream()
|
||||
.map(session -> session.getValue(SessionKeys.PLAYER_KILLS).orElse(new ArrayList<>()))
|
||||
.flatMap(Collection::stream)
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
public int toMobKillCount() {
|
||||
return sessions.stream()
|
||||
.mapToInt(session -> session.getValue(SessionKeys.MOB_KILL_COUNT).orElse(0))
|
||||
.sum();
|
||||
}
|
||||
|
||||
public int toDeathCount() {
|
||||
return sessions.stream()
|
||||
.mapToInt(session -> session.getValue(SessionKeys.DEATH_COUNT).orElse(0))
|
||||
.sum();
|
||||
}
|
||||
|
||||
public long toPlaytime() {
|
||||
return sessions.stream()
|
||||
.mapToLong(Session::getLength)
|
||||
.sum();
|
||||
}
|
||||
|
||||
public long toAfkTime() {
|
||||
return sessions.stream()
|
||||
.mapToLong(session -> session.getValue(SessionKeys.AFK_TIME).orElse(0L))
|
||||
.sum();
|
||||
}
|
||||
|
||||
public long toActivePlaytime() {
|
||||
return sessions.stream()
|
||||
.mapToLong(session -> session.getValue(SessionKeys.ACTIVE_TIME).orElse(0L))
|
||||
.sum();
|
||||
}
|
||||
|
||||
public long toLastSeen() {
|
||||
return sessions.stream()
|
||||
.mapToLong(session -> Math.max(session.getUnsafe(
|
||||
SessionKeys.START),
|
||||
session.getValue(SessionKeys.END).orElse(System.currentTimeMillis()))
|
||||
).max().orElse(-1);
|
||||
}
|
||||
|
||||
public long toLongestSessionLength() {
|
||||
OptionalLong longestSession = sessions.stream().mapToLong(Session::getLength).max();
|
||||
if (longestSession.isPresent()) {
|
||||
return longestSession.getAsLong();
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
public long toAverageSessionLength() {
|
||||
OptionalDouble average = sessions.stream().map(Session::getLength)
|
||||
.mapToLong(i -> i)
|
||||
.average();
|
||||
if (average.isPresent()) {
|
||||
return (long) average.getAsDouble();
|
||||
}
|
||||
return 0L;
|
||||
}
|
||||
|
||||
public long toMedianSessionLength() {
|
||||
List<Long> sessionLengths = sessions.stream().map(Session::getLength)
|
||||
.sorted()
|
||||
.collect(Collectors.toList());
|
||||
if (sessionLengths.isEmpty()) {
|
||||
return 0;
|
||||
}
|
||||
return sessionLengths.get(sessionLengths.size() / 2);
|
||||
}
|
||||
|
||||
public int toUniqueJoinsPerDay() {
|
||||
Map<Integer, Set<UUID>> uniqueJoins = new HashMap<>();
|
||||
Function<Long, Integer> function = Formatters.dayOfYear();
|
||||
|
||||
for (Session session : sessions) {
|
||||
Optional<UUID> uuidValue = session.getValue(SessionKeys.UUID);
|
||||
if (!uuidValue.isPresent()) {
|
||||
continue;
|
||||
}
|
||||
UUID uuid = uuidValue.get();
|
||||
int day = function.apply(session.getUnsafe(SessionKeys.START));
|
||||
|
||||
uniqueJoins.computeIfAbsent(day, computedDay -> new HashSet<>());
|
||||
uniqueJoins.get(day).add(uuid);
|
||||
}
|
||||
|
||||
int total = (int) uniqueJoins.values().stream().mapToInt(Set::size).count();
|
||||
int numberOfDays = uniqueJoins.size();
|
||||
|
||||
if (numberOfDays == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return total / numberOfDays;
|
||||
}
|
||||
|
||||
public int count() {
|
||||
return sessions.size();
|
||||
}
|
||||
|
||||
public int toPlayerKillCount() {
|
||||
return toPlayerKillList().size();
|
||||
}
|
||||
|
||||
public boolean playedBetween(long after, long before) {
|
||||
return sessions.stream().anyMatch(getBetweenPredicate(after, before));
|
||||
}
|
||||
|
||||
private Predicate<Session> getBetweenPredicate(long after, long before) {
|
||||
return session -> {
|
||||
Long start = session.getUnsafe(SessionKeys.START);
|
||||
Long end = session.getValue(SessionKeys.END).orElse(System.currentTimeMillis());
|
||||
return (after <= start && start <= before) || (after <= end && end <= before);
|
||||
};
|
||||
}
|
||||
}
|
@ -0,0 +1,225 @@
|
||||
package com.djrapitops.plan.data.store.mutators;
|
||||
|
||||
import com.djrapitops.plan.data.container.TPS;
|
||||
import com.djrapitops.plan.data.store.containers.DataContainer;
|
||||
import com.djrapitops.plan.data.store.keys.ServerKeys;
|
||||
import com.djrapitops.plan.system.settings.Settings;
|
||||
import com.djrapitops.plan.utilities.html.graphs.line.Point;
|
||||
import com.djrapitops.plugin.api.TimeAmount;
|
||||
import com.djrapitops.plugin.api.utility.log.Log;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.OptionalDouble;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* Mutator for a list of TPS data.
|
||||
* <p>
|
||||
* Can be used to get properties of a large number of TPS entries easily.
|
||||
*
|
||||
* @author Rsl1122
|
||||
*/
|
||||
public class TPSMutator {
|
||||
|
||||
private List<TPS> tpsData;
|
||||
|
||||
public TPSMutator(List<TPS> tpsData) {
|
||||
this.tpsData = tpsData;
|
||||
}
|
||||
|
||||
public static TPSMutator forContainer(DataContainer container) {
|
||||
if (!container.supports(ServerKeys.TPS)) {
|
||||
Log.warn(container.getClass().getSimpleName() + " does not support TPS key.");
|
||||
}
|
||||
return new TPSMutator(container.getValue(ServerKeys.TPS).orElse(new ArrayList<>()));
|
||||
}
|
||||
|
||||
public static TPSMutator copyOf(TPSMutator mutator) {
|
||||
return new TPSMutator(new ArrayList<>(mutator.tpsData));
|
||||
}
|
||||
|
||||
public TPSMutator filterDataBetween(long after, long before) {
|
||||
return new TPSMutator(tpsData.stream()
|
||||
.filter(tps -> tps.getDate() >= after && tps.getDate() <= before)
|
||||
.collect(Collectors.toList()));
|
||||
}
|
||||
|
||||
public List<TPS> all() {
|
||||
return tpsData;
|
||||
}
|
||||
|
||||
public List<Point> playersOnlinePoints() {
|
||||
return tpsData.stream()
|
||||
.map(tps -> new Point(tps.getDate(), tps.getPlayers()))
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
public List<Point> tpsPoints() {
|
||||
return tpsData.stream()
|
||||
.map(tps -> new Point(tps.getDate(), tps.getTicksPerSecond()))
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
public List<Point> cpuPoints() {
|
||||
return tpsData.stream()
|
||||
.map(tps -> new Point(tps.getDate(), tps.getCPUUsage()))
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
public List<Point> ramUsagePoints() {
|
||||
return tpsData.stream()
|
||||
.map(tps -> new Point(tps.getDate(), tps.getUsedMemory()))
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
public List<Point> entityPoints() {
|
||||
return tpsData.stream()
|
||||
.map(tps -> new Point(tps.getDate(), tps.getEntityCount()))
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
public List<Point> chunkPoints() {
|
||||
return tpsData.stream()
|
||||
.map(tps -> new Point(tps.getDate(), tps.getChunksLoaded()))
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
public long serverDownTime() {
|
||||
long lastDate = -1;
|
||||
long downTime = 0;
|
||||
for (TPS tps : tpsData) {
|
||||
long date = tps.getDate();
|
||||
if (lastDate == -1) {
|
||||
lastDate = date;
|
||||
continue;
|
||||
}
|
||||
|
||||
long diff = date - lastDate;
|
||||
if (diff > TimeAmount.MINUTE.ms() * 3L) {
|
||||
downTime += diff;
|
||||
}
|
||||
lastDate = date;
|
||||
}
|
||||
|
||||
return downTime;
|
||||
}
|
||||
|
||||
public long serverIdleTime() {
|
||||
long lastDate = -1;
|
||||
int lastPlayers = 0;
|
||||
long idleTime = 0;
|
||||
for (TPS tps : tpsData) {
|
||||
long date = tps.getDate();
|
||||
int players = tps.getPlayers();
|
||||
if (lastDate == -1) {
|
||||
lastDate = date;
|
||||
lastPlayers = players;
|
||||
continue;
|
||||
}
|
||||
|
||||
long diff = date - lastDate;
|
||||
if (lastPlayers == 0 && players == 0) {
|
||||
idleTime += diff;
|
||||
}
|
||||
|
||||
lastDate = date;
|
||||
lastPlayers = players;
|
||||
}
|
||||
|
||||
return idleTime;
|
||||
}
|
||||
|
||||
public double percentageTPSAboveLowThreshold() {
|
||||
if (tpsData.isEmpty()) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
int threshold = Settings.THEME_GRAPH_TPS_THRESHOLD_MED.getNumber();
|
||||
|
||||
long count = 0;
|
||||
for (TPS tps : tpsData) {
|
||||
if (tps.getTicksPerSecond() >= threshold) {
|
||||
count++;
|
||||
}
|
||||
}
|
||||
|
||||
return count * 1.0 / tpsData.size();
|
||||
}
|
||||
|
||||
public int lowTpsSpikeCount() {
|
||||
int mediumThreshold = Settings.THEME_GRAPH_TPS_THRESHOLD_MED.getNumber();
|
||||
|
||||
boolean wasLow = false;
|
||||
int spikeCount = 0;
|
||||
|
||||
for (TPS tpsObj : tpsData) {
|
||||
double tps = tpsObj.getTicksPerSecond();
|
||||
if (tps < mediumThreshold) {
|
||||
if (!wasLow) {
|
||||
spikeCount++;
|
||||
wasLow = true;
|
||||
}
|
||||
} else {
|
||||
wasLow = false;
|
||||
}
|
||||
}
|
||||
|
||||
return spikeCount;
|
||||
}
|
||||
|
||||
public double averageTPS() {
|
||||
OptionalDouble average = tpsData.stream()
|
||||
.mapToDouble(TPS::getTicksPerSecond)
|
||||
.filter(num -> num >= 0)
|
||||
.average();
|
||||
if (average.isPresent()) {
|
||||
return average.getAsDouble();
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
public double averageCPU() {
|
||||
OptionalDouble average = tpsData.stream()
|
||||
.mapToDouble(TPS::getCPUUsage)
|
||||
.filter(num -> num >= 0)
|
||||
.average();
|
||||
if (average.isPresent()) {
|
||||
return average.getAsDouble();
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
public double averageRAM() {
|
||||
OptionalDouble average = tpsData.stream()
|
||||
.mapToDouble(TPS::getUsedMemory)
|
||||
.filter(num -> num >= 0)
|
||||
.average();
|
||||
if (average.isPresent()) {
|
||||
return average.getAsDouble();
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
public double averageEntities() {
|
||||
OptionalDouble average = tpsData.stream()
|
||||
.mapToDouble(TPS::getEntityCount)
|
||||
.filter(num -> num >= 0)
|
||||
.average();
|
||||
if (average.isPresent()) {
|
||||
return average.getAsDouble();
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
public double averageChunks() {
|
||||
OptionalDouble average = tpsData.stream()
|
||||
.mapToDouble(TPS::getChunksLoaded)
|
||||
.filter(num -> num >= 0)
|
||||
.average();
|
||||
if (average.isPresent()) {
|
||||
return average.getAsDouble();
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
}
|
@ -0,0 +1,12 @@
|
||||
package com.djrapitops.plan.data.store.mutators.formatting;
|
||||
|
||||
import java.util.function.Function;
|
||||
|
||||
/**
|
||||
* Interface for formatting a value into a String.
|
||||
*
|
||||
* @author Rsl1122
|
||||
*/
|
||||
public interface Formatter<T> extends Function<T, String> {
|
||||
|
||||
}
|
@ -0,0 +1,82 @@
|
||||
package com.djrapitops.plan.data.store.mutators.formatting;
|
||||
|
||||
import com.djrapitops.plan.data.store.objects.DateHolder;
|
||||
import com.djrapitops.plan.utilities.FormatUtils;
|
||||
import com.djrapitops.plugin.api.TimeAmount;
|
||||
|
||||
import java.util.Calendar;
|
||||
import java.util.function.Function;
|
||||
|
||||
/**
|
||||
* Class that holds static methods for getting new instances of different {@link Formatter}s.
|
||||
*
|
||||
* @author Rsl1122
|
||||
*/
|
||||
public class Formatters {
|
||||
|
||||
private Formatters() {
|
||||
/* Static method class */
|
||||
}
|
||||
|
||||
public static Formatter<DateHolder> year() {
|
||||
return dateHolder -> {
|
||||
long date = dateHolder.getDate();
|
||||
return date > 0 ? FormatUtils.formatTimeStampYear(date) : "-";
|
||||
};
|
||||
}
|
||||
|
||||
public static Formatter<Long> yearLongValue() {
|
||||
return date -> date > 0 ? FormatUtils.formatTimeStampYear(date) : "-";
|
||||
}
|
||||
|
||||
public static Formatter<DateHolder> day() {
|
||||
return dateHolder -> {
|
||||
long date = dateHolder.getDate();
|
||||
return date > 0 ? FormatUtils.formatTimeStampDay(date) : "-";
|
||||
};
|
||||
}
|
||||
|
||||
public static Formatter<DateHolder> second() {
|
||||
return dateHolder -> {
|
||||
long date = dateHolder.getDate();
|
||||
return date > 0 ? FormatUtils.formatTimeStampSecond(date) : "-";
|
||||
};
|
||||
}
|
||||
|
||||
public static Formatter<DateHolder> clock() {
|
||||
return dateHolder -> {
|
||||
long date = dateHolder.getDate();
|
||||
return date > 0 ? FormatUtils.formatTimeStampClock(date) : "-";
|
||||
};
|
||||
}
|
||||
|
||||
public static Formatter<DateHolder> iso8601NoClock() {
|
||||
return dateHolder -> FormatUtils.formatTimeStampISO8601NoClock(dateHolder.getDate());
|
||||
}
|
||||
|
||||
public static Formatter<Long> timeAmount() {
|
||||
return new TimeAmountFormatter();
|
||||
}
|
||||
|
||||
public static Function<Long, Integer> dayOfYear() {
|
||||
return date -> {
|
||||
Calendar day = Calendar.getInstance();
|
||||
day.setTimeInMillis(date);
|
||||
return day.get(Calendar.DAY_OF_YEAR);
|
||||
};
|
||||
}
|
||||
|
||||
public static Formatter<Double> percentage() {
|
||||
return value -> value >= 0 ? FormatUtils.cutDecimals(value * 100.0) + "%" : "-";
|
||||
}
|
||||
|
||||
public static Formatter<Long> benchmark() {
|
||||
return ns -> {
|
||||
if (ns > TimeAmount.MILLISECOND.ns() * 5L) {
|
||||
return (ns / TimeAmount.MILLISECOND.ns()) + "ms";
|
||||
} else {
|
||||
return 1.0 * ns / TimeAmount.MILLISECOND.ns() + "ms";
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
@ -0,0 +1,58 @@
|
||||
package com.djrapitops.plan.data.store.mutators.formatting;
|
||||
|
||||
import com.djrapitops.plan.data.store.PlaceholderKey;
|
||||
import com.djrapitops.plan.data.store.containers.DataContainer;
|
||||
import com.djrapitops.plugin.api.utility.log.Log;
|
||||
import org.apache.commons.text.StringSubstitutor;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.HashMap;
|
||||
|
||||
/**
|
||||
* Formatter for replacing ${placeholder} values inside strings.
|
||||
*
|
||||
* @author Rsl1122
|
||||
*/
|
||||
public class PlaceholderReplacer extends HashMap<String, Serializable> implements Formatter<String> {
|
||||
|
||||
public <T> void addPlaceholderFrom(DataContainer container, PlaceholderKey<T> key) {
|
||||
if (!container.supports(key)) {
|
||||
return;
|
||||
}
|
||||
long ns = System.nanoTime();
|
||||
Log.debug(key.getPlaceholder());
|
||||
put(key.getPlaceholder(), container.getSupplier(key).get().toString());
|
||||
ns = System.nanoTime() - ns;
|
||||
Log.debug(key.getPlaceholder() + ": " + Formatters.benchmark().apply(ns));
|
||||
}
|
||||
|
||||
public void addAllPlaceholdersFrom(DataContainer container, PlaceholderKey... keys) {
|
||||
for (PlaceholderKey key : keys) {
|
||||
addPlaceholderFrom(container, key);
|
||||
}
|
||||
}
|
||||
|
||||
public <T> void addPlaceholderFrom(DataContainer container, Formatter<T> formatter, PlaceholderKey<T> key) {
|
||||
if (!container.supports(key)) {
|
||||
return;
|
||||
}
|
||||
long ns = System.nanoTime();
|
||||
Log.debug(key.getPlaceholder());
|
||||
put(key.getPlaceholder(), formatter.apply(container.getSupplier(key).get()));
|
||||
ns = System.nanoTime() - ns;
|
||||
Log.debug(key.getPlaceholder() + ": " + Formatters.benchmark().apply(ns));
|
||||
}
|
||||
|
||||
public <T> void addAllPlaceholdersFrom(DataContainer container, Formatter<T> formatter, PlaceholderKey<T>... keys) {
|
||||
for (PlaceholderKey<T> key : keys) {
|
||||
addPlaceholderFrom(container, formatter, key);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String apply(String string) {
|
||||
StringSubstitutor sub = new StringSubstitutor(this);
|
||||
sub.setEnableSubstitutionInVariables(true);
|
||||
return sub.replace(string);
|
||||
}
|
||||
}
|
@ -0,0 +1,131 @@
|
||||
package com.djrapitops.plan.data.store.mutators.formatting;
|
||||
|
||||
import com.djrapitops.plan.system.settings.Settings;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
/**
|
||||
* Formatter for time amount in milliseconds.
|
||||
*
|
||||
* @author Rsl1122
|
||||
*/
|
||||
public class TimeAmountFormatter implements Formatter<Long> {
|
||||
|
||||
// Placeholders for the config settings
|
||||
private final String zeroPH = "%zero%";
|
||||
private final String secondsPH = "%seconds%";
|
||||
private final String minutesPH = "%minutes%";
|
||||
private final String hoursPH = "%hours%";
|
||||
private final String daysPH = "%days%";
|
||||
private final String monthsPH = "%months%";
|
||||
private final String yearsPH = "%years%";
|
||||
|
||||
@Override
|
||||
public String apply(Long ms) {
|
||||
if (ms <= 0) {
|
||||
return "-";
|
||||
}
|
||||
StringBuilder builder = new StringBuilder();
|
||||
long x = ms / 1000;
|
||||
long seconds = x % 60;
|
||||
x /= 60;
|
||||
long minutes = x % 60;
|
||||
x /= 60;
|
||||
long hours = x % 24;
|
||||
x /= 24;
|
||||
long days = x % 365;
|
||||
long months = (days - days % 30) / 30;
|
||||
days -= months * 30;
|
||||
x /= 365;
|
||||
long years = x;
|
||||
|
||||
appendYears(builder, years);
|
||||
appendMonths(builder, months);
|
||||
appendDays(builder, days);
|
||||
|
||||
String hourFormat = Settings.FORMAT_HOURS.toString();
|
||||
String minuteFormat = Settings.FORMAT_MINUTES.toString();
|
||||
String secondFormat = Settings.FORMAT_SECONDS.toString();
|
||||
|
||||
appendHours(builder, hours, hourFormat);
|
||||
appendMinutes(builder, minutes, hours, hourFormat, minuteFormat);
|
||||
appendSeconds(builder, seconds, minutes, hours, hourFormat, minuteFormat, secondFormat);
|
||||
|
||||
String formattedTime = StringUtils.remove(builder.toString(), zeroPH);
|
||||
if (formattedTime.isEmpty()) {
|
||||
return Settings.FORMAT_ZERO_SECONDS.toString();
|
||||
}
|
||||
return formattedTime;
|
||||
}
|
||||
|
||||
private void appendSeconds(StringBuilder builder, long seconds, long minutes, long hours, String fHours, String fMinutes, String fSeconds) {
|
||||
if (seconds != 0) {
|
||||
String s = fSeconds.replace(secondsPH, String.valueOf(seconds));
|
||||
if (minutes == 0 && s.contains(minutesPH)) {
|
||||
if (hours == 0 && fMinutes.contains(hoursPH)) {
|
||||
builder.append(fHours.replace(zeroPH, "0").replace(hoursPH, "0"));
|
||||
}
|
||||
builder.append(fMinutes.replace(hoursPH, "").replace(zeroPH, "0").replace(minutesPH, "0"));
|
||||
}
|
||||
s = s.replace(minutesPH, "");
|
||||
if (s.contains(zeroPH) && String.valueOf(seconds).length() == 1) {
|
||||
builder.append('0');
|
||||
}
|
||||
builder.append(s);
|
||||
}
|
||||
}
|
||||
|
||||
private void appendMinutes(StringBuilder builder, long minutes, long hours, String fHours, String fMinutes) {
|
||||
if (minutes != 0) {
|
||||
String m = fMinutes.replace(minutesPH, String.valueOf(minutes));
|
||||
if (hours == 0 && m.contains(hoursPH)) {
|
||||
builder.append(fHours.replace(zeroPH, "0").replace(hoursPH, "0"));
|
||||
m = m.replace(hoursPH, "");
|
||||
}
|
||||
m = m.replace(hoursPH, "");
|
||||
if (m.contains(zeroPH) && String.valueOf(minutes).length() == 1) {
|
||||
builder.append('0');
|
||||
}
|
||||
builder.append(m);
|
||||
}
|
||||
}
|
||||
|
||||
private void appendHours(StringBuilder builder, long hours, String fHours) {
|
||||
if (hours != 0) {
|
||||
String h = fHours.replace(hoursPH, String.valueOf(hours));
|
||||
if (h.contains(zeroPH) && String.valueOf(hours).length() == 1) {
|
||||
builder.append('0');
|
||||
}
|
||||
builder.append(h);
|
||||
}
|
||||
}
|
||||
|
||||
private void appendDays(StringBuilder builder, long days) {
|
||||
String singular = Settings.FORMAT_DAY.toString();
|
||||
String plural = Settings.FORMAT_DAYS.toString();
|
||||
appendValue(builder, days, singular, plural, daysPH);
|
||||
}
|
||||
|
||||
private void appendMonths(StringBuilder builder, long months) {
|
||||
String singular = Settings.FORMAT_MONTH.toString();
|
||||
String plural = Settings.FORMAT_MONTHS.toString();
|
||||
|
||||
appendValue(builder, months, singular, plural, monthsPH);
|
||||
}
|
||||
|
||||
private void appendYears(StringBuilder builder, long years) {
|
||||
String singular = Settings.FORMAT_YEAR.toString();
|
||||
String plural = Settings.FORMAT_YEARS.toString();
|
||||
|
||||
appendValue(builder, years, singular, plural, yearsPH);
|
||||
}
|
||||
|
||||
private void appendValue(StringBuilder builder, long amount, String singular, String plural, String replace) {
|
||||
if (amount != 0) {
|
||||
if (amount == 1) {
|
||||
builder.append(singular);
|
||||
} else {
|
||||
builder.append(plural.replace(replace, String.valueOf(amount)));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,17 @@
|
||||
package com.djrapitops.plan.data.store.objects;
|
||||
|
||||
/**
|
||||
* Interface for objects that have a epoch ms date.
|
||||
*
|
||||
* @author Rsl1122
|
||||
*/
|
||||
public interface DateHolder {
|
||||
|
||||
/**
|
||||
* Get the date the object holds.
|
||||
*
|
||||
* @return Epoch ms - milliseconds passed since January 1st 1970.
|
||||
*/
|
||||
long getDate();
|
||||
|
||||
}
|
@ -0,0 +1,23 @@
|
||||
package com.djrapitops.plan.data.store.objects;
|
||||
|
||||
import java.util.TreeMap;
|
||||
|
||||
/**
|
||||
* Basic TreeMap that uses Epoch MS as keys.
|
||||
*
|
||||
* @author Rsl1122
|
||||
*/
|
||||
public class DateMap<T> extends TreeMap<Long, T> {
|
||||
|
||||
public DateMap() {
|
||||
super(Long::compareTo);
|
||||
}
|
||||
|
||||
public boolean hasValuesBetween(long after, long before) {
|
||||
return countBetween(after, before) > 0;
|
||||
}
|
||||
|
||||
public int countBetween(long after, long before) {
|
||||
return subMap(after, before).size();
|
||||
}
|
||||
}
|
@ -0,0 +1,26 @@
|
||||
package com.djrapitops.plan.data.store.objects;
|
||||
|
||||
/**
|
||||
* Object that has a value tied to a date.
|
||||
*
|
||||
* @author Rsl1122
|
||||
*/
|
||||
public class DateObj<T> implements DateHolder {
|
||||
|
||||
private final long date;
|
||||
private final T value;
|
||||
|
||||
public DateObj(long date, T value) {
|
||||
this.date = date;
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getDate() {
|
||||
return date;
|
||||
}
|
||||
|
||||
public T getValue() {
|
||||
return value;
|
||||
}
|
||||
}
|
@ -0,0 +1,20 @@
|
||||
package com.djrapitops.plan.data.store.objects;
|
||||
|
||||
import java.util.TreeSet;
|
||||
|
||||
/**
|
||||
* Basic TreeSet with Epoch ms as values.
|
||||
*
|
||||
* @author Rsl1122
|
||||
*/
|
||||
public class DateSet extends TreeSet<Long> {
|
||||
|
||||
public boolean hasValuesBetween(long after, long before) {
|
||||
return countBetween(after, before) > 0;
|
||||
}
|
||||
|
||||
public int countBetween(long after, long before) {
|
||||
return subSet(after, before).size();
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,58 @@
|
||||
package com.djrapitops.plan.data.store.objects;
|
||||
|
||||
import java.util.Objects;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* Object storing nickname information.
|
||||
*
|
||||
* @author Rsl1122
|
||||
*/
|
||||
public class Nickname implements DateHolder {
|
||||
|
||||
private final String name;
|
||||
private final long date;
|
||||
private final UUID serverUUID;
|
||||
|
||||
public Nickname(String name, long date, UUID serverUUID) {
|
||||
this.name = name;
|
||||
this.date = date;
|
||||
this.serverUUID = serverUUID;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public long getDate() {
|
||||
return date;
|
||||
}
|
||||
|
||||
public UUID getServerUUID() {
|
||||
return serverUUID;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Nickname{" +
|
||||
"name='" + name + '\'' +
|
||||
", date=" + date +
|
||||
", serverUUID=" + serverUUID +
|
||||
'}';
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (!(o instanceof Nickname)) return false;
|
||||
Nickname nickname = (Nickname) o;
|
||||
return Objects.equals(name, nickname.name) &&
|
||||
Objects.equals(serverUUID, nickname.serverUUID);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
|
||||
return Objects.hash(name, date, serverUUID);
|
||||
}
|
||||
}
|
@ -1,6 +1,6 @@
|
||||
package com.djrapitops.plan.system.cache;
|
||||
|
||||
import com.djrapitops.plan.api.exceptions.database.DBException;
|
||||
import com.djrapitops.plan.api.exceptions.database.DBOpException;
|
||||
import com.djrapitops.plan.system.PlanSystem;
|
||||
import com.djrapitops.plan.system.SubSystem;
|
||||
import com.djrapitops.plan.system.database.databases.Database;
|
||||
@ -69,18 +69,6 @@ public class DataCache extends SessionCache implements SubSystem {
|
||||
}
|
||||
}
|
||||
|
||||
public void cacheSavedNames() {
|
||||
try {
|
||||
Map<UUID, String> playerNames = db.fetch().getPlayerNames();
|
||||
this.playerNames.putAll(playerNames);
|
||||
for (Map.Entry<UUID, String> entry : playerNames.entrySet()) {
|
||||
uuids.put(entry.getValue(), entry.getKey());
|
||||
}
|
||||
} catch (DBException e) {
|
||||
Log.toLog(this.getClass(), e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to get the player name in the cache.
|
||||
*
|
||||
@ -93,7 +81,7 @@ public class DataCache extends SessionCache implements SubSystem {
|
||||
try {
|
||||
name = db.fetch().getPlayerName(uuid);
|
||||
playerNames.put(uuid, name);
|
||||
} catch (DBException e) {
|
||||
} catch (DBOpException e) {
|
||||
Log.toLog(this.getClass(), e);
|
||||
name = "Error occurred";
|
||||
}
|
||||
@ -118,7 +106,7 @@ public class DataCache extends SessionCache implements SubSystem {
|
||||
if (!nicknames.isEmpty()) {
|
||||
return nicknames.get(nicknames.size() - 1);
|
||||
}
|
||||
} catch (DBException e) {
|
||||
} catch (DBOpException e) {
|
||||
Log.toLog(this.getClass(), e);
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
package com.djrapitops.plan.system.cache;
|
||||
|
||||
import com.djrapitops.plan.api.exceptions.database.DBException;
|
||||
import com.djrapitops.plan.api.exceptions.database.DBOpException;
|
||||
import com.djrapitops.plan.data.container.Session;
|
||||
import com.djrapitops.plan.system.PlanSystem;
|
||||
import com.djrapitops.plan.system.database.databases.Database;
|
||||
@ -20,7 +20,6 @@ import java.util.UUID;
|
||||
*/
|
||||
public class SessionCache {
|
||||
|
||||
private static final Map<UUID, Integer> firstSessionInformation = new HashMap<>();
|
||||
private static final Map<UUID, Session> activeSessions = new HashMap<>();
|
||||
protected final PlanSystem system;
|
||||
|
||||
@ -61,7 +60,7 @@ public class SessionCache {
|
||||
}
|
||||
session.endSession(time);
|
||||
Database.getActive().save().session(uuid, session);
|
||||
} catch (DBException e) {
|
||||
} catch (DBOpException e) {
|
||||
Log.toLog(this.getClass(), e);
|
||||
} finally {
|
||||
activeSessions.remove(uuid);
|
||||
@ -88,40 +87,4 @@ public class SessionCache {
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
/**
|
||||
* Used for marking first Session Actions to be saved.
|
||||
*
|
||||
* @param uuid UUID of the new player.
|
||||
*/
|
||||
public void markFirstSession(UUID uuid) {
|
||||
firstSessionInformation.put(uuid, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a session is player's first session on the server.
|
||||
*
|
||||
* @param uuid UUID of the player
|
||||
* @return true / false
|
||||
*/
|
||||
public boolean isFirstSession(UUID uuid) {
|
||||
return firstSessionInformation.containsKey(uuid);
|
||||
}
|
||||
|
||||
public void endFirstSessionActionTracking(UUID uuid) {
|
||||
firstSessionInformation.remove(uuid);
|
||||
}
|
||||
|
||||
public void firstSessionMessageSent(UUID uuid) {
|
||||
Integer msgCount = firstSessionInformation.getOrDefault(uuid, 0);
|
||||
msgCount++;
|
||||
firstSessionInformation.put(uuid, msgCount);
|
||||
}
|
||||
|
||||
public int getFirstSessionMsgCount(UUID uuid) {
|
||||
return firstSessionInformation.getOrDefault(uuid, 0);
|
||||
}
|
||||
|
||||
public Map<UUID, Integer> getFirstSessionMsgCounts() {
|
||||
return firstSessionInformation;
|
||||
}
|
||||
}
|
||||
|
@ -1,14 +1,11 @@
|
||||
package com.djrapitops.plan.system.database.databases.operation;
|
||||
|
||||
import com.djrapitops.plan.api.exceptions.database.DBException;
|
||||
import com.djrapitops.plan.system.database.databases.Database;
|
||||
|
||||
import java.sql.SQLException;
|
||||
|
||||
public interface BackupOperations {
|
||||
|
||||
void backup(Database toDatabase) throws SQLException;
|
||||
void backup(Database toDatabase);
|
||||
|
||||
void restore(Database fromDatabase) throws DBException, SQLException;
|
||||
void restore(Database fromDatabase);
|
||||
|
||||
}
|
||||
|
@ -1,21 +1,20 @@
|
||||
package com.djrapitops.plan.system.database.databases.operation;
|
||||
|
||||
import com.djrapitops.plan.api.exceptions.database.DBException;
|
||||
import com.djrapitops.plan.system.info.server.ServerInfo;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
public interface CheckOperations {
|
||||
|
||||
boolean isPlayerRegistered(UUID player) throws DBException;
|
||||
boolean isPlayerRegistered(UUID player);
|
||||
|
||||
boolean isPlayerRegistered(UUID player, UUID server) throws DBException;
|
||||
boolean isPlayerRegistered(UUID player, UUID server);
|
||||
|
||||
boolean doesWebUserExists(String username) throws DBException;
|
||||
boolean doesWebUserExists(String username);
|
||||
|
||||
default boolean isPlayerRegisteredOnThisServer(UUID player) throws DBException {
|
||||
default boolean isPlayerRegisteredOnThisServer(UUID player) {
|
||||
return isPlayerRegistered(player, ServerInfo.getServerUUID());
|
||||
}
|
||||
|
||||
boolean isServerInDatabase(UUID serverUUID) throws DBException;
|
||||
boolean isServerInDatabase(UUID serverUUID);
|
||||
}
|
||||
|
@ -1,12 +1,10 @@
|
||||
package com.djrapitops.plan.system.database.databases.operation;
|
||||
|
||||
import com.djrapitops.plan.api.exceptions.database.DBException;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
public interface CountOperations {
|
||||
|
||||
int getServerPlayerCount(UUID server) throws DBException;
|
||||
int getServerPlayerCount(UUID server);
|
||||
|
||||
int getNetworkPlayerCount() throws DBException;
|
||||
int getNetworkPlayerCount();
|
||||
}
|
||||
|
@ -1,93 +1,119 @@
|
||||
package com.djrapitops.plan.system.database.databases.operation;
|
||||
|
||||
import com.djrapitops.plan.api.exceptions.database.DBException;
|
||||
import com.djrapitops.plan.data.PlayerProfile;
|
||||
import com.djrapitops.plan.data.ServerProfile;
|
||||
import com.djrapitops.plan.data.WebUser;
|
||||
import com.djrapitops.plan.data.container.*;
|
||||
import com.djrapitops.plan.data.container.GeoInfo;
|
||||
import com.djrapitops.plan.data.container.Session;
|
||||
import com.djrapitops.plan.data.container.TPS;
|
||||
import com.djrapitops.plan.data.container.UserInfo;
|
||||
import com.djrapitops.plan.data.store.containers.NetworkContainer;
|
||||
import com.djrapitops.plan.data.store.containers.PlayerContainer;
|
||||
import com.djrapitops.plan.data.store.containers.ServerContainer;
|
||||
import com.djrapitops.plan.system.info.server.Server;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
public interface FetchOperations {
|
||||
|
||||
// Profiles
|
||||
/**
|
||||
* Used to get a NetworkContainer, some limitations apply to values returned by DataContainer keys.
|
||||
* <p>
|
||||
* Limitations:
|
||||
* - Bungee ServerContainer does not support: ServerKeys WORLD_TIMES, PLAYER_KILLS, PLAYER_KILL_COUNT
|
||||
* - Bungee ServerContainer ServerKeys.TPS only contains playersOnline values
|
||||
* - NetworkKeys.PLAYERS PlayerContainers:
|
||||
* - do not support: PlayerKeys WORLD_TIMES, PLAYER_KILLS, PLAYER_KILL_COUNT
|
||||
* - PlayerKeys.PER_SERVER does not support: PerServerKeys WORLD_TIMES, PLAYER_KILLS, PLAYER_KILL_COUNT
|
||||
* <p>
|
||||
* Blocking methods are not called until DataContainer getter methods are called.
|
||||
*
|
||||
* @return a new NetworkContainer.
|
||||
*/
|
||||
NetworkContainer getNetworkContainer();
|
||||
|
||||
ServerProfile getServerProfile(UUID serverUUID) throws DBException;
|
||||
/**
|
||||
* Used to get a ServerContainer, some limitations apply to values returned by DataContainer keys.
|
||||
* <p>
|
||||
* Limitations:
|
||||
* - ServerKeys.PLAYERS PlayerContainers PlayerKeys.PER_SERVER only contains information about the queried server.
|
||||
* <p>
|
||||
* Blocking methods are not called until DataContainer getter methods are called.
|
||||
*
|
||||
* @param serverUUID UUID of the Server.
|
||||
* @return a new ServerContainer.
|
||||
*/
|
||||
ServerContainer getServerContainer(UUID serverUUID);
|
||||
|
||||
List<PlayerProfile> getPlayers(UUID serverUUID) throws DBException;
|
||||
/**
|
||||
* Used to get PlayerContainers of all players on the network, some limitations apply to DataContainer keys.
|
||||
* <p>
|
||||
* Limitations:
|
||||
* - PlayerContainers do not support: PlayerKeys WORLD_TIMES, PLAYER_KILLS, PLAYER_KILL_COUNT
|
||||
* - PlayerContainers PlayerKeys.PER_SERVER does not support: PerServerKeys WORLD_TIMES, PLAYER_KILLS, PLAYER_KILL_COUNT
|
||||
* <p>
|
||||
* Blocking methods are not called until DataContainer getter methods are called.
|
||||
*
|
||||
* @return a list of PlayerContainers in Plan database.
|
||||
*/
|
||||
List<PlayerContainer> getAllPlayerContainers();
|
||||
|
||||
PlayerProfile getPlayerProfile(UUID uuid) throws DBException;
|
||||
/**
|
||||
* Used to get a PlayerContainer of a specific player.
|
||||
* <p>
|
||||
* Blocking methods are not called until DataContainer getter methods are called.
|
||||
*
|
||||
* @param uuid UUID of the player.
|
||||
* @return a new PlayerContainer.
|
||||
*/
|
||||
PlayerContainer getPlayerContainer(UUID uuid);
|
||||
|
||||
// UUIDs
|
||||
|
||||
Set<UUID> getSavedUUIDs() throws DBException;
|
||||
Set<UUID> getSavedUUIDs();
|
||||
|
||||
Set<UUID> getSavedUUIDs(UUID server) throws DBException;
|
||||
Set<UUID> getSavedUUIDs(UUID server);
|
||||
|
||||
Map<UUID, String> getServerNames() throws DBException;
|
||||
Map<UUID, String> getServerNames();
|
||||
|
||||
Optional<UUID> getServerUUID(String serverName) throws DBException;
|
||||
Optional<UUID> getServerUUID(String serverName);
|
||||
|
||||
UUID getUuidOf(String playerName) throws DBException;
|
||||
UUID getUuidOf(String playerName);
|
||||
|
||||
// WebUsers
|
||||
|
||||
WebUser getWebUser(String username) throws DBException;
|
||||
WebUser getWebUser(String username);
|
||||
|
||||
// Servers
|
||||
|
||||
Optional<String> getServerName(UUID serverUUID) throws DBException;
|
||||
Optional<String> getServerName(UUID serverUUID);
|
||||
|
||||
Optional<Server> getBungeeInformation() throws DBException;
|
||||
Optional<Server> getBungeeInformation();
|
||||
|
||||
Optional<Integer> getServerID(UUID serverUUID) throws DBException;
|
||||
Optional<Integer> getServerID(UUID serverUUID);
|
||||
|
||||
// Raw Data
|
||||
|
||||
List<TPS> getTPSData(UUID serverUUID) throws DBException;
|
||||
List<TPS> getTPSData(UUID serverUUID);
|
||||
|
||||
List<TPS> getNetworkOnlineData() throws DBException;
|
||||
Map<UUID, Map<UUID, List<Session>>> getSessionsWithNoExtras();
|
||||
|
||||
List<Long> getRegisterDates() throws DBException;
|
||||
Map<UUID, UserInfo> getUsers();
|
||||
|
||||
Optional<TPS> getAllTimePeak(UUID serverUUID) throws DBException;
|
||||
Map<UUID, Long> getLastSeenForAllPlayers();
|
||||
|
||||
Optional<TPS> getPeakPlayerCount(UUID serverUUID, long afterDate) throws DBException;
|
||||
Map<UUID, List<GeoInfo>> getAllGeoInfo();
|
||||
|
||||
Map<UUID, Map<UUID, List<Session>>> getSessionsWithNoExtras() throws DBException;
|
||||
Map<UUID, String> getPlayerNames();
|
||||
|
||||
Map<UUID, Map<UUID, List<Session>>> getSessionsAndExtras() throws DBException;
|
||||
String getPlayerName(UUID playerUUID);
|
||||
|
||||
Set<String> getWorldNames(UUID serverUuid) throws DBException;
|
||||
List<String> getNicknames(UUID uuid);
|
||||
|
||||
List<String> getNicknamesOfPlayerOnServer(UUID uuid, UUID serverUUID) throws DBException;
|
||||
Map<UUID, Server> getBukkitServers();
|
||||
|
||||
List<Action> getActions(UUID uuid) throws DBException;
|
||||
List<WebUser> getWebUsers();
|
||||
|
||||
Map<UUID, UserInfo> getUsers() throws DBException;
|
||||
List<Server> getServers();
|
||||
|
||||
Map<UUID, Long> getLastSeenForAllPlayers() throws DBException;
|
||||
List<UUID> getServerUUIDs();
|
||||
|
||||
Map<UUID, List<GeoInfo>> getAllGeoInfo() throws DBException;
|
||||
|
||||
Map<UUID, String> getPlayerNames() throws DBException;
|
||||
|
||||
String getPlayerName(UUID playerUUID) throws DBException;
|
||||
|
||||
List<String> getNicknames(UUID uuid) throws DBException;
|
||||
|
||||
Map<UUID, Server> getBukkitServers() throws DBException;
|
||||
|
||||
List<WebUser> getWebUsers() throws DBException;
|
||||
|
||||
Map<Integer, String> getServerNamesByID() throws DBException;
|
||||
|
||||
Map<UUID, Map<UUID, List<Session>>> getSessionsInLastMonth() throws DBException;
|
||||
|
||||
List<Server> getServers() throws DBException;
|
||||
|
||||
List<UUID> getServerUUIDs() throws DBException;
|
||||
|
||||
List<String> getNetworkGeolocations() throws DBException;
|
||||
}
|
||||
|
@ -1,18 +1,12 @@
|
||||
package com.djrapitops.plan.system.database.databases.operation;
|
||||
|
||||
import com.djrapitops.plan.api.exceptions.database.DBException;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
public interface RemoveOperations {
|
||||
|
||||
void player(UUID uuid) throws DBException;
|
||||
void player(UUID uuid);
|
||||
|
||||
void player(UUID player, UUID server) throws DBException;
|
||||
void everything();
|
||||
|
||||
void server(UUID serverUUID) throws DBException;
|
||||
|
||||
void everything() throws DBException;
|
||||
|
||||
void webUser(String name) throws DBException;
|
||||
void webUser(String name);
|
||||
}
|
||||
|
@ -4,9 +4,12 @@
|
||||
*/
|
||||
package com.djrapitops.plan.system.database.databases.operation;
|
||||
|
||||
import com.djrapitops.plan.api.exceptions.database.DBException;
|
||||
import com.djrapitops.plan.data.WebUser;
|
||||
import com.djrapitops.plan.data.container.*;
|
||||
import com.djrapitops.plan.data.container.GeoInfo;
|
||||
import com.djrapitops.plan.data.container.Session;
|
||||
import com.djrapitops.plan.data.container.TPS;
|
||||
import com.djrapitops.plan.data.container.UserInfo;
|
||||
import com.djrapitops.plan.data.store.objects.Nickname;
|
||||
import com.djrapitops.plan.system.info.server.Server;
|
||||
|
||||
import java.util.List;
|
||||
@ -15,7 +18,7 @@ import java.util.UUID;
|
||||
|
||||
/**
|
||||
* Operation methods for saving data.
|
||||
*
|
||||
* <p>
|
||||
* Note: Method names subject to change (TODO remove insert update and such)
|
||||
*
|
||||
* @author Rsl1122
|
||||
@ -24,50 +27,47 @@ public interface SaveOperations {
|
||||
|
||||
// Bulk save
|
||||
|
||||
void insertTPS(Map<UUID, List<TPS>> ofServers) throws DBException;
|
||||
void insertTPS(Map<UUID, List<TPS>> ofServers);
|
||||
|
||||
void insertCommandUsage(Map<UUID, Map<String, Integer>> ofServers) throws DBException;
|
||||
void insertCommandUsage(Map<UUID, Map<String, Integer>> ofServers);
|
||||
|
||||
void insertUsers(Map<UUID, UserInfo> ofServers) throws DBException;
|
||||
void insertUsers(Map<UUID, UserInfo> ofServers);
|
||||
|
||||
void insertSessions(Map<UUID, Map<UUID, List<Session>>> ofServers, boolean containsExtraData)
|
||||
throws DBException;
|
||||
void insertSessions(Map<UUID, Map<UUID, List<Session>>> ofServers, boolean containsExtraData);
|
||||
|
||||
void kickAmount(Map<UUID, Integer> ofUsers) throws DBException;
|
||||
void kickAmount(Map<UUID, Integer> ofUsers);
|
||||
|
||||
void insertUserInfo(Map<UUID, List<UserInfo>> ofServers) throws DBException;
|
||||
void insertUserInfo(Map<UUID, List<UserInfo>> ofServers);
|
||||
|
||||
void insertNicknames(Map<UUID, Map<UUID, List<String>>> ofServers) throws DBException;
|
||||
void insertNicknames(Map<UUID, Map<UUID, List<Nickname>>> ofServers);
|
||||
|
||||
void insertAllGeoInfo(Map<UUID, List<GeoInfo>> ofUsers) throws DBException;
|
||||
void insertAllGeoInfo(Map<UUID, List<GeoInfo>> ofUsers);
|
||||
|
||||
// Single data point
|
||||
|
||||
void banStatus(UUID uuid, boolean banned) throws DBException;
|
||||
void banStatus(UUID uuid, boolean banned);
|
||||
|
||||
void opStatus(UUID uuid, boolean op) throws DBException;
|
||||
void opStatus(UUID uuid, boolean op);
|
||||
|
||||
void registerNewUser(UUID uuid, long registered, String name) throws DBException;
|
||||
void registerNewUser(UUID uuid, long registered, String name);
|
||||
|
||||
void action(UUID uuid, Action action) throws DBException;
|
||||
void geoInfo(UUID uuid, GeoInfo geoInfo);
|
||||
|
||||
void geoInfo(UUID uuid, GeoInfo geoInfo) throws DBException;
|
||||
void playerWasKicked(UUID uuid);
|
||||
|
||||
void playerWasKicked(UUID uuid) throws DBException;
|
||||
void playerName(UUID uuid, String playerName);
|
||||
|
||||
void playerName(UUID uuid, String playerName) throws DBException;
|
||||
void playerDisplayName(UUID uuid, Nickname nickname);
|
||||
|
||||
void playerDisplayName(UUID uuid, String displayName) throws DBException;
|
||||
void registerNewUserOnThisServer(UUID uuid, long registered);
|
||||
|
||||
void registerNewUserOnThisServer(UUID uuid, long registered) throws DBException;
|
||||
void commandUsed(String commandName);
|
||||
|
||||
void commandUsed(String commandName) throws DBException;
|
||||
void insertTPSforThisServer(TPS tps);
|
||||
|
||||
void insertTPSforThisServer(TPS tps) throws DBException;
|
||||
void session(UUID uuid, Session session);
|
||||
|
||||
void session(UUID uuid, Session session) throws DBException;
|
||||
void serverInfoForThisServer(Server server);
|
||||
|
||||
void serverInfoForThisServer(Server server) throws DBException;
|
||||
|
||||
void webUser(WebUser webUser) throws DBException;
|
||||
}
|
||||
void webUser(WebUser webUser);
|
||||
}
|
@ -1,11 +1,9 @@
|
||||
package com.djrapitops.plan.system.database.databases.operation;
|
||||
|
||||
import com.djrapitops.plan.api.exceptions.database.DBException;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface SearchOperations {
|
||||
|
||||
List<String> matchingPlayers(String search) throws DBException;
|
||||
List<String> matchingPlayers(String search);
|
||||
|
||||
}
|
||||
|
@ -4,8 +4,6 @@
|
||||
*/
|
||||
package com.djrapitops.plan.system.database.databases.operation;
|
||||
|
||||
import com.djrapitops.plan.api.exceptions.database.DBException;
|
||||
|
||||
import java.util.Optional;
|
||||
import java.util.UUID;
|
||||
|
||||
@ -20,12 +18,12 @@ public interface TransferOperations {
|
||||
|
||||
// Save
|
||||
|
||||
void storeConfigSettings(String encodedSettingString) throws DBException;
|
||||
void storeConfigSettings(String encodedSettingString);
|
||||
|
||||
// Get
|
||||
|
||||
@Deprecated
|
||||
Optional<UUID> getServerPlayerIsOnlineOn(UUID playerUUID) throws DBException;
|
||||
Optional<UUID> getServerPlayerIsOnlineOn(UUID playerUUID);
|
||||
|
||||
Optional<String> getEncodedConfigSettings() throws DBException;
|
||||
}
|
||||
Optional<String> getEncodedConfigSettings();
|
||||
}
|
@ -1,10 +1,12 @@
|
||||
package com.djrapitops.plan.system.database.databases.sql;
|
||||
|
||||
import com.djrapitops.plan.api.exceptions.database.DBException;
|
||||
import com.djrapitops.plan.api.exceptions.database.DBInitException;
|
||||
import com.djrapitops.plan.api.exceptions.database.DBOpException;
|
||||
import com.djrapitops.plan.system.database.databases.Database;
|
||||
import com.djrapitops.plan.system.database.databases.operation.*;
|
||||
import com.djrapitops.plan.system.database.databases.sql.operation.*;
|
||||
import com.djrapitops.plan.system.database.databases.sql.processing.ExecStatement;
|
||||
import com.djrapitops.plan.system.database.databases.sql.processing.QueryStatement;
|
||||
import com.djrapitops.plan.system.database.databases.sql.tables.*;
|
||||
import com.djrapitops.plan.system.database.databases.sql.tables.move.Version8TransferTable;
|
||||
import com.djrapitops.plan.system.settings.Settings;
|
||||
@ -16,6 +18,7 @@ import com.djrapitops.plugin.task.RunnableFactory;
|
||||
import org.apache.commons.dbcp2.BasicDataSource;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.SQLException;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
@ -32,7 +35,6 @@ public abstract class SQLDB extends Database {
|
||||
|
||||
private final UsersTable usersTable;
|
||||
private final UserInfoTable userInfoTable;
|
||||
private final ActionsTable actionsTable;
|
||||
private final KillsTable killsTable;
|
||||
private final NicknamesTable nicknamesTable;
|
||||
private final SessionsTable sessionsTable;
|
||||
@ -70,7 +72,6 @@ public abstract class SQLDB extends Database {
|
||||
|
||||
usersTable = new UsersTable(this);
|
||||
userInfoTable = new UserInfoTable(this);
|
||||
actionsTable = new ActionsTable(this);
|
||||
geoInfoTable = new GeoInfoTable(this);
|
||||
nicknamesTable = new NicknamesTable(this);
|
||||
sessionsTable = new SessionsTable(this);
|
||||
@ -115,7 +116,7 @@ public abstract class SQLDB extends Database {
|
||||
if (isOpen()) {
|
||||
clean();
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
} catch (DBOpException e) {
|
||||
Log.toLog(this.getClass(), e);
|
||||
cancel();
|
||||
}
|
||||
@ -139,7 +140,7 @@ public abstract class SQLDB extends Database {
|
||||
|
||||
if (newDatabase) {
|
||||
Log.info("New Database created.");
|
||||
versionTable.setVersion(18);
|
||||
versionTable.setVersion(19);
|
||||
}
|
||||
|
||||
int version = versionTable.getVersion();
|
||||
@ -151,7 +152,7 @@ public abstract class SQLDB extends Database {
|
||||
public void run() {
|
||||
try {
|
||||
new Version8TransferTable(db).alterTablesToV10();
|
||||
} catch (DBInitException | SQLException e) {
|
||||
} catch (DBInitException | DBOpException e) {
|
||||
Log.toLog(this.getClass(), e);
|
||||
}
|
||||
}
|
||||
@ -162,7 +163,6 @@ public abstract class SQLDB extends Database {
|
||||
versionTable.setVersion(11);
|
||||
}
|
||||
if (version < 12) {
|
||||
actionsTable.alterTableV12();
|
||||
geoInfoTable.alterTableV12();
|
||||
versionTable.setVersion(12);
|
||||
}
|
||||
@ -191,7 +191,10 @@ public abstract class SQLDB extends Database {
|
||||
geoInfoTable.alterTableV18();
|
||||
// version set in the runnable in above method
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
if (version < 19) {
|
||||
nicknamesTable.alterTableV19();
|
||||
}
|
||||
} catch (DBOpException e) {
|
||||
throw new DBInitException("Failed to set-up Database", e);
|
||||
}
|
||||
}
|
||||
@ -216,8 +219,8 @@ public abstract class SQLDB extends Database {
|
||||
return new Table[]{
|
||||
serverTable, usersTable, userInfoTable, geoInfoTable,
|
||||
nicknamesTable, sessionsTable, killsTable,
|
||||
commandUseTable, actionsTable, tpsTable,
|
||||
worldTable, worldTimesTable, securityTable, transferTable
|
||||
commandUseTable, tpsTable, worldTable,
|
||||
worldTimesTable, securityTable, transferTable
|
||||
};
|
||||
}
|
||||
|
||||
@ -229,10 +232,9 @@ public abstract class SQLDB extends Database {
|
||||
public Table[] getAllTablesInRemoveOrder() {
|
||||
return new Table[]{
|
||||
transferTable, geoInfoTable, nicknamesTable, killsTable,
|
||||
worldTimesTable, sessionsTable, actionsTable,
|
||||
worldTable, userInfoTable, usersTable,
|
||||
commandUseTable, tpsTable, securityTable,
|
||||
serverTable
|
||||
worldTimesTable, sessionsTable, worldTable,
|
||||
userInfoTable, usersTable, commandUseTable,
|
||||
tpsTable, securityTable, serverTable
|
||||
};
|
||||
}
|
||||
|
||||
@ -249,15 +251,15 @@ public abstract class SQLDB extends Database {
|
||||
}
|
||||
}
|
||||
|
||||
public int getVersion() throws SQLException {
|
||||
public int getVersion() {
|
||||
return versionTable.getVersion();
|
||||
}
|
||||
|
||||
public void setVersion(int version) throws SQLException {
|
||||
public void setVersion(int version) {
|
||||
versionTable.setVersion(version);
|
||||
}
|
||||
|
||||
private void clean() throws SQLException {
|
||||
private void clean() {
|
||||
tpsTable.clean();
|
||||
transferTable.clean();
|
||||
geoInfoTable.clean();
|
||||
@ -270,11 +272,7 @@ public abstract class SQLDB extends Database {
|
||||
.map(Map.Entry::getKey)
|
||||
.collect(Collectors.toList());
|
||||
for (UUID uuid : inactivePlayers) {
|
||||
try {
|
||||
removeOps.player(uuid);
|
||||
} catch (DBException e) {
|
||||
Log.toLog(this.getClass().getName(), e);
|
||||
}
|
||||
removeOps.player(uuid);
|
||||
}
|
||||
int removed = inactivePlayers.size();
|
||||
if (removed > 0) {
|
||||
@ -289,7 +287,7 @@ public abstract class SQLDB extends Database {
|
||||
* <p>
|
||||
* MySQL has Auto Commit enabled.
|
||||
*/
|
||||
public void commit(Connection connection) throws SQLException {
|
||||
public void commit(Connection connection) {
|
||||
try {
|
||||
if (!usingMySQL) {
|
||||
connection.commit();
|
||||
@ -303,9 +301,13 @@ public abstract class SQLDB extends Database {
|
||||
}
|
||||
}
|
||||
|
||||
public void returnToPool(Connection connection) throws SQLException {
|
||||
if (usingMySQL && connection != null) {
|
||||
connection.close();
|
||||
public void returnToPool(Connection connection) {
|
||||
try {
|
||||
if (usingMySQL && connection != null) {
|
||||
connection.close();
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
Log.toLog(this.getClass(), e);
|
||||
}
|
||||
}
|
||||
|
||||
@ -324,6 +326,48 @@ public abstract class SQLDB extends Database {
|
||||
}
|
||||
}
|
||||
|
||||
public boolean execute(ExecStatement statement) {
|
||||
Connection connection = null;
|
||||
try {
|
||||
connection = getConnection();
|
||||
try (PreparedStatement preparedStatement = connection.prepareStatement(statement.getSql())) {
|
||||
return statement.execute(preparedStatement);
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
throw DBOpException.forCause(statement.getSql(), e);
|
||||
} finally {
|
||||
commit(connection);
|
||||
}
|
||||
}
|
||||
|
||||
public void executeBatch(ExecStatement statement) {
|
||||
Connection connection = null;
|
||||
try {
|
||||
connection = getConnection();
|
||||
try (PreparedStatement preparedStatement = connection.prepareStatement(statement.getSql())) {
|
||||
statement.executeBatch(preparedStatement);
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
throw DBOpException.forCause(statement.getSql(), e);
|
||||
} finally {
|
||||
commit(connection);
|
||||
}
|
||||
}
|
||||
|
||||
public <T> T query(QueryStatement<T> statement) {
|
||||
Connection connection = null;
|
||||
try {
|
||||
connection = getConnection();
|
||||
try (PreparedStatement preparedStatement = connection.prepareStatement(statement.getSql())) {
|
||||
return statement.executeQuery(preparedStatement);
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
throw DBOpException.forCause(statement.getSql(), e);
|
||||
} finally {
|
||||
returnToPool(connection);
|
||||
}
|
||||
}
|
||||
|
||||
public UsersTable getUsersTable() {
|
||||
return usersTable;
|
||||
}
|
||||
@ -368,10 +412,6 @@ public abstract class SQLDB extends Database {
|
||||
return serverTable;
|
||||
}
|
||||
|
||||
public ActionsTable getActionsTable() {
|
||||
return actionsTable;
|
||||
}
|
||||
|
||||
public UserInfoTable getUserInfoTable() {
|
||||
return userInfoTable;
|
||||
}
|
||||
|
@ -5,8 +5,6 @@ import com.djrapitops.plan.system.database.databases.operation.BackupOperations;
|
||||
import com.djrapitops.plan.system.database.databases.sql.SQLDB;
|
||||
import com.djrapitops.plan.system.database.databases.sql.tables.move.BatchOperationTable;
|
||||
|
||||
import java.sql.SQLException;
|
||||
|
||||
public class SQLBackupOps extends SQLOps implements BackupOperations {
|
||||
|
||||
public SQLBackupOps(SQLDB db) {
|
||||
@ -14,7 +12,7 @@ public class SQLBackupOps extends SQLOps implements BackupOperations {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void backup(Database toDatabase) throws SQLException {
|
||||
public void backup(Database toDatabase) {
|
||||
BatchOperationTable toDB = new BatchOperationTable((SQLDB) toDatabase);
|
||||
BatchOperationTable fromDB = new BatchOperationTable(db);
|
||||
|
||||
@ -23,7 +21,7 @@ public class SQLBackupOps extends SQLOps implements BackupOperations {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void restore(Database fromDatabase) throws SQLException {
|
||||
public void restore(Database fromDatabase) {
|
||||
fromDatabase.backup().backup(db);
|
||||
}
|
||||
}
|
||||
|
@ -1,11 +1,9 @@
|
||||
package com.djrapitops.plan.system.database.databases.sql.operation;
|
||||
|
||||
import com.djrapitops.plan.api.exceptions.database.DBException;
|
||||
import com.djrapitops.plan.system.database.databases.operation.CheckOperations;
|
||||
import com.djrapitops.plan.system.database.databases.sql.SQLDB;
|
||||
import com.djrapitops.plan.system.info.server.ServerInfo;
|
||||
|
||||
import java.sql.SQLException;
|
||||
import java.util.UUID;
|
||||
|
||||
public class SQLCheckOps extends SQLOps implements CheckOperations {
|
||||
@ -15,43 +13,27 @@ public class SQLCheckOps extends SQLOps implements CheckOperations {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isPlayerRegistered(UUID player) throws DBException {
|
||||
try {
|
||||
return usersTable.isRegistered(player);
|
||||
} catch (SQLException e) {
|
||||
throw SQLErrorUtil.getExceptionFor(e);
|
||||
}
|
||||
public boolean isPlayerRegistered(UUID player) {
|
||||
return usersTable.isRegistered(player);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isPlayerRegistered(UUID player, UUID server) throws DBException {
|
||||
try {
|
||||
return userInfoTable.isRegistered(player, server);
|
||||
} catch (SQLException e) {
|
||||
throw SQLErrorUtil.getExceptionFor(e);
|
||||
}
|
||||
public boolean isPlayerRegistered(UUID player, UUID server) {
|
||||
return userInfoTable.isRegistered(player, server);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean doesWebUserExists(String username) throws DBException {
|
||||
try {
|
||||
return securityTable.userExists(username);
|
||||
} catch (SQLException e) {
|
||||
throw SQLErrorUtil.getExceptionFor(e);
|
||||
}
|
||||
public boolean doesWebUserExists(String username) {
|
||||
return securityTable.userExists(username);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isPlayerRegisteredOnThisServer(UUID player) throws DBException {
|
||||
public boolean isPlayerRegisteredOnThisServer(UUID player) {
|
||||
return isPlayerRegistered(player, ServerInfo.getServerUUID());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isServerInDatabase(UUID serverUUID) throws DBException {
|
||||
try {
|
||||
return serverTable.getServerID(serverUUID).isPresent();
|
||||
} catch (SQLException e) {
|
||||
throw SQLErrorUtil.getExceptionFor(e);
|
||||
}
|
||||
public boolean isServerInDatabase(UUID serverUUID) {
|
||||
return serverTable.getServerID(serverUUID).isPresent();
|
||||
}
|
||||
}
|
||||
|
@ -1,10 +1,8 @@
|
||||
package com.djrapitops.plan.system.database.databases.sql.operation;
|
||||
|
||||
import com.djrapitops.plan.api.exceptions.database.DBException;
|
||||
import com.djrapitops.plan.system.database.databases.operation.CountOperations;
|
||||
import com.djrapitops.plan.system.database.databases.sql.SQLDB;
|
||||
|
||||
import java.sql.SQLException;
|
||||
import java.util.UUID;
|
||||
|
||||
public class SQLCountOps extends SQLOps implements CountOperations {
|
||||
@ -14,20 +12,12 @@ public class SQLCountOps extends SQLOps implements CountOperations {
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getServerPlayerCount(UUID server) throws DBException {
|
||||
try {
|
||||
return userInfoTable.getServerUserCount(server);
|
||||
} catch (SQLException e) {
|
||||
throw SQLErrorUtil.getExceptionFor(e);
|
||||
}
|
||||
public int getServerPlayerCount(UUID server) {
|
||||
return userInfoTable.getServerUserCount(server);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getNetworkPlayerCount() throws DBException {
|
||||
try {
|
||||
return usersTable.getPlayerCount();
|
||||
} catch (SQLException e) {
|
||||
throw SQLErrorUtil.getExceptionFor(e);
|
||||
}
|
||||
public int getNetworkPlayerCount() {
|
||||
return usersTable.getPlayerCount();
|
||||
}
|
||||
}
|
||||
|
@ -1,16 +1,25 @@
|
||||
package com.djrapitops.plan.system.database.databases.sql.operation;
|
||||
|
||||
import com.djrapitops.plan.api.exceptions.database.DBException;
|
||||
import com.djrapitops.plan.data.PlayerProfile;
|
||||
import com.djrapitops.plan.data.ServerProfile;
|
||||
import com.djrapitops.plan.data.WebUser;
|
||||
import com.djrapitops.plan.data.container.*;
|
||||
import com.djrapitops.plan.data.container.GeoInfo;
|
||||
import com.djrapitops.plan.data.container.Session;
|
||||
import com.djrapitops.plan.data.container.TPS;
|
||||
import com.djrapitops.plan.data.container.UserInfo;
|
||||
import com.djrapitops.plan.data.store.containers.*;
|
||||
import com.djrapitops.plan.data.store.keys.PerServerKeys;
|
||||
import com.djrapitops.plan.data.store.keys.PlayerKeys;
|
||||
import com.djrapitops.plan.data.store.keys.ServerKeys;
|
||||
import com.djrapitops.plan.data.store.keys.SessionKeys;
|
||||
import com.djrapitops.plan.data.store.mutators.PerServerDataMutator;
|
||||
import com.djrapitops.plan.data.store.mutators.PlayersMutator;
|
||||
import com.djrapitops.plan.data.store.mutators.SessionsMutator;
|
||||
import com.djrapitops.plan.data.store.objects.DateObj;
|
||||
import com.djrapitops.plan.data.time.WorldTimes;
|
||||
import com.djrapitops.plan.system.database.databases.operation.FetchOperations;
|
||||
import com.djrapitops.plan.system.database.databases.sql.SQLDB;
|
||||
import com.djrapitops.plan.system.info.server.Server;
|
||||
import com.djrapitops.plugin.api.TimeAmount;
|
||||
|
||||
import java.sql.SQLException;
|
||||
import java.util.*;
|
||||
|
||||
public class SQLFetchOps extends SQLOps implements FetchOperations {
|
||||
@ -20,386 +29,397 @@ public class SQLFetchOps extends SQLOps implements FetchOperations {
|
||||
}
|
||||
|
||||
@Override
|
||||
public ServerProfile getServerProfile(UUID serverUUID) throws DBException {
|
||||
try {
|
||||
ServerProfile profile = new ServerProfile(serverUUID);
|
||||
public NetworkContainer getNetworkContainer() {
|
||||
return new NetworkContainer(getBungeeServerContainer());
|
||||
}
|
||||
|
||||
profile.setPlayers(getPlayers(serverUUID));
|
||||
profile.setTps(tpsTable.getTPSData(serverUUID));
|
||||
Optional<TPS> allTimePeak = tpsTable.getAllTimePeak(serverUUID);
|
||||
allTimePeak.ifPresent(peak -> {
|
||||
profile.setAllTimePeak(peak.getDate());
|
||||
profile.setAllTimePeakPlayers(peak.getPlayers());
|
||||
});
|
||||
Optional<TPS> lastPeak = tpsTable.getPeakPlayerCount(serverUUID, System.currentTimeMillis() - (TimeAmount.DAY.ms() * 2L));
|
||||
lastPeak.ifPresent(peak -> {
|
||||
profile.setLastPeakDate(peak.getDate());
|
||||
profile.setLastPeakPlayers(peak.getPlayers());
|
||||
});
|
||||
|
||||
profile.setCommandUsage(commandUseTable.getCommandUse(serverUUID));
|
||||
profile.setServerWorldtimes(worldTimesTable.getWorldTimesOfServer(serverUUID));
|
||||
|
||||
return profile;
|
||||
} catch (SQLException e) {
|
||||
throw SQLErrorUtil.getExceptionFor(e);
|
||||
private ServerContainer getBungeeServerContainer() {
|
||||
Optional<Server> bungeeInfo = serverTable.getBungeeInfo();
|
||||
if (!bungeeInfo.isPresent()) {
|
||||
return new ServerContainer();
|
||||
}
|
||||
|
||||
ServerContainer container = getServerContainer(bungeeInfo.get().getUuid());
|
||||
container.putSupplier(ServerKeys.PLAYERS, this::getAllPlayerContainers);
|
||||
container.putSupplier(ServerKeys.TPS, tpsTable::getNetworkOnlineData);
|
||||
container.putSupplier(ServerKeys.WORLD_TIMES, null); // Additional Session information not supported
|
||||
container.putSupplier(ServerKeys.PLAYER_KILLS, null);
|
||||
container.putSupplier(ServerKeys.PLAYER_KILL_COUNT, null);
|
||||
|
||||
return container;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<PlayerProfile> getPlayers(UUID serverUUID) throws DBException {
|
||||
try {
|
||||
List<UserInfo> serverUserInfo = userInfoTable.getServerUserInfo(serverUUID);
|
||||
Map<UUID, Integer> timesKicked = usersTable.getAllTimesKicked();
|
||||
Map<UUID, List<Action>> actions = actionsTable.getServerActions(serverUUID);
|
||||
Map<UUID, List<GeoInfo>> geoInfo = geoInfoTable.getAllGeoInfo();
|
||||
public ServerContainer getServerContainer(UUID serverUUID) {
|
||||
ServerContainer container = new ServerContainer();
|
||||
|
||||
Map<UUID, List<Session>> sessions = sessionsTable.getSessionInfoOfServer(serverUUID);
|
||||
Map<UUID, Map<UUID, List<Session>>> map = new HashMap<>();
|
||||
map.put(serverUUID, sessions);
|
||||
killsTable.addKillsToSessions(map);
|
||||
worldTimesTable.addWorldTimesToSessions(map);
|
||||
Optional<Server> serverInfo = serverTable.getServerInfo(serverUUID);
|
||||
if (!serverInfo.isPresent()) {
|
||||
return container;
|
||||
}
|
||||
|
||||
List<PlayerProfile> players = new ArrayList<>();
|
||||
container.putRawData(ServerKeys.SERVER_UUID, serverUUID);
|
||||
container.putRawData(ServerKeys.NAME, serverInfo.get().getName());
|
||||
container.putSupplier(ServerKeys.PLAYERS, () -> getPlayerContainers(serverUUID));
|
||||
container.putSupplier(ServerKeys.PLAYER_COUNT, () -> container.getUnsafe(ServerKeys.PLAYERS).size());
|
||||
|
||||
container.putSupplier(ServerKeys.TPS, () -> tpsTable.getTPSData(serverUUID));
|
||||
container.putSupplier(ServerKeys.ALL_TIME_PEAK_PLAYERS, () -> {
|
||||
Optional<TPS> allTimePeak = tpsTable.getAllTimePeak(serverUUID);
|
||||
if (allTimePeak.isPresent()) {
|
||||
TPS peak = allTimePeak.get();
|
||||
return new DateObj<>(peak.getDate(), peak.getPlayers());
|
||||
}
|
||||
return null;
|
||||
});
|
||||
container.putSupplier(ServerKeys.RECENT_PEAK_PLAYERS, () -> {
|
||||
long twoDaysAgo = System.currentTimeMillis() - (TimeAmount.DAY.ms() * 2L);
|
||||
Optional<TPS> lastPeak = tpsTable.getPeakPlayerCount(serverUUID, twoDaysAgo);
|
||||
if (lastPeak.isPresent()) {
|
||||
TPS peak = lastPeak.get();
|
||||
return new DateObj<>(peak.getDate(), peak.getPlayers());
|
||||
}
|
||||
return null;
|
||||
});
|
||||
|
||||
container.putSupplier(ServerKeys.COMMAND_USAGE, () -> commandUseTable.getCommandUse(serverUUID));
|
||||
container.putSupplier(ServerKeys.WORLD_TIMES, () -> worldTimesTable.getWorldTimesOfServer(serverUUID));
|
||||
|
||||
// Calculating getters
|
||||
container.putSupplier(ServerKeys.OPERATORS, () -> PlayersMutator.forContainer(container).operators());
|
||||
container.putSupplier(ServerKeys.SESSIONS, () -> PlayersMutator.forContainer(container).getSessions());
|
||||
container.putSupplier(ServerKeys.PLAYER_KILLS, () -> SessionsMutator.forContainer(container).toPlayerKillList());
|
||||
container.putSupplier(ServerKeys.PLAYER_KILL_COUNT, () -> container.getUnsafe(ServerKeys.PLAYER_KILLS).size());
|
||||
container.putSupplier(ServerKeys.MOB_KILL_COUNT, () -> SessionsMutator.forContainer(container).toMobKillCount());
|
||||
container.putSupplier(ServerKeys.DEATH_COUNT, () -> SessionsMutator.forContainer(container).toDeathCount());
|
||||
|
||||
return container;
|
||||
}
|
||||
|
||||
private List<PlayerContainer> getPlayerContainers(UUID serverUUID) {
|
||||
List<PlayerContainer> containers = new ArrayList<>();
|
||||
|
||||
List<UserInfo> serverUserInfo = userInfoTable.getServerUserInfo(serverUUID);
|
||||
Map<UUID, Integer> timesKicked = usersTable.getAllTimesKicked();
|
||||
Map<UUID, List<GeoInfo>> geoInfo = geoInfoTable.getAllGeoInfo();
|
||||
|
||||
Map<UUID, List<Session>> sessions = sessionsTable.getSessionInfoOfServer(serverUUID);
|
||||
Map<UUID, Map<UUID, List<Session>>> map = new HashMap<>();
|
||||
map.put(serverUUID, sessions);
|
||||
killsTable.addKillsToSessions(map);
|
||||
worldTimesTable.addWorldTimesToSessions(map);
|
||||
|
||||
Map<UUID, List<UserInfo>> serverUserInfos = Collections.singletonMap(serverUUID, serverUserInfo);
|
||||
Map<UUID, Map<UUID, List<Session>>> serverSessions = Collections.singletonMap(serverUUID, sessions);
|
||||
Map<UUID, PerServerContainer> perServerInfo = getPerServerData(serverSessions, serverUserInfos);
|
||||
|
||||
for (UserInfo userInfo : serverUserInfo) {
|
||||
PlayerContainer container = new PlayerContainer();
|
||||
UUID uuid = userInfo.getUuid();
|
||||
container.putRawData(PlayerKeys.UUID, uuid);
|
||||
|
||||
container.putRawData(PlayerKeys.REGISTERED, userInfo.getRegistered());
|
||||
container.putRawData(PlayerKeys.NAME, userInfo.getName());
|
||||
container.putRawData(PlayerKeys.KICK_COUNT, timesKicked.get(uuid));
|
||||
container.putSupplier(PlayerKeys.GEO_INFO, () -> geoInfo.get(uuid));
|
||||
container.putSupplier(PlayerKeys.NICKNAMES, () -> nicknamesTable.getNicknameInformation(uuid));
|
||||
container.putSupplier(PlayerKeys.PER_SERVER, () -> perServerInfo.get(uuid));
|
||||
|
||||
container.putRawData(PlayerKeys.BANNED, userInfo.isBanned());
|
||||
container.putRawData(PlayerKeys.OPERATOR, userInfo.isOperator());
|
||||
|
||||
container.putSupplier(PlayerKeys.SESSIONS, () -> {
|
||||
List<Session> playerSessions = sessions.getOrDefault(uuid, new ArrayList<>());
|
||||
container.getValue(PlayerKeys.ACTIVE_SESSION).ifPresent(playerSessions::add);
|
||||
return playerSessions;
|
||||
}
|
||||
);
|
||||
|
||||
// Calculating getters
|
||||
container.putSupplier(PlayerKeys.WORLD_TIMES, () -> {
|
||||
WorldTimes worldTimes = new PerServerDataMutator(container.getUnsafe(PlayerKeys.PER_SERVER)).flatMapWorldTimes();
|
||||
container.getValue(PlayerKeys.ACTIVE_SESSION)
|
||||
.ifPresent(session -> worldTimes.add(
|
||||
session.getValue(SessionKeys.WORLD_TIMES).orElse(new WorldTimes(new HashMap<>())))
|
||||
);
|
||||
return worldTimes;
|
||||
});
|
||||
|
||||
container.putSupplier(PlayerKeys.LAST_SEEN, () -> SessionsMutator.forContainer(container).toLastSeen());
|
||||
|
||||
container.putSupplier(PlayerKeys.PLAYER_KILLS, () -> SessionsMutator.forContainer(container).toPlayerKillList());
|
||||
container.putSupplier(PlayerKeys.PLAYER_KILL_COUNT, () -> container.getUnsafe(PlayerKeys.PLAYER_KILLS).size());
|
||||
container.putSupplier(PlayerKeys.MOB_KILL_COUNT, () -> SessionsMutator.forContainer(container).toMobKillCount());
|
||||
container.putSupplier(PlayerKeys.DEATH_COUNT, () -> SessionsMutator.forContainer(container).toDeathCount());
|
||||
|
||||
containers.add(container);
|
||||
}
|
||||
return containers;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<PlayerContainer> getAllPlayerContainers() {
|
||||
List<PlayerContainer> containers = new ArrayList<>();
|
||||
|
||||
Map<UUID, UserInfo> users = usersTable.getUsers();
|
||||
Map<UUID, Integer> timesKicked = usersTable.getAllTimesKicked();
|
||||
Map<UUID, List<GeoInfo>> geoInfo = geoInfoTable.getAllGeoInfo();
|
||||
|
||||
Map<UUID, Map<UUID, List<Session>>> sessions = sessionsTable.getAllSessions(false);
|
||||
Map<UUID, List<UserInfo>> allUserInfo = userInfoTable.getAllUserInfo();
|
||||
Map<UUID, PerServerContainer> perServerInfo = getPerServerData(sessions, allUserInfo);
|
||||
|
||||
for (UserInfo userInfo : users.values()) {
|
||||
PlayerContainer container = new PlayerContainer();
|
||||
UUID uuid = userInfo.getUuid();
|
||||
container.putRawData(PlayerKeys.UUID, uuid);
|
||||
|
||||
container.putRawData(PlayerKeys.REGISTERED, userInfo.getRegistered());
|
||||
container.putRawData(PlayerKeys.NAME, userInfo.getName());
|
||||
container.putRawData(PlayerKeys.KICK_COUNT, timesKicked.get(uuid));
|
||||
container.putSupplier(PlayerKeys.GEO_INFO, () -> geoInfo.get(uuid));
|
||||
container.putSupplier(PlayerKeys.NICKNAMES, () -> nicknamesTable.getNicknameInformation(uuid));
|
||||
container.putSupplier(PlayerKeys.PER_SERVER, () -> perServerInfo.get(uuid));
|
||||
|
||||
container.putSupplier(PlayerKeys.SESSIONS, () -> {
|
||||
List<Session> playerSessions = PerServerDataMutator.forContainer(container).flatMapSessions();
|
||||
container.getValue(PlayerKeys.ACTIVE_SESSION).ifPresent(playerSessions::add);
|
||||
return playerSessions;
|
||||
}
|
||||
);
|
||||
|
||||
// Calculating getters
|
||||
container.putSupplier(PlayerKeys.LAST_SEEN, () -> SessionsMutator.forContainer(container).toLastSeen());
|
||||
|
||||
container.putSupplier(PlayerKeys.MOB_KILL_COUNT, () -> SessionsMutator.forContainer(container).toMobKillCount());
|
||||
container.putSupplier(PlayerKeys.DEATH_COUNT, () -> SessionsMutator.forContainer(container).toDeathCount());
|
||||
|
||||
containers.add(container);
|
||||
}
|
||||
return containers;
|
||||
}
|
||||
|
||||
private Map<UUID, PerServerContainer> getPerServerData(Map<UUID, Map<UUID, List<Session>>> sessions, Map<UUID, List<UserInfo>> allUserInfo) {
|
||||
Map<UUID, PerServerContainer> perServerContainers = new HashMap<>();
|
||||
|
||||
for (Map.Entry<UUID, List<UserInfo>> entry : allUserInfo.entrySet()) {
|
||||
UUID serverUUID = entry.getKey();
|
||||
List<UserInfo> serverUserInfo = entry.getValue();
|
||||
|
||||
for (UserInfo userInfo : serverUserInfo) {
|
||||
UUID uuid = userInfo.getUuid();
|
||||
if (uuid == null) {
|
||||
continue;
|
||||
}
|
||||
PlayerProfile profile = new PlayerProfile(uuid, userInfo.getName(), userInfo.getRegistered());
|
||||
profile.setTimesKicked(timesKicked.getOrDefault(uuid, 0));
|
||||
if (userInfo.isBanned()) {
|
||||
profile.bannedOnServer(serverUUID);
|
||||
}
|
||||
if (userInfo.isOpped()) {
|
||||
profile.oppedOnServer(serverUUID);
|
||||
}
|
||||
profile.setActions(actions.getOrDefault(uuid, new ArrayList<>()));
|
||||
profile.setGeoInformation(geoInfo.getOrDefault(uuid, new ArrayList<>()));
|
||||
profile.setSessions(serverUUID, sessions.getOrDefault(uuid, new ArrayList<>()));
|
||||
|
||||
players.add(profile);
|
||||
PerServerContainer perServerContainer = perServerContainers.getOrDefault(uuid, new PerServerContainer());
|
||||
DataContainer container = perServerContainer.getOrDefault(serverUUID, new DataContainer());
|
||||
container.putRawData(PlayerKeys.REGISTERED, userInfo.getRegistered());
|
||||
container.putRawData(PlayerKeys.BANNED, userInfo.isBanned());
|
||||
container.putRawData(PlayerKeys.OPERATOR, userInfo.isOperator());
|
||||
perServerContainer.put(serverUUID, container);
|
||||
perServerContainers.put(uuid, perServerContainer);
|
||||
}
|
||||
return players;
|
||||
} catch (SQLException e) {
|
||||
throw SQLErrorUtil.getExceptionFor(e);
|
||||
}
|
||||
|
||||
for (Map.Entry<UUID, Map<UUID, List<Session>>> entry : sessions.entrySet()) {
|
||||
UUID serverUUID = entry.getKey();
|
||||
Map<UUID, List<Session>> serverUserSessions = entry.getValue();
|
||||
|
||||
for (Map.Entry<UUID, List<Session>> sessionEntry : serverUserSessions.entrySet()) {
|
||||
UUID uuid = sessionEntry.getKey();
|
||||
PerServerContainer perServerContainer = perServerContainers.getOrDefault(uuid, new PerServerContainer());
|
||||
DataContainer container = perServerContainer.getOrDefault(serverUUID, new DataContainer());
|
||||
|
||||
List<Session> serverSessions = sessionEntry.getValue();
|
||||
container.putRawData(PerServerKeys.SESSIONS, serverSessions);
|
||||
|
||||
container.putSupplier(PerServerKeys.LAST_SEEN, () -> SessionsMutator.forContainer(container).toLastSeen());
|
||||
|
||||
container.putSupplier(PerServerKeys.WORLD_TIMES, () -> SessionsMutator.forContainer(container).toTotalWorldTimes());
|
||||
container.putSupplier(PerServerKeys.PLAYER_KILLS, () -> SessionsMutator.forContainer(container).toPlayerKillList());
|
||||
container.putSupplier(PerServerKeys.PLAYER_KILL_COUNT, () -> container.getUnsafe(PerServerKeys.PLAYER_KILLS).size());
|
||||
container.putSupplier(PerServerKeys.MOB_KILL_COUNT, () -> SessionsMutator.forContainer(container).toMobKillCount());
|
||||
container.putSupplier(PerServerKeys.DEATH_COUNT, () -> SessionsMutator.forContainer(container).toDeathCount());
|
||||
perServerContainer.put(serverUUID, container);
|
||||
perServerContainers.put(uuid, perServerContainer);
|
||||
}
|
||||
}
|
||||
|
||||
return perServerContainers;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PlayerProfile getPlayerProfile(UUID uuid) throws DBException {
|
||||
try {
|
||||
if (!usersTable.isRegistered(uuid)) {
|
||||
return null;
|
||||
}
|
||||
public PlayerContainer getPlayerContainer(UUID uuid) {
|
||||
PlayerContainer container = new PlayerContainer();
|
||||
container.putRawData(PlayerKeys.UUID, uuid);
|
||||
|
||||
String playerName = usersTable.getPlayerName(uuid);
|
||||
Optional<Long> registerDate = usersTable.getRegisterDate(uuid);
|
||||
container.putAll(usersTable.getUserInformation(uuid));
|
||||
container.putSupplier(PlayerKeys.GEO_INFO, () -> geoInfoTable.getGeoInfo(uuid));
|
||||
container.putSupplier(PlayerKeys.NICKNAMES, () -> nicknamesTable.getNicknameInformation(uuid));
|
||||
container.putSupplier(PlayerKeys.PER_SERVER, () -> getPerServerData(uuid));
|
||||
|
||||
if (!registerDate.isPresent()) {
|
||||
throw new IllegalStateException("User has been saved with null register date to a NOT NULL column");
|
||||
}
|
||||
container.putSupplier(PlayerKeys.BANNED, () -> new PerServerDataMutator(container.getUnsafe(PlayerKeys.PER_SERVER)).isBanned());
|
||||
container.putSupplier(PlayerKeys.OPERATOR, () -> new PerServerDataMutator(container.getUnsafe(PlayerKeys.PER_SERVER)).isOperator());
|
||||
|
||||
PlayerProfile profile = new PlayerProfile(uuid, playerName, registerDate.get());
|
||||
profile.setTimesKicked(usersTable.getTimesKicked(uuid));
|
||||
container.putSupplier(PlayerKeys.SESSIONS, () -> {
|
||||
List<Session> sessions = new PerServerDataMutator(container.getUnsafe(PlayerKeys.PER_SERVER)).flatMapSessions();
|
||||
container.getValue(PlayerKeys.ACTIVE_SESSION).ifPresent(sessions::add);
|
||||
return sessions;
|
||||
}
|
||||
);
|
||||
container.putSupplier(PlayerKeys.WORLD_TIMES, () ->
|
||||
{
|
||||
WorldTimes worldTimes = new PerServerDataMutator(container.getUnsafe(PlayerKeys.PER_SERVER)).flatMapWorldTimes();
|
||||
container.getValue(PlayerKeys.ACTIVE_SESSION).ifPresent(session -> worldTimes.add(
|
||||
session.getValue(SessionKeys.WORLD_TIMES).orElse(new WorldTimes(new HashMap<>())))
|
||||
);
|
||||
return worldTimes;
|
||||
});
|
||||
|
||||
Map<UUID, UserInfo> userInfo = userInfoTable.getAllUserInfo(uuid);
|
||||
addUserInfoToProfile(profile, userInfo);
|
||||
container.putSupplier(PlayerKeys.LAST_SEEN, () -> SessionsMutator.forContainer(container).toLastSeen());
|
||||
|
||||
profile.setActions(actionsTable.getActions(uuid));
|
||||
profile.setNicknames(nicknamesTable.getAllNicknames(uuid));
|
||||
profile.setGeoInformation(geoInfoTable.getGeoInfo(uuid));
|
||||
container.putSupplier(PlayerKeys.PLAYER_KILLS, () -> SessionsMutator.forContainer(container).toPlayerKillList());
|
||||
container.putSupplier(PlayerKeys.PLAYER_KILL_COUNT, () -> container.getUnsafe(PlayerKeys.PLAYER_KILLS).size());
|
||||
container.putSupplier(PlayerKeys.MOB_KILL_COUNT, () -> SessionsMutator.forContainer(container).toMobKillCount());
|
||||
container.putSupplier(PlayerKeys.DEATH_COUNT, () -> SessionsMutator.forContainer(container).toDeathCount());
|
||||
|
||||
Map<UUID, List<Session>> sessions = sessionsTable.getSessions(uuid);
|
||||
profile.setSessions(sessions);
|
||||
profile.calculateWorldTimesPerServer();
|
||||
profile.setTotalWorldTimes(worldTimesTable.getWorldTimesOfUser(uuid));
|
||||
|
||||
return profile;
|
||||
} catch (SQLException e) {
|
||||
throw SQLErrorUtil.getExceptionFor(e);
|
||||
}
|
||||
return container;
|
||||
}
|
||||
|
||||
private void addUserInfoToProfile(PlayerProfile profile, Map<UUID, UserInfo> userInfo) {
|
||||
for (Map.Entry<UUID, UserInfo> entry : userInfo.entrySet()) {
|
||||
private PerServerContainer getPerServerData(UUID uuid) {
|
||||
PerServerContainer perServerContainer = new PerServerContainer();
|
||||
|
||||
Map<UUID, UserInfo> allUserInfo = userInfoTable.getAllUserInfo(uuid);
|
||||
for (Map.Entry<UUID, UserInfo> entry : allUserInfo.entrySet()) {
|
||||
UUID serverUUID = entry.getKey();
|
||||
UserInfo info = entry.getValue();
|
||||
|
||||
profile.setRegistered(serverUUID, info.getRegistered());
|
||||
if (info.isBanned()) {
|
||||
profile.bannedOnServer(serverUUID);
|
||||
}
|
||||
if (info.isOpped()) {
|
||||
profile.oppedOnServer(serverUUID);
|
||||
}
|
||||
DataContainer container = perServerContainer.getOrDefault(serverUUID, new DataContainer());
|
||||
container.putRawData(PlayerKeys.REGISTERED, info.getRegistered());
|
||||
container.putRawData(PlayerKeys.BANNED, info.isBanned());
|
||||
container.putRawData(PlayerKeys.OPERATOR, info.isOperator());
|
||||
perServerContainer.put(serverUUID, container);
|
||||
}
|
||||
|
||||
Map<UUID, List<Session>> sessions = sessionsTable.getSessions(uuid);
|
||||
for (Map.Entry<UUID, List<Session>> entry : sessions.entrySet()) {
|
||||
UUID serverUUID = entry.getKey();
|
||||
List<Session> serverSessions = entry.getValue();
|
||||
|
||||
DataContainer container = perServerContainer.getOrDefault(serverUUID, new DataContainer());
|
||||
container.putRawData(PerServerKeys.SESSIONS, serverSessions);
|
||||
|
||||
container.putSupplier(PerServerKeys.LAST_SEEN, () -> SessionsMutator.forContainer(container).toLastSeen());
|
||||
|
||||
container.putSupplier(PerServerKeys.WORLD_TIMES, () -> SessionsMutator.forContainer(container).toTotalWorldTimes());
|
||||
container.putSupplier(PerServerKeys.PLAYER_KILLS, () -> SessionsMutator.forContainer(container).toPlayerKillList());
|
||||
container.putSupplier(PerServerKeys.PLAYER_KILL_COUNT, () -> container.getUnsafe(PerServerKeys.PLAYER_KILLS).size());
|
||||
container.putSupplier(PerServerKeys.MOB_KILL_COUNT, () -> SessionsMutator.forContainer(container).toMobKillCount());
|
||||
container.putSupplier(PerServerKeys.DEATH_COUNT, () -> SessionsMutator.forContainer(container).toDeathCount());
|
||||
|
||||
perServerContainer.put(serverUUID, container);
|
||||
}
|
||||
|
||||
return perServerContainer;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<UUID> getSavedUUIDs() throws DBException {
|
||||
try {
|
||||
return usersTable.getSavedUUIDs();
|
||||
} catch (SQLException e) {
|
||||
throw SQLErrorUtil.getExceptionFor(e);
|
||||
}
|
||||
public Set<UUID> getSavedUUIDs() {
|
||||
return usersTable.getSavedUUIDs();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<UUID> getSavedUUIDs(UUID server) throws DBException {
|
||||
try {
|
||||
return userInfoTable.getSavedUUIDs(server);
|
||||
} catch (SQLException e) {
|
||||
throw SQLErrorUtil.getExceptionFor(e);
|
||||
}
|
||||
public Set<UUID> getSavedUUIDs(UUID server) {
|
||||
return userInfoTable.getSavedUUIDs(server);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<UUID, String> getServerNames() throws DBException {
|
||||
try {
|
||||
return serverTable.getServerNames();
|
||||
} catch (SQLException e) {
|
||||
throw SQLErrorUtil.getExceptionFor(e);
|
||||
}
|
||||
public Map<UUID, String> getServerNames() {
|
||||
return serverTable.getServerNames();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<UUID> getServerUUID(String serverName) throws DBException {
|
||||
try {
|
||||
return serverTable.getServerUUID(serverName);
|
||||
} catch (SQLException e) {
|
||||
throw SQLErrorUtil.getExceptionFor(e);
|
||||
}
|
||||
public Optional<UUID> getServerUUID(String serverName) {
|
||||
return serverTable.getServerUUID(serverName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public UUID getUuidOf(String playerName) throws DBException {
|
||||
try {
|
||||
return usersTable.getUuidOf(playerName);
|
||||
} catch (SQLException e) {
|
||||
throw SQLErrorUtil.getExceptionFor(e);
|
||||
}
|
||||
public UUID getUuidOf(String playerName) {
|
||||
return usersTable.getUuidOf(playerName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public WebUser getWebUser(String username) throws DBException {
|
||||
try {
|
||||
return securityTable.getWebUser(username);
|
||||
} catch (SQLException e) {
|
||||
throw SQLErrorUtil.getExceptionFor(e);
|
||||
}
|
||||
public WebUser getWebUser(String username) {
|
||||
return securityTable.getWebUser(username);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<TPS> getTPSData(UUID serverUUID) throws DBException {
|
||||
try {
|
||||
return tpsTable.getTPSData(serverUUID);
|
||||
} catch (SQLException e) {
|
||||
throw SQLErrorUtil.getExceptionFor(e);
|
||||
}
|
||||
public List<TPS> getTPSData(UUID serverUUID) {
|
||||
return tpsTable.getTPSData(serverUUID);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<TPS> getNetworkOnlineData() throws DBException {
|
||||
try {
|
||||
return tpsTable.getNetworkOnlineData();
|
||||
} catch (SQLException e) {
|
||||
throw SQLErrorUtil.getExceptionFor(e);
|
||||
}
|
||||
public Map<UUID, Map<UUID, List<Session>>> getSessionsWithNoExtras() {
|
||||
return sessionsTable.getAllSessions(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Long> getRegisterDates() throws DBException {
|
||||
try {
|
||||
return usersTable.getRegisterDates();
|
||||
} catch (SQLException e) {
|
||||
throw SQLErrorUtil.getExceptionFor(e);
|
||||
}
|
||||
public Map<UUID, UserInfo> getUsers() {
|
||||
return usersTable.getUsers();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<TPS> getAllTimePeak(UUID serverUUID) throws DBException {
|
||||
try {
|
||||
return tpsTable.getAllTimePeak(serverUUID);
|
||||
} catch (SQLException e) {
|
||||
throw SQLErrorUtil.getExceptionFor(e);
|
||||
}
|
||||
public Map<UUID, Long> getLastSeenForAllPlayers() {
|
||||
return sessionsTable.getLastSeenForAllPlayers();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<TPS> getPeakPlayerCount(UUID serverUUID, long afterDate) throws DBException {
|
||||
try {
|
||||
return tpsTable.getPeakPlayerCount(serverUUID, afterDate);
|
||||
} catch (SQLException e) {
|
||||
throw SQLErrorUtil.getExceptionFor(e);
|
||||
}
|
||||
public Map<UUID, List<GeoInfo>> getAllGeoInfo() {
|
||||
return geoInfoTable.getAllGeoInfo();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<UUID, Map<UUID, List<Session>>> getSessionsWithNoExtras() throws DBException {
|
||||
try {
|
||||
return sessionsTable.getAllSessions(false);
|
||||
} catch (SQLException e) {
|
||||
throw SQLErrorUtil.getExceptionFor(e);
|
||||
}
|
||||
public Map<UUID, String> getPlayerNames() {
|
||||
return usersTable.getPlayerNames();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<UUID, Map<UUID, List<Session>>> getSessionsAndExtras() throws DBException {
|
||||
try {
|
||||
return sessionsTable.getAllSessions(true);
|
||||
} catch (SQLException e) {
|
||||
throw SQLErrorUtil.getExceptionFor(e);
|
||||
}
|
||||
public String getPlayerName(UUID playerUUID) {
|
||||
return usersTable.getPlayerName(playerUUID);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<UUID, Map<UUID, List<Session>>> getSessionsInLastMonth() throws DBException {
|
||||
try {
|
||||
return sessionsTable.getSessionInLastMonth();
|
||||
} catch (SQLException e) {
|
||||
throw SQLErrorUtil.getExceptionFor(e);
|
||||
}
|
||||
public Optional<String> getServerName(UUID serverUUID) {
|
||||
return serverTable.getServerName(serverUUID);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<String> getWorldNames(UUID serverUuid) throws DBException {
|
||||
try {
|
||||
return worldTable.getWorldNames(serverUuid);
|
||||
} catch (SQLException e) {
|
||||
throw SQLErrorUtil.getExceptionFor(e);
|
||||
}
|
||||
public List<String> getNicknames(UUID uuid) {
|
||||
return nicknamesTable.getNicknames(uuid);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getNicknamesOfPlayerOnServer(UUID uuid, UUID serverUUID) throws DBException {
|
||||
try {
|
||||
return nicknamesTable.getNicknames(uuid, serverUUID);
|
||||
} catch (SQLException e) {
|
||||
throw SQLErrorUtil.getExceptionFor(e);
|
||||
}
|
||||
public Optional<Server> getBungeeInformation() {
|
||||
return serverTable.getBungeeInfo();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Action> getActions(UUID uuid) throws DBException {
|
||||
try {
|
||||
return actionsTable.getActions(uuid);
|
||||
} catch (SQLException e) {
|
||||
throw SQLErrorUtil.getExceptionFor(e);
|
||||
}
|
||||
public Optional<Integer> getServerID(UUID serverUUID) {
|
||||
return serverTable.getServerID(serverUUID);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<UUID, UserInfo> getUsers() throws DBException {
|
||||
try {
|
||||
return usersTable.getUsers();
|
||||
} catch (SQLException e) {
|
||||
throw SQLErrorUtil.getExceptionFor(e);
|
||||
}
|
||||
public Map<UUID, Server> getBukkitServers() {
|
||||
return serverTable.getBukkitServers();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<UUID, Long> getLastSeenForAllPlayers() throws DBException {
|
||||
try {
|
||||
return sessionsTable.getLastSeenForAllPlayers();
|
||||
} catch (SQLException e) {
|
||||
throw SQLErrorUtil.getExceptionFor(e);
|
||||
}
|
||||
public List<WebUser> getWebUsers() {
|
||||
return securityTable.getUsers();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<UUID, List<GeoInfo>> getAllGeoInfo() throws DBException {
|
||||
try {
|
||||
return geoInfoTable.getAllGeoInfo();
|
||||
} catch (SQLException e) {
|
||||
throw SQLErrorUtil.getExceptionFor(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<UUID, String> getPlayerNames() throws DBException {
|
||||
try {
|
||||
return usersTable.getPlayerNames();
|
||||
} catch (SQLException e) {
|
||||
throw SQLErrorUtil.getExceptionFor(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPlayerName(UUID playerUUID) throws DBException {
|
||||
try {
|
||||
return usersTable.getPlayerName(playerUUID);
|
||||
} catch (SQLException e) {
|
||||
throw SQLErrorUtil.getExceptionFor(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<String> getServerName(UUID serverUUID) throws DBException {
|
||||
try {
|
||||
return serverTable.getServerName(serverUUID);
|
||||
} catch (SQLException e) {
|
||||
throw SQLErrorUtil.getExceptionFor(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getNicknames(UUID uuid) throws DBException {
|
||||
try {
|
||||
return nicknamesTable.getNicknames(uuid);
|
||||
} catch (SQLException e) {
|
||||
throw SQLErrorUtil.getExceptionFor(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<Server> getBungeeInformation() throws DBException {
|
||||
try {
|
||||
return serverTable.getBungeeInfo();
|
||||
} catch (SQLException e) {
|
||||
throw SQLErrorUtil.getExceptionFor(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<Integer> getServerID(UUID serverUUID) throws DBException {
|
||||
try {
|
||||
return serverTable.getServerID(serverUUID);
|
||||
} catch (SQLException e) {
|
||||
throw SQLErrorUtil.getExceptionFor(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<UUID, Server> getBukkitServers() throws DBException {
|
||||
try {
|
||||
return serverTable.getBukkitServers();
|
||||
} catch (SQLException e) {
|
||||
throw SQLErrorUtil.getExceptionFor(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<WebUser> getWebUsers() throws DBException {
|
||||
try {
|
||||
return securityTable.getUsers();
|
||||
} catch (SQLException e) {
|
||||
throw SQLErrorUtil.getExceptionFor(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<Integer, String> getServerNamesByID() throws DBException {
|
||||
try {
|
||||
return serverTable.getServerNamesByID();
|
||||
} catch (SQLException e) {
|
||||
throw SQLErrorUtil.getExceptionFor(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Server> getServers() throws DBException {
|
||||
public List<Server> getServers() {
|
||||
Map<UUID, Server> bukkitServers = getBukkitServers();
|
||||
Optional<Server> bungeeInformation = getBungeeInformation();
|
||||
|
||||
@ -411,20 +431,8 @@ public class SQLFetchOps extends SQLOps implements FetchOperations {
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<UUID> getServerUUIDs() throws DBException {
|
||||
try {
|
||||
return serverTable.getServerUUIDs();
|
||||
} catch (SQLException e) {
|
||||
throw SQLErrorUtil.getExceptionFor(e);
|
||||
}
|
||||
public List<UUID> getServerUUIDs() {
|
||||
return serverTable.getServerUUIDs();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getNetworkGeolocations() throws DBException {
|
||||
try {
|
||||
return geoInfoTable.getNetworkGeolocations();
|
||||
} catch (SQLException e) {
|
||||
throw SQLErrorUtil.getExceptionFor(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -9,7 +9,6 @@ public class SQLOps {
|
||||
|
||||
protected final UsersTable usersTable;
|
||||
protected final UserInfoTable userInfoTable;
|
||||
protected final ActionsTable actionsTable;
|
||||
protected final KillsTable killsTable;
|
||||
protected final NicknamesTable nicknamesTable;
|
||||
protected final SessionsTable sessionsTable;
|
||||
@ -27,7 +26,6 @@ public class SQLOps {
|
||||
|
||||
usersTable = db.getUsersTable();
|
||||
userInfoTable = db.getUserInfoTable();
|
||||
actionsTable = db.getActionsTable();
|
||||
killsTable = db.getKillsTable();
|
||||
nicknamesTable = db.getNicknamesTable();
|
||||
sessionsTable = db.getSessionsTable();
|
||||
|
@ -1,13 +1,10 @@
|
||||
package com.djrapitops.plan.system.database.databases.sql.operation;
|
||||
|
||||
import com.djrapitops.plan.api.exceptions.database.DBException;
|
||||
import com.djrapitops.plan.api.exceptions.database.FatalDBException;
|
||||
import com.djrapitops.plan.system.database.databases.operation.RemoveOperations;
|
||||
import com.djrapitops.plan.system.database.databases.sql.SQLDB;
|
||||
import com.djrapitops.plan.system.database.databases.sql.tables.Table;
|
||||
import com.djrapitops.plan.system.database.databases.sql.tables.UserIDTable;
|
||||
|
||||
import java.sql.SQLException;
|
||||
import java.util.UUID;
|
||||
|
||||
public class SQLRemoveOps extends SQLOps implements RemoveOperations {
|
||||
@ -17,56 +14,34 @@ public class SQLRemoveOps extends SQLOps implements RemoveOperations {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void player(UUID uuid) throws DBException {
|
||||
public void player(UUID uuid) {
|
||||
if (uuid == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
String webUser = usersTable.getPlayerName(uuid);
|
||||
String webUser = usersTable.getPlayerName(uuid);
|
||||
|
||||
for (Table t : db.getAllTablesInRemoveOrder()) {
|
||||
if (!(t instanceof UserIDTable)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
UserIDTable table = (UserIDTable) t;
|
||||
table.removeUser(uuid);
|
||||
for (Table t : db.getAllTablesInRemoveOrder()) {
|
||||
if (!(t instanceof UserIDTable)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
securityTable.removeUser(webUser);
|
||||
} catch (SQLException e) {
|
||||
throw SQLErrorUtil.getFatalExceptionFor(e);
|
||||
UserIDTable table = (UserIDTable) t;
|
||||
table.removeUser(uuid);
|
||||
}
|
||||
|
||||
securityTable.removeUser(webUser);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void everything() {
|
||||
for (Table table : db.getAllTablesInRemoveOrder()) {
|
||||
table.removeAllData();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void player(UUID player, UUID server) throws DBException {
|
||||
throw new FatalDBException("Not Implemented");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void server(UUID serverUUID) throws DBException {
|
||||
throw new FatalDBException("Not Implemented");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void everything() throws DBException {
|
||||
try {
|
||||
for (Table table : db.getAllTablesInRemoveOrder()) {
|
||||
table.removeAllData();
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
throw SQLErrorUtil.getFatalExceptionFor(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void webUser(String userName) throws DBException {
|
||||
try {
|
||||
securityTable.removeUser(userName);
|
||||
} catch (SQLException e) {
|
||||
throw SQLErrorUtil.getFatalExceptionFor(e);
|
||||
}
|
||||
public void webUser(String userName) {
|
||||
securityTable.removeUser(userName);
|
||||
}
|
||||
}
|
||||
|
@ -4,14 +4,16 @@
|
||||
*/
|
||||
package com.djrapitops.plan.system.database.databases.sql.operation;
|
||||
|
||||
import com.djrapitops.plan.api.exceptions.database.DBException;
|
||||
import com.djrapitops.plan.data.WebUser;
|
||||
import com.djrapitops.plan.data.container.*;
|
||||
import com.djrapitops.plan.data.container.GeoInfo;
|
||||
import com.djrapitops.plan.data.container.Session;
|
||||
import com.djrapitops.plan.data.container.TPS;
|
||||
import com.djrapitops.plan.data.container.UserInfo;
|
||||
import com.djrapitops.plan.data.store.objects.Nickname;
|
||||
import com.djrapitops.plan.system.database.databases.operation.SaveOperations;
|
||||
import com.djrapitops.plan.system.database.databases.sql.SQLDB;
|
||||
import com.djrapitops.plan.system.info.server.Server;
|
||||
|
||||
import java.sql.SQLException;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
@ -28,200 +30,107 @@ public class SQLSaveOps extends SQLOps implements SaveOperations {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void insertTPS(Map<UUID, List<TPS>> ofServers) throws DBException {
|
||||
try {
|
||||
tpsTable.insertAllTPS(ofServers);
|
||||
} catch (SQLException e) {
|
||||
throw SQLErrorUtil.getExceptionFor(e);
|
||||
}
|
||||
public void insertTPS(Map<UUID, List<TPS>> ofServers) {
|
||||
tpsTable.insertAllTPS(ofServers);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void insertCommandUsage(Map<UUID, Map<String, Integer>> ofServers) throws DBException {
|
||||
try {
|
||||
commandUseTable.insertCommandUsage(ofServers);
|
||||
} catch (SQLException e) {
|
||||
throw SQLErrorUtil.getExceptionFor(e);
|
||||
}
|
||||
public void insertCommandUsage(Map<UUID, Map<String, Integer>> ofServers) {
|
||||
commandUseTable.insertCommandUsage(ofServers);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void insertUsers(Map<UUID, UserInfo> ofServers) throws DBException {
|
||||
try {
|
||||
usersTable.insertUsers(ofServers);
|
||||
} catch (SQLException e) {
|
||||
throw SQLErrorUtil.getExceptionFor(e);
|
||||
}
|
||||
public void insertUsers(Map<UUID, UserInfo> ofServers) {
|
||||
usersTable.insertUsers(ofServers);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void insertSessions(Map<UUID, Map<UUID, List<Session>>> ofServers, boolean containsExtraData) throws DBException {
|
||||
try {
|
||||
sessionsTable.insertSessions(ofServers, containsExtraData);
|
||||
} catch (SQLException e) {
|
||||
throw SQLErrorUtil.getExceptionFor(e);
|
||||
}
|
||||
public void insertSessions(Map<UUID, Map<UUID, List<Session>>> ofServers, boolean containsExtraData) {
|
||||
sessionsTable.insertSessions(ofServers, containsExtraData);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void kickAmount(Map<UUID, Integer> ofUsers) throws DBException {
|
||||
try {
|
||||
usersTable.updateKicked(ofUsers);
|
||||
} catch (SQLException e) {
|
||||
throw SQLErrorUtil.getExceptionFor(e);
|
||||
}
|
||||
public void kickAmount(Map<UUID, Integer> ofUsers) {
|
||||
usersTable.updateKicked(ofUsers);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void insertUserInfo(Map<UUID, List<UserInfo>> ofServers) throws DBException {
|
||||
try {
|
||||
userInfoTable.insertUserInfo(ofServers);
|
||||
} catch (SQLException e) {
|
||||
throw SQLErrorUtil.getExceptionFor(e);
|
||||
}
|
||||
public void insertUserInfo(Map<UUID, List<UserInfo>> ofServers) {
|
||||
userInfoTable.insertUserInfo(ofServers);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void insertNicknames(Map<UUID, Map<UUID, List<String>>> ofServers) throws DBException {
|
||||
try {
|
||||
nicknamesTable.insertNicknames(ofServers);
|
||||
} catch (SQLException e) {
|
||||
throw SQLErrorUtil.getExceptionFor(e);
|
||||
}
|
||||
public void insertNicknames(Map<UUID, Map<UUID, List<Nickname>>> ofServers) {
|
||||
nicknamesTable.insertNicknames(ofServers);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void insertAllGeoInfo(Map<UUID, List<GeoInfo>> ofUsers) throws DBException {
|
||||
try {
|
||||
geoInfoTable.insertAllGeoInfo(ofUsers);
|
||||
} catch (SQLException e) {
|
||||
throw SQLErrorUtil.getExceptionFor(e);
|
||||
}
|
||||
public void insertAllGeoInfo(Map<UUID, List<GeoInfo>> ofUsers) {
|
||||
geoInfoTable.insertAllGeoInfo(ofUsers);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void banStatus(UUID uuid, boolean banned) throws DBException {
|
||||
try {
|
||||
userInfoTable.updateBanStatus(uuid, banned);
|
||||
} catch (SQLException e) {
|
||||
throw SQLErrorUtil.getExceptionFor(e);
|
||||
}
|
||||
public void banStatus(UUID uuid, boolean banned) {
|
||||
userInfoTable.updateBanStatus(uuid, banned);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void opStatus(UUID uuid, boolean op) throws DBException {
|
||||
try {
|
||||
userInfoTable.updateOpStatus(uuid, op);
|
||||
} catch (SQLException e) {
|
||||
throw SQLErrorUtil.getExceptionFor(e);
|
||||
}
|
||||
public void opStatus(UUID uuid, boolean op) {
|
||||
userInfoTable.updateOpStatus(uuid, op);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerNewUser(UUID uuid, long registered, String name) throws DBException {
|
||||
try {
|
||||
usersTable.registerUser(uuid, registered, name);
|
||||
} catch (SQLException e) {
|
||||
throw SQLErrorUtil.getExceptionFor(e);
|
||||
}
|
||||
public void registerNewUser(UUID uuid, long registered, String name) {
|
||||
usersTable.registerUser(uuid, registered, name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void action(UUID uuid, Action action) throws DBException {
|
||||
try {
|
||||
actionsTable.insertAction(uuid, action);
|
||||
} catch (SQLException e) {
|
||||
throw SQLErrorUtil.getExceptionFor(e);
|
||||
}
|
||||
public void geoInfo(UUID uuid, GeoInfo geoInfo) {
|
||||
geoInfoTable.saveGeoInfo(uuid, geoInfo);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void geoInfo(UUID uuid, GeoInfo geoInfo) throws DBException {
|
||||
try {
|
||||
geoInfoTable.saveGeoInfo(uuid, geoInfo);
|
||||
} catch (SQLException e) {
|
||||
throw SQLErrorUtil.getExceptionFor(e);
|
||||
}
|
||||
public void playerWasKicked(UUID uuid) {
|
||||
usersTable.kicked(uuid);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void playerWasKicked(UUID uuid) throws DBException {
|
||||
try {
|
||||
usersTable.kicked(uuid);
|
||||
} catch (SQLException e) {
|
||||
throw SQLErrorUtil.getExceptionFor(e);
|
||||
}
|
||||
public void playerName(UUID uuid, String playerName) {
|
||||
usersTable.updateName(uuid, playerName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void playerName(UUID uuid, String playerName) throws DBException {
|
||||
try {
|
||||
usersTable.updateName(uuid, playerName);
|
||||
} catch (SQLException e) {
|
||||
throw SQLErrorUtil.getExceptionFor(e);
|
||||
}
|
||||
public void playerDisplayName(UUID uuid, Nickname nickname) {
|
||||
nicknamesTable.saveUserName(uuid, nickname);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void playerDisplayName(UUID uuid, String displayName) throws DBException {
|
||||
try {
|
||||
nicknamesTable.saveUserName(uuid, displayName);
|
||||
} catch (SQLException e) {
|
||||
throw SQLErrorUtil.getExceptionFor(e);
|
||||
}
|
||||
public void registerNewUserOnThisServer(UUID uuid, long registered) {
|
||||
userInfoTable.registerUserInfo(uuid, registered);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerNewUserOnThisServer(UUID uuid, long registered) throws DBException {
|
||||
try {
|
||||
userInfoTable.registerUserInfo(uuid, registered);
|
||||
} catch (SQLException e) {
|
||||
throw SQLErrorUtil.getExceptionFor(e);
|
||||
}
|
||||
public void commandUsed(String commandName) {
|
||||
commandUseTable.commandUsed(commandName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void commandUsed(String commandName) throws DBException {
|
||||
try {
|
||||
commandUseTable.commandUsed(commandName);
|
||||
} catch (SQLException e) {
|
||||
throw SQLErrorUtil.getExceptionFor(e);
|
||||
}
|
||||
public void insertTPSforThisServer(TPS tps) {
|
||||
tpsTable.insertTPS(tps);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void insertTPSforThisServer(TPS tps) throws DBException {
|
||||
try {
|
||||
tpsTable.insertTPS(tps);
|
||||
} catch (SQLException e) {
|
||||
throw SQLErrorUtil.getExceptionFor(e);
|
||||
}
|
||||
public void session(UUID uuid, Session session) {
|
||||
sessionsTable.saveSession(uuid, session);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void session(UUID uuid, Session session) throws DBException {
|
||||
try {
|
||||
sessionsTable.saveSession(uuid, session);
|
||||
} catch (SQLException e) {
|
||||
throw SQLErrorUtil.getExceptionFor(e);
|
||||
}
|
||||
public void serverInfoForThisServer(Server server) {
|
||||
serverTable.saveCurrentServerInfo(server);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void serverInfoForThisServer(Server server) throws DBException {
|
||||
try {
|
||||
serverTable.saveCurrentServerInfo(server);
|
||||
} catch (SQLException e) {
|
||||
throw SQLErrorUtil.getExceptionFor(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void webUser(WebUser webUser) throws DBException {
|
||||
try {
|
||||
securityTable.addNewUser(webUser);
|
||||
} catch (SQLException e) {
|
||||
throw SQLErrorUtil.getExceptionFor(e);
|
||||
}
|
||||
public void webUser(WebUser webUser) {
|
||||
securityTable.addNewUser(webUser);
|
||||
}
|
||||
}
|
||||
|
@ -1,10 +1,8 @@
|
||||
package com.djrapitops.plan.system.database.databases.sql.operation;
|
||||
|
||||
import com.djrapitops.plan.api.exceptions.database.DBException;
|
||||
import com.djrapitops.plan.system.database.databases.operation.SearchOperations;
|
||||
import com.djrapitops.plan.system.database.databases.sql.SQLDB;
|
||||
|
||||
import java.sql.SQLException;
|
||||
import java.util.List;
|
||||
|
||||
public class SQLSearchOps extends SQLOps implements SearchOperations {
|
||||
@ -14,11 +12,7 @@ public class SQLSearchOps extends SQLOps implements SearchOperations {
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> matchingPlayers(String search) throws DBException {
|
||||
try {
|
||||
return usersTable.getMatchingNames(search);
|
||||
} catch (SQLException e) {
|
||||
throw SQLErrorUtil.getExceptionFor(e);
|
||||
}
|
||||
public List<String> matchingPlayers(String search) {
|
||||
return usersTable.getMatchingNames(search);
|
||||
}
|
||||
}
|
||||
|
@ -4,11 +4,9 @@
|
||||
*/
|
||||
package com.djrapitops.plan.system.database.databases.sql.operation;
|
||||
|
||||
import com.djrapitops.plan.api.exceptions.database.DBException;
|
||||
import com.djrapitops.plan.system.database.databases.operation.TransferOperations;
|
||||
import com.djrapitops.plan.system.database.databases.sql.SQLDB;
|
||||
|
||||
import java.sql.SQLException;
|
||||
import java.util.Optional;
|
||||
import java.util.UUID;
|
||||
|
||||
@ -24,30 +22,18 @@ public class SQLTransferOps extends SQLOps implements TransferOperations {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<UUID> getServerPlayerIsOnlineOn(UUID playerUUID) throws DBException {
|
||||
try {
|
||||
return transferTable.getServerPlayerIsOnline(playerUUID);
|
||||
} catch (SQLException e) {
|
||||
throw SQLErrorUtil.getExceptionFor(e);
|
||||
}
|
||||
public Optional<UUID> getServerPlayerIsOnlineOn(UUID playerUUID) {
|
||||
return transferTable.getServerPlayerIsOnline(playerUUID);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void storeConfigSettings(String encodedSettingString) throws DBException {
|
||||
try {
|
||||
transferTable.storeConfigSettings(encodedSettingString);
|
||||
} catch (SQLException e) {
|
||||
throw SQLErrorUtil.getExceptionFor(e);
|
||||
}
|
||||
public void storeConfigSettings(String encodedSettingString) {
|
||||
transferTable.storeConfigSettings(encodedSettingString);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<String> getEncodedConfigSettings() throws DBException {
|
||||
try {
|
||||
return transferTable.getConfigSettings();
|
||||
} catch (SQLException e) {
|
||||
throw SQLErrorUtil.getExceptionFor(e);
|
||||
}
|
||||
public Optional<String> getEncodedConfigSettings() {
|
||||
return transferTable.getConfigSettings();
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,252 +0,0 @@
|
||||
/*
|
||||
* License is provided in the jar as LICENSE also here:
|
||||
* https://github.com/Rsl1122/Plan-PlayerAnalytics/blob/master/Plan/src/main/resources/LICENSE
|
||||
*/
|
||||
package com.djrapitops.plan.system.database.databases.sql.tables;
|
||||
|
||||
import com.djrapitops.plan.api.exceptions.database.DBInitException;
|
||||
import com.djrapitops.plan.data.Actions;
|
||||
import com.djrapitops.plan.data.container.Action;
|
||||
import com.djrapitops.plan.system.database.databases.sql.SQLDB;
|
||||
import com.djrapitops.plan.system.database.databases.sql.processing.ExecStatement;
|
||||
import com.djrapitops.plan.system.database.databases.sql.processing.QueryAllStatement;
|
||||
import com.djrapitops.plan.system.database.databases.sql.processing.QueryStatement;
|
||||
import com.djrapitops.plan.system.database.databases.sql.statements.Column;
|
||||
import com.djrapitops.plan.system.database.databases.sql.statements.Select;
|
||||
import com.djrapitops.plan.system.database.databases.sql.statements.Sql;
|
||||
import com.djrapitops.plan.system.database.databases.sql.statements.TableSqlParser;
|
||||
import com.djrapitops.plan.system.info.server.ServerInfo;
|
||||
import com.djrapitops.plugin.utilities.Verify;
|
||||
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* Table that is in charge of storing actions.
|
||||
*
|
||||
* Table Name: plan_actions
|
||||
*
|
||||
* For contained columns {@see Col}
|
||||
*
|
||||
* @author Rsl1122
|
||||
* @see Action
|
||||
*/
|
||||
public class ActionsTable extends UserIDTable {
|
||||
|
||||
public ActionsTable(SQLDB db) {
|
||||
super("plan_actions", db);
|
||||
serverTable = db.getServerTable();
|
||||
insertStatement = "INSERT INTO " + tableName + " ("
|
||||
+ Col.USER_ID + ", "
|
||||
+ Col.SERVER_ID + ", "
|
||||
+ Col.ACTION_ID + ", "
|
||||
+ Col.DATE + ", "
|
||||
+ Col.ADDITIONAL_INFO
|
||||
+ ") VALUES ("
|
||||
+ usersTable.statementSelectID + ", "
|
||||
+ serverTable.statementSelectServerID + ", "
|
||||
+ "?, ?, ?)";
|
||||
}
|
||||
|
||||
private final ServerTable serverTable;
|
||||
private String insertStatement;
|
||||
|
||||
@Override
|
||||
public void createTable() throws DBInitException {
|
||||
ServerTable serverTable = db.getServerTable();
|
||||
createTable(TableSqlParser.createTable(tableName)
|
||||
.column(Col.USER_ID, Sql.INT).notNull()
|
||||
.column(Col.SERVER_ID, Sql.INT).notNull()
|
||||
.column(Col.DATE, Sql.LONG).notNull()
|
||||
.column(Col.ACTION_ID, Sql.INT).notNull()
|
||||
.column(Col.ADDITIONAL_INFO, Sql.varchar(300))
|
||||
.foreignKey(Col.USER_ID, usersTable.toString(), UsersTable.Col.ID)
|
||||
.foreignKey(Col.SERVER_ID, serverTable.toString(), ServerTable.Col.SERVER_ID)
|
||||
.toString());
|
||||
}
|
||||
|
||||
public void alterTableV12() {
|
||||
if (usingMySQL) {
|
||||
executeUnsafe("ALTER TABLE " + tableName + " MODIFY " + Col.ADDITIONAL_INFO + " VARCHAR(300)");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to get all Actions done by a user on this server.
|
||||
*
|
||||
* @param uuid UUID of the player
|
||||
* @return List of actions done by the player. Does not include the kills.
|
||||
* @throws SQLException DB Error
|
||||
*/
|
||||
public List<Action> getActions(UUID uuid) throws SQLException {
|
||||
String sql = Select.all(tableName)
|
||||
.where(Col.USER_ID + "=" + usersTable.statementSelectID)
|
||||
.toString();
|
||||
|
||||
return query(new QueryStatement<List<Action>>(sql, 5000) {
|
||||
@Override
|
||||
public void prepare(PreparedStatement statement) throws SQLException {
|
||||
statement.setString(1, uuid.toString());
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Action> processResults(ResultSet set) throws SQLException {
|
||||
List<Action> actions = new ArrayList<>();
|
||||
while (set.next()) {
|
||||
int serverID = set.getInt(Col.SERVER_ID.get());
|
||||
long date = set.getLong(Col.DATE.get());
|
||||
Actions doneAction = Actions.getById(set.getInt(Col.ACTION_ID.get()));
|
||||
String additionalInfo = set.getString(Col.ADDITIONAL_INFO.get());
|
||||
actions.add(new Action(date, doneAction, additionalInfo, serverID));
|
||||
}
|
||||
return actions;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void insertAction(UUID uuid, Action action) throws SQLException {
|
||||
execute(new ExecStatement(insertStatement) {
|
||||
@Override
|
||||
public void prepare(PreparedStatement statement) throws SQLException {
|
||||
statement.setString(1, uuid.toString());
|
||||
statement.setString(2, ServerInfo.getServerUUID().toString());
|
||||
statement.setInt(3, action.getDoneAction().getId());
|
||||
statement.setLong(4, action.getDate());
|
||||
statement.setString(5, action.getAdditionalInfo());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public Map<UUID, Map<UUID, List<Action>>> getAllActions() throws SQLException {
|
||||
String usersIDColumn = usersTable + "." + UsersTable.Col.ID;
|
||||
String usersUUIDColumn = usersTable + "." + UsersTable.Col.UUID + " as uuid";
|
||||
String serverIDColumn = serverTable + "." + ServerTable.Col.SERVER_ID;
|
||||
String serverUUIDColumn = serverTable + "." + ServerTable.Col.SERVER_UUID + " as s_uuid";
|
||||
String sql = "SELECT " +
|
||||
Col.ACTION_ID + ", " +
|
||||
Col.DATE + ", " +
|
||||
Col.ADDITIONAL_INFO + ", " +
|
||||
usersUUIDColumn + ", " +
|
||||
serverUUIDColumn +
|
||||
" FROM " + tableName +
|
||||
" INNER JOIN " + usersTable + " on " + usersIDColumn + "=" + Col.USER_ID +
|
||||
" INNER JOIN " + serverTable + " on " + serverIDColumn + "=" + Col.SERVER_ID;
|
||||
|
||||
return query(new QueryAllStatement<Map<UUID, Map<UUID, List<Action>>>>(sql, 20000) {
|
||||
@Override
|
||||
public Map<UUID, Map<UUID, List<Action>>> processResults(ResultSet set) throws SQLException {
|
||||
Map<UUID, Map<UUID, List<Action>>> map = new HashMap<>();
|
||||
while (set.next()) {
|
||||
UUID serverUUID = UUID.fromString(set.getString("s_uuid"));
|
||||
UUID uuid = UUID.fromString(set.getString("uuid"));
|
||||
|
||||
Map<UUID, List<Action>> serverMap = map.getOrDefault(serverUUID, new HashMap<>());
|
||||
List<Action> actions = serverMap.getOrDefault(uuid, new ArrayList<>());
|
||||
|
||||
long date = set.getLong(Col.DATE.get());
|
||||
Actions doneAction = Actions.getById(set.getInt(Col.ACTION_ID.get()));
|
||||
String additionalInfo = set.getString(Col.ADDITIONAL_INFO.get());
|
||||
|
||||
actions.add(new Action(date, doneAction, additionalInfo, -1));
|
||||
|
||||
serverMap.put(uuid, actions);
|
||||
map.put(serverUUID, serverMap);
|
||||
}
|
||||
return map;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public Map<UUID, List<Action>> getServerActions(UUID serverUUID) throws SQLException {
|
||||
String usersIDColumn = usersTable + "." + UsersTable.Col.ID;
|
||||
String usersUUIDColumn = usersTable + "." + UsersTable.Col.UUID + " as uuid";
|
||||
String sql = "SELECT " +
|
||||
Col.ACTION_ID + ", " +
|
||||
Col.DATE + ", " +
|
||||
Col.ADDITIONAL_INFO + ", " +
|
||||
usersUUIDColumn +
|
||||
" FROM " + tableName +
|
||||
" INNER JOIN " + usersTable + " on " + usersIDColumn + "=" + Col.USER_ID +
|
||||
" WHERE " + serverTable.statementSelectServerID + "=" + Col.SERVER_ID;
|
||||
|
||||
return query(new QueryStatement<Map<UUID, List<Action>>>(sql, 20000) {
|
||||
@Override
|
||||
public void prepare(PreparedStatement statement) throws SQLException {
|
||||
statement.setString(1, serverUUID.toString());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<UUID, List<Action>> processResults(ResultSet set) throws SQLException {
|
||||
Map<UUID, List<Action>> map = new HashMap<>();
|
||||
while (set.next()) {
|
||||
UUID uuid = UUID.fromString(set.getString("uuid"));
|
||||
|
||||
List<Action> actions = map.getOrDefault(uuid, new ArrayList<>());
|
||||
|
||||
long date = set.getLong(Col.DATE.get());
|
||||
Actions doneAction = Actions.getById(set.getInt(Col.ACTION_ID.get()));
|
||||
String additionalInfo = set.getString(Col.ADDITIONAL_INFO.get());
|
||||
|
||||
actions.add(new Action(date, doneAction, additionalInfo, -1));
|
||||
|
||||
map.put(uuid, actions);
|
||||
}
|
||||
return map;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void insertActions(Map<UUID, Map<UUID, List<Action>>> allActions) throws SQLException {
|
||||
if (Verify.isEmpty(allActions)) {
|
||||
return;
|
||||
}
|
||||
|
||||
executeBatch(new ExecStatement(insertStatement) {
|
||||
@Override
|
||||
public void prepare(PreparedStatement statement) throws SQLException {
|
||||
for (UUID serverUUID : allActions.keySet()) {
|
||||
// Every User
|
||||
for (Map.Entry<UUID, List<Action>> entry : allActions.get(serverUUID).entrySet()) {
|
||||
UUID uuid = entry.getKey();
|
||||
// Every Action
|
||||
List<Action> actions = entry.getValue();
|
||||
for (Action action : actions) {
|
||||
statement.setString(1, uuid.toString());
|
||||
statement.setString(2, serverUUID.toString());
|
||||
statement.setInt(3, action.getDoneAction().getId());
|
||||
statement.setLong(4, action.getDate());
|
||||
statement.setString(5, action.getAdditionalInfo());
|
||||
statement.addBatch();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public enum Col implements Column {
|
||||
USER_ID(UserIDTable.Col.USER_ID.get()),
|
||||
SERVER_ID("server_id"),
|
||||
DATE("date"),
|
||||
ACTION_ID("action_id"),
|
||||
ADDITIONAL_INFO("additional_info");
|
||||
|
||||
private final String column;
|
||||
|
||||
Col(String column) {
|
||||
this.column = column;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String get() {
|
||||
return toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return column;
|
||||
}
|
||||
}
|
||||
}
|
@ -62,9 +62,8 @@ public class CommandUseTable extends Table {
|
||||
*
|
||||
* @param serverUUID UUID of the server.
|
||||
* @return command - times used Map
|
||||
* @throws SQLException DB Error
|
||||
*/
|
||||
public Map<String, Integer> getCommandUse(UUID serverUUID) throws SQLException {
|
||||
public Map<String, Integer> getCommandUse(UUID serverUUID) {
|
||||
String sql = Select.from(tableName,
|
||||
Col.COMMAND, Col.TIMES_USED)
|
||||
.where(Col.SERVER_ID + "=" + serverTable.statementSelectServerID)
|
||||
@ -93,13 +92,12 @@ public class CommandUseTable extends Table {
|
||||
* Used to get all commands used in this server.
|
||||
*
|
||||
* @return command - times used Map
|
||||
* @throws SQLException DB Error
|
||||
*/
|
||||
public Map<String, Integer> getCommandUse() throws SQLException {
|
||||
public Map<String, Integer> getCommandUse() {
|
||||
return getCommandUse(ServerInfo.getServerUUID());
|
||||
}
|
||||
|
||||
public void commandUsed(String command) throws SQLException {
|
||||
public void commandUsed(String command) {
|
||||
if (command.length() > 20) {
|
||||
return;
|
||||
}
|
||||
@ -121,7 +119,7 @@ public class CommandUseTable extends Table {
|
||||
}
|
||||
}
|
||||
|
||||
public Optional<String> getCommandByID(int id) throws SQLException {
|
||||
public Optional<String> getCommandByID(int id) {
|
||||
String sql = Select.from(tableName, Col.COMMAND).where(Col.COMMAND_ID + "=?").toString();
|
||||
|
||||
return query(new QueryStatement<Optional<String>>(sql) {
|
||||
@ -140,7 +138,7 @@ public class CommandUseTable extends Table {
|
||||
});
|
||||
}
|
||||
|
||||
private void insertCommand(String command) throws SQLException {
|
||||
private void insertCommand(String command) {
|
||||
execute(new ExecStatement(insertStatement) {
|
||||
@Override
|
||||
public void prepare(PreparedStatement statement) throws SQLException {
|
||||
@ -151,7 +149,7 @@ public class CommandUseTable extends Table {
|
||||
});
|
||||
}
|
||||
|
||||
public Optional<Integer> getCommandID(String command) throws SQLException {
|
||||
public Optional<Integer> getCommandID(String command) {
|
||||
String sql = Select.from(tableName, Col.COMMAND_ID).where(Col.COMMAND + "=?").toString();
|
||||
|
||||
return query(new QueryStatement<Optional<Integer>>(sql) {
|
||||
@ -170,7 +168,7 @@ public class CommandUseTable extends Table {
|
||||
});
|
||||
}
|
||||
|
||||
public Map<UUID, Map<String, Integer>> getAllCommandUsages() throws SQLException {
|
||||
public Map<UUID, Map<String, Integer>> getAllCommandUsages() {
|
||||
String serverIDColumn = serverTable + "." + ServerTable.Col.SERVER_ID;
|
||||
String serverUUIDColumn = serverTable + "." + ServerTable.Col.SERVER_UUID + " as s_uuid";
|
||||
String sql = "SELECT " +
|
||||
@ -223,7 +221,7 @@ public class CommandUseTable extends Table {
|
||||
}
|
||||
}
|
||||
|
||||
public void insertCommandUsage(Map<UUID, Map<String, Integer>> allCommandUsages) throws SQLException {
|
||||
public void insertCommandUsage(Map<UUID, Map<String, Integer>> allCommandUsages) {
|
||||
if (allCommandUsages.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
package com.djrapitops.plan.system.database.databases.sql.tables;
|
||||
|
||||
import com.djrapitops.plan.api.exceptions.database.DBInitException;
|
||||
import com.djrapitops.plan.api.exceptions.database.DBOpException;
|
||||
import com.djrapitops.plan.data.container.GeoInfo;
|
||||
import com.djrapitops.plan.system.database.databases.sql.SQLDB;
|
||||
import com.djrapitops.plan.system.database.databases.sql.processing.ExecStatement;
|
||||
@ -103,7 +104,7 @@ public class GeoInfoTable extends UserIDTable {
|
||||
GeoInfo updatedInfo = new GeoInfo(
|
||||
InetAddress.getByName(geoInfo.getIp()),
|
||||
geoInfo.getGeolocation(),
|
||||
geoInfo.getLastUsed()
|
||||
geoInfo.getDate()
|
||||
);
|
||||
statement.setString(1, updatedInfo.getIp());
|
||||
statement.setString(2, updatedInfo.getIpHash());
|
||||
@ -120,7 +121,7 @@ public class GeoInfoTable extends UserIDTable {
|
||||
});
|
||||
new Version18TransferTable(db).alterTableV18();
|
||||
db.setVersion(18);
|
||||
} catch (SQLException | DBInitException e) {
|
||||
} catch (DBOpException | DBInitException e) {
|
||||
Log.toLog(this.getClass(), e);
|
||||
}
|
||||
}
|
||||
@ -131,7 +132,7 @@ public class GeoInfoTable extends UserIDTable {
|
||||
|
||||
}
|
||||
|
||||
public List<GeoInfo> getGeoInfo(UUID uuid) throws SQLException {
|
||||
public List<GeoInfo> getGeoInfo(UUID uuid) {
|
||||
String sql = "SELECT DISTINCT * FROM " + tableName +
|
||||
" WHERE " + Col.USER_ID + "=" + usersTable.statementSelectID;
|
||||
|
||||
@ -156,7 +157,7 @@ public class GeoInfoTable extends UserIDTable {
|
||||
});
|
||||
}
|
||||
|
||||
private void updateGeoInfo(UUID uuid, GeoInfo info) throws SQLException {
|
||||
private void updateGeoInfo(UUID uuid, GeoInfo info) {
|
||||
String sql = "UPDATE " + tableName + " SET "
|
||||
+ Col.LAST_USED + "=?" +
|
||||
" WHERE " + Col.USER_ID + "=" + usersTable.statementSelectID +
|
||||
@ -166,7 +167,7 @@ public class GeoInfoTable extends UserIDTable {
|
||||
execute(new ExecStatement(sql) {
|
||||
@Override
|
||||
public void prepare(PreparedStatement statement) throws SQLException {
|
||||
statement.setLong(1, info.getLastUsed());
|
||||
statement.setLong(1, info.getDate());
|
||||
statement.setString(2, uuid.toString());
|
||||
statement.setString(3, info.getIpHash());
|
||||
statement.setString(4, info.getGeolocation());
|
||||
@ -174,7 +175,7 @@ public class GeoInfoTable extends UserIDTable {
|
||||
});
|
||||
}
|
||||
|
||||
public void saveGeoInfo(UUID uuid, GeoInfo info) throws SQLException {
|
||||
public void saveGeoInfo(UUID uuid, GeoInfo info) {
|
||||
List<GeoInfo> geoInfo = getGeoInfo(uuid);
|
||||
if (geoInfo.contains(info)) {
|
||||
updateGeoInfo(uuid, info);
|
||||
@ -183,7 +184,7 @@ public class GeoInfoTable extends UserIDTable {
|
||||
}
|
||||
}
|
||||
|
||||
private void insertGeoInfo(UUID uuid, GeoInfo info) throws SQLException {
|
||||
private void insertGeoInfo(UUID uuid, GeoInfo info) {
|
||||
execute(new ExecStatement(insertStatement) {
|
||||
@Override
|
||||
public void prepare(PreparedStatement statement) throws SQLException {
|
||||
@ -191,12 +192,12 @@ public class GeoInfoTable extends UserIDTable {
|
||||
statement.setString(2, info.getIp());
|
||||
statement.setString(3, info.getIpHash());
|
||||
statement.setString(4, info.getGeolocation());
|
||||
statement.setLong(5, info.getLastUsed());
|
||||
statement.setLong(5, info.getDate());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public Optional<String> getGeolocation(String ip) throws SQLException {
|
||||
public Optional<String> getGeolocation(String ip) {
|
||||
String sql = Select.from(tableName, Col.GEOLOCATION)
|
||||
.where(Col.IP + "=?")
|
||||
.toString();
|
||||
@ -217,7 +218,7 @@ public class GeoInfoTable extends UserIDTable {
|
||||
});
|
||||
}
|
||||
|
||||
public Map<UUID, List<GeoInfo>> getAllGeoInfo() throws SQLException {
|
||||
public Map<UUID, List<GeoInfo>> getAllGeoInfo() {
|
||||
String usersIDColumn = usersTable + "." + UsersTable.Col.ID;
|
||||
String usersUUIDColumn = usersTable + "." + UsersTable.Col.UUID + " as uuid";
|
||||
String sql = "SELECT " +
|
||||
@ -251,7 +252,7 @@ public class GeoInfoTable extends UserIDTable {
|
||||
});
|
||||
}
|
||||
|
||||
public List<String> getNetworkGeolocations() throws SQLException {
|
||||
public List<String> getNetworkGeolocations() {
|
||||
List<String> geolocations = new ArrayList<>();
|
||||
|
||||
Map<UUID, List<GeoInfo>> geoInfo = getAllGeoInfo();
|
||||
@ -266,7 +267,7 @@ public class GeoInfoTable extends UserIDTable {
|
||||
return geolocations;
|
||||
}
|
||||
|
||||
public void insertAllGeoInfo(Map<UUID, List<GeoInfo>> allIPsAndGeolocations) throws SQLException {
|
||||
public void insertAllGeoInfo(Map<UUID, List<GeoInfo>> allIPsAndGeolocations) {
|
||||
if (Verify.isEmpty(allIPsAndGeolocations)) {
|
||||
return;
|
||||
}
|
||||
@ -281,7 +282,7 @@ public class GeoInfoTable extends UserIDTable {
|
||||
String ip = info.getIp();
|
||||
String ipHash = info.getIpHash();
|
||||
String geoLocation = info.getGeolocation();
|
||||
long lastUsed = info.getLastUsed();
|
||||
long lastUsed = info.getDate();
|
||||
|
||||
statement.setString(1, uuid.toString());
|
||||
statement.setString(2, ip);
|
||||
|
@ -70,7 +70,7 @@ public class KillsTable extends UserIDTable {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeUser(UUID uuid) throws SQLException {
|
||||
public void removeUser(UUID uuid) {
|
||||
String sql = "DELETE FROM " + tableName +
|
||||
" WHERE " + Col.KILLER_ID + " = " + usersTable.statementSelectID +
|
||||
" OR " + Col.VICTIM_ID + " = " + usersTable.statementSelectID;
|
||||
@ -84,7 +84,7 @@ public class KillsTable extends UserIDTable {
|
||||
});
|
||||
}
|
||||
|
||||
public void addKillsToSessions(UUID uuid, Map<Integer, Session> sessions) throws SQLException {
|
||||
public void addKillsToSessions(UUID uuid, Map<Integer, Session> sessions) {
|
||||
String usersIDColumn = usersTable + "." + UsersTable.Col.ID;
|
||||
String usersUUIDColumn = usersTable + "." + UsersTable.Col.UUID + " as victim_uuid";
|
||||
String sql = "SELECT " +
|
||||
@ -121,7 +121,7 @@ public class KillsTable extends UserIDTable {
|
||||
});
|
||||
}
|
||||
|
||||
public void savePlayerKills(UUID uuid, int sessionID, List<PlayerKill> playerKills) throws SQLException {
|
||||
public void savePlayerKills(UUID uuid, int sessionID, List<PlayerKill> playerKills) {
|
||||
if (Verify.isEmpty(playerKills)) {
|
||||
return;
|
||||
}
|
||||
@ -131,7 +131,7 @@ public class KillsTable extends UserIDTable {
|
||||
public void prepare(PreparedStatement statement) throws SQLException {
|
||||
for (PlayerKill kill : playerKills) {
|
||||
UUID victim = kill.getVictim();
|
||||
long date = kill.getTime();
|
||||
long date = kill.getDate();
|
||||
String weapon = kill.getWeapon();
|
||||
if (Verify.containsNull(victim, uuid)) {
|
||||
continue;
|
||||
@ -149,7 +149,7 @@ public class KillsTable extends UserIDTable {
|
||||
});
|
||||
}
|
||||
|
||||
public Map<UUID, List<PlayerKill>> getPlayerKills() throws SQLException {
|
||||
public Map<UUID, List<PlayerKill>> getPlayerKills() {
|
||||
String usersVictimIDColumn = usersTable + "." + UsersTable.Col.ID;
|
||||
String usersKillerIDColumn = "a." + UsersTable.Col.ID;
|
||||
String usersVictimUUIDColumn = usersTable + "." + UsersTable.Col.UUID + " as victim_uuid";
|
||||
@ -181,7 +181,7 @@ public class KillsTable extends UserIDTable {
|
||||
});
|
||||
}
|
||||
|
||||
public Map<Integer, List<PlayerKill>> getAllPlayerKillsBySessionID() throws SQLException {
|
||||
public Map<Integer, List<PlayerKill>> getAllPlayerKillsBySessionID() {
|
||||
String usersIDColumn = usersTable + "." + UsersTable.Col.ID;
|
||||
String usersUUIDColumn = usersTable + "." + UsersTable.Col.UUID + " as victim_uuid";
|
||||
String sql = "SELECT " +
|
||||
@ -214,7 +214,7 @@ public class KillsTable extends UserIDTable {
|
||||
});
|
||||
}
|
||||
|
||||
public void addKillsToSessions(Map<UUID, Map<UUID, List<Session>>> map) throws SQLException {
|
||||
public void addKillsToSessions(Map<UUID, Map<UUID, List<Session>>> map) {
|
||||
Map<Integer, List<PlayerKill>> playerKillsBySessionID = getAllPlayerKillsBySessionID();
|
||||
for (UUID serverUUID : map.keySet()) {
|
||||
for (List<Session> sessions : map.get(serverUUID).values()) {
|
||||
@ -228,7 +228,7 @@ public class KillsTable extends UserIDTable {
|
||||
}
|
||||
}
|
||||
|
||||
public void savePlayerKills(Map<UUID, Map<UUID, List<Session>>> allSessions) throws SQLException {
|
||||
public void savePlayerKills(Map<UUID, Map<UUID, List<Session>>> allSessions) {
|
||||
if (Verify.isEmpty(allSessions)) {
|
||||
return;
|
||||
}
|
||||
@ -248,7 +248,7 @@ public class KillsTable extends UserIDTable {
|
||||
// Every kill
|
||||
for (PlayerKill kill : session.getPlayerKills()) {
|
||||
UUID victim = kill.getVictim();
|
||||
long date = kill.getTime();
|
||||
long date = kill.getDate();
|
||||
String weapon = kill.getWeapon();
|
||||
statement.setString(1, killer.toString());
|
||||
statement.setString(2, victim.toString());
|
||||
@ -265,7 +265,7 @@ public class KillsTable extends UserIDTable {
|
||||
});
|
||||
}
|
||||
|
||||
public void alterTableV16() throws SQLException {
|
||||
public void alterTableV16() {
|
||||
addColumns(Col.SERVER_ID + " integer NOT NULL DEFAULT 0");
|
||||
|
||||
Map<Integer, Integer> sessionIDServerIDRelation = sessionsTable.getIDServerIDRelation();
|
||||
|
@ -1,6 +1,7 @@
|
||||
package com.djrapitops.plan.system.database.databases.sql.tables;
|
||||
|
||||
import com.djrapitops.plan.api.exceptions.database.DBInitException;
|
||||
import com.djrapitops.plan.data.store.objects.Nickname;
|
||||
import com.djrapitops.plan.system.database.databases.sql.SQLDB;
|
||||
import com.djrapitops.plan.system.database.databases.sql.processing.ExecStatement;
|
||||
import com.djrapitops.plan.system.database.databases.sql.processing.QueryAllStatement;
|
||||
@ -9,6 +10,8 @@ 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.task.AbsRunnable;
|
||||
import com.djrapitops.plugin.task.RunnableFactory;
|
||||
import com.djrapitops.plugin.utilities.Verify;
|
||||
|
||||
import java.sql.PreparedStatement;
|
||||
@ -27,34 +30,110 @@ import java.util.*;
|
||||
*/
|
||||
public class NicknamesTable extends UserIDTable {
|
||||
|
||||
private final ServerTable serverTable;
|
||||
private String insertStatement;
|
||||
private final String updateStatement;
|
||||
|
||||
public NicknamesTable(SQLDB db) {
|
||||
super("plan_nicknames", db);
|
||||
serverTable = db.getServerTable();
|
||||
insertStatement = "INSERT INTO " + tableName + " (" +
|
||||
Col.USER_ID + ", " +
|
||||
Col.SERVER_ID + ", " +
|
||||
Col.NICKNAME +
|
||||
Col.NICKNAME + ", " +
|
||||
Col.LAST_USED +
|
||||
") VALUES (" +
|
||||
usersTable.statementSelectID + ", " +
|
||||
serverTable.statementSelectServerID + ", " +
|
||||
"?)";
|
||||
"?, ?)";
|
||||
updateStatement = "UPDATE " + tableName + " SET " + Col.LAST_USED + "=?" +
|
||||
" WHERE " + Col.NICKNAME + "=?" +
|
||||
" AND " + Col.USER_ID + "=" + usersTable.statementSelectID +
|
||||
" AND " + Col.SERVER_ID + "=" + serverTable.statementSelectServerID;
|
||||
}
|
||||
|
||||
private final ServerTable serverTable;
|
||||
private String insertStatement;
|
||||
|
||||
@Override
|
||||
public void createTable() throws DBInitException {
|
||||
createTable(TableSqlParser.createTable(tableName)
|
||||
.column(Col.USER_ID, Sql.INT).notNull()
|
||||
.column(Col.NICKNAME, Sql.varchar(75)).notNull()
|
||||
.column(Col.SERVER_ID, Sql.INT).notNull()
|
||||
.column(Col.LAST_USED, Sql.LONG).notNull()
|
||||
.foreignKey(Col.USER_ID, usersTable.getTableName(), UsersTable.Col.ID)
|
||||
.foreignKey(Col.SERVER_ID, serverTable.getTableName(), ServerTable.Col.SERVER_ID)
|
||||
.toString()
|
||||
);
|
||||
}
|
||||
|
||||
public void alterTableV19() {
|
||||
addColumns(Col.LAST_USED + " bigint NOT NULL DEFAULT '0'");
|
||||
|
||||
RunnableFactory.createNew(new AbsRunnable("DB version 18->19") {
|
||||
@Override
|
||||
public void run() {
|
||||
// Create actions table if version 18 transfer is run concurrently.
|
||||
execute("CREATE TABLE IF NOT EXISTS plan_actions " +
|
||||
"(action_id integer, date bigint, server_id integer, user_id integer, additional_info varchar(1))");
|
||||
|
||||
Map<Integer, UUID> serverUUIDsByID = serverTable.getServerUUIDsByID();
|
||||
Map<UUID, Integer> serverIDsByUUID = new HashMap<>();
|
||||
for (Map.Entry<Integer, UUID> entry : serverUUIDsByID.entrySet()) {
|
||||
serverIDsByUUID.put(entry.getValue(), entry.getKey());
|
||||
}
|
||||
|
||||
String fetchSQL = "SELECT * FROM plan_actions WHERE action_id=3 ORDER BY date DESC";
|
||||
Map<Integer, Set<Nickname>> nicknames = query(new QueryAllStatement<Map<Integer, Set<Nickname>>>(fetchSQL, 10000) {
|
||||
@Override
|
||||
public Map<Integer, Set<Nickname>> processResults(ResultSet set) throws SQLException {
|
||||
Map<Integer, Set<Nickname>> map = new HashMap<>();
|
||||
|
||||
while (set.next()) {
|
||||
long date = set.getLong("date");
|
||||
int userID = set.getInt(UserIDTable.Col.USER_ID.get());
|
||||
int serverID = set.getInt("server_id");
|
||||
UUID serverUUID = serverUUIDsByID.get(serverID);
|
||||
Nickname nick = new Nickname(set.getString("additional_info"), date, serverUUID);
|
||||
Set<Nickname> nicknames = map.getOrDefault(userID, new HashSet<>());
|
||||
if (serverUUID == null || nicknames.contains(nick)) {
|
||||
continue;
|
||||
}
|
||||
nicknames.add(nick);
|
||||
map.put(userID, nicknames);
|
||||
}
|
||||
|
||||
return map;
|
||||
}
|
||||
});
|
||||
|
||||
String updateSQL = "UPDATE " + tableName + " SET " + Col.LAST_USED + "=?" +
|
||||
" WHERE " + Col.NICKNAME + "=?" +
|
||||
" AND " + Col.USER_ID + "=?" +
|
||||
" AND " + Col.SERVER_ID + "=?";
|
||||
|
||||
executeBatch(new ExecStatement(updateSQL) {
|
||||
@Override
|
||||
public void prepare(PreparedStatement statement) throws SQLException {
|
||||
for (Map.Entry<Integer, Set<Nickname>> entry : nicknames.entrySet()) {
|
||||
Integer userId = entry.getKey();
|
||||
Set<Nickname> nicks = entry.getValue();
|
||||
for (Nickname nick : nicks) {
|
||||
Integer serverID = serverIDsByUUID.get(nick.getServerUUID());
|
||||
statement.setLong(1, nick.getDate());
|
||||
statement.setString(2, nick.getName());
|
||||
statement.setInt(3, userId);
|
||||
statement.setInt(4, serverID);
|
||||
statement.addBatch();
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
db.setVersion(19);
|
||||
executeUnsafe("DROP TABLE plan_actions");
|
||||
}
|
||||
}).runTaskAsynchronously();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get ALL nicknames of the user by Server UUID.
|
||||
* <p>
|
||||
@ -62,9 +141,8 @@ public class NicknamesTable extends UserIDTable {
|
||||
*
|
||||
* @param uuid UUID of the Player
|
||||
* @return The nicknames of the User in a map by ServerUUID
|
||||
* @throws SQLException when an error at retrieval happens
|
||||
*/
|
||||
public Map<UUID, List<String>> getAllNicknames(UUID uuid) throws SQLException {
|
||||
public Map<UUID, List<String>> getAllNicknames(UUID uuid) {
|
||||
String serverIDColumn = serverTable + "." + ServerTable.Col.SERVER_ID;
|
||||
String serverUUIDColumn = serverTable + "." + ServerTable.Col.SERVER_UUID + " as s_uuid";
|
||||
String sql = "SELECT " +
|
||||
@ -106,9 +184,8 @@ public class NicknamesTable extends UserIDTable {
|
||||
* @param uuid UUID of the Player
|
||||
* @param serverUUID UUID of the server
|
||||
* @return The nicknames of the User
|
||||
* @throws SQLException when an error at retrieval happens
|
||||
*/
|
||||
public List<String> getNicknames(UUID uuid, UUID serverUUID) throws SQLException {
|
||||
public List<String> getNicknames(UUID uuid, UUID serverUUID) {
|
||||
String sql = "SELECT " + Col.NICKNAME + " FROM " + tableName +
|
||||
" WHERE (" + Col.USER_ID + "=" + usersTable.statementSelectID + ")" +
|
||||
" AND " + Col.SERVER_ID + "=" + serverTable.statementSelectServerID;
|
||||
@ -144,37 +221,39 @@ public class NicknamesTable extends UserIDTable {
|
||||
*
|
||||
* @param uuid UUID of the Player
|
||||
* @return The nicknames of the User
|
||||
* @throws SQLException when an error at retrieval happens
|
||||
*/
|
||||
public List<String> getNicknames(UUID uuid) throws SQLException {
|
||||
public List<String> getNicknames(UUID uuid) {
|
||||
return getNicknames(uuid, ServerInfo.getServerUUID());
|
||||
}
|
||||
|
||||
public Map<UUID, Map<UUID, List<String>>> getAllNicknames() throws SQLException {
|
||||
public Map<UUID, Map<UUID, List<Nickname>>> getAllNicknames() {
|
||||
String usersIDColumn = usersTable + "." + UsersTable.Col.ID;
|
||||
String usersUUIDColumn = usersTable + "." + UsersTable.Col.UUID + " as uuid";
|
||||
String serverIDColumn = serverTable + "." + ServerTable.Col.SERVER_ID;
|
||||
String serverUUIDColumn = serverTable + "." + ServerTable.Col.SERVER_UUID + " as s_uuid";
|
||||
String sql = "SELECT " +
|
||||
Col.NICKNAME + ", " +
|
||||
Col.LAST_USED + ", " +
|
||||
usersUUIDColumn + ", " +
|
||||
serverUUIDColumn +
|
||||
" FROM " + tableName +
|
||||
" INNER JOIN " + usersTable + " on " + usersIDColumn + "=" + Col.USER_ID +
|
||||
" INNER JOIN " + serverTable + " on " + serverIDColumn + "=" + Col.SERVER_ID;
|
||||
|
||||
return query(new QueryAllStatement<Map<UUID, Map<UUID, List<String>>>>(sql, 5000) {
|
||||
return query(new QueryAllStatement<Map<UUID, Map<UUID, List<Nickname>>>>(sql, 5000) {
|
||||
@Override
|
||||
public Map<UUID, Map<UUID, List<String>>> processResults(ResultSet set) throws SQLException {
|
||||
Map<UUID, Map<UUID, List<String>>> map = new HashMap<>();
|
||||
public Map<UUID, Map<UUID, List<Nickname>>> processResults(ResultSet set) throws SQLException {
|
||||
Map<UUID, Map<UUID, List<Nickname>>> map = new HashMap<>();
|
||||
while (set.next()) {
|
||||
UUID serverUUID = UUID.fromString(set.getString("s_uuid"));
|
||||
UUID uuid = UUID.fromString(set.getString("uuid"));
|
||||
|
||||
Map<UUID, List<String>> serverMap = map.getOrDefault(serverUUID, new HashMap<>());
|
||||
List<String> nicknames = serverMap.getOrDefault(uuid, new ArrayList<>());
|
||||
Map<UUID, List<Nickname>> serverMap = map.getOrDefault(serverUUID, new HashMap<>());
|
||||
List<Nickname> nicknames = serverMap.getOrDefault(uuid, new ArrayList<>());
|
||||
|
||||
nicknames.add(set.getString(Col.NICKNAME.get()));
|
||||
nicknames.add(new Nickname(
|
||||
set.getString(Col.NICKNAME.get()), set.getLong(Col.LAST_USED.get()), serverUUID
|
||||
));
|
||||
|
||||
serverMap.put(uuid, nicknames);
|
||||
map.put(serverUUID, serverMap);
|
||||
@ -184,18 +263,94 @@ public class NicknamesTable extends UserIDTable {
|
||||
});
|
||||
}
|
||||
|
||||
public void saveUserName(UUID uuid, String displayName) throws SQLException {
|
||||
List<String> saved = getNicknames(uuid);
|
||||
if (saved.contains(displayName)) {
|
||||
return;
|
||||
public void saveUserName(UUID uuid, Nickname name) {
|
||||
List<Nickname> saved = getNicknameInformation(uuid);
|
||||
if (saved.contains(name)) {
|
||||
updateNickname(uuid, name);
|
||||
} else {
|
||||
insertNickname(uuid, name);
|
||||
}
|
||||
}
|
||||
|
||||
private void updateNickname(UUID uuid, Nickname name) {
|
||||
execute(new ExecStatement(updateStatement) {
|
||||
@Override
|
||||
public void prepare(PreparedStatement statement) throws SQLException {
|
||||
statement.setLong(1, name.getDate());
|
||||
statement.setString(2, name.getName());
|
||||
statement.setString(3, uuid.toString());
|
||||
statement.setString(4, ServerInfo.getServerUUID().toString());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void insertNickname(UUID uuid, Nickname name) {
|
||||
execute(new ExecStatement(insertStatement) {
|
||||
@Override
|
||||
public void prepare(PreparedStatement statement) throws SQLException {
|
||||
statement.setString(1, uuid.toString());
|
||||
statement.setString(2, ServerInfo.getServerUUID().toString());
|
||||
statement.setString(3, displayName);
|
||||
statement.setString(3, name.getName());
|
||||
statement.setLong(4, name.getDate());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public List<Nickname> getNicknameInformation(UUID uuid) {
|
||||
String serverIDColumn = serverTable + "." + ServerTable.Col.SERVER_ID;
|
||||
String serverUUIDColumn = serverTable + "." + ServerTable.Col.SERVER_UUID + " as s_uuid";
|
||||
String sql = "SELECT " +
|
||||
Col.NICKNAME + ", " +
|
||||
Col.LAST_USED + ", " +
|
||||
serverUUIDColumn +
|
||||
" FROM " + tableName +
|
||||
" INNER JOIN " + serverTable + " on " + serverIDColumn + "=" + Col.SERVER_ID +
|
||||
" WHERE (" + Col.USER_ID + "=" + usersTable.statementSelectID + ")";
|
||||
|
||||
return query(new QueryStatement<List<Nickname>>(sql, 5000) {
|
||||
|
||||
@Override
|
||||
public void prepare(PreparedStatement statement) throws SQLException {
|
||||
statement.setString(1, uuid.toString());
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Nickname> processResults(ResultSet set) throws SQLException {
|
||||
List<Nickname> nicknames = new ArrayList<>();
|
||||
while (set.next()) {
|
||||
UUID serverUUID = UUID.fromString(set.getString("s_uuid"));
|
||||
String nickname = set.getString(Col.NICKNAME.get());
|
||||
nicknames.add(new Nickname(nickname, set.getLong(Col.LAST_USED.get()), serverUUID));
|
||||
}
|
||||
return nicknames;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void insertNicknames(Map<UUID, Map<UUID, List<Nickname>>> allNicknames) {
|
||||
if (Verify.isEmpty(allNicknames)) {
|
||||
return;
|
||||
}
|
||||
|
||||
executeBatch(new ExecStatement(insertStatement) {
|
||||
@Override
|
||||
public void prepare(PreparedStatement statement) throws SQLException {
|
||||
// Every Server
|
||||
for (UUID serverUUID : allNicknames.keySet()) {
|
||||
// Every User
|
||||
for (Map.Entry<UUID, List<Nickname>> entry : allNicknames.get(serverUUID).entrySet()) {
|
||||
UUID uuid = entry.getKey();
|
||||
// Every Nickname
|
||||
List<Nickname> nicknames = entry.getValue();
|
||||
for (Nickname nickname : nicknames) {
|
||||
statement.setString(1, uuid.toString());
|
||||
statement.setString(2, serverUUID.toString());
|
||||
statement.setString(3, nickname.getName());
|
||||
statement.setLong(4, nickname.getDate());
|
||||
statement.addBatch();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
@ -203,7 +358,8 @@ public class NicknamesTable extends UserIDTable {
|
||||
public enum Col implements Column {
|
||||
USER_ID(UserIDTable.Col.USER_ID.get()),
|
||||
SERVER_ID("server_id"),
|
||||
NICKNAME("nickname");
|
||||
NICKNAME("nickname"),
|
||||
LAST_USED("last_used");
|
||||
|
||||
private final String column;
|
||||
|
||||
@ -221,31 +377,4 @@ public class NicknamesTable extends UserIDTable {
|
||||
return column;
|
||||
}
|
||||
}
|
||||
|
||||
public void insertNicknames(Map<UUID, Map<UUID, List<String>>> allNicknames) throws SQLException {
|
||||
if (Verify.isEmpty(allNicknames)) {
|
||||
return;
|
||||
}
|
||||
|
||||
executeBatch(new ExecStatement(insertStatement) {
|
||||
@Override
|
||||
public void prepare(PreparedStatement statement) throws SQLException {
|
||||
// Every Server
|
||||
for (UUID serverUUID : allNicknames.keySet()) {
|
||||
// Every User
|
||||
for (Map.Entry<UUID, List<String>> entry : allNicknames.get(serverUUID).entrySet()) {
|
||||
UUID uuid = entry.getKey();
|
||||
// Every Nickname
|
||||
List<String> nicknames = entry.getValue();
|
||||
for (String nickname : nicknames) {
|
||||
statement.setString(1, uuid.toString());
|
||||
statement.setString(2, serverUUID.toString());
|
||||
statement.setString(3, nickname);
|
||||
statement.addBatch();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -52,7 +52,7 @@ public class SecurityTable extends Table {
|
||||
);
|
||||
}
|
||||
|
||||
public void removeUser(String user) throws SQLException {
|
||||
public void removeUser(String user) {
|
||||
String sql = "DELETE FROM " + tableName + " WHERE (" + Col.USERNAME + "=?)";
|
||||
|
||||
execute(new ExecStatement(sql) {
|
||||
@ -63,7 +63,7 @@ public class SecurityTable extends Table {
|
||||
});
|
||||
}
|
||||
|
||||
public WebUser getWebUser(String user) throws SQLException {
|
||||
public WebUser getWebUser(String user) {
|
||||
String sql = Select.all(tableName).where(Col.USERNAME + "=?").toString();
|
||||
|
||||
return query(new QueryStatement<WebUser>(sql) {
|
||||
@ -84,11 +84,11 @@ public class SecurityTable extends Table {
|
||||
});
|
||||
}
|
||||
|
||||
public void addNewUser(WebUser info) throws SQLException {
|
||||
public void addNewUser(WebUser info) {
|
||||
addNewUser(info.getName(), info.getSaltedPassHash(), info.getPermLevel());
|
||||
}
|
||||
|
||||
public void addNewUser(String user, String saltPassHash, int permLevel) throws SQLException {
|
||||
public void addNewUser(String user, String saltPassHash, int permLevel) {
|
||||
execute(new ExecStatement(insertStatement) {
|
||||
@Override
|
||||
public void prepare(PreparedStatement statement) throws SQLException {
|
||||
@ -99,11 +99,11 @@ public class SecurityTable extends Table {
|
||||
});
|
||||
}
|
||||
|
||||
public boolean userExists(String user) throws SQLException {
|
||||
public boolean userExists(String user) {
|
||||
return getWebUser(user) != null;
|
||||
}
|
||||
|
||||
public List<WebUser> getUsers() throws SQLException {
|
||||
public List<WebUser> getUsers() {
|
||||
String sql = Select.all(tableName).toString();
|
||||
|
||||
return query(new QueryAllStatement<List<WebUser>>(sql, 5000) {
|
||||
@ -144,7 +144,7 @@ public class SecurityTable extends Table {
|
||||
}
|
||||
}
|
||||
|
||||
public void addUsers(List<WebUser> users) throws SQLException {
|
||||
public void addUsers(List<WebUser> users) {
|
||||
if (Verify.isEmpty(users)) {
|
||||
return;
|
||||
}
|
||||
|
@ -73,7 +73,7 @@ public class ServerTable extends Table {
|
||||
}
|
||||
}
|
||||
|
||||
private void updateServerInfo(Server info) throws SQLException {
|
||||
private void updateServerInfo(Server info) {
|
||||
String sql = Update.values(tableName,
|
||||
Col.SERVER_UUID,
|
||||
Col.NAME,
|
||||
@ -96,7 +96,7 @@ public class ServerTable extends Table {
|
||||
});
|
||||
}
|
||||
|
||||
public void saveCurrentServerInfo(Server info) throws SQLException {
|
||||
public void saveCurrentServerInfo(Server info) {
|
||||
if (getServerID(info.getUuid()).isPresent()) {
|
||||
updateServerInfo(info);
|
||||
} else {
|
||||
@ -109,9 +109,8 @@ public class ServerTable extends Table {
|
||||
*
|
||||
* @param serverUUID UUID of the server.
|
||||
* @return ID or or empty optional.
|
||||
* @throws SQLException DB Error
|
||||
*/
|
||||
public Optional<Integer> getServerID(UUID serverUUID) throws SQLException {
|
||||
public Optional<Integer> getServerID(UUID serverUUID) {
|
||||
String sql = Select.from(tableName,
|
||||
Col.SERVER_ID)
|
||||
.where(Col.SERVER_UUID + "=?")
|
||||
@ -139,9 +138,8 @@ public class ServerTable extends Table {
|
||||
*
|
||||
* @param info Info to instert (All variables should be present.
|
||||
* @throws IllegalStateException if one of the Server variables is null
|
||||
* @throws SQLException DB Error
|
||||
*/
|
||||
private void saveNewServerInfo(Server info) throws SQLException {
|
||||
private void saveNewServerInfo(Server info) {
|
||||
UUID uuid = info.getUuid();
|
||||
String name = info.getName();
|
||||
String webAddress = info.getWebAddress();
|
||||
@ -164,9 +162,8 @@ public class ServerTable extends Table {
|
||||
*
|
||||
* @param serverUUID UUID of the server.
|
||||
* @return Name or empty optional.
|
||||
* @throws SQLException DB Error
|
||||
*/
|
||||
public Optional<String> getServerName(UUID serverUUID) throws SQLException {
|
||||
public Optional<String> getServerName(UUID serverUUID) {
|
||||
String sql = Select.from(tableName,
|
||||
Col.NAME)
|
||||
.where(Col.SERVER_UUID + "=?")
|
||||
@ -189,7 +186,7 @@ public class ServerTable extends Table {
|
||||
});
|
||||
}
|
||||
|
||||
public Map<Integer, String> getServerNamesByID() throws SQLException {
|
||||
public Map<Integer, String> getServerNamesByID() {
|
||||
String sql = Select.from(tableName,
|
||||
Col.SERVER_ID, Col.NAME)
|
||||
.toString();
|
||||
@ -207,7 +204,7 @@ public class ServerTable extends Table {
|
||||
});
|
||||
}
|
||||
|
||||
public Map<UUID, String> getServerNames() throws SQLException {
|
||||
public Map<UUID, String> getServerNames() {
|
||||
String sql = Select.from(tableName,
|
||||
Col.SERVER_UUID, Col.NAME)
|
||||
.toString();
|
||||
@ -225,7 +222,7 @@ public class ServerTable extends Table {
|
||||
});
|
||||
}
|
||||
|
||||
public Map<Integer, UUID> getServerUUIDsByID() throws SQLException {
|
||||
public Map<Integer, UUID> getServerUUIDsByID() {
|
||||
String sql = Select.from(tableName,
|
||||
Col.SERVER_ID, Col.SERVER_UUID)
|
||||
.toString();
|
||||
@ -247,9 +244,8 @@ public class ServerTable extends Table {
|
||||
* Used to get BungeeCord WebServer info if present.
|
||||
*
|
||||
* @return information about Bungee server.
|
||||
* @throws SQLException DB Error
|
||||
*/
|
||||
public Optional<Server> getBungeeInfo() throws SQLException {
|
||||
public Optional<Server> getBungeeInfo() {
|
||||
String sql = Select.from(tableName, "*")
|
||||
.where(Col.NAME + "=?")
|
||||
.toString();
|
||||
@ -276,7 +272,7 @@ public class ServerTable extends Table {
|
||||
});
|
||||
}
|
||||
|
||||
public Map<UUID, Server> getBukkitServers() throws SQLException {
|
||||
public Map<UUID, Server> getBukkitServers() {
|
||||
String sql = Select.from(tableName, "*")
|
||||
.where(Col.NAME + "!=?")
|
||||
.toString();
|
||||
@ -304,7 +300,7 @@ public class ServerTable extends Table {
|
||||
});
|
||||
}
|
||||
|
||||
public List<UUID> getServerUUIDs() throws SQLException {
|
||||
public List<UUID> getServerUUIDs() {
|
||||
String sql = Select.from(tableName, Col.SERVER_UUID)
|
||||
.toString();
|
||||
|
||||
@ -325,7 +321,7 @@ public class ServerTable extends Table {
|
||||
return Col.SERVER_UUID.get();
|
||||
}
|
||||
|
||||
public void insertAllServers(List<Server> allServer) throws SQLException {
|
||||
public void insertAllServers(List<Server> allServer) {
|
||||
if (Verify.isEmpty(allServer)) {
|
||||
return;
|
||||
}
|
||||
@ -353,7 +349,7 @@ public class ServerTable extends Table {
|
||||
});
|
||||
}
|
||||
|
||||
public Optional<UUID> getServerUUID(String serverName) throws SQLException {
|
||||
public Optional<UUID> getServerUUID(String serverName) {
|
||||
String sql = Select.from(tableName,
|
||||
Col.SERVER_UUID)
|
||||
.where(Col.NAME + "=?")
|
||||
@ -376,7 +372,7 @@ public class ServerTable extends Table {
|
||||
});
|
||||
}
|
||||
|
||||
public Optional<Server> getServerInfo(UUID serverUUID) throws SQLException {
|
||||
public Optional<Server> getServerInfo(UUID serverUUID) {
|
||||
String sql = Select.from(tableName, "*")
|
||||
.where(Col.SERVER_UUID + "=?")
|
||||
.toString();
|
||||
@ -402,7 +398,7 @@ public class ServerTable extends Table {
|
||||
});
|
||||
}
|
||||
|
||||
public int getMaxPlayers() throws SQLException {
|
||||
public int getMaxPlayers() {
|
||||
String sql = "SELECT SUM(" + Col.MAX_PLAYERS + ") AS max FROM " + tableName;
|
||||
|
||||
return query(new QueryAllStatement<Integer>(sql) {
|
||||
|
@ -73,7 +73,7 @@ public class SessionsTable extends UserIDTable {
|
||||
* @param session session inserted.
|
||||
* @return ID of the inserted session or -1 if session has not been inserted.
|
||||
*/
|
||||
private int getSessionID(UUID uuid, Session session) throws SQLException {
|
||||
private int getSessionID(UUID uuid, Session session) {
|
||||
String sql = "SELECT " + Col.ID + " FROM " + tableName +
|
||||
" WHERE " + Col.USER_ID + "=" + usersTable.statementSelectID +
|
||||
" AND " + Col.SESSION_START + "=?" +
|
||||
@ -104,9 +104,8 @@ public class SessionsTable extends UserIDTable {
|
||||
*
|
||||
* @param uuid UUID of the player.
|
||||
* @param session Session of the player that has ended ({@code endSession} has been called)
|
||||
* @throws SQLException DB Error
|
||||
*/
|
||||
public void saveSession(UUID uuid, Session session) throws SQLException {
|
||||
public void saveSession(UUID uuid, Session session) {
|
||||
saveSessionInformation(uuid, session);
|
||||
int sessionID = getSessionID(uuid, session);
|
||||
if (sessionID == -1) {
|
||||
@ -124,9 +123,8 @@ public class SessionsTable extends UserIDTable {
|
||||
*
|
||||
* @param uuid UUID of the player.
|
||||
* @param session Session of the player that has ended ({@code endSession} has been called)
|
||||
* @throws SQLException DB Error
|
||||
*/
|
||||
private void saveSessionInformation(UUID uuid, Session session) throws SQLException {
|
||||
private void saveSessionInformation(UUID uuid, Session session) {
|
||||
execute(new ExecStatement(insertStatement) {
|
||||
@Override
|
||||
public void prepare(PreparedStatement statement) throws SQLException {
|
||||
@ -149,9 +147,8 @@ public class SessionsTable extends UserIDTable {
|
||||
*
|
||||
* @param uuid UUID of the player
|
||||
* @return Map with Sessions that don't contain Kills or WorldTimes.
|
||||
* @throws SQLException DB Error
|
||||
*/
|
||||
private Map<UUID, List<Session>> getSessionInformation(UUID uuid) throws SQLException {
|
||||
private Map<UUID, List<Session>> getSessionInformation(UUID uuid) {
|
||||
Map<Integer, UUID> serverUUIDs = serverTable.getServerUUIDsByID();
|
||||
String sql = Select.from(tableName, "*")
|
||||
.where(Col.USER_ID + "=" + usersTable.statementSelectID)
|
||||
@ -181,7 +178,7 @@ public class SessionsTable extends UserIDTable {
|
||||
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, timeAFK));
|
||||
sessions.add(new Session(id, uuid, serverUUID, start, end, mobKills, deaths, timeAFK));
|
||||
sessionsByServer.put(serverUUID, sessions);
|
||||
}
|
||||
return sessionsByServer;
|
||||
@ -196,9 +193,8 @@ public class SessionsTable extends UserIDTable {
|
||||
* @param serverUUID UUID of the server. @see ServerTable
|
||||
* @param afterDate Epoch ms (Playtime after this date is calculated)
|
||||
* @return Milliseconds played after given epoch ms on the server. 0 if player or server not found.
|
||||
* @throws SQLException DB Error
|
||||
*/
|
||||
public long getPlaytime(UUID uuid, UUID serverUUID, long afterDate) throws SQLException {
|
||||
public long getPlaytime(UUID uuid, UUID serverUUID, long afterDate) {
|
||||
String sql = "SELECT" +
|
||||
" (SUM(" + Col.SESSION_END + ") - SUM(" + Col.SESSION_START + ")) as playtime" +
|
||||
" FROM " + tableName +
|
||||
@ -224,7 +220,7 @@ public class SessionsTable extends UserIDTable {
|
||||
});
|
||||
}
|
||||
|
||||
public Map<UUID, List<Session>> getSessions(UUID uuid) throws SQLException {
|
||||
public Map<UUID, List<Session>> getSessions(UUID uuid) {
|
||||
Map<UUID, List<Session>> sessions = getSessionInformation(uuid);
|
||||
Map<Integer, Session> allSessions = sessions.values().stream().flatMap(Collection::stream).collect(Collectors.toMap(Session::getSessionID, Function.identity()));
|
||||
|
||||
@ -238,9 +234,8 @@ public class SessionsTable extends UserIDTable {
|
||||
*
|
||||
* @param uuid UUID of the player.
|
||||
* @return Milliseconds played on THIS server. 0 if player or server not found.
|
||||
* @throws SQLException DB Error
|
||||
*/
|
||||
public long getPlaytime(UUID uuid) throws SQLException {
|
||||
public long getPlaytime(UUID uuid) {
|
||||
return getPlaytime(uuid, ServerInfo.getServerUUID());
|
||||
}
|
||||
|
||||
@ -250,9 +245,8 @@ public class SessionsTable extends UserIDTable {
|
||||
* @param uuid UUID of the player.
|
||||
* @param afterDate Epoch ms (Playtime after this date is calculated)
|
||||
* @return Milliseconds played on THIS server. 0 if player or server not found.
|
||||
* @throws SQLException DB Error
|
||||
*/
|
||||
public long getPlaytime(UUID uuid, long afterDate) throws SQLException {
|
||||
public long getPlaytime(UUID uuid, long afterDate) {
|
||||
return getPlaytime(uuid, ServerInfo.getServerUUID(), afterDate);
|
||||
}
|
||||
|
||||
@ -262,9 +256,8 @@ public class SessionsTable extends UserIDTable {
|
||||
* @param uuid UUID of the player.
|
||||
* @param serverUUID UUID of the server. @see ServerTable
|
||||
* @return Milliseconds played on the server. 0 if player or server not found.
|
||||
* @throws SQLException DB Error
|
||||
*/
|
||||
public long getPlaytime(UUID uuid, UUID serverUUID) throws SQLException {
|
||||
public long getPlaytime(UUID uuid, UUID serverUUID) {
|
||||
return getPlaytime(uuid, serverUUID, 0L);
|
||||
}
|
||||
|
||||
@ -274,9 +267,8 @@ public class SessionsTable extends UserIDTable {
|
||||
* @param uuid UUID of the Player.
|
||||
* @param afterDate Epoch ms (Playtime after this date is calculated)
|
||||
* @return key - ServerName, value ms played
|
||||
* @throws SQLException DB Error
|
||||
*/
|
||||
public Map<String, Long> getPlaytimeByServer(UUID uuid, long afterDate) throws SQLException {
|
||||
public Map<String, Long> getPlaytimeByServer(UUID uuid, long afterDate) {
|
||||
Map<Integer, String> serverNames = serverTable.getServerNamesByID();
|
||||
String sql = "SELECT " +
|
||||
"(SUM(" + Col.SESSION_END + ") - SUM(" + Col.SESSION_START + ")) as playtime, " +
|
||||
@ -310,9 +302,8 @@ public class SessionsTable extends UserIDTable {
|
||||
*
|
||||
* @param uuid UUID of the Player.
|
||||
* @return key - ServerName, value ms played
|
||||
* @throws SQLException DB Error
|
||||
*/
|
||||
public Map<String, Long> getPlaytimeByServer(UUID uuid) throws SQLException {
|
||||
public Map<String, Long> getPlaytimeByServer(UUID uuid) {
|
||||
return getPlaytimeByServer(uuid, 0L);
|
||||
}
|
||||
|
||||
@ -322,9 +313,8 @@ public class SessionsTable extends UserIDTable {
|
||||
* @param serverUUID UUID of the server.
|
||||
* @param afterDate Epoch ms (Playtime after this date is calculated)
|
||||
* @return Milliseconds played after given epoch ms on the server. 0 if server not found.
|
||||
* @throws SQLException DB Error
|
||||
*/
|
||||
public long getPlaytimeOfServer(UUID serverUUID, long afterDate) throws SQLException {
|
||||
public long getPlaytimeOfServer(UUID serverUUID, long afterDate) {
|
||||
String sql = "SELECT" +
|
||||
" (SUM(" + Col.SESSION_END + ") - SUM(" + Col.SESSION_START + ")) as playtime" +
|
||||
" FROM " + tableName +
|
||||
@ -352,9 +342,8 @@ public class SessionsTable extends UserIDTable {
|
||||
* Used to get the Total Playtime of THIS Server.
|
||||
*
|
||||
* @return Milliseconds played on the server. 0 if server not found.
|
||||
* @throws SQLException DB Error
|
||||
*/
|
||||
public long getPlaytimeOfServer() throws SQLException {
|
||||
public long getPlaytimeOfServer() {
|
||||
return getPlaytimeOfServer(ServerInfo.getServerUUID());
|
||||
}
|
||||
|
||||
@ -363,9 +352,8 @@ public class SessionsTable extends UserIDTable {
|
||||
*
|
||||
* @param serverUUID UUID of the server.
|
||||
* @return Milliseconds played on the server. 0 if server not found.
|
||||
* @throws SQLException DB Error
|
||||
*/
|
||||
public long getPlaytimeOfServer(UUID serverUUID) throws SQLException {
|
||||
public long getPlaytimeOfServer(UUID serverUUID) {
|
||||
return getPlaytimeOfServer(serverUUID, 0L);
|
||||
}
|
||||
|
||||
@ -374,9 +362,8 @@ public class SessionsTable extends UserIDTable {
|
||||
*
|
||||
* @param afterDate Epoch ms (Playtime after this date is calculated)
|
||||
* @return Milliseconds played after given epoch ms on the server. 0 if server not found.
|
||||
* @throws SQLException DB Error
|
||||
*/
|
||||
public long getPlaytimeOfServer(long afterDate) throws SQLException {
|
||||
public long getPlaytimeOfServer(long afterDate) {
|
||||
return getPlaytimeOfServer(ServerInfo.getServerUUID(), afterDate);
|
||||
}
|
||||
|
||||
@ -387,9 +374,8 @@ public class SessionsTable extends UserIDTable {
|
||||
* @param serverUUID UUID of the server.
|
||||
* @param afterDate Epoch ms (Session count after this date is calculated)
|
||||
* @return How many sessions player has. 0 if player or server not found.
|
||||
* @throws SQLException DB Error
|
||||
*/
|
||||
public int getSessionCount(UUID uuid, UUID serverUUID, long afterDate) throws SQLException {
|
||||
public int getSessionCount(UUID uuid, UUID serverUUID, long afterDate) {
|
||||
String sql = "SELECT" +
|
||||
" COUNT(*) as logintimes" +
|
||||
" FROM " + tableName +
|
||||
@ -420,9 +406,8 @@ public class SessionsTable extends UserIDTable {
|
||||
*
|
||||
* @param uuid UUID of the player.
|
||||
* @return How many sessions player has. 0 if player or server not found.
|
||||
* @throws SQLException DB Error
|
||||
*/
|
||||
public int getSessionCount(UUID uuid) throws SQLException {
|
||||
public int getSessionCount(UUID uuid) {
|
||||
return getSessionCount(uuid, 0L);
|
||||
}
|
||||
|
||||
@ -432,9 +417,8 @@ public class SessionsTable extends UserIDTable {
|
||||
* @param uuid UUID of the player.
|
||||
* @param afterDate Epoch ms (Session count after this date is calculated)
|
||||
* @return How many sessions player has. 0 if player or server not found.
|
||||
* @throws SQLException DB Error
|
||||
*/
|
||||
public int getSessionCount(UUID uuid, long afterDate) throws SQLException {
|
||||
public int getSessionCount(UUID uuid, long afterDate) {
|
||||
return getSessionCount(uuid, ServerInfo.getServerUUID(), afterDate);
|
||||
}
|
||||
|
||||
@ -444,9 +428,8 @@ public class SessionsTable extends UserIDTable {
|
||||
* @param uuid UUID of the player.
|
||||
* @param serverUUID UUID of the server.
|
||||
* @return How many sessions player has. 0 if player or server not found.
|
||||
* @throws SQLException DB Error
|
||||
*/
|
||||
public int getSessionCount(UUID uuid, UUID serverUUID) throws SQLException {
|
||||
public int getSessionCount(UUID uuid, UUID serverUUID) {
|
||||
return getSessionCount(uuid, serverUUID, 0L);
|
||||
}
|
||||
|
||||
@ -455,7 +438,7 @@ public class SessionsTable extends UserIDTable {
|
||||
return Col.ID.get();
|
||||
}
|
||||
|
||||
public Map<UUID, List<Session>> getSessionInfoOfServer(UUID serverUUID) throws SQLException {
|
||||
public Map<UUID, List<Session>> getSessionInfoOfServer(UUID serverUUID) {
|
||||
String usersIDColumn = usersTable + "." + UsersTable.Col.ID;
|
||||
String usersUUIDColumn = usersTable + "." + UsersTable.Col.UUID + " as uuid";
|
||||
String sql = "SELECT " +
|
||||
@ -490,7 +473,7 @@ public class SessionsTable extends UserIDTable {
|
||||
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, timeAFK));
|
||||
sessions.add(new Session(set.getInt(Col.ID.get()), uuid, serverUUID, start, end, mobKills, deaths, timeAFK));
|
||||
sessionsByUser.put(uuid, sessions);
|
||||
}
|
||||
return sessionsByUser;
|
||||
@ -498,12 +481,12 @@ public class SessionsTable extends UserIDTable {
|
||||
});
|
||||
}
|
||||
|
||||
public Map<UUID, List<Session>> getSessionInfoOfServer() throws SQLException {
|
||||
public Map<UUID, List<Session>> getSessionInfoOfServer() {
|
||||
return getSessionInfoOfServer(ServerInfo.getServerUUID());
|
||||
}
|
||||
|
||||
// TODO Write tests for this method
|
||||
public long getLastSeen(UUID uuid) throws SQLException {
|
||||
public long getLastSeen(UUID uuid) {
|
||||
String sql = "SELECT" +
|
||||
" MAX(" + Col.SESSION_END + ") as last_seen" +
|
||||
" FROM " + tableName +
|
||||
@ -525,7 +508,7 @@ public class SessionsTable extends UserIDTable {
|
||||
});
|
||||
}
|
||||
|
||||
public Map<UUID, Long> getLastSeenForAllPlayers() throws SQLException {
|
||||
public Map<UUID, Long> getLastSeenForAllPlayers() {
|
||||
String usersIDColumn = usersTable + "." + UsersTable.Col.ID;
|
||||
String usersUUIDColumn = usersTable + "." + UsersTable.Col.UUID + " as uuid";
|
||||
String sql = "SELECT" +
|
||||
@ -549,7 +532,7 @@ public class SessionsTable extends UserIDTable {
|
||||
});
|
||||
}
|
||||
|
||||
public Map<UUID, Map<UUID, List<Session>>> getAllSessions(boolean getKillsAndWorldTimes) throws SQLException {
|
||||
public Map<UUID, Map<UUID, List<Session>>> getAllSessions(boolean getKillsAndWorldTimes) {
|
||||
Map<Integer, UUID> uuidsByID = usersTable.getUUIDsByID();
|
||||
Map<Integer, UUID> serverUUIDsByID = serverTable.getServerUUIDsByID();
|
||||
|
||||
@ -584,7 +567,7 @@ public class SessionsTable extends UserIDTable {
|
||||
|
||||
long timeAFK = set.getLong(Col.AFK_TIME.get());
|
||||
|
||||
Session session = new Session(id, start, end, mobKills, deaths, timeAFK);
|
||||
Session session = new Session(id, uuid, serverUUID, start, end, mobKills, deaths, timeAFK);
|
||||
sessions.add(session);
|
||||
|
||||
sessionsByUser.put(uuid, sessions);
|
||||
@ -599,7 +582,7 @@ public class SessionsTable extends UserIDTable {
|
||||
});
|
||||
}
|
||||
|
||||
public Map<UUID, Map<UUID, List<Session>>> getSessionInLastMonth() throws SQLException {
|
||||
public Map<UUID, Map<UUID, List<Session>>> getSessionInLastMonth() {
|
||||
Map<Integer, UUID> uuidsByID = usersTable.getUUIDsByID();
|
||||
Map<Integer, UUID> serverUUIDsByID = serverTable.getServerUUIDsByID();
|
||||
|
||||
@ -640,7 +623,7 @@ public class SessionsTable extends UserIDTable {
|
||||
|
||||
long timeAFK = set.getLong(Col.AFK_TIME.get());
|
||||
|
||||
Session session = new Session(id, start, end, mobKills, deaths, timeAFK);
|
||||
Session session = new Session(id, uuid, serverUUID, start, end, mobKills, deaths, timeAFK);
|
||||
sessions.add(session);
|
||||
|
||||
sessionsByUser.put(uuid, sessions);
|
||||
@ -651,7 +634,7 @@ public class SessionsTable extends UserIDTable {
|
||||
});
|
||||
}
|
||||
|
||||
public void insertSessions(Map<UUID, Map<UUID, List<Session>>> allSessions, boolean saveKillsAndWorldTimes) throws SQLException {
|
||||
public void insertSessions(Map<UUID, Map<UUID, List<Session>>> allSessions, boolean saveKillsAndWorldTimes) {
|
||||
if (Verify.isEmpty(allSessions)) {
|
||||
return;
|
||||
}
|
||||
@ -751,7 +734,7 @@ public class SessionsTable extends UserIDTable {
|
||||
addColumns(Col.AFK_TIME + " bigint NOT NULL DEFAULT 0");
|
||||
}
|
||||
|
||||
public Map<Integer, Integer> getIDServerIDRelation() throws SQLException {
|
||||
public Map<Integer, Integer> getIDServerIDRelation() {
|
||||
String sql = "SELECT " +
|
||||
Col.ID + ", " +
|
||||
Col.SERVER_ID +
|
||||
|
@ -68,7 +68,7 @@ public class TPSTable extends Table {
|
||||
);
|
||||
}
|
||||
|
||||
public List<TPS> getTPSData(UUID serverUUID) throws SQLException {
|
||||
public List<TPS> getTPSData(UUID serverUUID) {
|
||||
String sql = Select.all(tableName)
|
||||
.where(Col.SERVER_ID + "=" + serverTable.statementSelectServerID)
|
||||
.toString();
|
||||
@ -104,16 +104,14 @@ public class TPSTable extends Table {
|
||||
/**
|
||||
* @return @throws SQLException
|
||||
*/
|
||||
public List<TPS> getTPSData() throws SQLException {
|
||||
public List<TPS> getTPSData() {
|
||||
return getTPSData(ServerInfo.getServerUUID());
|
||||
}
|
||||
|
||||
/**
|
||||
* Clean the TPS Table of old data.
|
||||
*
|
||||
* @throws SQLException DB Error
|
||||
*/
|
||||
public void clean() throws SQLException {
|
||||
public void clean() {
|
||||
Optional<TPS> allTimePeak = getAllTimePeak();
|
||||
int p = -1;
|
||||
if (allTimePeak.isPresent()) {
|
||||
@ -137,7 +135,7 @@ public class TPSTable extends Table {
|
||||
});
|
||||
}
|
||||
|
||||
public void insertTPS(TPS tps) throws SQLException {
|
||||
public void insertTPS(TPS tps) {
|
||||
execute(new ExecStatement(insertStatement) {
|
||||
@Override
|
||||
public void prepare(PreparedStatement statement) throws SQLException {
|
||||
@ -153,7 +151,7 @@ public class TPSTable extends Table {
|
||||
});
|
||||
}
|
||||
|
||||
public Optional<TPS> getPeakPlayerCount(UUID serverUUID, long afterDate) throws SQLException {
|
||||
public Optional<TPS> getPeakPlayerCount(UUID serverUUID, long afterDate) {
|
||||
String sql = Select.all(tableName)
|
||||
.where(Col.SERVER_ID + "=" + serverTable.statementSelectServerID)
|
||||
.and(Col.PLAYERS_ONLINE + "= (SELECT MAX(" + Col.PLAYERS_ONLINE + ") FROM " + tableName + ")")
|
||||
@ -188,19 +186,19 @@ public class TPSTable extends Table {
|
||||
});
|
||||
}
|
||||
|
||||
public Optional<TPS> getAllTimePeak(UUID serverUUID) throws SQLException {
|
||||
public Optional<TPS> getAllTimePeak(UUID serverUUID) {
|
||||
return getPeakPlayerCount(serverUUID, 0);
|
||||
}
|
||||
|
||||
public Optional<TPS> getAllTimePeak() throws SQLException {
|
||||
public Optional<TPS> getAllTimePeak() {
|
||||
return getPeakPlayerCount(0);
|
||||
}
|
||||
|
||||
public Optional<TPS> getPeakPlayerCount(long afterDate) throws SQLException {
|
||||
public Optional<TPS> getPeakPlayerCount(long afterDate) {
|
||||
return getPeakPlayerCount(ServerInfo.getServerUUID(), afterDate);
|
||||
}
|
||||
|
||||
public Map<UUID, List<TPS>> getAllTPS() throws SQLException {
|
||||
public Map<UUID, List<TPS>> getAllTPS() {
|
||||
String serverIDColumn = serverTable + "." + ServerTable.Col.SERVER_ID;
|
||||
String serverUUIDColumn = serverTable + "." + ServerTable.Col.SERVER_UUID + " as s_uuid";
|
||||
String sql = "SELECT " +
|
||||
@ -242,7 +240,7 @@ public class TPSTable extends Table {
|
||||
});
|
||||
}
|
||||
|
||||
public List<TPS> getNetworkOnlineData() throws SQLException {
|
||||
public List<TPS> getNetworkOnlineData() {
|
||||
Optional<Server> bungeeInfo = serverTable.getBungeeInfo();
|
||||
if (!bungeeInfo.isPresent()) {
|
||||
return new ArrayList<>();
|
||||
@ -279,7 +277,7 @@ public class TPSTable extends Table {
|
||||
});
|
||||
}
|
||||
|
||||
public void insertAllTPS(Map<UUID, List<TPS>> allTPS) throws SQLException {
|
||||
public void insertAllTPS(Map<UUID, List<TPS>> allTPS) {
|
||||
if (Verify.isEmpty(allTPS)) {
|
||||
return;
|
||||
}
|
||||
|
@ -1,10 +1,13 @@
|
||||
package com.djrapitops.plan.system.database.databases.sql.tables;
|
||||
|
||||
import com.djrapitops.plan.api.exceptions.database.DBInitException;
|
||||
import com.djrapitops.plan.api.exceptions.database.DBOpException;
|
||||
import com.djrapitops.plan.system.database.databases.sql.SQLDB;
|
||||
import com.djrapitops.plan.system.database.databases.sql.processing.ExecStatement;
|
||||
import com.djrapitops.plan.system.database.databases.sql.processing.QueryStatement;
|
||||
import com.djrapitops.plan.system.settings.Settings;
|
||||
import com.djrapitops.plan.utilities.MiscUtils;
|
||||
import com.djrapitops.plugin.api.utility.log.Log;
|
||||
import com.djrapitops.plugin.utilities.Verify;
|
||||
import com.google.common.base.Objects;
|
||||
|
||||
@ -13,6 +16,8 @@ import java.sql.PreparedStatement;
|
||||
import java.sql.SQLException;
|
||||
|
||||
/**
|
||||
* Abstract representation of a SQL database table.
|
||||
*
|
||||
* @author Rsl1122
|
||||
*/
|
||||
public abstract class Table {
|
||||
@ -38,12 +43,12 @@ public abstract class Table {
|
||||
protected void createTable(String sql) throws DBInitException {
|
||||
try {
|
||||
execute(sql);
|
||||
} catch (SQLException e) {
|
||||
} catch (DBOpException e) {
|
||||
throw new DBInitException("Failed to create table: " + tableName, e);
|
||||
}
|
||||
}
|
||||
|
||||
protected void renameTable(String to) throws SQLException {
|
||||
protected void renameTable(String to) {
|
||||
String sql = usingMySQL ?
|
||||
"RENAME TABLE " + tableName + " TO " + to :
|
||||
"ALTER TABLE " + tableName + " RENAME TO " + to;
|
||||
@ -55,7 +60,9 @@ public abstract class Table {
|
||||
*
|
||||
* @return SQL Connection
|
||||
* @throws SQLException DB Error
|
||||
* @deprecated Use db.getConnection - db is protected variable.
|
||||
*/
|
||||
@Deprecated
|
||||
protected Connection getConnection() throws SQLException {
|
||||
return db.getConnection();
|
||||
}
|
||||
@ -64,20 +71,20 @@ public abstract class Table {
|
||||
* Get the Database Schema version from VersionTable.
|
||||
*
|
||||
* @return Database Schema version.
|
||||
* @throws SQLException DB Error
|
||||
* @deprecated Use db.getVersion - db is protected variable.
|
||||
*/
|
||||
public int getVersion() throws SQLException {
|
||||
@Deprecated
|
||||
public int getVersion() {
|
||||
return db.getVersion();
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes an SQL Statement
|
||||
*
|
||||
* @param statementString Statement to setUp
|
||||
* @return What setUp returns.
|
||||
* @throws SQLException DB error
|
||||
* @param statementString Statement to execute in the database.
|
||||
* @return true if rows were updated.
|
||||
*/
|
||||
protected boolean execute(String statementString) throws SQLException {
|
||||
protected boolean execute(String statementString) {
|
||||
return execute(new ExecStatement(statementString) {
|
||||
@Override
|
||||
public void prepare(PreparedStatement statement) {
|
||||
@ -87,7 +94,7 @@ public abstract class Table {
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to setUp queries while possible SQLExceptions are suppressed.
|
||||
* Used to execute statements while possible exceptions are suppressed.
|
||||
*
|
||||
* @param statements SQL statements to setUp
|
||||
*/
|
||||
@ -96,8 +103,10 @@ public abstract class Table {
|
||||
for (String statement : statements) {
|
||||
try {
|
||||
execute(statement);
|
||||
} catch (SQLException ignored) {
|
||||
/* Ignored */
|
||||
} catch (DBOpException e) {
|
||||
if (Settings.DEV_MODE.isTrue()) {
|
||||
Log.toLog(this.getClass(), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -118,7 +127,7 @@ public abstract class Table {
|
||||
/**
|
||||
* Removes all data from the table.
|
||||
*/
|
||||
public void removeAllData() throws SQLException {
|
||||
public void removeAllData() {
|
||||
execute("DELETE FROM " + tableName);
|
||||
}
|
||||
|
||||
@ -158,7 +167,11 @@ public abstract class Table {
|
||||
Objects.equal(db, table.db);
|
||||
}
|
||||
|
||||
protected void commit(Connection connection) throws SQLException {
|
||||
/**
|
||||
* @deprecated Use db.commit - db is a protected variable.
|
||||
*/
|
||||
@Deprecated
|
||||
protected void commit(Connection connection) {
|
||||
db.commit(connection);
|
||||
}
|
||||
|
||||
@ -167,45 +180,15 @@ public abstract class Table {
|
||||
return Objects.hashCode(tableName, db, usingMySQL);
|
||||
}
|
||||
|
||||
public SQLDB getDb() {
|
||||
return db;
|
||||
protected boolean execute(ExecStatement statement) {
|
||||
return db.execute(statement);
|
||||
}
|
||||
|
||||
protected boolean execute(ExecStatement statement) throws SQLException {
|
||||
Connection connection = null;
|
||||
try {
|
||||
connection = getConnection();
|
||||
try (PreparedStatement preparedStatement = connection.prepareStatement(statement.getSql())) {
|
||||
return statement.execute(preparedStatement);
|
||||
}
|
||||
} finally {
|
||||
commit(connection);
|
||||
db.returnToPool(connection);
|
||||
}
|
||||
protected void executeBatch(ExecStatement statement) {
|
||||
db.executeBatch(statement);
|
||||
}
|
||||
|
||||
protected void executeBatch(ExecStatement statement) throws SQLException {
|
||||
Connection connection = null;
|
||||
try {
|
||||
connection = getConnection();
|
||||
try (PreparedStatement preparedStatement = connection.prepareStatement(statement.getSql())) {
|
||||
statement.executeBatch(preparedStatement);
|
||||
}
|
||||
} finally {
|
||||
commit(connection);
|
||||
db.returnToPool(connection);
|
||||
}
|
||||
}
|
||||
|
||||
protected <T> T query(QueryStatement<T> statement) throws SQLException {
|
||||
Connection connection = null;
|
||||
try {
|
||||
connection = getConnection();
|
||||
try (PreparedStatement preparedStatement = connection.prepareStatement(statement.getSql())) {
|
||||
return statement.executeQuery(preparedStatement);
|
||||
}
|
||||
} finally {
|
||||
db.returnToPool(connection);
|
||||
}
|
||||
protected <T> T query(QueryStatement<T> statement) {
|
||||
return db.query(statement);
|
||||
}
|
||||
}
|
@ -75,7 +75,7 @@ public class TransferTable extends Table {
|
||||
addColumns(Col.PART + " bigint NOT NULL DEFAULT 0");
|
||||
}
|
||||
|
||||
public void clean() throws SQLException {
|
||||
public void clean() {
|
||||
String sql = "DELETE FROM " + tableName +
|
||||
" WHERE " + Col.EXPIRY + " < ?" +
|
||||
" AND " + Col.INFO_TYPE + " != ?";
|
||||
@ -101,7 +101,7 @@ public class TransferTable extends Table {
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public Optional<UUID> getServerPlayerIsOnline(UUID playerUUID) throws SQLException {
|
||||
public Optional<UUID> getServerPlayerIsOnline(UUID playerUUID) {
|
||||
String serverIDColumn = serverTable + "." + ServerTable.Col.SERVER_ID;
|
||||
String serverUUIDColumn = serverTable + "." + ServerTable.Col.SERVER_UUID + " as s_uuid";
|
||||
String sql = "SELECT " +
|
||||
@ -127,7 +127,7 @@ public class TransferTable extends Table {
|
||||
});
|
||||
}
|
||||
|
||||
public void storeConfigSettings(String encodedSettingString) throws SQLException {
|
||||
public void storeConfigSettings(String encodedSettingString) {
|
||||
execute(new ExecStatement(insertStatementNoParts) {
|
||||
@Override
|
||||
public void prepare(PreparedStatement statement) throws SQLException {
|
||||
@ -140,7 +140,7 @@ public class TransferTable extends Table {
|
||||
});
|
||||
}
|
||||
|
||||
public Optional<String> getConfigSettings() throws SQLException {
|
||||
public Optional<String> getConfigSettings() {
|
||||
return query(new QueryStatement<Optional<String>>(selectStatement, 100) {
|
||||
@Override
|
||||
public void prepare(PreparedStatement statement) throws SQLException {
|
||||
|
@ -42,7 +42,7 @@ public abstract class UserIDTable extends Table {
|
||||
usersTable = db.getUsersTable();
|
||||
}
|
||||
|
||||
public void removeUser(UUID uuid) throws SQLException {
|
||||
public void removeUser(UUID uuid) {
|
||||
String sql = "DELETE FROM " + tableName + " WHERE (" + Col.USER_ID + "=" + usersTable.statementSelectID + ")";
|
||||
|
||||
execute(new ExecStatement(sql) {
|
||||
|
@ -50,7 +50,7 @@ public class UserInfoTable extends UserIDTable {
|
||||
serverTable = db.getServerTable();
|
||||
}
|
||||
|
||||
public void registerUserInfo(UUID uuid, long registered) throws SQLException {
|
||||
public void registerUserInfo(UUID uuid, long registered) {
|
||||
if (!usersTable.isRegistered(uuid)) {
|
||||
usersTable.registerUser(uuid, registered, "Waiting for Update..");
|
||||
}
|
||||
@ -74,7 +74,7 @@ public class UserInfoTable extends UserIDTable {
|
||||
});
|
||||
}
|
||||
|
||||
public boolean isRegistered(UUID uuid, UUID serverUUID) throws SQLException {
|
||||
public boolean isRegistered(UUID uuid, UUID serverUUID) {
|
||||
String sql = Select.from(tableName, "COUNT(" + Col.USER_ID + ") as c")
|
||||
.where(Col.USER_ID + "=" + usersTable.statementSelectID)
|
||||
.and(Col.SERVER_ID + "=" + serverTable.statementSelectServerID)
|
||||
@ -94,11 +94,11 @@ public class UserInfoTable extends UserIDTable {
|
||||
});
|
||||
}
|
||||
|
||||
public boolean isRegistered(UUID uuid) throws SQLException {
|
||||
public boolean isRegistered(UUID uuid) {
|
||||
return isRegistered(uuid, ServerInfo.getServerUUID());
|
||||
}
|
||||
|
||||
public void updateOpStatus(UUID uuid, boolean op) throws SQLException {
|
||||
public void updateOpStatus(UUID uuid, boolean op) {
|
||||
String sql = Update.values(tableName, Col.OP)
|
||||
.where(Col.USER_ID + "=" + usersTable.statementSelectID)
|
||||
.toString();
|
||||
@ -112,7 +112,7 @@ public class UserInfoTable extends UserIDTable {
|
||||
});
|
||||
}
|
||||
|
||||
public void updateBanStatus(UUID uuid, boolean banned) throws SQLException {
|
||||
public void updateBanStatus(UUID uuid, boolean banned) {
|
||||
String sql = Update.values(tableName, Col.BANNED)
|
||||
.where(Col.USER_ID + "=" + usersTable.statementSelectID)
|
||||
.toString();
|
||||
@ -126,7 +126,7 @@ public class UserInfoTable extends UserIDTable {
|
||||
});
|
||||
}
|
||||
|
||||
public Map<UUID, UserInfo> getAllUserInfo(UUID uuid) throws SQLException {
|
||||
public Map<UUID, UserInfo> getAllUserInfo(UUID uuid) {
|
||||
String usersIDColumn = usersTable + "." + UsersTable.Col.ID;
|
||||
String serverIDColumn = serverTable + "." + ServerTable.Col.SERVER_ID;
|
||||
String usersNameColumn = usersTable + "." + UsersTable.Col.USER_NAME + " as name";
|
||||
@ -165,11 +165,11 @@ public class UserInfoTable extends UserIDTable {
|
||||
});
|
||||
}
|
||||
|
||||
public UserInfo getUserInfo(UUID uuid) throws SQLException {
|
||||
public UserInfo getUserInfo(UUID uuid) {
|
||||
return getAllUserInfo(uuid).get(ServerInfo.getServerUUID());
|
||||
}
|
||||
|
||||
public List<UserInfo> getServerUserInfo(UUID serverUUID) throws SQLException {
|
||||
public List<UserInfo> getServerUserInfo(UUID serverUUID) {
|
||||
Optional<Integer> serverID = serverTable.getServerID(serverUUID);
|
||||
if (!serverID.isPresent()) {
|
||||
return new ArrayList<>();
|
||||
@ -212,11 +212,11 @@ public class UserInfoTable extends UserIDTable {
|
||||
*
|
||||
* @return List of UserInfo objects.
|
||||
*/
|
||||
public List<UserInfo> getServerUserInfo() throws SQLException {
|
||||
public List<UserInfo> getServerUserInfo() {
|
||||
return getServerUserInfo(ServerInfo.getServerUUID());
|
||||
}
|
||||
|
||||
public Map<UUID, List<UserInfo>> getAllUserInfo() throws SQLException {
|
||||
public Map<UUID, List<UserInfo>> getAllUserInfo() {
|
||||
String usersIDColumn = usersTable + "." + UsersTable.Col.ID;
|
||||
String usersUUIDColumn = usersTable + "." + UsersTable.Col.UUID + " as uuid";
|
||||
String serverIDColumn = serverTable + "." + ServerTable.Col.SERVER_ID;
|
||||
@ -254,7 +254,7 @@ public class UserInfoTable extends UserIDTable {
|
||||
});
|
||||
}
|
||||
|
||||
public void insertUserInfo(Map<UUID, List<UserInfo>> allUserInfos) throws SQLException {
|
||||
public void insertUserInfo(Map<UUID, List<UserInfo>> allUserInfos) {
|
||||
if (Verify.isEmpty(allUserInfos)) {
|
||||
return;
|
||||
}
|
||||
@ -282,7 +282,7 @@ public class UserInfoTable extends UserIDTable {
|
||||
statement.setLong(2, user.getRegistered());
|
||||
statement.setString(3, serverUUID.toString());
|
||||
statement.setBoolean(4, user.isBanned());
|
||||
statement.setBoolean(5, user.isOpped());
|
||||
statement.setBoolean(5, user.isOperator());
|
||||
statement.addBatch();
|
||||
}
|
||||
}
|
||||
@ -290,7 +290,7 @@ public class UserInfoTable extends UserIDTable {
|
||||
});
|
||||
}
|
||||
|
||||
public Map<UUID, Set<UUID>> getSavedUUIDs() throws SQLException {
|
||||
public Map<UUID, Set<UUID>> getSavedUUIDs() {
|
||||
String usersIDColumn = usersTable + "." + UsersTable.Col.ID;
|
||||
String usersUUIDColumn = usersTable + "." + UsersTable.Col.UUID + " as uuid";
|
||||
String serverIDColumn = serverTable + "." + ServerTable.Col.SERVER_ID;
|
||||
@ -320,7 +320,7 @@ public class UserInfoTable extends UserIDTable {
|
||||
});
|
||||
}
|
||||
|
||||
public int getServerUserCount(UUID serverUUID) throws SQLException {
|
||||
public int getServerUserCount(UUID serverUUID) {
|
||||
String sql = "SELECT " +
|
||||
" COUNT(" + Col.REGISTERED + ") as c" +
|
||||
" FROM " + tableName +
|
||||
@ -366,7 +366,7 @@ public class UserInfoTable extends UserIDTable {
|
||||
}
|
||||
}
|
||||
|
||||
public Set<UUID> getSavedUUIDs(UUID serverUUID) throws SQLException {
|
||||
public Set<UUID> getSavedUUIDs(UUID serverUUID) {
|
||||
String usersIDColumn = usersTable + "." + UsersTable.Col.ID;
|
||||
String usersUUIDColumn = usersTable + "." + UsersTable.Col.UUID + " as uuid";
|
||||
String serverIDColumn = serverTable + "." + ServerTable.Col.SERVER_ID;
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user