Reworked all javadoc comments to follow official guidelines (#100)
This commit is contained in:
parent
5eb4a1705c
commit
93b44da8c7
|
@ -3,7 +3,28 @@
|
|||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>io.github.artemis-the-gr8</groupId>
|
||||
<artifactId>PlayerStats</artifactId>
|
||||
<version>1.6.1</version>
|
||||
<name>PlayerStats</name>
|
||||
<version>1.7</version>
|
||||
<description>Statistics Plugin</description>
|
||||
<url>https://www.spigotmc.org/resources/playerstats.102347/</url>
|
||||
<developers>
|
||||
<developer>
|
||||
<name>Artemis</name>
|
||||
<email>artemis.the.gr8@gmail.com</email>
|
||||
<url>https://github.com/Artemis-the-gr8</url>
|
||||
</developer>
|
||||
</developers>
|
||||
<licenses>
|
||||
<license>
|
||||
<name>MIT License</name>
|
||||
<url>http://www.opensource.org/licenses/mit-license.php</url>
|
||||
</license>
|
||||
</licenses>
|
||||
<scm>
|
||||
<connection>scm:git:git://github.com/itHotL/PlayerStats.git</connection>
|
||||
<developerConnection>scm:git:git://github.com/itHotL/PlayerStats.git</developerConnection>
|
||||
<url>https://github.com/itHotL/PlayerStats/tree/main</url>
|
||||
</scm>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
|
@ -92,6 +113,18 @@
|
|||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<artifactId>maven-javadoc-plugin</artifactId>
|
||||
<version>3.2.0</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>attach-javadocs</id>
|
||||
<goals>
|
||||
<goal>jar</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
<repositories>
|
||||
|
|
2
pom.xml
2
pom.xml
|
@ -6,7 +6,7 @@
|
|||
|
||||
<groupId>io.github.artemis-the-gr8</groupId>
|
||||
<artifactId>PlayerStats</artifactId>
|
||||
<version>1.6.1</version>
|
||||
<version>1.7</version>
|
||||
|
||||
<name>PlayerStats</name>
|
||||
<description>Statistics Plugin</description>
|
||||
|
|
|
@ -77,10 +77,6 @@ public final class Main extends JavaPlugin {
|
|||
this.getLogger().info("Disabled PlayerStats!");
|
||||
}
|
||||
|
||||
public static @NotNull Main getInstance() {
|
||||
return instance;
|
||||
}
|
||||
|
||||
public static @NotNull BukkitAudiences getAdventure() throws IllegalStateException {
|
||||
if (adventure == null) {
|
||||
throw new IllegalStateException("Tried to access Adventure without PlayerStats being enabled!");
|
||||
|
@ -104,7 +100,7 @@ public final class Main extends JavaPlugin {
|
|||
|
||||
public static @NotNull LanguageKeyHandler getLanguageKeyHandler() {
|
||||
if (languageKeyHandler == null) {
|
||||
languageKeyHandler = new LanguageKeyHandler();
|
||||
languageKeyHandler = new LanguageKeyHandler(instance);
|
||||
}
|
||||
return languageKeyHandler;
|
||||
}
|
||||
|
@ -143,7 +139,7 @@ public final class Main extends JavaPlugin {
|
|||
|
||||
config = new ConfigHandler(this);
|
||||
enumHandler = new EnumHandler();
|
||||
languageKeyHandler = new LanguageKeyHandler();
|
||||
languageKeyHandler = new LanguageKeyHandler(instance);
|
||||
offlinePlayerHandler = new OfflinePlayerHandler();
|
||||
|
||||
shareManager = new ShareManager(config);
|
||||
|
@ -159,7 +155,7 @@ public final class Main extends JavaPlugin {
|
|||
new BukkitRunnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
final Metrics metrics = new Metrics(getInstance(), 15923);
|
||||
final Metrics metrics = new Metrics(instance, 15923);
|
||||
final boolean placeholderExpansionActive;
|
||||
if (Bukkit.getPluginManager().isPluginEnabled("PlaceholderAPI")) {
|
||||
PlaceholderExpansion expansion = PlaceholderAPIPlugin
|
||||
|
|
|
@ -18,8 +18,12 @@ import java.util.concurrent.atomic.AtomicInteger;
|
|||
|
||||
import static java.time.temporal.ChronoUnit.SECONDS;
|
||||
|
||||
/** The manager of all Player-prompted statistic-sharing. If sharing is enabled, this class will save the
|
||||
results of past stat-lookups, so the results can be retrieved and shared when a Player clicks the share-button.*/
|
||||
/**
|
||||
* The manager of all Player-prompted statistic-sharing.
|
||||
* If sharing is enabled, this class will save the results
|
||||
* of past stat-lookups, so the results can be retrieved
|
||||
* and shared when a Player clicks the share-button.
|
||||
*/
|
||||
public final class ShareManager {
|
||||
|
||||
private static boolean isEnabled;
|
||||
|
@ -92,10 +96,13 @@ public final class ShareManager {
|
|||
return sharedResults.contains(shareCode);
|
||||
}
|
||||
|
||||
/** Takes a formattedComponent from the internal ConcurrentHashmap,
|
||||
puts the current time in the shareTimeStamp (ConcurrentHashMap),
|
||||
puts the shareCode (int hashCode) in the sharedResults (ArrayBlockingQueue),
|
||||
and returns the formattedComponent. If no formattedComponent was found, returns null.*/
|
||||
/**
|
||||
* Takes a formattedComponent from the internal ConcurrentHashmap,
|
||||
* puts the current time in the shareTimeStamp (ConcurrentHashMap),
|
||||
* puts the shareCode (int hashCode) in the sharedResults (ArrayBlockingQueue),
|
||||
* and returns the formattedComponent. If no formattedComponent was found,
|
||||
* returns null.
|
||||
*/
|
||||
public @Nullable InternalStatResult getStatResult(String playerName, int shareCode) {
|
||||
if (statResultQueue.containsKey(shareCode)) {
|
||||
shareTimeStamp.put(playerName, Instant.now());
|
||||
|
@ -122,8 +129,10 @@ public final class ShareManager {
|
|||
}
|
||||
}
|
||||
|
||||
/** If the given player already has more than x (in this case 25) StatResults saved,
|
||||
remove the oldest one.*/
|
||||
/**
|
||||
* If the given player already has more than x (in this case 25)
|
||||
* StatResults saved, remove the oldest one.
|
||||
*/
|
||||
private void removeExcessResults(String playerName) {
|
||||
List<InternalStatResult> alreadySavedResults = statResultQueue.values()
|
||||
.parallelStream()
|
||||
|
|
|
@ -12,11 +12,15 @@ import org.bukkit.command.CommandSender;
|
|||
|
||||
import java.util.HashMap;
|
||||
|
||||
/** The ThreadManager is in charge of the Threads that PlayerStats can utilize.
|
||||
It keeps track of past and currently active Threads, to ensure a Player cannot
|
||||
start multiple Threads at the same time (thereby limiting them to one stat-lookup at a time).
|
||||
It also passes appropriate references along to the {@link StatThread} or {@link ReloadThread},
|
||||
to ensure those will never run at the same time. */
|
||||
/**
|
||||
* The ThreadManager is in charge of the Threads that PlayerStats
|
||||
* can utilize. It keeps track of past and currently active Threads,
|
||||
* to ensure a Player cannot start multiple Threads at the same time
|
||||
* (thereby limiting them to one stat-lookup at a time). It also
|
||||
* passes appropriate references along to the {@link StatThread}
|
||||
* or {@link ReloadThread}, to ensure those will never run at the
|
||||
* same time.
|
||||
*/
|
||||
public final class ThreadManager {
|
||||
|
||||
private final static int threshold = 10;
|
||||
|
@ -77,14 +81,18 @@ public final class ThreadManager {
|
|||
}
|
||||
}
|
||||
|
||||
/** Store the duration in milliseconds of the last top-stat-lookup
|
||||
(or of loading the offline-player-list if no look-ups have been done yet). */
|
||||
/**
|
||||
* Store the duration in milliseconds of the last top-stat-lookup
|
||||
* (or of loading the offline-player-list if no look-ups have been done yet).
|
||||
*/
|
||||
public static void recordCalcTime(long time) {
|
||||
lastRecordedCalcTime = time;
|
||||
}
|
||||
|
||||
/** Returns the duration in milliseconds of the last top-stat-lookup
|
||||
(or of loading the offline-player-list if no look-ups have been done yet). */
|
||||
/**
|
||||
* Returns the duration in milliseconds of the last top-stat-lookup
|
||||
* (or of loading the offline-player-list if no look-ups have been done yet).
|
||||
*/
|
||||
public static long getLastRecordedCalcTime() {
|
||||
return lastRecordedCalcTime;
|
||||
}
|
||||
|
|
|
@ -8,142 +8,243 @@ import net.kyori.adventure.text.TextComponent;
|
|||
import org.bukkit.Statistic;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/** Formats messages meant for usage outside PlayerStats. For more information about
|
||||
the default formatting PlayerStats uses, see the class description of {@link StatResult}.*/
|
||||
/**
|
||||
* Formats messages meant for usage outside PlayerStats. For more information
|
||||
* about the default formatting PlayerStats uses, see the class description of
|
||||
* StatResult.
|
||||
|
||||
* @see StatResult
|
||||
*/
|
||||
public interface ApiFormatter {
|
||||
|
||||
/** Turns a TextComponent into its String representation. This method is equipped
|
||||
to turn all PlayerStats' formatted statResults into String.
|
||||
/**
|
||||
* Turns a TextComponent into its String representation. This method is equipped
|
||||
* to turn all PlayerStats' formatted statResults into String.
|
||||
|
||||
@return a String representation of this TextComponent, without hover/click events,
|
||||
but with color, style and formatting. TranslatableComponents will be turned into
|
||||
plain English.*/
|
||||
* @param component the Component to turn into String
|
||||
* @return a String representation of this TextComponent, without hover/click events,
|
||||
* but with color, style and formatting. TranslatableComponents will be turned into
|
||||
* plain English.
|
||||
*/
|
||||
default String TextComponentToString(TextComponent component) {
|
||||
return ComponentUtils.getTranslatableComponentSerializer()
|
||||
.serialize(component);
|
||||
}
|
||||
|
||||
/** Gets a {@link NumberFormatter} to format raw numbers into something more readable.*/
|
||||
/**
|
||||
* Gets a {@link NumberFormatter} to format raw numbers into something more readable.
|
||||
|
||||
* @return the <code>NumberFormatter</code>
|
||||
*/
|
||||
default NumberFormatter getNumberFormatter() {
|
||||
return new NumberFormatter();
|
||||
}
|
||||
|
||||
/** Gets the default prefix PlayerStats uses.
|
||||
@return [PlayerStats]*/
|
||||
/**
|
||||
* Gets the default prefix PlayerStats uses.
|
||||
* @return [PlayerStats]
|
||||
*/
|
||||
TextComponent getPluginPrefix();
|
||||
|
||||
/** Gets the special rainbow version of PlayerStats' prefix.
|
||||
@return [PlayerStats] in rainbow colors*/
|
||||
/**
|
||||
* Gets the special rainbow version of PlayerStats' prefix.
|
||||
* @return [PlayerStats] in rainbow color
|
||||
* s*/
|
||||
TextComponent getRainbowPluginPrefix();
|
||||
|
||||
/** Gets the version of the prefix that is surrounded by underscores. This is
|
||||
meant to be used as a title above a message or statistic display.
|
||||
@return ________ [PlayerStats] ________ */
|
||||
/**
|
||||
* Gets the version of the prefix that is surrounded by underscores.
|
||||
* This is meant to be used as a title above a message or statistic display.
|
||||
* @return ________ [PlayerStats] ________
|
||||
*/
|
||||
TextComponent getPluginPrefixAsTitle();
|
||||
|
||||
/** Gets the special rainbow version of the title-prefix.
|
||||
@return ________ [PlayerStats] ________ in rainbow colors*/
|
||||
/**
|
||||
* Gets the special rainbow version of the title-prefix.
|
||||
|
||||
* @return ________ [PlayerStats] ________ in rainbow colors
|
||||
*/
|
||||
TextComponent getRainbowPluginPrefixAsTitle();
|
||||
|
||||
/** Gets a formatted message that displays the name of this Statistic as it is
|
||||
displayed by PlayerStats. If this Statistic is not of Type.Untyped,
|
||||
include the name of the relevant sub-statistic (block, item or entity).
|
||||
@param statistic the Statistic enum constant to display the name of
|
||||
@param subStatName where necessary, the name of the Material or EntityType to include,
|
||||
acquired by doing #toString() on the Material/EntityType in question
|
||||
@return [stat-name] [sub-stat-name]*/
|
||||
/**
|
||||
* Gets a formatted message that displays the name of this Statistic as it is
|
||||
* displayed by PlayerStats. If this Statistic is not of Type.Untyped,
|
||||
* include the name of the relevant sub-statistic (block, item or entity).
|
||||
|
||||
* @param statistic the Statistic enum constant to display the name of
|
||||
* @param subStatName where necessary, the name of the Material or EntityType
|
||||
* to include, acquired by doing #toString() on the Material/EntityType in question
|
||||
* @return [stat-name] [sub-stat-name]
|
||||
*/
|
||||
TextComponent getStatTitle(Statistic statistic, @Nullable String subStatName);
|
||||
|
||||
/** Gets a formatted message that displays the name of this Statistic as it is
|
||||
displayed by PlayerStats in a top-stat-message. If this Statistic is not of Type.Untyped,
|
||||
include the name of the relevant sub-statistic (block, item or entity).
|
||||
@param statistic the Statistic enum constant for this message
|
||||
@param subStatName the name of the Material or EntityType to include,
|
||||
acquired by doing #toString() on the Material/EntityType in question
|
||||
@param topStatSize the size of the top-list this title is for
|
||||
@return Top [topStatSize] [stat-name] [sub-stat-name] */
|
||||
/**
|
||||
* Gets a formatted message that displays the name of this Statistic as it is
|
||||
* displayed by PlayerStats in a top-stat-message. If this Statistic is not
|
||||
* of Type.Untyped, include the name of the relevant sub-statistic
|
||||
* (block, item or entity).
|
||||
|
||||
* @param statistic the Statistic enum constant for this message
|
||||
* @param subStatName the name of the Material or EntityType to include,
|
||||
* acquired by doing #toString() on the Material/EntityType in question
|
||||
* @param topStatSize the size of the top-list this title is for
|
||||
* @return Top [topStatSize] [stat-name] [sub-stat-name]
|
||||
*/
|
||||
TextComponent getTopStatTitle(int topStatSize, Statistic statistic, @Nullable String subStatName);
|
||||
|
||||
/** Formats the input into a single top-statistic line. The stat-number
|
||||
is formatted into the most suitable {@link Unit} based on the provided Statistic.
|
||||
For Type.Time, the resulting formatted number will have one additional smaller
|
||||
Unit, unless <code>formatTopStatLineForTypeTime()</code> is used.
|
||||
@return a single line from a top-x statistic:
|
||||
* <br> [positionInTopList]. [player-name] ......... [stat-number] */
|
||||
/**
|
||||
* Formats the input into a single top-statistic line. The stat-number
|
||||
* is formatted into the most suitable {@link Unit} based on the provided
|
||||
* Statistic. For Type.Time, the resulting formatted number will have as
|
||||
* many additional smaller units as are specified in the config,
|
||||
* unless <code>formatTopStatLineForTypeTime()</code> is used.
|
||||
|
||||
* @param positionInTopList the rank-number in this list of the Player
|
||||
* @param playerName the name of the Player on this line
|
||||
* @param statNumber the result of Player#getStatistic()
|
||||
* @param statistic the Statistic enum constant for this message
|
||||
* @return a single line from a top-x statistic:
|
||||
* <br> [positionInTopList]. [player-name] ......... [stat-number]
|
||||
*/
|
||||
TextComponent formatTopStatLine(int positionInTopList, String playerName, long statNumber, Statistic statistic);
|
||||
|
||||
/** Formats the input into a single top-statistic line. The stat-number is formatted
|
||||
into the provided {@link Unit}. For Type.Time, the resulting formatted number
|
||||
will have one additional smaller Unit, unless <code>formatTopStatLineForTypeTime()</code>
|
||||
is used.
|
||||
@return a single line from a top-x statistic:
|
||||
* <br> [positionInTopList]. [player-name] ......... [stat-number] */
|
||||
/**
|
||||
* Formats the input into a single top-statistic line. The stat-number
|
||||
* is formatted into the provided {@link Unit}. For Type.Time, the
|
||||
* resulting formatted number will have as many additional smaller
|
||||
* units as are specified in the config, unless
|
||||
* <code>formatTopStatLineForTypeTime()</code> is used.
|
||||
|
||||
* @param positionInTopList the rank-number in this list of the Player
|
||||
* @param playerName the name of the Player on this line
|
||||
* @param statNumber the result of Player#getStatistic()
|
||||
* @param unit the Unit to format the <code>statNumber</code> with
|
||||
* @return a single line from a top-x statistic:
|
||||
* <br> [positionInTopList]. [player-name] ......... [stat-number]
|
||||
* */
|
||||
TextComponent formatTopStatLine(int positionInTopList, String playerName, long statNumber, Unit unit);
|
||||
|
||||
/** Formats the input into a single top-statistic line for a time-based statistic with the Unit-range
|
||||
that is between <code>bigUnit</code> and <code>smallUnit</code> (both inclusive).
|
||||
@param bigUnit the biggest Unit to use of {@link Unit.Type#TIME}
|
||||
@param smallUnit the smallest Unit to use of {@link Unit.Type#TIME}
|
||||
@return a single line from a stop-x statistic:
|
||||
<br>[positionInTopList]. [player-name] ......... [1D 2H 3M 4S]*/
|
||||
TextComponent formatTopStatLineForTypeTime(int positionInList, String playerName, long statNumber, Unit bigUnit, Unit smallUnit);
|
||||
/**
|
||||
* Formats the input into a single top-statistic line for a time-based
|
||||
* statistic with the Unit-range that is between <code>bigUnit</code>
|
||||
* and <code>smallUnit</code> (both inclusive).
|
||||
|
||||
/** Formats the input into a server statistic message. The stat-number
|
||||
is formatted into the most suitable {@link Unit} based on the provided Statistic.
|
||||
For Type.Time, the resulting formatted number will have one additional smaller
|
||||
Unit, unless <code>formatServerStatForTypeTime()</code> is used.
|
||||
@return [Total on this server]: [stat-number] [stat-name] */
|
||||
* @param positionInTopList the rank-number in this list of the Player
|
||||
* @param playerName the name of the Player on this line
|
||||
* @param statNumber the result of Player#getStatistic()
|
||||
* @param bigUnit the biggest Unit to use of {@link Unit.Type#TIME}
|
||||
* @param smallUnit the smallest Unit to use of {@link Unit.Type#TIME}
|
||||
* @return a single line from a stop-x statistic:
|
||||
* <br>[positionInTopList]. [player-name] ......... [1D 2H 3M 4S]
|
||||
*/
|
||||
TextComponent formatTopStatLineForTypeTime(int positionInTopList, String playerName, long statNumber, Unit bigUnit, Unit smallUnit);
|
||||
|
||||
/**
|
||||
* Formats the input into a server statistic message. The stat-number
|
||||
* is formatted into the most suitable {@link Unit} based on the provided
|
||||
* Statistic. For Type.Time, the resulting formatted number will have as
|
||||
* many additional smaller units as are specified in the config,
|
||||
* unless <code>formatServerStatForTypeTime()</code> is used.
|
||||
|
||||
* @param statNumber the result of all Player#getStatistic() values combined
|
||||
* @param statistic te Statistic enum constant for this message
|
||||
* @return [Total on this server]: [stat-number] [stat-name]
|
||||
*/
|
||||
TextComponent formatServerStat(long statNumber, Statistic statistic);
|
||||
|
||||
/** Formats the input into a server statistic message for a statistic that has a
|
||||
sub-statistic (block, item or entity).
|
||||
@param statistic the Statistic enum constant for this message
|
||||
@param statNumber the result of the statistic-lookup
|
||||
@param subStatName the name of the Material or EntityType of this statistic-lookup,
|
||||
acquired by doing #toString() on the Material/EntityType in question
|
||||
@return [Total on this server]: [stat-number] [stat-name] [sub-stat-name]*/
|
||||
/**
|
||||
* Formats the input into a server statistic message for a statistic
|
||||
* that has a sub-statistic (block, item or entity).
|
||||
|
||||
* @param statistic the Statistic enum constant for this message
|
||||
* @param statNumber the result of all Player#getStatistic() values combined
|
||||
* @param subStatName the name of the Material or EntityType of this
|
||||
* statistic-lookup, acquired by doing #toString() on the Material/
|
||||
* EntityType in question
|
||||
* @return [Total on this server]: [stat-number] [stat-name] [sub-stat-name]
|
||||
*/
|
||||
TextComponent formatServerStat(long statNumber, Statistic statistic, String subStatName);
|
||||
|
||||
/** Formats the input into a server statistic message with the specified {@link Unit}.
|
||||
The stat-number is formatted into the most suitable {@link Unit} based on the provided Statistic.
|
||||
For Type.Time, the resulting formatted number will have one additional smaller Unit,
|
||||
unless <code>formatServerStatForTypeTime()</code> is used.
|
||||
@return [Total on this server]: [stat-number] [stat-name] [unit-name]*/
|
||||
/**
|
||||
* Formats the input into a server statistic message with the specified
|
||||
* {@link Unit}. The stat-number is formatted into the most suitable
|
||||
* {@link Unit} based on the provided Statistic. For Type.Time, the
|
||||
* resulting formatted number will have as many additional smaller
|
||||
* units as are specified in the config, unless
|
||||
* <code>formatServerStatForTypeTime()</code> is used.
|
||||
|
||||
* @param statistic the Statistic enum constant for this message
|
||||
* @param statNumber the result of all Player#getStatistic() values combined
|
||||
* @param unit the Unit to use to format te <code>statNumber</code>
|
||||
* @return [Total on this server]: [stat-number] [stat-name] [unit-name]
|
||||
*/
|
||||
TextComponent formatServerStat(long statNumber, Statistic statistic, Unit unit);
|
||||
|
||||
/** Formats the input into a server statistic message for a time-based statistic with the Unit-range
|
||||
that is between <code>bigUnit</code> and <code>smallUnit</code> (both inclusive).
|
||||
@param bigUnit the biggest Unit to use of {@link Unit.Type#TIME}
|
||||
@param smallUnit the smallest Unit to use of {@link Unit.Type#TIME}
|
||||
@return [Total on this server]: [1D 2H 3M 4S] [stat-name] */
|
||||
/**
|
||||
* Formats the input into a server statistic message for a time-based
|
||||
* statistic with the Unit-range that is between <code>bigUnit</code>
|
||||
* and <code>smallUnit</code> (both inclusive).
|
||||
|
||||
* @param statistic the Statistic enum constant for this message
|
||||
* @param statNumber the result of all Player#getStatistic() values combined
|
||||
* @param bigUnit the biggest Unit to use of {@link Unit.Type#TIME}
|
||||
* @param smallUnit the smallest Unit to use of {@link Unit.Type#TIME}
|
||||
* @return [Total on this server]: [1D 2H 3M 4S] [stat-name]
|
||||
*/
|
||||
TextComponent formatServerStatForTypeTime(long statNumber, Statistic statistic, Unit bigUnit, Unit smallUnit);
|
||||
|
||||
/** Formats the input into a player statistic message. For Unit.Type.Time,
|
||||
the resulting formatted number will have one additional smaller Unit,
|
||||
unless <code>formatPlayerStatForTypeTime</code> is used.
|
||||
@return [player-name]: [stat-number] [stat-name]*/
|
||||
/**
|
||||
* Formats the input into a player statistic message. For Unit.Type.Time,
|
||||
* the resulting formatted number will have as many additional smaller
|
||||
* units as are specified in the config, unless
|
||||
* <code>formatPlayerStatForTypeTime</code> is used.
|
||||
|
||||
* @param playerName the name of the Player
|
||||
* @param statistic the Statistic enum constant for this message
|
||||
* @param statNumber the result of Player#getStatistic()
|
||||
* @return [player-name]: [stat-number] [stat-name]
|
||||
*/
|
||||
TextComponent formatPlayerStat(String playerName, int statNumber, Statistic statistic);
|
||||
|
||||
/** Formats the input into a player statistic message for a statistic that has a sub-statistic (block, item
|
||||
or entity).
|
||||
@param playerName the name of the Player
|
||||
@param statistic the Statistic enum constant
|
||||
@param statNumber the result of Player#getStatistic()
|
||||
@param subStatName the name of the Material or EntityType of this statistic-lookup,
|
||||
acquired by doing #toString() on the Material/EntityType in question
|
||||
@return [player-name]: [stat-number] [stat-name] [sub-stat-name]*/
|
||||
/**
|
||||
* Formats the input into a player statistic message for a statistic
|
||||
* that has a sub-statistic (block, item or entity).
|
||||
|
||||
* @param playerName the name of the Player
|
||||
* @param statistic the Statistic enum constant for this message
|
||||
* @param statNumber the result of Player#getStatistic()
|
||||
* @param subStatName the name of the Material or EntityType of
|
||||
* this statistic-lookup, acquired by doing #toString() on the
|
||||
* Material/EntityType in question
|
||||
* @return [player-name]: [stat-number] [stat-name] [sub-stat-name]
|
||||
*/
|
||||
TextComponent formatPlayerStat(String playerName, int statNumber, Statistic statistic, String subStatName);
|
||||
|
||||
/** Formats the input into a player statistic message with the specified {@link Unit}.
|
||||
For Unit.Type.Time, the resulting formatted number will have one additional smaller Unit,
|
||||
unless <code>formatPlayerStatForTypeTime</code> is used.
|
||||
@return [player-name]: [stat-number] [stat-name] [stat-unit] */
|
||||
/**
|
||||
* Formats the input into a player statistic message with the specified
|
||||
* {@link Unit}. For Unit.Type.Time, the resulting formatted number will
|
||||
* have as many additional smaller units as are specified in the config,
|
||||
* unless <code>formatPlayerStatForTypeTime</code> is used.
|
||||
|
||||
* @param playerName the name of the Player
|
||||
* @param statistic the Statistic enum constant for this message
|
||||
* @param statNumber the result of Player#getStatistic()
|
||||
* @param unit the Unit to use when formatting the <code>statNumber</code>
|
||||
* @return [player-name]: [stat-number] [stat-name] [stat-unit]
|
||||
*/
|
||||
TextComponent formatPlayerStat(String playerName, int statNumber, Statistic statistic, Unit unit);
|
||||
|
||||
/** Formats the input into a player statistic message for a time-based statistic with the Unit-range
|
||||
that is between <code>bigUnit</code> and <code>smallUnit</code> (both inclusive).
|
||||
@param bigUnit the biggest Unit to use of {@link Unit.Type#TIME}
|
||||
@param smallUnit the smallest Unit to use of {@link Unit.Type#TIME}
|
||||
@return [player-name]: [1D 2H 3M 4S] [stat-name]*/
|
||||
/**
|
||||
* Formats the input into a player statistic message for a time-based
|
||||
* statistic with the Unit-range that is between <code>bigUnit</code>
|
||||
* and <code>smallUnit</code> (both inclusive).
|
||||
|
||||
* @param playerName the name of the Player
|
||||
* @param statNumber the result of Player#getStatistic()
|
||||
* @param statistic the Statistic enum constant for this message
|
||||
* @param bigUnit the biggest Unit to use of {@link Unit.Type#TIME}
|
||||
* @param smallUnit the smallest Unit to use of {@link Unit.Type#TIME}
|
||||
* @return [player-name]: [1D 2H 3M 4S] [stat-name]
|
||||
*/
|
||||
TextComponent formatPlayerStatForTypeTime(String playerName, int statNumber, Statistic statistic, Unit bigUnit, Unit smallUnit);
|
||||
}
|
|
@ -6,20 +6,20 @@ import org.jetbrains.annotations.Contract;
|
|||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/** The outgoing API that you can use to access the core functionality of PlayerStats!
|
||||
To work with the API, 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.
|
||||
<br>
|
||||
<br>Since calculating a top or server statistics can take some time, I strongly
|
||||
encourage you to call {@link StatRequest#execute()} asynchronously.
|
||||
Otherwise, the main Thread will have to wait until all calculations are done,
|
||||
and this can severely impact server performance.
|
||||
* To work with the API, 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.
|
||||
* <br>
|
||||
* <br>Since calculating a top or server statistics can take some time, I strongly
|
||||
* encourage you to call {@link StatRequest#execute()} asynchronously.
|
||||
* Otherwise, the main Thread will have to wait until all calculations are done,
|
||||
* and this can severely impact server performance.
|
||||
*/
|
||||
public interface PlayerStats {
|
||||
|
||||
/** Gets an instance of the {@link PlayerStatsAPI}.
|
||||
|
||||
@return the PlayerStats API
|
||||
@throws IllegalStateException if PlayerStats is not loaded on the server when this method is called*/
|
||||
* @return the PlayerStats API
|
||||
* @throws IllegalStateException if PlayerStats is not loaded on the server when this method is called*/
|
||||
@Contract(pure = true)
|
||||
static @NotNull PlayerStats getAPI() throws IllegalStateException {
|
||||
return Main.getPlayerStatsAPI();
|
||||
|
|
|
@ -8,33 +8,33 @@ import org.bukkit.entity.EntityType;
|
|||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/** 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 StatCalculator}
|
||||
to get the desired statistic data.*/
|
||||
* the information PlayerStats needs to work with, and is used by the {@link StatCalculator}
|
||||
* to get the desired statistic data.*/
|
||||
public interface RequestGenerator<T> {
|
||||
|
||||
/** Gets an executable Request object for a Statistic of Statistic.Type {@code Untyped}.
|
||||
|
||||
@param statistic a Statistic of Type.Untyped
|
||||
@return a {@link StatRequest}
|
||||
@throws IllegalArgumentException if <code>statistic</code> is not of Type.Untyped*/
|
||||
* @param statistic a Statistic of Type.Untyped
|
||||
* @return a {@link StatRequest}
|
||||
* @throws IllegalArgumentException if <code>statistic</code> is not of Type.Untyped*/
|
||||
StatRequest<T> untyped(@NotNull Statistic statistic) throws IllegalArgumentException;
|
||||
|
||||
/** 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 material a block if the <code>statistic</code> is of Type.Block,
|
||||
and an item if the <code>statistic</code> is of Type.Item
|
||||
@return a {@link StatRequest}
|
||||
@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 an item as <code>material</code>) */
|
||||
* @param statistic a Statistic of Type.Block or Type.Item
|
||||
* @param material a block if the <code>statistic</code> is of Type.Block,
|
||||
* and an item if the <code>statistic</code> is of Type.Item
|
||||
* @return a {@link StatRequest}
|
||||
* @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 an item as <code>material</code>) */
|
||||
StatRequest<T> blockOrItemType(@NotNull Statistic statistic, @NotNull Material material) throws IllegalArgumentException;
|
||||
|
||||
/** Gets an executable Request object for a Statistic of Statistic.Type Entity.
|
||||
|
||||
@param statistic a Statistic of Type.Entity
|
||||
@param entityType an EntityType
|
||||
@return a {@link StatRequest}
|
||||
@throws IllegalArgumentException if <code>statistic</code> is not of Type.Entity*/
|
||||
* @param statistic a Statistic of Type.Entity
|
||||
* @param entityType an EntityType
|
||||
* @return a {@link StatRequest}
|
||||
* @throws IllegalArgumentException if <code>statistic</code> is not of Type.Entity*/
|
||||
StatRequest<T> entityType(@NotNull Statistic statistic, @NotNull EntityType entityType) throws IllegalArgumentException;
|
||||
}
|
|
@ -5,34 +5,33 @@ import java.util.LinkedHashMap;
|
|||
public interface StatManager {
|
||||
|
||||
/** Gets a RequestGenerator that can be used to create a PlayerStatRequest.
|
||||
This RequestGenerator will make sure all default settings
|
||||
for a player-statistic-lookup are configured.
|
||||
|
||||
@param playerName the player whose statistic is being requested
|
||||
@return the RequestGenerator */
|
||||
* This RequestGenerator will make sure all default settings
|
||||
* for a player-statistic-lookup are configured.
|
||||
*
|
||||
* @param playerName the player whose statistic is being requested
|
||||
* @return the RequestGenerator */
|
||||
RequestGenerator<Integer> playerStatRequest(String playerName);
|
||||
|
||||
/** Gets a RequestGenerator that can be used to create a ServerStatRequest.
|
||||
This RequestGenerator will make sure all default settings
|
||||
for a server-statistic-lookup are configured.
|
||||
|
||||
@return the RequestGenerator*/
|
||||
* This RequestGenerator will make sure all default settings
|
||||
* for a server-statistic-lookup are configured.
|
||||
*
|
||||
* @return the RequestGenerator*/
|
||||
RequestGenerator<Long> serverStatRequest();
|
||||
|
||||
/** Gets a RequestGenerator that can be used to create a TopStatRequest
|
||||
for a top-list of the specified size. This RequestGenerator will
|
||||
make sure all default settings for a top-statistic-lookup are configured.
|
||||
|
||||
@param topListSize how big the top-x should be (10 by default)
|
||||
@return the RequestGenerator*/
|
||||
* for a top-list of the specified size. This RequestGenerator will
|
||||
* make sure all default settings for a top-statistic-lookup are configured.
|
||||
*
|
||||
* @param topListSize how big the top-x should be (10 by default)
|
||||
* @return the RequestGenerator*/
|
||||
RequestGenerator<LinkedHashMap<String, Integer>> topStatRequest(int topListSize);
|
||||
|
||||
/** Gets a RequestGenerator that can be used to create a TopStatRequest
|
||||
for all offline players on the server (those that are included by
|
||||
PlayerStats' settings). This RequestGenerator will make sure
|
||||
all default settings for a top-statistic-lookup are configured.
|
||||
|
||||
|
||||
@return the RequestGenerator*/
|
||||
* for all offline players on the server (those that are included by
|
||||
* PlayerStats' settings). This RequestGenerator will make sure
|
||||
* all default settings for a top-statistic-lookup are configured.
|
||||
*
|
||||
* @return the RequestGenerator*/
|
||||
RequestGenerator<LinkedHashMap<String, Integer>> totalTopStatRequest();
|
||||
}
|
||||
|
|
|
@ -46,15 +46,17 @@ public final class StatCommand implements CommandExecutor {
|
|||
return true;
|
||||
}
|
||||
|
||||
/** 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.
|
||||
<br> The following is checked:
|
||||
<ul>
|
||||
<li>Is a <code>statistic</code> set?
|
||||
<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?
|
||||
</ul>
|
||||
@param requestSettings the RequestSettings to give feedback on
|
||||
/**
|
||||
* 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.
|
||||
* <br> The following is checked:
|
||||
* <ul>
|
||||
* <li>Is a <code>statistic</code> set?
|
||||
* <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?
|
||||
* </ul>
|
||||
*
|
||||
* @param requestSettings the RequestSettings to give feedback on
|
||||
*/
|
||||
private void sendFeedback(RequestSettings requestSettings) {
|
||||
CommandSender sender = requestSettings.getCommandSender();
|
||||
|
|
|
@ -11,6 +11,7 @@ import org.jetbrains.annotations.Nullable;
|
|||
|
||||
import java.io.File;
|
||||
|
||||
/** Handles all PlayerStats' config-settings. */
|
||||
public final class ConfigHandler {
|
||||
|
||||
private static Main plugin;
|
||||
|
@ -30,12 +31,17 @@ public final class ConfigHandler {
|
|||
MyLogger.setDebugLevel(getDebugLevel());
|
||||
}
|
||||
|
||||
/** Checks the number that "config-version" returns to see if the config needs updating, and if so, send it to the {@link ConfigUpdateHandler}.
|
||||
<br></br>
|
||||
<br>PlayerStats 1.1: "config-version" doesn't exist.</br>
|
||||
<br>PlayerStats 1.2: "config-version" is 2.</br>
|
||||
<br>PlayerStats 1.3: "config-version" is 3. </br>
|
||||
<br>PlayerStats 1.4: "config-version" is 4.</br>*/
|
||||
/**
|
||||
* Checks the number that "config-version" returns to see if the
|
||||
* config needs updating, and if so, send it to the {@link ConfigUpdateHandler}.
|
||||
* <br>
|
||||
* <br>PlayerStats 1.1: "config-version" doesn't exist.
|
||||
* <br>PlayerStats 1.2: "config-version" is 2.
|
||||
* <br>PlayerStats 1.3: "config-version" is 3.
|
||||
* <br>PlayerStats 1.4: "config-version" is 4.
|
||||
* <br>PlayerStats 1.5: "config-version" is 5.
|
||||
* <br>PlayerStats 1.6 and up: "config-version" is 6.
|
||||
*/
|
||||
private void checkConfigVersion() {
|
||||
if (!config.contains("config-version") || config.getInt("config-version") != configVersion) {
|
||||
new ConfigUpdateHandler(plugin, configFile, configVersion);
|
||||
|
@ -43,15 +49,23 @@ public final class ConfigHandler {
|
|||
}
|
||||
}
|
||||
|
||||
/** Create a config file if none exists yet (from the config.yml in the plugin's resources). */
|
||||
/**
|
||||
* Create a config file if none exists yet
|
||||
* (from the config.yml in the plugin's resources).
|
||||
*/
|
||||
private void saveDefaultConfig() {
|
||||
config = plugin.getConfig();
|
||||
plugin.saveDefaultConfig();
|
||||
configFile = new File(plugin.getDataFolder(), "config.yml");
|
||||
}
|
||||
|
||||
/** Reloads the config from file, or creates a new file with default values if there is none.
|
||||
Also reads the value for debug-level and passes it on to {@link MyLogger}. */
|
||||
/**
|
||||
* Reloads the config from file, or creates a new file with default values
|
||||
* if there is none. Also reads the value for debug-level and passes it
|
||||
* on to {@link MyLogger}.
|
||||
*
|
||||
* @return true if the config has been reloaded from disk, false if it failed
|
||||
*/
|
||||
public boolean reloadConfig() {
|
||||
if (!configFile.exists()) {
|
||||
saveDefaultConfig();
|
||||
|
@ -67,81 +81,108 @@ public final class ConfigHandler {
|
|||
}
|
||||
|
||||
/** Returns the desired debugging level.
|
||||
<br></br>
|
||||
<br>1 = low (only show unexpected errors)</br>
|
||||
<br>2 = medium (detail all encountered exceptions, log main tasks and show time taken)</br>
|
||||
<br>3 = high (log all tasks and time taken)</br>
|
||||
<br></br>
|
||||
<br>Default: 1</br>*/
|
||||
*
|
||||
* <br> 1 = low (only show unexpected errors)
|
||||
* <br> 2 = medium (detail all encountered exceptions, log main tasks and show time taken)
|
||||
* <br> 3 = high (log all tasks and time taken)
|
||||
*
|
||||
* @return the DebugLevel (default: 1)
|
||||
*/
|
||||
public int getDebugLevel() {
|
||||
return config.getInt("debug-level", 1);
|
||||
}
|
||||
|
||||
/** Returns true if command-senders should be limited to one stat-request at a time.
|
||||
<br>Default: true</br>*/
|
||||
/**
|
||||
* Whether command-senders should be limited to one stat-request at a time.
|
||||
* @return the config setting (default: true)
|
||||
*/
|
||||
public boolean limitStatRequests() {
|
||||
return config.getBoolean("only-allow-one-lookup-at-a-time-per-player", true);
|
||||
}
|
||||
|
||||
/** Returns true if stat-sharing is allowed.
|
||||
<br>Default: true</br>*/
|
||||
/**
|
||||
* Whether stat-sharing is allowed.
|
||||
* @return the config setting (default: true)
|
||||
*/
|
||||
public boolean allowStatSharing() {
|
||||
return config.getBoolean("enable-stat-sharing", true);
|
||||
}
|
||||
|
||||
/** Returns the number of minutes a player has to wait before being able to
|
||||
share another stat-result.
|
||||
<br>Default: 0</br>*/
|
||||
/**
|
||||
* The number of minutes a player has to wait before being able to
|
||||
* share another stat-result.
|
||||
* @return the number (default: 0)
|
||||
*/
|
||||
public int getStatShareWaitingTime() {
|
||||
return config.getInt("waiting-time-before-sharing-again", 0);
|
||||
}
|
||||
|
||||
/** Returns the config setting for include-whitelist-only.
|
||||
<br>Default: false</br>*/
|
||||
/**
|
||||
* Whether to limit stat-calculations to whitelisted players only.
|
||||
* @return the config setting (default: true)
|
||||
*/
|
||||
public boolean whitelistOnly() {
|
||||
return config.getBoolean("include-whitelist-only", false);
|
||||
}
|
||||
|
||||
/** Returns the config setting for exclude-banned-players.
|
||||
<br>Default: false</br>*/
|
||||
/**
|
||||
* Whether to exclude banned players from stat-calculations.
|
||||
* @return the config setting for exclude-banned-players (default: false)
|
||||
*/
|
||||
public boolean excludeBanned() {
|
||||
return config.getBoolean("exclude-banned-players", false);
|
||||
}
|
||||
|
||||
/** Returns the number of maximum days since a player has last been online.
|
||||
<br>Default: 0 (which signals not to use this limit)</br>*/
|
||||
/**
|
||||
* The number of maximum days since a player has last been online.
|
||||
* @return the number (default: 0 - which signals not to use this limit)
|
||||
*/
|
||||
public int getLastPlayedLimit() {
|
||||
return config.getInt("number-of-days-since-last-joined", 0);
|
||||
}
|
||||
|
||||
/** Whether to use TranslatableComponents wherever possible.
|
||||
Currently supported: statistic, block, item and entity names.
|
||||
<br>Default: true</br>*/
|
||||
/**
|
||||
* Whether to use TranslatableComponents wherever possible.
|
||||
*
|
||||
* @return the config setting (default: true)
|
||||
* @implNote Currently supported: statistic, block, item and entity names.
|
||||
*/
|
||||
public boolean useTranslatableComponents() {
|
||||
return config.getBoolean("translate-to-client-language", true);
|
||||
}
|
||||
|
||||
/** Whether to use HoverComponents for additional information.
|
||||
<br>Default: true</br>*/
|
||||
/**
|
||||
* Whether to use HoverComponents for additional information
|
||||
* @return the config setting (default: true)
|
||||
*/
|
||||
public boolean useHoverText() {
|
||||
return config.getBoolean("enable-hover-text", true);
|
||||
}
|
||||
|
||||
/** Whether to use festive formatting, such as pride colors.
|
||||
<br>Default: true</br> */
|
||||
/**
|
||||
* Whether to use festive formatting, such as pride colors
|
||||
* @return the config setting (default: true)
|
||||
*/
|
||||
public boolean useFestiveFormatting() {
|
||||
return config.getBoolean("enable-festive-formatting", true);
|
||||
}
|
||||
|
||||
/** Whether to use rainbow colors for the [PlayerStats] prefix rather than the default gold/purple.
|
||||
<br>Default: false</br> */
|
||||
/**
|
||||
* Whether to use rainbow colors for the [PlayerStats] prefix rather than the
|
||||
* default gold/purple
|
||||
* @return the config setting (default: false)
|
||||
*/
|
||||
public boolean useRainbowMode() {
|
||||
return config.getBoolean("rainbow-mode", false);
|
||||
}
|
||||
|
||||
/** Whether to use enters before the statistic output in chat.
|
||||
Enters create some separation between the previous things that have been said in chat and the stat-result.
|
||||
<br>Default: true for non-shared top statistics, false for everything else</br>*/
|
||||
/**
|
||||
* Whether to use enters before the statistic output in chat
|
||||
*
|
||||
* @param selection the Target (Player, Server or Top)
|
||||
* @return the config setting (default: true for non-shared top
|
||||
* statistics, false for everything else)
|
||||
*/
|
||||
public boolean useEnters(Target selection, boolean getSharedSetting) {
|
||||
ConfigurationSection section = config.getConfigurationSection("use-enters");
|
||||
boolean def = selection == Target.TOP && !getSharedSetting;
|
||||
|
@ -159,50 +200,77 @@ public final class ConfigHandler {
|
|||
return def;
|
||||
}
|
||||
|
||||
/** Returns the config setting for use-dots.
|
||||
<br>Default: true</br>*/
|
||||
/**
|
||||
* Whether dots should be used to align the numbers in a top-stat-result.
|
||||
* @return the config setting (default: true)
|
||||
*/
|
||||
public boolean useDots() {
|
||||
return config.getBoolean("use-dots", true);
|
||||
}
|
||||
|
||||
/** Returns the config setting for top-list-max-size.
|
||||
<br>Default: 10</br> */
|
||||
/**
|
||||
* The maximum size for the top-stat-list.
|
||||
* @return the config setting (default: 10)
|
||||
*/
|
||||
public int getTopListMaxSize() {
|
||||
return config.getInt("top-list-max-size", 10);
|
||||
}
|
||||
|
||||
/** Returns a String that represents the title for a top statistic.
|
||||
<br>Default: "Top"</br>*/
|
||||
/**
|
||||
* The title that a top-statistic should start with.
|
||||
* @return a String that represents the title for a top statistic
|
||||
* (default: "Top")
|
||||
*/
|
||||
public String getTopStatsTitle() {
|
||||
return config.getString("top-list-title", "Top");
|
||||
}
|
||||
|
||||
/** Returns a String that represents the title for a server stat.
|
||||
<br>Default: "Total on"</br> */
|
||||
/**
|
||||
* The title that a server statistic should start with.
|
||||
* @return the title (default: "Total on")
|
||||
*/
|
||||
public String getServerTitle() {
|
||||
return config.getString("total-server-stat-title", "Total on");
|
||||
}
|
||||
|
||||
/** Returns the specified server name for a server stat title.
|
||||
<br>Default: "this server"</br>*/
|
||||
/**
|
||||
* The specified server name for a server stat title.
|
||||
* @return the title (default: "this server")
|
||||
*/
|
||||
public String getServerName() {
|
||||
return config.getString("your-server-name", "this server");
|
||||
}
|
||||
|
||||
/** Returns the unit that should be used for distance-related statistics.
|
||||
<br>Default: Blocks for plain text, km for hover-text</br>*/
|
||||
/**
|
||||
* The unit that should be used for distance-related statistics.
|
||||
*
|
||||
* @param isUnitForHoverText whether the number formatted with this
|
||||
* Unit is inside a HoverComponent
|
||||
* @return the Unit (default: Blocks for plain text, km for hover-text)
|
||||
*/
|
||||
public String getDistanceUnit(boolean isUnitForHoverText) {
|
||||
return getUnitString(isUnitForHoverText, "blocks", "km", "distance-unit");
|
||||
}
|
||||
|
||||
/** Returns the unit that should be used for damage-based statistics.
|
||||
<br>Default: Hearts for plain text, HP for hover-text.</br>*/
|
||||
/**
|
||||
* The unit that should be used for damage-based statistics.
|
||||
*
|
||||
* @param isUnitForHoverText whether the number formatted with this
|
||||
* Unit is inside a HoverComponent
|
||||
* @return the Unit (default: Hearts for plain text, HP for hover-text)
|
||||
*/
|
||||
public String getDamageUnit(boolean isUnitForHoverText) {
|
||||
return getUnitString(isUnitForHoverText, "hearts", "hp", "damage-unit");
|
||||
}
|
||||
|
||||
/** Whether PlayerStats should automatically detect the most suitable unit to use for time-based statistics.
|
||||
<br>Default: true</br>*/
|
||||
/**
|
||||
* Whether PlayerStats should automatically detect the most suitable
|
||||
* unit to use for time-based statistics
|
||||
*
|
||||
* @param isUnitForHoverText whether the number formatted with this
|
||||
* Unit is inside a HoverComponent
|
||||
* @return the config setting (default: true)
|
||||
*/
|
||||
public boolean autoDetectTimeUnit(boolean isUnitForHoverText) {
|
||||
String path = "auto-detect-biggest-time-unit";
|
||||
if (isUnitForHoverText) {
|
||||
|
@ -212,8 +280,15 @@ public final class ConfigHandler {
|
|||
return config.getBoolean(path, defaultValue);
|
||||
}
|
||||
|
||||
/** How many additional units should be displayed next to the most suitable largest unit for time-based statistics.
|
||||
<br>Default: 1 for plain text, 0 for hover-text</br>*/
|
||||
/**
|
||||
* How many additional units should be displayed next to the most
|
||||
* suitable largest unit for time-based statistics
|
||||
*
|
||||
* @param isUnitForHoverText whether the number formatted with this
|
||||
* Unit is inside a HoverComponent
|
||||
* @return the config setting (default: 1 for plain text,
|
||||
* 0 for hover-text)
|
||||
*/
|
||||
public int getNumberOfExtraTimeUnits(boolean isUnitForHoverText) {
|
||||
String path = "number-of-extra-units";
|
||||
if (isUnitForHoverText) {
|
||||
|
@ -223,16 +298,28 @@ public final class ConfigHandler {
|
|||
return config.getInt(path, defaultValue);
|
||||
}
|
||||
|
||||
/** Returns the unit that should be used for time-based statistics.
|
||||
(this will return the largest unit that should be used).
|
||||
<br>Default: days for plain text, hours for hover-text</br>*/
|
||||
/**
|
||||
* The largest unit that should be used for time-based statistics.
|
||||
*
|
||||
* @param isUnitForHoverText whether the number formatted with this
|
||||
* Unit is inside a HoverComponent
|
||||
* @return a String representation of the largest time-unit
|
||||
* (default: days for plain text, hours for hover-text)
|
||||
*/
|
||||
public String getTimeUnit(boolean isUnitForHoverText) {
|
||||
return getTimeUnit(isUnitForHoverText, false);
|
||||
}
|
||||
|
||||
/** Returns the unit that should be used for time-based statistics. If the optional smallUnit flag is true,
|
||||
this will return the smallest unit (and otherwise the largest).
|
||||
<br>Default: hours for plain text, seconds for hover-text</br>*/
|
||||
/**
|
||||
* The unit that should be used for time-based statistics.
|
||||
* If the optional smallUnit flag is true, this will return
|
||||
* the smallest unit (and otherwise the biggest).
|
||||
*
|
||||
* @param isUnitForHoverText whether the number formatted with this
|
||||
* Unit is inside a HoverComponent
|
||||
* @param smallUnit if this is true, get the minimum time-unit
|
||||
* @return the Unit (default: hours for plain text, seconds for hover-text)
|
||||
*/
|
||||
public String getTimeUnit(boolean isUnitForHoverText, boolean smallUnit) {
|
||||
if (smallUnit) {
|
||||
return getUnitString(isUnitForHoverText, "hours", "seconds", "smallest-time-unit");
|
||||
|
@ -240,32 +327,51 @@ public final class ConfigHandler {
|
|||
return getUnitString(isUnitForHoverText, "days", "hours", "biggest-time-unit");
|
||||
}
|
||||
|
||||
/** Returns an integer between 0 and 100 that represents how much lighter a hoverColor should be.
|
||||
So 20 would mean 20% lighter.
|
||||
<br>Default: 20</br>*/
|
||||
/**
|
||||
* Returns an integer between 0 and 100 that represents how much lighter
|
||||
* a hoverColor should be.
|
||||
* @return an {@code int} that represents a percentage (default: 20)
|
||||
*/
|
||||
public int getHoverTextAmountLighter() {
|
||||
return config.getInt("hover-text-amount-lighter", 20);
|
||||
}
|
||||
|
||||
/** Returns a String that represents either a Chat Color, hex color code, or a Style. Default values are:
|
||||
* <br>Style: "italic"</br>
|
||||
* <br>Color: "gray"</br>*/
|
||||
/**
|
||||
* Gets a String that represents either a Chat Color, hex color code,
|
||||
* or a Style.
|
||||
*
|
||||
* @param getStyleSetting if true, returns a Style instead of a Color
|
||||
* @return the config setting. Default:
|
||||
* <br>Style: "italic"
|
||||
* <br>Color: "gray"
|
||||
*/
|
||||
public String getSharedByTextDecoration(boolean getStyleSetting) {
|
||||
String def = getStyleSetting ? "italic" : "gray";
|
||||
return getDecorationString(null, getStyleSetting, def, "shared-by");
|
||||
}
|
||||
|
||||
/** Returns a String that represents either a Chat Color, hex color code, or a Style. Default values are:
|
||||
* <br>Style: "none"</br>
|
||||
* <br>Color: "#845EC2"</br>*/
|
||||
/**
|
||||
* Gets a String that represents either a Chat Color, hex color code, or a Style.
|
||||
*
|
||||
* @param getStyleSetting if true, returns a Style instead of a Color
|
||||
* @return the config setting. Default:
|
||||
* <br>Style: "none"
|
||||
* <br>Color: "#845EC2"
|
||||
*/
|
||||
public String getSharerNameDecoration(boolean getStyleSetting) {
|
||||
return getDecorationString(null, getStyleSetting, "#845EC2", "player-name");
|
||||
}
|
||||
|
||||
/** Returns a String that represents either a Chat Color, hex color code, or a Style. Default values are:
|
||||
<br>Style: "none"</br>
|
||||
<br>Color Top: "green"</br>
|
||||
<br>Color Individual/Server: "gold"</br>*/
|
||||
/**
|
||||
* Gets a String that represents either a Chat Color, hex color code, or a Style.
|
||||
*
|
||||
* @param selection the Target (Player, Server or Top)
|
||||
* @param getStyleSetting if true, returns a Style instead of a Color
|
||||
* @return the config setting. Default:
|
||||
* <br>Style: "none"
|
||||
* <br>Color Top: "green"
|
||||
* <br>Color Individual/Server: "gold"
|
||||
*/
|
||||
public String getPlayerNameDecoration(Target selection, boolean getStyleSetting) {
|
||||
String def;
|
||||
if (selection == Target.TOP) {
|
||||
|
@ -277,8 +383,10 @@ public final class ConfigHandler {
|
|||
return getDecorationString(selection, getStyleSetting, def, "player-names");
|
||||
}
|
||||
|
||||
/** Returns true if playerNames Style is "bold" for a top-stat, false if it is not.
|
||||
<br>Default: false</br>*/
|
||||
/**
|
||||
* Whether the playerNames Style is "bold" for a top-stat.
|
||||
* @return the config setting (default: false)
|
||||
*/
|
||||
public boolean playerNameIsBold() {
|
||||
ConfigurationSection style = getRelevantSection(Target.TOP);
|
||||
|
||||
|
@ -289,24 +397,45 @@ public final class ConfigHandler {
|
|||
return false;
|
||||
}
|
||||
|
||||
/** Returns a String that represents either a Chat Color, hex color code, or a Style. Default values are:
|
||||
<br>Style: "none"</br>
|
||||
<br>Color: "yellow"</br>*/
|
||||
/**
|
||||
* Gets a String that represents either a Chat Color, hex color code,
|
||||
* or a Style.
|
||||
*
|
||||
* @param selection the Target (Player, Server or Top)
|
||||
* @param getStyleSetting if true, returns a Style instead of a Color
|
||||
* @return the config setting. Default:
|
||||
* <br>Style: "none"
|
||||
* <br>Color: "yellow"
|
||||
*/
|
||||
public String getStatNameDecoration(Target selection, boolean getStyleSetting) {
|
||||
return getDecorationString(selection, getStyleSetting, "yellow", "stat-names");
|
||||
}
|
||||
|
||||
/** Returns a String that represents either a Chat Color, hex color code, or a Style. Default values are:
|
||||
<br>Style: "none"</br>
|
||||
<br>Color: "#FFD52B"</br>*/
|
||||
/**
|
||||
* Gets a String that represents either a Chat Color, hex color code,
|
||||
* or a Style.
|
||||
*
|
||||
* @param selection the Target (Player, Server or Top)
|
||||
* @param getStyleSetting if true, returns a Style instead of a Color
|
||||
* @return the config setting. Default:
|
||||
* <br>Style: "none"
|
||||
* <br>Color: "#FFD52B"
|
||||
*/
|
||||
public String getSubStatNameDecoration(Target selection, boolean getStyleSetting) {
|
||||
return getDecorationString(selection, getStyleSetting, "#FFD52B", "sub-stat-names");
|
||||
}
|
||||
|
||||
/** Returns a String that represents either a Chat Color, hex color code, or Style. Default values are:
|
||||
<br>Style: "none"</br>
|
||||
<br>Color Top: "#55AAFF"</br>
|
||||
<br>Color Individual/Server: "#ADE7FF"</br> */
|
||||
/**
|
||||
* Gets a String that represents either a Chat Color, hex color code,
|
||||
* or Style.
|
||||
*
|
||||
* @param selection the Target (Player, Server or Top)
|
||||
* @param getStyleSetting if true, returns a Style instead of a Color
|
||||
* @return the config setting. Default:
|
||||
* <br>Style: "none"
|
||||
* <br>Color Top: "#55AAFF"
|
||||
* <br>Color Individual/Server: "#ADE7FF"
|
||||
*/
|
||||
public String getStatNumberDecoration(Target selection, boolean getStyleSetting) {
|
||||
String def;
|
||||
if (selection == Target.TOP) {
|
||||
|
@ -318,10 +447,17 @@ public final class ConfigHandler {
|
|||
return getDecorationString(selection, getStyleSetting, def,"stat-numbers");
|
||||
}
|
||||
|
||||
/** Returns a String that represents either a Chat Color, hex color code, or Style. Default values are:
|
||||
<br>Style: "none"</br>
|
||||
<br>Color Top: "yellow"</br>
|
||||
<br>Color Server: "gold"</br>*/
|
||||
/**
|
||||
* Gets a String that represents either a Chat Color, hex color code,
|
||||
* or Style.
|
||||
*
|
||||
* @param selection the Target (Player, Server or Top)
|
||||
* @param getStyleSetting if true, returns a Style instead of a Color
|
||||
* @return the config setting. Default:
|
||||
* <br>Style: "none"
|
||||
* <br>Color Top: "yellow"
|
||||
* <br>Color Server: "gold"
|
||||
*/
|
||||
public String getTitleDecoration(Target selection, boolean getStyleSetting) {
|
||||
String def;
|
||||
if (selection == Target.TOP) {
|
||||
|
@ -333,41 +469,71 @@ public final class ConfigHandler {
|
|||
return getDecorationString(selection, getStyleSetting, def, "title");
|
||||
}
|
||||
|
||||
/** Returns a String that represents either a Chat Color, hex color code, or Style. Default values are:
|
||||
<br>Style: "none"</br>
|
||||
<br>Color: "gold"</br>*/
|
||||
/**
|
||||
* Gets a String that represents either a Chat Color, hex color code,
|
||||
* or Style.
|
||||
*
|
||||
* @param getStyleSetting if true, returns a Style instead of a Color
|
||||
* @return the config setting. Default:
|
||||
* <br>Style: "none"
|
||||
* <br>Color: "gold"
|
||||
*/
|
||||
public String getTitleNumberDecoration(boolean getStyleSetting) {
|
||||
return getDecorationString(Target.TOP, getStyleSetting, "gold", "title-number");
|
||||
}
|
||||
|
||||
/** Returns a String that represents either a Chat Color, hex color code, or Style. Default values are:
|
||||
<br>Style: "none"</br>
|
||||
<br>Color: "#FFB80E"</br>*/
|
||||
/**
|
||||
* Gets a String that represents either a Chat Color, hex color code,
|
||||
* or Style.
|
||||
*
|
||||
* @param getStyleSetting if true, returns a Style instead of a Color
|
||||
* @return the config setting. Default:
|
||||
* <br>Style: "none"
|
||||
* <br>Color: "#FFB80E"
|
||||
*/
|
||||
public String getServerNameDecoration(boolean getStyleSetting) {
|
||||
return getDecorationString(Target.SERVER, getStyleSetting, "#FFB80E", "server-name");
|
||||
}
|
||||
|
||||
/** Returns a String that represents either a Chat Color, hex color code, or Style. Default values are:
|
||||
<br>Style: "none"</br>
|
||||
<br>Color: "gold"</br>*/
|
||||
/**
|
||||
* Gets a String that represents either a Chat Color, hex color code,
|
||||
* or Style.
|
||||
*
|
||||
* @param getStyleSetting if true, returns a Style instead of a Color
|
||||
* @return the config setting. Default:
|
||||
* <br>Style: "none"
|
||||
* <br>Color: "gold"
|
||||
*/
|
||||
public String getRankNumberDecoration(boolean getStyleSetting) {
|
||||
return getDecorationString(Target.TOP, getStyleSetting, "gold", "rank-numbers");
|
||||
}
|
||||
|
||||
/** Returns a String that represents either a Chat Color, hex color code, or Style. Default values are:
|
||||
<br>Style: "none"</br>
|
||||
<br>Color: "dark_gray"</br> */
|
||||
/**
|
||||
* Gets a String that represents either a Chat Color, hex color code,
|
||||
* or Style.
|
||||
*
|
||||
* @param getStyleSetting if true, returns a Style instead of a Color
|
||||
* @return the config setting. Default:
|
||||
* <br>Style: "none"
|
||||
* <br>Color: "dark_gray"
|
||||
*/
|
||||
public String getDotsDecoration(boolean getStyleSetting) {
|
||||
return getDecorationString(Target.TOP, getStyleSetting, "dark_gray", "dots");
|
||||
}
|
||||
|
||||
/** Returns a String representing the {@link Unit} that should be used for a certain {@link Unit.Type}.
|
||||
If no String can be retrieved from the config, the supplied defaultValue will be returned.
|
||||
If the defaultValue is different for hoverText, an optional String defaultHoverValue can be supplied.
|
||||
@param isHoverText if true, the unit for hovering text is returned, otherwise the unit for plain text
|
||||
@param defaultValue the default unit for plain text
|
||||
@param defaultHoverValue the default unit for hovering text
|
||||
@param pathName the config path to retrieve the value from*/
|
||||
/**
|
||||
* Gets a String representing a {@link Unit}.
|
||||
*
|
||||
* @return a String representing the {@link Unit} that should be used for a
|
||||
* certain {@link Unit.Type}. If no String can be retrieved from the config,
|
||||
* the supplied defaultValue will be returned. If the defaultValue is different
|
||||
* for hoverText, an optional String defaultHoverValue can be supplied.
|
||||
* @param isHoverText if true, the unit for hovering text is returned,
|
||||
* otherwise the unit for plain text
|
||||
* @param defaultValue the default unit for plain text
|
||||
* @param defaultHoverValue the default unit for hovering text
|
||||
* @param pathName the config path to retrieve the value from
|
||||
*/
|
||||
private String getUnitString(boolean isHoverText, String defaultValue, String defaultHoverValue, String pathName) {
|
||||
String path = isHoverText ? pathName + "-for-hover-text" : pathName;
|
||||
String def = defaultValue;
|
||||
|
@ -377,12 +543,16 @@ public final class ConfigHandler {
|
|||
return config.getString(path, def);
|
||||
}
|
||||
|
||||
/** Returns the config value for a color or style option in string-format, the supplied default value,
|
||||
or null if no configSection was found.
|
||||
@param selection the Target this decoration is meant for (Player, Server or Top)
|
||||
@param getStyleSetting if true, the result will be a style String, otherwise a color String
|
||||
@param defaultColor the default color to return if the config value cannot be found (for style, the default is always "none")
|
||||
@param pathName the config path to retrieve the value from*/
|
||||
/**
|
||||
* @return the config value for a color or style option in string-format,
|
||||
* the supplied default value, or null if no configSection was found.
|
||||
* @param selection the Target this decoration is meant for (Player, Server or Top)
|
||||
* @param getStyleSetting if true, the result will be a style String,
|
||||
* otherwise a color String
|
||||
* @param defaultColor the default color to return if the config value cannot be found
|
||||
* (for style, the default is always "none")
|
||||
* @param pathName the config path to retrieve the value from
|
||||
*/
|
||||
private @Nullable String getDecorationString(Target selection, boolean getStyleSetting, String defaultColor, String pathName){
|
||||
String path = getStyleSetting ? pathName + "-style" : pathName;
|
||||
String defaultValue = getStyleSetting ? "none" : defaultColor;
|
||||
|
@ -391,7 +561,9 @@ public final class ConfigHandler {
|
|||
return section != null ? section.getString(path, defaultValue) : null;
|
||||
}
|
||||
|
||||
/** Returns the config section that contains the relevant color or style option. */
|
||||
/**
|
||||
* @return the config section that contains the relevant color or style option.
|
||||
*/
|
||||
private @Nullable ConfigurationSection getRelevantSection(Target selection) {
|
||||
if (selection == null) { //rather than rework the whole Target enum, I have added shared-stats as the null-option for now
|
||||
return config.getConfigurationSection("shared-stats");
|
||||
|
|
|
@ -11,7 +11,10 @@ import com.tchristofferson.configupdater.ConfigUpdater;
|
|||
|
||||
public final class ConfigUpdateHandler {
|
||||
|
||||
/** Add new key-value pairs to the config without losing comments, using <a href="https://github.com/tchristofferson/Config-Updater">tchristofferson's Config-Updater</a> */
|
||||
/**
|
||||
* Add new key-value pairs to the config without losing comments,
|
||||
* using <a href="https://github.com/tchristofferson/Config-Updater">tchristofferson's Config-Updater</a>
|
||||
*/
|
||||
public ConfigUpdateHandler(Main plugin, File configFile, int configVersion) {
|
||||
YamlConfiguration configuration = YamlConfiguration.loadConfiguration(configFile);
|
||||
updateTopListDefault(configuration);
|
||||
|
@ -27,7 +30,10 @@ public final class ConfigUpdateHandler {
|
|||
}
|
||||
}
|
||||
|
||||
/** Adjusts the value for "top-list" to migrate the config file from versions 1 or 2 to version 3 and above.*/
|
||||
/**
|
||||
* Adjusts the value for "top-list" to migrate the config file from
|
||||
* versions 1 or 2 to version 3 and above.
|
||||
*/
|
||||
private void updateTopListDefault(YamlConfiguration configuration) {
|
||||
String oldTitle = configuration.getString("top-list-title");
|
||||
if (oldTitle != null && oldTitle.equalsIgnoreCase("Top [x]")) {
|
||||
|
@ -35,7 +41,10 @@ public final class ConfigUpdateHandler {
|
|||
}
|
||||
}
|
||||
|
||||
/** Adjusts some of the default colors to migrate from versions 2 or 3 to version 4 and above.*/
|
||||
/**
|
||||
* Adjusts some of the default colors to migrate from versions 2
|
||||
* or 3 to version 4 and above.
|
||||
*/
|
||||
private void updateDefaultColors(YamlConfiguration configuration) {
|
||||
updateColor(configuration, "top-list.title", "yellow", "#FFD52B");
|
||||
updateColor(configuration, "top-list.title", "#FFEA40", "#FFD52B");
|
||||
|
|
|
@ -1,10 +1,12 @@
|
|||
package com.github.artemis.the.gr8.playerstats.enums;
|
||||
|
||||
/** Represents the debugging level that PlayerStats can use.
|
||||
<br></br>
|
||||
<br>1 = low (only show unexpected errors)</br>
|
||||
<br>2 = medium (detail all encountered exceptions, log main tasks and show time taken)</br>
|
||||
<br>3 = high (log all tasks and time taken)</br>*/
|
||||
/**
|
||||
* Represents the debugging level that PlayerStats can use.
|
||||
* <br>
|
||||
* <br>1 = low (only show unexpected errors)
|
||||
* <br>2 = medium (detail all encountered exceptions, log main tasks and show time taken)
|
||||
* <br>3 = high (log all tasks and time taken)
|
||||
*/
|
||||
public enum DebugLevel {
|
||||
LOW, MEDIUM, HIGH
|
||||
}
|
|
@ -5,63 +5,102 @@ import net.kyori.adventure.text.format.TextColor;
|
|||
|
||||
import java.util.Random;
|
||||
|
||||
/** This enum represents the colorscheme PlayerStats uses in its output messages.
|
||||
The first set of colors is used throughout the plugin, while the set of NAME-colors
|
||||
represents the colors that player-names can be in the "shared by player-name" section of shared statistics.*/
|
||||
/**
|
||||
* This enum represents the colorscheme PlayerStats uses in its output messages.
|
||||
* The first set of colors is used throughout the plugin, while the set of NAME-colors
|
||||
* represents the colors that player-names can be in the "shared by player-name"
|
||||
* section of shared statistics
|
||||
*/
|
||||
public enum PluginColor {
|
||||
/** ChatColor Gray (#AAAAAA) */
|
||||
/**
|
||||
* ChatColor Gray (#AAAAAA)
|
||||
*/
|
||||
GRAY (NamedTextColor.GRAY),
|
||||
|
||||
/** A Dark Purple that is mainly used for title-underscores (#6E3485).*/
|
||||
/**
|
||||
* A Dark Purple that is mainly used for title-underscores (#6E3485).
|
||||
*/
|
||||
DARK_PURPLE (TextColor.fromHexString("#6E3485")),
|
||||
|
||||
/** A Light Purple that is meant to simulate the color of a clicked link.
|
||||
Used for the "Hover Here" part of shared statistics (#845EC2).*/
|
||||
/**
|
||||
* A Light Purple that is meant to simulate the color of a clicked link.
|
||||
* Used for the "Hover Here" part of shared statistics (#845EC2)
|
||||
* */
|
||||
LIGHT_PURPLE (TextColor.fromHexString("#845EC2")),
|
||||
|
||||
/** ChatColor Blue (#5555FF)*/
|
||||
/**
|
||||
* ChatColor Blue (#5555FF)
|
||||
*/
|
||||
BLUE (NamedTextColor.BLUE),
|
||||
|
||||
/** A Medium Blue that is used for default feedback and error messages (#55AAFF).*/
|
||||
/**
|
||||
* A Medium Blue that is used for default feedback and error messages (#55AAFF).
|
||||
*/
|
||||
MEDIUM_BLUE (TextColor.fromHexString("#55AAFF")),
|
||||
|
||||
/** A Light Blue that is used for hover-messages and the share-button (#55C6FF). */
|
||||
/**
|
||||
* A Light Blue that is used for hover-messages and the share-button (#55C6FF).
|
||||
*/
|
||||
LIGHT_BLUE (TextColor.fromHexString("#55C6FF")),
|
||||
|
||||
/** ChatColor Gold (#FFAA00)*/
|
||||
/**
|
||||
* ChatColor Gold (#FFAA00)
|
||||
*/
|
||||
GOLD (NamedTextColor.GOLD),
|
||||
|
||||
/** A Medium Gold that is used for the example message and for hover-text accents (#FFD52B).*/
|
||||
/**
|
||||
* A Medium Gold that is used for the example message and for hover-text accents (#FFD52B).
|
||||
*/
|
||||
MEDIUM_GOLD (TextColor.fromHexString("#FFD52B")),
|
||||
|
||||
/** A Light Gold that is used for the example message and for hover-text accents (#FFEA40).*/
|
||||
/**
|
||||
* A Light Gold that is used for the example message and for hover-text accents (#FFEA40).
|
||||
*/
|
||||
LIGHT_GOLD (TextColor.fromHexString("#FFEA40")),
|
||||
|
||||
/** A Light Yellow that is used for final accents in the example message (#FFFF8E).*/
|
||||
/**
|
||||
* A Light Yellow that is used for final accents in the example message (#FFFF8E).
|
||||
*/
|
||||
LIGHT_YELLOW (TextColor.fromHexString("#FFFF8E")),
|
||||
|
||||
/** The color of vanilla Minecraft hearts (#FF1313). */
|
||||
/**
|
||||
* The color of vanilla Minecraft hearts (#FF1313).
|
||||
*/
|
||||
RED (TextColor.fromHexString("#FF1313")),
|
||||
|
||||
/** ChatColor Blue (#5555FF)*/
|
||||
/**
|
||||
* ChatColor Blue (#5555FF)
|
||||
*/
|
||||
NAME_1 (NamedTextColor.BLUE), //#5555FF - blue
|
||||
|
||||
/** A shade of blue between Blue and Medium Blue (#4287F5)*/
|
||||
/**
|
||||
* A shade of blue between Blue and Medium Blue (#4287F5)
|
||||
*/
|
||||
NAME_2 (TextColor.fromHexString("#4287F5")),
|
||||
|
||||
/** Medium Blue (#55AAFF)*/
|
||||
/**
|
||||
* Medium Blue (#55AAFF)
|
||||
*/
|
||||
NAME_3 (TextColor.fromHexString("#55AAFF")),
|
||||
|
||||
/** A shade of magenta/purple (#D65DB1)*/
|
||||
/**
|
||||
* A shade of magenta/purple (#D65DB1)
|
||||
*/
|
||||
NAME_4 (TextColor.fromHexString("#D65DB1")),
|
||||
|
||||
/** A dark shade of orange (#EE8A19)*/
|
||||
/**
|
||||
* A dark shade of orange (#EE8A19)
|
||||
*/
|
||||
NAME_5 (TextColor.fromHexString("#EE8A19")),
|
||||
|
||||
/** A shade of green/aqua/cyan-ish (#01C1A7)*/
|
||||
/**
|
||||
* A shade of green/aqua/cyan-ish (#01C1A7)
|
||||
*/
|
||||
NAME_6 (TextColor.fromHexString("#01C1A7")),
|
||||
|
||||
/** A light shade of green (#46D858)*/
|
||||
/**
|
||||
* A light shade of green (#46D858)
|
||||
*/
|
||||
NAME_7 (TextColor.fromHexString("#46D858"));
|
||||
|
||||
|
||||
|
@ -71,23 +110,31 @@ public enum PluginColor {
|
|||
this.color = color;
|
||||
}
|
||||
|
||||
/** Returns the TextColor value belonging to the corresponding enum constant.*/
|
||||
/**
|
||||
* Returns the TextColor value belonging to the corresponding enum constant.
|
||||
*/
|
||||
public TextColor getColor() {
|
||||
return color;
|
||||
}
|
||||
|
||||
/** Gets the nearest NamedTextColor for the corresponding enum constant.*/
|
||||
/**
|
||||
* Gets the nearest NamedTextColor for the corresponding enum constant.
|
||||
*/
|
||||
public TextColor getConsoleColor() {
|
||||
return NamedTextColor.nearestTo(color);
|
||||
}
|
||||
|
||||
/** Randomly selects one of the 7 different NAME-colors.*/
|
||||
/**
|
||||
* Randomly selects one of the 7 different NAME-colors.
|
||||
*/
|
||||
public static TextColor getRandomNameColor() {
|
||||
return getRandomNameColor(false);
|
||||
}
|
||||
|
||||
/** Randomly selects one of the 7 different NAME-colors, and if isConsole is true,
|
||||
returns the closest NamedTextColor.*/
|
||||
/**
|
||||
* Randomly selects one of the 7 different NAME-colors, and if isConsole is true,
|
||||
* returns the closest NamedTextColor
|
||||
*/
|
||||
public static TextColor getRandomNameColor(boolean isConsole) {
|
||||
Random randomizer = new Random();
|
||||
PluginColor color = switch (randomizer.nextInt(7)) {
|
||||
|
|
|
@ -1,7 +1,10 @@
|
|||
package com.github.artemis.the.gr8.playerstats.enums;
|
||||
|
||||
/** All standard messages PlayerStats can send as feedback.
|
||||
These are all the messages that can be sent without needing additional parameters.*/
|
||||
/**
|
||||
* All standard messages PlayerStats can send as feedback.
|
||||
* These are all the messages that can be sent without needing
|
||||
* additional parameters.
|
||||
*/
|
||||
public enum StandardMessage {
|
||||
RELOADED_CONFIG,
|
||||
STILL_RELOADING,
|
||||
|
|
|
@ -1,6 +1,9 @@
|
|||
package com.github.artemis.the.gr8.playerstats.enums;
|
||||
|
||||
/** This enum represents the targets PlayerStats accepts for a stat-lookup (Player, Server and Top).*/
|
||||
/**
|
||||
* This enum represents the targets PlayerStats accepts
|
||||
* for a stat-lookup (Player, Server and Top).
|
||||
*/
|
||||
public enum Target {
|
||||
PLAYER, SERVER, TOP
|
||||
}
|
|
@ -3,7 +3,9 @@ package com.github.artemis.the.gr8.playerstats.enums;
|
|||
import org.bukkit.Statistic;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/** All the units PlayerStats can display statistics in, separated by Type.*/
|
||||
/**
|
||||
* All the units PlayerStats can display statistics in, separated by Type.
|
||||
*/
|
||||
public enum Unit {
|
||||
NUMBER (Type.UNTYPED, "Times"),
|
||||
KM (Type.DISTANCE, "km"),
|
||||
|
@ -26,21 +28,28 @@ public enum Unit {
|
|||
this.label = label;
|
||||
}
|
||||
|
||||
/** Returns a pretty name belonging to this enum constant. If the Unit is
|
||||
NUMBER, it will return null. */
|
||||
/**
|
||||
* Returns a pretty name belonging to this enum constant. If the Unit is
|
||||
* NUMBER, it will return null.
|
||||
*/
|
||||
public String getLabel() {
|
||||
return this.label;
|
||||
}
|
||||
|
||||
/** Returns the Type this enum constant belongs to.*/
|
||||
/**
|
||||
* Returns the Type this enum constant belongs to.
|
||||
*/
|
||||
public Type getType() {
|
||||
return this.type;
|
||||
}
|
||||
|
||||
/** For Type Time, Damage and Distance, this will return a smaller Unit than the current one
|
||||
(if there is a smaller Unit, that is, otherwise it will return itself).
|
||||
So for DAY, for example, it can return HOUR, MINUTE or SECOND.
|
||||
@param stepsSmaller how many steps smaller the returned Unit should be*/
|
||||
/**
|
||||
* For Type Time, Damage and Distance, this will return a smaller Unit than the current one
|
||||
* (if there is a smaller Unit, that is, otherwise it will return itself).
|
||||
* So for DAY, for example, it can return HOUR, MINUTE or SECOND.
|
||||
*
|
||||
* @param stepsSmaller how many steps smaller the returned Unit should be
|
||||
*/
|
||||
public Unit getSmallerUnit(int stepsSmaller) {
|
||||
switch (this) {
|
||||
case DAY -> {
|
||||
|
@ -99,7 +108,10 @@ public enum Unit {
|
|||
}
|
||||
}
|
||||
|
||||
/** Converts the current Unit into seconds (and returns -1 if the current Unit is not of Type TIME)*/
|
||||
/**
|
||||
* Converts the current Unit into seconds (and returns
|
||||
* -1 if the current Unit is not of Type TIME)
|
||||
*/
|
||||
public double getSeconds() {
|
||||
return switch (this) {
|
||||
case DAY -> 86400;
|
||||
|
@ -111,9 +123,13 @@ public enum Unit {
|
|||
};
|
||||
}
|
||||
|
||||
/** Returns the Unit corresponding to the given String. This String does NOT need to
|
||||
match exactly (it can be "day" or "days", for example), and is case-insensitive.
|
||||
@param unitName an approximation of the name belonging to the desired Unit, case-insensitive */
|
||||
/**
|
||||
* Returns the Unit corresponding to the given String. This String does NOT need to
|
||||
* match exactly (it can be "day" or "days", for example), and is case-insensitive.
|
||||
*
|
||||
* @param unitName an approximation of the name belonging to the desired Unit,
|
||||
* case-insensitive
|
||||
*/
|
||||
public static @NotNull Unit fromString(@NotNull String unitName) {
|
||||
return switch (unitName.toLowerCase()) {
|
||||
case "cm" -> Unit.CM;
|
||||
|
@ -131,8 +147,12 @@ public enum Unit {
|
|||
};
|
||||
}
|
||||
|
||||
/** Returns the Unit.Type of this Statistic, which can be Untyped, Distance, Damage, or Time.
|
||||
@param statistic the Statistic enum constant*/
|
||||
/**
|
||||
* Returns the Unit.Type of this Statistic, which can be Untyped,
|
||||
* Distance, Damage, or Time.
|
||||
*
|
||||
* @param statistic the Statistic enum constant
|
||||
*/
|
||||
public static @NotNull Type getTypeFromStatistic(Statistic statistic) {
|
||||
String name = statistic.toString().toLowerCase();
|
||||
if (name.contains("one_cm")) {
|
||||
|
@ -146,9 +166,12 @@ public enum Unit {
|
|||
}
|
||||
}
|
||||
|
||||
/** Returns the most suitable Unit for this number.
|
||||
@param type the Unit.Type of the statistic this number belongs to
|
||||
@param number the statistic number as returned by Player.getStatistic()*/
|
||||
/**
|
||||
* Returns the most suitable Unit for this number.
|
||||
*
|
||||
* @param type the Unit.Type of the statistic this number belongs to
|
||||
* @param number the statistic number as returned by Player.getStatistic()
|
||||
*/
|
||||
public static Unit getMostSuitableUnit(Unit.Type type, long number) {
|
||||
switch (type) {
|
||||
case TIME -> {
|
||||
|
|
|
@ -5,7 +5,9 @@ import org.bukkit.event.EventHandler;
|
|||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.player.PlayerJoinEvent;
|
||||
|
||||
/** Listens for new Players that join, and reloads PlayerStats if someone joins that hasn't joined before.*/
|
||||
/** Listens for new Players that join, and reloads PlayerStats
|
||||
* if someone joins that hasn't joined before.
|
||||
*/
|
||||
public class JoinListener implements Listener {
|
||||
|
||||
private static ThreadManager threadManager;
|
||||
|
|
|
@ -8,24 +8,28 @@ import org.jetbrains.annotations.ApiStatus.Internal;
|
|||
import java.util.LinkedHashMap;
|
||||
|
||||
/** The {@link InternalFormatter} formats raw numbers into pretty messages.
|
||||
This ApiFormatter takes a {@link RequestSettings} object and combines it with the raw data
|
||||
returned by the {@link StatCalculator}, and transforms those into a pretty message
|
||||
with all the relevant information in it.*/
|
||||
* This ApiFormatter takes a {@link RequestSettings} object and combines it with the raw data
|
||||
* returned by the {@link StatCalculator}, and transforms those into a pretty message
|
||||
* with all the relevant information in it.
|
||||
*/
|
||||
@Internal
|
||||
public interface InternalFormatter {
|
||||
|
||||
/** @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 formatAndSavePlayerStat(RequestSettings requestSettings, int playerStat);
|
||||
|
||||
/** @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 formatAndSaveServerStat(RequestSettings requestSettings, long serverStat);
|
||||
|
||||
/** @return a TextComponent with the following parts:
|
||||
<br>[PlayerStats] [Top 10] [stat-name] [sub-stat-name]
|
||||
<br> [1.] [player-name] [number]
|
||||
<br> [2.] [player-name] [number]
|
||||
<br> [3.] etc...*/
|
||||
* <br>[PlayerStats] [Top 10] [stat-name] [sub-stat-name]
|
||||
* <br> [1.] [player-name] [number]
|
||||
* <br> [2.] [player-name] [number]
|
||||
* <br> [3.] etc...
|
||||
*/
|
||||
TextComponent formatAndSaveTopStat(RequestSettings requestSettings, LinkedHashMap<String, Integer> topStats);
|
||||
}
|
|
@ -27,11 +27,13 @@ import java.util.function.BiFunction;
|
|||
|
||||
import static net.kyori.adventure.text.Component.*;
|
||||
|
||||
/** Composes messages to send to a Player or Console. This class is responsible
|
||||
for constructing a final Component with the text content of the desired message.
|
||||
The component parts (with appropriate formatting) are supplied by a {@link ComponentFactory}.
|
||||
By default, this class works with the default ComponentFactory, but you can
|
||||
give it a different ComponentFactory upon creation.*/
|
||||
/**
|
||||
* Composes messages to send to a Player or Console. This class is responsible
|
||||
* for constructing a final Component with the text content of the desired message.
|
||||
* The component parts (with appropriate formatting) are supplied by a
|
||||
* {@link ComponentFactory}. By default, this class works with the default
|
||||
* ComponentFactory, but you can give it a different ComponentFactory upon creation.
|
||||
*/
|
||||
public final class MessageBuilder implements ApiFormatter {
|
||||
|
||||
private static ConfigHandler config;
|
||||
|
@ -63,8 +65,10 @@ public final class MessageBuilder implements ApiFormatter {
|
|||
return new MessageBuilder(config, factory);
|
||||
}
|
||||
|
||||
/** Set whether this {@link MessageBuilder} should use hoverText.
|
||||
By default, this follows the setting specified in the {@link ConfigHandler}. */
|
||||
/**
|
||||
* Set whether this {@link MessageBuilder} should use hoverText.
|
||||
* By default, this follows the setting specified in the {@link ConfigHandler}.
|
||||
*/
|
||||
public void toggleHoverUse(boolean desiredSetting) {
|
||||
useHoverText = desiredSetting;
|
||||
}
|
||||
|
@ -223,11 +227,13 @@ public final class MessageBuilder implements ApiFormatter {
|
|||
return getTopStatLineComponent(positionInTopList, playerName, statNumberComponent);
|
||||
}
|
||||
|
||||
/** Time-number does not hover */
|
||||
/**
|
||||
* Time-number does not hover
|
||||
*/
|
||||
@Override
|
||||
public TextComponent formatTopStatLineForTypeTime(int positionInList, String playerName, long statNumber, Unit bigUnit, Unit smallUnit) {
|
||||
public TextComponent formatTopStatLineForTypeTime(int positionInTopList, String playerName, long statNumber, Unit bigUnit, Unit smallUnit) {
|
||||
TextComponent statNumberComponent = getBasicTimeNumberComponent(statNumber, Target.TOP, bigUnit, smallUnit);
|
||||
return getTopStatLineComponent(positionInList, playerName, statNumberComponent);
|
||||
return getTopStatLineComponent(positionInTopList, playerName, statNumberComponent);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -278,31 +284,49 @@ public final class MessageBuilder implements ApiFormatter {
|
|||
return getPlayerStatComponent(playerName, statNumberComponent, statistic, null, null);
|
||||
}
|
||||
|
||||
/** Returns a BiFunction for a player statistic. This BiFunction will return a formattedComponent,
|
||||
the shape of which is determined by the 2 parameters the BiFunction gets.
|
||||
<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>- If both parameters are null, the formattedComponent will be returned as is.</br>*/
|
||||
/**
|
||||
* Returns a BiFunction for a player statistic. This BiFunction will return
|
||||
* a formattedComponent, the shape of which is determined by the 2 parameters
|
||||
* the BiFunction gets.
|
||||
* <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>- If both parameters are null, the formattedComponent will be returned
|
||||
* as is.
|
||||
*/
|
||||
public BiFunction<Integer, CommandSender, TextComponent> formattedPlayerStatFunction(int stat, @NotNull RequestSettings request) {
|
||||
TextComponent playerStat = formatPlayerStat(request.getPlayerName(), stat, request.getStatistic(), request.getSubStatEntryName());
|
||||
return getFormattingFunction(playerStat, Target.PLAYER);
|
||||
}
|
||||
|
||||
/** Returns a BiFunction for a server statistic. This BiFunction will return a formattedComponent,
|
||||
the shape of which is determined by the 2 parameters the BiFunction gets.
|
||||
<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>- If both parameters are null, the formattedComponent will be returned as is.</br>*/
|
||||
/**
|
||||
* Returns a BiFunction for a server statistic. This BiFunction will return
|
||||
* a formattedComponent, the shape of which is determined by the 2 parameters
|
||||
* the BiFunction gets.
|
||||
* <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>- If both parameters are null, the formattedComponent will be returned
|
||||
* as is.
|
||||
*/
|
||||
public BiFunction<Integer, CommandSender, TextComponent> formattedServerStatFunction(long stat, @NotNull RequestSettings request) {
|
||||
TextComponent serverStat = formatServerStat(stat, request.getStatistic(), request.getSubStatEntryName());
|
||||
return getFormattingFunction(serverStat, Target.SERVER);
|
||||
}
|
||||
|
||||
/** Returns a BiFunction for a top statistic. This BiFunction will return a formattedComponent,
|
||||
the shape of which is determined by the 2 parameters the BiFunction gets.
|
||||
<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>- If both parameters are null, the formattedComponent will be returned as is.</br>*/
|
||||
/**
|
||||
* Returns a BiFunction for a top statistic. This BiFunction will return
|
||||
* a formattedComponent, the shape of which is determined by the 2 parameters
|
||||
* the BiFunction gets.
|
||||
* <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>- If both parameters are null, the formattedComponent will be returned
|
||||
* as is.
|
||||
*/
|
||||
public BiFunction<Integer, CommandSender, TextComponent> formattedTopStatFunction(@NotNull LinkedHashMap<String, Integer> topStats, @NotNull RequestSettings request) {
|
||||
final TextComponent title = getTopStatTitle(topStats.size(), request.getStatistic(), request.getSubStatEntryName());
|
||||
final TextComponent list = getTopStatListComponent(topStats, request.getStatistic());
|
||||
|
@ -562,7 +586,9 @@ public final class MessageBuilder implements ApiFormatter {
|
|||
return componentFactory.statNumber(formatter.formatNumber(statNumber), target);
|
||||
}
|
||||
|
||||
/** Provides its own space in front of it! */
|
||||
/**
|
||||
* Provides its own space in front of it!
|
||||
*/
|
||||
private TextComponent getStatUnitComponent(Statistic statistic, Target target) {
|
||||
Unit unit = switch (Unit.getTypeFromStatistic(statistic)) {
|
||||
case DAMAGE -> Unit.fromString(config.getDamageUnit(false));
|
||||
|
@ -580,7 +606,9 @@ public final class MessageBuilder implements ApiFormatter {
|
|||
};
|
||||
}
|
||||
|
||||
/** Provides its own space in front of it! */
|
||||
/**
|
||||
* Provides its own space in front of it!
|
||||
*/
|
||||
private TextComponent getDistanceUnitComponent(Unit unit, Target target) {
|
||||
if (config.useTranslatableComponents()) {
|
||||
String unitKey = languageKeyHandler.getUnitKey(unit);
|
||||
|
@ -593,7 +621,9 @@ public final class MessageBuilder implements ApiFormatter {
|
|||
.append(componentFactory.statUnit(unit.getLabel(), target));
|
||||
}
|
||||
|
||||
/** Provides its own space in front of it! */
|
||||
/**
|
||||
* Provides its own space in front of it!
|
||||
*/
|
||||
private TextComponent getDamageUnitComponent(Unit unit, Target target) {
|
||||
if (unit == Unit.HEART) {
|
||||
TextComponent heartUnit;
|
||||
|
@ -668,11 +698,13 @@ public final class MessageBuilder implements ApiFormatter {
|
|||
}
|
||||
}
|
||||
|
||||
/** Get an ArrayList consisting of 2 or 4 timeUnits. The order of items is:
|
||||
<p>0. maxUnit</p>
|
||||
<p>1. minUnit</p>
|
||||
<p>2. maxHoverUnit</p>
|
||||
<p>3. minHoverUnit</p>*/
|
||||
/**
|
||||
* Get an ArrayList consisting of 2 or 4 timeUnits. The order of items is:
|
||||
* <p>0. maxUnit</p>
|
||||
* <p>1. minUnit</p>
|
||||
* <p>2. maxHoverUnit</p>
|
||||
* <p>3. minHoverUnit</p>
|
||||
*/
|
||||
private ArrayList<Unit> getTimeUnitRange(long statNumber) {
|
||||
ArrayList<Unit> unitRange = new ArrayList<>();
|
||||
if (!config.autoDetectTimeUnit(false)) {
|
||||
|
|
|
@ -24,9 +24,13 @@ import java.util.function.Function;
|
|||
|
||||
import static com.github.artemis.the.gr8.playerstats.enums.StandardMessage.*;
|
||||
|
||||
/** This class manages all PlayerStats output. It is the only place where messages are sent.
|
||||
It gets its messages from a {@link MessageBuilder} configured for either a Console or for Players
|
||||
(mainly to deal with the lack of hover-text, and for Bukkit consoles to make up for the lack of hex-colors).*/
|
||||
/**
|
||||
* This class manages all PlayerStats output. It is the only
|
||||
* place where messages are sent. It gets its messages from a
|
||||
* {@link MessageBuilder} configured for either a Console or
|
||||
* for Players (mainly to deal with the lack of hover-text,
|
||||
* and for Bukkit consoles to make up for the lack of hex-colors).
|
||||
* */
|
||||
public final class OutputManager implements InternalFormatter {
|
||||
|
||||
private static BukkitAudiences adventure;
|
||||
|
|
|
@ -11,8 +11,11 @@ import org.jetbrains.annotations.Nullable;
|
|||
|
||||
import static net.kyori.adventure.text.Component.text;
|
||||
|
||||
/** The {@link ComponentFactory} that is used to build messages for a Bukkit Console.
|
||||
Bukkit consoles don't support hex colors, unlike Paper consoles.*/
|
||||
/**
|
||||
* The {@link ComponentFactory} that is used to build messages for
|
||||
* a Bukkit Console. Bukkit consoles don't support hex colors,
|
||||
* unlike Paper consoles.
|
||||
*/
|
||||
public class BukkitConsoleComponentFactory extends ComponentFactory {
|
||||
|
||||
public BukkitConsoleComponentFactory(ConfigHandler config) {
|
||||
|
|
|
@ -22,9 +22,12 @@ import org.jetbrains.annotations.Nullable;
|
|||
|
||||
import static net.kyori.adventure.text.Component.*;
|
||||
|
||||
/** Creates Components with the desired formatting for the {@link MessageBuilder} to build messages with.
|
||||
This class can put Strings into formatted Components with TextColor
|
||||
and TextDecoration, or return empty Components with the desired formatting.*/
|
||||
/** Creates Components with the desired formatting for the
|
||||
* {@link MessageBuilder} to build messages with. This class
|
||||
* can put Strings into formatted Components with TextColor
|
||||
* and TextDecoration, or return empty Components with the
|
||||
* desired formatting.
|
||||
* */
|
||||
public class ComponentFactory {
|
||||
|
||||
private static ConfigHandler config;
|
||||
|
@ -76,7 +79,9 @@ public class ComponentFactory {
|
|||
return getColorFromString(config.getSharerNameDecoration(false));
|
||||
}
|
||||
|
||||
/** Returns [PlayerStats]. */
|
||||
/**
|
||||
* Returns [PlayerStats].
|
||||
*/
|
||||
public TextComponent pluginPrefix() {
|
||||
return text("[")
|
||||
.color(BRACKETS)
|
||||
|
@ -84,7 +89,9 @@ public class ComponentFactory {
|
|||
.append(text("]"));
|
||||
}
|
||||
|
||||
/** Returns [PlayerStats] surrounded by underscores on both sides. */
|
||||
/**
|
||||
* Returns [PlayerStats] surrounded by underscores on both sides.
|
||||
*/
|
||||
public TextComponent pluginPrefixAsTitle() {
|
||||
//12 underscores for both console and in-game
|
||||
return text("____________").color(UNDERSCORE)
|
||||
|
@ -94,12 +101,18 @@ public class ComponentFactory {
|
|||
.append(text("____________"));
|
||||
}
|
||||
|
||||
/** Returns a TextComponent with the input String as content, with color Gray and decoration Italic.*/
|
||||
/**
|
||||
* Returns a TextComponent with the input String as content,
|
||||
* with color Gray and decoration Italic.
|
||||
*/
|
||||
public TextComponent subTitle(String content) {
|
||||
return text(content).color(BRACKETS).decorate(TextDecoration.ITALIC);
|
||||
}
|
||||
|
||||
/** Returns a TextComponents in the style of a default plugin message, with color Medium_Blue. */
|
||||
/**
|
||||
* Returns a TextComponents in the style of a default plugin message,
|
||||
* with color Medium_Blue.
|
||||
*/
|
||||
public TextComponent message() {
|
||||
return text().color(MSG_MAIN).build();
|
||||
}
|
||||
|
@ -181,8 +194,12 @@ public class ComponentFactory {
|
|||
.build());
|
||||
}
|
||||
|
||||
/** @param prettyStatName a statName with underscores removed and each word capitalized
|
||||
@param prettySubStatName if present, a subStatName with underscores removed and each word capitalized*/
|
||||
/**
|
||||
* @param prettyStatName a statName with underscores removed and each
|
||||
* word capitalized
|
||||
* @param prettySubStatName if present, a subStatName with underscores
|
||||
* removed and each word capitalized
|
||||
*/
|
||||
public TextComponent statAndSubStatName(String prettyStatName, @Nullable String prettySubStatName, Target target) {
|
||||
TextComponent.Builder totalStatNameBuilder = getComponentBuilder(prettyStatName,
|
||||
getColorFromString(config.getStatNameDecoration(target, false)),
|
||||
|
@ -197,7 +214,9 @@ public class ComponentFactory {
|
|||
return totalStatNameBuilder.build();
|
||||
}
|
||||
|
||||
/** Returns a TextComponent with TranslatableComponent as a child.*/
|
||||
/**
|
||||
* Returns a TextComponent with TranslatableComponent as a child.
|
||||
* */
|
||||
public TextComponent statAndSubStatNameTranslatable(String statKey, @Nullable String subStatKey, Target target) {
|
||||
TextComponent.Builder totalStatNameBuilder = getComponentBuilder(null,
|
||||
getColorFromString(config.getStatNameDecoration(target, false)),
|
||||
|
@ -307,7 +326,9 @@ public class ComponentFactory {
|
|||
.build();
|
||||
}
|
||||
|
||||
/** Returns a TextComponent for the subStatName, or an empty component.*/
|
||||
/**
|
||||
* Returns a TextComponent for the subStatName, or an empty component.
|
||||
*/
|
||||
private TextComponent subStatName(@Nullable String prettySubStatName, Target target) {
|
||||
if (prettySubStatName == null) {
|
||||
return Component.empty();
|
||||
|
@ -322,7 +343,9 @@ public class ComponentFactory {
|
|||
}
|
||||
}
|
||||
|
||||
/** Returns a TranslatableComponent for the subStatName, or an empty component.*/
|
||||
/**
|
||||
* Returns a TranslatableComponent for the subStatName, or an empty component.
|
||||
*/
|
||||
private TextComponent subStatNameTranslatable(@Nullable String subStatKey, Target target) {
|
||||
if (subStatKey != null) {
|
||||
return getComponentBuilder(null,
|
||||
|
@ -337,18 +360,26 @@ public class ComponentFactory {
|
|||
return Component.empty();
|
||||
}
|
||||
|
||||
/** Construct a custom translation for kill_entity with the language key for commands.kill.success.single ("Killed %s").
|
||||
@return a TranslatableComponent Builder with the subStat Component as args.*/
|
||||
/**
|
||||
* Construct a custom translation for kill_entity with the language key
|
||||
* for commands.kill.success.single ("Killed %s").
|
||||
*
|
||||
* @return a TranslatableComponent Builder with the subStat Component as args.
|
||||
*/
|
||||
private TranslatableComponent.Builder killEntityBuilder(@NotNull TextComponent subStat) {
|
||||
return translatable()
|
||||
.key(LanguageKeyHandler.getAlternativeKeyForKillEntity()) //"Killed %s"
|
||||
.args(subStat);
|
||||
}
|
||||
|
||||
/** Construct a custom translation for entity_killed_by with the language keys for stat.minecraft.deaths
|
||||
("Number of Deaths") and book.byAuthor ("by %s").
|
||||
@return a TranslatableComponent Builder with stat.minecraft.deaths as key, with a ChildComponent
|
||||
with book.byAuthor as key and the subStat Component as args.*/
|
||||
/**
|
||||
* Construct a custom translation for entity_killed_by with the language
|
||||
* keys for stat.minecraft.deaths ("Number of Deaths") and book.byAuthor
|
||||
* ("by %s").
|
||||
*
|
||||
* @return a TranslatableComponent Builder with stat.minecraft.deaths as key,
|
||||
* with a ChildComponent with book.byAuthor as key and the subStat Component as args.
|
||||
*/
|
||||
private TranslatableComponent.Builder entityKilledByBuilder(@NotNull TextComponent subStat) {
|
||||
return translatable()
|
||||
.key(LanguageKeyHandler.getAlternativeKeyForEntityKilledBy()) //"Number of Deaths"
|
||||
|
|
|
@ -6,13 +6,18 @@ import net.kyori.adventure.text.*;
|
|||
import net.kyori.adventure.text.flattener.ComponentFlattener;
|
||||
import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer;
|
||||
|
||||
/** A small utility class for turning PlayerStats' custom Components into String. */
|
||||
/**
|
||||
* A small utility class for turning PlayerStats' custom Components into String.
|
||||
*/
|
||||
public final class ComponentUtils {
|
||||
|
||||
/** Returns a LegacyComponentSerializer that is capable of serializing TranslatableComponents,
|
||||
and capable of dealing with the custom language-keys I am using to improve the entity-related
|
||||
statistic names. This serializer will create a String with hex colors and styles, and it will
|
||||
turn language keys into prettified, readable English. */
|
||||
/**
|
||||
* Returns a LegacyComponentSerializer that is capable of serializing
|
||||
* TranslatableComponents, and capable of dealing with the custom
|
||||
* language-keys I am using to improve the entity-related statistic
|
||||
* names. This serializer will create a String with hex colors and styles,
|
||||
* and it will turn language keys into prettified, readable English.
|
||||
*/
|
||||
public static LegacyComponentSerializer getTranslatableComponentSerializer() {
|
||||
LegacyComponentSerializer serializer = getTextComponentSerializer();
|
||||
|
||||
|
|
|
@ -11,7 +11,9 @@ import java.util.List;
|
|||
|
||||
import static net.kyori.adventure.text.Component.text;
|
||||
|
||||
/** A fully constructed message with examples on how to use PlayerStats.*/
|
||||
/**
|
||||
* A fully constructed message with examples on how to use PlayerStats.
|
||||
*/
|
||||
public final class ExampleMessage implements TextComponent {
|
||||
|
||||
private final TextComponent exampleMessage;
|
||||
|
|
|
@ -13,7 +13,9 @@ import java.util.List;
|
|||
|
||||
import static net.kyori.adventure.text.Component.text;
|
||||
|
||||
/** The help message that explains how to use PlayerStats.*/
|
||||
/**
|
||||
* The help message that explains how to use PlayerStats.
|
||||
*/
|
||||
public final class HelpMessage implements TextComponent {
|
||||
|
||||
private final TextComponent helpMessage;
|
||||
|
|
|
@ -11,7 +11,9 @@ import java.util.Random;
|
|||
|
||||
import static net.kyori.adventure.text.Component.*;
|
||||
|
||||
/** A festive version of the {@link ComponentFactory}*/
|
||||
/**
|
||||
* A festive version of the {@link ComponentFactory}
|
||||
*/
|
||||
public class PrideComponentFactory extends ComponentFactory {
|
||||
|
||||
public PrideComponentFactory(ConfigHandler c) {
|
||||
|
|
|
@ -12,8 +12,11 @@ import org.jetbrains.annotations.NotNull;
|
|||
|
||||
import java.util.Random;
|
||||
|
||||
/**This class is just for fun and adds some silly names for players on my server.
|
||||
It does not impact the rest of the plugin, and will only be used for the players mentioned in here.*/
|
||||
/**
|
||||
* This class is just for fun and adds some silly names for
|
||||
* players on my server. It does not impact the rest of the plugin,
|
||||
* and will only be used for the players mentioned in here.
|
||||
*/
|
||||
public final class EasterEggProvider {
|
||||
|
||||
private static boolean isEnabled;
|
||||
|
|
|
@ -2,7 +2,10 @@ package com.github.artemis.the.gr8.playerstats.msg.msgutils;
|
|||
|
||||
import org.bukkit.map.MinecraftFont;
|
||||
|
||||
/** A small utility class that helps calculate how many dots to use to get the numbers of a top-statistic aligned. */
|
||||
/**
|
||||
* A small utility class that helps calculate how many dots
|
||||
* to use to get the numbers of a top-statistic aligned.
|
||||
*/
|
||||
public final class FontUtils {
|
||||
|
||||
private FontUtils() {
|
||||
|
|
|
@ -16,21 +16,25 @@ import java.io.File;
|
|||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
|
||||
/** A utility class that provides language keys to be put in a TranslatableComponent.*/
|
||||
/**
|
||||
*
|
||||
* A utility class that provides language keys to be
|
||||
* put in a TranslatableComponent.
|
||||
*/
|
||||
public final class LanguageKeyHandler {
|
||||
|
||||
private static Main plugin;
|
||||
private static HashMap<Statistic, String> statNameKeys;
|
||||
private static File languageKeyFile;
|
||||
private static FileConfiguration languageKeys;
|
||||
|
||||
public LanguageKeyHandler() {
|
||||
public LanguageKeyHandler(Main plugin) {
|
||||
LanguageKeyHandler.plugin = plugin;
|
||||
statNameKeys = generateStatNameKeys();
|
||||
|
||||
loadFile();
|
||||
}
|
||||
|
||||
private static void loadFile() {
|
||||
Main plugin = Main.getInstance();
|
||||
languageKeyFile = new File(plugin.getDataFolder(), "language.yml");
|
||||
if (!languageKeyFile.exists()) {
|
||||
plugin.saveResource("language.yml", false);
|
||||
|
@ -47,42 +51,57 @@ public final class LanguageKeyHandler {
|
|||
}
|
||||
}
|
||||
|
||||
/** Checks if a given Key is the language key "stat_type.minecraft.killed"
|
||||
or "commands.kill.success.single" (which results in "Killed %s").*/
|
||||
/**
|
||||
* Checks if a given Key is the language key "stat_type.minecraft.killed"
|
||||
* or "commands.kill.success.single" (which results in "Killed %s").
|
||||
*/
|
||||
public static boolean isKeyForKillEntity(String statKey) {
|
||||
return statKey.equalsIgnoreCase("stat_type.minecraft.killed") ||
|
||||
statKey.equalsIgnoreCase("commands.kill.success.single");
|
||||
}
|
||||
|
||||
/** Returns a language key to replace the default Statistic.Kill_Entity key.
|
||||
@return the key "commands.kill.success.single", which results in "Killed %s" */
|
||||
/**
|
||||
* Returns a language key to replace the default Statistic.Kill_Entity key.
|
||||
*
|
||||
* @return the key "commands.kill.success.single", which results in "Killed %s"
|
||||
*/
|
||||
public static String getAlternativeKeyForKillEntity() {
|
||||
return "commands.kill.success.single";
|
||||
}
|
||||
|
||||
/** Checks if a given Key is the language key "stat_type.minecraft.killed_by"
|
||||
or "stat.minecraft.deaths" (which results in "Number of Deaths").*/
|
||||
/**
|
||||
* Checks if a given Key is the language key "stat_type.minecraft.killed_by"
|
||||
* or "stat.minecraft.deaths" (which results in "Number of Deaths").
|
||||
*/
|
||||
public static boolean isKeyForEntityKilledBy(String statKey) {
|
||||
return statKey.equalsIgnoreCase("stat_type.minecraft.killed_by") ||
|
||||
statKey.equalsIgnoreCase("stat.minecraft.deaths");
|
||||
}
|
||||
|
||||
/** Returns a language key to replace the default Statistic.Entity_Killed_By key.
|
||||
@return the key "stat.minecraft.deaths", which results in "Number of Deaths"
|
||||
(meant to be followed by {@link #getAlternativeKeyForEntityKilledByArg()})*/
|
||||
/**
|
||||
* Returns a language key to replace the default Statistic.Entity_Killed_By key.
|
||||
*
|
||||
* @return the key "stat.minecraft.deaths", which results in "Number of Deaths"
|
||||
* (meant to be followed by {@link #getAlternativeKeyForEntityKilledByArg()})
|
||||
*/
|
||||
public static String getAlternativeKeyForEntityKilledBy() {
|
||||
return "stat.minecraft.deaths";
|
||||
}
|
||||
|
||||
/** Checks if a given Key is the language key "book.byAuthor"
|
||||
(which results in "by %s"). */
|
||||
/**
|
||||
* Checks if a given Key is the language key "book.byAuthor"
|
||||
* (which results in "by %s").
|
||||
*/
|
||||
public static boolean isKeyForEntityKilledByArg(String statKey) {
|
||||
return statKey.equalsIgnoreCase("book.byAuthor");
|
||||
}
|
||||
|
||||
/** Returns a language key to complete the alternative key for Statistic.Entity_Killed_By.
|
||||
@return the key "book.byAuthor", which results in "by %". If used after
|
||||
{@link #getAlternativeKeyForEntityKilledBy()}, you will get "Number of Deaths" "by %s"*/
|
||||
/**
|
||||
* Returns a language key to complete the alternative key for Statistic.Entity_Killed_By.
|
||||
*
|
||||
* @return the key "book.byAuthor", which results in "by %". If used after
|
||||
* {@link #getAlternativeKeyForEntityKilledBy()}, you will get "Number of Deaths" "by %s"
|
||||
*/
|
||||
public static String getAlternativeKeyForEntityKilledByArg() {
|
||||
return "book.byAuthor";
|
||||
}
|
||||
|
@ -144,8 +163,10 @@ public final class LanguageKeyHandler {
|
|||
}
|
||||
}
|
||||
|
||||
/** Get the official Key from the NameSpacedKey for this entityType,
|
||||
or return null if no enum constant can be retrieved or entityType is UNKNOWN.*/
|
||||
/**
|
||||
* Get the official Key from the NameSpacedKey for this entityType,
|
||||
* or return null if no enum constant can be retrieved or entityType is UNKNOWN.
|
||||
*/
|
||||
public @Nullable String getEntityKey(EntityType entity) {
|
||||
if (entity == null || entity == EntityType.UNKNOWN) return null;
|
||||
else {
|
||||
|
@ -153,8 +174,10 @@ public final class LanguageKeyHandler {
|
|||
}
|
||||
}
|
||||
|
||||
/** Get the official Key from the NameSpacedKey for this item Material,
|
||||
or return null if no enum constant can be retrieved.*/
|
||||
/**
|
||||
* Get the official Key from the NameSpacedKey for this item Material,
|
||||
* or return null if no enum constant can be retrieved.
|
||||
*/
|
||||
public @Nullable String getItemKey(Material item) {
|
||||
if (item == null) return null;
|
||||
else if (item.isBlock()) {
|
||||
|
@ -165,8 +188,10 @@ public final class LanguageKeyHandler {
|
|||
}
|
||||
}
|
||||
|
||||
/** Returns the official Key from the NameSpacedKey for the block Material provided,
|
||||
or return null if no enum constant can be retrieved.*/
|
||||
/**
|
||||
* Returns the official Key from the NameSpacedKey for the block Material provided,
|
||||
* or return null if no enum constant can be retrieved.
|
||||
*/
|
||||
public @Nullable String getBlockKey(Material block) {
|
||||
if (block == null) return null;
|
||||
else if (block.toString().toLowerCase().contains("wall_banner")) { //replace wall_banner with regular banner, since there is no key for wall banners
|
||||
|
|
|
@ -5,9 +5,10 @@ import com.github.artemis.the.gr8.playerstats.enums.Unit;
|
|||
import java.text.DecimalFormat;
|
||||
|
||||
/** A utility class that formats statistic numbers into something more readable.
|
||||
It transforms numbers of {@link Unit.Type} Time, Damage, and Distance into numbers
|
||||
that are easier to understand (for example: from ticks to hours) and adds commas
|
||||
to break up large numbers.*/
|
||||
* It transforms numbers of {@link Unit.Type} Time, Damage, and Distance into numbers
|
||||
* that are easier to understand (for example: from ticks to hours) and adds commas
|
||||
* to break up large numbers.
|
||||
*/
|
||||
public final class NumberFormatter {
|
||||
|
||||
private final DecimalFormat format;
|
||||
|
@ -19,14 +20,16 @@ public final class NumberFormatter {
|
|||
}
|
||||
|
||||
/** Turns the input number into a more readable format depending on its type
|
||||
(number-of-times, time-, damage- or distance-based) according to the
|
||||
corresponding config settings, and adds commas in groups of 3.*/
|
||||
* (number-of-times, time-, damage- or distance-based) according to the
|
||||
* corresponding config settings, and adds commas in groups of 3.
|
||||
*/
|
||||
public String formatNumber(long number) {
|
||||
return format.format(number);
|
||||
}
|
||||
|
||||
/** The unit of damage-based statistics is half a heart by default.
|
||||
This method turns the number into hearts. */
|
||||
* This method turns the number into hearts.
|
||||
*/
|
||||
public String formatDamageNumber(long number, Unit statUnit) { //7 statistics
|
||||
if (statUnit == Unit.HEART) {
|
||||
return format.format(Math.round(number / 2.0));
|
||||
|
@ -35,8 +38,11 @@ public final class NumberFormatter {
|
|||
}
|
||||
}
|
||||
|
||||
/** The unit of distance-based statistics is cm by default. This method turns it into blocks by default,
|
||||
and turns it into km or leaves it as cm otherwise, depending on the config settings. */
|
||||
/** The unit of distance-based statistics is cm by default.
|
||||
* This method turns it into blocks by default,
|
||||
* and turns it into km or leaves it as cm otherwise,
|
||||
* depending on the config settings.
|
||||
*/
|
||||
public String formatDistanceNumber(long number, Unit statUnit) { //15 statistics
|
||||
switch (statUnit) {
|
||||
case CM -> {
|
||||
|
@ -55,7 +61,10 @@ public final class NumberFormatter {
|
|||
}
|
||||
|
||||
/** The unit of time-based statistics is ticks by default.
|
||||
@return a String with the form "1D 2H 3M 4S" (depending on the Unit range selected)*/
|
||||
*
|
||||
* @return a String with the form "1D 2H 3M 4S"
|
||||
* (depending on the Unit range selected)
|
||||
*/
|
||||
public String formatTimeNumber(long number, Unit bigUnit, Unit smallUnit) { //5 statistics
|
||||
if (number == 0) {
|
||||
return "-";
|
||||
|
|
|
@ -2,14 +2,20 @@ package com.github.artemis.the.gr8.playerstats.msg.msgutils;
|
|||
|
||||
import com.github.artemis.the.gr8.playerstats.utils.MyLogger;
|
||||
|
||||
/** A small utility class that helps make enum constant names prettier for output in stat-messages.*/
|
||||
/**
|
||||
* A small utility class that helps make enum constant
|
||||
* names prettier for output in stat-messages.
|
||||
*/
|
||||
public final class StringUtils {
|
||||
|
||||
private StringUtils() {
|
||||
}
|
||||
|
||||
/** Replace "_" with " " and capitalize each first letter of the input.
|
||||
@param input String to prettify, case-insensitive*/
|
||||
/**
|
||||
* Replace "_" with " " and capitalize each first letter of the input.
|
||||
*
|
||||
* @param input String to prettify, case-insensitive
|
||||
*/
|
||||
public static String prettify(String input) {
|
||||
if (input == null) return null;
|
||||
StringBuilder capitals = new StringBuilder(input.toLowerCase());
|
||||
|
|
|
@ -9,7 +9,9 @@ import java.util.UUID;
|
|||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.RecursiveAction;
|
||||
|
||||
/** The action that is executed when a reload-command is triggered. */
|
||||
/**
|
||||
* The action that is executed when a reload-command is triggered.
|
||||
*/
|
||||
final class ReloadAction extends RecursiveAction {
|
||||
|
||||
private static int threshold;
|
||||
|
@ -21,10 +23,13 @@ final class ReloadAction extends RecursiveAction {
|
|||
private final int lastPlayedLimit;
|
||||
private final ConcurrentHashMap<String, UUID> offlinePlayerUUIDs;
|
||||
|
||||
/** Fills a ConcurrentHashMap with PlayerNames and UUIDs for all OfflinePlayers that should be included in statistic calculations.
|
||||
/**
|
||||
* Fills a ConcurrentHashMap with PlayerNames and UUIDs for all OfflinePlayers
|
||||
* that should be included in statistic calculations.
|
||||
*
|
||||
* @param players array of all OfflinePlayers (straight from Bukkit)
|
||||
* @param lastPlayedLimit whether to set a limit based on last-played-date
|
||||
* @param offlinePlayerUUIDs the ConcurrentHashMap to put resulting playerNames and UUIDs on
|
||||
* @param offlinePlayerUUIDs the ConcurrentHashMap to put playerNames and UUIDs in
|
||||
*/
|
||||
public ReloadAction(OfflinePlayer[] players,
|
||||
int lastPlayedLimit, ConcurrentHashMap<String, UUID> offlinePlayerUUIDs) {
|
||||
|
|
|
@ -45,11 +45,15 @@ public final class ReloadThread extends Thread {
|
|||
MyLogger.logHighLevelMsg(this.getName() + " created!");
|
||||
}
|
||||
|
||||
/** 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,
|
||||
update the offlinePlayerList in the {@link OfflinePlayerHandler}, update the {@link DebugLevel},
|
||||
update the share-settings in {@link ShareManager} and topListSize-settings in {@link StatCalculator},
|
||||
and update the MessageBuilders in the {@link OutputManager}.*/
|
||||
/**
|
||||
* 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, update the offlinePlayerList in the
|
||||
* {@link OfflinePlayerHandler}, update the {@link DebugLevel}, update
|
||||
* the share-settings in {@link ShareManager} and topListSize-settings
|
||||
* in {@link StatCalculator}, and update the MessageBuilders in the
|
||||
* {@link OutputManager}.
|
||||
*/
|
||||
@Override
|
||||
public void run() {
|
||||
long time = System.currentTimeMillis();
|
||||
|
|
|
@ -11,7 +11,9 @@ import java.util.*;
|
|||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.RecursiveTask;
|
||||
|
||||
/** The action that is executed when a stat-command is triggered. */
|
||||
/**
|
||||
* The action that is executed when a stat-command is triggered.
|
||||
*/
|
||||
final class StatAction extends RecursiveTask<ConcurrentHashMap<String, Integer>> {
|
||||
|
||||
private static int threshold;
|
||||
|
@ -23,7 +25,8 @@ final class StatAction extends RecursiveTask<ConcurrentHashMap<String, Integer>>
|
|||
|
||||
/**
|
||||
* Gets the statistic numbers for all players whose name is on the list, puts them in a ConcurrentHashMap
|
||||
* 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 playerNames ImmutableList of playerNames for players that should be included in stat calculations
|
||||
* @param requestSettings a validated requestSettings
|
||||
|
|
|
@ -46,8 +46,11 @@ public final class StatCalculator {
|
|||
return numbers.parallelStream().mapToLong(Integer::longValue).sum();
|
||||
}
|
||||
|
||||
/** Invokes a bunch of worker pool threads to divide and conquer (get the statistics for all players
|
||||
that are stored in the {@link OfflinePlayerHandler}) */
|
||||
/**
|
||||
* Invokes a bunch of worker pool threads to divide and conquer
|
||||
* (get the statistics for all players that are stored in the
|
||||
* {@link OfflinePlayerHandler})
|
||||
*/
|
||||
private @NotNull ConcurrentHashMap<String, Integer> getAllStatsAsync(RequestSettings requestSettings) {
|
||||
long time = System.currentTimeMillis();
|
||||
|
||||
|
|
|
@ -12,7 +12,9 @@ import org.jetbrains.annotations.Nullable;
|
|||
|
||||
import java.util.*;
|
||||
|
||||
/** The Thread that is in charge of getting and calculating statistics.*/
|
||||
/**
|
||||
* The Thread that is in charge of getting and calculating statistics.
|
||||
*/
|
||||
public final class StatThread extends Thread {
|
||||
|
||||
private static OutputManager outputManager;
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
package com.github.artemis.the.gr8.playerstats.statistic.request;
|
||||
|
||||
import com.github.artemis.the.gr8.playerstats.Main;
|
||||
import com.github.artemis.the.gr8.playerstats.enums.Target;
|
||||
import com.github.artemis.the.gr8.playerstats.utils.EnumHandler;
|
||||
import com.github.artemis.the.gr8.playerstats.utils.OfflinePlayerHandler;
|
||||
import com.github.artemis.the.gr8.playerstats.enums.Target;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.Statistic;
|
||||
import org.bukkit.command.CommandSender;
|
||||
|
@ -41,7 +41,7 @@ public final class RequestHandler {
|
|||
}
|
||||
|
||||
/**
|
||||
@param sender the CommandSender that requested this specific statistic
|
||||
* @param sender the CommandSender that requested this specific statistic
|
||||
*/
|
||||
public static RequestSettings getBasicInternalStatRequest(CommandSender sender) {
|
||||
RequestSettings request = RequestSettings.getBasicRequest(sender);
|
||||
|
@ -84,15 +84,19 @@ public final class RequestHandler {
|
|||
}
|
||||
|
||||
/**
|
||||
This will create a {@link RequestSettings} object from the provided args, with the requesting Player (or Console)
|
||||
as CommandSender. This CommandSender will receive feedback messages if the RequestSettings could not be created.
|
||||
|
||||
@param args an Array of args such as a CommandSender would put in Minecraft chat:
|
||||
<p>- a <code>statName</code> (example: "mine_block")</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>- if "player" was chosen, include a <code>playerName</code></p>
|
||||
@return the generated RequestSettings
|
||||
* This will create a {@link RequestSettings} object from the provided args,
|
||||
* with the requesting Player (or Console) as CommandSender. This CommandSender
|
||||
* will receive feedback messages if the RequestSettings could not be created.
|
||||
*
|
||||
* @param args an Array of args such as a CommandSender would put in Minecraft chat:
|
||||
* <ul>
|
||||
* <li> a <code>statName</code> (example: "mine_block")
|
||||
* <li> if applicable, a <code>subStatEntryName</code> (example: diorite)
|
||||
* <li> a <code>target</code> for this lookup: can be "top", "server", "player"
|
||||
* (or "me" to indicate the current CommandSender)
|
||||
* <li> if "player" was chosen, include a <code>playerName</code>
|
||||
* </ul>
|
||||
* @return the generated RequestSettings
|
||||
*/
|
||||
public RequestSettings getRequestFromArgs(String[] args) {
|
||||
EnumHandler enumHandler = Main.getEnumHandler();
|
||||
|
@ -134,9 +138,10 @@ public final class RequestHandler {
|
|||
}
|
||||
|
||||
/**
|
||||
Adjust the RequestSettings object if needed: unpack the playerFlag into a subStatEntry,
|
||||
try to retrieve the corresponding Enum Constant for any relevant block/entity/item,
|
||||
and remove any unnecessary subStatEntries.
|
||||
* Adjust the RequestSettings object if needed: unpack the playerFlag
|
||||
* into a subStatEntry, try to retrieve the corresponding Enum Constant
|
||||
* for any relevant block/entity/item, and remove any unnecessary
|
||||
* subStatEntries.
|
||||
*/
|
||||
private void patchRequest(RequestSettings requestSettings) {
|
||||
if (requestSettings.getStatistic() != null) {
|
||||
|
|
|
@ -10,22 +10,30 @@ 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>*/
|
||||
/**
|
||||
* The object PlayerStats uses to calculate and format the requested
|
||||
* statistic. The settings in this RequestSettings object can be
|
||||
* configured from two different sources:
|
||||
* <br>- Internally: by PlayerStats itself when /stat is called,
|
||||
* using the args provided by the CommandSender.
|
||||
* <br>- Externally: through the API methods provided by the
|
||||
* {@link RequestGenerator} interface.
|
||||
* <br>
|
||||
* <br>For this RequestSettings object to be valid, the following
|
||||
* values need to be set:
|
||||
* <ul>
|
||||
* <li> a {@link Statistic} <code>statistic</code> </li>
|
||||
* <li> if this Statistic is not of {@link Statistic.Type} Untyped,
|
||||
* a <code>subStatEntryName</code> needs to be set, together with one
|
||||
* of the following values:
|
||||
* <br>- for Type.Block: a {@link Material} <code>blockMaterial</code>
|
||||
* <br>- for Type.Item: a {@link Material} <code>itemMaterial</code>
|
||||
* <br>- for Type.Entity: an {@link EntityType} <code>entityType</code>
|
||||
* <li> a {@link Target} <code>target</code> (defaults to Top)
|
||||
* <li> if the <code>target</code> is Target.Player, a
|
||||
* <code>playerName</code> needs to be added
|
||||
* </ul>
|
||||
*/
|
||||
public final class RequestSettings {
|
||||
|
||||
private final CommandSender sender;
|
||||
|
@ -40,14 +48,15 @@ public final class RequestSettings {
|
|||
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
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
private RequestSettings(@NotNull CommandSender sender) {
|
||||
this.sender = sender;
|
||||
|
|
|
@ -7,10 +7,14 @@ import org.bukkit.Statistic;
|
|||
import org.bukkit.entity.EntityType;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/** Holds all the information PlayerStats needs to perform a lookup, and can be executed
|
||||
to get the results. Calling {@link #execute()} on a Top- or ServerRequest can take some
|
||||
time (especially if there is a substantial amount of OfflinePlayers on this particular server),
|
||||
so I strongly advice you to call this asynchronously! */
|
||||
/**
|
||||
* Holds all the information PlayerStats needs to perform
|
||||
* a lookup, and can be executed to get the results. Calling
|
||||
* {@link #execute()} on a Top- or ServerRequest can take some
|
||||
* time (especially if there is a substantial amount of
|
||||
* OfflinePlayers on this particular server), so I strongly
|
||||
* advice you to call this asynchronously!
|
||||
*/
|
||||
public abstract class StatRequest<T> {
|
||||
|
||||
protected final RequestSettings requestSettings;
|
||||
|
@ -19,38 +23,56 @@ public abstract class StatRequest<T> {
|
|||
requestSettings = request;
|
||||
}
|
||||
|
||||
/** Executes this StatRequest. Don't call this from the Main Thread!
|
||||
@return a StatResult containing the value of this lookup, both as numerical value
|
||||
and as formatted message*/
|
||||
/**
|
||||
* Executes this StatRequest. Don't call this from the Main Thread!
|
||||
*
|
||||
* @return a StatResult containing the value of this lookup, both as
|
||||
* numerical value and as formatted message
|
||||
*/
|
||||
public abstract StatResult<T> execute();
|
||||
|
||||
/** @return the Statistic this StatRequest will get the data of */
|
||||
/**
|
||||
* @return the Statistic this StatRequest will get the data of
|
||||
* */
|
||||
public Statistic getStatisticSetting() {
|
||||
return requestSettings.getStatistic();
|
||||
}
|
||||
|
||||
/** If the Statistic setting for this StatRequest is of Type.Block,
|
||||
this will get the Material that was set
|
||||
@return a Material for which #isBlock is true, or null if no Material was set*/
|
||||
/**
|
||||
* If the Statistic setting for this StatRequest is of Type.Block,
|
||||
* this will get the Material that was set.
|
||||
*
|
||||
* @return a Material for which #isBlock is true, or null if no
|
||||
* Material was set
|
||||
*/
|
||||
public @Nullable Material getBlockSetting() {
|
||||
return requestSettings.getBlock();
|
||||
}
|
||||
|
||||
/** If the Statistic setting for this StatRequest is of Type.Item,
|
||||
this will get the Material that was set
|
||||
@return a Material for which #isItem is true, or null if no Material was set*/
|
||||
/**
|
||||
* If the Statistic setting for this StatRequest is of Type.Item,
|
||||
* this will get the Material that was set.
|
||||
*
|
||||
* @return a Material for which #isItem is true, or null if no
|
||||
* Material was set
|
||||
*/
|
||||
public @Nullable Material getItemSetting() {
|
||||
return requestSettings.getItem();
|
||||
}
|
||||
|
||||
/** If the Statistic setting for this StatRequest is of Type.Entity,
|
||||
this will get the EntityType that was set
|
||||
@return an EntityType, or null if no EntityType was set*/
|
||||
/**
|
||||
* If the Statistic setting for this StatRequest is of Type.Entity,
|
||||
* this will get the EntityType that was set.
|
||||
*
|
||||
* @return an EntityType, or null if no EntityType was set
|
||||
*/
|
||||
public @Nullable EntityType getEntitySetting() {
|
||||
return requestSettings.getEntity();
|
||||
}
|
||||
|
||||
/** @return the Target for this lookup (either Player, Server or Top)*/
|
||||
/**
|
||||
* @return the Target for this lookup (either Player, Server or Top)
|
||||
*/
|
||||
public Target getTargetSetting() {
|
||||
return requestSettings.getTarget();
|
||||
}
|
||||
|
|
|
@ -3,13 +3,20 @@ package com.github.artemis.the.gr8.playerstats.statistic.result;
|
|||
import com.github.artemis.the.gr8.playerstats.msg.components.ComponentUtils;
|
||||
import net.kyori.adventure.text.TextComponent;
|
||||
|
||||
/** This Record is used to store stat-results internally, so Players can share them by clicking a share-button.*/
|
||||
/**
|
||||
* This Record is used to store stat-results internally,
|
||||
* so Players can share them by clicking a share-button.
|
||||
*/
|
||||
public record InternalStatResult(String executorName, TextComponent formattedValue, int ID) implements StatResult<Integer> {
|
||||
|
||||
/** Gets the ID number for this StatResult. Unlike for the other {@link StatResult} implementations,
|
||||
this one does not return the actual statistic data, because this implementation is meant for internal
|
||||
saving-and-sharing only. This method is only for Interface-consistency, InternalStatResult#ID is better.
|
||||
|
||||
/**
|
||||
* Gets the ID number for this StatResult. Unlike for the
|
||||
* other {@link StatResult} implementations, this one does
|
||||
* not return the actual statistic data, because this
|
||||
* implementation is meant for internal saving-and-sharing only.
|
||||
* This method is only for Interface-consistency,
|
||||
* InternalStatResult#ID is better.
|
||||
*
|
||||
@return Integer that represents this StatResult's ID number
|
||||
*/
|
||||
@Override
|
||||
|
|
|
@ -4,60 +4,73 @@ import com.github.artemis.the.gr8.playerstats.api.ApiFormatter;
|
|||
import net.kyori.adventure.platform.bukkit.BukkitAudiences;
|
||||
import net.kyori.adventure.text.TextComponent;
|
||||
|
||||
/** Holds the result of a completed stat-lookup. The <code>Type</code> parameter
|
||||
<code>T</code> of this StatResult represents the data type of the stored number:
|
||||
<ul>
|
||||
<li> <code>Integer</code> for playerStat
|
||||
<li> <code>Long</code> for serverStat
|
||||
<li> <code>LinkedHashMap(String, Integer)</code> for topStat
|
||||
</ul>
|
||||
You can get these raw numbers with {@link #getNumericalValue()}. Additionally,
|
||||
you can get a formatted message that contains the following information:
|
||||
<ul>
|
||||
<li> for playerStat:
|
||||
<br> [player-name]: [formatted-number] [stat-name] [sub-stat-name]
|
||||
<li> for serverStat:
|
||||
<br> [Total on] [server-name]: [formatted-number] [stat-name] [sub-stat-name]
|
||||
<li> for topStat:
|
||||
<br> [PlayerStats] [Top x] [stat-name] [sub-stat-name]
|
||||
<br> [1.] [player-name] [.....] [formatted-number]
|
||||
<br> [2.] [player-name] [.....] [formatted-number]
|
||||
<br> [3.] etc...
|
||||
</ul>
|
||||
/**
|
||||
* Holds the result of a completed stat-lookup. The <code>Type</code> parameter
|
||||
* <code>T</code> of this StatResult represents the data type of the stored number:
|
||||
* <ul>
|
||||
* <li> <code>Integer</code> for playerStat
|
||||
* <li> <code>Long</code> for serverStat
|
||||
* <li> <code>LinkedHashMap(String, Integer)</code> for topStat
|
||||
* </ul>
|
||||
* You can get these raw numbers with {@link #getNumericalValue()}. Additionally,
|
||||
* you can get a formatted message that contains the following information:
|
||||
* <ul>
|
||||
* <li> for playerStat:
|
||||
* <br> [player-name]: [formatted-number] [stat-name] [sub-stat-name]
|
||||
* <li> for serverStat:
|
||||
* <br> [Total on] [server-name]: [formatted-number] [stat-name] [sub-stat-name]
|
||||
* <li> for topStat:
|
||||
* <br> [PlayerStats] [Top x] [stat-name] [sub-stat-name]
|
||||
* <br> [1.] [player-name] [.....] [formatted-number]
|
||||
* <br> [2.] [player-name] [.....] [formatted-number]
|
||||
* <br> [3.] etc...
|
||||
* </ul>
|
||||
|
||||
By default, the resulting message is a {@link 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, and use that to send the desired Component.
|
||||
Normally you would have to add Adventure as a dependency to your project,
|
||||
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 <a href="https://docs.adventure.kyori.net/platform/bukkit.html">Adventure's website</a>.
|
||||
|
||||
<p>You can also use the provided {@link #getFormattedString()} method to get the same information
|
||||
in String-format. Don't use Adventure's .content() or .toString() methods on the Components
|
||||
- those won't get the actual message. And finally, if you want the results to be
|
||||
formatted differently, you can get an instance of the {@link ApiFormatter}.
|
||||
* By default, the resulting message is a {@link 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,
|
||||
* and use that to send the desired Component. Normally you would have to add
|
||||
* Adventure as a dependency to your project, but since the library is included
|
||||
* in PlayerStats, you can access it through the PlayerStatsAPI. 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>.
|
||||
*
|
||||
* <p>You can also use the provided {@link #getFormattedString()} method to
|
||||
* get the same information in String-format. Don't use Adventure's .content()
|
||||
* or .toString() methods on the Components - those won't get the actual
|
||||
* message. And finally, if you want the results to be formatted differently,
|
||||
* you can get an instance of the {@link ApiFormatter}.
|
||||
*/
|
||||
public interface StatResult<T> {
|
||||
|
||||
/** Gets the raw number for the completed stat-lookup this {@link StatResult} stores.
|
||||
|
||||
@return {@code Integer} for playerStat, {@code Long} for serverStat,
|
||||
and {@code LinkedHashMap<String, Integer>} for topStat*/
|
||||
/**
|
||||
* Gets the raw number for the completed stat-lookup this {@link StatResult}
|
||||
* stores.
|
||||
*
|
||||
* @return {@code Integer} for playerStat, {@code Long} for serverStat,
|
||||
* and {@code LinkedHashMap<String, Integer>} for topStat
|
||||
*/
|
||||
T getNumericalValue();
|
||||
|
||||
/** Gets the formatted message for the completed stat-lookup this {@link StatResult} stores.
|
||||
/**
|
||||
* Gets the formatted message for the completed stat-lookup this
|
||||
* {@link StatResult} stores.
|
||||
|
||||
@return a {@code TextComponent} message containing the formatted number.
|
||||
This message follows the same style/color/language settings that are specified in the
|
||||
PlayerStats config. See class description for more information. */
|
||||
* @return a {@code TextComponent} message containing the formatted number.
|
||||
* This message follows the same style/color/language settings that are
|
||||
* specified in the PlayerStats config. See class description for more
|
||||
* information.
|
||||
*/
|
||||
TextComponent getFormattedTextComponent();
|
||||
|
||||
/** Gets the formatted message for the completed stat-lookup this {@link StatResult} stores.
|
||||
/**
|
||||
* Gets the formatted message for the completed stat-lookup this
|
||||
* {@link StatResult} stores.
|
||||
|
||||
@return a String message containing the formatted number. This message follows
|
||||
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
|
||||
for more information.*/
|
||||
* @return a String message containing the formatted number. This message
|
||||
* follows 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 for more information.
|
||||
*/
|
||||
String getFormattedString();
|
||||
}
|
|
@ -12,11 +12,13 @@ import java.util.List;
|
|||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
/** This class deals with Bukkit Enumerators. It holds private lists of all
|
||||
block-, item-, entity- and statistic-names, and has one big list of all
|
||||
possible sub-statistic-entries (block/item/entity). It can give the names
|
||||
of all aforementioned enums, check if something is a valid enum constant,
|
||||
and turn a name into its corresponding enum constant. */
|
||||
/**
|
||||
* This class deals with Bukkit Enumerators. It holds private lists of all
|
||||
* block-, item-, entity- and statistic-names, and has one big list of all
|
||||
* possible sub-statistic-entries (block/item/entity). It can give the names
|
||||
* of all aforementioned enums, check if something is a valid enum constant,
|
||||
* and turn a name into its corresponding enum constant.
|
||||
*/
|
||||
public final class EnumHandler {
|
||||
|
||||
private static List<String> blockNames;
|
||||
|
@ -28,24 +30,33 @@ public final class EnumHandler {
|
|||
prepareLists();
|
||||
}
|
||||
|
||||
/** Returns all block-names in lowercase */
|
||||
/**
|
||||
* Returns all block-names in lowercase.
|
||||
*/
|
||||
public List<String> getBlockNames() {
|
||||
return blockNames;
|
||||
}
|
||||
|
||||
/** Returns all item-names in lowercase*/
|
||||
/**
|
||||
* Returns all item-names in lowercase.
|
||||
*/
|
||||
public List<String> getItemNames() {
|
||||
return itemNames;
|
||||
}
|
||||
|
||||
/** Returns all statistic-names in lowercase */
|
||||
/**
|
||||
* Returns all statistic-names in lowercase.
|
||||
*/
|
||||
public List<String> getStatNames() {
|
||||
return statNames;
|
||||
}
|
||||
|
||||
/** Returns the corresponding Material enum constant for an itemName
|
||||
@param itemName String, case-insensitive
|
||||
@return Material enum constant, uppercase */
|
||||
/**
|
||||
* Returns the corresponding Material enum constant for an itemName.
|
||||
*
|
||||
* @param itemName String, case-insensitive
|
||||
* @return Material enum constant, uppercase
|
||||
*/
|
||||
public static @Nullable Material getItemEnum(String itemName) {
|
||||
if (itemName == null) return null;
|
||||
|
||||
|
@ -53,9 +64,12 @@ public final class EnumHandler {
|
|||
return (item != null && item.isItem()) ? item : null;
|
||||
}
|
||||
|
||||
/** Returns the corresponding EntityType enum constant for an entityName
|
||||
@param entityName String, case-insensitive
|
||||
@return EntityType enum constant, uppercase */
|
||||
/**
|
||||
* Returns the corresponding EntityType enum constant for an entityName.
|
||||
*
|
||||
* @param entityName String, case-insensitive
|
||||
* @return EntityType enum constant, uppercase
|
||||
*/
|
||||
public static @Nullable EntityType getEntityEnum(String entityName) {
|
||||
try {
|
||||
return EntityType.valueOf(entityName.toUpperCase());
|
||||
|
@ -65,9 +79,12 @@ public final class EnumHandler {
|
|||
}
|
||||
}
|
||||
|
||||
/** Returns the corresponding Material enum constant for a materialName
|
||||
@param materialName String, case-insensitive
|
||||
@return Material enum constant, uppercase */
|
||||
/**
|
||||
* Returns the corresponding Material enum constant for a materialName.
|
||||
*
|
||||
* @param materialName String, case-insensitive
|
||||
* @return Material enum constant, uppercase
|
||||
*/
|
||||
public static @Nullable Material getBlockEnum(String materialName) {
|
||||
if (materialName == null) return null;
|
||||
|
||||
|
@ -75,8 +92,11 @@ public final class EnumHandler {
|
|||
return (block != null && block.isBlock()) ? block : null;
|
||||
}
|
||||
|
||||
/** Returns the statistic enum constant, or null if that failed.
|
||||
@param statName String, case-insensitive */
|
||||
/**
|
||||
* Returns the statistic enum constant, or null if that failed.
|
||||
*
|
||||
* @param statName String, case-insensitive
|
||||
*/
|
||||
public static @Nullable Statistic getStatEnum(@NotNull String statName) {
|
||||
try {
|
||||
return Statistic.valueOf(statName.toUpperCase());
|
||||
|
@ -86,25 +106,37 @@ public final class EnumHandler {
|
|||
}
|
||||
}
|
||||
|
||||
/** Checks if string is a valid statistic
|
||||
@param statName String, case-insensitive */
|
||||
/**
|
||||
* Checks if string is a valid statistic.
|
||||
*
|
||||
* @param statName String, case-insensitive
|
||||
*/
|
||||
public boolean isStatistic(@NotNull String statName) {
|
||||
return statNames.contains(statName.toLowerCase());
|
||||
}
|
||||
|
||||
/** Checks whether the given String equals the name of an entity-type statistic. */
|
||||
/**
|
||||
* Checks whether the given String equals the name of an entity-type statistic.
|
||||
*/
|
||||
public boolean isEntityStatistic(String statName) {
|
||||
return statName.equalsIgnoreCase(Statistic.ENTITY_KILLED_BY.toString()) ||
|
||||
statName.equalsIgnoreCase(Statistic.KILL_ENTITY.toString());
|
||||
}
|
||||
|
||||
/** Checks if this statistic is a subStatEntry, meaning it is a block, item or entity
|
||||
@param statName String, case-insensitive*/
|
||||
/**
|
||||
* Checks if this statistic is a subStatEntry, meaning it is a block,
|
||||
* item or entity.
|
||||
*
|
||||
* @param statName String, case-insensitive
|
||||
*/
|
||||
public boolean isSubStatEntry(@NotNull String statName) {
|
||||
return subStatNames.contains(statName.toLowerCase());
|
||||
}
|
||||
|
||||
/** Returns "block", "entity", "item", or "sub-statistic" if the provided Type is null. */
|
||||
/**
|
||||
* Returns "block", "entity", "item", or "sub-statistic" if the
|
||||
* provided Type is null.
|
||||
*/
|
||||
public static String getSubStatTypeName(Statistic.Type statType) {
|
||||
String subStat = "sub-statistic";
|
||||
if (statType == null) return subStat;
|
||||
|
|
|
@ -10,7 +10,9 @@ import java.util.Collections;
|
|||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
/** The PlayerStats Logger*/
|
||||
/**
|
||||
* The PlayerStats Logger
|
||||
*/
|
||||
public final class MyLogger {
|
||||
|
||||
private static final Logger logger;
|
||||
|
@ -28,11 +30,13 @@ public final class MyLogger {
|
|||
private MyLogger() {
|
||||
}
|
||||
|
||||
/** Sets the desired debugging level.
|
||||
<br>1 = low (only show unexpected errors)</br>
|
||||
<br>2 = medium (detail all encountered exceptions, log main tasks and show time taken)</br>
|
||||
<br>3 = high (log all tasks and time taken)</br>
|
||||
<br>Default: 1</br>*/
|
||||
/**
|
||||
* Sets the desired debugging level.
|
||||
* <br>1 = low (only show unexpected errors)
|
||||
* <br>2 = medium (detail all encountered exceptions, log main tasks and show time taken)
|
||||
* <br>3 = high (log all tasks and time taken)
|
||||
* <br>Default: 1
|
||||
*/
|
||||
public static void setDebugLevel(int level) {
|
||||
if (level == 2) {
|
||||
debugLevel = DebugLevel.MEDIUM;
|
||||
|
@ -65,12 +69,16 @@ public final class MyLogger {
|
|||
logger.warning(content);
|
||||
}
|
||||
|
||||
/** Log the encountered exception as a warning to console,
|
||||
with some information about which class/method caught it
|
||||
and with a printStackTrace if DebugLevel is HIGH.
|
||||
@param exception The encountered exception
|
||||
@param caughtBy The name of the class that caught the exception
|
||||
@param additionalInfo e.g. the method-name or line where the exception is caught */
|
||||
/**
|
||||
* Log the encountered exception as a warning to console,
|
||||
* with some information about which class/method caught it
|
||||
* and with a printStackTrace if DebugLevel is HIGH.
|
||||
*
|
||||
* @param exception The encountered exception
|
||||
* @param caughtBy The name of the class that caught the exception
|
||||
* @param additionalInfo e.g. the method-name or line where the
|
||||
* exception is caught
|
||||
*/
|
||||
public static void logException(@NotNull Exception exception, String caughtBy, @Nullable String additionalInfo) {
|
||||
String extraInfo = (additionalInfo != null) ? " [" + additionalInfo + "]" : "";
|
||||
String info = " (" + caughtBy + extraInfo + ")";
|
||||
|
@ -81,8 +89,13 @@ public final class MyLogger {
|
|||
}
|
||||
}
|
||||
|
||||
/** If DebugLevel is MEDIUM or HIGH, output to console that an action has started.
|
||||
@param taskLength Length of the action (in terms of units-to-process)*/
|
||||
/**
|
||||
* If DebugLevel is MEDIUM or HIGH, output to console that an
|
||||
* action has started.
|
||||
*
|
||||
* @param taskLength Length of the action (in terms of
|
||||
* units-to-process)
|
||||
*/
|
||||
public static void actionCreated(int taskLength) {
|
||||
if (debugLevel != DebugLevel.LOW) {
|
||||
threadNames = new ConcurrentHashMap<>();
|
||||
|
@ -90,9 +103,13 @@ public final class MyLogger {
|
|||
}
|
||||
}
|
||||
|
||||
/** Internally save the name of the executing thread for later logging of this action.
|
||||
The list of names is reset upon the start of every new action.
|
||||
@param threadName Name of the executing thread*/
|
||||
/**
|
||||
* Internally save the name of the executing thread for later
|
||||
* logging of this action. The list of names is reset upon the
|
||||
* start of every new action.
|
||||
*
|
||||
* @param threadName Name of the executing thread
|
||||
*/
|
||||
public static void subActionCreated(String threadName) {
|
||||
if (debugLevel == DebugLevel.HIGH) {
|
||||
if (!threadNames.containsKey(threadName)) {
|
||||
|
@ -101,8 +118,11 @@ public final class MyLogger {
|
|||
}
|
||||
}
|
||||
|
||||
/** Internally save the name of the executing thread for logging.
|
||||
@param threadName Name of the executing thread */
|
||||
/**
|
||||
* Internally save the name of the executing thread for logging.
|
||||
*
|
||||
* @param threadName Name of the executing thread
|
||||
*/
|
||||
public static void actionRunning(String threadName) {
|
||||
if (debugLevel != DebugLevel.LOW) {
|
||||
if (!threadNames.containsKey(threadName)) {
|
||||
|
@ -111,8 +131,11 @@ public final class MyLogger {
|
|||
}
|
||||
}
|
||||
|
||||
/** Output to console that an action has finished if DebugLevel is MEDIUM or higher.
|
||||
If DebugLevel is HIGH, also output the names of the threads that were used. */
|
||||
/**
|
||||
* Output to console that an action has finished if DebugLevel is
|
||||
* MEDIUM or higher. If DebugLevel is HIGH, also output the names
|
||||
* of the threads that were used.
|
||||
*/
|
||||
public static void actionFinished() {
|
||||
if (debugLevel != DebugLevel.LOW) {
|
||||
logger.info("Finished Recursive Action! In total " +
|
||||
|
@ -133,10 +156,13 @@ public final class MyLogger {
|
|||
printTime(className, methodName, startTime);
|
||||
}
|
||||
|
||||
/** Output to console how long a certain task has taken.
|
||||
@param className Name of the class executing the task
|
||||
@param methodName Name or description of the task
|
||||
@param startTime Timestamp marking the beginning of the task */
|
||||
/**
|
||||
* Output to console how long a certain task has taken.
|
||||
*
|
||||
* @param className Name of the class executing the task
|
||||
* @param methodName Name or description of the task
|
||||
* @param startTime Timestamp marking the beginning of the task
|
||||
*/
|
||||
private static void printTime(String className, String methodName, long startTime) {
|
||||
logger.info(className + " " + methodName + ": " + (System.currentTimeMillis() - startTime) + "ms");
|
||||
}
|
||||
|
|
|
@ -6,9 +6,12 @@ import org.bukkit.OfflinePlayer;
|
|||
import java.util.*;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
/** A utility class that deals with OfflinePlayers. It stores a list of all OfflinePlayer-names
|
||||
that need to be included in statistic calculations, and can retrieve the corresponding OfflinePlayer
|
||||
object for a given player-name.*/
|
||||
/**
|
||||
* A utility class that deals with OfflinePlayers. It stores a list
|
||||
* of all OfflinePlayer-names that need to be included in statistic
|
||||
* calculations, and can retrieve the corresponding OfflinePlayer
|
||||
* object for a given player-name.
|
||||
*/
|
||||
public final class OfflinePlayerHandler {
|
||||
|
||||
private static ConcurrentHashMap<String, UUID> offlinePlayerUUIDs;
|
||||
|
@ -22,6 +25,7 @@ public final class OfflinePlayerHandler {
|
|||
/**
|
||||
* Get a new HashMap that stores the players to include in stat calculations.
|
||||
* This HashMap is stored as a private variable in OfflinePlayerHandler.
|
||||
*
|
||||
* @param playerList ConcurrentHashMap with keys: playerNames and values: UUIDs
|
||||
*/
|
||||
public static void updateOfflinePlayerList(ConcurrentHashMap<String, UUID> playerList) {
|
||||
|
@ -29,27 +33,40 @@ public final class OfflinePlayerHandler {
|
|||
playerNames = Collections.list(offlinePlayerUUIDs.keys());
|
||||
}
|
||||
|
||||
/** Checks if a given playerName is on the private HashMap of players that should be included in statistic calculations
|
||||
@param playerName String, case-sensitive */
|
||||
/**
|
||||
* Checks if a given playerName is on the private HashMap of players
|
||||
* that should be included in statistic calculations.
|
||||
*
|
||||
* @param playerName String, case-sensitive
|
||||
*/
|
||||
public boolean isRelevantPlayer(String playerName) {
|
||||
return offlinePlayerUUIDs.containsKey(playerName);
|
||||
}
|
||||
|
||||
/** Returns the number of OfflinePlayers that are included in statistic calculations */
|
||||
/**
|
||||
* Returns the number of OfflinePlayers that are included in
|
||||
* statistic calculations
|
||||
*/
|
||||
public int getOfflinePlayerCount() {
|
||||
return offlinePlayerUUIDs.size();
|
||||
}
|
||||
|
||||
/** Get an ArrayList of names from all OfflinePlayers that should be included in statistic calculations */
|
||||
/**
|
||||
* Gets an ArrayList of names from all OfflinePlayers that should
|
||||
* be included in statistic calculations.
|
||||
*/
|
||||
public ArrayList<String> getOfflinePlayerNames() {
|
||||
return playerNames;
|
||||
}
|
||||
|
||||
/**
|
||||
* Uses the playerName to get the player's UUID from a private HashMap, and uses the UUID to get the corresponding OfflinePlayer Object.
|
||||
* Uses the playerName to get the player's UUID from a private HashMap,
|
||||
* and uses the UUID to get the corresponding OfflinePlayer Object.
|
||||
*
|
||||
* @param playerName name of the target player (case-sensitive)
|
||||
* @return OfflinePlayer
|
||||
* @throws IllegalArgumentException if this player is not on the list of players that should be included in statistic calculations
|
||||
* @throws IllegalArgumentException if this player is not on the list
|
||||
* of players that should be included in statistic calculations
|
||||
*/
|
||||
public OfflinePlayer getOfflinePlayer(String playerName) throws IllegalArgumentException {
|
||||
if (offlinePlayerUUIDs.get(playerName) != null) {
|
||||
|
|
|
@ -1,15 +1,24 @@
|
|||
package com.github.artemis.the.gr8.playerstats.utils;
|
||||
|
||||
/** A small utility class that calculates with unix time.*/
|
||||
/**
|
||||
* A small utility class that calculates with unix time.
|
||||
*/
|
||||
public final class UnixTimeHandler {
|
||||
|
||||
private UnixTimeHandler() {
|
||||
}
|
||||
|
||||
/** Calculates whether a player has played recently enough to fall within the lastPlayedLimit.
|
||||
If lastPlayedLimit == 0, this always returns true (since there is no limit).
|
||||
@param lastPlayed a long that represents the amount of milliseconds between the unix start point and the time this player last joined
|
||||
@param lastPlayedLimit a long that represents the maximum-number-of-days-since-last-joined */
|
||||
/**
|
||||
* Calculates whether a player has played recently enough
|
||||
* to fall within the lastPlayedLimit. If lastPlayedLimit == 0,
|
||||
* this always returns true (since there is no limit).
|
||||
*
|
||||
* @param lastPlayed a long that represents the amount of
|
||||
* milliseconds between the unix start point
|
||||
* and the time this player last joined
|
||||
* @param lastPlayedLimit a long that represents the maximum-
|
||||
* number-of-days-since-last-joined
|
||||
*/
|
||||
public static boolean hasPlayedSince(long lastPlayedLimit, long lastPlayed) {
|
||||
long maxLastPlayed = System.currentTimeMillis() - lastPlayedLimit * 24 * 60 * 60 * 1000;
|
||||
return lastPlayedLimit == 0 || lastPlayed >= maxLastPlayed;
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
main: com.github.artemis.the.gr8.playerstats.Main
|
||||
name: PlayerStats
|
||||
version: 1.6.1
|
||||
version: 1.7
|
||||
api-version: 1.13
|
||||
description: adds commands to view player statistics in chat
|
||||
author: Artemis_the_gr8
|
||||
|
|
Loading…
Reference in New Issue