mirror of
https://github.com/itHotL/PlayerStats.git
synced 2024-11-26 12:36:16 +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;
|
||||
|
||||
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.utils.EnumHandler;
|
||||
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 net.kyori.adventure.platform.bukkit.BukkitAudiences;
|
||||
import net.kyori.adventure.text.TextComponent;
|
||||
import net.kyori.adventure.text.format.TextColor;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.Statistic;
|
||||
@ -22,8 +20,6 @@ import org.bukkit.entity.Player;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import static net.kyori.adventure.text.Component.text;
|
||||
|
||||
|
||||
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
|
||||
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 {
|
||||
StatRequest request = generateRequest(sender, args);
|
||||
TextComponent issues = checkRequest(request, isBukkitConsole);
|
||||
|
@ -104,7 +104,6 @@ public class ConfigHandler {
|
||||
return config.getBoolean("enable-hover-text", true);
|
||||
}
|
||||
|
||||
//TODO Test these default units
|
||||
public String getDistanceUnit(boolean isHoverText) {
|
||||
return getUnitString(isHoverText, "blocks", "km", "distance-unit");
|
||||
}
|
||||
@ -113,19 +112,37 @@ public class ConfigHandler {
|
||||
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,
|
||||
the minimum unit will be returned instead. */
|
||||
public String getTimeUnit(boolean isHoverText) {
|
||||
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. */
|
||||
public String getTimeUnit(boolean isHoverText, boolean minUnit) {
|
||||
if (minUnit) {
|
||||
return getUnitString(isHoverText, "seconds", "min-time-unit");
|
||||
public String getTimeUnit(boolean isHoverText, boolean smallUnit) {
|
||||
if (smallUnit) {
|
||||
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.
|
||||
@ -269,15 +286,6 @@ public class ConfigHandler {
|
||||
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.
|
||||
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.
|
||||
|
@ -3,142 +3,146 @@ package com.gmail.artemis.the.gr8.playerstats.enums;
|
||||
import org.bukkit.Statistic;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
|
||||
public enum Unit {
|
||||
NUMBER (Type.UNTYPED),
|
||||
CM (Type.DISTANCE),
|
||||
BLOCK (Type.DISTANCE),
|
||||
MILE (Type.DISTANCE),
|
||||
KM (Type.DISTANCE),
|
||||
HP (Type.DAMAGE),
|
||||
HEART (Type.DAMAGE),
|
||||
TICK (Type.TIME),
|
||||
SECOND (Type.TIME, 1),
|
||||
MINUTE (Type.TIME, 60),
|
||||
HOUR (Type.TIME, 3600),
|
||||
DAY (Type.TIME, 86400),
|
||||
WEEK (Type.TIME, 604800);
|
||||
NUMBER (Type.UNTYPED, "Times"),
|
||||
KM (Type.DISTANCE, "km"),
|
||||
MILE (Type.DISTANCE, "Miles"),
|
||||
BLOCK (Type.DISTANCE, "Blocks"),
|
||||
CM (Type.DISTANCE, "cm"),
|
||||
HP (Type.DAMAGE, "HP"),
|
||||
HEART (Type.DAMAGE, "Hearts"),
|
||||
DAY (Type.TIME, "days"),
|
||||
HOUR (Type.TIME, "hours"),
|
||||
MINUTE (Type.TIME, "minutes"),
|
||||
SECOND (Type.TIME, "seconds"),
|
||||
TICK (Type.TIME, "ticks");
|
||||
|
||||
private final Type type;
|
||||
private final int seconds;
|
||||
private final String label;
|
||||
|
||||
Unit(Type type) {
|
||||
this(type, -1);
|
||||
}
|
||||
|
||||
Unit(Type type, int seconds) {
|
||||
Unit(Type type, String label) {
|
||||
this.type = type;
|
||||
this.seconds = seconds;
|
||||
}
|
||||
|
||||
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;
|
||||
this.label = label;
|
||||
}
|
||||
|
||||
/** Returns a pretty name belonging to this enum constant. If the Unit is
|
||||
NUMBER, it will return an empty String. */
|
||||
public @NotNull String getName() throws NullPointerException {
|
||||
NUMBER, it will return null. */
|
||||
public String getLabel() {
|
||||
return this.label;
|
||||
}
|
||||
|
||||
public Type getType() {
|
||||
return this.type;
|
||||
}
|
||||
|
||||
public Unit getSmallerUnit(int stepsSmaller) {
|
||||
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 -> {
|
||||
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 -> {
|
||||
return "hours";
|
||||
if (stepsSmaller >= 2) {
|
||||
return Unit.SECOND;
|
||||
} else if (stepsSmaller == 1) {
|
||||
return Unit.MINUTE;
|
||||
} else {
|
||||
return this;
|
||||
}
|
||||
}
|
||||
case WEEK -> {
|
||||
return "weeks";
|
||||
case MINUTE -> {
|
||||
if (stepsSmaller >= 1) {
|
||||
return Unit.SECOND;
|
||||
} else {
|
||||
return this;
|
||||
}
|
||||
}
|
||||
case NUMBER -> {
|
||||
return "";
|
||||
case KM -> {
|
||||
if (stepsSmaller >= 2) {
|
||||
return Unit.CM;
|
||||
} else if (stepsSmaller == 1) {
|
||||
return Unit.BLOCK;
|
||||
} else {
|
||||
return this;
|
||||
}
|
||||
}
|
||||
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 BLOCK -> {
|
||||
if (stepsSmaller >= 1) {
|
||||
return Unit.CM;
|
||||
} else {
|
||||
return this;
|
||||
}
|
||||
}
|
||||
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;
|
||||
}
|
||||
case "tick", "ticks" -> {
|
||||
return Unit.TICK;
|
||||
case HEART -> {
|
||||
if (stepsSmaller >= 1) {
|
||||
return Unit.HP;
|
||||
} else {
|
||||
return this;
|
||||
}
|
||||
}
|
||||
default -> {
|
||||
return Unit.NUMBER;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static @NotNull Type fromStatistic(Statistic statistic) {
|
||||
return fromStatName(statistic.toString());
|
||||
public double getSeconds() {
|
||||
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.
|
||||
@param statName the name of the Statistic enum constant in String*/
|
||||
public static @NotNull Type fromStatName(String statName) {
|
||||
String name = statName.toLowerCase();
|
||||
@param statistic the Statistic enum constant*/
|
||||
public static @NotNull Type getTypeFromStatistic(Statistic statistic) {
|
||||
String name = statistic.toString().toLowerCase();
|
||||
if (name.contains("one_cm")) {
|
||||
return Type.DISTANCE;
|
||||
} 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{
|
||||
DAMAGE, //7 statistics
|
||||
DISTANCE, //15 statistics
|
||||
|
@ -159,7 +159,7 @@ public class ComponentFactory {
|
||||
}
|
||||
|
||||
//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,
|
||||
getColorFromString(config.getStatNumberDecoration(selection, false)),
|
||||
getStyleFromString(config.getStatNumberDecoration(selection, true)));
|
||||
|
@ -1,5 +1,6 @@
|
||||
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.config.ConfigHandler;
|
||||
import com.gmail.artemis.the.gr8.playerstats.enums.Unit;
|
||||
@ -127,21 +128,23 @@ public class MessageWriter {
|
||||
.append(getStatNameComponent(request))
|
||||
.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 boldNames = config.playerNameIsBold();
|
||||
|
||||
Set<String> playerNames = topStats.keySet();
|
||||
MinecraftFont font = new MinecraftFont();
|
||||
Set<String> playerNames = topStats.keySet();
|
||||
|
||||
int count = 0;
|
||||
for (String playerName : playerNames) {
|
||||
TextComponent.Builder playerNameBuilder = componentFactory.playerNameBuilder(playerName, Target.TOP);
|
||||
count = count+1;
|
||||
|
||||
count++;
|
||||
topList.append(newline())
|
||||
.append(componentFactory.rankingNumberComponent(count + ". "))
|
||||
.append(playerNameBuilder);
|
||||
|
||||
if (useDots) {
|
||||
topList.append(space());
|
||||
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);
|
||||
}
|
||||
if (dots >= 1) {
|
||||
topList.append(dotsBuilder
|
||||
.append(text((".".repeat(dots)))));
|
||||
topList.append(dotsBuilder.append(text((".".repeat(dots)))));
|
||||
}
|
||||
} else {
|
||||
topList.append(playerNameBuilder
|
||||
.append(text(":")));
|
||||
topList.append(playerNameBuilder.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();
|
||||
}
|
||||
@ -207,53 +210,90 @@ public class MessageWriter {
|
||||
}
|
||||
|
||||
private TextComponent getStatNumberComponent(Statistic statistic, long statNumber, Target selection) {
|
||||
Unit.Type type = Unit.fromStatistic(statistic);
|
||||
Unit.Type type = Unit.getTypeFromStatistic(statistic);
|
||||
Unit statUnit;
|
||||
switch (type) {
|
||||
case DISTANCE -> statUnit = Unit.fromString(config.getDistanceUnit(false));
|
||||
case DAMAGE -> statUnit = Unit.fromString(config.getDamageUnit(false));
|
||||
case TIME -> {
|
||||
return getTimeNumberComponent(statNumber, selection);
|
||||
return getTimeNumberComponent(statNumber, selection, getTimeUnitRange(statNumber));
|
||||
}
|
||||
default -> statUnit = Unit.NUMBER;
|
||||
}
|
||||
String prettyNumber = formatter.format(statNumber, statUnit);
|
||||
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.fromString(config.getDamageUnit(true));
|
||||
String prettyHoverNumber = formatter.format(statNumber, hoverUnit);
|
||||
MyLogger.logMsg("mainNumber: " + prettyNumber + "\n" + "hoverNumber: " + prettyHoverNumber, DebugLevel.HIGH);
|
||||
if (config.useTranslatableComponents()) {
|
||||
String unitKey = languageKeyHandler.getUnitKey(hoverUnit);
|
||||
if (unitKey == null) {
|
||||
unitKey = hoverUnit.getName();
|
||||
unitKey = hoverUnit.getLabel();
|
||||
}
|
||||
return componentFactory.statNumberHoverComponent(prettyNumber, prettyHoverNumber, null, unitKey, selection);
|
||||
}
|
||||
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) {
|
||||
Unit max = Unit.fromString(config.getTimeUnit(false));
|
||||
Unit min = Unit.fromString(config.getTimeUnit(false, true));
|
||||
String mainNumber = formatter.format(statNumber, max, min);
|
||||
if (!config.useHoverText()) {
|
||||
return componentFactory.statNumberComponent(mainNumber, selection).build();
|
||||
} else {
|
||||
Unit hoverMax = Unit.fromString(config.getTimeUnit(true));
|
||||
Unit hoverMin = Unit.fromString(config.getTimeUnit(true, true));
|
||||
return componentFactory.statNumberHoverComponent(mainNumber,
|
||||
formatter.format(statNumber, hoverMax, hoverMin),
|
||||
null, null, selection); //Time does not support translatable text,
|
||||
} //because the unit and number are so tightly interwoven.
|
||||
private TextComponent getTimeNumberComponent(long statNumber, Target selection, ArrayList<Unit> unitRange) {
|
||||
if (unitRange.size() <= 1 || (config.useHoverText() && unitRange.size() <= 3)) {
|
||||
MyLogger.logMsg(
|
||||
"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()) {
|
||||
return componentFactory.statNumberBuilder(mainNumber, selection).build();
|
||||
} else {
|
||||
String hoverNumber = formatter.format(statNumber, unitRange.get(2), unitRange.get(3));
|
||||
MyLogger.logMsg("mainNumber: " + mainNumber + ", hoverNumber: " + hoverNumber, DebugLevel.HIGH);
|
||||
return componentFactory.statNumberHoverComponent(mainNumber, hoverNumber,
|
||||
null, null, selection); //Time does not support translatable text,
|
||||
} //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) {
|
||||
Unit statUnit;
|
||||
switch (Unit.fromStatistic(statistic)) {
|
||||
switch (Unit.getTypeFromStatistic(statistic)) {
|
||||
case DAMAGE -> statUnit = Unit.fromString(config.getDamageUnit(false));
|
||||
case DISTANCE -> statUnit = Unit.fromString(config.getDistanceUnit(false));
|
||||
default -> {
|
||||
@ -268,7 +308,7 @@ public class MessageWriter {
|
||||
}
|
||||
}
|
||||
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. */
|
||||
|
@ -1,6 +1,7 @@
|
||||
package com.gmail.artemis.the.gr8.playerstats.msg;
|
||||
|
||||
import com.gmail.artemis.the.gr8.playerstats.enums.Unit;
|
||||
|
||||
import java.text.DecimalFormat;
|
||||
|
||||
public class NumberFormatter {
|
||||
@ -20,8 +21,8 @@ public class NumberFormatter {
|
||||
return format(number, statUnit, null);
|
||||
}
|
||||
|
||||
public String format(long number, Unit statUnit, Unit timeMinimumUnit) {
|
||||
if (timeMinimumUnit == null) {
|
||||
public String format(long number, Unit statUnit, Unit smallTimeUnit) {
|
||||
if (smallTimeUnit == null) {
|
||||
switch (statUnit.getType()) {
|
||||
case DISTANCE -> {
|
||||
return formatDistance(number, statUnit);
|
||||
@ -34,7 +35,7 @@ public class NumberFormatter {
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return formatTime(number, statUnit, timeMinimumUnit);
|
||||
return formatTime(number, statUnit, smallTimeUnit);
|
||||
}
|
||||
}
|
||||
|
||||
@ -56,7 +57,7 @@ public class NumberFormatter {
|
||||
return format.format(number);
|
||||
}
|
||||
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 -> {
|
||||
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.*/
|
||||
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) {
|
||||
return "-";
|
||||
}
|
||||
StringBuilder output = new StringBuilder();
|
||||
int max = maxUnit.getTimeInSeconds();
|
||||
int min = minUnit.getTimeInSeconds();
|
||||
if (bigUnit == Unit.TICK && smallUnit == Unit.TICK || bigUnit == Unit.NUMBER || smallUnit == Unit.NUMBER) {
|
||||
return format.format(number);
|
||||
}
|
||||
|
||||
StringBuilder output = new StringBuilder();
|
||||
double max = bigUnit.getSeconds();
|
||||
double min = smallUnit.getSeconds();
|
||||
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) {
|
||||
double days = leftover / 60 / 60 / 24;
|
||||
leftover = leftover % (60 * 60 * 24);
|
||||
if (minUnit == Unit.DAY) {
|
||||
if (smallUnit == Unit.DAY && leftover >= 43200) {
|
||||
days++;
|
||||
return output.append(format.format(Math.round(days)))
|
||||
.append("d").toString();
|
||||
@ -104,7 +96,7 @@ public class NumberFormatter {
|
||||
if (isInRange(max, min, 3600) && leftover >= 3600) {
|
||||
double hours = leftover / 60 / 60;
|
||||
leftover = leftover % (60 * 60);
|
||||
if (minUnit == Unit.HOUR) {
|
||||
if (smallUnit == Unit.HOUR && leftover >= 1800) {
|
||||
hours++;
|
||||
return output.append(format.format(Math.round(hours)))
|
||||
.append("h").toString();
|
||||
@ -115,7 +107,7 @@ public class NumberFormatter {
|
||||
if (isInRange(max, min, 60) && leftover >= 60) {
|
||||
double minutes = leftover / 60;
|
||||
leftover = leftover % 60;
|
||||
if (minUnit == Unit.MINUTE) {
|
||||
if (smallUnit == Unit.MINUTE && leftover >= 30) {
|
||||
minutes++;
|
||||
return output.append(format.format(Math.round(minutes)))
|
||||
.append("m").toString();
|
||||
@ -130,7 +122,7 @@ public class NumberFormatter {
|
||||
return output.toString();
|
||||
}
|
||||
|
||||
private boolean isInRange(int maxUnit, int minUnit, int unitToEvaluate) {
|
||||
return maxUnit >= unitToEvaluate && unitToEvaluate >= minUnit;
|
||||
private boolean isInRange(double bigUnit, double smallUnit, double unitToEvaluate) {
|
||||
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) {
|
||||
logMsg(content, DebugLevel.LOW, logAsWarning);
|
||||
}
|
||||
@ -129,7 +133,7 @@ public class MyLogger {
|
||||
if (debugLevel != DebugLevel.LOW) {
|
||||
threadNames = new ConcurrentHashMap<>();
|
||||
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;
|
||||
}
|
||||
else if (debugLevel == DebugLevel.MEDIUM) {
|
||||
else if (debugLevel == DebugLevel.MEDIUM || debugLevel == DebugLevel.HIGH && thread == 2) {
|
||||
nextPlayersIndex();
|
||||
}
|
||||
}
|
||||
@ -179,8 +183,10 @@ public class MyLogger {
|
||||
if (debugLevel != DebugLevel.LOW) {
|
||||
logger.info("Finished Recursive Action! In total " +
|
||||
threadNames.size() + " Threads were used to process " +
|
||||
playersIndex.get() + " Players: " +
|
||||
Collections.list(threadNames.keys()));
|
||||
playersIndex.get() + " Players.");
|
||||
}
|
||||
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-for-hover-text: hp
|
||||
|
||||
# Minecraft measures time in ticks. PlayerStats supports: weeks, days, hours, minutes, seconds, ticks
|
||||
# Below you can choose a range between the maximum and minimum unit you want to see
|
||||
# If the max and min are the same, only that unit will be displayed
|
||||
# For example, 5.000.000 ticks would become "4D", "3D 21H 27M 40S", "69H 27M 40S", "4168M", etc.
|
||||
max-time-unit: hours
|
||||
min-time-unit: seconds
|
||||
# Minecraft measures time in ticks. With the below settings, PlayerStats will:
|
||||
# Auto-detect the best maximum unit to use (weeks/days/hours/minutes/seconds) for your players' statistics
|
||||
# Show a specified amount of additional smaller units (example: "x days" would become "x days, y hours, z minutes")
|
||||
auto-detect-biggest-time-unit: true
|
||||
number-of-extra-units: 1
|
||||
auto-detect-biggest-time-unit-for-hover-text: false
|
||||
number-of-extra-units-for-hover-text: 0
|
||||
|
||||
max-time-unit-for-hover-text: days
|
||||
min-time-unit-for-hover-text: seconds
|
||||
# If you don't want the unit to be auto-detected, set the auto-detect settings to false and specify your own range here
|
||||
# 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
|
||||
enable-festive-formatting: true
|
||||
|
Loading…
Reference in New Issue
Block a user