Add support for passing Components as placeholders in LanguageManager (getComponent, getMessageList) and add Player extension overloads (sendMsg, trans) that accept component pairs. Replace usages of legacy serialized strings with direct Component placeholders across kits, scoreboard, and listeners (remove legacySerializer imports/usages). Also normalize placeholder keys (remove angle brackets in ConnectListener) and scope legacySerializer as private in Extensions.
139 lines
3.8 KiB
Kotlin
139 lines
3.8 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 getMessageList(
|
|
player: Player,
|
|
key: String,
|
|
placeholders: Map<String, String>,
|
|
components: Map<String, Component> = mapOf()
|
|
): List<Component>
|
|
{
|
|
val rawList = getRawMessageList( player, key )
|
|
val compTags = components.map { (k, v) -> Placeholder.component( k, v ) }
|
|
val tags = placeholders.map { (k, v) -> Placeholder.parsed( k, v ) }.plus( compTags )
|
|
return rawList.map { str -> miniMessage.deserialize( str, *tags.toTypedArray() ) }
|
|
}
|
|
|
|
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>,
|
|
components: Map<String, Component> = mapOf()
|
|
): Component
|
|
{
|
|
val prefixRaw = getRawMessage( player, "default.prefix" )
|
|
val prefixTag = Placeholder.parsed( "prefix", prefixRaw )
|
|
val raw = getRawMessage( player, key )
|
|
val compTags = components.map { (k, v) -> Placeholder.component( k, v ) }
|
|
val tags = placeholders.map { (k, v) -> Placeholder.parsed( k, v ) }.plus( prefixTag ).plus( compTags )
|
|
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() )
|
|
}
|
|
|
|
} |