Skip to content

Commit

Permalink
feat: add chat-filters
Browse files Browse the repository at this point in the history
  • Loading branch information
Boy0000 committed Jan 10, 2024
1 parent d796e4b commit c3c7a9f
Show file tree
Hide file tree
Showing 5 changed files with 67 additions and 19 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import com.mineinabyss.chatty.components.ChannelType
import com.mineinabyss.chatty.components.SpyOnChannels
import com.mineinabyss.chatty.queries.SpyingPlayers
import com.mineinabyss.geary.papermc.tracking.entities.toGeary
import com.mineinabyss.idofront.textcomponents.miniMsg
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
import net.kyori.adventure.audience.Audience
Expand Down Expand Up @@ -40,8 +41,9 @@ data class ChattyChannel(
}
}
val key by lazy { chatty.config.channels.entries.first { it.value == this }.key }
val messageColor: TextColor?
get() = _messageColor?.let { TextColor.fromHexString(_messageColor) ?: NamedTextColor.NAMES.value(_messageColor) }
val messageColor: TextColor? get() = _messageColor?.let {
TextColor.fromHexString(_messageColor) ?: NamedTextColor.NAMES.value(_messageColor) ?: ("<$_messageColor>").miniMsg().color()
}


fun getAudience(player: Player): Collection<Audience> {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
package com.mineinabyss.chatty

import com.charleskorn.kaml.YamlComment
import com.mineinabyss.chatty.components.ChannelType
import com.mineinabyss.idofront.serialization.DurationSerializer
import kotlinx.serialization.Serializable
import kotlinx.serialization.*
import kotlin.time.Duration
import kotlin.time.Duration.Companion.minutes

Expand All @@ -25,7 +26,16 @@ data class ChattyConfig(
data class Chat(
val disableChatSigning: Boolean = true,
val commandSpyFormat: String = "<gold><chatty_nickname>: ",
)
@YamlComment("Valid formats: STRIKETHROUGH, CENSOR, DELETE, BLOCK", "STRIKETHROUGH: Replaces filtered words with a strikethrough", "CENSOR: Replaces filtered words with a censor", "DELETE: Deletes filtered words", "BLOCK: Blocks filtered words from being sent")
val filterFormat: FilterFormat = FilterFormat.CENSOR,
@SerialName("filters") val _filters: List<String> = listOf(),
) {
enum class FilterFormat {
STRIKETHROUGH, CENSOR, DELETE, BLOCK
}
@Transient
val filters: List<@Contextual Regex> = _filters.map { it.toRegex() }
}

@Serializable
data class PrivateMessages(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,13 @@ import com.combimagnetron.imageloader.Avatar
import com.combimagnetron.imageloader.Image.ColorType
import com.combimagnetron.imageloader.ImageUtils
import com.mineinabyss.chatty.ChattyChannel
import com.mineinabyss.chatty.ChattyConfig
import com.mineinabyss.chatty.chatty
import com.mineinabyss.chatty.components.ChannelData
import com.mineinabyss.chatty.components.ChannelType
import com.mineinabyss.chatty.components.chattyNickname
import com.mineinabyss.chatty.placeholders.chattyPlaceholderTags
import com.mineinabyss.idofront.messaging.warn
import com.mineinabyss.idofront.textcomponents.miniMsg
import com.mineinabyss.idofront.textcomponents.serialize
import me.clip.placeholderapi.PlaceholderAPI
Expand Down Expand Up @@ -270,4 +272,34 @@ fun formatPlayerPingMessage(source: Player, pingedPlayer: Player?, audience: Aud
.build()
)
} ?: message
}

fun handleChatFilters(message: Component, player: Player, audience: Player) : Component {
var finalMessage = message
val serialized = finalMessage.serialize()
if (!player.hasPermission(ChattyPermissions.BYPASS_CHAT_FILTERS_PERM)) chatty.config.chat.filters.forEach { filter ->
filter.findAll(serialized).forEach { match ->
finalMessage = finalMessage.replaceText(TextReplacementConfig.builder()
.matchLiteral(match.value)
.replacement(Component.textOfChildren(
when (chatty.config.chat.filterFormat) {
ChattyConfig.Chat.FilterFormat.STRIKETHROUGH -> Component.text(match.value).style(Style.style(TextDecoration.STRIKETHROUGH))
ChattyConfig.Chat.FilterFormat.CENSOR -> Component.text("*".repeat(match.value.length))
ChattyConfig.Chat.FilterFormat.DELETE -> Component.empty()
ChattyConfig.Chat.FilterFormat.BLOCK -> {
player.warn("Your message contained a blocked word: <i>${match.value}")
if (audience.hasPermission(ChattyPermissions.MODERATION_PERM))
audience.sendFormattedMessage("Player <h:${player.name}> <red>sent a blocked message: <i>${match.value}")
return Component.empty()
}
}.let {
if (audience.hasPermission(ChattyPermissions.MODERATION_PERM))
it.hoverEventShowText(Component.text(match.value).style(Style.style(TextDecoration.ITALIC)))
else it
}
))
.build())
}
}
return finalMessage
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ object ChattyPermissions {
const val NICKNAME = "chatty.nickname"
const val NICKNAME_OTHERS = "chatty.nickname.others"
const val BYPASS_TAG_PERM = "chatty.tags.bypass"
const val BYPASS_CHAT_FILTERS_PERM = "chatty.chat.filters.bypass"
const val MODERATION_PERM = "chatty.moderation"
val chatFormattingPerms = mapOf(
Permission("chatty.tags.color") to StandardTags.color(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,11 +73,12 @@ class ChatListener : Listener {

val pingedPlayer = originalMessage().serialize().checkForPlayerPings(channelId)
val playerViewers = viewers().filterIsInstance<Player>().toSet()
var finalMessage = message()
when {
viewers().isEmpty() -> player.sendFormattedMessage(chatty.messages.channels.emptyChannelMessage)
chatty.config.chat.disableChatSigning -> {
playerViewers.forEach { receiver ->
var finalMessage = message()
finalMessage = handleChatFilters(finalMessage, player, receiver)
finalMessage = appendChannelFormat(finalMessage, player, channel)
finalMessage = formatPlayerPingMessage(player, pingedPlayer, receiver, finalMessage)
finalMessage = formatModerationMessage(
Expand All @@ -97,21 +98,23 @@ class ChatListener : Listener {
//isCancelled = true
}

else -> renderer { source, _, message, audience ->
var finalMessage = message
else -> {
finalMessage = appendChannelFormat(finalMessage, player, channel)
finalMessage = formatPlayerPingMessage(source, pingedPlayer, audience, finalMessage)
finalMessage = formatModerationMessage(
channel.messageDeletion,
finalMessage,
simpleMessage,
signedMessage(),
audience,
source,
playerViewers
)

return@renderer finalMessage
renderer { source, _, message, audience ->
finalMessage = handleChatFilters(finalMessage, player, audience as? Player ?: player)
finalMessage = formatPlayerPingMessage(source, pingedPlayer, audience, finalMessage)
finalMessage = formatModerationMessage(
channel.messageDeletion,
finalMessage,
simpleMessage,
signedMessage(),
audience,
source,
playerViewers
)

return@renderer finalMessage
}
}
}
}
Expand Down

0 comments on commit c3c7a9f

Please sign in to comment.