Analysis page now works. (Some placeholders not implemented)

Removed some Deprecated settings.
More TODO markings.
This commit is contained in:
Rsl1122 2017-08-21 11:06:20 +03:00
parent b8d2321584
commit 21da757362
43 changed files with 370 additions and 425 deletions

View File

@ -165,14 +165,11 @@ public class Plan extends BukkitPlugin<Plan> {
Benchmark.start("Analysis refresh task registration");
// Analysis refresh settings
boolean bootAnalysisIsEnabled = Settings.ANALYSIS_REFRESH_ON_ENABLE.isTrue();
int analysisRefreshMinutes = Settings.ANALYSIS_AUTO_REFRESH.getNumber();
boolean analysisRefreshTaskIsEnabled = analysisRefreshMinutes > 0;
// Analysis refresh tasks
if (bootAnalysisIsEnabled) {
startBootAnalysisTask();
}
startBootAnalysisTask();
if (analysisRefreshTaskIsEnabled) {
startAnalysisRefreshTask(analysisRefreshMinutes);
}
@ -180,23 +177,21 @@ public class Plan extends BukkitPlugin<Plan> {
Benchmark.stop("Enable", "Analysis refresh task registration");
Benchmark.start("WebServer Initialization");
// Data view settings
boolean webserverIsEnabled = Settings.WEBSERVER_ENABLED.isTrue();
boolean usingAlternativeIP = Settings.SHOW_ALTERNATIVE_IP.isTrue();
boolean usingAlternativeUI = Settings.USE_ALTERNATIVE_UI.isTrue();
boolean hasDataViewCapability = usingAlternativeIP || usingAlternativeUI || webserverIsEnabled;
uiServer = new WebServer(this);
if (webserverIsEnabled) {
registerWebAPIs();
uiServer.initServer();
registerWebAPIs(); // TODO Move to WebServer class
uiServer.initServer();
if (!uiServer.isEnabled()) {
Log.error("WebServer was not successfully initialized.");
}
if (!uiServer.isEnabled()) {
Log.error("WebServer was not successfully initialized.");
}
setupFilter(); // TODO Move to RegisterCommand Constructor
setupFilter();
} else if (!hasDataViewCapability) {
// Data view settings // TODO Rewrite. (TextUI removed & webserver might be running on bungee
boolean usingAlternativeIP = Settings.SHOW_ALTERNATIVE_IP.isTrue();
boolean hasDataViewCapability = usingAlternativeIP;
if (!hasDataViewCapability) {
Log.infoColor(Locale.get(Msg.ENABLE_NOTIFY_NO_DATA_VIEW).toString());
}
if (!usingAlternativeIP && serverVariableHolder.getIp().isEmpty()) {

View File

@ -13,31 +13,15 @@ public enum Settings {
// Boolean
BUNGEE_COPY_CONFIG("Bungee-Override.CopyBungeeConfig"),
BUNGEE_OVERRIDE_STANDALONE_MODE("Bungee-Override.StandaloneMode"),
@Deprecated WEBSERVER_ENABLED("Settings.WebServer.Enabled"),
@Deprecated ANALYSIS_REFRESH_ON_ENABLE("Settings.Cache.AnalysisCache.RefreshAnalysisCacheOnEnable"),
@Deprecated ANALYSIS_LOG_TO_CONSOLE("Settings.Analysis.LogProgressOnConsole"),
@Deprecated ANALYSIS_LOG_FINISHED("Settings.Analysis.NotifyWhenFinished"),
ANALYSIS_EXPORT("Analysis.Export.Enabled"),
SHOW_ALTERNATIVE_IP("Commands.AlternativeIP.Enabled"),
@Deprecated USE_ALTERNATIVE_UI("Settings.UseTextUI"),
LOG_UNKNOWN_COMMANDS("DAta.Commands.LogUnknownCommands"),
COMBINE_COMMAND_ALIASES("Data.Commands.CombineCommandAliases"),
@Deprecated SECURITY_IP_UUID("Settings.WebServer.Security.DisplayIPsAndUUIDs"),
@Deprecated PLAYERLIST_SHOW_IMAGES("Customization.SmallHeadImagesOnAnalysisPlayerlist"),
WRITE_NEW_LOCALE("Plugin.WriteNewLocaleFileOnStart"),
// Integer
@Deprecated ANALYSIS_MINUTES_FOR_ACTIVE("Settings.Analysis.MinutesPlayedUntilConsidiredActive"),
@Deprecated SAVE_CACHE_MIN("Settings.Cache.DataCache.SaveEveryXMinutes"),
@Deprecated CLEAR_INSPECT_CACHE("Settings.Cache.InspectCache.ClearFromInspectCacheAfterXMinutes"),
@Deprecated CLEAR_CACHE_X_SAVES("Settings.Cache.DataCache.ClearCacheEveryXSaves"),
WEBSERVER_PORT("WebServer.Port"),
ANALYSIS_AUTO_REFRESH("Analysis.AutoRefreshPeriod"),
@Deprecated PROCESS_GET_LIMIT("Settings.Cache.Processing.GetLimit"),
@Deprecated PROCESS_SAVE_LIMIT("Settings.Cache.Processing.SaveLimit"),
@Deprecated PROCESS_CLEAR_LIMIT("Settings.Cache.Processing.ClearLimit"),
@Deprecated TPS_GRAPH_HIGH("Customization.Colors.HTML.TPSGraph.TPSHigh"),
@Deprecated TPS_GRAPH_MED("Customization.Colors.HTML.TPSGraph.TPSMedium"),
// String
DEBUG("Plugin.Debug"),
ALTERNATIVE_IP("Commands.AlternativeIP.Link"),

View File

@ -26,10 +26,11 @@ public class ConditionUtils {
*
* @return true/false
*/
// TODO Rewrite this method
public static boolean pluginHasViewCapability() {
final boolean usingAlternativeIP = Settings.SHOW_ALTERNATIVE_IP.isTrue();
final boolean webserverIsOn = Settings.WEBSERVER_ENABLED.isTrue();
final boolean usingTextUI = Settings.USE_ALTERNATIVE_UI.isTrue();
final boolean webserverIsOn = true;
final boolean usingTextUI = false;
return webserverIsOn || usingAlternativeIP || usingTextUI;
}

View File

@ -10,12 +10,10 @@ import com.djrapitops.plugin.utilities.Verify;
import main.java.com.djrapitops.plan.Log;
import main.java.com.djrapitops.plan.Permissions;
import main.java.com.djrapitops.plan.Plan;
import main.java.com.djrapitops.plan.Settings;
import main.java.com.djrapitops.plan.command.ConditionUtils;
import main.java.com.djrapitops.plan.data.cache.InspectCacheHandler;
import main.java.com.djrapitops.plan.locale.Locale;
import main.java.com.djrapitops.plan.locale.Msg;
import main.java.com.djrapitops.plan.ui.text.TextUI;
import main.java.com.djrapitops.plan.utilities.Check;
import main.java.com.djrapitops.plan.utilities.HtmlUtils;
import main.java.com.djrapitops.plan.utilities.MiscUtils;
@ -126,24 +124,16 @@ public class InspectCommand extends SubCommand {
}
private void sendInspectMsg(ISender sender, String playerName, UUID uuid) {
boolean usingTextUI = Settings.USE_ALTERNATIVE_UI.isTrue();
sender.sendMessage(Locale.get(Msg.CMD_HEADER_INSPECT) + playerName);
if (usingTextUI) {
sender.sendMessage(TextUI.getInspectMessages(uuid));
// Link
String url = HtmlUtils.getInspectUrlWithProtocol(playerName);
String message = Locale.get(Msg.CMD_INFO_LINK).toString();
boolean console = !CommandUtils.isPlayer(sender);
if (console) {
sender.sendMessage(message + url);
} else {
// Link
String url = HtmlUtils.getInspectUrlWithProtocol(playerName);
String message = Locale.get(Msg.CMD_INFO_LINK).toString();
boolean console = !CommandUtils.isPlayer(sender);
if (console) {
sender.sendMessage(message + url);
} else {
sender.sendMessage(message);
sender.sendLink(" ", Locale.get(Msg.CMD_INFO_CLICK_ME).toString(), url);
}
sender.sendMessage(message);
sender.sendLink(" ", Locale.get(Msg.CMD_INFO_CLICK_ME).toString(), url);
}
sender.sendMessage(Locale.get(Msg.CMD_CONSTANT_FOOTER).toString());

View File

@ -49,8 +49,8 @@ public class AnalysisData extends RawData {
geolocationPart = new GeolocationPart();
joinInfoPart = new JoinInfoPart();
playerCountPart = new PlayerCountPart();
playtimePart = new PlaytimePart(playerCountPart);
killPart = new KillPart(playerCountPart);
playtimePart = new PlaytimePart();
killPart = new KillPart();
gamemodePart = new GamemodePart();
tpsPart = new TPSPart(tpsData);
activityPart = new ActivityPart(joinInfoPart, tpsPart);
@ -137,7 +137,7 @@ public class AnalysisData extends RawData {
Verify.nullCheck(pluginsTabLayout);
Verify.nullCheck(planVersion);
addValue("sortabletable", playersTable);
addValue("tableBodyPlayerList", playersTable);
addValue("version", planVersion);
final List<RawData> parts = getAllParts();

View File

@ -154,7 +154,7 @@ public abstract class PluginData {
* @see AnalysisType
*/
public final String getPlaceholder(String modifier) {
return "%" + sourcePlugin + "_" + placeholder + modifier + "%";
return "${" + sourcePlugin + "_" + placeholder + modifier + "}";
}
/**

View File

@ -2,13 +2,13 @@ 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.SessionData;
import main.java.com.djrapitops.plan.data.TPS;
import main.java.com.djrapitops.plan.ui.html.RecentPlayersButtonsCreator;
import main.java.com.djrapitops.plan.ui.html.graphs.PlayerActivityGraphCreator;
import main.java.com.djrapitops.plan.ui.html.graphs.PunchCardGraphCreator;
import main.java.com.djrapitops.plan.ui.html.graphs.SessionLengthDistributionGraphCreator;
import main.java.com.djrapitops.plan.ui.theme.Colors;
import main.java.com.djrapitops.plan.utilities.FormatUtils;
import main.java.com.djrapitops.plan.utilities.HtmlUtils;
import main.java.com.djrapitops.plan.utilities.MiscUtils;
@ -21,17 +21,22 @@ import java.util.stream.Collectors;
/**
* Part responsible for all Player Activity related analysis.
* <p>
* Online Graphs, Player-base pie-chart, Recent Players and Session
* visualisation.
* <p>
* Placeholder values can be retrieved using the get method.
* <p>
* Contains following place-holders: recentlogins, sessionaverage,
* datapunchcard, datasessiondistribution, labelssessiondistribution,
* datascatterday, datascatterweek, datascattermonth, playersonlinecolor,
* playersgraphfill, activecol, inactivecol, joinleavecol, bannedcol,
* activitycolors, labelsactivity, dataaactivity, active, inactive, joinleaver,
* banned
* Contains following placeholders after analyzed:
* ${active} - (Number)
* ${inactive} - (Number)
* ${joinLeaver} - (Number)
* ${banned} - (Number)
* ${activityColors} - Color array
* ${playersGraphColor} - Color
* <p>
* ${playersOnlineSeries} - Data for HighCharts
* ${sessionLengthSeries} - Data for HighCharts
* ${punchCardSeries} - Data for HighCharts
* <p>
* ${sessionAverage} - Formatted Time amount
* //TODO ${tableBodyRecentLogins}
*
* @author Rsl1122
* @since 3.5.2
@ -61,6 +66,7 @@ public class ActivityPart extends RawData {
Verify.nullCheck(recentPlayers);
Verify.nullCheck(recentPlayersUUIDs);
// TODO Recent logins table
addValue("recentlogins", RecentPlayersButtonsCreator.createRecentLoginsButtons(recentPlayers, 15));
activityPiechart();
@ -71,45 +77,34 @@ public class ActivityPart extends RawData {
List<Long> lengths = AnalysisUtils.transformSessionDataToLengths(sessions);
long averageLength = MathUtils.averageLong(lengths);
addValue("sessionaverage", FormatUtils.formatTimeAmount(averageLength));
addValue("sessionAverage", FormatUtils.formatTimeAmount(averageLength));
List<SessionData> sessionsMonth = sessions.stream()
.filter(s -> s.getSessionStart() > MiscUtils.getTime() - TimeAmount.MONTH.ms())
.collect(Collectors.toList());
addValue("punchcardseries", PunchCardGraphCreator.createDataSeries(sessionsMonth));
addValue("sessionlengthseries", SessionLengthDistributionGraphCreator.createDataSeries(lengths));
addValue("punchCardSeries", PunchCardGraphCreator.createDataSeries(sessionsMonth));
addValue("sessionLengthSeries", SessionLengthDistributionGraphCreator.createDataSeries(lengths));
}
private void playerActivityGraphs() {
List<TPS> tpsData = tpsPart.getTpsData();
addValue("playersonlineseries", PlayerActivityGraphCreator.buildSeriesDataString(tpsData));
addValue("playersgraphcolor", Settings.HCOLOR_ACT_ONL.toString());
addValue("playersOnlineSeries", PlayerActivityGraphCreator.buildSeriesDataString(tpsData));
addValue("playersGraphColor", Colors.PLAYERS_ONLINE.getColor());
}
private void activityPiechart() {
int[] counts = new int[]{active.size(), inactive.size(), joinedOnce.size(), bans.size()};
final String colAct = Settings.HCOLOR_ACTP_ACT.toString();
final String colIna = Settings.HCOLOR_ACTP_INA.toString();
final String colJoi = Settings.HCOLOR_ACTP_JON.toString();
final String colBan = Settings.HCOLOR_ACTP_BAN.toString();
addValue("activecol", colAct);
addValue("inactivecol", colIna);
addValue("joinleavecol", colJoi);
addValue("bancol", colBan);
String activityColors = HtmlUtils.separateWithQuotes(
"#" + colAct, "#" + colIna, "#" + colJoi, "#" + colBan
"#55ffff", "#ff55ff", "#ff5555", "#ffff55" //TODO Write Colors (enums) for Activity pie.
);
addValue("activitycolors", activityColors);
addValue("activityColors", activityColors);
String activityLabels = "[" + HtmlUtils.separateWithQuotes(
"Active", "Inactive", "Unknown", "Banned") + "]";
addValue("labelsactivity", activityLabels);
addValue("activitydata", Arrays.toString(counts));
// addValue("activitydata", Arrays.toString(counts)); // TODO Check if needed
addValue("playersActive", counts[0]);
addValue("active", counts[0]);
addValue("inactive", counts[1]);
addValue("joinleaver", counts[2]);
addValue("joinLeaver", counts[2]);
addValue("banned", counts[3]);
}

View File

@ -13,11 +13,12 @@ import java.util.Map;
/**
* Part responsible for all CommandUsage related analysis.
* <p>
* Command Usage Table.
* <p>
* Placeholder values can be retrieved using the get method.
* <p>
* Contains following place-holders: uniquecommands, totalcommands, commanduse
* Contains following placeholders after analyzed:
* ${commandCount} - (Number)
* ${commandUniqueCount} - (Number)
* ${tableBodyCommands} - Table body for CommandUsage table.
*
* @author Rsl1122
* @since 3.5.2
@ -32,10 +33,10 @@ public class CommandUsagePart extends RawData {
@Override
public void analyse() {
addValue("uniquecommands", String.valueOf(getUniqueCommands()));
addValue("totalcommands", String.valueOf(getCommandTotal()));
addValue("commandUniqueCount", String.valueOf(getUniqueCommands()));
addValue("commandCount", String.valueOf(getCommandTotal()));
String commandUsageTable = CommandUseTableCreator.createSortedCommandUseTable(commandUsage);
addValue("commanduse", HtmlUtils.removeXSS(commandUsageTable));
addValue("tableBodyCommands", HtmlUtils.removeXSS(commandUsageTable));
}
public int getUniqueCommands() {

View File

@ -1,12 +1,8 @@
package main.java.com.djrapitops.plan.data.analysis;
import com.djrapitops.plugin.utilities.Verify;
import main.java.com.djrapitops.plan.Settings;
import main.java.com.djrapitops.plan.utilities.FormatUtils;
import main.java.com.djrapitops.plan.utilities.HtmlUtils;
import java.util.Arrays;
/**
* Part responsible for all Gamemode usage related analysis.
* <p>
@ -20,6 +16,7 @@ import java.util.Arrays;
* @author Rsl1122
* @since 3.5.2
*/
@Deprecated
public class GamemodePart extends RawData {
private long survivalTime;
@ -41,51 +38,16 @@ public class GamemodePart extends RawData {
private void gamemodePiechart() {
long totalTime = survivalTime + creativeTime + adventureTime + spectatorTime;
addValue("gmtotal", FormatUtils.formatTimeAmount(totalTime));
double[] percentages = new double[]{
(survivalTime * 100.0) / totalTime,
(creativeTime * 100.0) / totalTime,
(adventureTime * 100.0) / totalTime,
(spectatorTime * 100.0) / totalTime
};
long[] times = new long[]{
survivalTime, creativeTime, adventureTime, spectatorTime
};
String col0 = Settings.HCOLOR_GMP_0.toString();
String col1 = Settings.HCOLOR_GMP_1.toString();
String col2 = Settings.HCOLOR_GMP_2.toString();
String col3 = Settings.HCOLOR_GMP_3.toString();
addValue("gm0col", col0);
addValue("gm1col", col1);
addValue("gm2col", col2);
addValue("gm3col", col3);
String gmColors = HtmlUtils.separateWithQuotes(
"#" + col0, "#" + col1, "#" + col2, "#" + col3
"#555", "#555", "#555", "#555" // TODO Write Colors (enum) variables for GameMode colors.
);
String gmLabels = "[" + HtmlUtils.separateWithQuotes(
"Survival", "Creative", "Adventure", "Spectator") + "]";
addValue("gmcolors", gmColors);
addValue("gmlabel", gmLabels);
// Adds Percentage indicators
for (int i = 0; i < percentages.length; i++) {
addValue("gm" + i, (int) (percentages[i]) + "%");
}
// Adds Value array for graph
addValue("gmdata", Arrays.toString(times));
// Adds formatted time amounts for each gamemode
for (int i = 0; i < times.length; i++) {
addValue("gm" + i + "total", FormatUtils.formatTimeAmount(times[i]));
}
addValue("gmColors", gmColors);
}
/**
* Adds time to a gamemode.
* @param gm Name of Gamemode
*
* @param gm Name of Gamemode
* @param amount milliseconds to add
* @throws IllegalArgumentException if gm is null
*/

View File

@ -8,11 +8,10 @@ import java.util.Map;
/**
* Part responsible for all Geolocation related analysis.
* <p>
* Player location World Choropleth map.
* <p>
* Placeholder values can be retrieved using the get method.
* <p>
* Contains following place-holders: geomapz, geomapcountries, geomapcodes
* Contains following placeholders after analyzed:
* ${geoMapSeries}
*
* @author Rsl1122
* @since 3.5.2
@ -39,7 +38,7 @@ public class GeolocationPart extends RawData {
@Override
public void analyse() {
addValue("geomapseries", WorldMapCreator.createDataSeries(geoCodeCounts));
addValue("geoMapSeries", WorldMapCreator.createDataSeries(geoCodeCounts));
}
public void addGeolocation(String country) {

View File

@ -12,15 +12,25 @@ import java.util.stream.Collectors;
/**
* Part responsible for all Player login related analysis.
* <p>
* Unique per Day, Unique, New Players, Logins
* <p>
* Placeholder values can be retrieved using the get method.
* <p>
* Contains following place-holders: totallogins, uniquejoinsday,
* uniquejoinsweek, uniquejoinsmonth, avguniquejoins, avguniquejoinsday,
* avguniquejoinsweek, avguniquejoinsmonth, npday, npweek, npmonth,
* npdataday, npdataweek, npdatamonth, newperday, newperdayday, newperdayweek, newperdaymonth
*
* Contains following placeholders after analyzed:
* ${playersAverage} - (Number)
* ${playersNewAverage} - (Number)
* <p>
* ${playersDay} - (Number)
* ${playersWeek} - (Number)
* ${playersMonth} - (Number)
* ${playersAverageDay} - (Number)
* ${playersAverageWeek} - (Number)
* ${playersAverageMonth} - (Number)
* ${playersNewDay} - (Number)
* ${playersNewWeek} - (Number)
* ${playersNewMonth} - (Number)
* ${playersNewAverageDay} - (Number)
* ${playersNewAverageWeek} - (Number)
* ${playersNewAverageMonth} - (Number)
* //TODO ${tableBodySessions}, ${sessionCount}, ${lastPeakTime}, ${playersLastPeak}, ${bestPeakTime}, ${playersBestPeak}
* @author Rsl1122
* @since 3.5.2
*/
@ -38,8 +48,6 @@ public class JoinInfoPart extends RawData {
@Override
public void analyse() {
addValue("totallogins", loginTimes);
newPlayers();
uniquePlayers();
uniquePlayersPerDay();
@ -50,9 +58,9 @@ public class JoinInfoPart extends RawData {
int uniqueWeek = AnalysisUtils.getUniqueJoins(sessions, TimeAmount.WEEK.ms());
int uniqueMonth = AnalysisUtils.getUniqueJoins(sessions, TimeAmount.MONTH.ms());
addValue("uniquejoinsday", uniqueDay);
addValue("uniquejoinsweek", uniqueWeek);
addValue("uniquejoinsmonth", uniqueMonth);
addValue("playersDay", uniqueDay);
addValue("playersWeek", uniqueWeek);
addValue("playersMonth", uniqueMonth);
}
private void uniquePlayersPerDay() {
@ -61,10 +69,10 @@ public class JoinInfoPart extends RawData {
int perDayWeek = AnalysisUtils.getUniqueJoinsPerDay(sessions, TimeAmount.WEEK.ms());
int perDayMonth = AnalysisUtils.getUniqueJoinsPerDay(sessions, TimeAmount.MONTH.ms());
addValue("avguniquejoins", perDay);
addValue("avguniquejoinsday", perDayDay);
addValue("avguniquejoinsweek", perDayWeek);
addValue("avguniquejoinsmonth", perDayMonth);
addValue("playersAverage", perDay);
addValue("playersAverageDay", perDayDay);
addValue("playersAverageWeek", perDayWeek);
addValue("playersAverageMonth", perDayMonth);
}
private void newPlayers() {
@ -73,19 +81,19 @@ public class JoinInfoPart extends RawData {
long newWeek = AnalysisUtils.getNewPlayers(registered, TimeAmount.WEEK.ms(), now);
long newMonth = AnalysisUtils.getNewPlayers(registered, TimeAmount.MONTH.ms(), now);
addValue("npday", newDay);
addValue("npweek", newWeek);
addValue("npmonth", newMonth);
addValue("playersNewDay", newDay);
addValue("playersNewWeek", newWeek);
addValue("playersNewMonth", newMonth);
long newPerDay = AnalysisUtils.getNewUsersPerDay(registered, -1);
long newPerDayDay = AnalysisUtils.getNewUsersPerDay(registered, TimeAmount.DAY.ms());
long newPerDayWeek = AnalysisUtils.getNewUsersPerDay(registered, TimeAmount.WEEK.ms());
long newPerDayMonth = AnalysisUtils.getNewUsersPerDay(registered, TimeAmount.MONTH.ms());
addValue("newperday", newPerDay);
addValue("newperdayday", newPerDayDay);
addValue("newperdayweek", newPerDayWeek);
addValue("newperdaymonth", newPerDayMonth);
addValue("playersNewAverage", newPerDay);
addValue("playersNewAverageDay", newPerDayDay);
addValue("playersNewAverageWeek", newPerDayWeek);
addValue("playersNewAverageMonth", newPerDayMonth);
}
public void addToLoginTimes() {

View File

@ -3,7 +3,6 @@ package main.java.com.djrapitops.plan.data.analysis;
import com.djrapitops.plugin.utilities.Verify;
import main.java.com.djrapitops.plan.data.KillData;
import main.java.com.djrapitops.plan.utilities.MiscUtils;
import main.java.com.djrapitops.plan.utilities.analysis.MathUtils;
import java.util.HashMap;
import java.util.List;
@ -13,24 +12,23 @@ import java.util.UUID;
/**
* Part responsible for all Death related analysis.
* <p>
* Totals
* <p>
* Placeholder values can be retrieved using the get method.
* <p>
* Contains following place-holders: deaths, mobkills, playerkills, avgdeaths, avgmobkills, avgplayerkills
* Contains following placeholders after analyzed:
* ${killCount} - (Number)
* ${mobKillCount} - (Number)
* ${deathCount} - (Number)
*
* @author Rsl1122
* @since 3.5.2
*/
public class KillPart extends RawData {
private final PlayerCountPart playerCountPart;
private final Map<UUID, List<KillData>> playerKills;
private long mobKills;
private long deaths;
public KillPart(PlayerCountPart playerCountPart) {
this.playerCountPart = playerCountPart;
public KillPart() {
playerKills = new HashMap<>();
mobKills = 0;
deaths = 0;
@ -38,14 +36,10 @@ public class KillPart extends RawData {
@Override
public void analyse() {
addValue("deaths", deaths);
addValue("mobkills", mobKills);
addValue("deathCount", deaths);
addValue("mobKillCount", mobKills);
int playerKillAmount = getAllPlayerKills().size();
addValue("playerkills", playerKillAmount);
int playerCount = playerCountPart.getPlayerCount();
addValue("avgdeaths", MathUtils.averageLong(deaths, playerCount));
addValue("avgmobkills", MathUtils.averageLong(mobKills, playerCount));
addValue("avgplayerkills", MathUtils.averageLong(playerKillAmount, playerCount));
addValue("killCount", playerKillAmount);
}
/**

View File

@ -10,11 +10,11 @@ import java.util.UUID;
/**
* Part responsible for counting players.
* <p>
* Total player count, op count
* <p>
* Placeholder values can be retrieved using the get method.
* <p>
* Contains following place-holders: activitytotal, ops
* Contains following placeholders after analyzed:
* ${playersTotal}
* //TODO ${playersOnline}, ${playersMax}
*
* @author Rsl1122
* @since 3.5.2
@ -31,8 +31,7 @@ public class PlayerCountPart extends RawData {
@Override
public void analyse() {
addValue("activitytotal", uuids.size());
addValue("ops", ops.size());
addValue("playersTotal", uuids.size());
}
public void addPlayer(UUID uuid) {

View File

@ -1,33 +1,29 @@
package main.java.com.djrapitops.plan.data.analysis;
import main.java.com.djrapitops.plan.utilities.FormatUtils;
import main.java.com.djrapitops.plan.utilities.analysis.MathUtils;
/**
* Part responsible for all Playtime related analysis.
* <p>
* Placeholder values can be retrieved using the get method.
* <p>
* Contains following place-holders: totalplaytime, avgplaytime
* Contains following placeholders after analyzed:
* ${playtimeTotal} - Formatted time amount
*
* @author Rsl1122
* @since 3.5.2
*/
public class PlaytimePart extends RawData {
private final PlayerCountPart playerCount;
private long totalPlaytime;
public PlaytimePart(PlayerCountPart part) {
playerCount = part;
public PlaytimePart() {
totalPlaytime = 0;
}
@Override
public void analyse() {
addValue("totalplaytime", FormatUtils.formatTimeAmount(totalPlaytime));
final long averagePlaytime = MathUtils.averageLong(totalPlaytime, playerCount.getPlayerCount());
addValue("avgplaytime", FormatUtils.formatTimeAmount(averagePlaytime));
addValue("playtimeTotal", FormatUtils.formatTimeAmount(totalPlaytime));
}
public void addToPlaytime(long amount) {

View File

@ -87,7 +87,7 @@ public abstract class RawData {
/**
* Used to get the value for a placeholder without the placeholder prefix and suffix.
*
* @param key placeholder without the prefix and suffix
* @param key placeholder name without ${ and }
* @return Value the placeholder should be replaced with or null.
*/
public String get(String key) {

View File

@ -7,6 +7,7 @@ import main.java.com.djrapitops.plan.ui.html.graphs.CPUGraphCreator;
import main.java.com.djrapitops.plan.ui.html.graphs.RamGraphCreator;
import main.java.com.djrapitops.plan.ui.html.graphs.TPSGraphCreator;
import main.java.com.djrapitops.plan.ui.html.graphs.WorldLoadGraphCreator;
import main.java.com.djrapitops.plan.ui.theme.Colors;
import main.java.com.djrapitops.plan.utilities.FormatUtils;
import main.java.com.djrapitops.plan.utilities.MiscUtils;
import main.java.com.djrapitops.plan.utilities.analysis.MathUtils;
@ -16,13 +17,31 @@ import java.util.List;
/**
* Part responsible for all TPS related analysis.
* <p>
* Ticks Per Second Graphs
* <p>
* Placeholder values can be retrieved using the get method.
* <p>
* Contains following place-holders: tpsscatterday, tpsscatterweek, cpuscatterday, cpuscatterweek, averagetps(-week),
* averagetpsday, averagecpuday, averagecpuweek, averagememoryday, averagememoryweek, averageentitiesday, averageentitiesweek,
* averagechunksday, averagechunkweek, ramscatterday, ramscatterweek
* Contains following placeholders after being analyzed:
* ${tpsSeries} - HighCharts data
* ${cpuSeries} - HighCharts data
* ${ramSeries} - HighCharts data
* ${entitySeries} - HighCharts data
* ${chunkSeries} - HighCharts data
* <p>
* ${tpsAverageDay} - (Number)
* ${tpsAverageWeek} - (Number)
* ${cpuAverageDay} - (Number)%
* ${cpuAverageWeek} - (Number)%
* ${ramAverageDay} - (Number) MB
* ${ramAverageWeek} - (Number) MB
* ${entityAverageDay} - (Number)
* ${entityAverageWeek} - (Number)
* ${chunkAverageDay} - (Number)
* ${chunkAverageWeek} - (Number)
* <p>
* ${tpsMedium} - (Number) Color Threshold for Medium TPS
* ${tpsHigh} - (Number) Color Threshold for High TPS
* ${tpsLowColor} - Color of Low TPS
* ${tpsMediumColor} - Color of Low TPS
* ${tpsHighColor} - Color of Low TPS
*
* @author Rsl1122
* @since 3.5.2
@ -41,17 +60,17 @@ public class TPSPart extends RawData {
List<TPS> week = TPSGraphCreator.filterTPS(tpsData, now - TimeAmount.WEEK.ms());
List<TPS> day = TPSGraphCreator.filterTPS(tpsData, now - TimeAmount.DAY.ms());
addValue("tpshighcol", "#"+ Settings.HCOLOR_TPS_HIGH);
addValue("tpsmediumcol", "#"+ Settings.HCOLOR_TPS_MED);
addValue("tpslowcol", "#"+ Settings.HCOLOR_TPS_LOW);
addValue("tpsmedium", Settings.TPS_GRAPH_MED.getNumber());
addValue("tpshigh", Settings.TPS_GRAPH_HIGH.getNumber());
addValue("tpsHighColor", Colors.TPS_HIGH.getColor());
addValue("tpsMediumColor", Colors.TPS_MED.getColor());
addValue("tpsLowColor", Colors.TPS_LOW.getColor());
addValue("tpsMedium", Settings.THEME_GRAPH_TPS_THRESHOLD_MED.getNumber());
addValue("tpsHigh", Settings.THEME_GRAPH_TPS_THRESHOLD_HIGH.getNumber());
addValue("tpsseries", TPSGraphCreator.buildSeriesDataString(tpsData));
addValue("cpuseries", CPUGraphCreator.buildSeriesDataString(tpsData));
addValue("ramseries", RamGraphCreator.buildSeriesDataString(tpsData));
addValue("entityseries", WorldLoadGraphCreator.buildSeriesDataStringEntities(tpsData));
addValue("chunkseries", WorldLoadGraphCreator.buildSeriesDataStringChunks(tpsData));
addValue("tpsSeries", TPSGraphCreator.buildSeriesDataString(tpsData));
addValue("cpuSeries", CPUGraphCreator.buildSeriesDataString(tpsData));
addValue("ramSeries", RamGraphCreator.buildSeriesDataString(tpsData));
addValue("entitySeries", WorldLoadGraphCreator.buildSeriesDataStringEntities(tpsData));
addValue("chunkSeries", WorldLoadGraphCreator.buildSeriesDataStringChunks(tpsData));
double averageTPSWeek = MathUtils.averageDouble(week.stream().map(TPS::getTicksPerSecond));
double averageTPSDay = MathUtils.averageDouble(day.stream().map(TPS::getTicksPerSecond));
@ -68,21 +87,20 @@ public class TPSPart extends RawData {
double averageChunksLoadedWeek = MathUtils.averageInt(week.stream().map(TPS::getChunksLoaded).filter(i -> i != 0));
double averageChunksLoadedDay = MathUtils.averageInt(day.stream().map(TPS::getChunksLoaded).filter(i -> i != 0));
addValue("averagetps", FormatUtils.cutDecimals(averageTPSWeek)); //Staying for backwards compatibility
addValue("averagetpsweek", FormatUtils.cutDecimals(averageTPSWeek));
addValue("averagetpsday", FormatUtils.cutDecimals(averageTPSDay));
addValue("tpsAverageWeek", FormatUtils.cutDecimals(averageTPSWeek));
addValue("tpsAverageDay", FormatUtils.cutDecimals(averageTPSDay));
addValue("averagecpuweek", averageCPUWeek >= 0 ? FormatUtils.cutDecimals(averageCPUWeek) + "%" : "Unavailable");
addValue("averagecpuday", averageCPUDay >= 0 ? FormatUtils.cutDecimals(averageCPUDay) + "%" : "Unavailable");
addValue("cpuAverageWeek", averageCPUWeek >= 0 ? FormatUtils.cutDecimals(averageCPUWeek) + "%" : "Unavailable");
addValue("cpuAverageDay", averageCPUDay >= 0 ? FormatUtils.cutDecimals(averageCPUDay) + "%" : "Unavailable");
addValue("averagememoryweek", FormatUtils.cutDecimals(averageUsedMemoryWeek));
addValue("averagememoryday", FormatUtils.cutDecimals(averageUsedMemoryDay));
addValue("ramAverageWeek", FormatUtils.cutDecimals(averageUsedMemoryWeek));
addValue("ramAverageDay", FormatUtils.cutDecimals(averageUsedMemoryDay));
addValue("averageentitiesweek", FormatUtils.cutDecimals(averageEntityCountWeek));
addValue("averageentitiesday", FormatUtils.cutDecimals(averageEntityCountDay));
addValue("entityAverageWeek", FormatUtils.cutDecimals(averageEntityCountWeek));
addValue("entityAverageDay", FormatUtils.cutDecimals(averageEntityCountDay));
addValue("averagechunksweek", FormatUtils.cutDecimals(averageChunksLoadedWeek));
addValue("averagechunksday", FormatUtils.cutDecimals(averageChunksLoadedDay));
addValue("chunkAverageWeek", FormatUtils.cutDecimals(averageChunksLoadedWeek));
addValue("chunkAverageDay", FormatUtils.cutDecimals(averageChunksLoadedDay));
}
public List<TPS> getTpsData() {

View File

@ -14,7 +14,9 @@ import java.util.Map;
* <p>
* Placeholder values can be retrieved using the get method.
* <p>
* Contains following place-holders: worldtotal, worldseries
* Contains following placeholders after analyzed:
* ${worldTotal} - Total playtime for all worlds
* ${worldSeries} - Data for HighCharts
*
* @author Rsl1122
* @since 3.6.0
@ -30,8 +32,8 @@ public class WorldPart extends RawData {
@Override
protected void analyse() {
WorldTimes t = new WorldTimes(worldTimes);
addValue("worldtotal", FormatUtils.formatTimeAmount(t.getTotal()));
addValue("worldseries", WorldPieCreator.createSeriesData(worldTimes));
addValue("worldTotal", FormatUtils.formatTimeAmount(t.getTotal()));
addValue("worldSeries", WorldPieCreator.createSeriesData(worldTimes));
}
public void addToWorld(String worldName, long playTime) {

View File

@ -4,11 +4,9 @@ import com.djrapitops.plugin.command.CommandUtils;
import com.djrapitops.plugin.command.ISender;
import com.djrapitops.plugin.utilities.player.IPlayer;
import main.java.com.djrapitops.plan.Plan;
import main.java.com.djrapitops.plan.Settings;
import main.java.com.djrapitops.plan.data.AnalysisData;
import main.java.com.djrapitops.plan.locale.Locale;
import main.java.com.djrapitops.plan.locale.Msg;
import main.java.com.djrapitops.plan.ui.text.TextUI;
import main.java.com.djrapitops.plan.utilities.HtmlUtils;
import main.java.com.djrapitops.plan.utilities.analysis.Analysis;
import org.bukkit.entity.Player;
@ -71,22 +69,19 @@ public class AnalysisCacheHandler {
}
public void sendAnalysisMessage(ISender sender) {
boolean textUI = Settings.USE_ALTERNATIVE_UI.isTrue();
sender.sendMessage(Locale.get(Msg.CMD_HEADER_ANALYZE).toString());
if (textUI) {
sender.sendMessage(TextUI.getAnalysisMessages());
// Link
String url = HtmlUtils.getServerAnalysisUrlWithProtocol();
String message = Locale.get(Msg.CMD_INFO_LINK).toString();
boolean console = !CommandUtils.isPlayer(sender);
if (console) {
sender.sendMessage(message + url);
} else {
// Link
String url = HtmlUtils.getServerAnalysisUrlWithProtocol();
String message = Locale.get(Msg.CMD_INFO_LINK).toString();
boolean console = !CommandUtils.isPlayer(sender);
if (console) {
sender.sendMessage(message + url);
} else {
sender.sendMessage(message);
sender.sendLink(" ", Locale.get(Msg.CMD_INFO_CLICK_ME).toString(), url);
}
sender.sendMessage(message);
sender.sendLink(" ", Locale.get(Msg.CMD_INFO_CLICK_ME).toString(), url);
}
sender.sendMessage(Locale.get(Msg.CMD_CONSTANT_FOOTER).toString());
}

View File

@ -4,7 +4,6 @@ import com.djrapitops.plugin.task.AbsRunnable;
import com.djrapitops.plugin.utilities.player.IPlayer;
import main.java.com.djrapitops.plan.Log;
import main.java.com.djrapitops.plan.Plan;
import main.java.com.djrapitops.plan.Settings;
import main.java.com.djrapitops.plan.data.TPS;
import main.java.com.djrapitops.plan.data.UserData;
import main.java.com.djrapitops.plan.data.handling.info.HandlingInfo;
@ -123,17 +122,6 @@ public class DataCacheHandler extends SessionCache {
* @throws IllegalStateException BukkitScheduler is in a wrong state.
*/
public void startAsyncPeriodicSaveTask() {
int minutes = Settings.SAVE_CACHE_MIN.getNumber();
if (minutes <= 0) {
minutes = 5;
}
final int clearAfterXsaves;
int configValue = Settings.CLEAR_CACHE_X_SAVES.getNumber();
if (configValue <= 1) {
clearAfterXsaves = 2;
} else {
clearAfterXsaves = configValue;
}
DataCacheHandler handler = this;
plugin.getRunnableFactory().createNew(new AbsRunnable("PeriodicCacheSaveTask") {
private int timesSaved = 0;
@ -148,9 +136,6 @@ public class DataCacheHandler extends SessionCache {
Log.debug("Database", "Periodic Cache Save: " + dataCache.size());
handler.saveHandlerDataToCache();
handler.saveCachedUserData();
if (timesSaved % clearAfterXsaves == 0) {
handler.clearCache();
}
saveCommandUse();
saveUnsavedTPSHistory();
timesSaved++;
@ -160,7 +145,7 @@ public class DataCacheHandler extends SessionCache {
periodicTaskIsSaving = false;
}
}
}).runTaskTimerAsynchronously(60L * 20L * minutes, 60L * 20L * minutes);
}).runTaskTimerAsynchronously(60L * 20L * 5, 60L * 20L * 5);
}
/**

View File

@ -1,7 +1,6 @@
package main.java.com.djrapitops.plan.data.time;
import com.djrapitops.plugin.utilities.Verify;
import main.java.com.djrapitops.plan.database.tables.GMTimesTable;
import java.util.Map;
@ -13,6 +12,12 @@ import java.util.Map;
*/
public class GMTimes extends TimeKeeper {
// TODO Make private once GMTimesTable is removed
public static final String SURVIVAL = "SURVIVAL";
public static final String CREATIVE = "CREATIVE";
public static final String ADVENTURE = "ADVENTURE";
public static final String SPECTATOR = "SPECTATOR";
public GMTimes(Map<String, Long> times, String lastState, long lastStateChange) {
super(times, lastState, lastStateChange);
}
@ -33,6 +38,10 @@ public class GMTimes extends TimeKeeper {
super();
}
public static String[] getGMKeyArray() {
return new String[]{SURVIVAL, CREATIVE, ADVENTURE, SPECTATOR};
}
/**
* Sets times for all 4 gamemodes.
* <p>
@ -47,7 +56,7 @@ public class GMTimes extends TimeKeeper {
*/
public void setAllGMTimes(long... times) {
Verify.nullCheck(times);
String[] gms = GMTimesTable.getGMKeyArray();
String[] gms = getGMKeyArray();
int size = times.length;
for (int i = 0; i < 4; i++) {
if (i >= size) {
@ -59,15 +68,15 @@ public class GMTimes extends TimeKeeper {
}
public void resetTimes(long playtime) {
resetState("SURVIVAL", playtime);
resetState("CREATIVE");
resetState("ADVENTURE");
resetState("SPECTATOR");
resetState(SURVIVAL, playtime);
resetState(CREATIVE);
resetState(ADVENTURE);
resetState(SPECTATOR);
}
@Override
public String getState() {
String state = super.getState();
return state != null ? state : "SURVIVAL";
return state != null ? state : SURVIVAL;
}
}

View File

@ -26,11 +26,6 @@ public class GMTimesTable extends UserIDTable {
private final String columnAdventureTime;
private final String columnSpectatorTime;
private static final String SURVIVAL = "SURVIVAL";
private static final String CREATIVE = "CREATIVE";
private static final String ADVENTURE = "ADVENTURE";
private static final String SPECTATOR = "SPECTATOR";
/**
* @param db
@ -45,10 +40,6 @@ public class GMTimesTable extends UserIDTable {
columnSpectatorTime = "SPECTATOR";
}
public static String[] getGMKeyArray() {
return new String[]{SURVIVAL, CREATIVE, ADVENTURE, SPECTATOR};
}
/**
* @return
*/
@ -95,10 +86,10 @@ public class GMTimesTable extends UserIDTable {
HashMap<String, Long> times = new HashMap<>();
while (set.next()) {
times.put(SURVIVAL, set.getLong(columnSurvivalTime));
times.put(CREATIVE, set.getLong(columnCreativeTime));
times.put(ADVENTURE, set.getLong(columnAdventureTime));
times.put(SPECTATOR, set.getLong(columnSpectatorTime));
times.put(GMTimes.SURVIVAL, set.getLong(columnSurvivalTime));
times.put(GMTimes.CREATIVE, set.getLong(columnCreativeTime));
times.put(GMTimes.ADVENTURE, set.getLong(columnAdventureTime));
times.put(GMTimes.SPECTATOR, set.getLong(columnSpectatorTime));
}
return times;
@ -123,10 +114,10 @@ public class GMTimesTable extends UserIDTable {
continue;
}
gmTimes.put(SURVIVAL, set.getLong(columnSurvivalTime));
gmTimes.put(CREATIVE, set.getLong(columnCreativeTime));
gmTimes.put(ADVENTURE, set.getLong(columnAdventureTime));
gmTimes.put(SPECTATOR, set.getLong(columnSpectatorTime));
gmTimes.put(GMTimes.SURVIVAL, set.getLong(columnSurvivalTime));
gmTimes.put(GMTimes.CREATIVE, set.getLong(columnCreativeTime));
gmTimes.put(GMTimes.ADVENTURE, set.getLong(columnAdventureTime));
gmTimes.put(GMTimes.SPECTATOR, set.getLong(columnSpectatorTime));
times.put(id, gmTimes);
}
@ -148,7 +139,7 @@ public class GMTimesTable extends UserIDTable {
}
PreparedStatement statement = null;
String[] gms = getGMKeyArray();
String[] gms = GMTimes.getGMKeyArray();
int update;
try {
@ -233,7 +224,7 @@ public class GMTimesTable extends UserIDTable {
return;
}
String[] gms = getGMKeyArray();
String[] gms = GMTimes.getGMKeyArray();
Set<Integer> savedIDs = getSavedIDs();
PreparedStatement statement = null;
@ -300,7 +291,7 @@ public class GMTimesTable extends UserIDTable {
return;
}
String[] gms = getGMKeyArray();
String[] gms = GMTimes.getGMKeyArray();
PreparedStatement statement = null;
try {
@ -338,7 +329,7 @@ public class GMTimesTable extends UserIDTable {
}
PreparedStatement statement = null;
String[] gms = getGMKeyArray();
String[] gms = GMTimes.getGMKeyArray();
try {
statement = prepareStatement("INSERT INTO " + tableName + " ("
+ columnUserID + ", "

View File

@ -2,7 +2,6 @@ package main.java.com.djrapitops.plan.queue;
import com.djrapitops.plugin.utilities.Verify;
import main.java.com.djrapitops.plan.Log;
import main.java.com.djrapitops.plan.Settings;
import main.java.com.djrapitops.plan.data.cache.DataCacheHandler;
import main.java.com.djrapitops.plan.locale.Locale;
import main.java.com.djrapitops.plan.locale.Msg;
@ -55,7 +54,7 @@ public class DataCacheClearQueue extends Queue<UUID> {
try {
queue.addAll(uuids.stream().filter(Objects::nonNull).collect(Collectors.toList()));
} catch (IllegalStateException e) {
Log.error(Locale.get(Msg.RUN_WARN_QUEUE_SIZE).parse("Clear Queue", Settings.PROCESS_CLEAR_LIMIT.getNumber()));
Log.error(Locale.get(Msg.RUN_WARN_QUEUE_SIZE).parse("Clear Queue", 20000));
}
}
}

View File

@ -3,7 +3,6 @@ package main.java.com.djrapitops.plan.queue;
import com.djrapitops.plugin.utilities.Verify;
import main.java.com.djrapitops.plan.Log;
import main.java.com.djrapitops.plan.Plan;
import main.java.com.djrapitops.plan.Settings;
import main.java.com.djrapitops.plan.data.cache.DBCallableProcessor;
import main.java.com.djrapitops.plan.database.Database;
import main.java.com.djrapitops.plan.locale.Locale;
@ -46,7 +45,7 @@ public class DataCacheGetQueue extends Queue<Map<UUID, List<DBCallableProcessor>
map.put(uuid, Arrays.asList(processors));
queue.add(map);
} catch (IllegalStateException e) {
Log.error(Locale.get(Msg.RUN_WARN_QUEUE_SIZE).parse("Get Queue", Settings.PROCESS_GET_LIMIT.getNumber()));
Log.error(Locale.get(Msg.RUN_WARN_QUEUE_SIZE).parse("Get Queue", 20000));
}
}

View File

@ -3,7 +3,6 @@ package main.java.com.djrapitops.plan.queue;
import com.djrapitops.plugin.utilities.Verify;
import main.java.com.djrapitops.plan.Log;
import main.java.com.djrapitops.plan.Plan;
import main.java.com.djrapitops.plan.Settings;
import main.java.com.djrapitops.plan.data.UserData;
import main.java.com.djrapitops.plan.data.cache.DataCacheHandler;
import main.java.com.djrapitops.plan.database.Database;
@ -45,7 +44,7 @@ public class DataCacheSaveQueue extends Queue<UserData> {
try {
queue.add(data);
} catch (IllegalStateException e) {
Log.error(Locale.get(Msg.RUN_WARN_QUEUE_SIZE).parse("Save Queue", Settings.PROCESS_SAVE_LIMIT.getNumber()));
Log.error(Locale.get(Msg.RUN_WARN_QUEUE_SIZE).parse("Save Queue", 20000));
}
}

View File

@ -11,6 +11,7 @@ import java.util.stream.Collectors;
/**
* @author Rsl1122
*/
@Deprecated // Not going to be used TODO REMOVE
public class SessionLengthDistributionGraphCreator {
/**

View File

@ -29,10 +29,9 @@ public class CommandUseTableCreator {
StringBuilder html = new StringBuilder();
if (sorted.isEmpty()) {
html.append(Html.ERROR_TABLE_2.parse());
html.append(Html.TABLELINE_2.parse("No Commands", ""));
} else {
Collections.reverse(sorted);
int i = 0;
for (String[] values : sorted) {
if (i >= 500) {

View File

@ -1,6 +1,5 @@
package main.java.com.djrapitops.plan.ui.html.tables;
import main.java.com.djrapitops.plan.Settings;
import main.java.com.djrapitops.plan.data.UserData;
import main.java.com.djrapitops.plan.ui.html.Html;
import main.java.com.djrapitops.plan.utilities.FormatUtils;
@ -30,7 +29,6 @@ public class PlayersTableCreator {
StringBuilder html = new StringBuilder();
long now = MiscUtils.getTime();
boolean showImages = Settings.PLAYERLIST_SHOW_IMAGES.isTrue();
int i = 0;
for (UserData uData : data) {
@ -45,10 +43,8 @@ public class PlayersTableCreator {
String activityString = getActivityString(isBanned, isUnknown, isActive);
String img = showImages ? Html.MINOTAR_SMALL_IMG.parse(uData.getName()) : "";
html.append(Html.TABLELINE_PLAYERS.parse(
img + Html.LINK.parse(HtmlUtils.getInspectUrl(uData.getName()), uData.getName()),
Html.LINK.parse(HtmlUtils.getRelativeInspectUrl(uData.getName()), uData.getName()),
activityString,
String.valueOf(uData.getPlayTime()), FormatUtils.formatTimeAmount(uData.getPlayTime()),
String.valueOf(uData.getLoginTimes()),

View File

@ -58,7 +58,7 @@ public enum Theme {
Theme(String... colors) {
int length = colors.length;
if (length != 19) {
if (length < Colors.values().length) {
Log.error("Not All colors (" + length + ") were specified in the theme file: " + name());
Log.error("If the theme is used it WILL CAUSE EXCEPTIONS.");
}
@ -94,4 +94,13 @@ public enum Theme {
Files.write(themeCss.toPath(), Collections.singletonList(t.replaceThemeColors(css)));
}
}
public static String replaceColors(String resourceString) {
Theme def = Theme.DEFAULT;
String replaced = resourceString;
for (Colors c : Colors.values()) {
replaced = replaced.replace("#" + def.getColor(c.getId()), c.getColor());
}
return replaced;
}
}

View File

@ -124,7 +124,9 @@ public class WebServer {
}
response = getResponse(target, user);
if (response instanceof CSSResponse) {
responseHeaders.set("Content-Type", "text/css");
}
sendData(responseHeaders, exchange, response);
} catch (Exception e) {
Log.toLog(this.getClass().getName(), e);
@ -352,11 +354,25 @@ public class WebServer {
}
}
boolean javaScriptRequest = target.endsWith(".js");
boolean cssRequest = target.endsWith(".css");
String[] args = target.split("/");
if (args.length < 2) {
return rootPageResponse(user);
}
if (javaScriptRequest) {
return getJSResponse(args[args.length - 1]);
}
if (cssRequest) {
try {
return new CSSResponse("main.css");
} catch (Exception e) {
return new InternalErrorResponse(e, target);
}
}
String page = args[1];
switch (page) {
case "players":
@ -370,6 +386,14 @@ public class WebServer {
}
}
private Response getJSResponse(String fileName) {
try {
return new JavaScriptResponse(fileName);
} catch (Exception e) {
return new InternalErrorResponse(e, fileName);
}
}
private Response forbiddenResponse(int permLevel, int required) {
return PageCacheHandler.loadPage("forbidden", () -> {
ForbiddenResponse response403 = new ForbiddenResponse();

View File

@ -1,6 +1,7 @@
package main.java.com.djrapitops.plan.ui.webserver.response;
import main.java.com.djrapitops.plan.ui.html.DataRequestHandler;
import main.java.com.djrapitops.plan.ui.theme.Theme;
/**
* @author Rsl1122
@ -10,6 +11,6 @@ public class AnalysisPageResponse extends Response {
public AnalysisPageResponse(DataRequestHandler h) {
super.setHeader("HTTP/1.1 200 OK");
super.setContent(h.getServerHtml());
super.setContent(Theme.replaceColors(h.getServerHtml()));
}
}

View File

@ -0,0 +1,15 @@
package main.java.com.djrapitops.plan.ui.webserver.response;
import main.java.com.djrapitops.plan.ui.theme.Theme;
/**
* @author Rsl1122
* @since 4.0.0
*/
public class CSSResponse extends FileResponse {
public CSSResponse(String fileName) {
super(fileName);
setContent(Theme.replaceColors(getContent()));
}
}

View File

@ -0,0 +1,31 @@
/*
* 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.ui.webserver.response;
import main.java.com.djrapitops.plan.Log;
import main.java.com.djrapitops.plan.utilities.file.FileUtil;
import java.io.FileNotFoundException;
/**
* Response class for returning file contents.
*
* Created to remove copy-paste.
*
* @author Rsl1122
* @since 4.0.0
*/
public class FileResponse extends Response {
public FileResponse(String fileName) {
super.setHeader("HTTP/1.1 200 OK");
try {
super.setContent(FileUtil.getStringFromResource(fileName));
} catch (FileNotFoundException e) {
Log.toLog(this.getClass().getName(), e);
super.setContent("");
}
}
}

View File

@ -1,6 +1,7 @@
package main.java.com.djrapitops.plan.ui.webserver.response;
import main.java.com.djrapitops.plan.ui.html.DataRequestHandler;
import main.java.com.djrapitops.plan.ui.theme.Theme;
import java.util.UUID;
@ -12,6 +13,6 @@ public class InspectPageResponse extends Response {
public InspectPageResponse(DataRequestHandler h, UUID uuid) {
super.setHeader("HTTP/1.1 200 OK");
super.setContent(h.getInspectHtml(uuid));
super.setContent(Theme.replaceColors(h.getInspectHtml(uuid)));
}
}

View File

@ -1,23 +1,12 @@
package main.java.com.djrapitops.plan.ui.webserver.response;
import main.java.com.djrapitops.plan.Log;
import main.java.com.djrapitops.plan.utilities.HtmlUtils;
import java.io.FileNotFoundException;
/**
* @author Rsl1122
* @since 3.5.2
*/
public class JavaScriptResponse extends Response {
public class JavaScriptResponse extends FileResponse {
public JavaScriptResponse(String resource) {
super.setHeader("HTTP/1.1 200 OK");
try {
super.setContent(HtmlUtils.getStringFromResource(resource));
} catch (FileNotFoundException e) {
Log.toLog(this.getClass().getName(), e);
super.setContent("");
}
public JavaScriptResponse(String fileName) {
super(fileName);
}
}

View File

@ -30,7 +30,9 @@ public class HtmlUtils {
* @param fileName
* @return
* @throws FileNotFoundException
* @deprecated Use FileUtil
*/
@Deprecated
public static String getStringFromResource(String fileName) throws FileNotFoundException {
return FileUtil.getStringFromResource(fileName);
}
@ -42,7 +44,7 @@ public class HtmlUtils {
*/
public static String replacePlaceholders(String html, Map<String, Serializable> replaceMap) {
StrSubstitutor sub = new StrSubstitutor(replaceMap);
sub.setEnableSubstitutionInVariables(true);
return sub.replace(html);
}
@ -119,6 +121,7 @@ public class HtmlUtils {
* @param placeholders
* @return
*/
// TODO REWRITE
public static String getPluginsTabLayout(List<String> pluginNames, Map<String, List<String>> placeholders) {
boolean sizeIsEvenNumber = pluginNames.size() % 2 == 0;
StringBuilder html = new StringBuilder();

View File

@ -6,8 +6,8 @@ import main.java.com.djrapitops.plan.data.AnalysisData;
import main.java.com.djrapitops.plan.data.SessionData;
import main.java.com.djrapitops.plan.data.UserData;
import main.java.com.djrapitops.plan.data.analysis.GamemodePart;
import main.java.com.djrapitops.plan.data.time.GMTimes;
import main.java.com.djrapitops.plan.data.time.WorldTimes;
import main.java.com.djrapitops.plan.database.tables.GMTimesTable;
import main.java.com.djrapitops.plan.locale.Locale;
import main.java.com.djrapitops.plan.locale.Msg;
import main.java.com.djrapitops.plan.ui.html.graphs.PlayerActivityGraphCreator;
@ -42,23 +42,16 @@ public class PlaceholderUtils {
public static Map<String, Serializable> getAnalysisReplaceRules(AnalysisData data) {
HashMap<String, Serializable> replaceMap = new HashMap<>();
replaceMap.putAll(data.getReplaceMap());
replaceMap.put("plugins", data.replacePluginsTabLayout());
replaceMap.put("tabContentPlugins", data.replacePluginsTabLayout());
replaceMap.put("refresh", FormatUtils.formatTimeAmountDifference(data.getRefreshDate(), MiscUtils.getTime()));
replaceMap.put("refreshlong", String.valueOf(data.getRefreshDate()));
// TODO Refresh time for Network pages
// replaceMap.put("refresh", FormatUtils.formatTimeAmountDifference(data.getRefreshDate(), MiscUtils.getTime()));
// replaceMap.put("refreshlong", String.valueOf(data.getRefreshDate()));
replaceMap.put("servername", Settings.SERVER_NAME.toString());
replaceMap.put("serverName", Settings.SERVER_NAME.toString());
replaceMap.put("timezone", MiscUtils.getTimeZoneOffsetHours());
// Html Theme colors
String[] colors = new String[]{Settings.HCOLOR_MAIN.toString(), Settings.HCOLOR_MAIN_DARK.toString(), Settings.HCOLOR_SEC.toString(), Settings.HCOLOR_TER.toString(), Settings.HCOLOR_TER_DARK.toString()};
String[] defaultCols = new String[]{"348e0f", "267F00", "5cb239", "89c471", "5da341"};
for (int i = 0; i < colors.length; i++) {
if (!defaultCols[i].equals(colors[i])) {
replaceMap.put("#" + defaultCols[i], "#" + colors[i]);
}
}
replaceMap.put("timeZone", MiscUtils.getTimeZoneOffsetHours());
// TODO Add Theme Replace somewhere when getting
return replaceMap;
}
@ -73,9 +66,7 @@ public class PlaceholderUtils {
HashMap<String, Serializable> replaceMap = new HashMap<>();
replaceMap.put("timezone", MiscUtils.getTimeZoneOffsetHours());
boolean showIPandUUID = Settings.SECURITY_IP_UUID.isTrue();
UUID uuid = data.getUuid();
replaceMap.put("uuid", (showIPandUUID ? uuid.toString() : "Hidden (Config)"));
replaceMap.put("lastseen", FormatUtils.formatTimeStampYear(data.getLastPlayed()));
replaceMap.put("logintimes", data.getLoginTimes());
replaceMap.put("geoloc", data.getGeolocation());
@ -84,7 +75,7 @@ public class PlaceholderUtils {
replaceMap.put("active", isActive ? Locale.get(Msg.HTML_ACTIVE).parse() : Locale.get(Msg.HTML_INACTIVE).parse());
GamemodePart gmPart = new GamemodePart();
Map<String, Long> gmTimes = data.getGmTimes().getTimes();
String[] gms = GMTimesTable.getGMKeyArray();
String[] gms = GMTimes.getGMKeyArray();
for (String gm : gms) {
Long time = gmTimes.get(gm);
if (time != null) {
@ -94,7 +85,6 @@ public class PlaceholderUtils {
gmPart.analyse();
replaceMap.putAll(gmPart.getReplaceMap());
replaceMap.put("ips", showIPandUUID ? data.getIps().toString() : "Hidden (Config)");
replaceMap.put("nicknames", HtmlUtils.removeXSS(HtmlUtils.swapColorsToSpan(data.getNicknames().toString())));
replaceMap.put("name", data.getName());
replaceMap.put("registered", FormatUtils.formatTimeStampYear(data.getRegistered()));

View File

@ -4,7 +4,6 @@ import com.djrapitops.plugin.task.AbsRunnable;
import com.djrapitops.plugin.utilities.Verify;
import main.java.com.djrapitops.plan.Log;
import main.java.com.djrapitops.plan.Plan;
import main.java.com.djrapitops.plan.Settings;
import main.java.com.djrapitops.plan.data.*;
import main.java.com.djrapitops.plan.data.additional.AnalysisType;
import main.java.com.djrapitops.plan.data.additional.HookHandler;
@ -162,9 +161,7 @@ public class Analysis {
Log.logDebug("Analysis", time);
if (Settings.ANALYSIS_LOG_FINISHED.isTrue()) {
Log.info(Locale.get(Msg.ANALYSIS_FINISHED).parse(String.valueOf(time), HtmlUtils.getServerAnalysisUrlWithProtocol()));
}
Log.info(Locale.get(Msg.ANALYSIS_FINISHED).parse(String.valueOf(time), HtmlUtils.getServerAnalysisUrlWithProtocol()));
PageCacheHandler.removeIf(identifier -> identifier.startsWith("inspectPage: ") || identifier.startsWith("inspectionJson: "));
PageCacheHandler.cachePage("analysisPage", () -> new AnalysisPageResponse(plugin.getUiServer().getDataReqHandler()));
@ -182,9 +179,8 @@ public class Analysis {
}
private void log(String msg) {
if (Settings.ANALYSIS_LOG_TO_CONSOLE.isTrue()) {
Log.info(msg);
}
// TODO Send info to the command sender. (Needs a new system)
Log.info(msg);
}
private Map<String, Serializable> analyzeAdditionalPluginData(List<UUID> uuids) {

View File

@ -1,7 +1,6 @@
package main.java.com.djrapitops.plan.utilities.analysis;
import main.java.com.djrapitops.plan.Log;
import main.java.com.djrapitops.plan.Settings;
import main.java.com.djrapitops.plan.data.SessionData;
import main.java.com.djrapitops.plan.data.additional.AnalysisType;
import main.java.com.djrapitops.plan.data.additional.PluginData;
@ -33,14 +32,9 @@ public class AnalysisUtils {
* @return
*/
public static boolean isActive(long now, long lastPlayed, long playTime, int loginTimes) {
int timeToActive = Settings.ANALYSIS_MINUTES_FOR_ACTIVE.getNumber();
if (timeToActive < 0) {
timeToActive = 0;
}
int timeToActive = 10;
long twoWeeks = 1209600000;
return now - lastPlayed < twoWeeks
&& loginTimes > 3
&& playTime > 60 * timeToActive;

View File

@ -198,11 +198,9 @@ public class DumpUtils {
* @param plan The Plan instance
*/
private static void addConfigurationDetails(DumpLog log, Plan plan) {
boolean webServerEnabled = Settings.WEBSERVER_ENABLED.isTrue();
boolean usingHTTPS = plan.getUiServer().usingHttps();
boolean refreshAnalysisOnEnable = Settings.ANALYSIS_REFRESH_ON_ENABLE.isTrue();
boolean analysisExport = Settings.ANALYSIS_EXPORT.isTrue();
boolean usingAlternativeServerIP = Settings.USE_ALTERNATIVE_UI.isTrue();
boolean usingAlternativeServerIP = Settings.SHOW_ALTERNATIVE_IP.isTrue();
boolean combineAliases = Settings.COMBINE_COMMAND_ALIASES.isTrue();
boolean unknownCommandLogging = Settings.LOG_UNKNOWN_COMMANDS.isTrue();
@ -212,9 +210,7 @@ public class DumpUtils {
log.addHeader("Plan Configuration");
log.add("Webserver Enabled", webServerEnabled);
log.add("Webserver HTTPS", usingHTTPS);
log.add("Refresh Analysis on Enable", refreshAnalysisOnEnable);
log.add("Analysis Export", analysisExport);
log.add("Alternative Server IP", usingAlternativeServerIP);

View File

@ -21,13 +21,10 @@ public class BStats {
}
private void registerConfigSettingGraphs() {
boolean webserver = Settings.WEBSERVER_ENABLED.isTrue();
boolean analysisRefreshEnable = Settings.ANALYSIS_REFRESH_ON_ENABLE.isTrue();
// TODO Write a Module bar graph
boolean analysisAutoRefresh = Settings.ANALYSIS_AUTO_REFRESH.getNumber() != -1;
boolean export = Settings.ANALYSIS_EXPORT.isTrue();
addEnabledDisabledPie("webserver_enabled", webserver);
addEnabledDisabledPie("analysis_enable_refresh", analysisRefreshEnable);
addEnabledDisabledPie("analysis_auto_refresh", analysisAutoRefresh);
addEnabledDisabledPie("html_export", export);

View File

@ -57,17 +57,18 @@ ${playersNewWeek} num
${contentServers} row[column[box-header, box, box-footer[p,button right, refresh button right]], column...], row...
server.html:
${serverName} String
${timeZone} num
${serverName} String //done
${timeZone} num //done
${playersOnline} num
${playersMax} num
${playersTotal} num
${playersActive} num
${playersTotal} num //done
${playersActive} num // done
//done
${playersAverage} num
${playersNewAverage} num
//done
${playersDay} num
${playersWeek} num
${playersMonth} num
@ -86,14 +87,19 @@ ${playersLastPeak} num
${bestPeakTime} time format full
${playersBestPeak} num
${sessionAverage} timeamount
${sessionAverage} timeamount // done
${playtimeTotal} timeamount
${playtimeTotal} timeamount // done
${sessionCount} num
// done
${killCount} num
${mobKillCount} num
${deathCount} num
${commandCount} num //TODO
${commandUniqueCount} num //TODO
//done
${tpsAverageDay} num
${tpsAverageWeek} num
${cpuAverageDay} num%
@ -107,41 +113,46 @@ ${chunkAverageWeek} num
${tableBodyRecentLogins} tr th html (2) (15-20)
${tableBodySessions} tr th html (4) (50)
${tableBodyPlayerList} tr th html (7) (250)
${tableBodyCommands} tr th html (2) (100)
${tableBodyPlayerList} tr th html (7) (250) // done
${tableBodyCommands} tr th html (2) (100) // done
${playersOnlineSeries}
${tpsSeries}
${cpuSeries}
${ramSeries}
${entitySeries}
${chunkSeries}
// done
${playersOnlineSeries}
${tpsSeries}
${cpuSeries}
${ramSeries}
${entitySeries}
${chunkSeries}
${worldSeries}
${geoMapSeries}
${sessionLengthSeries}
${punchCardSeries}
${geoMapSeries}
${sessionLengthSeries}
${punchCardSeries}
${playersGraphColor}
${playersGraphColor} // done
${gmData}
${gmTotal} timeamount
${gmColors}
${gmData} // TODO Remove
${gmTotal} timeamount // TODO Remove
${gmColors} // TODO Move to World Graph
// done
${active}
${inactive}
${joinLeaver}
${banned}
${activityColors}
${worldTotal} timeamount
${worldColors} NOT IMPLEMENTED //TODO
${worldTotal} timeamount //done
${worldColors} //TODO NOT IMPLEMENTED
//done
${tpsMedium}
${tpsHigh}
${tpsLowColor}
${tpsMediumColor}
${tpsHighColor}
// Replace done
${tabContentPlugins} row[column[box-header[h2[i, text]],box plugin], column...], row... + style="width: 200%;" <h2>That's all..</h2> <p>Do you have more plugins? ._.</p>
STYLE:

View File

@ -54,7 +54,7 @@
<h2><i class="fa fa-bar-chart"></i> Players Online</h2>
</div>
<div class="box-footer">
<div id="playersOnlineDay" style="width: 100%; height: 700px;"></div>
<div id="playerChartDay" style="width: 100%; height: 400px;"></div>
</div>
</div>
<div class="column">
@ -116,7 +116,7 @@
<h2><i class="fa fa-bar-chart"></i> Players Online</h2>
</div>
<div class="box-footer">
<div id="playersOnlineMonth" style="width: 100%; height: 700px;"></div>
<div id="playerChartMonth" style="width: 100%; height: 400px;"></div>
</div>
</div>
<div class="column">
@ -124,7 +124,7 @@
<h2><i class="fa fa-braille"></i> Player Join PunchCard</h2>
</div>
<div class="box-footer">
<div id="punchcard" style="width: 100%; height: 700px;"></div>
<div id="punchcard" style="width: 100%; height: 400px;"></div>
</div>
</div>
</div>
@ -193,26 +193,26 @@
<h2><i class="fa fa-pie-chart"></i> World Playtime</h2>
</div>
<div class="box-footer">
<div id="worldPie" style="width: 100%; height: 450px;"></div>
<div id="worldPie" style="width: 100%; height: 350px;"></div>
</div>
<div class="box-header">
<h2><i class="fa fa-pie-chart"></i> Playerbase</h2>
</div>
<div class="box-footer">
<div id="activityPie" style="width: 100%; height: 450px;"></div>
<div id="activityPie" style="width: 100%; height: 350px;"></div>
</div>
</div>
</div>
</div>
<div id="tab-performance" class="tab">
<div class="column">
<div class="row"> <!--First row (horizontal)-->
<div class="row">
<div class="column">
<div class="box-header">
<h2><i class="fa fa-bar-chart"></i> Ticks Per Second</h2>
</div>
<div class="box-footer">
<div id="tpsGraph" style="width: 100%; height: 700px;"></div>
<div id="tpsGraph" style="width: 100%; height: 350px;"></div>
</div>
</div>
<div class="column">
@ -220,17 +220,17 @@
<h2><i class="fa fa-bar-chart"></i> Resource Usage</h2>
</div>
<div class="box-footer">
<div id="resourceGraph" style="width: 100%; height: 700px;"></div>
<div id="resourceGraph" style="width: 100%; height: 350px;"></div>
</div>
</div>
</div> <!--First row (horizontal)-->
</div>
<div class="row">
<div class="column">
<div class="box-header">
<h2><i class="fa fa-bar-chart"></i> World Load</h2>
</div>
<div class="box-footer">
<div id="worldGraph" style="width: 100%; height: 700px;"></div>
<div id="worldGraph" style="width: 100%; height: 350px;"></div>
</div>
</div>
<div class="row">
@ -319,7 +319,7 @@
<h2><i class="fa fa-globe"></i> Geolocations</h2>
</div>
<div class="box-footer" style="padding: 2px;">
<div id="choropleth" style="width: 100%; height: 700px;"></div>
<div id="choropleth" style="width: 100%; height: 600px;"></div>
</div>
</div>
</div>
@ -333,11 +333,9 @@
<script src="https://code.highcharts.com/maps/modules/map.js"></script>
<script src="https://code.highcharts.com/mapdata/custom/world.js"></script>
<script src="./js/activityPie.js"></script>
<script src="./js/gmPie.js"></script>
<script src="./js/playerGraph.js"></script>
<script src="./js/punchCard.js"></script>
<script src="./js/resourceGraph.js"></script>
<script src="./js/sessionDistributionChart.js"></script>
<script src="./js/tpsGraph.js"></script>
<script src="./js/worldGraph.js"></script>
<script src="./js/worldMap.js"></script>
@ -434,43 +432,18 @@
y: ${banned}
}]
};
var gmData = ${gmData};
var gmSeries = {
name: 'GM Usage',
colorByPoint: true,
data: [{
name: 'Survival',
y: gmData[0],
sliced: true,
selected: true
}, {
name: 'Creative',
y: gmData[1]
}, {
name: 'Adventure',
y: gmData[2]
}, {
name: 'Spectator',
y: gmData[3]
}]
};
var worldSeries = {
name: 'World Playtime',
colorByPoint: true,
data: ${worldSeries}
};
var mapSeries = {
name: 'Players',
type: 'map',
mapData: Highcharts.maps['custom/world'],
data: ${geoMapSeries}
name: 'Players',
type: 'map',
mapData: Highcharts.maps['custom/world'],
data: ${geoMapSeries},
joinBy: ['iso-a3', 'code']
};
var sessionLengthSeries = {
name: 'Sessions',
color: '#89c471',
data: ${sessionLengthSeries}
};
var punchcardSeries = {
name: 'Relative Activity',
color: '#222',
@ -494,7 +467,6 @@
}
x.style.opacity = "1";
openFunc(slideIndex)();
/*gmPie('gmPie', gmSeries, '${gmTotal}', [${gmColors}]);
activityPie('activityPie', activitySeries, ${playersTotal}, [${activityColors}]);
worldPie('worldPie', worldSeries, '${worldTotal}');
playersChart('playerChartDay', playersOnlineSeries, 1);
@ -503,9 +475,8 @@
resourceChart('resourceGraph', cpuSeries, ramSeries);
worldChart('worldGraph', entitySeries, chunkSeries);
worldMap('choropleth', '#EEFFEE', '#267f00', mapSeries);
sessionDistributionChart('sessionDistribution', sessionLengthSeries);
punchCard('punchcard', punchcardSeries);
countUpTimer();*/
/*countUpTimer();*/
function openFunc(i) {
return function() {

View File

@ -6,7 +6,7 @@ import main.java.com.djrapitops.plan.data.UserData;
import main.java.com.djrapitops.plan.data.WebUser;
import main.java.com.djrapitops.plan.data.handling.info.HandlingInfo;
import main.java.com.djrapitops.plan.data.handling.info.InfoType;
import main.java.com.djrapitops.plan.database.tables.GMTimesTable;
import main.java.com.djrapitops.plan.data.time.GMTimes;
import main.java.com.djrapitops.plan.utilities.PassEncryptUtil;
import main.java.com.djrapitops.plan.utilities.analysis.Point;
import org.apache.commons.lang.RandomStringUtils;
@ -29,7 +29,7 @@ public class RandomData {
List<UserData> test = new ArrayList<>();
for (int i = 0; i < 20; i++) {
String randomName = randomString(10);
UserData uD = new UserData(UUID.randomUUID(), r.nextLong(), r.nextBoolean(), GMTimesTable.getGMKeyArray()[r.nextInt(3)], randomName, r.nextBoolean());
UserData uD = new UserData(UUID.randomUUID(), r.nextLong(), r.nextBoolean(), GMTimes.getGMKeyArray()[r.nextInt(3)], randomName, r.nextBoolean());
uD.setLastPlayed(r.nextLong());
test.add(uD);
}