Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

获取未处理的好友添加请求 #2786

Open
wants to merge 9 commits into
base: dev
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,10 @@ public abstract interface class net/mamoe/mirai/Bot : kotlinx/coroutines/Corouti
public static fun getInstances ()Ljava/util/List;
public static fun getInstancesSequence ()Lkotlin/sequences/Sequence;
public abstract fun getLogger ()Lnet/mamoe/mirai/utils/MiraiLogger;
public fun getNewFriendRequestList (Z)Ljava/util/List;
public abstract fun getNewFriendRequestList (ZLkotlin/coroutines/Continuation;)Ljava/lang/Object;
public static synthetic fun getNewFriendRequestList$default (Lnet/mamoe/mirai/Bot;ZILjava/lang/Object;)Ljava/util/List;
public static synthetic fun getNewFriendRequestList$default (Lnet/mamoe/mirai/Bot;ZLkotlin/coroutines/Continuation;ILjava/lang/Object;)Ljava/lang/Object;
public abstract fun getOtherClients ()Lnet/mamoe/mirai/contact/ContactList;
public fun getStranger (J)Lnet/mamoe/mirai/contact/Stranger;
public fun getStrangerOrFail (J)Lnet/mamoe/mirai/contact/Stranger;
Expand Down Expand Up @@ -137,6 +141,8 @@ public abstract interface annotation class net/mamoe/mirai/LowLevelApi : java/la
public abstract interface class net/mamoe/mirai/LowLevelApiAccessor {
public fun getGroupVoiceDownloadUrl (Lnet/mamoe/mirai/Bot;[BJJ)Ljava/lang/String;
public abstract fun getGroupVoiceDownloadUrl (Lnet/mamoe/mirai/Bot;[BJJLkotlin/coroutines/Continuation;)Ljava/lang/Object;
public fun getNewFriendRequestList (Lnet/mamoe/mirai/Bot;)Ljava/util/List;
public abstract fun getNewFriendRequestList (Lnet/mamoe/mirai/Bot;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
public fun getRawGroupList (Lnet/mamoe/mirai/Bot;)Lkotlin/sequences/Sequence;
public abstract fun getRawGroupList (Lnet/mamoe/mirai/Bot;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
public fun getRawGroupMemberList (Lnet/mamoe/mirai/Bot;JJJ)Lkotlin/sequences/Sequence;
Expand Down
6 changes: 6 additions & 0 deletions mirai-core-api/compatibility-validation/jvm/api/jvm.api
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,10 @@ public abstract interface class net/mamoe/mirai/Bot : kotlinx/coroutines/Corouti
public static fun getInstances ()Ljava/util/List;
public static fun getInstancesSequence ()Lkotlin/sequences/Sequence;
public abstract fun getLogger ()Lnet/mamoe/mirai/utils/MiraiLogger;
public fun getNewFriendRequestList (Z)Ljava/util/List;
public abstract fun getNewFriendRequestList (ZLkotlin/coroutines/Continuation;)Ljava/lang/Object;
public static synthetic fun getNewFriendRequestList$default (Lnet/mamoe/mirai/Bot;ZILjava/lang/Object;)Ljava/util/List;
public static synthetic fun getNewFriendRequestList$default (Lnet/mamoe/mirai/Bot;ZLkotlin/coroutines/Continuation;ILjava/lang/Object;)Ljava/lang/Object;
public abstract fun getOtherClients ()Lnet/mamoe/mirai/contact/ContactList;
public fun getStranger (J)Lnet/mamoe/mirai/contact/Stranger;
public fun getStrangerOrFail (J)Lnet/mamoe/mirai/contact/Stranger;
Expand Down Expand Up @@ -137,6 +141,8 @@ public abstract interface annotation class net/mamoe/mirai/LowLevelApi : java/la
public abstract interface class net/mamoe/mirai/LowLevelApiAccessor {
public fun getGroupVoiceDownloadUrl (Lnet/mamoe/mirai/Bot;[BJJ)Ljava/lang/String;
public abstract fun getGroupVoiceDownloadUrl (Lnet/mamoe/mirai/Bot;[BJJLkotlin/coroutines/Continuation;)Ljava/lang/Object;
public fun getNewFriendRequestList (Lnet/mamoe/mirai/Bot;)Ljava/util/List;
public abstract fun getNewFriendRequestList (Lnet/mamoe/mirai/Bot;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
public fun getRawGroupList (Lnet/mamoe/mirai/Bot;)Lkotlin/sequences/Sequence;
public abstract fun getRawGroupList (Lnet/mamoe/mirai/Bot;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
public fun getRawGroupMemberList (Lnet/mamoe/mirai/Bot;JJJ)Lkotlin/sequences/Sequence;
Expand Down
10 changes: 10 additions & 0 deletions mirai-core-api/src/commonMain/kotlin/Bot.kt
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,10 @@ import kotlinx.coroutines.*
import me.him188.kotlin.jvm.blocking.bridge.JvmBlockingBridge
import net.mamoe.mirai.contact.*
import net.mamoe.mirai.contact.friendgroup.FriendGroups
import net.mamoe.mirai.data.RequestEventData
import net.mamoe.mirai.event.EventChannel
import net.mamoe.mirai.event.events.BotEvent
import net.mamoe.mirai.event.events.NewFriendRequestEvent
import net.mamoe.mirai.message.action.BotNudge
import net.mamoe.mirai.message.action.MemberNudge
import net.mamoe.mirai.network.LoginFailedException
Expand Down Expand Up @@ -170,6 +172,14 @@ public interface Bot : CoroutineScope, ContactOrBot, UserOrBot {
*/
public override fun nudge(): BotNudge = BotNudge(this)

/**
* 获取未处理的好友请求,作为事件返回
*
* @param broadcast 是否广播该事件,默认为不广播
* @see NewFriendRequestEvent
* @since 2.16
*/
public suspend fun getNewFriendRequestList(broadcast: Boolean = false): List<NewFriendRequestEvent>
Him188 marked this conversation as resolved.
Show resolved Hide resolved

/**
* 关闭这个 [Bot], 立即取消 [Bot] 的 [SupervisorJob], 取消与这个 [Bot] 相关的所有有协程联系的任务.
Expand Down
7 changes: 7 additions & 0 deletions mirai-core-api/src/commonMain/kotlin/LowLevelApiAccessor.kt
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import me.him188.kotlin.jvm.blocking.bridge.JvmBlockingBridge
import net.mamoe.mirai.contact.*
import net.mamoe.mirai.data.FriendInfo
import net.mamoe.mirai.data.MemberInfo
import net.mamoe.mirai.data.RequestEventData
import net.mamoe.mirai.data.StrangerInfo
import net.mamoe.mirai.utils.MiraiExperimentalApi
import net.mamoe.mirai.utils.NotStableForInheritance
Expand Down Expand Up @@ -196,4 +197,10 @@ public interface LowLevelApiAccessor {
groupId: Long,
seconds: Int,
)

/**
* 获取新好友请求列表
*/
@LowLevelApi
StageGuard marked this conversation as resolved.
Show resolved Hide resolved
public suspend fun getNewFriendRequestList(bot: Bot): List<RequestEventData.NewFriendRequest>
}
5 changes: 5 additions & 0 deletions mirai-core-mock/src/internal/MockBotImpl.kt
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import net.mamoe.mirai.event.broadcast
import net.mamoe.mirai.event.events.BotEvent
import net.mamoe.mirai.event.events.BotOnlineEvent
import net.mamoe.mirai.event.events.BotReloginEvent
import net.mamoe.mirai.event.events.NewFriendRequestEvent
import net.mamoe.mirai.internal.network.component.ComponentStorage
import net.mamoe.mirai.internal.network.component.ConcurrentComponentStorage
import net.mamoe.mirai.internal.network.components.EventDispatcher
Expand Down Expand Up @@ -119,6 +120,10 @@ internal class MockBotImpl(
}
}

override suspend fun getNewFriendRequestList(broadcast: Boolean): List<NewFriendRequestEvent> {
return listOf()
}


@Suppress("INVISIBLE_MEMBER", "INVISIBLE_REFERENCE")
override fun close(cause: Throwable?) {
Expand Down
7 changes: 7 additions & 0 deletions mirai-core/src/commonMain/kotlin/MiraiImpl.kt
Original file line number Diff line number Diff line change
Expand Up @@ -801,4 +801,11 @@ internal open class MiraiImpl : IMirai, LowLevelApiAccessor {
}
}
}

override suspend fun getNewFriendRequestList(bot: Bot): List<RequestEventData.NewFriendRequest>{
bot.asQQAndroidBot()
val resp = bot.network.sendAndExpect(NewContact.SystemMsgNewFriend(bot.client))

return resp.list
}
}
16 changes: 16 additions & 0 deletions mirai-core/src/commonMain/kotlin/QQAndroidBot.kt
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,14 @@ package net.mamoe.mirai.internal
import kotlinx.atomicfu.atomic
import kotlinx.coroutines.*
import net.mamoe.mirai.Bot
import net.mamoe.mirai.Mirai
import net.mamoe.mirai.auth.AuthReason
import net.mamoe.mirai.data.RequestEventData
import net.mamoe.mirai.event.broadcast
import net.mamoe.mirai.event.events.BotOfflineEvent
import net.mamoe.mirai.event.events.BotOnlineEvent
import net.mamoe.mirai.event.events.BotReloginEvent
import net.mamoe.mirai.event.events.NewFriendRequestEvent
import net.mamoe.mirai.internal.contact.friendgroup.FriendGroupsImpl
import net.mamoe.mirai.internal.network.component.ComponentStorage
import net.mamoe.mirai.internal.network.component.ComponentStorageDelegate
Expand Down Expand Up @@ -318,6 +321,19 @@ internal open class QQAndroidBot constructor(
},
) // We can move the factory to configuration but this is not necessary for now.
}

override suspend fun getNewFriendRequestList(broadcast: Boolean): List<NewFriendRequestEvent> {
return Mirai.getNewFriendRequestList(this).map { data ->
NewFriendRequestEvent(
this,
data.eventId,
data.message,
data.requester,
data.fromGroupId,
data.requesterNick
).also { if (broadcast) it.broadcast() }
}
}
}

internal fun QQAndroidBot.getGroupByUinOrFail(uin: Long) =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,7 @@ internal abstract class MixedNoticeProcessor : AnyNoticeProcessor() {
is Structmsg.StructMsg -> processImpl(data)
is RequestPushStatus -> processImpl(data)
is DecodedNotifyMsgBody -> processImpl(data)
is Structmsg.RspSystemMsgNew -> processImpl(data)
}
}

Expand All @@ -183,4 +184,5 @@ internal abstract class MixedNoticeProcessor : AnyNoticeProcessor() {
protected open suspend fun NoticePipelineContext.processImpl(data: RequestPushStatus) {}

protected open suspend fun NoticePipelineContext.processImpl(data: DecodedNotifyMsgBody) {}
protected open suspend fun NoticePipelineContext.processImpl(data: Structmsg.RspSystemMsgNew) {}
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,19 +25,22 @@ import net.mamoe.mirai.internal.message.contextualBugReportException
import net.mamoe.mirai.internal.network.components.ContactUpdater
import net.mamoe.mirai.internal.network.components.MixedNoticeProcessor
import net.mamoe.mirai.internal.network.components.NoticePipelineContext
import net.mamoe.mirai.internal.network.components.SyncController.Companion.syncController
import net.mamoe.mirai.internal.network.notice.decoders.DecodedNotifyMsgBody
import net.mamoe.mirai.internal.network.protocol.data.jce.MsgType0x210
import net.mamoe.mirai.internal.network.protocol.data.proto.MsgComm
import net.mamoe.mirai.internal.network.protocol.data.proto.OnlinePushTrans
import net.mamoe.mirai.internal.network.protocol.data.proto.Structmsg
import net.mamoe.mirai.internal.network.protocol.data.proto.Submsgtype0x44
import net.mamoe.mirai.internal.network.protocol.packet.chat.NewContact
import net.mamoe.mirai.internal.utils.io.serialization.loadAs
import net.mamoe.mirai.internal.utils.parseToMessageDataList
import net.mamoe.mirai.internal.utils.toMemberInfo
import net.mamoe.mirai.utils.MiraiLogger
import net.mamoe.mirai.utils.context
import net.mamoe.mirai.utils.read
import net.mamoe.mirai.utils.structureToString
import kotlin.math.max


/**
Expand Down Expand Up @@ -197,19 +200,26 @@ internal class GroupOrMemberListNoticeProcessor(
// Structmsg.StructMsg
///////////////////////////////////////////////////////////////////////////

override suspend fun NoticePipelineContext.processImpl(data: Structmsg.StructMsg) = data.msg.context {
if (this == null) return
override suspend fun NoticePipelineContext.processImpl(data: Structmsg.StructMsg) {
val systemMsg = data.msg ?: return
if (attributes[NewContact.SYSTEM_MSG_TYPE] != 1) return

if (data.msgTime <= bot.syncController.latestMsgNewGroupTime) return
if (!bot.syncController.syncNewGroup(data.msgSeq, data.msgTime)) return // duplicate

markAsConsumed()
when (subType) {
var consumed = true

when (systemMsg.subType) {
0 -> {
if (groupMsgType == 8) {
if (systemMsg.groupMsgType == 8) {
// #1388: 使用手机TIM邀请入群,我为管理员,成功邀请 bot 入群

// 能正常解析 BotInvitedJoinGroupRequestEvent 和 BotJoinGroupEvent.Active, 因此忽略该通知
return
} else {
throw contextualBugReportException(
"解析 NewContact.SystemMsgNewGroup, subType=5, groupMsgType=$groupMsgType",
"解析 NewContact.SystemMsgNewGroup, subType=5, groupMsgType=${systemMsg.groupMsgType}",
data.structureToString(),
null,
"并描述此时机器人是否被邀请加入群等其他",
Expand All @@ -218,26 +228,27 @@ internal class GroupOrMemberListNoticeProcessor(
}

// 处理被邀请入群 或 处理成员入群申请
1 -> when (groupMsgType) {
1 -> when (systemMsg.groupMsgType) {
1 -> {
// 成员申请入群
collected += MemberJoinRequestEvent(
bot, data.msgSeq, msgAdditional,
data.reqUin, groupCode, groupName, reqUinNick
bot, data.msgSeq, systemMsg.msgAdditional,
data.reqUin, systemMsg.groupCode, systemMsg.groupName, systemMsg.reqUinNick
)
}
2 -> {
// Bot 被邀请入群
collected += BotInvitedJoinGroupRequestEvent(
bot, data.msgSeq, actionUin,
groupCode, groupName, actionUinNick
bot, data.msgSeq, systemMsg.actionUin,
systemMsg.groupCode, systemMsg.groupName, systemMsg.actionUinNick
)
}
22 -> {
// 成员邀请入群
collected += MemberJoinRequestEvent(
bot, data.msgSeq, msgAdditional,
data.reqUin, groupCode, groupName, reqUinNick, actionUin
bot, data.msgSeq, systemMsg.msgAdditional,
data.reqUin, systemMsg.groupCode, systemMsg.groupName,
systemMsg.reqUinNick, systemMsg.actionUin
)
}
else -> throw contextualBugReportException(
Expand All @@ -256,8 +267,8 @@ internal class GroupOrMemberListNoticeProcessor(
3 -> { // 已被请他管理员处理
}
5 -> {
val group = bot.getGroup(groupCode) ?: return
when (groupMsgType) {
val group = bot.getGroup(systemMsg.groupCode) ?: return
when (systemMsg.groupMsgType) {
3 -> {
// https://github.com/mamoe/mirai/issues/651
// msgDescribe=将你设置为管理员
Expand All @@ -268,7 +279,7 @@ internal class GroupOrMemberListNoticeProcessor(
// 但无法获取是哪个成员.
}
7 -> { // 机器人被踢
val operator = group[actionUin] ?: return
val operator = group[systemMsg.actionUin] ?: return
collected += BotLeaveEvent.Kick(operator)
}
6 -> {
Expand All @@ -284,15 +295,23 @@ internal class GroupOrMemberListNoticeProcessor(
}
else -> {
throw contextualBugReportException(
"解析 NewContact.SystemMsgNewGroup, subType=5, groupMsgType=$groupMsgType",
"解析 NewContact.SystemMsgNewGroup, subType=5, groupMsgType=${systemMsg.groupMsgType}",
this.structureToString(),
null,
"并描述此时机器人是否被踢出群等",
)
}
}
}
else -> markNotConsumed()
else -> {
consumed = false
markNotConsumed()
}
}

if (consumed) {
val latestTime = bot.syncController.latestMsgNewGroupTime
bot.syncController.latestMsgNewGroupTime = max(latestTime, data.msgTime)
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,13 @@ import net.mamoe.mirai.internal.contact.toMiraiFriendInfo
import net.mamoe.mirai.internal.network.components.MixedNoticeProcessor
import net.mamoe.mirai.internal.network.components.NoticePipelineContext
import net.mamoe.mirai.internal.network.components.NoticePipelineContext.Companion.msgInfo
import net.mamoe.mirai.internal.network.components.SyncController.Companion.syncController
import net.mamoe.mirai.internal.network.notice.NewContactSupport
import net.mamoe.mirai.internal.network.notice.group.get
import net.mamoe.mirai.internal.network.protocol.data.jce.MsgType0x210
import net.mamoe.mirai.internal.network.protocol.data.proto.FrdSysMsg
import net.mamoe.mirai.internal.network.protocol.data.proto.MsgComm
import net.mamoe.mirai.internal.network.protocol.data.proto.Structmsg
import net.mamoe.mirai.internal.network.protocol.data.proto.Submsgtype0x115.SubMsgType0x115
import net.mamoe.mirai.internal.network.protocol.data.proto.Submsgtype0x122
import net.mamoe.mirai.internal.network.protocol.data.proto.Submsgtype0x27.SubMsgType0x27.*
Expand All @@ -36,10 +38,12 @@ import net.mamoe.mirai.internal.network.protocol.packet.list.FriendList.GetFrien
import net.mamoe.mirai.internal.utils.io.ProtoBuf
import net.mamoe.mirai.internal.utils.io.serialization.loadAs
import net.mamoe.mirai.utils.*
import kotlin.math.max

/**
* All [FriendEvent] except [FriendMessageEvent]
* All [FriendEvent] except [FriendMessageEvent], plus [NewFriendRequestEvent]
*
* @see NewFriendRequestEvent
* @see FriendInputStatusChangedEvent
* @see FriendAddEvent
* @see StrangerRelationChangeEvent.Friended
Expand Down Expand Up @@ -136,6 +140,27 @@ internal class FriendNoticeProcessor(
}
}

override suspend fun NoticePipelineContext.processImpl(data: Structmsg.StructMsg) {
val systemMsg = data.msg ?: return
if (attributes[NewContact.SYSTEM_MSG_TYPE] != 0) return
markAsConsumed()

if (data.msgTime <= bot.syncController.latestMsgNewFriendTime) return
if (!bot.syncController.syncNewFriend(data.msgSeq, data.msgTime)) return // duplicate

collected += NewFriendRequestEvent(
bot,
data.msgSeq,
systemMsg.msgAdditional,
data.reqUin,
systemMsg.groupCode,
systemMsg.reqUinNick,
)

val latestTime = bot.syncController.latestMsgNewFriendTime
bot.syncController.latestMsgNewFriendTime = max(latestTime, data.msgTime)
}


@Serializable
private class Wording(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,7 @@ internal class Structmsg : ProtoBuf {
@ProtoNumber(8) @JvmField val isGetFrdRibbon: Boolean = true,
@ProtoNumber(9) @JvmField val isGetGrpRibbon: Boolean = true,
@ProtoNumber(10) @JvmField val friendMsgTypeFlag: Long = 0L,
@ProtoNumber(11) @JvmField val reqMsgType: Int = 0
) : ProtoBuf

@Serializable
Expand Down
Loading
Loading