Major refactor and bugfixes across language loading, kit lifecycle, and event handling:
- LanguageManager: Introduce LangData to hold string and list entries, load YAML lists alongside strings, and centralize retrieval (avoid reloading files at access time).
- GameManager: Use apply {} to configure worldBorder more concisely.
- KitManager.clearAll: Handle offline players by cleaning chargeData without calling lifecycle hooks (onActivate/onDeactivate cannot run for offline players).
- GoblinKit: Track per-player steal BukkitTask, cancel tasks on kit removal, only restore kits if player is still alive, and fix inventory removal by removing cached items and cleaning cache.
- KitEventDispatcher: Use null-safe chaining for victim passive hooks and early-return on non-block-position moves to ignore head-rotation events.
- GameStateListener: Add feastStarted flag placeholder and adjust iron ore handling/messages; add TODO for DB update.
- Extensions: Change legacySerializer visibility to internal.
These changes improve stability around scheduled tasks, offline cleanup, and language list support.
124 lines
3.3 KiB
Kotlin
124 lines
3.3 KiB
Kotlin
package club.mcscrims.speedhg.config
|
|
|
|
import net.kyori.adventure.text.Component
|
|
import net.kyori.adventure.text.minimessage.MiniMessage
|
|
import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder
|
|
import org.bukkit.configuration.file.YamlConfiguration
|
|
import org.bukkit.entity.Player
|
|
import org.bukkit.plugin.java.JavaPlugin
|
|
import java.io.File
|
|
import java.util.concurrent.ConcurrentHashMap
|
|
|
|
class LanguageManager(
|
|
private val plugin: JavaPlugin
|
|
) {
|
|
|
|
private data class LangData(
|
|
val strings: Map<String, String>,
|
|
val lists: Map<String, List<String>>
|
|
)
|
|
|
|
// Map: Sprachcode -> (Key -> Nachricht)
|
|
private val languages = ConcurrentHashMap<String, LangData>()
|
|
private val miniMessage = MiniMessage.miniMessage()
|
|
private val defaultLanguage = plugin.config.getString("default.language", "en_US")!!
|
|
|
|
init {
|
|
loadLanguages()
|
|
}
|
|
|
|
fun loadLanguages()
|
|
{
|
|
languages.clear()
|
|
val folder = File( plugin.dataFolder, "languages" )
|
|
|
|
if ( !folder.exists() ) {
|
|
folder.mkdirs()
|
|
createDefault("de_DE")
|
|
createDefault("en_US")
|
|
}
|
|
|
|
folder.walk().filter { it.extension == "yml" }.forEach { file ->
|
|
val langCode = file.nameWithoutExtension
|
|
val config = YamlConfiguration.loadConfiguration( file )
|
|
|
|
val strings = config.getKeys( true )
|
|
.filter { config.isString( it ) }
|
|
.associateWith { config.getString( it )!! }
|
|
|
|
val lists = config.getKeys( true )
|
|
.filter { config.isList( it ) }
|
|
.associateWith { config.getStringList( it ) }
|
|
|
|
languages[ langCode ] = LangData( strings, lists )
|
|
}
|
|
}
|
|
|
|
private fun createDefault(
|
|
locale: String
|
|
) {
|
|
val fileName = "languages/$locale.yml"
|
|
if (plugin.getResource( fileName ) != null) {
|
|
plugin.saveResource( fileName, false )
|
|
}
|
|
}
|
|
|
|
fun getRawMessage(
|
|
player: Player,
|
|
key: String
|
|
): String
|
|
{
|
|
val locale = player.locale().toString()
|
|
val langMap = languages[ locale ] ?: languages[ defaultLanguage ]
|
|
return langMap?.strings?.get( key ) ?: "<red>Missing Key: $key</red>"
|
|
}
|
|
|
|
fun getDefaultRawMessage(
|
|
key: String
|
|
): String
|
|
{
|
|
return languages[ defaultLanguage ]?.strings?.get( key ) ?: "<red>Missing Key: $key</red>"
|
|
}
|
|
|
|
fun getRawMessageList(
|
|
player: Player,
|
|
key: String
|
|
): List<String>
|
|
{
|
|
val locale = player.locale().toString()
|
|
val data = languages[ locale ] ?: languages[ defaultLanguage ]
|
|
return data?.lists?.get( key ) ?: listOf( "<red>Missing List: $key</red>" )
|
|
}
|
|
|
|
fun getDefaultRawMessageList(
|
|
key: String
|
|
): List<String>
|
|
{
|
|
val data = languages[ defaultLanguage ]
|
|
return data?.lists?.get( key ) ?: listOf( "<red>Missing List: $key</red>" )
|
|
}
|
|
|
|
fun getComponent(
|
|
player: Player,
|
|
key: String,
|
|
placeholders: Map<String, String>
|
|
): Component
|
|
{
|
|
val prefixRaw = getRawMessage( player, "default.prefix" )
|
|
val prefixTag = Placeholder.parsed( "prefix", prefixRaw )
|
|
val raw = getRawMessage( player, key )
|
|
val tags = placeholders.map { (k, v) -> Placeholder.parsed( k, v ) }.plus( prefixTag )
|
|
return miniMessage.deserialize( raw, *tags.toTypedArray() )
|
|
}
|
|
|
|
fun getDefaultComponent(
|
|
key: String,
|
|
placeholders: Map<String, String>
|
|
): Component
|
|
{
|
|
val raw = languages[ defaultLanguage ]?.strings?.get( key ) ?: "<red>Missing Key: $key</red>"
|
|
val tags = placeholders.map { (k, v) -> Placeholder.parsed( k, v ) }
|
|
return miniMessage.deserialize( raw, *tags.toTypedArray() )
|
|
}
|
|
|
|
} |