diff --git a/src/main/java/com/gmail/artemis/the/gr8/playerstats/api/PlayerStats.java b/src/main/java/com/gmail/artemis/the/gr8/playerstats/api/PlayerStats.java
index 314d4e2..7c36aca 100644
--- a/src/main/java/com/gmail/artemis/the/gr8/playerstats/api/PlayerStats.java
+++ b/src/main/java/com/gmail/artemis/the/gr8/playerstats/api/PlayerStats.java
@@ -1,34 +1,19 @@
package com.gmail.artemis.the.gr8.playerstats.api;
import com.gmail.artemis.the.gr8.playerstats.Main;
-import net.kyori.adventure.platform.bukkit.BukkitAudiences;
-import net.kyori.adventure.text.*;
-import org.bukkit.Material;
-import org.bukkit.Statistic;
-import org.bukkit.entity.EntityType;
+import com.gmail.artemis.the.gr8.playerstats.enums.Target;
import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.NotNull;
-
/** This is the outgoing API that you can use to access the core functionality of PlayerStats.
- To work with it, you need to call PlayerStats.{@link #getAPI()} to get an instance of {@link PlayerStatsAPI}.
- You can then use this object to access any of the further methods.
+ To work with it, you need to call PlayerStats.{@link #getAPI()} to get an instance of
+ {@link PlayerStatsAPI}. You can then use this object to access any of the further methods.
-
Since calculating a top or server statistics can take some time, it is recommended to call all the
- getServerStat() or getTopStats() methods asynchronously. Otherwise, the main Thread will have
- to wait until all calculations are done, and this might cause some lag spikes on the server.
-
-
The result of the methods in PlayerStats' API are returned in the form of a TextComponent,
- which can be sent directly to a Minecraft client or console with the Adventure library.
- To send a Component, you need to get a {@link BukkitAudiences} object. Normally you would
- have to add the library as a dependency, but since the library is included in PlayerStats, you can
- access it directly. Information on how to get and use the BukkitAudiences object can be found on
- Adventure's website.
-
-
Alternatively, you can also turn your TextComponent into a plain String with
- {@link #statResultComponentToString(TextComponent)}. Don't use Adventure's method .content()
- on your statResult to do this - because of the way the TextComponent is built by PlayerStats,
- you won't be able to get the full content that way.
- a stat-name (example: "mine_block")
- if applicable, a sub-stat-name (example: diorite)(
- a target for this lookup: can be "top", "server", "player" (or "me" to indicate the current CommandSender)
- if "player" was chosen, include a player-name
@param sender the CommandSender that requested this specific statistic + @return the generated StatRequest @throws IllegalArgumentException if the args do not result in a valid statistic look-up*/ StatRequest generateRequest(CommandSender sender, String[] args); - StatRequest generateRequest(@NotNull Target selection, @NotNull Statistic statistic, Material material, EntityType entity, String playerName); + StatRequest createPlayerStatRequest(String playerName, Statistic statistic, Material material, EntityType entity); + + StatRequest createServerStatRequest(Statistic statistic, Material material, EntityType entityType); + + StatRequest createTopStatRequest(Statistic statistic, Material material, EntityType entityType); } diff --git a/src/main/java/com/gmail/artemis/the/gr8/playerstats/api/StatCalculator.java b/src/main/java/com/gmail/artemis/the/gr8/playerstats/api/StatCalculator.java index 93e9b4b..d2aabc4 100644 --- a/src/main/java/com/gmail/artemis/the/gr8/playerstats/api/StatCalculator.java +++ b/src/main/java/com/gmail/artemis/the/gr8/playerstats/api/StatCalculator.java @@ -5,12 +5,16 @@ import com.gmail.artemis.the.gr8.playerstats.models.StatRequest; import java.util.LinkedHashMap; /** The {@link StatCalculator} represents the actual statistic-getting magic that happens once a valid - {@link StatRequest} has been obtained. It takes a valid StatRequest, and returns (a map of) numbers. */ + {@link StatRequest} is passed to it. It takes a valid StatRequest, and returns (a map of) numbers. + For more information on how to create a valid StatRequest, see the class description for {@link StatRequest}.*/ public interface StatCalculator { + /** Returns the requested Statistic*/ int getPlayerStat(StatRequest request); + /** Don't call from main Thread!*/ long getServerStat(StatRequest request); + /** Don't call from main Thread!*/ LinkedHashMapThe Formatter takes a {@link StatRequest} and the result of {@link StatCalculator} calculations, and transforms the
- request object and raw numbers into a pretty message (TextComponent) with all the relevant information in it.
- This output is ready to be sent to a Player or Console, or can be turned into a String representation if necessary.*/
+/** The {@link StatFormatter} formats raw numbers into pretty messages.
+ This Formatter takes a {@link StatRequest} and combines it with the raw number(s)
+ returned by the {@link StatCalculator}, and transforms those into a pretty message
+ (by default a TextComponent) with all the relevant information in it.
+ - a - if applicable, a - a - if "player" was chosen, include a The following is checked:
- The following is checked:
-
+
The output is ready to be sent to a Minecraft client or console with the Adventure library.
+ To send a Component, you need to get a {@link BukkitAudiences} object. Normally you would
+ have to add the library as a dependency, but since the library is included in PlayerStats, you can
+ access it directly. Information on how to get and use the BukkitAudiences object can be found on
+ Adventure's website.
+
+
Alternatively, you can also turn your TextComponent into a plain String with
+ {@link #statResultComponentToString(TextComponent)}. Don't use Adventure's method .content()
+ on your statResult to do this - because of the way the TextComponent is built by PlayerStats,
+ you won't be able to get the full content that way.*/
public interface StatFormatter {
/** Turns a TextComponent into its String representation. If you don't want to work with
Adventure's TextComponents, you can call this method to turn any stat-result into a String.
- @return a String representation of this TextComponent, without hover/click events, but with color, style and formatting */
+ @return a String representation of this TextComponent, without hover/click events,
+ but with color, style and formatting. TranslatableComponents will be turned into
+ plain English.*/
String statResultComponentToString(TextComponent statResult);
+ /** @return a TextComponent with the following parts:
+
[player-name]: [number] [stat-name] {sub-stat-name}*/
TextComponent formatPlayerStat(StatRequest request, int playerStat);
+ /** @return a TextComponent with the following parts:
+
[Total on] [server-name]: [number] [stat-name] [sub-stat-name]*/
TextComponent formatServerStat(StatRequest request, long serverStat);
+ /** @return a TextComponent with the following parts:
+
[PlayerStats] [Top 10] [stat-name] [sub-stat-name]
+
[1.] [player-name] [number]
+
[2.] [player-name] [number]
+
[3.] etc...*/
TextComponent formatTopStat(StatRequest request, LinkedHashMap
- Internally: by PlayerStats itself when /stat is called, using the args provided by the CommandSender.
+
- Externally: through the API methods provided by the {@link RequestGenerator} interface.
+
+
For this StatRequest to be valid, it needs the following values:
+
+
*/
+public class StatRequest {
private final CommandSender sender;
private boolean isAPIRequest;
private Statistic statistic;
private String playerName;
- private Target selection;
+ private Target target;
- private String subStatEntry;
+ private String subStatEntryName;
private EntityType entity;
private Material block;
private Material item;
private boolean playerFlag;
- //make a SimpleStatRequest for a given CommandSender with some default values
+ /** Create a new {@link StatRequest} with default values:
+ statistic
subStatEntryName
needs to be set,
+ together with one of the following values:
+
- for Type.Block: a {@link Material} blockMaterial
+
- for Type.Item: a {@link Material} itemMaterial
+
- for Type.Entity: an {@link EntityType} entityType
+ target
(automatically set for all API-requests)
+ target
is Target.Player, a playerName
needs to be added
+
- CommandSender sender (provided)
+
- Target target
= {@link Target#TOP}
+
- boolean playerFlag
= false
+
- boolean isAPIRequest
= false
+
+ @param sender the CommandSender who prompted this RequestGenerator
+ */
public StatRequest(@NotNull CommandSender sender) {
this(sender, false);
}
+ /** Create a new {@link StatRequest} with default values:
+
- CommandSender sender (provided)
+
- Target target = {@link Target#TOP}
+
- boolean playerFlag = false
+
- boolean isAPIRequest (provided)
+
+ @param sender the CommandSender who prompted this RequestGenerator
+ @param isAPIRequest whether this RequestGenerator is coming through the API or the onCommand
+ */
public StatRequest(@NotNull CommandSender sender, boolean isAPIRequest) {
this.sender = sender;
this.isAPIRequest = isAPIRequest;
- selection = Target.TOP;
+ target = Target.TOP;
playerFlag = false;
}
@@ -54,23 +84,30 @@ public final class StatRequest {
return sender instanceof ConsoleCommandSender;
}
+ /** Set a {@link Statistic} for this StatRequest.*/
public void setStatistic(Statistic statistic) {
this.statistic = statistic;
}
- /** Returns the set enum constant Statistic, or null if none was set. */
+ /** If a {@link Statistic} was set, this will return it.
+
+ @return the statistic
for this RequestGenerator*/
public Statistic getStatistic() {
return statistic;
}
- /** Sets the subStatEntry, and automatically tries to get the corresponding item/block/entity if there is a valid statType present.
- If the subStatEntry is set to null, any present item/block/entity is set to null again. */
- public void setSubStatEntry(String subStatEntry) {
- this.subStatEntry = subStatEntry;
+ /** Sets the subStatEntryName
(a block-, item- or entity-name). */
+ public void setSubStatEntryName(String subStatEntry) {
+ this.subStatEntryName = subStatEntry;
}
- public String getSubStatEntry() {
- return subStatEntry;
+ /** If a {@link Statistic} is set, and this Statistic is of Type Block, Item or Entity,
+ this will return the name of said block, item or entity
+ (in the way .toString would for the given enum constant).
+
+ @return the subStatEntryName
*/
+ public @Nullable String getSubStatEntryName() {
+ return subStatEntryName;
}
public void setPlayerName(String playerName) {
@@ -86,18 +123,24 @@ public final class StatRequest {
this.playerFlag = playerFlag;
}
- /** The "player" arg is a special case, because it could either be a valid subStatEntry, or indicate that the lookup action should target a specific player.
- This is why the playerFlag exists - if this is true, and playerName is null, subStatEntry should be set to "player". */
+ /** For internal use. The "player" arg is a special case, because it could either be
+ a valid subStatEntry
, or indicate that the lookup action should target
+ a specific player. This is why the playerFlag
exists - if this flag true,
+ and playerName
is null, the subStatEntry
should be set to "player". */
public boolean getPlayerFlag() {
return playerFlag;
}
- public void setSelection(Target selection) {
- this.selection = selection;
+ public void setTarget(Target target) {
+ this.target = target;
}
- public @NotNull Target getSelection() {
- return selection;
+ /** Returns the {@link Target} for this StatRequest.
+ If no Target is explicitly set, this will return {@link Target#TOP}.
+ All static factory methods that create a {@link StatRequest} set the
+ appropriate Target for themselves, so there is no need to manually set the Target.*/
+ public @NotNull Target getTarget() {
+ return target;
}
public void setEntity(EntityType entity) {
diff --git a/src/main/java/com/gmail/artemis/the/gr8/playerstats/msg/MessageBuilder.java b/src/main/java/com/gmail/artemis/the/gr8/playerstats/msg/MessageBuilder.java
index 4462a6d..fe30fb2 100644
--- a/src/main/java/com/gmail/artemis/the/gr8/playerstats/msg/MessageBuilder.java
+++ b/src/main/java/com/gmail/artemis/the/gr8/playerstats/msg/MessageBuilder.java
@@ -177,7 +177,7 @@ public class MessageBuilder {
.append(getStatNumberComponent(request.getStatistic(), stat, Target.PLAYER, request.isConsoleSender()))
.append(space())
.append(getStatNameComponent(request))
- .append(getStatUnitComponent(request.getStatistic(), request.getSelection(), request.isConsoleSender())) //space is provided by statUnitComponent
+ .append(getStatUnitComponent(request.getStatistic(), request.getTarget(), request.isConsoleSender())) //space is provided by statUnitComponent
.build();
return getFormattingFunction(playerStat, Target.PLAYER);
@@ -197,7 +197,7 @@ public class MessageBuilder {
.append(getStatNumberComponent(request.getStatistic(), stat, Target.SERVER, request.isConsoleSender()))
.append(space())
.append(getStatNameComponent(request))
- .append(getStatUnitComponent(request.getStatistic(), request.getSelection(), request.isConsoleSender())) //space is provided by statUnit
+ .append(getStatUnitComponent(request.getStatistic(), request.getTarget(), request.isConsoleSender())) //space is provided by statUnit
.build();
return getFormattingFunction(serverStat, Target.SERVER);
@@ -308,7 +308,7 @@ public class MessageBuilder {
.append(componentFactory.title(config.getTopStatsTitle(), Target.TOP)).append(space())
.append(componentFactory.titleNumber(statListSize)).append(space())
.append(getStatNameComponent(request)) //space is provided by statUnitComponent
- .append(getStatUnitComponent(request.getStatistic(), request.getSelection(), request.isConsoleSender()))
+ .append(getStatUnitComponent(request.getStatistic(), request.getTarget(), request.isConsoleSender()))
.build();
}
@@ -353,7 +353,7 @@ public class MessageBuilder {
private TextComponent getStatNameComponent(StatRequest request) {
if (config.useTranslatableComponents()) {
String statKey = languageKeyHandler.getStatKey(request.getStatistic());
- String subStatKey = request.getSubStatEntry();
+ String subStatKey = request.getSubStatEntryName();
if (subStatKey != null) {
switch (request.getStatistic().getType()) {
case BLOCK -> subStatKey = languageKeyHandler.getBlockKey(request.getBlock());
@@ -363,13 +363,13 @@ public class MessageBuilder {
}
}
}
- return componentFactory.statAndSubStatNameTranslatable(statKey, subStatKey, request.getSelection());
+ return componentFactory.statAndSubStatNameTranslatable(statKey, subStatKey, request.getTarget());
}
else {
return componentFactory.statAndSubStatName(
StringUtils.prettify(request.getStatistic().toString()),
- StringUtils.prettify(request.getSubStatEntry()),
- request.getSelection());
+ StringUtils.prettify(request.getSubStatEntryName()),
+ request.getTarget());
}
}
diff --git a/src/main/java/com/gmail/artemis/the/gr8/playerstats/reload/ReloadAction.java b/src/main/java/com/gmail/artemis/the/gr8/playerstats/reload/ReloadAction.java
index 03b55c2..784398b 100644
--- a/src/main/java/com/gmail/artemis/the/gr8/playerstats/reload/ReloadAction.java
+++ b/src/main/java/com/gmail/artemis/the/gr8/playerstats/reload/ReloadAction.java
@@ -10,7 +10,7 @@ import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.RecursiveAction;
/** The action that is executed when a reload-command is triggered. */
-public final class ReloadAction extends RecursiveAction {
+final class ReloadAction extends RecursiveAction {
private static int threshold;
diff --git a/src/main/java/com/gmail/artemis/the/gr8/playerstats/statistic/RequestManager.java b/src/main/java/com/gmail/artemis/the/gr8/playerstats/statistic/RequestManager.java
index dce94d2..833f0e8 100644
--- a/src/main/java/com/gmail/artemis/the/gr8/playerstats/statistic/RequestManager.java
+++ b/src/main/java/com/gmail/artemis/the/gr8/playerstats/statistic/RequestManager.java
@@ -16,18 +16,31 @@ import org.bukkit.entity.EntityType;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
-public class RequestManager implements RequestGenerator {
+public final class RequestManager extends StatRequest implements RequestGenerator {
private final EnumHandler enumHandler;
private final OfflinePlayerHandler offlinePlayerHandler;
private static OutputManager outputManager;
public RequestManager(EnumHandler enumHandler, OfflinePlayerHandler offlinePlayerHandler, OutputManager outputManager) {
+ super(Bukkit.getConsoleSender());
this.enumHandler = enumHandler;
this.offlinePlayerHandler = offlinePlayerHandler;
RequestManager.outputManager = outputManager;
}
+ /** This will create a {@link StatRequest} 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.
+
+ @param args an Array of args such as a CommandSender would put in Minecraft chat:
+ statName
(example: "mine_block")subStatEntryName
(example: diorite)(target
for this lookup: can be "top", "server", "player" (or "me" to indicate the current CommandSender)playerName
1. Is a Statistic set?
-
2. Is a sub-Statistic needed, and if so, is a corresponding Material/EntityType present?
-
3. If the target is PLAYER, is a valid PlayerName provided?
- @return true if the StatRequest is valid, and false otherwise. */
+
The following is checked:
+
+
+ @param request the StatRequest to check
+ @return true if the StatRequest is valid, and false otherwise.
+ */
public boolean validateRequest(StatRequest request) {
return validateRequestAndSendMessage(request, request.getCommandSender());
}
/** Checks if a given {@link StatRequest} would result in a valid statistic look-up,
and sends a feedback message in the server console if it is invalid.
- statistic
set?
+ subStatEntry
needed, and if so, is a corresponding Material/EntityType present?
+ target
is Player, is a valid playerName
provided?
+
1. Is a Statistic set?
-
2. Is a sub-Statistic needed, and if so, is a corresponding Material/EntityType present?
-
3. If the target is PLAYER, is a valid PlayerName provided?
- @return true if the StatRequest is valid, and false otherwise. */
+
The following is checked:
+
+
+ @param request the StatRequest to check
+ @return true if the StatRequest is valid, and false otherwise.
+ */
public boolean validateAPIRequest(StatRequest request) {
return validateRequestAndSendMessage(request, Bukkit.getConsoleSender());
}
@@ -123,15 +159,15 @@ public class RequestManager implements RequestGenerator {
return false;
}
Statistic.Type type = request.getStatistic().getType();
- if (request.getSubStatEntry() == null && type != Statistic.Type.UNTYPED) {
+ if (request.getSubStatEntryName() == null && type != Statistic.Type.UNTYPED) {
outputManager.sendFeedbackMsgMissingSubStat(sender, type);
return false;
}
else if (!hasMatchingSubStat(request)) {
- outputManager.sendFeedbackMsgWrongSubStat(sender, type, request.getSubStatEntry());
+ outputManager.sendFeedbackMsgWrongSubStat(sender, type, request.getSubStatEntryName());
return false;
}
- else if (request.getSelection() == Target.PLAYER && request.getPlayerName() == null) {
+ else if (request.getTarget() == Target.PLAYER && request.getPlayerName() == null) {
outputManager.sendFeedbackMsg(sender, StandardMessage.MISSING_PLAYER_NAME);
return false;
}
@@ -148,15 +184,15 @@ public class RequestManager implements RequestGenerator {
Statistic.Type type = request.getStatistic().getType();
if (request.getPlayerFlag()) { //unpack the playerFlag
- if (type == Statistic.Type.ENTITY && request.getSubStatEntry() == null) {
- request.setSubStatEntry("player");
+ if (type == Statistic.Type.ENTITY && request.getSubStatEntryName() == null) {
+ request.setSubStatEntryName("player");
}
else {
- request.setSelection(Target.PLAYER);
+ request.setTarget(Target.PLAYER);
}
}
- String subStatEntry = request.getSubStatEntry();
+ String subStatEntry = request.getSubStatEntryName();
switch (type) { //attempt to convert relevant subStatEntries into their corresponding Enum Constant
case BLOCK -> {
Material block = EnumHandler.getBlockEnum(subStatEntry);
@@ -171,7 +207,7 @@ public class RequestManager implements RequestGenerator {
if (item != null) request.setItem(item);
}
case UNTYPED -> { //remove unnecessary subStatEntries
- if (subStatEntry != null) request.setSubStatEntry(null);
+ if (subStatEntry != null) request.setSubStatEntryName(null);
}
}
}
diff --git a/src/main/java/com/gmail/artemis/the/gr8/playerstats/statistic/StatAction.java b/src/main/java/com/gmail/artemis/the/gr8/playerstats/statistic/StatAction.java
index 25b0c13..49adf19 100644
--- a/src/main/java/com/gmail/artemis/the/gr8/playerstats/statistic/StatAction.java
+++ b/src/main/java/com/gmail/artemis/the/gr8/playerstats/statistic/StatAction.java
@@ -12,7 +12,7 @@ import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.RecursiveTask;
/** The action that is executed when a stat-command is triggered. */
-public final class StatAction extends RecursiveTaskstatistic
set?
+ subStatEntry
needed, and if so, is a corresponding Material/EntityType present?
+ target
is Player, is a valid playerName
provided?
+