mirror of
https://github.com/mamoe/mirai.git
synced 2025-01-03 01:14:44 +08:00
Support BotJoinGroupEvent.Invite, close #344
This commit is contained in:
parent
e8345c382d
commit
ab464388c1
@ -450,9 +450,10 @@ internal fun List<ImMsgBody.Elem>.joinToMessageChain(groupIdOrZero: Long, bot: B
|
||||
internal fun contextualBugReportException(
|
||||
context: String,
|
||||
forDebug: String,
|
||||
e: Throwable? = null
|
||||
e: Throwable? = null,
|
||||
additional: String = ""
|
||||
): IllegalStateException {
|
||||
return IllegalStateException("在 $context 时遇到了意料之中的问题. 请完整复制此日志提交给 mirai. 调试信息: $forDebug", e)
|
||||
return IllegalStateException("在 $context 时遇到了意料之中的问题. 请完整复制此日志提交给 mirai. $additional 调试信息: $forDebug", e)
|
||||
}
|
||||
|
||||
@OptIn(ExperimentalContracts::class)
|
||||
|
@ -14,10 +14,7 @@ package net.mamoe.mirai.qqandroid.network.protocol.packet.chat
|
||||
import kotlinx.io.core.ByteReadPacket
|
||||
import kotlinx.io.core.readBytes
|
||||
import net.mamoe.mirai.contact.Group
|
||||
import net.mamoe.mirai.event.events.BotInvitedJoinGroupRequestEvent
|
||||
import net.mamoe.mirai.event.events.BotLeaveEvent
|
||||
import net.mamoe.mirai.event.events.MemberJoinRequestEvent
|
||||
import net.mamoe.mirai.event.events.NewFriendRequestEvent
|
||||
import net.mamoe.mirai.event.events.*
|
||||
import net.mamoe.mirai.qqandroid.QQAndroidBot
|
||||
import net.mamoe.mirai.qqandroid.message.contextualBugReportException
|
||||
import net.mamoe.mirai.qqandroid.network.Packet
|
||||
@ -25,6 +22,7 @@ import net.mamoe.mirai.qqandroid.network.QQAndroidClient
|
||||
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
|
||||
import net.mamoe.mirai.qqandroid.network.protocol.packet.chat.receive.getNewGroup
|
||||
import net.mamoe.mirai.qqandroid.utils._miraiContentToString
|
||||
import net.mamoe.mirai.qqandroid.utils.io.serialization.loadAs
|
||||
import net.mamoe.mirai.qqandroid.utils.io.serialization.writeProtoBuf
|
||||
@ -169,10 +167,19 @@ internal class NewContact {
|
||||
}
|
||||
else -> throw contextualBugReportException(
|
||||
"parse SystemMsgNewGroup, subType=1",
|
||||
forDebug = this._miraiContentToString()
|
||||
this._miraiContentToString(),
|
||||
additional = "并尽量描述此时机器人是否正被邀请加入群, 或者是有有新群员加入此群"
|
||||
)
|
||||
}
|
||||
}
|
||||
2 -> {
|
||||
// 被邀请入群, 自动同意
|
||||
|
||||
val group = bot.getNewGroup(groupCode) ?: return null
|
||||
val invitor = group[actionUin]
|
||||
|
||||
BotJoinGroupEvent.Invite(reqUinNick, invitor)
|
||||
}
|
||||
5 -> {
|
||||
val group = bot.getGroup(groupCode)
|
||||
val operator = group[actionUin]
|
||||
@ -180,7 +187,8 @@ internal class NewContact {
|
||||
}
|
||||
else -> throw contextualBugReportException(
|
||||
"parse SystemMsgNewGroup",
|
||||
forDebug = this._miraiContentToString()
|
||||
forDebug = this._miraiContentToString(),
|
||||
additional = "并尽量描述此时机器人是否正被邀请加入群, 或者是有有新群员加入此群"
|
||||
)
|
||||
}
|
||||
} as Packet // 没有 as Packet 垃圾 kotlin 会把类型推断为Any
|
||||
|
@ -7,6 +7,8 @@
|
||||
* https://github.com/mamoe/mirai/blob/master/LICENSE
|
||||
*/
|
||||
|
||||
@file:Suppress("INVISIBLE_MEMBER", "INVISIBLE_REFERENCE")
|
||||
|
||||
package net.mamoe.mirai.qqandroid.network.protocol.packet.chat.receive
|
||||
|
||||
import kotlinx.atomicfu.loop
|
||||
@ -105,42 +107,6 @@ internal object MessageSvcPbGetMsg : OutgoingPacketFactory<MessageSvcPbGetMsg.Re
|
||||
|
||||
object EmptyResponse : GetMsgSuccess(emptyList())
|
||||
|
||||
private suspend fun MsgComm.Msg.getNewGroup(bot: QQAndroidBot): Group? {
|
||||
val troopNum = bot.network.run {
|
||||
FriendList.GetTroopListSimplify(bot.client)
|
||||
.sendAndExpect<FriendList.GetTroopListSimplify.Response>(retry = 2)
|
||||
}.groups.firstOrNull { it.groupUin == msgHead.fromUin } ?: return null
|
||||
|
||||
@Suppress("DuplicatedCode")
|
||||
return GroupImpl(
|
||||
bot = bot,
|
||||
coroutineContext = bot.coroutineContext,
|
||||
id = Group.calculateGroupCodeByGroupUin(msgHead.fromUin),
|
||||
groupInfo = bot._lowLevelQueryGroupInfo(troopNum.groupCode).apply {
|
||||
this as GroupInfoImpl
|
||||
|
||||
if (this.delegate.groupName == null) {
|
||||
this.delegate.groupName = troopNum.groupName
|
||||
}
|
||||
|
||||
if (this.delegate.groupMemo == null) {
|
||||
this.delegate.groupMemo = troopNum.groupMemo
|
||||
}
|
||||
|
||||
if (this.delegate.groupUin == null) {
|
||||
this.delegate.groupUin = troopNum.groupUin
|
||||
}
|
||||
|
||||
this.delegate.groupCode = troopNum.groupCode
|
||||
},
|
||||
members = bot._lowLevelQueryGroupMemberList(
|
||||
troopNum.groupUin,
|
||||
troopNum.groupCode,
|
||||
troopNum.dwGroupOwnerUin
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
private fun MsgComm.Msg.getNewMemberInfo(): MemberInfo {
|
||||
return object : MemberInfo {
|
||||
override val nameCard: String get() = ""
|
||||
@ -189,10 +155,10 @@ internal object MessageSvcPbGetMsg : OutgoingPacketFactory<MessageSvcPbGetMsg.Re
|
||||
}
|
||||
// 新群
|
||||
|
||||
val newGroup = msg.getNewGroup(bot) ?: return@mapNotNull null
|
||||
@Suppress("INVISIBLE_MEMBER", "INVISIBLE_REFERENCE")
|
||||
val newGroup = bot.getNewGroup(Group.calculateGroupCodeByGroupUin(msg.msgHead.fromUin))
|
||||
?: return@mapNotNull null
|
||||
bot.groups.delegate.addLast(newGroup)
|
||||
return@mapNotNull BotJoinGroupEvent(newGroup)
|
||||
return@mapNotNull BotJoinGroupEvent.Active(newGroup)
|
||||
} else {
|
||||
group ?: return@mapNotNull null
|
||||
|
||||
@ -212,12 +178,10 @@ internal object MessageSvcPbGetMsg : OutgoingPacketFactory<MessageSvcPbGetMsg.Re
|
||||
discardExact(9)
|
||||
readByte().toInt().and(0xff)
|
||||
} == 0x83) {
|
||||
@Suppress("INVISIBLE_MEMBER", "INVISIBLE_REFERENCE")
|
||||
return@mapNotNull MemberJoinEvent.Invite(group.newMember(msg.getNewMemberInfo())
|
||||
.also { group.members.delegate.addLast(it) })
|
||||
}
|
||||
|
||||
@Suppress("INVISIBLE_MEMBER", "INVISIBLE_REFERENCE")
|
||||
return@mapNotNull MemberJoinEvent.Active(group.newMember(msg.getNewMemberInfo())
|
||||
.also { group.members.delegate.addLast(it) })
|
||||
}
|
||||
@ -394,3 +358,39 @@ internal object MessageSvcPbGetMsg : OutgoingPacketFactory<MessageSvcPbGetMsg.Re
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
internal suspend fun QQAndroidBot.getNewGroup(groupCode: Long): Group? {
|
||||
val troopNum = network.run {
|
||||
FriendList.GetTroopListSimplify(client)
|
||||
.sendAndExpect<FriendList.GetTroopListSimplify.Response>(timeoutMillis = 10_000, retry = 5)
|
||||
}.groups.firstOrNull { it.groupCode == groupCode } ?: return null
|
||||
|
||||
@Suppress("DuplicatedCode")
|
||||
return GroupImpl(
|
||||
bot = this,
|
||||
coroutineContext = coroutineContext,
|
||||
id = groupCode,
|
||||
groupInfo = _lowLevelQueryGroupInfo(troopNum.groupCode).apply {
|
||||
this as GroupInfoImpl
|
||||
|
||||
if (this.delegate.groupName == null) {
|
||||
this.delegate.groupName = troopNum.groupName
|
||||
}
|
||||
|
||||
if (this.delegate.groupMemo == null) {
|
||||
this.delegate.groupMemo = troopNum.groupMemo
|
||||
}
|
||||
|
||||
if (this.delegate.groupUin == null) {
|
||||
this.delegate.groupUin = troopNum.groupUin
|
||||
}
|
||||
|
||||
this.delegate.groupCode = troopNum.groupCode
|
||||
},
|
||||
members = _lowLevelQueryGroupMemberList(
|
||||
troopNum.groupUin,
|
||||
troopNum.groupCode,
|
||||
troopNum.dwGroupOwnerUin
|
||||
)
|
||||
)
|
||||
}
|
||||
|
@ -174,6 +174,7 @@ abstract class Group : Contact(), CoroutineScope {
|
||||
|
||||
companion object {
|
||||
/**
|
||||
* 使用 groupCode 计算 groupUin. 这两个值仅在 mirai 内部协议区分, 一般人使用时无需在意.
|
||||
* @suppress internal api
|
||||
*/
|
||||
@JvmStatic
|
||||
@ -181,6 +182,7 @@ abstract class Group : Contact(), CoroutineScope {
|
||||
CommonGroupCalculations.calculateGroupUinByGroupCode(groupCode)
|
||||
|
||||
/**
|
||||
* 使用 groupUin 计算 groupCode. 这两个值仅在 mirai 内部协议区分, 一般人使用时无需在意.
|
||||
* @suppress internal api
|
||||
*/
|
||||
@JvmStatic
|
||||
|
@ -9,7 +9,7 @@
|
||||
|
||||
@file:JvmMultifileClass
|
||||
@file:JvmName("BotEventsKt")
|
||||
@file:Suppress("unused", "FunctionName")
|
||||
@file:Suppress("unused", "FunctionName", "INVISIBLE_REFERENCE", "INVISIBLE_MEMBER")
|
||||
|
||||
package net.mamoe.mirai.event.events
|
||||
|
||||
@ -25,6 +25,7 @@ import net.mamoe.mirai.event.internal.MiraiAtomicBoolean
|
||||
import net.mamoe.mirai.qqandroid.network.Packet
|
||||
import net.mamoe.mirai.utils.MiraiExperimentalAPI
|
||||
import net.mamoe.mirai.utils.internal.runBlocking
|
||||
import kotlin.internal.LowPriorityInOverloadResolution
|
||||
import kotlin.jvm.*
|
||||
|
||||
/**
|
||||
@ -91,10 +92,44 @@ data class BotUnmuteEvent internal constructor(
|
||||
/**
|
||||
* Bot 成功加入了一个新群
|
||||
*/
|
||||
@MiraiExperimentalAPI
|
||||
data class BotJoinGroupEvent internal constructor(
|
||||
override val group: Group
|
||||
) : BotPassiveEvent, GroupEvent, Packet, AbstractEvent()
|
||||
sealed class BotJoinGroupEvent : GroupEvent, Packet, AbstractEvent() {
|
||||
abstract override val group: Group
|
||||
|
||||
/**
|
||||
* 不确定. 可能是主动加入
|
||||
*/
|
||||
@MiraiExperimentalAPI
|
||||
data class Active internal constructor(
|
||||
override val group: Group
|
||||
) : BotPassiveEvent, GroupEvent, Packet, AbstractEvent() {
|
||||
override fun toString(): String {
|
||||
return "BotJoinGroupEvent.Active(group=$group)"
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Bot 被一个群内的成员直接邀请加入了群.
|
||||
*
|
||||
* 此时服务器基于 Bot 的 QQ 设置自动同意了请求.
|
||||
*/
|
||||
@MiraiExperimentalAPI
|
||||
data class Invite internal constructor(
|
||||
/**
|
||||
* 邀请人昵称 (可能为备注或群名片)
|
||||
*/
|
||||
val invitorName: String,
|
||||
/**
|
||||
* 邀请人
|
||||
*/
|
||||
val invitor: Member
|
||||
) : BotPassiveEvent, GroupEvent, Packet, AbstractEvent() {
|
||||
override val group: Group get() = invitor.group
|
||||
|
||||
override fun toString(): String {
|
||||
return "BotJoinGroupEvent.Invite(invitorName='$invitorName', invitor=$invitor)"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// region 群设置
|
||||
|
||||
@ -121,6 +156,7 @@ data class GroupNameChangeEvent internal constructor(
|
||||
*/
|
||||
override val operator: Member?
|
||||
) : GroupSettingChangeEvent<String>, Packet, GroupOperableEvent, AbstractEvent() {
|
||||
@LowPriorityInOverloadResolution
|
||||
@Deprecated("for binary compatibility", level = DeprecationLevel.HIDDEN)
|
||||
val isByBot: Boolean
|
||||
get() = operator == null
|
||||
@ -202,7 +238,8 @@ data class GroupAllowMemberInviteEvent internal constructor(
|
||||
/**
|
||||
* 成员已经加入群的事件
|
||||
*/
|
||||
sealed class MemberJoinEvent(override val member: Member) : GroupMemberEvent, BotPassiveEvent, Packet, AbstractEvent() {
|
||||
sealed class MemberJoinEvent(override val member: Member) : GroupMemberEvent, BotPassiveEvent, Packet,
|
||||
AbstractEvent() {
|
||||
/**
|
||||
* 被邀请加入群
|
||||
*/
|
||||
|
@ -7,7 +7,7 @@
|
||||
* https://github.com/mamoe/mirai/blob/master/LICENSE
|
||||
*/
|
||||
|
||||
@file:Suppress("WRONG_MODIFIER_CONTAINING_DECLARATION")
|
||||
@file:Suppress("WRONG_MODIFIER_CONTAINING_DECLARATION", "INVISIBLE_REFERENCE", "INVISIBLE_MEMBER")
|
||||
|
||||
package net.mamoe.mirai.event.events
|
||||
|
||||
@ -16,6 +16,7 @@ import net.mamoe.mirai.contact.Friend
|
||||
import net.mamoe.mirai.contact.Group
|
||||
import net.mamoe.mirai.contact.Member
|
||||
import net.mamoe.mirai.event.Event
|
||||
import kotlin.internal.HidesMembers
|
||||
import kotlin.jvm.JvmSynthetic
|
||||
|
||||
/**
|
||||
@ -69,6 +70,7 @@ interface GroupOperableEvent : GroupEvent {
|
||||
/**
|
||||
* 是否由 [Bot] 操作
|
||||
*/
|
||||
@HidesMembers
|
||||
@get:JvmSynthetic // inline: planning to change to another file (1.2.0)
|
||||
inline val GroupOperableEvent.isByBot: Boolean
|
||||
get() = operator == null
|
||||
|
Loading…
Reference in New Issue
Block a user