Moved Inspect page generation to Bungee #630, prevented #488

This commit is contained in:
Rsl1122 2018-07-12 13:08:19 +03:00
parent a7fd378ca8
commit fd65f00487
17 changed files with 153 additions and 91 deletions

View File

@ -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);

View File

@ -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;

View File

@ -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);

View File

@ -0,0 +1,18 @@
package com.djrapitops.plan.system.cache;
import com.djrapitops.plan.system.PlanSystem;
/**
* CacheSystem for Bungee.
* <p>
* Used for overriding {@link DataCache} with {@link BungeeDataCache}
*
* @author Rsl1122
*/
public class BungeeCacheSystem extends CacheSystem {
public BungeeCacheSystem(PlanSystem system) {
super(new BungeeDataCache(system));
}
}

View File

@ -0,0 +1,25 @@
package com.djrapitops.plan.system.cache;
import com.djrapitops.plan.system.PlanSystem;
import java.util.UUID;
/**
* Bungee specific DataCache.
* <p>
* 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.. */
}
}

View File

@ -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();
}

View File

@ -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.
*/

View File

@ -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.
* <p>
* Used for testing.
*
* @return key:value UUID:Session
*/
public static Map<UUID, Session> 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<Session> 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);
}
}

View File

@ -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

View File

@ -61,7 +61,7 @@ public abstract class InfoSystem implements SubSystem {
try {
sendRequest(infoRequest);
} catch (ConnectionFailException e) {
connectionSystem.sendWideInfoRequest(infoRequest);
runLocally(infoRequest);
}
}

View File

@ -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<UUID> 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());

View File

@ -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<UUID> 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<String, InfoRequest> loadDataRequests() {
Map<String, InfoRequest> requests = new HashMap<>();
putRequest(requests, CacheInspectPageRequest.createHandler());

View File

@ -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<UUID> 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());

View File

@ -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;

View File

@ -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);
}
}
}

View File

@ -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<Session> 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"));
}

View File

@ -165,18 +165,14 @@ public class HtmlStructure {
"})</script>";
}
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("<p>");
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("</p>");
if (op) {