Minimize permission check procedure

This commit is contained in:
Him188 2020-04-01 17:48:22 +08:00
parent a150af2e3e
commit 6a09aff16d
2 changed files with 48 additions and 43 deletions

View File

@ -35,7 +35,7 @@ import kotlin.jvm.JvmSynthetic
@OptIn(LowLevelAPI::class) @OptIn(LowLevelAPI::class)
@Suppress("MemberVisibilityCanBePrivate") @Suppress("MemberVisibilityCanBePrivate")
internal class MemberImpl constructor( internal class MemberImpl constructor(
val qq: QQImpl, // 不要 WeakRef val qq: QQImpl, // 不要 WeakRef
group: GroupImpl, group: GroupImpl,
override val coroutineContext: CoroutineContext, override val coroutineContext: CoroutineContext,
@ -144,10 +144,7 @@ internal class MemberImpl constructor(
@JvmSynthetic @JvmSynthetic
override suspend fun mute(durationSeconds: Int) { override suspend fun mute(durationSeconds: Int) {
if (group.botPermission != MemberPermission.OWNER && (!group.botPermission.isOperator() || this.isOperator())) { checkBotPermissionHigherThanThis()
throw PermissionDeniedException()
}
bot.network.run { bot.network.run {
TroopManagement.Mute( TroopManagement.Mute(
client = bot.client, client = bot.client,
@ -161,12 +158,18 @@ internal class MemberImpl constructor(
net.mamoe.mirai.event.events.MemberMuteEvent(this@MemberImpl, durationSeconds, null).broadcast() 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 @JvmSynthetic
override suspend fun unmute() { override suspend fun unmute() {
if (group.botPermission != MemberPermission.OWNER && (!group.botPermission.isOperator() || this.isOperator())) { checkBotPermissionHigherThanThis()
throw PermissionDeniedException()
}
bot.network.run { bot.network.run {
TroopManagement.Mute( TroopManagement.Mute(
client = bot.client, client = bot.client,
@ -182,18 +185,17 @@ internal class MemberImpl constructor(
@JvmSynthetic @JvmSynthetic
override suspend fun kick(message: String) { override suspend fun kick(message: String) {
if (group.botPermission != MemberPermission.OWNER && (!group.botPermission.isOperator() || this.isOperator())) { checkBotPermissionHigherThanThis()
throw PermissionDeniedException()
}
bot.network.run { bot.network.run {
TroopManagement.Kick( val response: TroopManagement.Kick.Response = TroopManagement.Kick(
client = bot.client, client = bot.client,
member = this@MemberImpl, member = this@MemberImpl,
message = message message = message
).sendAndExpect<TroopManagement.Kick.Response>().success.also { ).sendAndExpect()
MemberLeaveEvent.Kick(this@MemberImpl, null).broadcast()
} check(response.success) { "kick failed: $message" }
MemberLeaveEvent.Kick(this@MemberImpl, null).broadcast()
} }
} }

View File

@ -16,9 +16,9 @@ import kotlinx.io.core.toByteArray
import net.mamoe.mirai.LowLevelAPI import net.mamoe.mirai.LowLevelAPI
import net.mamoe.mirai.contact.Group import net.mamoe.mirai.contact.Group
import net.mamoe.mirai.contact.Member import net.mamoe.mirai.contact.Member
import net.mamoe.mirai.qqandroid.network.Packet
import net.mamoe.mirai.qqandroid.QQAndroidBot import net.mamoe.mirai.qqandroid.QQAndroidBot
import net.mamoe.mirai.qqandroid.io.serialization.* 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.QQAndroidClient
import net.mamoe.mirai.qqandroid.network.protocol.data.jce.ModifyGroupCardReq import net.mamoe.mirai.qqandroid.network.protocol.data.jce.ModifyGroupCardReq
import net.mamoe.mirai.qqandroid.network.protocol.data.jce.RequestPacket 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 { 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) return GroupInfoImpl(this)
} }
} }
@ -144,44 +147,44 @@ internal class TroopManagement {
internal object Kick : OutgoingPacketFactory<Kick.Response>("OidbSvc.0x8a0_0") { internal object Kick : OutgoingPacketFactory<Kick.Response>("OidbSvc.0x8a0_0") {
override suspend fun ByteReadPacket.decode(bot: QQAndroidBot): Response { 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( class Response(
val success: Boolean val success: Boolean
) : Packet { ) : Packet {
override fun toString(): String = "Response(Kick Member)" override fun toString(): String = "TroopManagement.Kick.Response($success)"
} }
operator fun invoke( operator fun invoke(
client: QQAndroidClient, client: QQAndroidClient,
member: Member, member: Member,
message: String message: String
): OutgoingPacket { ): OutgoingPacket = buildOutgoingUniPacket(client) {
return buildOutgoingUniPacket(client) { writeProtoBuf(
writeProtoBuf( OidbSso.OIDBSSOPkg.serializer(),
OidbSso.OIDBSSOPkg.serializer(), OidbSso.OIDBSSOPkg(
OidbSso.OIDBSSOPkg( command = 2208,
command = 2208, serviceType = 0,//或者1
serviceType = 0,//或者1 result = 0,
result = 0, bodybuffer = Oidb0x8a0.ReqBody(
bodybuffer = Oidb0x8a0.ReqBody( optUint64GroupCode = member.group.id,
optUint64GroupCode = member.group.id, msgKickList = listOf(
msgKickList = listOf( Oidb0x8a0.KickMemberInfo(
Oidb0x8a0.KickMemberInfo( optUint32Operate = 5,
optUint32Operate = 5, optUint64MemberUin = member.id,
optUint64MemberUin = member.id, optUint32Flag = 1//或者0
optUint32Flag = 1//或者0 )
) ),
), kickMsg = message.toByteArray()
kickMsg = message.toByteArray() ).toByteArray(Oidb0x8a0.ReqBody.serializer())
).toByteArray(Oidb0x8a0.ReqBody.serializer())
)
) )
} )
} }
} }
internal object GroupOperation : OutgoingPacketFactory<GroupOperation.Response>("OidbSvc.0x89a_0") { internal object GroupOperation : OutgoingPacketFactory<GroupOperation.Response>("OidbSvc.0x89a_0") {