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)
@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<TroopManagement.Kick.Response>().success.also {
MemberLeaveEvent.Kick(this@MemberImpl, null).broadcast()
}
).sendAndExpect()
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.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<Kick.Response>("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<GroupOperation.Response>("OidbSvc.0x89a_0") {