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 9c23a94..5e5f271 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 @@ -40,4 +40,5 @@ public interface ConfigManager { CoreShadersOption shaders(); boolean useCoreShaders(); boolean showMeHealthBar(); + boolean resourcePackObfuscation(); } diff --git a/build.gradle.kts b/build.gradle.kts index 55822dd..42fea45 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -17,7 +17,7 @@ allprojects { apply(plugin = "kotlin") apply(plugin = "org.jetbrains.dokka") group = "kr.toxicity.healthbar" - version = "3.7.2" + version = "3.7.3" repositories { mavenCentral() maven("https://repo.papermc.io/repository/maven-public/") @@ -79,8 +79,8 @@ val dist = getApiDependencyProject("dist").spigot() .dependency("io.github.arcaneplugins:levelledmobs-plugin:4.0.3.1") .dependency("me.clip:placeholderapi:2.11.6") .dependency("com.alessiodp.parties:parties-bukkit:3.2.16") - .dependency("io.github.toxicity188:BetterHud-standard-api:1.10.1") - .dependency("io.github.toxicity188:BetterHud-bukkit-api:1.10.1") + .dependency("io.github.toxicity188:BetterHud-standard-api:1.10.3") + .dependency("io.github.toxicity188:BetterHud-bukkit-api:1.10.3") .dependency("net.citizensnpcs:citizens-main:2.0.35-SNAPSHOT") .dependency("com.github.SkriptLang:Skript:2.9.5") .dependency("com.nexomc:nexo:0.4.0") @@ -165,7 +165,7 @@ tasks { version("1.21.1") //TODO set this to 'minecraft' when other plugins support the latest version. pluginJars(fileTree("plugins")) downloadPlugins { - hangar("BetterHud", "1.10.1") + hangar("BetterHud", "1.10.3") hangar("PlaceholderAPI", "2.11.6") hangar("Skript", "2.9.5") } diff --git a/dist/src/main/kotlin/kr/toxicity/healthbar/BetterHealthBarImpl.kt b/dist/src/main/kotlin/kr/toxicity/healthbar/BetterHealthBarImpl.kt index f3d9527..4a76575 100644 --- a/dist/src/main/kotlin/kr/toxicity/healthbar/BetterHealthBarImpl.kt +++ b/dist/src/main/kotlin/kr/toxicity/healthbar/BetterHealthBarImpl.kt @@ -57,6 +57,7 @@ class BetterHealthBarImpl : BetterHealthBar() { private val scheduler = if (isFolia) FoliaScheduler() else StandardScheduler() private val managers = listOf( + EncodeManager, CompatibilityManager, ConfigManagerImpl, ListenerManagerImpl, diff --git a/dist/src/main/kotlin/kr/toxicity/healthbar/layout/ImageLayoutImpl.kt b/dist/src/main/kotlin/kr/toxicity/healthbar/layout/ImageLayoutImpl.kt index b14e610..05deaf1 100644 --- a/dist/src/main/kotlin/kr/toxicity/healthbar/layout/ImageLayoutImpl.kt +++ b/dist/src/main/kotlin/kr/toxicity/healthbar/layout/ImageLayoutImpl.kt @@ -10,6 +10,7 @@ import kr.toxicity.healthbar.api.layout.ImageLayout import kr.toxicity.healthbar.api.listener.HealthBarListener import kr.toxicity.healthbar.api.renderer.ImageRenderer import kr.toxicity.healthbar.data.BitmapData +import kr.toxicity.healthbar.manager.EncodeManager import kr.toxicity.healthbar.manager.ImageManagerImpl import kr.toxicity.healthbar.manager.ListenerManagerImpl import kr.toxicity.healthbar.pack.PackResource @@ -41,7 +42,7 @@ class ImageLayoutImpl( val componentMap = HashMap() image.images().forEach { val list = ArrayList() - val dir = "${parent.name}/image/${layer()}/${it.name}" + val dir = "${parent.name}/image/${layer()}/${it.name}".encodeFile(EncodeManager.EncodeNamespace.TEXTURES) resource.textures.add(dir) { it.image.image.withOpacity(layer()).toByteArray() } diff --git a/dist/src/main/kotlin/kr/toxicity/healthbar/layout/LayoutGroupImpl.kt b/dist/src/main/kotlin/kr/toxicity/healthbar/layout/LayoutGroupImpl.kt index 52ebcb2..976984a 100644 --- a/dist/src/main/kotlin/kr/toxicity/healthbar/layout/LayoutGroupImpl.kt +++ b/dist/src/main/kotlin/kr/toxicity/healthbar/layout/LayoutGroupImpl.kt @@ -6,6 +6,7 @@ import kr.toxicity.healthbar.api.layout.ImageLayout import kr.toxicity.healthbar.api.layout.LayoutGroup import kr.toxicity.healthbar.api.layout.TextLayout import kr.toxicity.healthbar.manager.ConfigManagerImpl +import kr.toxicity.healthbar.manager.EncodeManager import kr.toxicity.healthbar.pack.PackResource import kr.toxicity.healthbar.util.* import net.kyori.adventure.key.Key @@ -21,7 +22,8 @@ class LayoutGroupImpl( var index = ADVENTURE_START_INT - private val imageKey = Key.key(NAMESPACE, "$name/images") + private val encodedName = encodeKey(EncodeManager.EncodeNamespace.FONT, "$name/images") + private val imageKey = createAdventureKey(encodedName) private val group = section.getString("group") private var i = 0 @@ -68,7 +70,7 @@ class LayoutGroupImpl( images.forEach { it.build(resource, min, count, json) } - resource.font.add("$name/images.json") { + resource.font.add("$encodedName.json") { JsonObject().apply { add("providers", json) }.save() diff --git a/dist/src/main/kotlin/kr/toxicity/healthbar/layout/TextLayoutImpl.kt b/dist/src/main/kotlin/kr/toxicity/healthbar/layout/TextLayoutImpl.kt index 61f533a..03fb7d6 100644 --- a/dist/src/main/kotlin/kr/toxicity/healthbar/layout/TextLayoutImpl.kt +++ b/dist/src/main/kotlin/kr/toxicity/healthbar/layout/TextLayoutImpl.kt @@ -11,6 +11,7 @@ import kr.toxicity.healthbar.api.placeholder.PlaceholderOption import kr.toxicity.healthbar.api.renderer.TextRenderer import kr.toxicity.healthbar.api.text.TextAlign import kr.toxicity.healthbar.data.BitmapData +import kr.toxicity.healthbar.manager.EncodeManager import kr.toxicity.healthbar.manager.TextManagerImpl import kr.toxicity.healthbar.pack.PackResource import kr.toxicity.healthbar.util.* @@ -70,7 +71,7 @@ class TextLayoutImpl( val dataList = ArrayList() val fileParent = "${parent.name}/text/${layer()}" text.bitmap().forEachIndexed { index, textBitmap -> - val fileName = "$fileParent/${index + 1}.png" + val fileName = "${encodeKey(EncodeManager.EncodeNamespace.TEXTURES, "$fileParent/${index + 1}")}.png" dataList.add(JsonData( "$NAMESPACE:$fileName", textBitmap.array @@ -83,7 +84,7 @@ class TextLayoutImpl( val map = HashMap() for (i in 0..>(EncodeNamespace::class.java) + + override fun reload(resource: PackResource) { + + } + + override fun postReload() { + encodeMap.clear() + } + enum class EncodeNamespace { + FONT, + TEXTURES + } + fun generateKey(namespace: EncodeNamespace, name: String): String { + val map = synchronized(encodeMap) { + encodeMap.computeIfAbsent(namespace) { + mutableMapOf() + } + } + return synchronized(map) { + map.computeIfAbsent(name) { + map.size + }.encode() + } + } + + private fun Int.encode(): String { + var i = this + val size = chars.size + return buildString { + while (i >= size) { + append(chars.first()) + i -= size + } + append(chars[i]) + } + } + + private val chars = listOf( + 'a', 'b', 'c', 'd', 'e', 'f', 'g', + 'h', 'i', 'j', 'k', 'm', 'n', 'l', 'o', 'p', + 'q', 'r', 's', 't', 'u', 'v', + 'w', 'x', 'y', 'z', + '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' + ) +} \ No newline at end of file diff --git a/dist/src/main/kotlin/kr/toxicity/healthbar/manager/HealthBarManagerImpl.kt b/dist/src/main/kotlin/kr/toxicity/healthbar/manager/HealthBarManagerImpl.kt index 366578c..44469c0 100644 --- a/dist/src/main/kotlin/kr/toxicity/healthbar/manager/HealthBarManagerImpl.kt +++ b/dist/src/main/kotlin/kr/toxicity/healthbar/manager/HealthBarManagerImpl.kt @@ -4,7 +4,7 @@ import kr.toxicity.healthbar.api.healthbar.HealthBar import kr.toxicity.healthbar.api.manager.HealthBarManager import kr.toxicity.healthbar.healthbar.HealthBarImpl import kr.toxicity.healthbar.pack.PackResource -import kr.toxicity.healthbar.util.forEachAllYamlAsync +import kr.toxicity.healthbar.util.forEachAllYaml import kr.toxicity.healthbar.util.putSync import kr.toxicity.healthbar.util.runWithHandleException import kr.toxicity.healthbar.util.subFolder @@ -28,7 +28,7 @@ object HealthBarManagerImpl : HealthBarManager, BetterHealthBerManager { override fun reload(resource: PackResource) { healthBarMap.clear() uuidSet.clear() - resource.dataFolder.subFolder("healthbars").forEachAllYamlAsync { file, s, section -> + resource.dataFolder.subFolder("healthbars").forEachAllYaml { file, s, section -> runWithHandleException("Unable to load this health bar: $s in ${file.path}") { var uuid = UUID.randomUUID() while (!uuidSet.add(uuid)) uuid = UUID.randomUUID() diff --git a/dist/src/main/kotlin/kr/toxicity/healthbar/manager/ImageManagerImpl.kt b/dist/src/main/kotlin/kr/toxicity/healthbar/manager/ImageManagerImpl.kt index 8f3f554..ff27ca6 100644 --- a/dist/src/main/kotlin/kr/toxicity/healthbar/manager/ImageManagerImpl.kt +++ b/dist/src/main/kotlin/kr/toxicity/healthbar/manager/ImageManagerImpl.kt @@ -23,7 +23,7 @@ object ImageManagerImpl : ImageManager, BetterHealthBerManager { override fun reload(resource: PackResource) { imageMap.clear() val images = resource.dataFolder.subFolder("assets") - resource.dataFolder.subFolder("images").forEachAllYamlAsync { file, s, section -> + resource.dataFolder.subFolder("images").forEachAllYaml { file, s, section -> runWithHandleException("Unable to load this image: $s in ${file.path}") { val typeValue = section.getString("type").ifNull("Unable to find 'type' configuration.") val image = when (val type = ImageType.valueOf(typeValue.uppercase())) { diff --git a/dist/src/main/kotlin/kr/toxicity/healthbar/manager/LayoutManagerImpl.kt b/dist/src/main/kotlin/kr/toxicity/healthbar/manager/LayoutManagerImpl.kt index 23461d4..ee968b7 100644 --- a/dist/src/main/kotlin/kr/toxicity/healthbar/manager/LayoutManagerImpl.kt +++ b/dist/src/main/kotlin/kr/toxicity/healthbar/manager/LayoutManagerImpl.kt @@ -4,7 +4,7 @@ import kr.toxicity.healthbar.api.layout.LayoutGroup import kr.toxicity.healthbar.api.manager.LayoutManager import kr.toxicity.healthbar.layout.LayoutGroupImpl import kr.toxicity.healthbar.pack.PackResource -import kr.toxicity.healthbar.util.forEachAllYamlAsync +import kr.toxicity.healthbar.util.forEachAllYaml import kr.toxicity.healthbar.util.putSync import kr.toxicity.healthbar.util.runWithHandleException import kr.toxicity.healthbar.util.subFolder @@ -29,7 +29,7 @@ object LayoutManagerImpl : LayoutManager, BetterHealthBerManager { layoutMap.clear() groupData.clear() - resource.dataFolder.subFolder("layouts").forEachAllYamlAsync { file, s, configurationSection -> + resource.dataFolder.subFolder("layouts").forEachAllYaml { file, s, configurationSection -> runWithHandleException("Unable to load this layout: $s in ${file.path}") { val layout = LayoutGroupImpl( file.path, diff --git a/dist/src/main/kotlin/kr/toxicity/healthbar/manager/MobManagerImpl.kt b/dist/src/main/kotlin/kr/toxicity/healthbar/manager/MobManagerImpl.kt index 2cc22c0..ef51398 100644 --- a/dist/src/main/kotlin/kr/toxicity/healthbar/manager/MobManagerImpl.kt +++ b/dist/src/main/kotlin/kr/toxicity/healthbar/manager/MobManagerImpl.kt @@ -8,7 +8,7 @@ import kr.toxicity.healthbar.api.mob.MobProvider import kr.toxicity.healthbar.entity.HealthBarEntityImpl import kr.toxicity.healthbar.mob.MobConfigurationImpl import kr.toxicity.healthbar.pack.PackResource -import kr.toxicity.healthbar.util.forEachAllYamlAsync +import kr.toxicity.healthbar.util.forEachAllYaml import kr.toxicity.healthbar.util.putSync import kr.toxicity.healthbar.util.runWithHandleException import kr.toxicity.healthbar.util.subFolder @@ -25,7 +25,7 @@ object MobManagerImpl : BetterHealthBerManager, MobManager { override fun reload(resource: PackResource) { mobConfigurationMap.clear() - resource.dataFolder.subFolder("mobs").forEachAllYamlAsync { file, s, configurationSection -> + resource.dataFolder.subFolder("mobs").forEachAllYaml { file, s, configurationSection -> runWithHandleException("Unable to load mob: $s in ${file.path}") { val config = MobConfigurationImpl(file.path, configurationSection) mobConfigurationMap.putSync("mob", s) { diff --git a/dist/src/main/kotlin/kr/toxicity/healthbar/manager/TextManagerImpl.kt b/dist/src/main/kotlin/kr/toxicity/healthbar/manager/TextManagerImpl.kt index 4660b29..73642e3 100644 --- a/dist/src/main/kotlin/kr/toxicity/healthbar/manager/TextManagerImpl.kt +++ b/dist/src/main/kotlin/kr/toxicity/healthbar/manager/TextManagerImpl.kt @@ -55,7 +55,7 @@ object TextManagerImpl : TextManager, BetterHealthBerManager { textMap.clear() textMap["default"] = default val fonts = resource.dataFolder.subFolder("fonts") - resource.dataFolder.subFolder("texts").forEachAllYamlAsync { file, s, configurationSection -> + resource.dataFolder.subFolder("texts").forEachAllYaml { file, s, configurationSection -> runWithHandleException("Unable to read this text: $s in ${file.path}") { val font = Font.createFont(Font.TRUETYPE_FONT, File(fonts, configurationSection.getString("file").ifNull("Unable to find 'file' configuration.").replace('/', File.separatorChar)).apply { if (!exists()) throw RuntimeException("Unable to find this font: $path") diff --git a/dist/src/main/kotlin/kr/toxicity/healthbar/util/Adventures.kt b/dist/src/main/kotlin/kr/toxicity/healthbar/util/Adventures.kt index fd11d9b..99df6fb 100644 --- a/dist/src/main/kotlin/kr/toxicity/healthbar/util/Adventures.kt +++ b/dist/src/main/kotlin/kr/toxicity/healthbar/util/Adventures.kt @@ -3,7 +3,6 @@ package kr.toxicity.healthbar.util import kr.toxicity.healthbar.api.component.PixelComponent import kr.toxicity.healthbar.api.component.WidthComponent import kr.toxicity.healthbar.manager.ConfigManagerImpl -import net.kyori.adventure.key.Key import net.kyori.adventure.text.Component import net.kyori.adventure.text.format.TextDecoration import net.kyori.adventure.text.minimessage.MiniMessage @@ -42,7 +41,7 @@ val MINI_MESSAGE = MiniMessage.builder() .build() val SPACE_KEY - get() = Key.key(NAMESPACE, "space") + get() = createAdventureKey("space") val NEGATIVE_ONE_SPACE_COMPONENT get() = WidthComponent(0, Component.text().font(SPACE_KEY).content((ADVENTURE_START_INT - 1).parseChar())) diff --git a/dist/src/main/kotlin/kr/toxicity/healthbar/util/Encodes.kt b/dist/src/main/kotlin/kr/toxicity/healthbar/util/Encodes.kt new file mode 100644 index 0000000..fa6afa5 --- /dev/null +++ b/dist/src/main/kotlin/kr/toxicity/healthbar/util/Encodes.kt @@ -0,0 +1,15 @@ +package kr.toxicity.healthbar.util + +import kr.toxicity.healthbar.manager.ConfigManagerImpl +import kr.toxicity.healthbar.manager.EncodeManager +import net.kyori.adventure.key.Key + +fun String.encodeFile(path: EncodeManager.EncodeNamespace): String { + val split = split('.') + if (split.size != 2) throw RuntimeException("Invaild file name: $this") + return "${encodeKey(path, split[0])}.${split[1]}" +} + +fun encodeKey(path: EncodeManager.EncodeNamespace, name: String) = if (ConfigManagerImpl.resourcePackObfuscation()) EncodeManager.generateKey(path, name) else name + +fun createAdventureKey(path: String) = Key.key(NAMESPACE, path) \ No newline at end of file diff --git a/dist/src/main/kotlin/kr/toxicity/healthbar/util/Files.kt b/dist/src/main/kotlin/kr/toxicity/healthbar/util/Files.kt index 5d20d89..e4807d6 100644 --- a/dist/src/main/kotlin/kr/toxicity/healthbar/util/Files.kt +++ b/dist/src/main/kotlin/kr/toxicity/healthbar/util/Files.kt @@ -11,7 +11,7 @@ fun File.requireExists() = apply { if (!exists()) throw RuntimeException("This file doesn't exist: $path") } -fun File.forEachAllYamlAsync(block: (File, String, ConfigurationSection) -> Unit) { +fun File.forEachAllYaml(block: (File, String, ConfigurationSection) -> Unit) { fun getAll(file: File): List { return if (file.isDirectory) { file.listFiles()?.map { subFile -> @@ -21,34 +21,16 @@ fun File.forEachAllYamlAsync(block: (File, String, ConfigurationSection) -> Unit listOf(file) } } - val list = getAll(this).filter { + getAll(this).filter { it.extension == "yml" - }.mapNotNull { - runCatching { + }.forEach { + runWithHandleException("Unable to load this yml file: ${it.name}") { val yaml = it.toYaml() - val list = ArrayList>() - yaml.getKeys(false).forEach { - yaml.getConfigurationSection(it)?.let { section -> - list.add(it to section) + yaml.getKeys(false).forEach { key -> + yaml.getConfigurationSection(key)?.let { section -> + block(it, key, section) } } - if (list.isNotEmpty()) it to list else null - }.getOrElse { e -> - warn( - "Unable to load this yml file: ${it.name}", - "Reason: ${e.message}" - ) - null } } - if (list.isEmpty()) return - list.map { - { - it.second.forEach { pair -> - block(it.first, pair.first, pair.second) - } - } - }.forEachAsync { - it() - } } \ No newline at end of file