diff --git a/Plan/src/main/java/com/djrapitops/plan/data/store/containers/AnalysisContainer.java b/Plan/src/main/java/com/djrapitops/plan/data/store/containers/AnalysisContainer.java index 0441a3bb6..99f03cd5f 100644 --- a/Plan/src/main/java/com/djrapitops/plan/data/store/containers/AnalysisContainer.java +++ b/Plan/src/main/java/com/djrapitops/plan/data/store/containers/AnalysisContainer.java @@ -6,6 +6,7 @@ import com.djrapitops.plan.data.store.keys.AnalysisKeys; import com.djrapitops.plan.data.store.keys.PlayerKeys; import com.djrapitops.plan.data.store.keys.ServerKeys; import com.djrapitops.plan.data.store.mutators.CommandUseMutator; +import com.djrapitops.plan.data.store.mutators.PlayersMutator; import com.djrapitops.plan.data.store.mutators.SessionsMutator; import com.djrapitops.plan.data.store.mutators.TPSMutator; import com.djrapitops.plan.data.store.mutators.formatting.Formatters; @@ -17,7 +18,12 @@ 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.utilities.MiscUtils; +import com.djrapitops.plan.utilities.html.graphs.ActivityStackGraph; +import com.djrapitops.plan.utilities.html.graphs.PunchCardGraph; +import com.djrapitops.plan.utilities.html.graphs.WorldMap; +import com.djrapitops.plan.utilities.html.graphs.calendar.ServerCalendar; import com.djrapitops.plan.utilities.html.graphs.line.*; +import com.djrapitops.plan.utilities.html.graphs.pie.ActivityPie; import com.djrapitops.plan.utilities.html.graphs.pie.WorldPie; import com.djrapitops.plan.utilities.html.structure.RecentLoginList; import com.djrapitops.plan.utilities.html.structure.SessionAccordion; @@ -51,6 +57,7 @@ public class AnalysisContainer extends DataContainer { private void addAnalysisSuppliers() { putSupplier(AnalysisKeys.SESSIONS_MUTATOR, () -> SessionsMutator.forContainer(serverContainer)); putSupplier(AnalysisKeys.TPS_MUTATOR, () -> TPSMutator.forContainer(serverContainer)); + putSupplier(AnalysisKeys.PLAYERS_MUTATOR, () -> PlayersMutator.forContainer(serverContainer)); addConstants(); addPlayerSuppliers(); @@ -123,7 +130,7 @@ public class AnalysisContainer extends DataContainer { ); putSupplier(AnalysisKeys.OPERATORS, () -> serverContainer.getValue(ServerKeys.OPERATORS).map(List::size).orElse(0)); putSupplier(AnalysisKeys.PLAYERS_TABLE, () -> - PlayersTable.forServerPage(serverContainer.getValue(ServerKeys.PLAYERS).orElse(new ArrayList<>())).parseHtml() + PlayersTable.forServerPage(getUnsafe(AnalysisKeys.PLAYERS_MUTATOR).all()).parseHtml() ); } @@ -160,6 +167,13 @@ public class AnalysisContainer extends DataContainer { putSupplier(AnalysisKeys.AVERAGE_SESSION_LENGTH_F, () -> Formatters.timeAmount() .apply(getUnsafe(AnalysisKeys.SESSIONS_MUTATOR).toAverageSessionLength()) ); + putSupplier(AnalysisKeys.PUNCHCARD_SERIES, () -> new PunchCardGraph( + SessionsMutator.copyOf(getUnsafe(AnalysisKeys.SESSIONS_MUTATOR) + .filterSessionsBetween( + getUnsafe(AnalysisKeys.ANALYSIS_TIME_MONTH_AGO), + getUnsafe(AnalysisKeys.ANALYSIS_TIME)) + ).all()).toHighChartsSeries() + ); } private void addGraphSuppliers() { @@ -175,6 +189,19 @@ public class AnalysisContainer extends DataContainer { putSupplier(AnalysisKeys.RAM_SERIES, () -> new RamGraph(getUnsafe(AnalysisKeys.TPS_MUTATOR)).toHighChartsSeries()); putSupplier(AnalysisKeys.ENTITY_SERIES, () -> new EntityGraph(getUnsafe(AnalysisKeys.TPS_MUTATOR)).toHighChartsSeries()); putSupplier(AnalysisKeys.CHUNK_SERIES, () -> new ChunkGraph(getUnsafe(AnalysisKeys.TPS_MUTATOR)).toHighChartsSeries()); + putSupplier(AnalysisKeys.WORLD_MAP_SERIES, () -> + new WorldMap(getUnsafe(AnalysisKeys.PLAYERS_MUTATOR).getGeolocations()).toHighChartsSeries() + ); + putSupplier(AnalysisKeys.CALENDAR_SERIES, () -> new ServerCalendar(getUnsafe(AnalysisKeys.PLAYERS_MUTATOR)).toCalendarSeries()); + + putSupplier(AnalysisKeys.ACTIVITY_DATA, () -> getUnsafe(AnalysisKeys.PLAYERS_MUTATOR).toActivityDataMap(getUnsafe(AnalysisKeys.ANALYSIS_TIME))); + Key activityStackGraph = new Key<>(ActivityStackGraph.class, "ACTIVITY_STACK_GRAPH"); + putSupplier(activityStackGraph, () -> new ActivityStackGraph(getUnsafe(AnalysisKeys.ACTIVITY_DATA))); + putSupplier(AnalysisKeys.ACTIVITY_STACK_CATEGORIES, () -> getUnsafe(activityStackGraph).toHighChartsLabels()); + putSupplier(AnalysisKeys.ACTIVITY_STACK_SERIES, () -> getUnsafe(activityStackGraph).toHighChartsSeries()); + putSupplier(AnalysisKeys.ACTIVITY_PIE_SERIES, () -> + new ActivityPie(getUnsafe(AnalysisKeys.ACTIVITY_DATA).get(getUnsafe(AnalysisKeys.ANALYSIS_TIME))).toHighChartsSeries() + ); } private void addTPSAverageSuppliers() { diff --git a/Plan/src/main/java/com/djrapitops/plan/data/store/keys/AnalysisKeys.java b/Plan/src/main/java/com/djrapitops/plan/data/store/keys/AnalysisKeys.java index bdbea77b5..334aede97 100644 --- a/Plan/src/main/java/com/djrapitops/plan/data/store/keys/AnalysisKeys.java +++ b/Plan/src/main/java/com/djrapitops/plan/data/store/keys/AnalysisKeys.java @@ -3,11 +3,14 @@ package com.djrapitops.plan.data.store.keys; import com.djrapitops.plan.data.store.Key; import com.djrapitops.plan.data.store.PlaceholderKey; import com.djrapitops.plan.data.store.Type; +import com.djrapitops.plan.data.store.mutators.PlayersMutator; import com.djrapitops.plan.data.store.mutators.SessionsMutator; import com.djrapitops.plan.data.store.mutators.TPSMutator; import com.djrapitops.plan.utilities.html.structure.SessionAccordion; import java.util.Map; +import java.util.Set; +import java.util.TreeMap; import java.util.UUID; /** @@ -127,6 +130,7 @@ public class AnalysisKeys { // Variables used only during analysis public static final Key SESSIONS_MUTATOR = new Key<>(SessionsMutator.class, "SESSIONS_MUTATOR"); public static final Key TPS_MUTATOR = new Key<>(TPSMutator.class, "TPS_MUTATOR"); + public static final Key PLAYERS_MUTATOR = new Key<>(PlayersMutator.class, "PLAYERS_MUTATOR"); public static final Key PLAYTIME_TOTAL = new Key<>(Long.class, "PLAYTIME_TOTAL"); public static final Key ANALYSIS_TIME = new Key<>(Long.class, "ANALYSIS_TIME"); public static final Key ANALYSIS_TIME_DAY_AGO = new Key<>(Long.class, "ANALYSIS_TIME_DAY_AGO"); @@ -134,6 +138,7 @@ public class AnalysisKeys { public static final Key ANALYSIS_TIME_MONTH_AGO = new Key<>(Long.class, "ANALYSIS_TIME_MONTH_AGO"); public static final Key SESSION_ACCORDION = new Key<>(SessionAccordion.class, "SESSION_ACCORDION"); public static final Key> PLAYER_NAMES = new Key<>(new Type>() {}, "PLAYER_NAMES"); + public static final Key>>> ACTIVITY_DATA = new Key<>(new Type>>>() {}, "ACTIVITY_DATA"); private AnalysisKeys() { /* Static variable class */ diff --git a/Plan/src/main/java/com/djrapitops/plan/data/store/mutators/PlayersMutator.java b/Plan/src/main/java/com/djrapitops/plan/data/store/mutators/PlayersMutator.java new file mode 100644 index 000000000..2aaca2717 --- /dev/null +++ b/Plan/src/main/java/com/djrapitops/plan/data/store/mutators/PlayersMutator.java @@ -0,0 +1,67 @@ +package com.djrapitops.plan.data.store.mutators; + +import com.djrapitops.plan.data.calculation.ActivityIndex; +import com.djrapitops.plan.data.container.GeoInfo; +import com.djrapitops.plan.data.store.containers.DataContainer; +import com.djrapitops.plan.data.store.containers.PlayerContainer; +import com.djrapitops.plan.data.store.keys.PlayerKeys; +import com.djrapitops.plan.data.store.keys.ServerKeys; +import com.djrapitops.plugin.api.TimeAmount; + +import java.util.*; + +/** + * Mutator for a bunch of {@link com.djrapitops.plan.data.store.containers.PlayerContainer}s. + * + * @author Rsl1122 + */ +public class PlayersMutator { + + private List players; + + public PlayersMutator(List players) { + this.players = players; + } + + public static PlayersMutator copyOf(PlayersMutator mutator) { + return new PlayersMutator(new ArrayList<>(mutator.players)); + } + + public static PlayersMutator forContainer(DataContainer container) { + return new PlayersMutator(container.getValue(ServerKeys.PLAYERS).orElse(new ArrayList<>())); + } + + public List all() { + return players; + } + + public List getGeolocations() { + List geolocations = new ArrayList<>(); + + for (PlayerContainer player : players) { + Optional mostRecent = GeoInfoMutator.forContainer(player).mostRecent(); + mostRecent.ifPresent(geoInfo -> geolocations.add(geoInfo.getGeolocation())); + } + + return geolocations; + } + + public TreeMap>> toActivityDataMap(long date) { + TreeMap>> activityData = new TreeMap<>(); + if (!players.isEmpty()) { + for (PlayerContainer player : players) { + for (long time = date; time >= time - TimeAmount.MONTH.ms() * 2L; time -= TimeAmount.WEEK.ms()) { + ActivityIndex activityIndex = new ActivityIndex(player, time); + String activityGroup = activityIndex.getGroup(); + + Map> map = activityData.getOrDefault(time, new HashMap<>()); + Set uuids = map.getOrDefault(activityGroup, new HashSet<>()); + uuids.add(player.getUnsafe(PlayerKeys.UUID)); + map.put(activityGroup, uuids); + activityData.put(time, map); + } + } + } + return activityData; + } +} \ No newline at end of file diff --git a/Plan/src/main/java/com/djrapitops/plan/data/store/mutators/formatting/PlaceholderReplacer.java b/Plan/src/main/java/com/djrapitops/plan/data/store/mutators/formatting/PlaceholderReplacer.java index e409c0c8a..cb7618854 100644 --- a/Plan/src/main/java/com/djrapitops/plan/data/store/mutators/formatting/PlaceholderReplacer.java +++ b/Plan/src/main/java/com/djrapitops/plan/data/store/mutators/formatting/PlaceholderReplacer.java @@ -14,16 +14,16 @@ import java.util.HashMap; */ public class PlaceholderReplacer extends HashMap implements Formatter { - public void addPlaceholder(DataContainer container, PlaceholderKey key) { + public void addPlaceholderFrom(DataContainer container, PlaceholderKey key) { if (!container.supports(key)) { return; } put(key.getPlaceholder(), container.get(key).get().toString()); } - public void addAllPlaceholders(DataContainer container, PlaceholderKey... keys) { + public void addAllPlaceholdersFrom(DataContainer container, PlaceholderKey... keys) { for (PlaceholderKey key : keys) { - addPlaceholder(container, key); + addPlaceholderFrom(container, key); } } diff --git a/Plan/src/main/java/com/djrapitops/plan/system/database/databases/operation/FetchOperations.java b/Plan/src/main/java/com/djrapitops/plan/system/database/databases/operation/FetchOperations.java index 555bd03a7..40f74eb32 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/database/databases/operation/FetchOperations.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/database/databases/operation/FetchOperations.java @@ -5,6 +5,7 @@ import com.djrapitops.plan.data.ServerProfile; import com.djrapitops.plan.data.WebUser; import com.djrapitops.plan.data.container.*; import com.djrapitops.plan.data.store.containers.PlayerContainer; +import com.djrapitops.plan.data.store.containers.ServerContainer; import com.djrapitops.plan.system.info.server.Server; import java.util.*; @@ -13,6 +14,8 @@ public interface FetchOperations { // Profiles + ServerContainer getServerContainer(UUID serverUUID); + ServerProfile getServerProfile(UUID serverUUID); List getPlayers(UUID serverUUID); diff --git a/Plan/src/main/java/com/djrapitops/plan/system/database/databases/sql/operation/SQLFetchOps.java b/Plan/src/main/java/com/djrapitops/plan/system/database/databases/sql/operation/SQLFetchOps.java index 5214007d1..dcfec59d8 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/database/databases/sql/operation/SQLFetchOps.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/database/databases/sql/operation/SQLFetchOps.java @@ -29,6 +29,7 @@ public class SQLFetchOps extends SQLOps implements FetchOperations { super(db); } + @Override public ServerContainer getServerContainer(UUID serverUUID) { ServerContainer container = new ServerContainer(); diff --git a/Plan/src/main/java/com/djrapitops/plan/system/info/request/GenerateAnalysisPageRequest.java b/Plan/src/main/java/com/djrapitops/plan/system/info/request/GenerateAnalysisPageRequest.java index 3116a8e8a..e7fbc0273 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/info/request/GenerateAnalysisPageRequest.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/info/request/GenerateAnalysisPageRequest.java @@ -7,23 +7,20 @@ package com.djrapitops.plan.system.info.request; import com.djrapitops.plan.api.exceptions.connection.BadRequestException; import com.djrapitops.plan.api.exceptions.connection.InternalErrorException; import com.djrapitops.plan.api.exceptions.connection.WebException; -import com.djrapitops.plan.api.exceptions.database.DBException; -import com.djrapitops.plan.data.calculation.AnalysisData; -import com.djrapitops.plan.system.cache.DataCache; +import com.djrapitops.plan.api.exceptions.database.DBOpException; +import com.djrapitops.plan.data.store.containers.AnalysisContainer; 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.webserver.pages.parsing.AnalysisPage; import com.djrapitops.plan.system.webserver.response.DefaultResponses; import com.djrapitops.plan.system.webserver.response.Response; -import com.djrapitops.plan.system.webserver.response.errors.InternalErrorResponse; import com.djrapitops.plan.utilities.analysis.Analysis; import com.djrapitops.plugin.api.utility.log.Log; import com.djrapitops.plugin.utilities.Verify; import java.util.Map; import java.util.UUID; -import java.util.concurrent.ExecutionException; /** * InfoRequest to generate Analysis page HTML at the receiving end. @@ -78,18 +75,14 @@ public class GenerateAnalysisPageRequest extends InfoRequestWithVariables implem try { UUID serverUUID = ServerInfo.getServerUUID(); Database db = Database.getActive(); - DataCache dataCache = DataCache.getInstance(); - AnalysisData analysisData = Analysis.runAnalysisFor(serverUUID, db, dataCache); - return new AnalysisPage(analysisData).toHtml(); - } catch (DBException e) { + AnalysisContainer analysisContainer = new AnalysisContainer(db.fetch().getServerContainer(serverUUID)); + return new AnalysisPage(analysisContainer).toHtml(); + } catch (DBOpException e) { if (!e.getCause().getMessage().contains("Connection is closed")) { Log.toLog(this.getClass(), e); } throw new InternalErrorException("Analysis failed due to exception", e); - } catch (InterruptedException | ExecutionException e) { - /* Plugin is shutting down, exceptions ignored */ - return new InternalErrorResponse("Plugin may be shutting down", e).getContent(); } catch (Exception e) { Log.toLog(this.getClass(), e); throw new InternalErrorException("Analysis failed due to exception", e); diff --git a/Plan/src/main/java/com/djrapitops/plan/system/webserver/pages/parsing/AnalysisPage.java b/Plan/src/main/java/com/djrapitops/plan/system/webserver/pages/parsing/AnalysisPage.java index 74058108d..8a0136748 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/webserver/pages/parsing/AnalysisPage.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/webserver/pages/parsing/AnalysisPage.java @@ -5,10 +5,10 @@ package com.djrapitops.plan.system.webserver.pages.parsing; import com.djrapitops.plan.api.exceptions.ParseException; -import com.djrapitops.plan.data.calculation.AnalysisData; +import com.djrapitops.plan.data.store.containers.AnalysisContainer; +import com.djrapitops.plan.data.store.mutators.formatting.PlaceholderReplacer; import com.djrapitops.plan.system.webserver.response.errors.ErrorResponse; import com.djrapitops.plan.utilities.file.FileUtil; -import com.djrapitops.plan.utilities.html.HtmlUtils; import java.io.IOException; @@ -19,10 +19,10 @@ import java.io.IOException; */ public class AnalysisPage extends Page { - private final AnalysisData data; + private final AnalysisContainer analysisContainer; - public AnalysisPage(AnalysisData analysisData) { - this.data = analysisData; + public AnalysisPage(AnalysisContainer analysisContainer) { + this.analysisContainer = analysisContainer; } public static String getRefreshingHtml() { @@ -35,10 +35,52 @@ public class AnalysisPage extends Page { @Override public String toHtml() throws ParseException { - addValues(data.getReplaceMap()); + PlaceholderReplacer placeholderReplacer = new PlaceholderReplacer(); +// placeholderReplacer.addAllPlaceholdersFrom(analysisContainer, +// VERSION, SERVER_NAME, TIME_ZONE, +// FIRST_DAY, TPS_MEDIUM, TPS_HIGH, +// PLAYERS_MAX, PLAYERS_ONLINE, PLAYERS_TOTAL, +// +// WORLD_PIE_COLORS, GM_PIE_COLORS, ACTIVITY_PIE_COLORS, +// PLAYERS_GRAPH_COLOR, TPS_HIGH_COLOR, TPS_MEDIUM_COLOR, +// TPS_LOW_COLOR, WORLD_MAP_HIGH_COLOR, WORLD_MAP_LOW_COLOR, +// +// PLAYERS_TABLE, SESSION_ACCORDION_HTML, SESSION_ACCORDION_FUNCTIONS, +// SESSION_TABLE, RECENT_LOGINS, COMMAND_USAGE_TABLE, +// HEALTH_NOTES, PLUGINS_TAB, PLUGINS_TAB_NAV, +// +// REFRESH_TIME_F, LAST_PEAK_TIME_F, ALL_TIME_PEAK_TIME_F, +// AVERAGE_SESSION_LENGTH_F, AVERAGE_PLAYTIME_F, PLAYTIME_F, +// +// PLAYERS_LAST_PEAK, PLAYERS_ALL_TIME_PEAK, OPERATORS, +// PLAYERS_REGULAR, SESSION_COUNT, DEATHS, +// MOB_KILL_COUNT, PLAYER_KILL_COUNT, HEALTH_INDEX, +// COMMAND_COUNT, COMMAND_COUNT_UNIQUE, +// +// PLAYERS_DAY, PLAYERS_WEEK, PLAYERS_MONTH, +// PLAYERS_NEW_DAY, PLAYERS_NEW_WEEK, PLAYERS_NEW_MONTH, +// AVG_PLAYERS, AVG_PLAYERS_DAY, AVG_PLAYERS_WEEK, +// AVG_PLAYERS_MONTH, AVG_PLAYERS_NEW, AVG_PLAYERS_NEW_DAY, +// AVG_PLAYERS_NEW_WEEK, AVG_PLAYERS_NEW_MONTH, PLAYERS_STUCK_DAY, +// PLAYERS_STUCK_DAY_PERC, PLAYERS_STUCK_WEEK, PLAYERS_STUCK_WEEK_PERC, +// PLAYERS_STUCK_MONTH, PLAYERS_STUCK_MONTH_PERC, +// +// TPS_SPIKE_MONTH, TPS_SPIKE_WEEK, TPS_SPIKE_DAY, +// AVG_TPS_MONTH, AVG_TPS_WEEK, AVG_TPS_DAY, +// AVG_CPU_MONTH, AVG_CPU_WEEK, AVG_CPU_DAY, +// AVG_RAM_MONTH, AVG_RAM_WEEK, AVG_RAM_DAY, +// AVG_ENTITY_MONTH, AVG_ENTITY_WEEK, AVG_ENTITY_DAY, +// AVG_CHUNK_MONTH, AVG_CHUNK_WEEK, AVG_CHUNK_DAY, +// +// WORLD_PIE_SERIES, GM_PIE_SERIES, PLAYERS_ONLINE_SERIES, +// TPS_SERIES, CPU_SERIES, RAM_SERIES, +// ENTITY_SERIES, CHUNK_SERIES, PUNCHCARD_SERIES, +// WORLD_MAP_SERIES, ACTIVITY_STACK_SERIES, ACTIVITY_STACK_CATEGORIES, +// ACTIVITY_PIE_SERIES, CALENDAR_SERIES +// ); try { - return HtmlUtils.replacePlaceholders(FileUtil.getStringFromResource("web/server.html"), placeHolders); + return placeholderReplacer.apply(FileUtil.getStringFromResource("web/server.html")); } catch (IOException e) { throw new ParseException(e); } diff --git a/Plan/src/main/java/com/djrapitops/plan/utilities/analysis/AnalysisUtils.java b/Plan/src/main/java/com/djrapitops/plan/utilities/analysis/AnalysisUtils.java index 0c378dce9..792de41c8 100644 --- a/Plan/src/main/java/com/djrapitops/plan/utilities/analysis/AnalysisUtils.java +++ b/Plan/src/main/java/com/djrapitops/plan/utilities/analysis/AnalysisUtils.java @@ -167,6 +167,7 @@ public class AnalysisUtils { return userSessions; } + @Deprecated public static TreeMap>> turnToActivityDataMap(long time, List players) { TreeMap>> activityData = new TreeMap<>(); if (!players.isEmpty()) { diff --git a/Plan/src/main/java/com/djrapitops/plan/utilities/html/graphs/ActivityStackGraph.java b/Plan/src/main/java/com/djrapitops/plan/utilities/html/graphs/ActivityStackGraph.java index 70b43d280..cb1e44d25 100644 --- a/Plan/src/main/java/com/djrapitops/plan/utilities/html/graphs/ActivityStackGraph.java +++ b/Plan/src/main/java/com/djrapitops/plan/utilities/html/graphs/ActivityStackGraph.java @@ -5,6 +5,7 @@ package com.djrapitops.plan.utilities.html.graphs; import com.djrapitops.plan.data.calculation.ActivityIndex; +import com.djrapitops.plan.data.store.mutators.PlayersMutator; import com.djrapitops.plan.system.settings.theme.Theme; import com.djrapitops.plan.system.settings.theme.ThemeVal; import com.djrapitops.plan.utilities.FormatUtils; @@ -26,6 +27,10 @@ public class ActivityStackGraph extends AbstractStackGraph { super(getLabels(activityData.navigableKeySet()), getDataSets(activityData)); } + public ActivityStackGraph(long date, PlayersMutator mutator) { + this(mutator.toActivityDataMap(date)); + } + private static String[] getLabels(NavigableSet dates) { return dates.stream() .map(FormatUtils::formatTimeStampDay) diff --git a/Plan/src/main/java/com/djrapitops/plan/utilities/html/graphs/calendar/ServerCalendar.java b/Plan/src/main/java/com/djrapitops/plan/utilities/html/graphs/calendar/ServerCalendar.java index f81a24c4f..942f81d64 100644 --- a/Plan/src/main/java/com/djrapitops/plan/utilities/html/graphs/calendar/ServerCalendar.java +++ b/Plan/src/main/java/com/djrapitops/plan/utilities/html/graphs/calendar/ServerCalendar.java @@ -5,6 +5,9 @@ package com.djrapitops.plan.utilities.html.graphs.calendar; import com.djrapitops.plan.data.container.Session; +import com.djrapitops.plan.data.store.containers.PlayerContainer; +import com.djrapitops.plan.data.store.keys.PlayerKeys; +import com.djrapitops.plan.data.store.mutators.PlayersMutator; import com.djrapitops.plan.data.store.mutators.formatting.Formatters; import com.djrapitops.plan.system.settings.theme.Theme; import com.djrapitops.plan.system.settings.theme.ThemeVal; @@ -27,6 +30,17 @@ public class ServerCalendar { this.sessions = sessions; } + public ServerCalendar(PlayersMutator mutator) { + registerDates = new ArrayList<>(); + sessions = new HashMap<>(); + + for (PlayerContainer container : mutator.all()) { + UUID uuid = container.getUnsafe(PlayerKeys.UUID); + registerDates.add(container.getValue(PlayerKeys.REGISTERED).orElse(0L)); + sessions.put(uuid, container.getValue(PlayerKeys.SESSIONS).orElse(new ArrayList<>())); + } + } + public String toCalendarSeries() { StringBuilder series = new StringBuilder("[");