Network page

This commit is contained in:
Rsl1122 2017-09-25 17:37:24 +03:00
parent 22579ecf24
commit 9c14f49b21
16 changed files with 238 additions and 30 deletions

View File

@ -88,15 +88,16 @@ public enum Settings {
THEME_GRAPH_RAM("Theme.Graphs.RAM"),
THEME_GRAPH_CHUNKS("Theme.Graphs.Chunks"),
THEME_GRAPH_ENTITIES("Theme.Graphs.Entities"),
THEME_GRAPH_WORLDPIE("Theme.Graphs.WorldPie"),
THEME_GRAPH_ACTIVITYPIE("Theme.Graphs.ActivityPie"),
THEME_GRAPH_SERVERPREFPIE("Theme.Graphs.ServerPreferencePie"),
THEME_GRAPH_WORLD_PIE("Theme.Graphs.WorldPie"),
THEME_GRAPH_ACTIVITY_PIE("Theme.Graphs.ActivityPie"),
THEME_GRAPH_SERVER_PREF_PIE("Theme.Graphs.ServerPreferencePie"),
// StringList
HIDE_FACTIONS("Plugins.Factions.HideFactions"),
HIDE_TOWNS("Plugins.Towny.HideTowns"),
//
// Bungee
BUNGEE_IP("Server.IP");
BUNGEE_IP("Server.IP"),
BUNGEE_NETWROK_NAME("Network.Name");
private static final ServerSpecificSettings serverSpecificSettings = new ServerSpecificSettings();

View File

@ -2,6 +2,7 @@ package main.java.com.djrapitops.plan.data.analysis;
import com.djrapitops.plugin.api.TimeAmount;
import com.djrapitops.plugin.utilities.Verify;
import main.java.com.djrapitops.plan.Settings;
import main.java.com.djrapitops.plan.data.Session;
import main.java.com.djrapitops.plan.data.TPS;
import main.java.com.djrapitops.plan.systems.webserver.theme.Colors;
@ -9,13 +10,11 @@ import main.java.com.djrapitops.plan.utilities.FormatUtils;
import main.java.com.djrapitops.plan.utilities.MiscUtils;
import main.java.com.djrapitops.plan.utilities.analysis.AnalysisUtils;
import main.java.com.djrapitops.plan.utilities.analysis.MathUtils;
import main.java.com.djrapitops.plan.utilities.html.HtmlUtils;
import main.java.com.djrapitops.plan.utilities.html.graphs.PlayerActivityGraphCreator;
import main.java.com.djrapitops.plan.utilities.html.graphs.PunchCardGraphCreator;
import java.util.*;
import java.util.stream.Collectors;
import main.java.com.djrapitops.plan.Settings;
/**
* Part responsible for all Player Activity related analysis.
@ -93,7 +92,7 @@ public class ActivityPart extends RawData {
int[] counts = new int[]{active.size(), inactive.size(), joinedOnce.size(), bans.size()};
addValue("activityPieColors", Settings.THEME_GRAPH_ACTIVITYPIE.toString());
addValue("activityPieColors", Settings.THEME_GRAPH_ACTIVITY_PIE.toString());
addValue("playersActive", counts[0]);
addValue("active", counts[0]);
addValue("inactive", counts[1]);

View File

@ -1,11 +1,11 @@
package main.java.com.djrapitops.plan.data.analysis;
import main.java.com.djrapitops.plan.Settings;
import main.java.com.djrapitops.plan.data.time.WorldTimes;
import main.java.com.djrapitops.plan.utilities.FormatUtils;
import main.java.com.djrapitops.plan.utilities.html.graphs.WorldPieCreator;
import java.util.HashMap;
import main.java.com.djrapitops.plan.Settings;
/**
* Part responsible for all World Playtime related analysis.
@ -35,7 +35,7 @@ public class WorldPart extends RawData {
String[] seriesData = WorldPieCreator.createSeriesData(worldTimes);
addValue("worldSeries", seriesData[0]);
addValue("gmSeries", seriesData[1]);
addValue("worldPieColors", Settings.THEME_GRAPH_WORLDPIE.toString());
addValue("worldPieColors", Settings.THEME_GRAPH_WORLD_PIE.toString());
}
public WorldTimes getWorldTimes() {

View File

@ -365,4 +365,22 @@ public class ServerTable extends Table {
close(set, statement);
}
}
public int getMaxPlayers() throws SQLException {
PreparedStatement statement = null;
ResultSet set = null;
try {
statement = prepareStatement("SELECT SUM(" + columnMaxPlayers + ") AS max FROM " + tableName);
statement.setFetchSize(5000);
set = statement.executeQuery();
if (set.next()) {
return set.getInt("max");
}
return 0;
} finally {
endTransaction(statement);
close(set, statement);
}
}
}

View File

@ -272,4 +272,30 @@ public class TPSTable extends Table {
close(statement);
}
}
public List<TPS> getNetworkOnlineData() throws SQLException {
PreparedStatement statement = null;
ResultSet set = null;
try {
statement = prepareStatement("SELECT " +
columnDate + ", " +
"SUM(" + columnPlayers + ") as players" +
" FROM " + tableName +
" GROUP BY " + columnDate
);
statement.setFetchSize(50000);
set = statement.executeQuery();
List<TPS> tpsList = new ArrayList<>();
while (set.next()) {
long date = set.getLong(columnDate);
int players = set.getInt("players");
tpsList.add(new TPS(date, 0, players, 0, 0, 0, 0));
}
return tpsList;
} finally {
endTransaction(statement);
close(set, statement);
}
}
}

View File

@ -429,4 +429,22 @@ public class UsersTable extends UserIDTable {
close(set, statement);
}
}
public int getPlayerCount() throws SQLException {
PreparedStatement statement = null;
ResultSet set = null;
try {
statement = prepareStatement("SELECT COUNT(*) AS player_count FROM " + tableName);
statement.setFetchSize(5000);
set = statement.executeQuery();
if (set.next()) {
return set.getInt("player_count");
}
return 0;
} finally {
endTransaction(statement);
close(set, statement);
}
}
}

View File

@ -20,6 +20,7 @@ import main.java.com.djrapitops.plan.systems.processing.Processor;
import main.java.com.djrapitops.plan.systems.webserver.PageCache;
import main.java.com.djrapitops.plan.systems.webserver.response.AnalysisPageResponse;
import main.java.com.djrapitops.plan.systems.webserver.response.InspectPageResponse;
import main.java.com.djrapitops.plan.systems.webserver.response.InternalErrorResponse;
import main.java.com.djrapitops.plan.systems.webserver.response.Response;
import main.java.com.djrapitops.plan.systems.webserver.theme.Theme;
import main.java.com.djrapitops.plan.systems.webserver.webapi.WebAPIManager;
@ -169,9 +170,8 @@ public class BukkitInformationManager extends InformationManager {
try {
return Theme.replaceColors(new AnalysisPageParser(analysisData, plugin).parse());
} catch (ParseException e) {
Log.toLog(this.getClass().getName(), e);
return new InternalErrorResponse(e, this.getClass().getSimpleName()).getContent();
}
return "";
}
@Override
@ -179,9 +179,8 @@ public class BukkitInformationManager extends InformationManager {
try {
return Theme.replaceColors(new InspectPageParser(uuid, plugin).parse());
} catch (ParseException e) {
Log.toLog(this.getClass().getName(), e);
return new InternalErrorResponse(e, this.getClass().getSimpleName()).getContent();
}
return "";
}
@Override

View File

@ -6,13 +6,16 @@ package main.java.com.djrapitops.plan.systems.info;
import main.java.com.djrapitops.plan.Log;
import main.java.com.djrapitops.plan.PlanBungee;
import main.java.com.djrapitops.plan.api.exceptions.ParseException;
import main.java.com.djrapitops.plan.api.exceptions.WebAPIConnectionFailException;
import main.java.com.djrapitops.plan.api.exceptions.WebAPIException;
import main.java.com.djrapitops.plan.api.exceptions.WebAPINotFoundException;
import main.java.com.djrapitops.plan.systems.cache.DataCache;
import main.java.com.djrapitops.plan.systems.info.parsing.NetworkPageParser;
import main.java.com.djrapitops.plan.systems.info.server.ServerInfo;
import main.java.com.djrapitops.plan.systems.webserver.PageCache;
import main.java.com.djrapitops.plan.systems.webserver.response.InspectPageResponse;
import main.java.com.djrapitops.plan.systems.webserver.response.InternalErrorResponse;
import main.java.com.djrapitops.plan.systems.webserver.response.NotFoundResponse;
import main.java.com.djrapitops.plan.systems.webserver.response.Response;
import main.java.com.djrapitops.plan.systems.webserver.webapi.WebAPIManager;
@ -162,7 +165,11 @@ public class BungeeInformationManager extends InformationManager {
@Override
public String getAnalysisHtml() {
return new NotFoundResponse("Network page not yet created").getContent();
try {
return new NetworkPageParser(plugin).parse();
} catch (ParseException e) {
return new InternalErrorResponse(e, this.getClass().getSimpleName()).getContent();
}
}
@Override
@ -201,7 +208,7 @@ public class BungeeInformationManager extends InformationManager {
public void askForNetWorkPageContent() {
// TODO WebAPI for network page content
}
public void cacheNetworkPageContent(UUID serverUUID, String html) {
networkPageContent.put(serverUUID, html);
}

View File

@ -6,6 +6,7 @@ package main.java.com.djrapitops.plan.systems.info.parsing;
import com.djrapitops.plugin.api.TimeAmount;
import main.java.com.djrapitops.plan.Log;
import main.java.com.djrapitops.plan.Settings;
import main.java.com.djrapitops.plan.api.IPlan;
import main.java.com.djrapitops.plan.api.exceptions.ParseException;
import main.java.com.djrapitops.plan.data.Action;
@ -25,6 +26,7 @@ import main.java.com.djrapitops.plan.utilities.file.FileUtil;
import main.java.com.djrapitops.plan.utilities.html.HtmlStructure;
import main.java.com.djrapitops.plan.utilities.html.HtmlUtils;
import main.java.com.djrapitops.plan.utilities.html.graphs.PunchCardGraphCreator;
import main.java.com.djrapitops.plan.utilities.html.graphs.ServerPreferencePieCreator;
import main.java.com.djrapitops.plan.utilities.html.graphs.WorldPieCreator;
import main.java.com.djrapitops.plan.utilities.html.tables.ActionsTableCreator;
@ -33,8 +35,6 @@ import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.stream.Collectors;
import main.java.com.djrapitops.plan.Settings;
import main.java.com.djrapitops.plan.utilities.html.graphs.ServerPreferencePieCreator;
/**
* Used for parsing Inspect page out of database data and the html.
@ -82,8 +82,8 @@ public class InspectPageParser extends PageParser {
Map<String, Long> playtimeByServer = sessionsTable.getPlaytimeByServer(uuid);
addValue("serverPieSeries", ServerPreferencePieCreator.createSeriesData(playtimeByServer));
addValue("worldPieColors", Settings.THEME_GRAPH_WORLDPIE.toString());
addValue("serverPieColors", Settings.THEME_GRAPH_SERVERPREFPIE.toString());
addValue("worldPieColors", Settings.THEME_GRAPH_WORLD_PIE.toString());
addValue("serverPieColors", Settings.THEME_GRAPH_SERVER_PREF_PIE.toString());
List<String> geolocations = db.getIpsTable().getGeolocations(uuid);
List<String> nicknames = db.getNicknamesTable().getNicknames(uuid).stream()

View File

@ -0,0 +1,65 @@
/*
* 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.systems.info.parsing;
import com.djrapitops.plugin.api.TimeAmount;
import main.java.com.djrapitops.plan.PlanBungee;
import main.java.com.djrapitops.plan.Settings;
import main.java.com.djrapitops.plan.api.exceptions.ParseException;
import main.java.com.djrapitops.plan.data.TPS;
import main.java.com.djrapitops.plan.database.Database;
import main.java.com.djrapitops.plan.systems.info.BungeeInformationManager;
import main.java.com.djrapitops.plan.utilities.MiscUtils;
import main.java.com.djrapitops.plan.utilities.analysis.AnalysisUtils;
import main.java.com.djrapitops.plan.utilities.file.FileUtil;
import main.java.com.djrapitops.plan.utilities.html.HtmlStructure;
import main.java.com.djrapitops.plan.utilities.html.HtmlUtils;
import main.java.com.djrapitops.plan.utilities.html.graphs.PlayerActivityGraphCreator;
import java.util.List;
import java.util.Map;
import java.util.UUID;
/**
* //TODO Class Javadoc Comment
*
* @author Rsl1122
*/
public class NetworkPageParser extends PageParser {
private final PlanBungee plugin;
public NetworkPageParser(PlanBungee plugin) {
this.plugin = plugin;
}
@Override
public String parse() throws ParseException {
try {
long now = MiscUtils.getTime();
Database db = plugin.getDB();
List<TPS> networkOnlineData = db.getTpsTable().getNetworkOnlineData();
addValue("networkName", Settings.BUNGEE_NETWROK_NAME.toString());
addValue("version", plugin.getVersion());
addValue("playersOnlineSeries", PlayerActivityGraphCreator.buildSeriesDataString(networkOnlineData));
addValue("playersOnline", plugin.getProxy().getOnlineCount());
addValue("playersMax", db.getServerTable().getMaxPlayers());
addValue("playersTotal", db.getUsersTable().getPlayerCount());
List<Long> registerDates = db.getUsersTable().getRegisterDates();
addValue("playersNewDay", AnalysisUtils.getNewPlayers(registerDates, TimeAmount.DAY.ms(), now));
addValue("playersNewWeek", AnalysisUtils.getNewPlayers(registerDates, TimeAmount.WEEK.ms(), now));
Map<UUID, String> networkPageContents = ((BungeeInformationManager) plugin.getInfoManager()).getNetworkPageContent();
addValue("contentServers", HtmlStructure.createNetworkPageContent(networkPageContents));
return HtmlUtils.replacePlaceholders(FileUtil.getStringFromResource("network.html"), placeHolders);
} catch (Exception e) {
throw new ParseException(e);
}
}
}

View File

@ -21,10 +21,24 @@ public class InternalErrorResponse extends ErrorResponse {
for (StackTraceElement element : e.getStackTrace()) {
paragraph.append("<br>");
paragraph.append(" ").append(element);
paragraph.append("&nbsp;&nbsp;").append(element);
}
if (e.getCause() != null) {
appendCause(e.getCause(), paragraph);
}
super.setParagraph(paragraph.toString());
super.replacePlaceholders();
}
private void appendCause(Throwable cause, StringBuilder paragraph) {
paragraph.append("<br>Caused by: ").append(cause);
for (StackTraceElement element : cause.getStackTrace()) {
paragraph.append("<br>");
paragraph.append("&nbsp;&nbsp;").append(element);
}
if (cause.getCause() != null) {
appendCause(cause.getCause(), paragraph);
}
}
}

View File

@ -5,9 +5,11 @@
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.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;
@ -196,7 +198,7 @@ public class HtmlStructure {
"<div class=\"row\">" +
"<div class=\"column\">" +
"<div class=\"box-header\">" +
"<h2><i class=\"fa fa-server\" aria-hidden=\"true\"></i> "+ serverName+
"<h2><i class=\"fa fa-server\" aria-hidden=\"true\"></i> " + serverName +
"</h2><p>No Compatible Plugins</p>" +
"</div></div></div></div></div>";
}
@ -376,4 +378,60 @@ public class HtmlStructure {
"</div></div>" +
"</div>";
}
public static String createNetworkPageContent(Map<UUID, String> networkPageContents) {
if (Verify.isEmpty(networkPageContents)) {
return "";
}
int i = 0;
StringBuilder b = new StringBuilder();
Collection<String> values = networkPageContents.values();
int size = values.size();
for (String server : values) {
if (i % 3 == 0) {
b.append("<div class=\"row\">");
}
b.append(server);
if ((i + 1) % 3 == 0 || i + 1 == size) {
b.append("</div>");
}
i++;
}
return b.toString();
}
public static String createServerContainer(Plan plugin) {
int maxPlayers = plugin.getVariable().getMaxPlayers();
int online = plugin.getServer().getOnlinePlayers().size();
Optional<Long> analysisRefreshDate = ((BukkitInformationManager) plugin.getInfoManager()).getAnalysisRefreshDate();
String refresh = analysisRefreshDate.map(FormatUtils::formatTimeStamp).orElse("-");
boolean analysisIsAvailable = analysisRefreshDate.isPresent();
String serverName = plugin.getServerInfoManager().getServerName();
String address = plugin.getInfoManager().getLinkTo("/server/" + serverName).relative().toString();
StringBuilder b = new StringBuilder("<div class=\"column\">");
// Header
b.append("<div class=\"box-header\"><h2><i class=\"fa fa-server\" aria-hidden=\"true\"></i> ")
.append(serverName)
.append("</h2></div>");
// Online players
b.append("<div class=\"box\"><p>").append(online).append("/").append(maxPlayers)
.append(" Players Online</p></div>");
// Footer
b.append("<div class=\"box-footer\"><p>Last Refresh: ").append(refresh).append("</p>");
if (analysisIsAvailable) {
b.append("<a href=\"").append(address).append("\" class=\"button right\">Analysis</a>");
} else {
b.append("<a class=\"button disabled right\">Analysis</a>");
}
// TODO Refresh functionality
b.append("</div>")
.append("</div>");
return b.toString();
}
}

View File

@ -1,5 +1,7 @@
Server:
IP: 0.0.0.0
Network:
Name: Plan
Plugin:
Debug: 'false'

View File

@ -30,7 +30,7 @@
<div class="box-header">
<h2><i class="fa fa-exclamation-circle"></i> ${title}</h2>
</div>
<div class="box" style="height: 75%;">
<div class="box scrollbar" style="height: 75%;">
<p>${paragraph}</p>
</div>
</div>

View File

@ -32,7 +32,7 @@
<h2><i class="fa fa-bar-chart"></i> Players Online</h2>
</div>
<div class="box-footer">
<div id="playersOnline" style="width: 100%; height: 500px;"></div>
<div id="playersOnline" style="width: 100%; height: 400px;"></div>
</div>
</div>
<div class="column">
@ -41,26 +41,27 @@
</div>
<div class="box" style="height: 75%;">
<p>${playersOnline}/${playersMax} Players Online</p>
<p>${playersActive} Active Players<br>${playersTotal} Total Players</p>
<p>${playersTotal} Total Players</p>
<p>${playersNewDay} New Players Today<br>${playersNewWeek} New Players This Week</p>
</div>
</div>
</div>
${contentServers}
</div>
<script src="https://code.highcharts.com/modules/no-data-to-display.js"></script>
<script src="https://code.highcharts.com/stock/highstock.js"></script>
<script src="./js/playerGraph.js"></script>
<script>
var playersOnlineSeries = {
name: 'Players Online',
data: ${playersonlineseries},
data: ${playersOnlineSeries},
type: 'areaspline',
color: '#${playersgraphcolor}',
color: '${playersGraphColor}',
tooltip: {
valueDecimals: 0
}
};
//playersChart('playerChart', playersOnlineSeries, 3);
playersChart('playersOnline', playersOnlineSeries, 3);
</script>
</body>
</html>

View File

@ -349,8 +349,8 @@
type: 'areaspline',
color: '${playersGraphColor}',
tooltip: {
valueDecimals: 0
}
valueDecimals: 0
}
};
var tpsSeries = {
name: 'TPS',