添加管理员修改功能 (#1178)

* add modifyAdmin

* 修复赋予相同权限时不会抛错并且仍然广播事件的 bug

* fix test failed

* fix test failed AGAIN

* fix myself

* 是这样吗

* i am so sorry :(

* fix fixed bug
This commit is contained in:
Hoshino Tented 2021-04-16 08:33:07 +08:00 committed by GitHub
parent 3adba24163
commit 1bf1e3686f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 100 additions and 3 deletions

View File

@ -484,6 +484,9 @@ public abstract interface class net/mamoe/mirai/contact/NormalMember : net/mamoe
public synthetic fun kick (Ljava/lang/String;)Lkotlin/Unit;
public fun kick (Ljava/lang/String;)V
public abstract fun kick (Ljava/lang/String;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
public synthetic fun modifyAdmin (Z)Lkotlin/Unit;
public fun modifyAdmin (Z)V
public abstract fun modifyAdmin (ZLkotlin/coroutines/Continuation;)Ljava/lang/Object;
public fun nudge ()Lnet/mamoe/mirai/message/action/MemberNudge;
public synthetic fun nudge ()Lnet/mamoe/mirai/message/action/Nudge;
public synthetic fun nudge ()Lnet/mamoe/mirai/message/action/UserNudge;

View File

@ -484,6 +484,9 @@ public abstract interface class net/mamoe/mirai/contact/NormalMember : net/mamoe
public synthetic fun kick (Ljava/lang/String;)Lkotlin/Unit;
public fun kick (Ljava/lang/String;)V
public abstract fun kick (Ljava/lang/String;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
public synthetic fun modifyAdmin (Z)Lkotlin/Unit;
public fun modifyAdmin (Z)V
public abstract fun modifyAdmin (ZLkotlin/coroutines/Continuation;)Ljava/lang/Object;
public fun nudge ()Lnet/mamoe/mirai/message/action/MemberNudge;
public synthetic fun nudge ()Lnet/mamoe/mirai/message/action/Nudge;
public synthetic fun nudge ()Lnet/mamoe/mirai/message/action/UserNudge;

View File

@ -108,6 +108,18 @@ public interface NormalMember : Member {
*/
public suspend fun kick(message: String)
/**
* 给予或移除群成员的管理员权限
*
* 此操作需要 Bot 为群主 [MemberPermission.OWNER]
*
* @param operation true 为给予
*
* @see MemberPermissionChangeEvent 群成员权限变更事件
* @throws PermissionDeniedException 无权限修改时抛出
*/
public suspend fun modifyAdmin(operation: Boolean)
/**
* 向群成员发送消息.
* 若群成员同时是好友, 则会发送好友消息. 否则发送临时会话消息.

View File

@ -17,7 +17,6 @@ import kotlinx.coroutines.*
import net.mamoe.mirai.LowLevelApi
import net.mamoe.mirai.contact.*
import net.mamoe.mirai.data.MemberInfo
import net.mamoe.mirai.event.broadcast
import net.mamoe.mirai.event.events.*
import net.mamoe.mirai.internal.message.OnlineMessageSourceToTempImpl
import net.mamoe.mirai.internal.network.protocol.packet.chat.TroopManagement
@ -46,7 +45,7 @@ internal class NormalMemberImpl constructor(
override fun toString(): String = "NormalMember($id)"
private val handler by lazy { GroupTempSendMessageHandler(this) }
private val handler: GroupTempSendMessageHandler by lazy { GroupTempSendMessageHandler(this) }
@Suppress("DuplicatedCode")
override suspend fun sendMessage(message: Message): MessageReceipt<NormalMember> {
@ -183,6 +182,43 @@ internal class NormalMemberImpl constructor(
MemberLeaveEvent.Kick(this@NormalMemberImpl, null).broadcastWithBot(bot)
}
}
override suspend fun modifyAdmin(operation: Boolean) {
checkBotPermissionHighest("modifyAdmin")
val origin = this@NormalMemberImpl.permission
val new = if (operation) {
MemberPermission.ADMINISTRATOR
} else {
MemberPermission.MEMBER
}
if (origin == new) return
bot.network.run {
val resp: TroopManagement.ModifyAdmin.Response = TroopManagement.ModifyAdmin(
client = bot.client,
member = this@NormalMemberImpl,
operation = operation
).sendAndExpect()
check(resp.success) {
"Failed to modify admin, cause: ${resp.msg}"
}
this@NormalMemberImpl.permission = new
MemberPermissionChangeEvent(this@NormalMemberImpl, origin, new).broadcastWithBot(bot)
}
}
}
internal fun Member.checkBotPermissionHighest(operationName: String) {
check(group.botPermission == MemberPermission.OWNER) {
throw PermissionDeniedException(
"`$operationName` operation requires the OWNER permission, while bot has ${group.botPermission}"
)
}
}
internal fun Member.checkBotPermissionHigherThanThis(operationName: String) {

View File

@ -145,6 +145,7 @@ internal object KnownPacketFactories {
TroopManagement.Mute,
TroopManagement.GroupOperation,
TroopManagement.GetTroopConfig,
TroopManagement.ModifyAdmin,
// TroopManagement.GetGroupInfo,
TroopManagement.EditGroupNametag,
TroopManagement.Kick,

View File

@ -30,7 +30,6 @@ import net.mamoe.mirai.internal.utils.io.serialization.*
import net.mamoe.mirai.utils.daysToSeconds
internal class TroopManagement {
internal object Mute : OutgoingPacketFactory<Mute.Response>("OidbSvc.0x570_8") {
override suspend fun ByteReadPacket.decode(bot: QQAndroidBot): Response {
//屁用没有
@ -377,4 +376,47 @@ internal class TroopManagement {
}
}
internal object ModifyAdmin : OutgoingPacketFactory<ModifyAdmin.Response>("OidbSvc.0x55c_1") {
data class Response(val success: Boolean, val msg: String) : Packet {
override fun toString(): String {
return "TroopManagement.ModifyAdmin.Response(success=${success}, msg=${msg})"
}
}
/**
* @param operation: true is add
*/
operator fun invoke(
client: QQAndroidClient,
member: Member,
operation: Boolean
): OutgoingPacket {
return buildOutgoingUniPacket(client) {
writeProtoBuf(
OidbSso.OIDBSSOPkg.serializer(),
OidbSso.OIDBSSOPkg(
command = 1372,
serviceType = 1,
bodybuffer = buildPacket {
writeInt(member.group.id.toInt())
writeInt(member.id.toInt())
writeByte(if (operation) 1 else 0)
}.readBytes()
)
)
}
}
override suspend fun ByteReadPacket.decode(bot: QQAndroidBot): ModifyAdmin.Response {
val stupidPacket = readProtoBuf(OidbSso.OIDBSSOPkg.serializer())
return stupidPacket.run {
ModifyAdmin.Response(
this.result == 0,
this.errorMsg
)
}
}
}
}