mirror of
https://github.com/plan-player-analytics/Plan.git
synced 2025-02-02 05:21:36 +01:00
JavaDocs and Cleaning
Created javadoc headers for everything but UserData and SQLDB classes. Now to just figure how to get it visible.
This commit is contained in:
parent
7803e5dc18
commit
5525ea2754
@ -32,7 +32,6 @@ PlanLite Top 20 most votes
|
||||
Top 20 most active
|
||||
Clear setting multiper (InspectCache)
|
||||
Clear check for existing clear task. (InspectCache)
|
||||
Update Version checker so it doesn't fail
|
||||
*/
|
||||
|
||||
/**
|
||||
|
@ -22,7 +22,7 @@ import static org.bukkit.plugin.java.JavaPlugin.getPlugin;
|
||||
*
|
||||
* @author Rsl1122
|
||||
*/
|
||||
public class PlanLiteHook implements Hook{
|
||||
public class PlanLiteHook implements Hook {
|
||||
|
||||
private PlanLite planLite;
|
||||
private Plan plugin;
|
||||
@ -62,42 +62,91 @@ public class PlanLiteHook implements Hook{
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Set of the Enabled hooks names.
|
||||
*/
|
||||
public Set<String> getEnabledHooksNames() {
|
||||
return planLite.getHooks().keySet();
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to get data from PlanLite for the Analysis & Inspect.
|
||||
*
|
||||
* @param playerName Name of the player.
|
||||
* @param dataPoint true (use datapoint system)
|
||||
* @return The data about the player.
|
||||
*/
|
||||
public HashMap<String, DataPoint> getData(String playerName, boolean dataPoint) {
|
||||
return planLiteApi.getData(playerName, dataPoint);
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to get data from PlanLite for the Analysis & Inspect.
|
||||
*
|
||||
* @param playerName Name of the player.
|
||||
* @param dataPoint true (use datapoint system)
|
||||
* @return The data about the player.
|
||||
*/
|
||||
public HashMap<String, DataPoint> getAllData(String playerName, boolean dataPoint) {
|
||||
return planLiteApi.getAllData(playerName, dataPoint);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return true if the config setting is true & PlanLite is installed.
|
||||
*/
|
||||
public boolean isEnabled() {
|
||||
return enabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* Passes commands to PlanLite.
|
||||
*
|
||||
* Used by /plan lite
|
||||
* @param sender
|
||||
* @param cmd
|
||||
* @param commandLabel
|
||||
* @param args
|
||||
* @return
|
||||
*/
|
||||
public boolean passCommand(CommandSender sender, Command cmd, String commandLabel, String[] args) {
|
||||
return planLite.getPlanCommand().onCommand(sender, cmd, commandLabel, args);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return true if server has towny
|
||||
*/
|
||||
public boolean hasTowny() {
|
||||
return getEnabledHooksNames().contains("Towny");
|
||||
}
|
||||
|
||||
/**
|
||||
* @return true if server has factions
|
||||
*/
|
||||
public boolean hasFactions() {
|
||||
return getEnabledHooksNames().contains("Factions");
|
||||
}
|
||||
|
||||
/**
|
||||
* @return true if server has superbvote
|
||||
*/
|
||||
public boolean hasSuperbVote() {
|
||||
return getEnabledHooksNames().contains("SuperbVote");
|
||||
}
|
||||
|
||||
/**
|
||||
* @return true if server has vault
|
||||
*/
|
||||
public boolean hasVault() {
|
||||
return getEnabledHooksNames().contains("Vault");
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to send data to PlanLite if it's use as UI is enabled.
|
||||
*
|
||||
* @param playername
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
@Override
|
||||
public HashMap<String, DataPoint> getData(String playername) throws Exception {
|
||||
HashMap<String, DataPoint> data = new HashMap<>();
|
||||
@ -112,7 +161,7 @@ public class PlanLiteHook implements Hook{
|
||||
if (key.equals("%planlite%") || key.equals("%gmpiechart%")) {
|
||||
continue;
|
||||
}
|
||||
data.put("PLA-"+key.toUpperCase().substring(1, key.length()-1), new DataPoint(userData.get(key), DataType.OTHER));
|
||||
data.put("PLA-" + key.toUpperCase().substring(1, key.length() - 1), new DataPoint(userData.get(key), DataType.OTHER));
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
@ -120,6 +169,13 @@ public class PlanLiteHook implements Hook{
|
||||
return data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to send data to PlanLite if it's use as UI is enabled.
|
||||
*
|
||||
* @param playername
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
@Override
|
||||
public HashMap<String, DataPoint> getAllData(String playername) throws Exception {
|
||||
return getData(playername);
|
||||
|
@ -3,8 +3,13 @@ package com.djrapitops.plan.api;
|
||||
public enum Gender {
|
||||
MALE, FEMALE, OTHER, UNKNOWN;
|
||||
|
||||
public static Gender parse(String string) {
|
||||
switch (string) {
|
||||
/**
|
||||
* Gets the Enum that corresponds to the name.
|
||||
* @param name name of the gender enum.
|
||||
* @return Gender Enum
|
||||
*/
|
||||
public static Gender parse(String name) {
|
||||
switch (name) {
|
||||
case "female":
|
||||
return Gender.FEMALE;
|
||||
case "male":
|
||||
|
@ -3,6 +3,10 @@ package com.djrapitops.plan.command;
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.command.CommandSender;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Rsl1122
|
||||
*/
|
||||
public abstract class SubCommand {
|
||||
|
||||
private final String name;
|
||||
@ -11,6 +15,14 @@ public abstract class SubCommand {
|
||||
private final CommandType commandType;
|
||||
private final String arguments;
|
||||
|
||||
/**
|
||||
* Class constructor, called with super(...) in subcommands.
|
||||
* @param name Name(s) (aliases) of the command
|
||||
* @param permission Required permission
|
||||
* @param usage Usage information
|
||||
* @param commandType Type Enum
|
||||
* @param arguments Additional possible arguments the command requires
|
||||
*/
|
||||
public SubCommand(String name, String permission, String usage, CommandType commandType, String arguments) {
|
||||
this.name = name;
|
||||
this.permission = permission;
|
||||
@ -19,29 +31,55 @@ public abstract class SubCommand {
|
||||
this.arguments = arguments;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Additional possible arguments the command requires
|
||||
*/
|
||||
public String getArguments() {
|
||||
return arguments;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return First alias of the command
|
||||
*/
|
||||
public String getFirstName() {
|
||||
return name.split(",")[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return All aliases
|
||||
*/
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Required permission
|
||||
*/
|
||||
public String getPermission() {
|
||||
return permission;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Usage information
|
||||
*/
|
||||
public String getUsage() {
|
||||
return usage;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return CommandType Enum.
|
||||
*/
|
||||
public CommandType getCommandType() {
|
||||
return commandType;
|
||||
}
|
||||
|
||||
/**
|
||||
* The Command Execution method.
|
||||
* @param sender
|
||||
* @param cmd
|
||||
* @param commandLabel
|
||||
* @param args
|
||||
* @return
|
||||
*/
|
||||
public abstract boolean onCommand(CommandSender sender, Command cmd, String commandLabel, String[] args);
|
||||
}
|
||||
|
@ -25,7 +25,7 @@ public class AnalyzeCommand extends SubCommand {
|
||||
private AnalysisCacheHandler analysisCache;
|
||||
|
||||
/**
|
||||
* Class Constructor.
|
||||
* Subcommand Constructor.
|
||||
*
|
||||
* @param plugin Current instance of Plan
|
||||
*/
|
||||
@ -77,6 +77,12 @@ public class AnalyzeCommand extends SubCommand {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to send the message after /plan analysis.
|
||||
* @param sender Command sender.
|
||||
* @param config Plan config.
|
||||
* @throws CommandException
|
||||
*/
|
||||
public void sendAnalysisMessage(CommandSender sender, FileConfiguration config) throws CommandException {
|
||||
ChatColor oColor = Phrase.COLOR_MAIN.color();
|
||||
ChatColor tColor = Phrase.COLOR_SEC.color();
|
||||
|
@ -11,11 +11,21 @@ import org.bukkit.command.Command;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Rsl1122
|
||||
*/
|
||||
public class HelpCommand extends SubCommand {
|
||||
|
||||
private final Plan plugin;
|
||||
private final PlanCommand command;
|
||||
|
||||
/**
|
||||
* Subcommand Constructor.
|
||||
*
|
||||
* @param plugin Current instance of Plan
|
||||
* @param command Current instance of PlanCommand
|
||||
*/
|
||||
public HelpCommand(Plan plugin, PlanCommand command) {
|
||||
super("help,?", "plan.?", "Show command list.", CommandType.CONSOLE, "");
|
||||
|
||||
@ -47,7 +57,7 @@ public class HelpCommand extends SubCommand {
|
||||
}
|
||||
|
||||
sender.sendMessage(tColor + " " + Phrase.BALL.toString() + oColor
|
||||
+ " /plan " + command.getFirstName() +" "+ command.getArguments() + tColor + " - " + command.getUsage());
|
||||
+ " /plan " + command.getFirstName() + " " + command.getArguments() + tColor + " - " + command.getUsage());
|
||||
}
|
||||
// Footer
|
||||
sender.sendMessage(hColor + Phrase.ARROWS_RIGHT.toString());
|
||||
|
@ -9,10 +9,19 @@ import org.bukkit.ChatColor;
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.command.CommandSender;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Rsl1122
|
||||
*/
|
||||
public class InfoCommand extends SubCommand {
|
||||
|
||||
private Plan plugin;
|
||||
|
||||
/**
|
||||
* Subcommand Constructor.
|
||||
*
|
||||
* @param plugin Current instance of Plan
|
||||
*/
|
||||
public InfoCommand(Plan plugin) {
|
||||
super("info", "plan.info", "View Version of Plan", CommandType.CONSOLE, "");
|
||||
|
||||
@ -28,7 +37,7 @@ public class InfoCommand extends SubCommand {
|
||||
String[] messages = {
|
||||
hColor + Phrase.ARROWS_RIGHT.toString() + oColor + " Player Analytics - Info",
|
||||
tColor + " " + Phrase.BALL.toString() + oColor + " Version: " + tColor + plugin.getDescription().getVersion(),
|
||||
tColor + " " + Phrase.BALL.toString() + tColor +" "+ MiscUtils.checkVersion(),
|
||||
tColor + " " + Phrase.BALL.toString() + tColor + " " + MiscUtils.checkVersion(),
|
||||
hColor + Phrase.ARROWS_RIGHT.toString()
|
||||
};
|
||||
sender.sendMessage(messages);
|
||||
|
@ -7,7 +7,6 @@ import com.djrapitops.plan.utilities.UUIDFetcher;
|
||||
import com.djrapitops.plan.command.CommandType;
|
||||
import com.djrapitops.plan.command.SubCommand;
|
||||
|
||||
import java.util.Date;
|
||||
import com.djrapitops.plan.data.cache.InspectCacheHandler;
|
||||
import com.djrapitops.plan.utilities.MiscUtils;
|
||||
import java.util.UUID;
|
||||
@ -17,11 +16,11 @@ import org.bukkit.ChatColor;
|
||||
import org.bukkit.OfflinePlayer;
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import static org.bukkit.Bukkit.getOfflinePlayer;
|
||||
import org.bukkit.configuration.file.FileConfiguration;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.scheduler.BukkitRunnable;
|
||||
import static org.bukkit.Bukkit.getOfflinePlayer;
|
||||
import static org.bukkit.Bukkit.getOfflinePlayer;
|
||||
|
||||
/**
|
||||
*
|
||||
@ -110,7 +109,7 @@ public class InspectCommand extends SubCommand {
|
||||
(new BukkitRunnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (inspectCache.getCache().containsKey(uuid)) {
|
||||
if (inspectCache.isCached(uuid)) {
|
||||
// Header
|
||||
sender.sendMessage(hColor + Phrase.ARROWS_RIGHT.toString() + oColor
|
||||
+ " Player Analytics - Inspect results: " + oColor + playerName);
|
||||
|
@ -7,11 +7,20 @@ import com.djrapitops.plan.command.SubCommand;
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.command.CommandSender;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Rsl1122
|
||||
*/
|
||||
public class LiteCommand extends SubCommand {
|
||||
|
||||
private Plan plugin;
|
||||
private PlanLiteHook hook;
|
||||
|
||||
/**
|
||||
* Subcommand Constructor.
|
||||
*
|
||||
* @param plugin Current instance of Plan
|
||||
*/
|
||||
public LiteCommand(Plan plugin) {
|
||||
super("lite", "plan.?", "Use PlanLite Commands", CommandType.CONSOLE, "<planlite command>");
|
||||
|
||||
|
@ -1,6 +1,5 @@
|
||||
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;
|
||||
@ -8,10 +7,19 @@ import org.bukkit.ChatColor;
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.command.CommandSender;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Rsl1122
|
||||
*/
|
||||
public class ReloadCommand extends SubCommand {
|
||||
|
||||
private Plan plugin;
|
||||
|
||||
/**
|
||||
* Subcommand constructor.
|
||||
*
|
||||
* @param plugin Current instance of Plan
|
||||
*/
|
||||
public ReloadCommand(Plan plugin) {
|
||||
super("reload", "plan.reload", "Reload plugin config & save cached data", CommandType.CONSOLE, "");
|
||||
|
||||
|
@ -38,199 +38,359 @@ public class AnalysisData {
|
||||
private boolean planLiteEnabled;
|
||||
private PlanLiteAnalyzedData planLiteData;
|
||||
|
||||
/**
|
||||
* Class constructor.
|
||||
*
|
||||
* All data has to be set with setters to avoid NPE.
|
||||
*/
|
||||
public AnalysisData() {
|
||||
}
|
||||
|
||||
// Getters and setters v---------------------------------v
|
||||
|
||||
/**
|
||||
* @return The Amount of players who have joined only once
|
||||
*/
|
||||
public int getJoinleaver() {
|
||||
return joinleaver;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param joinleaver The Amount of players who have joined only once
|
||||
*/
|
||||
public void setJoinleaver(int joinleaver) {
|
||||
this.joinleaver = joinleaver;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return true if PlanLite was enabled at the time of Analysis
|
||||
*/
|
||||
public boolean isPlanLiteEnabled() {
|
||||
return planLiteEnabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param planLiteEnabled true if PlanLite was enabled at the time of Analysis
|
||||
*/
|
||||
public void setPlanLiteEnabled(boolean planLiteEnabled) {
|
||||
this.planLiteEnabled = planLiteEnabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the PlanLiteAnalyzedData.
|
||||
*
|
||||
* null if planLiteEnabled = false
|
||||
* @return Seperate object used to save PlanLiteData
|
||||
*/
|
||||
public PlanLiteAnalyzedData getPlanLiteData() {
|
||||
return planLiteData;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the PlanLiteAnalyzedData.
|
||||
* @param planLiteData Seperate object used to save PlanLiteData
|
||||
*/
|
||||
public void setPlanLiteData(PlanLiteAnalyzedData planLiteData) {
|
||||
this.planLiteData = planLiteData;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return HTML String of the Month Activity graph
|
||||
*/
|
||||
public String getPlayersChartImgHtmlMonth() {
|
||||
return playersChartImgHtmlMonth;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param playersChartImgHtmlMonth HTML String of the Month Activity graph
|
||||
*/
|
||||
public void setPlayersChartImgHtmlMonth(String playersChartImgHtmlMonth) {
|
||||
this.playersChartImgHtmlMonth = playersChartImgHtmlMonth;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return HTML String of the Week Activity graph
|
||||
*/
|
||||
public String getPlayersChartImgHtmlWeek() {
|
||||
return playersChartImgHtmlWeek;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param playersChartImgHtmlWeek HTML String of the Week Activity graph
|
||||
*/
|
||||
public void setPlayersChartImgHtmlWeek(String playersChartImgHtmlWeek) {
|
||||
this.playersChartImgHtmlWeek = playersChartImgHtmlWeek;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return HTML String of the Day Activity graph
|
||||
*/
|
||||
public String getPlayersChartImgHtmlDay() {
|
||||
return playersChartImgHtmlDay;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param playersChartImgHtmlDay HTML String of the Day Activity graph
|
||||
*/
|
||||
public void setPlayersChartImgHtmlDay(String playersChartImgHtmlDay) {
|
||||
this.playersChartImgHtmlDay = playersChartImgHtmlDay;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return HTML String of the Top50CommandsList
|
||||
*/
|
||||
public String getTop50CommandsListHtml() {
|
||||
return top50CommandsListHtml;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param top50CommandsListHtml HTML String of the Top50CommandsList
|
||||
*/
|
||||
public void setTop50CommandsListHtml(String top50CommandsListHtml) {
|
||||
this.top50CommandsListHtml = top50CommandsListHtml;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Amount of banned players
|
||||
*/
|
||||
public int getBanned() {
|
||||
return banned;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param banned Amount of banned players
|
||||
*/
|
||||
public void setBanned(int banned) {
|
||||
this.banned = banned;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the amount of active players.
|
||||
*
|
||||
* Activity is determined by AnalysisUtils.isActive()
|
||||
*
|
||||
* @return Amount of active players
|
||||
*/
|
||||
public int getActive() {
|
||||
return active;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the amount of active players.
|
||||
*
|
||||
* Activity is determined by AnalysisUtils.isActive()
|
||||
*
|
||||
* @param active Amount of active players
|
||||
*/
|
||||
public void setActive(int active) {
|
||||
this.active = active;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Amount of inactive players
|
||||
*/
|
||||
public int getInactive() {
|
||||
return inactive;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param inactive Amount of inactive players
|
||||
*/
|
||||
public void setInactive(int inactive) {
|
||||
this.inactive = inactive;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Total Amount of players used to calculate activity
|
||||
*/
|
||||
public int getTotal() {
|
||||
return total;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param total Total Amount of players used to calculate activity
|
||||
*/
|
||||
public void setTotal(int total) {
|
||||
this.total = total;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Percentage of Gamemode usage time as a whole
|
||||
*/
|
||||
public double getGm0Perc() {
|
||||
return gm0Perc;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param gm0Perc Percentage of Gamemode usage time as a whole
|
||||
*/
|
||||
public void setGm0Perc(double gm0Perc) {
|
||||
this.gm0Perc = gm0Perc;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Percentage of Gamemode usage time as a whole
|
||||
*/
|
||||
public double getGm1Perc() {
|
||||
return gm1Perc;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param gm1Perc Percentage of Gamemode usage time as a whole
|
||||
*/
|
||||
public void setGm1Perc(double gm1Perc) {
|
||||
this.gm1Perc = gm1Perc;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Percentage of Gamemode usage time as a whole
|
||||
*/
|
||||
public double getGm2Perc() {
|
||||
return gm2Perc;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param gm2Perc Percentage of Gamemode usage time as a whole
|
||||
*/
|
||||
public void setGm2Perc(double gm2Perc) {
|
||||
this.gm2Perc = gm2Perc;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Percentage of Gamemode usage time as a whole
|
||||
*/
|
||||
public double getGm3Perc() {
|
||||
return gm3Perc;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param gm3Perc Percentage of Gamemode usage time as a whole
|
||||
*/
|
||||
public void setGm3Perc(double gm3Perc) {
|
||||
this.gm3Perc = gm3Perc;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Total number of players according to bukkit's data.
|
||||
*/
|
||||
public int getTotalPlayers() {
|
||||
return totalPlayers;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param totalPlayers Total number of players according to bukkit's data.
|
||||
*/
|
||||
public void setTotalPlayers(int totalPlayers) {
|
||||
this.totalPlayers = totalPlayers;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return How long has been played, long in ms.
|
||||
*/
|
||||
public long getTotalPlayTime() {
|
||||
return totalPlayTime;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param totalPlayTime How long has been played, long in ms.
|
||||
*/
|
||||
public void setTotalPlayTime(long totalPlayTime) {
|
||||
this.totalPlayTime = totalPlayTime;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Last Analysis Refresh, long in ms.
|
||||
*/
|
||||
public long getRefreshDate() {
|
||||
return refreshDate;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return How long has been played on average, long in ms.
|
||||
*/
|
||||
public long getAveragePlayTime() {
|
||||
return averagePlayTime;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Average age of the players whose age has been gathered.
|
||||
*/
|
||||
public double getAverageAge() {
|
||||
return averageAge;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return HTML String of the GMTimes Piechart
|
||||
*/
|
||||
public String getGmTimesChartImgHtml() {
|
||||
return gmTimesChartImgHtml;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return HTML String of the Activity Piechart
|
||||
*/
|
||||
public String getActivityChartImgHtml() {
|
||||
return activityChartImgHtml;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return How many times players have joined.
|
||||
*/
|
||||
public long getTotalLoginTimes() {
|
||||
return totalLoginTimes;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return How many operators are on the server.
|
||||
*/
|
||||
public int getOps() {
|
||||
return ops;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param refreshDate Last Analysis Refresh, long in ms.
|
||||
*/
|
||||
public void setRefreshDate(long refreshDate) {
|
||||
this.refreshDate = refreshDate;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param averagePlayTime long in ms.
|
||||
*/
|
||||
public void setAveragePlayTime(long averagePlayTime) {
|
||||
this.averagePlayTime = averagePlayTime;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param averageAge Average age of the players whose age has been gathered.
|
||||
*/
|
||||
public void setAverageAge(double averageAge) {
|
||||
this.averageAge = averageAge;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param gmTimesChartImgHtml HTML String of the GMTimes Piechart
|
||||
*/
|
||||
public void setGmTimesChartImgHtml(String gmTimesChartImgHtml) {
|
||||
this.gmTimesChartImgHtml = gmTimesChartImgHtml;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param activityChartImgHtml HTML String of the Activity Piechart
|
||||
*/
|
||||
public void setActivityChartImgHtml(String activityChartImgHtml) {
|
||||
this.activityChartImgHtml = activityChartImgHtml;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param totalLoginTimes How many times playes have logged in
|
||||
*/
|
||||
public void setTotalLoginTimes(long totalLoginTimes) {
|
||||
this.totalLoginTimes = totalLoginTimes;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ops Amount of operators.
|
||||
*/
|
||||
public void setOps(int ops) {
|
||||
this.ops = ops;
|
||||
}
|
||||
|
@ -2,44 +2,74 @@ package com.djrapitops.plan.data;
|
||||
|
||||
import com.djrapitops.plan.api.Gender;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Rsl1122
|
||||
*/
|
||||
public class DemographicsData {
|
||||
|
||||
private int age;
|
||||
private Gender gender;
|
||||
private String geoLocation;
|
||||
|
||||
/**
|
||||
* Creates demographics data object from existing data.
|
||||
*
|
||||
* @param age
|
||||
* @param gender
|
||||
* @param geoLocation
|
||||
*/
|
||||
public DemographicsData(int age, Gender gender, String geoLocation) {
|
||||
this.age = age;
|
||||
this.gender = gender;
|
||||
this.geoLocation = geoLocation;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates new demographics data object with default parameters.
|
||||
*/
|
||||
public DemographicsData() {
|
||||
this(-1, Gender.UNKNOWN, "Not Known");
|
||||
}
|
||||
|
||||
// Getters
|
||||
/**
|
||||
* @return Age of the player, -1 if not known
|
||||
*/
|
||||
public int getAge() {
|
||||
return age;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Gender Enum of the Player. UNKNOWN if not known
|
||||
*/
|
||||
public Gender getGender() {
|
||||
return gender;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Geolocation string of the player "Not known" if not known.
|
||||
*/
|
||||
public String getGeoLocation() {
|
||||
return geoLocation;
|
||||
}
|
||||
|
||||
// Setters
|
||||
/**
|
||||
* @param age
|
||||
*/
|
||||
public void setAge(int age) {
|
||||
this.age = age;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param gender
|
||||
*/
|
||||
public void setGender(Gender gender) {
|
||||
this.gender = gender;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param geoLocation
|
||||
*/
|
||||
public void setGeoLocation(String geoLocation) {
|
||||
this.geoLocation = geoLocation;
|
||||
}
|
||||
|
@ -1,4 +1,3 @@
|
||||
|
||||
package main.java.com.djrapitops.plan.data;
|
||||
|
||||
import java.util.HashMap;
|
||||
@ -14,41 +13,68 @@ public class PlanLiteAnalyzedData {
|
||||
private int totalVotes;
|
||||
private int totalMoney;
|
||||
|
||||
/**
|
||||
* Class Constructor.
|
||||
*
|
||||
* All data has to be set to avoid NPE.
|
||||
*/
|
||||
public PlanLiteAnalyzedData() {
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Map of Town names with residents inside them.
|
||||
*/
|
||||
public HashMap<String, Integer> getTownMap() {
|
||||
return townMap;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param townMap Map of Town names with residents inside them.
|
||||
*/
|
||||
public void setTownMap(HashMap<String, Integer> townMap) {
|
||||
this.townMap = townMap;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Map of Faction names with players inside them.
|
||||
*/
|
||||
public HashMap<String, Integer> getFactionMap() {
|
||||
return factionMap;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param factionMap Map of Faction names with players inside them.
|
||||
*/
|
||||
public void setFactionMap(HashMap<String, Integer> factionMap) {
|
||||
this.factionMap = factionMap;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Amount of votes the server has recieved.
|
||||
*/
|
||||
public int getTotalVotes() {
|
||||
return totalVotes;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param totalVotes Amount of votes the server has recieved.
|
||||
*/
|
||||
public void setTotalVotes(int totalVotes) {
|
||||
this.totalVotes = totalVotes;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Amount of money that is in the economy.
|
||||
*/
|
||||
public int getTotalMoney() {
|
||||
return totalMoney;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param totalMoney Amount of money that is in the economy.
|
||||
*/
|
||||
public void setTotalMoney(int totalMoney) {
|
||||
this.totalMoney = totalMoney;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
@ -22,69 +22,122 @@ public class PlanLitePlayerData {
|
||||
|
||||
private double money;
|
||||
|
||||
/**
|
||||
* Class Constructor.
|
||||
*
|
||||
* All data has to be set to avoid NPE
|
||||
*/
|
||||
public PlanLitePlayerData() {
|
||||
}
|
||||
|
||||
/**
|
||||
* @param towny Is Towny installed?
|
||||
*/
|
||||
public void setTowny(boolean towny) {
|
||||
this.towny = towny;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param factions Is Factions installed?
|
||||
*/
|
||||
public void setFactions(boolean factions) {
|
||||
this.factions = factions;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param superbVote Is SuperbVote installed?
|
||||
*/
|
||||
public void setSuperbVote(boolean superbVote) {
|
||||
this.superbVote = superbVote;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param vault Is Vault installed?
|
||||
*/
|
||||
public void setVault(boolean vault) {
|
||||
this.vault = vault;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param town Name of town player is resident in (Towny)
|
||||
*/
|
||||
public void setTown(String town) {
|
||||
this.town = town;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param friends Friends of player (Towny)
|
||||
*/
|
||||
public void setFriends(String friends) {
|
||||
this.friends = friends;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param plotPerms Perms of player (Towny)
|
||||
*/
|
||||
public void setPlotPerms(String plotPerms) {
|
||||
this.plotPerms = plotPerms;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param plotOptions Options of player (Towny)
|
||||
*/
|
||||
public void setPlotOptions(String plotOptions) {
|
||||
this.plotOptions = plotOptions;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param faction Faction the player is in
|
||||
*/
|
||||
public void setFaction(String faction) {
|
||||
this.faction = faction;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param votes How many votes the player has
|
||||
*/
|
||||
public void setVotes(int votes) {
|
||||
this.votes = votes;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param money How much money the player has
|
||||
*/
|
||||
public void setMoney(double money) {
|
||||
this.money = money;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Is Towny installed?
|
||||
*/
|
||||
public boolean hasTowny() {
|
||||
return towny;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Is Factions installed?
|
||||
*/
|
||||
public boolean hasFactions() {
|
||||
return factions;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Is Superbvote installed?
|
||||
*/
|
||||
public boolean hasSuperbVote() {
|
||||
return superbVote;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Is Vault installed?
|
||||
*/
|
||||
public boolean hasVault() {
|
||||
return vault;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Town player is resident in
|
||||
*/
|
||||
public String getTown() {
|
||||
if (towny) {
|
||||
return town;
|
||||
@ -92,6 +145,9 @@ public class PlanLitePlayerData {
|
||||
return "";
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Friends of player (towny)
|
||||
*/
|
||||
public String getFriends() {
|
||||
if (towny) {
|
||||
return friends;
|
||||
@ -99,6 +155,9 @@ public class PlanLitePlayerData {
|
||||
return "";
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Perms of player (towny)
|
||||
*/
|
||||
public String getPlotPerms() {
|
||||
if (towny) {
|
||||
return plotPerms;
|
||||
@ -106,6 +165,9 @@ public class PlanLitePlayerData {
|
||||
return "";
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Options of player (towny)
|
||||
*/
|
||||
public String getPlotOptions() {
|
||||
if (towny) {
|
||||
return plotOptions;
|
||||
@ -113,6 +175,9 @@ public class PlanLitePlayerData {
|
||||
return "";
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Faction of player
|
||||
*/
|
||||
public String getFaction() {
|
||||
if (factions) {
|
||||
return faction;
|
||||
@ -120,6 +185,9 @@ public class PlanLitePlayerData {
|
||||
return "";
|
||||
}
|
||||
|
||||
/**
|
||||
* @return How many times player has voted, -1 if superbvote not installed
|
||||
*/
|
||||
public int getVotes() {
|
||||
if (superbVote) {
|
||||
return votes;
|
||||
@ -127,6 +195,9 @@ public class PlanLitePlayerData {
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return How much money player has. -1 if vault not installed
|
||||
*/
|
||||
public double getMoney() {
|
||||
if (vault) {
|
||||
return money;
|
||||
|
@ -82,7 +82,9 @@ public class ServerData {
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds command to the commandUse Map and adds 1 to the amount it has been used.
|
||||
* Adds command to the commandUse Map and adds 1 to the amount it has been
|
||||
* used.
|
||||
*
|
||||
* @param command Used command (eg. /plan)
|
||||
*/
|
||||
public void commandRegistered(String command) {
|
||||
|
@ -14,24 +14,42 @@ public class AnalysisCacheHandler {
|
||||
private AnalysisData cache;
|
||||
private Analysis analysis;
|
||||
|
||||
/**
|
||||
* Class Constructor.
|
||||
* @param plugin Current instance of Plan
|
||||
*/
|
||||
public AnalysisCacheHandler(Plan plugin) {
|
||||
this.plugin = plugin;
|
||||
analysis = new Analysis(plugin);
|
||||
}
|
||||
|
||||
/**
|
||||
* Runs analysis, cache method is called after analysis is complete.
|
||||
*/
|
||||
public void updateCache() {
|
||||
cache = null;
|
||||
analysis.analyze(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Saves the new analysis data to cache.
|
||||
* @param data AnalysisData generated by Analysis.analyze
|
||||
*/
|
||||
public void cache(AnalysisData data) {
|
||||
cache = data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the cached AnalysisData.
|
||||
* @return null if not cached
|
||||
*/
|
||||
public AnalysisData getData() {
|
||||
return cache;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return true if there is data in the cache.
|
||||
*/
|
||||
public boolean isCached() {
|
||||
return (cache != null);
|
||||
}
|
||||
|
@ -12,7 +12,6 @@ import org.bukkit.Bukkit;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.scheduler.BukkitRunnable;
|
||||
import static org.bukkit.Bukkit.getPlayer;
|
||||
import static org.bukkit.Bukkit.getPlayer;
|
||||
|
||||
/**
|
||||
*
|
||||
|
@ -64,7 +64,13 @@ public class InspectCacheHandler {
|
||||
return cache.get(uuid);
|
||||
}
|
||||
|
||||
public HashMap<UUID, UserData> getCache() {
|
||||
return cache;
|
||||
/**
|
||||
* Check if the data of a player is in the inspect cache.
|
||||
*
|
||||
* @param uuid UUID of player.
|
||||
* @return true if cached.
|
||||
*/
|
||||
public boolean isCached(UUID uuid) {
|
||||
return cache.containsKey(uuid);
|
||||
}
|
||||
}
|
||||
|
@ -12,6 +12,10 @@ import main.java.com.djrapitops.plan.data.PlanLitePlayerData;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.player.PlayerJoinEvent;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Rsl1122
|
||||
*/
|
||||
public class PlanLiteHandler {
|
||||
|
||||
private Plan plugin;
|
||||
@ -19,6 +23,11 @@ public class PlanLiteHandler {
|
||||
private DataCacheHandler handler;
|
||||
private boolean enabled;
|
||||
|
||||
/**
|
||||
* Class Constructor.
|
||||
*
|
||||
* @param plugin Current instance of Plan
|
||||
*/
|
||||
public PlanLiteHandler(Plan plugin) {
|
||||
this.plugin = plugin;
|
||||
PlanLiteHook planLiteHook = plugin.getPlanLiteHook();
|
||||
@ -28,6 +37,12 @@ public class PlanLiteHandler {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles the player login by getting the data of the player from planlite.
|
||||
*
|
||||
* @param event LoginEvent
|
||||
* @param data UserData for the player.
|
||||
*/
|
||||
public void handleLogin(PlayerJoinEvent event, UserData data) {
|
||||
if (!enabled) {
|
||||
data.setPlanLiteFound(false);
|
||||
@ -39,6 +54,15 @@ public class PlanLiteHandler {
|
||||
handleEvents(playerName, data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Places the data to the PlanLitePlayerData and saves that to UserData.
|
||||
*
|
||||
* If PlanLite is used as UI the additional data of PlanLite has to be
|
||||
* disabled to avoid stackoverflow.
|
||||
*
|
||||
* @param playerName Name of the Player
|
||||
* @param data UserData for the player.
|
||||
*/
|
||||
public void handleEvents(String playerName, UserData data) {
|
||||
if (!enabled) {
|
||||
return;
|
||||
|
@ -2,26 +2,50 @@ package com.djrapitops.plan.data.handlers;
|
||||
|
||||
import com.djrapitops.plan.data.ServerData;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Rsl1122
|
||||
*/
|
||||
public class ServerDataHandler {
|
||||
|
||||
private ServerData serverData;
|
||||
|
||||
/**
|
||||
* Class constructor.
|
||||
*
|
||||
* @param serverData ServerData in the DataCacheHandler.
|
||||
*/
|
||||
public ServerDataHandler(ServerData serverData) {
|
||||
this.serverData = serverData;
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates playercount and adds new player if player is new.
|
||||
*
|
||||
* @param newPlayer true if player not in database.
|
||||
*/
|
||||
public void handleLogin(boolean newPlayer) {
|
||||
serverData.playerJoined(newPlayer);
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates playercount.
|
||||
*/
|
||||
public void handleLogout() {
|
||||
serverData.playerLeft();
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates playercount.
|
||||
*/
|
||||
public void handleKick() {
|
||||
handleLogout();
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds command to the command usage.
|
||||
* @param command Used command, first part (eg. /plan)
|
||||
*/
|
||||
public void handleCommand(String command) {
|
||||
serverData.commandRegistered(command);
|
||||
}
|
||||
|
@ -8,18 +8,32 @@ import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.player.PlayerCommandPreprocessEvent;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Rsl1122
|
||||
*/
|
||||
public class PlanCommandPreprocessListener implements Listener {
|
||||
|
||||
private final Plan plugin;
|
||||
private final DataCacheHandler handler;
|
||||
private final ServerDataHandler serverH;
|
||||
|
||||
/**
|
||||
* Class Constructor.
|
||||
*
|
||||
* @param plugin Current instance of Plan
|
||||
*/
|
||||
public PlanCommandPreprocessListener(Plan plugin) {
|
||||
this.plugin = plugin;
|
||||
handler = plugin.getHandler();
|
||||
serverH = handler.getServerDataHandler();
|
||||
}
|
||||
|
||||
/**
|
||||
* Command use listener.
|
||||
*
|
||||
* @param event Fired event.
|
||||
*/
|
||||
@EventHandler(priority = EventPriority.MONITOR)
|
||||
public void onPlayerCommand(PlayerCommandPreprocessEvent event) {
|
||||
if (event.isCancelled()) {
|
||||
|
@ -10,18 +10,32 @@ import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.player.PlayerGameModeChangeEvent;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Rsl1122
|
||||
*/
|
||||
public class PlanGamemodeChangeListener implements Listener {
|
||||
|
||||
private final Plan plugin;
|
||||
private final DataCacheHandler handler;
|
||||
private final GamemodeTimesHandler gmTimesH;
|
||||
|
||||
/**
|
||||
* Class Constructor.
|
||||
*
|
||||
* @param plugin Current instance of Plan
|
||||
*/
|
||||
public PlanGamemodeChangeListener(Plan plugin) {
|
||||
this.plugin = plugin;
|
||||
handler = plugin.getHandler();
|
||||
gmTimesH = handler.getGamemodeTimesHandler();
|
||||
}
|
||||
|
||||
/**
|
||||
* GM Change Event Listener.
|
||||
*
|
||||
* @param event Fired Event.
|
||||
*/
|
||||
@EventHandler(priority = EventPriority.MONITOR)
|
||||
public void onGamemodeChange(PlayerGameModeChangeEvent event) {
|
||||
if (event.isCancelled()) {
|
||||
|
@ -7,48 +7,130 @@ import org.bukkit.configuration.ConfigurationSection;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Rsl1122
|
||||
*/
|
||||
public abstract class Database {
|
||||
|
||||
private final Plan plugin;
|
||||
protected boolean cacheAccounts;
|
||||
|
||||
/**
|
||||
* Abstract class constructor.
|
||||
*
|
||||
* @param plugin Current instance of Plan
|
||||
*/
|
||||
public Database(Plan plugin) {
|
||||
this.plugin = plugin;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initiates the Database.
|
||||
*
|
||||
* @return false
|
||||
*/
|
||||
public boolean init() {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the UserData fetched from the Database.
|
||||
*
|
||||
* @param uuid UUID of Player
|
||||
* @return UserData of Player
|
||||
*/
|
||||
public abstract UserData getUserData(UUID uuid);
|
||||
|
||||
/**
|
||||
* Saves the UserData to the Database.
|
||||
*
|
||||
* @param uuid UUID of Player
|
||||
* @param data UserData of Player
|
||||
*/
|
||||
public abstract void saveUserData(UUID uuid, UserData data);
|
||||
|
||||
/**
|
||||
* Check if the player is found in the database.
|
||||
*
|
||||
* @param uuid UUID of Player
|
||||
* @return true if player is found in the database
|
||||
*/
|
||||
public abstract boolean wasSeenBefore(UUID uuid);
|
||||
|
||||
/**
|
||||
* Gets the settings to the config for each database type.
|
||||
*
|
||||
* @param section
|
||||
*/
|
||||
public abstract void getConfigDefaults(ConfigurationSection section);
|
||||
|
||||
/**
|
||||
* Cleans the database.
|
||||
*/
|
||||
public abstract void clean();
|
||||
|
||||
/**
|
||||
* Used by the Config section.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public abstract String getName();
|
||||
|
||||
/**
|
||||
* Used by the Config section.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public String getConfigName() {
|
||||
return getName().toLowerCase().replace(" ", "");
|
||||
}
|
||||
|
||||
/**
|
||||
* Used by the Config section.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public ConfigurationSection getConfigSection() {
|
||||
return plugin.getConfig().getConfigurationSection(getConfigName());
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the version of the database in case of updates.
|
||||
*
|
||||
* @return Current version of the database
|
||||
*/
|
||||
public abstract int getVersion();
|
||||
|
||||
/**
|
||||
* Set the version of the database.
|
||||
*
|
||||
* @param version Version number
|
||||
*/
|
||||
public abstract void setVersion(int version);
|
||||
|
||||
/**
|
||||
* Saves new server data to the table
|
||||
*
|
||||
* @param serverData Current serverdata
|
||||
*/
|
||||
public abstract void saveServerData(ServerData serverData);
|
||||
|
||||
/**
|
||||
* Gets the newest serverdata from the database.
|
||||
*
|
||||
* @return ServerData with the highest save date.
|
||||
*/
|
||||
public abstract ServerData getNewestServerData();
|
||||
|
||||
/**
|
||||
* Closes the database.
|
||||
*/
|
||||
public abstract void close();
|
||||
|
||||
/**
|
||||
* Returns raw data for analysis, contains all of player activity history.
|
||||
*
|
||||
* @return HashMap with save date (long in ms) and ServerData.
|
||||
*/
|
||||
public abstract HashMap<Long, ServerData> getServerDataHashMap();
|
||||
}
|
||||
|
@ -7,12 +7,26 @@ import java.sql.Connection;
|
||||
import java.sql.DriverManager;
|
||||
import java.sql.SQLException;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Rsl1122
|
||||
*/
|
||||
public class MySQLDB extends SQLDB {
|
||||
|
||||
/**
|
||||
* Class Constructor.
|
||||
*
|
||||
* @param plugin Current instance of Plan
|
||||
*/
|
||||
public MySQLDB(Plan plugin) {
|
||||
super(plugin, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new connection to the database.
|
||||
*
|
||||
* @return the new Connection.
|
||||
*/
|
||||
@Override
|
||||
protected Connection getNewConnection() {
|
||||
ConfigurationSection config = getConfigSection();
|
||||
|
@ -8,16 +8,30 @@ import java.sql.Connection;
|
||||
import java.sql.DriverManager;
|
||||
import java.sql.SQLException;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Rsl1122
|
||||
*/
|
||||
public class SQLiteDB extends SQLDB {
|
||||
|
||||
private final Plan plugin;
|
||||
|
||||
/**
|
||||
* Class Constructor.
|
||||
*
|
||||
* @param plugin Current instance of Plan
|
||||
*/
|
||||
public SQLiteDB(Plan plugin) {
|
||||
super(plugin, false);
|
||||
|
||||
this.plugin = plugin;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new connection to the database.
|
||||
*
|
||||
* @return the new Connection.
|
||||
*/
|
||||
@Override
|
||||
public Connection getNewConnection() {
|
||||
try {
|
||||
|
@ -19,16 +19,34 @@ public class DataRequestHandler {
|
||||
private InspectCacheHandler inspectCache;
|
||||
private AnalysisCacheHandler analysisCache;
|
||||
|
||||
/**
|
||||
* Class Constructor.
|
||||
*
|
||||
* @param plugin Current instance of Plan
|
||||
*/
|
||||
public DataRequestHandler(Plan plugin) {
|
||||
this.plugin = plugin;
|
||||
this.inspectCache = plugin.getInspectCache();
|
||||
this.analysisCache = plugin.getAnalysisCache();
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the Players data is in the inspect cache.
|
||||
*
|
||||
* @param uuid UUID of Player
|
||||
* @return true if cached.
|
||||
*/
|
||||
public boolean checkIfCached(UUID uuid) {
|
||||
return inspectCache.getCache().containsKey(uuid);
|
||||
return inspectCache.isCached(uuid);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the player.html as string with replaced placeholders.
|
||||
*
|
||||
* @param uuid UUID of player, whose UserData is used to replace
|
||||
* placeholders with
|
||||
* @return The html
|
||||
*/
|
||||
public String getDataHtml(UUID uuid) {
|
||||
UserData data = inspectCache.getFromCache(uuid);
|
||||
if (data == null) {
|
||||
@ -49,6 +67,10 @@ public class DataRequestHandler {
|
||||
return html;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the analysis.html as string with replaced placeholders.
|
||||
* @return the html
|
||||
*/
|
||||
public String getAnalysisHtml() {
|
||||
if (!analysisCache.isCached()) {
|
||||
return "<h1>404 Data was not found in cache</h1>";
|
||||
@ -68,6 +90,10 @@ public class DataRequestHandler {
|
||||
return html;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the AnalysisData is cached.
|
||||
* @return true if cached.
|
||||
*/
|
||||
public boolean checkIfAnalysisIsCached() {
|
||||
return analysisCache.isCached();
|
||||
}
|
||||
|
@ -36,10 +36,10 @@ public class ActivityPieChartCreator {
|
||||
actPerc--;
|
||||
}
|
||||
|
||||
Slice bannedSlice = Slice.newSlice((int) (banPerc), Color.newColor(Phrase.HCOLOR_ACTP_BAN+""), "Banned", "Banned");
|
||||
Slice joinLeaverSlice = Slice.newSlice((int) (joinlPerc), Color.newColor(Phrase.HCOLOR_ACTP_JON+""), "Unknown", "Unknown");
|
||||
Slice inactiveSlice = Slice.newSlice((int) (inacPerc), Color.newColor(Phrase.HCOLOR_ACTP_INA+""), "Inactive", "Inactive");
|
||||
Slice activeSlice = Slice.newSlice((int) (actPerc), Color.newColor(Phrase.HCOLOR_ACTP_ACT+""), "Active", "Active");
|
||||
Slice bannedSlice = Slice.newSlice((int) (banPerc), Color.newColor(Phrase.HCOLOR_ACTP_BAN + ""), "Banned", "Banned");
|
||||
Slice joinLeaverSlice = Slice.newSlice((int) (joinlPerc), Color.newColor(Phrase.HCOLOR_ACTP_JON + ""), "Unknown", "Unknown");
|
||||
Slice inactiveSlice = Slice.newSlice((int) (inacPerc), Color.newColor(Phrase.HCOLOR_ACTP_INA + ""), "Inactive", "Inactive");
|
||||
Slice activeSlice = Slice.newSlice((int) (actPerc), Color.newColor(Phrase.HCOLOR_ACTP_ACT + ""), "Active", "Active");
|
||||
|
||||
PieChart refChart = GCharts.newPieChart(activeSlice, bannedSlice, inactiveSlice, joinLeaverSlice);
|
||||
refChart.setSize(400, 150);
|
||||
|
@ -55,9 +55,9 @@ public class GMTimesPieChartCreator {
|
||||
}
|
||||
|
||||
Slice s1 = Slice.newSlice(zero, Color.newColor(Phrase.HCOLOR_GMP_0 + ""), "Survival", "Survival");
|
||||
Slice s2 = Slice.newSlice(one, Color.newColor(Phrase.HCOLOR_GMP_1+""), "Creative", "Creative");
|
||||
Slice s3 = Slice.newSlice(two, Color.newColor(Phrase.HCOLOR_GMP_2+""), "Adventure", "Adventure");
|
||||
Slice s4 = Slice.newSlice(three, Color.newColor(Phrase.HCOLOR_GMP_3+""), "Spectator", "Spectator");
|
||||
Slice s2 = Slice.newSlice(one, Color.newColor(Phrase.HCOLOR_GMP_1 + ""), "Creative", "Creative");
|
||||
Slice s3 = Slice.newSlice(two, Color.newColor(Phrase.HCOLOR_GMP_2 + ""), "Adventure", "Adventure");
|
||||
Slice s4 = Slice.newSlice(three, Color.newColor(Phrase.HCOLOR_GMP_3 + ""), "Spectator", "Spectator");
|
||||
|
||||
PieChart refChart = GCharts.newPieChart(s1, s2, s3, s4);
|
||||
refChart.setSize(400, 150);
|
||||
|
@ -24,6 +24,13 @@ import static org.bukkit.plugin.java.JavaPlugin.getPlugin;
|
||||
*/
|
||||
public class PlayerActivityGraphCreator {
|
||||
|
||||
/**
|
||||
* Creates a new url for a PlayerActivity graph.
|
||||
*
|
||||
* @param rawServerData HashMap of all ServerData
|
||||
* @param scale Long in ms, time the graph will be limited to.
|
||||
* @return Url of charts4j image link.
|
||||
*/
|
||||
public static String createChart(HashMap<Long, ServerData> rawServerData, long scale) {
|
||||
|
||||
List<Double> xListDate = new ArrayList<>();
|
||||
@ -53,7 +60,7 @@ public class PlayerActivityGraphCreator {
|
||||
Double scaledPlayerValue = (lastPValue * 1.0 / maxPlayers) * 100;
|
||||
Double scaledNewPValue = (lastNValue * 1.0 / maxPlayers) * 100;
|
||||
|
||||
if (lastSavedPValue != lastPValue || lastSavedNValue != lastNValue || i-lastSaveI > (scale / (long) 50)) {
|
||||
if (lastSavedPValue != lastPValue || lastSavedNValue != lastNValue || i - lastSaveI > (scale / (long) 50)) {
|
||||
lastSaveI = i;
|
||||
xListDate.add(scaledDateValue);
|
||||
pYList.add((lastSavedPValue * 1.0 / maxPlayers) * 100);
|
||||
|
@ -12,10 +12,17 @@ public class Request {
|
||||
private InputStream input;
|
||||
private String uri;
|
||||
|
||||
/**
|
||||
* Creates a new Request object.
|
||||
* @param input InputStream to read the web request from.
|
||||
*/
|
||||
public Request(InputStream input) {
|
||||
this.input = input;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses the request URI.
|
||||
*/
|
||||
public void parse() {
|
||||
// Read a set of characters from the socket
|
||||
StringBuffer request = new StringBuffer(2048);
|
||||
@ -48,6 +55,9 @@ public class Request {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Parsed URI
|
||||
*/
|
||||
public String getUri() {
|
||||
return uri;
|
||||
}
|
||||
|
@ -103,6 +103,9 @@ public class WebSocketServer {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return DataRequestHandler used by the WebServer.
|
||||
*/
|
||||
public DataRequestHandler getDataReqHandler() {
|
||||
return dataReqHandler;
|
||||
}
|
||||
|
@ -17,6 +17,10 @@ import org.bukkit.GameMode;
|
||||
import org.bukkit.OfflinePlayer;
|
||||
import org.bukkit.scheduler.BukkitRunnable;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Rsl1122
|
||||
*/
|
||||
public class Analysis {
|
||||
|
||||
private Plan plugin;
|
||||
@ -25,6 +29,11 @@ public class Analysis {
|
||||
private HashMap<Long, ServerData> rawServerData;
|
||||
private final List<UUID> added;
|
||||
|
||||
/**
|
||||
* Class Constructor.
|
||||
*
|
||||
* @param plugin Current instance of Plan
|
||||
*/
|
||||
public Analysis(Plan plugin) {
|
||||
this.plugin = plugin;
|
||||
this.inspectCache = plugin.getInspectCache();
|
||||
@ -32,6 +41,15 @@ public class Analysis {
|
||||
added = new ArrayList<>();
|
||||
}
|
||||
|
||||
/**
|
||||
* Analyzes the data of all offlineplayers on the server.
|
||||
*
|
||||
* First retrieves all Offlineplayers and checks those that are in the
|
||||
* database. Then Runs a new Analysis Task Asyncronously. Saves AnalysisData
|
||||
* to the provided Cache.
|
||||
*
|
||||
* @param analysisCache Cache that the data is saved to.
|
||||
*/
|
||||
public void analyze(AnalysisCacheHandler analysisCache) {
|
||||
rawData.clear();
|
||||
added.clear();
|
||||
|
@ -25,16 +25,36 @@ import static org.bukkit.plugin.java.JavaPlugin.getPlugin;
|
||||
*/
|
||||
public class AnalysisUtils {
|
||||
|
||||
/**
|
||||
* Creates a GMTimesPieChart image HTML.
|
||||
*
|
||||
* @param gmTimes HashMap of gamemodes and time in ms how long has been
|
||||
* played in them.
|
||||
* @return Html img tag with url.
|
||||
*/
|
||||
public static String createGMPieChart(HashMap<GameMode, Long> gmTimes) {
|
||||
String url = GMTimesPieChartCreator.createChart(gmTimes);
|
||||
return "<img src=\"" + url + "\">";
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a GMTimesPieChart image HTML.
|
||||
*
|
||||
* @param gmTimes HashMap of gamemodes and time in ms how long has been
|
||||
* played in them.
|
||||
* @param total Total time played in all gamemodes
|
||||
* @return Html img tag with url.
|
||||
*/
|
||||
public static String createGMPieChart(HashMap<GameMode, Long> gmTimes, long total) {
|
||||
String url = GMTimesPieChartCreator.createChart(gmTimes, total);
|
||||
return "<img src=\"" + url + "\">";
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the HashMap that is used to replace placeholders.
|
||||
* @param data UserData used to replace the placeholders with
|
||||
* @return HashMap that contains string for each placeholder.
|
||||
*/
|
||||
public static HashMap<String, String> getInspectReplaceRules(UserData data) {
|
||||
HashMap<String, String> replaceMap = new HashMap<>();
|
||||
replaceMap.put("%uuid%", "" + data.getUuid());
|
||||
@ -67,10 +87,10 @@ public class AnalysisUtils {
|
||||
replaceMap.put("%playtime%", FormatUtils.formatTimeAmount("" + data.getPlayTime()));
|
||||
replaceMap.put("%banned%", data.isBanned() ? "Banned" : "Not Banned");
|
||||
replaceMap.put("%op%", data.isOp() ? ", Operator (Op)" : "");
|
||||
replaceMap.put("%isonline%", (data.isOnline()) ? "| Online":"| Offline");
|
||||
replaceMap.put("%isonline%", (data.isOnline()) ? "| Online" : "| Offline");
|
||||
PlanLiteHook hook = getPlugin(Plan.class).getPlanLiteHook();
|
||||
replaceMap.put("%planlite%", hook.isEnabled() ? getPlanLitePlayerHtml(data.getPlanLiteData()) : "");
|
||||
replaceMap.put("%inaccuratedatawarning%", (new Date().getTime()-data.getRegistered() < 180000)
|
||||
replaceMap.put("%inaccuratedatawarning%", (new Date().getTime() - data.getRegistered() < 180000)
|
||||
? "<h3>Data might be inaccurate, player has just registered.</h3>" : "");
|
||||
return replaceMap;
|
||||
}
|
||||
@ -80,6 +100,11 @@ public class AnalysisUtils {
|
||||
return "<img src=\"" + url + "\">";
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the HashMap that is used to replace placeholders in Analysis.
|
||||
* @param data AnalysisData used to replace the placeholders with
|
||||
* @return HashMap that contains string for each placeholder.
|
||||
*/
|
||||
public static HashMap<String, String> getAnalysisReplaceRules(AnalysisData data) {
|
||||
HashMap<String, String> replaceMap = new HashMap<>();
|
||||
replaceMap.put("%activitypiechart%", data.getActivityChartImgHtml());
|
||||
@ -91,7 +116,7 @@ public class AnalysisUtils {
|
||||
replaceMap.put("%active%", "" + data.getActive());
|
||||
replaceMap.put("%banned%", "" + data.getBanned());
|
||||
replaceMap.put("%inactive%", "" + data.getInactive());
|
||||
replaceMap.put("%joinleaver%", ""+data.getJoinleaver());
|
||||
replaceMap.put("%joinleaver%", "" + data.getJoinleaver());
|
||||
replaceMap.put("%activitytotal%", "" + data.getTotal());
|
||||
replaceMap.put("%playerchartmonth%", data.getPlayersChartImgHtmlMonth());
|
||||
replaceMap.put("%playerchartweek%", data.getPlayersChartImgHtmlWeek());
|
||||
@ -199,13 +224,13 @@ public class AnalysisUtils {
|
||||
private static HashMap<String, String> getPlanLitePlayerReplaceRules(PlanLitePlayerData planLiteData) {
|
||||
HashMap<String, String> replaceMap = new HashMap<>();
|
||||
PlanLiteHook hook = getPlugin(Plan.class).getPlanLiteHook();
|
||||
replaceMap.put("%townylinetown%", hook.hasTowny() ? "<p>Town: "+planLiteData.getTown()+"</p>" : "");
|
||||
replaceMap.put("%townylinetown%", hook.hasTowny() ? "<p>Town: " + planLiteData.getTown() + "</p>" : "");
|
||||
replaceMap.put("%townylineplotperms%", "");
|
||||
replaceMap.put("%townylineplotoptions%", hook.hasTowny() ? "<p>Plot options: "+planLiteData.getPlotOptions()+"</p>" : "");
|
||||
replaceMap.put("%townylinefriends%", hook.hasTowny() ? "<p>Friends with "+planLiteData.getFriends()+"</p>" : "");
|
||||
replaceMap.put("%factionsline%", hook.hasFactions() ? "<p>Faction: "+planLiteData.getFaction()+"</p>" : "");
|
||||
replaceMap.put("%totalmoneyline%", hook.hasVault() ? "<p>Balance: "+planLiteData.getMoney()+"</p>" : "");
|
||||
replaceMap.put("%totalvotesline%", hook.hasSuperbVote() ? "<p>Player has voted " + planLiteData.getVotes()+ " times.</p>" : "");
|
||||
replaceMap.put("%townylineplotoptions%", hook.hasTowny() ? "<p>Plot options: " + planLiteData.getPlotOptions() + "</p>" : "");
|
||||
replaceMap.put("%townylinefriends%", hook.hasTowny() ? "<p>Friends with " + planLiteData.getFriends() + "</p>" : "");
|
||||
replaceMap.put("%factionsline%", hook.hasFactions() ? "<p>Faction: " + planLiteData.getFaction() + "</p>" : "");
|
||||
replaceMap.put("%totalmoneyline%", hook.hasVault() ? "<p>Balance: " + planLiteData.getMoney() + "</p>" : "");
|
||||
replaceMap.put("%totalvotesline%", hook.hasSuperbVote() ? "<p>Player has voted " + planLiteData.getVotes() + " times.</p>" : "");
|
||||
return replaceMap;
|
||||
}
|
||||
}
|
||||
|
@ -1,9 +1,6 @@
|
||||
package com.djrapitops.plan.utilities;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import org.bukkit.Location;
|
||||
|
||||
/**
|
||||
@ -12,32 +9,64 @@ import org.bukkit.Location;
|
||||
*/
|
||||
public class FormatUtils {
|
||||
|
||||
// Formats Time Since (0 -> string)
|
||||
/**
|
||||
* Formats a String of long in ms to readable format.
|
||||
*
|
||||
* @param string String of a Long in ms
|
||||
* @return Readable format
|
||||
* @throws NumberFormatException if String is not long.
|
||||
*/
|
||||
public static String formatTimeAmount(String string) throws NumberFormatException {
|
||||
long ms = Long.parseLong(string);
|
||||
return turnMsLongToString(ms);
|
||||
}
|
||||
|
||||
// Formats Time Difference Date before -> Date now
|
||||
/**
|
||||
* Formats the difference between the two dates into readable format.
|
||||
*
|
||||
* @param before
|
||||
* @param now
|
||||
* @return Readable format
|
||||
* @throws NumberFormatException
|
||||
*/
|
||||
public static String formatTimeAmountSinceDate(Date before, Date now) throws NumberFormatException {
|
||||
long ms = Math.abs((now.toInstant().getEpochSecond() * 1000) - (before.toInstant().getEpochSecond() * 1000));
|
||||
return turnMsLongToString(ms);
|
||||
}
|
||||
|
||||
// Creates a new Date with Epoch second and returns Date and Time String
|
||||
/**
|
||||
* Creates a new Date with Epoch second and returns Date and Time String.
|
||||
*
|
||||
* @param string
|
||||
* @return Readable TimeStamp
|
||||
* @throws NumberFormatException String is not Long
|
||||
*/
|
||||
public static String formatTimeStamp(String string) throws NumberFormatException {
|
||||
long ms = Long.parseLong(string);
|
||||
Date sfd = new Date(ms);
|
||||
return ("" + sfd).substring(4, 19);
|
||||
}
|
||||
|
||||
// Formats Time Difference String before -> Date now
|
||||
/**
|
||||
* Formats the difference between the two dates, where first is in String of
|
||||
* Long format, into readable format.
|
||||
*
|
||||
* @param string Long in ms, date
|
||||
* @param now
|
||||
* @return
|
||||
* @throws NumberFormatException
|
||||
*/
|
||||
public static String formatTimeAmountSinceString(String string, Date now) throws NumberFormatException {
|
||||
long ms = Math.abs((now.toInstant().getEpochSecond() * 1000) - Long.parseLong(string));
|
||||
return turnMsLongToString(ms);
|
||||
}
|
||||
|
||||
// Removes letters from a string leaving only numbers and dots.
|
||||
/**
|
||||
* Removes letters from a string leaving only numbers and dots.
|
||||
*
|
||||
* @param dataPoint
|
||||
* @return
|
||||
*/
|
||||
public static String removeLetters(String dataPoint) {
|
||||
return dataPoint.replaceAll("[^\\d.]", "");
|
||||
}
|
||||
@ -111,6 +140,12 @@ public class FormatUtils {
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Formats a Minecraft Location into readable format.
|
||||
*
|
||||
* @param loc Location to format
|
||||
* @return Readable location format.
|
||||
*/
|
||||
public static String formatLocation(Location loc) {
|
||||
return "x " + loc.getBlockX() + " z " + loc.getBlockZ() + " in " + loc.getWorld();
|
||||
}
|
||||
|
@ -56,6 +56,14 @@ public class MiscUtils {
|
||||
return "Failed to get newest version number.";
|
||||
}
|
||||
|
||||
/**
|
||||
* Used by the inspect command.
|
||||
*
|
||||
* @param args Arguments of the inspect command
|
||||
* @param sender Command sender
|
||||
* @return The name of the player searched for, if the arguments are empty
|
||||
* player's own name is returned.
|
||||
*/
|
||||
public static String getPlayerDisplayname(String[] args, CommandSender sender) {
|
||||
String playerName = "";
|
||||
Plan plugin = getPlugin(Plan.class);
|
||||
@ -79,6 +87,11 @@ public class MiscUtils {
|
||||
return playerName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get matching playernames from the offlineplayers
|
||||
* @param search Part of a name to search for.
|
||||
* @return Set of OfflinePlayers that match.
|
||||
*/
|
||||
public static Set<OfflinePlayer> getMatchingDisplaynames(String search) {
|
||||
List<OfflinePlayer> players = new ArrayList<>();
|
||||
players.addAll(Arrays.asList(Bukkit.getOfflinePlayers()));
|
||||
|
@ -5,14 +5,25 @@ import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Rsl1122
|
||||
*/
|
||||
public class MapComparator {
|
||||
|
||||
/**
|
||||
* Sorts a HashMap of String, Integer by the Values of the HashMap.
|
||||
*
|
||||
* @param hashMap
|
||||
* @return List with String Array, where first value is the value and second
|
||||
* is the key.
|
||||
*/
|
||||
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) -> Integer.parseInt(strings[0])-(Integer.parseInt(otherStrings[0])));
|
||||
Collections.sort(sortedList, (String[] strings, String[] otherStrings) -> Integer.parseInt(strings[0]) - (Integer.parseInt(otherStrings[0])));
|
||||
return sortedList;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user