diff --git a/api/src/main/java/kr/toxicity/healthbar/api/manager/ConfigManager.java b/api/src/main/java/kr/toxicity/healthbar/api/manager/ConfigManager.java index 73a5f46..852a45f 100644 --- a/api/src/main/java/kr/toxicity/healthbar/api/manager/ConfigManager.java +++ b/api/src/main/java/kr/toxicity/healthbar/api/manager/ConfigManager.java @@ -7,6 +7,8 @@ import org.jetbrains.annotations.Unmodifiable; import java.io.File; +import java.text.DecimalFormat; +import java.text.NumberFormat; import java.util.Set; public interface ConfigManager { @@ -28,6 +30,7 @@ public interface ConfigManager { boolean createPackMcmeta(); boolean enableSelfHost(); int selfHostPort(); + @NotNull NumberFormat numberFormat(); @NotNull @Unmodifiable Set blacklistEntityType(); diff --git a/api/src/main/java/kr/toxicity/healthbar/api/placeholder/PlaceholderBuilder.java b/api/src/main/java/kr/toxicity/healthbar/api/placeholder/PlaceholderBuilder.java index a9762e1..e8288a5 100644 --- a/api/src/main/java/kr/toxicity/healthbar/api/placeholder/PlaceholderBuilder.java +++ b/api/src/main/java/kr/toxicity/healthbar/api/placeholder/PlaceholderBuilder.java @@ -2,38 +2,78 @@ import kr.toxicity.healthbar.api.event.HealthBarCreateEvent; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import java.util.List; +import java.util.Objects; import java.util.function.Function; public interface PlaceholderBuilder { @NotNull HealthBarPlaceholder build(@NotNull List strings); int requiredArgsCount(); - static PlaceholderBuilder of(int length, @NotNull Class clazz, @NotNull Function, Function> tFunction) { - return new PlaceholderBuilder<>() { - @Override - public @NotNull HealthBarPlaceholder build(@NotNull List strings) { - var get = tFunction.apply(strings); - return new HealthBarPlaceholder<>() { - @NotNull - @Override - public Class type() { - return clazz; - } - - @NotNull - @Override - public T value(@NotNull HealthBarCreateEvent event) { - return get.apply(event); - } - }; - } - - @Override - public int requiredArgsCount() { - return length; - } - }; + static @NotNull Builder builder(@NotNull PlaceholderContainer container) { + return new Builder<>(Objects.requireNonNull(container)); } + + static @Nullable Builder builder(@NotNull Class clazz) { + var get = PlaceholderContainer.find(clazz); + return get != null ? get.create() : null; + } + + class Builder { + private final Class clazz; + private Function stringMapper; + private Function, Function> parser; + private int argsLength; + private Builder(@NotNull PlaceholderContainer container) { + clazz = container.clazz(); + stringMapper = container.stringMapper(); + } + + public @NotNull Builder stringMapper(@NotNull Function mapper) { + stringMapper = Objects.requireNonNull(mapper); + return this; + } + public @NotNull Builder parser(@NotNull Function, Function> parser) { + this.parser = Objects.requireNonNull(parser); + return this; + } + public @NotNull Builder argsLength(int argsLength) { + this.argsLength = argsLength; + return this; + } + + public @NotNull PlaceholderBuilder build() { + return new PlaceholderBuilder<>() { + @Override + public @NotNull HealthBarPlaceholder build(@NotNull List strings) { + var valueFunction = parser.apply(strings); + return new HealthBarPlaceholder<>() { + @Override + public @NotNull Class type() { + return clazz; + } + + @Override + public @Nullable R value(@NotNull HealthBarCreateEvent event) { + return valueFunction.apply(event); + } + + @Override + public @Nullable String stringValue(@NotNull HealthBarCreateEvent event) { + var parsed = value(event); + return parsed != null ? stringMapper.apply(parsed) : null; + } + }; + } + + @Override + public int requiredArgsCount() { + return argsLength; + } + }; + } + } + } diff --git a/api/src/main/java/kr/toxicity/healthbar/api/placeholder/PlaceholderContainer.java b/api/src/main/java/kr/toxicity/healthbar/api/placeholder/PlaceholderContainer.java index e385ec2..4746ece 100644 --- a/api/src/main/java/kr/toxicity/healthbar/api/placeholder/PlaceholderContainer.java +++ b/api/src/main/java/kr/toxicity/healthbar/api/placeholder/PlaceholderContainer.java @@ -1,5 +1,6 @@ package kr.toxicity.healthbar.api.placeholder; +import kr.toxicity.healthbar.api.BetterHealthBar; import kr.toxicity.healthbar.api.event.HealthBarCreateEvent; import net.kyori.adventure.text.Component; import net.kyori.adventure.text.TextReplacementConfig; @@ -8,7 +9,6 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import java.text.DecimalFormat; import java.util.*; import java.util.function.Function; import java.util.regex.Pattern; @@ -31,6 +31,23 @@ public PlaceholderContainer(@NotNull Class clazz, String name, @NotNull Funct STRING_MAP.put(name, this); } + @SuppressWarnings("unchecked") + public static @Nullable PlaceholderContainer find(@NotNull Class clazz) { + return (PlaceholderContainer) CLASS_MAP.get(clazz); + } + + public @NotNull PlaceholderBuilder.Builder create() { + return PlaceholderBuilder.builder(this); + } + + @NotNull Class clazz() { + return clazz; + } + + @NotNull Function stringMapper() { + return stringMapper; + } + public static final PlaceholderContainer NUMBER = new PlaceholderContainer<>( Number.class, "number", @@ -41,7 +58,7 @@ public PlaceholderContainer(@NotNull Class clazz, String name, @NotNull Funct return null; } }, - s -> DecimalFormat.getInstance().format(s) + s -> BetterHealthBar.inst().configManager().numberFormat().format(s) ); public static final PlaceholderContainer STRING = new PlaceholderContainer<>( String.class, @@ -78,7 +95,7 @@ public int requiredArgsCount() { @Override public @NotNull HealthBarPlaceholder build(@NotNull List strings) { return new HealthBarPlaceholder<>() { - @NotNull + @Nullable @Override public T value(@NotNull HealthBarCreateEvent event) { return function.apply(event); @@ -89,10 +106,19 @@ public T value(@NotNull HealthBarCreateEvent event) { public Class type() { return clazz; } + + @Override + public @Nullable String stringValue(@NotNull HealthBarCreateEvent event) { + var value = value(event); + return value != null ? stringMapper.apply(value) : null; + } }; } }); } + public void addPlaceholder(@NotNull String name, @NotNull PlaceholderBuilder.Builder builder) { + addPlaceholder(name, builder.build()); + } public void addPlaceholder(@NotNull String name, @NotNull PlaceholderBuilder builder) { map.put(name, builder); } @@ -127,10 +153,11 @@ public Class type() { return String.class; } - @NotNull + @Nullable @Override public String value(@NotNull HealthBarCreateEvent event) { - return stringMapper.apply(apply.value(event)); + var value = apply.value(event); + return value != null ? value.toString() : null; } }; } @@ -196,7 +223,8 @@ public Class type() { @Nullable @Override public Object value(@NotNull HealthBarCreateEvent event) { - return cast.parser.apply(string.value(event)); + var value = string.value(event); + return value != null ? cast.parser.apply(value) : null; } @Override diff --git a/build.gradle.kts b/build.gradle.kts index 0df9fb3..ae5a593 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -175,7 +175,7 @@ tasks { version("1.21.1") //TODO set this to 'minecraft' when other plugins support the latest version. pluginJars(fileTree("plugins")) downloadPlugins { - modrinth("betterhud2", "1.7.DEV-266") + modrinth("betterhud2", "1.8") hangar("PlaceholderAPI", "2.11.6") hangar("Skript", "2.9.3") } diff --git a/dist/src/main/kotlin/kr/toxicity/healthbar/manager/ConfigManagerImpl.kt b/dist/src/main/kotlin/kr/toxicity/healthbar/manager/ConfigManagerImpl.kt index 1de992a..d3b1033 100644 --- a/dist/src/main/kotlin/kr/toxicity/healthbar/manager/ConfigManagerImpl.kt +++ b/dist/src/main/kotlin/kr/toxicity/healthbar/manager/ConfigManagerImpl.kt @@ -10,6 +10,8 @@ import kr.toxicity.healthbar.util.* import org.bstats.bukkit.Metrics import org.bukkit.entity.EntityType import java.io.File +import java.text.DecimalFormat +import java.text.NumberFormat import java.util.Collections import java.util.EnumSet @@ -27,6 +29,7 @@ object ConfigManagerImpl : ConfigManager, BetterHealthBerManager { private var mergeOtherFolder = emptySet() private var createPackMemeta = true private var enableSelfHost = false + private var numberFormat = DecimalFormat.getNumberInstance() private var selfHostPort = 8163 private var blackListEntityType = emptySet() private var disableToInvulnerableMob = true @@ -67,6 +70,11 @@ object ConfigManagerImpl : ConfigManager, BetterHealthBerManager { createPackMemeta = config.getBoolean("create-pack-mcmeta", true) enableSelfHost = config.getBoolean("enable-self-host", false) selfHostPort = config.getInt("self-host-port", 8163) + numberFormat = runCatching { + DecimalFormat(config.getString("number-format", "#,###")) + }.getOrElse { + DecimalFormat.getNumberInstance() + } blackListEntityType = Collections.unmodifiableSet(EnumSet.copyOf(config.getStringList("blacklist-entity-type").mapNotNull { runCatching { EntityType.valueOf(it.uppercase()) @@ -81,6 +89,7 @@ object ConfigManagerImpl : ConfigManager, BetterHealthBerManager { } useCoreShaders = config.getBoolean("use-core-shaders", true) showMeHealthBar = config.getBoolean("show-me-healthbar", true) + if (!metrics) { bstats?.shutdown() bstats = null @@ -106,6 +115,7 @@ object ConfigManagerImpl : ConfigManager, BetterHealthBerManager { override fun createPackMcmeta(): Boolean = createPackMemeta override fun enableSelfHost(): Boolean = enableSelfHost override fun selfHostPort(): Int = selfHostPort + override fun numberFormat(): NumberFormat = numberFormat override fun blacklistEntityType(): Set = blackListEntityType override fun disableToInvulnerableMob(): Boolean = disableToInvulnerableMob override fun shaders(): CoreShadersOption = shaders diff --git a/dist/src/main/kotlin/kr/toxicity/healthbar/util/Functions.kt b/dist/src/main/kotlin/kr/toxicity/healthbar/util/Functions.kt index 7777fdc..5cc88fe 100644 --- a/dist/src/main/kotlin/kr/toxicity/healthbar/util/Functions.kt +++ b/dist/src/main/kotlin/kr/toxicity/healthbar/util/Functions.kt @@ -19,6 +19,8 @@ fun Throwable.handleException(log: String): Array { ) } -inline fun placeholder(length: Int, function: Function, Function>): PlaceholderBuilder { - return PlaceholderBuilder.of(length, T::class.java, function) +inline fun placeholder(length: Int, function: Function, Function>): PlaceholderBuilder.Builder { + return PlaceholderBuilder.builder(T::class.java).ifNull("Unable to find this type: ${T::class.java.simpleName}") + .argsLength(length) + .parser(function) } \ No newline at end of file diff --git a/dist/src/main/resources/config.yml b/dist/src/main/resources/config.yml index 7d33b21..2aacb6c 100644 --- a/dist/src/main/resources/config.yml +++ b/dist/src/main/resources/config.yml @@ -11,6 +11,7 @@ merge-other-folder: [] create-pack-mcmeta: true enable-self-host: true self-host-port: 8163 +number-format: "#,###" blacklist-entity-type: - ARMOR_STAND - TEXT_DISPLAY