Improved Request-business inside API

This commit is contained in:
Artemis-the-gr8 2022-08-08 17:24:22 +02:00
parent 3a9eb86c1e
commit eeb164e194
26 changed files with 518 additions and 495 deletions

View File

@ -2,6 +2,7 @@ package com.gmail.artemis.the.gr8.playerstats;
import com.gmail.artemis.the.gr8.playerstats.api.PlayerStats; import com.gmail.artemis.the.gr8.playerstats.api.PlayerStats;
import com.gmail.artemis.the.gr8.playerstats.api.PlayerStatsAPI; import com.gmail.artemis.the.gr8.playerstats.api.PlayerStatsAPI;
import com.gmail.artemis.the.gr8.playerstats.api.StatFormatter;
import com.gmail.artemis.the.gr8.playerstats.commands.ReloadCommand; import com.gmail.artemis.the.gr8.playerstats.commands.ReloadCommand;
import com.gmail.artemis.the.gr8.playerstats.commands.ShareCommand; import com.gmail.artemis.the.gr8.playerstats.commands.ShareCommand;
import com.gmail.artemis.the.gr8.playerstats.commands.StatCommand; import com.gmail.artemis.the.gr8.playerstats.commands.StatCommand;
@ -9,7 +10,7 @@ import com.gmail.artemis.the.gr8.playerstats.commands.TabCompleter;
import com.gmail.artemis.the.gr8.playerstats.config.ConfigHandler; import com.gmail.artemis.the.gr8.playerstats.config.ConfigHandler;
import com.gmail.artemis.the.gr8.playerstats.listeners.JoinListener; import com.gmail.artemis.the.gr8.playerstats.listeners.JoinListener;
import com.gmail.artemis.the.gr8.playerstats.msg.OutputManager; import com.gmail.artemis.the.gr8.playerstats.msg.OutputManager;
import com.gmail.artemis.the.gr8.playerstats.statistic.StatRetriever; import com.gmail.artemis.the.gr8.playerstats.statistic.StatCalculator;
import com.gmail.artemis.the.gr8.playerstats.utils.EnumHandler; import com.gmail.artemis.the.gr8.playerstats.utils.EnumHandler;
import com.gmail.artemis.the.gr8.playerstats.utils.OfflinePlayerHandler; import com.gmail.artemis.the.gr8.playerstats.utils.OfflinePlayerHandler;
import net.kyori.adventure.platform.bukkit.BukkitAudiences; import net.kyori.adventure.platform.bukkit.BukkitAudiences;
@ -29,6 +30,7 @@ public final class Main extends JavaPlugin {
private static OutputManager outputManager; private static OutputManager outputManager;
private static ShareManager shareManager; private static ShareManager shareManager;
private static StatCalculator statCalculator;
private static ThreadManager threadManager; private static ThreadManager threadManager;
private static PlayerStats playerStatsAPI; private static PlayerStats playerStatsAPI;
@ -82,6 +84,13 @@ public final class Main extends JavaPlugin {
return config; return config;
} }
public static @NotNull OfflinePlayerHandler getOfflinePlayerHandler() throws IllegalStateException {
if (offlinePlayerHandler == null) {
throw new IllegalStateException("PlayerStats does not seem to be fully loaded!");
}
return offlinePlayerHandler;
}
public static @NotNull EnumHandler getEnumHandler() { public static @NotNull EnumHandler getEnumHandler() {
if (enumHandler == null) { if (enumHandler == null) {
enumHandler = new EnumHandler(); enumHandler = new EnumHandler();
@ -89,11 +98,18 @@ public final class Main extends JavaPlugin {
return enumHandler; return enumHandler;
} }
public static @NotNull OfflinePlayerHandler getOfflinePlayerHandler() throws IllegalStateException { public static @NotNull StatCalculator getStatCalculator() throws IllegalStateException {
if (offlinePlayerHandler == null) { if (statCalculator == null) {
throw new IllegalStateException("PlayerStats does not seem to be fully loaded!"); throw new IllegalStateException("PlayerStats does not seem to be loaded!");
} }
return offlinePlayerHandler; return statCalculator;
}
public static @NotNull StatFormatter getStatFormatter() throws IllegalStateException {
if (outputManager == null) {
throw new IllegalStateException("PlayerStats does not seem to be loaded!");
}
return outputManager;
} }
public static @NotNull PlayerStats getPlayerStatsAPI() throws IllegalStateException { public static @NotNull PlayerStats getPlayerStatsAPI() throws IllegalStateException {
@ -112,9 +128,9 @@ public final class Main extends JavaPlugin {
shareManager = new ShareManager(config); shareManager = new ShareManager(config);
outputManager = new OutputManager(getAdventure(), config, shareManager); outputManager = new OutputManager(getAdventure(), config, shareManager);
StatRetriever statRetriever = new StatRetriever(offlinePlayerHandler); statCalculator = new StatCalculator(offlinePlayerHandler);
threadManager = new ThreadManager(config, statRetriever, outputManager); threadManager = new ThreadManager(config, statCalculator, outputManager);
playerStatsAPI = new PlayerStatsAPI(statRetriever, outputManager, offlinePlayerHandler); playerStatsAPI = new PlayerStatsAPI(outputManager, offlinePlayerHandler);
} }
} }

View File

@ -2,10 +2,10 @@ package com.gmail.artemis.the.gr8.playerstats;
import com.gmail.artemis.the.gr8.playerstats.config.ConfigHandler; import com.gmail.artemis.the.gr8.playerstats.config.ConfigHandler;
import com.gmail.artemis.the.gr8.playerstats.enums.StandardMessage; import com.gmail.artemis.the.gr8.playerstats.enums.StandardMessage;
import com.gmail.artemis.the.gr8.playerstats.statistic.request.StatRequest; import com.gmail.artemis.the.gr8.playerstats.statistic.request.RequestSettings;
import com.gmail.artemis.the.gr8.playerstats.msg.OutputManager; import com.gmail.artemis.the.gr8.playerstats.msg.OutputManager;
import com.gmail.artemis.the.gr8.playerstats.reload.ReloadThread; import com.gmail.artemis.the.gr8.playerstats.reload.ReloadThread;
import com.gmail.artemis.the.gr8.playerstats.statistic.StatRetriever; import com.gmail.artemis.the.gr8.playerstats.statistic.StatCalculator;
import com.gmail.artemis.the.gr8.playerstats.statistic.StatThread; import com.gmail.artemis.the.gr8.playerstats.statistic.StatThread;
import com.gmail.artemis.the.gr8.playerstats.utils.MyLogger; import com.gmail.artemis.the.gr8.playerstats.utils.MyLogger;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
@ -25,17 +25,17 @@ public final class ThreadManager {
private static ConfigHandler config; private static ConfigHandler config;
private static OutputManager outputManager; private static OutputManager outputManager;
private static StatRetriever statRetriever; private static StatCalculator statCalculator;
private ReloadThread lastActiveReloadThread; private ReloadThread lastActiveReloadThread;
private StatThread lastActiveStatThread; private StatThread lastActiveStatThread;
private final HashMap<String, Thread> statThreads; private final HashMap<String, Thread> statThreads;
private static long lastRecordedCalcTime; private static long lastRecordedCalcTime;
public ThreadManager(ConfigHandler config, StatRetriever statRetriever, OutputManager outputManager) { public ThreadManager(ConfigHandler config, StatCalculator statCalculator, OutputManager outputManager) {
ThreadManager.config = config; ThreadManager.config = config;
ThreadManager.outputManager = outputManager; ThreadManager.outputManager = outputManager;
ThreadManager.statRetriever = statRetriever; ThreadManager.statCalculator = statCalculator;
statThreads = new HashMap<>(); statThreads = new HashMap<>();
statThreadID = 0; statThreadID = 0;
@ -61,19 +61,19 @@ public final class ThreadManager {
} }
} }
public void startStatThread(StatRequest statRequest) { public void startStatThread(RequestSettings requestSettings) {
statThreadID += 1; statThreadID += 1;
String cmdSender = statRequest.getCommandSender().getName(); String cmdSender = requestSettings.getCommandSender().getName();
if (config.limitStatRequests() && statThreads.containsKey(cmdSender)) { if (config.limitStatRequests() && statThreads.containsKey(cmdSender)) {
Thread runningThread = statThreads.get(cmdSender); Thread runningThread = statThreads.get(cmdSender);
if (runningThread.isAlive()) { if (runningThread.isAlive()) {
outputManager.sendFeedbackMsg(statRequest.getCommandSender(), StandardMessage.REQUEST_ALREADY_RUNNING); outputManager.sendFeedbackMsg(requestSettings.getCommandSender(), StandardMessage.REQUEST_ALREADY_RUNNING);
} else { } else {
startNewStatThread(statRequest); startNewStatThread(requestSettings);
} }
} else { } else {
startNewStatThread(statRequest); startNewStatThread(requestSettings);
} }
} }
@ -89,9 +89,9 @@ public final class ThreadManager {
return lastRecordedCalcTime; return lastRecordedCalcTime;
} }
private void startNewStatThread(StatRequest statRequest) { private void startNewStatThread(RequestSettings requestSettings) {
lastActiveStatThread = new StatThread(outputManager, statRetriever, statThreadID, statRequest, lastActiveReloadThread); lastActiveStatThread = new StatThread(outputManager, statCalculator, statThreadID, requestSettings, lastActiveReloadThread);
statThreads.put(statRequest.getCommandSender().getName(), lastActiveStatThread); statThreads.put(requestSettings.getCommandSender().getName(), lastActiveStatThread);
lastActiveStatThread.start(); lastActiveStatThread.start();
} }
} }

View File

@ -1,6 +1,7 @@
package com.gmail.artemis.the.gr8.playerstats.api; package com.gmail.artemis.the.gr8.playerstats.api;
import com.gmail.artemis.the.gr8.playerstats.Main; import com.gmail.artemis.the.gr8.playerstats.Main;
import com.gmail.artemis.the.gr8.playerstats.statistic.request.StatRequest;
import org.jetbrains.annotations.Contract; import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
@ -9,7 +10,7 @@ import org.jetbrains.annotations.NotNull;
{@link PlayerStatsAPI}. You can then use this object to access any of the further methods. {@link PlayerStatsAPI}. You can then use this object to access any of the further methods.
<br> <br>
<br>Since calculating a top or server statistics can take some time, I strongly <br>Since calculating a top or server statistics can take some time, I strongly
encourage you to call all the serverStat() and topStat() methods asynchronously. encourage you to call {@link StatRequest#execute()} asynchronously.
Otherwise, the main Thread will have to wait until all calculations are done, Otherwise, the main Thread will have to wait until all calculations are done,
and this can severely impact server performance. and this can severely impact server performance.
*/ */

View File

@ -1,7 +1,5 @@
package com.gmail.artemis.the.gr8.playerstats.api; package com.gmail.artemis.the.gr8.playerstats.api;
import com.gmail.artemis.the.gr8.playerstats.statistic.StatRetriever;
import com.gmail.artemis.the.gr8.playerstats.statistic.request.*; import com.gmail.artemis.the.gr8.playerstats.statistic.request.*;
import com.gmail.artemis.the.gr8.playerstats.utils.OfflinePlayerHandler; import com.gmail.artemis.the.gr8.playerstats.utils.OfflinePlayerHandler;
@ -11,24 +9,14 @@ import static org.jetbrains.annotations.ApiStatus.Internal;
public final class PlayerStatsAPI implements PlayerStats, StatManager { public final class PlayerStatsAPI implements PlayerStats, StatManager {
private final OfflinePlayerHandler offlinePlayerHandler; private final OfflinePlayerHandler offlinePlayerHandler;
private static StatRetriever statRetriever;
private static StatFormatter statFormatter; private static StatFormatter statFormatter;
@Internal @Internal
public PlayerStatsAPI(StatRetriever stat, StatFormatter format, OfflinePlayerHandler offlinePlayers) { public PlayerStatsAPI(StatFormatter format, OfflinePlayerHandler offlinePlayers) {
statRetriever = stat;
statFormatter = format; statFormatter = format;
offlinePlayerHandler = offlinePlayers; offlinePlayerHandler = offlinePlayers;
} }
static StatRetriever statCalculator() {
return statRetriever;
}
static StatFormatter statFormatter() {
return statFormatter;
}
@Override @Override
public Formatter getFormatter() { public Formatter getFormatter() {
return statFormatter; return statFormatter;
@ -40,26 +28,26 @@ public final class PlayerStatsAPI implements PlayerStats, StatManager {
} }
@Override @Override
public RequestGenerator<Integer> getPlayerStat(String playerName) { public RequestGenerator<Integer> playerStatRequest(String playerName) {
StatRequest request = StatRequestHandler.getBasicPlayerStatRequest(playerName); RequestSettings request = RequestHandler.getBasicPlayerStatRequest(playerName);
return new PlayerStatRequest(request); return new PlayerStatRequest(request);
} }
@Override @Override
public ServerStatRequest calculateServerStat() { public ServerStatRequest serverStatRequest() {
StatRequest request = StatRequestHandler.getBasicServerStatRequest(); RequestSettings request = RequestHandler.getBasicServerStatRequest();
return new ServerStatRequest(request); return new ServerStatRequest(request);
} }
@Override @Override
public TopStatRequest calculateTopStat(int topListSize) { public TopStatRequest topStatRequest(int topListSize) {
StatRequest request = StatRequestHandler.getBasicTopStatRequest(topListSize); RequestSettings request = RequestHandler.getBasicTopStatRequest(topListSize);
return new TopStatRequest(request); return new TopStatRequest(request);
} }
@Override @Override
public TopStatRequest calculateTotalTopStatList() { public TopStatRequest totalTopStatListRequest() {
int playerCount = offlinePlayerHandler.getOfflinePlayerCount(); int playerCount = offlinePlayerHandler.getOfflinePlayerCount();
return calculateTopStat(playerCount); return topStatRequest(playerCount);
} }
} }

View File

@ -1,20 +0,0 @@
package com.gmail.artemis.the.gr8.playerstats.api;
import com.gmail.artemis.the.gr8.playerstats.statistic.StatRetriever;
import com.gmail.artemis.the.gr8.playerstats.statistic.result.StatResult;
import com.gmail.artemis.the.gr8.playerstats.statistic.request.StatRequest;
/** Completes a basic {@link StatRequest} provided by the {@link PlayerStatsAPI}
and performs a statistic lookup with the information that is stored inside this StatRequest.*/
public interface RequestExecutor<T> {
static StatRetriever getStatCalculator() {
return PlayerStatsAPI.statCalculator();
}
static StatFormatter getStatFormatter() {
return PlayerStatsAPI.statFormatter();
}
StatResult<T> execute();
}

View File

@ -1,25 +1,25 @@
package com.gmail.artemis.the.gr8.playerstats.api; package com.gmail.artemis.the.gr8.playerstats.api;
import com.gmail.artemis.the.gr8.playerstats.statistic.StatRetriever; import com.gmail.artemis.the.gr8.playerstats.statistic.StatCalculator;
import com.gmail.artemis.the.gr8.playerstats.statistic.request.StatRequest; import com.gmail.artemis.the.gr8.playerstats.statistic.request.StatRequest;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.Statistic; import org.bukkit.Statistic;
import org.bukkit.entity.EntityType; import org.bukkit.entity.EntityType;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
/** Turns user input into a completed {@link StatRequest}. This StatRequest should hold all /** Is responsible for creating an executable {@link StatRequest}. This Request holds all
the information PlayerStats needs to work with, and is used by the {@link StatRetriever} the information PlayerStats needs to work with, and is used by the {@link StatCalculator}
to get the desired statistic data.*/ to get the desired statistic data.*/
public interface RequestGenerator<T> { public interface RequestGenerator<T> {
/** Gets a StatRequest for a Statistic of Statistic.Type {@code Untyped}. /** Gets an executable Request object for a Statistic of Statistic.Type {@code Untyped}.
@param statistic a Statistic of Type.Untyped @param statistic a Statistic of Type.Untyped
@return a {@link StatRequest} @return a {@link StatRequest}
@throws IllegalArgumentException if <code>statistic</code> is not of Type.Untyped*/ @throws IllegalArgumentException if <code>statistic</code> is not of Type.Untyped*/
RequestExecutor<T> untyped(@NotNull Statistic statistic) throws IllegalArgumentException; StatRequest<T> untyped(@NotNull Statistic statistic) throws IllegalArgumentException;
/** Gets a StatRequest for a Statistic of Statistic.Type Block or Item. /** Gets an executable Request object for a Statistic of Statistic.Type Block or Item.
@param statistic a Statistic of Type.Block or Type.Item @param statistic a Statistic of Type.Block or Type.Item
@param material a block if the <code>statistic</code> is of Type.Block, @param material a block if the <code>statistic</code> is of Type.Block,
@ -28,13 +28,13 @@ public interface RequestGenerator<T> {
@throws IllegalArgumentException if <code>statistic</code> is not of Type.Block @throws IllegalArgumentException if <code>statistic</code> is not of Type.Block
(with a block as <code>material</code>), or <code>statistic</code> is not of Type.Item (with a block as <code>material</code>), or <code>statistic</code> is not of Type.Item
(with an item as <code>material</code>) */ (with an item as <code>material</code>) */
RequestExecutor<T> blockOrItemType(@NotNull Statistic statistic, @NotNull Material material) throws IllegalArgumentException; StatRequest<T> blockOrItemType(@NotNull Statistic statistic, @NotNull Material material) throws IllegalArgumentException;
/** Gets a StatRequest for a Statistic of Statistic.Type Entity. /** Gets an executable Request object for a Statistic of Statistic.Type Entity.
@param statistic a Statistic of Type.Entity @param statistic a Statistic of Type.Entity
@param entityType an EntityType @param entityType an EntityType
@return a {@link StatRequest} @return a {@link StatRequest}
@throws IllegalArgumentException if <code>statistic</code> is not of Type.Entity*/ @throws IllegalArgumentException if <code>statistic</code> is not of Type.Entity*/
RequestExecutor<T> entityType(@NotNull Statistic statistic, @NotNull EntityType entityType) throws IllegalArgumentException; StatRequest<T> entityType(@NotNull Statistic statistic, @NotNull EntityType entityType) throws IllegalArgumentException;
} }

View File

@ -1,6 +1,7 @@
package com.gmail.artemis.the.gr8.playerstats.api; package com.gmail.artemis.the.gr8.playerstats.api;
import com.gmail.artemis.the.gr8.playerstats.statistic.request.StatRequest; import com.gmail.artemis.the.gr8.playerstats.statistic.request.RequestSettings;
import com.gmail.artemis.the.gr8.playerstats.statistic.StatCalculator;
import net.kyori.adventure.platform.bukkit.BukkitAudiences; import net.kyori.adventure.platform.bukkit.BukkitAudiences;
import net.kyori.adventure.text.*; import net.kyori.adventure.text.*;
import org.jetbrains.annotations.ApiStatus.Internal; import org.jetbrains.annotations.ApiStatus.Internal;
@ -8,7 +9,7 @@ import org.jetbrains.annotations.ApiStatus.Internal;
import java.util.LinkedHashMap; import java.util.LinkedHashMap;
/** The {@link StatFormatter} formats raw numbers into pretty messages. /** The {@link StatFormatter} formats raw numbers into pretty messages.
This Formatter takes a {@link StatRequest} and combines it with the raw number(s) This Formatter takes a {@link RequestSettings} object and combines it with the raw number(s)
returned by the {@link StatCalculator}, and transforms those into a pretty message returned by the {@link StatCalculator}, and transforms those into a pretty message
(by default a TextComponent) with all the relevant information in it. (by default a TextComponent) with all the relevant information in it.
<br> <br>
@ -28,16 +29,16 @@ interface StatFormatter extends Formatter {
/** @return a TextComponent with the following parts: /** @return a TextComponent with the following parts:
<br>[player-name]: [number] [stat-name] {sub-stat-name}*/ <br>[player-name]: [number] [stat-name] {sub-stat-name}*/
TextComponent formatPlayerStat(StatRequest statRequest, int playerStat); TextComponent formatPlayerStat(RequestSettings requestSettings, int playerStat);
/** @return a TextComponent with the following parts: /** @return a TextComponent with the following parts:
<br>[Total on] [server-name]: [number] [stat-name] [sub-stat-name]*/ <br>[Total on] [server-name]: [number] [stat-name] [sub-stat-name]*/
TextComponent formatServerStat(StatRequest statRequest, long serverStat); TextComponent formatServerStat(RequestSettings requestSettings, long serverStat);
/** @return a TextComponent with the following parts: /** @return a TextComponent with the following parts:
<br>[PlayerStats] [Top 10] [stat-name] [sub-stat-name] <br>[PlayerStats] [Top 10] [stat-name] [sub-stat-name]
<br> [1.] [player-name] [number] <br> [1.] [player-name] [number]
<br> [2.] [player-name] [number] <br> [2.] [player-name] [number]
<br> [3.] etc...*/ <br> [3.] etc...*/
TextComponent formatTopStat(StatRequest statRequest, LinkedHashMap<String, Integer> topStats); TextComponent formatTopStat(RequestSettings requestSettings, LinkedHashMap<String, Integer> topStats);
} }

View File

@ -4,32 +4,33 @@ import java.util.LinkedHashMap;
public interface StatManager { public interface StatManager {
/** Gets a StatRequest object that can be used to look up a player-statistic. /** Gets a RequestGenerator that can be used to create a PlayerStatRequest.
This StatRequest will have all default settings already configured, This RequestGenerator will make sure all default settings
and will be processed as soon as you call one of its methods. for a player-statistic-lookup are configured.
@return a PlayerStatRequest that can be used to look up a statistic for the @param playerName the player whose statistic is being requested
Player whose name is provided*/ @return the RequestGenerator */
RequestGenerator<Integer> getPlayerStat(String playerName); RequestGenerator<Integer> playerStatRequest(String playerName);
/** Gets a StatRequest object that can be used to look up a server-statistic. /** Gets a RequestGenerator that can be used to create a ServerStatRequest.
This StatRequest will have all default settings already configured, This RequestGenerator will make sure all default settings
and will be processed as soon as you call one of its methods. for a server-statistic-lookup are configured.
<br>
<br> Don't call this from the main Thread! (see class description)
@return a ServerStatRequest that can be used to look up a server total*/ @return the RequestGenerator*/
RequestGenerator<Long> calculateServerStat(); RequestGenerator<Long> serverStatRequest();
/** Gets a StatRequest object that can be used to look up a top-x-statistic. /** Gets a RequestGenerator that can be used to create a TopStatRequest
This StatRequest will have all default settings already configured, and will be for a top-list of the specified size. This RequestGenerator will
processed as soon as you call one of its methods. make sure all default settings for a top-statistic-lookup are configured.
<br>
<br> Don't call this from the main Thread! (see class description)
@param topListSize how big the top-x should be (10 by default) @param topListSize how big the top-x should be (10 by default)
@return a TopStatRequest that can be used to look up a top statistic*/ @return the RequestGenerator*/
RequestGenerator<LinkedHashMap<String, Integer>> calculateTopStat(int topListSize); RequestGenerator<LinkedHashMap<String, Integer>> topStatRequest(int topListSize);
RequestGenerator<LinkedHashMap<String, Integer>> calculateTotalTopStatList(); /** Gets a RequestGenerator that can be used to create a TopStatRequest
for all offline players on the server. This RequestGenerator will make sure
all default settings for a top-statistic-lookup are configured.
@return the RequestGenerator*/
RequestGenerator<LinkedHashMap<String, Integer>> totalTopStatListRequest();
} }

View File

@ -3,8 +3,8 @@ package com.gmail.artemis.the.gr8.playerstats.commands;
import com.gmail.artemis.the.gr8.playerstats.ThreadManager; import com.gmail.artemis.the.gr8.playerstats.ThreadManager;
import com.gmail.artemis.the.gr8.playerstats.enums.StandardMessage; import com.gmail.artemis.the.gr8.playerstats.enums.StandardMessage;
import com.gmail.artemis.the.gr8.playerstats.enums.Target; import com.gmail.artemis.the.gr8.playerstats.enums.Target;
import com.gmail.artemis.the.gr8.playerstats.statistic.request.StatRequestHandler; import com.gmail.artemis.the.gr8.playerstats.statistic.request.RequestSettings;
import com.gmail.artemis.the.gr8.playerstats.statistic.request.StatRequest; import com.gmail.artemis.the.gr8.playerstats.statistic.request.RequestHandler;
import com.gmail.artemis.the.gr8.playerstats.msg.OutputManager; import com.gmail.artemis.the.gr8.playerstats.msg.OutputManager;
import org.bukkit.Statistic; import org.bukkit.Statistic;
import org.bukkit.command.Command; import org.bukkit.command.Command;
@ -32,10 +32,10 @@ public final class StatCommand implements CommandExecutor {
outputManager.sendExamples(sender); outputManager.sendExamples(sender);
} }
else { else {
StatRequest baseRequest = StatRequestHandler.getBasicInternalStatRequest(sender); RequestSettings baseRequest = RequestHandler.getBasicInternalStatRequest(sender);
StatRequestHandler statRequestHandler = new StatRequestHandler(baseRequest); RequestHandler requestHandler = new RequestHandler(baseRequest);
StatRequest completedRequest = statRequestHandler.getRequestFromArgs(args); RequestSettings completedRequest = requestHandler.getRequestFromArgs(args);
if (completedRequest.isValid()) { if (completedRequest.isValid()) {
threadManager.startStatThread(completedRequest); threadManager.startStatThread(completedRequest);
} else { } else {
@ -46,7 +46,7 @@ public final class StatCommand implements CommandExecutor {
return true; return true;
} }
/** If a given {@link StatRequest} does not result in a valid statistic look-up, /** If a given {@link RequestSettings} does not result in a valid statistic look-up,
this will send a feedback message to the CommandSender that made the request. this will send a feedback message to the CommandSender that made the request.
<br> The following is checked: <br> The following is checked:
<ul> <ul>
@ -54,23 +54,23 @@ public final class StatCommand implements CommandExecutor {
<li>Is a <code>subStatEntry</code> needed, and if so, is a corresponding Material/EntityType present? <li>Is a <code>subStatEntry</code> needed, and if so, is a corresponding Material/EntityType present?
<li>If the <code>target</code> is Player, is a valid <code>playerName</code> provided? <li>If the <code>target</code> is Player, is a valid <code>playerName</code> provided?
</ul> </ul>
@param statRequest the StatRequest to give feedback on @param requestSettings the RequestSettings to give feedback on
*/ */
private void sendFeedback(StatRequest statRequest) { private void sendFeedback(RequestSettings requestSettings) {
CommandSender sender = statRequest.getCommandSender(); CommandSender sender = requestSettings.getCommandSender();
if (statRequest.getStatistic() == null) { if (requestSettings.getStatistic() == null) {
outputManager.sendFeedbackMsg(sender, StandardMessage.MISSING_STAT_NAME); outputManager.sendFeedbackMsg(sender, StandardMessage.MISSING_STAT_NAME);
} }
else if (statRequest.getTarget() == Target.PLAYER && statRequest.getPlayerName() == null) { else if (requestSettings.getTarget() == Target.PLAYER && requestSettings.getPlayerName() == null) {
outputManager.sendFeedbackMsg(sender, StandardMessage.MISSING_PLAYER_NAME); outputManager.sendFeedbackMsg(sender, StandardMessage.MISSING_PLAYER_NAME);
} }
else { else {
Statistic.Type type = statRequest.getStatistic().getType(); Statistic.Type type = requestSettings.getStatistic().getType();
if (type != Statistic.Type.UNTYPED && statRequest.getSubStatEntryName() == null) { if (type != Statistic.Type.UNTYPED && requestSettings.getSubStatEntryName() == null) {
outputManager.sendFeedbackMsgMissingSubStat(sender, type); outputManager.sendFeedbackMsgMissingSubStat(sender, type);
} else { } else {
outputManager.sendFeedbackMsgWrongSubStat(sender, type, statRequest.getSubStatEntryName()); outputManager.sendFeedbackMsgWrongSubStat(sender, type, requestSettings.getSubStatEntryName());
} }
} }
} }

View File

@ -5,7 +5,7 @@ import com.gmail.artemis.the.gr8.playerstats.enums.Target;
import com.gmail.artemis.the.gr8.playerstats.config.ConfigHandler; import com.gmail.artemis.the.gr8.playerstats.config.ConfigHandler;
import com.gmail.artemis.the.gr8.playerstats.enums.Unit; import com.gmail.artemis.the.gr8.playerstats.enums.Unit;
import com.gmail.artemis.the.gr8.playerstats.statistic.request.StatRequest; import com.gmail.artemis.the.gr8.playerstats.statistic.request.RequestSettings;
import com.gmail.artemis.the.gr8.playerstats.msg.components.ComponentFactory; import com.gmail.artemis.the.gr8.playerstats.msg.components.ComponentFactory;
import com.gmail.artemis.the.gr8.playerstats.msg.components.ExampleMessage; import com.gmail.artemis.the.gr8.playerstats.msg.components.ExampleMessage;
import com.gmail.artemis.the.gr8.playerstats.msg.components.HelpMessage; import com.gmail.artemis.the.gr8.playerstats.msg.components.HelpMessage;
@ -182,15 +182,15 @@ public final class MessageBuilder {
<p>- Integer shareCode: if a shareCode is provided, a clickable "share" button will be added. <p>- Integer shareCode: if a shareCode is provided, a clickable "share" button will be added.
<br>- CommandSender sender: if a sender is provided, a signature with "shared by sender-name" will be added.</br> <br>- CommandSender sender: if a sender is provided, a signature with "shared by sender-name" will be added.</br>
<br>- If both parameters are null, the formattedValue will be returned as is.</br>*/ <br>- If both parameters are null, the formattedValue will be returned as is.</br>*/
public BiFunction<Integer, CommandSender, TextComponent> formattedPlayerStatFunction(int stat, @NotNull StatRequest statRequest) { public BiFunction<Integer, CommandSender, TextComponent> formattedPlayerStatFunction(int stat, @NotNull RequestSettings requestSettings) {
TextComponent playerStat = Component.text() TextComponent playerStat = Component.text()
.append(componentFactory.playerName(statRequest.getPlayerName(), Target.PLAYER) .append(componentFactory.playerName(requestSettings.getPlayerName(), Target.PLAYER)
.append(text(":")) .append(text(":"))
.append(space())) .append(space()))
.append(getStatNumberComponent(statRequest, stat)) .append(getStatNumberComponent(requestSettings, stat))
.append(space()) .append(space())
.append(getStatNameComponent(statRequest)) .append(getStatNameComponent(requestSettings))
.append(getStatUnitComponent(statRequest.getStatistic(), statRequest.getTarget())) //space is provided by statUnitComponent .append(getStatUnitComponent(requestSettings.getStatistic(), requestSettings.getTarget())) //space is provided by statUnitComponent
.build(); .build();
return getFormattingFunction(playerStat, Target.PLAYER); return getFormattingFunction(playerStat, Target.PLAYER);
@ -201,16 +201,16 @@ public final class MessageBuilder {
<p>- Integer shareCode: if a shareCode is provided, a clickable "share" button will be added. <p>- Integer shareCode: if a shareCode is provided, a clickable "share" button will be added.
<br>- CommandSender sender: if a sender is provided, a signature with "shared by sender-name" will be added.</br> <br>- CommandSender sender: if a sender is provided, a signature with "shared by sender-name" will be added.</br>
<br>- If both parameters are null, the formattedValue will be returned as is.</br>*/ <br>- If both parameters are null, the formattedValue will be returned as is.</br>*/
public BiFunction<Integer, CommandSender, TextComponent> formattedServerStatFunction(long stat, @NotNull StatRequest statRequest) { public BiFunction<Integer, CommandSender, TextComponent> formattedServerStatFunction(long stat, @NotNull RequestSettings requestSettings) {
TextComponent serverStat = text() TextComponent serverStat = text()
.append(componentFactory.title(config.getServerTitle(), Target.SERVER)) .append(componentFactory.title(config.getServerTitle(), Target.SERVER))
.append(space()) .append(space())
.append(componentFactory.serverName(config.getServerName())) .append(componentFactory.serverName(config.getServerName()))
.append(space()) .append(space())
.append(getStatNumberComponent(statRequest, stat)) .append(getStatNumberComponent(requestSettings, stat))
.append(space()) .append(space())
.append(getStatNameComponent(statRequest)) .append(getStatNameComponent(requestSettings))
.append(getStatUnitComponent(statRequest.getStatistic(), statRequest.getTarget())) //space is provided by statUnit .append(getStatUnitComponent(requestSettings.getStatistic(), requestSettings.getTarget())) //space is provided by statUnit
.build(); .build();
return getFormattingFunction(serverStat, Target.SERVER); return getFormattingFunction(serverStat, Target.SERVER);
@ -221,10 +221,10 @@ public final class MessageBuilder {
<p>- Integer shareCode: if a shareCode is provided, a clickable "share" button will be added. <p>- Integer shareCode: if a shareCode is provided, a clickable "share" button will be added.
<br>- CommandSender sender: if a sender is provided, a signature with "shared by sender-name" will be added.</br> <br>- CommandSender sender: if a sender is provided, a signature with "shared by sender-name" will be added.</br>
<br>- If both parameters are null, the formattedValue will be returned as is.</br>*/ <br>- If both parameters are null, the formattedValue will be returned as is.</br>*/
public BiFunction<Integer, CommandSender, TextComponent> formattedTopStatFunction(@NotNull LinkedHashMap<String, Integer> topStats, @NotNull StatRequest statRequest) { public BiFunction<Integer, CommandSender, TextComponent> formattedTopStatFunction(@NotNull LinkedHashMap<String, Integer> topStats, @NotNull RequestSettings requestSettings) {
final TextComponent title = getTopStatsTitleComponent(statRequest, topStats.size()); final TextComponent title = getTopStatsTitleComponent(requestSettings, topStats.size());
final TextComponent shortTitle = getTopStatDescription(statRequest, topStats.size()); final TextComponent shortTitle = getTopStatDescription(requestSettings, topStats.size());
final TextComponent list = getTopStatListComponent(topStats, statRequest); final TextComponent list = getTopStatListComponent(topStats, requestSettings);
final boolean useEnters = config.useEnters(Target.TOP, false); final boolean useEnters = config.useEnters(Target.TOP, false);
final boolean useEntersForShared = config.useEnters(Target.TOP, true); final boolean useEntersForShared = config.useEnters(Target.TOP, true);
@ -296,25 +296,25 @@ public final class MessageBuilder {
return componentFactory.sharerName(sender.getName()); return componentFactory.sharerName(sender.getName());
} }
private TextComponent getTopStatsTitleComponent(StatRequest statRequest, int statListSize) { private TextComponent getTopStatsTitleComponent(RequestSettings requestSettings, int statListSize) {
return Component.text() return Component.text()
.append(componentFactory.pluginPrefix()).append(space()) .append(componentFactory.pluginPrefix()).append(space())
.append(componentFactory.title(config.getTopStatsTitle(), Target.TOP)).append(space()) .append(componentFactory.title(config.getTopStatsTitle(), Target.TOP)).append(space())
.append(componentFactory.titleNumber(statListSize)).append(space()) .append(componentFactory.titleNumber(statListSize)).append(space())
.append(getStatNameComponent(statRequest)) //space is provided by statUnitComponent .append(getStatNameComponent(requestSettings)) //space is provided by statUnitComponent
.append(getStatUnitComponent(statRequest.getStatistic(), statRequest.getTarget())) .append(getStatUnitComponent(requestSettings.getStatistic(), requestSettings.getTarget()))
.build(); .build();
} }
private TextComponent getTopStatDescription(StatRequest statRequest, int statListSize) { private TextComponent getTopStatDescription(RequestSettings requestSettings, int statListSize) {
return Component.text() return Component.text()
.append(componentFactory.title(config.getTopStatsTitle(), Target.TOP)).append(space()) .append(componentFactory.title(config.getTopStatsTitle(), Target.TOP)).append(space())
.append(componentFactory.titleNumber(statListSize)).append(space()) .append(componentFactory.titleNumber(statListSize)).append(space())
.append(getStatNameComponent(statRequest)) //space is provided by statUnitComponent .append(getStatNameComponent(requestSettings)) //space is provided by statUnitComponent
.build(); .build();
} }
private TextComponent getTopStatListComponent(LinkedHashMap<String, Integer> topStats, StatRequest statRequest) { private TextComponent getTopStatListComponent(LinkedHashMap<String, Integer> topStats, RequestSettings requestSettings) {
TextComponent.Builder topList = Component.text(); TextComponent.Builder topList = Component.text();
Set<String> playerNames = topStats.keySet(); Set<String> playerNames = topStats.keySet();
boolean useDots = config.useDots(); boolean useDots = config.useDots();
@ -331,7 +331,7 @@ public final class MessageBuilder {
else { else {
topList.append(componentFactory.playerName(playerName + ":", Target.TOP)); topList.append(componentFactory.playerName(playerName + ":", Target.TOP));
} }
topList.append(space()).append(getStatNumberComponent(statRequest, topStats.get(playerName))); topList.append(space()).append(getStatNumberComponent(requestSettings, topStats.get(playerName)));
} }
return topList.build(); return topList.build();
} }
@ -350,30 +350,30 @@ public final class MessageBuilder {
/** Depending on the config settings, return either a TranslatableComponent representing /** Depending on the config settings, return either a TranslatableComponent representing
the statName (and potential subStatName), or a TextComponent with capitalized English names.*/ the statName (and potential subStatName), or a TextComponent with capitalized English names.*/
private TextComponent getStatNameComponent(StatRequest statRequest) { private TextComponent getStatNameComponent(RequestSettings requestSettings) {
if (config.useTranslatableComponents()) { if (config.useTranslatableComponents()) {
String statKey = languageKeyHandler.getStatKey(statRequest.getStatistic()); String statKey = languageKeyHandler.getStatKey(requestSettings.getStatistic());
String subStatKey = statRequest.getSubStatEntryName(); String subStatKey = requestSettings.getSubStatEntryName();
if (subStatKey != null) { if (subStatKey != null) {
switch (statRequest.getStatistic().getType()) { switch (requestSettings.getStatistic().getType()) {
case BLOCK -> subStatKey = languageKeyHandler.getBlockKey(statRequest.getBlock()); case BLOCK -> subStatKey = languageKeyHandler.getBlockKey(requestSettings.getBlock());
case ENTITY -> subStatKey = languageKeyHandler.getEntityKey(statRequest.getEntity()); case ENTITY -> subStatKey = languageKeyHandler.getEntityKey(requestSettings.getEntity());
case ITEM -> subStatKey = languageKeyHandler.getItemKey(statRequest.getItem()); case ITEM -> subStatKey = languageKeyHandler.getItemKey(requestSettings.getItem());
default -> { default -> {
} }
} }
} }
return componentFactory.statAndSubStatNameTranslatable(statKey, subStatKey, statRequest.getTarget()); return componentFactory.statAndSubStatNameTranslatable(statKey, subStatKey, requestSettings.getTarget());
} }
else { else {
return componentFactory.statAndSubStatName( return componentFactory.statAndSubStatName(
StringUtils.prettify(statRequest.getStatistic().toString()), StringUtils.prettify(requestSettings.getStatistic().toString()),
StringUtils.prettify(statRequest.getSubStatEntryName()), StringUtils.prettify(requestSettings.getSubStatEntryName()),
statRequest.getTarget()); requestSettings.getTarget());
} }
} }
private TextComponent getStatNumberComponent(StatRequest request, long statNumber) { private TextComponent getStatNumberComponent(RequestSettings request, long statNumber) {
return getStatNumberComponent(request.getStatistic(), request.getTarget(), statNumber); return getStatNumberComponent(request.getStatistic(), request.getTarget(), statNumber);
} }

View File

@ -5,7 +5,7 @@ import com.gmail.artemis.the.gr8.playerstats.api.StatFormatter;
import com.gmail.artemis.the.gr8.playerstats.config.ConfigHandler; import com.gmail.artemis.the.gr8.playerstats.config.ConfigHandler;
import com.gmail.artemis.the.gr8.playerstats.enums.StandardMessage; import com.gmail.artemis.the.gr8.playerstats.enums.StandardMessage;
import com.gmail.artemis.the.gr8.playerstats.msg.components.ComponentFactory; import com.gmail.artemis.the.gr8.playerstats.msg.components.ComponentFactory;
import com.gmail.artemis.the.gr8.playerstats.statistic.request.StatRequest; import com.gmail.artemis.the.gr8.playerstats.statistic.request.RequestSettings;
import com.gmail.artemis.the.gr8.playerstats.msg.components.BukkitConsoleComponentFactory; import com.gmail.artemis.the.gr8.playerstats.msg.components.BukkitConsoleComponentFactory;
import com.gmail.artemis.the.gr8.playerstats.msg.components.PrideComponentFactory; import com.gmail.artemis.the.gr8.playerstats.msg.components.PrideComponentFactory;
import net.kyori.adventure.platform.bukkit.BukkitAudiences; import net.kyori.adventure.platform.bukkit.BukkitAudiences;
@ -77,19 +77,19 @@ public final class OutputManager implements StatFormatter {
} }
@Override @Override
public TextComponent formatPlayerStat(@NotNull StatRequest statRequest, int playerStat) { public TextComponent formatPlayerStat(@NotNull RequestSettings requestSettings, int playerStat) {
BiFunction<Integer, CommandSender, TextComponent> playerStatFunction = BiFunction<Integer, CommandSender, TextComponent> playerStatFunction =
getMessageBuilder(statRequest).formattedPlayerStatFunction(playerStat, statRequest); getMessageBuilder(requestSettings).formattedPlayerStatFunction(playerStat, requestSettings);
return processFunction(statRequest.getCommandSender(), playerStatFunction); return processFunction(requestSettings.getCommandSender(), playerStatFunction);
} }
@Override @Override
public TextComponent formatServerStat(@NotNull StatRequest statRequest, long serverStat) { public TextComponent formatServerStat(@NotNull RequestSettings requestSettings, long serverStat) {
BiFunction<Integer, CommandSender, TextComponent> serverStatFunction = BiFunction<Integer, CommandSender, TextComponent> serverStatFunction =
getMessageBuilder(statRequest).formattedServerStatFunction(serverStat, statRequest); getMessageBuilder(requestSettings).formattedServerStatFunction(serverStat, requestSettings);
return processFunction(statRequest.getCommandSender(), serverStatFunction); return processFunction(requestSettings.getCommandSender(), serverStatFunction);
} }
@Override @Override
@ -98,11 +98,11 @@ public final class OutputManager implements StatFormatter {
} }
@Override @Override
public TextComponent formatTopStat(@NotNull StatRequest statRequest, @NotNull LinkedHashMap<String, Integer> topStats) { public TextComponent formatTopStat(@NotNull RequestSettings requestSettings, @NotNull LinkedHashMap<String, Integer> topStats) {
BiFunction<Integer, CommandSender, TextComponent> topStatFunction = BiFunction<Integer, CommandSender, TextComponent> topStatFunction =
getMessageBuilder(statRequest).formattedTopStatFunction(topStats, statRequest); getMessageBuilder(requestSettings).formattedTopStatFunction(topStats, requestSettings);
return processFunction(statRequest.getCommandSender(), topStatFunction); return processFunction(requestSettings.getCommandSender(), topStatFunction);
} }
public void sendFeedbackMsg(@NotNull CommandSender sender, StandardMessage message) { public void sendFeedbackMsg(@NotNull CommandSender sender, StandardMessage message) {
@ -168,8 +168,8 @@ public final class OutputManager implements StatFormatter {
return sender instanceof ConsoleCommandSender ? consoleMessageBuilder : messageBuilder; return sender instanceof ConsoleCommandSender ? consoleMessageBuilder : messageBuilder;
} }
private MessageBuilder getMessageBuilder(StatRequest statRequest) { private MessageBuilder getMessageBuilder(RequestSettings requestSettings) {
if (statRequest.isAPIRequest() || !statRequest.isConsoleSender()) { if (requestSettings.isAPIRequest() || !requestSettings.isConsoleSender()) {
return messageBuilder; return messageBuilder;
} else { } else {
return consoleMessageBuilder; return consoleMessageBuilder;

View File

@ -7,7 +7,7 @@ import com.gmail.artemis.the.gr8.playerstats.enums.DebugLevel;
import com.gmail.artemis.the.gr8.playerstats.enums.StandardMessage; import com.gmail.artemis.the.gr8.playerstats.enums.StandardMessage;
import com.gmail.artemis.the.gr8.playerstats.msg.OutputManager; import com.gmail.artemis.the.gr8.playerstats.msg.OutputManager;
import com.gmail.artemis.the.gr8.playerstats.statistic.StatThread; import com.gmail.artemis.the.gr8.playerstats.statistic.StatThread;
import com.gmail.artemis.the.gr8.playerstats.statistic.StatRetriever; import com.gmail.artemis.the.gr8.playerstats.statistic.StatCalculator;
import com.gmail.artemis.the.gr8.playerstats.utils.MyLogger; import com.gmail.artemis.the.gr8.playerstats.utils.MyLogger;
import com.gmail.artemis.the.gr8.playerstats.utils.OfflinePlayerHandler; import com.gmail.artemis.the.gr8.playerstats.utils.OfflinePlayerHandler;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
@ -47,7 +47,7 @@ public final class ReloadThread extends Thread {
/** This method will perform a series of tasks. If a {@link StatThread} is still running, /** This method will perform a series of tasks. If a {@link StatThread} is still running,
it will join the statThread and wait for it to finish. Then, it will reload the config, it will join the statThread and wait for it to finish. Then, it will reload the config,
update the offlinePlayerList in the {@link OfflinePlayerHandler}, update the {@link DebugLevel}, update the offlinePlayerList in the {@link OfflinePlayerHandler}, update the {@link DebugLevel},
update the share-settings in {@link ShareManager} and topListSize-settings in {@link StatRetriever}, update the share-settings in {@link ShareManager} and topListSize-settings in {@link StatCalculator},
and update the MessageBuilders in the {@link OutputManager}.*/ and update the MessageBuilders in the {@link OutputManager}.*/
@Override @Override
public void run() { public void run() {

View File

@ -1,7 +1,7 @@
package com.gmail.artemis.the.gr8.playerstats.statistic; package com.gmail.artemis.the.gr8.playerstats.statistic;
import com.gmail.artemis.the.gr8.playerstats.ThreadManager; import com.gmail.artemis.the.gr8.playerstats.ThreadManager;
import com.gmail.artemis.the.gr8.playerstats.statistic.request.StatRequest; import com.gmail.artemis.the.gr8.playerstats.statistic.request.RequestSettings;
import com.gmail.artemis.the.gr8.playerstats.utils.MyLogger; import com.gmail.artemis.the.gr8.playerstats.utils.MyLogger;
import com.gmail.artemis.the.gr8.playerstats.utils.OfflinePlayerHandler; import com.gmail.artemis.the.gr8.playerstats.utils.OfflinePlayerHandler;
import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableList;
@ -18,7 +18,7 @@ final class StatAction extends RecursiveTask<ConcurrentHashMap<String, Integer>>
private final OfflinePlayerHandler offlinePlayerHandler; private final OfflinePlayerHandler offlinePlayerHandler;
private final ImmutableList<String> playerNames; private final ImmutableList<String> playerNames;
private final StatRequest statRequest; private final RequestSettings requestSettings;
private final ConcurrentHashMap<String, Integer> allStats; private final ConcurrentHashMap<String, Integer> allStats;
/** /**
@ -26,15 +26,15 @@ final class StatAction extends RecursiveTask<ConcurrentHashMap<String, Integer>>
* using the default ForkJoinPool, and returns the ConcurrentHashMap when everything is done * using the default ForkJoinPool, and returns the ConcurrentHashMap when everything is done
* @param offlinePlayerHandler the OfflinePlayerHandler to convert playerNames into Players * @param offlinePlayerHandler the OfflinePlayerHandler to convert playerNames into Players
* @param playerNames ImmutableList of playerNames for players that should be included in stat calculations * @param playerNames ImmutableList of playerNames for players that should be included in stat calculations
* @param statRequest a validated statRequest * @param requestSettings a validated requestSettings
* @param allStats the ConcurrentHashMap to put the results on * @param allStats the ConcurrentHashMap to put the results on
*/ */
public StatAction(OfflinePlayerHandler offlinePlayerHandler, ImmutableList<String> playerNames, StatRequest statRequest, ConcurrentHashMap<String, Integer> allStats) { public StatAction(OfflinePlayerHandler offlinePlayerHandler, ImmutableList<String> playerNames, RequestSettings requestSettings, ConcurrentHashMap<String, Integer> allStats) {
threshold = ThreadManager.getTaskThreshold(); threshold = ThreadManager.getTaskThreshold();
this.offlinePlayerHandler = offlinePlayerHandler; this.offlinePlayerHandler = offlinePlayerHandler;
this.playerNames = playerNames; this.playerNames = playerNames;
this.statRequest = statRequest; this.requestSettings = requestSettings;
this.allStats = allStats; this.allStats = allStats;
MyLogger.subActionCreated(Thread.currentThread().getName()); MyLogger.subActionCreated(Thread.currentThread().getName());
@ -46,8 +46,8 @@ final class StatAction extends RecursiveTask<ConcurrentHashMap<String, Integer>>
return getStatsDirectly(); return getStatsDirectly();
} }
else { else {
final StatAction subTask1 = new StatAction(offlinePlayerHandler, playerNames.subList(0, playerNames.size()/2), statRequest, allStats); final StatAction subTask1 = new StatAction(offlinePlayerHandler, playerNames.subList(0, playerNames.size()/2), requestSettings, allStats);
final StatAction subTask2 = new StatAction(offlinePlayerHandler, playerNames.subList(playerNames.size()/2, playerNames.size()), statRequest, allStats); final StatAction subTask2 = new StatAction(offlinePlayerHandler, playerNames.subList(playerNames.size()/2, playerNames.size()), requestSettings, allStats);
//queue and compute all subtasks in the right order //queue and compute all subtasks in the right order
subTask1.fork(); subTask1.fork();
@ -65,11 +65,11 @@ final class StatAction extends RecursiveTask<ConcurrentHashMap<String, Integer>>
OfflinePlayer player = offlinePlayerHandler.getOfflinePlayer(playerName); OfflinePlayer player = offlinePlayerHandler.getOfflinePlayer(playerName);
if (player != null) { if (player != null) {
int statistic = 0; int statistic = 0;
switch (statRequest.getStatistic().getType()) { switch (requestSettings.getStatistic().getType()) {
case UNTYPED -> statistic = player.getStatistic(statRequest.getStatistic()); case UNTYPED -> statistic = player.getStatistic(requestSettings.getStatistic());
case ENTITY -> statistic = player.getStatistic(statRequest.getStatistic(), statRequest.getEntity()); case ENTITY -> statistic = player.getStatistic(requestSettings.getStatistic(), requestSettings.getEntity());
case BLOCK -> statistic = player.getStatistic(statRequest.getStatistic(), statRequest.getBlock()); case BLOCK -> statistic = player.getStatistic(requestSettings.getStatistic(), requestSettings.getBlock());
case ITEM -> statistic = player.getStatistic(statRequest.getStatistic(), statRequest.getItem()); case ITEM -> statistic = player.getStatistic(requestSettings.getStatistic(), requestSettings.getItem());
} }
if (statistic > 0) { if (statistic > 0) {
allStats.put(playerName, statistic); allStats.put(playerName, statistic);

View File

@ -2,7 +2,7 @@ package com.gmail.artemis.the.gr8.playerstats.statistic;
import com.gmail.artemis.the.gr8.playerstats.ThreadManager; import com.gmail.artemis.the.gr8.playerstats.ThreadManager;
import com.gmail.artemis.the.gr8.playerstats.enums.DebugLevel; import com.gmail.artemis.the.gr8.playerstats.enums.DebugLevel;
import com.gmail.artemis.the.gr8.playerstats.statistic.request.StatRequest; import com.gmail.artemis.the.gr8.playerstats.statistic.request.RequestSettings;
import com.gmail.artemis.the.gr8.playerstats.utils.MyLogger; import com.gmail.artemis.the.gr8.playerstats.utils.MyLogger;
import com.gmail.artemis.the.gr8.playerstats.utils.OfflinePlayerHandler; import com.gmail.artemis.the.gr8.playerstats.utils.OfflinePlayerHandler;
import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableList;
@ -14,37 +14,37 @@ import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ForkJoinPool; import java.util.concurrent.ForkJoinPool;
import java.util.stream.Collectors; import java.util.stream.Collectors;
public final class StatRetriever { public final class StatCalculator {
private final OfflinePlayerHandler offlinePlayerHandler; private final OfflinePlayerHandler offlinePlayerHandler;
public StatRetriever(OfflinePlayerHandler offlinePlayerHandler) { public StatCalculator(OfflinePlayerHandler offlinePlayerHandler) {
this.offlinePlayerHandler = offlinePlayerHandler; this.offlinePlayerHandler = offlinePlayerHandler;
} }
public int getPlayerStat(StatRequest statRequest) { public int getPlayerStat(RequestSettings requestSettings) {
OfflinePlayer player = offlinePlayerHandler.getOfflinePlayer(statRequest.getPlayerName()); OfflinePlayer player = offlinePlayerHandler.getOfflinePlayer(requestSettings.getPlayerName());
if (player != null) { if (player != null) {
return switch (statRequest.getStatistic().getType()) { return switch (requestSettings.getStatistic().getType()) {
case UNTYPED -> player.getStatistic(statRequest.getStatistic()); case UNTYPED -> player.getStatistic(requestSettings.getStatistic());
case ENTITY -> player.getStatistic(statRequest.getStatistic(), statRequest.getEntity()); case ENTITY -> player.getStatistic(requestSettings.getStatistic(), requestSettings.getEntity());
case BLOCK -> player.getStatistic(statRequest.getStatistic(), statRequest.getBlock()); case BLOCK -> player.getStatistic(requestSettings.getStatistic(), requestSettings.getBlock());
case ITEM -> player.getStatistic(statRequest.getStatistic(), statRequest.getItem()); case ITEM -> player.getStatistic(requestSettings.getStatistic(), requestSettings.getItem());
}; };
} }
return 0; return 0;
} }
public LinkedHashMap<String, Integer> getTopStats(StatRequest statRequest) { public LinkedHashMap<String, Integer> getTopStats(RequestSettings requestSettings) {
return getAllStatsAsync(statRequest).entrySet().stream() return getAllStatsAsync(requestSettings).entrySet().stream()
.sorted(Map.Entry.comparingByValue(Comparator.reverseOrder())) .sorted(Map.Entry.comparingByValue(Comparator.reverseOrder()))
.limit(statRequest.getTopListSize()) .limit(requestSettings.getTopListSize())
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (e1, e2) -> e1, LinkedHashMap::new)); .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (e1, e2) -> e1, LinkedHashMap::new));
} }
public long getServerStat(StatRequest statRequest) { public long getServerStat(RequestSettings requestSettings) {
List<Integer> numbers = getAllStatsAsync(statRequest) List<Integer> numbers = getAllStatsAsync(requestSettings)
.values() .values()
.parallelStream() .parallelStream()
.toList(); .toList();
@ -53,16 +53,16 @@ public final class StatRetriever {
/** Invokes a bunch of worker pool threads to divide and conquer (get the statistics for all players /** Invokes a bunch of worker pool threads to divide and conquer (get the statistics for all players
that are stored in the {@link OfflinePlayerHandler}) */ that are stored in the {@link OfflinePlayerHandler}) */
private @NotNull ConcurrentHashMap<String, Integer> getAllStatsAsync(StatRequest statRequest) { private @NotNull ConcurrentHashMap<String, Integer> getAllStatsAsync(RequestSettings requestSettings) {
long time = System.currentTimeMillis(); long time = System.currentTimeMillis();
ForkJoinPool commonPool = ForkJoinPool.commonPool(); ForkJoinPool commonPool = ForkJoinPool.commonPool();
ConcurrentHashMap<String, Integer> allStats; ConcurrentHashMap<String, Integer> allStats;
try { try {
allStats = commonPool.invoke(getStatTask(statRequest)); allStats = commonPool.invoke(getStatTask(requestSettings));
} catch (ConcurrentModificationException e) { } catch (ConcurrentModificationException e) {
MyLogger.logMsg("The statRequest could not be executed due to a ConcurrentModificationException. " + MyLogger.logMsg("The requestSettings could not be executed due to a ConcurrentModificationException. " +
"This likely happened because Bukkit hasn't fully initialized all player-data yet. " + "This likely happened because Bukkit hasn't fully initialized all player-data yet. " +
"Try again and it should be fine!", true); "Try again and it should be fine!", true);
throw new ConcurrentModificationException(e.toString()); throw new ConcurrentModificationException(e.toString());
@ -75,12 +75,12 @@ public final class StatRetriever {
return allStats; return allStats;
} }
private StatAction getStatTask(StatRequest statRequest) { private StatAction getStatTask(RequestSettings requestSettings) {
int size = offlinePlayerHandler.getOfflinePlayerCount() != 0 ? offlinePlayerHandler.getOfflinePlayerCount() : 16; int size = offlinePlayerHandler.getOfflinePlayerCount() != 0 ? offlinePlayerHandler.getOfflinePlayerCount() : 16;
ConcurrentHashMap<String, Integer> allStats = new ConcurrentHashMap<>(size); ConcurrentHashMap<String, Integer> allStats = new ConcurrentHashMap<>(size);
ImmutableList<String> playerNames = ImmutableList.copyOf(offlinePlayerHandler.getOfflinePlayerNames()); ImmutableList<String> playerNames = ImmutableList.copyOf(offlinePlayerHandler.getOfflinePlayerNames());
StatAction task = new StatAction(offlinePlayerHandler, playerNames, statRequest, allStats); StatAction task = new StatAction(offlinePlayerHandler, playerNames, requestSettings, allStats);
MyLogger.actionCreated(playerNames.size()); MyLogger.actionCreated(playerNames.size());
return task; return task;

View File

@ -3,7 +3,7 @@ package com.gmail.artemis.the.gr8.playerstats.statistic;
import com.gmail.artemis.the.gr8.playerstats.enums.StandardMessage; import com.gmail.artemis.the.gr8.playerstats.enums.StandardMessage;
import com.gmail.artemis.the.gr8.playerstats.enums.Target; import com.gmail.artemis.the.gr8.playerstats.enums.Target;
import com.gmail.artemis.the.gr8.playerstats.msg.components.ComponentUtils; import com.gmail.artemis.the.gr8.playerstats.msg.components.ComponentUtils;
import com.gmail.artemis.the.gr8.playerstats.statistic.request.StatRequest; import com.gmail.artemis.the.gr8.playerstats.statistic.request.RequestSettings;
import com.gmail.artemis.the.gr8.playerstats.msg.OutputManager; import com.gmail.artemis.the.gr8.playerstats.msg.OutputManager;
import com.gmail.artemis.the.gr8.playerstats.reload.ReloadThread; import com.gmail.artemis.the.gr8.playerstats.reload.ReloadThread;
import com.gmail.artemis.the.gr8.playerstats.ThreadManager; import com.gmail.artemis.the.gr8.playerstats.ThreadManager;
@ -17,19 +17,19 @@ import java.util.*;
public final class StatThread extends Thread { public final class StatThread extends Thread {
private static OutputManager outputManager; private static OutputManager outputManager;
private static StatRetriever statRetriever; private static StatCalculator statCalculator;
private final ReloadThread reloadThread; private final ReloadThread reloadThread;
private final StatRequest statRequest; private final RequestSettings requestSettings;
public StatThread(OutputManager m, StatRetriever t, int ID, StatRequest s, @Nullable ReloadThread r) { public StatThread(OutputManager m, StatCalculator t, int ID, RequestSettings s, @Nullable ReloadThread r) {
outputManager = m; outputManager = m;
statRetriever = t; statCalculator = t;
reloadThread = r; reloadThread = r;
statRequest = s; requestSettings = s;
this.setName("StatThread-" + statRequest.getCommandSender().getName() + "-" + ID); this.setName("StatThread-" + requestSettings.getCommandSender().getName() + "-" + ID);
MyLogger.threadCreated(this.getName()); MyLogger.threadCreated(this.getName());
} }
@ -37,13 +37,13 @@ public final class StatThread extends Thread {
public void run() throws IllegalStateException, NullPointerException { public void run() throws IllegalStateException, NullPointerException {
MyLogger.threadStart(this.getName()); MyLogger.threadStart(this.getName());
if (statRequest == null) { if (requestSettings == null) {
throw new NullPointerException("No statistic statRequest was found!"); throw new NullPointerException("No statistic requestSettings was found!");
} }
if (reloadThread != null && reloadThread.isAlive()) { if (reloadThread != null && reloadThread.isAlive()) {
try { try {
MyLogger.waitingForOtherThread(this.getName(), reloadThread.getName()); MyLogger.waitingForOtherThread(this.getName(), reloadThread.getName());
outputManager.sendFeedbackMsg(statRequest.getCommandSender(), StandardMessage.STILL_RELOADING); outputManager.sendFeedbackMsg(requestSettings.getCommandSender(), StandardMessage.STILL_RELOADING);
reloadThread.join(); reloadThread.join();
} catch (InterruptedException e) { } catch (InterruptedException e) {
@ -54,28 +54,28 @@ public final class StatThread extends Thread {
long lastCalc = ThreadManager.getLastRecordedCalcTime(); long lastCalc = ThreadManager.getLastRecordedCalcTime();
if (lastCalc > 2000) { if (lastCalc > 2000) {
outputManager.sendFeedbackMsgWaitAMoment(statRequest.getCommandSender(), lastCalc > 20000); outputManager.sendFeedbackMsgWaitAMoment(requestSettings.getCommandSender(), lastCalc > 20000);
} }
Target selection = statRequest.getTarget(); Target selection = requestSettings.getTarget();
try { try {
TextComponent statResult = switch (selection) { TextComponent statResult = switch (selection) {
case PLAYER -> outputManager.formatPlayerStat(statRequest, statRetriever.getPlayerStat(statRequest)); case PLAYER -> outputManager.formatPlayerStat(requestSettings, statCalculator.getPlayerStat(requestSettings));
case TOP -> outputManager.formatTopStat(statRequest, statRetriever.getTopStats(statRequest)); case TOP -> outputManager.formatTopStat(requestSettings, statCalculator.getTopStats(requestSettings));
case SERVER -> outputManager.formatServerStat(statRequest, statRetriever.getServerStat(statRequest)); case SERVER -> outputManager.formatServerStat(requestSettings, statCalculator.getServerStat(requestSettings));
}; };
if (statRequest.isAPIRequest()) { if (requestSettings.isAPIRequest()) {
String msg = ComponentUtils.getTranslatableComponentSerializer() String msg = ComponentUtils.getTranslatableComponentSerializer()
.serialize(statResult); .serialize(statResult);
statRequest.getCommandSender().sendMessage(msg); requestSettings.getCommandSender().sendMessage(msg);
} }
else { else {
outputManager.sendToCommandSender(statRequest.getCommandSender(), statResult); outputManager.sendToCommandSender(requestSettings.getCommandSender(), statResult);
} }
} }
catch (ConcurrentModificationException e) { catch (ConcurrentModificationException e) {
if (!statRequest.isConsoleSender()) { if (!requestSettings.isConsoleSender()) {
outputManager.sendFeedbackMsg(statRequest.getCommandSender(), StandardMessage.UNKNOWN_ERROR); outputManager.sendFeedbackMsg(requestSettings.getCommandSender(), StandardMessage.UNKNOWN_ERROR);
} }
} }
} }

View File

@ -1,7 +1,7 @@
package com.gmail.artemis.the.gr8.playerstats.statistic.request; package com.gmail.artemis.the.gr8.playerstats.statistic.request;
import com.gmail.artemis.the.gr8.playerstats.Main;
import com.gmail.artemis.the.gr8.playerstats.api.RequestGenerator; import com.gmail.artemis.the.gr8.playerstats.api.RequestGenerator;
import com.gmail.artemis.the.gr8.playerstats.api.RequestExecutor;
import com.gmail.artemis.the.gr8.playerstats.statistic.result.PlayerStatResult; import com.gmail.artemis.the.gr8.playerstats.statistic.result.PlayerStatResult;
import com.gmail.artemis.the.gr8.playerstats.statistic.result.StatResult; import com.gmail.artemis.the.gr8.playerstats.statistic.result.StatResult;
import net.kyori.adventure.text.TextComponent; import net.kyori.adventure.text.TextComponent;
@ -10,43 +10,42 @@ import org.bukkit.Statistic;
import org.bukkit.entity.EntityType; import org.bukkit.entity.EntityType;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
public final class PlayerStatRequest implements RequestGenerator<Integer>, RequestExecutor<Integer> { public final class PlayerStatRequest extends StatRequest<Integer> implements RequestGenerator<Integer> {
private final StatRequest statRequest; private final RequestHandler requestHandler;
private final StatRequestHandler statRequestHandler;
public PlayerStatRequest(StatRequest request) { public PlayerStatRequest(RequestSettings request) {
statRequest = request; super(request);
statRequestHandler = new StatRequestHandler(request); requestHandler = new RequestHandler(request);
} }
@Override @Override
public RequestExecutor<Integer> untyped(@NotNull Statistic statistic) { public StatRequest<Integer> untyped(@NotNull Statistic statistic) {
StatRequest completedRequest = statRequestHandler.untyped(statistic); RequestSettings completedRequest = requestHandler.untyped(statistic);
return new PlayerStatRequest(completedRequest); return new PlayerStatRequest(completedRequest);
} }
@Override @Override
public RequestExecutor<Integer> blockOrItemType(@NotNull Statistic statistic, @NotNull Material material) { public StatRequest<Integer> blockOrItemType(@NotNull Statistic statistic, @NotNull Material material) {
StatRequest completedRequest = statRequestHandler.blockOrItemType(statistic, material); RequestSettings completedRequest = requestHandler.blockOrItemType(statistic, material);
return new PlayerStatRequest(completedRequest); return new PlayerStatRequest(completedRequest);
} }
@Override @Override
public RequestExecutor<Integer> entityType(@NotNull Statistic statistic, @NotNull EntityType entityType) { public StatRequest<Integer> entityType(@NotNull Statistic statistic, @NotNull EntityType entityType) {
StatRequest completedRequest = statRequestHandler.entityType(statistic, entityType); RequestSettings completedRequest = requestHandler.entityType(statistic, entityType);
return new PlayerStatRequest(completedRequest); return new PlayerStatRequest(completedRequest);
} }
@Override @Override
public StatResult<Integer> execute() { public StatResult<Integer> execute() {
return getStatResult(statRequest); return getStatResult(super.requestSettings);
} }
private PlayerStatResult getStatResult(StatRequest completedRequest) { private PlayerStatResult getStatResult(RequestSettings completedRequest) {
int stat = RequestExecutor.getStatCalculator() int stat = Main.getStatCalculator()
.getPlayerStat(completedRequest); .getPlayerStat(completedRequest);
TextComponent prettyStat = RequestExecutor.getStatFormatter() TextComponent prettyStat = Main.getStatFormatter()
.formatPlayerStat(completedRequest, stat); .formatPlayerStat(completedRequest, stat);
return new PlayerStatResult(stat, prettyStat); return new PlayerStatResult(stat, prettyStat);

View File

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

View File

@ -0,0 +1,186 @@
package com.gmail.artemis.the.gr8.playerstats.statistic.request;
import com.gmail.artemis.the.gr8.playerstats.api.RequestGenerator;
import com.gmail.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> (automatically set for all API-requests)
<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 boolean isAPIRequest;
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
<br>- boolean isAPIRequest
@param sender the CommandSender who prompted this RequestGenerator
@param isAPIRequest whether this RequestGenerator is coming through the API or the onCommand
*/
private RequestSettings(@NotNull CommandSender sender, boolean isAPIRequest) {
this.sender = sender;
this.isAPIRequest = isAPIRequest;
target = Target.TOP;
playerFlag = false;
}
public static RequestSettings getBasicRequest(CommandSender sender) {
return new RequestSettings(sender, false);
}
public static RequestSettings getBasicAPIRequest() {
return new RequestSettings(Bukkit.getConsoleSender(), true);
}
public void setAPIRequest() {
this.isAPIRequest = true;
}
public boolean isAPIRequest() {
return isAPIRequest;
}
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(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

@ -1,6 +1,6 @@
package com.gmail.artemis.the.gr8.playerstats.statistic.request; package com.gmail.artemis.the.gr8.playerstats.statistic.request;
import com.gmail.artemis.the.gr8.playerstats.api.RequestExecutor; import com.gmail.artemis.the.gr8.playerstats.Main;
import com.gmail.artemis.the.gr8.playerstats.api.RequestGenerator; import com.gmail.artemis.the.gr8.playerstats.api.RequestGenerator;
import com.gmail.artemis.the.gr8.playerstats.statistic.result.ServerStatResult; import com.gmail.artemis.the.gr8.playerstats.statistic.result.ServerStatResult;
import com.gmail.artemis.the.gr8.playerstats.statistic.result.StatResult; import com.gmail.artemis.the.gr8.playerstats.statistic.result.StatResult;
@ -10,43 +10,42 @@ import org.bukkit.Statistic;
import org.bukkit.entity.EntityType; import org.bukkit.entity.EntityType;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
public final class ServerStatRequest implements RequestGenerator<Long>, RequestExecutor<Long> { public final class ServerStatRequest extends StatRequest<Long> implements RequestGenerator<Long> {
private final StatRequest statRequest; private final RequestHandler requestHandler;
private final StatRequestHandler statRequestHandler;
public ServerStatRequest(StatRequest request) { public ServerStatRequest(RequestSettings request) {
statRequest = request; super(request);
statRequestHandler = new StatRequestHandler(statRequest); requestHandler = new RequestHandler(requestSettings);
} }
@Override @Override
public RequestExecutor<Long> untyped(@NotNull Statistic statistic) { public StatRequest<Long> untyped(@NotNull Statistic statistic) {
StatRequest completedRequest = statRequestHandler.untyped(statistic); RequestSettings completedRequest = requestHandler.untyped(statistic);
return new ServerStatRequest(completedRequest); return new ServerStatRequest(completedRequest);
} }
@Override @Override
public RequestExecutor<Long> blockOrItemType(@NotNull Statistic statistic, @NotNull Material material) { public StatRequest<Long> blockOrItemType(@NotNull Statistic statistic, @NotNull Material material) {
StatRequest completedRequest = statRequestHandler.blockOrItemType(statistic, material); RequestSettings completedRequest = requestHandler.blockOrItemType(statistic, material);
return new ServerStatRequest(completedRequest); return new ServerStatRequest(completedRequest);
} }
@Override @Override
public RequestExecutor<Long> entityType(@NotNull Statistic statistic, @NotNull EntityType entityType) { public StatRequest<Long> entityType(@NotNull Statistic statistic, @NotNull EntityType entityType) {
StatRequest completedRequest = statRequestHandler.entityType(statistic, entityType); RequestSettings completedRequest = requestHandler.entityType(statistic, entityType);
return new ServerStatRequest(completedRequest); return new ServerStatRequest(completedRequest);
} }
@Override @Override
public StatResult<Long> execute() { public StatResult<Long> execute() {
return getStatResult(statRequest); return getStatResult(requestSettings);
} }
private ServerStatResult getStatResult(StatRequest completedRequest) { private ServerStatResult getStatResult(RequestSettings completedRequest) {
long stat = RequestExecutor.getStatCalculator() long stat = Main.getStatCalculator()
.getServerStat(completedRequest); .getServerStat(completedRequest);
TextComponent prettyStat = RequestExecutor.getStatFormatter() TextComponent prettyStat = Main.getStatFormatter()
.formatServerStat(completedRequest, stat); .formatServerStat(completedRequest, stat);
return new ServerStatResult(stat, prettyStat); return new ServerStatResult(stat, prettyStat);

View File

@ -1,186 +1,40 @@
package com.gmail.artemis.the.gr8.playerstats.statistic.request; package com.gmail.artemis.the.gr8.playerstats.statistic.request;
import com.gmail.artemis.the.gr8.playerstats.api.RequestGenerator;
import com.gmail.artemis.the.gr8.playerstats.enums.Target; import com.gmail.artemis.the.gr8.playerstats.enums.Target;
import org.bukkit.Bukkit; import com.gmail.artemis.the.gr8.playerstats.statistic.result.StatResult;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.Statistic; import org.bukkit.Statistic;
import org.bukkit.command.CommandSender;
import org.bukkit.command.ConsoleCommandSender;
import org.bukkit.entity.EntityType; import org.bukkit.entity.EntityType;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable;
/** A StatRequest is the object PlayerStats uses to calculate and format the requested statistic. public abstract class StatRequest<T> {
This object can be generated 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 StatRequest to be valid, it needs the following values:
<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> (automatically set for all API-requests)
<li> if the <code>target</code> is Target.Player, a <code>playerName</code> needs to be added
</ul>*/
public final class StatRequest {
private final CommandSender sender; protected final RequestSettings requestSettings;
private boolean isAPIRequest;
private Statistic statistic;
private String playerName;
private Target target;
private int topListSize;
private String subStatEntryName; protected StatRequest(RequestSettings request) {
private EntityType entity; requestSettings = request;
private Material block;
private Material item;
private boolean playerFlag;
/** Create a new {@link StatRequest} with default values:
<br>- CommandSender sender (provided)
<br>- Target target = {@link Target#TOP}
<br>- int topListSize = 10
<br>- boolean playerFlag = false
<br>- boolean isAPIRequest
@param sender the CommandSender who prompted this RequestGenerator
@param isAPIRequest whether this RequestGenerator is coming through the API or the onCommand
*/
private StatRequest(@NotNull CommandSender sender, boolean isAPIRequest) {
this.sender = sender;
this.isAPIRequest = isAPIRequest;
target = Target.TOP;
playerFlag = false;
} }
public static StatRequest getBasicRequest(CommandSender sender) { /** Don't call this from the Main Thread!*/
return new StatRequest(sender, false); public abstract StatResult<T> execute();
}
public static StatRequest getBasicAPIRequest() {
return new StatRequest(Bukkit.getConsoleSender(), true);
}
public void setAPIRequest() {
this.isAPIRequest = true;
}
public boolean isAPIRequest() {
return isAPIRequest;
}
public @NotNull CommandSender getCommandSender() {
return sender;
}
public boolean isConsoleSender() {
return sender instanceof ConsoleCommandSender;
}
public void setStatistic(Statistic statistic) {
this.statistic = statistic;
}
public Statistic getStatistic() { public Statistic getStatistic() {
return statistic; return requestSettings.getStatistic();
} }
public void setSubStatEntryName(String subStatEntry) { public @Nullable Material getBlock() {
this.subStatEntryName = subStatEntry; return requestSettings.getBlock();
} }
public String getSubStatEntryName() { public @Nullable Material getItem() {
return subStatEntryName; return requestSettings.getItem();
} }
public void setPlayerName(String playerName) { public @Nullable EntityType getEntity() {
this.playerName = playerName; return requestSettings.getEntity();
} }
public String getPlayerName() { public Target getTarget() {
return playerName; return requestSettings.getTarget();
}
public void setPlayerFlag(boolean playerFlag) {
this.playerFlag = playerFlag;
}
public boolean getPlayerFlag() {
return playerFlag;
}
public void setTarget(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

@ -1,6 +1,6 @@
package com.gmail.artemis.the.gr8.playerstats.statistic.request; package com.gmail.artemis.the.gr8.playerstats.statistic.request;
import com.gmail.artemis.the.gr8.playerstats.api.RequestExecutor; import com.gmail.artemis.the.gr8.playerstats.Main;
import com.gmail.artemis.the.gr8.playerstats.api.RequestGenerator; import com.gmail.artemis.the.gr8.playerstats.api.RequestGenerator;
import com.gmail.artemis.the.gr8.playerstats.statistic.result.StatResult; import com.gmail.artemis.the.gr8.playerstats.statistic.result.StatResult;
import com.gmail.artemis.the.gr8.playerstats.statistic.result.TopStatResult; import com.gmail.artemis.the.gr8.playerstats.statistic.result.TopStatResult;
@ -12,43 +12,42 @@ import org.jetbrains.annotations.NotNull;
import java.util.LinkedHashMap; import java.util.LinkedHashMap;
public final class TopStatRequest implements RequestGenerator<LinkedHashMap<String, Integer>>, RequestExecutor<LinkedHashMap<String, Integer>> { public final class TopStatRequest extends StatRequest<LinkedHashMap<String, Integer>> implements RequestGenerator<LinkedHashMap<String, Integer>> {
private final StatRequest statRequest; private final RequestHandler requestHandler;
private final StatRequestHandler statRequestHandler;
public TopStatRequest(StatRequest request) { public TopStatRequest(RequestSettings request) {
statRequest = request; super(request);
statRequestHandler = new StatRequestHandler(request); requestHandler = new RequestHandler(request);
} }
@Override @Override
public TopStatRequest untyped(@NotNull Statistic statistic) { public StatRequest<LinkedHashMap<String, Integer>> untyped(@NotNull Statistic statistic) {
StatRequest completedRequest = statRequestHandler.untyped(statistic); RequestSettings completedRequest = requestHandler.untyped(statistic);
return new TopStatRequest(completedRequest); return new TopStatRequest(completedRequest);
} }
@Override @Override
public TopStatRequest blockOrItemType(@NotNull Statistic statistic, @NotNull Material material) { public TopStatRequest blockOrItemType(@NotNull Statistic statistic, @NotNull Material material) {
StatRequest completedRequest = statRequestHandler.blockOrItemType(statistic, material); RequestSettings completedRequest = requestHandler.blockOrItemType(statistic, material);
return new TopStatRequest(completedRequest); return new TopStatRequest(completedRequest);
} }
@Override @Override
public TopStatRequest entityType(@NotNull Statistic statistic, @NotNull EntityType entityType) { public TopStatRequest entityType(@NotNull Statistic statistic, @NotNull EntityType entityType) {
StatRequest completedRequest = statRequestHandler.entityType(statistic, entityType); RequestSettings completedRequest = requestHandler.entityType(statistic, entityType);
return new TopStatRequest(completedRequest); return new TopStatRequest(completedRequest);
} }
@Override @Override
public StatResult<LinkedHashMap<String, Integer>> execute() { public StatResult<LinkedHashMap<String, Integer>> execute() {
return getStatResult(statRequest); return getStatResult(super.requestSettings);
} }
private TopStatResult getStatResult(StatRequest completedRequest) { private TopStatResult getStatResult(RequestSettings completedRequest) {
LinkedHashMap<String, Integer> stat = RequestExecutor.getStatCalculator() LinkedHashMap<String, Integer> stat = Main.getStatCalculator()
.getTopStats(completedRequest); .getTopStats(completedRequest);
TextComponent prettyStat = RequestExecutor.getStatFormatter() TextComponent prettyStat = Main.getStatFormatter()
.formatTopStat(completedRequest, stat); .formatTopStat(completedRequest, stat);
return new TopStatResult(stat, prettyStat); return new TopStatResult(stat, prettyStat);

View File

@ -23,7 +23,7 @@ public record InternalStatResult(String executorName, TextComponent formattedVal
} }
@Override @Override
public String toString() { public String getFormattedString() {
return ComponentUtils.getTranslatableComponentSerializer() return ComponentUtils.getTranslatableComponentSerializer()
.serialize(formattedValue); .serialize(formattedValue);
} }

View File

@ -16,7 +16,7 @@ public record PlayerStatResult(int value, TextComponent formattedValue) implemen
} }
@Override @Override
public String toString() { public String getFormattedString() {
return ComponentUtils.getTranslatableComponentSerializer() return ComponentUtils.getTranslatableComponentSerializer()
.serialize(formattedValue); .serialize(formattedValue);
} }

View File

@ -16,7 +16,7 @@ public record ServerStatResult(long value, TextComponent formattedValue) impleme
} }
@Override @Override
public String toString() { public String getFormattedString() {
return ComponentUtils.getTranslatableComponentSerializer() return ComponentUtils.getTranslatableComponentSerializer()
.serialize(formattedValue); .serialize(formattedValue);
} }

View File

@ -33,7 +33,7 @@ import net.kyori.adventure.text.TextComponent;
Information on how to get and use the BukkitAudiences object can be Information on how to get and use the BukkitAudiences object can be
found on <a href="https://docs.adventure.kyori.net/platform/bukkit.html">Adventure's website</a>. found on <a href="https://docs.adventure.kyori.net/platform/bukkit.html">Adventure's website</a>.
<p>You can also use the provided {@link #toString()} method to get the same information <p>You can also use the provided {@link #getFormattedString()} method to get the same information
in String-format. Don't use Adventure's toString methods on the Components in String-format. Don't use Adventure's toString methods on the Components
- those are for debugging purposes. And finally, if you want the results to be - those are for debugging purposes. And finally, if you want the results to be
formatted differently, you can get an instance of the {@link Formatter}. formatted differently, you can get an instance of the {@link Formatter}.
@ -59,5 +59,5 @@ public interface StatResult<T> {
the same style and color settings that are specified in the PlayerStats config, the same style and color settings that are specified in the PlayerStats config,
but it is not translatable (it is always plain English). See class description but it is not translatable (it is always plain English). See class description
for more information.*/ for more information.*/
String toString(); String getFormattedString();
} }

View File

@ -18,7 +18,7 @@ public record TopStatResult(LinkedHashMap<String, Integer> value, TextComponent
} }
@Override @Override
public String toString() { public String getFormattedString() {
return ComponentUtils.getTranslatableComponentSerializer() return ComponentUtils.getTranslatableComponentSerializer()
.serialize(formattedValue); .serialize(formattedValue);
} }