Support Component placeholders in language API

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.
This commit is contained in:
TDSTOS
2026-03-25 18:29:21 +01:00
parent 9385269c50
commit 237ce56614
6 changed files with 52 additions and 26 deletions

View File

@@ -4,7 +4,6 @@ import club.mcscrims.speedhg.SpeedHG
import club.mcscrims.speedhg.game.GameState import club.mcscrims.speedhg.game.GameState
import club.mcscrims.speedhg.kit.Playstyle import club.mcscrims.speedhg.kit.Playstyle
import club.mcscrims.speedhg.kit.impl.BackupKit import club.mcscrims.speedhg.kit.impl.BackupKit
import club.mcscrims.speedhg.util.legacySerializer
import club.mcscrims.speedhg.util.sendMsg import club.mcscrims.speedhg.util.sendMsg
import org.bukkit.command.Command import org.bukkit.command.Command
import org.bukkit.command.CommandExecutor import org.bukkit.command.CommandExecutor
@@ -74,14 +73,14 @@ class KitCommand : CommandExecutor, TabCompleter {
plugin.kitManager.selectPlaystyle( player, playstyle ) plugin.kitManager.selectPlaystyle( player, playstyle )
plugin.kitManager.applyKit( player ) plugin.kitManager.applyKit( player )
player.sendMsg( "commands.kit.selected", "playstyle" to playstyle.displayName, "kit" to legacySerializer.serialize( kit.displayName )) player.sendMsg( "commands.kit.selected", mapOf( "playstyle" to playstyle.displayName ), "kit" to kit.displayName )
return true return true
} }
plugin.kitManager.selectKit( player, kit ) plugin.kitManager.selectKit( player, kit )
plugin.kitManager.selectPlaystyle( player, playstyle ) plugin.kitManager.selectPlaystyle( player, playstyle )
player.sendMsg( "commands.kit.selected", "playstyle" to playstyle.displayName, "kit" to legacySerializer.serialize( kit.displayName )) player.sendMsg( "commands.kit.selected", mapOf( "playstyle" to playstyle.displayName ), "kit" to kit.displayName )
return true return true
} }

View File

@@ -90,6 +90,19 @@ class LanguageManager(
return data?.lists?.get( key ) ?: listOf( "<red>Missing List: $key</red>" ) 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( fun getDefaultRawMessageList(
key: String key: String
): List<String> ): List<String>
@@ -101,13 +114,15 @@ class LanguageManager(
fun getComponent( fun getComponent(
player: Player, player: Player,
key: String, key: String,
placeholders: Map<String, String> placeholders: Map<String, String>,
components: Map<String, Component> = mapOf()
): Component ): Component
{ {
val prefixRaw = getRawMessage( player, "default.prefix" ) val prefixRaw = getRawMessage( player, "default.prefix" )
val prefixTag = Placeholder.parsed( "prefix", prefixRaw ) val prefixTag = Placeholder.parsed( "prefix", prefixRaw )
val raw = getRawMessage( player, key ) val raw = getRawMessage( player, key )
val tags = placeholders.map { (k, v) -> Placeholder.parsed( k, v ) }.plus( prefixTag ) 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() ) return miniMessage.deserialize( raw, *tags.toTypedArray() )
} }

View File

@@ -8,7 +8,6 @@ import club.mcscrims.speedhg.kit.ability.ActiveAbility
import club.mcscrims.speedhg.kit.ability.PassiveAbility import club.mcscrims.speedhg.kit.ability.PassiveAbility
import club.mcscrims.speedhg.util.ItemBuilder import club.mcscrims.speedhg.util.ItemBuilder
import club.mcscrims.speedhg.util.WorldEditUtils import club.mcscrims.speedhg.util.WorldEditUtils
import club.mcscrims.speedhg.util.legacySerializer
import club.mcscrims.speedhg.util.trans import club.mcscrims.speedhg.util.trans
import net.kyori.adventure.text.Component import net.kyori.adventure.text.Component
import org.bukkit.Bukkit import org.bukkit.Bukkit
@@ -157,7 +156,7 @@ class GoblinKit : Kit() {
activeStealTasks[ player.uniqueId ] = task activeStealTasks[ player.uniqueId ] = task
player.playSound( player.location, Sound.ENTITY_EVOKER_CAST_SPELL, 1f, 1.5f ) player.playSound( player.location, Sound.ENTITY_EVOKER_CAST_SPELL, 1f, 1.5f )
player.sendActionBar(player.trans( "kits.goblin.messages.stole_kit", "kit" to legacySerializer.serialize( targetKit.displayName ))) player.sendActionBar(player.trans( "kits.goblin.messages.stole_kit", mapOf(), "kit" to targetKit.displayName ))
return AbilityResult.Success return AbilityResult.Success
} }

View File

@@ -28,7 +28,7 @@ class ConnectListener : Listener {
return return
Bukkit.getOnlinePlayers().forEach { p -> Bukkit.getOnlinePlayers().forEach { p ->
p.sendMsg( "game.join", "<name>" to player.name ) p.sendMsg( "game.join", "name" to player.name )
} }
player.showTitle(Title.title( player.showTitle(Title.title(
@@ -49,7 +49,7 @@ class ConnectListener : Listener {
return return
Bukkit.getOnlinePlayers().forEach { p -> Bukkit.getOnlinePlayers().forEach { p ->
p.sendMsg( "game.quit", "<name>" to player.name ) p.sendMsg( "game.quit", "name" to player.name )
} }
} }

View File

@@ -2,9 +2,7 @@ package club.mcscrims.speedhg.scoreboard
import club.mcscrims.speedhg.SpeedHG import club.mcscrims.speedhg.SpeedHG
import club.mcscrims.speedhg.game.GameState import club.mcscrims.speedhg.game.GameState
import club.mcscrims.speedhg.util.legacySerializer
import club.mcscrims.speedhg.util.trans import club.mcscrims.speedhg.util.trans
import club.mcscrims.speedhg.util.transList
import fr.mrmicky.fastboard.adventure.FastBoard import fr.mrmicky.fastboard.adventure.FastBoard
import net.kyori.adventure.text.Component import net.kyori.adventure.text.Component
import org.bukkit.Bukkit import org.bukkit.Bukkit
@@ -66,7 +64,7 @@ class ScoreboardManager(
val online = Bukkit.getOnlinePlayers().size.toString() val online = Bukkit.getOnlinePlayers().size.toString()
val max = Bukkit.getMaxPlayers().toString() val max = Bukkit.getMaxPlayers().toString()
val kitName = legacySerializer.serialize(plugin.kitManager.getSelectedKit( player )?.displayName ?: Component.text( "None" )) val kitName = plugin.kitManager.getSelectedKit( player )?.displayName ?: Component.text( "None" )
val lines: List<Component> val lines: List<Component>
@@ -74,12 +72,11 @@ class ScoreboardManager(
{ {
val timeString = if ( state == GameState.STARTING ) formatTime( gm.timer ) else "Waiting..." val timeString = if ( state == GameState.STARTING ) formatTime( gm.timer ) else "Waiting..."
lines = player.transList( "scoreboard.lobby", mapOf( lines = plugin.languageManager.getMessageList(
"online" to online, player, "scoreboard.lobby",
"max" to max, mapOf( "online" to online, "max" to max, "time" to timeString ),
"kit" to kitName, mapOf( "kit" to kitName )
"time" to timeString )
))
} }
else else
{ {
@@ -88,13 +85,11 @@ class ScoreboardManager(
val kills = player.getStatistic( Statistic.PLAYER_KILLS ).toString() val kills = player.getStatistic( Statistic.PLAYER_KILLS ).toString()
val border = String.format( "%.0f", player.world.worldBorder.size ) val border = String.format( "%.0f", player.world.worldBorder.size )
lines = player.transList( "scoreboard.ingame", mapOf( lines = plugin.languageManager.getMessageList(
"timer" to timeString, player, "scoreboard.ingame",
"alive" to alive, mapOf( "timer" to timeString, "alive" to alive, "kills" to kills, "border" to border ),
"kills" to kills, mapOf( "kit" to kitName )
"border" to border, )
"kit" to kitName
))
} }
board.updateLines( lines ) board.updateLines( lines )

View File

@@ -8,7 +8,7 @@ import org.bukkit.entity.Player
private val langManager get() = SpeedHG.instance.languageManager private val langManager get() = SpeedHG.instance.languageManager
internal val legacySerializer = LegacyComponentSerializer.builder() private val legacySerializer = LegacyComponentSerializer.builder()
.character('§') .character('§')
.hexColors() .hexColors()
.useUnusualXRepeatedCharacterHexFormat() .useUnusualXRepeatedCharacterHexFormat()
@@ -22,6 +22,15 @@ fun Player.sendMsg(
this.sendMessage( component ) this.sendMessage( component )
} }
fun Player.sendMsg(
key: String,
placeholders: Map<String, String>,
vararg components: Pair<String, Component>
) {
val component = langManager.getComponent( this, key, placeholders, components.toMap() )
this.sendMessage( component )
}
fun Player.trans( fun Player.trans(
key: String, key: String,
vararg placeholders: Pair<String, String> vararg placeholders: Pair<String, String>
@@ -30,6 +39,15 @@ fun Player.trans(
return langManager.getComponent( this, key, placeholders.toMap() ) return langManager.getComponent( this, key, placeholders.toMap() )
} }
fun Player.trans(
key: String,
placeholders: Map<String, String>,
vararg components: Pair<String, Component>
): Component
{
return langManager.getComponent( this, key, placeholders, components.toMap() )
}
fun Player.transList( fun Player.transList(
key: String, key: String,
placeholders: Map<String, String> placeholders: Map<String, String>