Skip to content

Commit 53061c2

Browse files
committed
additional and better detections
1 parent 43ee927 commit 53061c2

File tree

2 files changed

+63
-7
lines changed

2 files changed

+63
-7
lines changed

src/main/kotlin/com/lambda/module/modules/chat/AntiSpam.kt

Lines changed: 35 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,20 @@ package com.lambda.module.modules.chat
1919

2020
import com.lambda.config.Configurable
2121
import com.lambda.config.SettingGroup
22+
import com.lambda.config.applyEdits
2223
import com.lambda.config.groups.ReplaceConfig
2324
import com.lambda.event.events.ChatEvent
2425
import com.lambda.event.listener.SafeListener.Companion.listen
26+
import com.lambda.friend.FriendManager
2527
import com.lambda.module.Module
2628
import com.lambda.module.tag.ModuleTag
29+
import com.lambda.util.ChatUtils.addresses
30+
import com.lambda.util.ChatUtils.colors
31+
import com.lambda.util.ChatUtils.discord
32+
import com.lambda.util.ChatUtils.sexual
33+
import com.lambda.util.ChatUtils.slurs
34+
import com.lambda.util.ChatUtils.swears
35+
import com.lambda.util.ChatUtils.toAscii
2736
import com.lambda.util.NamedEnum
2837
import net.minecraft.text.Text
2938

@@ -32,28 +41,38 @@ object AntiSpam : Module(
3241
description = "Keeps your chat clean",
3342
tag = ModuleTag.CHAT,
3443
) {
44+
private val ignoreSelf by setting("Ignore Self", true)
45+
private val ignoreFriends by setting("Ignore Friends", true)
46+
private val fancyChats by setting("Replace Fancy Chat", false)
47+
3548
private val detectSlurs = ReplaceSettings("Slurs", this, Group.Slurs)
3649
private val detectSwears = ReplaceSettings("Swears", this, Group.Swears)
3750
private val detectSexual = ReplaceSettings("Sexual", this, Group.Sexual)
51+
private val detectDiscord = ReplaceSettings("Discord", this, Group.Discord)
52+
.apply { applyEdits { editTyped(::action) { defaultValue(ReplaceConfig.ActionStrategy.Hide) } } }
3853
private val detectAddresses = ReplaceSettings("Addresses", this, Group.Addresses)
39-
40-
val slurs = sequenceOf("\\bch[i1l]nks?\\b", "\\bc[o0]{2}ns?\\b", "f[a@4](g{1,2}|qq)([e3il1o0]t{1,2}(ry|r[i1l]e)?)?\\b", "\\bk[il1y]k[e3](ry|r[i1l]e)?s?\\b", "\\b(s[a4]nd)?n[ila4o10][gq]{1,2}(l[e3]t|[e3]r|[a4]|n[o0]g)?s?\\b", "\\btr[a4]n{1,2}([il1][e3]|y|[e3]r)s?\\b").map { Regex(it) }
41-
val swears = sequenceOf("fuck(er)?", "shit", "cunt", "puss(ie|y)", "bitch", "twat").map { Regex(it) }
42-
val sexual = sequenceOf("^cum[s\\$]?$", "cumm?[i1]ng", "h[o0]rny", "mast(e|ur)b(8|ait|ate)").map { Regex(it) }
43-
val addresses = sequenceOf("^((25[0-5]|2[0-4]\\d|1\\d{2}|[1-9]?\\d)(\\.)){3}(25[0-5]|2[0-4]\\d|1\\d{2}|[1-9]?\\d)$", "^(\\:\\:)?[0-9a-fA-F]{1,4}(\\:\\:?[0-9a-fA-F]{1,4}){0,7}(\\:\\:)?$", "[A-Za-z0-9-]{1,63}\\.[A-Za-z]{2,6}$").map { Regex(it) }
54+
.apply { applyEdits { editTyped(::action) { defaultValue(ReplaceConfig.ActionStrategy.Hide) } } }
55+
private val detectColors = ReplaceSettings("Colors", this, Group.Colors)
56+
.apply { applyEdits { editTyped(::action) { defaultValue(ReplaceConfig.ActionStrategy.None) } } }
4457

4558
enum class Group(override val displayName: String) : NamedEnum {
59+
General("General"),
4660
Slurs("Slurs"),
4761
Swears("Swears"),
4862
Sexual("Sexual"),
63+
Discord("Discord Invites"),
4964
Addresses("IPs and Addresses"),
65+
Colors("Color Prefixes")
5066
}
5167

5268
init {
5369
listen<ChatEvent.Message> { event ->
54-
val author = event.message.string.substringBefore(' ')
70+
val author = event.message.string.substringAfter('<').substringBefore('>')
5571
var content = event.message.string.substringAfter(' ')
5672

73+
if (!ignoreFriends && FriendManager.isFriend(author) ||
74+
!ignoreSelf && player.gameProfile.name == author) return@listen
75+
5776
val slurMatches = slurs.takeIf { detectSlurs.enabled }.orEmpty()
5877
.flatMap { it.findAll(content).toList().reversed() }
5978

@@ -63,9 +82,15 @@ object AntiSpam : Module(
6382
val sexualMatches = sexual.takeIf { detectSexual.enabled }.orEmpty()
6483
.flatMap { it.findAll(content).toList().reversed() }
6584

85+
val discordMatches = discord.takeIf { detectDiscord.enabled }.orEmpty()
86+
.flatMap { it.findAll(content).toList().reversed() }
87+
6688
val addressMatches = addresses.takeIf { detectAddresses.enabled }.orEmpty()
6789
.flatMap { it.findAll(content).toList().reversed() }
6890

91+
val colorMatches = colors.takeIf { detectColors.enabled }.orEmpty()
92+
.flatMap { it.findAll(content).toList().reversed() }
93+
6994
var cancelled = false
7095
var hasMatches = false
7196

@@ -85,11 +110,14 @@ object AntiSpam : Module(
85110
doMatch(detectSlurs, slurMatches)
86111
doMatch(detectSwears, swearMatches)
87112
doMatch(detectSexual, sexualMatches)
113+
doMatch(detectDiscord, discordMatches)
88114
doMatch(detectAddresses, addressMatches)
115+
doMatch(detectColors, colorMatches)
89116

90117
if (!hasMatches) return@listen
91118

92-
event.message = Text.of("$author $content")
119+
val postprocessed = if (fancyChats) content.toAscii else content
120+
event.message = Text.of("<$author> $postprocessed")
93121
}
94122
}
95123

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
/*
2+
* Copyright 2025 Lambda
3+
*
4+
* This program is free software: you can redistribute it and/or modify
5+
* it under the terms of the GNU General Public License as published by
6+
* the Free Software Foundation, either version 3 of the License, or
7+
* (at your option) any later version.
8+
*
9+
* This program is distributed in the hope that it will be useful,
10+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12+
* GNU General Public License for more details.
13+
*
14+
* You should have received a copy of the GNU General Public License
15+
* along with this program. If not, see <http://www.gnu.org/licenses/>.
16+
*/
17+
18+
package com.lambda.util
19+
20+
object ChatUtils {
21+
val slurs = sequenceOf("\\bch[i1l]nks?\\b", "\\bc[o0]{2}ns?\\b", "f[a@4](g{1,2}|qq)([e3il1o0]t{1,2}(ry|r[i1l]e)?)?\\b", "\\bk[il1y]k[e3](ry|r[i1l]e)?s?\\b", "\\b(s[a4]nd)?n[ila4o10][gq]{1,2}(l[e3]t|[e3]r|[a4]|n[o0]g)?s?\\b", "\\btr[a4]n{1,2}([il1][e3]|y|[e3]r)s?\\b").map { Regex(it) }
22+
val swears = sequenceOf("fuck(er)?", "shit", "cunt", "puss(ie|y)", "bitch", "twat").map { Regex(it) }
23+
val sexual = sequenceOf("^cum[s\\$]?$", "cumm?[i1]ng", "h[o0]rny", "mast(e|ur)b(8|ait|ate)").map { Regex(it) }
24+
val discord = sequenceOf("(http(s)?:\\/\\/)?(discord)?(\\.)?gg(\\/| ).\\S{1,25}", "(http(s)?:\\/\\/)?(discord)?(\\.)?com\\/invite(\\/| ).\\S{1,25}", "(dsc)?(\\.)?gg(\\/| ).\\S{1,25}").map { Regex(it) }
25+
val addresses = sequenceOf("^(?:[0-9]{1,3}\\.){3}[0-9]{1,3}(:\\d{1,5}$)?", "^(\\[?)(\\:\\:)?[0-9a-fA-F]{1,4}(\\:\\:?[0-9a-fA-F]{1,4}){0,7}(\\:\\:)?(\\])?(:\\d{1,5}$)?$").map { Regex(it) }
26+
val colors = sequenceOf(">", "`").map { Regex(it) }
27+
28+
}

0 commit comments

Comments
 (0)