From 0e72f24164c54940b97df40425c4377af094a9cd Mon Sep 17 00:00:00 2001 From: Kariya Date: Wed, 17 Dec 2025 08:49:33 +0000 Subject: [PATCH] refactor: Restructure configuration into nested data classes and update component references. --- .../net/hareworks/hcu/items/config/Config.kt | 341 ++++++++++++------ .../content/components/BlinkComponent.kt | 2 +- .../content/components/DoubleJumpComponent.kt | 6 +- .../content/components/GliderComponent.kt | 4 +- .../content/components/VeinMinerComponent.kt | 17 +- .../hcu/items/listeners/EventListener.kt | 2 +- 6 files changed, 253 insertions(+), 119 deletions(-) diff --git a/src/main/kotlin/net/hareworks/hcu/items/config/Config.kt b/src/main/kotlin/net/hareworks/hcu/items/config/Config.kt index 373f495..64abc74 100644 --- a/src/main/kotlin/net/hareworks/hcu/items/config/Config.kt +++ b/src/main/kotlin/net/hareworks/hcu/items/config/Config.kt @@ -1,80 +1,176 @@ package net.hareworks.hcu.items.config +import org.bukkit.Color +import org.bukkit.Material +import org.bukkit.NamespacedKey +import org.bukkit.Tag +import org.bukkit.Bukkit import org.bukkit.configuration.file.FileConfiguration import org.bukkit.plugin.java.JavaPlugin +/** + * プラグインの設定を管理するシングルトンオブジェクト + */ object Config { - // Component Settings - var blinkCooldown: Long = 1500 - var doubleJumpCooldown: Long = 1500 - var doubleJumpPowerVertical: Double = 0.5 - var doubleJumpPowerForward: Double = 0.3 + // グローバル設定 + var global = GlobalSettings() - // Global Settings - var componentTickInterval: Long = 1L + // コンポーネント設定 + var blink = BlinkSettings() + var doubleJump = DoubleJumpSettings() + var veinMiner = VeinMinerSettings() - // Vein Miner - data class ToolCategory(val tool: String, val blocks: List) - var veinMinerMaxBlocks: Int = 64 - var veinMinerActivationMode: String = "SNEAK" // "SNEAK", "ALWAYS", "STAND" - val veinMinerCompatibleMaterials: MutableMap> = mutableMapOf() - val veinMinerBlockColors: MutableMap = mutableMapOf() - val veinMinerToolCategories: MutableList = mutableListOf() + /** + * グローバル設定 + */ + data class GlobalSettings( + var tickInterval: Long = 1L + ) + /** + * Blinkコンポーネント設定 + */ + data class BlinkSettings( + var cooldown: Long = 1500 + ) + /** + * DoubleJumpコンポーネント設定 + */ + data class DoubleJumpSettings( + var cooldown: Long = 1500, + var powerVertical: Double = 0.5, + var powerForward: Double = 0.3 + ) + + /** + * VeinMinerコンポーネント設定 + */ + data class VeinMinerSettings( + var maxBlocks: Int = 64, + var activationMode: ActivationMode = ActivationMode.SNEAK, + val compatibleMaterials: MutableMap> = mutableMapOf(), + val blockColors: MutableMap = mutableMapOf(), + val toolCategories: MutableList = mutableListOf() + ) + + /** + * VeinMinerのアクティベーションモード + */ + enum class ActivationMode { + SNEAK, // スニーク時のみ有効 + ALWAYS, // 常に有効 + STAND; // 立っている時のみ有効 + + companion object { + fun fromString(value: String): ActivationMode { + return values().find { it.name.equals(value, ignoreCase = true) } ?: SNEAK + } + } + } + + /** + * ツールカテゴリ設定 + */ + data class ToolCategory( + val tool: String, + val blocks: List + ) + + /** + * 設定ファイルから設定を読み込む + */ fun load(plugin: JavaPlugin) { plugin.reloadConfig() val config = plugin.config - // Global - componentTickInterval = config.getLong("components.global.tick_interval", 1L).coerceAtLeast(1L) - - // Blink - blinkCooldown = config.getLong("components.blink.cooldown", 1500) + loadGlobalSettings(config) + loadBlinkSettings(config) + loadDoubleJumpSettings(config) + loadVeinMinerSettings(plugin, config) - // Double Jump - doubleJumpCooldown = config.getLong("components.double_jump.cooldown", 1500) - doubleJumpPowerVertical = config.getDouble("components.double_jump.power.vertical", 0.5) - doubleJumpPowerForward = config.getDouble("components.double_jump.power.forward", 0.3) - - // Vein Miner - val rawMaxBlocks = config.getInt("components.vein_miner.max_blocks", 64) - if (rawMaxBlocks > 2048) { - plugin.logger.warning("Vein miner max blocks set to $rawMaxBlocks, which is very high. Capping at 2048 to prevent crashes.") - veinMinerMaxBlocks = 2048 - } else { - veinMinerMaxBlocks = rawMaxBlocks - } - - veinMinerActivationMode = config.getString("components.vein_miner.activation_mode", "SNEAK") ?: "SNEAK" - loadCompatibleGroups(config) - loadBlockColors(config) - loadToolCategories(config) - - // Save back to ensure defaults are written if missing saveDefaults(plugin, config) } + /** + * グローバル設定を読み込む + */ + private fun loadGlobalSettings(config: FileConfiguration) { + global = GlobalSettings( + tickInterval = config.getLong("components.global.tick_interval", 1L).coerceAtLeast(1L) + ) + } + + /** + * Blink設定を読み込む + */ + private fun loadBlinkSettings(config: FileConfiguration) { + blink = BlinkSettings( + cooldown = config.getLong("components.blink.cooldown", 1500) + ) + } + + /** + * DoubleJump設定を読み込む + */ + private fun loadDoubleJumpSettings(config: FileConfiguration) { + doubleJump = DoubleJumpSettings( + cooldown = config.getLong("components.double_jump.cooldown", 1500), + powerVertical = config.getDouble("components.double_jump.power.vertical", 0.5), + powerForward = config.getDouble("components.double_jump.power.forward", 0.3) + ) + } + + /** + * VeinMiner設定を読み込む + */ + private fun loadVeinMinerSettings(plugin: JavaPlugin, config: FileConfiguration) { + val rawMaxBlocks = config.getInt("components.vein_miner.max_blocks", 64) + val maxBlocks = if (rawMaxBlocks > 2048) { + plugin.logger.warning("Vein miner max blocks set to $rawMaxBlocks, which is very high. Capping at 2048 to prevent crashes.") + 2048 + } else { + rawMaxBlocks + } + + val activationModeStr = config.getString("components.vein_miner.activation_mode", "SNEAK") ?: "SNEAK" + val activationMode = ActivationMode.fromString(activationModeStr) + + veinMiner = VeinMinerSettings( + maxBlocks = maxBlocks, + activationMode = activationMode + ) + + loadCompatibleGroups(config, veinMiner.compatibleMaterials) + loadBlockColors(config, veinMiner.blockColors) + loadToolCategories(config, veinMiner.toolCategories) + } + + /** + * デフォルト設定を保存する + */ private fun saveDefaults(plugin: JavaPlugin, config: FileConfiguration) { config.addDefault("components.global.tick_interval", 1L) - config.addDefault("components.blink.cooldown", 1500) config.addDefault("components.double_jump.cooldown", 1500) config.addDefault("components.double_jump.power.vertical", 0.5) config.addDefault("components.double_jump.power.forward", 0.3) - config.addDefault("components.vein_miner.max_blocks", 64) - // Groups default is complex to add here, relying on config.yml resource or existing file - - // Tool categories default is handled by config.yml resource + config.addDefault("components.vein_miner.activation_mode", "SNEAK") config.options().copyDefaults(true) plugin.saveConfig() } - private fun loadCompatibleGroups(config: FileConfiguration) { - veinMinerCompatibleMaterials.clear() + /** + * 互換性のあるブロックグループを読み込む + */ + private fun loadCompatibleGroups( + config: FileConfiguration, + compatibleMaterials: MutableMap> + ) { + compatibleMaterials.clear() val groups = config.getList("components.vein_miner.compatible_groups") as? List<*> ?: return for (groupObj in groups) { @@ -84,82 +180,121 @@ object Config { else -> continue } - val materials = mutableSetOf() - - for (it in group) { - val name = (it as? String) ?: continue - if (name.startsWith("#")) { - val key = org.bukkit.NamespacedKey.fromString(name.substring(1)) - if (key != null) { - val tag = org.bukkit.Bukkit.getTag(org.bukkit.Tag.REGISTRY_BLOCKS, key, org.bukkit.Material::class.java) - if (tag != null) { - materials.addAll(tag.values) - } - } - } else { - try { - materials.add(org.bukkit.Material.valueOf(name.uppercase().removePrefix("MINECRAFT:"))) - } catch (e: IllegalArgumentException) { - // Ignore - } - } - } + val materials = parseMaterialList(group) + // 各マテリアルに対して、グループ内の全マテリアルを互換性リストに追加 for (mat in materials) { - val existing = veinMinerCompatibleMaterials.getOrDefault(mat, emptySet()) - veinMinerCompatibleMaterials[mat] = existing + materials + val existing = compatibleMaterials.getOrDefault(mat, emptySet()) + compatibleMaterials[mat] = existing + materials } } } - private fun loadToolCategories(config: FileConfiguration) { - veinMinerToolCategories.clear() + /** + * ツールカテゴリを読み込む + */ + private fun loadToolCategories( + config: FileConfiguration, + toolCategories: MutableList + ) { + toolCategories.clear() val list = config.getMapList("components.vein_miner.tool_categories") for (map in list) { val tool = map["tool"] as? String ?: continue val blocks = (map["active_blocks"] as? List<*>)?.filterIsInstance() ?: continue - veinMinerToolCategories.add(ToolCategory(tool, blocks)) + toolCategories.add(ToolCategory(tool, blocks)) } } - private fun loadBlockColors(config: FileConfiguration) { - veinMinerBlockColors.clear() + + /** + * ブロックの色設定を読み込む + */ + private fun loadBlockColors( + config: FileConfiguration, + blockColors: MutableMap + ) { + blockColors.clear() val section = config.getConfigurationSection("components.vein_miner.block_colors") ?: return for (keyStr in section.getKeys(false)) { val hexOrRgb = section.getString(keyStr) ?: continue - val color = try { - if (hexOrRgb.contains(",")) { - val parts = hexOrRgb.split(",").map { it.trim().toInt() } - if (parts.size == 3) org.bukkit.Color.fromRGB(parts[0], parts[1], parts[2]) else null - } else { - val hex = hexOrRgb.removePrefix("#") - org.bukkit.Color.fromRGB(hex.toInt(16)) - } - } catch (e: Exception) { - null - } + val color = parseColor(hexOrRgb) ?: continue - if (color == null) continue - - if (keyStr.startsWith("#")) { - val key = org.bukkit.NamespacedKey.fromString(keyStr.substring(1)) - if (key != null) { - val tag = org.bukkit.Bukkit.getTag(org.bukkit.Tag.REGISTRY_BLOCKS, key, org.bukkit.Material::class.java) - if (tag != null) { - for (mat in tag.values) { - veinMinerBlockColors[mat] = color - } - } - } - } else { - try { - val mat = org.bukkit.Material.valueOf(keyStr.uppercase().removePrefix("MINECRAFT:")) - veinMinerBlockColors[mat] = color - } catch (e: IllegalArgumentException) { - continue - } + val materials = parseMaterialKey(keyStr) + for (mat in materials) { + blockColors[mat] = color } } } + + /** + * マテリアルリストを解析する + */ + private fun parseMaterialList(list: List<*>): Set { + val materials = mutableSetOf() + + for (item in list) { + val name = (item as? String) ?: continue + materials.addAll(parseMaterialKey(name)) + } + + return materials + } + + /** + * マテリアルキーを解析する(タグまたは個別マテリアル) + */ + private fun parseMaterialKey(key: String): Set { + return if (key.startsWith("#")) { + // タグとして解析 + parseTag(key.substring(1)) + } else { + // 個別マテリアルとして解析 + parseSingleMaterial(key)?.let { setOf(it) } ?: emptySet() + } + } + + /** + * タグからマテリアルセットを取得する + */ + private fun parseTag(tagName: String): Set { + val key = NamespacedKey.fromString(tagName) ?: return emptySet() + val tag = Bukkit.getTag(Tag.REGISTRY_BLOCKS, key, Material::class.java) ?: return emptySet() + return tag.values.toSet() + } + + /** + * 単一のマテリアルを解析する + */ + private fun parseSingleMaterial(name: String): Material? { + return try { + Material.valueOf(name.uppercase().removePrefix("MINECRAFT:")) + } catch (e: IllegalArgumentException) { + null + } + } + + /** + * 色文字列を解析する(HEXまたはRGB) + */ + private fun parseColor(colorStr: String): Color? { + return try { + if (colorStr.contains(",")) { + // RGB形式 + val parts = colorStr.split(",").map { it.trim().toInt() } + if (parts.size == 3) { + Color.fromRGB(parts[0], parts[1], parts[2]) + } else { + null + } + } else { + // HEX形式 + val hex = colorStr.removePrefix("#") + Color.fromRGB(hex.toInt(16)) + } + } catch (e: Exception) { + null + } + } } diff --git a/src/main/kotlin/net/hareworks/hcu/items/content/components/BlinkComponent.kt b/src/main/kotlin/net/hareworks/hcu/items/content/components/BlinkComponent.kt index 9427e03..ffed388 100644 --- a/src/main/kotlin/net/hareworks/hcu/items/content/components/BlinkComponent.kt +++ b/src/main/kotlin/net/hareworks/hcu/items/content/components/BlinkComponent.kt @@ -35,7 +35,7 @@ class BlinkComponent(private val plugin: App) : AbstractComponent(plugin, "blink companion object { // Track players who have used their blink (GLIDER is removed until landing) private val usedBlink = ConcurrentHashMap.newKeySet() - private val cooldown = Cooldown(net.hareworks.hcu.items.config.Config.blinkCooldown) + private val cooldown = Cooldown(net.hareworks.hcu.items.config.Config.blink.cooldown) // Color scheme - Purple/Magenta for teleport/blink theme private val PRIMARY_COLOR = TextColor.color(0xDA70D6) // Orchid diff --git a/src/main/kotlin/net/hareworks/hcu/items/content/components/DoubleJumpComponent.kt b/src/main/kotlin/net/hareworks/hcu/items/content/components/DoubleJumpComponent.kt index 740185e..08893bd 100644 --- a/src/main/kotlin/net/hareworks/hcu/items/content/components/DoubleJumpComponent.kt +++ b/src/main/kotlin/net/hareworks/hcu/items/content/components/DoubleJumpComponent.kt @@ -34,7 +34,7 @@ class DoubleJumpComponent(private val plugin: App) : AbstractComponent(plugin, " companion object { // Track players who have used their double jump (GLIDER is removed) private val usedDoubleJump = ConcurrentHashMap.newKeySet() - private val cooldown = Cooldown(net.hareworks.hcu.items.config.Config.doubleJumpCooldown) + private val cooldown = Cooldown(net.hareworks.hcu.items.config.Config.doubleJump.cooldown) // Color scheme private val PRIMARY_COLOR = TextColor.color(0x7DF9FF) // Electric Cyan @@ -127,8 +127,8 @@ class DoubleJumpComponent(private val plugin: App) : AbstractComponent(plugin, " val currentVelocity = player.velocity // Base power + Tier bonus - val verticalPower = net.hareworks.hcu.items.config.Config.doubleJumpPowerVertical + (tier.level * 0.15) - val forwardPower = net.hareworks.hcu.items.config.Config.doubleJumpPowerForward + (tier.level * 0.1) + val verticalPower = net.hareworks.hcu.items.config.Config.doubleJump.powerVertical + (tier.level * 0.15) + val forwardPower = net.hareworks.hcu.items.config.Config.doubleJump.powerForward + (tier.level * 0.1) player.velocity = currentVelocity.add(direction.multiply(forwardPower)).setY(verticalPower) diff --git a/src/main/kotlin/net/hareworks/hcu/items/content/components/GliderComponent.kt b/src/main/kotlin/net/hareworks/hcu/items/content/components/GliderComponent.kt index 77e2d13..31ed8f3 100644 --- a/src/main/kotlin/net/hareworks/hcu/items/content/components/GliderComponent.kt +++ b/src/main/kotlin/net/hareworks/hcu/items/content/components/GliderComponent.kt @@ -45,7 +45,7 @@ class GliderComponent(private val plugin: App) : AbstractComponent(plugin, "glid init { // Global Ticker for active gliders - val interval = net.hareworks.hcu.items.config.Config.componentTickInterval + val interval = net.hareworks.hcu.items.config.Config.global.tickInterval plugin.server.scheduler.runTaskTimer(plugin, Runnable { if (activeGliders.isEmpty()) return@Runnable @@ -120,7 +120,7 @@ class GliderComponent(private val plugin: App) : AbstractComponent(plugin, "glid // Find the itemStack that has this component in user's equipment private fun findGliderItem(player: Player): ItemStack? { - val equipment = player.equipment ?: return null + val equipment = player.equipment val candidates = mutableListOf() candidates.addAll(equipment.armorContents.filterNotNull()) candidates.add(equipment.itemInMainHand) diff --git a/src/main/kotlin/net/hareworks/hcu/items/content/components/VeinMinerComponent.kt b/src/main/kotlin/net/hareworks/hcu/items/content/components/VeinMinerComponent.kt index 3d16502..80bb21b 100644 --- a/src/main/kotlin/net/hareworks/hcu/items/content/components/VeinMinerComponent.kt +++ b/src/main/kotlin/net/hareworks/hcu/items/content/components/VeinMinerComponent.kt @@ -120,7 +120,7 @@ class VeinMinerComponent(private val plugin: JavaPlugin) : ToolComponent { org.joml.AxisAngle4f(0f, 0f, 0f, 1f) ) e.isGlowing = true - e.glowColorOverride = Config.veinMinerBlockColors[block.type] ?: block.blockData.getMapColor() + e.glowColorOverride = Config.veinMiner.blockColors[block.type] ?: block.blockData.getMapColor() e.brightness = Display.Brightness(15, 15) // 最大輝度 e.isVisibleByDefault = false } @@ -180,11 +180,10 @@ class VeinMinerComponent(private val plugin: JavaPlugin) : ToolComponent { } private fun shouldActivate(player: Player): Boolean { - return when (Config.veinMinerActivationMode) { - "SNEAK" -> player.isSneaking - "STAND" -> !player.isSneaking - "ALWAYS" -> true - else -> player.isSneaking + return when (Config.veinMiner.activationMode) { + Config.ActivationMode.SNEAK -> player.isSneaking + Config.ActivationMode.STAND -> !player.isSneaking + Config.ActivationMode.ALWAYS -> true } } @@ -196,14 +195,14 @@ class VeinMinerComponent(private val plugin: JavaPlugin) : ToolComponent { // 互換ブロックタイプ抽出 val startType = startBlock.type - val targetMaterials = Config.veinMinerCompatibleMaterials[startType] ?: setOf() + val targetMaterials = Config.veinMiner.compatibleMaterials[startType] ?: setOf() val efficientTargets = if (targetMaterials.isNotEmpty()) targetMaterials else setOf(startType) val queue: Queue = LinkedList() visited.add(startBlock) queue.add(startBlock) - val max = Config.veinMinerMaxBlocks + val max = Config.veinMiner.maxBlocks // 見つかったブロックの実リスト val foundBlocks = mutableSetOf() foundBlocks.add(startBlock) @@ -240,7 +239,7 @@ class VeinMinerComponent(private val plugin: JavaPlugin) : ToolComponent { private fun isValidTarget(block: Block, item: ItemStack): Boolean { if (block.getDrops(item).isEmpty()) return false - for (category in Config.veinMinerToolCategories) { + for (category in Config.veinMiner.toolCategories) { if (matchesTool(item, category.tool)) { for (blockPattern in category.blocks) { if (matchesBlock(block, blockPattern)) { diff --git a/src/main/kotlin/net/hareworks/hcu/items/listeners/EventListener.kt b/src/main/kotlin/net/hareworks/hcu/items/listeners/EventListener.kt index 582ad84..70ab5de 100644 --- a/src/main/kotlin/net/hareworks/hcu/items/listeners/EventListener.kt +++ b/src/main/kotlin/net/hareworks/hcu/items/listeners/EventListener.kt @@ -22,7 +22,7 @@ class EventListener(private val plugin: Plugin) : Listener { init { // Use configurable tick interval (defaulting to 1L if something goes wrong, though Config handles defaults) - val interval = net.hareworks.hcu.items.config.Config.componentTickInterval + val interval = net.hareworks.hcu.items.config.Config.global.tickInterval plugin.server.scheduler.runTaskTimer(plugin, Runnable { tickComponents() }, 1L, interval)