feat(Scout): remove empty discriminator from user searches

This commit is contained in:
Cilly Leang 2025-10-18 01:12:20 +11:00
parent fa9fb104b1
commit 67b2c22200
Signed by: cilly
GPG key ID: 6500251E087653C9

View file

@ -12,7 +12,6 @@ import com.aliucord.patcher.*
import com.aliucord.utils.DimenUtils.dp import com.aliucord.utils.DimenUtils.dp
import com.aliucord.utils.ViewUtils.findViewById import com.aliucord.utils.ViewUtils.findViewById
import com.aliucord.wrappers.ChannelWrapper.Companion.id import com.aliucord.wrappers.ChannelWrapper.Companion.id
import com.aliucord.wrappers.ChannelWrapper.Companion.type
import com.discord.BuildConfig import com.discord.BuildConfig
import com.discord.api.channel.Channel import com.discord.api.channel.Channel
import com.discord.api.channel.ChannelUtils import com.discord.api.channel.ChannelUtils
@ -38,6 +37,7 @@ import com.discord.utilities.search.query.node.QueryNode
import com.discord.utilities.search.query.node.answer.ChannelNode import com.discord.utilities.search.query.node.answer.ChannelNode
import com.discord.utilities.search.query.node.answer.HasAnswerOption import com.discord.utilities.search.query.node.answer.HasAnswerOption
import com.discord.utilities.search.query.node.answer.HasNode import com.discord.utilities.search.query.node.answer.HasNode
import com.discord.utilities.search.query.node.answer.UserNode
import com.discord.utilities.search.query.node.content.ContentNode import com.discord.utilities.search.query.node.content.ContentNode
import com.discord.utilities.search.query.node.filter.FilterNode import com.discord.utilities.search.query.node.filter.FilterNode
import com.discord.utilities.search.query.parsing.QueryParser import com.discord.utilities.search.query.parsing.QueryParser
@ -53,7 +53,6 @@ import com.franmontiel.persistentcookiejar.PersistentCookieJar
import com.franmontiel.persistentcookiejar.cache.SetCookieCache import com.franmontiel.persistentcookiejar.cache.SetCookieCache
import com.franmontiel.persistentcookiejar.persistence.SharedPrefsCookiePersistor import com.franmontiel.persistentcookiejar.persistence.SharedPrefsCookiePersistor
import com.lytefast.flexinput.R import com.lytefast.flexinput.R
import de.robv.android.xposed.XposedBridge
import moe.lava.awoocord.scout.api.SearchAPIInterface import moe.lava.awoocord.scout.api.SearchAPIInterface
import moe.lava.awoocord.scout.parsing.* import moe.lava.awoocord.scout.parsing.*
import moe.lava.awoocord.scout.ui.* import moe.lava.awoocord.scout.ui.*
@ -82,6 +81,7 @@ class Scout : Plugin() {
patchSearchUI(context) patchSearchUI(context)
patchSearchPadding() patchSearchPadding()
patchThreadSupport() patchThreadSupport()
patchUsernameDiscriminator()
} }
override fun stop(context: Context) { override fun stop(context: Context) {
@ -609,6 +609,7 @@ class Scout : Plugin() {
} }
} }
// Adds support for searching in threads
private fun patchThreadSupport() { private fun patchThreadSupport() {
// Patch query parser for in: to support names with spaces, by wrapping them in quotes // Patch query parser for in: to support names with spaces, by wrapping them in quotes
// This enables searching for threads which can have spaces in their names // This enables searching for threads which can have spaces in their names
@ -626,8 +627,8 @@ class Scout : Plugin() {
Map::class.java Map::class.java
) { ( ) { (
param, param,
members: Map<Long, GuildMember>, /* members */ _: Map<Long, GuildMember>,
users: Map<Long, User>, /* users*/ _: Map<Long, User>,
channels: Map<Long, Channel>, channels: Map<Long, Channel>,
permissions: Map<Long, Long> permissions: Map<Long, Long>
) -> ) ->
@ -691,7 +692,7 @@ class Scout : Plugin() {
"onConfigure", "onConfigure",
Int::class.javaPrimitiveType!!, Int::class.javaPrimitiveType!!,
MGRecyclerDataPayload::class.java MGRecyclerDataPayload::class.java
) { (param, _: Int, payload: SingleTypePayload<ChannelSuggestion>) -> ) { (_, _: Int, payload: SingleTypePayload<ChannelSuggestion>) ->
StoreStream.getChannels().getChannel(payload.data.channelId)?.let { StoreStream.getChannels().getChannel(payload.data.channelId)?.let {
if (ChannelUtils.H(it)) { if (ChannelUtils.H(it)) {
itemView.findViewById<ImageView>("search_suggestions_item_channel_icon") itemView.findViewById<ImageView>("search_suggestions_item_channel_icon")
@ -700,4 +701,27 @@ class Scout : Plugin() {
} }
} }
} }
// Removes the #0000 discriminator from usernames when searching
private fun patchUsernameDiscriminator() {
// Change the regex for the user rule
// Previously it matches something like <username>#<discrim>
// Now it matches something like @<username>[#<discrim>] (bots still have discriminators)
// The @ is required unfortunately, to distinguish it from literally any other word
patcher.instead<QueryParser.Companion>("getUserRule") {
val regex = Pattern.compile("^\\s*@(?:([^@#:]+)#([0-9]{4})|([a-z0-9._]{2,32}))", 64);
// Returns a new rule to support our optional second group (discriminator)
return@instead SimpleParserRule(regex) { matcher, _, obj ->
val username = matcher.group(3) ?: matcher.group(1)!!
val discrim = matcher.group(2)?.toInt() ?: 0
ParseSpec(UserNode(username, discrim), obj)
}
}
// Patches the node's string representation to add an @ and remove empty discriminators
patcher.after<UserNode>("getText") { param ->
param.result = "@" + (param.result as String).replace("#0000", "")
}
}
} }