mirror of
https://github.com/mamoe/mirai.git
synced 2025-01-11 02:50:15 +08:00
Fix fuzzyCompare
This commit is contained in:
parent
faaf8d34f2
commit
cdc9f8f613
@ -195,12 +195,15 @@ public object ExistMemberArgumentParser : InternalCommandArgumentParserExtension
|
|||||||
- `botId.group.memberId`
|
- `botId.group.memberId`
|
||||||
- `botId.group.memberCard` (模糊搜索, 寻找最优匹配)
|
- `botId.group.memberCard` (模糊搜索, 寻找最优匹配)
|
||||||
- `~` (指代指令调用人自己. 仅聊天环境下)
|
- `~` (指代指令调用人自己. 仅聊天环境下)
|
||||||
|
- `$` (随机成员)
|
||||||
|
|
||||||
当只登录了一个 [Bot] 时, 无需上述 `botId` 参数即可
|
当只登录了一个 [Bot] 时, 无需上述 `botId` 参数即可
|
||||||
""".trimIndent()
|
""".trimIndent()
|
||||||
|
|
||||||
public override fun parse(raw: String, sender: CommandSender): Member {
|
public override fun parse(raw: String, sender: CommandSender): Member {
|
||||||
if (raw == "~") return (sender as? MemberCommandSender)?.user ?: illegalArgument("当前语境下无法推断目标群员")
|
if (raw == "~") return (sender as? MemberCommandSender)?.user ?: illegalArgument("当前语境下无法推断自身作为群员")
|
||||||
|
if (raw == "\$") return (sender as? MemberCommandSender)?.group?.members?.randomOrNull()
|
||||||
|
?: illegalArgument("当前语境下无法推断随机群员")
|
||||||
|
|
||||||
val components = raw.split(".")
|
val components = raw.split(".")
|
||||||
|
|
||||||
@ -221,7 +224,12 @@ public object ExistMemberArgumentParser : InternalCommandArgumentParserExtension
|
|||||||
public override fun parse(raw: SingleMessage, sender: CommandSender): Member {
|
public override fun parse(raw: SingleMessage, sender: CommandSender): Member {
|
||||||
return if (raw is At) {
|
return if (raw is At) {
|
||||||
checkArgument(sender is MemberCommandSender)
|
checkArgument(sender is MemberCommandSender)
|
||||||
sender.group.members[raw.target]
|
val bot = sender.inferBotOrFail()
|
||||||
|
val group = sender.inferGroupOrFail()
|
||||||
|
if (raw.target == bot.id) {
|
||||||
|
return group.botAsMember
|
||||||
|
}
|
||||||
|
group[raw.target]
|
||||||
} else {
|
} else {
|
||||||
parse(raw.content, sender)
|
parse(raw.content, sender)
|
||||||
}
|
}
|
||||||
@ -247,10 +255,12 @@ internal interface InternalCommandArgumentParserExtensions<T : Any> : CommandArg
|
|||||||
fun Bot.findMemberOrFail(id: String): Friend =
|
fun Bot.findMemberOrFail(id: String): Friend =
|
||||||
getFriendOrNull(id.parseToLongOrFail()) ?: illegalArgument("无法找到群员: $this")
|
getFriendOrNull(id.parseToLongOrFail()) ?: illegalArgument("无法找到群员: $this")
|
||||||
|
|
||||||
fun Group.findMemberOrFail(idOrCard: String): Member =
|
fun Group.findMemberOrFail(idOrCard: String): Member {
|
||||||
idOrCard.toLongOrNull()?.let { getOrNull(it) }
|
if (idOrCard == "\$") return members.randomOrNull() ?: illegalArgument("当前语境下无法推断随机群员")
|
||||||
|
return idOrCard.toLongOrNull()?.let { getOrNull(it) }
|
||||||
?: fuzzySearchMember(idOrCard)
|
?: fuzzySearchMember(idOrCard)
|
||||||
?: illegalArgument("无法找到目标群员 $idOrCard")
|
?: illegalArgument("无法找到目标群员 $idOrCard")
|
||||||
|
}
|
||||||
|
|
||||||
fun CommandSender.inferBotOrFail(): Bot = (this as? BotAwareCommandSender)?.bot ?: illegalArgument("当前语境下无法推断目标群员")
|
fun CommandSender.inferBotOrFail(): Bot = (this as? BotAwareCommandSender)?.bot ?: illegalArgument("当前语境下无法推断目标群员")
|
||||||
|
|
||||||
|
@ -14,6 +14,7 @@ import net.mamoe.mirai.console.command.description.CommandArgumentParserExceptio
|
|||||||
import net.mamoe.mirai.contact.Group
|
import net.mamoe.mirai.contact.Group
|
||||||
import net.mamoe.mirai.contact.Member
|
import net.mamoe.mirai.contact.Member
|
||||||
import net.mamoe.mirai.contact.nameCardOrNick
|
import net.mamoe.mirai.contact.nameCardOrNick
|
||||||
|
import kotlin.math.max
|
||||||
|
|
||||||
|
|
||||||
internal infix fun Array<String>.matchesBeginning(list: List<Any>): Boolean {
|
internal infix fun Array<String>.matchesBeginning(list: List<Any>): Boolean {
|
||||||
@ -31,53 +32,39 @@ internal infix fun Array<out String>.intersectsIgnoringCase(other: Array<out Str
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
internal fun String.fuzzyCompare(target: String): Double {
|
internal fun String.fuzzyMatchWith(target: String): Double {
|
||||||
var step = 0
|
|
||||||
if (this == target) {
|
if (this == target) {
|
||||||
return 1.0
|
return 1.0
|
||||||
}
|
}
|
||||||
if (target.length > this.length) {
|
var match = 0
|
||||||
return 0.0
|
for (i in 0..(max(this.lastIndex, target.lastIndex))) {
|
||||||
}
|
val t = target.getOrNull(match)
|
||||||
for (i in this.indices) {
|
if (t == this.getOrNull(i) && t != null) {
|
||||||
if (target.length == i) {
|
match++
|
||||||
step--
|
|
||||||
} else {
|
|
||||||
if (this[i] != target[i]) {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
step++
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return match.toDouble() / (max(this.lastIndex, target.lastIndex) + 1)
|
||||||
if (step == this.length - 1) {
|
|
||||||
return 1.0
|
|
||||||
}
|
|
||||||
return step.toDouble() / this.length
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 模糊搜索一个List中index最接近target的东西
|
|
||||||
*/
|
|
||||||
internal inline fun <T : Any> Collection<T>.fuzzySearch(
|
internal inline fun <T : Any> Collection<T>.fuzzySearch(
|
||||||
target: String,
|
target: String,
|
||||||
index: (T) -> String
|
crossinline index: (T) -> String
|
||||||
): T? {
|
): T? {
|
||||||
var potential: T? = null
|
var maxElement: T? = null
|
||||||
var rate = 0.0
|
var max = 0.0
|
||||||
this.forEach {
|
|
||||||
val thisIndex = index(it)
|
for (t in this) {
|
||||||
if (thisIndex == target) {
|
val r = index(t).fuzzyMatchWith(target)
|
||||||
return it
|
if (r > max) {
|
||||||
}
|
maxElement = t
|
||||||
with(thisIndex.fuzzyCompare(target)) {
|
max = r
|
||||||
if (this > rate) {
|
|
||||||
rate = this
|
|
||||||
potential = it
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (max >= 0.7) {
|
||||||
|
return maxElement
|
||||||
}
|
}
|
||||||
return potential
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -93,7 +80,7 @@ internal inline fun <T : Any> Collection<T>.fuzzySearchOnly(
|
|||||||
var rate = 0.0
|
var rate = 0.0
|
||||||
var collide = 0
|
var collide = 0
|
||||||
this.forEach {
|
this.forEach {
|
||||||
with(index(it).fuzzyCompare(target)) {
|
with(index(it).fuzzyMatchWith(target)) {
|
||||||
if (this > rate) {
|
if (this > rate) {
|
||||||
rate = this
|
rate = this
|
||||||
potential = it
|
potential = it
|
||||||
|
Loading…
Reference in New Issue
Block a user