Skip to content

Commit

Permalink
cleanup chat format
Browse files Browse the repository at this point in the history
  • Loading branch information
Miles Holder committed May 8, 2024
1 parent 1f7bef3 commit 139d621
Show file tree
Hide file tree
Showing 18 changed files with 420 additions and 135 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,17 @@ import org.bukkit.command.CommandSender
class GreedyStringArg(name: String) : CommandArgument<String>(name) {
override val greedy: Boolean = true

override fun parse(sender: CommandSender, value: String): String {
override fun parse(
sender: CommandSender,
value: String,
): String {
return value
}

override fun tabComplete(sender: CommandSender, typing: String): List<String> {
override fun tabComplete(
sender: CommandSender,
typing: String,
): List<String> {
return emptyList()
}
}
Original file line number Diff line number Diff line change
@@ -1,14 +1,17 @@
package com.github.spigotbasics.modules.basicsbroadcast

import com.github.spigotbasics.core.command.parsed.arguments.AnyStringArg
import com.github.spigotbasics.core.command.parsed.arguments.GreedyStringArg
import com.github.spigotbasics.core.command.parsed.arguments.LiteralArg
import com.github.spigotbasics.core.module.AbstractBasicsModule
import com.github.spigotbasics.core.module.loader.ModuleInstantiationContext

class BasicsBroadcastModule(context: ModuleInstantiationContext) : AbstractBasicsModule(context) {
private val commandPerm = permissionManager.createSimplePermission("basics.broadcast", "Allows the user to broadcast messages")
private val parsedPerm = permissionManager.createSimplePermission("basics.broadcast.parsed", "Allows the user to broadcast parsed messages")
private val parsedPerm =
permissionManager.createSimplePermission(
"basics.broadcast.parsed",
"Allows the user to broadcast parsed messages",
)

override fun onEnable() {
commandFactory.parsedCommandBuilder("broadcast", commandPerm)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,19 @@ import org.bukkit.command.CommandSender
import org.bukkit.entity.Player

class BroadcastCommand(private val module: BasicsBroadcastModule) : CommandContextExecutor<MapContext> {

override fun execute(sender: CommandSender, context: MapContext) {
override fun execute(
sender: CommandSender,
context: MapContext,
) {
val parsed = context["parsed"] != null
val rawMessage = context["message"] as String

val message = if (parsed) {
module.messageFactory.createMessage(rawMessage).concerns(sender as? Player)
} else {
module.messageFactory.createPlainMessage(rawMessage)
}
val message =
if (parsed) {
module.messageFactory.createMessage(rawMessage).concerns(sender as? Player)
} else {
module.messageFactory.createPlainMessage(rawMessage)
}

message.sendToAllPlayers()
message.sendToConsole()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,115 +2,112 @@ package com.github.spigotbasics.modules.basicschatformat

import com.github.spigotbasics.core.Serialization
import com.github.spigotbasics.core.Spiper
import com.github.spigotbasics.core.command.parsed.arguments.AnyStringArg
import com.github.spigotbasics.core.config.ConfigName
import com.github.spigotbasics.core.messages.Message
import com.github.spigotbasics.core.module.AbstractBasicsModule
import com.github.spigotbasics.core.module.loader.ModuleInstantiationContext
import com.github.spigotbasics.core.storage.NamespacedStorage
import com.github.spigotbasics.modules.basicschatformat.commmands.ColorChatCommand
import com.github.spigotbasics.modules.basicschatformat.data.ChatData
import org.bukkit.event.EventPriority
import org.bukkit.event.player.AsyncPlayerChatEvent
import com.github.spigotbasics.modules.basicschatformat.data.ChatFormatData
import com.github.spigotbasics.modules.basicschatformat.data.ChatFormatStore
import com.github.spigotbasics.modules.basicschatformat.listener.PaperChatEventListener
import com.github.spigotbasics.modules.basicschatformat.listener.SpigotChatEventListener
import java.util.UUID
import java.util.concurrent.CompletableFuture
import java.util.logging.Level

private fun String.escapeFormat(): String {
return this.replace("%", "%%")
}

class BasicsChatFormatModule(context: ModuleInstantiationContext) : AbstractBasicsModule(context) {
private var storage: NamespacedStorage? = null
private val chatData = mutableMapOf<UUID, ChatData>()
override val messages = getConfig(ConfigName.MESSAGES, Messages::class.java)
companion object {
lateinit var instance: BasicsChatFormatModule
}

val permissionChatColor =
private val permissionChatColor =
permissionManager.createSimplePermission("basics.chatcolor", "Allows access to the /chatcolor command")

val format: Message
get() = config.getMessage("chat-format")

val permissionNamedColors =
permissionManager.createSimplePermission("basics.chatcolor.named", "Allows access to all named colors")
val permissionHexColors =
permissionManager.createSimplePermission("basics.chatcolor.hex", "Allows access to all hex colors")
val permissionGradientNamed =
permissionManager.createSimplePermission(
"basics.chatcolor.gradient.named",
"Allows access to gradient with named colors only",
)
val permissionGradientHex =
permissionManager.createSimplePermission(
"basics.chatcolor.gradient.hex",
"Allows access to gradient with hex colors only",
)

val chatFormat: Message = config.getMessage("chat-format")
val messageColor: String get() = config.getString("default-message-color") ?: "white"
val chatFormatStore = ChatFormatStore(this)
override val messages: Messages = getConfig(ConfigName.MESSAGES, Messages::class.java)

val regex: Regex
get() =
Regex(
config.getString(
"regex-whitelist",
config.getString(
"regex-blacklist",
"\\b(bold|b|italic|em|i|underlined|u|strikethrough|st|obfuscated|obf)\\b",
)!!,
)!!,
)
private lateinit var storage: NamespacedStorage

override fun onEnable() {
storage = createStorage()
instance = this
storage = createStorage(name = "chat_format")

if (Spiper.isPaper) {
eventBus.subscribe(PaperChatEventListener(this))
} else {
eventBus.subscribe(AsyncPlayerChatEvent::class.java, this::changeChatFormatSpigot, EventPriority.HIGHEST)
eventBus.subscribe(
SpigotChatEventListener(this),
)
}

commandFactory.rawCommandBuilder("chatcolor", permissionChatColor)
.description("Sets your chat color")
.usage("[reset|<color>]")
.executor(ColorChatCommand(this))
.register()
commandFactory.parsedCommandBuilder("chatcolor", permissionChatColor).mapContext {
usage = "[reset|set] <color>"
path {
playerOnly()

arguments {
sub("set")
named("color", AnyStringArg("color"))
}
}

path {
playerOnly()

arguments {
sub("reset")
}
}
}.executor(ChatColorCommand(this)).register()
}

override fun reloadConfig() {
config.reload()
messages.reload()
}

fun changeChatFormatSpigot(event: AsyncPlayerChatEvent) {
event.format =
format
.concerns(event.player)
.tagUnparsed("message", event.message) // TODO: To allow MiniMessage in chat, this should be parsed.
.tagParsed("message-color", "<${getChatDataOrDefault(event.player.uniqueId).color}>")
.toLegacyString().escapeFormat()
}

fun getChatDataOrDefault(uuid: UUID) = chatData.getOrDefault(uuid, ChatData(messageColor))

fun setChatData(
uuid: UUID,
chatData: ChatData,
) {
this.chatData[uuid] = chatData
}

override fun loadPlayerData(uuid: UUID): CompletableFuture<Void?> =
CompletableFuture.runAsync {
loadPlayerDataBlocking(uuid)?.let { chatData[uuid] = it }
loadPlayerDataBlocking(uuid)?.let { chatFormatStore.chatFormatData[uuid] = it }
}

override fun savePlayerData(uuid: UUID): CompletableFuture<Void?> {
val chatDatum = chatData[uuid]
val chatDatum = chatFormatStore.chatFormatData[uuid]
val storage = storage ?: error("Storage is null")
return storage.setJsonElement(uuid.toString(), Serialization.toJson(chatDatum))
}

override fun forgetPlayerData(uuid: UUID) {
chatData.remove(uuid)
chatFormatStore.chatFormatData.remove(uuid)
}

private fun loadPlayerDataBlocking(uuid: UUID): ChatData? {
val storage = storage ?: error("Storage is null")
private fun loadPlayerDataBlocking(uuid: UUID): ChatFormatData? {
val storage = storage
try {
val json = storage.getJsonElement(uuid.toString()).join() ?: return null
return Serialization.fromJson(json, ChatData::class.java)
return Serialization.fromJson(json, ChatFormatData::class.java)
} catch (e: Exception) {
logger.log(Level.SEVERE, "Failed to load chat data for $uuid", e)
}

return null
}

fun resetChatColor(uniqueId: UUID) {
forgetPlayerData(uniqueId)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
package com.github.spigotbasics.modules.basicschatformat

import com.github.spigotbasics.core.command.parsed.CommandContextExecutor
import com.github.spigotbasics.core.command.parsed.context.MapContext
import com.github.spigotbasics.modules.basicschatformat.data.ChatFormatData
import com.github.spigotbasics.modules.basicschatformat.data.packages.ChatColorPackage
import com.github.spigotbasics.modules.basicschatformat.data.packages.ColorType
import org.bukkit.command.CommandSender
import org.bukkit.entity.Player

class ChatColorCommand(private val module: BasicsChatFormatModule) : CommandContextExecutor<MapContext> {
override fun execute(
sender: CommandSender,
context: MapContext,
) {
val player = sender as Player

val rawColor = context["color"] as String?
if (rawColor == null) {
module.forgetPlayerData(player.uniqueId)
module.messages.colorReset.concerns(player).sendToSender(player)
return
}
val color = clean(rawColor)
if (color == null) {
module.messages.colorInvalid(rawColor).concerns(player).sendToSender(player)
return
}

var colorPackage: ChatColorPackage? = null
for (value in ColorType.entries) {
if (value.colorPackage.check(color)) {
colorPackage = value.colorPackage
break
}
}

if (colorPackage == null) {
module.messages.colorInvalid(color).sendToSender(player)
return
}

if (!colorPackage.hasPermission(player, color)) {
module.coreMessages.noPermission.concerns(player).sendToSender(player)
return
}

val setupColor = colorPackage.setup(color)
module.chatFormatStore.setChatData(player.uniqueId, ChatFormatData(setupColor))
module.messages.colorSet("<$setupColor>", rawColor).concerns(player).sendToSender(player)
}

private fun clean(dirtyColor: String): String? {
val builder = StringBuilder()
for ((index, c) in dirtyColor.withIndex()) {
if (c == '<' && index != 0 || c == '>' && index != dirtyColor.length - 1) {
return null
}

if (c == '<' || c == '>') {
continue
}

builder.append(c)
}

return builder.toString()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,12 @@ import com.github.spigotbasics.core.config.ConfigInstantiationContext
import com.github.spigotbasics.core.config.SavedConfig

class Messages(context: ConfigInstantiationContext) : SavedConfig(context) {
fun colorSet(color: String) =
getMessage("color-set")
.tagParsed("selected-color-parsed", "<$color>")
.tagUnparsed("selected-color-name", color)
fun colorSet(
colorParsed: String,
colorRaw: String,
) = getMessage("color-set")
.tagParsed("selected-color-parsed", colorParsed)
.tagUnparsed("selected-color-name", colorRaw)

fun colorInvalid(color: String) =
getMessage("color-invalid")
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
package com.github.spigotbasics.modules.basicschatformat.data

data class ChatData(var color: String)
data class ChatFormatData(var color: String)
Loading

0 comments on commit 139d621

Please sign in to comment.