diff --git a/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/contact/MemberImpl.kt b/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/contact/MemberImpl.kt index b4d203af6..38bb4791f 100644 --- a/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/contact/MemberImpl.kt +++ b/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/contact/MemberImpl.kt @@ -35,7 +35,7 @@ import kotlin.jvm.JvmSynthetic @OptIn(LowLevelAPI::class) @Suppress("MemberVisibilityCanBePrivate") -internal class MemberImpl constructor( +internal class MemberImpl constructor( val qq: QQImpl, // 不要 WeakRef group: GroupImpl, override val coroutineContext: CoroutineContext, @@ -144,10 +144,7 @@ internal class MemberImpl constructor( @JvmSynthetic override suspend fun mute(durationSeconds: Int) { - if (group.botPermission != MemberPermission.OWNER && (!group.botPermission.isOperator() || this.isOperator())) { - throw PermissionDeniedException() - } - + checkBotPermissionHigherThanThis() bot.network.run { TroopManagement.Mute( client = bot.client, @@ -161,12 +158,18 @@ internal class MemberImpl constructor( net.mamoe.mirai.event.events.MemberMuteEvent(this@MemberImpl, durationSeconds, null).broadcast() } + private fun checkBotPermissionHigherThanThis(){ + check(group.botPermission > this.permission) { + throw PermissionDeniedException( + "`kick` operation requires bot to have a higher permission than the target member, " + + "but bot's is ${group.botPermission}, target's is ${this.permission}" + ) + } + } + @JvmSynthetic override suspend fun unmute() { - if (group.botPermission != MemberPermission.OWNER && (!group.botPermission.isOperator() || this.isOperator())) { - throw PermissionDeniedException() - } - + checkBotPermissionHigherThanThis() bot.network.run { TroopManagement.Mute( client = bot.client, @@ -182,18 +185,17 @@ internal class MemberImpl constructor( @JvmSynthetic override suspend fun kick(message: String) { - if (group.botPermission != MemberPermission.OWNER && (!group.botPermission.isOperator() || this.isOperator())) { - throw PermissionDeniedException() - } - + checkBotPermissionHigherThanThis() bot.network.run { - TroopManagement.Kick( + val response: TroopManagement.Kick.Response = TroopManagement.Kick( client = bot.client, member = this@MemberImpl, message = message - ).sendAndExpect().success.also { - MemberLeaveEvent.Kick(this@MemberImpl, null).broadcast() - } + ).sendAndExpect() + + check(response.success) { "kick failed: $message" } + + MemberLeaveEvent.Kick(this@MemberImpl, null).broadcast() } } diff --git a/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/packet/chat/TroopManagement.kt b/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/packet/chat/TroopManagement.kt index 8f7447e0f..b6de49a8e 100644 --- a/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/packet/chat/TroopManagement.kt +++ b/mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/packet/chat/TroopManagement.kt @@ -16,9 +16,9 @@ import kotlinx.io.core.toByteArray import net.mamoe.mirai.LowLevelAPI import net.mamoe.mirai.contact.Group import net.mamoe.mirai.contact.Member -import net.mamoe.mirai.qqandroid.network.Packet import net.mamoe.mirai.qqandroid.QQAndroidBot import net.mamoe.mirai.qqandroid.io.serialization.* +import net.mamoe.mirai.qqandroid.network.Packet import net.mamoe.mirai.qqandroid.network.QQAndroidClient import net.mamoe.mirai.qqandroid.network.protocol.data.jce.ModifyGroupCardReq import net.mamoe.mirai.qqandroid.network.protocol.data.jce.RequestPacket @@ -136,7 +136,10 @@ internal class TroopManagement { } override suspend fun ByteReadPacket.decode(bot: QQAndroidBot): GroupInfoImpl { - with(this.readBytes().loadAs(OidbSso.OIDBSSOPkg.serializer()).bodybuffer.loadAs(Oidb0x88d.RspBody.serializer()).stzrspgroupinfo!![0].stgroupinfo!!) { + with( + this.readBytes() + .loadAs(OidbSso.OIDBSSOPkg.serializer()).bodybuffer.loadAs(Oidb0x88d.RspBody.serializer()).stzrspgroupinfo!![0].stgroupinfo!! + ) { return GroupInfoImpl(this) } } @@ -144,44 +147,44 @@ internal class TroopManagement { internal object Kick : OutgoingPacketFactory("OidbSvc.0x8a0_0") { override suspend fun ByteReadPacket.decode(bot: QQAndroidBot): Response { - return Response(this.readBytes().loadAs(OidbSso.OIDBSSOPkg.serializer()).bodybuffer.loadAs(Oidb0x8a0.RspBody.serializer()).msgKickResult!![0].optUint32Result == 1) + return Response( + this.readBytes() + .loadAs(OidbSso.OIDBSSOPkg.serializer()).bodybuffer.loadAs(Oidb0x8a0.RspBody.serializer()).msgKickResult!![0].optUint32Result == 1 + ) } class Response( val success: Boolean ) : Packet { - override fun toString(): String = "Response(Kick Member)" + override fun toString(): String = "TroopManagement.Kick.Response($success)" } operator fun invoke( client: QQAndroidClient, member: Member, message: String - ): OutgoingPacket { - return buildOutgoingUniPacket(client) { - writeProtoBuf( - OidbSso.OIDBSSOPkg.serializer(), - OidbSso.OIDBSSOPkg( - command = 2208, - serviceType = 0,//或者1 - result = 0, - bodybuffer = Oidb0x8a0.ReqBody( - optUint64GroupCode = member.group.id, - msgKickList = listOf( - Oidb0x8a0.KickMemberInfo( - optUint32Operate = 5, - optUint64MemberUin = member.id, - optUint32Flag = 1//或者0 - ) - ), - kickMsg = message.toByteArray() - ).toByteArray(Oidb0x8a0.ReqBody.serializer()) - ) + ): OutgoingPacket = buildOutgoingUniPacket(client) { + writeProtoBuf( + OidbSso.OIDBSSOPkg.serializer(), + OidbSso.OIDBSSOPkg( + command = 2208, + serviceType = 0,//或者1 + result = 0, + bodybuffer = Oidb0x8a0.ReqBody( + optUint64GroupCode = member.group.id, + msgKickList = listOf( + Oidb0x8a0.KickMemberInfo( + optUint32Operate = 5, + optUint64MemberUin = member.id, + optUint32Flag = 1//或者0 + ) + ), + kickMsg = message.toByteArray() + ).toByteArray(Oidb0x8a0.ReqBody.serializer()) ) - } + ) } - } internal object GroupOperation : OutgoingPacketFactory("OidbSvc.0x89a_0") {