Support handle bot invited into a group, close #259

This commit is contained in:
ryoii 2020-04-25 00:24:16 +08:00
parent 69827701e3
commit bb3944d5ae
5 changed files with 136 additions and 15 deletions

View File

@ -28,6 +28,7 @@ import net.mamoe.mirai.*
import net.mamoe.mirai.contact.*
import net.mamoe.mirai.data.*
import net.mamoe.mirai.event.broadcast
import net.mamoe.mirai.event.events.BotInvitedJoinGroupRequestEvent
import net.mamoe.mirai.event.events.MemberJoinRequestEvent
import net.mamoe.mirai.event.events.MessageRecallEvent
import net.mamoe.mirai.event.events.NewFriendRequestEvent
@ -56,6 +57,7 @@ import kotlin.contracts.ExperimentalContracts
import kotlin.contracts.contract
import kotlin.coroutines.CoroutineContext
import kotlin.jvm.JvmSynthetic
import kotlin.jvm.Synchronized
import kotlin.math.absoluteValue
import kotlin.random.Random
import net.mamoe.mirai.qqandroid.network.protocol.data.jce.FriendInfo as JceFriendInfo
@ -205,6 +207,31 @@ internal class QQAndroidBot constructor(
).sendWithoutExpect()
}
}
override suspend fun acceptInvitedJoinGroupRequest(event: BotInvitedJoinGroupRequestEvent)
= solveInvitedJoinGroupRequest(event, accept = true)
override suspend fun ignoreInvitedJoinGroupRequest(event: BotInvitedJoinGroupRequestEvent)
= solveInvitedJoinGroupRequest(event, accept = false)
private suspend fun solveInvitedJoinGroupRequest(event: BotInvitedJoinGroupRequestEvent, accept: Boolean) {
check(event.responded.compareAndSet(false, true)) {
"the request $this has already been responded"
}
check(!groups.contains(event.groupId)) {
"the request $this is outdated: Bot has been already in the group."
}
network.run {
NewContact.SystemMsgNewGroup.Action(
bot.client,
event,
accept = accept
).sendWithoutExpect()
}
}
}
@OptIn(MiraiInternalAPI::class, MiraiExperimentalAPI::class)

View File

@ -2,12 +2,12 @@ package net.mamoe.mirai.qqandroid.network.protocol.packet.chat
import kotlinx.io.core.ByteReadPacket
import kotlinx.io.core.readBytes
import net.mamoe.mirai.event.events.BotInvitedJoinGroupRequestEvent
import net.mamoe.mirai.event.events.MemberJoinRequestEvent
import net.mamoe.mirai.event.events.NewFriendRequestEvent
import net.mamoe.mirai.qqandroid.QQAndroidBot
import net.mamoe.mirai.qqandroid.network.Packet
import net.mamoe.mirai.qqandroid.network.QQAndroidClient
import net.mamoe.mirai.qqandroid.network.protocol.data.proto.MsgComm
import net.mamoe.mirai.qqandroid.network.protocol.data.proto.MsgSvc
import net.mamoe.mirai.qqandroid.network.protocol.data.proto.Structmsg
import net.mamoe.mirai.qqandroid.network.protocol.packet.OutgoingPacketFactory
import net.mamoe.mirai.qqandroid.network.protocol.packet.buildOutgoingUniPacket
@ -93,7 +93,7 @@ internal class NewContact {
internal object SystemMsgNewGroup :
OutgoingPacketFactory<MemberJoinRequestEvent?>("ProfileService.Pb.ReqSystemMsgNew.Group") {
OutgoingPacketFactory<Packet?>("ProfileService.Pb.ReqSystemMsgNew.Group") {
operator fun invoke(client: QQAndroidClient) = buildOutgoingUniPacket(client) {
writeProtoBuf(
@ -129,22 +129,35 @@ internal class NewContact {
}
override suspend fun ByteReadPacket.decode(bot: QQAndroidBot): MemberJoinRequestEvent? {
override suspend fun ByteReadPacket.decode(bot: QQAndroidBot): Packet? {
readBytes().loadAs(Structmsg.RspSystemMsgNew.serializer()).run {
val struct = groupmsgs?.firstOrNull()
return if (struct == null) null else {
struct.msg?.run {
MemberJoinRequestEvent(
bot,
struct.msgSeq,
msgAdditional,
struct.reqUin,
groupCode,
groupName,
reqUinNick
)
}
if (c2cInviteJoinGroupFlag == 1) {
// 被邀请入群
BotInvitedJoinGroupRequestEvent(
bot,
struct.msgSeq,
actionUin,
groupCode,
groupName,
actionUinNick
)
} else {
// 成员申请入群
MemberJoinRequestEvent(
bot,
struct.msgSeq,
msgAdditional,
struct.reqUin,
groupCode,
groupName,
reqUinNick
)
}
} as Packet // 没有 as Packet 垃圾 kotlin 会把类型推断为Any
}
}
}
@ -183,6 +196,30 @@ internal class NewContact {
)
}
operator fun invoke(
client: QQAndroidClient,
event: BotInvitedJoinGroupRequestEvent,
accept: Boolean
) =
buildOutgoingUniPacket(client) {
writeProtoBuf(
Structmsg.ReqSystemMsgAction.serializer(),
Structmsg.ReqSystemMsgAction(
actionInfo = Structmsg.SystemMsgActionInfo(
type = if (accept) 11 else 12,
groupCode = event.groupId
),
groupMsgType = 2,
language = 1000,
msgSeq = event.eventId,
reqUin = event.invitorId,
srcId = 3,
subSrcId = 10016,
subType = 1
)
)
}
override suspend fun ByteReadPacket.decode(bot: QQAndroidBot) = null
}
}

View File

@ -307,7 +307,7 @@ internal class MessageSvc {
} else return@mapNotNull null
}
}
84 -> { // 请求入群验证
84, 87 -> { // 请求入群验证 和 被要求入群
bot.network.run {
NewContact.SystemMsgNewGroup(bot.client).sendWithoutExpect()
}

View File

@ -19,6 +19,7 @@ import kotlinx.coroutines.io.ByteReadChannel
import kotlinx.coroutines.launch
import net.mamoe.mirai.contact.*
import net.mamoe.mirai.data.AddFriendResult
import net.mamoe.mirai.event.events.BotInvitedJoinGroupRequestEvent
import net.mamoe.mirai.event.events.MemberJoinRequestEvent
import net.mamoe.mirai.event.events.NewFriendRequestEvent
import net.mamoe.mirai.message.MessageReceipt
@ -271,6 +272,24 @@ abstract class Bot : CoroutineScope, LowLevelBotAPIAccessor, BotJavaFriendlyAPI(
@JvmSynthetic
abstract suspend fun ignoreMemberJoinRequest(event: MemberJoinRequestEvent, blackList: Boolean = false)
/**
* 接收邀请入群需管理员权限
*
* @param event 邀请入群的事件对象
*/
@SinceMirai("0.40.0")
@JvmSynthetic
abstract suspend fun acceptInvitedJoinGroupRequest(event: BotInvitedJoinGroupRequestEvent)
/**
* 忽略邀请入群需管理员权限
*
* @param event 邀请入群的事件对象
*/
@JvmSynthetic
@SinceMirai("0.40.0")
abstract suspend fun ignoreInvitedJoinGroupRequest(event: BotInvitedJoinGroupRequestEvent)
// endregion
/**

View File

@ -711,4 +711,42 @@ data class MemberJoinRequestEvent(
runBlocking { bot.ignoreMemberJoinRequest(this@MemberJoinRequestEvent, blackList) }
}
@SinceMirai("0.40.0")
data class BotInvitedJoinGroupRequestEvent(
override val bot: Bot,
/**
* 事件唯一识别号
*/
val eventId: Long,
/**
* 邀请入群的账号的 id
*/
val invitorId: Long,
val groupId: Long,
val groupName: String,
/**
* 邀请人昵称
*/
val invitorNick: String
) : BotEvent, Packet {
val invitor: Friend = this.bot.getFriend(invitorId)
@JvmField
internal val responded: MiraiAtomicBoolean = MiraiAtomicBoolean(false)
@JvmSynthetic
suspend fun accept() = bot.acceptInvitedJoinGroupRequest(this)
@JvmSynthetic
suspend fun ignore() = bot
@JavaFriendlyAPI
@JvmName("accept")
fun __acceptBlockingForJava__() = runBlocking { bot.acceptInvitedJoinGroupRequest(this@BotInvitedJoinGroupRequestEvent) }
@JavaFriendlyAPI
@JvmName("ignore")
fun __ignoreBlockingForJava__() = runBlocking { bot.ignoreInvitedJoinGroupRequest(this@BotInvitedJoinGroupRequestEvent) }
}
// endregion 好友、群认证