Commit bb3944d5 authored by ryoii's avatar ryoii

Support handle bot invited into a group, close #259

parent 69827701
...@@ -28,6 +28,7 @@ import net.mamoe.mirai.* ...@@ -28,6 +28,7 @@ import net.mamoe.mirai.*
import net.mamoe.mirai.contact.* import net.mamoe.mirai.contact.*
import net.mamoe.mirai.data.* import net.mamoe.mirai.data.*
import net.mamoe.mirai.event.broadcast 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.MemberJoinRequestEvent
import net.mamoe.mirai.event.events.MessageRecallEvent import net.mamoe.mirai.event.events.MessageRecallEvent
import net.mamoe.mirai.event.events.NewFriendRequestEvent import net.mamoe.mirai.event.events.NewFriendRequestEvent
...@@ -56,6 +57,7 @@ import kotlin.contracts.ExperimentalContracts ...@@ -56,6 +57,7 @@ import kotlin.contracts.ExperimentalContracts
import kotlin.contracts.contract import kotlin.contracts.contract
import kotlin.coroutines.CoroutineContext import kotlin.coroutines.CoroutineContext
import kotlin.jvm.JvmSynthetic import kotlin.jvm.JvmSynthetic
import kotlin.jvm.Synchronized
import kotlin.math.absoluteValue import kotlin.math.absoluteValue
import kotlin.random.Random import kotlin.random.Random
import net.mamoe.mirai.qqandroid.network.protocol.data.jce.FriendInfo as JceFriendInfo import net.mamoe.mirai.qqandroid.network.protocol.data.jce.FriendInfo as JceFriendInfo
...@@ -205,6 +207,31 @@ internal class QQAndroidBot constructor( ...@@ -205,6 +207,31 @@ internal class QQAndroidBot constructor(
).sendWithoutExpect() ).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) @OptIn(MiraiInternalAPI::class, MiraiExperimentalAPI::class)
......
...@@ -2,12 +2,12 @@ package net.mamoe.mirai.qqandroid.network.protocol.packet.chat ...@@ -2,12 +2,12 @@ package net.mamoe.mirai.qqandroid.network.protocol.packet.chat
import kotlinx.io.core.ByteReadPacket import kotlinx.io.core.ByteReadPacket
import kotlinx.io.core.readBytes 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.MemberJoinRequestEvent
import net.mamoe.mirai.event.events.NewFriendRequestEvent import net.mamoe.mirai.event.events.NewFriendRequestEvent
import net.mamoe.mirai.qqandroid.QQAndroidBot 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.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.data.proto.Structmsg
import net.mamoe.mirai.qqandroid.network.protocol.packet.OutgoingPacketFactory import net.mamoe.mirai.qqandroid.network.protocol.packet.OutgoingPacketFactory
import net.mamoe.mirai.qqandroid.network.protocol.packet.buildOutgoingUniPacket import net.mamoe.mirai.qqandroid.network.protocol.packet.buildOutgoingUniPacket
...@@ -93,7 +93,7 @@ internal class NewContact { ...@@ -93,7 +93,7 @@ internal class NewContact {
internal object SystemMsgNewGroup : internal object SystemMsgNewGroup :
OutgoingPacketFactory<MemberJoinRequestEvent?>("ProfileService.Pb.ReqSystemMsgNew.Group") { OutgoingPacketFactory<Packet?>("ProfileService.Pb.ReqSystemMsgNew.Group") {
operator fun invoke(client: QQAndroidClient) = buildOutgoingUniPacket(client) { operator fun invoke(client: QQAndroidClient) = buildOutgoingUniPacket(client) {
writeProtoBuf( writeProtoBuf(
...@@ -129,22 +129,35 @@ internal class NewContact { ...@@ -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 { readBytes().loadAs(Structmsg.RspSystemMsgNew.serializer()).run {
val struct = groupmsgs?.firstOrNull() val struct = groupmsgs?.firstOrNull()
return if (struct == null) null else { return if (struct == null) null else {
struct.msg?.run { struct.msg?.run {
MemberJoinRequestEvent( if (c2cInviteJoinGroupFlag == 1) {
bot, // 被邀请入群
struct.msgSeq, BotInvitedJoinGroupRequestEvent(
msgAdditional, bot,
struct.reqUin, struct.msgSeq,
groupCode, actionUin,
groupName, groupCode,
reqUinNick 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 { ...@@ -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 override suspend fun ByteReadPacket.decode(bot: QQAndroidBot) = null
} }
} }
......
...@@ -307,7 +307,7 @@ internal class MessageSvc { ...@@ -307,7 +307,7 @@ internal class MessageSvc {
} else return@mapNotNull null } else return@mapNotNull null
} }
} }
84 -> { // 请求入群验证 84, 87 -> { // 请求入群验证 和 被要求入群
bot.network.run { bot.network.run {
NewContact.SystemMsgNewGroup(bot.client).sendWithoutExpect() NewContact.SystemMsgNewGroup(bot.client).sendWithoutExpect()
} }
......
...@@ -19,6 +19,7 @@ import kotlinx.coroutines.io.ByteReadChannel ...@@ -19,6 +19,7 @@ import kotlinx.coroutines.io.ByteReadChannel
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import net.mamoe.mirai.contact.* import net.mamoe.mirai.contact.*
import net.mamoe.mirai.data.AddFriendResult 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.MemberJoinRequestEvent
import net.mamoe.mirai.event.events.NewFriendRequestEvent import net.mamoe.mirai.event.events.NewFriendRequestEvent
import net.mamoe.mirai.message.MessageReceipt import net.mamoe.mirai.message.MessageReceipt
...@@ -271,6 +272,24 @@ abstract class Bot : CoroutineScope, LowLevelBotAPIAccessor, BotJavaFriendlyAPI( ...@@ -271,6 +272,24 @@ abstract class Bot : CoroutineScope, LowLevelBotAPIAccessor, BotJavaFriendlyAPI(
@JvmSynthetic @JvmSynthetic
abstract suspend fun ignoreMemberJoinRequest(event: MemberJoinRequestEvent, blackList: Boolean = false) 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 // endregion
/** /**
......
...@@ -711,4 +711,42 @@ data class MemberJoinRequestEvent( ...@@ -711,4 +711,42 @@ data class MemberJoinRequestEvent(
runBlocking { bot.ignoreMemberJoinRequest(this@MemberJoinRequestEvent, blackList) } 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 好友、群认证 // endregion 好友、群认证
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment