diff --git a/Plan/src/main/java/com/djrapitops/plan/data/container/Session.java b/Plan/src/main/java/com/djrapitops/plan/data/container/Session.java index aed45ecea..6a9fff349 100644 --- a/Plan/src/main/java/com/djrapitops/plan/data/container/Session.java +++ b/Plan/src/main/java/com/djrapitops/plan/data/container/Session.java @@ -6,10 +6,7 @@ import com.djrapitops.plan.data.store.objects.DateHolder; import com.djrapitops.plan.data.time.WorldTimes; import com.djrapitops.plan.system.info.server.ServerInfo; -import java.util.ArrayList; -import java.util.List; -import java.util.Objects; -import java.util.UUID; +import java.util.*; /** * DataContainer for information about a player's play session. @@ -71,6 +68,8 @@ public class Session extends DataContainer implements DateHolder { putRawData(SessionKeys.SERVER_UUID, serverUUID); putRawData(SessionKeys.START, sessionStart); putRawData(SessionKeys.END, sessionEnd); + putRawData(SessionKeys.WORLD_TIMES, new WorldTimes(new HashMap<>())); + putRawData(SessionKeys.PLAYER_KILLS, new ArrayList<>()); putSupplier(SessionKeys.MOB_KILL_COUNT, () -> mobKills); putSupplier(SessionKeys.DEATH_COUNT, () -> deaths); putSupplier(SessionKeys.AFK_TIME, () -> afkTime); diff --git a/Plan/src/main/java/com/djrapitops/plan/data/store/containers/DataContainer.java b/Plan/src/main/java/com/djrapitops/plan/data/store/containers/DataContainer.java index 5ffa53881..656d82ada 100644 --- a/Plan/src/main/java/com/djrapitops/plan/data/store/containers/DataContainer.java +++ b/Plan/src/main/java/com/djrapitops/plan/data/store/containers/DataContainer.java @@ -26,7 +26,7 @@ public class DataContainer extends HashMap { * @param Type of the object */ public void putRawData(Key key, T obj) { - super.put(key, () -> obj); + putSupplier(key, () -> obj); } public void putSupplier(Key key, Supplier supplier) { diff --git a/Plan/src/main/java/com/djrapitops/plan/data/store/mutators/formatting/Formatters.java b/Plan/src/main/java/com/djrapitops/plan/data/store/mutators/formatting/Formatters.java index 978681309..2d1ca0cfc 100644 --- a/Plan/src/main/java/com/djrapitops/plan/data/store/mutators/formatting/Formatters.java +++ b/Plan/src/main/java/com/djrapitops/plan/data/store/mutators/formatting/Formatters.java @@ -17,36 +17,33 @@ public class Formatters { public static Formatter year() { return dateHolder -> { long date = dateHolder.getDate(); - return date <= 0 ? FormatUtils.formatTimeStampYear(date) : "-"; + return date > 0 ? FormatUtils.formatTimeStampYear(date) : "-"; }; } public static Formatter day() { return dateHolder -> { long date = dateHolder.getDate(); - return date <= 0 ? FormatUtils.formatTimeStampDay(date) : "-"; + return date > 0 ? FormatUtils.formatTimeStampDay(date) : "-"; }; } public static Formatter second() { return dateHolder -> { long date = dateHolder.getDate(); - return date <= 0 ? FormatUtils.formatTimeStampSecond(date) : "-"; + return date > 0 ? FormatUtils.formatTimeStampSecond(date) : "-"; }; } public static Formatter clock() { return dateHolder -> { long date = dateHolder.getDate(); - return date <= 0 ? FormatUtils.formatTimeStampClock(date) : "-"; + return date > 0 ? FormatUtils.formatTimeStampClock(date) : "-"; }; } public static Formatter iso8601NoClock() { - return dateHolder -> { - long date = dateHolder.getDate(); - return date <= 0 ? FormatUtils.formatTimeStampISO8601NoClock(date) : "-"; - }; + return dateHolder -> FormatUtils.formatTimeStampISO8601NoClock(dateHolder.getDate()); } public static Formatter timeAmount() { diff --git a/Plan/src/main/java/com/djrapitops/plan/system/webserver/pages/parsing/InspectPage.java b/Plan/src/main/java/com/djrapitops/plan/system/webserver/pages/parsing/InspectPage.java index 357be93a7..0c924c731 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/webserver/pages/parsing/InspectPage.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/webserver/pages/parsing/InspectPage.java @@ -35,6 +35,7 @@ import com.djrapitops.plan.utilities.html.graphs.calendar.PlayerCalendar; import com.djrapitops.plan.utilities.html.graphs.pie.ServerPreferencePie; import com.djrapitops.plan.utilities.html.graphs.pie.WorldPie; import com.djrapitops.plan.utilities.html.structure.ServerAccordion; +import com.djrapitops.plan.utilities.html.structure.SessionAccordion; import com.djrapitops.plan.utilities.html.tables.ActionsTable; import com.djrapitops.plan.utilities.html.tables.GeoInfoTable; import com.djrapitops.plan.utilities.html.tables.NicknameTable; @@ -133,8 +134,8 @@ public class InspectPage extends Page { SessionsMutator allSessionsMutator = new SessionsMutator(allSessions); allSessions.sort(new SessionStartComparator()); - String[] sessionsAccordion = HtmlStructure.createSessionsTabContentInspectPage(sessionsByServerName, allSessions, uuid); - + SessionAccordion sessionAccordion = SessionAccordion.forPlayer(allSessions, () -> serverNames); + // TODO Session table if setting is enabled ServerAccordion serverAccordion = new ServerAccordion(container, serverNames); PlayerCalendar playerCalendar = new PlayerCalendar(allSessions, registered); @@ -142,9 +143,9 @@ public class InspectPage extends Page { addValue("calendarSeries", playerCalendar.toCalendarSeries()); addValue("firstDay", 1); - addValue("accordionSessions", sessionsAccordion[0]); + addValue("accordionSessions", sessionAccordion.toHtml()); addValue("accordionServers", serverAccordion.toHtml()); - addValue("sessionTabGraphViewFunctions", sessionsAccordion[1] + serverAccordion.toViewScript()); + addValue("sessionTabGraphViewFunctions", sessionAccordion.toViewScript() + serverAccordion.toViewScript()); long dayAgo = now - TimeAmount.DAY.ms(); long weekAgo = now - TimeAmount.WEEK.ms(); diff --git a/Plan/src/main/java/com/djrapitops/plan/utilities/html/HtmlStructure.java b/Plan/src/main/java/com/djrapitops/plan/utilities/html/HtmlStructure.java index acc7af330..de90531fd 100644 --- a/Plan/src/main/java/com/djrapitops/plan/utilities/html/HtmlStructure.java +++ b/Plan/src/main/java/com/djrapitops/plan/utilities/html/HtmlStructure.java @@ -61,6 +61,7 @@ public class HtmlStructure { return builder.toString(); } + @Deprecated public static String[] createSessionsTabContentInspectPage(Map> sessions, List allSessions, UUID uuid) { if (Settings.DISPLAY_SESSIONS_AS_TABLE.isTrue()) { Map> sessionsByPlayer = new HashMap<>(); diff --git a/Plan/src/main/java/com/djrapitops/plan/utilities/html/structure/SessionAccordion.java b/Plan/src/main/java/com/djrapitops/plan/utilities/html/structure/SessionAccordion.java index 615fa386b..e9c14f01a 100644 --- a/Plan/src/main/java/com/djrapitops/plan/utilities/html/structure/SessionAccordion.java +++ b/Plan/src/main/java/com/djrapitops/plan/utilities/html/structure/SessionAccordion.java @@ -1,5 +1,23 @@ package com.djrapitops.plan.utilities.html.structure; +import com.djrapitops.plan.api.PlanAPI; +import com.djrapitops.plan.data.container.Session; +import com.djrapitops.plan.data.store.keys.SessionKeys; +import com.djrapitops.plan.data.store.mutators.formatting.Formatter; +import com.djrapitops.plan.data.store.mutators.formatting.Formatters; +import com.djrapitops.plan.data.store.objects.DateHolder; +import com.djrapitops.plan.data.time.WorldTimes; +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.html.HtmlStructure; +import com.djrapitops.plan.utilities.html.graphs.pie.WorldPie; +import com.djrapitops.plan.utilities.html.tables.KillsTable; +import com.djrapitops.plan.utilities.html.tables.SessionsTableCreator; + +import java.util.*; +import java.util.function.Supplier; + /** * Utility for creating Session accordion html and javascript from Session objects. * @@ -9,24 +27,41 @@ package com.djrapitops.plan.utilities.html.structure; public class SessionAccordion extends AbstractAccordion { private final boolean forPlayer; + private final List sessions; + private final Supplier> serverNamesSupplier; + private final Supplier> playerNamesSupplier; private final StringBuilder viewScript; + private final boolean appendWorldPercentage; + private int maxSessions; - private SessionAccordion(boolean forPlayer) { + private SessionAccordion(boolean forPlayer, List sessions, + Supplier> serverNamesSupplier, + Supplier> playerNamesSupplier) { super("session_accordion"); this.forPlayer = forPlayer; + this.sessions = sessions; + this.serverNamesSupplier = serverNamesSupplier; + this.playerNamesSupplier = playerNamesSupplier; viewScript = new StringBuilder(); + maxSessions = Settings.MAX_SESSIONS.getNumber(); + if (maxSessions <= 0) { + maxSessions = 50; + } + appendWorldPercentage = Settings.APPEND_WORLD_PERC.isTrue(); + addElements(); } - public static SessionAccordion forServer() { - return new SessionAccordion(false); + public static SessionAccordion forServer(List sessions, Supplier> serverNamesSupplier, + Supplier> playerNamesSupplier) { + return new SessionAccordion(false, sessions, serverNamesSupplier, playerNamesSupplier); } - public static SessionAccordion forPlayer() { - return new SessionAccordion(true); + public static SessionAccordion forPlayer(List sessions, Supplier> serverNamesSupplier) { + return new SessionAccordion(true, sessions, serverNamesSupplier, HashMap::new); } public String toViewScript() { @@ -43,11 +78,143 @@ public class SessionAccordion extends AbstractAccordion { } private void addElementsForServer() { + Map serverNames = serverNamesSupplier.get(); + Map playerNames = playerNamesSupplier.get(); + Formatter timeFormatter = Formatters.timeAmount(); + Formatter timeStampFormatter = Formatters.year(); + int i = 0; + for (Session session : sessions) { + if (i >= maxSessions) { + break; + } + + String serverName = serverNames.getOrDefault(session.getValue(SessionKeys.SERVER_UUID).orElse(null), "Unknown"); + String playerName = playerNames.getOrDefault(session.getValue(SessionKeys.UUID).orElse(null), "Unknown"); + String sessionStart = timeStampFormatter.apply(session); + + WorldTimes worldTimes = session.getValue(SessionKeys.WORLD_TIMES).orElse(new WorldTimes(new HashMap<>())); + WorldPie worldPie = new WorldPie(worldTimes); + + boolean hasEnded = session.supports(SessionKeys.END); + String sessionEnd = hasEnded ? timeStampFormatter.apply(() -> session.getUnsafe(SessionKeys.END)) : "Online"; + + String length = (hasEnded ? "" : "(Online) ") + timeFormatter.apply(session.getValue(SessionKeys.LENGTH).orElse(0L)); + String afk = (hasEnded ? "" : "(Inaccurate) ") + timeFormatter.apply(session.getValue(SessionKeys.AFK_TIME).orElse(0L)); + + int playerKillCount = session.getValue(SessionKeys.PLAYER_KILL_COUNT).orElse(0); + int mobKillCount = session.getValue(SessionKeys.MOB_KILL_COUNT).orElse(0); + int deaths = session.getValue(SessionKeys.DEATH_COUNT).orElse(0); + + String info = appendWorldPercentage + ? HtmlStructure.separateWithDots(sessionStart, SessionsTableCreator.getLongestWorldPlayed(session)) + : sessionStart; + String title = HtmlStructure.separateWithDots(playerName, info) + "" + length + ""; + String htmlID = "" + session.getValue(SessionKeys.START).orElse(0L) + i; + String worldHtmlID = "worldPieSession" + htmlID; + + String leftSide = new AccordionElementContentBuilder() + .addRowBold("teal", "clock-o", "Session Ended", sessionEnd) + .addRowBold("green", "clock-o", "Session Length", length) + .addRowBold("grey", "clock-o", "AFK", afk) + .addRowBold("green", "server", "Server", serverName) + .addBreak() + .addRowBold("red", "crosshairs", "Player Kills", playerKillCount) + .addRowBold("green", "crosshairs", "Mob Kills", mobKillCount) + .addRowBold("red", "frown-o", "Deaths", deaths) + .toHtml(); + + String rightSide = "
" + + ""; + viewScript.append("worldPie(") + .append(worldHtmlID).append(", ") + .append(worldHtmlID).append("series, ") + .append(worldHtmlID).append("gmseries") + .append(");"); + + String leftBottom = new KillsTable(session.getValue(SessionKeys.PLAYER_KILLS).orElse(new ArrayList<>())).parseHtml(); + + String link = PlanAPI.getInstance().getPlayerInspectPageLink(playerName); + String rightBottom = ""; + + addElement(new AccordionElement(htmlID, title) + .setColor(Theme.getValue(ThemeVal.PARSED_SESSION_ACCORDION)) + .setLeftSide(leftSide + leftBottom) + .setRightSide(rightSide + rightBottom)); + i++; + } } private void addElementsForPlayer() { + Map serverNames = serverNamesSupplier.get(); + Formatter timeFormatter = Formatters.timeAmount(); + Formatter timeStampFormatter = Formatters.year(); + int i = 0; + for (Session session : sessions) { + if (i >= maxSessions) { + break; + } + + String serverName = serverNames.getOrDefault(session.getValue(SessionKeys.SERVER_UUID).orElse(null), "Unknown"); + String sessionStart = timeStampFormatter.apply(session); + + WorldTimes worldTimes = session.getValue(SessionKeys.WORLD_TIMES).orElse(new WorldTimes(new HashMap<>())); + WorldPie worldPie = new WorldPie(worldTimes); + + boolean hasEnded = session.supports(SessionKeys.END); + String sessionEnd = hasEnded ? timeStampFormatter.apply(() -> session.getValue(SessionKeys.END).orElse(0L)) : "Online"; + + String length = (hasEnded ? "" : "(Online) ") + timeFormatter.apply(session.getValue(SessionKeys.LENGTH).orElse(0L)); + String afk = (hasEnded ? "" : "(Inaccurate) ") + timeFormatter.apply(session.getValue(SessionKeys.AFK_TIME).orElse(0L)); + + int playerKillCount = session.getValue(SessionKeys.PLAYER_KILL_COUNT).orElse(0); + int mobKillCount = session.getValue(SessionKeys.MOB_KILL_COUNT).orElse(0); + int deaths = session.getValue(SessionKeys.DEATH_COUNT).orElse(0); + + String info = appendWorldPercentage + ? HtmlStructure.separateWithDots(sessionStart, SessionsTableCreator.getLongestWorldPlayed(session)) + : sessionStart; + String title = HtmlStructure.separateWithDots(serverName, info) + "" + length + ""; + String htmlID = "" + session.getValue(SessionKeys.START).orElse(0L) + i; + String worldHtmlID = "worldPieSession" + htmlID; + + String leftSide = new AccordionElementContentBuilder() + .addRowBold("teal", "clock-o", "Session Ended", sessionEnd) + .addRowBold("green", "clock-o", "Session Length", length) + .addRowBold("grey", "clock-o", "AFK", afk) + .addRowBold("grey", "server", "Server", serverName) + .addBreak() + .addRowBold("red", "crosshairs", "Player Kills", playerKillCount) + .addRowBold("green", "crosshairs", "Mob Kills", mobKillCount) + .addRowBold("red", "frown-o", "Deaths", deaths) + .toHtml(); + + String rightSide = "
" + + ""; + viewScript.append("worldPie(") + .append(worldHtmlID).append(", ") + .append(worldHtmlID).append("series, ") + .append(worldHtmlID).append("gmseries") + .append(");"); + + String leftBottom = new KillsTable(session.getValue(SessionKeys.PLAYER_KILLS).orElse(new ArrayList<>())).parseHtml(); + + addElement(new AccordionElement(htmlID, title) + .setColor(Theme.getValue(ThemeVal.PARSED_SESSION_ACCORDION)) + .setLeftSide(leftSide + leftBottom) + .setRightSide(rightSide)); + + i++; + } } } \ No newline at end of file