Ignores duplicated hashtags in different char cases when processing hashtag spam

This commit is contained in:
Vitor Pamplona
2026-05-16 11:34:11 -04:00
parent 3bf3157b17
commit 32b9a06612
5 changed files with 34 additions and 4 deletions
@@ -26,6 +26,8 @@ fun Event.anyHashTag(onEach: (str: String) -> Boolean) = tags.anyHashTag(onEach)
fun Event.countHashtags() = tags.countHashtags()
fun Event.hasMoreHashtagsThan(limit: Int) = tags.hasMoreHashtagsThan(limit)
fun Event.hasHashtags() = tags.hasHashtags()
fun Event.hashtags() = tags.hashtags()
@@ -46,6 +46,13 @@ class HashtagTag {
return tag[1]
}
fun parseLowercase(tag: Array<String>): String? {
ensure(tag.has(1)) { return null }
ensure(tag[0] == TAG_NAME) { return null }
ensure(tag[1].isNotEmpty()) { return null }
return tag[1].lowercase()
}
fun assemble(name: String) = arrayOf(TAG_NAME, name)
fun assembleDualCase(name: String): List<Array<String>> {
@@ -38,8 +38,29 @@ fun TagArray.hashtags() = this.mapNotNull(HashtagTag::parse)
fun TagArray.countHashtags() = this.count(HashtagTag::isTagged)
fun TagArray.hasMoreHashtagsThan(limit: Int): Boolean {
val count = this.count(HashtagTag::isTagged)
return count > limit && this.countUnique(count, HashtagTag::parseLowercase) > limit
}
fun TagArray.isTaggedHash(hashtag: String) = this.isTagged(HashtagTag.TAG_NAME, hashtag, true)
fun TagArray.isTaggedHashes(hashtags: Set<String>) = this.isAnyLowercaseTagged(HashtagTag.TAG_NAME, hashtags)
fun TagArray.firstIsTaggedHashes(hashtags: Set<String>) = this.firstAnyLowercaseTaggedValue(HashtagTag.TAG_NAME, hashtags)
public inline fun <T, U> Array<out T>.countUnique(
size: Int,
transform: (T) -> U?,
): Int {
// Pre-allocate hash set to avoid frequent resizing for larger arrays
val seen = HashSet<U>(size)
var count = 0
for (element in this) {
val value = transform(element)
if (value != null && seen.add(value)) {
++count
}
}
return count
}