Removed some unused html parsing utilities

This commit is contained in:
Rsl1122 2019-08-24 11:05:21 +03:00
parent b895bd1a8a
commit 1dc3e294b5
22 changed files with 21 additions and 1487 deletions

View File

@ -17,7 +17,6 @@
package com.djrapitops.plan.data.element; package com.djrapitops.plan.data.element;
import com.djrapitops.plan.utilities.formatting.Formatter; import com.djrapitops.plan.utilities.formatting.Formatter;
import com.djrapitops.plan.utilities.html.Html;
import com.djrapitops.plan.utilities.html.icon.Icon; import com.djrapitops.plan.utilities.html.icon.Icon;
import com.djrapitops.plugin.utilities.ArrayUtil; import com.djrapitops.plugin.utilities.ArrayUtil;
@ -74,7 +73,7 @@ public class TableContainer {
if (values.isEmpty()) { if (values.isEmpty()) {
addRow("No Data"); addRow("No Data");
} }
return Html.TABLE_BODY.parse(buildBody()); return "<tbody>" + buildBody() + "</tbody>";
} }
@ -136,8 +135,6 @@ public class TableContainer {
* Make use of jQuery Data-tables plugin. * Make use of jQuery Data-tables plugin.
* <p> * <p>
* Use this with custom tables. * Use this with custom tables.
* <p>
* If this is called, result of {@code parseHtml()} should be wrapped with {@code Html.PANEL.parse(Html.PANEL_BODY.parse(result))}
*/ */
public void useJqueryDataTables() { public void useJqueryDataTables() {
this.jqueryDatatable = "player-plugin-table"; this.jqueryDatatable = "player-plugin-table";
@ -154,9 +151,12 @@ public class TableContainer {
private String getTableHeader() { private String getTableHeader() {
if (jqueryDatatable != null) { if (jqueryDatatable != null) {
return "<div class=\"table-responsive\">" + Html.TABLE_JQUERY.parse(jqueryDatatable); return "<div class=\"table-responsive\">" +
"<table class=\"table table-bordered table-striped table-hover " +
jqueryDatatable +
" dataTable\">";
} else { } else {
return Html.TABLE_SCROLL.parse(); return "<div class=\"scrollbar\"><table class=\"table table-striped\">";
} }
} }
} }

View File

@ -18,7 +18,6 @@ package com.djrapitops.plan.data.plugin;
import com.djrapitops.plan.data.element.AnalysisContainer; import com.djrapitops.plan.data.element.AnalysisContainer;
import com.djrapitops.plan.data.element.InspectContainer; import com.djrapitops.plan.data.element.InspectContainer;
import com.djrapitops.plan.utilities.html.Html;
import com.djrapitops.plan.utilities.html.icon.Color; import com.djrapitops.plan.utilities.html.icon.Color;
import com.djrapitops.plan.utilities.html.icon.Icon; import com.djrapitops.plan.utilities.html.icon.Icon;
@ -94,7 +93,7 @@ public abstract class PluginData {
} }
protected final void setHelpText(String html) { protected final void setHelpText(String html) {
helpText = Html.HELP_BUBBLE.parse(sourcePlugin, html); // no-op
} }
@Override @Override

View File

@ -18,7 +18,6 @@ package com.djrapitops.plan.system;
import com.djrapitops.plan.utilities.formatting.Formatters; import com.djrapitops.plan.utilities.formatting.Formatters;
import com.djrapitops.plan.utilities.html.graphs.Graphs; import com.djrapitops.plan.utilities.html.graphs.Graphs;
import com.djrapitops.plan.utilities.html.structure.Accordions;
import com.djrapitops.plan.utilities.html.tables.HtmlTables; import com.djrapitops.plan.utilities.html.tables.HtmlTables;
import dagger.Lazy; import dagger.Lazy;
@ -31,19 +30,16 @@ public class HtmlUtilities {
private final Lazy<Formatters> formatters; private final Lazy<Formatters> formatters;
private final Lazy<HtmlTables> htmlTables; private final Lazy<HtmlTables> htmlTables;
private final Lazy<Graphs> graphs; private final Lazy<Graphs> graphs;
private final Lazy<Accordions> accordions;
@Inject @Inject
public HtmlUtilities( public HtmlUtilities(
Lazy<Formatters> formatters, Lazy<Formatters> formatters,
Lazy<HtmlTables> htmlTables, Lazy<HtmlTables> htmlTables,
Lazy<Graphs> graphs, Lazy<Graphs> graphs
Lazy<Accordions> accordions
) { ) {
this.formatters = formatters; this.formatters = formatters;
this.htmlTables = htmlTables; this.htmlTables = htmlTables;
this.graphs = graphs; this.graphs = graphs;
this.accordions = accordions;
} }
public Formatters getFormatters() { public Formatters getFormatters() {
@ -58,8 +54,4 @@ public class HtmlUtilities {
return graphs.get(); return graphs.get();
} }
public Accordions getAccordions() {
return accordions.get();
}
} }

View File

@ -17,6 +17,7 @@
package com.djrapitops.plan.utilities.html; package com.djrapitops.plan.utilities.html;
import org.apache.commons.text.StringSubstitutor; import org.apache.commons.text.StringSubstitutor;
import org.apache.commons.text.TextStringBuilder;
import java.io.Serializable; import java.io.Serializable;
import java.util.HashMap; import java.util.HashMap;
@ -44,57 +45,9 @@ public enum Html {
COLOR_E("<span class=\"yellow\">"), COLOR_E("<span class=\"yellow\">"),
COLOR_F("<span class=\"white\">"), COLOR_F("<span class=\"white\">"),
/**
* @deprecated Use com.djrapitops.plan.utilities.html.icon.Icon instead
*/
@Deprecated
FONT_AWESOME_ICON("<i class=\"fa fa-${0}\"></i>"),
/**
* @deprecated Use com.djrapitops.plan.utilities.html.icon.Icon instead
*/
@Deprecated
FA_COLORED_ICON("<i class=\"col-${0} fa fa-${1}\"></i>"),
SPAN("${0}</span>"), SPAN("${0}</span>"),
BUTTON("<a class=\"button\" href=\"${0}\">${1}</a>"),
BUTTON_CLASS("class=\"button\""),
LINK("<a class=\"link\" href=\"${0}\">${1}</a>"), LINK("<a class=\"link\" href=\"${0}\">${1}</a>"),
LINK_A("<a href=\"${0}\">${1}</a>"), LINK_EXTERNAL("<a class=\"link\" rel=\"noopener noreferrer\" target=\"_blank\" 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}\">"),
PARAGRAPH("<p>${0}</p>"),
HEADER("<h1>${0}</h1>"),
HEADER_2("<h2>${0}</h2>"),
DIV_W_CLASS("<div class=\"${0}\">${1}</div>"),
DIV_W_CLASS_STYLE("<div class=\"${0}\" style=\"${1}\">${2}</div>"),
ROW("<div class=\"row\">${0}</div>"),
CARD("<div class=\"card\">${0}</div>"),
BODY("<div class=\"card-body\">${0}</div>"),
PANEL("<div class=\"panel panel-default\">${0}</div>"),
PANEL_BODY("<div class=\"panel-body\">${0}</div>"),
HELP_BUBBLE("<div class=\"col-xs-6 col-sm-6 col-lg-6\"><a href=\"javascript:void(0)\" class=\"help material-icons pull-right\" data-trigger=\"focus\" data-toggle=\"popover\" data-placement=\"left\" data-container=\"body\" data-html=\"true\" data-original-title=\"${0}\" data-content=\"${1}\">help_outline</a></div>"),
TABLE_END("</tbody></table>"),
TABLE("<table class=\"table table-striped\">"),
TABLE_SCROLL("<div class=\"scrollbar\"><table class=\"table table-striped\">"),
TABLE_JQUERY("<table class=\"table table-bordered table-striped table-hover ${0} dataTable\">"),
TABLE_COLORED("<table class=\"bg-${0} table table-striped\">"),
TABLE_HEAD("<thead>${0}</thead>"),
TABLE_BODY("<tbody>${0}</tbody>"),
TABLE_START_2("<table class=\"table table-striped\"><thead><tr><th>${0}</th><th>${1}</th></tr></thead><tbody>"),
TABLE_START_3("<table class=\"table table-striped\"><thead><tr><th>${0}</th><th>${1}</th><th>${2}</th></tr></thead><tbody>"),
TABLE_START_4("<table class=\"table table-striped\"><thead><tr><th>${0}</th><th>${1}</th><th>${2}</th><th>${3}</th></tr></thead><tbody>"),
TABLELINE_2("<tr><td><b>${0}</b></td><td>${1}</td></tr>"),
TABLELINE_3("<tr><td><b>${0}</b></td><td>${1}</td><td>${2}</td></tr>"),
TABLELINE_4("<tr><td><b>${0}</b></td><td>${1}</td><td>${2}</td><td>${3}</td></tr>"),
TABLELINE_PLAYERS("<tr><td>${0}</td><td>${1}</td><td data-order=\"${2}\">${3}</td><td>${4}</td><td data-order=\"${5}\">${6}</td>" + "<td data-order=\"${7}\">${8}</td><td>${9}</td></tr>"),
TABLELINE_PLAYERS_PLAYERS_PAGE("<tr><td>${0}</td><td data-order=\"${1}\">${2}</td><td>${3}</td><td>${4}</td>" + "<td>${5}</td><td>${6}</td></tr>"),
TABLELINE_3_CUSTOMKEY("<tr><td sorttable_customkey=\"${0}\">${1}</td><td sorttable_customkey=\"${2}\">${3}</td><td sorttable_customkey=\"${4}\">${5}</td></tr>"),
TABLELINE_3_CUSTOMKEY_1("<tr><td sorttable_customkey=\"${0}\">${1}</td><td>${2}</td><td>${3}</td></tr>");
private final String html; private final String html;
@ -109,6 +62,12 @@ public enum Html {
return html; return html;
} }
public static String separateWithDots(String... elements) {
TextStringBuilder builder = new TextStringBuilder();
builder.appendWithSeparators(elements, " &#x2022; ");
return builder.toString();
}
/** /**
* Changes Minecraft color codes to HTML span elements with correct color class assignments. * Changes Minecraft color codes to HTML span elements with correct color class assignments.
* *

View File

@ -1,87 +0,0 @@
/*
* 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.utilities.html;
import com.djrapitops.plan.utilities.html.icon.Color;
import com.djrapitops.plan.utilities.html.icon.Icon;
import com.djrapitops.plan.utilities.html.icon.Icons;
import org.apache.commons.text.TextStringBuilder;
/**
* Class for parsing layout components of the websites.
*
* @author Rsl1122
*/
public class HtmlStructure {
private HtmlStructure() {
/* Static method class */
}
public static String separateWithDots(String... elements) {
TextStringBuilder builder = new TextStringBuilder();
builder.appendWithSeparators(elements, " &#x2022; ");
return builder.toString();
}
public static String createDotList(String... elements) {
if (elements.length == 0) {
return "";
}
StringBuilder builder = new StringBuilder();
for (String element : elements) {
if (element.isEmpty()) {
continue;
}
builder.append("&#x2022; ");
builder.append(element);
builder.append("<br>");
}
return builder.toString();
}
@Deprecated
public static String[] createInspectPageTabContentCalculating() {
String tab = "<div class=\"tab\">" +
"<div class=\"row clearfix\">" +
"<div class=\"col-lg-12 col-md-12 col-sm-12 col-xs-12\">" +
"<div class=\"card\">" +
"<div class=\"header\"><h2><i class=\"fa fa-users\"></i> Plugin Data</h2></div>" +
"<div class=\"body\">" +
"<p><i class=\"fa fa-spin fa-refresh\"></i> Calculating Plugins tab, refresh (F5) shortly..</p>" +
"</div></div>" +
"</div></div></div>";
return new String[]{"<li><a>Calculating... Refresh shortly</a></li>", tab};
}
public static String playerStatus(boolean online, boolean banned, boolean op) {
StringBuilder html = new StringBuilder("<p>");
if (online) {
html.append(Icon.called("circle").of(Color.GREEN)).append(" Online");
} else {
html.append(Icon.called("circle").of(Color.RED)).append(" Offline");
}
html.append("</p>");
if (op) {
html.append("<p>").append(Icons.OPERATOR).append(" Operator</p>");
}
if (banned) {
html.append("<p>").append(Icons.BANNED).append(" Banned</p>");
}
return html.toString();
}
}

View File

@ -1,52 +0,0 @@
/*
* 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.utilities.html;
/**
* @author Rsl1122
*/
public class HtmlUtils {
/**
* Constructor used to hide the public constructor
*/
private HtmlUtils() {
throw new IllegalStateException("Utility class");
}
/**
* Attempts to remove XSS components.
*
* @param string String to remove XSS components from
* @return String but with the components removed
*/
public static String removeXSS(String string) {
return string.replace("<!--", "").replace("-->", "").replace("</script>", "").replace("<script>", "");
}
/**
* Changes Minecraft color codes to HTML span elements with correct color class assignments.
*
* @param string String to replace Minecraft color codes from
* @deprecated Use {@link Html#swapColorCodesToSpan(String)} instead.
* @return String with span elements.
*/
@Deprecated
public static String swapColorsToSpan(String string) {
return Html.swapColorCodesToSpan(string);
}
}

View File

@ -28,7 +28,6 @@ import com.djrapitops.plan.system.webserver.cache.ResponseCache;
import com.djrapitops.plan.utilities.formatting.Formatter; import com.djrapitops.plan.utilities.formatting.Formatter;
import com.djrapitops.plan.utilities.formatting.Formatters; import com.djrapitops.plan.utilities.formatting.Formatters;
import com.djrapitops.plan.utilities.html.Html; import com.djrapitops.plan.utilities.html.Html;
import com.djrapitops.plan.utilities.html.HtmlStructure;
import com.djrapitops.plan.utilities.html.icon.Icon; import com.djrapitops.plan.utilities.html.icon.Icon;
import com.djrapitops.plan.utilities.html.structure.TabsElement; import com.djrapitops.plan.utilities.html.structure.TabsElement;
import com.djrapitops.plugin.benchmarking.Benchmark; import com.djrapitops.plugin.benchmarking.Benchmark;
@ -87,7 +86,7 @@ public class DebugPage implements Page {
String hastebinLink = Html.LINK_EXTERNAL.parse("https://hastebin.com/", "Create a new hastebin paste"); String hastebinLink = Html.LINK_EXTERNAL.parse("https://hastebin.com/", "Create a new hastebin paste");
preContent.append("<p>") preContent.append("<p>")
.append(HtmlStructure.separateWithDots(issueLink, hastebinLink)).append("<br><br>") .append(Html.separateWithDots(issueLink, hastebinLink)).append("<br><br>")
.append("This page contains debug information for an issue ticket. You can copy it directly into the issue, the info is pre-formatted.") .append("This page contains debug information for an issue ticket. You can copy it directly into the issue, the info is pre-formatted.")
.append("</p>"); .append("</p>");

View File

@ -26,7 +26,6 @@ import com.djrapitops.plan.extension.implementation.results.ExtensionTableData;
import com.djrapitops.plan.extension.implementation.results.player.ExtensionPlayerData; import com.djrapitops.plan.extension.implementation.results.player.ExtensionPlayerData;
import com.djrapitops.plan.utilities.formatting.Formatter; import com.djrapitops.plan.utilities.formatting.Formatter;
import com.djrapitops.plan.utilities.formatting.Formatters; import com.djrapitops.plan.utilities.formatting.Formatters;
import com.djrapitops.plan.utilities.html.Html;
import com.djrapitops.plan.utilities.html.icon.Icon; import com.djrapitops.plan.utilities.html.icon.Icon;
import com.djrapitops.plan.utilities.html.structure.NavLink; import com.djrapitops.plan.utilities.html.structure.NavLink;
import com.djrapitops.plan.utilities.html.structure.TabsElement; import com.djrapitops.plan.utilities.html.structure.TabsElement;
@ -92,7 +91,7 @@ public class PlayerPluginTab implements Comparable<PlayerPluginTab> {
if (playerData.isEmpty()) { if (playerData.isEmpty()) {
nav = NavLink.collapsed(Icon.called("cubes").build(), serverName + " (No Data)").toHtml(); nav = NavLink.collapsed(Icon.called("cubes").build(), serverName + " (No Data)").toHtml();
tab = wrapInTab( tab = wrapInTab(
"<div class=\"col-md-12\">" + Html.CARD.parse("<div class=\"card-body\"><p>No Extension Data</p></div>") + "</div>" "<div class=\"col-md-12\"><div class=\"card\"><div class=\"card-body\"><p>No Extension Data</p></div></div></div>"
); );
} else { } else {
nav = NavLink.collapsed(Icon.called("cubes").build(), serverName).toHtml(); nav = NavLink.collapsed(Icon.called("cubes").build(), serverName).toHtml();
@ -152,7 +151,7 @@ public class PlayerPluginTab implements Comparable<PlayerPluginTab> {
ElementOrder[] order = tabInformation.getTabElementOrder().orElse(ElementOrder.values()); ElementOrder[] order = tabInformation.getTabElementOrder().orElse(ElementOrder.values());
String values = parseValuesHtml(tabData); String values = parseValuesHtml(tabData);
String valuesHtml = values.isEmpty() ? "" : Html.BODY.parse(values); String valuesHtml = values.isEmpty() ? "" : "<div class=\"card-body\">" + values + "</div>";
String tablesHtml = parseTablesHtml(tabData); String tablesHtml = parseTablesHtml(tabData);
StringBuilder builder = new StringBuilder(); StringBuilder builder = new StringBuilder();

View File

@ -26,7 +26,6 @@ import com.djrapitops.plan.extension.implementation.results.ExtensionTableData;
import com.djrapitops.plan.extension.implementation.results.server.ExtensionServerData; import com.djrapitops.plan.extension.implementation.results.server.ExtensionServerData;
import com.djrapitops.plan.utilities.formatting.Formatter; import com.djrapitops.plan.utilities.formatting.Formatter;
import com.djrapitops.plan.utilities.formatting.Formatters; import com.djrapitops.plan.utilities.formatting.Formatters;
import com.djrapitops.plan.utilities.html.Html;
import com.djrapitops.plan.utilities.html.icon.Icon; import com.djrapitops.plan.utilities.html.icon.Icon;
import com.djrapitops.plan.utilities.html.structure.NavLink; import com.djrapitops.plan.utilities.html.structure.NavLink;
import com.djrapitops.plan.utilities.html.structure.TabsElement; import com.djrapitops.plan.utilities.html.structure.TabsElement;
@ -92,7 +91,7 @@ public class ServerPluginTabs {
if (serverData.isEmpty()) { if (serverData.isEmpty()) {
nav = new NavLink(Icon.called("cubes").build(), "Overview (No Data)").toHtml(); nav = new NavLink(Icon.called("cubes").build(), "Overview (No Data)").toHtml();
tab = wrapInTab( tab = wrapInTab(
"<div class=\"col-md-12\">" + Html.CARD.parse("<div class=\"card-body\"><p>No Extension Data</p></div>") + "</div>" "<div class=\"col-md-12\"><div class=\"card\"><div class=\"card-body\"><p>No Extension Data</p></div></div></div>"
); );
} else { } else {
nav = new NavLink(Icon.called("cubes").build(), "Overview").toHtml(); nav = new NavLink(Icon.called("cubes").build(), "Overview").toHtml();
@ -152,7 +151,7 @@ public class ServerPluginTabs {
ElementOrder[] order = tabInformation.getTabElementOrder().orElse(ElementOrder.values()); ElementOrder[] order = tabInformation.getTabElementOrder().orElse(ElementOrder.values());
String values = parseValuesHtml(tabData); String values = parseValuesHtml(tabData);
String valuesHtml = values.isEmpty() ? "" : Html.BODY.parse(values); String valuesHtml = values.isEmpty() ? "" : "<div class=\"card-body\">" + values + "</div>";
String tablesHtml = parseTablesHtml(tabData); String tablesHtml = parseTablesHtml(tabData);
StringBuilder builder = new StringBuilder(); StringBuilder builder = new StringBuilder();

View File

@ -1,68 +0,0 @@
/*
* 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.utilities.html.structure;
import com.djrapitops.plugin.utilities.Format;
import java.util.ArrayList;
import java.util.List;
/**
* Utility for creating html accordions.
*
* @author Rsl1122
*/
public class Accordion {
private final String id;
private final List<AccordionElement> elements;
private String emptyText = "No Data";
public Accordion(String id) {
this.id = new Format(id)
.removeSymbols()
.removeWhitespace()
.toString();
elements = new ArrayList<>();
}
public String toHtml() {
StringBuilder html = new StringBuilder();
html.append("<div class=\"panel-group scrollbar\" id=\"").append(id).append("\" role=\"tablist\" aria-multiselectable=\"true\">");
if (elements.isEmpty()) {
return "<div class=\"body\"><p>" + emptyText + "</p></div>";
} else {
for (AccordionElement element : elements) {
html.append(element.toHtml());
}
}
return html.append("</div>").toString(); // Close panel-group scrollbar
}
public void addElement(AccordionElement element) {
element.setParentId(id);
elements.add(element);
}
protected void setEmptyText(String text) {
emptyText = text;
}
}

View File

@ -1,115 +0,0 @@
/*
* 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.utilities.html.structure;
import com.djrapitops.plugin.utilities.Format;
import com.djrapitops.plugin.utilities.Verify;
/**
* Utility for creating html accordion elements.
*
* @author Rsl1122
*/
public class AccordionElement {
private final String id;
private final String title;
private String color;
private String parentId;
private String leftSide;
private String rightSide;
public AccordionElement(String id, String title) {
this.id = new Format(id)
.removeSymbols()
.removeWhitespace()
.toString();
this.title = title;
}
public void setParentId(String parentId) {
this.parentId = parentId;
}
public AccordionElement setColor(String color) {
this.color = color;
return this;
}
public AccordionElement setLeftSide(String leftSide) {
this.leftSide = leftSide;
return this;
}
public AccordionElement setRightSide(String rightSide) {
this.rightSide = rightSide;
return this;
}
public String toHtml() {
Verify.nullCheck(parentId, () -> new IllegalStateException("Parent ID not specified"));
StringBuilder html = new StringBuilder();
appendPanelHeading(html);
appendLeftContent(html);
appendRightContent(html);
// Finalize content
html.append("</div>") // Closes row clearfix
.append("</div>") // Closes panel-body
.append("</div>") // Closes panel-collapse
.append("</div>"); // Closes panel
return html.toString();
}
private void appendRightContent(StringBuilder html) {
if (rightSide != null) {
html.append("<div class=\"col-xs-12 col-sm-6 col-md-6 col-lg-6\">") // Right col-6
.append(rightSide)
.append("</div>"); // Right col-6
}
}
private void appendLeftContent(StringBuilder html) {
Verify.nullCheck(leftSide, () -> new IllegalStateException("No Content specified"));
html.append("<div id=\"").append(id).append("\" class=\"panel-collapse collapse\" role=\"tabpanel\"")
.append(" aria-labelledby=\"heading_").append(id).append("\">")
.append("<div class=\"panel-body\"><div class=\"row clearfix\">")
.append("<div class=\"col-xs-12 col-sm-6 col-md-6 col-lg-6\">") // Left col-6
.append(leftSide)
.append("</div>"); // Closes Left col-6
}
private void appendPanelHeading(StringBuilder html) {
html.append("<div class=\"panel");
if (color != null) {
html.append(" panel-col-").append(color);
}
html.append("\">")
.append("<div class=\"panel-heading\" role=\"tab\" id=\"heading_").append(id).append("\">")
.append("<h4 class=\"panel-title\">")
.append("<a class=\"collapsed\" role=\"button\" data-toggle=\"collapse\" data-parent=\"#")
.append(parentId).append("\" ")
.append("href=\"#").append(id).append("\" aria-expanded=\"false\" ")
.append("aria-controls=\"").append(id).append("\">")
.append(title) // Title (header)
.append("</a></h4>") // Closes collapsed & panel title
.append("</div>"); // Closes panel heading
}
}

View File

@ -1,81 +0,0 @@
/*
* 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.utilities.html.structure;
import com.djrapitops.plan.utilities.html.icon.Color;
import com.djrapitops.plan.utilities.html.icon.Icon;
import java.io.Serializable;
/**
* Utility for filling AccordionElements.
*
* @author Rsl1122
* @see AccordionElement
*/
public class AccordionElementContentBuilder {
private StringBuilder html;
public AccordionElementContentBuilder() {
this.html = new StringBuilder();
}
@Deprecated
public AccordionElementContentBuilder addRowBold(String color, String icon, String text, Serializable value) {
return addRowBold(Icon.called(icon).of(Color.matchString(color)), text, value);
}
public AccordionElementContentBuilder addRowBold(Icon.Builder iconBuilder, String text, Serializable value) {
return addRowBold(iconBuilder.build(), text, value);
}
public AccordionElementContentBuilder addRowBold(Icon icon, String text, Serializable value) {
html.append("<p>").append(icon).append(" ").append(text);
html.append("<span class=\"pull-right\"><b>").append(value).append("</b></span></p>");
return this;
}
@Deprecated
public AccordionElementContentBuilder addRow(String color, String icon, String text, Serializable value) {
return addRow(Icon.called(icon).of(Color.matchString(color)), text, value);
}
public AccordionElementContentBuilder addRow(Icon.Builder iconBuilder, String text, Serializable value) {
return addRow(iconBuilder.build(), text, value);
}
public AccordionElementContentBuilder addRow(Icon icon, String text, Serializable value) {
html.append("<p>").append(icon).append(" ").append(text);
html.append("<span class=\"pull-right\">").append(value).append("</span></p>");
return this;
}
public AccordionElementContentBuilder addHtml(String html) {
this.html.append(html);
return this;
}
public String toHtml() {
return html.toString();
}
public AccordionElementContentBuilder addBreak() {
html.append("<br>");
return this;
}
}

View File

@ -1,86 +0,0 @@
/*
* 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.utilities.html.structure;
import com.djrapitops.plan.data.container.Session;
import com.djrapitops.plan.system.settings.config.PlanConfig;
import com.djrapitops.plan.system.settings.paths.DisplaySettings;
import com.djrapitops.plan.system.settings.theme.Theme;
import com.djrapitops.plan.utilities.formatting.Formatters;
import com.djrapitops.plan.utilities.html.graphs.Graphs;
import com.djrapitops.plan.utilities.html.tables.HtmlTables;
import javax.inject.Inject;
import javax.inject.Singleton;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.function.Supplier;
/**
* Factory class for different {@link Accordion} objects.
*
* @author Rsl1122
*/
@Singleton
public class Accordions {
private final PlanConfig config;
private final Theme theme;
private final Graphs graphs;
private final HtmlTables tables;
private final Formatters formatters;
@Inject
public Accordions(
PlanConfig config,
Theme theme,
Graphs graphs,
HtmlTables tables,
Formatters formatters
) {
this.config = config;
this.theme = theme;
this.graphs = graphs;
this.tables = tables;
this.formatters = formatters;
}
/**
* Create a new Session accordion for a server.
*
* @param sessions Sessions that have occurred on a server.
* @param serverNamesSupplier Supplier for server names.
* @param playerNamesSupplier Supplier for names of players.
* @return a new {@link SessionAccordion}
*/
public SessionAccordion serverSessionAccordion(
List<Session> sessions,
Supplier<Map<UUID, String>> serverNamesSupplier,
Supplier<Map<UUID, String>> playerNamesSupplier
) {
boolean appendWorldPercentage = config.isTrue(DisplaySettings.SESSION_MOST_PLAYED_WORLD_IN_TITLE);
int maxSessions = config.get(DisplaySettings.SESSIONS_PER_PAGE);
return new SessionAccordion(
false, sessions,
serverNamesSupplier, playerNamesSupplier,
appendWorldPercentage, maxSessions,
config.getWorldAliasSettings(), theme, graphs, tables,
formatters.year(), formatters.timeAmount()
);
}
}

View File

@ -1,105 +0,0 @@
/*
* 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.utilities.html.structure;
import com.djrapitops.plan.data.store.mutators.PlayersOnlineResolver;
import com.djrapitops.plan.data.store.mutators.TPSMutator;
import com.djrapitops.plan.system.info.server.Server;
import com.djrapitops.plan.utilities.html.graphs.Graphs;
import java.util.Optional;
import java.util.UUID;
import java.util.concurrent.ThreadLocalRandom;
/**
* Html that represents a server box on the network page.
*
* @author Rsl1122
*/
public class NetworkServerBox {
private final Server server;
private final int registeredPlayers;
private final TPSMutator tpsMutator;
private final Graphs graphs;
public NetworkServerBox(
Server server,
int registeredPlayers,
TPSMutator tpsMutator,
Graphs graphs
) {
this.server = server;
this.registeredPlayers = registeredPlayers;
this.tpsMutator = tpsMutator;
this.graphs = graphs;
}
public String toHtml() {
Optional<Integer> playersOnline = new PlayersOnlineResolver(tpsMutator).getOnlineOn(System.currentTimeMillis());
int onlineCount = playersOnline.orElse(0);
int maxCount = server.getMaxPlayers();
String serverName = server.getName();
String address = "../server/" + serverName;
UUID serverUUID = server.getUuid();
String htmlID = ThreadLocalRandom.current().nextInt(100) + serverUUID.toString().replace("-", "");
String playersOnlineData = graphs.line().playersOnlineGraph(tpsMutator).toHighChartsSeries();
return "<div class=\"col-xs-12 col-sm-12 col-md-6 col-lg-6\">" +
"<div class=\"card\">" +
"<div class=\"header\">" +
"<div class=\"row clearfix\">" +
"<div class=\"col-xs-12 col-sm-12\">" +
"<h2><i class=\"col-light-green fa fa-server\"></i> " + serverName + "</h2>" +
"</div></div></div>" +
"<div class=\"panel panel-default\">" +
"<div class=\"panel-heading\">" +
"<div class=\"row\">" +
"<div id=\"playerChart" + htmlID + "\" style=\"width: 100%; height: 300px;\"></div>" +
"</div></div>" +
"<div class=\"panel-body\">" +
"<div class=\"row\">" +
"<div class=\"col-md-8\">" +
"<p><i class=\"fa fa-users\"></i> Registered Players " +
"<span class=\"pull-right\">" + registeredPlayers + "</span></p>" +
"<p><i class=\"col-blue fa fa-user\"></i> Players Online " +
"<span class=\"pull-right\">" + onlineCount + " / " + maxCount + "</span></p>" +
"</div>" +
"<div class=\"col-md-4\">" +
"<a href=\"" + address + "\"><button href=\"" + address + "\" type=\"button\" class=\"pull-right btn bg-light-green waves-effect\">" +
"<i class=\"material-icons\">trending_up</i>" +
"<span>ANALYSIS</span>" +
"</button></a></div></div></div></div></div></div>" +
"<script>" +
"var playersOnlineSeries" + htmlID + " = {" +
"name: 'Players Online'," +
"data: " + playersOnlineData + "," +
"type: 'areaspline'," +
"color: '${playersGraphColor}'," +
"tooltip: {" +
"valueDecimals: 0" +
"}};" +
"</script>" +
"<script>$(function () {setTimeout(" +
"function() {" +
"playersChartNoNav(playerChart" + htmlID + ", playersOnlineSeries" + htmlID + ");}, 1000);" +
"})</script>";
}
}

View File

@ -1,252 +0,0 @@
/*
* 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.utilities.html.structure;
import com.djrapitops.plan.api.PlanAPI;
import com.djrapitops.plan.data.container.PlayerKill;
import com.djrapitops.plan.data.container.Session;
import com.djrapitops.plan.data.store.keys.SessionKeys;
import com.djrapitops.plan.data.store.objects.DateHolder;
import com.djrapitops.plan.data.time.WorldTimes;
import com.djrapitops.plan.system.settings.config.WorldAliasSettings;
import com.djrapitops.plan.system.settings.theme.Theme;
import com.djrapitops.plan.system.settings.theme.ThemeVal;
import com.djrapitops.plan.utilities.comparators.DateHolderRecentComparator;
import com.djrapitops.plan.utilities.formatting.Formatter;
import com.djrapitops.plan.utilities.html.HtmlStructure;
import com.djrapitops.plan.utilities.html.graphs.Graphs;
import com.djrapitops.plan.utilities.html.graphs.pie.WorldPie;
import com.djrapitops.plan.utilities.html.icon.Icons;
import com.djrapitops.plan.utilities.html.tables.HtmlTables;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.function.Supplier;
/**
* Utility for creating Session accordion html and javascript from Session objects.
*
* @author Rsl1122
* @see com.djrapitops.plan.data.container.Session for object
*/
public class SessionAccordion extends Accordion {
private final boolean forPlayer;
private final List<Session> sessions;
private final Supplier<Map<UUID, String>> serverNamesSupplier;
private final Supplier<Map<UUID, String>> playerNamesSupplier;
private final StringBuilder viewScript;
private final boolean appendWorldPercentage;
private final int maxSessions;
private final WorldAliasSettings worldAliasSettings;
private final Theme theme;
private final Graphs graphs;
private final HtmlTables tables;
private final Formatter<DateHolder> yearFormatter;
private final Formatter<Long> timeAmountFormatter;
SessionAccordion(boolean forPlayer, List<Session> sessions,
Supplier<Map<UUID, String>> serverNamesSupplier,
Supplier<Map<UUID, String>> playerNamesSupplier,
boolean appendWorldPercentage,
int maxSessions,
WorldAliasSettings worldAliasSettings,
Theme theme,
Graphs graphs,
HtmlTables tables,
Formatter<DateHolder> yearFormatter,
Formatter<Long> timeAmountFormatter
) {
super("session_accordion");
this.forPlayer = forPlayer;
this.sessions = sessions;
this.serverNamesSupplier = serverNamesSupplier;
this.playerNamesSupplier = playerNamesSupplier;
this.appendWorldPercentage = appendWorldPercentage;
this.maxSessions = maxSessions;
this.worldAliasSettings = worldAliasSettings;
this.theme = theme;
this.graphs = graphs;
this.tables = tables;
this.yearFormatter = yearFormatter;
this.timeAmountFormatter = timeAmountFormatter;
viewScript = new StringBuilder();
addElements();
}
public String toViewScript() {
return viewScript.toString();
}
private void addElements() {
if (forPlayer) {
addElementsForPlayer();
} else {
addElementsForServer();
}
// Requires refactoring of Session object to contain information about player and server
}
private void addElementsForServer() {
Map<UUID, String> serverNames = serverNamesSupplier.get();
Map<UUID, String> playerNames = playerNamesSupplier.get();
sessions.sort(new DateHolderRecentComparator());
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 = yearFormatter.apply(session);
WorldTimes worldTimes = session.getValue(SessionKeys.WORLD_TIMES).orElse(new WorldTimes());
WorldPie worldPie = graphs.pie().worldPie(worldTimes);
String longestWorldPlayed = worldAliasSettings.getLongestWorldPlayed(session);
boolean hasEnded = session.supports(SessionKeys.END);
String sessionEnd = hasEnded ? yearFormatter.apply(() -> session.getUnsafe(SessionKeys.END)) : "Online";
String length = (hasEnded ? "" : "(Online) ") + timeAmountFormatter.apply(session.getValue(SessionKeys.LENGTH).orElse(0L));
String afk = (hasEnded ? "" : "(Inaccurate) ") + timeAmountFormatter.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, longestWorldPlayed)
: sessionStart;
String title = HtmlStructure.separateWithDots(playerName, info) + "<span class=\"pull-right\">" + length + "</span>";
String htmlID = "" + session.getValue(SessionKeys.START).orElse(0L) + i;
String worldHtmlID = "worldPieSession" + htmlID;
String leftSide = new AccordionElementContentBuilder()
.addRowBold(Icons.SESSION_LENGTH, "Session Ended", sessionEnd)
.addRowBold(Icons.PLAYTIME, "Session Length", length)
.addRowBold(Icons.AFK_LENGTH, "AFK", afk)
.addRowBold(Icons.SERVER, "Server", serverName)
.addBreak()
.addRowBold(Icons.PLAYER_KILLS, "Player Kills", playerKillCount)
.addRowBold(Icons.MOB_KILLS, "Mob Kills", mobKillCount)
.addRowBold(Icons.DEATHS, "Deaths", deaths)
.toHtml();
String rightSide = "<div id=\"" + worldHtmlID + "\" class=\"dashboard-donut-chart\"></div>" +
"<script>" +
"var " + worldHtmlID + "series = {name:'World Playtime',colorByPoint:true,data:" + worldPie.toHighChartsSeries() + "};" +
"var " + worldHtmlID + "gmseries = " + worldPie.toHighChartsDrilldown() + ";" +
"</script>";
viewScript.append("worldPie(")
.append(worldHtmlID).append(", ")
.append(worldHtmlID).append("series, ")
.append(worldHtmlID).append("gmseries")
.append(");");
List<PlayerKill> kills = session.getValue(SessionKeys.PLAYER_KILLS).orElse(new ArrayList<>());
String leftBottom = tables.killsTable(kills, null).parseHtml();
String link = PlanAPI.getInstance().getPlayerInspectPageLink(playerName);
String rightBottom = "<a target=\"_blank\" href=\"" + link + "\"><button href=\"" + link +
"\" type=\"button\" class=\"pull-right btn bg-blue waves-effect\">" +
"<i class=\"material-icons\">person</i><span>INSPECT PAGE</span></button></a>";
addElement(new AccordionElement(htmlID, title)
.setColor(theme.getValue(ThemeVal.PARSED_SESSION_ACCORDION))
.setLeftSide(leftSide + leftBottom)
.setRightSide(rightSide + rightBottom));
i++;
}
}
private void addElementsForPlayer() {
Map<UUID, String> serverNames = serverNamesSupplier.get();
sessions.sort(new DateHolderRecentComparator());
int i = 0;
for (Session session : new ArrayList<>(sessions)) {
if (i >= maxSessions) {
break;
}
String serverName = serverNames.getOrDefault(session.getValue(SessionKeys.SERVER_UUID).orElse(null), "Unknown");
String sessionStart = yearFormatter.apply(session);
WorldTimes worldTimes = session.getValue(SessionKeys.WORLD_TIMES).orElse(new WorldTimes());
WorldPie worldPie = graphs.pie().worldPie(worldTimes);
String longestWorldPlayed = worldAliasSettings.getLongestWorldPlayed(session);
boolean hasEnded = session.supports(SessionKeys.END);
String sessionEnd = hasEnded ? yearFormatter.apply(() -> session.getValue(SessionKeys.END).orElse(0L)) : "Online";
String length = (hasEnded ? "" : "(Online) ") + timeAmountFormatter.apply(session.getValue(SessionKeys.LENGTH).orElse(0L));
String afk = (hasEnded ? "" : "(Inaccurate) ") + timeAmountFormatter.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, longestWorldPlayed)
: sessionStart;
String title = HtmlStructure.separateWithDots(serverName, info) + "<span class=\"pull-right\">" + length + "</span>";
String htmlID = "" + session.getValue(SessionKeys.START).orElse(0L) + i;
String worldHtmlID = "worldPieSession" + htmlID;
String leftSide = new AccordionElementContentBuilder()
.addRowBold(Icons.SESSION_LENGTH, "Session Ended", sessionEnd)
.addRowBold(Icons.PLAYTIME, "Session Length", length)
.addRowBold(Icons.AFK_LENGTH, "AFK", afk)
.addRowBold(Icons.SERVER, "Server", serverName)
.addBreak()
.addRowBold(Icons.PLAYER_KILLS, "Player Kills", playerKillCount)
.addRowBold(Icons.MOB_KILLS, "Mob Kills", mobKillCount)
.addRowBold(Icons.DEATHS, "Deaths", deaths)
.toHtml();
String rightSide = "<div id=\"" + worldHtmlID + "\" class=\"dashboard-donut-chart\"></div>" +
"<script>" +
"var " + worldHtmlID + "series = {name:'World Playtime',colorByPoint:true,data:" + worldPie.toHighChartsSeries() + "};" +
"var " + worldHtmlID + "gmseries = " + worldPie.toHighChartsDrilldown() + ";" +
"</script>";
viewScript.append("worldPie(")
.append(worldHtmlID).append(", ")
.append(worldHtmlID).append("series, ")
.append(worldHtmlID).append("gmseries")
.append(");");
List<PlayerKill> kills = session.getValue(SessionKeys.PLAYER_KILLS).orElse(new ArrayList<>());
String leftBottom = tables.killsTable(kills, null).parseHtml();
addElement(new AccordionElement(htmlID, title)
.setColor(theme.getValue(ThemeVal.PARSED_SESSION_ACCORDION))
.setLeftSide(leftSide + leftBottom)
.setRightSide(rightSide));
i++;
}
}
}

View File

@ -1,70 +0,0 @@
/*
* 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.utilities.html.tables;
import com.djrapitops.plan.data.element.TableContainer;
import com.djrapitops.plan.data.store.containers.DataContainer;
import com.djrapitops.plan.data.store.keys.ServerKeys;
import com.djrapitops.plan.utilities.html.HtmlUtils;
import com.djrapitops.plan.utilities.html.icon.Icon;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
/**
* Html table that displays how many times each command is used.
*
* @author Rsl1122
*/
class CommandUseTable extends TableContainer {
CommandUseTable(DataContainer container) {
super(Icon.called("terminal") + " Command", Icon.called("list-ol") + "Times Used");
Map<String, Integer> commandUse = container.getValue(ServerKeys.COMMAND_USAGE).orElse(new HashMap<>());
setColor("lime");
if (commandUse.isEmpty()) {
addRow("No Commands");
} else {
addValues(commandUse);
}
}
private List<Map.Entry<String, Integer>> sortByValue(Map<String, Integer> map) {
return map.entrySet().stream()
.sorted((one, two) -> Integer.compare(two.getValue(), one.getValue()))
.collect(Collectors.toList());
}
private void addValues(Map<String, Integer> commandUse) {
List<Map.Entry<String, Integer>> sorted = sortByValue(commandUse);
int i = 0;
for (Map.Entry<String, Integer> entry : sorted) {
if (i >= 500) {
break;
}
String command = HtmlUtils.removeXSS(entry.getKey());
addRow(command, entry.getValue());
i++;
}
}
}

View File

@ -16,13 +16,7 @@
*/ */
package com.djrapitops.plan.utilities.html.tables; package com.djrapitops.plan.utilities.html.tables;
import com.djrapitops.plan.data.container.Ping;
import com.djrapitops.plan.data.container.PlayerKill;
import com.djrapitops.plan.data.container.Session;
import com.djrapitops.plan.data.element.AnalysisContainer;
import com.djrapitops.plan.data.element.TableContainer; import com.djrapitops.plan.data.element.TableContainer;
import com.djrapitops.plan.data.plugin.PluginData;
import com.djrapitops.plan.data.store.containers.DataContainer;
import com.djrapitops.plan.data.store.containers.PlayerContainer; import com.djrapitops.plan.data.store.containers.PlayerContainer;
import com.djrapitops.plan.system.settings.config.PlanConfig; import com.djrapitops.plan.system.settings.config.PlanConfig;
import com.djrapitops.plan.system.settings.paths.DisplaySettings; import com.djrapitops.plan.system.settings.paths.DisplaySettings;
@ -31,10 +25,7 @@ import com.djrapitops.plan.utilities.formatting.Formatters;
import javax.inject.Inject; import javax.inject.Inject;
import javax.inject.Singleton; import javax.inject.Singleton;
import java.util.Collection;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.UUID;
/** /**
* Factory class for objects that represent HTML tables. * Factory class for objects that represent HTML tables.
@ -56,67 +47,6 @@ public class HtmlTables {
this.formatters = formatters; this.formatters = formatters;
} }
/**
* Create a new Command usage table.
*
* @param container Container that supports ServerKeys.COMMAND_USAGE.
* @return a new {@link CommandUseTable}.
*/
public TableContainer commandUseTable(DataContainer container) {
return new CommandUseTable(container);
}
/**
* Create a new Kill table.
*
* @param kills List of {@link PlayerKill}s to be added to the table.
* @param color Color the table header should be.
* @return a new {@link KillsTable}.
*/
public TableContainer killsTable(List<PlayerKill> kills, String color) {
return new KillsTable(kills, color, formatters.year());
}
/**
* Create a new Country - Ping table.
*
* @param pingPerCountry Map of {@link Ping}s sorted by country names.
* @return a new {@link PingTable}.
*/
public TableContainer pingTable(Map<String, List<Ping>> pingPerCountry) {
return new PingTable(pingPerCountry, formatters.decimals());
}
/**
* Create a new Session table for a server.
*
* @param playerNames Map of UUID - Name pairs of the players.
* @param sessions List of {@link Session}s that occurred on the server.
* @return a new {@link ServerSessionTable}.
*/
public TableContainer serverSessionTable(Map<UUID, String> playerNames, List<Session> sessions) {
return new ServerSessionTable(
playerNames, sessions,
config.get(DisplaySettings.SESSIONS_PER_PAGE), config.getWorldAliasSettings(), formatters.year(), formatters.timeAmount()
);
}
/**
* Create a Player table for a server.
*
* @param players List of {@link PlayerContainer}s of players who have played on the server.
* @return a new {@link PlayersTable}.
*/
public TableContainer playerTableForServerPage(List<PlayerContainer> players) {
return new PlayersTable(
players,
config.get(DisplaySettings.PLAYERS_PER_SERVER_PAGE),
config.get(TimeSettings.ACTIVE_PLAY_THRESHOLD),
config.get(DisplaySettings.OPEN_PLAYER_LINKS_IN_NEW_TAB),
formatters.timeAmount(), formatters.yearLong(), formatters.decimals()
);
}
/** /**
* Create a Player table for a players page. * Create a Player table for a players page.
* *
@ -132,18 +62,4 @@ public class HtmlTables {
); );
} }
/**
* Create a new Player table that contains Plugin Data.
*
* @param containers PluginData AnalysisContainers.
* @param players List of {@link PlayerContainer}s of players.
* @return a new {@link PluginPlayersTable}.
*/
public TableContainer pluginPlayersTable(Map<PluginData, AnalysisContainer> containers, Collection<PlayerContainer> players) {
return new PluginPlayersTable(
containers, players,
config.get(DisplaySettings.PLAYERS_PER_SERVER_PAGE),
config.get(DisplaySettings.OPEN_PLAYER_LINKS_IN_NEW_TAB)
);
}
} }

View File

@ -1,72 +0,0 @@
/*
* 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.utilities.html.tables;
import com.djrapitops.plan.api.PlanAPI;
import com.djrapitops.plan.data.container.PlayerKill;
import com.djrapitops.plan.data.element.TableContainer;
import com.djrapitops.plan.data.store.objects.DateHolder;
import com.djrapitops.plan.utilities.comparators.DateHolderRecentComparator;
import com.djrapitops.plan.utilities.formatting.Formatter;
import com.djrapitops.plan.utilities.html.Html;
import com.djrapitops.plan.utilities.html.icon.Family;
import com.djrapitops.plan.utilities.html.icon.Icon;
import java.util.List;
/**
* Html table that displays kills Player has performed.
*
* @author Rsl1122
*/
class KillsTable extends TableContainer {
private final Formatter<DateHolder> yearFormatter;
KillsTable(List<PlayerKill> playerKills, String color, Formatter<DateHolder> yearFormatter) {
super(Icon.called("clock").of(Family.REGULAR) + " Time", "Killed", "With");
setColor(color);
this.yearFormatter = yearFormatter;
if (playerKills.isEmpty()) {
addRow("No Kills");
} else {
addValues(playerKills);
}
}
private void addValues(List<PlayerKill> playerKills) {
playerKills.sort(new DateHolderRecentComparator());
int i = 0;
for (PlayerKill kill : playerKills) {
if (i >= 40) {
break;
}
String victimName = kill.getVictimName().orElse("Unknown");
addRow(
yearFormatter.apply(kill),
Html.LINK.parse(PlanAPI.getInstance().getPlayerInspectPageLink(victimName), victimName),
kill.getWeapon()
);
i++;
}
}
}

View File

@ -1,78 +0,0 @@
/*
* 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.utilities.html.tables;
import com.djrapitops.plan.data.container.Ping;
import com.djrapitops.plan.data.element.TableContainer;
import com.djrapitops.plan.data.store.mutators.PingMutator;
import com.djrapitops.plan.utilities.formatting.Formatter;
import com.djrapitops.plan.utilities.html.icon.Icon;
import com.djrapitops.plan.utilities.html.icon.Icons;
import java.util.*;
/**
* Html table that displays countries and their average, worst and best pings.
*
* @author Rsl1122
*/
class PingTable extends TableContainer {
private final Formatter<Double> decimalFormatter;
PingTable(Map<String, List<Ping>> pingPerCountry, Formatter<Double> decimalFormatter) {
super(
Icon.called("globe") + " Country",
Icons.SIGNAL + " Average Ping",
Icons.SIGNAL + " Worst Ping",
Icons.SIGNAL + " Best Ping"
);
this.decimalFormatter = decimalFormatter;
setColor("amber");
addRows(pingPerCountry);
}
private void addRows(Map<String, List<Ping>> pingPerCountry) {
Map<String, Double> avg = new HashMap<>();
Map<String, Integer> max = new HashMap<>();
Map<String, Integer> min = new HashMap<>();
for (Map.Entry<String, List<Ping>> entry : pingPerCountry.entrySet()) {
PingMutator pingMutator = new PingMutator(entry.getValue());
String country = entry.getKey();
avg.put(country, pingMutator.average());
max.put(country, pingMutator.max());
min.put(country, pingMutator.min());
}
List<String> sortedKeys = new ArrayList<>(avg.keySet());
Collections.sort(sortedKeys);
for (String country : sortedKeys) {
Double average = avg.get(country);
Integer maximum = max.get(country);
Integer minimum = min.get(country);
addRow(
country,
average >= 0 ? decimalFormatter.apply(average) + " ms" : "-",
maximum >= 0 ? maximum + " ms" : "-",
minimum >= 0 ? minimum + " ms" : "-"
);
}
}
}

View File

@ -1,132 +0,0 @@
/*
* 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.utilities.html.tables;
import com.djrapitops.plan.api.PlanAPI;
import com.djrapitops.plan.data.element.AnalysisContainer;
import com.djrapitops.plan.data.element.TableContainer;
import com.djrapitops.plan.data.plugin.PluginData;
import com.djrapitops.plan.data.store.containers.PlayerContainer;
import com.djrapitops.plan.data.store.keys.PlayerKeys;
import com.djrapitops.plan.utilities.html.Html;
import com.djrapitops.plugin.utilities.ArrayUtil;
import java.io.Serializable;
import java.util.*;
/**
* Html table that displays players data in various plugins.
*
* @author Rsl1122
*/
class PluginPlayersTable extends TableContainer {
private Collection<PlayerContainer> players;
private final int maxPlayers;
private final boolean openPlayerPageInNewTab;
PluginPlayersTable(
Map<PluginData, AnalysisContainer> containers,
Collection<PlayerContainer> players,
int maxPlayers,
boolean openPlayerPageInNewTab
) {
this(getPluginDataSet(containers), players, maxPlayers, openPlayerPageInNewTab);
}
private PluginPlayersTable(
TreeMap<String, Map<UUID, ? extends Serializable>> pluginDataSet,
Collection<PlayerContainer> players,
int maxPlayers,
boolean openPlayerPageInNewTab
) {
super(true, getHeaders(pluginDataSet.keySet()));
this.players = players;
this.maxPlayers = maxPlayers;
this.openPlayerPageInNewTab = openPlayerPageInNewTab;
useJqueryDataTables("player-plugin-table");
if (players.isEmpty()) {
addRow("No Players");
} else {
Map<UUID, Serializable[]> rows = getRows(pluginDataSet);
addValues(rows);
}
}
private static String[] getHeaders(Set<String> columnNames) {
List<String> header = new ArrayList<>(columnNames);
Collections.sort(header);
return header.toArray(new String[0]);
}
private static TreeMap<String, Map<UUID, ? extends Serializable>> getPluginDataSet(Map<PluginData, AnalysisContainer> containers) {
TreeMap<String, Map<UUID, ? extends Serializable>> data = new TreeMap<>();
for (AnalysisContainer container : containers.values()) {
if (!container.hasPlayerTableValues()) {
continue;
}
data.putAll(container.getPlayerTableValues());
}
return data;
}
private void addValues(Map<UUID, Serializable[]> rows) {
int i = 0;
for (PlayerContainer profile : players) {
if (i >= maxPlayers) {
break;
}
UUID uuid = profile.getUnsafe(PlayerKeys.UUID);
String name = profile.getValue(PlayerKeys.NAME).orElse("Unknown");
Html link = openPlayerPageInNewTab ? Html.LINK_EXTERNAL : Html.LINK;
String linkHtml = link.parse(PlanAPI.getInstance().getPlayerInspectPageLink(name), name);
Serializable[] playerData = ArrayUtil.merge(new Serializable[]{linkHtml}, rows.getOrDefault(uuid, new Serializable[]{}));
addRow(playerData);
i++;
}
}
private Map<UUID, Serializable[]> getRows(TreeMap<String, Map<UUID, ? extends Serializable>> data) {
Map<UUID, Serializable[]> rows = new HashMap<>();
int size = header.length - 1;
for (PlayerContainer profile : players) {
UUID uuid = profile.getUnsafe(PlayerKeys.UUID);
Serializable[] row = new Serializable[size];
for (int i = 0; i < size; i++) {
String label = header[i + 1];
Map<UUID, ? extends Serializable> playerSpecificData = data.getOrDefault(label, new HashMap<>());
Serializable value = playerSpecificData.get(uuid);
if (value != null) {
row[i] = value;
}
}
rows.put(uuid, row);
}
return rows;
}
}

View File

@ -1,90 +0,0 @@
/*
* 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.utilities.html.tables;
import com.djrapitops.plan.api.PlanAPI;
import com.djrapitops.plan.data.container.Session;
import com.djrapitops.plan.data.element.TableContainer;
import com.djrapitops.plan.data.store.keys.SessionKeys;
import com.djrapitops.plan.data.store.objects.DateHolder;
import com.djrapitops.plan.system.settings.config.WorldAliasSettings;
import com.djrapitops.plan.utilities.formatting.Formatter;
import com.djrapitops.plan.utilities.html.Html;
import java.util.List;
import java.util.Map;
import java.util.UUID;
/**
* Html table that can be used to replace a {@link com.djrapitops.plan.utilities.html.structure.SessionAccordion}.
*
* @author Rsl1122
*/
class ServerSessionTable extends TableContainer {
private final int maxSessions;
private final WorldAliasSettings worldAliasSettings;
private final Formatter<DateHolder> yearFormatter;
private final Formatter<Long> timeAmountFormatter;
private final List<Session> sessions;
private Map<UUID, String> playerNames;
ServerSessionTable(
Map<UUID, String> playerNames, List<Session> sessions,
int maxSessions,
WorldAliasSettings worldAliasSettings,
Formatter<DateHolder> yearFormatter,
Formatter<Long> timeAmountFormatter
) {
super("Player", "Start", "Length", "World");
this.playerNames = playerNames;
this.sessions = sessions;
this.maxSessions = maxSessions;
this.worldAliasSettings = worldAliasSettings;
this.yearFormatter = yearFormatter;
this.timeAmountFormatter = timeAmountFormatter;
addRows();
}
private void addRows() {
int i = 0;
for (Session session : sessions) {
if (i >= maxSessions) {
break;
}
String start = yearFormatter.apply(session);
String length = session.supports(SessionKeys.END)
? timeAmountFormatter.apply(session.getValue(SessionKeys.LENGTH).orElse(0L))
: "Online";
String world = worldAliasSettings.getLongestWorldPlayed(session);
String toolTip = "Session ID: " + session.getValue(SessionKeys.DB_ID)
.map(Object::toString)
.orElse("Not Saved.");
String playerName = playerNames.getOrDefault(session.getValue(SessionKeys.UUID).orElse(null), "Unknown");
String inspectUrl = PlanAPI.getInstance().getPlayerInspectPageLink(playerName);
addRow(Html.LINK_TOOLTIP.parse(inspectUrl, playerName, toolTip), start, length, world);
i++;
}
}
}

View File

@ -1,41 +0,0 @@
/*
* 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.utilities.html;
import org.junit.jupiter.api.Test;
import org.junit.platform.runner.JUnitPlatform;
import org.junit.runner.RunWith;
import utilities.RandomData;
import static org.junit.jupiter.api.Assertions.assertEquals;
/**
* @author Rsl1122
*/
@RunWith(JUnitPlatform.class)
class HtmlUtilsTest {
@Test
void testRemoveXSS() {
String randomString = RandomData.randomString(10);
String xss = "<script>" + randomString + "</script><!---->";
String result = HtmlUtils.removeXSS(xss);
assertEquals(randomString, result);
}
}