Skip to content

Commit

Permalink
Merge pull request #1 from TheChilliPL/dev
Browse files Browse the repository at this point in the history
Version 0.1, merge dev to master
  • Loading branch information
TheChilliPL authored Aug 10, 2020
2 parents 1b95ccf + 49e4bdf commit d917c31
Show file tree
Hide file tree
Showing 9 changed files with 295 additions and 37 deletions.
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,5 @@ gradle-app.setting
.gradletasknamecache

# IntelliJ IDEA
/.idea/
/.idea/*
!/.idea/codeStyles
26 changes: 26 additions & 0 deletions .idea/codeStyles/Project.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions .idea/codeStyles/codeStyleConfig.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package me.patrykanuszczyk.textcomponentserialization

import net.md_5.bungee.api.chat.TextComponent
import org.bukkit.configuration.ConfigurationSection
import org.bukkit.inventory.ItemStack

fun ConfigurationSection.getTextComponent(path: String): TextComponent? {
return deserializeTextComponent(this.get(path))
}

fun ConfigurationSection.setTextComponent(path: String, value: TextComponent?) {
this.set(path, value.serialize())
}

fun ConfigurationSection.getTextComponentList(path: String): List<TextComponent?> {
return this.getList(path).map { deserializeTextComponent(it) }
}

fun ConfigurationSection.setTextComponentList(path: String, value: List<TextComponent?>) {
this.set(path, value.map { it.serialize() })
}

fun ConfigurationSection.getBook(path: String): ItemStack? {
return deserializeBook(this.get(path))
}

fun ConfigurationSection.setBook(path: String, value: ItemStack?) {
this.set(path, serializeBook(value))
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,15 @@ import net.md_5.bungee.api.ChatColor
import net.md_5.bungee.api.chat.ClickEvent
import net.md_5.bungee.api.chat.HoverEvent
import net.md_5.bungee.api.chat.TextComponent
import org.bukkit.Material
import org.bukkit.configuration.ConfigurationSection
import org.bukkit.inventory.ItemStack
import org.bukkit.inventory.meta.BookMeta

/**
* Deserializes a text component.
* @since 1.0
*/
fun deserializeTextComponent(obj: Any?): TextComponent? {
val map = when (obj) {
null -> return null
Expand All @@ -20,16 +27,17 @@ fun deserializeTextComponent(obj: Any?): TextComponent? {

component.text = map["text"] as String? ?: ""

component.extra = (map["extra"] as List<*>)
.map {
deserializeTextComponent(
it ?: throw NullPointerException("Extra object is null!")
)
}
if (map["extra"] != null)
component.extra = (map["extra"] as List<*>)
.map {
deserializeTextComponent(
it ?: throw NullPointerException("Extra object is null!")
)
}

val color = deserializeChatColor(map["color"])

component.color = color

component.setBold(map["bold"] as Boolean?)
component.setItalic(map["italic"] as Boolean?)
component.setUnderlined(map["underlined"] as Boolean?)
Expand All @@ -46,8 +54,12 @@ fun deserializeTextComponent(obj: Any?): TextComponent? {
return component
}

/**
* Deserializes a chat color.
* @since 1.0
*/
fun deserializeChatColor(obj: Any?): ChatColor? {
if(obj == null) return null
if (obj == null) return null
require(obj is String) { "Color has to be a string!" }

val canonicalName = obj
Expand All @@ -57,33 +69,93 @@ fun deserializeChatColor(obj: Any?): ChatColor? {
return ChatColor.valueOf(canonicalName)
}

/**
* Deserializes a click event.
* @since 1.0
*/
fun deserializeClickEvent(obj: Any?): ClickEvent? {
if (obj == null) return null
require(obj is ConfigurationSection) { "Click event has to be a configuration section or null!" }
val map = when(obj) {
null -> return null
is ConfigurationSection -> obj.getValues(false)
is Map<*,*> -> obj
else -> throw IllegalArgumentException("Couldn't deserialize click event from ${obj::class.qualifiedName}!")
}.toMapOf<String, String>()

val actionString = obj.getString("action")
val actionString = map["action"] ?: throw NullPointerException("No action specified for click event!")
val actionCanonicalName = actionString
.replace(' ', '_')
.toUpperCase()
val action = ClickEvent.Action.valueOf(actionCanonicalName)

val value = obj.getString("value")
val value = map["value"]

return ClickEvent(action, value)
}

/**
* Deserializes a hover event.
* @since 1.0
*/
fun deserializeHoverEvent(obj: Any?): HoverEvent? {
if(obj == null) return null
require(obj is ConfigurationSection) { "Hover event has to be a configuration section or null!" }
val map = when(obj) {
null -> return null
is ConfigurationSection -> obj.getValues(true)
is Map<*,*> -> obj
else -> throw IllegalArgumentException("Couldn't deserialize click event from ${obj::class.qualifiedName}!")
}.toMapOf<String, Any>()

val actionString = obj.getString("action")
val actionString = map["action"] as String
val actionCanonicalName = actionString
.replace(' ', '_')
.toUpperCase()
val action = HoverEvent.Action.valueOf(actionCanonicalName)

val value =
deserializeTextComponent(obj.get("value"))
deserializeTextComponent(map["value"])

return HoverEvent(action, arrayOf(value))
}

/**
* Deserializes a book.
* @since 1.0
*/
fun deserializeBook(obj: Any?): ItemStack? {
val map = when (obj) {
null -> return null
is ConfigurationSection -> obj.getValues(true)
is Map<*, *> -> obj.toMapOf<String, Any>()
else -> throw IllegalArgumentException("Couldn't deserialize text component from ${obj::class.qualifiedName}!")
}

val stack = ItemStack(Material.WRITTEN_BOOK)

val meta = stack.itemMeta as BookMeta

meta.title = map["title"] as String?
meta.author = map["author"] as String?
meta.generation = deserializeBookGeneration(map["generation"])

meta.spigot().pages = (map["pages"] as List<*>).map {
arrayOf(deserializeTextComponent(it))
}

stack.itemMeta = meta

return stack
}

/**
* Deserializes book generation.
* @since 1.0
*/
fun deserializeBookGeneration(obj: Any?): BookMeta.Generation? {
if (obj == null) return null
require(obj is String) { "Book generation has to be a string!" }

val canonicalName = obj
.replace(' ', '_')
.toUpperCase()

return BookMeta.Generation.valueOf(canonicalName)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
package me.patrykanuszczyk.textcomponentserialization

import net.md_5.bungee.api.chat.ClickEvent
import net.md_5.bungee.api.chat.HoverEvent
import net.md_5.bungee.api.chat.TextComponent
import org.bukkit.ChatColor
import org.bukkit.inventory.ItemStack
import org.bukkit.inventory.meta.BookMeta

fun formatString(string: String, placeholders: Map<String, String>? = null): String {
var stringFormatted = string
placeholders?.forEach { (key, value) ->
stringFormatted = stringFormatted.replace("{$key}", value, true)
}
return ChatColor.translateAlternateColorCodes('&', stringFormatted)
}

fun TextComponent.format(placeholders: Map<String, String>? = null): TextComponent {
val newComponent = TextComponent(this)
if (text != null) newComponent.text = formatString(text, placeholders)
//extra?.forEach { newComponent.addExtra((it as TextComponent).format(placeholders)) }
if(extra != null)
newComponent.extra = extra.map { (it as TextComponent).format(placeholders) }
if (insertion != null) newComponent.insertion = formatString(insertion, placeholders)
if (clickEvent != null)
newComponent.clickEvent = ClickEvent(clickEvent.action, formatString(clickEvent.value, placeholders))
if (hoverEvent != null)
newComponent.hoverEvent = HoverEvent(hoverEvent.action, hoverEvent.value.map {
(it as TextComponent).format(placeholders)
}.toTypedArray())
return newComponent
}

fun formatBook(book: ItemStack?, placeholders: Map<String, String>? = null): ItemStack? {
if (book == null) return null

val oldMeta = book.itemMeta as BookMeta

val newBook = ItemStack(book)

val meta = newBook.itemMeta as BookMeta
meta.title = formatString(oldMeta.title, placeholders)
meta.author = formatString(oldMeta.author, placeholders)
meta.generation = oldMeta.generation

meta.spigot().addPage(*oldMeta.spigot().pages.map { page ->
page.map {
(it as TextComponent).format(placeholders)
}.toTypedArray()
}.toTypedArray())

newBook.itemMeta = meta

return newBook
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package me.patrykanuszczyk.textcomponentserialization

import net.md_5.bungee.api.chat.TextComponent

val TextComponent.isEmpty: Boolean
get() {
if(!text.isNullOrEmpty()) return false

return extra.all { it is TextComponent && it.isEmpty }
}

val TextComponent.isNotEmpty: Boolean get() = !isEmpty
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package me.patrykanuszczyk.textcomponentserialization

@JvmSynthetic
internal inline fun <reified K, reified V> Map<*, *>.toMapOf(): MutableMap<K, V> {
inline fun <reified K, reified V> Map<*, *>.toMapOf(): MutableMap<K, V> {
val map = mutableMapOf<K, V>()

for ((key, value) in this) {
Expand Down
Loading

0 comments on commit d917c31

Please sign in to comment.