From a26622aa66a55d5581bf30b7a71e0ad909fad9a0 Mon Sep 17 00:00:00 2001 From: Rsl1122 Date: Thu, 12 Jan 2017 01:34:39 +0200 Subject: [PATCH] Analysis 80% complete [2.0.0-SNAPSHOT] Known bugs: - Commands: Link does not show ip, might be related to localhost - Page has to be refreshed multiple times to view (Faulty response probably) - Gamemode Times corrupted somehow - 0 0 0 0 0 debug in console - GM Pie doesn't check if total 100 - Average Age shows NaN because dividing by 0 - (Inspect cache not updating properly) - PlanLite features not implemented yet --- .../main/java/com/djrapitops/plan/Phrase.java | 6 +- .../main/java/com/djrapitops/plan/Plan.java | 21 ++- .../plan/command/commands/AnalyzeCommand.java | 38 ++-- .../plan/command/commands/InspectCommand.java | 56 ++---- .../djrapitops/plan/data/AnalysisData.java | 173 +++++++++++++++++- .../plan/data/cache/AnalysisCacheHandler.java | 22 ++- .../plan/ui/DataRequestHandler.java | 48 ++--- .../djrapitops/plan/ui/WebSocketServer.java | 5 +- .../ui/graphs/ActivityPieChartCreator.java | 39 ++++ .../ui/graphs/GMTimesPieChartCreator.java | 25 ++- .../djrapitops/plan/ui/webserver/Request.java | 2 - .../plan/ui/webserver/Response.java | 15 +- .../djrapitops/plan/utilities/Analysis.java | 112 ++++++++++-- .../plan/utilities/AnalysisUtils.java | 88 ++++++++- Plan/src/main/resources/analysis.html | 31 +++- Plan/src/main/resources/config.yml | 25 +-- Plan/src/main/resources/player.html | 2 +- 17 files changed, 544 insertions(+), 164 deletions(-) create mode 100644 Plan/src/main/java/com/djrapitops/plan/ui/graphs/ActivityPieChartCreator.java diff --git a/Plan/src/main/java/com/djrapitops/plan/Phrase.java b/Plan/src/main/java/com/djrapitops/plan/Phrase.java index a3ade1d37..fc392d094 100644 --- a/Plan/src/main/java/com/djrapitops/plan/Phrase.java +++ b/Plan/src/main/java/com/djrapitops/plan/Phrase.java @@ -10,9 +10,9 @@ public enum Phrase { DATABASE_TYPE_DOES_NOT_EXIST("That database type doesn't exist."), DATABASE_FAILURE_DISABLE("Database initialization has failed, disabling Plan."), PLANLITE_REG_HOOK("Registered additional hook, passed on to PlanLite: "), - USERNAME_NOT_VALID("This Player doesn't exist."), - USERNAME_NOT_SEEN("This Player has not played on this server."), - USERNAME_NOT_KNOWN("Player not found from the database."), + USERNAME_NOT_VALID(ChatColor.RED+"This Player doesn't exist."), + USERNAME_NOT_SEEN(ChatColor.RED+"This Player has not played on this server."), + USERNAME_NOT_KNOWN(ChatColor.RED+"Player not found from the database."), COLOR_MAIN(ChatColor.DARK_GREEN), COLOR_SEC(ChatColor.GRAY), COLOR_TER(ChatColor.DARK_GRAY), diff --git a/Plan/src/main/java/com/djrapitops/plan/Plan.java b/Plan/src/main/java/com/djrapitops/plan/Plan.java index 9433503cb..a1d2c796a 100644 --- a/Plan/src/main/java/com/djrapitops/plan/Plan.java +++ b/Plan/src/main/java/com/djrapitops/plan/Plan.java @@ -25,6 +25,7 @@ import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import org.bukkit.Bukkit; import org.bukkit.configuration.ConfigurationSection; +import org.bukkit.scheduler.BukkitRunnable; public class Plan extends JavaPlugin { @@ -86,11 +87,23 @@ public class Plan extends JavaPlugin { this.api = new API(this); handler.handleReload(); - + uiServer = new WebSocketServer(this); uiServer.initServer(); log("Player Analytics Enabled."); + + if (getConfig().getBoolean("RefreshAnalysisOnEnable")) { + log("Analysis | Boot analysis in 30 seconds.."); + (new BukkitRunnable() { + @Override + public void run() { + log("Analysis | Starting Boot Analysis.."); + analysisCache.updateCache(); + this.cancel(); + } + }).runTaskLater(this, 30 * 20); + } } public void hookPlanLite() { @@ -118,7 +131,7 @@ public class Plan extends JavaPlugin { handler.saveCacheOnDisable(); }); scheduler.shutdown(); - + log("Player Analytics Disabled."); } @@ -205,11 +218,11 @@ public class Plan extends JavaPlugin { public AnalysisCacheHandler getAnalysisCache() { return analysisCache; } - + public InspectCacheHandler getInspectCache() { return inspectCache; } - + public DataCacheHandler getHandler() { return handler; } diff --git a/Plan/src/main/java/com/djrapitops/plan/command/commands/AnalyzeCommand.java b/Plan/src/main/java/com/djrapitops/plan/command/commands/AnalyzeCommand.java index 55afd486f..aa6331130 100644 --- a/Plan/src/main/java/com/djrapitops/plan/command/commands/AnalyzeCommand.java +++ b/Plan/src/main/java/com/djrapitops/plan/command/commands/AnalyzeCommand.java @@ -1,35 +1,51 @@ package com.djrapitops.plan.command.commands; +import com.djrapitops.plan.Phrase; import com.djrapitops.plan.Plan; import com.djrapitops.plan.command.CommandType; import com.djrapitops.plan.command.SubCommand; -import com.djrapitops.plan.command.utils.DataFormatUtils; +import com.djrapitops.plan.data.cache.AnalysisCacheHandler; import com.djrapitops.plan.utilities.FormatUtils; import java.util.Date; import org.bukkit.ChatColor; import org.bukkit.command.Command; import org.bukkit.command.CommandSender; +import org.bukkit.scheduler.BukkitRunnable; public class AnalyzeCommand extends SubCommand { private Plan plugin; - private Date refreshDate; + private AnalysisCacheHandler analysisCache; public AnalyzeCommand(Plan plugin) { - super("analyze", "plan.analyze", "Analyze data of all players /plan analyze [-refresh]", CommandType.CONSOLE); + super("analyze", "plan.analyze", "Analyze data of all players /plan analyze", CommandType.CONSOLE); this.plugin = plugin; + analysisCache = plugin.getAnalysisCache(); } @Override public boolean onCommand(CommandSender sender, Command cmd, String commandLabel, String[] args) { - ChatColor operatorColor = ChatColor.DARK_GREEN; - ChatColor textColor = ChatColor.GRAY; - - //header - sender.sendMessage(textColor + "-- [" + operatorColor + "PLAN - Analysis results, refreshed " - + FormatUtils.formatTimeAmountSinceDate(refreshDate, new Date()) + " ago:" + textColor + "] --"); - - sender.sendMessage(textColor + "-- o --"); + if (!analysisCache.isCached()) { + analysisCache.updateCache(); + } else if (new Date().getTime() - analysisCache.getData().getRefreshDate() > 60 * 5) { + analysisCache.updateCache(); + } + ChatColor operatorColor = Phrase.COLOR_MAIN.color(); + ChatColor textColor = Phrase.COLOR_SEC.color(); + (new BukkitRunnable() { + @Override + public void run() { + if (analysisCache.isCached()) { + sender.sendMessage(textColor + "-- [" + operatorColor + "PLAN - Analysis results, refreshed " + + FormatUtils.formatTimeAmountSinceString("" + analysisCache.getData().getRefreshDate(), new Date()) + " ago:" + textColor + "] --"); + sender.sendMessage(operatorColor + "Link: " + textColor + + "http://" + plugin.getServer().getIp() + ":" + plugin.getConfig().getString("WebServer.Port" + ) + "/server"); + sender.sendMessage(textColor + "-- o --"); + this.cancel(); + } + } + }).runTaskTimer(plugin, 1 * 20, 5 * 20); return true; } } diff --git a/Plan/src/main/java/com/djrapitops/plan/command/commands/InspectCommand.java b/Plan/src/main/java/com/djrapitops/plan/command/commands/InspectCommand.java index 1ac8cdaec..9550d6f91 100644 --- a/Plan/src/main/java/com/djrapitops/plan/command/commands/InspectCommand.java +++ b/Plan/src/main/java/com/djrapitops/plan/command/commands/InspectCommand.java @@ -5,15 +5,11 @@ import com.djrapitops.plan.Plan; import com.djrapitops.plan.utilities.UUIDFetcher; import com.djrapitops.plan.command.CommandType; import com.djrapitops.plan.command.SubCommand; -import com.djrapitops.plan.data.ServerData; import java.util.Date; -import com.djrapitops.plan.data.UserData; import com.djrapitops.plan.data.cache.InspectCacheHandler; import com.djrapitops.plan.utilities.FormatUtils; import com.djrapitops.plan.utilities.MiscUtils; -import java.util.ArrayList; -import java.util.List; import java.util.UUID; import org.bukkit.ChatColor; @@ -21,7 +17,7 @@ import org.bukkit.OfflinePlayer; import org.bukkit.command.Command; import org.bukkit.command.CommandSender; import static org.bukkit.Bukkit.getOfflinePlayer; -import static org.bukkit.Bukkit.getOfflinePlayer; +import org.bukkit.scheduler.BukkitRunnable; public class InspectCommand extends SubCommand { @@ -29,7 +25,7 @@ public class InspectCommand extends SubCommand { private InspectCacheHandler inspectCache; public InspectCommand(Plan plugin) { - super("inspect", "plan.inspect", "Inspect data /plan [-a, -r].", CommandType.CONSOLE_WITH_ARGUMENTS); + super("inspect", "plan.inspect", "Inspect data /plan ", CommandType.CONSOLE_WITH_ARGUMENTS); this.plugin = plugin; inspectCache = plugin.getInspectCache(); @@ -61,42 +57,22 @@ public class InspectCommand extends SubCommand { Date refreshDate = new Date(); inspectCache.cache(uuid); - UserData data = inspectCache.getFromCache(uuid); - ChatColor operatorColor = Phrase.COLOR_MAIN.color(); ChatColor textColor = Phrase.COLOR_SEC.color(); - - List msgs = new ArrayList<>(); - msgs.add("Logintimes " + data.getLoginTimes()); - msgs.add("BedLocation " + data.getBedLocation().getBlockX()); - msgs.add("GeoLoc " + data.getDemData().getGeoLocation()); - msgs.add("GMTimes values " + data.getGmTimes().values().toString()); - msgs.add("Ips " + data.getIps().toString()); - msgs.add("Last gamemode " + data.getLastGamemode()); - msgs.add("Last gm swap time " + data.getLastGmSwapTime()); - msgs.add("Last Played " + data.getLastPlayed()); - msgs.add("Location " + data.getLocation().getBlockX()); - msgs.add("Locations "+data.getLocations().size()); - msgs.add("Nicknames " + data.getNicknames().toString()); - msgs.add("Registered " + data.getRegistered()); - msgs.add("TimesKicked " + data.getTimesKicked()); - msgs.add("Uuid " + data.getUuid()); - msgs.add("PlayTime " + data.getPlayTime()); - msgs.add("Banned "+ data.isBanned()); - msgs.add("Opped" + data.isOp()); - msgs.add(operatorColor + "SERVER"); - ServerData sdata = plugin.getHandler().getServerData(); - msgs.add("Commands " + sdata.getCommandUsage().keySet().toString()); - msgs.add("New Players " + sdata.getNewPlayers()); - msgs.add("Online Players " + sdata.getPlayersOnline()); - //header - sender.sendMessage(textColor + "-- [" + operatorColor + "PLAN - Inspect results: " + playerName + " - took " + FormatUtils.formatTimeAmountSinceDate(refreshDate, new Date()) + textColor + "] --"); - - for (String message : msgs) { - sender.sendMessage(textColor + message); - } - - sender.sendMessage(textColor + "-- o --"); + (new BukkitRunnable() { + @Override + public void run() { + if (inspectCache.getCache().containsKey(uuid)) { + sender.sendMessage(textColor + "-- [" + operatorColor + "PLAN - Inspect results: " + playerName + " - took " + FormatUtils.formatTimeAmountSinceDate(refreshDate, new Date()) + textColor + "] --"); + sender.sendMessage(operatorColor + "Link: " + textColor + + "http://" + plugin.getServer().getIp() + ":" + plugin.getConfig().getString("WebServer.Port" + ) + "/player/" + playerName); + sender.sendMessage(textColor+"Results will be available for 5 minutes."); + sender.sendMessage(textColor + "-- o --"); + this.cancel(); + } + } + }).runTaskTimer(plugin, 1 * 20, 5 * 20); return true; } } diff --git a/Plan/src/main/java/com/djrapitops/plan/data/AnalysisData.java b/Plan/src/main/java/com/djrapitops/plan/data/AnalysisData.java index 6b10eca52..2dbc44d46 100644 --- a/Plan/src/main/java/com/djrapitops/plan/data/AnalysisData.java +++ b/Plan/src/main/java/com/djrapitops/plan/data/AnalysisData.java @@ -1,4 +1,3 @@ - package com.djrapitops.plan.data; /** @@ -6,6 +5,176 @@ package com.djrapitops.plan.data; * @author Rsl1122 */ public class AnalysisData { + + private long refreshDate; + private long averagePlayTime; - + private long totalPlayTime; + private double averageAge; + private String gmTimesChartImgHtml; + private String playersChartImgHtml; + private String activityChartImgHtml; + + private int gm0Perc; + private int gm1Perc; + private int gm2Perc; + private int gm3Perc; + + private int banned; + private int active; + private int inactive; + private int total; + + private int totalPlayers; + private long totalLoginTimes; + private int ops; + + public AnalysisData() { + } + + // Getters and setters v---------------------------------v + public int getBanned() { + return banned; + } + + public void setBanned(int banned) { + this.banned = banned; + } + + public int getActive() { + return active; + } + + public void setActive(int active) { + this.active = active; + } + + public int getInactive() { + return inactive; + } + + public void setInactive(int inactive) { + this.inactive = inactive; + } + + public int getTotal() { + return total; + } + + public void setTotal(int total) { + this.total = total; + } + + public int getGm0Perc() { + return gm0Perc; + } + + public void setGm0Perc(int gm0Perc) { + this.gm0Perc = gm0Perc; + } + + public int getGm1Perc() { + return gm1Perc; + } + + public void setGm1Perc(int gm1Perc) { + this.gm1Perc = gm1Perc; + } + + public int getGm2Perc() { + return gm2Perc; + } + + public void setGm2Perc(int gm2Perc) { + this.gm2Perc = gm2Perc; + } + + public int getGm3Perc() { + return gm3Perc; + } + + public void setGm3Perc(int gm3Perc) { + this.gm3Perc = gm3Perc; + } + + public int getTotalPlayers() { + return totalPlayers; + } + + public void setTotalPlayers(int totalPlayers) { + this.totalPlayers = totalPlayers; + } + + public long getTotalPlayTime() { + return totalPlayTime; + } + + public void setTotalPlayTime(long totalPlayTime) { + this.totalPlayTime = totalPlayTime; + } + + public long getRefreshDate() { + return refreshDate; + } + + public long getAveragePlayTime() { + return averagePlayTime; + } + + public double getAverageAge() { + return averageAge; + } + + public String getGmTimesChartImgHtml() { + return gmTimesChartImgHtml; + } + + public String getPlayersChartImgHtml() { + return playersChartImgHtml; + } + + public String getActivityChartImgHtml() { + return activityChartImgHtml; + } + + public long getTotalLoginTimes() { + return totalLoginTimes; + } + + public int getOps() { + return ops; + } + + public void setRefreshDate(long refreshDate) { + this.refreshDate = refreshDate; + } + + public void setAveragePlayTime(long averagePlayTime) { + this.averagePlayTime = averagePlayTime; + } + + public void setAverageAge(double averageAge) { + this.averageAge = averageAge; + } + + public void setGmTimesChartImgHtml(String gmTimesChartImgHtml) { + this.gmTimesChartImgHtml = gmTimesChartImgHtml; + } + + public void setPlayersChartImgHtml(String playersChartImgHtml) { + this.playersChartImgHtml = playersChartImgHtml; + } + + public void setActivityChartImgHtml(String activityChartImgHtml) { + this.activityChartImgHtml = activityChartImgHtml; + } + + public void setTotalLoginTimes(long totalLoginTimes) { + this.totalLoginTimes = totalLoginTimes; + } + + public void setOps(int ops) { + this.ops = ops; + } + } diff --git a/Plan/src/main/java/com/djrapitops/plan/data/cache/AnalysisCacheHandler.java b/Plan/src/main/java/com/djrapitops/plan/data/cache/AnalysisCacheHandler.java index 8c8d70271..c97e19ea8 100644 --- a/Plan/src/main/java/com/djrapitops/plan/data/cache/AnalysisCacheHandler.java +++ b/Plan/src/main/java/com/djrapitops/plan/data/cache/AnalysisCacheHandler.java @@ -2,6 +2,8 @@ package com.djrapitops.plan.data.cache; import com.djrapitops.plan.Plan; +import com.djrapitops.plan.data.AnalysisData; +import com.djrapitops.plan.utilities.Analysis; /** * @@ -9,14 +11,28 @@ import com.djrapitops.plan.Plan; */ public class AnalysisCacheHandler { private Plan plugin; - private InspectCacheHandler inspectCache; + private AnalysisData cache; + private Analysis analysis; public AnalysisCacheHandler(Plan plugin) { this.plugin = plugin; - this.inspectCache = plugin.getInspectCache(); + analysis = new Analysis(plugin); + } + + public void updateCache() { + cache = null; + analysis.analyze(this); + } + + public void cache(AnalysisData data) { + cache = data; + } + + public AnalysisData getData() { + return cache; } public boolean isCached() { - return true; + return (cache != null); } } diff --git a/Plan/src/main/java/com/djrapitops/plan/ui/DataRequestHandler.java b/Plan/src/main/java/com/djrapitops/plan/ui/DataRequestHandler.java index 4b7c37480..ae8133840 100644 --- a/Plan/src/main/java/com/djrapitops/plan/ui/DataRequestHandler.java +++ b/Plan/src/main/java/com/djrapitops/plan/ui/DataRequestHandler.java @@ -6,11 +6,9 @@ import com.djrapitops.plan.data.UserData; import com.djrapitops.plan.data.cache.AnalysisCacheHandler; import com.djrapitops.plan.data.cache.InspectCacheHandler; import com.djrapitops.plan.utilities.AnalysisUtils; -import com.djrapitops.plan.utilities.FormatUtils; import java.util.HashMap; import java.util.Scanner; import java.util.UUID; -import org.bukkit.GameMode; /** * @@ -42,34 +40,7 @@ public class DataRequestHandler { String line = scanner.nextLine(); html += line + "\r\n"; } - HashMap replaceMap = new HashMap<>(); - replaceMap.put("%uuid%", ""+data.getUuid()); - replaceMap.put("%logintimes%", ""+data.getLoginTimes()); - replaceMap.put("%bed%", FormatUtils.formatLocation(data.getBedLocation())); - replaceMap.put("%geoloc%", data.getDemData().getGeoLocation()); - int age = data.getDemData().getAge(); - replaceMap.put("%age%", (age != -1) ? ""+age:"Not known"); - replaceMap.put("%gender%", ""+data.getDemData().getGender().name().toLowerCase()); - HashMap gmTimes = data.getGmTimes(); - replaceMap.put("%gmpiechart%", AnalysisUtils.createPieChart(gmTimes, data.getUuid().toString())); - long gmZero = gmTimes.get(GameMode.SURVIVAL); - long gmOne = gmTimes.get(GameMode.CREATIVE); - long gmTwo = gmTimes.get(GameMode.ADVENTURE); - long gmThree = gmTimes.get(GameMode.SPECTATOR); - long total = gmZero + gmOne + gmTwo + gmThree; - replaceMap.put("%gm0%", FormatUtils.formatTimeAmount(""+gmZero)); - replaceMap.put("%gm1%", FormatUtils.formatTimeAmount(""+gmOne)); - replaceMap.put("%gm2%", FormatUtils.formatTimeAmount(""+gmTwo)); - replaceMap.put("%gm3%", FormatUtils.formatTimeAmount(""+gmThree)); - replaceMap.put("%gmtotal%", FormatUtils.formatTimeAmount(""+total)); - replaceMap.put("%ips%", data.getIps().toString()); - replaceMap.put("%nicknames%", data.getNicknames().toString()); - replaceMap.put("%name%", data.getName()); - replaceMap.put("%registered%", FormatUtils.formatTimeStamp(""+data.getRegistered())); - replaceMap.put("%timeskicked%", ""+data.getTimesKicked()); - replaceMap.put("%playtime%", FormatUtils.formatTimeAmount(""+data.getPlayTime())); - replaceMap.put("%banned%", data.isBanned() ? "Banned":"Not Banned"); - replaceMap.put("%op%", data.isOp() ? ", Operator (Op)":""); + HashMap replaceMap = AnalysisUtils.getInspectReplaceRules(data); for (String key : replaceMap.keySet()) { html = html.replaceAll(key, replaceMap.get(key)); @@ -79,7 +50,22 @@ public class DataRequestHandler { } public String getAnalysisHtml() { - return "Test Successful"; + if (!analysisCache.isCached()) { + return "

404 Data was not found in cache

"; + } + Scanner scanner = new Scanner(plugin.getResource("analysis.html")); + String html = ""; + while (scanner.hasNextLine()) { + String line = scanner.nextLine(); + html += line + "\r\n"; + } + HashMap replaceMap = AnalysisUtils.getAnalysisReplaceRules(analysisCache.getData()); + + for (String key : replaceMap.keySet()) { + html = html.replaceAll(key, replaceMap.get(key)); + } + + return html; } public boolean checkIfAnalysisIsCached() { diff --git a/Plan/src/main/java/com/djrapitops/plan/ui/WebSocketServer.java b/Plan/src/main/java/com/djrapitops/plan/ui/WebSocketServer.java index c3ec9f6da..9b2bd9e38 100644 --- a/Plan/src/main/java/com/djrapitops/plan/ui/WebSocketServer.java +++ b/Plan/src/main/java/com/djrapitops/plan/ui/WebSocketServer.java @@ -47,7 +47,7 @@ public class WebSocketServer { try { //Setup server try { - server = new ServerSocket(PORT, 1, InetAddress.getByName("127.0.0.1")); + server = new ServerSocket(PORT, 1, InetAddress.getByName("0.0.0.0")); } catch (IOException e) { System.exit(1); } @@ -63,7 +63,6 @@ public class WebSocketServer { socket = server.accept(); input = socket.getInputStream(); output = socket.getOutputStream(); - plugin.log("Connected: " + socket.getRemoteSocketAddress().toString()); Request request = new Request(input); request.parse(); @@ -79,7 +78,7 @@ public class WebSocketServer { ENABLED = true; - plugin.log("Webserver running: " + server.getInetAddress().getHostAddress() + ":" + server.getLocalPort()); + plugin.log("Webserver running on PORT "+server.getLocalPort()); } catch (Exception e) { ENABLED = false; } diff --git a/Plan/src/main/java/com/djrapitops/plan/ui/graphs/ActivityPieChartCreator.java b/Plan/src/main/java/com/djrapitops/plan/ui/graphs/ActivityPieChartCreator.java new file mode 100644 index 000000000..a78199122 --- /dev/null +++ b/Plan/src/main/java/com/djrapitops/plan/ui/graphs/ActivityPieChartCreator.java @@ -0,0 +1,39 @@ +package main.java.com.djrapitops.plan.ui.graphs; + +import com.googlecode.charts4j.Color; +import com.googlecode.charts4j.GCharts; +import com.googlecode.charts4j.PieChart; +import com.googlecode.charts4j.Slice; + +/** + * + * @author Rsl1122 + */ +public class ActivityPieChartCreator { + + public static String createChart(int totalBanned, int active, int inactive) { + + int total = totalBanned + active + inactive; + + int banPerc = (int) (totalBanned / total); + int inacPerc = (int) (inactive / total); + int actPerc = (int) (active / total); + while (banPerc + inacPerc + actPerc < 100) { + actPerc++; + } + while (banPerc + inacPerc + actPerc > 100) { + actPerc--; + } + + Slice s1 = Slice.newSlice((int) (banPerc), Color.newColor("951800"), "Banned", "Banned"); + Slice s3 = Slice.newSlice((int) (inacPerc), Color.newColor("A9A9A9"), "Inactive", "Inactive"); + Slice s4 = Slice.newSlice((int) (actPerc), Color.newColor("228B22"), "Active", "Active"); + + PieChart refChart = GCharts.newPieChart(s4, s3, s1); + refChart.setSize(500, 150); + refChart.setThreeD(true); + String refURL = refChart.toURLString(); + return refURL; + } + +} diff --git a/Plan/src/main/java/com/djrapitops/plan/ui/graphs/GMTimesPieChartCreator.java b/Plan/src/main/java/com/djrapitops/plan/ui/graphs/GMTimesPieChartCreator.java index 52418251a..dad4f0b46 100644 --- a/Plan/src/main/java/com/djrapitops/plan/ui/graphs/GMTimesPieChartCreator.java +++ b/Plan/src/main/java/com/djrapitops/plan/ui/graphs/GMTimesPieChartCreator.java @@ -13,19 +13,32 @@ import org.bukkit.GameMode; */ public class GMTimesPieChartCreator { - public static String createChart(HashMap gmTimes, String uuid) { + public static String createChart(HashMap gmTimes) { + long total = gmTimes.get(GameMode.SURVIVAL) + gmTimes.get(GameMode.CREATIVE) + + gmTimes.get(GameMode.ADVENTURE) + gmTimes.get(GameMode.SPECTATOR); + return createChart(gmTimes, total); + } + + public static String createChart(HashMap gmTimes, long total) { long gmZero = gmTimes.get(GameMode.SURVIVAL); long gmOne = gmTimes.get(GameMode.CREATIVE); long gmTwo = gmTimes.get(GameMode.ADVENTURE); long gmThree = gmTimes.get(GameMode.SPECTATOR); + int zero = (int) (gmZero / total); + int one = (int) (gmOne / total); + int two = (int) (gmTwo / total); + int three = (int) (gmThree / total); - long total = gmZero + gmOne + gmTwo + gmThree; + System.out.println(zero + " " + one + " " + two + " " + three + " " + (zero + one + two + three)); - Slice s1 = Slice.newSlice((int) (gmZero / total), Color.newColor("951800"), "Survival", "Survival"); - Slice s2 = Slice.newSlice((int) (gmOne / total), Color.newColor("01A1DB"), "Creative", "Creative"); - Slice s3 = Slice.newSlice((int) (gmThree / total), Color.newColor("FFFF33"), "Adventure", "Adventure"); - Slice s4 = Slice.newSlice((int) (gmTwo / total), Color.newColor("228B22"), "Spectator", "Spectator"); + Slice s1 = Slice.newSlice((zero), Color.newColor("951800"), "Survival", "Survival"); + + Slice s2 = Slice.newSlice((one), Color.newColor("01A1DB"), "Creative", "Creative"); + + Slice s3 = Slice.newSlice((two), Color.newColor("FFFF33"), "Adventure", "Adventure"); + + Slice s4 = Slice.newSlice((three), Color.newColor("228B22"), "Spectator", "Spectator"); PieChart refChart = GCharts.newPieChart(s1, s2, s3, s4); refChart.setSize(500, 150); diff --git a/Plan/src/main/java/com/djrapitops/plan/ui/webserver/Request.java b/Plan/src/main/java/com/djrapitops/plan/ui/webserver/Request.java index 498971dd8..3b0c0160c 100644 --- a/Plan/src/main/java/com/djrapitops/plan/ui/webserver/Request.java +++ b/Plan/src/main/java/com/djrapitops/plan/ui/webserver/Request.java @@ -32,8 +32,6 @@ public class Request { for (int j = 0; j < i; j++) { request.append((char) buffer[j]); } - - System.out.print(request.toString()); uri = parseUri(request.toString()); } diff --git a/Plan/src/main/java/com/djrapitops/plan/ui/webserver/Response.java b/Plan/src/main/java/com/djrapitops/plan/ui/webserver/Response.java index 99c61a6d4..c5ea36be9 100644 --- a/Plan/src/main/java/com/djrapitops/plan/ui/webserver/Response.java +++ b/Plan/src/main/java/com/djrapitops/plan/ui/webserver/Response.java @@ -1,13 +1,10 @@ package com.djrapitops.plan.ui.webserver; -import com.djrapitops.plan.Plan; import com.djrapitops.plan.ui.DataRequestHandler; import com.djrapitops.plan.utilities.UUIDFetcher; import java.io.IOException; import java.io.OutputStream; -import java.util.Arrays; import java.util.UUID; -import static org.bukkit.plugin.java.JavaPlugin.getPlugin; /** * @@ -18,11 +15,11 @@ public class Response { private OutputStream output; private Request request; - private DataRequestHandler handler; + private DataRequestHandler requestHandler; public Response(OutputStream output, DataRequestHandler h) { this.output = output; - handler = h; + requestHandler = h; } public void sendStaticResource() throws IOException { @@ -56,8 +53,8 @@ public class Response { output.write(errorMessage.getBytes()); return; } - if (handler.checkIfCached(uuid)) { - String dataHtml = handler.getDataHtml(uuid); + if (requestHandler.checkIfCached(uuid)) { + String dataHtml = requestHandler.getDataHtml(uuid); String htmlDef = "HTTP/1.1 Inspect\r\n" + "Content-Type: text/html\r\n" + "Content-Length: " + dataHtml.length() + "\r\n" @@ -67,8 +64,8 @@ public class Response { } } } else if (command.equals("server")) { - if (handler.checkIfAnalysisIsCached()) { - String analysisHtml = handler.getAnalysisHtml(); + if (requestHandler.checkIfAnalysisIsCached()) { + String analysisHtml = requestHandler.getAnalysisHtml(); String htmlDef = "HTTP/1.1 Analysis\r\n" + "Content-Type: text/html\r\n" + "Content-Length: " + analysisHtml.length() + "\r\n" diff --git a/Plan/src/main/java/com/djrapitops/plan/utilities/Analysis.java b/Plan/src/main/java/com/djrapitops/plan/utilities/Analysis.java index c936693eb..8ad45afed 100644 --- a/Plan/src/main/java/com/djrapitops/plan/utilities/Analysis.java +++ b/Plan/src/main/java/com/djrapitops/plan/utilities/Analysis.java @@ -4,19 +4,21 @@ import com.djrapitops.plan.Plan; import com.djrapitops.plan.data.AnalysisData; import com.djrapitops.plan.data.ServerData; import com.djrapitops.plan.data.UserData; +import com.djrapitops.plan.data.cache.AnalysisCacheHandler; import com.djrapitops.plan.data.cache.InspectCacheHandler; import java.util.ArrayList; +import java.util.Date; import java.util.HashMap; import java.util.List; import java.util.UUID; import org.bukkit.Bukkit; +import org.bukkit.GameMode; import org.bukkit.OfflinePlayer; import org.bukkit.scheduler.BukkitRunnable; public class Analysis { private Plan plugin; - private AnalysisData data; private InspectCacheHandler inspectCache; private final List rawData; private HashMap rawServerData; @@ -29,11 +31,17 @@ public class Analysis { added = new ArrayList<>(); } - public void analyze() { + public void analyze(AnalysisCacheHandler analysisCache) { rawData.clear(); added.clear(); plugin.log("Analysis | Beginning analysis of user data.."); - OfflinePlayer[] offlinePlayers = Bukkit.getServer().getOfflinePlayers(); + OfflinePlayer[] offlinePlayers; + try { + offlinePlayers = plugin.getServer().getOfflinePlayers(); + } catch (IndexOutOfBoundsException e) { + plugin.log("Analysis | Analysis failed, no known players."); + return; + } final List uuids = new ArrayList<>(); for (OfflinePlayer p : offlinePlayers) { UUID uuid = p.getUniqueId(); @@ -41,6 +49,10 @@ public class Analysis { uuids.add(uuid); } } + if (uuids.isEmpty()) { + plugin.log("Analysis | Analysis failed, no data in the database."); + return; + } (new BukkitRunnable() { @Override public void run() { @@ -49,23 +61,95 @@ public class Analysis { }); plugin.log("Analysis | Fetching Data.."); while (rawData.size() != uuids.size()) { - try { - this.wait(1); - } catch (InterruptedException ex) { - } uuids.stream() .filter((uuid) -> (!added.contains(uuid))) .forEach((uuid) -> { - UserData userData = inspectCache.getFromCache(uuid); - if (userData != null) { - rawData.add(userData); - added.add(uuid); - } - }); + UserData userData = inspectCache.getFromCache(uuid); + if (userData != null) { + rawData.add(userData); + added.add(uuid); + } + }); } rawServerData = plugin.getDB().getServerDataHashMap(); plugin.log("Analysis | Data Fetched, beginning Analysis of data.."); - + AnalysisData data = new AnalysisData(); + String playerActivityHtml = AnalysisUtils.createPlayerActivityGraph(rawServerData, new Date().getTime()); + data.setPlayersChartImgHtml(playerActivityHtml); + long gmZero = 0; + long gmOne = 0; + long gmTwo = 0; + long gmThree = 0; + + long totalPlaytime = 0; + int totalBanned = 0; + long totalLoginTimes = 0; + int active = 0; + int inactive = 0; + int ops = 0; + List ages = new ArrayList<>(); + + for (UserData uData : rawData) { + HashMap gmTimes = uData.getGmTimes(); + gmZero += gmTimes.get(GameMode.SURVIVAL); + gmOne += gmTimes.get(GameMode.CREATIVE); + gmTwo += gmTimes.get(GameMode.ADVENTURE); + gmThree += gmTimes.get(GameMode.SPECTATOR); + totalPlaytime += uData.getPlayTime(); + totalLoginTimes += uData.getLoginTimes(); + int age = uData.getDemData().getAge(); + if (age != -1) { + ages.add(age); + } + if (uData.isOp()) { + ops++; + } + + if (uData.isBanned()) { + totalBanned++; + } else if (AnalysisUtils.isActive(uData.getLastPlayed(), uData.getPlayTime(), uData.getLoginTimes())) { + active++; + } else { + inactive++; + } + } + data.setTotalLoginTimes(totalLoginTimes); + + String activityPieChartHtml = AnalysisUtils.createActivityPieChart(totalBanned, active, inactive); + data.setActivityChartImgHtml(activityPieChartHtml); + data.setActive(active); + data.setInactive(inactive); + data.setBanned(totalBanned); + data.setTotal(offlinePlayers.length); + + data.setOps(ops); + + data.setTotalPlayTime(totalPlaytime); + long averagePlaytime = totalPlaytime / rawData.size(); + data.setAveragePlayTime(averagePlaytime); + int totalAge = 0; + for (int age : ages) { + totalAge += age; + } + double averageAge = totalAge * 1.0 / ages.size(); + data.setAverageAge(averageAge); + long gmTotal = gmZero + gmOne + gmTwo + gmThree; + HashMap totalGmTimes = new HashMap<>(); + totalGmTimes.put(GameMode.SURVIVAL, gmZero); + totalGmTimes.put(GameMode.CREATIVE, gmOne); + totalGmTimes.put(GameMode.ADVENTURE, gmTwo); + totalGmTimes.put(GameMode.SPECTATOR, gmThree); + String serverGMChartHtml = AnalysisUtils.createGMPieChart(totalGmTimes, gmTotal); + data.setGmTimesChartImgHtml(serverGMChartHtml); + data.setGm0Perc((int) (gmZero / gmTotal)); + data.setGm1Perc((int) (gmOne / gmTotal)); + data.setGm2Perc((int) (gmTwo / gmTotal)); + data.setGm3Perc((int) (gmThree / gmTotal)); + + data.setRefreshDate(new Date().getTime()); + analysisCache.cache(data); + plugin.log("Analysis | Analysis Complete."); + this.cancel(); } }).runTaskAsynchronously(plugin); } diff --git a/Plan/src/main/java/com/djrapitops/plan/utilities/AnalysisUtils.java b/Plan/src/main/java/com/djrapitops/plan/utilities/AnalysisUtils.java index 52b8c355b..38b8c3020 100644 --- a/Plan/src/main/java/com/djrapitops/plan/utilities/AnalysisUtils.java +++ b/Plan/src/main/java/com/djrapitops/plan/utilities/AnalysisUtils.java @@ -1,8 +1,13 @@ package com.djrapitops.plan.utilities; import com.djrapitops.plan.Plan; +import com.djrapitops.plan.data.AnalysisData; +import com.djrapitops.plan.data.ServerData; +import com.djrapitops.plan.data.UserData; import com.djrapitops.plan.ui.graphs.GMTimesPieChartCreator; +import java.util.Date; import java.util.HashMap; +import main.java.com.djrapitops.plan.ui.graphs.ActivityPieChartCreator; import org.bukkit.GameMode; import static org.bukkit.plugin.java.JavaPlugin.getPlugin; @@ -12,9 +17,88 @@ import static org.bukkit.plugin.java.JavaPlugin.getPlugin; */ public class AnalysisUtils { - public static String createPieChart(HashMap gmTimes, String uuid) { - String url = GMTimesPieChartCreator.createChart(gmTimes, uuid); + public static String createGMPieChart(HashMap gmTimes) { + String url = GMTimesPieChartCreator.createChart(gmTimes); + return ""; + } + public static String createGMPieChart(HashMap gmTimes, long total) { + String url = GMTimesPieChartCreator.createChart(gmTimes, total); return ""; } + public static HashMap getInspectReplaceRules(UserData data) { + HashMap replaceMap = new HashMap<>(); + replaceMap.put("%uuid%", "" + data.getUuid()); + replaceMap.put("%logintimes%", "" + data.getLoginTimes()); + replaceMap.put("%bed%", FormatUtils.formatLocation(data.getBedLocation())); + replaceMap.put("%geoloc%", data.getDemData().getGeoLocation()); + int age = data.getDemData().getAge(); + replaceMap.put("%age%", (age != -1) ? "" + age : "Not known"); + replaceMap.put("%gender%", "" + data.getDemData().getGender().name().toLowerCase()); + HashMap gmTimes = data.getGmTimes(); + replaceMap.put("%gmpiechart%", createGMPieChart(gmTimes)); + long gmZero = gmTimes.get(GameMode.SURVIVAL); + long gmOne = gmTimes.get(GameMode.CREATIVE); + long gmTwo = gmTimes.get(GameMode.ADVENTURE); + long gmThree = gmTimes.get(GameMode.SPECTATOR); + long total = gmZero + gmOne + gmTwo + gmThree; + replaceMap.put("%gm0%", FormatUtils.formatTimeAmount("" + gmZero)); + replaceMap.put("%gm1%", FormatUtils.formatTimeAmount("" + gmOne)); + replaceMap.put("%gm2%", FormatUtils.formatTimeAmount("" + gmTwo)); + replaceMap.put("%gm3%", FormatUtils.formatTimeAmount("" + gmThree)); + replaceMap.put("%gmtotal%", FormatUtils.formatTimeAmount("" + total)); + replaceMap.put("%ips%", data.getIps().toString()); + replaceMap.put("%nicknames%", data.getNicknames().toString()); + replaceMap.put("%name%", data.getName()); + replaceMap.put("%registered%", FormatUtils.formatTimeStamp("" + data.getRegistered())); + replaceMap.put("%timeskicked%", "" + data.getTimesKicked()); + replaceMap.put("%playtime%", FormatUtils.formatTimeAmount("" + data.getPlayTime())); + replaceMap.put("%banned%", data.isBanned() ? "Banned" : "Not Banned"); + replaceMap.put("%op%", data.isOp() ? ", Operator (Op)" : ""); + return replaceMap; + } + + static String createPlayerActivityGraph(HashMap rawServerData, long time) { + return ""; + } + + public static HashMap getAnalysisReplaceRules(AnalysisData data) { + HashMap replaceMap = new HashMap<>(); + replaceMap.put("%activitypiechart%", data.getActivityChartImgHtml()); + replaceMap.put("%gmpiechart%", data.getGmTimesChartImgHtml()); + replaceMap.put("%gm0%", data.getGm0Perc()*100+"%"); + replaceMap.put("%gm1%", data.getGm1Perc()*100+"%"); + replaceMap.put("%gm2%", data.getGm2Perc()*100+"%"); + replaceMap.put("%gm3%", data.getGm3Perc()*100+"%"); + replaceMap.put("%active%", "" + data.getActive()); + replaceMap.put("%banned%", "" + data.getBanned()); + replaceMap.put("%inactive%", "" + data.getInactive()); + replaceMap.put("%activitytotal%", "" + data.getTotal()); + replaceMap.put("%playerchart%", data.getPlayersChartImgHtml()); + replaceMap.put("%avgage%", ""+data.getAverageAge()); + replaceMap.put("%avgplaytime%", FormatUtils.formatTimeAmount(""+data.getAveragePlayTime())); + replaceMap.put("%totalplaytime%", FormatUtils.formatTimeAmount(""+data.getTotalPlayTime())); + replaceMap.put("%ops%", ""+data.getOps()); + replaceMap.put("%refresh%", FormatUtils.formatTimeAmountSinceString(""+data.getRefreshDate(), new Date())); + replaceMap.put("%totallogins%", ""+data.getTotalLoginTimes()); + return replaceMap; + } + + static boolean isActive(long lastPlayed, long playTime, int loginTimes) { + Plan plugin = getPlugin(Plan.class); + long twoWeeks = 1209600; + if (new Date().getTime() - lastPlayed < twoWeeks) { + if (loginTimes > 3) { + if (playTime > 3600) { + return true; + } + } + } + return false; + } + + static String createActivityPieChart(int totalBanned, int active, int inactive) { + String url = ActivityPieChartCreator.createChart(totalBanned, active, inactive); + return ""; + } } diff --git a/Plan/src/main/resources/analysis.html b/Plan/src/main/resources/analysis.html index b78c3d99c..0e32a475a 100644 --- a/Plan/src/main/resources/analysis.html +++ b/Plan/src/main/resources/analysis.html @@ -16,25 +16,38 @@

Plan | Server Analysis

+

Analysis refreshed %refresh% ago

-
-

%activitygraph%

+ %playerchart%
-

%activitypiegraph%

+ box-shadow: 5px 5px 4px 0px #888888;text-align: center;"> + %activitypiechart% +

Active %active% | Inactive %inactive% | Banned %banned% | Total Players: %activitytotal%

-
-

Averages

-
+ + +

%activitytotal% players have played on this server.

+

A Total of %totalplaytime% has been played with the average of %avgplaytime%

+

Players have joined %totallogins% times.

+

The average age of known players is %avgage%.

+ + + %gmpiechart% +

Survival: %gm0% | Creative: %gm1% | Adventure: %gm2% | Spectator: %gm3%

+ + +
\ No newline at end of file diff --git a/Plan/src/main/resources/config.yml b/Plan/src/main/resources/config.yml index 281878a81..61ec394d2 100644 --- a/Plan/src/main/resources/config.yml +++ b/Plan/src/main/resources/config.yml @@ -1,5 +1,6 @@ debug: true +RefreshAnalysisOnEnable: true saveEveryXMinutes: 5 database: type: sqlite @@ -23,30 +24,6 @@ enabledData: commandUsage: true playersOnline: true amountOfNewPlayers: true - - player: - basic info: - uuid: true - ipAddresses: true - usedNicknames: true - opped: true - activity: - dateRegistered: true - lastLogin: true - playTime: true - loginTimes: true - gamemodePercentages: true - location: - showLocation: true - locationHeatmap: true - bedLocation: true - ruleBreaking: - banLogging: true - timesKicked: true - demographics: - geoLocation: true - age: true - gender: true diff --git a/Plan/src/main/resources/player.html b/Plan/src/main/resources/player.html index 468168de5..047ad3dfa 100644 --- a/Plan/src/main/resources/player.html +++ b/Plan/src/main/resources/player.html @@ -26,7 +26,7 @@

Nicknames: %nicknames% | Has connected from ips: %ips%

Geolocation: %geoloc%

Playtime: %playtime%

-

Has logged in %logintimes% times.

+

Has logged in %logintimes% times. | Has been kicked %timeskicked% times.

Age: %age% | Gender: %gender%