mirror of
https://github.com/plan-player-analytics/Plan.git
synced 2024-12-25 18:47:50 +01:00
NetworkContainer, Improved PerServer data fetching for large numbers of players
This commit is contained in:
parent
fc4942b59b
commit
e65106382b
@ -1,25 +1,32 @@
|
||||
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) {
|
||||
if (cachedValue == null || System.currentTimeMillis() - cacheTime > TimeAmount.SECOND.ms() * 30L) {
|
||||
cachedValue = original.get();
|
||||
cacheTime = System.currentTimeMillis();
|
||||
}
|
||||
return cachedValue;
|
||||
}
|
||||
|
@ -3,6 +3,7 @@ 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;
|
||||
|
||||
@ -22,9 +23,13 @@ public class PerServerDataMutator {
|
||||
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()
|
||||
.map(container -> container.getUnsafe(PlayerKeys.SESSIONS))
|
||||
.map(container -> container.getUnsafe(PerServerKeys.SESSIONS))
|
||||
.flatMap(Collection::stream)
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
@ -33,7 +38,7 @@ public class PerServerDataMutator {
|
||||
WorldTimes total = new WorldTimes(new HashMap<>());
|
||||
|
||||
for (DataContainer container : data.values()) {
|
||||
WorldTimes worldTimes = container.getUnsafe(PlayerKeys.WORLD_TIMES);
|
||||
WorldTimes worldTimes = container.getUnsafe(PerServerKeys.WORLD_TIMES);
|
||||
total.add(worldTimes);
|
||||
}
|
||||
|
||||
@ -43,7 +48,7 @@ public class PerServerDataMutator {
|
||||
public Map<UUID, WorldTimes> worldTimesPerServer() {
|
||||
Map<UUID, WorldTimes> timesMap = new HashMap<>();
|
||||
for (Map.Entry<UUID, DataContainer> entry : data.entrySet()) {
|
||||
timesMap.put(entry.getKey(), entry.getValue().getUnsafe(PlayerKeys.WORLD_TIMES));
|
||||
timesMap.put(entry.getKey(), entry.getValue().getUnsafe(PerServerKeys.WORLD_TIMES));
|
||||
}
|
||||
return timesMap;
|
||||
}
|
||||
@ -53,9 +58,7 @@ public class PerServerDataMutator {
|
||||
UUID maxServer = null;
|
||||
|
||||
for (Map.Entry<UUID, DataContainer> entry : data.entrySet()) {
|
||||
long total = entry.getValue().getValue(PlayerKeys.WORLD_TIMES)
|
||||
.orElse(new WorldTimes(new HashMap<>()))
|
||||
.getTotal();
|
||||
long total = SessionsMutator.forContainer(entry.getValue()).toPlaytime();
|
||||
if (total > max) {
|
||||
max = total;
|
||||
maxServer = entry.getKey();
|
||||
@ -68,7 +71,7 @@ public class PerServerDataMutator {
|
||||
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().getUnsafe(PlayerKeys.SESSIONS));
|
||||
sessionMap.put(entry.getKey(), entry.getValue().getUnsafe(PerServerKeys.SESSIONS));
|
||||
}
|
||||
return sessionMap;
|
||||
}
|
||||
|
@ -204,4 +204,9 @@ public class PlayersMutator {
|
||||
.filter(Objects::nonNull)
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
public List<PlayerContainer> operators() {
|
||||
return players.stream()
|
||||
.filter(player -> player.getValue(PlayerKeys.OPERATOR).orElse(false)).collect(Collectors.toList());
|
||||
}
|
||||
}
|
@ -32,7 +32,7 @@ public class PlaceholderReplacer extends HashMap<String, Serializable> implement
|
||||
}
|
||||
}
|
||||
|
||||
public <T> void addPlaceholderFrom(DataContainer container, Formatter<T> formatter, PlaceholderKey<T> key) {
|
||||
public <T> void addAllPlaceholderFrom(DataContainer container, Formatter<T> formatter, PlaceholderKey<T> key) {
|
||||
if (!container.supports(key)) {
|
||||
return;
|
||||
}
|
||||
@ -45,7 +45,7 @@ public class PlaceholderReplacer extends HashMap<String, Serializable> implement
|
||||
|
||||
public <T> void addPlaceholdersFrom(DataContainer container, Formatter<T> formatter, PlaceholderKey<T>... keys) {
|
||||
for (PlaceholderKey<T> key : keys) {
|
||||
addPlaceholderFrom(container, formatter, key);
|
||||
addAllPlaceholderFrom(container, formatter, key);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -5,6 +5,7 @@ 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;
|
||||
@ -13,14 +14,60 @@ 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();
|
||||
|
||||
/**
|
||||
* 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);
|
||||
|
||||
// UUIDs
|
||||
/**
|
||||
* 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();
|
||||
|
||||
/**
|
||||
* 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();
|
||||
|
||||
Set<UUID> getSavedUUIDs(UUID server);
|
||||
@ -47,22 +94,8 @@ public interface FetchOperations {
|
||||
|
||||
List<TPS> getTPSData(UUID serverUUID);
|
||||
|
||||
List<TPS> getNetworkOnlineData();
|
||||
|
||||
List<Long> getRegisterDates();
|
||||
|
||||
Optional<TPS> getAllTimePeak(UUID serverUUID);
|
||||
|
||||
Optional<TPS> getPeakPlayerCount(UUID serverUUID, long afterDate);
|
||||
|
||||
Map<UUID, Map<UUID, List<Session>>> getSessionsWithNoExtras();
|
||||
|
||||
Map<UUID, Map<UUID, List<Session>>> getSessionsAndExtras();
|
||||
|
||||
Set<String> getWorldNames(UUID serverUuid);
|
||||
|
||||
List<String> getNicknamesOfPlayerOnServer(UUID uuid, UUID serverUUID);
|
||||
|
||||
Map<UUID, UserInfo> getUsers();
|
||||
|
||||
Map<UUID, Long> getLastSeenForAllPlayers();
|
||||
@ -79,13 +112,8 @@ public interface FetchOperations {
|
||||
|
||||
List<WebUser> getWebUsers();
|
||||
|
||||
Map<Integer, String> getServerNamesByID();
|
||||
|
||||
Map<UUID, Map<UUID, List<Session>>> getSessionsInLastMonth();
|
||||
|
||||
List<Server> getServers();
|
||||
|
||||
List<UUID> getServerUUIDs();
|
||||
|
||||
List<String> getNetworkGeolocations();
|
||||
}
|
||||
|
@ -5,10 +5,7 @@ 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.DataContainer;
|
||||
import com.djrapitops.plan.data.store.containers.PerServerContainer;
|
||||
import com.djrapitops.plan.data.store.containers.PlayerContainer;
|
||||
import com.djrapitops.plan.data.store.containers.ServerContainer;
|
||||
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;
|
||||
@ -23,7 +20,6 @@ import com.djrapitops.plan.system.info.server.Server;
|
||||
import com.djrapitops.plugin.api.TimeAmount;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class SQLFetchOps extends SQLOps implements FetchOperations {
|
||||
|
||||
@ -31,6 +27,27 @@ public class SQLFetchOps extends SQLOps implements FetchOperations {
|
||||
super(db);
|
||||
}
|
||||
|
||||
@Override
|
||||
public NetworkContainer getNetworkContainer() {
|
||||
return new NetworkContainer(getBungeeServerContainer());
|
||||
}
|
||||
|
||||
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 ServerContainer getServerContainer(UUID serverUUID) {
|
||||
ServerContainer container = new ServerContainer();
|
||||
@ -68,8 +85,7 @@ public class SQLFetchOps extends SQLOps implements FetchOperations {
|
||||
container.putSupplier(ServerKeys.WORLD_TIMES, () -> worldTimesTable.getWorldTimesOfServer(serverUUID));
|
||||
|
||||
// Calculating getters
|
||||
container.putSupplier(ServerKeys.OPERATORS, () -> container.getUnsafe(ServerKeys.PLAYERS).stream()
|
||||
.filter(player -> player.getValue(PlayerKeys.OPERATOR).orElse(false)).collect(Collectors.toList()));
|
||||
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);
|
||||
@ -92,6 +108,10 @@ public class SQLFetchOps extends SQLOps implements FetchOperations {
|
||||
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();
|
||||
@ -102,7 +122,7 @@ public class SQLFetchOps extends SQLOps implements FetchOperations {
|
||||
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, () -> getPerServerData(uuid));
|
||||
container.putSupplier(PlayerKeys.PER_SERVER, () -> perServerInfo.get(uuid));
|
||||
|
||||
container.putRawData(PlayerKeys.BANNED, userInfo.isBanned());
|
||||
container.putRawData(PlayerKeys.OPERATOR, userInfo.isOperator());
|
||||
@ -134,6 +154,95 @@ public class SQLFetchOps extends SQLOps implements FetchOperations {
|
||||
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();
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
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 PlayerContainer getPlayerContainer(UUID uuid) {
|
||||
PlayerContainer container = new PlayerContainer();
|
||||
@ -242,51 +351,11 @@ public class SQLFetchOps extends SQLOps implements FetchOperations {
|
||||
return tpsTable.getTPSData(serverUUID);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<TPS> getNetworkOnlineData() {
|
||||
return tpsTable.getNetworkOnlineData();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Long> getRegisterDates() {
|
||||
return usersTable.getRegisterDates();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<TPS> getAllTimePeak(UUID serverUUID) {
|
||||
return tpsTable.getAllTimePeak(serverUUID);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<TPS> getPeakPlayerCount(UUID serverUUID, long afterDate) {
|
||||
return tpsTable.getPeakPlayerCount(serverUUID, afterDate);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<UUID, Map<UUID, List<Session>>> getSessionsWithNoExtras() {
|
||||
return sessionsTable.getAllSessions(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<UUID, Map<UUID, List<Session>>> getSessionsAndExtras() {
|
||||
return sessionsTable.getAllSessions(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<UUID, Map<UUID, List<Session>>> getSessionsInLastMonth() {
|
||||
return sessionsTable.getSessionInLastMonth();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<String> getWorldNames(UUID serverUuid) {
|
||||
return worldTable.getWorldNames(serverUuid);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getNicknamesOfPlayerOnServer(UUID uuid, UUID serverUUID) {
|
||||
return nicknamesTable.getNicknames(uuid, serverUUID);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<UUID, UserInfo> getUsers() {
|
||||
return usersTable.getUsers();
|
||||
@ -342,11 +411,6 @@ public class SQLFetchOps extends SQLOps implements FetchOperations {
|
||||
return securityTable.getUsers();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<Integer, String> getServerNamesByID() {
|
||||
return serverTable.getServerNamesByID();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Server> getServers() {
|
||||
Map<UUID, Server> bukkitServers = getBukkitServers();
|
||||
@ -364,8 +428,4 @@ public class SQLFetchOps extends SQLOps implements FetchOperations {
|
||||
return serverTable.getServerUUIDs();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getNetworkGeolocations() {
|
||||
return geoInfoTable.getNetworkGeolocations();
|
||||
}
|
||||
}
|
||||
|
@ -5,30 +5,15 @@
|
||||
package com.djrapitops.plan.system.webserver.pages.parsing;
|
||||
|
||||
import com.djrapitops.plan.api.exceptions.ParseException;
|
||||
import com.djrapitops.plan.data.container.Session;
|
||||
import com.djrapitops.plan.data.container.TPS;
|
||||
import com.djrapitops.plan.data.store.mutators.formatting.Formatters;
|
||||
import com.djrapitops.plan.data.store.containers.NetworkContainer;
|
||||
import com.djrapitops.plan.data.store.mutators.formatting.PlaceholderReplacer;
|
||||
import com.djrapitops.plan.system.database.databases.Database;
|
||||
import com.djrapitops.plan.system.info.server.ServerInfo;
|
||||
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.system.update.VersionCheckSystem;
|
||||
import com.djrapitops.plan.system.webserver.response.cache.PageId;
|
||||
import com.djrapitops.plan.system.webserver.response.cache.ResponseCache;
|
||||
import com.djrapitops.plan.system.webserver.response.pages.parts.NetworkPageContent;
|
||||
import com.djrapitops.plan.utilities.MiscUtils;
|
||||
import com.djrapitops.plan.utilities.analysis.AnalysisUtils;
|
||||
import com.djrapitops.plan.utilities.file.FileUtil;
|
||||
import com.djrapitops.plan.utilities.html.HtmlUtils;
|
||||
import com.djrapitops.plan.utilities.html.graphs.WorldMap;
|
||||
import com.djrapitops.plan.utilities.html.graphs.line.OnlineActivityGraph;
|
||||
import com.djrapitops.plugin.api.TimeAmount;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.UUID;
|
||||
import static com.djrapitops.plan.data.store.keys.NetworkKeys.*;
|
||||
|
||||
/**
|
||||
* Html String parser for /network page.
|
||||
@ -40,76 +25,26 @@ public class NetworkPage extends Page {
|
||||
@Override
|
||||
public String toHtml() throws ParseException {
|
||||
try {
|
||||
UUID serverUUID = ServerInfo.getServerUUID();
|
||||
long now = System.currentTimeMillis();
|
||||
Database database = Database.getActive();
|
||||
List<TPS> networkOnlineData = database.fetch().getNetworkOnlineData();
|
||||
List<String> geolocations = database.fetch().getNetworkGeolocations();
|
||||
|
||||
peakTimes(serverUUID, now, database);
|
||||
|
||||
uniquePlayers(now, database);
|
||||
|
||||
addValue("timeZone", MiscUtils.getTimeZoneOffsetHours());
|
||||
addValue("networkName", Settings.BUNGEE_NETWORK_NAME.toString());
|
||||
addValue("version", VersionCheckSystem.getCurrentVersion());
|
||||
addValue("playersOnlineSeries", new OnlineActivityGraph(networkOnlineData).toHighChartsSeries());
|
||||
addValue("playersGraphColor", Theme.getValue(ThemeVal.GRAPH_PLAYERS_ONLINE));
|
||||
addValue("worldMapColLow", Theme.getValue(ThemeVal.WORLD_MAP_LOW));
|
||||
addValue("worldMapColHigh", Theme.getValue(ThemeVal.WORLD_MAP_HIGH));
|
||||
addValue("playersOnline", ServerInfo.getServerProperties().getOnlinePlayers());
|
||||
|
||||
addValue("playersTotal", database.count().getNetworkPlayerCount());
|
||||
|
||||
addValue("geoMapSeries", new WorldMap(geolocations).toHighChartsSeries());
|
||||
|
||||
List<Long> registerDates = database.fetch().getRegisterDates();
|
||||
addValue("playersNewDay", AnalysisUtils.getNewPlayers(registerDates, TimeAmount.DAY.ms(), now));
|
||||
addValue("playersNewWeek", AnalysisUtils.getNewPlayers(registerDates, TimeAmount.WEEK.ms(), now));
|
||||
addValue("playersNewMonth", AnalysisUtils.getNewPlayers(registerDates, TimeAmount.MONTH.ms(), now));
|
||||
NetworkContainer networkContainer = database.fetch().getNetworkContainer();
|
||||
|
||||
PlaceholderReplacer placeholderReplacer = new PlaceholderReplacer();
|
||||
placeholderReplacer.addAllPlaceholdersFrom(networkContainer,
|
||||
VERSION, NETWORK_NAME, TIME_ZONE,
|
||||
PLAYERS_ONLINE_SERIES, PLAYERS_TOTAL, PLAYERS_GRAPH_COLOR,
|
||||
REFRESH_TIME_F, RECENT_PEAK_TIME_F, ALL_TIME_PEAK_TIME_F,
|
||||
PLAYERS_ALL_TIME_PEAK, PLAYERS_RECENT_PEAK,
|
||||
PLAYERS_DAY, PLAYERS_WEEK, PLAYERS_MONTH,
|
||||
PLAYERS_NEW_DAY, PLAYERS_NEW_WEEK, PLAYERS_NEW_MONTH,
|
||||
WORLD_MAP_SERIES, WORLD_MAP_HIGH_COLOR, WORLD_MAP_LOW_COLOR
|
||||
);
|
||||
NetworkPageContent networkPageContent = (NetworkPageContent)
|
||||
ResponseCache.loadResponse(PageId.NETWORK_CONTENT.id(), NetworkPageContent::new);
|
||||
addValue("tabContentServers", networkPageContent.getContents());
|
||||
|
||||
return HtmlUtils.replacePlaceholders(FileUtil.getStringFromResource("web/network.html"), placeHolders);
|
||||
return placeholderReplacer.apply(FileUtil.getStringFromResource("web/network.html"));
|
||||
} catch (Exception e) {
|
||||
throw new ParseException(e);
|
||||
}
|
||||
}
|
||||
|
||||
private void uniquePlayers(long now, Database db) {
|
||||
Map<UUID, Map<UUID, List<Session>>> allSessions = db.fetch().getSessionsInLastMonth();
|
||||
Map<UUID, List<Session>> userSessions = AnalysisUtils.sortSessionsByUser(allSessions);
|
||||
|
||||
long dayAgo = now - TimeAmount.DAY.ms();
|
||||
long weekAgo = now - TimeAmount.WEEK.ms();
|
||||
long monthAgo = now - TimeAmount.MONTH.ms();
|
||||
|
||||
addValue("playersUniqueDay", AnalysisUtils.getUniquePlayers(userSessions, dayAgo));
|
||||
addValue("playersUniqueWeek", AnalysisUtils.getUniquePlayers(userSessions, weekAgo));
|
||||
addValue("playersUniqueMonth", AnalysisUtils.getUniquePlayers(userSessions, monthAgo));
|
||||
}
|
||||
|
||||
private void peakTimes(UUID serverUUID, long now, Database db) {
|
||||
Optional<TPS> allTimePeak = db.fetch().getAllTimePeak(serverUUID);
|
||||
Optional<TPS> lastPeak = db.fetch().getPeakPlayerCount(serverUUID, now - TimeAmount.DAY.ms() * 2L);
|
||||
|
||||
if (allTimePeak.isPresent()) {
|
||||
TPS tps = allTimePeak.get();
|
||||
addValue("bestPeakTime", Formatters.year().apply(tps));
|
||||
addValue("playersBestPeak", tps.getPlayers());
|
||||
} else {
|
||||
addValue("bestPeakTime", "No Data");
|
||||
addValue("playersBestPeak", "");
|
||||
}
|
||||
if (lastPeak.isPresent()) {
|
||||
TPS tps = lastPeak.get();
|
||||
addValue("lastPeakTime", Formatters.year().apply(tps));
|
||||
addValue("playersLastPeak", tps.getPlayers());
|
||||
} else {
|
||||
addValue("lastPeakTime", "No Data");
|
||||
addValue("playersLastPeak", "");
|
||||
}
|
||||
}
|
||||
}
|
@ -12,9 +12,11 @@ import com.djrapitops.plan.data.WebUser;
|
||||
import com.djrapitops.plan.data.container.*;
|
||||
import com.djrapitops.plan.data.store.Key;
|
||||
import com.djrapitops.plan.data.store.containers.AnalysisContainer;
|
||||
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.data.store.keys.AnalysisKeys;
|
||||
import com.djrapitops.plan.data.store.keys.NetworkKeys;
|
||||
import com.djrapitops.plan.data.store.keys.PlayerKeys;
|
||||
import com.djrapitops.plan.data.store.keys.ServerKeys;
|
||||
import com.djrapitops.plan.data.store.objects.Nickname;
|
||||
@ -1124,4 +1126,23 @@ public class SQLiteTest {
|
||||
|
||||
assertTrue("Some keys are not supported by AnalysisContainer: AnalysisKeys." + unsupported.toString(), unsupported.isEmpty());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void networkContainerSupportsAllNetworkKeys() throws IllegalAccessException, UnsupportedEncodingException, NoSuchAlgorithmException {
|
||||
serverContainerSupportsAllServerKeys();
|
||||
NetworkContainer networkContainer = db.fetch().getNetworkContainer();
|
||||
|
||||
List<String> unsupported = new ArrayList<>();
|
||||
for (Field field : NetworkKeys.class.getDeclaredFields()) {
|
||||
if (!Modifier.isPublic(field.getModifiers())) {
|
||||
continue;
|
||||
}
|
||||
Key key = (Key) field.get(null);
|
||||
if (!networkContainer.supports(key)) {
|
||||
unsupported.add(field.getName());
|
||||
}
|
||||
}
|
||||
|
||||
assertTrue("Some keys are not supported by NetworkContainer: NetworkKeys." + unsupported.toString(), unsupported.isEmpty());
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user