From 9e496914b35c7c11eaf92f3060e1e33ae8ebd8af Mon Sep 17 00:00:00 2001 From: Rsl1122 Date: Fri, 25 Jan 2019 20:42:06 +0200 Subject: [PATCH] Refactored SQLFetchOps#get___PlayerContainers to a queries --- .../containers/AllPlayerContainersQuery.java | 161 +++++++++++++++ .../ContainerFetchQueries.java | 21 +- .../containers/NetworkContainerQuery.java | 3 +- .../containers/ServerContainerQuery.java | 2 +- .../ServerPlayerContainersQuery.java | 122 +++++++++++ .../databases/operation/FetchOperations.java | 2 - .../databases/sql/operation/SQLFetchOps.java | 195 +----------------- 7 files changed, 311 insertions(+), 195 deletions(-) create mode 100644 Plan/common/src/main/java/com/djrapitops/plan/db/sql/queries/containers/AllPlayerContainersQuery.java rename Plan/common/src/main/java/com/djrapitops/plan/db/sql/queries/{ => containers}/ContainerFetchQueries.java (76%) create mode 100644 Plan/common/src/main/java/com/djrapitops/plan/db/sql/queries/containers/ServerPlayerContainersQuery.java diff --git a/Plan/common/src/main/java/com/djrapitops/plan/db/sql/queries/containers/AllPlayerContainersQuery.java b/Plan/common/src/main/java/com/djrapitops/plan/db/sql/queries/containers/AllPlayerContainersQuery.java new file mode 100644 index 000000000..d29fd80c4 --- /dev/null +++ b/Plan/common/src/main/java/com/djrapitops/plan/db/sql/queries/containers/AllPlayerContainersQuery.java @@ -0,0 +1,161 @@ +/* + * This file is part of Player Analytics (Plan). + * + * Plan is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License v3 as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Plan is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Plan. If not, see . + */ +package com.djrapitops.plan.db.sql.queries.containers; + +import com.djrapitops.plan.data.container.*; +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.keys.PerServerKeys; +import com.djrapitops.plan.data.store.keys.PlayerKeys; +import com.djrapitops.plan.data.store.mutators.PerServerMutator; +import com.djrapitops.plan.data.store.mutators.SessionsMutator; +import com.djrapitops.plan.data.store.objects.Nickname; +import com.djrapitops.plan.db.SQLDB; +import com.djrapitops.plan.db.access.Query; +import com.djrapitops.plan.db.sql.queries.LargeFetchQueries; + +import java.util.*; + +/** + * Used to get PlayerContainers of all players on the network, some limitations apply to DataContainer keys. + *

+ * 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 + *

+ * Blocking methods are not called until DataContainer getter methods are called. + * + * @author Rsl1122 + */ +public class AllPlayerContainersQuery implements Query> { + + static Map getPerServerData( + Map>> sessions, + Map> allUserInfo, + Map> allPings + ) { + Map perServerContainers = new HashMap<>(); + + for (Map.Entry> entry : allUserInfo.entrySet()) { + UUID serverUUID = entry.getKey(); + List serverUserInfo = entry.getValue(); + + for (UserInfo userInfo : serverUserInfo) { + UUID uuid = userInfo.getUuid(); + if (uuid == null) { + continue; + } + 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>> entry : sessions.entrySet()) { + UUID serverUUID = entry.getKey(); + Map> serverUserSessions = entry.getValue(); + + for (Map.Entry> sessionEntry : serverUserSessions.entrySet()) { + UUID uuid = sessionEntry.getKey(); + PerServerContainer perServerContainer = perServerContainers.getOrDefault(uuid, new PerServerContainer()); + DataContainer container = perServerContainer.getOrDefault(serverUUID, new DataContainer()); + + List 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_DEATHS, () -> SessionsMutator.forContainer(container).toPlayerDeathList()); + 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); + } + } + + for (Map.Entry> entry : allPings.entrySet()) { + UUID uuid = entry.getKey(); + for (Ping ping : entry.getValue()) { + UUID serverUUID = ping.getServerUUID(); + PerServerContainer perServerContainer = perServerContainers.getOrDefault(uuid, new PerServerContainer()); + DataContainer container = perServerContainer.getOrDefault(serverUUID, new DataContainer()); + + if (!container.supports(PerServerKeys.PING)) { + container.putRawData(PerServerKeys.PING, new ArrayList<>()); + } + container.getUnsafe(PerServerKeys.PING).add(ping); + + perServerContainer.put(serverUUID, container); + perServerContainers.put(uuid, perServerContainer); + } + } + + return perServerContainers; + } + + @Override + public List executeQuery(SQLDB db) { + List containers = new ArrayList<>(); + + Collection users = db.query(LargeFetchQueries.fetchAllCommonUserInformation()); + Map> geoInfo = db.query(LargeFetchQueries.fetchAllGeoInformation()); + Map> allPings = db.query(LargeFetchQueries.fetchAllPingData()); + Map> allNicknames = db.query(LargeFetchQueries.fetchAllNicknameDataByPlayerUUIDs()); + + Map>> sessions = db.query(LargeFetchQueries.fetchAllSessionsWithoutKillOrWorldData()); + Map> allUserInfo = db.query(LargeFetchQueries.fetchPerServerUserInformation()); + Map perServerInfo = getPerServerData(sessions, allUserInfo, allPings); + + for (BaseUser baseUser : users) { + PlayerContainer container = new PlayerContainer(); + UUID uuid = baseUser.getUuid(); + container.putRawData(PlayerKeys.UUID, uuid); + + container.putRawData(PlayerKeys.REGISTERED, baseUser.getRegistered()); + container.putRawData(PlayerKeys.NAME, baseUser.getName()); + container.putRawData(PlayerKeys.KICK_COUNT, baseUser.getTimesKicked()); + container.putRawData(PlayerKeys.GEO_INFO, geoInfo.get(uuid)); + container.putRawData(PlayerKeys.PING, allPings.get(uuid)); + container.putRawData(PlayerKeys.NICKNAMES, allNicknames.get(uuid)); + container.putRawData(PlayerKeys.PER_SERVER, perServerInfo.get(uuid)); + + container.putCachingSupplier(PlayerKeys.SESSIONS, () -> { + List playerSessions = PerServerMutator.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; + } +} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/db/sql/queries/ContainerFetchQueries.java b/Plan/common/src/main/java/com/djrapitops/plan/db/sql/queries/containers/ContainerFetchQueries.java similarity index 76% rename from Plan/common/src/main/java/com/djrapitops/plan/db/sql/queries/ContainerFetchQueries.java rename to Plan/common/src/main/java/com/djrapitops/plan/db/sql/queries/containers/ContainerFetchQueries.java index 289ebb418..556ee5ea0 100644 --- a/Plan/common/src/main/java/com/djrapitops/plan/db/sql/queries/ContainerFetchQueries.java +++ b/Plan/common/src/main/java/com/djrapitops/plan/db/sql/queries/containers/ContainerFetchQueries.java @@ -14,16 +14,14 @@ * You should have received a copy of the GNU Lesser General Public License * along with Plan. If not, see . */ -package com.djrapitops.plan.db.sql.queries; +package com.djrapitops.plan.db.sql.queries.containers; 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.db.access.Query; -import com.djrapitops.plan.db.sql.queries.containers.NetworkContainerQuery; -import com.djrapitops.plan.db.sql.queries.containers.PlayerContainerQuery; -import com.djrapitops.plan.db.sql.queries.containers.ServerContainerQuery; +import java.util.List; import java.util.UUID; /** @@ -71,4 +69,19 @@ public class ContainerFetchQueries { return new PlayerContainerQuery(playerUUID); } + /** + * Used to get PlayerContainers of all players on the network, some limitations apply to DataContainer keys. + *

+ * 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 + *

+ * Blocking methods are not called until DataContainer getter methods are called. + * + * @return a list of PlayerContainers in Plan database. + */ + public static Query> fetchAllPlayerContainers() { + return new AllPlayerContainersQuery(); + } + } \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/db/sql/queries/containers/NetworkContainerQuery.java b/Plan/common/src/main/java/com/djrapitops/plan/db/sql/queries/containers/NetworkContainerQuery.java index 96655181e..da703a1f7 100644 --- a/Plan/common/src/main/java/com/djrapitops/plan/db/sql/queries/containers/NetworkContainerQuery.java +++ b/Plan/common/src/main/java/com/djrapitops/plan/db/sql/queries/containers/NetworkContainerQuery.java @@ -22,7 +22,6 @@ import com.djrapitops.plan.data.store.keys.NetworkKeys; import com.djrapitops.plan.data.store.keys.ServerKeys; import com.djrapitops.plan.db.SQLDB; import com.djrapitops.plan.db.access.Query; -import com.djrapitops.plan.db.sql.queries.ContainerFetchQueries; import com.djrapitops.plan.db.sql.queries.LargeFetchQueries; import com.djrapitops.plan.db.sql.queries.OptionalFetchQueries; import com.djrapitops.plan.system.info.server.Server; @@ -56,7 +55,7 @@ public class NetworkContainerQuery implements Query { UUID serverUUID = proxyInformation.get().getUuid(); ServerContainer container = db.query(ContainerFetchQueries.fetchServerContainer(serverUUID)); - container.putCachingSupplier(ServerKeys.PLAYERS, db.fetch()::getAllPlayerContainers); + container.putCachingSupplier(ServerKeys.PLAYERS, () -> db.query(ContainerFetchQueries.fetchAllPlayerContainers())); container.putCachingSupplier(ServerKeys.TPS, db.getTpsTable()::getNetworkOnlineData); container.putSupplier(ServerKeys.WORLD_TIMES, null); // Additional Session information not supported container.putSupplier(ServerKeys.PLAYER_KILLS, null); diff --git a/Plan/common/src/main/java/com/djrapitops/plan/db/sql/queries/containers/ServerContainerQuery.java b/Plan/common/src/main/java/com/djrapitops/plan/db/sql/queries/containers/ServerContainerQuery.java index ef91f421f..d526f5f0e 100644 --- a/Plan/common/src/main/java/com/djrapitops/plan/db/sql/queries/containers/ServerContainerQuery.java +++ b/Plan/common/src/main/java/com/djrapitops/plan/db/sql/queries/containers/ServerContainerQuery.java @@ -62,7 +62,7 @@ public class ServerContainerQuery implements Query { container.putRawData(ServerKeys.SERVER_UUID, serverUUID); container.putRawData(ServerKeys.NAME, serverInfo.get().getName()); - container.putCachingSupplier(ServerKeys.PLAYERS, () -> db.fetch().getPlayerContainers(serverUUID)); + container.putCachingSupplier(ServerKeys.PLAYERS, () -> db.query(new ServerPlayerContainersQuery(serverUUID))); container.putSupplier(ServerKeys.PLAYER_COUNT, () -> container.getUnsafe(ServerKeys.PLAYERS).size()); container.putCachingSupplier(ServerKeys.TPS, () -> db.getTpsTable().getTPSData(serverUUID)); diff --git a/Plan/common/src/main/java/com/djrapitops/plan/db/sql/queries/containers/ServerPlayerContainersQuery.java b/Plan/common/src/main/java/com/djrapitops/plan/db/sql/queries/containers/ServerPlayerContainersQuery.java new file mode 100644 index 000000000..575758397 --- /dev/null +++ b/Plan/common/src/main/java/com/djrapitops/plan/db/sql/queries/containers/ServerPlayerContainersQuery.java @@ -0,0 +1,122 @@ +/* + * This file is part of Player Analytics (Plan). + * + * Plan is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License v3 as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Plan is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Plan. If not, see . + */ +package com.djrapitops.plan.db.sql.queries.containers; + +import com.djrapitops.plan.data.container.GeoInfo; +import com.djrapitops.plan.data.container.Ping; +import com.djrapitops.plan.data.container.Session; +import com.djrapitops.plan.data.container.UserInfo; +import com.djrapitops.plan.data.store.containers.PerServerContainer; +import com.djrapitops.plan.data.store.containers.PlayerContainer; +import com.djrapitops.plan.data.store.keys.PlayerKeys; +import com.djrapitops.plan.data.store.keys.SessionKeys; +import com.djrapitops.plan.data.store.mutators.PerServerMutator; +import com.djrapitops.plan.data.store.mutators.SessionsMutator; +import com.djrapitops.plan.data.store.objects.Nickname; +import com.djrapitops.plan.data.time.WorldTimes; +import com.djrapitops.plan.db.SQLDB; +import com.djrapitops.plan.db.access.Query; +import com.djrapitops.plan.db.sql.queries.LargeFetchQueries; + +import java.util.*; + +/** + * Used to get PlayerContainers of all players on a server, some limitations apply to DataContainer keys. + *

+ * 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 + *

+ * Blocking methods are not called until DataContainer getter methods are called. + * + * @author Rsl1122 + */ +public class ServerPlayerContainersQuery implements Query> { + + private final UUID serverUUID; + + public ServerPlayerContainersQuery(UUID serverUUID) { + this.serverUUID = serverUUID; + } + + @Override + public List executeQuery(SQLDB db) { + List containers = new ArrayList<>(); + + List serverUserInfo = db.getUserInfoTable().getServerUserInfo(serverUUID); // TODO Optimize and sort out + Map timesKicked = db.getUsersTable().getAllTimesKicked(); // TODO Optimize and sort out + Map> geoInfo = db.query(LargeFetchQueries.fetchAllGeoInformation()); // TODO Optimize + Map> allPings = db.query(LargeFetchQueries.fetchAllPingData()); // TODO Optimize + Map> allNicknames = db.query(LargeFetchQueries.fetchAllNicknameDataByPlayerUUIDs()); // TODO Optimize + + Map> sessions = db.getSessionsTable().getSessionInfoOfServer(serverUUID); + Map>> map = new HashMap<>(); + map.put(serverUUID, sessions); + db.getKillsTable().addKillsToSessions(map); // TODO Optimize + db.getWorldTimesTable().addWorldTimesToSessions(map); // TODO Optimize + + Map> serverUserInfos = Collections.singletonMap(serverUUID, serverUserInfo); + Map>> serverSessions = Collections.singletonMap(serverUUID, sessions); + Map perServerInfo = AllPlayerContainersQuery.getPerServerData( + serverSessions, serverUserInfos, allPings + ); + + 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.putRawData(PlayerKeys.GEO_INFO, geoInfo.get(uuid)); + container.putRawData(PlayerKeys.PING, allPings.get(uuid)); + container.putRawData(PlayerKeys.NICKNAMES, allNicknames.get(uuid)); + container.putRawData(PlayerKeys.PER_SERVER, perServerInfo.get(uuid)); + + container.putRawData(PlayerKeys.BANNED, userInfo.isBanned()); + container.putRawData(PlayerKeys.OPERATOR, userInfo.isOperator()); + + container.putCachingSupplier(PlayerKeys.SESSIONS, () -> { + List playerSessions = sessions.getOrDefault(uuid, new ArrayList<>()); + container.getValue(PlayerKeys.ACTIVE_SESSION).ifPresent(playerSessions::add); + return playerSessions; + } + ); + + // Calculating getters + container.putCachingSupplier(PlayerKeys.WORLD_TIMES, () -> { + WorldTimes worldTimes = new PerServerMutator(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; + } +} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/system/database/databases/operation/FetchOperations.java b/Plan/common/src/main/java/com/djrapitops/plan/system/database/databases/operation/FetchOperations.java index 518386b58..0df76caf1 100644 --- a/Plan/common/src/main/java/com/djrapitops/plan/system/database/databases/operation/FetchOperations.java +++ b/Plan/common/src/main/java/com/djrapitops/plan/system/database/databases/operation/FetchOperations.java @@ -63,8 +63,6 @@ public interface FetchOperations { @Deprecated ServerContainer getServerContainer(UUID serverUUID); - List getPlayerContainers(UUID serverUUID); - /** * Used to get PlayerContainers of all players on the network, some limitations apply to DataContainer keys. *

diff --git a/Plan/common/src/main/java/com/djrapitops/plan/system/database/databases/sql/operation/SQLFetchOps.java b/Plan/common/src/main/java/com/djrapitops/plan/system/database/databases/sql/operation/SQLFetchOps.java index 879a69546..6fbce0acb 100644 --- a/Plan/common/src/main/java/com/djrapitops/plan/system/database/databases/sql/operation/SQLFetchOps.java +++ b/Plan/common/src/main/java/com/djrapitops/plan/system/database/databases/sql/operation/SQLFetchOps.java @@ -17,19 +17,17 @@ package com.djrapitops.plan.system.database.databases.sql.operation; import com.djrapitops.plan.data.WebUser; -import com.djrapitops.plan.data.container.*; -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.SessionKeys; -import com.djrapitops.plan.data.store.mutators.PerServerMutator; -import com.djrapitops.plan.data.store.mutators.SessionsMutator; -import com.djrapitops.plan.data.store.objects.Nickname; -import com.djrapitops.plan.data.time.WorldTimes; +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.db.SQLDB; -import com.djrapitops.plan.db.sql.queries.ContainerFetchQueries; import com.djrapitops.plan.db.sql.queries.LargeFetchQueries; import com.djrapitops.plan.db.sql.queries.OptionalFetchQueries; +import com.djrapitops.plan.db.sql.queries.containers.ContainerFetchQueries; import com.djrapitops.plan.system.database.databases.operation.FetchOperations; import com.djrapitops.plan.system.info.server.Server; import com.djrapitops.plan.system.settings.config.Config; @@ -53,184 +51,9 @@ public class SQLFetchOps extends SQLOps implements FetchOperations { return db.query(ContainerFetchQueries.fetchServerContainer(serverUUID)); } - @Override - public List getPlayerContainers(UUID serverUUID) { - List containers = new ArrayList<>(); - - List serverUserInfo = userInfoTable.getServerUserInfo(serverUUID); // TODO Optimize and sort out - Map timesKicked = usersTable.getAllTimesKicked(); // TODO Optimize and sort out - Map> geoInfo = db.query(LargeFetchQueries.fetchAllGeoInformation()); // TODO Optimize - Map> allPings = db.query(LargeFetchQueries.fetchAllPingData()); // TODO Optimize - Map> allNicknames = db.query(LargeFetchQueries.fetchAllNicknameDataByPlayerUUIDs()); // TODO Optimize - - Map> sessions = sessionsTable.getSessionInfoOfServer(serverUUID); - Map>> map = new HashMap<>(); - map.put(serverUUID, sessions); - killsTable.addKillsToSessions(map); // TODO Optimize - worldTimesTable.addWorldTimesToSessions(map); // TODO Optimize - - Map> serverUserInfos = Collections.singletonMap(serverUUID, serverUserInfo); - Map>> serverSessions = Collections.singletonMap(serverUUID, sessions); - Map perServerInfo = getPerServerData(serverSessions, serverUserInfos, allPings); - - 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.putRawData(PlayerKeys.GEO_INFO, geoInfo.get(uuid)); - container.putRawData(PlayerKeys.PING, allPings.get(uuid)); - container.putRawData(PlayerKeys.NICKNAMES, allNicknames.get(uuid)); - container.putRawData(PlayerKeys.PER_SERVER, perServerInfo.get(uuid)); - - container.putRawData(PlayerKeys.BANNED, userInfo.isBanned()); - container.putRawData(PlayerKeys.OPERATOR, userInfo.isOperator()); - - container.putCachingSupplier(PlayerKeys.SESSIONS, () -> { - List playerSessions = sessions.getOrDefault(uuid, new ArrayList<>()); - container.getValue(PlayerKeys.ACTIVE_SESSION).ifPresent(playerSessions::add); - return playerSessions; - } - ); - - // Calculating getters - container.putCachingSupplier(PlayerKeys.WORLD_TIMES, () -> { - WorldTimes worldTimes = new PerServerMutator(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 getAllPlayerContainers() { - List containers = new ArrayList<>(); - - Collection users = db.query(LargeFetchQueries.fetchAllCommonUserInformation()); - Map> geoInfo = db.query(LargeFetchQueries.fetchAllGeoInformation()); - Map> allPings = db.query(LargeFetchQueries.fetchAllPingData()); - Map> allNicknames = db.query(LargeFetchQueries.fetchAllNicknameDataByPlayerUUIDs()); - - Map>> sessions = db.query(LargeFetchQueries.fetchAllSessionsWithoutKillOrWorldData()); - Map> allUserInfo = db.query(LargeFetchQueries.fetchPerServerUserInformation()); - Map perServerInfo = getPerServerData(sessions, allUserInfo, allPings); - - for (BaseUser baseUser : users) { - PlayerContainer container = new PlayerContainer(); - UUID uuid = baseUser.getUuid(); - container.putRawData(PlayerKeys.UUID, uuid); - - container.putRawData(PlayerKeys.REGISTERED, baseUser.getRegistered()); - container.putRawData(PlayerKeys.NAME, baseUser.getName()); - container.putRawData(PlayerKeys.KICK_COUNT, baseUser.getTimesKicked()); - container.putRawData(PlayerKeys.GEO_INFO, geoInfo.get(uuid)); - container.putRawData(PlayerKeys.PING, allPings.get(uuid)); - container.putRawData(PlayerKeys.NICKNAMES, allNicknames.get(uuid)); - container.putRawData(PlayerKeys.PER_SERVER, perServerInfo.get(uuid)); - - container.putCachingSupplier(PlayerKeys.SESSIONS, () -> { - List playerSessions = PerServerMutator.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 getPerServerData( - Map>> sessions, - Map> allUserInfo, - Map> allPings - ) { - Map perServerContainers = new HashMap<>(); - - for (Map.Entry> entry : allUserInfo.entrySet()) { - UUID serverUUID = entry.getKey(); - List serverUserInfo = entry.getValue(); - - for (UserInfo userInfo : serverUserInfo) { - UUID uuid = userInfo.getUuid(); - if (uuid == null) { - continue; - } - 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>> entry : sessions.entrySet()) { - UUID serverUUID = entry.getKey(); - Map> serverUserSessions = entry.getValue(); - - for (Map.Entry> sessionEntry : serverUserSessions.entrySet()) { - UUID uuid = sessionEntry.getKey(); - PerServerContainer perServerContainer = perServerContainers.getOrDefault(uuid, new PerServerContainer()); - DataContainer container = perServerContainer.getOrDefault(serverUUID, new DataContainer()); - - List 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_DEATHS, () -> SessionsMutator.forContainer(container).toPlayerDeathList()); - 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); - } - } - - for (Map.Entry> entry : allPings.entrySet()) { - UUID uuid = entry.getKey(); - for (Ping ping : entry.getValue()) { - UUID serverUUID = ping.getServerUUID(); - PerServerContainer perServerContainer = perServerContainers.getOrDefault(uuid, new PerServerContainer()); - DataContainer container = perServerContainer.getOrDefault(serverUUID, new DataContainer()); - - if (!container.supports(PerServerKeys.PING)) { - container.putRawData(PerServerKeys.PING, new ArrayList<>()); - } - container.getUnsafe(PerServerKeys.PING).add(ping); - - perServerContainer.put(serverUUID, container); - perServerContainers.put(uuid, perServerContainer); - } - } - - return perServerContainers; + return db.query(ContainerFetchQueries.fetchAllPlayerContainers()); } @Override