Redesign Announcement API

Co-authored-by: Karlatemp <karlatemp@vip.qq.com>
This commit is contained in:
Him188 2021-07-04 17:58:15 +08:00
parent 194d34d309
commit f5ce64ba4f
18 changed files with 1249 additions and 660 deletions

View File

@ -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 <init> (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 <init> ()V
public final fun builder ()Lnet/mamoe/mirai/data/AnnouncementParametersBuilder;
public synthetic fun <init> (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 <init> ()V
public fun <init> (Lnet/mamoe/mirai/data/AnnouncementParameters;)V
public synthetic fun <init> (Lnet/mamoe/mirai/data/AnnouncementParameters;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
public final fun build ()Lnet/mamoe/mirai/data/AnnouncementParameters;
public fun <init> (Lnet/mamoe/mirai/contact/announcement/AnnouncementParameters;)V
public synthetic fun <init> (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;

View File

@ -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 <init> (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 <init> ()V
public final fun builder ()Lnet/mamoe/mirai/data/AnnouncementParametersBuilder;
public synthetic fun <init> (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 <init> ()V
public fun <init> (Lnet/mamoe/mirai/data/AnnouncementParameters;)V
public synthetic fun <init> (Lnet/mamoe/mirai/data/AnnouncementParameters;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
public final fun build ()Lnet/mamoe/mirai/data/AnnouncementParameters;
public fun <init> (Lnet/mamoe/mirai/contact/announcement/AnnouncementParameters;)V
public synthetic fun <init> (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;

View File

@ -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?
/**

View File

@ -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<NormalMember>
/**
* 获取群公告相关功能接口
* @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<Announcement>
/**
* 删除一条群公告
* @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)
}
}

View File

@ -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)

View File

@ -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"
}
}

View File

@ -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()
}
}

View File

@ -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()
}

View File

@ -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<OnlineAnnouncement>
/**
* 创建一个能获取该群内所有群公告列表的 [Stream]. [Stream] 被使用时才会分页下载 [OnlineAnnouncement].
*/
public suspend fun asStream(): Stream<OnlineAnnouncement>
/**
* 获取所有群公告列表, 将全部 [OnlineAnnouncement] 都下载后再返回.
* @return 此时刻的群公告列表
*/
public suspend fun toList(): List<OnlineAnnouncement> = 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
}

View File

@ -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<OfflineAnnouncement> by OfflineAnnouncementImpl.serializer().map(
resultantDescriptor = OfflineAnnouncementImpl.serializer().descriptor.copy(SERIAL_NAME),
deserialize = { it },
serialize = { it.safeCast<OfflineAnnouncementImpl>() ?: 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)"
}

View File

@ -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-01T000000Z 的秒数)
*
* @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

View File

@ -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-01T000000Z 的秒数)
*
* @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,
)
}

View File

@ -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<GroupAnnouncement>? = null, //群公告列表
val inst: List<GroupAnnouncement>? = 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
)

View File

@ -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 <T> stream(@BuilderInference noinline block: suspend SequenceScope<T>.() -> Unit): Stream<T> =
sequence(block).asStream()

View File

@ -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<String> {
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<String> {
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<String> {
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<String> {
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<String> {

View File

@ -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<OnlineAnnouncement> {
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<OnlineAnnouncement> {
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<String> {
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<String> {
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
)
}

View File

@ -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<ReceiveAnnouncement> =
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)"
}

View File

@ -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<OnlineAnnouncementImpl> 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"
// }
}