diff --git a/Plan/src/main/java/com/djrapitops/plan/system/BungeeSystem.java b/Plan/src/main/java/com/djrapitops/plan/system/BungeeSystem.java index 3aae3842b..3e087a7f6 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/BungeeSystem.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/BungeeSystem.java @@ -8,6 +8,7 @@ import com.djrapitops.plan.PlanBungee; import com.djrapitops.plan.api.BungeeAPI; import com.djrapitops.plan.api.exceptions.EnableException; import com.djrapitops.plan.data.plugin.HookHandler; +import com.djrapitops.plan.system.cache.BungeeCacheSystem; import com.djrapitops.plan.system.database.BungeeDBSystem; import com.djrapitops.plan.system.database.DBSystem; import com.djrapitops.plan.system.file.FileSystem; @@ -37,6 +38,7 @@ public class BungeeSystem extends PlanSystem { fileSystem = new FileSystem(plugin); configSystem = new BungeeConfigSystem(); databaseSystem = new BungeeDBSystem(); + cacheSystem = new BungeeCacheSystem(this); listenerSystem = new BungeeListenerSystem(plugin); taskSystem = new BungeeTaskSystem(plugin); diff --git a/Plan/src/main/java/com/djrapitops/plan/system/PlanSystem.java b/Plan/src/main/java/com/djrapitops/plan/system/PlanSystem.java index 950b83ba9..536f084e5 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/PlanSystem.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/PlanSystem.java @@ -36,7 +36,7 @@ public abstract class PlanSystem implements SubSystem { // Initialized in this class private Processing processing; protected final WebServerSystem webServerSystem; - protected final CacheSystem cacheSystem; + protected CacheSystem cacheSystem; // These need to be initialized in the sub class. protected VersionCheckSystem versionCheckSystem; diff --git a/Plan/src/main/java/com/djrapitops/plan/system/SpongeSystem.java b/Plan/src/main/java/com/djrapitops/plan/system/SpongeSystem.java index b54d8029e..74d7dd87d 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/SpongeSystem.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/SpongeSystem.java @@ -29,8 +29,6 @@ import com.djrapitops.plugin.api.utility.log.Log; */ public class SpongeSystem extends PlanSystem implements ServerSystem { - private boolean firstInstall = false; - public SpongeSystem(PlanSponge plugin) { setTestSystem(this); diff --git a/Plan/src/main/java/com/djrapitops/plan/system/cache/BungeeCacheSystem.java b/Plan/src/main/java/com/djrapitops/plan/system/cache/BungeeCacheSystem.java new file mode 100644 index 000000000..3babf2a10 --- /dev/null +++ b/Plan/src/main/java/com/djrapitops/plan/system/cache/BungeeCacheSystem.java @@ -0,0 +1,18 @@ +package com.djrapitops.plan.system.cache; + +import com.djrapitops.plan.system.PlanSystem; + +/** + * CacheSystem for Bungee. + *

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

+ * Used for overriding {@link SessionCache#endSession(UUID, long)}. + * + * @author Rsl1122 + */ +public class BungeeDataCache extends DataCache { + + public BungeeDataCache(PlanSystem system) { + super(system); + } + + @Override + public void endSession(UUID uuid, long time) { + removeSessionFromCache(uuid); + /* Bungee should not save sessions so session is not removed.. */ + } +} diff --git a/Plan/src/main/java/com/djrapitops/plan/system/cache/CacheSystem.java b/Plan/src/main/java/com/djrapitops/plan/system/cache/CacheSystem.java index 522698c37..41b57d069 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/cache/CacheSystem.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/cache/CacheSystem.java @@ -20,7 +20,11 @@ public class CacheSystem implements SubSystem { private final GeolocationCache geolocationCache; public CacheSystem(PlanSystem system) { - dataCache = new DataCache(system); + this(new DataCache(system)); + } + + protected CacheSystem(DataCache dataCache) { + this.dataCache = dataCache; geolocationCache = new GeolocationCache(); } diff --git a/Plan/src/main/java/com/djrapitops/plan/system/cache/DataCache.java b/Plan/src/main/java/com/djrapitops/plan/system/cache/DataCache.java index 8039ad9cc..7218465c1 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/cache/DataCache.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/cache/DataCache.java @@ -72,6 +72,11 @@ public class DataCache extends SessionCache implements SubSystem { /** * Used to get the player name in the cache. * + * It is recommended to use + * {@link com.djrapitops.plan.data.store.keys.AnalysisKeys#PLAYER_NAMES} and + * {@link com.djrapitops.plan.data.store.keys.PlayerKeys#NAME} when possible + * because this method will call database if a name is not found. + * * @param uuid UUID of the player. * @return name or null if not cached. */ diff --git a/Plan/src/main/java/com/djrapitops/plan/system/cache/SessionCache.java b/Plan/src/main/java/com/djrapitops/plan/system/cache/SessionCache.java index 2def82cea..dbd86adee 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/cache/SessionCache.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/cache/SessionCache.java @@ -2,6 +2,7 @@ package com.djrapitops.plan.system.cache; import com.djrapitops.plan.api.exceptions.database.DBOpException; import com.djrapitops.plan.data.container.Session; +import com.djrapitops.plan.data.store.keys.SessionKeys; import com.djrapitops.plan.system.PlanSystem; import com.djrapitops.plan.system.database.databases.Database; import com.djrapitops.plugin.api.utility.log.Log; @@ -33,13 +34,6 @@ public class SessionCache { return dataCache; } - /** - * Used to get the Map of active sessions. - *

- * Used for testing. - * - * @return key:value UUID:Session - */ public static Map getActiveSessions() { return activeSessions; } @@ -48,28 +42,9 @@ public class SessionCache { activeSessions.clear(); } - public void cacheSession(UUID uuid, Session session) { - activeSessions.put(uuid, session); - } - - public void endSession(UUID uuid, long time) { - try { - Session session = activeSessions.get(uuid); - if (session == null) { - return; - } - session.endSession(time); - Database.getActive().save().session(uuid, session); - } catch (DBOpException e) { - Log.toLog(this.getClass(), e); - } finally { - activeSessions.remove(uuid); - } - } - public static void refreshActiveSessionsState() { for (Session session : activeSessions.values()) { - session.getWorldTimes().updateState(System.currentTimeMillis()); + session.getUnsafe(SessionKeys.WORLD_TIMES).updateState(System.currentTimeMillis()); } } @@ -77,14 +52,42 @@ public class SessionCache { * Used to get the Session of the player in the sessionCache. * * @param uuid UUID of the player. - * @return Session or null if not cached. + * @return Optional with the session inside it if found. */ public static Optional getCachedSession(UUID uuid) { - Session session = activeSessions.get(uuid); - if (session != null) { - return Optional.of(session); - } - return Optional.empty(); + return Optional.ofNullable(activeSessions.get(uuid)); } + public static boolean isOnline(UUID uuid) { + return getCachedSession(uuid).isPresent(); + } + + public void cacheSession(UUID uuid, Session session) { + if (getCachedSession(uuid).isPresent()) { + endSession(uuid, System.currentTimeMillis()); + } + activeSessions.put(uuid, session); + } + + public void endSession(UUID uuid, long time) { + Session session = activeSessions.get(uuid); + if (session == null) { + return; + } + if (session.getUnsafe(SessionKeys.START) > time) { + return; + } + try { + session.endSession(time); + Database.getActive().save().session(uuid, session); + } catch (DBOpException e) { + Log.toLog(this.getClass(), e); + } finally { + removeSessionFromCache(uuid); + } + } + + protected void removeSessionFromCache(UUID uuid) { + activeSessions.remove(uuid); + } } diff --git a/Plan/src/main/java/com/djrapitops/plan/system/info/BungeeInfoSystem.java b/Plan/src/main/java/com/djrapitops/plan/system/info/BungeeInfoSystem.java index 91c7e0492..acf13549f 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/info/BungeeInfoSystem.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/info/BungeeInfoSystem.java @@ -9,6 +9,8 @@ import com.djrapitops.plan.api.exceptions.connection.NoServersException; import com.djrapitops.plan.api.exceptions.connection.WebException; import com.djrapitops.plan.api.exceptions.connection.WebFailException; import com.djrapitops.plan.system.info.connection.BungeeConnectionSystem; +import com.djrapitops.plan.system.info.request.CacheRequest; +import com.djrapitops.plan.system.info.request.GenerateInspectPageRequest; import com.djrapitops.plan.system.info.request.InfoRequest; import com.djrapitops.plan.system.info.server.ServerInfo; import com.djrapitops.plan.system.webserver.pages.parsing.NetworkPage; @@ -29,8 +31,13 @@ public class BungeeInfoSystem extends InfoSystem { @Override public void runLocally(InfoRequest infoRequest) throws WebException { - // runLocally is called when ConnectionSystem has no servers. - throw new NoServersException("No servers were available to process this request (Local attempt): " + infoRequest.getClass().getSimpleName()); + if (infoRequest instanceof CacheRequest || + infoRequest instanceof GenerateInspectPageRequest) { + infoRequest.runLocally(); + } else { + // runLocally is called when ConnectionSystem has no servers. + throw new NoServersException("No servers were available to process this request (Local attempt): " + infoRequest.getClass().getSimpleName()); + } } @Override diff --git a/Plan/src/main/java/com/djrapitops/plan/system/info/InfoSystem.java b/Plan/src/main/java/com/djrapitops/plan/system/info/InfoSystem.java index c925e55b4..e99b0ad43 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/info/InfoSystem.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/info/InfoSystem.java @@ -61,7 +61,7 @@ public abstract class InfoSystem implements SubSystem { try { sendRequest(infoRequest); } catch (ConnectionFailException e) { - connectionSystem.sendWideInfoRequest(infoRequest); + runLocally(infoRequest); } } diff --git a/Plan/src/main/java/com/djrapitops/plan/system/info/connection/BungeeConnectionSystem.java b/Plan/src/main/java/com/djrapitops/plan/system/info/connection/BungeeConnectionSystem.java index 52be57380..e87255bad 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/info/connection/BungeeConnectionSystem.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/info/connection/BungeeConnectionSystem.java @@ -9,6 +9,7 @@ import com.djrapitops.plan.api.exceptions.database.DBOpException; import com.djrapitops.plan.system.database.databases.Database; import com.djrapitops.plan.system.info.request.*; import com.djrapitops.plan.system.info.server.Server; +import com.djrapitops.plan.system.info.server.ServerInfo; import com.djrapitops.plan.system.webserver.WebServerSystem; import com.djrapitops.plugin.api.TimeAmount; import com.djrapitops.plugin.api.utility.log.Log; @@ -51,12 +52,8 @@ public class BungeeConnectionSystem extends ConnectionSystem { UUID serverUUID = ((GenerateAnalysisPageRequest) infoRequest).getServerUUID(); server = bukkitServers.get(serverUUID); } else if (infoRequest instanceof GenerateInspectPageRequest) { - Optional serverUUID = getServerWherePlayerIsOnline((GenerateInspectPageRequest) infoRequest); - if (serverUUID.isPresent()) { - server = bukkitServers.getOrDefault(serverUUID.get(), getOneBukkitServer()); - } else { - server = getOneBukkitServer(); - } + // Run locally + server = ServerInfo.getServer(); } if (server == null) { throw new NoServersException("Proper server is not available to process request: " + infoRequest.getClass().getSimpleName()); diff --git a/Plan/src/main/java/com/djrapitops/plan/system/info/connection/ConnectionSystem.java b/Plan/src/main/java/com/djrapitops/plan/system/info/connection/ConnectionSystem.java index 4ac15d21c..70a4054b2 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/info/connection/ConnectionSystem.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/info/connection/ConnectionSystem.java @@ -4,19 +4,13 @@ */ package com.djrapitops.plan.system.info.connection; -import com.djrapitops.plan.Plan; import com.djrapitops.plan.api.exceptions.connection.NoServersException; -import com.djrapitops.plan.api.exceptions.connection.UnsupportedTransferDatabaseException; import com.djrapitops.plan.api.exceptions.connection.WebException; -import com.djrapitops.plan.api.exceptions.database.DBOpException; import com.djrapitops.plan.system.SubSystem; -import com.djrapitops.plan.system.database.databases.Database; import com.djrapitops.plan.system.info.InfoSystem; import com.djrapitops.plan.system.info.request.*; import com.djrapitops.plan.system.info.server.Server; import com.djrapitops.plan.system.info.server.ServerInfo; -import com.djrapitops.plugin.api.Check; -import com.djrapitops.plugin.api.utility.log.Log; import com.djrapitops.plugin.utilities.Verify; import java.util.*; @@ -93,23 +87,6 @@ public abstract class ConnectionSystem implements SubSystem { public abstract void sendWideInfoRequest(WideRequest infoRequest) throws NoServersException; - protected Optional getServerWherePlayerIsOnline(GenerateInspectPageRequest infoRequest) { - UUID playerUUID = infoRequest.getPlayerUUID(); - - if (Check.isBukkitAvailable() && Plan.getInstance().getServer().getPlayer(playerUUID) != null) { - return Optional.of(ServerInfo.getServerUUID()); - } - - try { - return Database.getActive().transfer().getServerPlayerIsOnlineOn(playerUUID); - } catch (UnsupportedTransferDatabaseException e) { - /* Do nothing */ - } catch (DBOpException e) { - Log.toLog(this.getClass(), e); - } - return Optional.empty(); - } - private Map loadDataRequests() { Map requests = new HashMap<>(); putRequest(requests, CacheInspectPageRequest.createHandler()); diff --git a/Plan/src/main/java/com/djrapitops/plan/system/info/connection/ServerConnectionSystem.java b/Plan/src/main/java/com/djrapitops/plan/system/info/connection/ServerConnectionSystem.java index 13360bac1..04064e4b3 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/info/connection/ServerConnectionSystem.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/info/connection/ServerConnectionSystem.java @@ -57,16 +57,12 @@ public class ServerConnectionSystem extends ConnectionSystem { } Server server = null; - if (infoRequest instanceof CacheRequest) { + if (infoRequest instanceof CacheRequest || + infoRequest instanceof GenerateInspectPageRequest) { server = mainServer; } else if (infoRequest instanceof GenerateAnalysisPageRequest) { UUID serverUUID = ((GenerateAnalysisPageRequest) infoRequest).getServerUUID(); server = bukkitServers.get(serverUUID); - } else if (infoRequest instanceof GenerateInspectPageRequest) { - Optional serverUUID = getServerWherePlayerIsOnline((GenerateInspectPageRequest) infoRequest); - if (serverUUID.isPresent()) { - server = bukkitServers.getOrDefault(serverUUID.get(), ServerInfo.getServer()); - } } if (server == null) { throw new NoServersException("Proper server is not available to process request: " + infoRequest.getClass().getSimpleName()); diff --git a/Plan/src/main/java/com/djrapitops/plan/system/info/request/GenerateInspectPageRequest.java b/Plan/src/main/java/com/djrapitops/plan/system/info/request/GenerateInspectPageRequest.java index 16c89fcb3..8c524d2d7 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/info/request/GenerateInspectPageRequest.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/info/request/GenerateInspectPageRequest.java @@ -22,7 +22,7 @@ import java.util.UUID; * * @author Rsl1122 */ -public class GenerateInspectPageRequest extends InfoRequestWithVariables implements GenerateRequest, WideRequest { +public class GenerateInspectPageRequest extends InfoRequestWithVariables implements GenerateRequest { private final UUID playerUUID; diff --git a/Plan/src/main/java/com/djrapitops/plan/system/listeners/bungee/PlayerOnlineListener.java b/Plan/src/main/java/com/djrapitops/plan/system/listeners/bungee/PlayerOnlineListener.java index a70344050..e5d88990c 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/listeners/bungee/PlayerOnlineListener.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/listeners/bungee/PlayerOnlineListener.java @@ -4,12 +4,16 @@ */ package com.djrapitops.plan.system.listeners.bungee; +import com.djrapitops.plan.data.container.Session; +import com.djrapitops.plan.system.cache.SessionCache; import com.djrapitops.plan.system.processing.Processing; import com.djrapitops.plan.system.processing.processors.player.BungeePlayerRegisterProcessor; import com.djrapitops.plan.system.processing.processors.player.IPUpdateProcessor; import com.djrapitops.plugin.api.utility.log.Log; import net.md_5.bungee.api.connection.ProxiedPlayer; import net.md_5.bungee.api.event.PostLoginEvent; +import net.md_5.bungee.api.event.ServerDisconnectEvent; +import net.md_5.bungee.api.event.ServerSwitchEvent; import net.md_5.bungee.api.plugin.Listener; import net.md_5.bungee.event.EventHandler; @@ -32,6 +36,8 @@ public class PlayerOnlineListener implements Listener { InetAddress address = player.getAddress().getAddress(); long now = System.currentTimeMillis(); + SessionCache.getInstance().cacheSession(uuid, new Session(uuid, now, "", "")); + Processing.submit(new BungeePlayerRegisterProcessor(uuid, name, now, new IPUpdateProcessor(uuid, address, now)) ); @@ -39,4 +45,30 @@ public class PlayerOnlineListener implements Listener { Log.toLog(this.getClass(), e); } } + + @EventHandler + public void onLogout(ServerDisconnectEvent event) { + try { + ProxiedPlayer player = event.getPlayer(); + UUID uuid = player.getUniqueId(); + + SessionCache.getInstance().endSession(uuid, System.currentTimeMillis()); + } catch (Exception e) { + Log.toLog(this.getClass(), e); + } + } + + @EventHandler + public void onServerSwitch(ServerSwitchEvent event) { + try { + ProxiedPlayer player = event.getPlayer(); + UUID uuid = player.getUniqueId(); + + long now = System.currentTimeMillis(); + // Replaces the current session in the cache. + SessionCache.getInstance().cacheSession(uuid, new Session(uuid, now, "", "")); + } catch (Exception e) { + Log.toLog(this.getClass(), e); + } + } } diff --git a/Plan/src/main/java/com/djrapitops/plan/system/webserver/pages/parsing/InspectPage.java b/Plan/src/main/java/com/djrapitops/plan/system/webserver/pages/parsing/InspectPage.java index 7d6b534ea..2d5660995 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/webserver/pages/parsing/InspectPage.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/webserver/pages/parsing/InspectPage.java @@ -19,7 +19,6 @@ import com.djrapitops.plan.data.store.mutators.formatting.PlaceholderReplacer; import com.djrapitops.plan.data.time.WorldTimes; import com.djrapitops.plan.system.cache.SessionCache; import com.djrapitops.plan.system.database.databases.Database; -import com.djrapitops.plan.system.info.InfoSystem; import com.djrapitops.plan.system.info.server.ServerInfo; import com.djrapitops.plan.system.settings.Settings; import com.djrapitops.plan.system.settings.theme.Theme; @@ -87,12 +86,12 @@ public class InspectPage implements Page { replacer.put("version", MiscUtils.getPlanVersion()); replacer.put("timeZone", MiscUtils.getTimeZoneOffsetHours()); - String online = "Offline"; + boolean online = false; Optional activeSession = SessionCache.getCachedSession(uuid); if (activeSession.isPresent()) { Session session = activeSession.get(); session.setSessionID(Integer.MAX_VALUE); - online = serverNames.get(serverUUID); + online = true; container.putRawData(PlayerKeys.ACTIVE_SESSION, session); } @@ -182,9 +181,12 @@ public class InspectPage implements Page { container.getValue(PlayerKeys.BANNED).orElse(false), container.getValue(PlayerKeys.OPERATOR).orElse(false))); - if (!InfoSystem.getInstance().getConnectionSystem().isServerAvailable()) { - replacer.put("networkName", Settings.SERVER_NAME.toString().replaceAll("[^a-zA-Z0-9_\\s]", "_")); - } + String serverName = serverNames.get(serverUUID); + replacer.put("networkName", + serverName.equalsIgnoreCase("bungee") + ? Settings.BUNGEE_NETWORK_NAME.toString() + : serverName + ); return replacer.apply(FileUtil.getStringFromResource("web/player.html")); } diff --git a/Plan/src/main/java/com/djrapitops/plan/utilities/html/HtmlStructure.java b/Plan/src/main/java/com/djrapitops/plan/utilities/html/HtmlStructure.java index 7b23dbe9c..810de7303 100644 --- a/Plan/src/main/java/com/djrapitops/plan/utilities/html/HtmlStructure.java +++ b/Plan/src/main/java/com/djrapitops/plan/utilities/html/HtmlStructure.java @@ -165,18 +165,14 @@ public class HtmlStructure { "})"; } - public static String playerStatus(String online, boolean banned, boolean op) { - boolean offline = "offline".equalsIgnoreCase(online); - + public static String playerStatus(boolean online, boolean banned, boolean op) { StringBuilder html = new StringBuilder("

"); - if (offline) { + if (online) { + html.append(Icon.called("circle").of(Color.GREEN)) + .append(" Online"); + } else { html.append(Icon.called("circle").of(Color.RED)) .append(" Offline"); - } else { - html.append(Icon.called("circle").of(Color.GREEN)) - .append(" Online (") - .append(online) - .append(")"); } html.append("

"); if (op) {