Rewrote StatCommand logic, got rid of RequestSettings and RequestHandler and instead made InternalStatRequest to mirror the other StatRequest classes

This commit is contained in:
Artemis-the-gr8 2022-10-07 17:45:56 +02:00
parent 56dc30830a
commit e4fca5a0c8
10 changed files with 213 additions and 493 deletions

View File

@ -9,7 +9,6 @@ import com.artemis.the.gr8.playerstats.commands.StatCommand;
import com.artemis.the.gr8.playerstats.commands.TabCompleter;
import com.artemis.the.gr8.playerstats.config.ConfigHandler;
import com.artemis.the.gr8.playerstats.listeners.JoinListener;
import com.artemis.the.gr8.playerstats.msg.InternalFormatter;
import com.artemis.the.gr8.playerstats.msg.MessageBuilder;
import com.artemis.the.gr8.playerstats.msg.msgutils.LanguageKeyHandler;
import com.artemis.the.gr8.playerstats.statistic.StatCalculator;
@ -111,7 +110,7 @@ public final class Main extends JavaPlugin {
return playerStatsAPI;
}
public static @NotNull InternalFormatter getOutputManager() throws IllegalStateException {
public static @NotNull OutputManager getOutputManager() throws IllegalStateException {
if (outputManager == null) {
throw new IllegalStateException("PlayerStats does not seem to be loaded!");
}

View File

@ -3,7 +3,6 @@ package com.artemis.the.gr8.playerstats;
import com.artemis.the.gr8.playerstats.msg.OutputManager;
import com.artemis.the.gr8.playerstats.config.ConfigHandler;
import com.artemis.the.gr8.playerstats.enums.StandardMessage;
import com.artemis.the.gr8.playerstats.statistic.request.RequestSettings;
import com.artemis.the.gr8.playerstats.reload.ReloadThread;
import com.artemis.the.gr8.playerstats.statistic.StatCalculator;
import com.artemis.the.gr8.playerstats.statistic.StatThread;
@ -64,19 +63,19 @@ public final class ThreadManager {
}
}
public void startStatThread(StatRequest.Settings requestSettings) {
public void startStatThread(StatRequest<?> request) {
statThreadID += 1;
String cmdSender = requestSettings.getCommandSender().getName();
String cmdSender = request.getSettings().getCommandSender().getName();
if (config.limitStatRequests() && statThreads.containsKey(cmdSender)) {
Thread runningThread = statThreads.get(cmdSender);
if (runningThread.isAlive()) {
outputManager.sendFeedbackMsg(requestSettings.getCommandSender(), StandardMessage.REQUEST_ALREADY_RUNNING);
outputManager.sendFeedbackMsg(request.getSettings().getCommandSender(), StandardMessage.REQUEST_ALREADY_RUNNING);
} else {
startNewStatThread(requestSettings);
startNewStatThread(request);
}
} else {
startNewStatThread(requestSettings);
startNewStatThread(request);
}
}
@ -96,9 +95,9 @@ public final class ThreadManager {
return lastRecordedCalcTime;
}
private void startNewStatThread(StatRequest.Settings requestSettings) {
private void startNewStatThread(StatRequest<?> requestSettings) {
lastActiveStatThread = new StatThread(outputManager, statCalculator, statThreadID, requestSettings, lastActiveReloadThread);
statThreads.put(requestSettings.getCommandSender().getName(), lastActiveStatThread);
statThreads.put(requestSettings.getSettings().getCommandSender().getName(), lastActiveStatThread);
lastActiveStatThread.start();
}
}

View File

@ -4,15 +4,14 @@ import com.artemis.the.gr8.playerstats.ThreadManager;
import com.artemis.the.gr8.playerstats.enums.StandardMessage;
import com.artemis.the.gr8.playerstats.enums.Target;
import com.artemis.the.gr8.playerstats.msg.OutputManager;
import com.artemis.the.gr8.playerstats.statistic.request.RequestHandler;
import com.artemis.the.gr8.playerstats.statistic.request.RequestSettings;
import com.artemis.the.gr8.playerstats.statistic.request.*;
import org.bukkit.Statistic;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
import org.jetbrains.annotations.NotNull;
public final class StatCommand implements CommandExecutor {
public class StatCommand implements CommandExecutor {
private static ThreadManager threadManager;
private static OutputManager outputManager;
@ -32,14 +31,11 @@ public final class StatCommand implements CommandExecutor {
outputManager.sendExamples(sender);
}
else {
RequestSettings baseRequest = RequestHandler.getBasicInternalStatRequest(sender);
RequestHandler requestHandler = new RequestHandler(baseRequest);
RequestSettings completedRequest = requestHandler.getRequestFromArgs(args);
if (completedRequest.isValid()) {
threadManager.startStatThread(completedRequest);
InternalStatRequest request = new InternalStatRequest(sender, args);
if (request.isValid()) {
threadManager.startStatThread(request);
} else {
sendFeedback(completedRequest);
sendFeedback(request);
return false;
}
}
@ -47,7 +43,7 @@ public final class StatCommand implements CommandExecutor {
}
/**
* If a given {@link RequestSettings} object does not result in a valid
* If a given {@link StatRequest} object does not result in a valid
* statistic look-up, this will send a feedback message to the CommandSender
* that made the request. The following is checked:
* <ul>
@ -56,23 +52,24 @@ public final class StatCommand implements CommandExecutor {
* <li>If the <code>target</code> is Player, is a valid <code>playerName</code> provided?
* </ul>
*
* @param requestSettings the RequestSettings to give feedback on
* @param request the StatRequest to give feedback on
*/
private void sendFeedback(RequestSettings requestSettings) {
CommandSender sender = requestSettings.getCommandSender();
private void sendFeedback(InternalStatRequest request) {
StatRequest.Settings settings = request.getSettings();
CommandSender sender = settings.getCommandSender();
if (requestSettings.getStatistic() == null) {
if (settings.getStatistic() == null) {
outputManager.sendFeedbackMsg(sender, StandardMessage.MISSING_STAT_NAME);
}
else if (requestSettings.getTarget() == Target.PLAYER && requestSettings.getPlayerName() == null) {
else if (settings.getTarget() == Target.PLAYER && settings.getPlayerName() == null) {
outputManager.sendFeedbackMsg(sender, StandardMessage.MISSING_PLAYER_NAME);
}
else {
Statistic.Type type = requestSettings.getStatistic().getType();
if (type != Statistic.Type.UNTYPED && requestSettings.getSubStatEntryName() == null) {
Statistic.Type type = settings.getStatistic().getType();
if (type != Statistic.Type.UNTYPED && settings.getSubStatEntryName() == null) {
outputManager.sendFeedbackMsgMissingSubStat(sender, type);
} else {
outputManager.sendFeedbackMsgWrongSubStat(sender, type, requestSettings.getSubStatEntryName());
outputManager.sendFeedbackMsgWrongSubStat(sender, type, settings.getSubStatEntryName());
}
}
}

View File

@ -1,37 +0,0 @@
package com.artemis.the.gr8.playerstats.msg;
import com.artemis.the.gr8.playerstats.statistic.request.RequestSettings;
import com.artemis.the.gr8.playerstats.statistic.StatCalculator;
import com.artemis.the.gr8.playerstats.statistic.request.StatRequest;
import net.kyori.adventure.text.*;
import org.jetbrains.annotations.ApiStatus.Internal;
import java.util.LinkedHashMap;
/** The {@link InternalFormatter} formats raw numbers into pretty messages.
* This Formatter takes a {@link RequestSettings} object and combines it
* with the raw data returned by the {@link StatCalculator}, and transforms
* those into a pretty message with all the relevant information in it.
* @see MessageBuilder
*/
@Internal
public interface InternalFormatter {
/** @return a TextComponent with the following parts:
* <br>[player-name]: [number] [stat-name] {sub-stat-name}
*/
TextComponent formatAndSavePlayerStat(StatRequest.Settings requestSettings, int playerStat);
/** @return a TextComponent with the following parts:
* <br>[Total on] [server-name]: [number] [stat-name] [sub-stat-name]
*/
TextComponent formatAndSaveServerStat(StatRequest.Settings requestSettings, long serverStat);
/** @return a TextComponent with the following parts:
* <br>[PlayerStats] [Top 10] [stat-name] [sub-stat-name]
* <br> [1.] [player-name] [number]
* <br> [2.] [player-name] [number]
* <br> [3.] etc...
*/
TextComponent formatAndSaveTopStat(StatRequest.Settings requestSettings, LinkedHashMap<String, Integer> topStats);
}

View File

@ -3,7 +3,6 @@ package com.artemis.the.gr8.playerstats.msg;
import com.artemis.the.gr8.playerstats.ShareManager;
import com.artemis.the.gr8.playerstats.config.ConfigHandler;
import com.artemis.the.gr8.playerstats.enums.StandardMessage;
import com.artemis.the.gr8.playerstats.statistic.request.RequestSettings;
import com.artemis.the.gr8.playerstats.msg.components.BukkitConsoleComponentFactory;
import com.artemis.the.gr8.playerstats.msg.components.PrideComponentFactory;
import com.artemis.the.gr8.playerstats.statistic.request.StatRequest;
@ -32,7 +31,7 @@ import static com.artemis.the.gr8.playerstats.enums.StandardMessage.*;
* for Players (mainly to deal with the lack of hover-text,
* and for Bukkit consoles to make up for the lack of hex-colors).
*/
public final class OutputManager implements InternalFormatter {
public final class OutputManager {
private static BukkitAudiences adventure;
private static ConfigHandler config;
@ -55,7 +54,9 @@ public final class OutputManager implements InternalFormatter {
getMessageBuilders();
}
@Override
/** @return a TextComponent with the following parts:
* <br>[player-name]: [number] [stat-name] {sub-stat-name}
*/
public TextComponent formatAndSavePlayerStat(@NotNull StatRequest.Settings requestSettings, int playerStat) {
BiFunction<Integer, CommandSender, TextComponent> playerStatFunction =
getMessageBuilder(requestSettings.getCommandSender()).formattedPlayerStatFunction(playerStat, requestSettings);
@ -63,7 +64,9 @@ public final class OutputManager implements InternalFormatter {
return processFunction(requestSettings.getCommandSender(), playerStatFunction);
}
@Override
/** @return a TextComponent with the following parts:
* <br>[Total on] [server-name]: [number] [stat-name] [sub-stat-name]
*/
public TextComponent formatAndSaveServerStat(@NotNull StatRequest.Settings requestSettings, long serverStat) {
BiFunction<Integer, CommandSender, TextComponent> serverStatFunction =
getMessageBuilder(requestSettings.getCommandSender()).formattedServerStatFunction(serverStat, requestSettings);
@ -71,7 +74,12 @@ public final class OutputManager implements InternalFormatter {
return processFunction(requestSettings.getCommandSender(), serverStatFunction);
}
@Override
/** @return a TextComponent with the following parts:
* <br>[PlayerStats] [Top 10] [stat-name] [sub-stat-name]
* <br> [1.] [player-name] [number]
* <br> [2.] [player-name] [number]
* <br> [3.] etc...
*/
public TextComponent formatAndSaveTopStat(@NotNull StatRequest.Settings requestSettings, @NotNull LinkedHashMap<String, Integer> topStats) {
BiFunction<Integer, CommandSender, TextComponent> topStatFunction =
getMessageBuilder(requestSettings.getCommandSender()).formattedTopStatFunction(topStats, requestSettings);

View File

@ -6,7 +6,6 @@ import com.artemis.the.gr8.playerstats.statistic.request.StatRequest;
import com.artemis.the.gr8.playerstats.utils.MyLogger;
import com.artemis.the.gr8.playerstats.enums.StandardMessage;
import com.artemis.the.gr8.playerstats.enums.Target;
import com.artemis.the.gr8.playerstats.statistic.request.RequestSettings;
import com.artemis.the.gr8.playerstats.reload.ReloadThread;
import net.kyori.adventure.text.TextComponent;
import org.jetbrains.annotations.Nullable;
@ -22,16 +21,16 @@ public final class StatThread extends Thread {
private static StatCalculator statCalculator;
private final ReloadThread reloadThread;
private final StatRequest.Settings requestSettings;
private final StatRequest<?> statRequest;
public StatThread(OutputManager m, StatCalculator t, int ID, StatRequest.Settings s, @Nullable ReloadThread r) {
public StatThread(OutputManager m, StatCalculator t, int ID, StatRequest<?> s, @Nullable ReloadThread r) {
outputManager = m;
statCalculator = t;
reloadThread = r;
requestSettings = s;
statRequest = s;
this.setName("StatThread-" + requestSettings.getCommandSender().getName() + "-" + ID);
this.setName("StatThread-" + statRequest.getSettings().getCommandSender().getName() + "-" + ID);
MyLogger.logHighLevelMsg(this.getName() + " created!");
}
@ -39,13 +38,13 @@ public final class StatThread extends Thread {
public void run() throws IllegalStateException, NullPointerException {
MyLogger.logHighLevelMsg(this.getName() + " started!");
if (requestSettings == null) {
if (statRequest == null) {
throw new NullPointerException("No statistic requestSettings was found!");
}
if (reloadThread != null && reloadThread.isAlive()) {
try {
MyLogger.logLowLevelMsg(this.getName() + ": Waiting for " + reloadThread.getName() + " to finish up...");
outputManager.sendFeedbackMsg(requestSettings.getCommandSender(), StandardMessage.STILL_RELOADING);
outputManager.sendFeedbackMsg(statRequest.getSettings().getCommandSender(), StandardMessage.STILL_RELOADING);
reloadThread.join();
} catch (InterruptedException e) {
@ -56,21 +55,21 @@ public final class StatThread extends Thread {
long lastCalc = ThreadManager.getLastRecordedCalcTime();
if (lastCalc > 2000) {
outputManager.sendFeedbackMsgWaitAMoment(requestSettings.getCommandSender(), lastCalc > 20000);
outputManager.sendFeedbackMsgWaitAMoment(statRequest.getSettings().getCommandSender(), lastCalc > 20000);
}
Target selection = requestSettings.getTarget();
Target selection = statRequest.getSettings().getTarget();
try {
TextComponent statResult = switch (selection) {
case PLAYER -> outputManager.formatAndSavePlayerStat(requestSettings, statCalculator.getPlayerStat(requestSettings));
case TOP -> outputManager.formatAndSaveTopStat(requestSettings, statCalculator.getTopStats(requestSettings));
case SERVER -> outputManager.formatAndSaveServerStat(requestSettings, statCalculator.getServerStat(requestSettings));
case PLAYER -> outputManager.formatAndSavePlayerStat(statRequest.getSettings(), statCalculator.getPlayerStat(statRequest.getSettings()));
case TOP -> outputManager.formatAndSaveTopStat(statRequest.getSettings(), statCalculator.getTopStats(statRequest.getSettings()));
case SERVER -> outputManager.formatAndSaveServerStat(statRequest.getSettings(), statCalculator.getServerStat(statRequest.getSettings()));
};
outputManager.sendToCommandSender(requestSettings.getCommandSender(), statResult);
outputManager.sendToCommandSender(statRequest.getSettings().getCommandSender(), statResult);
}
catch (ConcurrentModificationException e) {
if (!requestSettings.isConsoleSender()) {
outputManager.sendFeedbackMsg(requestSettings.getCommandSender(), StandardMessage.UNKNOWN_ERROR);
if (!statRequest.getSettings().isConsoleSender()) {
outputManager.sendFeedbackMsg(statRequest.getSettings().getCommandSender(), StandardMessage.UNKNOWN_ERROR);
}
}
}

View File

@ -0,0 +1,142 @@
package com.artemis.the.gr8.playerstats.statistic.request;
import com.artemis.the.gr8.playerstats.Main;
import com.artemis.the.gr8.playerstats.statistic.result.StatResult;
import com.artemis.the.gr8.playerstats.utils.EnumHandler;
import com.artemis.the.gr8.playerstats.utils.OfflinePlayerHandler;
import org.bukkit.Material;
import org.bukkit.Statistic;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class InternalStatRequest extends StatRequest<Object> {
private final OfflinePlayerHandler offlinePlayerHandler;
private final EnumHandler enumHandler;
private final Pattern targetPattern;
public InternalStatRequest(CommandSender sender, String[] args) {
super(sender);
offlinePlayerHandler = Main.getOfflinePlayerHandler();
enumHandler = Main.getEnumHandler();
targetPattern = Pattern.compile("top|server|me|player");
String[] argsMinusTarget = extractAndStoreTarget(sender, args);
String[] argsMinusStatistic = extractAndStoreStatistic(argsMinusTarget);
findAndStoreSubStat(argsMinusStatistic);
}
@Override
public StatResult<Object> execute() {
return null;
}
private String[] extractAndStoreTarget(CommandSender sender, @NotNull String[] leftoverArgs) {
String playerName = tryToFindPlayerName(leftoverArgs);
for (String arg : leftoverArgs) {
Matcher targetMatcher = targetPattern.matcher(arg);
if (targetMatcher.find()) {
switch (targetMatcher.group()) {
case "player" -> {
if (playerName == null) {
continue;
}
else {
super.settings.configureForPlayer(playerName);
String[] extractedPlayerName = removeArg(leftoverArgs, playerName);
return removeArg(extractedPlayerName, arg);
}
}
case "me" -> {
if (sender instanceof Player) {
super.settings.configureForPlayer(sender.getName());
} else {
super.settings.configureForServer();
}
}
case "server" -> super.settings.configureForServer();
case "top" -> super.settings.configureForTop();
}
return removeArg(leftoverArgs, arg);
}
}
//if no target is found, but there is a playerName, assume target = Target.PLAYER
if (playerName != null) {
super.settings.configureForPlayer(playerName);
return removeArg(leftoverArgs, playerName);
}
//otherwise, assume target = Target.TOP
super.settings.configureForTop();
return leftoverArgs;
}
private String[] extractAndStoreStatistic(@NotNull String[] leftoverArgs) {
for (String arg : leftoverArgs) {
if (enumHandler.isStatistic(arg)) {
super.settings.setStatistic(EnumHandler.getStatEnum(arg));
return removeArg(leftoverArgs, arg);
}
}
return leftoverArgs;
}
private void findAndStoreSubStat(@NotNull String[] leftoverArgs) {
Statistic statistic = super.settings.getStatistic();
if (statistic == null || leftoverArgs.length == 0) {
return;
}
for (String arg : leftoverArgs) {
if (enumHandler.isSubStatEntry(arg)) {
switch (statistic.getType()) {
case UNTYPED -> super.configureUntyped(statistic);
case ITEM -> {
Material item = EnumHandler.getItemEnum(arg);
if (item != null) {
super.configureBlockOrItemType(statistic, item);
}
}
case BLOCK -> {
Material block = EnumHandler.getBlockEnum(arg);
if (block != null) {
super.configureBlockOrItemType(statistic, block);
}
}
case ENTITY -> {
EntityType entityType = EnumHandler.getEntityEnum(arg);
if (entityType != null) {
super.configureEntityType(statistic, entityType);
}
}
}
break;
}
}
}
@Contract(pure = true)
private @Nullable String tryToFindPlayerName(@NotNull String[] args) {
for (String arg : args) {
if (offlinePlayerHandler.isRelevantPlayer(arg)) {
return arg;
}
}
return null;
}
private String[] removeArg(@NotNull String[] args, String argToRemove) {
ArrayList<String> currentArgs = new ArrayList<>(Arrays.asList(args));
currentArgs.remove(argToRemove);
return currentArgs.toArray(String[]::new);
}
}

View File

@ -1,178 +0,0 @@
package com.artemis.the.gr8.playerstats.statistic.request;
import com.artemis.the.gr8.playerstats.Main;
import com.artemis.the.gr8.playerstats.utils.EnumHandler;
import com.artemis.the.gr8.playerstats.utils.OfflinePlayerHandler;
import com.artemis.the.gr8.playerstats.enums.Target;
import org.bukkit.Material;
import org.bukkit.Statistic;
import org.bukkit.command.CommandSender;
import org.bukkit.command.ConsoleCommandSender;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
public final class RequestHandler {
private final RequestSettings requestSettings;
public RequestHandler(RequestSettings request) {
requestSettings = request;
}
public static RequestSettings getBasicPlayerStatRequest(String playerName) {
RequestSettings request = RequestSettings.getBasicAPIRequest();
request.setTarget(Target.PLAYER);
request.setPlayerName(playerName);
return request;
}
public static RequestSettings getBasicServerStatRequest() {
RequestSettings request = RequestSettings.getBasicAPIRequest();
request.setTarget(Target.SERVER);
return request;
}
public static RequestSettings getBasicTopStatRequest(int topListSize) {
RequestSettings request = RequestSettings.getBasicAPIRequest();
request.setTarget(Target.TOP);
request.setTopListSize(topListSize != 0 ? topListSize : Main.getConfigHandler().getTopListMaxSize());
return request;
}
/**
* @param sender the CommandSender that requested this specific statistic
*/
public static RequestSettings getBasicInternalStatRequest(CommandSender sender) {
RequestSettings request = RequestSettings.getBasicRequest(sender);
request.setTopListSize(Main.getConfigHandler().getTopListMaxSize());
return request;
}
public RequestSettings untyped(@NotNull Statistic statistic) throws IllegalArgumentException {
if (statistic.getType() == Statistic.Type.UNTYPED) {
requestSettings.setStatistic(statistic);
return requestSettings;
}
throw new IllegalArgumentException("This statistic is not of Type.Untyped");
}
public RequestSettings blockOrItemType(@NotNull Statistic statistic, @NotNull Material material) throws IllegalArgumentException {
Statistic.Type type = statistic.getType();
if (type == Statistic.Type.BLOCK && material.isBlock()) {
requestSettings.setBlock(material);
}
else if (type == Statistic.Type.ITEM && material.isItem()){
requestSettings.setItem(material);
}
else {
throw new IllegalArgumentException("Either this statistic is not of Type.Block or Type.Item, or no valid block or item has been provided");
}
requestSettings.setStatistic(statistic);
requestSettings.setSubStatEntryName(material.toString());
return requestSettings;
}
public RequestSettings entityType(@NotNull Statistic statistic, @NotNull EntityType entityType) throws IllegalArgumentException {
if (statistic.getType() == Statistic.Type.ENTITY) {
requestSettings.setStatistic(statistic);
requestSettings.setSubStatEntryName(entityType.toString());
requestSettings.setEntity(entityType);
return requestSettings;
}
throw new IllegalArgumentException("This statistic is not of Type.Entity");
}
/**
* This will create a {@link RequestSettings} object from the provided args,
* with the requesting Player (or Console) as CommandSender. This CommandSender
* will receive feedback messages if the RequestSettings could not be created.
*
* @param args an Array of args such as a CommandSender would put in Minecraft chat:
* <ul>
* <li> a <code>statName</code> (example: "mine_block")
* <li> if applicable, a <code>subStatEntryName</code> (example: diorite)
* <li> a <code>target</code> for this lookup: can be "top", "server", "player"
* (or "me" to indicate the current CommandSender)
* <li> if "player" was chosen, include a <code>playerName</code>
* </ul>
* @return the generated RequestSettings
*/
public RequestSettings getRequestFromArgs(String[] args) {
EnumHandler enumHandler = Main.getEnumHandler();
OfflinePlayerHandler offlinePlayerHandler = Main.getOfflinePlayerHandler();
CommandSender sender = requestSettings.getCommandSender();
for (String arg : args) {
//check for statName
if (enumHandler.isStatistic(arg) && requestSettings.getStatistic() == null) {
requestSettings.setStatistic(EnumHandler.getStatEnum(arg));
}
//check for subStatEntry and playerFlag
else if (enumHandler.isSubStatEntry(arg)) {
if (arg.equalsIgnoreCase("player") && !requestSettings.getPlayerFlag()) {
requestSettings.setPlayerFlag(true);
} else {
if (requestSettings.getSubStatEntryName() == null) requestSettings.setSubStatEntryName(arg);
}
}
//check for selection
else if (arg.equalsIgnoreCase("top")) {
requestSettings.setTarget(Target.TOP);
} else if (arg.equalsIgnoreCase("server")) {
requestSettings.setTarget(Target.SERVER);
} else if (arg.equalsIgnoreCase("me")) {
if (sender instanceof Player) {
requestSettings.setPlayerName(sender.getName());
requestSettings.setTarget(Target.PLAYER);
} else if (sender instanceof ConsoleCommandSender) {
requestSettings.setTarget(Target.SERVER);
}
} else if (offlinePlayerHandler.isRelevantPlayer(arg) && requestSettings.getPlayerName() == null) {
requestSettings.setPlayerName(arg);
requestSettings.setTarget(Target.PLAYER);
}
}
patchRequest(requestSettings);
return requestSettings;
}
/**
* Adjust the RequestSettings object if needed: unpack the playerFlag
* into a subStatEntry, try to retrieve the corresponding Enum Constant
* for any relevant block/entity/item, and remove any unnecessary
* subStatEntries.
*/
private void patchRequest(RequestSettings requestSettings) {
if (requestSettings.getStatistic() != null) {
Statistic.Type type = requestSettings.getStatistic().getType();
if (requestSettings.getPlayerFlag()) { //unpack the playerFlag
if (type == Statistic.Type.ENTITY && requestSettings.getSubStatEntryName() == null) {
requestSettings.setSubStatEntryName("player");
} else {
requestSettings.setTarget(Target.PLAYER);
}
}
String subStatEntry = requestSettings.getSubStatEntryName();
switch (type) { //attempt to convert relevant subStatEntries into their corresponding Enum Constant
case BLOCK -> {
Material block = EnumHandler.getBlockEnum(subStatEntry);
if (block != null) requestSettings.setBlock(block);
}
case ENTITY -> {
EntityType entity = EnumHandler.getEntityEnum(subStatEntry);
if (entity != null) requestSettings.setEntity(entity);
}
case ITEM -> {
Material item = EnumHandler.getItemEnum(subStatEntry);
if (item != null) requestSettings.setItem(item);
}
case UNTYPED -> { //remove unnecessary subStatEntries
if (subStatEntry != null) requestSettings.setSubStatEntryName(null);
}
}
}
}
}

View File

@ -1,183 +0,0 @@
package com.artemis.the.gr8.playerstats.statistic.request;
import com.artemis.the.gr8.playerstats.api.RequestGenerator;
import com.artemis.the.gr8.playerstats.enums.Target;
import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.Statistic;
import org.bukkit.command.CommandSender;
import org.bukkit.command.ConsoleCommandSender;
import org.bukkit.entity.EntityType;
import org.jetbrains.annotations.NotNull;
/**
* The object PlayerStats uses to calculate and format the requested
* statistic. The settings in this RequestSettings object can be
* configured from two different sources:
* <br>- Internally: by PlayerStats itself when /stat is called,
* using the args provided by the CommandSender.
* <br>- Externally: through the API methods provided by the
* {@link RequestGenerator} interface.
* <br>
* <br>For this RequestSettings object to be valid, the following
* values need to be set:
* <ul>
* <li> a {@link Statistic} <code>statistic</code> </li>
* <li> if this Statistic is not of {@link Statistic.Type} Untyped,
* a <code>subStatEntryName</code> needs to be set, together with one
* of the following values:
* <br>- for Type.Block: a {@link Material} <code>blockMaterial</code>
* <br>- for Type.Item: a {@link Material} <code>itemMaterial</code>
* <br>- for Type.Entity: an {@link EntityType} <code>entityType</code>
* <li> a {@link Target} <code>target</code> (defaults to Top)
* <li> if the <code>target</code> is Target.Player, a
* <code>playerName</code> needs to be added
* </ul>
*/
public final class RequestSettings {
private final CommandSender sender;
private Statistic statistic;
private String playerName;
private Target target;
private int topListSize;
private String subStatEntryName;
private EntityType entity;
private Material block;
private Material item;
private boolean playerFlag;
/**
* Create a new {@link RequestSettings} with default values:
* <br>- CommandSender sender (provided)
* <br>- Target target = {@link Target#TOP}
* <br>- int topListSize = 10
* <br>- boolean playerFlag = false
*
* @param sender the CommandSender who prompted this RequestGenerator
*/
private RequestSettings(@NotNull CommandSender sender) {
this.sender = sender;
target = Target.TOP;
playerFlag = false;
}
public static RequestSettings getBasicRequest(CommandSender sender) {
return new RequestSettings(sender);
}
public static RequestSettings getBasicAPIRequest() {
return new RequestSettings(Bukkit.getConsoleSender());
}
public @NotNull CommandSender getCommandSender() {
return sender;
}
public boolean isConsoleSender() {
return sender instanceof ConsoleCommandSender;
}
public void setStatistic(Statistic statistic) {
this.statistic = statistic;
}
public Statistic getStatistic() {
return statistic;
}
public void setSubStatEntryName(String subStatEntry) {
this.subStatEntryName = subStatEntry;
}
public String getSubStatEntryName() {
return subStatEntryName;
}
public void setPlayerName(String playerName) {
this.playerName = playerName;
}
public String getPlayerName() {
return playerName;
}
public void setPlayerFlag(boolean playerFlag) {
this.playerFlag = playerFlag;
}
public boolean getPlayerFlag() {
return playerFlag;
}
public void setTarget(@NotNull Target target) {
this.target = target;
}
public @NotNull Target getTarget() {
return target;
}
public void setTopListSize(int topListSize) {
this.topListSize = topListSize;
}
public int getTopListSize() {
return this.topListSize;
}
public void setEntity(EntityType entity) {
this.entity = entity;
}
public EntityType getEntity() {
return entity;
}
public void setBlock(Material block) {
this.block = block;
}
public Material getBlock() {
return block;
}
public void setItem(Material item) {
this.item = item;
}
public Material getItem() {
return item;
}
public boolean isValid() {
if (statistic == null) {
return false;
} else if (target == Target.PLAYER && playerName == null) {
return false;
} else if (statistic.getType() != Statistic.Type.UNTYPED &&
subStatEntryName == null) {
return false;
} else {
return hasMatchingSubStat();
}
}
private boolean hasMatchingSubStat() {
switch (statistic.getType()) {
case BLOCK -> {
return block != null;
}
case ENTITY -> {
return entity != null;
}
case ITEM -> {
return item != null;
}
default -> {
return true;
}
}
}
}

View File

@ -73,6 +73,14 @@ public abstract class StatRequest<T> {
*/
public abstract StatResult<T> execute();
/**
* Use this method to view the settings that have
* been configured for this StatRequest.
*/
public Settings getSettings() {
return settings;
}
public boolean isValid() {
if (settings.statistic == null) {
return false;
@ -103,14 +111,6 @@ public abstract class StatRequest<T> {
}
}
/**
* Use this method to view the settings that have
* been configured for this StatRequest.
*/
public Settings getSettings() {
return settings;
}
public static final class Settings {
private final CommandSender sender;
private Statistic statistic;
@ -122,38 +122,32 @@ public abstract class StatRequest<T> {
private EntityType entity;
private Material block;
private Material item;
private boolean playerFlag;
/**
* Create a new {@link Settings} with default values:
* <br>- CommandSender sender (provided)
* <br>- Target target = {@link Target#TOP}
* <br>- int topListSize = 10
* <br>- boolean playerFlag = false
*
* @param sender the CommandSender who prompted this RequestGenerator
*/
private Settings(@NotNull CommandSender sender) {
this.sender = sender;
target = Target.TOP;
playerFlag = false;
this.sender = sender;
}
void configureForPlayer(String playerName) {
setTarget(Target.PLAYER);
setPlayerName(playerName);
this.target = Target.PLAYER;
this.playerName = playerName;
}
void configureForServer() {
setTarget(Target.SERVER);
this.target = Target.SERVER;
}
void configureForTop() {
configureForTop(Main.getConfigHandler().getTopListMaxSize());
}
void configureForTop(int topListSize) {
setTarget(Target.TOP);
this.topListSize = topListSize != 0 ?
topListSize :
Main.getConfigHandler().getTopListMaxSize();
this.target = Target.TOP;
this.topListSize = topListSize != 0 ?
topListSize :
Main.getConfigHandler().getTopListMaxSize();
}
public @NotNull CommandSender getCommandSender() {
@ -180,34 +174,14 @@ public abstract class StatRequest<T> {
return subStatEntryName;
}
void setPlayerName(String playerName) {
this.playerName = playerName;
}
public String getPlayerName() {
return playerName;
}
void setPlayerFlag(boolean playerFlag) {
this.playerFlag = playerFlag;
}
public boolean getPlayerFlag() {
return playerFlag;
}
void setTarget(@NotNull Target target) {
this.target = target;
}
public @NotNull Target getTarget() {
return target;
}
void setTopListSize(int topListSize) {
this.topListSize = topListSize;
}
public int getTopListSize() {
return this.topListSize;
}