Changed some shit idk #7

Merged
SKBotNL merged 13 commits from main into main 2025-08-27 18:23:41 -04:00
20 changed files with 550 additions and 216 deletions

No files matched your search

@@ -7,7 +7,7 @@ import kotlinx.coroutines.launch
class BlocklistManager {
private val lock = Any()
private var blockList = mutableListOf<String>()
private val blockList = mutableListOf<String>()
init {
ChatOG.plugin.logger.info("Loading the blocklists...")
@@ -24,14 +24,13 @@ class BlocklistManager {
private fun refresh() {
blockList.clear()
URI("https://raw.githubusercontent.com/hagezi/dns-blocklists/main/domains/multi.txt")
.toURL()
.openStream()
.use { input ->
ChatOG.config.blocklists.forEach { blocklist ->
URI(blocklist).toURL().openStream().use { input ->
input.bufferedReader().use { bufferedReader ->
synchronized(lock) { bufferedReader.lines().forEach { if (!it.startsWith("#")) blockList.add(it) } }
}
}
}
}
private val urlRegex = Regex("(?:https?://)?([a-zA-Z0-9.-]+\\.[a-zA-Z]{2,})")
@@ -1,32 +0,0 @@
package nl.skbotnl.chatog
import me.clip.placeholderapi.PlaceholderAPI
import net.kyori.adventure.text.TextComponent
import net.trueog.utilitiesog.UtilitiesOG
import nl.skbotnl.chatog.Helper.legacyToMm
import org.bukkit.entity.Player
internal object ChatHelper {
fun getPlayerPart(player: Player, addSuffix: Boolean): TextComponent {
val playerPartString = getPlayerPartString(player)
val suffix =
if (addSuffix) {
PlayerAffix.getSuffix(player.uniqueId)
} else {
""
}
return UtilitiesOG.trueogColorize(legacyToMm("$playerPartString<reset>$suffix"))
}
fun getPlayerPartString(player: Player): String {
var playerPart = "${PlayerAffix.getPrefix(player.uniqueId)}${player.name}"
if (PlaceholderAPI.setPlaceholders(player, "%simpleclans_clan_color_tag%") != "") {
playerPart = PlaceholderAPI.setPlaceholders(player, "&8[%simpleclans_clan_color_tag%&8] $playerPart")
}
return playerPart
}
}
+17 -5
View File
@@ -19,7 +19,7 @@ internal class ChatOG : JavaPlugin() {
lateinit var plugin: JavaPlugin
lateinit var config: Config
lateinit var blocklistManager: BlocklistManager
var blocklistManager: BlocklistManager? = null
lateinit var luckPerms: LuckPerms
lateinit var languageDatabase: LanguageDatabase
var translator: OpenAI? = null
@@ -27,6 +27,8 @@ internal class ChatOG : JavaPlugin() {
val discordBridgeLock = ReentrantReadWriteLock()
var essentials = Bukkit.getServer().pluginManager.getPlugin("Essentials") as Essentials
var lastMessagedMap: MutableMap<UUID, UUID> = HashMap()
fun isLanguageDatabaseInitialized() = ::languageDatabase.isInitialized
}
@OptIn(DelicateCoroutinesApi::class)
@@ -40,18 +42,20 @@ internal class ChatOG : JavaPlugin() {
return
}
blocklistManager = BlocklistManager()
if (Companion.config.blocklistEnabled) {
blocklistManager = BlocklistManager()
}
translator =
if (Companion.config.openAIEnabled) {
if (Companion.config.openAIBaseUrl == null) {
this.logger.warning(
"You have enabled OpenAI but have not set up the base url, not enabling the translator"
"You have enabled OpenAI translation but have not set up the base url, not enabling the translator"
)
null
} else if (Companion.config.openAIApiKey == null) {
this.logger.warning(
"You have enabled OpenAI but have not set up the api key, not enabling the translator"
"You have enabled OpenAI translation but have not set up the api key, not enabling the translator"
)
null
} else {
@@ -81,10 +85,14 @@ internal class ChatOG : JavaPlugin() {
this.getCommand("translatesettings")?.setExecutor(TranslateSettings())
this.getCommand("translatesettings")?.tabCompleter = TranslateSettingsTabCompleter()
this.getCommand("chatconfigreload")?.setExecutor(ChatConfigReload())
this.getCommand("gc")?.setExecutor(GeneralChat())
this.getCommand("g")?.setExecutor(GeneralChat())
this.getCommand("sc")?.setExecutor(StaffChat())
this.getCommand("s")?.setExecutor(StaffChat())
this.getCommand("pc")?.setExecutor(PremiumChat())
this.getCommand("p")?.setExecutor(PremiumChat())
this.getCommand("dc")?.setExecutor(DeveloperChat())
this.getCommand("d")?.setExecutor(DeveloperChat())
this.getCommand("msg")?.setExecutor(PrivateMessage())
this.getCommand("whisper")?.setExecutor(PrivateMessage())
this.getCommand("pm")?.setExecutor(PrivateMessage())
@@ -100,7 +108,7 @@ internal class ChatOG : JavaPlugin() {
}
override fun onDisable() {
if (Companion.config.discordEnabled) {
if (discordBridge != null) {
discordBridgeLock.read {
val discordBridge = discordBridge
val serverHasStoppedMessage =
@@ -117,6 +125,10 @@ internal class ChatOG : JavaPlugin() {
}
}
if (isLanguageDatabaseInitialized()) {
languageDatabase.shutdown()
}
scope.cancel()
runBlocking { scope.coroutineContext[Job]?.join() }
+56 -18
View File
@@ -11,8 +11,7 @@ import net.kyori.adventure.text.event.HoverEvent
import net.trueog.utilitiesog.UtilitiesOG
import nl.skbotnl.chatog.ChatOG.Companion.config
import nl.skbotnl.chatog.ChatOG.Companion.discordBridgeLock
import nl.skbotnl.chatog.Helper.legacyToMm
import nl.skbotnl.chatog.Helper.removeColor
import nl.skbotnl.chatog.ChatUtil.legacyToMm
import nl.skbotnl.chatog.commands.TranslateMessage
import org.bukkit.Bukkit
import org.bukkit.entity.Player
@@ -23,29 +22,26 @@ internal object ChatSystem {
GENERAL_CHAT,
STAFF_CHAT,
PREMIUM_CHAT,
DEVELOPER_CHAT,
}
var inChat: MutableMap<UUID, ChatType> = HashMap()
fun sendMessageInStaffChat(player: Player, text: String) {
var playerPartString = ChatHelper.getPlayerPartString(player)
var playerPartString = ChatUtil.getPlayerPartString(player)
playerPartString = "&cSTAFF | $playerPartString"
if (config.staffDiscordEnabled) {
val discordMessageString = Helper.convertEmojis(text)
val discordMessageString = ChatUtil.convertEmojis(text)
ChatOG.scope.launch {
discordBridgeLock.read {
ChatOG.discordBridge?.sendStaffMessage(
discordMessageString,
removeColor(playerPartString),
player.uniqueId,
)
ChatOG.discordBridge?.sendStaffMessage(discordMessageString, playerPartString, player.uniqueId)
}
}
}
val messageComponent = Helper.processText(text, player)
val messageComponent = ChatUtil.processText(text, player)
if (messageComponent == null) {
return
}
@@ -78,24 +74,20 @@ internal object ChatSystem {
}
fun sendMessageInPremiumChat(player: Player, text: String) {
var playerPartString = ChatHelper.getPlayerPartString(player)
var playerPartString = ChatUtil.getPlayerPartString(player)
playerPartString = "&aPREMIUM | $playerPartString"
if (config.premiumDiscordEnabled) {
val discordMessageString = Helper.convertEmojis(text)
val discordMessageString = ChatUtil.convertEmojis(text)
ChatOG.scope.launch {
discordBridgeLock.read {
ChatOG.discordBridge?.sendPremiumMessage(
discordMessageString,
removeColor(playerPartString),
player.uniqueId,
)
ChatOG.discordBridge?.sendPremiumMessage(discordMessageString, playerPartString, player.uniqueId)
}
}
}
val messageComponent = Helper.processText(text, player)
val messageComponent = ChatUtil.processText(text, player)
if (messageComponent == null) {
return
}
@@ -126,4 +118,50 @@ internal object ChatSystem {
}
}
}
fun sendMessageInDeveloperChat(player: Player, text: String) {
var playerPartString = ChatUtil.getPlayerPartString(player)
playerPartString = "<aqua>DEVELOPER | $playerPartString"
if (config.premiumDiscordEnabled) {
val discordMessageString = ChatUtil.convertEmojis(text)
ChatOG.scope.launch {
discordBridgeLock.read {
ChatOG.discordBridge?.sendDeveloperMessage(discordMessageString, playerPartString, player.uniqueId)
}
}
}
val messageComponent = ChatUtil.processText(text, player)
if (messageComponent == null) {
return
}
val chatComponent =
UtilitiesOG.trueogColorize(legacyToMm("$playerPartString<reset>${PlayerAffix.getSuffix(player.uniqueId)}"))
var textComponent = Component.join(JoinConfiguration.noSeparators(), chatComponent, messageComponent)
textComponent =
textComponent.hoverEvent(
HoverEvent.hoverEvent(
HoverEvent.Action.SHOW_TEXT,
UtilitiesOG.trueogColorize("<green>Click to translate this message"),
)
)
val randomUUID = UUID.randomUUID()
textComponent =
textComponent.clickEvent(
ClickEvent.clickEvent(ClickEvent.Action.RUN_COMMAND, "/translatemessage $randomUUID 1")
)
TranslateMessage.chatMessages[randomUUID] = TranslateMessage.SentChatMessage(text, player)
for (p in Bukkit.getOnlinePlayers()) {
if (p.hasPermission("chat-og.developer")) {
p.sendMessage(textComponent)
}
}
}
}
@@ -1,9 +1,13 @@
package nl.skbotnl.chatog
import dev.minn.jda.ktx.coroutines.await
import java.util.*
import java.util.HashMap
import java.util.UUID
import kotlin.collections.forEach
import kotlin.concurrent.read
import me.clip.placeholderapi.PlaceholderAPI
import net.kyori.adventure.text.Component
import net.kyori.adventure.text.TextComponent
import net.kyori.adventure.text.event.ClickEvent
import net.kyori.adventure.text.event.HoverEvent
import net.kyori.adventure.text.format.TextColor
@@ -13,14 +17,54 @@ import net.kyori.adventure.text.minimessage.tag.Tag
import net.kyori.adventure.text.minimessage.tag.resolver.ArgumentQueue
import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver
import net.kyori.adventure.text.minimessage.tag.standard.StandardTags
import net.kyori.adventure.text.serializer.plain.PlainTextComponentSerializer
import net.trueog.utilitiesog.UtilitiesOG
import nl.skbotnl.chatog.ChatOG.Companion.blocklistManager
import nl.skbotnl.chatog.ChatOG.Companion.config
import nl.skbotnl.chatog.ChatOG.Companion.discordBridgeLock
import org.bukkit.Bukkit
import org.bukkit.Sound
import org.bukkit.entity.Player
internal object Helper {
internal object ChatUtil {
fun getPlayerPart(player: Player, addSuffix: Boolean): TextComponent {
val playerPartString = getPlayerPartString(player)
val suffix =
if (addSuffix) {
PlayerAffix.getSuffix(player.uniqueId)
} else {
""
}
return UtilitiesOG.trueogColorize(legacyToMm("$playerPartString<reset>$suffix"))
}
fun getPlayerPartString(player: Player): String {
var playerPart = "${PlayerAffix.getPrefix(player.uniqueId)}${player.name}"
if (PlaceholderAPI.setPlaceholders(player, "%simpleclans_clan_color_tag%") != "") {
playerPart = PlaceholderAPI.setPlaceholders(player, "&8[%simpleclans_clan_color_tag%&8] $playerPart")
}
return playerPart
}
val mentionRegex = Regex("@([A-Za-z0-9_]{3,16})")
fun dingForMentions(dontDingFor: UUID, component: Component) {
val messageContent = PlainTextComponentSerializer.plainText().serialize(component)
val namesToMention = mutableListOf<String>()
mentionRegex.findAll(messageContent).iterator().forEach { namesToMention += it.groups[1]!!.value.lowercase() }
for (player in Bukkit.getOnlinePlayers()) {
if (player.uniqueId == dontDingFor) continue
if (player.name.lowercase() !in namesToMention) continue
player.playSound(player, Sound.ENTITY_EXPERIENCE_ORB_PICKUP, 1f, 1f)
}
}
private var translateTimeout: MutableMap<UUID, Long> = HashMap()
fun getTranslateTimeout(uuid: UUID): Long {
@@ -70,14 +114,6 @@ internal object Helper {
return legacyRegex.replace(text) { legacyToMmMap[it.groupValues[1].lowercase()] ?: it.value }
}
private val colorRegex = Regex("[§&]?[§&]([0-9a-fk-orA-FK-OR])")
fun removeColor(text: String): String {
var tempText = text
colorRegex.findAll(text).iterator().forEach { tempText = tempText.replace(it.value, "") }
return tempText
}
private val getHandle = Regex("@([a-z0-9_.]{2,32})")
suspend fun convertMentions(text: String): String {
@@ -103,7 +139,11 @@ internal object Helper {
private val urlRegex = Regex("(.*?)((?:https?://)?[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}(?:/?[a-zA-Z]*)+)(.*)")
val noColorMm = MiniMessage.builder().editTags { b -> b.tag("a", Helper::createA) }.build()
val noColorMm =
MiniMessage.builder()
.tags(TagResolver.builder().build())
.editTags { b -> b.tag("a", ChatUtil::createA) }
.build()
val colorMm =
MiniMessage.builder()
@@ -117,7 +157,7 @@ internal object Helper {
.resolver(StandardTags.gradient())
.build()
)
.editTags { b -> b.tag("a", Helper::createA) }
.editTags { b -> b.tag("a", ChatUtil::createA) }
.build()
fun createA(args: ArgumentQueue, @Suppress("unused") ctx: Context): Tag {
@@ -136,11 +176,11 @@ internal object Helper {
)
}
fun processText(text: String, player: Player) = processText(text, player, null)
fun processText(text: String, player: Player) = processText(text, player, null, false)
fun processText(text: String, username: String) = processText(text, null, username)
fun processText(text: String, username: String, color: Boolean) = processText(text, null, username, color)
private fun processText(text: String, player: Player?, username: String?): Component? {
private fun processText(text: String, player: Player?, username: String?, color: Boolean): Component? {
val words: MutableList<String> = mutableListOf()
legacyToMm(text).split(" ").forEach { word ->
@@ -148,7 +188,7 @@ internal object Helper {
if (url != null) {
val link = url.groups[2]?.value ?: ""
if (blocklistManager.checkUrl(link)) {
if (blocklistManager?.checkUrl(link) == true) {
player?.sendMessage(
UtilitiesOG.trueogColorize(
"${config.prefix}<reset>: <red>WARNING: You are not allowed to post links like that here."
@@ -181,7 +221,11 @@ internal object Helper {
return if (player?.hasPermission("chat-og.color") == true) {
colorMm.deserialize(words.joinToString(" "))
} else {
noColorMm.deserialize(words.joinToString(" "))
if (color) {
colorMm.deserialize(words.joinToString(" "))
} else {
noColorMm.deserialize(words.joinToString(" "))
}
}
}
@@ -222,4 +266,15 @@ internal object Helper {
return tempText
}
fun recolorComponent(component: Component, color: TextColor): Component {
var newComponent = component
if (component.color() == null) {
newComponent = component.color(color)
}
val children = newComponent.children().map { recolorComponent(it, color) }
newComponent.children(children)
return newComponent
}
}
+129 -54
View File
@@ -6,6 +6,8 @@ import org.bukkit.configuration.file.YamlConfiguration
internal class Config private constructor() {
lateinit var prefix: String
var blocklistEnabled = false
var blocklists = listOf<String>()
lateinit var redisUrl: String
var openAIEnabled = false
var openAIBaseUrl: String? = null
@@ -14,6 +16,7 @@ internal class Config private constructor() {
var discordEnabled = false
var staffDiscordEnabled = false
var premiumDiscordEnabled = false
var developerDiscordEnabled = false
var status: String? = null
var serverHasStartedMessage: String? = null
var serverHasStoppedMessage: String? = null
@@ -21,15 +24,20 @@ internal class Config private constructor() {
var channelId: String? = null
var staffChannelId: String? = null
var premiumChannelId: String? = null
var developerChannelId: String? = null
var guildId: String? = null
var webhook: String? = null
var staffWebhook: String? = null
var premiumWebhook: String? = null
var developerWebhook: String? = null
var listCommandName: String? = null
var listCommandText: String? = null
var colorCodeRoles: List<String> = listOf()
var roles: Set<String> = setOf()
var useColorCodeRoles = false
var colorCodeRoles = listOf<String>()
var roles = setOf<String>()
var roleMessageColor: MutableMap<String, Any> = mutableMapOf()
var rolesWithSuffixes = setOf<String>()
var roleSuffix: MutableMap<String, String> = mutableMapOf()
data class RGBColor(val r: Int, val g: Int, val b: Int)
@@ -50,6 +58,17 @@ internal class Config private constructor() {
return null
}
try {
config.blocklistEnabled = yamlConfig.get("blocklistEnabled") as Boolean
} catch (_: Exception) {
ChatOG.plugin.logger.severe("Failed to parse config option \"blocklistEnabled\" as a boolean")
return null
}
if (config.blocklistEnabled) {
config.blocklists = yamlConfig.getStringList("blocklists")
}
try {
config.redisUrl = yamlConfig.get("redisUrl") as String
} catch (_: Exception) {
@@ -108,6 +127,13 @@ internal class Config private constructor() {
return null
}
try {
config.developerDiscordEnabled = yamlConfig.get("developerDiscordEnabled") as Boolean
} catch (_: Exception) {
ChatOG.plugin.logger.severe("Failed to parse config option \"developerDiscordEnabled\" as a boolean")
return null
}
if (config.discordEnabled) {
try {
config.status = yamlConfig.get("status") as String
@@ -183,6 +209,22 @@ internal class Config private constructor() {
}
}
if (config.developerDiscordEnabled) {
try {
config.developerChannelId = (yamlConfig.get("developerChannelId") as Long).toString()
} catch (_: Exception) {
ChatOG.plugin.logger.severe("Failed to parse config option \"developerChannelId\" as a long")
return null
}
try {
config.developerWebhook = yamlConfig.get("developerWebhook") as String
} catch (_: Exception) {
ChatOG.plugin.logger.severe("Failed to parse config option \"developerWebhook\" as a string")
return null
}
}
try {
config.webhook = yamlConfig.get("webhook") as String
} catch (_: Exception) {
@@ -204,69 +246,102 @@ internal class Config private constructor() {
return null
}
try {
config.useColorCodeRoles = yamlConfig.get("useColorCodeRoles") as Boolean
} catch (_: Exception) {
ChatOG.plugin.logger.severe("Failed to parse config option \"useColorCodeRoles\" as a boolean")
return null
}
config.colorCodeRoles = yamlConfig.getStringList("colorCodeRoles")
config.roles = yamlConfig.getConfigurationSection("roles")?.getKeys(false) ?: setOf()
config.rolesWithSuffixes = yamlConfig.getConfigurationSection("roleSuffixes")?.getKeys(false) ?: setOf()
}
if (config.roles.isEmpty()) {
config.roleMessageColor = mutableMapOf()
return config
}
if (config.roles.isNotEmpty()) {
val messageColors =
mapOf<String, NamedTextColor>(
Pair("BLACK", NamedTextColor.BLACK),
Pair("DARK_BLUE", NamedTextColor.DARK_BLUE),
Pair("DARK_GREEN", NamedTextColor.DARK_GREEN),
Pair("DARK_AQUA", NamedTextColor.DARK_AQUA),
Pair("DARK_RED", NamedTextColor.DARK_RED),
Pair("DARK_PURPLE", NamedTextColor.DARK_PURPLE),
Pair("GOLD", NamedTextColor.GOLD),
Pair("GRAY", NamedTextColor.GRAY),
Pair("DARK_GRAY", NamedTextColor.DARK_GRAY),
Pair("BLUE", NamedTextColor.BLUE),
Pair("GREEN", NamedTextColor.GREEN),
Pair("AQUA", NamedTextColor.AQUA),
Pair("RED", NamedTextColor.RED),
Pair("LIGHT_PURPLE", NamedTextColor.LIGHT_PURPLE),
Pair("YELLOW", NamedTextColor.YELLOW),
Pair("WHITE", NamedTextColor.WHITE),
)
config.roles.forEach {
val messageColorList = yamlConfig.getStringList("roles.$it.message_color")
config.roleMessageColor[it] =
if (messageColorList.isEmpty()) {
try {
yamlConfig.get("roles.$it.message_color") as String
} catch (_: Exception) {
ChatOG.plugin.logger.warning(
"Failed to parse config option \"role.$it.message_color\" as a string"
)
return@forEach
}
val messageColors =
mapOf<String, NamedTextColor>(
Pair("BLACK", NamedTextColor.BLACK),
Pair("DARK_BLUE", NamedTextColor.DARK_BLUE),
Pair("DARK_GREEN", NamedTextColor.DARK_GREEN),
Pair("DARK_AQUA", NamedTextColor.DARK_AQUA),
Pair("DARK_RED", NamedTextColor.DARK_RED),
Pair("DARK_PURPLE", NamedTextColor.DARK_PURPLE),
Pair("GOLD", NamedTextColor.GOLD),
Pair("GRAY", NamedTextColor.GRAY),
Pair("DARK_GRAY", NamedTextColor.DARK_GRAY),
Pair("BLUE", NamedTextColor.BLUE),
Pair("GREEN", NamedTextColor.GREEN),
Pair("AQUA", NamedTextColor.AQUA),
Pair("RED", NamedTextColor.RED),
Pair("LIGHT_PURPLE", NamedTextColor.LIGHT_PURPLE),
Pair("YELLOW", NamedTextColor.YELLOW),
Pair("WHITE", NamedTextColor.WHITE),
)
config.roles.forEach {
val messageColorList = yamlConfig.getStringList("roles.$it.message_color")
config.roleMessageColor[it] =
if (messageColorList.isEmpty()) {
try {
yamlConfig.get("roles.$it.message_color") as String
} catch (_: Exception) {
return@forEach
if (!messageColors.contains(messageColorList[0].uppercase())) {
ChatOG.plugin.logger.severe(
"The message color for \"$it\" (\"${messageColorList[0]}\") is invalid."
)
return@forEach
}
messageColors[messageColorList[0].uppercase()]!!
} else {
if (messageColorList.size != 3) {
ChatOG.plugin.logger.severe(
"The message color for \"$it\" is not a color or an RGB value."
)
return@forEach
}
messageColorList.forEach colorForEach@{ colorInList ->
try {
colorInList.toUByte()
} catch (_: Exception) {
ChatOG.plugin.logger.severe("The RGB value for \"$it\" is invalid.")
return@forEach
}
}
RGBColor(
messageColorList[0].toInt(),
messageColorList[1].toInt(),
messageColorList[2].toInt(),
)
}
}
} else {
config.roleMessageColor = mutableMapOf()
}
if (!messageColors.contains(messageColorList[0].uppercase())) {
ChatOG.plugin.logger.severe(
"The message color for \"$it\" (\"${messageColorList[0]}\") is invalid."
if (config.rolesWithSuffixes.isNotEmpty()) {
config.rolesWithSuffixes.forEach {
val suffixList =
try {
yamlConfig.get("roleSuffixes.$it.suffix") as String
} catch (_: Exception) {
ChatOG.plugin.logger.warning(
"Failed to parse config option \"roleSuffixes.$it.suffix\" as a string"
)
return@forEach
}
messageColors[messageColorList[0].uppercase()]!!
} else {
if (messageColorList.size != 3) {
ChatOG.plugin.logger.severe("The message color for \"$it\" is not a color or an RGB value.")
return@forEach
}
messageColorList.forEach colorForEach@{ colorInList ->
try {
colorInList.toUByte()
} catch (_: Exception) {
ChatOG.plugin.logger.severe("The RGB value for \"$it\" is invalid.")
return@forEach
}
}
RGBColor(messageColorList[0].toInt(), messageColorList[1].toInt(), messageColorList[2].toInt())
}
config.roleSuffix[it] = suffixList
}
} else {
config.roleSuffix = mutableMapOf()
}
return config
@@ -29,8 +29,9 @@ import net.kyori.adventure.text.format.NamedTextColor
import net.kyori.adventure.text.format.TextColor
import net.trueog.utilitiesog.UtilitiesOG
import nl.skbotnl.chatog.ChatOG.Companion.config
import nl.skbotnl.chatog.Helper.convertMentions
import nl.skbotnl.chatog.Helper.stripGroupMentions
import nl.skbotnl.chatog.ChatUtil.convertMentions
import nl.skbotnl.chatog.ChatUtil.recolorComponent
import nl.skbotnl.chatog.ChatUtil.stripGroupMentions
import nl.skbotnl.chatog.commands.TranslateMessage
import org.bukkit.Bukkit
import org.bukkit.entity.Player
@@ -40,6 +41,7 @@ internal class DiscordBridge private constructor() {
private lateinit var webhook: WebhookClient
private var staffWebhook: WebhookClient? = null
private var premiumWebhook: WebhookClient? = null
private var developerWebhook: WebhookClient? = null
companion object {
fun create(): DiscordBridge? {
@@ -72,6 +74,17 @@ internal class DiscordBridge private constructor() {
} else if (config.premiumDiscordEnabled) {
ChatOG.plugin.logger.warning("You have enabled premium Discord but have not set up the premium webhook")
}
if (config.developerWebhook != null) {
try {
discordBridge.developerWebhook = WebhookClient.withUrl(config.developerWebhook!!)
} catch (_: IllegalArgumentException) {
ChatOG.plugin.logger.warning("Config option \"developer\" is invalid")
}
} else if (config.premiumDiscordEnabled) {
ChatOG.plugin.logger.warning(
"You have enabled developer Discord but have not set up the developer webhook"
)
}
if (config.botToken == null) {
ChatOG.plugin.logger.severe("You have enabled Discord but have not set up the bot token")
@@ -162,7 +175,8 @@ internal class DiscordBridge private constructor() {
if (
it.channel.id != config.channelId &&
(if (config.staffDiscordEnabled) it.channel.id != config.staffChannelId else true) &&
(if (config.premiumDiscordEnabled) it.channel.id != config.premiumChannelId else true)
(if (config.premiumDiscordEnabled) it.channel.id != config.premiumChannelId else true) &&
(if (config.developerDiscordEnabled) it.channel.id != config.developerChannelId else true)
) {
return@listener
}
@@ -185,6 +199,7 @@ internal class DiscordBridge private constructor() {
val roles = member.roles
val topRole = roles.maxByOrNull { role -> role.positionRaw }
val sortedRoles = member.roles.sortedByDescending { role -> role.positionRaw }
val discordComponent = Component.text("Discord: ").color(TextColor.color(88, 101, 242))
val userComponent: TextComponent =
@@ -198,13 +213,7 @@ internal class DiscordBridge private constructor() {
if (config.roles.isEmpty()) {
NamedTextColor.GRAY
} else {
val roleId =
message.guild
.getRoleById(
config.roles
.filter { role -> topRole!!.id == message.guild.getRoleById(role)?.id }[0]
)
?.id
val roleId = sortedRoles.first { role -> role.id in config.roles }?.id
if (roleId != null) {
val roleColor = config.roleMessageColor[roleId]
@@ -216,7 +225,19 @@ internal class DiscordBridge private constructor() {
} else NamedTextColor.GRAY
}
val messageComponents = mutableListOf<Component>(Component.text(">"))
val suffix =
if (config.rolesWithSuffixes.isEmpty()) {
">"
} else {
val roleId = sortedRoles.first { role -> role.id in config.rolesWithSuffixes }?.id
if (roleId != null) {
config.roleSuffix[roleId]!!
} else {
">"
}
}
val messageComponents = mutableListOf<Component>(UtilitiesOG.trueogColorize(suffix))
val attachmentComponents = mutableListOf<Component>()
@@ -243,19 +264,30 @@ internal class DiscordBridge private constructor() {
}
}
val useColor =
if (config.useColorCodeRoles) {
roles.any { role -> role.id in config.colorCodeRoles }
} else {
true
}
if (message.contentDisplay != "") {
messageComponents +=
Helper.processText(
recolorComponent(
ChatUtil.processText(
EmojiConverter.replaceEmojisWithNames(message.contentDisplay),
"@${user.name}",
)
?.color(messageColor) ?: return@listener
useColor,
) ?: return@listener,
messageColor,
)
}
val contentComponent =
Component.join(
JoinConfiguration.separator(Component.text(" ")),
messageComponents + attachmentComponents,
Component.join(JoinConfiguration.noSeparators(), messageComponents),
Component.join(JoinConfiguration.noSeparators(), attachmentComponents),
)
var replyComponent = Component.text("")
@@ -297,6 +329,18 @@ internal class DiscordBridge private constructor() {
)
}
config.developerChannelId -> {
val developerComponent = Component.text("DEVELOPER | ").color(NamedTextColor.AQUA)
Component.join(
JoinConfiguration.noSeparators(),
discordComponent,
developerComponent,
replyComponent,
userComponent,
contentComponent,
)
}
else -> {
Component.join(
JoinConfiguration.noSeparators(),
@@ -351,7 +395,7 @@ internal class DiscordBridge private constructor() {
message.contentDisplay,
member.effectiveName,
Component.join(JoinConfiguration.noSeparators(), discordComponent, userComponent),
Component.text("> "),
Component.text("$suffix "),
)
}
return discordBridge
@@ -381,7 +425,7 @@ internal class DiscordBridge private constructor() {
suspend fun sendMessage(message: String, player: Player) {
val webhookMessage =
WebhookMessageBuilder()
.setUsername(UtilitiesOG.stripFormatting(ChatHelper.getPlayerPartString(player)))
.setUsername(UtilitiesOG.stripFormatting(ChatUtil.getPlayerPartString(player)))
.setContent(UtilitiesOG.stripFormatting(stripGroupMentions(convertMentions(message))))
.setAvatarUrl("https://minotar.net/helm/${player.uniqueId}.png")
@@ -435,6 +479,24 @@ internal class DiscordBridge private constructor() {
premiumWebhook!!.send(webhookMessage.build())
}
suspend fun sendDeveloperMessage(message: String, name: String, uuid: UUID?) {
if (!config.developerDiscordEnabled) return
if (developerWebhook == null) {
ChatOG.plugin.logger.warning("developerWebhook has not been set or is invalid")
return
}
val webhookMessage =
WebhookMessageBuilder().apply {
setUsername(UtilitiesOG.stripFormatting(name))
setContent(UtilitiesOG.stripFormatting(stripGroupMentions((convertMentions(message)))))
if (uuid != null) setAvatarUrl("https://minotar.net/helm/$uuid.png")
}
developerWebhook!!.send(webhookMessage.build())
}
fun sendEmbed(message: String, uuid: UUID?, color: Int?) {
var iconUrl: String? = null
if (uuid != null) {
+29 -21
View File
@@ -21,8 +21,7 @@ import net.trueog.utilitiesog.UtilitiesOG
import nl.skbotnl.chatog.ChatOG.Companion.config
import nl.skbotnl.chatog.ChatOG.Companion.discordBridgeLock
import nl.skbotnl.chatog.ChatSystem.ChatType
import nl.skbotnl.chatog.Helper.legacyToMm
import nl.skbotnl.chatog.Helper.removeColor
import nl.skbotnl.chatog.ChatUtil.legacyToMm
import nl.skbotnl.chatog.commands.TranslateMessage
import org.bukkit.Bukkit
import org.bukkit.event.EventHandler
@@ -43,7 +42,7 @@ internal class Events : Listener {
return
}
val playerPartString = ChatHelper.getPlayerPartString(event.player)
val playerPartString = ChatUtil.getPlayerPartString(event.player)
ChatOG.scope.launch {
discordBridgeLock.read {
@@ -67,12 +66,12 @@ internal class Events : Listener {
return
}
val playerPartString = ChatHelper.getPlayerPartString(event.player)
val playerPartString = ChatUtil.getPlayerPartString(event.player)
ChatOG.scope.launch {
discordBridgeLock.read {
ChatOG.discordBridge?.sendEmbed(
"${removeColor(playerPartString)} has left the game. ${
"$playerPartString has left the game. ${
Bukkit.getOnlinePlayers().count() - 1
} player(s) online.",
event.player.uniqueId,
@@ -91,14 +90,14 @@ internal class Events : Listener {
return
}
val playerPartString = ChatHelper.getPlayerPartString(event.player)
val playerPartString = ChatUtil.getPlayerPartString(event.player)
val reason = PlainTextComponentSerializer.plainText().serialize(event.reason())
ChatOG.scope.launch {
discordBridgeLock.read {
ChatOG.discordBridge?.sendEmbed(
"${removeColor(playerPartString)} was kicked with reason: \"${reason}\". ${
"$playerPartString was kicked with reason: \"${reason}\". ${
Bukkit.getOnlinePlayers().count() - 1
} player(s) online.",
event.player.uniqueId,
@@ -117,7 +116,7 @@ internal class Events : Listener {
return
}
val playerPartString = ChatHelper.getPlayerPartString(event.player)
val playerPartString = ChatUtil.getPlayerPartString(event.player)
val advancementTitleKey = event.advancement.display?.title() ?: return
val advancementTitle = PlainTextComponentSerializer.plainText().serialize(advancementTitleKey)
@@ -135,7 +134,7 @@ internal class Events : Listener {
ChatOG.scope.launch {
discordBridgeLock.read {
ChatOG.discordBridge?.sendEmbed(
"${removeColor(playerPartString)} $advancementMessage.",
"$playerPartString $advancementMessage.",
event.player.uniqueId,
0xFFFF00,
)
@@ -169,23 +168,30 @@ internal class Events : Listener {
val eventMessage = event.message() as TextComponent
if (ChatSystem.inChat[event.player.uniqueId] == ChatType.STAFF_CHAT) {
ChatSystem.sendMessageInStaffChat(event.player, eventMessage.content())
return
}
if (ChatSystem.inChat[event.player.uniqueId] == ChatType.PREMIUM_CHAT) {
ChatSystem.sendMessageInPremiumChat(event.player, eventMessage.content())
return
when (ChatSystem.inChat[event.player.uniqueId]) {
ChatType.STAFF_CHAT -> {
ChatSystem.sendMessageInStaffChat(event.player, eventMessage.content())
return
}
ChatType.PREMIUM_CHAT -> {
ChatSystem.sendMessageInPremiumChat(event.player, eventMessage.content())
return
}
ChatType.DEVELOPER_CHAT -> {
ChatSystem.sendMessageInDeveloperChat(event.player, eventMessage.content())
return
}
else -> {}
}
val discordMessageString = Helper.convertEmojis(eventMessage.content())
val discordMessageString = ChatUtil.convertEmojis(eventMessage.content())
ChatOG.scope.launch {
discordBridgeLock.read { ChatOG.discordBridge?.sendMessage(discordMessageString, event.player) }
}
val playerPart = ChatHelper.getPlayerPart(event.player, true)
val playerPart = ChatUtil.getPlayerPart(event.player, true)
val messageComponent = Helper.processText(eventMessage.content(), event.player)
val messageComponent = ChatUtil.processText(eventMessage.content(), event.player)
if (messageComponent == null) {
return
}
@@ -207,6 +213,8 @@ internal class Events : Listener {
event.viewers().forEach { it.sendMessage(textComponent) }
ChatUtil.dingForMentions(event.player.uniqueId, messageComponent)
TranslateMessage.chatMessages[randomUUID] =
TranslateMessage.SentChatMessage(eventMessage.content(), event.player)
}
@@ -224,7 +232,7 @@ internal class Events : Listener {
ChatOG.scope.launch {
discordBridgeLock.read {
ChatOG.discordBridge?.sendEmbed(
removeColor((event.deathMessage() as TextComponent).content()),
(event.deathMessage() as TextComponent).content(),
event.player.uniqueId,
0xFF0000,
)
@@ -254,7 +262,7 @@ internal class Events : Listener {
ChatOG.scope.launch {
discordBridgeLock.read {
ChatOG.discordBridge?.sendEmbed(removeColor(translatedDeathMessage), event.player.uniqueId, 0xFF0000)
ChatOG.discordBridge?.sendEmbed(translatedDeathMessage, event.player.uniqueId, 0xFF0000)
}
}
}
@@ -33,4 +33,8 @@ internal class LanguageDatabase {
commands.set("chatog:language:$uuid", language)
connection.close()
}
fun shutdown() {
redisClient.shutdown()
}
}
@@ -1,41 +1,9 @@
package nl.skbotnl.chatog
import java.util.*
import nl.skbotnl.chatog.ChatUtil.legacyToMm
internal object PlayerAffix {
private val legacyToMmMap =
mapOf(
"0" to "<black>",
"1" to "<dark_blue>",
"2" to "<dark_green>",
"3" to "<dark_aqua>",
"4" to "<dark_red>",
"5" to "<dark_purple>",
"6" to "<gold>",
"7" to "<gray>",
"8" to "<dark_gray>",
"9" to "<blue>",
"a" to "<green>",
"b" to "<aqua>",
"c" to "<red>",
"d" to "<light_purple>",
"e" to "<yellow>",
"f" to "<white>",
"k" to "<obfuscated>",
"l" to "<bold>",
"m" to "<strikethrough>",
"n" to "<underlined>",
"o" to "<italic>",
"r" to "<reset>",
"*" to "<rainbow>",
)
val legacyRegex = Regex("[§&]([0-9a-fk-or*])", RegexOption.IGNORE_CASE)
fun legacyToMm(text: String): String {
return legacyRegex.replace(text) { legacyToMmMap[it.groupValues[1].lowercase()] ?: it.value }
}
fun getPrefix(uuid: UUID): String {
var user = ChatOG.luckPerms.userManager.getUser(uuid)
if (user == null) {
@@ -3,13 +3,17 @@ package nl.skbotnl.chatog.commands
import kotlin.concurrent.write
import kotlinx.coroutines.launch
import net.trueog.utilitiesog.UtilitiesOG
import nl.skbotnl.chatog.BlocklistManager
import nl.skbotnl.chatog.ChatOG
import nl.skbotnl.chatog.ChatOG.Companion.blocklistManager
import nl.skbotnl.chatog.ChatOG.Companion.config
import nl.skbotnl.chatog.ChatOG.Companion.discordBridgeLock
import nl.skbotnl.chatog.ChatOG.Companion.scope
import nl.skbotnl.chatog.ChatOG.Companion.translator
import nl.skbotnl.chatog.Config
import nl.skbotnl.chatog.DiscordBridge
import nl.skbotnl.chatog.LanguageDatabase
import nl.skbotnl.chatog.OpenAI
import org.bukkit.Bukkit
import org.bukkit.command.Command
import org.bukkit.command.CommandExecutor
@@ -29,6 +33,27 @@ internal class ChatConfigReload : CommandExecutor {
return true
}
if (config.blocklistEnabled) {
blocklistManager = BlocklistManager()
}
translator =
if (config.openAIEnabled) {
if (config.openAIBaseUrl == null) {
ChatOG.plugin.logger.warning(
"You have enabled OpenAI translation but have not set up the base url, not enabling the translator"
)
null
} else if (config.openAIApiKey == null) {
ChatOG.plugin.logger.warning(
"You have enabled OpenAI translation but have not set up the api key, not enabling the translator"
)
null
} else {
OpenAI()
}
} else null
ChatOG.languageDatabase = LanguageDatabase()
if (ChatOG.languageDatabase.testConnection()) {
ChatOG.plugin.logger.severe("Could not connect to Redis")
@@ -0,0 +1,49 @@
package nl.skbotnl.chatog.commands
import kotlin.collections.set
import net.trueog.utilitiesog.UtilitiesOG
import nl.skbotnl.chatog.ChatOG.Companion.config
import nl.skbotnl.chatog.ChatSystem
import nl.skbotnl.chatog.ChatSystem.ChatType
import org.bukkit.command.Command
import org.bukkit.command.CommandExecutor
import org.bukkit.command.CommandSender
import org.bukkit.entity.Player
class DeveloperChat : CommandExecutor {
override fun onCommand(sender: CommandSender, command: Command, label: String, args: Array<out String>?): Boolean {
if (sender !is Player) {
sender.sendMessage("You can only execute this command as a player.")
return true
}
if (!sender.hasPermission("chat-og.developer")) {
sender.sendMessage(
UtilitiesOG.trueogColorize(
"${config.prefix}<reset>: <red>You do not have permission to run this command."
)
)
return true
}
if (args == null || args.isEmpty()) {
if (ChatSystem.inChat[sender.uniqueId] == ChatType.DEVELOPER_CHAT) {
ChatSystem.inChat[sender.uniqueId] = ChatType.GENERAL_CHAT
sender.sendMessage(
UtilitiesOG.trueogColorize("${config.prefix}<reset>: You are now talking in the general chat.")
)
return true
}
ChatSystem.inChat[sender.uniqueId] = ChatType.DEVELOPER_CHAT
sender.sendMessage(
UtilitiesOG.trueogColorize("${config.prefix}<reset>: You are now talking in the developer chat.")
)
return true
}
ChatSystem.sendMessageInDeveloperChat(sender, args.joinToString(separator = " "))
return true
}
}
@@ -0,0 +1,41 @@
package nl.skbotnl.chatog.commands
import kotlin.collections.set
import net.trueog.utilitiesog.UtilitiesOG
import nl.skbotnl.chatog.ChatOG.Companion.config
import nl.skbotnl.chatog.ChatSystem
import nl.skbotnl.chatog.ChatSystem.ChatType
import org.bukkit.command.Command
import org.bukkit.command.CommandExecutor
import org.bukkit.command.CommandSender
import org.bukkit.entity.Player
class GeneralChat : CommandExecutor {
override fun onCommand(sender: CommandSender, command: Command, label: String, args: Array<out String>?): Boolean {
if (sender !is Player) {
sender.sendMessage("You can only execute this command as a player.")
return true
}
if (args == null || args.isEmpty()) {
if (ChatSystem.inChat[sender.uniqueId] != ChatType.GENERAL_CHAT) {
ChatSystem.inChat[sender.uniqueId] = ChatType.GENERAL_CHAT
sender.sendMessage(
UtilitiesOG.trueogColorize("${config.prefix}<reset>: You are now talking in the general chat.")
)
return true
}
sender.sendMessage(
UtilitiesOG.trueogColorize("${config.prefix}<reset>: You are already talking in the general chat.")
)
return true
}
val originalChat = ChatSystem.inChat[sender.uniqueId]
ChatSystem.inChat[sender.uniqueId] = ChatType.GENERAL_CHAT
sender.chat(args.joinToString(separator = " "))
if (originalChat != null) ChatSystem.inChat[sender.uniqueId] = originalChat
return true
}
}
@@ -28,13 +28,13 @@ internal class PremiumChat : CommandExecutor {
ChatSystem.inChat[sender.uniqueId] = ChatType.GENERAL_CHAT
sender.sendMessage(
UtilitiesOG.trueogColorize("${config.prefix}<reset>: You are now talking in normal chat.")
UtilitiesOG.trueogColorize("${config.prefix}<reset>: You are now talking in the general chat.")
)
return true
}
ChatSystem.inChat[sender.uniqueId] = ChatType.PREMIUM_CHAT
sender.sendMessage(
UtilitiesOG.trueogColorize("${config.prefix}<reset>: You are now talking in premium chat.")
UtilitiesOG.trueogColorize("${config.prefix}<reset>: You are now talking in the premium chat.")
)
return true
}
@@ -9,7 +9,7 @@ import net.kyori.adventure.text.event.HoverEvent
import net.trueog.utilitiesog.UtilitiesOG
import nl.skbotnl.chatog.ChatOG.Companion.config
import nl.skbotnl.chatog.ChatOG.Companion.lastMessagedMap
import nl.skbotnl.chatog.Helper
import nl.skbotnl.chatog.ChatUtil
import org.bukkit.Bukkit
import org.bukkit.command.Command
import org.bukkit.command.CommandExecutor
@@ -57,7 +57,7 @@ internal class PrivateMessage : CommandExecutor {
TranslateMessage.pmMessages[randomUUID] =
TranslateMessage.SentPMMessage(message, sender.uniqueId, toPlayer.uniqueId)
val messageComponent = Helper.processText(message, sender)
val messageComponent = ChatUtil.processText(message, sender)
if (messageComponent == null) {
return true
}
@@ -9,7 +9,7 @@ import net.kyori.adventure.text.event.HoverEvent
import net.trueog.utilitiesog.UtilitiesOG
import nl.skbotnl.chatog.ChatOG.Companion.config
import nl.skbotnl.chatog.ChatOG.Companion.lastMessagedMap
import nl.skbotnl.chatog.Helper
import nl.skbotnl.chatog.ChatUtil
import org.bukkit.Bukkit
import org.bukkit.command.Command
import org.bukkit.command.CommandExecutor
@@ -53,7 +53,7 @@ internal class Reply : CommandExecutor {
TranslateMessage.pmMessages[randomUUID] =
TranslateMessage.SentPMMessage(message, sender.uniqueId, toPlayer.uniqueId)
val messageComponent = Helper.processText(message, sender)
val messageComponent = ChatUtil.processText(message, sender)
if (messageComponent == null) {
return true
}
@@ -15,6 +15,7 @@ internal class StaffChat : CommandExecutor {
sender.sendMessage("You can only execute this command as a player.")
return true
}
if (!sender.hasPermission("chat-og.staff")) {
sender.sendMessage(
UtilitiesOG.trueogColorize(
@@ -23,12 +24,13 @@ internal class StaffChat : CommandExecutor {
)
return true
}
if (args == null || args.isEmpty()) {
if (ChatSystem.inChat[sender.uniqueId] == ChatType.STAFF_CHAT) {
ChatSystem.inChat[sender.uniqueId] = ChatType.GENERAL_CHAT
sender.sendMessage(
UtilitiesOG.trueogColorize("${config.prefix}<reset>: You are now talking in normal chat.")
UtilitiesOG.trueogColorize("${config.prefix}<reset>: You are now talking in general chat.")
)
return true
}
@@ -9,8 +9,8 @@ import net.kyori.adventure.text.format.NamedTextColor
import net.trueog.utilitiesog.UtilitiesOG
import nl.skbotnl.chatog.ChatOG
import nl.skbotnl.chatog.ChatOG.Companion.config
import nl.skbotnl.chatog.Helper
import nl.skbotnl.chatog.Helper.legacyToMm
import nl.skbotnl.chatog.ChatUtil
import nl.skbotnl.chatog.ChatUtil.legacyToMm
import nl.skbotnl.chatog.PlayerAffix
import org.bukkit.Bukkit
import org.bukkit.command.Command
@@ -56,7 +56,7 @@ internal class TranslateMessage : CommandExecutor {
}
val player: Player = sender
if (Helper.getTranslateTimeout(player.uniqueId) != 0L) {
if (ChatUtil.getTranslateTimeout(player.uniqueId) != 0L) {
player.sendMessage(UtilitiesOG.trueogColorize("${config.prefix}<reset>: <red>You're doing that too fast."))
return true
}
+19 -3
View File
@@ -1,6 +1,11 @@
# ---General---
# MiniMessage-formatted prefix (https://docs.advntr.dev/minimessage/format.html)
prefix: <dark_gray>[<green>Chat<white>-<dark_red>OG<dark_gray>]
blocklistEnabled: true
# Only blocklists with just a list of domains
blocklists:
- https://raw.githubusercontent.com/hagezi/dns-blocklists/main/domains/multi.txt
- https://raw.githubusercontent.com/hagezi/dns-blocklists/main/wildcard/nsfw-onlydomains.txt
# ---Redis---
# Redis URL according to https://redis.github.io/lettuce/user-guide/connecting-redis/#uri-syntax
@@ -20,6 +25,7 @@ model: ""
discordEnabled: false
staffDiscordEnabled: false
premiumDiscordEnabled: false
developerDiscordEnabled: false
status: Minecraft
serverHasStartedMessage: The server has started
serverHasStoppedMessage: The server has stopped
@@ -28,13 +34,16 @@ guildId: <put the id of the guild here>
channelId: <put the id of the channel here>
staffChannelId: <put the id of the channel here>
premiumChannelId: <put the id of the channel here>
developerChannelId: <put the id of the channel here>
webhook: <put the webhook here>
staffWebhook: <put the webhook here>
premiumWebhook: <put the webhook here>
staffWebhook: <put the webhook url here>
premiumWebhook: <put the webhook url here>
developerWebhook: <put the webhook url here>
listCommandName: list
# Available placeholders: %onlineplayers%, %maxplayers%
listCommandText: "%onlineplayers% player(s) online:"
useColorCodeRoles: false
# Configure which roles can use color codes with Discord -> Minecraft
# For example:
#
@@ -47,10 +56,17 @@ listCommandText: "%onlineplayers% player(s) online:"
# 1234567891234567890:
# message_color: RED
#
# message_color can be one of these: BLACK, DARK_BLUE, DARK_GREEN, DARK_AQUA, DARK_RED, DARK_PURPLE, GOLD, GRAY, DARK_GRAY, BLUE, GREEN, AQUA, RED, LIGHT_PURPLE, YELLOW, WHITE
# message_color can be one of the following: BLACK, DARK_BLUE, DARK_GREEN, DARK_AQUA, DARK_RED, DARK_PURPLE, GOLD, GRAY, DARK_GRAY, BLUE, GREEN, AQUA, RED, LIGHT_PURPLE, YELLOW, WHITE
#
# You can also use RGB for the color:
#
# roles:
# 1234567891234567890:
# message_color: [255, 255, 255]
# Configure the suffix for roles (has to include the space). color codes are allowed.
# For example:
# roleSuffixes:
# 1234567891234567890:
# suffix: ": "
+13 -1
View File
@@ -20,6 +20,12 @@ commands:
chatconfigreload:
description: Reload Chat-OG's config
usage: /chatconfigreload
gc:
description: Toggle or talk in general chat
usage: /gc OR /gc <message here>
g:
description: Toggle or talk in general chat
usage: /g OR /g <message here>
sc:
description: Toggle or talk in staff chat
usage: /sc OR /sc <message here>
@@ -28,10 +34,16 @@ commands:
usage: /s OR /s <message here>
pc:
description: Toggle or talk in premium chat
usage: /p OR /p <message here>
usage: /pc OR /pc <message here>
p:
description: Toggle or talk in premium chat
usage: /p OR /p <message here>
dc:
description: Toggle or talk in developer chat
usage: /dc OR /dc <message here>
d:
description: Toggle or talk in developer chat
usage: /d OR /d <message here>
msg:
description: Send a private message to a player
usage: /msg <player name> <message>