Support delete friend (#776)

* Support delete friend

* Improvement Member delete

* Add @JvmBlockingBridge

* Revert changes in GetFriendListReq

* Fix build error

* Apply suggestions, check if friend still exist before executing

Co-authored-by: Him188 <Him188@mamoe.net>

* Just let delete function existed in Friend

* Delete missed delete function

* Revert kick function return value to unit

* Let delete function throwing exception instead of returning boolean

* Update doc

* Revert missed kick function change

Co-authored-by: Him188 <Him188@mamoe.net>
This commit is contained in:
sandtechnology 2020-12-28 00:36:34 +08:00 committed by GitHub
parent 2b1fe9f27a
commit ca5835e058
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 83 additions and 5 deletions

View File

@ -14,10 +14,7 @@ package net.mamoe.mirai.contact
import kotlinx.coroutines.CoroutineScope
import net.mamoe.kjbb.JvmBlockingBridge
import net.mamoe.mirai.Bot
import net.mamoe.mirai.event.events.EventCancelledException
import net.mamoe.mirai.event.events.FriendMessageEvent
import net.mamoe.mirai.event.events.FriendMessagePostSendEvent
import net.mamoe.mirai.event.events.FriendMessagePreSendEvent
import net.mamoe.mirai.event.events.*
import net.mamoe.mirai.message.MessageReceipt
import net.mamoe.mirai.message.action.FriendNudge
import net.mamoe.mirai.message.action.Nudge
@ -69,6 +66,14 @@ public interface Friend : User, CoroutineScope {
@JvmBlockingBridge
public override suspend fun sendMessage(message: Message): MessageReceipt<Friend>
/**
* 删除并屏蔽该好友, 屏蔽后对方将无法发送临时会话消息
*
* @see FriendDeleteEvent 好友删除事件
*/
@JvmBlockingBridge
public suspend fun delete()
/**
* 发送纯文本消息
* @see sendMessage

View File

@ -88,6 +88,7 @@ public interface NormalMember : Member {
*
* @see MemberLeaveEvent.Kick 成员被踢出事件.
* @throws PermissionDeniedException 无权限修改时
*
*/
@JvmBlockingBridge
public suspend fun kick(message: String)

View File

@ -25,6 +25,7 @@ import net.mamoe.mirai.contact.Friend
import net.mamoe.mirai.data.FriendInfo
import net.mamoe.mirai.data.FriendInfoImpl
import net.mamoe.mirai.internal.QQAndroidBot
import net.mamoe.mirai.internal.network.protocol.packet.list.FriendList
import net.mamoe.mirai.message.MessageReceipt
import net.mamoe.mirai.message.data.Message
import net.mamoe.mirai.message.data.isContentNotEmpty
@ -65,6 +66,18 @@ internal class FriendImpl(
@Suppress("unused") // bug
val lastMessageSequence: AtomicInt = atomic(-1)
override suspend fun delete() {
check(bot.friends[this.id] != null) {
"Friend ${this.id} had already been deleted"
}
bot.network.run {
FriendList.DelFriend.invoke(bot.client, this@FriendImpl)
.sendAndExpect<FriendList.DelFriend.Response>().also {
check(it.isSuccess) { "delete friend failed: ${it.resultCode}" }
}
}
}
@Suppress("DuplicatedCode")
override suspend fun sendMessage(message: Message): MessageReceipt<Friend> {
require(message.isContentNotEmpty()) { "message is empty" }
@ -78,4 +91,4 @@ internal class FriendImpl(
}
override fun toString(): String = "Friend($id)"
}
}

View File

@ -13,6 +13,23 @@ import kotlinx.serialization.Serializable
import net.mamoe.mirai.internal.utils.io.JceStruct
import net.mamoe.mirai.internal.utils.io.serialization.tars.TarsId
@Serializable
internal class DelFriendReq(
@JvmField @TarsId(0) val uin: Long,
@JvmField @TarsId(1) val delUin: Long,
@JvmField @TarsId(2) val delType: Byte,
@JvmField @TarsId(3) val version: Int? = null
) : JceStruct
@Serializable
internal class DelFriendResp(
@JvmField @TarsId(0) val uin: Long,
@JvmField @TarsId(1) val delUin: Long,
@JvmField @TarsId(2) val result: Int,
@JvmField @TarsId(3) val errorCode: Short? = null
) : JceStruct
@Serializable
internal class ModifyGroupCardReq(
@TarsId(0) @JvmField val dwZero: Long,

View File

@ -129,6 +129,7 @@ internal object KnownPacketFactories {
MessageSvcPbSendMsg,
MessageSvcPbDeleteMsg,
FriendList.GetFriendGroupList,
FriendList.DelFriend,
FriendList.GetTroopListSimplify,
FriendList.GetTroopMemberList,
ImgStore.GroupPicUp,

View File

@ -10,7 +10,9 @@
package net.mamoe.mirai.internal.network.protocol.packet.list
import kotlinx.io.core.ByteReadPacket
import net.mamoe.mirai.contact.Friend
import net.mamoe.mirai.internal.QQAndroidBot
import net.mamoe.mirai.internal.contact.uin
import net.mamoe.mirai.internal.network.Packet
import net.mamoe.mirai.internal.network.QQAndroidClient
import net.mamoe.mirai.internal.network.protocol.data.jce.*
@ -122,6 +124,45 @@ internal class FriendList {
}
}
internal object DelFriend :
OutgoingPacketFactory<DelFriend.Response>("friendlist.delFriend") {
class Response(val isSuccess: Boolean, val resultCode: Int) : Packet {
override fun toString(): String = "FriendList.DelFriend.Response(isSuccess=$isSuccess)"
}
override suspend fun ByteReadPacket.decode(bot: QQAndroidBot): Response {
val res = this.readUniPacket(DelFriendResp.serializer())
return Response(res.result == 0, res.result)
}
operator fun invoke(
client: QQAndroidClient,
friend: Friend
): OutgoingPacket {
return buildOutgoingUniPacket(client, bodyType = 1, key = client.wLoginSigInfo.d2Key) {
writeJceStruct(
RequestPacket.serializer(),
RequestPacket(
funcName = "DelFriendReq",
servantName = "mqq.IMService.FriendListServiceServantObj",
version = 3,
sBuffer = jceRequestSBuffer(
"DF",
DelFriendReq.serializer(),
DelFriendReq(
uin = client.uin,
delType = 2,
delUin = friend.uin,
version = 1
)
)
)
)
}
}
}
internal object GetFriendGroupList :
OutgoingPacketFactory<GetFriendGroupList.Response>("friendlist.getFriendGroupList") {