mirror of
https://github.com/mamoe/mirai.git
synced 2025-02-05 11:37:00 +08:00
Merge remote-tracking branch 'origin/dev' into maven-central
# Conflicts: # .github/workflows/bintray.yml # .github/workflows/release.yml
This commit is contained in:
commit
32ef89add1
12
.github/workflows/build.yml
vendored
12
.github/workflows/build.yml
vendored
@ -19,13 +19,13 @@ jobs:
|
||||
run: chmod -R 777 *
|
||||
|
||||
- name: Init gradle project
|
||||
run: ./gradlew clean --info --stacktrace
|
||||
run: ./gradlew clean --scan
|
||||
|
||||
- name: Build mirai-core series
|
||||
run: ./gradlew assemble --info --stacktrace
|
||||
run: ./gradlew assemble --scan
|
||||
|
||||
- name: mirai-core Tests
|
||||
run: ./gradlew check --info --stacktrace
|
||||
run: ./gradlew check --scan
|
||||
|
||||
build-all:
|
||||
runs-on: ubuntu-latest
|
||||
@ -45,10 +45,10 @@ jobs:
|
||||
run: chmod -R 777 *
|
||||
|
||||
- name: Init gradle project
|
||||
run: ./gradlew clean --info --stacktrace
|
||||
run: ./gradlew clean --scan
|
||||
|
||||
- name: Build all
|
||||
run: ./gradlew assemble --info --stacktrace
|
||||
run: ./gradlew assemble --scan
|
||||
|
||||
- name: All Tests
|
||||
run: ./gradlew check --info --stacktrace
|
||||
run: ./gradlew check --scan
|
||||
|
16
.github/workflows/release.yml
vendored
16
.github/workflows/release.yml
vendored
@ -51,7 +51,7 @@ jobs:
|
||||
BINTRAY_KEY: ${{ secrets.BINTRAY_KEY }}
|
||||
|
||||
- name: Init gradle project
|
||||
run: ./gradlew clean --info
|
||||
run: ./gradlew clean --scan
|
||||
|
||||
- name: Check keys
|
||||
run: >
|
||||
@ -68,25 +68,25 @@ jobs:
|
||||
- name: fillBuildConstants
|
||||
run: >
|
||||
./gradlew
|
||||
fillBuildConstants --info --stacktrace
|
||||
fillBuildConstants --scan
|
||||
|
||||
- name: Assemble
|
||||
run: ./gradlew assemble --info --stacktrace
|
||||
run: ./gradlew assemble --scan
|
||||
|
||||
- name: Check
|
||||
run: ./gradlew check --info --stacktrace
|
||||
run: ./gradlew check --scan
|
||||
|
||||
- name: Gradle :mirai-core-utils:publish
|
||||
run: >
|
||||
./gradlew :mirai-core-utils:publish --info --stacktrace
|
||||
./gradlew :mirai-core-utils:publish --scan
|
||||
|
||||
- name: Gradle :mirai-core-api:publish
|
||||
run: >
|
||||
./gradlew :mirai-core-api:publish --info --stacktrace
|
||||
./gradlew :mirai-core-api:publish --scan
|
||||
|
||||
- name: Gradle :mirai-core:publish
|
||||
run: >
|
||||
./gradlew :mirai-core:publish --info --stacktrace
|
||||
./gradlew :mirai-core:publish --scan
|
||||
|
||||
- name: Gradle :mirai-core-all:publish
|
||||
run: >
|
||||
@ -115,7 +115,7 @@ jobs:
|
||||
- name: Publish Gradle plugin
|
||||
run: >
|
||||
./gradlew
|
||||
:mirai-console-gradle:publishPlugins --info --stacktrace
|
||||
:mirai-console-gradle:publishPlugins --scan
|
||||
-Dgradle.publish.key=${{ secrets.GRADLE_PUBLISH_KEY }} -Pgradle.publish.key=${{ secrets.GRADLE_PUBLISH_KEY }}
|
||||
-Dgradle.publish.secret=${{ secrets.GRADLE_PUBLISH_SECRET }} -Pgradle.publish.secret=${{ secrets.GRADLE_PUBLISH_SECRET }}
|
||||
|
||||
|
@ -89,25 +89,16 @@ public abstract interface class net/mamoe/mirai/IMirai : net/mamoe/mirai/LowLeve
|
||||
public fun calculateGroupUinByGroupCode (J)J
|
||||
public abstract fun constructMessageSource (JLnet/mamoe/mirai/message/data/MessageSourceKind;JJ[II[ILnet/mamoe/mirai/message/data/MessageChain;)Lnet/mamoe/mirai/message/data/OfflineMessageSource;
|
||||
public abstract fun createImage (Ljava/lang/String;)Lnet/mamoe/mirai/message/data/Image;
|
||||
public synthetic fun deleteGroupAnnouncement (Lnet/mamoe/mirai/Bot;JLjava/lang/String;)Lkotlin/Unit;
|
||||
public fun deleteGroupAnnouncement (Lnet/mamoe/mirai/Bot;JLjava/lang/String;)V
|
||||
public fun downloadForwardMessage (Lnet/mamoe/mirai/Bot;Ljava/lang/String;)Ljava/util/List;
|
||||
public abstract fun downloadForwardMessage (Lnet/mamoe/mirai/Bot;Ljava/lang/String;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
|
||||
public fun downloadLongMessage (Lnet/mamoe/mirai/Bot;Ljava/lang/String;)Lnet/mamoe/mirai/message/data/MessageChain;
|
||||
public abstract fun downloadLongMessage (Lnet/mamoe/mirai/Bot;Ljava/lang/String;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
|
||||
public abstract fun getBotFactory ()Lnet/mamoe/mirai/BotFactory;
|
||||
public abstract fun getFileCacheStrategy ()Lnet/mamoe/mirai/utils/FileCacheStrategy;
|
||||
public fun getGroupAnnouncement (Lnet/mamoe/mirai/Bot;JLjava/lang/String;)Lnet/mamoe/mirai/data/GroupAnnouncement;
|
||||
public fun getGroupVoiceDownloadUrl (Lnet/mamoe/mirai/Bot;[BJJ)Ljava/lang/String;
|
||||
public abstract fun getHttp ()Lio/ktor/client/HttpClient;
|
||||
public fun getOnlineOtherClientsList (Lnet/mamoe/mirai/Bot;Z)Ljava/util/List;
|
||||
public abstract fun getOnlineOtherClientsList (Lnet/mamoe/mirai/Bot;ZLkotlin/coroutines/Continuation;)Ljava/lang/Object;
|
||||
public static synthetic fun getOnlineOtherClientsList$default (Lnet/mamoe/mirai/IMirai;Lnet/mamoe/mirai/Bot;ZLkotlin/coroutines/Continuation;ILjava/lang/Object;)Ljava/lang/Object;
|
||||
public fun getRawGroupActiveData (Lnet/mamoe/mirai/Bot;JI)Lnet/mamoe/mirai/data/GroupActiveData;
|
||||
public fun getRawGroupAnnouncements (Lnet/mamoe/mirai/Bot;JII)Lnet/mamoe/mirai/data/GroupAnnouncementList;
|
||||
public fun getRawGroupHonorListData (Lnet/mamoe/mirai/Bot;JLnet/mamoe/mirai/data/GroupHonorType;)Lnet/mamoe/mirai/data/GroupHonorListData;
|
||||
public fun getRawGroupList (Lnet/mamoe/mirai/Bot;)Lkotlin/sequences/Sequence;
|
||||
public fun getRawGroupMemberList (Lnet/mamoe/mirai/Bot;JJJ)Lkotlin/sequences/Sequence;
|
||||
public fun getUin (Lnet/mamoe/mirai/contact/ContactOrBot;)J
|
||||
public synthetic fun ignoreInvitedJoinGroupRequest (Lnet/mamoe/mirai/event/events/BotInvitedJoinGroupRequestEvent;)Lkotlin/Unit;
|
||||
public fun ignoreInvitedJoinGroupRequest (Lnet/mamoe/mirai/event/events/BotInvitedJoinGroupRequestEvent;)V
|
||||
@ -116,15 +107,10 @@ public abstract interface class net/mamoe/mirai/IMirai : net/mamoe/mirai/LowLeve
|
||||
public fun ignoreMemberJoinRequest (Lnet/mamoe/mirai/event/events/MemberJoinRequestEvent;Z)V
|
||||
public abstract fun ignoreMemberJoinRequest (Lnet/mamoe/mirai/event/events/MemberJoinRequestEvent;ZLkotlin/coroutines/Continuation;)Ljava/lang/Object;
|
||||
public static synthetic fun ignoreMemberJoinRequest$default (Lnet/mamoe/mirai/IMirai;Lnet/mamoe/mirai/event/events/MemberJoinRequestEvent;ZLkotlin/coroutines/Continuation;ILjava/lang/Object;)Ljava/lang/Object;
|
||||
public synthetic fun muteAnonymousMember (Lnet/mamoe/mirai/Bot;Ljava/lang/String;Ljava/lang/String;JI)Lkotlin/Unit;
|
||||
public fun muteAnonymousMember (Lnet/mamoe/mirai/Bot;Ljava/lang/String;Ljava/lang/String;JI)V
|
||||
public fun queryImageUrl (Lnet/mamoe/mirai/Bot;Lnet/mamoe/mirai/message/data/Image;)Ljava/lang/String;
|
||||
public abstract fun queryImageUrl (Lnet/mamoe/mirai/Bot;Lnet/mamoe/mirai/message/data/Image;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
|
||||
public fun queryProfile (Lnet/mamoe/mirai/Bot;J)Lnet/mamoe/mirai/data/UserProfile;
|
||||
public abstract fun queryProfile (Lnet/mamoe/mirai/Bot;JLkotlin/coroutines/Continuation;)Ljava/lang/Object;
|
||||
public fun recallFriendMessageRaw (Lnet/mamoe/mirai/Bot;J[I[II)Z
|
||||
public fun recallGroupMessageRaw (Lnet/mamoe/mirai/Bot;J[I[I)Z
|
||||
public fun recallGroupTempMessageRaw (Lnet/mamoe/mirai/Bot;JJ[I[II)Z
|
||||
public synthetic fun recallMessage (Lnet/mamoe/mirai/Bot;Lnet/mamoe/mirai/message/data/MessageSource;)Lkotlin/Unit;
|
||||
public fun recallMessage (Lnet/mamoe/mirai/Bot;Lnet/mamoe/mirai/message/data/MessageSource;)V
|
||||
public abstract fun recallMessage (Lnet/mamoe/mirai/Bot;Lnet/mamoe/mirai/message/data/MessageSource;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
|
||||
@ -136,17 +122,10 @@ public abstract interface class net/mamoe/mirai/IMirai : net/mamoe/mirai/LowLeve
|
||||
public fun rejectNewFriendRequest (Lnet/mamoe/mirai/event/events/NewFriendRequestEvent;Z)V
|
||||
public abstract fun rejectNewFriendRequest (Lnet/mamoe/mirai/event/events/NewFriendRequestEvent;ZLkotlin/coroutines/Continuation;)Ljava/lang/Object;
|
||||
public static synthetic fun rejectNewFriendRequest$default (Lnet/mamoe/mirai/IMirai;Lnet/mamoe/mirai/event/events/NewFriendRequestEvent;ZLkotlin/coroutines/Continuation;ILjava/lang/Object;)Ljava/lang/Object;
|
||||
public fun sendGroupAnnouncement (Lnet/mamoe/mirai/Bot;JLnet/mamoe/mirai/data/GroupAnnouncement;)Ljava/lang/String;
|
||||
public fun sendNudge (Lnet/mamoe/mirai/Bot;Lnet/mamoe/mirai/message/action/Nudge;Lnet/mamoe/mirai/contact/Contact;)Z
|
||||
public abstract fun sendNudge (Lnet/mamoe/mirai/Bot;Lnet/mamoe/mirai/message/action/Nudge;Lnet/mamoe/mirai/contact/Contact;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
|
||||
public abstract fun setFileCacheStrategy (Lnet/mamoe/mirai/utils/FileCacheStrategy;)V
|
||||
public abstract fun setHttp (Lio/ktor/client/HttpClient;)V
|
||||
public synthetic fun solveBotInvitedJoinGroupRequestEvent (Lnet/mamoe/mirai/Bot;JJJZ)Lkotlin/Unit;
|
||||
public fun solveBotInvitedJoinGroupRequestEvent (Lnet/mamoe/mirai/Bot;JJJZ)V
|
||||
public synthetic fun solveMemberJoinRequestEvent (Lnet/mamoe/mirai/Bot;JJLjava/lang/String;JLjava/lang/Boolean;ZLjava/lang/String;)Lkotlin/Unit;
|
||||
public fun solveMemberJoinRequestEvent (Lnet/mamoe/mirai/Bot;JJLjava/lang/String;JLjava/lang/Boolean;ZLjava/lang/String;)V
|
||||
public synthetic fun solveNewFriendRequestEvent (Lnet/mamoe/mirai/Bot;JJLjava/lang/String;ZZ)Lkotlin/Unit;
|
||||
public fun solveNewFriendRequestEvent (Lnet/mamoe/mirai/Bot;JJLjava/lang/String;ZZ)V
|
||||
}
|
||||
|
||||
public abstract interface annotation class net/mamoe/mirai/LowLevelApi : java/lang/annotation/Annotation {
|
||||
@ -183,6 +162,8 @@ public abstract interface class net/mamoe/mirai/LowLevelApiAccessor {
|
||||
public abstract fun recallGroupMessageRaw (Lnet/mamoe/mirai/Bot;J[I[ILkotlin/coroutines/Continuation;)Ljava/lang/Object;
|
||||
public fun recallGroupTempMessageRaw (Lnet/mamoe/mirai/Bot;JJ[I[II)Z
|
||||
public abstract fun recallGroupTempMessageRaw (Lnet/mamoe/mirai/Bot;JJ[I[IILkotlin/coroutines/Continuation;)Ljava/lang/Object;
|
||||
public synthetic fun refreshKeys (Lnet/mamoe/mirai/Bot;)Lkotlin/Unit;
|
||||
public fun refreshKeys (Lnet/mamoe/mirai/Bot;)V
|
||||
public abstract fun refreshKeys (Lnet/mamoe/mirai/Bot;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
|
||||
public fun sendGroupAnnouncement (Lnet/mamoe/mirai/Bot;JLnet/mamoe/mirai/data/GroupAnnouncement;)Ljava/lang/String;
|
||||
public abstract fun sendGroupAnnouncement (Lnet/mamoe/mirai/Bot;JLnet/mamoe/mirai/data/GroupAnnouncement;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
|
||||
@ -205,12 +186,9 @@ public final class net/mamoe/mirai/Mirai {
|
||||
|
||||
public abstract interface class net/mamoe/mirai/contact/AnonymousMember : net/mamoe/mirai/contact/Member {
|
||||
public abstract fun getAnonymousId ()Ljava/lang/String;
|
||||
public synthetic fun mute (I)Lkotlin/Unit;
|
||||
public fun mute (I)V
|
||||
public fun nudge ()Lnet/mamoe/mirai/message/action/MemberNudge;
|
||||
public synthetic fun nudge ()Lnet/mamoe/mirai/message/action/Nudge;
|
||||
public synthetic fun nudge ()Lnet/mamoe/mirai/message/action/UserNudge;
|
||||
public fun queryProfile ()Lnet/mamoe/mirai/data/UserProfile;
|
||||
public fun sendMessage (Ljava/lang/String;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
|
||||
public fun sendMessage (Lnet/mamoe/mirai/message/data/Message;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
|
||||
public fun uploadImage (Lnet/mamoe/mirai/utils/ExternalResource;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
|
||||
@ -373,12 +351,10 @@ public abstract interface class net/mamoe/mirai/contact/Friend : kotlinx/corouti
|
||||
public fun nudge ()Lnet/mamoe/mirai/message/action/FriendNudge;
|
||||
public synthetic fun nudge ()Lnet/mamoe/mirai/message/action/Nudge;
|
||||
public synthetic fun nudge ()Lnet/mamoe/mirai/message/action/UserNudge;
|
||||
public fun queryProfile ()Lnet/mamoe/mirai/data/UserProfile;
|
||||
public fun sendMessage (Ljava/lang/String;)Lnet/mamoe/mirai/message/MessageReceipt;
|
||||
public fun sendMessage (Ljava/lang/String;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
|
||||
public fun sendMessage (Lnet/mamoe/mirai/message/data/Message;)Lnet/mamoe/mirai/message/MessageReceipt;
|
||||
public abstract fun sendMessage (Lnet/mamoe/mirai/message/data/Message;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
|
||||
public fun uploadImage (Lnet/mamoe/mirai/utils/ExternalResource;)Lnet/mamoe/mirai/message/data/Image;
|
||||
}
|
||||
|
||||
public abstract interface class net/mamoe/mirai/contact/Group : kotlinx/coroutines/CoroutineScope, net/mamoe/mirai/contact/Contact {
|
||||
@ -405,7 +381,6 @@ public abstract interface class net/mamoe/mirai/contact/Group : kotlinx/coroutin
|
||||
public fun setEssenceMessage (Lnet/mamoe/mirai/message/data/MessageSource;)Z
|
||||
public abstract fun setEssenceMessage (Lnet/mamoe/mirai/message/data/MessageSource;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
|
||||
public abstract fun setName (Ljava/lang/String;)V
|
||||
public fun uploadImage (Lnet/mamoe/mirai/utils/ExternalResource;)Lnet/mamoe/mirai/message/data/Image;
|
||||
public fun uploadVoice (Lnet/mamoe/mirai/utils/ExternalResource;)Lnet/mamoe/mirai/message/data/Voice;
|
||||
public abstract fun uploadVoice (Lnet/mamoe/mirai/utils/ExternalResource;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
|
||||
}
|
||||
@ -441,10 +416,10 @@ public abstract interface class net/mamoe/mirai/contact/Member : net/mamoe/mirai
|
||||
public fun mute (I)V
|
||||
public abstract fun mute (ILkotlin/coroutines/Continuation;)Ljava/lang/Object;
|
||||
public abstract fun nudge ()Lnet/mamoe/mirai/message/action/MemberNudge;
|
||||
public fun queryProfile ()Lnet/mamoe/mirai/data/UserProfile;
|
||||
public fun sendMessage (Ljava/lang/String;)Lnet/mamoe/mirai/message/MessageReceipt;
|
||||
public abstract fun sendMessage (Ljava/lang/String;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
|
||||
public fun sendMessage (Lnet/mamoe/mirai/message/data/Message;)Lnet/mamoe/mirai/message/MessageReceipt;
|
||||
public abstract fun sendMessage (Lnet/mamoe/mirai/message/data/Message;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
|
||||
public fun uploadImage (Lnet/mamoe/mirai/utils/ExternalResource;)Lnet/mamoe/mirai/message/data/Image;
|
||||
}
|
||||
|
||||
public final class net/mamoe/mirai/contact/MemberKt {
|
||||
@ -490,12 +465,9 @@ public abstract interface class net/mamoe/mirai/contact/NormalMember : net/mamoe
|
||||
public synthetic fun kick (Ljava/lang/String;)Lkotlin/Unit;
|
||||
public fun kick (Ljava/lang/String;)V
|
||||
public abstract fun kick (Ljava/lang/String;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
|
||||
public synthetic fun mute (I)Lkotlin/Unit;
|
||||
public fun mute (I)V
|
||||
public fun nudge ()Lnet/mamoe/mirai/message/action/MemberNudge;
|
||||
public synthetic fun nudge ()Lnet/mamoe/mirai/message/action/Nudge;
|
||||
public synthetic fun nudge ()Lnet/mamoe/mirai/message/action/UserNudge;
|
||||
public fun queryProfile ()Lnet/mamoe/mirai/data/UserProfile;
|
||||
public fun sendMessage (Ljava/lang/String;)Lnet/mamoe/mirai/message/MessageReceipt;
|
||||
public fun sendMessage (Ljava/lang/String;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
|
||||
public fun sendMessage (Lnet/mamoe/mirai/message/data/Message;)Lnet/mamoe/mirai/message/MessageReceipt;
|
||||
@ -505,7 +477,6 @@ public abstract interface class net/mamoe/mirai/contact/NormalMember : net/mamoe
|
||||
public synthetic fun unmute ()Lkotlin/Unit;
|
||||
public fun unmute ()V
|
||||
public abstract fun unmute (Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
|
||||
public fun uploadImage (Lnet/mamoe/mirai/utils/ExternalResource;)Lnet/mamoe/mirai/message/data/Image;
|
||||
}
|
||||
|
||||
public final class net/mamoe/mirai/contact/NormalMemberKt {
|
||||
@ -518,7 +489,6 @@ public abstract interface class net/mamoe/mirai/contact/OtherClient : net/mamoe/
|
||||
public abstract fun getBot ()Lnet/mamoe/mirai/Bot;
|
||||
public fun getId ()J
|
||||
public abstract fun getInfo ()Lnet/mamoe/mirai/contact/OtherClientInfo;
|
||||
public fun sendMessage (Ljava/lang/String;)Lnet/mamoe/mirai/message/MessageReceipt;
|
||||
public fun sendMessage (Lnet/mamoe/mirai/message/data/Message;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
|
||||
public fun uploadImage (Lnet/mamoe/mirai/utils/ExternalResource;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
|
||||
}
|
||||
@ -575,12 +545,10 @@ public abstract interface class net/mamoe/mirai/contact/Stranger : kotlinx/corou
|
||||
public synthetic fun nudge ()Lnet/mamoe/mirai/message/action/Nudge;
|
||||
public fun nudge ()Lnet/mamoe/mirai/message/action/StrangerNudge;
|
||||
public synthetic fun nudge ()Lnet/mamoe/mirai/message/action/UserNudge;
|
||||
public fun queryProfile ()Lnet/mamoe/mirai/data/UserProfile;
|
||||
public fun sendMessage (Ljava/lang/String;)Lnet/mamoe/mirai/message/MessageReceipt;
|
||||
public fun sendMessage (Ljava/lang/String;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
|
||||
public fun sendMessage (Lnet/mamoe/mirai/message/data/Message;)Lnet/mamoe/mirai/message/MessageReceipt;
|
||||
public abstract fun sendMessage (Lnet/mamoe/mirai/message/data/Message;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
|
||||
public fun uploadImage (Lnet/mamoe/mirai/utils/ExternalResource;)Lnet/mamoe/mirai/message/data/Image;
|
||||
}
|
||||
|
||||
public final class net/mamoe/mirai/contact/StrangerKt {
|
||||
@ -589,10 +557,6 @@ public final class net/mamoe/mirai/contact/StrangerKt {
|
||||
}
|
||||
|
||||
public abstract interface class net/mamoe/mirai/contact/TempUser : net/mamoe/mirai/contact/User {
|
||||
public fun queryProfile ()Lnet/mamoe/mirai/data/UserProfile;
|
||||
public fun sendMessage (Ljava/lang/String;)Lnet/mamoe/mirai/message/MessageReceipt;
|
||||
public fun sendMessage (Lnet/mamoe/mirai/message/data/Message;)Lnet/mamoe/mirai/message/MessageReceipt;
|
||||
public fun uploadImage (Lnet/mamoe/mirai/utils/ExternalResource;)Lnet/mamoe/mirai/message/data/Image;
|
||||
}
|
||||
|
||||
public abstract interface class net/mamoe/mirai/contact/User : kotlinx/coroutines/CoroutineScope, net/mamoe/mirai/contact/Contact, net/mamoe/mirai/contact/UserOrBot {
|
||||
@ -606,7 +570,6 @@ public abstract interface class net/mamoe/mirai/contact/User : kotlinx/coroutine
|
||||
public fun sendMessage (Ljava/lang/String;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
|
||||
public fun sendMessage (Lnet/mamoe/mirai/message/data/Message;)Lnet/mamoe/mirai/message/MessageReceipt;
|
||||
public abstract fun sendMessage (Lnet/mamoe/mirai/message/data/Message;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
|
||||
public fun uploadImage (Lnet/mamoe/mirai/utils/ExternalResource;)Lnet/mamoe/mirai/message/data/Image;
|
||||
}
|
||||
|
||||
public final class net/mamoe/mirai/contact/UserKt {
|
||||
@ -5087,6 +5050,7 @@ public final class net/mamoe/mirai/message/data/RichMessage$Key : net/mamoe/mira
|
||||
public final class net/mamoe/mirai/message/data/RichMessageKind : java/lang/Enum {
|
||||
public static final field FORWARD Lnet/mamoe/mirai/message/data/RichMessageKind;
|
||||
public static final field LONG Lnet/mamoe/mirai/message/data/RichMessageKind;
|
||||
public static final field MUSIC_SHARE Lnet/mamoe/mirai/message/data/RichMessageKind;
|
||||
public static fun valueOf (Ljava/lang/String;)Lnet/mamoe/mirai/message/data/RichMessageKind;
|
||||
public static fun values ()[Lnet/mamoe/mirai/message/data/RichMessageKind;
|
||||
}
|
||||
@ -5401,6 +5365,7 @@ public class net/mamoe/mirai/utils/BotConfiguration {
|
||||
public static synthetic fun fileBasedDeviceInfo$default (Lnet/mamoe/mirai/utils/BotConfiguration;Ljava/lang/String;ILjava/lang/Object;)V
|
||||
public final fun getAutoReconnectOnForceOffline ()Z
|
||||
public final fun getBotLoggerSupplier ()Lkotlin/jvm/functions/Function1;
|
||||
public final fun getCacheDirSupplier ()Lkotlin/jvm/functions/Function0;
|
||||
public static final fun getDefault ()Lnet/mamoe/mirai/utils/BotConfiguration;
|
||||
public final fun getDeviceInfo ()Lkotlin/jvm/functions/Function1;
|
||||
public final fun getFirstReconnectDelayMillis ()J
|
||||
@ -5442,6 +5407,7 @@ public class net/mamoe/mirai/utils/BotConfiguration {
|
||||
public static synthetic fun redirectNetworkLogToFile$default (Lnet/mamoe/mirai/utils/BotConfiguration;Ljava/io/File;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)V
|
||||
public final fun setAutoReconnectOnForceOffline (Z)V
|
||||
public final fun setBotLoggerSupplier (Lkotlin/jvm/functions/Function1;)V
|
||||
public final fun setCacheDirSupplier (Lkotlin/jvm/functions/Function0;)V
|
||||
public final fun setDeviceInfo (Lkotlin/jvm/functions/Function1;)V
|
||||
public final fun setFirstReconnectDelayMillis (J)V
|
||||
public final fun setFriendListCache (Lnet/mamoe/mirai/utils/BotConfiguration$FriendListCache;)V
|
||||
|
@ -140,10 +140,20 @@ subprojects {
|
||||
tasks.register("cleanExceptIntellij") {
|
||||
group = "build"
|
||||
allprojects.forEach { proj ->
|
||||
if (proj.name != "mirai-console-intellij")
|
||||
if (proj.name != "mirai-console-intellij") {
|
||||
|
||||
// Type mismatch
|
||||
// proj.tasks.findByName("clean")?.let(::dependsOn)
|
||||
|
||||
proj.tasks.findByName("clean")?.let { dependsOn(it) }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extensions.findByName("buildScan")?.withGroovyBuilder {
|
||||
setProperty("termsOfServiceUrl", "https://gradle.com/terms-of-service")
|
||||
setProperty("termsOfServiceAgree", "yes")
|
||||
}
|
||||
|
||||
fun Project.useIr() {
|
||||
kotlinCompilations?.forEach { kotlinCompilation ->
|
||||
|
@ -32,7 +32,7 @@ object Versions {
|
||||
const val io = "0.1.16"
|
||||
const val coroutinesIo = "0.1.16"
|
||||
|
||||
const val blockingBridge = "1.7.4"
|
||||
const val blockingBridge = "1.10.0"
|
||||
|
||||
const val androidGradlePlugin = "3.5.3"
|
||||
|
||||
|
@ -22,7 +22,6 @@
|
||||
[NoneBot]: https://github.com/nonebot/nonebot2
|
||||
[RedBeanN/node-mirai]: https://github.com/RedBeanN/node-mirai
|
||||
[Logiase/gomirai]: https://github.com/Logiase/gomirai
|
||||
[StageGuard/mirai-rhinojs-sdk]: https://github.com/StageGuard/mirai-rhinojs-sdk
|
||||
[cyanray/mirai-cpp]: https://github.com/cyanray/mirai-cpp
|
||||
[Chlorie/miraipp]: https://github.com/Chlorie/miraipp-template
|
||||
[Executor-Cheng/mirai-CSharp]: https://github.com/Executor-Cheng/mirai-CSharp
|
||||
@ -36,29 +35,29 @@
|
||||
|
||||
[Rhino]: https://github.com/mozilla/rhino
|
||||
[OneBot]: https://github.com/howmanybots/onebot
|
||||
[Nambers/MiraiCP]: https://github.com/Nambers/MiraiCP
|
||||
|
||||
| 技术 | 实现 | 维护者及项目地址 |
|
||||
|:-------------------|:-----------------------------|:--------------------------------------------|
|
||||
| ***Mirai Http*** | Mirai 标准 | [mamoe/mirai-api-http] |
|
||||
| *OneBot Http* | [OneBot] 标准 | [yyuueexxiinngg/onebot-kotlin] |
|
||||
| `C++` | JNI | [Nambers/MiraiCP]
|
||||
| `Kotlin Scripting` | JVM | [iTXTech/mirai-kts] |
|
||||
| `Python` | *Mirai Http* | [Graia Framework][GraiaProject/Application] |
|
||||
| `Python` | *Mirai Http* / *OneBot Http* | [NoneBot] |
|
||||
| `C++` | JNI | [Nambers/MiraiCP] |
|
||||
| `C++` | *Mirai Http* | [cyanray/mirai-cpp] |
|
||||
| `C++` | *Mirai Http* | [Chlorie/miraipp] |
|
||||
| `C#` | *Mirai Http* | [Executor-Cheng/mirai-CSharp] |
|
||||
| `C#` | *Mirai Http* | [Hyperai][theGravityLab/ProjHyperai] |
|
||||
| `Rust` | *Mirai Http* | [HoshinoTented/mirai-rs] |
|
||||
| `JavaScript` | [Rhino] / JVM | [iTXTech/mirai-js] |
|
||||
| `JavaScript` | Node.js / *Mirai Http* | [RedBeanN/node-mirai] |
|
||||
| `JavaScript` | TypeScript / *Mirai Http* | [YunYouJun/mirai-ts] |
|
||||
| `JavaScript` | Node.js / *Mirai Http* | [drinkal/Mirai-js] |
|
||||
| `.Net/C#` | *Mirai Http* | [Hyperai][theGravityLab/ProjHyperai] |
|
||||
| `Go` | *Mirai Http* | [Logiase/gomirai] |
|
||||
| `易语言` | *Mirai Http* | [only52607/e-mirai] |
|
||||
| *酷 Q DLL 插件* | JNI | [iTXTech/mirai-native] |
|
||||
|
||||
> 排名不分先后
|
||||
> *想在这里添加你的项目?欢迎[提交 PR](https://github.com/mamoe/mirai/edit/dev/docs/README.md)。*
|
||||
|
||||
特别地,有一些 SDK 直接基于 mirai-core 开发,不需要 [`mirai-console`]:
|
||||
|
@ -43,6 +43,7 @@ public suspend inline fun <B : Bot> B.alsoLogin(): B = also { login() }
|
||||
*
|
||||
* @see BotFactory 构造 [Bot] 的工厂, [Bot] 唯一的构造方式.
|
||||
*/
|
||||
@JvmBlockingBridge
|
||||
public interface Bot : CoroutineScope, ContactOrBot, UserOrBot {
|
||||
/**
|
||||
* Bot 配置
|
||||
@ -161,7 +162,6 @@ public interface Bot : CoroutineScope, ContactOrBot, UserOrBot {
|
||||
* @throws LoginFailedException 正常登录失败时抛出
|
||||
* @see alsoLogin `.apply { login() }` 捷径
|
||||
*/
|
||||
@JvmBlockingBridge
|
||||
public suspend fun login()
|
||||
|
||||
/**
|
||||
@ -232,7 +232,6 @@ public interface Bot : CoroutineScope, ContactOrBot, UserOrBot {
|
||||
* 挂起协程直到 [Bot] 协程被关闭 ([Bot.close]).
|
||||
* 即使 [Bot] 离线, 也会等待直到协程关闭.
|
||||
*/
|
||||
@JvmBlockingBridge
|
||||
public suspend fun join(): Unit = supervisorJob.join()
|
||||
|
||||
|
||||
@ -243,7 +242,6 @@ public interface Bot : CoroutineScope, ContactOrBot, UserOrBot {
|
||||
*
|
||||
* @param cause 原因. 为 null 时视为正常关闭, 非 null 时视为异常关闭
|
||||
*/
|
||||
@JvmBlockingBridge
|
||||
public suspend fun closeAndJoin(cause: Throwable? = null) {
|
||||
close(cause)
|
||||
join()
|
||||
|
@ -41,6 +41,7 @@ public val Mirai: IMirai by lazy { findMiraiInstance() }
|
||||
*
|
||||
* @see Mirai 获取实例
|
||||
*/
|
||||
@JvmBlockingBridge
|
||||
public interface IMirai : LowLevelApiAccessor {
|
||||
/**
|
||||
* 请优先使用 [BotFactory.INSTANCE]
|
||||
@ -121,13 +122,11 @@ public interface IMirai : LowLevelApiAccessor {
|
||||
* @see IMirai.recallMessage (扩展函数) 接受参数 [MessageChain]
|
||||
* @see MessageSource.recall 撤回消息扩展
|
||||
*/
|
||||
@JvmBlockingBridge
|
||||
public suspend fun recallMessage(bot: Bot, source: MessageSource)
|
||||
|
||||
/**
|
||||
* 发送戳一戳消息
|
||||
*/
|
||||
@JvmBlockingBridge
|
||||
public suspend fun sendNudge(bot: Bot, nudge: Nudge, receiver: Contact): Boolean
|
||||
|
||||
/**
|
||||
@ -143,7 +142,6 @@ public interface IMirai : LowLevelApiAccessor {
|
||||
*
|
||||
* @see Image.queryUrl [Image] 的扩展函数
|
||||
*/
|
||||
@JvmBlockingBridge
|
||||
public suspend fun queryImageUrl(bot: Bot, image: Image): String
|
||||
|
||||
/**
|
||||
@ -151,7 +149,6 @@ public interface IMirai : LowLevelApiAccessor {
|
||||
*
|
||||
* @since 2.1
|
||||
*/
|
||||
@JvmBlockingBridge
|
||||
public suspend fun queryProfile(bot: Bot, targetId: Long): UserProfile
|
||||
|
||||
/**
|
||||
@ -173,7 +170,6 @@ public interface IMirai : LowLevelApiAccessor {
|
||||
/**
|
||||
* @since 2.3
|
||||
*/
|
||||
@JvmBlockingBridge
|
||||
public suspend fun downloadLongMessage(
|
||||
bot: Bot,
|
||||
resourceId: String,
|
||||
@ -182,7 +178,6 @@ public interface IMirai : LowLevelApiAccessor {
|
||||
/**
|
||||
* @since 2.3
|
||||
*/
|
||||
@JvmBlockingBridge
|
||||
public suspend fun downloadForwardMessage(
|
||||
bot: Bot,
|
||||
resourceId: String,
|
||||
@ -193,7 +188,6 @@ public interface IMirai : LowLevelApiAccessor {
|
||||
*
|
||||
* @param event 好友验证的事件对象
|
||||
*/
|
||||
@JvmBlockingBridge
|
||||
public suspend fun acceptNewFriendRequest(event: NewFriendRequestEvent)
|
||||
|
||||
/**
|
||||
@ -202,7 +196,6 @@ public interface IMirai : LowLevelApiAccessor {
|
||||
* @param event 好友验证的事件对象
|
||||
* @param blackList 拒绝后是否拉入黑名单
|
||||
*/
|
||||
@JvmBlockingBridge
|
||||
public suspend fun rejectNewFriendRequest(event: NewFriendRequestEvent, blackList: Boolean = false)
|
||||
|
||||
/**
|
||||
@ -210,7 +203,6 @@ public interface IMirai : LowLevelApiAccessor {
|
||||
*
|
||||
* @param event 加群验证的事件对象
|
||||
*/
|
||||
@JvmBlockingBridge
|
||||
public suspend fun acceptMemberJoinRequest(event: MemberJoinRequestEvent)
|
||||
|
||||
/**
|
||||
@ -219,7 +211,6 @@ public interface IMirai : LowLevelApiAccessor {
|
||||
* @param event 加群验证的事件对象
|
||||
* @param blackList 拒绝后是否拉入黑名单
|
||||
*/
|
||||
@JvmBlockingBridge
|
||||
public suspend fun rejectMemberJoinRequest(
|
||||
event: MemberJoinRequestEvent,
|
||||
blackList: Boolean = false,
|
||||
@ -230,7 +221,6 @@ public interface IMirai : LowLevelApiAccessor {
|
||||
* 获取在线的 [OtherClient] 列表
|
||||
* @param mayIncludeSelf 服务器返回的列表可能包含 [Bot] 自己. [mayIncludeSelf] 为 `false` 会排除自己
|
||||
*/
|
||||
@JvmBlockingBridge
|
||||
public suspend fun getOnlineOtherClientsList(
|
||||
bot: Bot,
|
||||
mayIncludeSelf: Boolean = false
|
||||
@ -242,7 +232,6 @@ public interface IMirai : LowLevelApiAccessor {
|
||||
* @param event 加群验证的事件对象
|
||||
* @param blackList 忽略后是否拉入黑名单
|
||||
*/
|
||||
@JvmBlockingBridge
|
||||
public suspend fun ignoreMemberJoinRequest(event: MemberJoinRequestEvent, blackList: Boolean = false)
|
||||
|
||||
/**
|
||||
@ -250,7 +239,6 @@ public interface IMirai : LowLevelApiAccessor {
|
||||
*
|
||||
* @param event 邀请入群的事件对象
|
||||
*/
|
||||
@JvmBlockingBridge
|
||||
public suspend fun acceptInvitedJoinGroupRequest(event: BotInvitedJoinGroupRequestEvent)
|
||||
|
||||
/**
|
||||
@ -258,7 +246,6 @@ public interface IMirai : LowLevelApiAccessor {
|
||||
*
|
||||
* @param event 邀请入群的事件对象
|
||||
*/
|
||||
@JvmBlockingBridge
|
||||
public suspend fun ignoreInvitedJoinGroupRequest(event: BotInvitedJoinGroupRequestEvent)
|
||||
}
|
||||
|
||||
|
@ -36,6 +36,7 @@ public annotation class LowLevelApi
|
||||
* **警告**: 所有的低级 API 都可能在任意时刻不经过任何警告和迭代就被修改. 因此非常不建议在任何情况下使用这些 API.
|
||||
*/
|
||||
@LowLevelApi
|
||||
@JvmBlockingBridge
|
||||
public interface LowLevelApiAccessor {
|
||||
/**
|
||||
* 主动刷新 keys, 如 SKey, PSKey 等.
|
||||
@ -70,7 +71,6 @@ public interface LowLevelApiAccessor {
|
||||
* @see recallMessage
|
||||
*/
|
||||
@LowLevelApi
|
||||
@JvmBlockingBridge
|
||||
public suspend fun recallGroupMessageRaw(
|
||||
bot: Bot,
|
||||
groupCode: Long,
|
||||
@ -83,7 +83,6 @@ public interface LowLevelApiAccessor {
|
||||
* @see recallMessage
|
||||
*/
|
||||
@LowLevelApi
|
||||
@JvmBlockingBridge
|
||||
public suspend fun recallFriendMessageRaw(
|
||||
bot: Bot,
|
||||
targetId: Long,
|
||||
@ -97,7 +96,6 @@ public interface LowLevelApiAccessor {
|
||||
* @see recallMessage
|
||||
*/
|
||||
@LowLevelApi
|
||||
@JvmBlockingBridge
|
||||
public suspend fun recallGroupTempMessageRaw(
|
||||
bot: Bot,
|
||||
groupUin: Long,
|
||||
@ -111,7 +109,6 @@ public interface LowLevelApiAccessor {
|
||||
* 向服务器查询群列表. 返回值高 32 bits 为 uin, 低 32 bits 为 groupCode
|
||||
*/
|
||||
@LowLevelApi
|
||||
@JvmBlockingBridge
|
||||
public suspend fun getRawGroupList(bot: Bot): Sequence<Long>
|
||||
|
||||
/**
|
||||
@ -123,7 +120,6 @@ public interface LowLevelApiAccessor {
|
||||
* @see IMirai.calculateGroupUinByGroupCode 使用 groupCode 计算 groupUin
|
||||
*/
|
||||
@LowLevelApi
|
||||
@JvmBlockingBridge
|
||||
public suspend fun getRawGroupMemberList(
|
||||
bot: Bot,
|
||||
groupUin: Long,
|
||||
@ -137,7 +133,6 @@ public interface LowLevelApiAccessor {
|
||||
*/
|
||||
@LowLevelApi
|
||||
@MiraiExperimentalApi
|
||||
@JvmBlockingBridge
|
||||
public suspend fun getRawGroupAnnouncements(
|
||||
bot: Bot,
|
||||
groupId: Long,
|
||||
@ -151,7 +146,6 @@ public interface LowLevelApiAccessor {
|
||||
* @return 公告的fid
|
||||
*/
|
||||
@LowLevelApi
|
||||
@JvmBlockingBridge
|
||||
@MiraiExperimentalApi
|
||||
public suspend fun sendGroupAnnouncement(
|
||||
bot: Bot,
|
||||
@ -165,7 +159,6 @@ public interface LowLevelApiAccessor {
|
||||
* @param fid [GroupAnnouncement.fid]
|
||||
*/
|
||||
@LowLevelApi
|
||||
@JvmBlockingBridge
|
||||
@MiraiExperimentalApi
|
||||
public suspend fun deleteGroupAnnouncement(
|
||||
bot: Bot,
|
||||
@ -178,7 +171,6 @@ public interface LowLevelApiAccessor {
|
||||
* @param fid [GroupAnnouncement.fid]
|
||||
*/
|
||||
@LowLevelApi
|
||||
@JvmBlockingBridge
|
||||
@MiraiExperimentalApi
|
||||
public suspend fun getGroupAnnouncement(
|
||||
bot: Bot,
|
||||
@ -193,7 +185,6 @@ public interface LowLevelApiAccessor {
|
||||
* page从0开始传入可以得到发言列表
|
||||
*/
|
||||
@LowLevelApi
|
||||
@JvmBlockingBridge
|
||||
@MiraiExperimentalApi
|
||||
public suspend fun getRawGroupActiveData(bot: Bot, groupId: Long, page: Int = -1): GroupActiveData
|
||||
|
||||
@ -203,7 +194,6 @@ public interface LowLevelApiAccessor {
|
||||
*/
|
||||
@LowLevelApi
|
||||
@MiraiExperimentalApi
|
||||
@JvmBlockingBridge
|
||||
public suspend fun getRawGroupHonorListData(
|
||||
bot: Bot,
|
||||
groupId: Long,
|
||||
@ -214,7 +204,6 @@ public interface LowLevelApiAccessor {
|
||||
/**
|
||||
* 处理一个账号请求添加机器人为好友的事件
|
||||
*/
|
||||
@JvmBlockingBridge
|
||||
@LowLevelApi
|
||||
public suspend fun solveNewFriendRequestEvent(
|
||||
bot: Bot,
|
||||
@ -229,7 +218,6 @@ public interface LowLevelApiAccessor {
|
||||
* 处理被邀请加入一个群请求事件
|
||||
*/
|
||||
@LowLevelApi
|
||||
@JvmBlockingBridge
|
||||
public suspend fun solveBotInvitedJoinGroupRequestEvent(
|
||||
bot: Bot,
|
||||
eventId: Long,
|
||||
@ -242,7 +230,6 @@ public interface LowLevelApiAccessor {
|
||||
* 处理账号请求加入群事件
|
||||
*/
|
||||
@LowLevelApi
|
||||
@JvmBlockingBridge
|
||||
public suspend fun solveMemberJoinRequestEvent(
|
||||
bot: Bot,
|
||||
eventId: Long,
|
||||
@ -258,7 +245,6 @@ public interface LowLevelApiAccessor {
|
||||
* 查询语音的下载连接
|
||||
*/
|
||||
@LowLevelApi
|
||||
@JvmBlockingBridge
|
||||
public suspend fun getGroupVoiceDownloadUrl(
|
||||
bot: Bot,
|
||||
md5: ByteArray,
|
||||
@ -272,7 +258,6 @@ public interface LowLevelApiAccessor {
|
||||
* @param anonymousId [AnonymousMember.anonymousId]
|
||||
*/
|
||||
@LowLevelApi
|
||||
@JvmBlockingBridge
|
||||
public suspend fun muteAnonymousMember(
|
||||
bot: Bot,
|
||||
anonymousId: String,
|
||||
|
@ -27,6 +27,7 @@ import java.io.InputStream
|
||||
/**
|
||||
* 联系对象, 即可以与 [Bot] 互动的对象. 包含 [用户][User], 和 [群][Group].
|
||||
*/
|
||||
@JvmBlockingBridge
|
||||
public interface Contact : ContactOrBot, CoroutineScope {
|
||||
/**
|
||||
* 这个联系对象所属 [Bot].
|
||||
@ -57,14 +58,12 @@ public interface Contact : ContactOrBot, CoroutineScope {
|
||||
*
|
||||
* @return 消息回执. 可 [引用][MessageReceipt.quote] 或 [撤回][MessageReceipt.recall] 这条消息.
|
||||
*/
|
||||
@JvmBlockingBridge
|
||||
public suspend fun sendMessage(message: Message): MessageReceipt<Contact>
|
||||
|
||||
/**
|
||||
* 发送纯文本消息
|
||||
* @see sendMessage
|
||||
*/
|
||||
@JvmBlockingBridge
|
||||
public suspend fun sendMessage(message: String): MessageReceipt<Contact> = this.sendMessage(message.toPlainText())
|
||||
|
||||
/**
|
||||
@ -84,9 +83,9 @@ public interface Contact : ContactOrBot, CoroutineScope {
|
||||
* @throws EventCancelledException 当发送消息事件被取消时抛出
|
||||
* @throws OverFileSizeMaxException 当图片文件过大而被服务器拒绝上传时抛出. (最大大小约为 20 MB, 但 mirai 限制的大小为 30 MB)
|
||||
*/
|
||||
@JvmBlockingBridge
|
||||
public suspend fun uploadImage(resource: ExternalResource): Image
|
||||
|
||||
@JvmBlockingBridge
|
||||
public companion object {
|
||||
/**
|
||||
* 读取 [InputStream] 到临时文件并将其作为图片发送到指定联系人
|
||||
@ -98,7 +97,6 @@ public interface Contact : ContactOrBot, CoroutineScope {
|
||||
* @see FileCacheStrategy
|
||||
*/
|
||||
@JvmStatic
|
||||
@JvmBlockingBridge
|
||||
@JvmOverloads
|
||||
public suspend fun <C : Contact> C.sendImage(
|
||||
imageStream: InputStream,
|
||||
@ -112,7 +110,6 @@ public interface Contact : ContactOrBot, CoroutineScope {
|
||||
* @see FileCacheStrategy
|
||||
*/
|
||||
@JvmStatic
|
||||
@JvmBlockingBridge
|
||||
@JvmOverloads
|
||||
public suspend fun <C : Contact> C.sendImage(
|
||||
file: File,
|
||||
@ -124,7 +121,6 @@ public interface Contact : ContactOrBot, CoroutineScope {
|
||||
*
|
||||
* @see Contact.sendMessage 最终调用, 发送消息.
|
||||
*/
|
||||
@JvmBlockingBridge
|
||||
@JvmStatic
|
||||
public suspend fun <C : Contact> C.sendImage(resource: ExternalResource): MessageReceipt<C> =
|
||||
resource.sendAsImageTo(this)
|
||||
@ -139,7 +135,6 @@ public interface Contact : ContactOrBot, CoroutineScope {
|
||||
* @throws OverFileSizeMaxException
|
||||
*/
|
||||
@JvmStatic
|
||||
@JvmBlockingBridge
|
||||
@JvmOverloads
|
||||
public suspend fun Contact.uploadImage(
|
||||
imageStream: InputStream,
|
||||
@ -152,7 +147,6 @@ public interface Contact : ContactOrBot, CoroutineScope {
|
||||
* @throws OverFileSizeMaxException
|
||||
*/
|
||||
@JvmStatic
|
||||
@JvmBlockingBridge
|
||||
@JvmOverloads
|
||||
public suspend fun Contact.uploadImage(
|
||||
file: File,
|
||||
@ -165,7 +159,6 @@ public interface Contact : ContactOrBot, CoroutineScope {
|
||||
*/
|
||||
@Throws(OverFileSizeMaxException::class)
|
||||
@JvmStatic
|
||||
@JvmBlockingBridge
|
||||
@Suppress("INVISIBLE_MEMBER", "INVISIBLE_REFERENCE", "EXTENSION_SHADOWED_BY_MEMBER")
|
||||
@kotlin.internal.LowPriorityInOverloadResolution // for better Java API
|
||||
public suspend fun Contact.uploadImage(resource: ExternalResource): Image = this.uploadImage(resource)
|
||||
|
@ -31,6 +31,7 @@ import net.mamoe.mirai.message.data.toPlainText
|
||||
*
|
||||
* @see FriendMessageEvent
|
||||
*/
|
||||
@JvmBlockingBridge
|
||||
public interface Friend : User, CoroutineScope {
|
||||
/**
|
||||
* QQ 号码
|
||||
@ -62,7 +63,6 @@ public interface Friend : User, CoroutineScope {
|
||||
*
|
||||
* @return 消息回执. 可 [引用][MessageReceipt.quote] 或 [撤回][MessageReceipt.recall] 这条消息.
|
||||
*/
|
||||
@JvmBlockingBridge
|
||||
public override suspend fun sendMessage(message: Message): MessageReceipt<Friend>
|
||||
|
||||
/**
|
||||
@ -70,14 +70,12 @@ public interface Friend : User, CoroutineScope {
|
||||
*
|
||||
* @see FriendDeleteEvent 好友删除事件
|
||||
*/
|
||||
@JvmBlockingBridge
|
||||
public suspend fun delete()
|
||||
|
||||
/**
|
||||
* 发送纯文本消息
|
||||
* @see sendMessage
|
||||
*/
|
||||
@JvmBlockingBridge
|
||||
public override suspend fun sendMessage(message: String): MessageReceipt<Friend> =
|
||||
this.sendMessage(message.toPlainText())
|
||||
|
||||
|
@ -25,6 +25,7 @@ import net.mamoe.mirai.utils.OverFileSizeMaxException
|
||||
/**
|
||||
* 群.
|
||||
*/
|
||||
@JvmBlockingBridge
|
||||
public interface Group : Contact, CoroutineScope {
|
||||
/**
|
||||
* 群名称.
|
||||
@ -123,7 +124,6 @@ public interface Group : Contact, CoroutineScope {
|
||||
* @throws IllegalStateException 当机器人为群主时
|
||||
* @return 退出成功时 true; 已经退出时 false
|
||||
*/
|
||||
@JvmBlockingBridge
|
||||
public suspend fun quit(): Boolean
|
||||
|
||||
/**
|
||||
@ -141,14 +141,12 @@ public interface Group : Contact, CoroutineScope {
|
||||
*
|
||||
* @return 消息回执. 可进行撤回 ([MessageReceipt.recall])
|
||||
*/
|
||||
@JvmBlockingBridge
|
||||
public override suspend fun sendMessage(message: Message): MessageReceipt<Group>
|
||||
|
||||
/**
|
||||
* 发送纯文本消息
|
||||
* @see sendMessage
|
||||
*/
|
||||
@JvmBlockingBridge
|
||||
public override suspend fun sendMessage(message: String): MessageReceipt<Group> =
|
||||
this.sendMessage(message.toPlainText())
|
||||
|
||||
@ -163,7 +161,6 @@ public interface Group : Contact, CoroutineScope {
|
||||
* @throws EventCancelledException 当发送消息事件被取消
|
||||
* @throws OverFileSizeMaxException 当语音文件过大而被服务器拒绝上传时. (最大大小约为 1 MB)
|
||||
*/
|
||||
@JvmBlockingBridge
|
||||
public suspend fun uploadVoice(resource: ExternalResource): Voice
|
||||
|
||||
|
||||
@ -175,7 +172,6 @@ public interface Group : Contact, CoroutineScope {
|
||||
*
|
||||
* @since 2.2
|
||||
*/
|
||||
@JvmBlockingBridge
|
||||
public suspend fun setEssenceMessage(source: MessageSource): Boolean
|
||||
|
||||
public companion object {
|
||||
|
@ -34,6 +34,7 @@ import net.mamoe.mirai.utils.WeakRefProperty
|
||||
* - [Member.asFriend] 转换为 [Friend]
|
||||
* - [Member.asStranger] 转换为 [Stranger]
|
||||
*/
|
||||
@JvmBlockingBridge
|
||||
public interface Member : User {
|
||||
/**
|
||||
* 所在的群.
|
||||
@ -79,7 +80,6 @@ public interface Member : User {
|
||||
*
|
||||
* @see Member.mute 支持 Kotlin [kotlin.time.Duration] 的扩展
|
||||
*/
|
||||
@JvmBlockingBridge
|
||||
public suspend fun mute(durationSeconds: Int)
|
||||
|
||||
/**
|
||||
|
@ -27,6 +27,7 @@ import kotlin.time.ExperimentalTime
|
||||
* 群成员可能也是好友, 但他们在对象类型上不同.
|
||||
* 群成员可以通过 [asFriend] 得到相关好友对象.
|
||||
*/
|
||||
@JvmBlockingBridge
|
||||
public interface NormalMember : Member {
|
||||
/**
|
||||
* 群名片. 可能为空.
|
||||
@ -88,7 +89,6 @@ public interface NormalMember : Member {
|
||||
*
|
||||
* @throws PermissionDeniedException 无权限修改时抛出
|
||||
*/
|
||||
@JvmBlockingBridge
|
||||
public suspend fun unmute()
|
||||
|
||||
/**
|
||||
@ -100,7 +100,6 @@ public interface NormalMember : Member {
|
||||
* @throws PermissionDeniedException 无权限修改时
|
||||
*
|
||||
*/
|
||||
@JvmBlockingBridge
|
||||
public suspend fun kick(message: String)
|
||||
|
||||
/**
|
||||
@ -122,14 +121,12 @@ public interface NormalMember : Member {
|
||||
*
|
||||
* @return 消息回执. 可进行撤回 ([MessageReceipt.recall])
|
||||
*/
|
||||
@JvmBlockingBridge
|
||||
public override suspend fun sendMessage(message: Message): MessageReceipt<NormalMember>
|
||||
|
||||
/**
|
||||
* 发送纯文本消息
|
||||
* @see sendMessage
|
||||
*/
|
||||
@JvmBlockingBridge
|
||||
public override suspend fun sendMessage(message: String): MessageReceipt<NormalMember> =
|
||||
this.sendMessage(message.toPlainText())
|
||||
|
||||
|
@ -39,6 +39,7 @@ import net.mamoe.mirai.message.data.toPlainText
|
||||
*
|
||||
* @see StrangerMessageEvent
|
||||
*/
|
||||
@JvmBlockingBridge
|
||||
public interface Stranger : User, CoroutineScope {
|
||||
/**
|
||||
* QQ 号码
|
||||
@ -66,7 +67,6 @@ public interface Stranger : User, CoroutineScope {
|
||||
*
|
||||
* @return 消息回执. 可进行撤回 ([MessageReceipt.recall])
|
||||
*/
|
||||
@JvmBlockingBridge
|
||||
public override suspend fun sendMessage(message: Message): MessageReceipt<Stranger>
|
||||
|
||||
/**
|
||||
@ -74,14 +74,12 @@ public interface Stranger : User, CoroutineScope {
|
||||
*
|
||||
* @see StrangerRelationChangeEvent.Deleted 陌生人删除事件
|
||||
*/
|
||||
@JvmBlockingBridge
|
||||
public suspend fun delete()
|
||||
|
||||
/**
|
||||
* 发送纯文本消息
|
||||
* @see sendMessage
|
||||
*/
|
||||
@JvmBlockingBridge
|
||||
public override suspend fun sendMessage(message: String): MessageReceipt<Stranger> =
|
||||
this.sendMessage(message.toPlainText())
|
||||
|
||||
|
@ -36,6 +36,7 @@ import net.mamoe.mirai.message.data.toPlainText
|
||||
*
|
||||
* 对于同一个 [Bot] 任何一个人的 [User] 实例都是单一的.
|
||||
*/
|
||||
@JvmBlockingBridge
|
||||
public interface User : Contact, UserOrBot, CoroutineScope {
|
||||
/**
|
||||
* QQ 号码
|
||||
@ -72,14 +73,12 @@ public interface User : Contact, UserOrBot, CoroutineScope {
|
||||
*
|
||||
* @return 消息回执. 可 [引用][MessageReceipt.quote] 或 [撤回][MessageReceipt.recall] 这条消息.
|
||||
*/
|
||||
@JvmBlockingBridge
|
||||
public override suspend fun sendMessage(message: Message): MessageReceipt<User>
|
||||
|
||||
/**
|
||||
* 发送纯文本消息
|
||||
* @see sendMessage
|
||||
*/
|
||||
@JvmBlockingBridge
|
||||
public override suspend fun sendMessage(message: String): MessageReceipt<User> =
|
||||
this.sendMessage(message.toPlainText())
|
||||
|
||||
@ -95,7 +94,6 @@ public interface User : Contact, UserOrBot, CoroutineScope {
|
||||
*
|
||||
* @since 2.1
|
||||
*/
|
||||
@JvmBlockingBridge
|
||||
public suspend fun queryProfile(): UserProfile = Mirai.queryProfile(bot, this.id)
|
||||
}
|
||||
|
||||
|
@ -39,6 +39,7 @@ import net.mamoe.mirai.utils.MiraiInternalApi
|
||||
* @see MessageReceipt.sourceIds 源 ids
|
||||
* @see MessageReceipt.sourceTime 源时间
|
||||
*/
|
||||
@JvmBlockingBridge
|
||||
public open class MessageReceipt<out C : Contact> @MiraiInternalApi constructor(
|
||||
/**
|
||||
* 指代发送出去的消息.
|
||||
@ -59,7 +60,6 @@ public open class MessageReceipt<out C : Contact> @MiraiInternalApi constructor(
|
||||
*
|
||||
* @see IMirai.recallMessage
|
||||
*/
|
||||
@JvmBlockingBridge
|
||||
public suspend inline fun recall() {
|
||||
return Mirai.recallMessage(target.bot, source)
|
||||
}
|
||||
@ -82,7 +82,6 @@ public open class MessageReceipt<out C : Contact> @MiraiInternalApi constructor(
|
||||
* 引用这条消息并回复.
|
||||
* @see MessageSource.quote 引用一条消息
|
||||
*/
|
||||
@JvmBlockingBridge
|
||||
public suspend inline fun quoteReply(message: Message): MessageReceipt<C> {
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
return target.sendMessage(this.quote() + message) as MessageReceipt<C>
|
||||
@ -92,7 +91,6 @@ public open class MessageReceipt<out C : Contact> @MiraiInternalApi constructor(
|
||||
* 引用这条消息并回复.
|
||||
* @see MessageSource.quote 引用一条消息
|
||||
*/
|
||||
@JvmBlockingBridge
|
||||
public suspend inline fun quoteReply(message: String): MessageReceipt<C> {
|
||||
return this.quoteReply(PlainText(message))
|
||||
}
|
||||
|
@ -98,6 +98,9 @@ public interface RichMessage : MessageContent, ConstrainSingle {
|
||||
@Serializable
|
||||
@SerialName(LightApp.SERIAL_NAME)
|
||||
public data class LightApp(override val content: String) : RichMessage, CodableMessage {
|
||||
// implementation notes: LightApp is always decoded as LightAppInternal
|
||||
// which are transformed as RefinableMessage to LightApp
|
||||
|
||||
public companion object Key : AbstractMessageKey<LightApp>({ it.safeCast() }) {
|
||||
public const val SERIAL_NAME: String = "LightApp"
|
||||
}
|
||||
|
@ -108,8 +108,14 @@ public enum class RichMessageKind {
|
||||
|
||||
/**
|
||||
* 合并转发
|
||||
* @see ForwardMessage
|
||||
*/
|
||||
FORWARD,
|
||||
|
||||
// TODO: 2021/2/3 MusicShare RichMessageKind
|
||||
/**
|
||||
* 音乐分享
|
||||
* @see MusicShare
|
||||
* @since 2.4
|
||||
*/
|
||||
MUSIC_SHARE,
|
||||
}
|
@ -56,6 +56,11 @@ public open class BotConfiguration { // open for Java
|
||||
*/
|
||||
public var workingDir: File = File(".")
|
||||
|
||||
/**
|
||||
* 缓存数据目录
|
||||
*/
|
||||
public var cacheDirSupplier: (() -> File) = { workingDir.resolve("cache") }
|
||||
|
||||
/**
|
||||
* Json 序列化器, 使用 'kotlinx.serialization'
|
||||
*/
|
||||
@ -396,11 +401,11 @@ public open class BotConfiguration { // open for Java
|
||||
*/
|
||||
public class FriendListCache @JvmOverloads constructor(
|
||||
/**
|
||||
* 缓存文件位置, 相对于 [workingDir] 的路径.
|
||||
* 缓存文件位置, 相对于 [cacheDirSupplier] 的路径.
|
||||
*
|
||||
* 注意: 保存的文件仅供内部使用, 将来可能会变化.
|
||||
*/
|
||||
public val cacheFile: File = File("cache/friends.json"),
|
||||
public val cacheFile: File = File("friends.json"),
|
||||
/**
|
||||
* 在有好友列表修改时自动保存间隔
|
||||
*/
|
||||
@ -432,11 +437,11 @@ public open class BotConfiguration { // open for Java
|
||||
*/
|
||||
public class GroupMemberListCache @JvmOverloads constructor(
|
||||
/**
|
||||
* 缓存目录位置, 相对于 [workingDir] 的路径.
|
||||
* 缓存目录位置, 相对于 [cacheDirSupplier] 的路径.
|
||||
*
|
||||
* 注意: 保存的文件仅供内部使用, 将来可能会变化.
|
||||
*/
|
||||
public val cacheDir: File = File("cache/groups"),
|
||||
public val cacheDir: File = File("groups"),
|
||||
/**
|
||||
* 在有成员列表修改时自动保存间隔
|
||||
*/
|
||||
@ -470,6 +475,7 @@ public open class BotConfiguration { // open for Java
|
||||
return BotConfiguration().also { new ->
|
||||
// To structural order
|
||||
new.workingDir = workingDir
|
||||
new.cacheDirSupplier = cacheDirSupplier
|
||||
new.json = json
|
||||
new.parentCoroutineContext = parentCoroutineContext
|
||||
new.heartbeatPeriodMillis = heartbeatPeriodMillis
|
||||
|
@ -68,7 +68,7 @@ internal abstract class AbstractBot<N : BotNetworkHandler> constructor(
|
||||
}
|
||||
|
||||
// region network
|
||||
internal val serverList: MutableList<Pair<String, Int>> = DefaultServerList.toMutableList()
|
||||
internal val serverList: MutableList<Pair<String, Int>> = mutableListOf()
|
||||
|
||||
val network: N get() = _network
|
||||
|
||||
@ -148,8 +148,11 @@ internal abstract class AbstractBot<N : BotNetworkHandler> constructor(
|
||||
bot.logger.info { "Connection lost, retrying login ($causeMessage)" }
|
||||
|
||||
bot.asQQAndroidBot().client.run {
|
||||
if (serverList.isEmpty()) {
|
||||
bot.asQQAndroidBot().bdhSyncer.loadServerListFromCache()
|
||||
if (serverList.isEmpty()) {
|
||||
serverList.addAll(DefaultServerList)
|
||||
} else Unit
|
||||
} else serverList.removeAt(0)
|
||||
}
|
||||
|
||||
|
@ -25,6 +25,7 @@ import net.mamoe.mirai.internal.contact.info.StrangerInfoImpl
|
||||
import net.mamoe.mirai.internal.contact.uin
|
||||
import net.mamoe.mirai.internal.message.*
|
||||
import net.mamoe.mirai.internal.network.*
|
||||
import net.mamoe.mirai.internal.network.handler.BdhSessionSyncer
|
||||
import net.mamoe.mirai.internal.network.handler.QQAndroidBotNetworkHandler
|
||||
import net.mamoe.mirai.internal.network.protocol.packet.OutgoingPacket
|
||||
import net.mamoe.mirai.internal.network.protocol.packet.OutgoingPacketWithRespType
|
||||
@ -57,6 +58,8 @@ internal class QQAndroidBot constructor(
|
||||
private val account: BotAccount,
|
||||
configuration: BotConfiguration
|
||||
) : AbstractBot<QQAndroidBotNetworkHandler>(configuration, account.id) {
|
||||
val bdhSyncer: BdhSessionSyncer = BdhSessionSyncer(this)
|
||||
|
||||
var client: QQAndroidClient = initClient()
|
||||
private set
|
||||
|
||||
@ -79,7 +82,7 @@ internal class QQAndroidBot constructor(
|
||||
|
||||
val friendListCache: FriendListCache? by lazy {
|
||||
configuration.friendListCache?.cacheFile?.let { cacheFile ->
|
||||
val ret = configuration.workingDir.resolve(cacheFile).loadAs(FriendListCache.serializer(), JsonForCache) ?: FriendListCache()
|
||||
val ret = configuration.cacheDirSupplier().resolve(cacheFile).loadAs(FriendListCache.serializer(), JsonForCache) ?: FriendListCache()
|
||||
|
||||
@Suppress("INVISIBLE_MEMBER", "INVISIBLE_REFERENCE")
|
||||
bot.eventChannel.parentScope(this@QQAndroidBot)
|
||||
@ -130,6 +133,7 @@ internal class QQAndroidBot constructor(
|
||||
@ThisApiMustBeUsedInWithConnectionLockBlock
|
||||
@Throws(LoginFailedException::class) // only
|
||||
override suspend fun relogin(cause: Throwable?) {
|
||||
bdhSyncer.loadFromCache()
|
||||
client.useNextServers { host, port ->
|
||||
network.closeEverythingAndRelogin(host, port, cause, 0)
|
||||
}
|
||||
|
@ -87,6 +87,9 @@ internal data class ForwardMessageInternal(override val content: String, val res
|
||||
|
||||
internal interface RefinableMessage : SingleMessage {
|
||||
|
||||
/**
|
||||
* This message [RefinableMessage] will be replaced by return value of [refine]
|
||||
*/
|
||||
suspend fun refine(
|
||||
contact: Contact,
|
||||
context: MessageChain,
|
||||
|
@ -278,7 +278,7 @@ private object ReceiveMessageTransformer {
|
||||
}
|
||||
}
|
||||
|
||||
list.add(LightApp(content).refine())
|
||||
list.add(LightAppInternal(content))
|
||||
}
|
||||
|
||||
private fun decodeCustomElem(
|
||||
|
@ -12,42 +12,48 @@ package net.mamoe.mirai.internal.message
|
||||
import kotlinx.serialization.SerialName
|
||||
import kotlinx.serialization.Serializable
|
||||
import kotlinx.serialization.json.Json
|
||||
import net.mamoe.mirai.message.data.LightApp
|
||||
import net.mamoe.mirai.message.data.MusicKind
|
||||
import net.mamoe.mirai.message.data.MusicShare
|
||||
import net.mamoe.mirai.message.data.SingleMessage
|
||||
import net.mamoe.mirai.contact.Contact
|
||||
import net.mamoe.mirai.message.data.*
|
||||
import net.mamoe.mirai.utils.safeCast
|
||||
|
||||
private val json = Json {
|
||||
ignoreUnknownKeys = true
|
||||
}
|
||||
internal data class LightAppInternal(
|
||||
override val content: String
|
||||
) : RichMessage, RefinableMessage {
|
||||
companion object Key :
|
||||
AbstractPolymorphicMessageKey<RichMessage, LightAppInternal>(RichMessage, { it.safeCast() })
|
||||
|
||||
internal fun LightApp.tryDeserialize(): LightAppStruct? {
|
||||
return kotlin.runCatching {
|
||||
json.decodeFromString(LightAppStruct.serializer(), this.content)
|
||||
}.getOrNull()
|
||||
}
|
||||
|
||||
/**
|
||||
* 识别 app 内容, 如果有必要
|
||||
*/
|
||||
internal fun LightApp.refine(): SingleMessage {
|
||||
val struct = tryDeserialize() ?: return this
|
||||
override suspend fun refine(contact: Contact, context: MessageChain): Message {
|
||||
val struct = tryDeserialize() ?: return LightApp(content)
|
||||
struct.run {
|
||||
if (meta.music != null) {
|
||||
MusicKind.values().find { it.appId.toInt() == meta.music.appid }?.let { musicType ->
|
||||
meta.music.run {
|
||||
return MusicShare(
|
||||
return RichMessageOrigin(
|
||||
LightApp(content),
|
||||
null,
|
||||
RichMessageKind.MUSIC_SHARE
|
||||
) + MusicShare(
|
||||
kind = musicType, title = title, summary = desc,
|
||||
jumpUrl = jumpUrl, pictureUrl = preview, musicUrl = musicUrl, brief = prompt
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
return this
|
||||
return LightApp(content)
|
||||
}
|
||||
}
|
||||
|
||||
private val json = Json {
|
||||
ignoreUnknownKeys = true
|
||||
isLenient = true
|
||||
}
|
||||
|
||||
internal fun LightAppInternal.tryDeserialize(): LightAppStruct? {
|
||||
return kotlin.runCatching {
|
||||
json.decodeFromString(LightAppStruct.serializer(), this.content)
|
||||
}.getOrNull()
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -84,7 +84,7 @@ internal class GroupMemberListCaches(
|
||||
}
|
||||
|
||||
private val cacheDir by lazy {
|
||||
bot.configuration.groupMemberListCache!!.cacheDir.let { bot.configuration.workingDir.resolve(it) }
|
||||
bot.configuration.groupMemberListCache!!.cacheDir.let { bot.configuration.cacheDirSupplier().resolve(it) }
|
||||
}
|
||||
|
||||
private fun resolveCacheFile(groupCode: Long): File {
|
||||
|
@ -19,6 +19,7 @@ import kotlinx.io.core.BytePacketBuilder
|
||||
import kotlinx.io.core.String
|
||||
import kotlinx.io.core.toByteArray
|
||||
import kotlinx.io.core.writeFully
|
||||
import kotlinx.serialization.Serializable
|
||||
import net.mamoe.mirai.data.OnlineStatus
|
||||
import net.mamoe.mirai.internal.BotAccount
|
||||
import net.mamoe.mirai.internal.QQAndroidBot
|
||||
@ -281,11 +282,6 @@ internal open class QQAndroidClient(
|
||||
|
||||
lateinit var t104: ByteArray
|
||||
|
||||
/**
|
||||
* from ConfigPush.PushReq
|
||||
*/
|
||||
@JvmField
|
||||
val bdhSession: CompletableDeferred<BdhSession> = CompletableDeferred()
|
||||
}
|
||||
|
||||
internal fun BytePacketBuilder.writeLoginExtraData(loginExtraData: LoginExtraData) {
|
||||
@ -298,6 +294,7 @@ internal fun BytePacketBuilder.writeLoginExtraData(loginExtraData: LoginExtraDat
|
||||
}
|
||||
}
|
||||
|
||||
@Serializable
|
||||
internal class BdhSession(
|
||||
val sigSession: ByteArray,
|
||||
val sessionKey: ByteArray,
|
||||
|
@ -0,0 +1,120 @@
|
||||
/*
|
||||
* 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
|
||||
*/
|
||||
|
||||
package net.mamoe.mirai.internal.network.handler
|
||||
|
||||
import kotlinx.coroutines.CompletableDeferred
|
||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||
import kotlinx.serialization.KSerializer
|
||||
import kotlinx.serialization.builtins.ListSerializer
|
||||
import kotlinx.serialization.builtins.PairSerializer
|
||||
import kotlinx.serialization.builtins.serializer
|
||||
import net.mamoe.mirai.internal.QQAndroidBot
|
||||
import net.mamoe.mirai.internal.network.BdhSession
|
||||
import net.mamoe.mirai.internal.network.JsonForCache
|
||||
import java.io.File
|
||||
|
||||
private val ServerListSerializer: KSerializer<List<Pair<String, Int>>> =
|
||||
ListSerializer(PairSerializer(String.serializer(), Int.serializer()))
|
||||
|
||||
@OptIn(ExperimentalCoroutinesApi::class)
|
||||
internal class BdhSessionSyncer(
|
||||
private val bot: QQAndroidBot
|
||||
) {
|
||||
var bdhSession: CompletableDeferred<BdhSession> = CompletableDeferred()
|
||||
val hasSession: Boolean get() = bdhSession.isCompleted
|
||||
|
||||
fun overrideSession(
|
||||
session: BdhSession,
|
||||
doSave: Boolean = true
|
||||
) {
|
||||
bdhSession.complete(session)
|
||||
bdhSession = CompletableDeferred(session)
|
||||
if (doSave) {
|
||||
saveToCache()
|
||||
}
|
||||
}
|
||||
|
||||
private val sessionCacheFile: File
|
||||
get() = bot.configuration.cacheDirSupplier().resolve("session.json")
|
||||
private val serverListCacheFile: File
|
||||
get() = bot.configuration.cacheDirSupplier().resolve("serverlist.json")
|
||||
|
||||
fun loadServerListFromCache() {
|
||||
val serverListCacheFile = this.serverListCacheFile
|
||||
if (serverListCacheFile.isFile) {
|
||||
bot.network.logger.verbose("Loading server list from cache.")
|
||||
kotlin.runCatching {
|
||||
val list = JsonForCache.decodeFromString(ServerListSerializer, serverListCacheFile.readText())
|
||||
bot.serverList.clear()
|
||||
bot.serverList.addAll(list)
|
||||
}.onFailure {
|
||||
bot.network.logger.warning("Error in loading server list from cache", it)
|
||||
}
|
||||
} else {
|
||||
bot.network.logger.verbose("No server list cached.")
|
||||
}
|
||||
}
|
||||
|
||||
fun loadFromCache() {
|
||||
val sessionCacheFile = this.sessionCacheFile
|
||||
if (sessionCacheFile.isFile) {
|
||||
bot.network.logger.verbose("Loading BdhSession from cache file")
|
||||
kotlin.runCatching {
|
||||
overrideSession(
|
||||
JsonForCache.decodeFromString(BdhSession.serializer(), sessionCacheFile.readText()),
|
||||
doSave = false
|
||||
)
|
||||
}.onFailure {
|
||||
bot.network.logger.warning("Error in loading BdhSession from cache", it)
|
||||
}
|
||||
} else {
|
||||
bot.network.logger.verbose("No BdhSession cache")
|
||||
}
|
||||
}
|
||||
|
||||
fun saveServerListToCache() {
|
||||
val serverListCacheFile = this.serverListCacheFile
|
||||
serverListCacheFile.parentFile?.mkdirs()
|
||||
|
||||
bot.network.logger.verbose("Saving server list to cache")
|
||||
kotlin.runCatching {
|
||||
serverListCacheFile.writeText(
|
||||
JsonForCache.encodeToString(
|
||||
ServerListSerializer,
|
||||
bot.serverList
|
||||
)
|
||||
)
|
||||
}.onFailure {
|
||||
bot.network.logger.warning("Error in saving ServerList to cache.", it)
|
||||
}
|
||||
}
|
||||
|
||||
fun saveToCache() {
|
||||
val sessionCacheFile = this.sessionCacheFile
|
||||
sessionCacheFile.parentFile?.mkdirs()
|
||||
if (bdhSession.isCompleted) {
|
||||
bot.network.logger.verbose("Saving bdh session to cache")
|
||||
kotlin.runCatching {
|
||||
sessionCacheFile.writeText(
|
||||
JsonForCache.encodeToString(
|
||||
BdhSession.serializer(),
|
||||
bdhSession.getCompleted()
|
||||
)
|
||||
)
|
||||
}.onFailure {
|
||||
bot.network.logger.warning("Error in saving BdhSession to cache.", it)
|
||||
}
|
||||
} else {
|
||||
sessionCacheFile.delete()
|
||||
bot.network.logger.verbose("No BdhSession to save to cache")
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@ -359,24 +359,20 @@ internal class QQAndroidBotNetworkHandler(coroutineContext: CoroutineContext, bo
|
||||
logger.info { "Awaiting ConfigPushSvc.PushReq." }
|
||||
when (val resp: ConfigPushSvc.PushReq.PushReqResponse? = nextEventOrNull(20_000)) {
|
||||
null -> {
|
||||
kotlin.runCatching { bot.client.bdhSession.completeExceptionally(CancellationException("Timeout waiting for ConfigPushSvc.PushReq")) }
|
||||
val hasSession = bot.bdhSyncer.hasSession
|
||||
kotlin.runCatching { bot.bdhSyncer.bdhSession.completeExceptionally(CancellationException("Timeout waiting for ConfigPushSvc.PushReq")) }
|
||||
if (!hasSession) {
|
||||
logger.warning { "Missing ConfigPushSvc.PushReq. File uploading may be affected." }
|
||||
} else {
|
||||
logger.warning { "Missing ConfigPushSvc.PushReq. Using latest response. File uploading may be affected." }
|
||||
}
|
||||
}
|
||||
is ConfigPushSvc.PushReq.PushReqResponse.Success -> {
|
||||
logger.info { "ConfigPushSvc.PushReq: Success." }
|
||||
}
|
||||
is ConfigPushSvc.PushReq.PushReqResponse.ChangeServer -> {
|
||||
bot.logger.info { "Server requires reconnect." }
|
||||
bot.logger.info { "Server list: ${resp.serverList.joinToString()}." }
|
||||
|
||||
if (resp.serverList.isNotEmpty()) {
|
||||
bot.serverList.clear()
|
||||
resp.serverList.shuffled().forEach {
|
||||
bot.serverList.add(it.host to it.port)
|
||||
}
|
||||
}
|
||||
|
||||
bot.launch { BotOfflineEvent.RequireReconnect(bot).broadcast() }
|
||||
logger.info { "ConfigPushSvc.PushReq: Require reconnect" }
|
||||
// handled in ConfigPushSvc
|
||||
return@launch
|
||||
}
|
||||
}
|
||||
|
@ -59,7 +59,7 @@ internal object Highway {
|
||||
fallbackSession: (Throwable) -> BdhSession = { throw IllegalStateException("Failed to get bdh session", it) }
|
||||
): BdhUploadResponse {
|
||||
val bdhSession = kotlin.runCatching {
|
||||
val deferred = bot.client.bdhSession
|
||||
val deferred = bot.bdhSyncer.bdhSession
|
||||
// no need to care about timeout. proceed by bot init
|
||||
@OptIn(ExperimentalCoroutinesApi::class)
|
||||
if (noBdhAwait) deferred.getCompleted() else deferred.await()
|
||||
|
@ -199,9 +199,12 @@ internal open class KeyWithCreationTime(
|
||||
}
|
||||
|
||||
internal suspend inline fun QQAndroidClient.useNextServers(crossinline block: suspend (host: String, port: Int) -> Unit) {
|
||||
if (bot.serverList.isEmpty()) {
|
||||
bot.bdhSyncer.loadServerListFromCache()
|
||||
if (bot.serverList.isEmpty()) {
|
||||
bot.serverList.addAll(DefaultServerList)
|
||||
}
|
||||
}
|
||||
retryCatchingExceptions(bot.serverList.size, except = LoginFailedException::class) l@{
|
||||
val pair = bot.serverList[0]
|
||||
runCatchingExceptions {
|
||||
|
@ -9,10 +9,14 @@
|
||||
|
||||
package net.mamoe.mirai.internal.network.protocol.packet.login
|
||||
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.io.core.ByteReadPacket
|
||||
import kotlinx.serialization.Serializable
|
||||
import net.mamoe.mirai.event.AbstractEvent
|
||||
import net.mamoe.mirai.event.Event
|
||||
import net.mamoe.mirai.event.broadcast
|
||||
import net.mamoe.mirai.event.events.BotOfflineEvent
|
||||
import net.mamoe.mirai.internal.QQAndroidBot
|
||||
import net.mamoe.mirai.internal.message.contextualBugReportException
|
||||
import net.mamoe.mirai.internal.network.BdhSession
|
||||
@ -30,6 +34,7 @@ import net.mamoe.mirai.internal.utils.io.serialization.loadAs
|
||||
import net.mamoe.mirai.internal.utils.io.serialization.readUniPacket
|
||||
import net.mamoe.mirai.internal.utils.io.serialization.tars.TarsId
|
||||
import net.mamoe.mirai.internal.utils.io.serialization.writeJceStruct
|
||||
import net.mamoe.mirai.utils.info
|
||||
import net.mamoe.mirai.utils.toUHexString
|
||||
import java.lang.IllegalStateException
|
||||
import net.mamoe.mirai.internal.network.protocol.data.jce.PushReq as PushReqJceStruct
|
||||
@ -110,7 +115,7 @@ internal class ConfigPushSvc {
|
||||
|
||||
val bigDataChannel = fileStoragePushFSSvcList.bigDataChannel
|
||||
if (bigDataChannel?.vBigdataPbBuf == null) {
|
||||
client.bdhSession.completeExceptionally(IllegalStateException("BdhSession not received."))
|
||||
bot.bdhSyncer.bdhSession.completeExceptionally(IllegalStateException("BdhSession not received."))
|
||||
return
|
||||
}
|
||||
|
||||
@ -134,16 +139,35 @@ internal class ConfigPushSvc {
|
||||
session
|
||||
}.fold(
|
||||
onSuccess = {
|
||||
client.bdhSession.complete(it)
|
||||
bdhSyncer.overrideSession(it)
|
||||
},
|
||||
onFailure = { cause ->
|
||||
val e = IllegalStateException("Failed to decode BdhSession", cause)
|
||||
client.bdhSession.completeExceptionally(e)
|
||||
bdhSyncer.bdhSession.completeExceptionally(e)
|
||||
logger.error(e)
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
fun handleRequireReconnect(resp: PushReqResponse.ChangeServer) {
|
||||
bot.logger.info { "Server requires reconnect." }
|
||||
bot.logger.info { "Server list: ${resp.serverList.joinToString()}." }
|
||||
|
||||
if (resp.serverList.isNotEmpty()) {
|
||||
bot.serverList.clear()
|
||||
resp.serverList.shuffled().forEach {
|
||||
bot.serverList.add(it.host to it.port)
|
||||
}
|
||||
}
|
||||
bot.bdhSyncer.saveToCache()
|
||||
bot.bdhSyncer.saveServerListToCache()
|
||||
|
||||
bot.launch {
|
||||
delay(1000)
|
||||
BotOfflineEvent.RequireReconnect(bot).broadcast()
|
||||
}
|
||||
}
|
||||
|
||||
when (packet) {
|
||||
is PushReqResponse.Success -> {
|
||||
handleSuccess(packet)
|
||||
@ -172,6 +196,10 @@ internal class ConfigPushSvc {
|
||||
// writePacket(this.build().debugPrintThis())
|
||||
}
|
||||
}
|
||||
is PushReqResponse.ChangeServer -> {
|
||||
handleRequireReconnect(packet)
|
||||
return null
|
||||
}
|
||||
else -> {
|
||||
// handled in QQABot
|
||||
return null
|
||||
|
Loading…
Reference in New Issue
Block a user