mirror of
https://github.com/itHotL/PlayerStats.git
synced 2024-11-29 13:05:32 +01:00
Added feature to automatically detect the best unit to use (#80), improved MyLogger
This commit is contained in:
parent
31df67bc12
commit
6a040a9e82
@ -1,7 +1,6 @@
|
|||||||
package com.gmail.artemis.the.gr8.playerstats.commands;
|
package com.gmail.artemis.the.gr8.playerstats.commands;
|
||||||
|
|
||||||
import com.gmail.artemis.the.gr8.playerstats.ThreadManager;
|
import com.gmail.artemis.the.gr8.playerstats.ThreadManager;
|
||||||
import com.gmail.artemis.the.gr8.playerstats.enums.PluginColor;
|
|
||||||
import com.gmail.artemis.the.gr8.playerstats.enums.Target;
|
import com.gmail.artemis.the.gr8.playerstats.enums.Target;
|
||||||
import com.gmail.artemis.the.gr8.playerstats.utils.EnumHandler;
|
import com.gmail.artemis.the.gr8.playerstats.utils.EnumHandler;
|
||||||
import com.gmail.artemis.the.gr8.playerstats.statistic.StatRequest;
|
import com.gmail.artemis.the.gr8.playerstats.statistic.StatRequest;
|
||||||
@ -9,7 +8,6 @@ import com.gmail.artemis.the.gr8.playerstats.utils.OfflinePlayerHandler;
|
|||||||
import com.gmail.artemis.the.gr8.playerstats.msg.MessageWriter;
|
import com.gmail.artemis.the.gr8.playerstats.msg.MessageWriter;
|
||||||
import net.kyori.adventure.platform.bukkit.BukkitAudiences;
|
import net.kyori.adventure.platform.bukkit.BukkitAudiences;
|
||||||
import net.kyori.adventure.text.TextComponent;
|
import net.kyori.adventure.text.TextComponent;
|
||||||
import net.kyori.adventure.text.format.TextColor;
|
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.Material;
|
import org.bukkit.Material;
|
||||||
import org.bukkit.Statistic;
|
import org.bukkit.Statistic;
|
||||||
@ -22,8 +20,6 @@ import org.bukkit.entity.Player;
|
|||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
import static net.kyori.adventure.text.Component.text;
|
|
||||||
|
|
||||||
|
|
||||||
public class StatCommand implements CommandExecutor {
|
public class StatCommand implements CommandExecutor {
|
||||||
|
|
||||||
@ -47,16 +43,6 @@ public class StatCommand implements CommandExecutor {
|
|||||||
args[0].equalsIgnoreCase("example")) { //in case of "statistic examples", show examples
|
args[0].equalsIgnoreCase("example")) { //in case of "statistic examples", show examples
|
||||||
adventure.sender(sender).sendMessage(messageWriter.usageExamples(isBukkitConsole));
|
adventure.sender(sender).sendMessage(messageWriter.usageExamples(isBukkitConsole));
|
||||||
}
|
}
|
||||||
else if (args[0].equalsIgnoreCase("test")) {
|
|
||||||
TextComponent msg = text("Tier 1").color(PluginColor.GOLD.getColor())
|
|
||||||
.append(text("Tier 2").color(PluginColor.MEDIUM_GOLD.getColor())
|
|
||||||
.append(text("Tier 3").color(TextColor.fromHexString("#FFEA40"))
|
|
||||||
.append(text("Tier 4").color(PluginColor.LIGHT_GOLD.getColor()))
|
|
||||||
.append(text("Tier 3?")))
|
|
||||||
.append(text("Tier 2?")))
|
|
||||||
.append(text("Tier 1?"));
|
|
||||||
adventure.sender(sender).sendMessage(msg);
|
|
||||||
}
|
|
||||||
else {
|
else {
|
||||||
StatRequest request = generateRequest(sender, args);
|
StatRequest request = generateRequest(sender, args);
|
||||||
TextComponent issues = checkRequest(request, isBukkitConsole);
|
TextComponent issues = checkRequest(request, isBukkitConsole);
|
||||||
|
@ -104,7 +104,6 @@ public class ConfigHandler {
|
|||||||
return config.getBoolean("enable-hover-text", true);
|
return config.getBoolean("enable-hover-text", true);
|
||||||
}
|
}
|
||||||
|
|
||||||
//TODO Test these default units
|
|
||||||
public String getDistanceUnit(boolean isHoverText) {
|
public String getDistanceUnit(boolean isHoverText) {
|
||||||
return getUnitString(isHoverText, "blocks", "km", "distance-unit");
|
return getUnitString(isHoverText, "blocks", "km", "distance-unit");
|
||||||
}
|
}
|
||||||
@ -113,19 +112,37 @@ public class ConfigHandler {
|
|||||||
return getUnitString(isHoverText, "hearts", "hp", "damage-unit");
|
return getUnitString(isHoverText, "hearts", "hp", "damage-unit");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean autoDetectTimeUnit(boolean isHoverText) {
|
||||||
|
String path = "auto-detect-biggest-time-unit";
|
||||||
|
if (isHoverText) {
|
||||||
|
path = path + "-for-hover-text";
|
||||||
|
}
|
||||||
|
boolean defaultValue = !isHoverText;
|
||||||
|
return config.getBoolean(path, defaultValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getNumberOfExtraTimeUnits(boolean isHoverText) {
|
||||||
|
String path = "number-of-extra-units";
|
||||||
|
if (isHoverText) {
|
||||||
|
path = path + "-for-hover-text";
|
||||||
|
}
|
||||||
|
int defaultValue = isHoverText ? 0 : 1;
|
||||||
|
return config.getInt(path, defaultValue);
|
||||||
|
}
|
||||||
|
|
||||||
/** By default, getTimeUnit will return the maxUnit. If the optional minUnit flag is specified,
|
/** By default, getTimeUnit will return the maxUnit. If the optional minUnit flag is specified,
|
||||||
the minimum unit will be returned instead. */
|
the minimum unit will be returned instead. */
|
||||||
public String getTimeUnit(boolean isHoverText) {
|
public String getTimeUnit(boolean isHoverText) {
|
||||||
return getTimeUnit(isHoverText, false);
|
return getTimeUnit(isHoverText, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** By default, getTimeUnit will return the maxUnit. If the optional minUnit flag is specified,
|
/** By default, getTimeUnit will return the maxUnit. If the optional smallUnit flag is specified,
|
||||||
the minimum unit will be returned instead. */
|
the minimum unit will be returned instead. */
|
||||||
public String getTimeUnit(boolean isHoverText, boolean minUnit) {
|
public String getTimeUnit(boolean isHoverText, boolean smallUnit) {
|
||||||
if (minUnit) {
|
if (smallUnit) {
|
||||||
return getUnitString(isHoverText, "seconds", "min-time-unit");
|
return getUnitString(isHoverText, "hours", "seconds", "smallest-time-unit");
|
||||||
}
|
}
|
||||||
return getUnitString(isHoverText, "hours", "days", "max-time-unit");
|
return getUnitString(isHoverText, "days", "hours", "biggest-time-unit");
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Whether to use festive formatting, such as pride colors.
|
/** Whether to use festive formatting, such as pride colors.
|
||||||
@ -269,15 +286,6 @@ public class ConfigHandler {
|
|||||||
return getDecorationString(Target.TOP, getStyle, "dark_gray", "dots");
|
return getDecorationString(Target.TOP, getStyle, "dark_gray", "dots");
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Returns a String representing the Unit that should be used for a certain Unit.Type.
|
|
||||||
If no String can be retrieved from the config, the supplied defaultValue will be returned.
|
|
||||||
@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 pathName the config path to retrieve the value from*/
|
|
||||||
private String getUnitString(boolean isHoverText, String defaultValue, String pathName) {
|
|
||||||
return getUnitString(isHoverText, defaultValue, null, pathName);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Returns a String representing the Unit that should be used for a certain Unit.Type.
|
/** Returns a String representing the Unit that should be used for a certain Unit.Type.
|
||||||
If no String can be retrieved from the config, the supplied defaultValue will be returned.
|
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.
|
If the defaultValue is different for hoverText, an optional String defaultHoverValue can be supplied.
|
||||||
|
@ -3,142 +3,146 @@ package com.gmail.artemis.the.gr8.playerstats.enums;
|
|||||||
import org.bukkit.Statistic;
|
import org.bukkit.Statistic;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
|
||||||
public enum Unit {
|
public enum Unit {
|
||||||
NUMBER (Type.UNTYPED),
|
NUMBER (Type.UNTYPED, "Times"),
|
||||||
CM (Type.DISTANCE),
|
KM (Type.DISTANCE, "km"),
|
||||||
BLOCK (Type.DISTANCE),
|
MILE (Type.DISTANCE, "Miles"),
|
||||||
MILE (Type.DISTANCE),
|
BLOCK (Type.DISTANCE, "Blocks"),
|
||||||
KM (Type.DISTANCE),
|
CM (Type.DISTANCE, "cm"),
|
||||||
HP (Type.DAMAGE),
|
HP (Type.DAMAGE, "HP"),
|
||||||
HEART (Type.DAMAGE),
|
HEART (Type.DAMAGE, "Hearts"),
|
||||||
TICK (Type.TIME),
|
DAY (Type.TIME, "days"),
|
||||||
SECOND (Type.TIME, 1),
|
HOUR (Type.TIME, "hours"),
|
||||||
MINUTE (Type.TIME, 60),
|
MINUTE (Type.TIME, "minutes"),
|
||||||
HOUR (Type.TIME, 3600),
|
SECOND (Type.TIME, "seconds"),
|
||||||
DAY (Type.TIME, 86400),
|
TICK (Type.TIME, "ticks");
|
||||||
WEEK (Type.TIME, 604800);
|
|
||||||
|
|
||||||
private final Type type;
|
private final Type type;
|
||||||
private final int seconds;
|
private final String label;
|
||||||
|
|
||||||
Unit(Type type) {
|
Unit(Type type, String label) {
|
||||||
this(type, -1);
|
|
||||||
}
|
|
||||||
|
|
||||||
Unit(Type type, int seconds) {
|
|
||||||
this.type = type;
|
this.type = type;
|
||||||
this.seconds = seconds;
|
this.label = label;
|
||||||
}
|
|
||||||
|
|
||||||
public Type getType() {
|
|
||||||
return type;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Returns the given Unit in seconds, or -1 if the Unit is not a TimeUnit.*/
|
|
||||||
public int getTimeInSeconds() {
|
|
||||||
return this.seconds;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Returns a pretty name belonging to this enum constant. If the Unit is
|
/** Returns a pretty name belonging to this enum constant. If the Unit is
|
||||||
NUMBER, it will return an empty String. */
|
NUMBER, it will return null. */
|
||||||
public @NotNull String getName() throws NullPointerException {
|
public String getLabel() {
|
||||||
|
return this.label;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Type getType() {
|
||||||
|
return this.type;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Unit getSmallerUnit(int stepsSmaller) {
|
||||||
switch (this) {
|
switch (this) {
|
||||||
case CM -> {
|
|
||||||
return "cm";
|
|
||||||
}
|
|
||||||
case BLOCK -> {
|
|
||||||
return "Blocks";
|
|
||||||
}
|
|
||||||
case MILE -> {
|
|
||||||
return "Miles";
|
|
||||||
}
|
|
||||||
case KM -> {
|
|
||||||
return "km";
|
|
||||||
}
|
|
||||||
case HP -> {
|
|
||||||
return "HP";
|
|
||||||
}
|
|
||||||
case HEART -> {
|
|
||||||
return "Hearts";
|
|
||||||
}
|
|
||||||
case TICK -> {
|
|
||||||
return "ticks";
|
|
||||||
}
|
|
||||||
case SECOND -> {
|
|
||||||
return "seconds";
|
|
||||||
}
|
|
||||||
case MINUTE -> {
|
|
||||||
return "minutes";
|
|
||||||
}
|
|
||||||
case DAY -> {
|
case DAY -> {
|
||||||
return "days";
|
if (stepsSmaller >= 3) {
|
||||||
|
return Unit.SECOND;
|
||||||
|
} else if (stepsSmaller == 2) {
|
||||||
|
return Unit.MINUTE;
|
||||||
|
} else if (stepsSmaller == 1) {
|
||||||
|
return Unit.HOUR;
|
||||||
|
} else {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
case HOUR -> {
|
case HOUR -> {
|
||||||
return "hours";
|
if (stepsSmaller >= 2) {
|
||||||
}
|
|
||||||
case WEEK -> {
|
|
||||||
return "weeks";
|
|
||||||
}
|
|
||||||
case NUMBER -> {
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
default ->
|
|
||||||
throw new NullPointerException("Trying to get the name of an enum constant that does not exist!");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static @NotNull Unit fromString(String unitName) {
|
|
||||||
switch (unitName.toLowerCase()) {
|
|
||||||
case "cm" -> {
|
|
||||||
return Unit.CM;
|
|
||||||
}
|
|
||||||
case "m", "block", "blocks" -> {
|
|
||||||
return Unit.BLOCK;
|
|
||||||
}
|
|
||||||
case "mile", "miles" -> {
|
|
||||||
return Unit.MILE;
|
|
||||||
}
|
|
||||||
case "km" -> {
|
|
||||||
return Unit.KM;
|
|
||||||
}
|
|
||||||
case "hp" -> {
|
|
||||||
return Unit.HP;
|
|
||||||
}
|
|
||||||
case "heart", "hearts" -> {
|
|
||||||
return Unit.HEART;
|
|
||||||
}
|
|
||||||
case "week", "weeks" -> {
|
|
||||||
return Unit.WEEK;
|
|
||||||
}
|
|
||||||
case "day", "days" -> {
|
|
||||||
return Unit.DAY;
|
|
||||||
}
|
|
||||||
case "hour", "hours" -> {
|
|
||||||
return Unit.HOUR;
|
|
||||||
}
|
|
||||||
case "minute", "minutes", "min" -> {
|
|
||||||
return Unit.MINUTE;
|
|
||||||
}
|
|
||||||
case "second", "seconds", "sec" -> {
|
|
||||||
return Unit.SECOND;
|
return Unit.SECOND;
|
||||||
|
} else if (stepsSmaller == 1) {
|
||||||
|
return Unit.MINUTE;
|
||||||
|
} else {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case MINUTE -> {
|
||||||
|
if (stepsSmaller >= 1) {
|
||||||
|
return Unit.SECOND;
|
||||||
|
} else {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case KM -> {
|
||||||
|
if (stepsSmaller >= 2) {
|
||||||
|
return Unit.CM;
|
||||||
|
} else if (stepsSmaller == 1) {
|
||||||
|
return Unit.BLOCK;
|
||||||
|
} else {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case BLOCK -> {
|
||||||
|
if (stepsSmaller >= 1) {
|
||||||
|
return Unit.CM;
|
||||||
|
} else {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case HEART -> {
|
||||||
|
if (stepsSmaller >= 1) {
|
||||||
|
return Unit.HP;
|
||||||
|
} else {
|
||||||
|
return this;
|
||||||
}
|
}
|
||||||
case "tick", "ticks" -> {
|
|
||||||
return Unit.TICK;
|
|
||||||
}
|
}
|
||||||
default -> {
|
default -> {
|
||||||
return Unit.NUMBER;
|
return this;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static @NotNull Type fromStatistic(Statistic statistic) {
|
public double getSeconds() {
|
||||||
return fromStatName(statistic.toString());
|
switch (this) {
|
||||||
|
case DAY -> {
|
||||||
|
return 86400;
|
||||||
|
}
|
||||||
|
case HOUR -> {
|
||||||
|
return 3600;
|
||||||
|
}
|
||||||
|
case MINUTE -> {
|
||||||
|
return 60;
|
||||||
|
}
|
||||||
|
case SECOND -> {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
case TICK -> {
|
||||||
|
return 1 / 20.0;
|
||||||
|
}
|
||||||
|
default -> {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 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) {
|
||||||
|
Unit unit;
|
||||||
|
switch (unitName.toLowerCase()) {
|
||||||
|
case "cm" -> unit = Unit.CM;
|
||||||
|
case "m", "block", "blocks" -> unit = Unit.BLOCK;
|
||||||
|
case "mile", "miles" -> unit = Unit.MILE;
|
||||||
|
case "km" -> unit = Unit.KM;
|
||||||
|
case "hp" -> unit = Unit.HP;
|
||||||
|
case "heart", "hearts" -> unit = Unit.HEART;
|
||||||
|
case "day", "days" -> unit = Unit.DAY;
|
||||||
|
case "hour", "hours" -> unit = Unit.HOUR;
|
||||||
|
case "minute", "minutes", "min" -> unit = Unit.MINUTE;
|
||||||
|
case "second", "seconds", "sec" -> unit = Unit.SECOND;
|
||||||
|
case "tick", "ticks" -> unit = Unit.TICK;
|
||||||
|
default -> unit = Unit.NUMBER;
|
||||||
|
}
|
||||||
|
return unit;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Returns the Unit.Type of this Statistic, which can be Untyped, Distance, Damage, or Time.
|
/** Returns the Unit.Type of this Statistic, which can be Untyped, Distance, Damage, or Time.
|
||||||
@param statName the name of the Statistic enum constant in String*/
|
@param statistic the Statistic enum constant*/
|
||||||
public static @NotNull Type fromStatName(String statName) {
|
public static @NotNull Type getTypeFromStatistic(Statistic statistic) {
|
||||||
String name = statName.toLowerCase();
|
String name = statistic.toString().toLowerCase();
|
||||||
if (name.contains("one_cm")) {
|
if (name.contains("one_cm")) {
|
||||||
return Type.DISTANCE;
|
return Type.DISTANCE;
|
||||||
} else if (name.contains("damage")) {
|
} else if (name.contains("damage")) {
|
||||||
@ -150,6 +154,39 @@ public enum Unit {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Returns the most suitable timeUnit 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 -> {
|
||||||
|
long statNumber = number / 20;
|
||||||
|
if (statNumber >= 86400) {
|
||||||
|
return Unit.DAY;
|
||||||
|
} else if (statNumber >= 3600) {
|
||||||
|
return Unit.HOUR;
|
||||||
|
} else if (statNumber >= 60) {
|
||||||
|
return Unit.MINUTE;
|
||||||
|
} else {
|
||||||
|
return Unit.SECOND;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case DISTANCE -> {
|
||||||
|
if (number >= 100000) {
|
||||||
|
return Unit.KM;
|
||||||
|
} else {
|
||||||
|
return Unit.BLOCK;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case DAMAGE -> {
|
||||||
|
return Unit.HEART;
|
||||||
|
}
|
||||||
|
default -> {
|
||||||
|
return Unit.NUMBER;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public enum Type{
|
public enum Type{
|
||||||
DAMAGE, //7 statistics
|
DAMAGE, //7 statistics
|
||||||
DISTANCE, //15 statistics
|
DISTANCE, //15 statistics
|
||||||
|
@ -159,7 +159,7 @@ public class ComponentFactory {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//TODO Add hoverComponent with full number
|
//TODO Add hoverComponent with full number
|
||||||
public TextComponent.Builder statNumberComponent(String prettyNumber, Target selection) {
|
public TextComponent.Builder statNumberBuilder(String prettyNumber, Target selection) {
|
||||||
return getComponentBuilder(prettyNumber,
|
return getComponentBuilder(prettyNumber,
|
||||||
getColorFromString(config.getStatNumberDecoration(selection, false)),
|
getColorFromString(config.getStatNumberDecoration(selection, false)),
|
||||||
getStyleFromString(config.getStatNumberDecoration(selection, true)));
|
getStyleFromString(config.getStatNumberDecoration(selection, true)));
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
package com.gmail.artemis.the.gr8.playerstats.msg;
|
package com.gmail.artemis.the.gr8.playerstats.msg;
|
||||||
|
|
||||||
|
import com.gmail.artemis.the.gr8.playerstats.enums.DebugLevel;
|
||||||
import com.gmail.artemis.the.gr8.playerstats.enums.Target;
|
import com.gmail.artemis.the.gr8.playerstats.enums.Target;
|
||||||
import com.gmail.artemis.the.gr8.playerstats.config.ConfigHandler;
|
import com.gmail.artemis.the.gr8.playerstats.config.ConfigHandler;
|
||||||
import com.gmail.artemis.the.gr8.playerstats.enums.Unit;
|
import com.gmail.artemis.the.gr8.playerstats.enums.Unit;
|
||||||
@ -127,21 +128,23 @@ public class MessageWriter {
|
|||||||
.append(getStatNameComponent(request))
|
.append(getStatNameComponent(request))
|
||||||
.append(getStatUnitComponent(request.getStatistic(), request.getSelection()));
|
.append(getStatUnitComponent(request.getStatistic(), request.getSelection()));
|
||||||
|
|
||||||
|
ArrayList<Unit> timeUnits = null;
|
||||||
|
if (Unit.getTypeFromStatistic(request.getStatistic()) == Unit.Type.TIME) {
|
||||||
|
timeUnits = getTimeUnitRange(topStats.values().iterator().next());
|
||||||
|
}
|
||||||
boolean useDots = config.useDots();
|
boolean useDots = config.useDots();
|
||||||
boolean boldNames = config.playerNameIsBold();
|
boolean boldNames = config.playerNameIsBold();
|
||||||
|
|
||||||
Set<String> playerNames = topStats.keySet();
|
|
||||||
MinecraftFont font = new MinecraftFont();
|
MinecraftFont font = new MinecraftFont();
|
||||||
|
Set<String> playerNames = topStats.keySet();
|
||||||
|
|
||||||
int count = 0;
|
int count = 0;
|
||||||
for (String playerName : playerNames) {
|
for (String playerName : playerNames) {
|
||||||
TextComponent.Builder playerNameBuilder = componentFactory.playerNameBuilder(playerName, Target.TOP);
|
TextComponent.Builder playerNameBuilder = componentFactory.playerNameBuilder(playerName, Target.TOP);
|
||||||
count = count+1;
|
count++;
|
||||||
|
|
||||||
topList.append(newline())
|
topList.append(newline())
|
||||||
.append(componentFactory.rankingNumberComponent(count + ". "))
|
.append(componentFactory.rankingNumberComponent(count + ". "))
|
||||||
.append(playerNameBuilder);
|
.append(playerNameBuilder);
|
||||||
|
|
||||||
if (useDots) {
|
if (useDots) {
|
||||||
topList.append(space());
|
topList.append(space());
|
||||||
TextComponent.Builder dotsBuilder = componentFactory.dotsBuilder();
|
TextComponent.Builder dotsBuilder = componentFactory.dotsBuilder();
|
||||||
@ -154,16 +157,16 @@ public class MessageWriter {
|
|||||||
dots = (int) Math.round((130.0 - font.getWidth(count + ". ") - (font.getWidth(playerName) * 1.19))/2);
|
dots = (int) Math.round((130.0 - font.getWidth(count + ". ") - (font.getWidth(playerName) * 1.19))/2);
|
||||||
}
|
}
|
||||||
if (dots >= 1) {
|
if (dots >= 1) {
|
||||||
topList.append(dotsBuilder
|
topList.append(dotsBuilder.append(text((".".repeat(dots)))));
|
||||||
.append(text((".".repeat(dots)))));
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
topList.append(playerNameBuilder
|
topList.append(playerNameBuilder.append(text(":")));
|
||||||
.append(text(":")));
|
}
|
||||||
|
if (timeUnits != null) {
|
||||||
|
topList.append(space()).append(getTimeNumberComponent(topStats.get(playerName), request.getSelection(), timeUnits));
|
||||||
|
} else {
|
||||||
|
topList.append(space()).append(getStatNumberComponent(request.getStatistic(), topStats.get(playerName), Target.TOP));
|
||||||
}
|
}
|
||||||
topList.append(space())
|
|
||||||
.append(getStatNumberComponent(request.getStatistic(), topStats.get(playerName), Target.TOP));
|
|
||||||
|
|
||||||
}
|
}
|
||||||
return topList.build();
|
return topList.build();
|
||||||
}
|
}
|
||||||
@ -207,53 +210,90 @@ public class MessageWriter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private TextComponent getStatNumberComponent(Statistic statistic, long statNumber, Target selection) {
|
private TextComponent getStatNumberComponent(Statistic statistic, long statNumber, Target selection) {
|
||||||
Unit.Type type = Unit.fromStatistic(statistic);
|
Unit.Type type = Unit.getTypeFromStatistic(statistic);
|
||||||
Unit statUnit;
|
Unit statUnit;
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case DISTANCE -> statUnit = Unit.fromString(config.getDistanceUnit(false));
|
case DISTANCE -> statUnit = Unit.fromString(config.getDistanceUnit(false));
|
||||||
case DAMAGE -> statUnit = Unit.fromString(config.getDamageUnit(false));
|
case DAMAGE -> statUnit = Unit.fromString(config.getDamageUnit(false));
|
||||||
case TIME -> {
|
case TIME -> {
|
||||||
return getTimeNumberComponent(statNumber, selection);
|
return getTimeNumberComponent(statNumber, selection, getTimeUnitRange(statNumber));
|
||||||
}
|
}
|
||||||
default -> statUnit = Unit.NUMBER;
|
default -> statUnit = Unit.NUMBER;
|
||||||
}
|
}
|
||||||
String prettyNumber = formatter.format(statNumber, statUnit);
|
String prettyNumber = formatter.format(statNumber, statUnit);
|
||||||
if (!config.useHoverText() || statUnit == Unit.NUMBER) {
|
if (!config.useHoverText() || statUnit == Unit.NUMBER) {
|
||||||
return componentFactory.statNumberComponent(prettyNumber, selection).build();
|
return componentFactory.statNumberBuilder(prettyNumber, selection).build();
|
||||||
}
|
}
|
||||||
Unit hoverUnit = type == Unit.Type.DISTANCE ? Unit.fromString(config.getDistanceUnit(true)) :
|
Unit hoverUnit = type == Unit.Type.DISTANCE ? Unit.fromString(config.getDistanceUnit(true)) :
|
||||||
Unit.fromString(config.getDamageUnit(true));
|
Unit.fromString(config.getDamageUnit(true));
|
||||||
String prettyHoverNumber = formatter.format(statNumber, hoverUnit);
|
String prettyHoverNumber = formatter.format(statNumber, hoverUnit);
|
||||||
|
MyLogger.logMsg("mainNumber: " + prettyNumber + "\n" + "hoverNumber: " + prettyHoverNumber, DebugLevel.HIGH);
|
||||||
if (config.useTranslatableComponents()) {
|
if (config.useTranslatableComponents()) {
|
||||||
String unitKey = languageKeyHandler.getUnitKey(hoverUnit);
|
String unitKey = languageKeyHandler.getUnitKey(hoverUnit);
|
||||||
if (unitKey == null) {
|
if (unitKey == null) {
|
||||||
unitKey = hoverUnit.getName();
|
unitKey = hoverUnit.getLabel();
|
||||||
}
|
}
|
||||||
return componentFactory.statNumberHoverComponent(prettyNumber, prettyHoverNumber, null, unitKey, selection);
|
return componentFactory.statNumberHoverComponent(prettyNumber, prettyHoverNumber, null, unitKey, selection);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return componentFactory.statNumberHoverComponent(prettyNumber, prettyHoverNumber, hoverUnit.getName(), null, selection);
|
return componentFactory.statNumberHoverComponent(prettyNumber, prettyHoverNumber, hoverUnit.getLabel(), null, selection);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private TextComponent getTimeNumberComponent(long statNumber, Target selection) {
|
private TextComponent getTimeNumberComponent(long statNumber, Target selection, ArrayList<Unit> unitRange) {
|
||||||
Unit max = Unit.fromString(config.getTimeUnit(false));
|
if (unitRange.size() <= 1 || (config.useHoverText() && unitRange.size() <= 3)) {
|
||||||
Unit min = Unit.fromString(config.getTimeUnit(false, true));
|
MyLogger.logMsg(
|
||||||
String mainNumber = formatter.format(statNumber, max, min);
|
"There is something wrong with the time-units you specified, please check your config!",
|
||||||
|
true);
|
||||||
|
return componentFactory.statNumberBuilder("-", selection).build();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
String mainNumber = formatter.format(statNumber, unitRange.get(0), unitRange.get(1));
|
||||||
if (!config.useHoverText()) {
|
if (!config.useHoverText()) {
|
||||||
return componentFactory.statNumberComponent(mainNumber, selection).build();
|
return componentFactory.statNumberBuilder(mainNumber, selection).build();
|
||||||
} else {
|
} else {
|
||||||
Unit hoverMax = Unit.fromString(config.getTimeUnit(true));
|
String hoverNumber = formatter.format(statNumber, unitRange.get(2), unitRange.get(3));
|
||||||
Unit hoverMin = Unit.fromString(config.getTimeUnit(true, true));
|
MyLogger.logMsg("mainNumber: " + mainNumber + ", hoverNumber: " + hoverNumber, DebugLevel.HIGH);
|
||||||
return componentFactory.statNumberHoverComponent(mainNumber,
|
return componentFactory.statNumberHoverComponent(mainNumber, hoverNumber,
|
||||||
formatter.format(statNumber, hoverMax, hoverMin),
|
|
||||||
null, null, selection); //Time does not support translatable text,
|
null, null, selection); //Time does not support translatable text,
|
||||||
} //because the unit and number are so tightly interwoven.
|
} //because the unit and number are so tightly interwoven.
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 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)) {
|
||||||
|
unitRange.add(Unit.fromString(config.getTimeUnit(false)));
|
||||||
|
unitRange.add(Unit.fromString(config.getTimeUnit(false, true)));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
Unit bigUnit = Unit.getMostSuitableUnit(Unit.Type.TIME, statNumber);
|
||||||
|
unitRange.add(bigUnit);
|
||||||
|
unitRange.add(bigUnit.getSmallerUnit(config.getNumberOfExtraTimeUnits(false)));
|
||||||
|
}
|
||||||
|
if (config.useHoverText()) {
|
||||||
|
if (!config.autoDetectTimeUnit(true)) {
|
||||||
|
unitRange.add(Unit.fromString(config.getTimeUnit(true)));
|
||||||
|
unitRange.add(Unit.fromString(config.getTimeUnit(true, true)));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
Unit bigHoverUnit = Unit.getMostSuitableUnit(Unit.Type.TIME, statNumber);
|
||||||
|
unitRange.add(bigHoverUnit);
|
||||||
|
unitRange.add(bigHoverUnit.getSmallerUnit(config.getNumberOfExtraTimeUnits(true)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
MyLogger.logMsg("total selected unitRange for this statistic: " + unitRange, DebugLevel.MEDIUM);
|
||||||
|
return unitRange;
|
||||||
|
}
|
||||||
|
|
||||||
private TextComponent getStatUnitComponent(Statistic statistic, Target selection) {
|
private TextComponent getStatUnitComponent(Statistic statistic, Target selection) {
|
||||||
Unit statUnit;
|
Unit statUnit;
|
||||||
switch (Unit.fromStatistic(statistic)) {
|
switch (Unit.getTypeFromStatistic(statistic)) {
|
||||||
case DAMAGE -> statUnit = Unit.fromString(config.getDamageUnit(false));
|
case DAMAGE -> statUnit = Unit.fromString(config.getDamageUnit(false));
|
||||||
case DISTANCE -> statUnit = Unit.fromString(config.getDistanceUnit(false));
|
case DISTANCE -> statUnit = Unit.fromString(config.getDistanceUnit(false));
|
||||||
default -> {
|
default -> {
|
||||||
@ -268,7 +308,7 @@ public class MessageWriter {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
return Component.space()
|
return Component.space()
|
||||||
.append(componentFactory.statUnitComponent(statUnit.getName(), null, selection));
|
.append(componentFactory.statUnitComponent(statUnit.getLabel(), null, selection));
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 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. */
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package com.gmail.artemis.the.gr8.playerstats.msg;
|
package com.gmail.artemis.the.gr8.playerstats.msg;
|
||||||
|
|
||||||
import com.gmail.artemis.the.gr8.playerstats.enums.Unit;
|
import com.gmail.artemis.the.gr8.playerstats.enums.Unit;
|
||||||
|
|
||||||
import java.text.DecimalFormat;
|
import java.text.DecimalFormat;
|
||||||
|
|
||||||
public class NumberFormatter {
|
public class NumberFormatter {
|
||||||
@ -20,8 +21,8 @@ public class NumberFormatter {
|
|||||||
return format(number, statUnit, null);
|
return format(number, statUnit, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public String format(long number, Unit statUnit, Unit timeMinimumUnit) {
|
public String format(long number, Unit statUnit, Unit smallTimeUnit) {
|
||||||
if (timeMinimumUnit == null) {
|
if (smallTimeUnit == null) {
|
||||||
switch (statUnit.getType()) {
|
switch (statUnit.getType()) {
|
||||||
case DISTANCE -> {
|
case DISTANCE -> {
|
||||||
return formatDistance(number, statUnit);
|
return formatDistance(number, statUnit);
|
||||||
@ -34,7 +35,7 @@ public class NumberFormatter {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return formatTime(number, statUnit, timeMinimumUnit);
|
return formatTime(number, statUnit, smallTimeUnit);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -56,7 +57,7 @@ public class NumberFormatter {
|
|||||||
return format.format(number);
|
return format.format(number);
|
||||||
}
|
}
|
||||||
case MILE -> {
|
case MILE -> {
|
||||||
return format.format(Math.round(number / 160900.0)); //to get from CM to Miles
|
return format.format(Math.round(number / 160934.4)); //to get from CM to Miles
|
||||||
}
|
}
|
||||||
case KM -> {
|
case KM -> {
|
||||||
return format.format(Math.round(number / 100000.0)); //divide by 100 to get M, divide by 1000 to get KM
|
return format.format(Math.round(number / 100000.0)); //divide by 100 to get M, divide by 1000 to get KM
|
||||||
@ -67,33 +68,24 @@ public class NumberFormatter {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//TODO Fix spaces
|
|
||||||
/** The unit of time-based statistics is ticks by default.*/
|
/** The unit of time-based statistics is ticks by default.*/
|
||||||
private String formatTime(long number, Unit maxUnit, Unit minUnit) { //5 statistics
|
private String formatTime(long number, Unit bigUnit, Unit smallUnit) { //5 statistics
|
||||||
if (number == 0) {
|
if (number == 0) {
|
||||||
return "-";
|
return "-";
|
||||||
}
|
}
|
||||||
StringBuilder output = new StringBuilder();
|
if (bigUnit == Unit.TICK && smallUnit == Unit.TICK || bigUnit == Unit.NUMBER || smallUnit == Unit.NUMBER) {
|
||||||
int max = maxUnit.getTimeInSeconds();
|
return format.format(number);
|
||||||
int min = minUnit.getTimeInSeconds();
|
}
|
||||||
|
|
||||||
|
StringBuilder output = new StringBuilder();
|
||||||
|
double max = bigUnit.getSeconds();
|
||||||
|
double min = smallUnit.getSeconds();
|
||||||
double leftover = number / 20.0;
|
double leftover = number / 20.0;
|
||||||
|
|
||||||
if (isInRange(max, min, 604800) && leftover >= 604800) {
|
|
||||||
double weeks = leftover / 7 / 60 / 60 / 24;
|
|
||||||
leftover = leftover % (7 * 60 * 60 * 24);
|
|
||||||
if (minUnit == Unit.WEEK && leftover >= 302400) {
|
|
||||||
weeks++;
|
|
||||||
return output.append(format.format(Math.round(weeks)))
|
|
||||||
.append("w").toString();
|
|
||||||
}
|
|
||||||
output.append(format.format(Math.round(weeks)))
|
|
||||||
.append("w ");
|
|
||||||
}
|
|
||||||
if (isInRange(max, min, 86400) && leftover >= 86400) {
|
if (isInRange(max, min, 86400) && leftover >= 86400) {
|
||||||
double days = leftover / 60 / 60 / 24;
|
double days = leftover / 60 / 60 / 24;
|
||||||
leftover = leftover % (60 * 60 * 24);
|
leftover = leftover % (60 * 60 * 24);
|
||||||
if (minUnit == Unit.DAY) {
|
if (smallUnit == Unit.DAY && leftover >= 43200) {
|
||||||
days++;
|
days++;
|
||||||
return output.append(format.format(Math.round(days)))
|
return output.append(format.format(Math.round(days)))
|
||||||
.append("d").toString();
|
.append("d").toString();
|
||||||
@ -104,7 +96,7 @@ public class NumberFormatter {
|
|||||||
if (isInRange(max, min, 3600) && leftover >= 3600) {
|
if (isInRange(max, min, 3600) && leftover >= 3600) {
|
||||||
double hours = leftover / 60 / 60;
|
double hours = leftover / 60 / 60;
|
||||||
leftover = leftover % (60 * 60);
|
leftover = leftover % (60 * 60);
|
||||||
if (minUnit == Unit.HOUR) {
|
if (smallUnit == Unit.HOUR && leftover >= 1800) {
|
||||||
hours++;
|
hours++;
|
||||||
return output.append(format.format(Math.round(hours)))
|
return output.append(format.format(Math.round(hours)))
|
||||||
.append("h").toString();
|
.append("h").toString();
|
||||||
@ -115,7 +107,7 @@ public class NumberFormatter {
|
|||||||
if (isInRange(max, min, 60) && leftover >= 60) {
|
if (isInRange(max, min, 60) && leftover >= 60) {
|
||||||
double minutes = leftover / 60;
|
double minutes = leftover / 60;
|
||||||
leftover = leftover % 60;
|
leftover = leftover % 60;
|
||||||
if (minUnit == Unit.MINUTE) {
|
if (smallUnit == Unit.MINUTE && leftover >= 30) {
|
||||||
minutes++;
|
minutes++;
|
||||||
return output.append(format.format(Math.round(minutes)))
|
return output.append(format.format(Math.round(minutes)))
|
||||||
.append("m").toString();
|
.append("m").toString();
|
||||||
@ -130,7 +122,7 @@ public class NumberFormatter {
|
|||||||
return output.toString();
|
return output.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isInRange(int maxUnit, int minUnit, int unitToEvaluate) {
|
private boolean isInRange(double bigUnit, double smallUnit, double unitToEvaluate) {
|
||||||
return maxUnit >= unitToEvaluate && unitToEvaluate >= minUnit;
|
return bigUnit >= unitToEvaluate && unitToEvaluate >= smallUnit;
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -52,6 +52,10 @@ public class MyLogger {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void logMsg(String content) {
|
||||||
|
logMsg(content, DebugLevel.LOW, false);
|
||||||
|
}
|
||||||
|
|
||||||
public static void logMsg(String content, boolean logAsWarning) {
|
public static void logMsg(String content, boolean logAsWarning) {
|
||||||
logMsg(content, DebugLevel.LOW, logAsWarning);
|
logMsg(content, DebugLevel.LOW, logAsWarning);
|
||||||
}
|
}
|
||||||
@ -129,7 +133,7 @@ public class MyLogger {
|
|||||||
if (debugLevel != DebugLevel.LOW) {
|
if (debugLevel != DebugLevel.LOW) {
|
||||||
threadNames = new ConcurrentHashMap<>();
|
threadNames = new ConcurrentHashMap<>();
|
||||||
playersIndex.set(0);
|
playersIndex.set(0);
|
||||||
logger.info("Initial Action created for " + taskLength + " Players. Start Index is " + playersIndex.get() + ". Processing...");
|
logger.info("Initial Action created for " + taskLength + " Players. Processing...");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -161,7 +165,7 @@ public class MyLogger {
|
|||||||
}
|
}
|
||||||
processedPlayers[nextPlayersIndex() % 10] = playerName;
|
processedPlayers[nextPlayersIndex() % 10] = playerName;
|
||||||
}
|
}
|
||||||
else if (debugLevel == DebugLevel.MEDIUM) {
|
else if (debugLevel == DebugLevel.MEDIUM || debugLevel == DebugLevel.HIGH && thread == 2) {
|
||||||
nextPlayersIndex();
|
nextPlayersIndex();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -179,8 +183,10 @@ public class MyLogger {
|
|||||||
if (debugLevel != DebugLevel.LOW) {
|
if (debugLevel != DebugLevel.LOW) {
|
||||||
logger.info("Finished Recursive Action! In total " +
|
logger.info("Finished Recursive Action! In total " +
|
||||||
threadNames.size() + " Threads were used to process " +
|
threadNames.size() + " Threads were used to process " +
|
||||||
playersIndex.get() + " Players: " +
|
playersIndex.get() + " Players.");
|
||||||
Collections.list(threadNames.keys()));
|
}
|
||||||
|
if (debugLevel == DebugLevel.HIGH) {
|
||||||
|
logger.info(Collections.list(threadNames.keys()).toString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -43,15 +43,21 @@ distance-unit-for-hover-text: km
|
|||||||
damage-unit: hearts
|
damage-unit: hearts
|
||||||
damage-unit-for-hover-text: hp
|
damage-unit-for-hover-text: hp
|
||||||
|
|
||||||
# Minecraft measures time in ticks. PlayerStats supports: weeks, days, hours, minutes, seconds, ticks
|
# Minecraft measures time in ticks. With the below settings, PlayerStats will:
|
||||||
# Below you can choose a range between the maximum and minimum unit you want to see
|
# Auto-detect the best maximum unit to use (weeks/days/hours/minutes/seconds) for your players' statistics
|
||||||
# If the max and min are the same, only that unit will be displayed
|
# Show a specified amount of additional smaller units (example: "x days" would become "x days, y hours, z minutes")
|
||||||
# For example, 5.000.000 ticks would become "4D", "3D 21H 27M 40S", "69H 27M 40S", "4168M", etc.
|
auto-detect-biggest-time-unit: true
|
||||||
max-time-unit: hours
|
number-of-extra-units: 1
|
||||||
min-time-unit: seconds
|
auto-detect-biggest-time-unit-for-hover-text: false
|
||||||
|
number-of-extra-units-for-hover-text: 0
|
||||||
|
|
||||||
max-time-unit-for-hover-text: days
|
# If you don't want the unit to be auto-detected, set the auto-detect settings to false and specify your own range here
|
||||||
min-time-unit-for-hover-text: seconds
|
# If the max and min are the same, only that unit will be displayed
|
||||||
|
# PlayerStats supports: days, hours, minutes, seconds (and ticks if you want the original number)
|
||||||
|
biggest-time-unit: days
|
||||||
|
smallest-time-unit: hours
|
||||||
|
biggest-time-unit-for-hover-text: hours
|
||||||
|
smallest-time-unit-for-hover-text: seconds
|
||||||
|
|
||||||
# Automatically use themed formatting for the duration of certain holidays or festivals
|
# Automatically use themed formatting for the duration of certain holidays or festivals
|
||||||
enable-festive-formatting: true
|
enable-festive-formatting: true
|
||||||
|
Loading…
Reference in New Issue
Block a user