1
0
mirror of https://github.com/mamoe/mirai.git synced 2025-04-24 20:43:33 +08:00
This commit is contained in:
cssxsh 2024-09-23 19:52:05 +08:00 committed by GitHub
commit 649457b727
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
17 changed files with 1094 additions and 10 deletions
mirai-core-api
compatibility-validation
android/api
jvm/api
src/commonMain/kotlin
mirai-core-mock/src
mirai-core/src/commonMain/kotlin

View File

@ -488,6 +488,7 @@ public abstract interface class net/mamoe/mirai/contact/Group : kotlinx/coroutin
public fun getOrFail (J)Lnet/mamoe/mirai/contact/NormalMember;
public abstract fun getOwner ()Lnet/mamoe/mirai/contact/NormalMember;
public abstract fun getSettings ()Lnet/mamoe/mirai/contact/GroupSettings;
public abstract fun getTodo ()Lnet/mamoe/mirai/contact/todo/GroupTodo;
public fun quit ()Z
public abstract fun quit (Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
public fun sendMessage (Ljava/lang/String;)Lnet/mamoe/mirai/message/MessageReceipt;
@ -1214,6 +1215,47 @@ public abstract interface class net/mamoe/mirai/contact/roaming/RoamingSupported
public abstract fun getRoamingMessages ()Lnet/mamoe/mirai/contact/roaming/RoamingMessages;
}
public abstract interface class net/mamoe/mirai/contact/todo/GroupTodo {
public fun close (Lnet/mamoe/mirai/contact/todo/GroupTodoRecord;)V
public abstract fun close (Lnet/mamoe/mirai/contact/todo/GroupTodoRecord;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
public fun close (Lnet/mamoe/mirai/message/data/MessageSource;)V
public abstract fun close (Lnet/mamoe/mirai/message/data/MessageSource;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
public fun complete (Lnet/mamoe/mirai/contact/todo/GroupTodoRecord;)V
public abstract fun complete (Lnet/mamoe/mirai/contact/todo/GroupTodoRecord;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
public fun complete (Lnet/mamoe/mirai/message/data/MessageSource;)V
public abstract fun complete (Lnet/mamoe/mirai/message/data/MessageSource;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
public fun current ()Lnet/mamoe/mirai/contact/todo/GroupTodoRecord;
public abstract fun current (Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
public fun recall (Lnet/mamoe/mirai/contact/todo/GroupTodoRecord;)V
public abstract fun recall (Lnet/mamoe/mirai/contact/todo/GroupTodoRecord;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
public fun recall (Lnet/mamoe/mirai/message/data/MessageSource;)V
public abstract fun recall (Lnet/mamoe/mirai/message/data/MessageSource;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
public fun set (Lnet/mamoe/mirai/message/data/MessageSource;)Lnet/mamoe/mirai/contact/todo/GroupTodoRecord;
public abstract fun set (Lnet/mamoe/mirai/message/data/MessageSource;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
public fun status ()Lnet/mamoe/mirai/contact/todo/GroupTodoStatus;
public abstract fun status (Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
}
public final class net/mamoe/mirai/contact/todo/GroupTodoRecord {
public final fun getGroup ()Lnet/mamoe/mirai/contact/Group;
public final fun getMsgRandom ()J
public final fun getMsgSeq ()J
public final fun getOperator ()Lnet/mamoe/mirai/contact/NormalMember;
public final fun getOperatorId ()J
public final fun getOperatorNick ()Ljava/lang/String;
public final fun getOperatorTime ()I
public final fun getTitle ()Ljava/lang/String;
public fun toString ()Ljava/lang/String;
}
public final class net/mamoe/mirai/contact/todo/GroupTodoStatus : java/lang/Enum {
public static final field CLOSED Lnet/mamoe/mirai/contact/todo/GroupTodoStatus;
public static final field COMPLETED Lnet/mamoe/mirai/contact/todo/GroupTodoStatus;
public static final field NONE Lnet/mamoe/mirai/contact/todo/GroupTodoStatus;
public static fun valueOf (Ljava/lang/String;)Lnet/mamoe/mirai/contact/todo/GroupTodoStatus;
public static fun values ()[Lnet/mamoe/mirai/contact/todo/GroupTodoStatus;
}
public abstract interface class net/mamoe/mirai/data/FriendInfo : net/mamoe/mirai/data/UserInfo {
public abstract fun getFriendGroupId ()I
public abstract fun getNick ()Ljava/lang/String;
@ -2581,6 +2623,18 @@ public final class net/mamoe/mirai/event/events/MemberCardChangeEvent : net/mamo
public fun toString ()Ljava/lang/String;
}
public final class net/mamoe/mirai/event/events/MemberCompleteTodoEvent : net/mamoe/mirai/event/AbstractEvent, net/mamoe/mirai/event/events/BotPassiveEvent, net/mamoe/mirai/event/events/GroupMemberEvent, net/mamoe/mirai/internal/network/Packet {
public fun <init> (Lnet/mamoe/mirai/contact/NormalMember;)V
public synthetic fun getMember ()Lnet/mamoe/mirai/contact/Member;
public fun getMember ()Lnet/mamoe/mirai/contact/NormalMember;
public fun toString ()Ljava/lang/String;
}
public abstract class net/mamoe/mirai/event/events/MemberHonorChangeEvent : net/mamoe/mirai/event/AbstractEvent, net/mamoe/mirai/event/events/BotPassiveEvent, net/mamoe/mirai/event/events/GroupMemberEvent, net/mamoe/mirai/internal/network/Packet {
public abstract fun getHonorType ()I
public abstract fun getMember ()Lnet/mamoe/mirai/contact/NormalMember;
}
public final class net/mamoe/mirai/event/events/MemberHonorChangeEvent$Achieve : net/mamoe/mirai/event/events/MemberHonorChangeEvent {
public synthetic fun <init> (Lnet/mamoe/mirai/contact/NormalMember;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
public final fun component1 ()Lnet/mamoe/mirai/contact/NormalMember;
@ -2725,6 +2779,14 @@ public final class net/mamoe/mirai/event/events/MemberLeaveEvent$Quit : net/mamo
public fun toString ()Ljava/lang/String;
}
public final class net/mamoe/mirai/event/events/MemberLuckyWordEvent : net/mamoe/mirai/event/AbstractEvent, net/mamoe/mirai/event/events/BotPassiveEvent, net/mamoe/mirai/event/events/GroupMemberEvent, net/mamoe/mirai/internal/network/Packet {
public fun <init> (Lnet/mamoe/mirai/contact/NormalMember;Ljava/util/List;)V
public final fun getImages ()Ljava/util/List;
public synthetic fun getMember ()Lnet/mamoe/mirai/contact/Member;
public fun getMember ()Lnet/mamoe/mirai/contact/NormalMember;
public fun toString ()Ljava/lang/String;
}
public final class net/mamoe/mirai/event/events/MemberMuteEvent : net/mamoe/mirai/event/AbstractEvent, net/mamoe/mirai/event/events/GroupMemberEvent, net/mamoe/mirai/event/events/GroupMemberInfoChangeEvent, net/mamoe/mirai/event/events/GroupOperableEvent, net/mamoe/mirai/internal/network/Packet {
public final fun component1 ()Lnet/mamoe/mirai/contact/Member;
public final fun component2 ()I
@ -2754,6 +2816,20 @@ public final class net/mamoe/mirai/event/events/MemberPermissionChangeEvent : ne
public fun toString ()Ljava/lang/String;
}
public final class net/mamoe/mirai/event/events/MemberRecallTodoEvent : net/mamoe/mirai/event/AbstractEvent, net/mamoe/mirai/event/events/BotPassiveEvent, net/mamoe/mirai/event/events/GroupMemberEvent, net/mamoe/mirai/internal/network/Packet {
public fun <init> (Lnet/mamoe/mirai/contact/NormalMember;)V
public synthetic fun getMember ()Lnet/mamoe/mirai/contact/Member;
public fun getMember ()Lnet/mamoe/mirai/contact/NormalMember;
public fun toString ()Ljava/lang/String;
}
public final class net/mamoe/mirai/event/events/MemberSetTodoEvent : net/mamoe/mirai/event/AbstractEvent, net/mamoe/mirai/event/events/BotPassiveEvent, net/mamoe/mirai/event/events/GroupMemberEvent, net/mamoe/mirai/internal/network/Packet {
public fun <init> (Lnet/mamoe/mirai/contact/NormalMember;)V
public synthetic fun getMember ()Lnet/mamoe/mirai/contact/Member;
public fun getMember ()Lnet/mamoe/mirai/contact/NormalMember;
public fun toString ()Ljava/lang/String;
}
public final class net/mamoe/mirai/event/events/MemberSpecialTitleChangeEvent : net/mamoe/mirai/event/AbstractEvent, net/mamoe/mirai/event/events/GroupMemberEvent, net/mamoe/mirai/event/events/GroupMemberInfoChangeEvent, net/mamoe/mirai/event/events/GroupOperableEvent, net/mamoe/mirai/internal/network/Packet {
public final fun component1 ()Ljava/lang/String;
public final fun component2 ()Ljava/lang/String;
@ -2772,6 +2848,15 @@ public final class net/mamoe/mirai/event/events/MemberSpecialTitleChangeEvent :
public fun toString ()Ljava/lang/String;
}
public final class net/mamoe/mirai/event/events/MemberTemperatureTitleChangeEvent : net/mamoe/mirai/event/AbstractEvent, net/mamoe/mirai/event/events/BotPassiveEvent, net/mamoe/mirai/event/events/GroupMemberEvent, net/mamoe/mirai/internal/network/Packet {
public fun <init> (Lnet/mamoe/mirai/contact/NormalMember;ILjava/lang/String;)V
public synthetic fun getMember ()Lnet/mamoe/mirai/contact/Member;
public fun getMember ()Lnet/mamoe/mirai/contact/NormalMember;
public final fun getTemperature ()I
public final fun getTitle ()Ljava/lang/String;
public fun toString ()Ljava/lang/String;
}
public final class net/mamoe/mirai/event/events/MemberUnmuteEvent : net/mamoe/mirai/event/AbstractEvent, net/mamoe/mirai/event/events/GroupMemberEvent, net/mamoe/mirai/event/events/GroupMemberInfoChangeEvent, net/mamoe/mirai/event/events/GroupOperableEvent, net/mamoe/mirai/internal/network/Packet {
public final fun component1 ()Lnet/mamoe/mirai/contact/Member;
public final fun component2 ()Lnet/mamoe/mirai/contact/Member;

View File

@ -488,6 +488,7 @@ public abstract interface class net/mamoe/mirai/contact/Group : kotlinx/coroutin
public fun getOrFail (J)Lnet/mamoe/mirai/contact/NormalMember;
public abstract fun getOwner ()Lnet/mamoe/mirai/contact/NormalMember;
public abstract fun getSettings ()Lnet/mamoe/mirai/contact/GroupSettings;
public abstract fun getTodo ()Lnet/mamoe/mirai/contact/todo/GroupTodo;
public fun quit ()Z
public abstract fun quit (Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
public fun sendMessage (Ljava/lang/String;)Lnet/mamoe/mirai/message/MessageReceipt;
@ -1214,6 +1215,47 @@ public abstract interface class net/mamoe/mirai/contact/roaming/RoamingSupported
public abstract fun getRoamingMessages ()Lnet/mamoe/mirai/contact/roaming/RoamingMessages;
}
public abstract interface class net/mamoe/mirai/contact/todo/GroupTodo {
public fun close (Lnet/mamoe/mirai/contact/todo/GroupTodoRecord;)V
public abstract fun close (Lnet/mamoe/mirai/contact/todo/GroupTodoRecord;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
public fun close (Lnet/mamoe/mirai/message/data/MessageSource;)V
public abstract fun close (Lnet/mamoe/mirai/message/data/MessageSource;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
public fun complete (Lnet/mamoe/mirai/contact/todo/GroupTodoRecord;)V
public abstract fun complete (Lnet/mamoe/mirai/contact/todo/GroupTodoRecord;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
public fun complete (Lnet/mamoe/mirai/message/data/MessageSource;)V
public abstract fun complete (Lnet/mamoe/mirai/message/data/MessageSource;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
public fun current ()Lnet/mamoe/mirai/contact/todo/GroupTodoRecord;
public abstract fun current (Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
public fun recall (Lnet/mamoe/mirai/contact/todo/GroupTodoRecord;)V
public abstract fun recall (Lnet/mamoe/mirai/contact/todo/GroupTodoRecord;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
public fun recall (Lnet/mamoe/mirai/message/data/MessageSource;)V
public abstract fun recall (Lnet/mamoe/mirai/message/data/MessageSource;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
public fun set (Lnet/mamoe/mirai/message/data/MessageSource;)Lnet/mamoe/mirai/contact/todo/GroupTodoRecord;
public abstract fun set (Lnet/mamoe/mirai/message/data/MessageSource;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
public fun status ()Lnet/mamoe/mirai/contact/todo/GroupTodoStatus;
public abstract fun status (Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
}
public final class net/mamoe/mirai/contact/todo/GroupTodoRecord {
public final fun getGroup ()Lnet/mamoe/mirai/contact/Group;
public final fun getMsgRandom ()J
public final fun getMsgSeq ()J
public final fun getOperator ()Lnet/mamoe/mirai/contact/NormalMember;
public final fun getOperatorId ()J
public final fun getOperatorNick ()Ljava/lang/String;
public final fun getOperatorTime ()I
public final fun getTitle ()Ljava/lang/String;
public fun toString ()Ljava/lang/String;
}
public final class net/mamoe/mirai/contact/todo/GroupTodoStatus : java/lang/Enum {
public static final field CLOSED Lnet/mamoe/mirai/contact/todo/GroupTodoStatus;
public static final field COMPLETED Lnet/mamoe/mirai/contact/todo/GroupTodoStatus;
public static final field NONE Lnet/mamoe/mirai/contact/todo/GroupTodoStatus;
public static fun valueOf (Ljava/lang/String;)Lnet/mamoe/mirai/contact/todo/GroupTodoStatus;
public static fun values ()[Lnet/mamoe/mirai/contact/todo/GroupTodoStatus;
}
public abstract interface class net/mamoe/mirai/data/FriendInfo : net/mamoe/mirai/data/UserInfo {
public abstract fun getFriendGroupId ()I
public abstract fun getNick ()Ljava/lang/String;
@ -2581,6 +2623,18 @@ public final class net/mamoe/mirai/event/events/MemberCardChangeEvent : net/mamo
public fun toString ()Ljava/lang/String;
}
public final class net/mamoe/mirai/event/events/MemberCompleteTodoEvent : net/mamoe/mirai/event/AbstractEvent, net/mamoe/mirai/event/events/BotPassiveEvent, net/mamoe/mirai/event/events/GroupMemberEvent, net/mamoe/mirai/internal/network/Packet {
public fun <init> (Lnet/mamoe/mirai/contact/NormalMember;)V
public synthetic fun getMember ()Lnet/mamoe/mirai/contact/Member;
public fun getMember ()Lnet/mamoe/mirai/contact/NormalMember;
public fun toString ()Ljava/lang/String;
}
public abstract class net/mamoe/mirai/event/events/MemberHonorChangeEvent : net/mamoe/mirai/event/AbstractEvent, net/mamoe/mirai/event/events/BotPassiveEvent, net/mamoe/mirai/event/events/GroupMemberEvent, net/mamoe/mirai/internal/network/Packet {
public abstract fun getHonorType ()I
public abstract fun getMember ()Lnet/mamoe/mirai/contact/NormalMember;
}
public final class net/mamoe/mirai/event/events/MemberHonorChangeEvent$Achieve : net/mamoe/mirai/event/events/MemberHonorChangeEvent {
public synthetic fun <init> (Lnet/mamoe/mirai/contact/NormalMember;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
public final fun component1 ()Lnet/mamoe/mirai/contact/NormalMember;
@ -2725,6 +2779,14 @@ public final class net/mamoe/mirai/event/events/MemberLeaveEvent$Quit : net/mamo
public fun toString ()Ljava/lang/String;
}
public final class net/mamoe/mirai/event/events/MemberLuckyWordEvent : net/mamoe/mirai/event/AbstractEvent, net/mamoe/mirai/event/events/BotPassiveEvent, net/mamoe/mirai/event/events/GroupMemberEvent, net/mamoe/mirai/internal/network/Packet {
public fun <init> (Lnet/mamoe/mirai/contact/NormalMember;Ljava/util/List;)V
public final fun getImages ()Ljava/util/List;
public synthetic fun getMember ()Lnet/mamoe/mirai/contact/Member;
public fun getMember ()Lnet/mamoe/mirai/contact/NormalMember;
public fun toString ()Ljava/lang/String;
}
public final class net/mamoe/mirai/event/events/MemberMuteEvent : net/mamoe/mirai/event/AbstractEvent, net/mamoe/mirai/event/events/GroupMemberEvent, net/mamoe/mirai/event/events/GroupMemberInfoChangeEvent, net/mamoe/mirai/event/events/GroupOperableEvent, net/mamoe/mirai/internal/network/Packet {
public final fun component1 ()Lnet/mamoe/mirai/contact/Member;
public final fun component2 ()I
@ -2754,6 +2816,20 @@ public final class net/mamoe/mirai/event/events/MemberPermissionChangeEvent : ne
public fun toString ()Ljava/lang/String;
}
public final class net/mamoe/mirai/event/events/MemberRecallTodoEvent : net/mamoe/mirai/event/AbstractEvent, net/mamoe/mirai/event/events/BotPassiveEvent, net/mamoe/mirai/event/events/GroupMemberEvent, net/mamoe/mirai/internal/network/Packet {
public fun <init> (Lnet/mamoe/mirai/contact/NormalMember;)V
public synthetic fun getMember ()Lnet/mamoe/mirai/contact/Member;
public fun getMember ()Lnet/mamoe/mirai/contact/NormalMember;
public fun toString ()Ljava/lang/String;
}
public final class net/mamoe/mirai/event/events/MemberSetTodoEvent : net/mamoe/mirai/event/AbstractEvent, net/mamoe/mirai/event/events/BotPassiveEvent, net/mamoe/mirai/event/events/GroupMemberEvent, net/mamoe/mirai/internal/network/Packet {
public fun <init> (Lnet/mamoe/mirai/contact/NormalMember;)V
public synthetic fun getMember ()Lnet/mamoe/mirai/contact/Member;
public fun getMember ()Lnet/mamoe/mirai/contact/NormalMember;
public fun toString ()Ljava/lang/String;
}
public final class net/mamoe/mirai/event/events/MemberSpecialTitleChangeEvent : net/mamoe/mirai/event/AbstractEvent, net/mamoe/mirai/event/events/GroupMemberEvent, net/mamoe/mirai/event/events/GroupMemberInfoChangeEvent, net/mamoe/mirai/event/events/GroupOperableEvent, net/mamoe/mirai/internal/network/Packet {
public final fun component1 ()Ljava/lang/String;
public final fun component2 ()Ljava/lang/String;
@ -2772,6 +2848,15 @@ public final class net/mamoe/mirai/event/events/MemberSpecialTitleChangeEvent :
public fun toString ()Ljava/lang/String;
}
public final class net/mamoe/mirai/event/events/MemberTemperatureTitleChangeEvent : net/mamoe/mirai/event/AbstractEvent, net/mamoe/mirai/event/events/BotPassiveEvent, net/mamoe/mirai/event/events/GroupMemberEvent, net/mamoe/mirai/internal/network/Packet {
public fun <init> (Lnet/mamoe/mirai/contact/NormalMember;ILjava/lang/String;)V
public synthetic fun getMember ()Lnet/mamoe/mirai/contact/Member;
public fun getMember ()Lnet/mamoe/mirai/contact/NormalMember;
public final fun getTemperature ()I
public final fun getTitle ()Ljava/lang/String;
public fun toString ()Ljava/lang/String;
}
public final class net/mamoe/mirai/event/events/MemberUnmuteEvent : net/mamoe/mirai/event/AbstractEvent, net/mamoe/mirai/event/events/GroupMemberEvent, net/mamoe/mirai/event/events/GroupMemberInfoChangeEvent, net/mamoe/mirai/event/events/GroupOperableEvent, net/mamoe/mirai/internal/network/Packet {
public final fun component1 ()Lnet/mamoe/mirai/contact/Member;
public final fun component2 ()Lnet/mamoe/mirai/contact/Member;

View File

@ -20,6 +20,7 @@ import net.mamoe.mirai.contact.announcement.Announcements
import net.mamoe.mirai.contact.essence.Essences
import net.mamoe.mirai.contact.file.RemoteFiles
import net.mamoe.mirai.contact.roaming.RoamingSupported
import net.mamoe.mirai.contact.todo.GroupTodo
import net.mamoe.mirai.event.events.*
import net.mamoe.mirai.message.MessageReceipt
import net.mamoe.mirai.message.data.*
@ -237,6 +238,13 @@ public interface Group : Contact, CoroutineScope, FileSupported, AudioSupported,
*/
public val essences: Essences
/**
* 群待办相关功能接口
*
* @since 2.16
*/
public val todo: GroupTodo
public companion object {
/**
* 将一条消息设置为群精华消息, 需要管理员或群主权限.

View File

@ -0,0 +1,89 @@
/*
* Copyright 2019-2023 Mamoe Technologies and contributors.
*
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
* Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
*
* https://github.com/mamoe/mirai/blob/dev/LICENSE
*/
package net.mamoe.mirai.contact.todo
import me.him188.kotlin.jvm.blocking.bridge.JvmBlockingBridge
import net.mamoe.mirai.event.events.MemberCompleteTodoEvent
import net.mamoe.mirai.event.events.MemberRecallTodoEvent
import net.mamoe.mirai.event.events.MemberSetTodoEvent
import net.mamoe.mirai.message.data.MessageSource
import net.mamoe.mirai.contact.Group
import net.mamoe.mirai.utils.NotStableForInheritance
/**
* 表示一个群待办管理.
*
* ## 获取 [GroupTodo] 实例
*
* 只可以通过 [Group.todo] 获取一个群的精华消息管理, [GroupTodo] 实例.
*
* ### 获取当前群待办内容
*
* 通过 [current] 可以获得当前群待办内容
*
* ### 获取当前群待办状态
*
* 通过 [status] 可以获得当前群待办内容
*
* ### 操作群待办
*
* 通过 [set] 可以设置新的群待办
*
* 通过 [close] 可以关闭群待办
*
* 通过 [complete] 可以完成群待办
*
* 通过 [recall] 可以撤销群待办
*
* @since 2.16
*/
@NotStableForInheritance
@JvmBlockingBridge
public interface GroupTodo {
public suspend fun status(): GroupTodoStatus
public suspend fun current(): GroupTodoRecord?
/**
* @see MemberSetTodoEvent
*/
public suspend fun set(source: MessageSource): GroupTodoRecord
/**
* @see MemberRecallTodoEvent
*/
public suspend fun recall(source: MessageSource)
/**
* @see MemberRecallTodoEvent
*/
public suspend fun recall(record: GroupTodoRecord)
/**
* @see MemberCompleteTodoEvent
*/
public suspend fun complete(source: MessageSource)
/**
* @see MemberCompleteTodoEvent
*/
public suspend fun complete(record: GroupTodoRecord)
/**
* @see MemberSetTodoEvent
*/
public suspend fun close(source: MessageSource)
/**
* @see MemberSetTodoEvent
*/
public suspend fun close(record: GroupTodoRecord)
}

View File

@ -0,0 +1,29 @@
/*
* Copyright 2019-2023 Mamoe Technologies and contributors.
*
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
* Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
*
* https://github.com/mamoe/mirai/blob/dev/LICENSE
*/
package net.mamoe.mirai.contact.todo
import net.mamoe.mirai.contact.Group
import net.mamoe.mirai.contact.NormalMember
import net.mamoe.mirai.utils.MiraiInternalApi
public class GroupTodoRecord @MiraiInternalApi constructor(
public val group: Group,
public val title: String,
public val operator: NormalMember?,
public val operatorId: Long,
public val operatorNick: String,
public val operatorTime: Int,
@MiraiInternalApi public val msgSeq: Long,
@MiraiInternalApi public val msgRandom: Long
) {
override fun toString(): String {
return "GroupTodoRecord(title=${title}, operator=${operatorId}, group=${group.id}, time=${operatorTime})"
}
}

View File

@ -0,0 +1,14 @@
/*
* Copyright 2019-2023 Mamoe Technologies and contributors.
*
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
* Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
*
* https://github.com/mamoe/mirai/blob/dev/LICENSE
*/
package net.mamoe.mirai.contact.todo
public enum class GroupTodoStatus {
NONE, COMPLETED, CLOSED
}

View File

@ -520,8 +520,29 @@ public data class MemberSpecialTitleChangeEvent @MiraiInternalApi constructor(
public override val operator: NormalMember?
) : GroupMemberEvent, GroupOperableEvent, AbstractEvent(), Packet, GroupMemberInfoChangeEvent
// endregion
/**
* [Member] 活跃度头衔改变时的事件目前只有 Bot 自身会触发
*/
public class MemberTemperatureTitleChangeEvent(
/**
* 改变活跃度头衔的群成员
*/
public override val member: NormalMember,
/**
* 活跃度
*/
public val temperature: Int,
/**
* 获得头衔
*/
public val title: String
) : Packet, GroupMemberEvent, BotPassiveEvent, AbstractEvent() {
override fun toString(): String {
return "MemberTemperatureTitleChangeEvent(group=${group.id}, member=${member.id}, temperature=${temperature}, title=${title})"
}
}
// endregion
// region 成员权限
@ -536,7 +557,6 @@ public data class MemberPermissionChangeEvent @MiraiInternalApi constructor(
// endregion
// region 禁言
/**
@ -570,9 +590,8 @@ public data class MemberUnmuteEvent @MiraiInternalApi constructor(
// region 群荣誉
/**
* [Member] 荣誉改变时的事件, 目前只支持龙王
* [Member] 荣誉改变时的事件
*/
@MiraiExperimentalApi
public sealed class MemberHonorChangeEvent : GroupMemberEvent, BotPassiveEvent, Packet, AbstractEvent() {
/**
* 改变荣誉的群成员
@ -633,4 +652,78 @@ public data class GroupTalkativeChangeEvent(
// endregion
// region 群幸运词
/**
* [Member] 触发群幸运词事件
*/
public class MemberLuckyWordEvent(
/**
* 触发群幸运词的群成员
*/
public override val member: NormalMember,
/**
* 群幸运词的图片链接
*/
public val images: List<String>
) : Packet, GroupMemberEvent, BotPassiveEvent, AbstractEvent() {
override fun toString(): String {
return "MemberLuckyWordEvent(group=${group.id}, member=${member.id})"
}
}
// endregion
// region 群待办
/**
* [Member] 设置群待办事件
*
* QQ 自身限制无法获取到待办内容
*/
public class MemberSetTodoEvent(
/**
* 设置群待办的群成员
*/
public override val member: NormalMember,
) : Packet, GroupMemberEvent, BotPassiveEvent, AbstractEvent() {
override fun toString(): String {
return "MemberSetTodoEvent(group=${group.id}, member=${member.id})"
}
}
/**
* [Member] 撤回群待办事件
*
* QQ 自身限制无法获取到待办内容
*/
public class MemberRecallTodoEvent(
/**
* 完成群待办的群成员
*/
public override val member: NormalMember,
) : Packet, GroupMemberEvent, BotPassiveEvent, AbstractEvent() {
override fun toString(): String {
return "MemberRecallTodoEvent(group=${group.id}, member=${member.id})"
}
}
/**
* [Member] 完成群待办事件可能会在成员完成群待办时触发
*
* QQ 自身限制无法获取到待办内容
*/
public class MemberCompleteTodoEvent(
/**
* 完成群待办的群成员
*/
public override val member: NormalMember,
) : Packet, GroupMemberEvent, BotPassiveEvent, AbstractEvent() {
override fun toString(): String {
return "MemberCompleteTodoEvent(group=${group.id}, member=${member.id})"
}
}
// endregion
// endregion

View File

@ -0,0 +1,16 @@
/*
* Copyright 2019-2023 Mamoe Technologies and contributors.
*
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
* Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
*
* https://github.com/mamoe/mirai/blob/dev/LICENSE
*/
package net.mamoe.mirai.mock.contact.todo
import net.mamoe.mirai.contact.todo.GroupTodo
public interface MockGroupTodo : GroupTodo {
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 2019-2022 Mamoe Technologies and contributors.
* Copyright 2019-2023 Mamoe Technologies and contributors.
*
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
* Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
@ -32,9 +32,11 @@ import net.mamoe.mirai.mock.contact.MockGroupControlPane
import net.mamoe.mirai.mock.contact.MockNormalMember
import net.mamoe.mirai.mock.contact.active.MockGroupActive
import net.mamoe.mirai.mock.contact.essence.MockEssences
import net.mamoe.mirai.mock.contact.todo.MockGroupTodo
import net.mamoe.mirai.mock.internal.contact.active.MockGroupActiveImpl
import net.mamoe.mirai.mock.internal.contact.essence.MockEssencesImpl
import net.mamoe.mirai.mock.internal.contact.roaming.MockRoamingMessages
import net.mamoe.mirai.mock.internal.contact.todo.MockGroupTodoImpl
import net.mamoe.mirai.mock.internal.msgsrc.OnlineMsgSrcToGroup
import net.mamoe.mirai.mock.internal.msgsrc.newMsgSrc
import net.mamoe.mirai.mock.utils.broadcastBlocking
@ -340,6 +342,8 @@ internal class MockGroupImpl(
override val essences: MockEssences = MockEssencesImpl(this)
override val todo: MockGroupTodo = MockGroupTodoImpl(this)
@Deprecated("Please use files instead.", replaceWith = ReplaceWith("files.root"))
@Suppress("OverridingDeprecatedMember", "DEPRECATION", "DEPRECATION_ERROR")
override val filesRoot: RemoteFile by lazy {

View File

@ -0,0 +1,125 @@
/*
* Copyright 2019-2023 Mamoe Technologies and contributors.
*
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
* Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
*
* https://github.com/mamoe/mirai/blob/dev/LICENSE
*/
package net.mamoe.mirai.mock.internal.contact.todo
import kotlinx.coroutines.launch
import net.mamoe.mirai.contact.MemberPermission
import net.mamoe.mirai.contact.checkBotPermission
import net.mamoe.mirai.contact.todo.GroupTodoRecord
import net.mamoe.mirai.contact.todo.GroupTodoStatus
import net.mamoe.mirai.event.broadcast
import net.mamoe.mirai.event.events.MemberCompleteTodoEvent
import net.mamoe.mirai.event.events.MemberRecallTodoEvent
import net.mamoe.mirai.event.events.MemberSetTodoEvent
import net.mamoe.mirai.message.data.MessageSource
import net.mamoe.mirai.mock.contact.todo.MockGroupTodo
import net.mamoe.mirai.mock.internal.contact.MockGroupImpl
import net.mamoe.mirai.utils.currentTimeSeconds
import net.mamoe.mirai.utils.toLongUnsigned
import java.util.concurrent.atomic.AtomicReference
internal class MockGroupTodoImpl(
private val group: MockGroupImpl
) : MockGroupTodo {
private val status: AtomicReference<GroupTodoStatus> = AtomicReference()
private val current: AtomicReference<GroupTodoRecord> = AtomicReference()
override suspend fun status(): GroupTodoStatus {
return status.get() ?: GroupTodoStatus.NONE
}
override suspend fun current(): GroupTodoRecord? {
return current.get()
}
override suspend fun set(source: MessageSource): GroupTodoRecord {
group.checkBotPermission(MemberPermission.ADMINISTRATOR)
val record = GroupTodoRecord(
group = group,
title = source.originalMessage.contentToString(),
operator = group.botAsMember,
operatorId = group.bot.id,
operatorNick = group.botAsMember.nick,
operatorTime = currentTimeSeconds().toInt(),
msgSeq = source.ids.first().toLongUnsigned(),
msgRandom = source.internalIds.first().toLongUnsigned()
)
current.set(record)
status.set(GroupTodoStatus.NONE)
group.launch {
MemberSetTodoEvent(member = group.botAsMember).broadcast()
}
return record
}
override suspend fun recall(source: MessageSource) {
val current = checkNotNull(current.get()) { "current no todo" }
val id = source.ids.first().toLongUnsigned()
val internalId = source.internalIds.first().toLongUnsigned()
check(id == current.msgSeq && internalId == current.msgRandom) { "todo no match" }
status.set(GroupTodoStatus.NONE)
group.launch {
MemberRecallTodoEvent(member = group.botAsMember).broadcast()
}
}
override suspend fun recall(record: GroupTodoRecord) {
val current = checkNotNull(current.get()) { "current no todo" }
check(record.msgSeq == current.msgSeq && record.msgRandom == current.msgRandom) { "todo no match" }
status.set(GroupTodoStatus.NONE)
group.launch {
MemberRecallTodoEvent(member = group.botAsMember).broadcast()
}
}
override suspend fun complete(source: MessageSource) {
val current = checkNotNull(current.get()) { "current no todo" }
val id = source.ids.first().toLongUnsigned()
val internalId = source.internalIds.first().toLongUnsigned()
check(id == current.msgSeq && internalId == current.msgRandom) { "todo no match" }
status.set(GroupTodoStatus.COMPLETED)
group.launch {
MemberCompleteTodoEvent(member = group.botAsMember).broadcast()
}
}
override suspend fun complete(record: GroupTodoRecord) {
val current = checkNotNull(current.get()) { "current no todo" }
check(record.msgSeq == current.msgSeq && record.msgRandom == current.msgRandom) { "todo no match" }
status.set(GroupTodoStatus.COMPLETED)
group.launch {
MemberCompleteTodoEvent(member = group.botAsMember).broadcast()
}
}
override suspend fun close(source: MessageSource) {
group.checkBotPermission(MemberPermission.ADMINISTRATOR)
val current = checkNotNull(current.get()) { "current no todo" }
val id = source.ids.first().toLongUnsigned()
val internalId = source.internalIds.first().toLongUnsigned()
check(id == current.msgSeq && internalId == current.msgRandom) { "todo no match" }
status.set(GroupTodoStatus.CLOSED)
group.launch {
MemberSetTodoEvent(member = group.botAsMember).broadcast()
}
}
override suspend fun close(record: GroupTodoRecord) {
group.checkBotPermission(MemberPermission.ADMINISTRATOR)
val current = checkNotNull(current.get()) { "current no todo" }
check(record.msgSeq == current.msgSeq && record.msgRandom == current.msgRandom) { "todo no match" }
status.set(GroupTodoStatus.CLOSED)
group.launch {
MemberSetTodoEvent(member = group.botAsMember).broadcast()
}
}
}

View File

@ -22,6 +22,7 @@ import net.mamoe.mirai.contact.announcement.Announcements
import net.mamoe.mirai.contact.essence.Essences
import net.mamoe.mirai.contact.file.RemoteFiles
import net.mamoe.mirai.contact.roaming.RoamingMessages
import net.mamoe.mirai.contact.todo.GroupTodo
import net.mamoe.mirai.data.GroupHonorType
import net.mamoe.mirai.data.GroupInfo
import net.mamoe.mirai.data.MemberInfo
@ -34,6 +35,7 @@ import net.mamoe.mirai.internal.contact.essence.EssencesImpl
import net.mamoe.mirai.internal.contact.file.RemoteFilesImpl
import net.mamoe.mirai.internal.contact.info.MemberInfoImpl
import net.mamoe.mirai.internal.contact.roaming.RoamingMessagesImplGroup
import net.mamoe.mirai.internal.contact.todo.GroupTodoImpl
import net.mamoe.mirai.internal.message.contextualBugReportException
import net.mamoe.mirai.internal.message.data.OfflineAudioImpl
import net.mamoe.mirai.internal.message.image.OfflineGroupImage
@ -416,6 +418,13 @@ internal abstract class CommonGroupImpl constructor(
)
}
override val todo: GroupTodo by lazy {
GroupTodoImpl(
this as GroupImpl,
bot.network.logger.subLogger("Group $id"),
)
}
override fun toString(): String = "Group($id)"
}

View File

@ -0,0 +1,176 @@
/*
* Copyright 2019-2023 Mamoe Technologies and contributors.
*
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
* Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
*
* https://github.com/mamoe/mirai/blob/dev/LICENSE
*/
package net.mamoe.mirai.internal.contact.todo
import net.mamoe.mirai.contact.MemberPermission
import net.mamoe.mirai.contact.checkBotPermission
import net.mamoe.mirai.contact.todo.GroupTodo
import net.mamoe.mirai.contact.todo.GroupTodoRecord
import net.mamoe.mirai.contact.todo.GroupTodoStatus
import net.mamoe.mirai.internal.contact.GroupImpl
import net.mamoe.mirai.internal.network.protocol.data.proto.Oidb0xf8e
import net.mamoe.mirai.internal.network.protocol.data.proto.Oidb0xf90
import net.mamoe.mirai.internal.network.protocol.packet.chat.TroopTodoManager
import net.mamoe.mirai.message.data.MessageSource
import net.mamoe.mirai.utils.MiraiLogger
import net.mamoe.mirai.utils.toLongUnsigned
internal class GroupTodoImpl(
internal val group: GroupImpl,
internal val logger: MiraiLogger,
) : GroupTodo {
private fun Oidb0xf8e.RspBody.toGroupTodoRecord(): GroupTodoRecord? {
val info = info ?: return null
return GroupTodoRecord(
group = group,
title = info.title,
operator = group[info.uin],
operatorId = info.uin,
operatorNick = info.nickname,
operatorTime = info.createTime,
msgSeq = info.seq,
msgRandom = info.random.toLongUnsigned()
)
}
private fun Oidb0xf90.TodoInfo.toGroupTodoRecord(): GroupTodoRecord {
return GroupTodoRecord(
group = group,
title = title,
operator = group[uin],
operatorId = uin,
operatorNick = nickname,
operatorTime = createTime,
msgSeq = seq,
msgRandom = random.toLongUnsigned()
)
}
override suspend fun status(): GroupTodoStatus {
val result = group.bot.network.sendAndExpect(
TroopTodoManager.Status(
group.bot.client,
group.uin,
)
)
check(result.pkg.result == 0) { result.pkg.errorMsg }
return when (val code = result.body.rptGroupList?.single()?.status) {
null, 0 -> GroupTodoStatus.NONE
1 -> GroupTodoStatus.COMPLETED
2 -> GroupTodoStatus.CLOSED
else -> throw IllegalStateException("status: $code")
}
}
override suspend fun current(): GroupTodoRecord? {
val result = group.bot.network.sendAndExpect(
TroopTodoManager.Current(
group.bot.client,
group.uin,
)
)
return result.body.toGroupTodoRecord()
}
override suspend fun set(source: MessageSource): GroupTodoRecord {
group.checkBotPermission(MemberPermission.ADMINISTRATOR)
val result = group.bot.network.sendAndExpect(
TroopTodoManager.SetTodo(
group.bot.client,
group.uin,
source.internalIds.first().toLongUnsigned(),
source.ids.first().toLongUnsigned()
)
)
check(result.pkg.result == 0) { result.pkg.errorMsg }
val info = result.info!!
return info.toGroupTodoRecord()
}
override suspend fun recall(source: MessageSource) {
group.checkBotPermission(MemberPermission.ADMINISTRATOR)
val result = group.bot.network.sendAndExpect(
TroopTodoManager.RecallTodo(
group.bot.client,
group.uin,
source.internalIds.first().toLongUnsigned(),
source.ids.first().toLongUnsigned()
)
)
check(result.pkg.result == 0) { result.pkg.errorMsg }
}
override suspend fun recall(record: GroupTodoRecord) {
group.checkBotPermission(MemberPermission.ADMINISTRATOR)
val result = group.bot.network.sendAndExpect(
TroopTodoManager.RecallTodo(
group.bot.client,
group.uin,
record.msgRandom,
record.msgSeq
)
)
check(result.pkg.result == 0) { result.pkg.errorMsg }
}
override suspend fun complete(source: MessageSource) {
val result = group.bot.network.sendAndExpect(
TroopTodoManager.CompleteTodo(
group.bot.client,
group.uin,
source.internalIds.first().toLongUnsigned(),
source.ids.first().toLongUnsigned()
)
)
check(result.pkg.result == 0) { result.pkg.errorMsg }
}
override suspend fun complete(record: GroupTodoRecord) {
val result = group.bot.network.sendAndExpect(
TroopTodoManager.CompleteTodo(
group.bot.client,
group.uin,
record.msgRandom,
record.msgSeq
)
)
check(result.pkg.result == 0) { result.pkg.errorMsg }
}
override suspend fun close(source: MessageSource) {
group.checkBotPermission(MemberPermission.ADMINISTRATOR)
val result = group.bot.network.sendAndExpect(
TroopTodoManager.CloseTodo(
group.bot.client,
group.uin,
source.internalIds.first().toLongUnsigned(),
source.ids.first().toLongUnsigned()
)
)
check(result.pkg.result == 0) { result.pkg.errorMsg }
}
override suspend fun close(record: GroupTodoRecord) {
group.checkBotPermission(MemberPermission.ADMINISTRATOR)
val result = group.bot.network.sendAndExpect(
TroopTodoManager.CloseTodo(
group.bot.client,
group.uin,
record.msgRandom,
record.msgSeq
)
)
check(result.pkg.result == 0) { result.pkg.errorMsg }
}
}

View File

@ -328,8 +328,23 @@ internal class GroupNotificationProcessor(
) = data.context {
val grayTip = buf.loadAs(TroopTips0x857.NotifyMsgBody.serializer(), 1).optGeneralGrayTip
?: return@context markNotConsumed()
markAsConsumed()
when (grayTip?.templId) {
when (grayTip.templId) {
// 群幸运词
10047L, 10048L -> {
val user = grayTip.msgTemplParam["uin"]?.findMember() ?: group.botAsMember
val images = listOfNotNull(
grayTip.msgTemplParam["img_url"],
grayTip.msgTemplParam["img_url_1"],
grayTip.msgTemplParam["img_url_2"]
)
collected += MemberLuckyWordEvent(
member = user,
images = images
)
}
// 群戳一戳
10043L, 1133L, 1132L, 1134L, 1135L, 1136L -> {
@ -380,6 +395,15 @@ internal class GroupNotificationProcessor(
rank = rank
)
}
// 群待办
10134L, 10135L, 10136L -> {
val user = grayTip.msgTemplParam["uin"]?.findMember() ?: group.botAsMember
when (grayTip.templId) {
10134L -> collected += MemberSetTodoEvent(member = user)
10135L -> collected += MemberCompleteTodoEvent(member = user)
10136L -> collected += MemberRecallTodoEvent(member = user)
}
}
// 龙王
10093L, 10094L, 1053L, 1054L, 1103L -> {
val now = grayTip.msgTemplParam["uin"]?.findMember() ?: group.botAsMember
@ -398,14 +422,14 @@ internal class GroupNotificationProcessor(
}
}
// 群聊之火
1052L, 1129L -> {
1052L, 1129L, 10095L -> {
val now = grayTip.msgTemplParam["uin"]?.findMember() ?: group.botAsMember
now.info.honors += GroupHonorType.PERFORMER
collect(MemberHonorChangeEvent.Achieve(now, GroupHonorType.PERFORMER))
}
// 群聊炽焰
1055L -> {
1055L, 10096L -> {
val now = grayTip.msgTemplParam["uin"]?.findMember() ?: group.botAsMember
now.info.honors -= GroupHonorType.PERFORMER
@ -433,11 +457,23 @@ internal class GroupNotificationProcessor(
collect(MemberHonorChangeEvent.Achieve(now, GroupHonorType.RED_PACKET))
}
}
//
// 等级头衔
10097L -> {
// XXX: 目前只有机器人本身会触发
val user = grayTip.msgTemplParam["uin"]?.findMember() ?: group.botAsMember
val level = grayTip.msgTemplParam["level"]?.removePrefix("LV")?.toIntOrNull() ?: 1
val title = grayTip.msgTemplParam["title"] ?: grayTip.msgTemplParam["level"] ?: ""
collected += MemberTemperatureTitleChangeEvent(
member = user,
temperature = level,
title = title
)
}
else -> {
markNotConsumed()
logger.debug {
"Unknown Transformers528 0x14 template\ntemplId=${grayTip?.templId}\nPermList=${grayTip?.msgTemplParam?.structureToString()}"
"Unknown Transformers528 0x14 template\ntemplId=${grayTip.templId}\nPermList=${grayTip.msgTemplParam.structureToString()}"
}
}
}

View File

@ -0,0 +1,53 @@
/*
* Copyright 2019-2023 Mamoe Technologies and contributors.
*
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
* Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
*
* https://github.com/mamoe/mirai/blob/dev/LICENSE
*/
package net.mamoe.mirai.internal.network.protocol.data.proto
import kotlinx.serialization.Serializable
import kotlinx.serialization.protobuf.ProtoNumber
import net.mamoe.mirai.internal.utils.io.ProtoBuf
@Serializable
internal class Oidb0xf8e : ProtoBuf {
@Serializable
internal class InfoValue(
@JvmField @ProtoNumber(1) val groupCode: Long = 0,
@JvmField @ProtoNumber(2) val seq: Long = 0,
@JvmField @ProtoNumber(3) val random: Int = 0,
@JvmField @ProtoNumber(4) val uin: Long = 0,
@JvmField @ProtoNumber(5) val nickname: String = "",
@JvmField @ProtoNumber(6) val title: String = "",
@JvmField @ProtoNumber(7) val jumpUrl: String = "",
@JvmField @ProtoNumber(8) val iconUrl: String = "",
@JvmField @ProtoNumber(9) val createTime: Int = 0,
@JvmField @ProtoNumber(10) val appName: String = "",
@JvmField @ProtoNumber(11) val appId: Long = 0,
@JvmField @ProtoNumber(12) val msgType: Int = 0,
) : ProtoBuf
@Serializable
internal class ReqBody(
@JvmField @ProtoNumber(1) val groupCode: Long = 0,
) : ProtoBuf
@Serializable
internal class RspBody(
@JvmField @ProtoNumber(1) val info: InfoValue? = null,
@JvmField @ProtoNumber(2) val rptGroupList: List<UserNode>? = null,
@JvmField @ProtoNumber(3) val expTime: Int = 0,
) : ProtoBuf
@Serializable
internal class UserNode(
@JvmField @ProtoNumber(1) val groupCode: Long = 0,
@JvmField @ProtoNumber(2) val seq: Long = 0,
@JvmField @ProtoNumber(3) val status: Int = 0,
) : ProtoBuf
}

View File

@ -0,0 +1,47 @@
/*
* Copyright 2019-2023 Mamoe Technologies and contributors.
*
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
* Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
*
* https://github.com/mamoe/mirai/blob/dev/LICENSE
*/
package net.mamoe.mirai.internal.network.protocol.data.proto
import kotlinx.serialization.Serializable
import kotlinx.serialization.protobuf.ProtoNumber
import net.mamoe.mirai.internal.utils.io.ProtoBuf
@Serializable
internal class Oidb0xf90 : ProtoBuf {
@Serializable
internal class ReqBody(
@JvmField @ProtoNumber(1) val groupCode: Long = 0,
@JvmField @ProtoNumber(2) val seq: Long = 0,
@JvmField @ProtoNumber(3) val random: Long = 0,
@JvmField @ProtoNumber(4) val appId: Long = 0
) : ProtoBuf
@Serializable
internal class RspBody(
@JvmField @ProtoNumber(1) val info: TodoInfo? = null,
) : ProtoBuf
@Serializable
internal class TodoInfo(
@JvmField @ProtoNumber(1) val groupCode: Long = 0,
@JvmField @ProtoNumber(2) val seq: Long = 0,
@JvmField @ProtoNumber(3) val random: Int = 0,
@JvmField @ProtoNumber(4) val uin: Long = 0,
@JvmField @ProtoNumber(5) val nickname: String = "",
@JvmField @ProtoNumber(6) val title: String = "",
@JvmField @ProtoNumber(7) val jumpUrl: String = "",
@JvmField @ProtoNumber(8) val iconUrl: String = "",
@JvmField @ProtoNumber(9) val createTime: Int = 0,
@JvmField @ProtoNumber(10) val appName: String = "",
@JvmField @ProtoNumber(11) val appId: Long = 0,
@JvmField @ProtoNumber(12) val msgType: Int = 0,
) : ProtoBuf
}

View File

@ -168,6 +168,12 @@ internal object KnownPacketFactories {
TroopManagement.SwitchAnonymousChat,
TroopEssenceMsgManager.SetEssence,
TroopEssenceMsgManager.RemoveEssence,
TroopTodoManager.Current,
TroopTodoManager.Status,
TroopTodoManager.SetTodo,
TroopTodoManager.RecallTodo,
TroopTodoManager.CompleteTodo,
TroopTodoManager.CloseTodo,
NudgePacket,
Heartbeat.Alive,
PbMessageSvc.PbMsgWithDraw,

View File

@ -0,0 +1,209 @@
/*
* Copyright 2019-2023 Mamoe Technologies and contributors.
*
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
* Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
*
* https://github.com/mamoe/mirai/blob/dev/LICENSE
*/
package net.mamoe.mirai.internal.network.protocol.packet.chat
import io.ktor.utils.io.core.*
import net.mamoe.mirai.internal.QQAndroidBot
import net.mamoe.mirai.internal.network.Packet
import net.mamoe.mirai.internal.network.QQAndroidClient
import net.mamoe.mirai.internal.network.protocol.data.proto.OidbSso
import net.mamoe.mirai.internal.network.protocol.data.proto.Oidb0xf90
import net.mamoe.mirai.internal.network.protocol.data.proto.Oidb0xf8e
import net.mamoe.mirai.internal.network.protocol.packet.OutgoingPacketFactory
import net.mamoe.mirai.internal.network.protocol.packet.buildOutgoingUniPacket
import net.mamoe.mirai.internal.utils.io.serialization.loadAs
import net.mamoe.mirai.internal.utils.io.serialization.readProtoBuf
import net.mamoe.mirai.internal.utils.io.serialization.toByteArray
import net.mamoe.mirai.internal.utils.io.serialization.writeProtoBuf
/**
* 群待办管理
*
* */
internal class TroopTodoManager {
// region OidbSvcTrpcTcp.0xf8e
class Fetch(
val pkg: OidbSso.OIDBSSOPkg,
) : Packet {
val body by lazy {
pkg.bodybuffer.loadAs(Oidb0xf8e.RspBody.serializer())
}
override fun toString(): String =
"TroopTodoManager.Fetch(success=${pkg.result == 0}, error=${pkg.errorMsg})"
}
internal object Current : OutgoingPacketFactory<Fetch>("OidbSvcTrpcTcp.0xf8e_1") {
operator fun invoke(
client: QQAndroidClient,
groupCode: Long
) = buildOutgoingUniPacket(client) {
writeProtoBuf(
OidbSso.OIDBSSOPkg.serializer(), OidbSso.OIDBSSOPkg(
command = 3982,
serviceType = 1,
bodybuffer = Oidb0xf8e.ReqBody(
groupCode = groupCode
).toByteArray(Oidb0xf8e.ReqBody.serializer()),
)
)
}
override suspend fun ByteReadPacket.decode(bot: QQAndroidBot): Fetch {
return Fetch(readProtoBuf(OidbSso.OIDBSSOPkg.serializer()))
}
}
internal object Status : OutgoingPacketFactory<Fetch>("OidbSvcTrpcTcp.0xf8e_2") {
operator fun invoke(
client: QQAndroidClient,
groupCode: Long
) = buildOutgoingUniPacket(client) {
writeProtoBuf(
OidbSso.OIDBSSOPkg.serializer(), OidbSso.OIDBSSOPkg(
command = 3982,
serviceType = 2,
bodybuffer = Oidb0xf8e.ReqBody(
groupCode = groupCode
).toByteArray(Oidb0xf8e.ReqBody.serializer()),
)
)
}
override suspend fun ByteReadPacket.decode(bot: QQAndroidBot): Fetch {
return Fetch(readProtoBuf(OidbSso.OIDBSSOPkg.serializer()))
}
}
// endregion
// region OidbSvcTrpcTcp.0xf90
class Response(
val pkg: OidbSso.OIDBSSOPkg,
) : Packet {
val info by lazy {
pkg.bodybuffer.loadAs(Oidb0xf90.RspBody.serializer()).info
}
override fun toString(): String =
"TroopTodoManager.Response(success=${pkg.result == 0}, error=${pkg.errorMsg})"
}
internal object SetTodo : OutgoingPacketFactory<Response>("OidbSvcTrpcTcp.0xf90_1") {
operator fun invoke(
client: QQAndroidClient,
groupCode: Long,
msgRandom: Long,
msgSeq: Long
) = buildOutgoingUniPacket(client) {
writeProtoBuf(
OidbSso.OIDBSSOPkg.serializer(), OidbSso.OIDBSSOPkg(
command = 3984,
serviceType = 1,
bodybuffer = Oidb0xf90.ReqBody(
groupCode = groupCode,
seq = msgSeq,
random = msgRandom,
).toByteArray(Oidb0xf90.ReqBody.serializer()),
)
)
}
override suspend fun ByteReadPacket.decode(bot: QQAndroidBot): Response {
return Response(readProtoBuf(OidbSso.OIDBSSOPkg.serializer()))
}
}
internal object CompleteTodo : OutgoingPacketFactory<Response>("OidbSvcTrpcTcp.0xf90_2") {
operator fun invoke(
client: QQAndroidClient,
groupCode: Long,
msgRandom: Long,
msgSeq: Long
) = buildOutgoingUniPacket(client) {
writeProtoBuf(
OidbSso.OIDBSSOPkg.serializer(), OidbSso.OIDBSSOPkg(
command = 3984,
serviceType = 2,
bodybuffer = Oidb0xf90.ReqBody(
groupCode = groupCode,
seq = msgSeq,
random = msgRandom,
).toByteArray(Oidb0xf90.ReqBody.serializer()),
)
)
}
override suspend fun ByteReadPacket.decode(bot: QQAndroidBot): Response {
return Response(readProtoBuf(OidbSso.OIDBSSOPkg.serializer()))
}
}
internal object RecallTodo : OutgoingPacketFactory<Response>("OidbSvcTrpcTcp.0xf90_3") {
operator fun invoke(
client: QQAndroidClient,
groupCode: Long,
msgRandom: Long,
msgSeq: Long
) = buildOutgoingUniPacket(client) {
writeProtoBuf(
OidbSso.OIDBSSOPkg.serializer(), OidbSso.OIDBSSOPkg(
command = 3984,
serviceType = 3,
bodybuffer = Oidb0xf90.ReqBody(
groupCode = groupCode,
seq = msgSeq,
random = msgRandom,
).toByteArray(Oidb0xf90.ReqBody.serializer()),
)
)
}
override suspend fun ByteReadPacket.decode(bot: QQAndroidBot): Response {
return Response(readProtoBuf(OidbSso.OIDBSSOPkg.serializer()))
}
}
internal object CloseTodo : OutgoingPacketFactory<Response>("OidbSvcTrpcTcp.0xf90_4") {
operator fun invoke(
client: QQAndroidClient,
groupCode: Long,
msgRandom: Long,
msgSeq: Long
) = buildOutgoingUniPacket(client) {
writeProtoBuf(
OidbSso.OIDBSSOPkg.serializer(), OidbSso.OIDBSSOPkg(
command = 3984,
serviceType = 4,
bodybuffer = Oidb0xf90.ReqBody(
groupCode = groupCode,
seq = msgSeq,
random = msgRandom,
).toByteArray(Oidb0xf90.ReqBody.serializer()),
)
)
}
override suspend fun ByteReadPacket.decode(bot: QQAndroidBot): Response {
return Response(readProtoBuf(OidbSso.OIDBSSOPkg.serializer()))
}
}
// endregion
}