Implemented unified Session display on both pages (#354) and added SessionID as a tooltip. (#332)

This commit is contained in:
Rsl1122 2017-10-27 19:08:48 +03:00
parent c6f7fa34cc
commit 4b26755d5b
8 changed files with 216 additions and 128 deletions

View File

@ -27,14 +27,14 @@ import java.util.UUID;
* @author Rsl1122
* @see PluginData
* @see AnalysisType
* @since 2.0.0
* @since 4.0.0
*/
public class API {
private final Plan plugin;
/**
* Class Constructor.
* Creates a new API instance - not supposed to be called outside {@code Plan.onEnable}.
*
* @param plugin Current instance of Plan
*/
@ -78,7 +78,7 @@ public class API {
* {@code <a href="Link">PlayerName</a>}
*
* @param name Name of the player
* @return ./player/PlayerName
* @return {@code ../player/PlayerName}
*/
public String getPlayerInspectPageLink(String name) {
String link = "../player/" + name;
@ -86,7 +86,7 @@ public class API {
}
/**
* Check if Players's Inspect page is cached to pagecache.
* Check if Players's Inspect page is cached to PageCache.
*
* @param uuid UUID of the player.
* @return true/false
@ -97,12 +97,21 @@ public class API {
return isPlayerHtmlCached(uuid);
}
/**
* Check if Players's Inspect page is cached to PageCache of the providing WebServer.
* <p>
* Using BungeeCord: Will send a {@code IsCachedWebAPI} request to check if the page is in Bungee's PageCache.
* Only Bukkit: Checks PageCache for page.
*
* @param uuid UUID of the player.
* @return true/false
*/
public boolean isPlayerHtmlCached(UUID uuid) {
return plugin.getInfoManager().isCached(uuid);
}
/**
* Cache Players's Inspect page to the PageCache of the WebServer.
* Cache Players's Inspect page to the PageCache of the providing WebServer.
*
* @param uuid UUID of the player.
* @deprecated use {@code cachePlayerHtml}
@ -113,9 +122,13 @@ public class API {
}
/**
* Cache Players's Inspect page to the PageCache of the WebServer.
* Cache Players's Inspect page to the PageCache of the providing WebServer.
* <p>
* Using BungeeCord: Will send a {@code PostHtmlWebAPI} request after calculating the inspect page.
* Only Bukkit: Calculates inspect page and places it in the PageCache.
*
* @param uuid UUID of the player.
* @deprecated use {@code cachePlayerHtml}
*/
public void cachePlayerHtml(UUID uuid) {
plugin.getInfoManager().cachePlayer(uuid);
@ -124,7 +137,7 @@ public class API {
/**
* Used to get the full Html of the Inspect page as a string.
* <p>
* Check if the data is cached to InspectCache before calling this.
* Re-calculates the inspect html on this server.
*
* @param uuid UUID of the player.
* @return player.html with all placeholders replaced.

View File

@ -5,6 +5,7 @@ import com.djrapitops.plugin.utilities.Verify;
import main.java.com.djrapitops.plan.data.Session;
import main.java.com.djrapitops.plan.utilities.MiscUtils;
import main.java.com.djrapitops.plan.utilities.analysis.AnalysisUtils;
import main.java.com.djrapitops.plan.utilities.html.structure.SessionTabStructureCreator;
import main.java.com.djrapitops.plan.utilities.html.tables.SessionsTableCreator;
import java.util.*;
@ -62,6 +63,9 @@ public class JoinInfoPart extends RawData {
private void sessionTables() {
String[] tables = SessionsTableCreator.createTable(this);
String[] sessionContent = SessionTabStructureCreator.creteStructure(this);
addValue("contentSessions", sessionContent[0]);
addValue("sessionTabGraphViewFunctions", sessionContent[1]);
addValue("tableBodySessions", tables[0]);
addValue("tableBodyRecentLogins", tables[1]);
}

View File

@ -98,7 +98,7 @@ public class InspectPageParser extends PageParser {
Map<String, List<Session>> sessions = sessionsTable.getSessions(uuid);
List<Session> allSessions = sessions.values().stream()
.flatMap(Collection::stream)
.sorted(new SessionStartComparator())
.sorted(new SessionStartComparator()) // Sorted Newest first.
.collect(Collectors.toList());
String[] sessionsTabContent = HtmlStructure.createSessionsTabContentInspectPage(sessions, allSessions, uuid);

View File

@ -33,6 +33,7 @@ public enum Html {
BUTTON("<a class=\"button\" href=\"${0}\">${1}</a>"),
BUTTON_CLASS("class=\"button\""),
LINK("<a class=\"link\" href=\"${0}\">${1}</a>"),
LINK_TOOLTIP("<a title=\"${2}\" class=\"link\" href=\"${0}\">${1}</a>"),
LINK_EXTERNAL("<a class=\"link\" target=\"_blank\" href=\"${0}\">${1}</a>"),
LINK_CLASS("class=\"link\""),
IMG("<img src=\"${0}\">"),

View File

@ -6,15 +6,13 @@ package main.java.com.djrapitops.plan.utilities.html;
import com.djrapitops.plugin.utilities.Verify;
import main.java.com.djrapitops.plan.Plan;
import main.java.com.djrapitops.plan.Settings;
import main.java.com.djrapitops.plan.data.Session;
import main.java.com.djrapitops.plan.data.additional.AnalysisType;
import main.java.com.djrapitops.plan.data.additional.PluginData;
import main.java.com.djrapitops.plan.systems.info.BukkitInformationManager;
import main.java.com.djrapitops.plan.utilities.FormatUtils;
import main.java.com.djrapitops.plan.utilities.analysis.AnalysisUtils;
import main.java.com.djrapitops.plan.utilities.html.graphs.WorldPieCreator;
import main.java.com.djrapitops.plan.utilities.html.tables.KillsTableCreator;
import main.java.com.djrapitops.plan.utilities.html.structure.SessionTabStructureCreator;
import main.java.com.djrapitops.plan.utilities.html.tables.SessionsTableCreator;
import org.apache.commons.lang3.text.StrSubstitutor;
@ -95,105 +93,9 @@ public class HtmlStructure {
}
public static String[] createSessionsTabContentInspectPage(Map<String, List<Session>> sessions, List<Session> allSessions, UUID uuid) throws FileNotFoundException {
if (Settings.DISPLAY_SESSIONS_AS_TABLE.isTrue()) {
return getSessionsAsTable(sessions, allSessions, uuid);
}
Map<Integer, String> serverNameIDRelationMap = new HashMap<>();
if (Verify.isEmpty(allSessions)) {
return new String[]{"<div class=\"session column\">" +
"<div class=\"session-header\">" +
"<div class=\"session-col\" style=\"width: 200%;\">" +
"<h3>No Sessions</h3>" +
"</div></div></div>", ""};
}
for (Map.Entry<String, List<Session>> entry : sessions.entrySet()) {
String serverName = entry.getKey();
List<Session> serverSessions = entry.getValue();
for (Session session : serverSessions) {
serverNameIDRelationMap.put(session.getSessionID(), serverName);
}
}
StringBuilder html = new StringBuilder();
StringBuilder viewScript = new StringBuilder();
int i = 0;
for (Session session : allSessions) {
if (i >= 50) {
break;
}
String sessionStart = FormatUtils.formatTimeStampYear(session.getSessionStart());
String sessionLength = FormatUtils.formatTimeAmount(session.getLength());
String sessionEnd = FormatUtils.formatTimeStampYear(session.getSessionEnd());
String dotSeparated = separateWithDots(sessionStart, sessionLength);
// Session-column starts & header.
html.append("<div class=\"session column\">")
.append("<div class=\"session-header\">")
.append("<div class=\"session-col\" style=\"width: 200%;\">")
.append("<h3><i style=\"color:#777\" class=\"fa fa-chevron-down\" aria-hidden=\"true\"></i> ").append(dotSeparated).append("</h3>")
.append("</div>")
.append("</div>");
String serverName = serverNameIDRelationMap.get(session.getSessionID());
// Left side of Session box
html.append("<div class=\"session-content\">")
.append("<div class=\"row\">") //
.append("<div class=\"session-col\" style=\"padding: 0px;\">");
// Left side header
html.append("<div class=\"box-header\" style=\"margin: 0px;\">")
.append("<h2><i class=\"fa fa-calendar\" aria-hidden=\"true\"></i> ")
.append(sessionStart)
.append("</h2>")
.append("</div>");
// Left side content
html.append("<div class=\"box\" style=\"margin: 0px;\">")
.append("<p>Session Length: ").append(sessionLength).append("<br>")
.append("Session Ended: ").append(sessionEnd).append("<br>")
.append("Server: ").append(serverName).append("<br><br>")
.append("Mob Kills: ").append(session.getMobKills()).append("<br>")
.append("Deaths: ").append(session.getDeaths()).append("</p>");
html.append(KillsTableCreator.createTable(session.getPlayerKills()))
.append("</div>"); // Left Side content ends
// Left side ends & Right side starts
html.append("</div>")
.append("<div class=\"session-col\">");
String id = "worldPie" + session.getSessionStart() + i;
html.append("<div id=\"").append(id).append("\" style=\"width: 100%; height: 400px;\"></div>");
String[] worldData = WorldPieCreator.createSeriesData(session.getWorldTimes());
html.append("<script>")
.append("var ").append(id).append("series = {name:'World Playtime',colors: worldPieColors,colorByPoint:true,data:").append(worldData[0]).append("};")
.append("var ").append(id).append("gmseries = ").append(worldData[1]).append(";")
.append("</script>");
viewScript.append("worldPie(")
.append(id).append(", ")
.append(id).append("series, ")
.append(id).append("gmseries")
.append(");");
// Session-col, Row, Session-Content, Session-column ends.
html.append("</div>")
.append("</div>")
.append("</div>")
.append("</div>");
i++;
}
return new String[]{html.toString(), viewScript.toString()};
Map<UUID, Map<String, List<Session>>> map = new HashMap<>();
map.put(uuid, sessions);
return SessionTabStructureCreator.creteStructure(map, allSessions, false);
}
private static String[] getSessionsAsTable(Map<String, List<Session>> sessions, List<Session> allSessions, UUID uuid) {

View File

@ -0,0 +1,177 @@
/*
* Licence is provided in the jar as license.yml also here:
* https://github.com/Rsl1122/Plan-PlayerAnalytics/blob/master/Plan/src/main/resources/license.yml
*/
package main.java.com.djrapitops.plan.utilities.html.structure;
import com.djrapitops.plugin.utilities.Verify;
import main.java.com.djrapitops.plan.Plan;
import main.java.com.djrapitops.plan.Settings;
import main.java.com.djrapitops.plan.data.Session;
import main.java.com.djrapitops.plan.data.analysis.JoinInfoPart;
import main.java.com.djrapitops.plan.utilities.FormatUtils;
import main.java.com.djrapitops.plan.utilities.comparators.SessionStartComparator;
import main.java.com.djrapitops.plan.utilities.html.Html;
import main.java.com.djrapitops.plan.utilities.html.HtmlStructure;
import main.java.com.djrapitops.plan.utilities.html.graphs.WorldPieCreator;
import main.java.com.djrapitops.plan.utilities.html.tables.KillsTableCreator;
import main.java.com.djrapitops.plan.utilities.html.tables.SessionsTableCreator;
import java.util.*;
import java.util.stream.Collectors;
/**
* //TODO Class Javadoc Comment
*
* @author Rsl1122
*/
public class SessionTabStructureCreator {
public static String[] creteStructure(Map<UUID, Map<String, List<Session>>> sessions, List<Session> allSessions, boolean appendName) {
Map<Integer, UUID> uuidsByID = generateIDtoUUIDMap(sessions);
if (Settings.DISPLAY_SESSIONS_AS_TABLE.isTrue()) {
return new String[]{Html.TABLE_SESSIONS.parse(SessionsTableCreator.createTable(uuidsByID, allSessions)[0]), ""};
}
if (Verify.isEmpty(allSessions)) {
return new String[]{"<div class=\"session column\">" +
"<div class=\"session-header\">" +
"<div class=\"session-col\" style=\"width: 200%;\">" +
"<h3>No Sessions</h3>" +
"</div></div></div>", ""};
}
Map<Integer, String> serverNameIDMap = generateIDtoServerNameMap(sessions);
StringBuilder html = new StringBuilder();
StringBuilder viewScript = new StringBuilder();
int i = 0;
for (Session session : allSessions) {
if (i >= 50) {
break;
}
int sessionID = session.getSessionID();
UUID uuid = uuidsByID.get(sessionID);
String serverName = serverNameIDMap.get(sessionID);
String sessionStart = FormatUtils.formatTimeStampYear(session.getSessionStart());
String sessionLength = FormatUtils.formatTimeAmount(session.getLength());
String sessionEnd = FormatUtils.formatTimeStampYear(session.getSessionEnd());
String name = Plan.getInstance().getDataCache().getName(uuid);
String link = Html.LINK.parse(Plan.getPlanAPI().getPlayerInspectPageLink(name), name);
String dotSeparated = appendName ?
HtmlStructure.separateWithDots(link, sessionStart, sessionLength) :
HtmlStructure.separateWithDots(sessionStart, sessionLength);
// Session-column starts & header.
html.append("<div class=\"session column\">")
.append("<div title=\"Session ID: ").append(sessionID).append("\" class=\"session-header\">")
.append("<div class=\"session-col\" style=\"width: 200%;\">")
.append("<h3><i style=\"color:#777\" class=\"fa fa-chevron-down\" aria-hidden=\"true\"></i> ").append(dotSeparated).append("</h3>")
.append("</div>")
.append("</div>");
// Left side of Session box
html.append("<div class=\"session-content\">")
.append("<div class=\"row\">") //
.append("<div class=\"session-col\" style=\"padding: 0px;\">");
// Left side header
html.append("<div class=\"box-header\" style=\"margin: 0px;\">")
.append("<h2><i class=\"fa fa-calendar\" aria-hidden=\"true\"></i> ")
.append(sessionStart)
.append("</h2>")
.append("</div>");
// Left side content
html.append("<div class=\"box\" style=\"margin: 0px;\">")
.append("<p>Session Length: ").append(sessionLength).append("<br>")
.append("Session Ended: ").append(sessionEnd).append("<br>")
.append("Server: ").append(serverName).append("<br><br>")
.append("Mob Kills: ").append(session.getMobKills()).append("<br>")
.append("Deaths: ").append(session.getDeaths()).append("</p>");
html.append(KillsTableCreator.createTable(session.getPlayerKills()))
.append("</div>"); // Left Side content ends
// Left side ends & Right side starts
html.append("</div>")
.append("<div class=\"session-col\">");
String id = "worldPie" + session.getSessionStart() + i;
html.append("<div id=\"").append(id).append("\" style=\"width: 100%; height: 400px;\"></div>");
String[] worldData = WorldPieCreator.createSeriesData(session.getWorldTimes());
html.append("<script>")
.append("var ").append(id).append("series = {name:'World Playtime',colors: worldPieColors,colorByPoint:true,data:").append(worldData[0]).append("};")
.append("var ").append(id).append("gmseries = ").append(worldData[1]).append(";")
.append("</script>");
viewScript.append("worldPie(")
.append(id).append(", ")
.append(id).append("series, ")
.append(id).append("gmseries")
.append(");");
// Session-col, Row, Session-Content, Session-column ends.
html.append("</div>")
.append("</div>")
.append("</div>")
.append("</div>");
i++;
}
return new String[]{html.toString(), viewScript.toString()};
}
private static Map<Integer, String> generateIDtoServerNameMap(Map<UUID, Map<String, List<Session>>> sessions) {
Map<Integer, String> serverNameIDRelationMap = new HashMap<>();
for (Map<String, List<Session>> map : sessions.values()) {
for (Map.Entry<String, List<Session>> entry : map.entrySet()) {
String serverName = entry.getKey();
List<Session> serverSessions = entry.getValue();
for (Session session : serverSessions) {
serverNameIDRelationMap.put(session.getSessionID(), serverName);
}
}
}
return serverNameIDRelationMap;
}
private static Map<Integer, UUID> generateIDtoUUIDMap(Map<UUID, Map<String, List<Session>>> sessions) {
Map<Integer, UUID> uuidsByID = new HashMap<>();
for (Map.Entry<UUID, Map<String, List<Session>>> entry : sessions.entrySet()) {
UUID uuid = entry.getKey();
for (List<Session> sessionList : entry.getValue().values()) {
for (Session session : sessionList) {
uuidsByID.put(session.getSessionID(), uuid);
}
}
}
return uuidsByID;
}
public static String[] creteStructure(JoinInfoPart joinInfoPart) {
Map<UUID, Map<String, List<Session>>> map = new HashMap<>();
Map<UUID, List<Session>> sessions = joinInfoPart.getSessions();
for (Map.Entry<UUID, List<Session>> entry : sessions.entrySet()) {
Map<String, List<Session>> serverSpecificMap = new HashMap<>();
serverSpecificMap.put("This server", entry.getValue());
map.put(entry.getKey(), serverSpecificMap);
}
List<Session> allSessions = sessions.values().stream()
.flatMap(Collection::stream)
.sorted(new SessionStartComparator())
.collect(Collectors.toList());
return creteStructure(map, allSessions, true);
}
}

View File

@ -77,8 +77,9 @@ public class SessionsTableCreator {
String world = getLongestWorldPlayed(session);
String inspectUrl = Plan.getPlanAPI().getPlayerInspectPageLink(name);
String toolTip = "Session ID: " + (session.isFetchedFromDB() ? session.getSessionID() : "Not Saved.");
sessionTableBuilder.append(Html.TABLELINE_4.parse(
Html.LINK.parse(inspectUrl, name),
Html.LINK_TOOLTIP.parse(inspectUrl, name, toolTip),
start,
length,
world

View File

@ -14,6 +14,10 @@
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
</head>
<body>
<script>
var worldPieColors = [${worldPieColors}];
var gmPieColors = [${gmPieColors}];
</script>
<header>
<div>
<div class="right fa-stack fa-lg" style="padding: 23px; margin:8px">
@ -183,21 +187,7 @@
<div class="box-header">
<h2><i class="fa fa-calendar"></i> 50 Most Recent Sessions</h2>
</div>
<div class="box-footer scrollbar" style="padding: 2px;">
<table class="sortable table">
<thead>
<tr>
<th>Player</th>
<th>Started</th>
<th>Length</th>
<th>World - Time</th>
</tr>
</thead>
<tbody>
${tableBodySessions}
</tbody>
</table>
</div>
${contentSessions}
</div>
</div>
<div class="row">
@ -358,6 +348,7 @@
<script src="./js/performanceGraph.js"></script>
<script src="./js/worldMap.js"></script>
<script src="./js/worldPie.js"></script>
<script src="./js/sessionTabExpand.js"></script>
<script>
Highcharts.setOptions({
lang: {noData: "No Data to Display"},
@ -449,8 +440,6 @@
y: ${banned}
}]
};
var worldPieColors = [${worldPieColors}];
var gmPieColors = [${gmPieColors}];
var worldSeries = {
name: 'World Playtime',
colorByPoint: true,
@ -502,6 +491,7 @@
worldChart('worldGraph', entitySeries, chunkSeries, playersOnlineSeries);
worldMap('choropleth', '#EEFFEE', '#267f00', mapSeries);
punchCard('punchcard', punchcardSeries);
${sessionTabGraphViewFunctions}
/*countUpTimer();*/
function openFunc(i) {