Skip to content

Commit 834390d

Browse files
Merge pull request #2 from 4o4E/main
修改指令
2 parents c0a6ccd + f5385f1 commit 834390d

File tree

1 file changed

+133
-59
lines changed

1 file changed

+133
-59
lines changed

src/main/kotlin/Command.kt

+133-59
Original file line numberDiff line numberDiff line change
@@ -1,81 +1,155 @@
11
package org.fenglin
22

3+
import kotlinx.coroutines.runBlocking
34
import net.mamoe.mirai.console.command.CommandSender
45
import net.mamoe.mirai.console.command.CompositeCommand
5-
import net.mamoe.mirai.contact.NormalMember
6-
import net.mamoe.mirai.contact.User
6+
import net.mamoe.mirai.console.command.MemberCommandSender
7+
import net.mamoe.mirai.contact.*
78
import net.mamoe.mirai.data.UserProfile
89
import net.mamoe.mirai.message.data.At
9-
import org.fenglin.Command.data
10-
import org.fenglin.Command.normalMember
11-
import org.fenglin.Command.playing
10+
import net.mamoe.mirai.message.data.MessageChain
11+
import net.mamoe.mirai.message.data.MessageSource.Key.quote
12+
import net.mamoe.mirai.message.data.PlainText
13+
import net.mamoe.mirai.message.data.buildMessageChain
1214
import java.text.SimpleDateFormat
1315
import java.util.*
14-
16+
import java.util.concurrent.ConcurrentHashMap
17+
import kotlin.random.Random
1518

1619
object Command : CompositeCommand(
1720
GuessGroupFriends,
1821
"猜群友",
1922
"猜群友游戏",
2023
description = "开始猜群友!"
2124
) {
22-
var normalMember: NormalMember? = null
23-
var playing:Boolean=false;
24-
var data:ArrayList<String>?=null
25-
@SubCommand // 标记这是指令处理器 // 函数名随意
26-
suspend fun CommandSender.paly() {
27-
if (playing){
28-
sendMessage("游戏进行中")
29-
return;
25+
/**
26+
* 正在进行的游戏 <群号, 游戏>
27+
*/
28+
private val games = ConcurrentHashMap<Long, Game>()
29+
30+
// 最近24小时发言过的
31+
private const val lastSpeakLimit = 24 * 60 * 60 * 1000L
32+
// 缓存有效期10分钟
33+
private const val profileCacheTimeout = 600_000
34+
private val sdf = SimpleDateFormat("yyyy/MM/dd HH:mm:ss")
35+
36+
/**
37+
* 用户UserProfile缓存 <id, <profile, 缓存时间戳>>
38+
*/
39+
private val profileCache = ConcurrentHashMap<Long, Pair<UserProfile, Long>>()
40+
suspend fun Member.getCacheProfile(): UserProfile {
41+
val pair = profileCache[id]
42+
if (pair != null
43+
&& pair.second > System.currentTimeMillis() - profileCacheTimeout
44+
) return pair.first
45+
// 缓存过期
46+
return queryProfile().also {
47+
profileCache[id] = Pair(it, System.currentTimeMillis())
3048
}
31-
this.subject?.id?.let { it ->
32-
// 获取群友
33-
val members = this.bot?.getGroup(it)?.members?.toList()
34-
normalMember = members?.get((0 until members.size).random())
35-
if (normalMember==null){
36-
sendMessage("获取群友失败")
37-
return;
38-
}
39-
//获取信息
40-
val sdf = SimpleDateFormat("yyyy/MM/dd HH:mm:ss")
41-
data= arrayListOf(
42-
"ta的网名中含有${normalMember!!.nick.random()}",
43-
"ta的入群时间为:${sdf.format(Date(normalMember!!.joinTimestamp.toLong()*1000L))}",
44-
"ta的最后发言时间:${sdf.format(Date(normalMember!!.lastSpeakTimestamp.toLong()*1000L))}",
45-
"ta的性别:${if(normalMember?.queryProfile()?.sex== UserProfile.Sex.MALE && normalMember?.queryProfile()?.sex != UserProfile.Sex.UNKNOWN) "" else ""}",
46-
"ta的QQ等级:${normalMember?.queryProfile()?.qLevel?:"没有获取到"}",
47-
"ta的个性签名:${normalMember?.queryProfile()?.sign?:"没有获取到"}",
48-
"ta的年龄:${normalMember?.queryProfile()?.age?:"没有获取到"}"
49+
}
50+
51+
private fun UserProfile.Sex.alias() = when (this) {
52+
UserProfile.Sex.MALE -> ""
53+
UserProfile.Sex.FEMALE -> ""
54+
UserProfile.Sex.UNKNOWN -> "未知"
55+
}
56+
57+
private val conditions = mutableListOf<NormalMember.() -> Boolean>(
58+
{ lastSpeakTimestamp * 1000L + lastSpeakLimit >= System.currentTimeMillis() }
59+
)
60+
61+
/**
62+
* 代表一个群里正在进行的游戏
63+
*
64+
* @param group 群
65+
* @param member 正在猜的群友
66+
*/
67+
class Game(val group: Group, val member: NormalMember) {
68+
private val profile by lazy { runBlocking { member.getCacheProfile() } }
69+
private val hint = arrayListOf(
70+
{ PlainText("ta的网名中含有${member.nameCardOrNick.random()}") },
71+
{ PlainText("ta的入群时间为:${sdf.format(Date(member.joinTimestamp * 1000L))}") },
72+
{ PlainText("ta的最后发言时间:${sdf.format(Date(member.lastSpeakTimestamp * 1000L))}") },
73+
{ PlainText("ta的性别:${profile.sex.alias()}") },
74+
{ PlainText("ta的QQ等级:${profile.qLevel}") },
75+
{ PlainText("ta的个性签名:${profile.sign}") },
76+
{ PlainText("ta的年龄:${profile.age}") },
77+
)
78+
79+
fun getHint() =
80+
if (hint.isEmpty()) null
81+
else hint.removeAt(Random.nextInt(hint.size)).invoke()
82+
83+
suspend fun start() {
84+
group.sendMessage(
85+
"""游戏开始,下面将发送第一条线索
86+
|如果回答错误,将随机发送一条线索,线索用完时游戏失败
87+
|发送 `/猜群友 猜 @群友` 进行游戏
88+
""".trimMargin()
4989
)
50-
sendMessage("游戏开始!下面将发送第一条线索。如果回答错误,将随机发送一条线索!")
51-
sendMessage(random())
52-
playing = true
90+
group.sendMessage(getHint()!!)
91+
}
92+
93+
fun end() {
94+
games.remove(group.id)
5395
}
5496
}
55-
// 猜群友
56-
@SubCommand
57-
suspend fun CommandSender.guess(target: User) {
58-
if (!playing) {this.sendMessage("游戏未开始!");} else {
59-
if (target.id == normalMember?.id) {
60-
this.sendMessage(At(this.user!!).plus("恭喜你回答正确!"))
61-
} else {
62-
this.sendMessage(At(this.user!!).plus("回答错误!出现新提示:").plus(random()))
63-
}
97+
98+
// 开始游戏
99+
@SubCommand("开始")
100+
@Description("开始猜群友游戏")
101+
suspend fun CommandSender.play() {
102+
if (this !is MemberCommandSender) {
103+
sendMessage("仅可在群聊中使用")
104+
return
64105
}
106+
if (games[group.id] != null) {
107+
sendMessage("游戏进行中, 发送 `/猜群友 猜 @猜的群友` 来猜群友")
108+
return
109+
}
110+
// 获取群友
111+
val member = group.members.filter { member ->
112+
conditions.all { it.invoke(member) }
113+
}[Random.nextInt(group.members.size)]
114+
val game = Game(group, member)
115+
game.start()
65116
}
66-
}
67-
private fun random():String{
68-
if (data.isNullOrEmpty()) {
69-
playing = false;
70-
return "看来没人能猜到我,我要公布答案了:这位群友是:${normalMember?.nick}"
71-
} else{
72-
val r = (0 until data?.size!!).random()
73-
if (data!!.elementAtOrNull(r)==null){
74-
playing = false;
75-
return "看来没人能猜到我,我要公布答案了:这位群友是:${normalMember?.nick}"
76-
}
77-
val res = data!![r]
78-
data?.removeAt(r)
79-
return res
117+
118+
// 猜群友
119+
@SubCommand("")
120+
@Description("在猜群友游戏猜一次群友")
121+
suspend fun CommandSender.guess(target: User, chain: MessageChain) {
122+
if (this !is MemberCommandSender) {
123+
sendMessage("仅可在群聊中使用")
124+
return
80125
}
81-
}
126+
val game = games[group.id]
127+
if (game == null) {
128+
sendMessage("游戏未开始!")
129+
return
130+
}
131+
val success = target.id == game.member.id
132+
if (success) {
133+
group.sendMessage(buildMessageChain {
134+
append(PlainText("恭喜 "))
135+
append(At(user))
136+
append(PlainText(" 猜出了群友, 游戏结束\n发送 `/猜群友 开始` 开始新游戏"))
137+
})
138+
return
139+
}
140+
val hint = game.getHint()
141+
// 提示用完
142+
if (hint == null) {
143+
game.end()
144+
sendMessage("看来没人能猜到我,我要公布答案了:这位群友是: ${game.member.nameCardOrNick}")
145+
return
146+
}
147+
sendMessage(
148+
buildMessageChain {
149+
append(chain.quote())
150+
append(At(user))
151+
append("回答错误!\n新提示:$hint")
152+
}
153+
)
154+
}
155+
}

0 commit comments

Comments
 (0)