From 8b094e334482addfd0715f686e291b90a0c99d40 Mon Sep 17 00:00:00 2001 From: Jannis Kramer Date: Tue, 29 Mar 2022 16:31:19 +0200 Subject: [PATCH] more Components instead of Strings (#44) Closes #36 --- .../axay/kspigot/chat/LiteralTextBuilder.kt | 4 +- .../input/implementations/PlayerInputChat.kt | 2 +- .../kspigot/extensions/GeneralExtensions.kt | 8 ++++ .../extensions/bukkit/ComponentExtensions.kt | 43 +++++++++++++++++++ .../extensions/bukkit/EntityExtensions.kt | 23 ++++++---- src/main/kotlin/net/axay/kspigot/gui/GUI.kt | 3 +- .../kotlin/net/axay/kspigot/gui/GUIBuilder.kt | 4 +- .../kotlin/net/axay/kspigot/gui/GUIType.kt | 10 ++--- .../net/axay/kspigot/items/KSpigotItems.kt | 12 ++++++ 9 files changed, 89 insertions(+), 20 deletions(-) create mode 100644 src/main/kotlin/net/axay/kspigot/extensions/bukkit/ComponentExtensions.kt diff --git a/src/main/kotlin/net/axay/kspigot/chat/LiteralTextBuilder.kt b/src/main/kotlin/net/axay/kspigot/chat/LiteralTextBuilder.kt index 86946f0d..0dfb0c99 100644 --- a/src/main/kotlin/net/axay/kspigot/chat/LiteralTextBuilder.kt +++ b/src/main/kotlin/net/axay/kspigot/chat/LiteralTextBuilder.kt @@ -38,9 +38,7 @@ class LiteralTextBuilder(val internalText: Component) { * This can be set in the following way: * * e.g. Medium turquoise: - * - `color = col(0x4BD6CB)` - * - `color = col(4970187)` - * - `color = col("#4BD6CB")` + * - `color = TextColor.color(72, 209, 204)` * - `color = KColors.MEDIUMTURQUOISE` */ var color: TextColor? = null diff --git a/src/main/kotlin/net/axay/kspigot/chat/input/implementations/PlayerInputChat.kt b/src/main/kotlin/net/axay/kspigot/chat/input/implementations/PlayerInputChat.kt index 46fae1e3..18814b8b 100644 --- a/src/main/kotlin/net/axay/kspigot/chat/input/implementations/PlayerInputChat.kt +++ b/src/main/kotlin/net/axay/kspigot/chat/input/implementations/PlayerInputChat.kt @@ -21,8 +21,8 @@ internal class PlayerInputChat( override val inputListeners = listOf( listen(EventPriority.LOWEST) { if (it.player == player) { - onReceive(it.message()) it.isCancelled = true + onReceive(it.message()) } } ) diff --git a/src/main/kotlin/net/axay/kspigot/extensions/GeneralExtensions.kt b/src/main/kotlin/net/axay/kspigot/extensions/GeneralExtensions.kt index 4979e4cc..8fa4e90a 100644 --- a/src/main/kotlin/net/axay/kspigot/extensions/GeneralExtensions.kt +++ b/src/main/kotlin/net/axay/kspigot/extensions/GeneralExtensions.kt @@ -3,6 +3,7 @@ package net.axay.kspigot.extensions import net.axay.kspigot.main.PluginInstance +import net.kyori.adventure.text.Component import net.kyori.adventure.text.Component.text import org.bukkit.Bukkit import org.bukkit.NamespacedKey @@ -41,6 +42,13 @@ val pluginManager get() = Bukkit.getPluginManager() */ fun broadcast(msg: String) = Bukkit.getServer().broadcast(text(msg)) +/** + * Broadcasts a message ([msg]) on the server. + * @return the number of recipients + * @see Bukkit.broadcastMessage + */ +fun broadcast(msg: Component) = Bukkit.getServer().broadcast(msg) + /** * Shortcut to get the ConsoleSender. * @see Bukkit.getConsoleSender diff --git a/src/main/kotlin/net/axay/kspigot/extensions/bukkit/ComponentExtensions.kt b/src/main/kotlin/net/axay/kspigot/extensions/bukkit/ComponentExtensions.kt new file mode 100644 index 00000000..eea77c0f --- /dev/null +++ b/src/main/kotlin/net/axay/kspigot/extensions/bukkit/ComponentExtensions.kt @@ -0,0 +1,43 @@ +@file:Suppress("unused") +package net.axay.kspigot.extensions.bukkit + +import net.kyori.adventure.text.Component +import net.kyori.adventure.text.TranslatableComponent +import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer +import net.kyori.adventure.text.serializer.plain.PlainTextComponentSerializer +import net.kyori.adventure.translation.GlobalTranslator +import java.util.Locale + +/** + * Returns a [Component] from a [String] + */ +fun String.toComponent(): Component = Component.text(this) + +/** + * Returns a [TranslatableComponent] with the given [String] as key and [args] + */ +fun String.asTranslatable(vararg args: Component): TranslatableComponent = Component.translatable(this, *args) + +/** + * Returns a [Component] from a [String] with legacy formatting + */ +fun String.legacyToComponent(): Component = LegacyComponentSerializer.legacyAmpersand().deserialize(this) + +/** + * Returns a [String] with legacy formatting from a [Component] + * + * Note: Render [TranslatableComponent]s before using this + */ +fun Component.toLegacyString(): String = LegacyComponentSerializer.legacyAmpersand().serialize(this) + +/** + * Returns a [String] from a [Component] + * + * Note: Render [TranslatableComponent]s before using this + */ +fun Component.plainText(): String = PlainTextComponentSerializer.plainText().serialize(this) + +/** + * Renders a [TranslatableComponent] with the given [locale] + */ +fun TranslatableComponent.render(locale: Locale): Component = GlobalTranslator.render(this, locale) diff --git a/src/main/kotlin/net/axay/kspigot/extensions/bukkit/EntityExtensions.kt b/src/main/kotlin/net/axay/kspigot/extensions/bukkit/EntityExtensions.kt index 299d0499..ebb07a5c 100644 --- a/src/main/kotlin/net/axay/kspigot/extensions/bukkit/EntityExtensions.kt +++ b/src/main/kotlin/net/axay/kspigot/extensions/bukkit/EntityExtensions.kt @@ -7,12 +7,20 @@ import net.axay.kspigot.chat.literalText import net.axay.kspigot.extensions.onlinePlayers import net.axay.kspigot.main.PluginInstance import net.axay.kspigot.pluginmessages.PluginMessageConnect +import net.kyori.adventure.text.Component +import net.kyori.adventure.title.Title import org.bukkit.Location import org.bukkit.Material import org.bukkit.attribute.Attribute -import org.bukkit.entity.* +import org.bukkit.entity.ArmorStand +import org.bukkit.entity.Damageable +import org.bukkit.entity.Entity +import org.bukkit.entity.EntityType +import org.bukkit.entity.LivingEntity +import org.bukkit.entity.Player import org.bukkit.inventory.EquipmentSlot import org.bukkit.inventory.ItemStack +import java.time.Duration /** * Checks if the entities' head is in water. @@ -123,14 +131,13 @@ fun Location.spawnCleanEntity(entityType: EntityType): Entity? { * @param fadeOut time in ticks for titles to fade out */ fun Player.title( - mainText: String? = null, - subText: String? = null, - fadeIn: Int = 10, - stay: Int = 70, - fadeOut: Int = 20, + mainText: Component = Component.empty(), + subText: Component = Component.empty(), + fadeIn: Duration = Duration.ofMillis(500), + stay: Duration = Duration.ofMillis(3500), + fadeOut: Duration = Duration.ofMillis(1000), ) { - @Suppress("DEPRECATION") - sendTitle(mainText, subText, fadeIn, stay, fadeOut) + showTitle(Title.title(mainText, subText, Title.Times.times(fadeIn, stay, fadeOut))) } /** diff --git a/src/main/kotlin/net/axay/kspigot/gui/GUI.kt b/src/main/kotlin/net/axay/kspigot/gui/GUI.kt index a9e92d25..3caa57bf 100644 --- a/src/main/kotlin/net/axay/kspigot/gui/GUI.kt +++ b/src/main/kotlin/net/axay/kspigot/gui/GUI.kt @@ -5,6 +5,7 @@ package net.axay.kspigot.gui import net.axay.kspigot.event.listen import net.axay.kspigot.extensions.bukkit.closeForViewers import net.axay.kspigot.main.PluginInstance +import net.kyori.adventure.text.Component import org.bukkit.entity.Player import org.bukkit.event.inventory.InventoryCloseEvent import org.bukkit.event.player.PlayerQuitEvent @@ -13,7 +14,7 @@ import org.bukkit.inventory.ItemStack class GUIData( val guiType: GUIType, - val title: String?, + val title: Component, internal val pages: Map>, val defaultPage: Int, val transitionTo: InventoryChangeEffect?, diff --git a/src/main/kotlin/net/axay/kspigot/gui/GUIBuilder.kt b/src/main/kotlin/net/axay/kspigot/gui/GUIBuilder.kt index c199e24c..8faed12b 100644 --- a/src/main/kotlin/net/axay/kspigot/gui/GUIBuilder.kt +++ b/src/main/kotlin/net/axay/kspigot/gui/GUIBuilder.kt @@ -3,7 +3,7 @@ package net.axay.kspigot.gui import net.axay.kspigot.gui.elements.* -import org.bukkit.event.inventory.InventoryCloseEvent +import net.kyori.adventure.text.Component import org.bukkit.inventory.ItemStack import kotlin.math.absoluteValue @@ -24,7 +24,7 @@ class GUIBuilder( * This title will be visible for every page of * this GUI. */ - var title: String = "" + var title: Component = Component.empty() /** * The transition applied, if another GUI redirects to diff --git a/src/main/kotlin/net/axay/kspigot/gui/GUIType.kt b/src/main/kotlin/net/axay/kspigot/gui/GUIType.kt index 556678f7..c0b0dbcf 100644 --- a/src/main/kotlin/net/axay/kspigot/gui/GUIType.kt +++ b/src/main/kotlin/net/axay/kspigot/gui/GUIType.kt @@ -2,7 +2,8 @@ package net.axay.kspigot.gui -import net.kyori.adventure.text.Component.text +import net.kyori.adventure.text.Component +import net.kyori.adventure.text.Component.empty import org.bukkit.Bukkit import org.bukkit.event.inventory.InventoryType import org.bukkit.inventory.Inventory @@ -25,11 +26,10 @@ class GUIType( GUIType(InventoryDimensions(3, 3), bukkitType = InventoryType.DROPPER) } - fun createBukkitInv(holder: InventoryHolder? = null, title: String? = null): Inventory { - val realTitle = title ?: "" + fun createBukkitInv(holder: InventoryHolder? = null, title: Component = empty()): Inventory { return when { - bukkitType != null -> Bukkit.createInventory(holder, bukkitType, text(realTitle)) - else -> Bukkit.createInventory(holder, dimensions.slotAmount, text(realTitle)) + bukkitType != null -> Bukkit.createInventory(holder, bukkitType, title) + else -> Bukkit.createInventory(holder, dimensions.slotAmount, title) } } } diff --git a/src/main/kotlin/net/axay/kspigot/items/KSpigotItems.kt b/src/main/kotlin/net/axay/kspigot/items/KSpigotItems.kt index 851ed788..acab4647 100644 --- a/src/main/kotlin/net/axay/kspigot/items/KSpigotItems.kt +++ b/src/main/kotlin/net/axay/kspigot/items/KSpigotItems.kt @@ -82,9 +82,19 @@ inline fun ItemMeta.addLore(builder: ItemMetaLoreBuilder.() -> Unit) { */ class ItemMetaLoreBuilder { val lorelist = ArrayList() + + /** + * Adds a new line to the lore. + * + * Note: Render [TranslatableComponent]s before adding them to the lore. + */ operator fun Component.unaryPlus() { lorelist += this } + + /** + * Adds a new line to the lore. + */ operator fun String.unaryPlus() { lorelist += text(this) } @@ -112,6 +122,8 @@ fun ItemMeta.removeFlags(vararg itemFlag: ItemFlag) = removeItemFlags(*itemFlag) /** * Provides safe access to the items' displayName. + * + * Note: Render [TranslatableComponent]s before setting them as the displayName. */ var ItemMeta.name: Component? get() = if (hasDisplayName()) displayName() else null