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
This commit is contained in:
Rsl1122 2017-01-12 01:34:39 +02:00
parent 88283969b1
commit a26622aa66
17 changed files with 544 additions and 164 deletions

View File

@ -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),

View File

@ -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;
}

View File

@ -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;
}
}

View File

@ -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 <player> [-a, -r].", CommandType.CONSOLE_WITH_ARGUMENTS);
super("inspect", "plan.inspect", "Inspect data /plan <player>", 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<String> 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;
}
}

View File

@ -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;
}
}

View File

@ -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);
}
}

View File

@ -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<String, String> 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<GameMode, Long> 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<String, String> 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 "<h1>404 Data was not found in cache</h1>";
}
Scanner scanner = new Scanner(plugin.getResource("analysis.html"));
String html = "";
while (scanner.hasNextLine()) {
String line = scanner.nextLine();
html += line + "\r\n";
}
HashMap<String, String> replaceMap = AnalysisUtils.getAnalysisReplaceRules(analysisCache.getData());
for (String key : replaceMap.keySet()) {
html = html.replaceAll(key, replaceMap.get(key));
}
return html;
}
public boolean checkIfAnalysisIsCached() {

View File

@ -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;
}

View File

@ -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;
}
}

View File

@ -13,19 +13,32 @@ import org.bukkit.GameMode;
*/
public class GMTimesPieChartCreator {
public static String createChart(HashMap<GameMode, Long> gmTimes, String uuid) {
public static String createChart(HashMap<GameMode, Long> 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<GameMode, Long> 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);

View File

@ -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());
}

View File

@ -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"

View File

@ -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<UserData> rawData;
private HashMap<Long, ServerData> 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<UUID> 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<Integer> ages = new ArrayList<>();
for (UserData uData : rawData) {
HashMap<GameMode, Long> 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<GameMode, Long> 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);
}

View File

@ -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<GameMode, Long> gmTimes, String uuid) {
String url = GMTimesPieChartCreator.createChart(gmTimes, uuid);
public static String createGMPieChart(HashMap<GameMode, Long> gmTimes) {
String url = GMTimesPieChartCreator.createChart(gmTimes);
return "<img src=\"" + url + "\">";
}
public static String createGMPieChart(HashMap<GameMode, Long> gmTimes, long total) {
String url = GMTimesPieChartCreator.createChart(gmTimes, total);
return "<img src=\"" + url + "\">";
}
public static HashMap<String, String> getInspectReplaceRules(UserData data) {
HashMap<String, String> 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<GameMode, Long> 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<Long, ServerData> rawServerData, long time) {
return "<img src=\"" + "\">";
}
public static HashMap<String, String> getAnalysisReplaceRules(AnalysisData data) {
HashMap<String, String> 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 "<img src=\"" + url + "\">";
}
}

View File

@ -16,25 +16,38 @@
<body>
<div style="line-height: 55%; font-family: Verdana, Geneva, sans-serif;">
<h1 style="text-decoration: underline;">Plan | Server Analysis</h1>
<h4>Analysis refreshed %refresh% ago</h4>
<table>
<tr>
<td style="margin-left: 3px; margin-right: auto;
border-style: groove; border-width: 3px; border-radius: 12px;
box-shadow: 5px 5px 4px 0px #888888;">
<p>%activitygraph%</p>
%playerchart%
</td>
<td style="margin-left: 3px; margin-right: auto;
border-style: groove; border-width: 3px; border-radius: 12px;
box-shadow: 5px 5px 4px 0px #888888;">
<p>%activitypiegraph%</p>
box-shadow: 5px 5px 4px 0px #888888;text-align: center;">
%activitypiechart%
<p>Active %active% | Inactive %inactive% | Banned %banned% | Total Players: %activitytotal%</p>
</td>
</tr>
</table>
<div style="margin-left: 3px; margin-right: auto;
border-style: groove; border-width: 3px; border-radius: 12px;
box-shadow: 5px 5px 4px 0px #888888;">
<p>Averages</p>
</div>
<tr>
<td style="margin-left: 3px; margin-right: auto;
border-style: groove; border-width: 3px; border-radius: 12px;
box-shadow: 5px 5px 4px 0px #888888;">
<p>%activitytotal% players have played on this server.</p>
<p>A Total of %totalplaytime% has been played with the average of %avgplaytime%</p>
<p>Players have joined %totallogins% times.</p>
<p>The average age of known players is %avgage%.</p>
</td>
<td style="margin-left: 3px; margin-right: auto;
border-style: groove; border-width: 3px; border-radius: 12px;
box-shadow: 5px 5px 4px 0px #888888;text-align: center;">
%gmpiechart%
<p>Survival: %gm0% | Creative: %gm1% | Adventure: %gm2% | Spectator: %gm3%</p>
</td>
</tr>
</table>
</div>
</body>
</html>

View File

@ -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

View File

@ -26,7 +26,7 @@
<p>Nicknames: %nicknames% | Has connected from ips: %ips%</p>
<p>Geolocation: %geoloc%</p>
<p>Playtime: %playtime%</p>
<p>Has logged in %logintimes% times.</p>
<p>Has logged in %logintimes% times. | Has been kicked %timeskicked% times.</p>
<p>Age: %age% | Gender: %gender%</p>
</td>
<td style="margin-left: 3px; margin-right: auto;