diff --git a/chatty-paper/src/main/kotlin/com/mineinabyss/chatty/ChattyMessages.kt b/chatty-paper/src/main/kotlin/com/mineinabyss/chatty/ChattyMessages.kt index 5468581..b2d08f0 100644 --- a/chatty-paper/src/main/kotlin/com/mineinabyss/chatty/ChattyMessages.kt +++ b/chatty-paper/src/main/kotlin/com/mineinabyss/chatty/ChattyMessages.kt @@ -20,7 +20,7 @@ class ChattyMessages( data class ChatFilter( val blockMessage: String = "Your message contained blocked words:", val deleteWordsEmptyMessage: String = "Your message was not sent as it contained only blocked words.", - val notifyStaff: String = " sent a message containing blocked words:" + val notifyStaff: String = " sent a message containing blocked words: " ) @Serializable diff --git a/chatty-paper/src/main/kotlin/com/mineinabyss/chatty/helpers/ChatHelpers.kt b/chatty-paper/src/main/kotlin/com/mineinabyss/chatty/helpers/ChatHelpers.kt index f63a2a9..12bb1dc 100644 --- a/chatty-paper/src/main/kotlin/com/mineinabyss/chatty/helpers/ChatHelpers.kt +++ b/chatty-paper/src/main/kotlin/com/mineinabyss/chatty/helpers/ChatHelpers.kt @@ -178,13 +178,14 @@ fun formatPlayerPingMessage(source: Player, pingedPlayer: Player?, audience: Aud } ?: message } -fun handleChatFilters(message: Component, player: Player?, audience: Player?) : Component? { +fun handleChatFilters(message: Component, player: Player?, audience: Player?, silent: Boolean) : Component? { var finalMessage = message val serialized = finalMessage.asFlatTextContent() if (player?.hasPermission(ChattyPermissions.BYPASS_CHAT_FILTERS_PERM) == true) return finalMessage + val staffAudience = audience?.takeUnless { silent }?.let { listOf(it) } ?: Bukkit.getServer().onlinePlayers.filter { !silent && it.hasPermission(ChattyPermissions.MODERATION_PERM) } val matchResults = chatty.config.chat.filters.flatMap { it.regex.findAll(serialized).map { m -> m to it.format } } - val blockedWords = matchResults.joinToString(", ") { it.first.value } + val blockedWords = matchResults.distinctBy { it.first.value }.joinToString(", "){ it.first.value } matchResults.forEach { (match, format) -> finalMessage = finalMessage.replaceText(TextReplacementConfig.builder() .matchLiteral(match.value) @@ -194,13 +195,12 @@ fun handleChatFilters(message: Component, player: Player?, audience: Player?) : FilterFormat.CENSOR -> Component.text("⁎".repeat(match.value.length)) FilterFormat.DELETE -> Component.empty() FilterFormat.BLOCK -> { - player?.sendFormattedMessage(chatty.messages.chatFilter.blockMessage, blockedWords) - if (audience?.hasPermission(ChattyPermissions.MODERATION_PERM) == true) - audience.sendFormattedMessage(chatty.messages.chatFilter.notifyStaff + blockedWords) + player?.takeUnless { silent }?.sendFormattedMessage(chatty.messages.chatFilter.blockMessage, blockedWords) + staffAudience.forEach { it.sendFormattedMessage(chatty.messages.chatFilter.notifyStaff + blockedWords, optionalPlayer = player) } return null } }.takeIf { it != Component.empty() }?.let { - if (audience?.hasPermission(ChattyPermissions.MODERATION_PERM) == true) + if (!silent && audience?.hasPermission(ChattyPermissions.MODERATION_PERM) == true) it.hoverEventShowText(Component.text(match.value.toCharArray().joinToString(Space.PLUS_1.unicode)).style(Style.style(TextDecoration.ITALIC))) else it } ?: Component.empty() @@ -211,9 +211,8 @@ fun handleChatFilters(message: Component, player: Player?, audience: Player?) : // If filterFormat is DELETE and message is empty, aka only containing blocked words // Give feedback to player and notify staff if (finalMessage == Component.empty() && matchResults.any { it.second == FilterFormat.DELETE }) { - if (audience == player) player?.sendFormattedMessage(chatty.messages.chatFilter.deleteWordsEmptyMessage) - else if (audience?.hasPermission(ChattyPermissions.MODERATION_PERM) == true) - audience.sendFormattedMessage(chatty.messages.chatFilter.notifyStaff, blockedWords, optionalPlayer = player) + if (audience == player && !silent) player?.sendFormattedMessage(chatty.messages.chatFilter.deleteWordsEmptyMessage) + staffAudience.forEach { it.sendFormattedMessage(chatty.messages.chatFilter.notifyStaff, blockedWords, optionalPlayer = player) } } return finalMessage.compact().takeIf { it != Component.empty() } diff --git a/chatty-paper/src/main/kotlin/com/mineinabyss/chatty/listeners/ChatListener.kt b/chatty-paper/src/main/kotlin/com/mineinabyss/chatty/listeners/ChatListener.kt index 8b3f073..c29d54f 100644 --- a/chatty-paper/src/main/kotlin/com/mineinabyss/chatty/listeners/ChatListener.kt +++ b/chatty-paper/src/main/kotlin/com/mineinabyss/chatty/listeners/ChatListener.kt @@ -80,13 +80,14 @@ class ChatListener : Listener { handleProxyMessage(player, channelId, channel, message(), simpleMessage) val pingedPlayer = originalMessage().serialize().checkForPlayerPings(channelId) - val playerViewers = viewers().mapNotNull { it as? Player }.toSet() + val playerViewers = viewers().mapNotNull { it as? Player }.toMutableSet() when { playerViewers.isEmpty() -> player.sendFormattedMessage(chatty.messages.channels.emptyChannelMessage) chatty.config.chat.disableChatSigning -> { + if (handleChatFilters(baseMessage, null, null, false) == null) playerViewers.clear() playerViewers.forEach { receiver -> var finalMessage = message() - finalMessage = handleChatFilters(finalMessage, player, receiver) ?: return@forEach + finalMessage = handleChatFilters(finalMessage, player, receiver, false) ?: return@forEach finalMessage = formatPlayerPingMessage(player, pingedPlayer, receiver, finalMessage) finalMessage = formatModerationMessage( channel.messageDeletion, @@ -105,22 +106,25 @@ class ChatListener : Listener { //isCancelled = true } - else -> renderer { source, _, message, audience -> - var finalMessage = message - finalMessage = handleChatFilters(finalMessage, player, audience as? Player) - ?: return@renderer Component.empty() - finalMessage = formatPlayerPingMessage(source, pingedPlayer, audience, finalMessage) - finalMessage = formatModerationMessage( - channel.messageDeletion, - finalMessage, - simpleMessage, - signedMessage(), - audience, - source, - playerViewers - ) - - return@renderer finalMessage + else -> { + if (handleChatFilters(baseMessage, player, null, false) == null) viewers().clear() + renderer { source, _, message, audience -> + var finalMessage = message + finalMessage = handleChatFilters(finalMessage, player, audience as? Player, false) + ?: return@renderer Component.empty() + finalMessage = formatPlayerPingMessage(source, pingedPlayer, audience, finalMessage) + finalMessage = formatModerationMessage( + channel.messageDeletion, + finalMessage, + simpleMessage, + signedMessage(), + audience, + source, + playerViewers + ) + + return@renderer finalMessage + } } } } diff --git a/chatty-paper/src/main/kotlin/com/mineinabyss/chatty/listeners/DiscordListener.kt b/chatty-paper/src/main/kotlin/com/mineinabyss/chatty/listeners/DiscordListener.kt index 0e54daa..4e5457b 100644 --- a/chatty-paper/src/main/kotlin/com/mineinabyss/chatty/listeners/DiscordListener.kt +++ b/chatty-paper/src/main/kotlin/com/mineinabyss/chatty/listeners/DiscordListener.kt @@ -36,7 +36,7 @@ class DiscordListener { val channelId = ComponentDSV.text(channel.key) val simpleMessage = mm.deserialize(message.author.name + ": " + message.contentRaw) var message = handleUrlReplacements(minecraftMessage.toComponent(), null) - message = handleChatFilters(message, null, null) ?: run { isCancelled = true; return } + message = handleChatFilters(message, null, null, true) ?: run { isCancelled = true; return } val minecraftMessage = ComponentDSV.textOfChildren(senderName, channelId, message.toComponentDSV(), simpleMessage) chatty.plugin.server.sendPluginMessage(chatty.plugin, discordSrvChannel, gson.serialize(minecraftMessage).toByteArray()) @@ -50,7 +50,7 @@ class DiscordListener { fun GameChatMessagePreProcessEvent.onChat() { val channel = player.toGeary().get()?.withChannelVerified()?.channel ?: return val baseMessage = messageComponent.children().last().toComponent() - val filteredMessage = handleChatFilters(baseMessage, player, null)?.toComponentDSV() + val filteredMessage = handleChatFilters(baseMessage, player, null, true)?.toComponentDSV() if (!channel.discordsrv || filteredMessage == null) isCancelled = true else messageComponent = filteredMessage }