From f5ce64ba4f05b7c30c03280e0c46c4b6a9b38f23 Mon Sep 17 00:00:00 2001 From: Him188 Date: Sun, 4 Jul 2021 17:58:15 +0800 Subject: [PATCH] Redesign Announcement API Co-authored-by: Karlatemp --- ...binary-compatibility-validator-android.api | 168 +++++++--- .../api/binary-compatibility-validator.api | 168 +++++++--- .../commonMain/kotlin/LowLevelApiAccessor.kt | 44 +-- .../src/commonMain/kotlin/contact/Group.kt | 68 +--- .../contact/announcement/Announcement.kt | 56 ++++ .../contact/announcement/AnnouncementImage.kt | 31 ++ .../announcement/AnnouncementParameters.kt | 83 +++++ .../AnnouncementParametersBuilder.kt | 152 +++++++++ .../contact/announcement/Announcements.kt | 77 +++++ .../announcement/OfflineAnnouncement.kt | 84 +++++ .../announcement/OnlineAnnouncement.kt | 82 +++++ .../commonMain/kotlin/data/Announcement.kt | 312 ------------------ .../kotlin/data/GroupAnnouncement.kt | 54 ++- .../src/commonMain/kotlin/Streams.kt | 21 ++ mirai-core/src/commonMain/kotlin/MiraiImpl.kt | 133 ++------ .../kotlin/contact/AnnouncementsImpl.kt | 257 +++++++++++++++ .../commonMain/kotlin/contact/GroupImpl.kt | 35 +- .../kotlin/contact/OnlineAnnouncementImpl.kt | 84 +++++ 18 files changed, 1249 insertions(+), 660 deletions(-) create mode 100644 mirai-core-api/src/commonMain/kotlin/contact/announcement/Announcement.kt create mode 100644 mirai-core-api/src/commonMain/kotlin/contact/announcement/AnnouncementImage.kt create mode 100644 mirai-core-api/src/commonMain/kotlin/contact/announcement/AnnouncementParameters.kt create mode 100644 mirai-core-api/src/commonMain/kotlin/contact/announcement/AnnouncementParametersBuilder.kt create mode 100644 mirai-core-api/src/commonMain/kotlin/contact/announcement/Announcements.kt create mode 100644 mirai-core-api/src/commonMain/kotlin/contact/announcement/OfflineAnnouncement.kt create mode 100644 mirai-core-api/src/commonMain/kotlin/contact/announcement/OnlineAnnouncement.kt delete mode 100644 mirai-core-api/src/commonMain/kotlin/data/Announcement.kt create mode 100644 mirai-core-utils/src/commonMain/kotlin/Streams.kt create mode 100644 mirai-core/src/commonMain/kotlin/contact/AnnouncementsImpl.kt create mode 100644 mirai-core/src/commonMain/kotlin/contact/OnlineAnnouncementImpl.kt diff --git a/binary-compatibility-validator/android/api/binary-compatibility-validator-android.api b/binary-compatibility-validator/android/api/binary-compatibility-validator-android.api index 7b87b3490..57eb866ec 100644 --- a/binary-compatibility-validator/android/api/binary-compatibility-validator-android.api +++ b/binary-compatibility-validator/android/api/binary-compatibility-validator-android.api @@ -350,6 +350,7 @@ public abstract interface class net/mamoe/mirai/contact/Group : kotlinx/coroutin public abstract fun contains (J)Z public fun contains (Lnet/mamoe/mirai/contact/NormalMember;)Z public abstract fun get (J)Lnet/mamoe/mirai/contact/NormalMember; + public abstract fun getAnnouncements ()Lnet/mamoe/mirai/contact/announcement/Announcements; public fun getAvatarUrl ()Ljava/lang/String; public abstract fun getBotAsMember ()Lnet/mamoe/mirai/contact/NormalMember; public fun getBotMuteRemaining ()I @@ -374,8 +375,6 @@ public abstract interface class net/mamoe/mirai/contact/Group : kotlinx/coroutin } public final class net/mamoe/mirai/contact/Group$Companion { - public static synthetic fun sendAnnouncement$default (Lnet/mamoe/mirai/contact/Group$Companion;Lnet/mamoe/mirai/contact/Group;Ljava/lang/String;Ljava/lang/String;Lnet/mamoe/mirai/data/AnnouncementParameters;ILjava/lang/Object;)V - public static synthetic fun sendAnnouncement$default (Lnet/mamoe/mirai/contact/Group$Companion;Lnet/mamoe/mirai/contact/Group;Ljava/lang/String;Ljava/lang/String;Lnet/mamoe/mirai/data/AnnouncementParameters;Lkotlin/coroutines/Continuation;ILjava/lang/Object;)Ljava/lang/Object; public final fun setEssenceMessage (Lnet/mamoe/mirai/contact/Group;Lnet/mamoe/mirai/message/data/MessageChain;)Z public final fun setEssenceMessage (Lnet/mamoe/mirai/contact/Group;Lnet/mamoe/mirai/message/data/MessageChain;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; } @@ -574,28 +573,50 @@ public abstract interface class net/mamoe/mirai/contact/VoiceSupported : net/mam public abstract fun uploadVoice (Lnet/mamoe/mirai/utils/ExternalResource;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; } -public class net/mamoe/mirai/data/Announcement { - public static final field Companion Lnet/mamoe/mirai/data/Announcement$Companion; - public static final fun create (JLjava/lang/String;Ljava/lang/String;Lnet/mamoe/mirai/data/AnnouncementParameters;)Lnet/mamoe/mirai/data/Announcement; - public final fun getBotId ()J - public final fun getMsg ()Ljava/lang/String; - public final fun getParameters ()Lnet/mamoe/mirai/data/AnnouncementParameters; - public final fun getTitle ()Ljava/lang/String; - public fun publish (Lnet/mamoe/mirai/contact/Group;)V - public final fun publish (Lnet/mamoe/mirai/contact/Group;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; +public abstract interface class net/mamoe/mirai/contact/announcement/Announcement { + public abstract fun getBody ()Ljava/lang/String; + public abstract fun getParameters ()Lnet/mamoe/mirai/contact/announcement/AnnouncementParameters; + public abstract fun getTitle ()Ljava/lang/String; + public fun publishTo (Lnet/mamoe/mirai/contact/Group;)Lnet/mamoe/mirai/contact/announcement/OnlineAnnouncement; + public fun publishTo (Lnet/mamoe/mirai/contact/Group;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; } -public final class net/mamoe/mirai/data/Announcement$Companion { - public final fun create (JLjava/lang/String;Ljava/lang/String;Lnet/mamoe/mirai/data/AnnouncementParameters;)Lnet/mamoe/mirai/data/Announcement; +public final class net/mamoe/mirai/contact/announcement/AnnouncementImage { + public static final field Companion Lnet/mamoe/mirai/contact/announcement/AnnouncementImage$Companion; + public static final field SERIAL_NAME Ljava/lang/String; + public synthetic fun (ILjava/lang/String;Ljava/lang/String;Ljava/lang/String;Lkotlinx/serialization/internal/SerializationConstructorMarker;)V + public final fun getHeight ()Ljava/lang/String; + public final fun getId ()Ljava/lang/String; + public final fun getWidth ()Ljava/lang/String; } -public final class net/mamoe/mirai/data/AnnouncementKt { - public static final fun buildAnnouncementParameters (Lkotlin/jvm/functions/Function1;)Lnet/mamoe/mirai/data/AnnouncementParameters; +public final class net/mamoe/mirai/contact/announcement/AnnouncementImage$$serializer : kotlinx/serialization/internal/GeneratedSerializer { + public static final field INSTANCE Lnet/mamoe/mirai/contact/announcement/AnnouncementImage$$serializer; + public static final synthetic field descriptor Lkotlinx/serialization/descriptors/SerialDescriptor; + public fun childSerializers ()[Lkotlinx/serialization/KSerializer; + public synthetic fun deserialize (Lkotlinx/serialization/encoding/Decoder;)Ljava/lang/Object; + public fun deserialize (Lkotlinx/serialization/encoding/Decoder;)Lnet/mamoe/mirai/contact/announcement/AnnouncementImage; + public fun getDescriptor ()Lkotlinx/serialization/descriptors/SerialDescriptor; + public synthetic fun serialize (Lkotlinx/serialization/encoding/Encoder;Ljava/lang/Object;)V + public fun serialize (Lkotlinx/serialization/encoding/Encoder;Lnet/mamoe/mirai/contact/announcement/AnnouncementImage;)V + public fun typeParametersSerializers ()[Lkotlinx/serialization/KSerializer; } -public final class net/mamoe/mirai/data/AnnouncementParameters { +public final class net/mamoe/mirai/contact/announcement/AnnouncementImage$Companion { + public final fun serializer ()Lkotlinx/serialization/KSerializer; +} + +public final class net/mamoe/mirai/contact/announcement/AnnouncementKt { + public static final fun toOffline (Lnet/mamoe/mirai/contact/announcement/Announcement;)Lnet/mamoe/mirai/contact/announcement/OfflineAnnouncement; +} + +public final class net/mamoe/mirai/contact/announcement/AnnouncementParameters { + public static final field Companion Lnet/mamoe/mirai/contact/announcement/AnnouncementParameters$Companion; + public static final field SERIAL_NAME Ljava/lang/String; public fun ()V - public final fun builder ()Lnet/mamoe/mirai/data/AnnouncementParametersBuilder; + public synthetic fun (IZZZZZLkotlinx/serialization/internal/SerializationConstructorMarker;)V + public final fun builder ()Lnet/mamoe/mirai/contact/announcement/AnnouncementParametersBuilder; + public static final fun getDefault ()Lnet/mamoe/mirai/contact/announcement/AnnouncementParameters; public final fun getImage ()[B public final fun getNeedConfirm ()Z public final fun getSendToNewMember ()Z @@ -604,29 +625,98 @@ public final class net/mamoe/mirai/data/AnnouncementParameters { public final fun isTip ()Z } -public final class net/mamoe/mirai/data/AnnouncementParametersBuilder { +public final class net/mamoe/mirai/contact/announcement/AnnouncementParameters$$serializer : kotlinx/serialization/internal/GeneratedSerializer { + public static final field INSTANCE Lnet/mamoe/mirai/contact/announcement/AnnouncementParameters$$serializer; + public static final synthetic field descriptor Lkotlinx/serialization/descriptors/SerialDescriptor; + public fun childSerializers ()[Lkotlinx/serialization/KSerializer; + public synthetic fun deserialize (Lkotlinx/serialization/encoding/Decoder;)Ljava/lang/Object; + public fun deserialize (Lkotlinx/serialization/encoding/Decoder;)Lnet/mamoe/mirai/contact/announcement/AnnouncementParameters; + public fun getDescriptor ()Lkotlinx/serialization/descriptors/SerialDescriptor; + public synthetic fun serialize (Lkotlinx/serialization/encoding/Encoder;Ljava/lang/Object;)V + public fun serialize (Lkotlinx/serialization/encoding/Encoder;Lnet/mamoe/mirai/contact/announcement/AnnouncementParameters;)V + public fun typeParametersSerializers ()[Lkotlinx/serialization/KSerializer; +} + +public final class net/mamoe/mirai/contact/announcement/AnnouncementParameters$Companion { + public final fun getDefault ()Lnet/mamoe/mirai/contact/announcement/AnnouncementParameters; + public final fun serializer ()Lkotlinx/serialization/KSerializer; +} + +public final class net/mamoe/mirai/contact/announcement/AnnouncementParametersBuilder { public fun ()V - public fun (Lnet/mamoe/mirai/data/AnnouncementParameters;)V - public synthetic fun (Lnet/mamoe/mirai/data/AnnouncementParameters;ILkotlin/jvm/internal/DefaultConstructorMarker;)V - public final fun build ()Lnet/mamoe/mirai/data/AnnouncementParameters; + public fun (Lnet/mamoe/mirai/contact/announcement/AnnouncementParameters;)V + public synthetic fun (Lnet/mamoe/mirai/contact/announcement/AnnouncementParameters;ILkotlin/jvm/internal/DefaultConstructorMarker;)V + public final fun build ()Lnet/mamoe/mirai/contact/announcement/AnnouncementParameters; public final fun getImage ()[B public final fun getNeedConfirm ()Z public final fun getSendToNewMember ()Z - public final fun image ([B)Lnet/mamoe/mirai/data/AnnouncementParametersBuilder; public final fun isPinned ()Z public final fun isShowEditCard ()Z public final fun isTip ()Z - public final fun needConfirm (Z)Lnet/mamoe/mirai/data/AnnouncementParametersBuilder; - public final fun pinned (Z)Lnet/mamoe/mirai/data/AnnouncementParametersBuilder; - public final fun sendToNewMember (Z)Lnet/mamoe/mirai/data/AnnouncementParametersBuilder; + public final fun needConfirm (Z)Lnet/mamoe/mirai/contact/announcement/AnnouncementParametersBuilder; + public final fun pinned (Z)Lnet/mamoe/mirai/contact/announcement/AnnouncementParametersBuilder; + public final fun sendToNewMember (Z)Lnet/mamoe/mirai/contact/announcement/AnnouncementParametersBuilder; public final fun setImage ([B)V public final fun setNeedConfirm (Z)V public final fun setPinned (Z)V public final fun setSendToNewMember (Z)V public final fun setShowEditCard (Z)V public final fun setTip (Z)V - public final fun showEditCard (Z)Lnet/mamoe/mirai/data/AnnouncementParametersBuilder; - public final fun tip (Z)Lnet/mamoe/mirai/data/AnnouncementParametersBuilder; + public final fun showEditCard (Z)Lnet/mamoe/mirai/contact/announcement/AnnouncementParametersBuilder; + public final fun tip (Z)Lnet/mamoe/mirai/contact/announcement/AnnouncementParametersBuilder; +} + +public final class net/mamoe/mirai/contact/announcement/AnnouncementParametersBuilderKt { + public static final fun buildAnnouncementParameters (Lkotlin/jvm/functions/Function1;)Lnet/mamoe/mirai/contact/announcement/AnnouncementParameters; +} + +public abstract interface class net/mamoe/mirai/contact/announcement/Announcements { + public fun asFlow ()Lkotlinx/coroutines/flow/Flow; + public abstract fun asFlow (Lkotlin/coroutines/Continuation;)Ljava/lang/Object; + public fun asStream ()Ljava/util/stream/Stream; + public abstract fun asStream (Lkotlin/coroutines/Continuation;)Ljava/lang/Object; + public fun delete (Ljava/lang/String;)Z + public abstract fun delete (Ljava/lang/String;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; + public fun get (Ljava/lang/String;)Lnet/mamoe/mirai/contact/announcement/OnlineAnnouncement; + public abstract fun get (Ljava/lang/String;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; + public fun publish (Lnet/mamoe/mirai/contact/announcement/Announcement;)Lnet/mamoe/mirai/contact/announcement/OnlineAnnouncement; + public abstract fun publish (Lnet/mamoe/mirai/contact/announcement/Announcement;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; + public fun toList ()Ljava/util/List; + public fun toList (Lkotlin/coroutines/Continuation;)Ljava/lang/Object; + public fun uploadImage (Lnet/mamoe/mirai/utils/ExternalResource;)Lnet/mamoe/mirai/contact/announcement/AnnouncementImage; + public abstract fun uploadImage (Lnet/mamoe/mirai/utils/ExternalResource;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; +} + +public abstract interface class net/mamoe/mirai/contact/announcement/OfflineAnnouncement : net/mamoe/mirai/contact/announcement/Announcement { + public static final field Companion Lnet/mamoe/mirai/contact/announcement/OfflineAnnouncement$Companion; + public static final field SERIAL_NAME Ljava/lang/String; + public static fun create (Ljava/lang/String;Ljava/lang/String;Lkotlin/jvm/functions/Function1;)Lnet/mamoe/mirai/contact/announcement/OfflineAnnouncement; + public static fun create (Ljava/lang/String;Ljava/lang/String;Lnet/mamoe/mirai/contact/announcement/AnnouncementParameters;)Lnet/mamoe/mirai/contact/announcement/OfflineAnnouncement; + public static fun from (Lnet/mamoe/mirai/contact/announcement/Announcement;)Lnet/mamoe/mirai/contact/announcement/OfflineAnnouncement; +} + +public final class net/mamoe/mirai/contact/announcement/OfflineAnnouncement$Companion { + public static final field SERIAL_NAME Ljava/lang/String; + public final fun create (Ljava/lang/String;Ljava/lang/String;Lkotlin/jvm/functions/Function1;)Lnet/mamoe/mirai/contact/announcement/OfflineAnnouncement; + public final fun create (Ljava/lang/String;Ljava/lang/String;Lnet/mamoe/mirai/contact/announcement/AnnouncementParameters;)Lnet/mamoe/mirai/contact/announcement/OfflineAnnouncement; + public static synthetic fun create$default (Lnet/mamoe/mirai/contact/announcement/OfflineAnnouncement$Companion;Ljava/lang/String;Ljava/lang/String;Lnet/mamoe/mirai/contact/announcement/AnnouncementParameters;ILjava/lang/Object;)Lnet/mamoe/mirai/contact/announcement/OfflineAnnouncement; + public final fun from (Lnet/mamoe/mirai/contact/announcement/Announcement;)Lnet/mamoe/mirai/contact/announcement/OfflineAnnouncement; +} + +public abstract interface class net/mamoe/mirai/contact/announcement/OnlineAnnouncement : net/mamoe/mirai/contact/announcement/Announcement { + public fun delete ()Z + public fun delete (Lkotlin/coroutines/Continuation;)Ljava/lang/Object; + public abstract fun getFid ()Ljava/lang/String; + public abstract fun getGroup ()Lnet/mamoe/mirai/contact/Group; + public abstract fun getPublishTime ()J + public abstract fun getReadMemberNumber ()I + public abstract fun getSender ()Lnet/mamoe/mirai/contact/NormalMember; + public abstract fun getSenderId ()J + public abstract fun isAllRead ()Z +} + +public final class net/mamoe/mirai/contact/announcement/OnlineAnnouncementKt { + public static final fun getBot (Lnet/mamoe/mirai/contact/announcement/OnlineAnnouncement;)Lnet/mamoe/mirai/Bot; } public abstract interface class net/mamoe/mirai/data/FriendInfo : net/mamoe/mirai/data/UserInfo { @@ -930,22 +1020,6 @@ public final class net/mamoe/mirai/data/GroupAnnouncement$Companion { public final fun serializer ()Lkotlinx/serialization/KSerializer; } -public final class net/mamoe/mirai/data/GroupAnnouncementImage$$serializer : kotlinx/serialization/internal/GeneratedSerializer { - public static final field INSTANCE Lnet/mamoe/mirai/data/GroupAnnouncementImage$$serializer; - public static final synthetic field descriptor Lkotlinx/serialization/descriptors/SerialDescriptor; - public fun childSerializers ()[Lkotlinx/serialization/KSerializer; - public synthetic fun deserialize (Lkotlinx/serialization/encoding/Decoder;)Ljava/lang/Object; - public fun deserialize (Lkotlinx/serialization/encoding/Decoder;)Lnet/mamoe/mirai/data/GroupAnnouncementImage; - public fun getDescriptor ()Lkotlinx/serialization/descriptors/SerialDescriptor; - public synthetic fun serialize (Lkotlinx/serialization/encoding/Encoder;Ljava/lang/Object;)V - public fun serialize (Lkotlinx/serialization/encoding/Encoder;Lnet/mamoe/mirai/data/GroupAnnouncementImage;)V - public fun typeParametersSerializers ()[Lkotlinx/serialization/KSerializer; -} - -public final class net/mamoe/mirai/data/GroupAnnouncementImage$Companion { - public final fun serializer ()Lkotlinx/serialization/KSerializer; -} - public final class net/mamoe/mirai/data/GroupAnnouncementList$$serializer : kotlinx/serialization/internal/GeneratedSerializer { public static final field INSTANCE Lnet/mamoe/mirai/data/GroupAnnouncementList$$serializer; public static final synthetic field descriptor Lkotlinx/serialization/descriptors/SerialDescriptor; @@ -1308,14 +1382,6 @@ public final class net/mamoe/mirai/data/OnlineStatus$Companion { public final fun ofIdOrNull (I)Lnet/mamoe/mirai/data/OnlineStatus; } -public final class net/mamoe/mirai/data/ReceiveAnnouncement : net/mamoe/mirai/data/Announcement { - public final fun getFid ()Ljava/lang/String; - public final fun getPublishTime ()J - public final fun getReadMemberNumber ()I - public final fun getSenderId ()J - public final fun isAllRead ()Z -} - public abstract interface class net/mamoe/mirai/data/StrangerInfo : net/mamoe/mirai/data/UserInfo { public abstract fun getFromGroup ()J public abstract fun getNick ()Ljava/lang/String; diff --git a/binary-compatibility-validator/api/binary-compatibility-validator.api b/binary-compatibility-validator/api/binary-compatibility-validator.api index 617212022..9d36ad5d3 100644 --- a/binary-compatibility-validator/api/binary-compatibility-validator.api +++ b/binary-compatibility-validator/api/binary-compatibility-validator.api @@ -350,6 +350,7 @@ public abstract interface class net/mamoe/mirai/contact/Group : kotlinx/coroutin public abstract fun contains (J)Z public fun contains (Lnet/mamoe/mirai/contact/NormalMember;)Z public abstract fun get (J)Lnet/mamoe/mirai/contact/NormalMember; + public abstract fun getAnnouncements ()Lnet/mamoe/mirai/contact/announcement/Announcements; public fun getAvatarUrl ()Ljava/lang/String; public abstract fun getBotAsMember ()Lnet/mamoe/mirai/contact/NormalMember; public fun getBotMuteRemaining ()I @@ -374,8 +375,6 @@ public abstract interface class net/mamoe/mirai/contact/Group : kotlinx/coroutin } public final class net/mamoe/mirai/contact/Group$Companion { - public static synthetic fun sendAnnouncement$default (Lnet/mamoe/mirai/contact/Group$Companion;Lnet/mamoe/mirai/contact/Group;Ljava/lang/String;Ljava/lang/String;Lnet/mamoe/mirai/data/AnnouncementParameters;ILjava/lang/Object;)V - public static synthetic fun sendAnnouncement$default (Lnet/mamoe/mirai/contact/Group$Companion;Lnet/mamoe/mirai/contact/Group;Ljava/lang/String;Ljava/lang/String;Lnet/mamoe/mirai/data/AnnouncementParameters;Lkotlin/coroutines/Continuation;ILjava/lang/Object;)Ljava/lang/Object; public final fun setEssenceMessage (Lnet/mamoe/mirai/contact/Group;Lnet/mamoe/mirai/message/data/MessageChain;)Z public final fun setEssenceMessage (Lnet/mamoe/mirai/contact/Group;Lnet/mamoe/mirai/message/data/MessageChain;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; } @@ -574,28 +573,50 @@ public abstract interface class net/mamoe/mirai/contact/VoiceSupported : net/mam public abstract fun uploadVoice (Lnet/mamoe/mirai/utils/ExternalResource;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; } -public class net/mamoe/mirai/data/Announcement { - public static final field Companion Lnet/mamoe/mirai/data/Announcement$Companion; - public static final fun create (JLjava/lang/String;Ljava/lang/String;Lnet/mamoe/mirai/data/AnnouncementParameters;)Lnet/mamoe/mirai/data/Announcement; - public final fun getBotId ()J - public final fun getMsg ()Ljava/lang/String; - public final fun getParameters ()Lnet/mamoe/mirai/data/AnnouncementParameters; - public final fun getTitle ()Ljava/lang/String; - public fun publish (Lnet/mamoe/mirai/contact/Group;)V - public final fun publish (Lnet/mamoe/mirai/contact/Group;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; +public abstract interface class net/mamoe/mirai/contact/announcement/Announcement { + public abstract fun getBody ()Ljava/lang/String; + public abstract fun getParameters ()Lnet/mamoe/mirai/contact/announcement/AnnouncementParameters; + public abstract fun getTitle ()Ljava/lang/String; + public fun publishTo (Lnet/mamoe/mirai/contact/Group;)Lnet/mamoe/mirai/contact/announcement/OnlineAnnouncement; + public fun publishTo (Lnet/mamoe/mirai/contact/Group;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; } -public final class net/mamoe/mirai/data/Announcement$Companion { - public final fun create (JLjava/lang/String;Ljava/lang/String;Lnet/mamoe/mirai/data/AnnouncementParameters;)Lnet/mamoe/mirai/data/Announcement; +public final class net/mamoe/mirai/contact/announcement/AnnouncementImage { + public static final field Companion Lnet/mamoe/mirai/contact/announcement/AnnouncementImage$Companion; + public static final field SERIAL_NAME Ljava/lang/String; + public synthetic fun (ILjava/lang/String;Ljava/lang/String;Ljava/lang/String;Lkotlinx/serialization/internal/SerializationConstructorMarker;)V + public final fun getHeight ()Ljava/lang/String; + public final fun getId ()Ljava/lang/String; + public final fun getWidth ()Ljava/lang/String; } -public final class net/mamoe/mirai/data/AnnouncementKt { - public static final fun buildAnnouncementParameters (Lkotlin/jvm/functions/Function1;)Lnet/mamoe/mirai/data/AnnouncementParameters; +public final class net/mamoe/mirai/contact/announcement/AnnouncementImage$$serializer : kotlinx/serialization/internal/GeneratedSerializer { + public static final field INSTANCE Lnet/mamoe/mirai/contact/announcement/AnnouncementImage$$serializer; + public static final synthetic field descriptor Lkotlinx/serialization/descriptors/SerialDescriptor; + public fun childSerializers ()[Lkotlinx/serialization/KSerializer; + public synthetic fun deserialize (Lkotlinx/serialization/encoding/Decoder;)Ljava/lang/Object; + public fun deserialize (Lkotlinx/serialization/encoding/Decoder;)Lnet/mamoe/mirai/contact/announcement/AnnouncementImage; + public fun getDescriptor ()Lkotlinx/serialization/descriptors/SerialDescriptor; + public synthetic fun serialize (Lkotlinx/serialization/encoding/Encoder;Ljava/lang/Object;)V + public fun serialize (Lkotlinx/serialization/encoding/Encoder;Lnet/mamoe/mirai/contact/announcement/AnnouncementImage;)V + public fun typeParametersSerializers ()[Lkotlinx/serialization/KSerializer; } -public final class net/mamoe/mirai/data/AnnouncementParameters { +public final class net/mamoe/mirai/contact/announcement/AnnouncementImage$Companion { + public final fun serializer ()Lkotlinx/serialization/KSerializer; +} + +public final class net/mamoe/mirai/contact/announcement/AnnouncementKt { + public static final fun toOffline (Lnet/mamoe/mirai/contact/announcement/Announcement;)Lnet/mamoe/mirai/contact/announcement/OfflineAnnouncement; +} + +public final class net/mamoe/mirai/contact/announcement/AnnouncementParameters { + public static final field Companion Lnet/mamoe/mirai/contact/announcement/AnnouncementParameters$Companion; + public static final field SERIAL_NAME Ljava/lang/String; public fun ()V - public final fun builder ()Lnet/mamoe/mirai/data/AnnouncementParametersBuilder; + public synthetic fun (IZZZZZLkotlinx/serialization/internal/SerializationConstructorMarker;)V + public final fun builder ()Lnet/mamoe/mirai/contact/announcement/AnnouncementParametersBuilder; + public static final fun getDefault ()Lnet/mamoe/mirai/contact/announcement/AnnouncementParameters; public final fun getImage ()[B public final fun getNeedConfirm ()Z public final fun getSendToNewMember ()Z @@ -604,29 +625,98 @@ public final class net/mamoe/mirai/data/AnnouncementParameters { public final fun isTip ()Z } -public final class net/mamoe/mirai/data/AnnouncementParametersBuilder { +public final class net/mamoe/mirai/contact/announcement/AnnouncementParameters$$serializer : kotlinx/serialization/internal/GeneratedSerializer { + public static final field INSTANCE Lnet/mamoe/mirai/contact/announcement/AnnouncementParameters$$serializer; + public static final synthetic field descriptor Lkotlinx/serialization/descriptors/SerialDescriptor; + public fun childSerializers ()[Lkotlinx/serialization/KSerializer; + public synthetic fun deserialize (Lkotlinx/serialization/encoding/Decoder;)Ljava/lang/Object; + public fun deserialize (Lkotlinx/serialization/encoding/Decoder;)Lnet/mamoe/mirai/contact/announcement/AnnouncementParameters; + public fun getDescriptor ()Lkotlinx/serialization/descriptors/SerialDescriptor; + public synthetic fun serialize (Lkotlinx/serialization/encoding/Encoder;Ljava/lang/Object;)V + public fun serialize (Lkotlinx/serialization/encoding/Encoder;Lnet/mamoe/mirai/contact/announcement/AnnouncementParameters;)V + public fun typeParametersSerializers ()[Lkotlinx/serialization/KSerializer; +} + +public final class net/mamoe/mirai/contact/announcement/AnnouncementParameters$Companion { + public final fun getDefault ()Lnet/mamoe/mirai/contact/announcement/AnnouncementParameters; + public final fun serializer ()Lkotlinx/serialization/KSerializer; +} + +public final class net/mamoe/mirai/contact/announcement/AnnouncementParametersBuilder { public fun ()V - public fun (Lnet/mamoe/mirai/data/AnnouncementParameters;)V - public synthetic fun (Lnet/mamoe/mirai/data/AnnouncementParameters;ILkotlin/jvm/internal/DefaultConstructorMarker;)V - public final fun build ()Lnet/mamoe/mirai/data/AnnouncementParameters; + public fun (Lnet/mamoe/mirai/contact/announcement/AnnouncementParameters;)V + public synthetic fun (Lnet/mamoe/mirai/contact/announcement/AnnouncementParameters;ILkotlin/jvm/internal/DefaultConstructorMarker;)V + public final fun build ()Lnet/mamoe/mirai/contact/announcement/AnnouncementParameters; public final fun getImage ()[B public final fun getNeedConfirm ()Z public final fun getSendToNewMember ()Z - public final fun image ([B)Lnet/mamoe/mirai/data/AnnouncementParametersBuilder; public final fun isPinned ()Z public final fun isShowEditCard ()Z public final fun isTip ()Z - public final fun needConfirm (Z)Lnet/mamoe/mirai/data/AnnouncementParametersBuilder; - public final fun pinned (Z)Lnet/mamoe/mirai/data/AnnouncementParametersBuilder; - public final fun sendToNewMember (Z)Lnet/mamoe/mirai/data/AnnouncementParametersBuilder; + public final fun needConfirm (Z)Lnet/mamoe/mirai/contact/announcement/AnnouncementParametersBuilder; + public final fun pinned (Z)Lnet/mamoe/mirai/contact/announcement/AnnouncementParametersBuilder; + public final fun sendToNewMember (Z)Lnet/mamoe/mirai/contact/announcement/AnnouncementParametersBuilder; public final fun setImage ([B)V public final fun setNeedConfirm (Z)V public final fun setPinned (Z)V public final fun setSendToNewMember (Z)V public final fun setShowEditCard (Z)V public final fun setTip (Z)V - public final fun showEditCard (Z)Lnet/mamoe/mirai/data/AnnouncementParametersBuilder; - public final fun tip (Z)Lnet/mamoe/mirai/data/AnnouncementParametersBuilder; + public final fun showEditCard (Z)Lnet/mamoe/mirai/contact/announcement/AnnouncementParametersBuilder; + public final fun tip (Z)Lnet/mamoe/mirai/contact/announcement/AnnouncementParametersBuilder; +} + +public final class net/mamoe/mirai/contact/announcement/AnnouncementParametersBuilderKt { + public static final fun buildAnnouncementParameters (Lkotlin/jvm/functions/Function1;)Lnet/mamoe/mirai/contact/announcement/AnnouncementParameters; +} + +public abstract interface class net/mamoe/mirai/contact/announcement/Announcements { + public fun asFlow ()Lkotlinx/coroutines/flow/Flow; + public abstract fun asFlow (Lkotlin/coroutines/Continuation;)Ljava/lang/Object; + public fun asStream ()Ljava/util/stream/Stream; + public abstract fun asStream (Lkotlin/coroutines/Continuation;)Ljava/lang/Object; + public fun delete (Ljava/lang/String;)Z + public abstract fun delete (Ljava/lang/String;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; + public fun get (Ljava/lang/String;)Lnet/mamoe/mirai/contact/announcement/OnlineAnnouncement; + public abstract fun get (Ljava/lang/String;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; + public fun publish (Lnet/mamoe/mirai/contact/announcement/Announcement;)Lnet/mamoe/mirai/contact/announcement/OnlineAnnouncement; + public abstract fun publish (Lnet/mamoe/mirai/contact/announcement/Announcement;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; + public fun toList ()Ljava/util/List; + public fun toList (Lkotlin/coroutines/Continuation;)Ljava/lang/Object; + public fun uploadImage (Lnet/mamoe/mirai/utils/ExternalResource;)Lnet/mamoe/mirai/contact/announcement/AnnouncementImage; + public abstract fun uploadImage (Lnet/mamoe/mirai/utils/ExternalResource;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; +} + +public abstract interface class net/mamoe/mirai/contact/announcement/OfflineAnnouncement : net/mamoe/mirai/contact/announcement/Announcement { + public static final field Companion Lnet/mamoe/mirai/contact/announcement/OfflineAnnouncement$Companion; + public static final field SERIAL_NAME Ljava/lang/String; + public static fun create (Ljava/lang/String;Ljava/lang/String;Lkotlin/jvm/functions/Function1;)Lnet/mamoe/mirai/contact/announcement/OfflineAnnouncement; + public static fun create (Ljava/lang/String;Ljava/lang/String;Lnet/mamoe/mirai/contact/announcement/AnnouncementParameters;)Lnet/mamoe/mirai/contact/announcement/OfflineAnnouncement; + public static fun from (Lnet/mamoe/mirai/contact/announcement/Announcement;)Lnet/mamoe/mirai/contact/announcement/OfflineAnnouncement; +} + +public final class net/mamoe/mirai/contact/announcement/OfflineAnnouncement$Companion { + public static final field SERIAL_NAME Ljava/lang/String; + public final fun create (Ljava/lang/String;Ljava/lang/String;Lkotlin/jvm/functions/Function1;)Lnet/mamoe/mirai/contact/announcement/OfflineAnnouncement; + public final fun create (Ljava/lang/String;Ljava/lang/String;Lnet/mamoe/mirai/contact/announcement/AnnouncementParameters;)Lnet/mamoe/mirai/contact/announcement/OfflineAnnouncement; + public static synthetic fun create$default (Lnet/mamoe/mirai/contact/announcement/OfflineAnnouncement$Companion;Ljava/lang/String;Ljava/lang/String;Lnet/mamoe/mirai/contact/announcement/AnnouncementParameters;ILjava/lang/Object;)Lnet/mamoe/mirai/contact/announcement/OfflineAnnouncement; + public final fun from (Lnet/mamoe/mirai/contact/announcement/Announcement;)Lnet/mamoe/mirai/contact/announcement/OfflineAnnouncement; +} + +public abstract interface class net/mamoe/mirai/contact/announcement/OnlineAnnouncement : net/mamoe/mirai/contact/announcement/Announcement { + public fun delete ()Z + public fun delete (Lkotlin/coroutines/Continuation;)Ljava/lang/Object; + public abstract fun getFid ()Ljava/lang/String; + public abstract fun getGroup ()Lnet/mamoe/mirai/contact/Group; + public abstract fun getPublishTime ()J + public abstract fun getReadMemberNumber ()I + public abstract fun getSender ()Lnet/mamoe/mirai/contact/NormalMember; + public abstract fun getSenderId ()J + public abstract fun isAllRead ()Z +} + +public final class net/mamoe/mirai/contact/announcement/OnlineAnnouncementKt { + public static final fun getBot (Lnet/mamoe/mirai/contact/announcement/OnlineAnnouncement;)Lnet/mamoe/mirai/Bot; } public abstract interface class net/mamoe/mirai/data/FriendInfo : net/mamoe/mirai/data/UserInfo { @@ -930,22 +1020,6 @@ public final class net/mamoe/mirai/data/GroupAnnouncement$Companion { public final fun serializer ()Lkotlinx/serialization/KSerializer; } -public final class net/mamoe/mirai/data/GroupAnnouncementImage$$serializer : kotlinx/serialization/internal/GeneratedSerializer { - public static final field INSTANCE Lnet/mamoe/mirai/data/GroupAnnouncementImage$$serializer; - public static final synthetic field descriptor Lkotlinx/serialization/descriptors/SerialDescriptor; - public fun childSerializers ()[Lkotlinx/serialization/KSerializer; - public synthetic fun deserialize (Lkotlinx/serialization/encoding/Decoder;)Ljava/lang/Object; - public fun deserialize (Lkotlinx/serialization/encoding/Decoder;)Lnet/mamoe/mirai/data/GroupAnnouncementImage; - public fun getDescriptor ()Lkotlinx/serialization/descriptors/SerialDescriptor; - public synthetic fun serialize (Lkotlinx/serialization/encoding/Encoder;Ljava/lang/Object;)V - public fun serialize (Lkotlinx/serialization/encoding/Encoder;Lnet/mamoe/mirai/data/GroupAnnouncementImage;)V - public fun typeParametersSerializers ()[Lkotlinx/serialization/KSerializer; -} - -public final class net/mamoe/mirai/data/GroupAnnouncementImage$Companion { - public final fun serializer ()Lkotlinx/serialization/KSerializer; -} - public final class net/mamoe/mirai/data/GroupAnnouncementList$$serializer : kotlinx/serialization/internal/GeneratedSerializer { public static final field INSTANCE Lnet/mamoe/mirai/data/GroupAnnouncementList$$serializer; public static final synthetic field descriptor Lkotlinx/serialization/descriptors/SerialDescriptor; @@ -1308,14 +1382,6 @@ public final class net/mamoe/mirai/data/OnlineStatus$Companion { public final fun ofIdOrNull (I)Lnet/mamoe/mirai/data/OnlineStatus; } -public final class net/mamoe/mirai/data/ReceiveAnnouncement : net/mamoe/mirai/data/Announcement { - public final fun getFid ()Ljava/lang/String; - public final fun getPublishTime ()J - public final fun getReadMemberNumber ()I - public final fun getSenderId ()J - public final fun isAllRead ()Z -} - public abstract interface class net/mamoe/mirai/data/StrangerInfo : net/mamoe/mirai/data/UserInfo { public abstract fun getFromGroup ()J public abstract fun getNick ()Ljava/lang/String; diff --git a/mirai-core-api/src/commonMain/kotlin/LowLevelApiAccessor.kt b/mirai-core-api/src/commonMain/kotlin/LowLevelApiAccessor.kt index dd325bdd7..f36eecedf 100644 --- a/mirai-core-api/src/commonMain/kotlin/LowLevelApiAccessor.kt +++ b/mirai-core-api/src/commonMain/kotlin/LowLevelApiAccessor.kt @@ -1,10 +1,10 @@ /* * Copyright 2019-2021 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. + * 此源代码的使用受 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/master/LICENSE + * https://github.com/mamoe/mirai/blob/dev/LICENSE */ @file:JvmBlockingBridge @@ -133,6 +133,8 @@ public interface LowLevelApiAccessor { * 获取群公告列表 * @param page 页码 */ + @Suppress("DEPRECATION") + @Deprecated("Will be removed in the future. Use Announcement instead.", level = DeprecationLevel.WARNING) @LowLevelApi @MiraiExperimentalApi public suspend fun getRawGroupAnnouncements( @@ -142,23 +144,13 @@ public interface LowLevelApiAccessor { amount: Int = 10 ): GroupAnnouncementList - /** - * 上传群公告的所需要的一个图片,但不发送 - * - */ - @LowLevelApi - @MiraiExperimentalApi - public suspend fun uploadGroupAnnouncementImage( - bot: Bot, - groupId: Long, - resource: ExternalResource - ): GroupAnnouncementImage - /** * 发送群公告 * * @return 公告的fid */ + @Suppress("DEPRECATION") + @Deprecated("Will be removed in the future. Use Announcement instead.", level = DeprecationLevel.WARNING) @LowLevelApi @MiraiExperimentalApi public suspend fun sendGroupAnnouncement( @@ -167,43 +159,33 @@ public interface LowLevelApiAccessor { announcement: GroupAnnouncement ): String - /** - * 发送包含图片的群公告 - * - * @return 公告的fid - */ - @LowLevelApi - @MiraiExperimentalApi - public suspend fun sendGroupAnnouncementWithImage( - bot: Bot, - groupId: Long, - image: GroupAnnouncementImage, - announcement: GroupAnnouncement - ): String - /** * 删除群公告 * @param fid [GroupAnnouncement.fid] */ + @Suppress("DEPRECATION") + @Deprecated("Will be removed in the future. Use Announcement instead.", level = DeprecationLevel.WARNING) @LowLevelApi @MiraiExperimentalApi public suspend fun deleteGroupAnnouncement( bot: Bot, groupId: Long, fid: String - ) + ): Boolean /** * 获取一条群公告 * @param fid [GroupAnnouncement.fid] */ + @Suppress("DEPRECATION") + @Deprecated("Will be removed in the future. Use Announcement instead.", level = DeprecationLevel.WARNING) @LowLevelApi @MiraiExperimentalApi public suspend fun getGroupAnnouncement( bot: Bot, groupId: Long, fid: String - ): GroupAnnouncement + ): GroupAnnouncement? /** diff --git a/mirai-core-api/src/commonMain/kotlin/contact/Group.kt b/mirai-core-api/src/commonMain/kotlin/contact/Group.kt index ef699125e..0ccdc0e52 100644 --- a/mirai-core-api/src/commonMain/kotlin/contact/Group.kt +++ b/mirai-core-api/src/commonMain/kotlin/contact/Group.kt @@ -13,14 +13,9 @@ package net.mamoe.mirai.contact import kotlinx.coroutines.CoroutineScope -import kotlinx.coroutines.flow.Flow import net.mamoe.kjbb.JvmBlockingBridge import net.mamoe.mirai.Bot -import net.mamoe.mirai.Mirai -import net.mamoe.mirai.data.Announcement -import net.mamoe.mirai.data.AnnouncementParameters -import net.mamoe.mirai.data.ReceiveAnnouncement -import net.mamoe.mirai.data.covertToGroupAnnouncement +import net.mamoe.mirai.contact.announcement.Announcements import net.mamoe.mirai.event.events.* import net.mamoe.mirai.message.MessageReceipt import net.mamoe.mirai.message.data.* @@ -96,6 +91,12 @@ public interface Group : Contact, CoroutineScope, FileSupported, VoiceSupported */ public val members: ContactList + /** + * 获取群公告相关功能接口 + * @since 2.7 + */ + public val announcements: Announcements + /** * 获取群成员实例. 不存在时返回 `null`. * @@ -167,28 +168,6 @@ public interface Group : Contact, CoroutineScope, FileSupported, VoiceSupported */ public suspend fun setEssenceMessage(source: MessageSource): Boolean - /** - * 获取所有群公告列表 - */ - @MiraiExperimentalApi - public suspend fun getAnnouncements(): Flow - - /** - * 删除一条群公告 - * @param fid 公告的id [ReceiveAnnouncement.fid] - * - * @throws PermissionDeniedException 没有权限时抛出 - */ - @MiraiExperimentalApi - public suspend fun deleteAnnouncement(fid: String) - - /** - * 获取一条群公告 - * @param fid 公告的id [ReceiveAnnouncement.fid] - */ - @MiraiExperimentalApi - public suspend fun getAnnouncement(fid: String): ReceiveAnnouncement - public companion object { /** * 将一条消息设置为群精华消息, 需要管理员或群主权限. @@ -202,39 +181,6 @@ public interface Group : Contact, CoroutineScope, FileSupported, VoiceSupported @JvmBlockingBridge @JvmStatic public suspend fun Group.setEssenceMessage(chain: MessageChain): Boolean = setEssenceMessage(chain.source) - - /** - * 发送一个 [Announcement] - * - * @param title 公告标题 - * @param msg 公告内容 - * @param announcementParameters 公告设置 - */ - @MiraiExperimentalApi - @JvmBlockingBridge - @JvmStatic - public suspend fun Group.sendAnnouncement( - title: String, - msg: String, - announcementParameters: AnnouncementParameters = AnnouncementParameters() - ) { - checkBotPermission(MemberPermission.ADMINISTRATOR) { "Only administrator have permission to send group announcement" } - Mirai.sendGroupAnnouncement( - bot, - id, - Announcement(bot.id, title, msg, announcementParameters).covertToGroupAnnouncement() - ) - } - - /** - * 删除一条群公告 - * @param receiveAnnouncement 公告 [ReceiveAnnouncement] - */ - @MiraiExperimentalApi - @JvmBlockingBridge - @JvmStatic - public suspend fun Group.deleteAnnouncement(receiveAnnouncement: ReceiveAnnouncement): Unit = - deleteAnnouncement(receiveAnnouncement.fid) } } diff --git a/mirai-core-api/src/commonMain/kotlin/contact/announcement/Announcement.kt b/mirai-core-api/src/commonMain/kotlin/contact/announcement/Announcement.kt new file mode 100644 index 000000000..251835617 --- /dev/null +++ b/mirai-core-api/src/commonMain/kotlin/contact/announcement/Announcement.kt @@ -0,0 +1,56 @@ +/* + * Copyright 2019-2021 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 + */ + +@file:Suppress("INAPPLICABLE_JVM_NAME", "NOTHING_TO_INLINE") +@file:JvmBlockingBridge + +package net.mamoe.mirai.contact.announcement + +import net.mamoe.kjbb.JvmBlockingBridge +import net.mamoe.mirai.contact.Group + + +/** + * 表示一个群公告. + * + * @see Announcement + * + * @since 2.7 + */ +public sealed interface Announcement { + /** + * 标题 + */ + public val title: String + + /** + * 内容 + */ + public val body: String + + /** + * 附加参数. 可以通过 [AnnouncementParametersBuilder] 构建获得. + * @see AnnouncementParameters + * @see AnnouncementParametersBuilder + */ + public val parameters: AnnouncementParameters + + /** + * 在该群发布群公告并获得 [OnlineAnnouncement]. + */ + public suspend fun publishTo(group: Group): OnlineAnnouncement = group.announcements.publish(this) +} + +/** + * 创建 [OfflineAnnouncement]. 若 [this] 类型为 [OfflineAnnouncement] 则直接返回 [this]. + * @since 2.7 + */ +public inline fun Announcement.toOffline(): OfflineAnnouncement = OfflineAnnouncement.from(this) + + diff --git a/mirai-core-api/src/commonMain/kotlin/contact/announcement/AnnouncementImage.kt b/mirai-core-api/src/commonMain/kotlin/contact/announcement/AnnouncementImage.kt new file mode 100644 index 000000000..710e25f1b --- /dev/null +++ b/mirai-core-api/src/commonMain/kotlin/contact/announcement/AnnouncementImage.kt @@ -0,0 +1,31 @@ +/* + * Copyright 2019-2021 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.announcement + +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable +import net.mamoe.mirai.utils.MiraiInternalApi + + +/** + * 群公告图片. 可通过 [Announcements.uploadImage] 上传获得. 不确定服务器会保存多久. + * @since 2.7 + */ +@SerialName(AnnouncementImage.SERIAL_NAME) +@Serializable +public class AnnouncementImage @MiraiInternalApi public constructor( + @SerialName("h") public val height: String, + @SerialName("w") public val width: String, + @SerialName("id") public val id: String +) { + public companion object { + public const val SERIAL_NAME: String = "AnnouncementImage" + } +} \ No newline at end of file diff --git a/mirai-core-api/src/commonMain/kotlin/contact/announcement/AnnouncementParameters.kt b/mirai-core-api/src/commonMain/kotlin/contact/announcement/AnnouncementParameters.kt new file mode 100644 index 000000000..8b9d62552 --- /dev/null +++ b/mirai-core-api/src/commonMain/kotlin/contact/announcement/AnnouncementParameters.kt @@ -0,0 +1,83 @@ +/* + * Copyright 2019-2021 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.announcement + +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable +import kotlinx.serialization.Transient +import net.mamoe.mirai.utils.MiraiExperimentalApi + +/** + * 群公告的附加参数. + * + * 可通过 [AnnouncementParametersBuilder] 构建. + * + * @since 2.7 + */ +@SerialName(AnnouncementParameters.SERIAL_NAME) +@Serializable +public class AnnouncementParameters internal constructor( + /** + * 群公告的图片,目前仅支持发送图片,不支持获得图片 + * @suppress 此 API 不稳定, 可能在任意时间改动 + */ + @Transient // do not serialize unstable properties + @MiraiExperimentalApi + public val image: ByteArray? = null, + + /** + * 是否发送给新成员 + */ + public val sendToNewMember: Boolean = false, + + /** + * 是否置顶,可以有多个置顶公告 + */ + public val isPinned: Boolean = false, + + /** + * 是否显示能够引导群成员修改昵称的窗口 + */ + public val isShowEditCard: Boolean = false, + + /** + * 是否使用弹窗 + */ + public val isTip: Boolean = false, + + /** + * 是否需要群成员确认 + */ + public val needConfirm: Boolean = false, +) { + /** + * 以该对象作为原型创建一个 [AnnouncementParametersBuilder]. + */ + public fun builder(): AnnouncementParametersBuilder = AnnouncementParametersBuilder().apply { + val outer = this@AnnouncementParameters + this.image = outer.image + this.sendToNewMember = outer.sendToNewMember + this.isPinned = outer.isPinned + this.isShowEditCard = outer.isShowEditCard + this.isTip = outer.isTip + this.needConfirm = outer.needConfirm + } + + public companion object { + public const val SERIAL_NAME: String = "AnnouncementParameters" + + /** + * 使用默认值的 [AnnouncementParameters] 实例 + */ + @JvmStatic + @get:JvmName("getDefault") + public val DEFAULT: AnnouncementParameters = AnnouncementParameters() + } +} \ No newline at end of file diff --git a/mirai-core-api/src/commonMain/kotlin/contact/announcement/AnnouncementParametersBuilder.kt b/mirai-core-api/src/commonMain/kotlin/contact/announcement/AnnouncementParametersBuilder.kt new file mode 100644 index 000000000..1c529bfc3 --- /dev/null +++ b/mirai-core-api/src/commonMain/kotlin/contact/announcement/AnnouncementParametersBuilder.kt @@ -0,0 +1,152 @@ +/* + * Copyright 2019-2021 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 + */ + +@file:Suppress("unused") + +package net.mamoe.mirai.contact.announcement + +import net.mamoe.mirai.utils.MiraiExperimentalApi +import kotlin.contracts.InvocationKind +import kotlin.contracts.contract + + +/** + * [AnnouncementParameters] 的构建器. 可以构建一个 [AnnouncementParameters] 实例. + * + * ## 获得实例 + * + * 直接构造实例: `new AnnouncementParametersBuilder()` 或者从已有的公告中获取 [AnnouncementParameters.builder]. + * + * ## 使用 + * + * ### 在 Kotlin 使用 + * + * ``` + * val parameters = buildAnnouncementParameters { + * sendToNewMember = true + * // ... + * } + * ``` + * + * ### 在 Java 使用 + * + * ```java + * AnnouncementParameters parameters = new AnnouncementParametersBuilder() + * .sendToNewMember(true) + * .pinned(true) + * .build(); + * ``` + * + * @see buildAnnouncementParameters + * + * @since 2.7 + */ +public class AnnouncementParametersBuilder @JvmOverloads constructor( + prototype: AnnouncementParameters = AnnouncementParameters.DEFAULT +) { + /** + * @see AnnouncementParameters.image + * @suppress 此 API 不稳定, 可能在任意时间改动 + */ + @MiraiExperimentalApi + public var image: ByteArray? = prototype.image + + /** + * @see AnnouncementParameters.sendToNewMember + */ + public var sendToNewMember: Boolean = prototype.sendToNewMember + + /** + * @see AnnouncementParameters.isPinned + */ + public var isPinned: Boolean = prototype.isPinned + + /** + * @see AnnouncementParameters.isShowEditCard + */ + public var isShowEditCard: Boolean = prototype.isShowEditCard + + /** + * @see AnnouncementParameters.isTip + */ + public var isTip: Boolean = prototype.isTip + + /** + * @see AnnouncementParameters.needConfirm + */ + public var needConfirm: Boolean = prototype.needConfirm + + /** + * @suppress 此 API 不稳定, 可能在任意时间改动 + */ + @MiraiExperimentalApi + public fun image(image: ByteArray?): AnnouncementParametersBuilder { + this.image = image + return this + } + + /** + * @see AnnouncementParameters.sendToNewMember + */ + public fun sendToNewMember(sendToNewMember: Boolean): AnnouncementParametersBuilder { + this.sendToNewMember = sendToNewMember + return this + } + + /** + * @see AnnouncementParameters.isPinned + */ + public fun pinned(isPinned: Boolean): AnnouncementParametersBuilder { + this.isPinned = isPinned + return this + } + + /** + * @see AnnouncementParameters.isShowEditCard + */ + public fun showEditCard(isShowEditCard: Boolean): AnnouncementParametersBuilder { + this.isShowEditCard = isShowEditCard + return this + } + + /** + * @see AnnouncementParameters.isTip + */ + public fun tip(isTip: Boolean): AnnouncementParametersBuilder { + this.isTip = isTip + return this + } + + /** + * @see AnnouncementParameters.needConfirm + */ + public fun needConfirm(needConfirm: Boolean): AnnouncementParametersBuilder { + this.needConfirm = needConfirm + return this + } + + /** + * 使用当前参数构造 [AnnouncementParameters]. + */ + public fun build(): AnnouncementParameters = + AnnouncementParameters(image, sendToNewMember, isPinned, isShowEditCard, isTip, needConfirm) +} + +/** + * 使用 [AnnouncementParametersBuilder] 构建 [AnnouncementParameters]. + * @see AnnouncementParametersBuilder + * + * @since 2.7 + */ +public inline fun buildAnnouncementParameters( + builderAction: AnnouncementParametersBuilder.() -> Unit +): AnnouncementParameters { + contract { callsInPlace(builderAction, InvocationKind.EXACTLY_ONCE) } + return AnnouncementParametersBuilder().apply(builderAction).build() +} \ No newline at end of file diff --git a/mirai-core-api/src/commonMain/kotlin/contact/announcement/Announcements.kt b/mirai-core-api/src/commonMain/kotlin/contact/announcement/Announcements.kt new file mode 100644 index 000000000..468458b41 --- /dev/null +++ b/mirai-core-api/src/commonMain/kotlin/contact/announcement/Announcements.kt @@ -0,0 +1,77 @@ +/* + * Copyright 2019-2021 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 + */ + +@file:JvmBlockingBridge +@file:Suppress("INAPPLICABLE_JVM_NAME") + +package net.mamoe.mirai.contact.announcement + +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.toList +import net.mamoe.kjbb.JvmBlockingBridge +import net.mamoe.mirai.contact.PermissionDeniedException +import net.mamoe.mirai.utils.ExternalResource +import java.util.stream.Stream + + +/** + * 表示一个群的公告列表 (管理器). + * + * @since 2.7 + */ +public interface Announcements { + /** + * 创建一个能获取该群内所有群公告列表的 [Flow]. 在 [Flow] 被使用时才会分页下载 [OnlineAnnouncement]. + */ + public suspend fun asFlow(): Flow + + /** + * 创建一个能获取该群内所有群公告列表的 [Stream]. 在 [Stream] 被使用时才会分页下载 [OnlineAnnouncement]. + */ + public suspend fun asStream(): Stream + + /** + * 获取所有群公告列表, 将全部 [OnlineAnnouncement] 都下载后再返回. + * @return 此时刻的群公告列表 + */ + public suspend fun toList(): List = asFlow().toList() + + + /** + * 删除一条群公告. 需要管理员权限. 使用 [OnlineAnnouncement.delete] 与此方法效果相同. + * + * @param fid 公告的id [OnlineAnnouncement.fid] + * @return 成功返回 `true`, 群公告不存在时返回 `false` + * + * @throws PermissionDeniedException 当没有权限时抛出 + * + * @see OnlineAnnouncement.delete + */ + public suspend fun delete(fid: String): Boolean + + /** + * 获取一条群公告. + * @param fid 公告的id [OnlineAnnouncement.fid] + * @return 返回 `null` 表示不存在该 [fid] 的群公告 + */ + public suspend fun get(fid: String): OnlineAnnouncement? + + /** + * 在该群发布群公告并获得 [OnlineAnnouncement]. + * @throws PermissionDeniedException 当没有权限时抛出 + */ + public suspend fun publish(announcement: Announcement): OnlineAnnouncement + + /** + * 上传群公告图片 + * + * 注意: 需要由调用方关闭 [resource]. + */ + public suspend fun uploadImage(resource: ExternalResource): AnnouncementImage +} diff --git a/mirai-core-api/src/commonMain/kotlin/contact/announcement/OfflineAnnouncement.kt b/mirai-core-api/src/commonMain/kotlin/contact/announcement/OfflineAnnouncement.kt new file mode 100644 index 000000000..afe1ead40 --- /dev/null +++ b/mirai-core-api/src/commonMain/kotlin/contact/announcement/OfflineAnnouncement.kt @@ -0,0 +1,84 @@ +/* + * Copyright 2019-2021 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 + */ + +@file:Suppress("NOTHING_TO_INLINE") + +package net.mamoe.mirai.contact.announcement + +import kotlinx.serialization.KSerializer +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable +import net.mamoe.mirai.utils.cast +import net.mamoe.mirai.utils.copy +import net.mamoe.mirai.utils.map +import net.mamoe.mirai.utils.safeCast + +/** + * 表示在本地构建的, 无唯一标识符的 [Announcement]. + * @see OnlineAnnouncement.publishTo + * + * @since 2.7 + */ +@Serializable(OfflineAnnouncement.Companion.Serializer::class) +@SerialName(OfflineAnnouncement.SERIAL_NAME) +public sealed interface OfflineAnnouncement : Announcement { + public companion object { + public const val SERIAL_NAME: String = "OfflineAnnouncement" + + /** + * 创建 [OfflineAnnouncement]. 若 [announcement] 类型为 [OfflineAnnouncement] 则直接返回 [announcement]. + */ + @JvmStatic + public inline fun from(announcement: Announcement): OfflineAnnouncement = + announcement.safeCast() ?: announcement.run { create(title, body, parameters) } + + /** + * 创建 [OfflineAnnouncement]. + * @param title 标题 + * @param body 公告内容 + * @param parameters 附加参数 + */ + @JvmStatic + public fun create( + title: String, + body: String, + parameters: AnnouncementParameters = AnnouncementParameters.DEFAULT + ): OfflineAnnouncement = OfflineAnnouncementImpl(title, body, parameters) + + /** + * 创建 [AnnouncementParameters] 并创建 [OfflineAnnouncement]. + * @param title 标题 + * @param body 公告内容 + * @param parameters 附加参数 + * @see AnnouncementParametersBuilder + * */ + @JvmStatic + public inline fun create( + title: String, + body: String, + parameters: AnnouncementParametersBuilder.() -> Unit + ): OfflineAnnouncement = create(title, body, buildAnnouncementParameters(parameters)) + + internal object Serializer : KSerializer by OfflineAnnouncementImpl.serializer().map( + resultantDescriptor = OfflineAnnouncementImpl.serializer().descriptor.copy(SERIAL_NAME), + deserialize = { it }, + serialize = { it.safeCast() ?: create(title, body, parameters).cast() } + ) + } +} + +@SerialName(OfflineAnnouncement.SERIAL_NAME) +@Serializable +private data class OfflineAnnouncementImpl( + override val title: String, + override val body: String, + override val parameters: AnnouncementParameters +) : OfflineAnnouncement { + override fun toString() = "OfflineAnnouncement(title='$title', body='$body', parameters=$parameters)" +} \ No newline at end of file diff --git a/mirai-core-api/src/commonMain/kotlin/contact/announcement/OnlineAnnouncement.kt b/mirai-core-api/src/commonMain/kotlin/contact/announcement/OnlineAnnouncement.kt new file mode 100644 index 000000000..d62cf0397 --- /dev/null +++ b/mirai-core-api/src/commonMain/kotlin/contact/announcement/OnlineAnnouncement.kt @@ -0,0 +1,82 @@ +/* + * Copyright 2019-2021 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 + */ + +@file:Suppress("INAPPLICABLE_JVM_NAME", "NOTHING_TO_INLINE") +@file:JvmBlockingBridge + +package net.mamoe.mirai.contact.announcement + +import net.mamoe.kjbb.JvmBlockingBridge +import net.mamoe.mirai.Bot +import net.mamoe.mirai.contact.Group +import net.mamoe.mirai.contact.NormalMember +import net.mamoe.mirai.contact.PermissionDeniedException +import java.time.Instant + + +/** + * 表示从 [Announcements.get] 等途径在线获取的, 已经存在于服务器的公告. + * + * [OnlineAnnouncement] 拥有唯一识别属性 [fid] 代表其存在于服务器中的 ID. 可进行 [删除][delete] + * + * @since 2.7 + */ +public interface OnlineAnnouncement : Announcement { + /** + * 公告所属群 + */ + public val group: Group + + /** + * 公告发送者 [NormalMember.id] + */ + public val senderId: Long + + /** + * 公告发送者. 当该成员已经离开群后为 `null` + */ + public val sender: NormalMember? + + /** + * 唯一识别属性 + */ + public val fid: String + + /** + * 所有人都已阅读, 如果 [AnnouncementParameters.needConfirm] 为 `true` 则为所有人都已确认. + */ + public val isAllRead: Boolean + + /** + * 已经阅读的成员数量,如果 [AnnouncementParameters.needConfirm] 为 `true` 则为已经确认的成员数量 + */ + public val readMemberNumber: Int + + /** + * 公告发出的时间,为 EpochSecond (自 1970-01-01T00:00:00Z 的秒数) + * + * @see Instant.ofEpochSecond + */ + public val publishTime: Long + + /** + * 删除这个公告. 需要管理员权限. + * + * @return 成功返回 `true`, 群公告已被删除时返回 `false` + * @throws PermissionDeniedException 没有权限时抛出 + * @see Announcements.delete + */ + public suspend fun delete(): Boolean = group.announcements.delete(fid) +} + +/** + * 公告所属 [Bot], 即 `sender.bot`. + * @since 2.7 + */ +public inline val OnlineAnnouncement.bot: Bot get() = group.bot diff --git a/mirai-core-api/src/commonMain/kotlin/data/Announcement.kt b/mirai-core-api/src/commonMain/kotlin/data/Announcement.kt deleted file mode 100644 index 52e24dc69..000000000 --- a/mirai-core-api/src/commonMain/kotlin/data/Announcement.kt +++ /dev/null @@ -1,312 +0,0 @@ -/* - * Copyright 2019-2021 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/master/LICENSE - */ - -@file:Suppress("unused") -@file:JvmBlockingBridge - -package net.mamoe.mirai.data - -import net.mamoe.kjbb.JvmBlockingBridge -import net.mamoe.mirai.Mirai -import net.mamoe.mirai.contact.Group -import net.mamoe.mirai.contact.MemberPermission -import net.mamoe.mirai.contact.checkBotPermission -import net.mamoe.mirai.utils.ExternalResource.Companion.toExternalResource -import java.time.Instant - -/** - * 表示一个群公告. [ReceiveAnnouncement] 表示 - * - * 可通过 [Announcement.create] 构造. - * - * @see Announcement - * - * @since 2.7 - */ -public open class Announcement internal constructor( - /** - * bot的Id - */ - public val botId: Long, - - /** - * 公告的标题 - */ - public val title: String, - - /** - * 公告的内容 - */ - public val msg: String, - - /** - * 公告的可变参数. 可以通过 [AnnouncementParametersBuilder] 构建获得. - * @see AnnouncementParameters - * @see AnnouncementParametersBuilder - */ - public val parameters: AnnouncementParameters -) { - /** - * 发送该公告到群 - */ - public suspend fun publish(group: Group) { - val bot = group.bot - group.checkBotPermission(MemberPermission.ADMINISTRATOR) { "Only administrator have permission to send group announcement" } - if (parameters.image == null) - Mirai.sendGroupAnnouncement(bot, group.id, covertToGroupAnnouncement()) - else { - parameters.image.toExternalResource().use { - val image = - Mirai.uploadGroupAnnouncementImage(bot, group.id, it) - Mirai.sendGroupAnnouncementWithImage(bot, group.id, image, covertToGroupAnnouncement()) - } - } - } - - public companion object { - /** - * 构造一个 [Announcement]. - * @see Announcement - */ - @JvmStatic - public fun create(botId: Long, title: String, msg: String, parameters: AnnouncementParameters): Announcement { - return Announcement(botId, title, msg, parameters) - } - } -} - -/** - * 群公告的扩展参数. - * - * 可通过 [AnnouncementParametersBuilder] 构建. [AnnouncementParameters] 用于 [创建公告][Announcement.create]. - * - * @since 2.7 - */ -public class AnnouncementParameters internal constructor( - /** - * 群公告的图片,目前仅支持发送图片,不支持获得图片 - */ - public val image: ByteArray? = null, - - /** - * 是否发送给新成员 - */ - public val sendToNewMember: Boolean = false, - - /** - * 是否置顶,可以有多个置顶公告 - */ - public val isPinned: Boolean = false, - - /** - * 是否显示能够引导群成员修改昵称的窗口 - */ - public val isShowEditCard: Boolean = false, - - /** - * 是否使用弹窗 - */ - public val isTip: Boolean = false, - - /** - * 是否需要群成员确认 - */ - public val needConfirm: Boolean = false, -) { - /** - * 以该对象的参数创建一个 [AnnouncementParametersBuilder]. - */ - public fun builder(): AnnouncementParametersBuilder = AnnouncementParametersBuilder().apply { - val outer = this@AnnouncementParameters - this.image = outer.image - this.sendToNewMember = outer.sendToNewMember - this.isPinned = outer.isPinned - this.isShowEditCard = outer.isShowEditCard - this.isTip = outer.isTip - this.needConfirm = outer.needConfirm - } -} - -/** - * 表示一个收到的群公告. 只能由 mirai 构造. - * - * @since 2.7 - */ -public class ReceiveAnnouncement internal constructor( - /** - * bot的 Id - */ - botId: Long, - /** - * 公告的标题 - */ - title: String, - /** - * 公告的内容 - */ - msg: String, - /** - * 公告的可变参数 - */ - parameters: AnnouncementParameters, - /** - * 公告发送者的 QQ 号 - */ - public val senderId: Long, - - /** - * 公告的 `fid,每个公告仅有一条 `fid`,类似于主键 - */ - public val fid: String, - - /** - * 所有人都已阅读, 如果 [AnnouncementParameters.needConfirm] 为 `true` 则为所有人都已确认, - */ - public val isAllRead: Boolean, - - /** - * 已经阅读的成员数量,如果 [AnnouncementParameters.needConfirm] 为 `true` 则为已经确认的成员数量 - */ - public val readMemberNumber: Int, - - /** - * 公告发出的时间,为 EpochSecond (自 1970-01-01T00:00:00Z 的秒数) - * - * @see Instant.ofEpochSecond - */ - public val publishTime: Long, -) : Announcement(botId, title, msg, parameters) - -/** - * [AnnouncementParameters] 的构建器. 可以构建一个 [AnnouncementParameters] 实例. - * - * ## 获得实例 - * - * 直接构造实例: `new AnnouncementParametersBuilder()` 或者从已有的公告中获取 [AnnouncementParameters.builder]. - * - * ## 使用 - * - * ### 在 Kotlin 使用 - * - * ``` - * val parameters = buildAnnouncementParameters { - * sendToNewMember = true - * // ... - * } - * ``` - * - * ### 在 Java 使用 - * - * ```java - * AnnouncementParameters parameters = new AnnouncementParametersBuilder() - * .sendToNewMember(true) - * .pinned(true) - * .build(); - * ``` - * - * @see buildAnnouncementParameters - * - * @since 2.7 - */ -public class AnnouncementParametersBuilder @JvmOverloads constructor( - prototype: AnnouncementParameters = AnnouncementParameters() -) { - public var image: ByteArray? = prototype.image - public var sendToNewMember: Boolean = prototype.sendToNewMember - public var isPinned: Boolean = prototype.isPinned - public var isShowEditCard: Boolean = prototype.isShowEditCard - public var isTip: Boolean = prototype.isTip - public var needConfirm: Boolean = prototype.needConfirm - - public fun image(image: ByteArray?): AnnouncementParametersBuilder { - this.image = image - return this - } - - public fun sendToNewMember(sendToNewMember: Boolean): AnnouncementParametersBuilder { - this.sendToNewMember = sendToNewMember - return this - } - - public fun pinned(isPinned: Boolean): AnnouncementParametersBuilder { - this.isPinned = isPinned - return this - } - - public fun showEditCard(isShowEditCard: Boolean): AnnouncementParametersBuilder { - this.isShowEditCard = isShowEditCard - return this - } - - public fun tip(isTip: Boolean): AnnouncementParametersBuilder { - this.isTip = isTip - return this - } - - public fun needConfirm(needConfirm: Boolean): AnnouncementParametersBuilder { - this.needConfirm = needConfirm - return this - } - - /** - * 使用当前参数构造 [AnnouncementParameters]. - */ - public fun build(): AnnouncementParameters = - AnnouncementParameters(image, sendToNewMember, isPinned, isShowEditCard, isTip, needConfirm) -} - -/** - * 使用 [AnnouncementParametersBuilder] 构建 [AnnouncementParameters]. - * @see AnnouncementParametersBuilder - * - * @since 2.7 - */ -public inline fun buildAnnouncementParameters( - builderAction: AnnouncementParametersBuilder.() -> Unit -): AnnouncementParameters = AnnouncementParametersBuilder().apply(builderAction).build() - -internal fun GroupAnnouncement.covertToAnnouncement(botId: Long): ReceiveAnnouncement { - check(this.fid != null) { "GroupAnnouncement don't have id" } - check(this.settings != null) { "GroupAnnouncement don't have setting" } - - return ReceiveAnnouncement( - botId = botId, - fid = fid, - senderId = sender, - publishTime = time, - title = msg.title ?: "", - msg = msg.text, - readMemberNumber = readNum, - isAllRead = isAllConfirm != 0, - parameters = buildAnnouncementParameters { - isPinned = pinned == 1 - sendToNewMember = type == 20 - isTip = settings.tipWindowType == 0 - needConfirm = settings.confirmRequired == 1 - isShowEditCard = settings.isShowEditCard == 1 - } - ) -} - -internal fun Announcement.covertToGroupAnnouncement(): GroupAnnouncement { - return GroupAnnouncement( - sender = botId, - msg = GroupAnnouncementMsg( - title = title, - text = msg - ), - type = if (parameters.sendToNewMember) 20 else 6, - settings = GroupAnnouncementSettings( - isShowEditCard = if (parameters.isShowEditCard) 1 else 0, - tipWindowType = if (parameters.isTip) 0 else 1, - confirmRequired = if (parameters.needConfirm) 1 else 0, - ), - pinned = if (parameters.isPinned) 1 else 0, - ) -} \ No newline at end of file diff --git a/mirai-core-api/src/commonMain/kotlin/data/GroupAnnouncement.kt b/mirai-core-api/src/commonMain/kotlin/data/GroupAnnouncement.kt index c85cfa61b..c2dbec363 100644 --- a/mirai-core-api/src/commonMain/kotlin/data/GroupAnnouncement.kt +++ b/mirai-core-api/src/commonMain/kotlin/data/GroupAnnouncement.kt @@ -1,25 +1,27 @@ /* * Copyright 2019-2021 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. + * 此源代码的使用受 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/master/LICENSE + * https://github.com/mamoe/mirai/blob/dev/LICENSE */ +@file:Suppress("DEPRECATION") + package net.mamoe.mirai.data import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable +import net.mamoe.mirai.contact.announcement.Announcement import net.mamoe.mirai.utils.MiraiExperimentalApi /** - * 群公告数据类 - * getGroupAnnouncementList时,如果page=1,那么你可以在inst里拿到一些置顶公告 - * - * 发公告时只需要填写text,其他参数可为默认值 + * 群公告的协议数据结构. 仅同于内部操作, 用户请使用 [Announcement]. * + * @suppress 此 API 非常不稳定, 将在未来版本删除 */ +@Deprecated("Will be removed in the future. Use Announcement instead.", level = DeprecationLevel.WARNING) @MiraiExperimentalApi @Serializable public data class GroupAnnouncementList( @@ -27,8 +29,24 @@ public data class GroupAnnouncementList( @SerialName("em") val msg: String, //信息 val feeds: List? = null, //群公告列表 val inst: List? = null //置顶列表? 应该是发送给新成员的 -) +) { + /* + // notes from original implementor, luo123, on 2020/3/13 + * 群公告数据类 + * getGroupAnnouncementList时,如果page=1,那么你可以在inst里拿到一些置顶公告 + * + * 发公告时只需要填写text,其他参数可为默认值 + * + */ +} + +/** + * 群公告的协议数据结构. 仅同于内部操作, 用户请使用 [AnnouncementImpl]. + * + * @suppress 此 API 非常不稳定, 将在未来版本删除 + */ +@Deprecated("Will be removed in the future. Use Announcement instead.", level = DeprecationLevel.WARNING) @MiraiExperimentalApi @Serializable public data class GroupAnnouncement( @@ -44,6 +62,12 @@ public data class GroupAnnouncement( val fid: String? = null, //公告的id ) +/** + * 群公告的协议数据结构. 仅同于内部操作, 用户请使用 [AnnouncementImpl]. + * + * @suppress 此 API 非常不稳定, 将在未来版本删除 + */ +@Deprecated("Will be removed in the future. Use Announcement instead.", level = DeprecationLevel.WARNING) @MiraiExperimentalApi @Serializable public data class GroupAnnouncementMsg( @@ -52,6 +76,12 @@ public data class GroupAnnouncementMsg( val title: String? = null ) +/** + * 群公告的协议数据结构. 仅同于内部操作, 用户请使用 [AnnouncementImpl]. + * + * @suppress 此 API 非常不稳定, 将在未来版本删除 + */ +@Deprecated("Will be removed in the future. Use Announcement instead.", level = DeprecationLevel.WARNING) @MiraiExperimentalApi @Serializable public data class GroupAnnouncementSettings( @@ -60,11 +90,3 @@ public data class GroupAnnouncementSettings( @SerialName("tip_window_type") val tipWindowType: Int = 0, //是否用弹窗展示 1 不使用 @SerialName("confirm_required") val confirmRequired: Int = 0 // 是否需要确认收到 1 需要 ) - -@MiraiExperimentalApi -@Serializable -public data class GroupAnnouncementImage( - @SerialName("h") val height: String, - @SerialName("w") val width: String, - @SerialName("id") val id: String -) \ No newline at end of file diff --git a/mirai-core-utils/src/commonMain/kotlin/Streams.kt b/mirai-core-utils/src/commonMain/kotlin/Streams.kt new file mode 100644 index 000000000..a8352715e --- /dev/null +++ b/mirai-core-utils/src/commonMain/kotlin/Streams.kt @@ -0,0 +1,21 @@ +/* + * Copyright 2019-2021 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 + */ + +@file:JvmMultifileClass +@file:JvmName("MiraiUtils") +@file:Suppress("NOTHING_TO_INLINE") + +package net.mamoe.mirai.utils + +import java.util.stream.Stream +import kotlin.streams.asStream + +@JvmSynthetic +public inline fun stream(@BuilderInference noinline block: suspend SequenceScope.() -> Unit): Stream = + sequence(block).asStream() \ No newline at end of file diff --git a/mirai-core/src/commonMain/kotlin/MiraiImpl.kt b/mirai-core/src/commonMain/kotlin/MiraiImpl.kt index 15b92c1bb..6d39eac7d 100644 --- a/mirai-core/src/commonMain/kotlin/MiraiImpl.kt +++ b/mirai-core/src/commonMain/kotlin/MiraiImpl.kt @@ -1,10 +1,10 @@ /* * Copyright 2019-2021 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. + * 此源代码的使用受 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/master/LICENSE + * https://github.com/mamoe/mirai/blob/dev/LICENSE */ package net.mamoe.mirai.internal @@ -14,11 +14,8 @@ import io.ktor.client.engine.okhttp.* import io.ktor.client.features.* import io.ktor.client.request.* import io.ktor.client.request.forms.* -import io.ktor.http.* -import io.ktor.utils.io.core.* import kotlinx.coroutines.SupervisorJob import kotlinx.coroutines.currentCoroutineContext -import kotlinx.coroutines.withContext import kotlinx.io.core.discardExact import kotlinx.io.core.readBytes import kotlinx.serialization.json.* @@ -59,7 +56,6 @@ import net.mamoe.mirai.message.data.Image.Key.IMAGE_RESOURCE_ID_REGEX_1 import net.mamoe.mirai.message.data.Image.Key.IMAGE_RESOURCE_ID_REGEX_2 import net.mamoe.mirai.utils.* import net.mamoe.mirai.utils.ExternalResource.Companion.toExternalResource -import kotlin.io.use import kotlin.math.absoluteValue import kotlin.random.Random @@ -561,6 +557,7 @@ internal open class MiraiImpl : IMirai, LowLevelApiAccessor { check(response is PbMessageSvc.PbMsgWithDraw.Response.Success) { "Failed to recall message #${source.ids.contentToString()}: $response" } } + @Suppress("DEPRECATION", "OverridingDeprecatedMember") @LowLevelApi @MiraiExperimentalApi override suspend fun getRawGroupAnnouncements( @@ -598,47 +595,7 @@ internal open class MiraiImpl : IMirai, LowLevelApiAccessor { isLenient = true } - @LowLevelApi - @MiraiExperimentalApi - override suspend fun uploadGroupAnnouncementImage( - bot: Bot, - groupId: Long, - resource: ExternalResource - ): GroupAnnouncementImage = bot.asQQAndroidBot().run { - //https://youtrack.jetbrains.com/issue/KTOR-455 - val rep = Mirai.Http.post { - url("https://web.qun.qq.com/cgi-bin/announce/upload_img") - body = MultiPartFormDataContent(formData { - append("\"bkn\"", bkn) - append("\"source\"", "troopNotice") - append("m", "0") - append( - "\"pic_up\"", - headers = Headers.build { - append(HttpHeaders.ContentType, ContentType.Image.PNG) - append(HttpHeaders.ContentDisposition, "filename=\"temp_uploadFile.png\"") - } - ) { - writeFully(resource.inputStream().withUse { readBytes() }) - } - }) - headers { - append( - "cookie", - " p_uin=o${id};" + - " p_skey=${client.wLoginSigInfo.psKeyMap["qun.qq.com"]?.data?.encodeToString() ?: error("cookie parse p_skey error")}; " - ) - } - } - val jsonObj = json.parseToJsonElement(rep) - if (jsonObj.jsonObject["ec"]?.jsonPrimitive?.int != 0) { - throw IllegalStateException("Upload group announcement image fail group:$groupId msg:${jsonObj.jsonObject["em"]}") - } - val id = jsonObj.jsonObject["id"]?.jsonPrimitive?.content - ?: throw IllegalStateException("Upload group announcement image fail group:$groupId msg:${jsonObj.jsonObject["em"]}") - return json.decodeFromString(GroupAnnouncementImage.serializer(), id) - } - + @Suppress("DEPRECATION", "OverridingDeprecatedMember") @LowLevelApi @MiraiExperimentalApi override suspend fun sendGroupAnnouncement(bot: Bot, groupId: Long, announcement: GroupAnnouncement): String = @@ -674,83 +631,41 @@ internal open class MiraiImpl : IMirai, LowLevelApiAccessor { ?: throw throw IllegalStateException("Send Announcement fail group:$groupId msg:${jsonObj.jsonObject["em"]} content:${announcement.msg.text}") } + @Suppress("DEPRECATION", "OverridingDeprecatedMember") @LowLevelApi @MiraiExperimentalApi - override suspend fun sendGroupAnnouncementWithImage( - bot: Bot, - groupId: Long, - image: GroupAnnouncementImage, - announcement: GroupAnnouncement - ): String = bot.asQQAndroidBot().run { - val rep = withContext(network.coroutineContext) { - Mirai.Http.post { - url("https://web.qun.qq.com/cgi-bin/announce/add_qun_notice") + override suspend fun deleteGroupAnnouncement(bot: Bot, groupId: Long, fid: String): Boolean = + bot.asQQAndroidBot().run { + val data = Mirai.Http.post { + url("https://web.qun.qq.com/cgi-bin/announce/del_feed") body = MultiPartFormDataContent(formData { append("qid", groupId) append("bkn", bkn) - append("text", announcement.msg.text) - append("pinned", announcement.pinned) - append("pic", image.id) - append("imgWidth", image.width) - append("imgHeight", image.height) - append( - "settings", - json.encodeToString( - GroupAnnouncementSettings.serializer(), - announcement.settings ?: GroupAnnouncementSettings() - ) - ) + append("fid", fid) append("format", "json") }) headers { append( "cookie", - " p_uin=o${id};" + - " p_skey=${ - client.wLoginSigInfo.psKeyMap["qun.qq.com"]?.data?.encodeToString() ?: error( - "parse error" - ) - }; " + "uin=o${id};" + + " skey=${client.wLoginSigInfo.sKey.data.encodeToString()};" + + " p_uin=o${id};" + + " p_skey=${client.wLoginSigInfo.psKeyMap["qun.qq.com"]?.data?.encodeToString()}; " ) } - } - } - val jsonObj = json.parseToJsonElement(rep) - return jsonObj.jsonObject["new_fid"]?.jsonPrimitive?.content - ?: throw throw IllegalStateException("Send Announcement with image fail group:$groupId msg:${jsonObj.jsonObject["em"]} content:${announcement.msg.text}") - } + val jsonObj = json.parseToJsonElement(data) + if (jsonObj.jsonObject["ec"]?.jsonPrimitive?.int ?: 1 != 0) { + throw throw IllegalStateException("delete Announcement fail group:$groupId msg:${jsonObj.jsonObject["em"]} fid:$fid") + } + return jsonObj.jsonObject["ec"]?.jsonPrimitive?.int == 0 + } + + @Suppress("DEPRECATION", "OverridingDeprecatedMember") @LowLevelApi @MiraiExperimentalApi - override suspend fun deleteGroupAnnouncement(bot: Bot, groupId: Long, fid: String) = bot.asQQAndroidBot().run { - val data = Mirai.Http.post { - url("https://web.qun.qq.com/cgi-bin/announce/del_feed") - body = MultiPartFormDataContent(formData { - append("qid", groupId) - append("bkn", bkn) - append("fid", fid) - append("format", "json") - }) - headers { - append( - "cookie", - "uin=o${id};" + - " skey=${client.wLoginSigInfo.sKey.data.encodeToString()};" + - " p_uin=o${id};" + - " p_skey=${client.wLoginSigInfo.psKeyMap["qun.qq.com"]?.data?.encodeToString()}; " - ) - } - } - val jsonObj = json.parseToJsonElement(data) - if (jsonObj.jsonObject["ec"]?.jsonPrimitive?.int ?: 1 != 0) { - throw throw IllegalStateException("delete Announcement fail group:$groupId msg:${jsonObj.jsonObject["em"]} fid:$fid") - } - } - - @LowLevelApi - @MiraiExperimentalApi - override suspend fun getGroupAnnouncement(bot: Bot, groupId: Long, fid: String): GroupAnnouncement = + override suspend fun getGroupAnnouncement(bot: Bot, groupId: Long, fid: String): GroupAnnouncement? = bot.asQQAndroidBot().run { val rep = network.run { Mirai.Http.post { diff --git a/mirai-core/src/commonMain/kotlin/contact/AnnouncementsImpl.kt b/mirai-core/src/commonMain/kotlin/contact/AnnouncementsImpl.kt new file mode 100644 index 000000000..b4fbeb960 --- /dev/null +++ b/mirai-core/src/commonMain/kotlin/contact/AnnouncementsImpl.kt @@ -0,0 +1,257 @@ +/* + * Copyright 2019-2021 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 + */ + +@file:Suppress("DEPRECATION") + +package net.mamoe.mirai.internal.contact + +import io.ktor.client.request.* +import io.ktor.client.request.forms.* +import io.ktor.http.* +import io.ktor.utils.io.core.* +import kotlinx.coroutines.flow.* +import kotlinx.coroutines.runBlocking +import kotlinx.coroutines.withContext +import kotlinx.serialization.json.Json +import kotlinx.serialization.json.int +import kotlinx.serialization.json.jsonObject +import kotlinx.serialization.json.jsonPrimitive +import net.mamoe.mirai.Bot +import net.mamoe.mirai.Mirai +import net.mamoe.mirai.contact.Group +import net.mamoe.mirai.contact.MemberPermission +import net.mamoe.mirai.contact.announcement.* +import net.mamoe.mirai.contact.checkBotPermission +import net.mamoe.mirai.data.GroupAnnouncement +import net.mamoe.mirai.data.GroupAnnouncementList +import net.mamoe.mirai.data.GroupAnnouncementMsg +import net.mamoe.mirai.data.GroupAnnouncementSettings +import net.mamoe.mirai.internal.asQQAndroidBot +import net.mamoe.mirai.utils.* +import net.mamoe.mirai.utils.ExternalResource.Companion.toExternalResource +import java.util.stream.Stream +import kotlin.io.use + +internal class AnnouncementsImpl( + private val group: GroupImpl, +) : Announcements { + inline val bot get() = group.bot + + override suspend fun asFlow(): Flow { + return flow { + var i = 1 + while (true) { + val result = Mirai.getRawGroupAnnouncements(bot, group.id, i++) + checkResult(result, i) + + if (result.inst.isNullOrEmpty() && result.feeds.isNullOrEmpty()) break + + result.inst?.let { emitAll(it.asFlow()) } + result.feeds?.let { emitAll(it.asFlow()) } + } + }.map { it.toAnnouncement(group) } + } + + override suspend fun asStream(): Stream { + return stream { + var i = 1 + while (true) { + val result = runBlocking { Mirai.getRawGroupAnnouncements(bot, group.id, i++) } + checkResult(result, i) + + if (result.inst.isNullOrEmpty() && result.feeds.isNullOrEmpty()) break + + result.inst?.let { yieldAll(it) } + result.feeds?.let { yieldAll(it) } + } + }.map { it.toAnnouncement(group) } + } + + private fun checkResult(result: GroupAnnouncementList, i: Int) { + if (result.ec != 0) { + bot.logger.warning { "Failed to get announcements for group ${group.id}, at page $i. result=$result" } + } + } + + override suspend fun delete(fid: String): Boolean { + group.checkBotPermission(MemberPermission.ADMINISTRATOR) { "Only administrator have permission to delete group announcement" } + return Mirai.deleteGroupAnnouncement(bot, group.id, fid) + } + + override suspend fun get(fid: String): OnlineAnnouncement? { + return Mirai.getGroupAnnouncement(bot, group.id, fid)?.toAnnouncement(group) + } + + override suspend fun publish(announcement: Announcement): OnlineAnnouncement = announcement.run { + val bot = group.bot + group.checkBotPermission(MemberPermission.ADMINISTRATOR) { "Only administrator have permission to send group announcement" } + val image = parameters.image + val fid = image?.toExternalResource()?.use { + val imageUp = AnnouncementProtocol.uploadGroupAnnouncementImage(bot, group.id, it) + AnnouncementProtocol.sendGroupAnnouncementWithImage(bot, group.id, imageUp, toGroupAnnouncement(bot.id)) + } ?: Mirai.sendGroupAnnouncement(bot, group.id, toGroupAnnouncement(bot.id)) + + return OnlineAnnouncementImpl( + group = group, + senderId = bot.id, + sender = group.botAsMember, + title = title, + body = body, + parameters = parameters, + fid = fid, + isAllRead = false, + readMemberNumber = 0, + publishTime = currentTimeSeconds() + ) + } + + override suspend fun uploadImage(resource: ExternalResource): AnnouncementImage { + return AnnouncementProtocol.uploadGroupAnnouncementImage(bot, group.id, resource) + } +} + +@Suppress("DEPRECATION") +internal object AnnouncementProtocol { + private val json = Json { + ignoreUnknownKeys = true + isLenient = true + } + + suspend fun uploadGroupAnnouncementImage( + bot: Bot, + groupId: Long, + resource: ExternalResource + ): AnnouncementImage = bot.asQQAndroidBot().run { + //https://youtrack.jetbrains.com/issue/KTOR-455 + val rep = Mirai.Http.post { + url("https://web.qun.qq.com/cgi-bin/announce/upload_img") + body = MultiPartFormDataContent(formData { + append("\"bkn\"", bkn) + append("\"source\"", "troopNotice") + append("m", "0") + append( + "\"pic_up\"", + headers = Headers.build { + append(HttpHeaders.ContentType, ContentType.Image.PNG) + append(HttpHeaders.ContentDisposition, "filename=\"temp_uploadFile.png\"") + } + ) { + writeFully(resource.inputStream().withUse { readBytes() }) + } + }) + headers { + append( + "cookie", + " p_uin=o${id};" + + " p_skey=${client.wLoginSigInfo.psKeyMap["qun.qq.com"]?.data?.encodeToString() ?: error("cookie parse p_skey error")}; " + ) + } + } + val jsonObj = json.parseToJsonElement(rep) + if (jsonObj.jsonObject["ec"]?.jsonPrimitive?.int != 0) { + throw IllegalStateException("Upload group announcement image fail group:$groupId msg:${jsonObj.jsonObject["em"]}") + } + val id = jsonObj.jsonObject["id"]?.jsonPrimitive?.content + ?: throw IllegalStateException("Upload group announcement image fail group:$groupId msg:${jsonObj.jsonObject["em"]}") + return json.decodeFromString(AnnouncementImage.serializer(), id) + } + + suspend fun sendGroupAnnouncementWithImage( + bot: Bot, + groupId: Long, + image: AnnouncementImage, + announcement: GroupAnnouncement + ): String = bot.asQQAndroidBot().run { + val rep = withContext(network.coroutineContext) { + Mirai.Http.post { + url("https://web.qun.qq.com/cgi-bin/announce/add_qun_notice") + body = MultiPartFormDataContent(formData { + append("qid", groupId) + append("bkn", bkn) + append("text", announcement.msg.text) + append("pinned", announcement.pinned) + append("pic", image.id) + append("imgWidth", image.width) + append("imgHeight", image.height) + append( + "settings", + json.encodeToString( + GroupAnnouncementSettings.serializer(), + announcement.settings ?: GroupAnnouncementSettings() + ) + ) + append("format", "json") + }) + headers { + append( + "cookie", + " p_uin=o${id};" + + " p_skey=${ + client.wLoginSigInfo.psKeyMap["qun.qq.com"]?.data?.encodeToString() ?: error( + "parse error" + ) + }; " + ) + } + + } + } + val jsonObj = json.parseToJsonElement(rep) + return jsonObj.jsonObject["new_fid"]?.jsonPrimitive?.content + ?: throw throw IllegalStateException("Send Announcement with image fail group:$groupId msg:${jsonObj.jsonObject["em"]} content:${announcement.msg.text}") + } + + +} + +@Suppress("DEPRECATION") +internal fun Announcement.toGroupAnnouncement(senderId: Long): GroupAnnouncement { + return GroupAnnouncement( + sender = senderId, + msg = GroupAnnouncementMsg( + title = title, + text = body + ), + type = if (parameters.sendToNewMember) 20 else 6, + settings = GroupAnnouncementSettings( + isShowEditCard = if (parameters.isShowEditCard) 1 else 0, + tipWindowType = if (parameters.isTip) 0 else 1, + confirmRequired = if (parameters.needConfirm) 1 else 0, + ), + pinned = if (parameters.isPinned) 1 else 0, + ) +} + +@Suppress("DEPRECATION") +private fun GroupAnnouncement.toAnnouncement(group: Group): OnlineAnnouncementImpl { + val fid = this.fid + val settings = this.settings + + check(fid != null) { "GroupAnnouncement don't have id" } + check(settings != null) { "GroupAnnouncement don't have setting" } + + return OnlineAnnouncementImpl( + group = group, + senderId = sender, + sender = group[sender], + title = msg.title ?: "", + body = msg.text, + parameters = buildAnnouncementParameters { + isPinned = pinned == 1 + sendToNewMember = type == 20 + isTip = settings.tipWindowType == 0 + needConfirm = settings.confirmRequired == 1 + isShowEditCard = settings.isShowEditCard == 1 + }, + fid = fid, + isAllRead = isAllConfirm != 0, + readMemberNumber = readNum, + publishTime = time + ) +} diff --git a/mirai-core/src/commonMain/kotlin/contact/GroupImpl.kt b/mirai-core/src/commonMain/kotlin/contact/GroupImpl.kt index 7efbe492e..5a5b18328 100644 --- a/mirai-core/src/commonMain/kotlin/contact/GroupImpl.kt +++ b/mirai-core/src/commonMain/kotlin/contact/GroupImpl.kt @@ -1,10 +1,10 @@ /* * Copyright 2019-2021 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. + * 此源代码的使用受 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/master/LICENSE + * https://github.com/mamoe/mirai/blob/dev/LICENSE */ @file:Suppress("INAPPLICABLE_JVM_NAME", "DEPRECATION_ERROR", "INVISIBLE_MEMBER", "INVISIBLE_REFERENCE") @@ -12,14 +12,12 @@ package net.mamoe.mirai.internal.contact -import kotlinx.coroutines.flow.* import net.mamoe.mirai.LowLevelApi import net.mamoe.mirai.Mirai import net.mamoe.mirai.contact.* +import net.mamoe.mirai.contact.announcement.Announcements import net.mamoe.mirai.data.GroupInfo import net.mamoe.mirai.data.MemberInfo -import net.mamoe.mirai.data.ReceiveAnnouncement -import net.mamoe.mirai.data.covertToAnnouncement import net.mamoe.mirai.event.broadcast import net.mamoe.mirai.event.events.* import net.mamoe.mirai.internal.QQAndroidBot @@ -94,6 +92,8 @@ internal class GroupImpl( } }) + override val announcements: Announcements by lazy { AnnouncementsImpl(this) } + val groupPkgMsgParsingCache = GroupPkgMsgParsingCache() override suspend fun quit(): Boolean { @@ -251,29 +251,6 @@ internal class GroupImpl( return result.success } - override suspend fun getAnnouncements(): Flow = - flow { - var i = 1 - while (true) { - val result = Mirai.getRawGroupAnnouncements(bot, id, i++) - check(result.ec == 0) { "Get Group Announcement error at page $i" } - - if (result.inst.isNullOrEmpty() && result.feeds.isNullOrEmpty()) - return@flow - - result.inst?.let { emitAll(it.asFlow()) } - result.feeds?.let { emitAll(it.asFlow()) } - } - }.map { it.covertToAnnouncement(bot.id) } - - override suspend fun deleteAnnouncement(fid: String) { - checkBotPermission(MemberPermission.ADMINISTRATOR) { "Only administrator have permission to delete group announcement" } - Mirai.deleteGroupAnnouncement(bot, id, fid) - } - - override suspend fun getAnnouncement(fid: String): ReceiveAnnouncement = - Mirai.getGroupAnnouncement(bot, id, fid).covertToAnnouncement(bot.id) - override fun toString(): String = "Group($id)" } diff --git a/mirai-core/src/commonMain/kotlin/contact/OnlineAnnouncementImpl.kt b/mirai-core/src/commonMain/kotlin/contact/OnlineAnnouncementImpl.kt new file mode 100644 index 000000000..9567aefe1 --- /dev/null +++ b/mirai-core/src/commonMain/kotlin/contact/OnlineAnnouncementImpl.kt @@ -0,0 +1,84 @@ +/* + * Copyright 2019-2021 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 + +import net.mamoe.mirai.contact.Group +import net.mamoe.mirai.contact.NormalMember +import net.mamoe.mirai.contact.announcement.AnnouncementParameters +import net.mamoe.mirai.contact.announcement.OnlineAnnouncement + +/** + * Note: Online is not designed to be serializable + * + * @since 2.7 + */ +//@SerialName(OnlineAnnouncementImpl.SERIAL_NAME) +//@Serializable(OnlineAnnouncementImpl.Serializer::class) +internal class OnlineAnnouncementImpl constructor( + override val group: Group, + override val senderId: Long, + override val sender: NormalMember?, + override val title: String, + override val body: String, + override val parameters: AnnouncementParameters, + override val fid: String, + override val isAllRead: Boolean, + override val readMemberNumber: Int, + override val publishTime: Long, +) : OnlineAnnouncement { +// +// @Serializable +// private data class SerialData( +// val botId: Long, +// val groupId: Long, +// val memberId: Long, +// val title: String, +// val body: String, +// val parameters: AnnouncementParameters, +// val fid: String, +// val isAllRead: Boolean, +// val readMemberNumber: Int, +// val publishTime: Long, +// ) +// +// internal object Serializer : KSerializer by SerialData.serializer().map( +// SerialData.serializer().descriptor.copy(SERIAL_NAME), +// { +// OnlineAnnouncementImpl( +// sender = Bot.getInstance(botId).getGroupOrFail(groupId).getMemberOrFail(memberId), +// title = title, +// body = body, +// parameters = parameters, +// fid = Fid(fid), +// isAllRead = isAllRead, +// readMemberNumber = readMemberNumber, +// publishTime = publishTime +// ) +// }, +// { +// SerialData( +// botId = sender.bot.id, +// groupId = sender.group.id, +// memberId = sender.id, +// title = title, +// body = body, +// parameters = parameters, +// fid = fid.toString(), +// isAllRead = isAllRead, +// readMemberNumber = readMemberNumber, +// publishTime = publishTime +// ) +// } +// ) + +// companion object { +// const val SERIAL_NAME: String = "ReceiveAnnouncement" +// } +} \ No newline at end of file