Refactored SQLFetchOps#get___PlayerContainers to a queries

This commit is contained in:
Rsl1122 2019-01-25 20:42:06 +02:00
parent d4b5731e2e
commit 9e496914b3
7 changed files with 311 additions and 195 deletions

View File

@ -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 <https://www.gnu.org/licenses/>.
*/
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.
* <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.
*
* @author Rsl1122
*/
public class AllPlayerContainersQuery implements Query<List<PlayerContainer>> {
static Map<UUID, PerServerContainer> getPerServerData(
Map<UUID, Map<UUID, List<Session>>> sessions,
Map<UUID, List<UserInfo>> allUserInfo,
Map<UUID, List<Ping>> allPings
) {
Map<UUID, PerServerContainer> perServerContainers = new HashMap<>();
for (Map.Entry<UUID, List<UserInfo>> entry : allUserInfo.entrySet()) {
UUID serverUUID = entry.getKey();
List<UserInfo> serverUserInfo = entry.getValue();
for (UserInfo userInfo : serverUserInfo) {
UUID uuid = userInfo.getUuid();
if (uuid == null) {
continue;
}
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_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<UUID, List<Ping>> 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<PlayerContainer> executeQuery(SQLDB db) {
List<PlayerContainer> containers = new ArrayList<>();
Collection<BaseUser> users = db.query(LargeFetchQueries.fetchAllCommonUserInformation());
Map<UUID, List<GeoInfo>> geoInfo = db.query(LargeFetchQueries.fetchAllGeoInformation());
Map<UUID, List<Ping>> allPings = db.query(LargeFetchQueries.fetchAllPingData());
Map<UUID, List<Nickname>> allNicknames = db.query(LargeFetchQueries.fetchAllNicknameDataByPlayerUUIDs());
Map<UUID, Map<UUID, List<Session>>> sessions = db.query(LargeFetchQueries.fetchAllSessionsWithoutKillOrWorldData());
Map<UUID, List<UserInfo>> allUserInfo = db.query(LargeFetchQueries.fetchPerServerUserInformation());
Map<UUID, PerServerContainer> 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<Session> 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;
}
}

View File

@ -14,16 +14,14 @@
* You should have received a copy of the GNU Lesser General Public License
* along with Plan. If not, see <https://www.gnu.org/licenses/>.
*/
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.
* <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.
*/
public static Query<List<PlayerContainer>> fetchAllPlayerContainers() {
return new AllPlayerContainersQuery();
}
}

View File

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

View File

@ -62,7 +62,7 @@ public class ServerContainerQuery implements Query<ServerContainer> {
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));

View File

@ -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 <https://www.gnu.org/licenses/>.
*/
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.
* <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.
*
* @author Rsl1122
*/
public class ServerPlayerContainersQuery implements Query<List<PlayerContainer>> {
private final UUID serverUUID;
public ServerPlayerContainersQuery(UUID serverUUID) {
this.serverUUID = serverUUID;
}
@Override
public List<PlayerContainer> executeQuery(SQLDB db) {
List<PlayerContainer> containers = new ArrayList<>();
List<UserInfo> serverUserInfo = db.getUserInfoTable().getServerUserInfo(serverUUID); // TODO Optimize and sort out
Map<UUID, Integer> timesKicked = db.getUsersTable().getAllTimesKicked(); // TODO Optimize and sort out
Map<UUID, List<GeoInfo>> geoInfo = db.query(LargeFetchQueries.fetchAllGeoInformation()); // TODO Optimize
Map<UUID, List<Ping>> allPings = db.query(LargeFetchQueries.fetchAllPingData()); // TODO Optimize
Map<UUID, List<Nickname>> allNicknames = db.query(LargeFetchQueries.fetchAllNicknameDataByPlayerUUIDs()); // TODO Optimize
Map<UUID, List<Session>> sessions = db.getSessionsTable().getSessionInfoOfServer(serverUUID);
Map<UUID, Map<UUID, List<Session>>> map = new HashMap<>();
map.put(serverUUID, sessions);
db.getKillsTable().addKillsToSessions(map); // TODO Optimize
db.getWorldTimesTable().addWorldTimesToSessions(map); // TODO Optimize
Map<UUID, List<UserInfo>> serverUserInfos = Collections.singletonMap(serverUUID, serverUserInfo);
Map<UUID, Map<UUID, List<Session>>> serverSessions = Collections.singletonMap(serverUUID, sessions);
Map<UUID, PerServerContainer> 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<Session> 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;
}
}

View File

@ -63,8 +63,6 @@ public interface FetchOperations {
@Deprecated
ServerContainer getServerContainer(UUID serverUUID);
List<PlayerContainer> getPlayerContainers(UUID serverUUID);
/**
* Used to get PlayerContainers of all players on the network, some limitations apply to DataContainer keys.
* <p>

View File

@ -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<PlayerContainer> getPlayerContainers(UUID serverUUID) {
List<PlayerContainer> containers = new ArrayList<>();
List<UserInfo> serverUserInfo = userInfoTable.getServerUserInfo(serverUUID); // TODO Optimize and sort out
Map<UUID, Integer> timesKicked = usersTable.getAllTimesKicked(); // TODO Optimize and sort out
Map<UUID, List<GeoInfo>> geoInfo = db.query(LargeFetchQueries.fetchAllGeoInformation()); // TODO Optimize
Map<UUID, List<Ping>> allPings = db.query(LargeFetchQueries.fetchAllPingData()); // TODO Optimize
Map<UUID, List<Nickname>> allNicknames = db.query(LargeFetchQueries.fetchAllNicknameDataByPlayerUUIDs()); // TODO Optimize
Map<UUID, List<Session>> sessions = sessionsTable.getSessionInfoOfServer(serverUUID);
Map<UUID, Map<UUID, List<Session>>> map = new HashMap<>();
map.put(serverUUID, sessions);
killsTable.addKillsToSessions(map); // TODO Optimize
worldTimesTable.addWorldTimesToSessions(map); // TODO Optimize
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, 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<Session> 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<PlayerContainer> getAllPlayerContainers() {
List<PlayerContainer> containers = new ArrayList<>();
Collection<BaseUser> users = db.query(LargeFetchQueries.fetchAllCommonUserInformation());
Map<UUID, List<GeoInfo>> geoInfo = db.query(LargeFetchQueries.fetchAllGeoInformation());
Map<UUID, List<Ping>> allPings = db.query(LargeFetchQueries.fetchAllPingData());
Map<UUID, List<Nickname>> allNicknames = db.query(LargeFetchQueries.fetchAllNicknameDataByPlayerUUIDs());
Map<UUID, Map<UUID, List<Session>>> sessions = db.query(LargeFetchQueries.fetchAllSessionsWithoutKillOrWorldData());
Map<UUID, List<UserInfo>> allUserInfo = db.query(LargeFetchQueries.fetchPerServerUserInformation());
Map<UUID, PerServerContainer> 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<Session> 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<UUID, PerServerContainer> getPerServerData(
Map<UUID, Map<UUID, List<Session>>> sessions,
Map<UUID, List<UserInfo>> allUserInfo,
Map<UUID, List<Ping>> allPings
) {
Map<UUID, PerServerContainer> perServerContainers = new HashMap<>();
for (Map.Entry<UUID, List<UserInfo>> entry : allUserInfo.entrySet()) {
UUID serverUUID = entry.getKey();
List<UserInfo> serverUserInfo = entry.getValue();
for (UserInfo userInfo : serverUserInfo) {
UUID uuid = userInfo.getUuid();
if (uuid == null) {
continue;
}
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_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<UUID, List<Ping>> 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