Made commands work as intended and look better. Bugfixes, top 50 commands

- Updated config file to clearer structure

Fixed bugs:
- Commands now show link with /tellraw command.
- PieCharts now check if total is not 100,
- Piecharts now render correctly (There was some issues with int)
- InspectCache updates properly.
- ClassCastException on start-up when PlanLite is not installed fixed.
- DataCache now returns active data to InspectCache if it is present.

Known Bugs:
- GMTimes on analysis page still shows 0 but graph works
- Page has to be refreshed multiple times to view (Faulty response)
- Top50Commands not pretty yet.
- Extra panel to put PlanLite stuff on is empty

Not implemented:
- PlanLite features
- Player Activity Graph
This commit is contained in:
Rsl1122 2017-01-12 13:38:13 +02:00
parent a26622aa66
commit 8c4d3e0f4d
27 changed files with 342 additions and 241 deletions

View File

@ -15,12 +15,15 @@ public enum Phrase {
USERNAME_NOT_KNOWN(ChatColor.RED+"Player not found from the database."), USERNAME_NOT_KNOWN(ChatColor.RED+"Player not found from the database."),
COLOR_MAIN(ChatColor.DARK_GREEN), COLOR_MAIN(ChatColor.DARK_GREEN),
COLOR_SEC(ChatColor.GRAY), COLOR_SEC(ChatColor.GRAY),
COLOR_TER(ChatColor.DARK_GRAY), COLOR_TER(ChatColor.WHITE),
ARROWS_RIGHT("»"),
BALL(""),
ERROR_PLANLITE("PlanLite not found, if you're have plugins using PlanAPI v1.6.0 download PlanLite."), ERROR_PLANLITE("PlanLite not found, if you're have plugins using PlanAPI v1.6.0 download PlanLite."),
ERROR_NO_USERNAME("INSPECT-GETNAME\nNo username given, returned empty username.\n"), ERROR_NO_USERNAME("INSPECT-GETNAME\nNo username given, returned empty username.\n"),
COMMAND_SENDER_NOT_PLAYER(ChatColor.RED + "[PLAN] This command can be only used as a player."), COMMAND_SENDER_NOT_PLAYER(ChatColor.RED + "[Plan] This command can be only used as a player."),
COMMAND_REQUIRES_ARGUMENTS(ChatColor.RED + "[PLAN] Command requires arguments."), COMMAND_REQUIRES_ARGUMENTS(ChatColor.RED + "[Plan] Command requires arguments."),
COMMAND_NO_PERMISSION(ChatColor.RED + "[PLAN] You do not have the required permmission."); COMMAND_REQUIRES_ARGUMENTS_ONE(ChatColor.RED + "[Plan] Command requires one argument."),
COMMAND_NO_PERMISSION(ChatColor.RED + "[Plan] You do not have the required permmission.");
private final String text; private final String text;
private final ChatColor color; private final ChatColor color;

View File

@ -93,7 +93,7 @@ public class Plan extends JavaPlugin {
log("Player Analytics Enabled."); log("Player Analytics Enabled.");
if (getConfig().getBoolean("RefreshAnalysisOnEnable")) { if (getConfig().getBoolean("Settings.Cache.AnalysisCache.RefreshAnalysisCacheOnEnable")) {
log("Analysis | Boot analysis in 30 seconds.."); log("Analysis | Boot analysis in 30 seconds..");
(new BukkitRunnable() { (new BukkitRunnable() {
@Override @Override
@ -108,7 +108,7 @@ public class Plan extends JavaPlugin {
public void hookPlanLite() { public void hookPlanLite() {
try { try {
if (getConfig().getBoolean("enabledData.planLite.pluginEnabled")) { if (getConfig().getBoolean("Settings.PlanLite.Enabled")) {
planLiteHook = new PlanLiteHook(this); planLiteHook = new PlanLiteHook(this);
} }
} catch (NoClassDefFoundError | Exception e) { } catch (NoClassDefFoundError | Exception e) {

View File

@ -33,8 +33,7 @@ public class PlanLiteHook {
} }
planLiteApi = planLite.getAPI(); planLiteApi = planLite.getAPI();
} catch (Exception e) { } catch (Exception e) {
plugin.logError(e.toString());
e.printStackTrace();
} }
} }

View File

@ -4,7 +4,6 @@ import com.djrapitops.plan.Plan;
import com.djrapitops.plan.PlanLiteHook; import com.djrapitops.plan.PlanLiteHook;
import com.djrapitops.planlite.api.DataPoint; import com.djrapitops.planlite.api.DataPoint;
import com.djrapitops.planlite.api.Hook; import com.djrapitops.planlite.api.Hook;
import com.djrapitops.plan.command.utils.DataFormatUtils;
import com.djrapitops.plan.utilities.FormatUtils; import com.djrapitops.plan.utilities.FormatUtils;
import java.util.Date; import java.util.Date;
import java.util.HashMap; import java.util.HashMap;

View File

@ -8,7 +8,6 @@ import com.djrapitops.plan.command.commands.InfoCommand;
import com.djrapitops.plan.command.commands.InspectCommand; import com.djrapitops.plan.command.commands.InspectCommand;
import com.djrapitops.plan.command.commands.ReloadCommand; import com.djrapitops.plan.command.commands.ReloadCommand;
import com.djrapitops.plan.command.commands.SearchCommand; import com.djrapitops.plan.command.commands.SearchCommand;
import com.djrapitops.plan.utilities.MiscUtils;
import com.djrapitops.plan.utilities.FormatUtils; import com.djrapitops.plan.utilities.FormatUtils;
import org.bukkit.command.Command; import org.bukkit.command.Command;

View File

@ -3,60 +3,45 @@ package com.djrapitops.plan.command;
import org.bukkit.command.Command; import org.bukkit.command.Command;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
public abstract class SubCommand public abstract class SubCommand {
{
private final String name; private final String name;
private final String permission; private final String permission;
private final String usage; private final String usage;
// private final Phrase description;
private final CommandType commandType; private final CommandType commandType;
private final String arguments;
public SubCommand( String name, String permission, String usage, CommandType commandType ) public SubCommand(String name, String permission, String usage, CommandType commandType, String arguments) {
{
this.name = name; this.name = name;
this.permission = permission; this.permission = permission;
this.usage = usage; this.usage = usage;
// this.description = description;
this.commandType = commandType; this.commandType = commandType;
this.arguments = arguments;
} }
public String getFirstName() public String getArguments() {
{ return arguments;
return name.split( "," )[0]; }
public String getFirstName() {
return name.split(",")[0];
} }
public String getName() public String getName() {
{
return name; return name;
} }
public String getPermission() public String getPermission() {
{
return permission; return permission;
} }
public String getUsage() public String getUsage() {
{
return usage; return usage;
} }
// public Phrase getDescription() public CommandType getCommandType() {
// {
// return description;
// }
public CommandType getCommandType()
{
return commandType; return commandType;
} }
public abstract boolean onCommand( CommandSender sender, Command cmd, String commandLabel, String[] args ); public abstract boolean onCommand(CommandSender sender, Command cmd, String commandLabel, String[] args);
} }

View File

@ -7,9 +7,12 @@ import com.djrapitops.plan.command.SubCommand;
import com.djrapitops.plan.data.cache.AnalysisCacheHandler; import com.djrapitops.plan.data.cache.AnalysisCacheHandler;
import com.djrapitops.plan.utilities.FormatUtils; import com.djrapitops.plan.utilities.FormatUtils;
import java.util.Date; import java.util.Date;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor; import org.bukkit.ChatColor;
import org.bukkit.command.Command; import org.bukkit.command.Command;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.entity.Player;
import org.bukkit.scheduler.BukkitRunnable; import org.bukkit.scheduler.BukkitRunnable;
public class AnalyzeCommand extends SubCommand { public class AnalyzeCommand extends SubCommand {
@ -18,30 +21,50 @@ public class AnalyzeCommand extends SubCommand {
private AnalysisCacheHandler analysisCache; private AnalysisCacheHandler analysisCache;
public AnalyzeCommand(Plan plugin) { public AnalyzeCommand(Plan plugin) {
super("analyze", "plan.analyze", "Analyze data of all players /plan analyze", CommandType.CONSOLE); super("analyze", "plan.analyze", "View the Server Analysis", CommandType.CONSOLE, "");
this.plugin = plugin; this.plugin = plugin;
analysisCache = plugin.getAnalysisCache(); analysisCache = plugin.getAnalysisCache();
} }
@Override @Override
public boolean onCommand(CommandSender sender, Command cmd, String commandLabel, String[] args) { public boolean onCommand(CommandSender sender, Command cmd, String commandLabel, String[] args) {
Date refresh = new Date();
if (!analysisCache.isCached()) { if (!analysisCache.isCached()) {
analysisCache.updateCache(); analysisCache.updateCache();
} else if (new Date().getTime() - analysisCache.getData().getRefreshDate() > 60 * 5) { } else if (new Date().getTime() - analysisCache.getData().getRefreshDate() > 60 * 5) {
analysisCache.updateCache(); analysisCache.updateCache();
} }
ChatColor operatorColor = Phrase.COLOR_MAIN.color(); ChatColor oColor = Phrase.COLOR_MAIN.color();
ChatColor textColor = Phrase.COLOR_SEC.color(); ChatColor tColor = Phrase.COLOR_SEC.color();
ChatColor hColor = Phrase.COLOR_TER.color();
FileConfiguration config = plugin.getConfig();
final boolean useAlternativeIP = config.getBoolean("Settings.WebServer.ShowAlternativeServerIP");
final int port = config.getInt("Settings.WebServer.Port");
final String alternativeIP = config.getString("Settings.WebServer.AlternativeIP").replaceAll("%port%", "" + port);
(new BukkitRunnable() { (new BukkitRunnable() {
@Override @Override
public void run() { public void run() {
if (analysisCache.isCached()) { if (analysisCache.isCached()) {
sender.sendMessage(textColor + "-- [" + operatorColor + "PLAN - Analysis results, refreshed " // Header
+ FormatUtils.formatTimeAmountSinceString("" + analysisCache.getData().getRefreshDate(), new Date()) + " ago:" + textColor + "] --"); sender.sendMessage(hColor + Phrase.ARROWS_RIGHT.toString() + oColor
sender.sendMessage(operatorColor + "Link: " + textColor + " Player Analytics - Analysis results");
+ "http://" + plugin.getServer().getIp() + ":" + plugin.getConfig().getString("WebServer.Port" // Link
) + "/server"); String url = "http://" + (useAlternativeIP ? alternativeIP : plugin.getServer().getIp() + ":" + port)
sender.sendMessage(textColor + "-- o --"); + "/server";
String message = tColor + " " + Phrase.BALL.toString() + oColor + " Link: " + hColor;
boolean console = !(sender instanceof Player);
if (console) {
sender.sendMessage(message + url);
} else {
sender.sendMessage(message);
Player player = (Player) sender;
Bukkit.getServer().dispatchCommand(
Bukkit.getConsoleSender(),
"tellraw " + player.getName() + " [\"\",{\"text\":\" Analysis Results\",\"underlined\":true,"
+ "\"clickEvent\":{\"action\":\"open_url\",\"value\":\"" + url + "\"}}]");
}
// Footer
sender.sendMessage(hColor + Phrase.ARROWS_RIGHT.toString());
this.cancel(); this.cancel();
} }
} }

View File

@ -1,36 +0,0 @@
package com.djrapitops.plan.command.commands;
import com.djrapitops.plan.Plan;
import com.djrapitops.plan.command.CommandType;
import com.djrapitops.plan.command.SubCommand;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
public class DebugCommand extends SubCommand {
private Plan plugin;
public DebugCommand(Plan plugin) {
super("debug", "plan.debug", "Test plugin for possible errors (debug feature)", CommandType.PLAYER);
this.plugin = plugin;
}
@Override
public boolean onCommand(CommandSender sender, Command cmd, String commandLabel, String[] args) {
if (!plugin.getConfig().getBoolean("debug")) {
sender.sendMessage(ChatColor.RED+"[Plan] Debug disabled in config");
return true;
}
String[] commands = {"plan", "plan info", "plan reload", "plan inspect",
"plan inspect "+sender.getName()+"-a", "plan inspect reinogiern",
"plan analyze", "plan search", "plan search "+sender.getName()+" -p"};
for (String command : commands) {
Bukkit.dispatchCommand(sender, command);
}
sender.sendMessage(ChatColor.GREEN+"[Plan] Debug successful, possible errors written in file.");
return true;
}
}

View File

@ -1,6 +1,7 @@
package com.djrapitops.plan.command.commands; package com.djrapitops.plan.command.commands;
//import com.djrapitops.plan.Phrase; //import com.djrapitops.plan.Phrase;
import com.djrapitops.plan.Phrase;
import com.djrapitops.plan.Plan; import com.djrapitops.plan.Plan;
import com.djrapitops.plan.command.CommandType; import com.djrapitops.plan.command.CommandType;
import com.djrapitops.plan.command.PlanCommand; import com.djrapitops.plan.command.PlanCommand;
@ -16,7 +17,7 @@ public class HelpCommand extends SubCommand {
private final PlanCommand command; private final PlanCommand command;
public HelpCommand(Plan plugin, PlanCommand command) { public HelpCommand(Plan plugin, PlanCommand command) {
super("help,?", "plan.?", "Show command list.", CommandType.CONSOLE); super("help,?", "plan.?", "Show command list.", CommandType.CONSOLE, "");
this.plugin = plugin; this.plugin = plugin;
this.command = command; this.command = command;
@ -25,12 +26,13 @@ public class HelpCommand extends SubCommand {
@Override @Override
public boolean onCommand(CommandSender sender, Command cmd, String commandLabel, String[] args) { public boolean onCommand(CommandSender sender, Command cmd, String commandLabel, String[] args) {
ChatColor operatorColor = ChatColor.DARK_GREEN; ChatColor oColor = Phrase.COLOR_MAIN.color();
ChatColor tColor = Phrase.COLOR_SEC.color();
ChatColor textColor = ChatColor.GRAY; ChatColor hColor = Phrase.COLOR_TER.color();
sender.sendMessage(textColor + "-- [" + operatorColor + "PLAN - Player Analytics" + textColor + "] --");
// Header
sender.sendMessage(hColor + Phrase.ARROWS_RIGHT.toString() + oColor + " Player Analytics - Help");
// Help results
for (SubCommand command : this.command.getCommands()) { for (SubCommand command : this.command.getCommands()) {
if (command.getName().equalsIgnoreCase(getName())) { if (command.getName().equalsIgnoreCase(getName())) {
continue; continue;
@ -44,9 +46,11 @@ public class HelpCommand extends SubCommand {
continue; continue;
} }
sender.sendMessage(operatorColor + "/plan " + command.getFirstName() + textColor + " - " + command.getUsage()); sender.sendMessage(tColor + " " + Phrase.BALL.toString() + oColor
+ " /plan " + command.getFirstName() + command.getArguments() + tColor + " - " + command.getUsage());
} }
// Footer
sender.sendMessage(hColor + Phrase.ARROWS_RIGHT.toString());
return true; return true;
} }

View File

@ -14,22 +14,22 @@ public class InfoCommand extends SubCommand {
private Plan plugin; private Plan plugin;
public InfoCommand(Plan plugin) { public InfoCommand(Plan plugin) {
super("info", "plan.info", "View version and enabled hooks", CommandType.CONSOLE); super("info", "plan.info", "View Version of Plan", CommandType.CONSOLE, "");
this.plugin = plugin; this.plugin = plugin;
} }
@Override @Override
public boolean onCommand(CommandSender sender, Command cmd, String commandLabel, String[] args) { public boolean onCommand(CommandSender sender, Command cmd, String commandLabel, String[] args) {
plugin.reloadConfig();
ChatColor oColor = Phrase.COLOR_MAIN.color(); ChatColor oColor = Phrase.COLOR_MAIN.color();
ChatColor tColor = Phrase.COLOR_SEC.color(); ChatColor tColor = Phrase.COLOR_SEC.color();
ChatColor hColor = Phrase.COLOR_TER.color();
String[] messages = { String[] messages = {
tColor +"--["+oColor+"PLAN - Info"+tColor+"]--", hColor + Phrase.ARROWS_RIGHT.toString()+oColor+"Player Analytics - Info",
oColor+"Version: "+tColor+plugin.getDescription().getVersion(), tColor + " " + Phrase.BALL.toString() +oColor+"Version: "+tColor+plugin.getDescription().getVersion(),
tColor+MiscUtils.checkVersion(), tColor + " " + Phrase.BALL.toString() +tColor+MiscUtils.checkVersion(),
oColor+"Cache Size: "+tColor+plugin.getHandler().getDataCache().keySet().size(), hColor + Phrase.ARROWS_RIGHT.toString()
oColor+"InspectCache Size: "+tColor+plugin.getInspectCache().getCache().keySet().size()
}; };
sender.sendMessage(messages); sender.sendMessage(messages);
return true; return true;

View File

@ -10,13 +10,17 @@ import java.util.Date;
import com.djrapitops.plan.data.cache.InspectCacheHandler; import com.djrapitops.plan.data.cache.InspectCacheHandler;
import com.djrapitops.plan.utilities.FormatUtils; import com.djrapitops.plan.utilities.FormatUtils;
import com.djrapitops.plan.utilities.MiscUtils; import com.djrapitops.plan.utilities.MiscUtils;
import static com.google.common.base.Predicates.instanceOf;
import java.util.UUID; import java.util.UUID;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor; import org.bukkit.ChatColor;
import org.bukkit.OfflinePlayer; import org.bukkit.OfflinePlayer;
import org.bukkit.command.Command; import org.bukkit.command.Command;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
import static org.bukkit.Bukkit.getOfflinePlayer; import static org.bukkit.Bukkit.getOfflinePlayer;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.entity.Player;
import org.bukkit.scheduler.BukkitRunnable; import org.bukkit.scheduler.BukkitRunnable;
public class InspectCommand extends SubCommand { public class InspectCommand extends SubCommand {
@ -25,7 +29,7 @@ public class InspectCommand extends SubCommand {
private InspectCacheHandler inspectCache; private InspectCacheHandler inspectCache;
public InspectCommand(Plan plugin) { public InspectCommand(Plan plugin) {
super("inspect", "plan.inspect", "Inspect data /plan <player>", CommandType.CONSOLE_WITH_ARGUMENTS); super("inspect", "plan.inspect", "Inspect Player's Data", CommandType.CONSOLE_WITH_ARGUMENTS, "<player>");
this.plugin = plugin; this.plugin = plugin;
inspectCache = plugin.getInspectCache(); inspectCache = plugin.getInspectCache();
@ -57,18 +61,42 @@ public class InspectCommand extends SubCommand {
Date refreshDate = new Date(); Date refreshDate = new Date();
inspectCache.cache(uuid); inspectCache.cache(uuid);
ChatColor operatorColor = Phrase.COLOR_MAIN.color(); ChatColor oColor = Phrase.COLOR_MAIN.color();
ChatColor textColor = Phrase.COLOR_SEC.color(); ChatColor tColor = Phrase.COLOR_SEC.color();
ChatColor hColor = Phrase.COLOR_TER.color();
FileConfiguration config = plugin.getConfig();
final boolean useAlternativeIP = config.getBoolean("Settings.WebServer.ShowAlternativeServerIP");
final int port = config.getInt("Settings.WebServer.Port");
final String alternativeIP = config.getString("Settings.WebServer.AlternativeIP").replaceAll("%port%", "" + port);
final int available = config.getInt("Settings.Cache.InspectCache.ClearFromInspectCacheAfterXMinutes");
(new BukkitRunnable() { (new BukkitRunnable() {
@Override @Override
public void run() { public void run() {
if (inspectCache.getCache().containsKey(uuid)) { if (inspectCache.getCache().containsKey(uuid)) {
sender.sendMessage(textColor + "-- [" + operatorColor + "PLAN - Inspect results: " + playerName + " - took " + FormatUtils.formatTimeAmountSinceDate(refreshDate, new Date()) + textColor + "] --"); // Header
sender.sendMessage(operatorColor + "Link: " + textColor sender.sendMessage(hColor + Phrase.ARROWS_RIGHT.toString() + oColor
+ "http://" + plugin.getServer().getIp() + ":" + plugin.getConfig().getString("WebServer.Port" + " Player Analytics - Inspect results: " + oColor + playerName
) + "/player/" + playerName); + tColor + " | took " + oColor + FormatUtils.formatTimeAmountSinceDate(refreshDate, new Date()));
sender.sendMessage(textColor+"Results will be available for 5 minutes."); // Link
sender.sendMessage(textColor + "-- o --"); String url = "http://" + (useAlternativeIP ? alternativeIP : plugin.getServer().getIp() + ":" + port)
+ "/player/" + playerName;
String message = tColor + " " + Phrase.BALL.toString() + oColor + " Link: " + hColor;
boolean console = !(sender instanceof Player);
if (console) {
sender.sendMessage(message + url);
} else {
sender.sendMessage(message);
Player player = (Player) sender;
Bukkit.getServer().dispatchCommand(
Bukkit.getConsoleSender(),
"tellraw " + player.getName() + " [\"\",{\"text\":\" Inspect Results\",\"underlined\":true,"
+ "\"clickEvent\":{\"action\":\"open_url\",\"value\":\"" + url + "\"}}]");
}
sender.sendMessage(tColor + " Results will be available for " + hColor + available + tColor + " minutes.");
// Footer
sender.sendMessage(hColor + Phrase.ARROWS_RIGHT.toString());
this.cancel(); this.cancel();
} }
} }

View File

@ -13,7 +13,7 @@ public class ReloadCommand extends SubCommand {
private Plan plugin; private Plan plugin;
public ReloadCommand(Plan plugin) { public ReloadCommand(Plan plugin) {
super("reload", "plan.reload", "Reload plugin config & save cached data", CommandType.CONSOLE); super("reload", "plan.reload", "Reload plugin config & save cached data", CommandType.CONSOLE, "");
this.plugin = plugin; this.plugin = plugin;
} }
@ -23,9 +23,7 @@ public class ReloadCommand extends SubCommand {
plugin.reloadConfig(); plugin.reloadConfig();
plugin.getHandler().saveCachedData(); plugin.getHandler().saveCachedData();
plugin.hookPlanLite(); plugin.hookPlanLite();
ChatColor operatorColor = Phrase.COLOR_MAIN.color(); sender.sendMessage(ChatColor.GREEN+"[Plan] Reload complete.");
ChatColor textColor = Phrase.COLOR_SEC.color();
sender.sendMessage(textColor + "[" + operatorColor + "PLAN" + textColor + "] Reload complete.");
return true; return true;
} }

View File

@ -4,42 +4,89 @@ import com.djrapitops.plan.Phrase;
import com.djrapitops.plan.Plan; import com.djrapitops.plan.Plan;
import com.djrapitops.plan.command.CommandType; import com.djrapitops.plan.command.CommandType;
import com.djrapitops.plan.command.SubCommand; import com.djrapitops.plan.command.SubCommand;
import com.djrapitops.plan.utilities.FormatUtils; import com.djrapitops.plan.data.cache.InspectCacheHandler;
import com.djrapitops.plan.utilities.MiscUtils;
import java.util.Arrays; import java.util.Arrays;
import java.util.Date; import java.util.HashSet;
import java.util.Set; import java.util.Set;
import java.util.UUID;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor; import org.bukkit.ChatColor;
import org.bukkit.OfflinePlayer; import org.bukkit.OfflinePlayer;
import org.bukkit.command.Command; import org.bukkit.command.Command;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.entity.Player;
public class SearchCommand extends SubCommand { public class SearchCommand extends SubCommand {
private final Plan plugin; private final Plan plugin;
private InspectCacheHandler inspectCache;
public SearchCommand(Plan plugin) { public SearchCommand(Plan plugin) {
super("search", "plan.search", "Inspect specific data /plan <search terms> [-p]", CommandType.CONSOLE_WITH_ARGUMENTS); super("search", "plan.search", "Search for player", CommandType.CONSOLE_WITH_ARGUMENTS, "<Part of Playername");
this.plugin = plugin; this.plugin = plugin;
inspectCache = plugin.getInspectCache();
} }
@Override @Override
public boolean onCommand(CommandSender sender, Command cmd, String commandLabel, String[] args) { public boolean onCommand(CommandSender sender, Command cmd, String commandLabel, String[] args) {
if (args.length != 1) {
Date refreshDate = new Date(); sender.sendMessage(Phrase.COMMAND_REQUIRES_ARGUMENTS_ONE.toString());
ChatColor operatorColor = Phrase.COLOR_MAIN.color();
ChatColor textColor = Phrase.COLOR_SEC.color();
//header
sender.sendMessage(textColor + "-- [" + operatorColor + "PLAN - Search results: took " + FormatUtils.formatTimeAmountSinceDate(refreshDate, new Date()) + textColor + "] --");
sender.sendMessage(operatorColor + "Results for: " + Arrays.toString(args));
sender.sendMessage(textColor + "Matching player: ");
if (false) {
sender.sendMessage(operatorColor + "No results for " + textColor + Arrays.toString(args) + operatorColor + ".");
} }
sender.sendMessage(textColor + "-- o --");
ChatColor oColor = Phrase.COLOR_MAIN.color();
ChatColor tColor = Phrase.COLOR_SEC.color();
ChatColor hColor = Phrase.COLOR_TER.color();
Set<OfflinePlayer> matches = MiscUtils.getMatchingDisplaynames(args[0]);
Set<UUID> uuids = new HashSet<>();
for (OfflinePlayer match : matches) {
UUID uuid = match.getUniqueId();
if (plugin.getDB().wasSeenBefore(uuid)) {
uuids.add(uuid);
inspectCache.cache(uuid);
}
}
FileConfiguration config = plugin.getConfig();
final boolean useAlternativeIP = config.getBoolean("Settings.WebServer.ShowAlternativeServerIP");
final int port = config.getInt("Settings.WebServer.Port");
final String alternativeIP = config.getString("Settings.WebServer.AlternativeIP").replaceAll("%port%", "" + port);
final int available = config.getInt("Settings.Cache.InspectCache.ClearFromInspectCacheAfterXMinutes");
// Header
sender.sendMessage(hColor + Phrase.ARROWS_RIGHT.toString() + oColor + " Player Analytics - Search results for: " + args[0]);
// Results
if (uuids.isEmpty()) {
sender.sendMessage(tColor + " " + Phrase.BALL.toString() + oColor + "No results for " + tColor + Arrays.toString(args) + oColor + ".");
} else {
for (OfflinePlayer match : matches) {
if (!uuids.contains(match.getUniqueId())) {
continue;
}
String name = match.getName();
sender.sendMessage(tColor + " Matching player: " + hColor + name);
// Link
String url = "http://" + (useAlternativeIP ? alternativeIP : plugin.getServer().getIp() + ":" + port)
+ "/player/" + name;
String message = tColor + " " + Phrase.BALL.toString() + oColor + " Link: " + hColor;
boolean console = !(sender instanceof Player);
if (console) {
sender.sendMessage(message + url);
} else {
sender.sendMessage(message);
Player player = (Player) sender;
Bukkit.getServer().dispatchCommand(
Bukkit.getConsoleSender(),
"tellraw "+player.getName()+ " [\"\",{\"text\":\" Search Result\",\"underlined\":true,"
+ "\"clickEvent\":{\"action\":\"open_url\",\"value\":\""+url+"\"}}]");
}
}
}
sender.sendMessage(tColor + " Results will be available for " + hColor + available + tColor + " minutes.");
// Footer
sender.sendMessage(hColor + Phrase.ARROWS_RIGHT.toString());
return true; return true;
} }
} }

View File

@ -1,51 +0,0 @@
package com.djrapitops.plan.command.utils;
import com.djrapitops.plan.Plan;
import com.djrapitops.plan.api.DataPoint;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import static org.bukkit.plugin.java.JavaPlugin.getPlugin;
public class DataFormatUtils {
// Saved in case I need these later on in development before release.
@Deprecated
public static void removeExtraDataPointsSearch(HashMap<String, DataPoint> dataMap, String[] args) {
if (args.length <= 1) {
}
HashMap<String, DataPoint> returnMap = new HashMap<>();
String errors = "FORMAT-SEARCH\n";
for (String key : dataMap.keySet()) {
for (String arg : args) {
try {
if (key.toLowerCase().contains(arg.toLowerCase())) {
returnMap.put(key, dataMap.get(key));
}
} catch (Exception e) {
if (!errors.contains(Arrays.toString(args))) {
errors += Arrays.toString(args) + "\n";
}
errors += (e + "\n" + key + " " + arg + "\n");
}
}
}
if (!errors.equals("FORMAT-SEARCH\n")) {
Plan plugin = getPlugin(Plan.class);
plugin.logToFile(errors);
}
}
@Deprecated
public static List<String[]> turnDataHashMapToSortedListOfArrays(HashMap<String, DataPoint> data) {
List<String[]> dataList = new ArrayList<>();
data.keySet().stream().forEach((key) -> {
dataList.add(new String[]{key, data.get(key).data()});
});
Collections.sort(dataList, (String[] strings, String[] otherStrings) -> strings[0].compareTo(otherStrings[0]));
return dataList;
}
}

View File

@ -14,11 +14,12 @@ public class AnalysisData {
private String gmTimesChartImgHtml; private String gmTimesChartImgHtml;
private String playersChartImgHtml; private String playersChartImgHtml;
private String activityChartImgHtml; private String activityChartImgHtml;
private String top50CommandsListHtml;
private int gm0Perc; private double gm0Perc;
private int gm1Perc; private double gm1Perc;
private int gm2Perc; private double gm2Perc;
private int gm3Perc; private double gm3Perc;
private int banned; private int banned;
private int active; private int active;
@ -33,6 +34,15 @@ public class AnalysisData {
} }
// Getters and setters v---------------------------------v // Getters and setters v---------------------------------v
public String getTop50CommandsListHtml() {
return top50CommandsListHtml;
}
public void setTop50CommandsListHtml(String top50CommandsListHtml) {
this.top50CommandsListHtml = top50CommandsListHtml;
}
public int getBanned() { public int getBanned() {
return banned; return banned;
} }
@ -65,38 +75,40 @@ public class AnalysisData {
this.total = total; this.total = total;
} }
public int getGm0Perc() { public double getGm0Perc() {
return gm0Perc; return gm0Perc;
} }
public void setGm0Perc(int gm0Perc) { public void setGm0Perc(double gm0Perc) {
this.gm0Perc = gm0Perc; this.gm0Perc = gm0Perc;
} }
public int getGm1Perc() { public double getGm1Perc() {
return gm1Perc; return gm1Perc;
} }
public void setGm1Perc(int gm1Perc) { public void setGm1Perc(double gm1Perc) {
this.gm1Perc = gm1Perc; this.gm1Perc = gm1Perc;
} }
public int getGm2Perc() { public double getGm2Perc() {
return gm2Perc; return gm2Perc;
} }
public void setGm2Perc(int gm2Perc) { public void setGm2Perc(double gm2Perc) {
this.gm2Perc = gm2Perc; this.gm2Perc = gm2Perc;
} }
public int getGm3Perc() { public double getGm3Perc() {
return gm3Perc; return gm3Perc;
} }
public void setGm3Perc(int gm3Perc) { public void setGm3Perc(double gm3Perc) {
this.gm3Perc = gm3Perc; this.gm3Perc = gm3Perc;
} }
public int getTotalPlayers() { public int getTotalPlayers() {
return totalPlayers; return totalPlayers;
} }

View File

@ -60,17 +60,24 @@ public class DataCacheHandler {
timesSaved = 0; timesSaved = 0;
int minutes = plugin.getConfig().getInt("saveEveryXMinutes"); int minutes = plugin.getConfig().getInt("Settings.Cache.DataCache.SaveEveryXMinutes");
if (minutes <= 0) { if (minutes <= 0) {
minutes = 5; minutes = 5;
} }
final int clearAfterXsaves;
int configValue = plugin.getConfig().getInt("Settings.Cache.DataCache.ClearCacheEveryXSaves");
if (configValue <= 1) {
clearAfterXsaves = 2;
} else {
clearAfterXsaves = configValue;
}
(new BukkitRunnable() { (new BukkitRunnable() {
@Override @Override
public void run() { public void run() {
DataCacheHandler handler = plugin.getHandler(); DataCacheHandler handler = plugin.getHandler();
handler.saveHandlerDataToCache(); handler.saveHandlerDataToCache();
handler.saveCachedData(); handler.saveCachedData();
if (timesSaved % 5 == 0) { if (timesSaved % clearAfterXsaves == 0) {
handler.clearCache(); handler.clearCache();
} }
timesSaved++; timesSaved++;
@ -96,6 +103,9 @@ public class DataCacheHandler {
} }
return dataCache.get(uuid); return dataCache.get(uuid);
} else { } else {
if (dataCache.get(uuid) != null) {
return dataCache.get(uuid);
}
return db.getUserData(uuid); return db.getUserData(uuid);
} }
} }

View File

@ -28,7 +28,7 @@ public class InspectCacheHandler {
} }
/** /**
* Caches the UserData of user to the HashMap for 5 minutes. Data is removed * Caches the UserData of user to the HashMap for X minutes. Data is removed
* from the cache automatically after 5 minutes with a BukkitRunnable * from the cache automatically after 5 minutes with a BukkitRunnable
* *
* @param uuid UUID of the player * @param uuid UUID of the player
@ -38,12 +38,16 @@ public class InspectCacheHandler {
return; return;
} }
cache.put(uuid, handler.getCurrentData(uuid, false)); cache.put(uuid, handler.getCurrentData(uuid, false));
int minutes = plugin.getConfig().getInt("Settings.Cache.InspectCache.ClearFromInspectCacheAfterXMinutes");
if (minutes <= 0) {
minutes = 3;
}
(new BukkitRunnable() { (new BukkitRunnable() {
@Override @Override
public void run() { public void run() {
clearFomCache(uuid); clearFomCache(uuid);
} }
}).runTaskLater(plugin, 60 * 20 * 3); }).runTaskLater(plugin, 60 * 20 * minutes);
} }
private void clearFomCache(UUID uuid) { private void clearFomCache(UUID uuid) {

View File

@ -21,7 +21,6 @@ import java.util.logging.Logger;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.GameMode; import org.bukkit.GameMode;
import org.bukkit.Location; import org.bukkit.Location;
import static org.bukkit.Bukkit.getOfflinePlayer;
import org.bukkit.World; import org.bukkit.World;
import org.bukkit.scheduler.BukkitRunnable; import org.bukkit.scheduler.BukkitRunnable;
import static org.bukkit.Bukkit.getOfflinePlayer; import static org.bukkit.Bukkit.getOfflinePlayer;

View File

@ -33,7 +33,7 @@ public class WebSocketServer {
public WebSocketServer(Plan plugin) { public WebSocketServer(Plan plugin) {
this.plugin = plugin; this.plugin = plugin;
this.inspectHandler = plugin.getInspectCache(); this.inspectHandler = plugin.getInspectCache();
this.PORT = plugin.getConfig().getInt("WebServer.Port"); this.PORT = plugin.getConfig().getInt("Settings.WebServer.Port");
shutdown = false; shutdown = false;
dataReqHandler = new DataRequestHandler(plugin); dataReqHandler = new DataRequestHandler(plugin);
} }

View File

@ -15,9 +15,9 @@ public class ActivityPieChartCreator {
int total = totalBanned + active + inactive; int total = totalBanned + active + inactive;
int banPerc = (int) (totalBanned / total); int banPerc = (int) ((totalBanned / total) * 100);
int inacPerc = (int) (inactive / total); int inacPerc = (int) ((inactive / total) * 100);
int actPerc = (int) (active / total); int actPerc = (int) ((active / total) * 100);
while (banPerc + inacPerc + actPerc < 100) { while (banPerc + inacPerc + actPerc < 100) {
actPerc++; actPerc++;
} }

View File

@ -25,20 +25,21 @@ public class GMTimesPieChartCreator {
long gmOne = gmTimes.get(GameMode.CREATIVE); long gmOne = gmTimes.get(GameMode.CREATIVE);
long gmTwo = gmTimes.get(GameMode.ADVENTURE); long gmTwo = gmTimes.get(GameMode.ADVENTURE);
long gmThree = gmTimes.get(GameMode.SPECTATOR); long gmThree = gmTimes.get(GameMode.SPECTATOR);
int zero = (int) (gmZero / total); int zero = (int) ((gmZero * 1.0 / total) * 100);
int one = (int) (gmOne / total); int one = (int) ((gmOne * 1.0 / total) * 100);
int two = (int) (gmTwo / total); int two = (int) ((gmTwo * 1.0 / total) * 100);
int three = (int) (gmThree / total); int three = (int) ((gmThree * 1.0 / total) * 100);
while (zero + one + two + three < 100) {
one++;
}
while (zero + one + two + three > 100) {
one--;
}
System.out.println(zero + " " + one + " " + two + " " + three + " " + (zero + one + two + three)); Slice s1 = Slice.newSlice(zero, Color.newColor("951800"), "Survival", "Survival");
Slice s2 = Slice.newSlice(one, Color.newColor("01A1DB"), "Creative", "Creative");
Slice s1 = Slice.newSlice((zero), Color.newColor("951800"), "Survival", "Survival"); Slice s3 = Slice.newSlice(two, Color.newColor("FFFF33"), "Adventure", "Adventure");
Slice s4 = Slice.newSlice(three, Color.newColor("228B22"), "Spectator", "Spectator");
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); PieChart refChart = GCharts.newPieChart(s1, s2, s3, s4);
refChart.setSize(500, 150); refChart.setSize(500, 150);

View File

@ -141,10 +141,23 @@ public class Analysis {
totalGmTimes.put(GameMode.SPECTATOR, gmThree); totalGmTimes.put(GameMode.SPECTATOR, gmThree);
String serverGMChartHtml = AnalysisUtils.createGMPieChart(totalGmTimes, gmTotal); String serverGMChartHtml = AnalysisUtils.createGMPieChart(totalGmTimes, gmTotal);
data.setGmTimesChartImgHtml(serverGMChartHtml); data.setGmTimesChartImgHtml(serverGMChartHtml);
data.setGm0Perc((int) (gmZero / gmTotal)); data.setGm0Perc((gmZero * 1.0 / gmTotal));
data.setGm1Perc((int) (gmOne / gmTotal)); data.setGm1Perc((gmOne * 1.0 / gmTotal));
data.setGm2Perc((int) (gmTwo / gmTotal)); data.setGm2Perc((gmTwo * 1.0 / gmTotal));
data.setGm3Perc((int) (gmThree / gmTotal)); data.setGm3Perc((gmThree * 1.0 / gmTotal));
if (rawServerData.keySet().size() > 0) {
ServerData sData = null;
for (long sDataKey : rawServerData.keySet()) {
sData = rawServerData.get(sDataKey);
break;
}
if (sData != null) {
data.setTop50CommandsListHtml(AnalysisUtils.createCommandUseListHtml(sData.getCommandUsage()));
}
} else {
data.setTop50CommandsListHtml("<p>Error Calcuclating Command usages (No usage data)</p>");
}
data.setRefreshDate(new Date().getTime()); data.setRefreshDate(new Date().getTime());
analysisCache.cache(data); analysisCache.cache(data);

View File

@ -7,7 +7,9 @@ import com.djrapitops.plan.data.UserData;
import com.djrapitops.plan.ui.graphs.GMTimesPieChartCreator; import com.djrapitops.plan.ui.graphs.GMTimesPieChartCreator;
import java.util.Date; import java.util.Date;
import java.util.HashMap; import java.util.HashMap;
import java.util.List;
import main.java.com.djrapitops.plan.ui.graphs.ActivityPieChartCreator; import main.java.com.djrapitops.plan.ui.graphs.ActivityPieChartCreator;
import main.java.com.djrapitops.plan.utilities.comparators.MapComparator;
import org.bukkit.GameMode; import org.bukkit.GameMode;
import static org.bukkit.plugin.java.JavaPlugin.getPlugin; import static org.bukkit.plugin.java.JavaPlugin.getPlugin;
@ -66,15 +68,16 @@ public class AnalysisUtils {
HashMap<String, String> replaceMap = new HashMap<>(); HashMap<String, String> replaceMap = new HashMap<>();
replaceMap.put("%activitypiechart%", data.getActivityChartImgHtml()); replaceMap.put("%activitypiechart%", data.getActivityChartImgHtml());
replaceMap.put("%gmpiechart%", data.getGmTimesChartImgHtml()); replaceMap.put("%gmpiechart%", data.getGmTimesChartImgHtml());
replaceMap.put("%gm0%", data.getGm0Perc()*100+"%"); replaceMap.put("%gm0%", (int) data.getGm0Perc()*100+"%");
replaceMap.put("%gm1%", data.getGm1Perc()*100+"%"); replaceMap.put("%gm1%", (int) data.getGm1Perc()*100+"%");
replaceMap.put("%gm2%", data.getGm2Perc()*100+"%"); replaceMap.put("%gm2%", (int) data.getGm2Perc()*100+"%");
replaceMap.put("%gm3%", data.getGm3Perc()*100+"%"); replaceMap.put("%gm3%", (int) data.getGm3Perc()*100+"%");
replaceMap.put("%active%", "" + data.getActive()); replaceMap.put("%active%", "" + data.getActive());
replaceMap.put("%banned%", "" + data.getBanned()); replaceMap.put("%banned%", "" + data.getBanned());
replaceMap.put("%inactive%", "" + data.getInactive()); replaceMap.put("%inactive%", "" + data.getInactive());
replaceMap.put("%activitytotal%", "" + data.getTotal()); replaceMap.put("%activitytotal%", "" + data.getTotal());
replaceMap.put("%playerchart%", data.getPlayersChartImgHtml()); replaceMap.put("%playerchart%", data.getPlayersChartImgHtml());
replaceMap.put("%top50commands%", data.getTop50CommandsListHtml());
replaceMap.put("%avgage%", ""+data.getAverageAge()); replaceMap.put("%avgage%", ""+data.getAverageAge());
replaceMap.put("%avgplaytime%", FormatUtils.formatTimeAmount(""+data.getAveragePlayTime())); replaceMap.put("%avgplaytime%", FormatUtils.formatTimeAmount(""+data.getAveragePlayTime()));
replaceMap.put("%totalplaytime%", FormatUtils.formatTimeAmount(""+data.getTotalPlayTime())); replaceMap.put("%totalplaytime%", FormatUtils.formatTimeAmount(""+data.getTotalPlayTime()));
@ -86,10 +89,11 @@ public class AnalysisUtils {
static boolean isActive(long lastPlayed, long playTime, int loginTimes) { static boolean isActive(long lastPlayed, long playTime, int loginTimes) {
Plan plugin = getPlugin(Plan.class); Plan plugin = getPlugin(Plan.class);
int timeToActive = plugin.getConfig().getInt("Settings.Analysis.MinutesPlayedUntilConsidiredActive");
long twoWeeks = 1209600; long twoWeeks = 1209600;
if (new Date().getTime() - lastPlayed < twoWeeks) { if (new Date().getTime() - lastPlayed < twoWeeks) {
if (loginTimes > 3) { if (loginTimes > 3) {
if (playTime > 3600) { if (playTime > 60 * timeToActive) {
return true; return true;
} }
} }
@ -101,4 +105,23 @@ public class AnalysisUtils {
String url = ActivityPieChartCreator.createChart(totalBanned, active, inactive); String url = ActivityPieChartCreator.createChart(totalBanned, active, inactive);
return "<img src=\"" + url + "\">"; return "<img src=\"" + url + "\">";
} }
static String createCommandUseListHtml(HashMap<String, Integer> commandUse) {
List<String[]> sorted = MapComparator.sortByValue(commandUse);
String html ="<table>";
if (sorted.isEmpty()) {
html = "<p>Error Calcuclating Command usages</p>";
return html;
}
int i = 1;
for (String[] values : sorted) {
if (i >= 50) {
break;
}
html += "<tr style=\"text-align: center;\"><td><b>"+values[1]+"</b></td>\r\n<td>"+values[0]+"</td></tr>";
i++;
}
html += "</table>";
return html;
}
} }

View File

@ -2,7 +2,6 @@ package com.djrapitops.plan.utilities;
import com.djrapitops.plan.Phrase; import com.djrapitops.plan.Phrase;
import com.djrapitops.plan.Plan; import com.djrapitops.plan.Plan;
import com.djrapitops.plan.utilities.FormatUtils;
import java.net.URL; import java.net.URL;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
@ -83,9 +82,11 @@ public class MiscUtils {
List<OfflinePlayer> players = new ArrayList<>(); List<OfflinePlayer> players = new ArrayList<>();
players.addAll(Arrays.asList(Bukkit.getOfflinePlayers())); players.addAll(Arrays.asList(Bukkit.getOfflinePlayers()));
Set<OfflinePlayer> matches = new HashSet<>(); Set<OfflinePlayer> matches = new HashSet<>();
players.parallelStream().filter((OfflinePlayer player) -> (player.getName().contains(search))).forEach((OfflinePlayer player) -> { players.parallelStream()
matches.add(player); .filter((OfflinePlayer player) -> (player.getName().toLowerCase().contains(search.toLowerCase())))
}); .forEach((OfflinePlayer player) -> {
matches.add(player);
});
return matches; return matches;
} }

View File

@ -0,0 +1,20 @@
package main.java.com.djrapitops.plan.utilities.comparators;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
public class MapComparator {
public static List<String[]> sortByValue(HashMap<String, Integer> hashMap) {
List<String[]> sortedList = new ArrayList<>();
hashMap.keySet().stream().forEach((key) -> {
sortedList.add(new String[]{""+hashMap.get(key), key});
});
Collections.sort(sortedList, (String[] strings, String[] otherStrings) -> strings[0].compareTo(otherStrings[0]));
return sortedList;
}
}

View File

@ -47,7 +47,19 @@
<p>Survival: %gm0% | Creative: %gm1% | Adventure: %gm2% | Spectator: %gm3%</p> <p>Survival: %gm0% | Creative: %gm1% | Adventure: %gm2% | Spectator: %gm3%</p>
</td> </td>
</tr> </tr>
</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;text-align: center;">
%top50commands%
</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;">
%top50commands%
</td>
</tr>
</table>
</div> </div>
</body> </body>
</html> </html>

View File

@ -1,13 +1,26 @@
debug: true debug: true
RefreshAnalysisOnEnable: true Settings:
saveEveryXMinutes: 5 Analysis:
MinutesPlayedUntilConsidiredActive: 10
Cache:
AnalysisCache:
RefreshAnalysisCacheOnEnable: true
InspectCache:
ClearFromInspectCacheAfterXMinutes: 3
DataCache:
SaveEveryXMinutes: 5
ClearCacheEveryXSaves: 5
WebServer:
Port: 8804
ShowAlternativeServerIP: false
AlternativeIP: your.ip.here:%port%
PlanLite:
Enabled: false
database: database:
type: sqlite type: sqlite
WebServer:
Port: 8804
enabledData: enabledData:
planLite: planLite:
pluginEnabled: true pluginEnabled: true
@ -19,11 +32,6 @@ enabledData:
economy: true economy: true
essentials: essentials:
ruleBreaking: true ruleBreaking: true
server:
commandUsage: true
playersOnline: true
amountOfNewPlayers: true