Him188 5 лет назад
Родитель
Сommit
2be325d781
44 измененных файлов с 148 добавлено и 936 удалено
  1. 0 8
      mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/QQAndroidBot.common.kt
  2. 6 5
      mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/contact/FriendImpl.kt
  3. 2 2
      mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/contact/GroupImpl.kt
  4. 2 1
      mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/contact/MemberImpl.kt
  5. 3 3
      mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/message/convension.kt
  6. 4 0
      mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/QQAndroidBotNetworkHandler.kt
  7. 9 9
      mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/highway/HighwayHelper.kt
  8. 3 3
      mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/highway/highway.kt
  9. 1 0
      mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/packet/PacketFactory.kt
  10. 3 5
      mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/packet/chat/image/ImgStore.kt
  11. 3 0
      mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/packet/chat/receive/MessageSvc.kt
  12. 5 4
      mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/packet/chat/receive/OnlinePush.kt
  13. 3 33
      mirai-core/src/commonMain/kotlin/net.mamoe.mirai/Bot.kt
  14. 1 5
      mirai-core/src/commonMain/kotlin/net.mamoe.mirai/BotImpl.kt
  15. 8 80
      mirai-core/src/commonMain/kotlin/net.mamoe.mirai/contact/ContactList.kt
  16. 1 1
      mirai-core/src/commonMain/kotlin/net.mamoe.mirai/contact/Friend.kt
  17. 1 13
      mirai-core/src/commonMain/kotlin/net.mamoe.mirai/contact/Member.kt
  18. 0 74
      mirai-core/src/commonMain/kotlin/net.mamoe.mirai/contact/QQ.kt
  19. 1 1
      mirai-core/src/commonMain/kotlin/net.mamoe.mirai/contact/javaFriendly.kt
  20. 1 1
      mirai-core/src/commonMain/kotlin/net.mamoe.mirai/event/Event.kt
  21. 0 75
      mirai-core/src/commonMain/kotlin/net.mamoe.mirai/event/MessageSubscribersBuilder.kt
  22. 9 40
      mirai-core/src/commonMain/kotlin/net.mamoe.mirai/event/events/BotEvents.kt
  23. 0 9
      mirai-core/src/commonMain/kotlin/net.mamoe.mirai/event/events/types.kt
  24. 0 3
      mirai-core/src/commonMain/kotlin/net.mamoe.mirai/event/select.kt
  25. 5 59
      mirai-core/src/commonMain/kotlin/net.mamoe.mirai/message/ContactMessage.kt
  26. 0 11
      mirai-core/src/commonMain/kotlin/net.mamoe.mirai/message/FriendMessage.kt
  27. 0 7
      mirai-core/src/commonMain/kotlin/net.mamoe.mirai/message/GroupMessage.kt
  28. 2 13
      mirai-core/src/commonMain/kotlin/net.mamoe.mirai/message/MessageReceipt.kt
  29. 3 6
      mirai-core/src/commonMain/kotlin/net.mamoe.mirai/message/TempMessage.kt
  30. 0 10
      mirai-core/src/commonMain/kotlin/net.mamoe.mirai/message/data/At.kt
  31. 4 22
      mirai-core/src/commonMain/kotlin/net.mamoe.mirai/message/data/Image.kt
  32. 3 101
      mirai-core/src/commonMain/kotlin/net.mamoe.mirai/message/data/Message.kt
  33. 2 45
      mirai-core/src/commonMain/kotlin/net.mamoe.mirai/message/data/MessageChain.kt
  34. 4 28
      mirai-core/src/commonMain/kotlin/net.mamoe.mirai/message/data/MessageSource.kt
  35. 1 1
      mirai-core/src/commonMain/kotlin/net.mamoe.mirai/message/data/PlainText.kt
  36. 1 77
      mirai-core/src/commonMain/kotlin/net.mamoe.mirai/message/data/RichMessage.kt
  37. 0 43
      mirai-core/src/commonMain/kotlin/net.mamoe.mirai/message/data/_HummerMessage.kt
  38. 0 45
      mirai-core/src/commonMain/kotlin/net.mamoe.mirai/message/data/_Message.kt
  39. 0 10
      mirai-core/src/commonMain/kotlin/net.mamoe.mirai/message/data/impl.kt
  40. 16 15
      mirai-core/src/commonMain/kotlin/net.mamoe.mirai/utils/ExternalImage.kt
  41. 9 20
      mirai-core/src/commonMain/kotlin/net.mamoe.mirai/utils/LockFreeLinkedList.kt
  42. 31 0
      mirai-core/src/jvmMain/kotlin/net/mamoe/mirai/Mirai.kt
  43. 1 1
      mirai-core/src/jvmMain/kotlin/net/mamoe/mirai/contact/ContactJavaFriendlyAPI.kt
  44. 0 47
      mirai-core/src/jvmMain/kotlin/net/mamoe/mirai/message/MessagePacket.kt

+ 0 - 8
mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/QQAndroidBot.common.kt

@@ -15,7 +15,6 @@ import io.ktor.client.HttpClient
 import io.ktor.client.request.*
 import io.ktor.client.request.*
 import io.ktor.client.request.forms.MultiPartFormDataContent
 import io.ktor.client.request.forms.MultiPartFormDataContent
 import io.ktor.client.request.forms.formData
 import io.ktor.client.request.forms.formData
-import io.ktor.client.statement.HttpResponse
 import kotlinx.coroutines.CoroutineName
 import kotlinx.coroutines.CoroutineName
 import kotlinx.coroutines.async
 import kotlinx.coroutines.async
 import kotlinx.coroutines.io.ByteReadChannel
 import kotlinx.coroutines.io.ByteReadChannel
@@ -766,13 +765,6 @@ internal abstract class QQAndroidBotBase constructor(
         }
         }
     }
     }
 
 
-    @Suppress("DeprecatedCallableAddReplaceWith")
-    @PlannedRemoval("1.0.0")
-    @Deprecated("use your own Http clients, this is going to be removed in 1.0.0", level = DeprecationLevel.WARNING)
-    override suspend fun openChannel(image: Image): ByteReadChannel {
-        return MiraiPlatformUtils.Http.get<HttpResponse>(queryImageUrl(image)).content.toKotlinByteReadChannel()
-    }
-
     /**
     /**
      * 获取 获取群公告 所需的 bkn 参数
      * 获取 获取群公告 所需的 bkn 参数
      * */
      * */

+ 6 - 5
mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/contact/FriendImpl.kt

@@ -97,13 +97,14 @@ internal class FriendImpl(
                     dstUin = id.toInt(),
                     dstUin = id.toInt(),
                     fileId = 0,
                     fileId = 0,
                     fileMd5 = image.md5,
                     fileMd5 = image.md5,
-                    fileSize = image.inputSize.toInt(),
+                    fileSize = @Suppress("INVISIBLE_MEMBER")
+                    image.input.size.toInt(),
                     fileName = image.md5.toUHexString("") + "." + ExternalImage.defaultFormatName,
                     fileName = image.md5.toUHexString("") + "." + ExternalImage.defaultFormatName,
                     imgOriginal = 1
                     imgOriginal = 1
                 )
                 )
             ).sendAndExpect<LongConn.OffPicUp.Response>()
             ).sendAndExpect<LongConn.OffPicUp.Response>()
 
 
-            @Suppress("UNCHECKED_CAST", "DEPRECATION") // bug
+            @Suppress("UNCHECKED_CAST", "DEPRECATION", "INVISIBLE_MEMBER")
             return when (response) {
             return when (response) {
                 is LongConn.OffPicUp.Response.FileExists -> net.mamoe.mirai.message.data.OfflineFriendImage(response.resourceId)
                 is LongConn.OffPicUp.Response.FileExists -> net.mamoe.mirai.message.data.OfflineFriendImage(response.resourceId)
                     .also {
                     .also {
@@ -111,7 +112,7 @@ internal class FriendImpl(
                     }
                     }
                 is LongConn.OffPicUp.Response.RequireUpload -> {
                 is LongConn.OffPicUp.Response.RequireUpload -> {
                     bot.network.logger.verbose {
                     bot.network.logger.verbose {
-                        "[Http] Uploading friend image, size=${image.inputSize.sizeToString()}"
+                        "[Http] Uploading friend image, size=${image.input.size.sizeToString()}"
                     }
                     }
 
 
                     val time = measureTime {
                     val time = measureTime {
@@ -120,13 +121,12 @@ internal class FriendImpl(
                             bot.id,
                             bot.id,
                             null,
                             null,
                             imageInput = image.input,
                             imageInput = image.input,
-                            inputSize = image.inputSize,
                             uKeyHex = response.uKey.toUHexString("")
                             uKeyHex = response.uKey.toUHexString("")
                         )
                         )
                     }
                     }
 
 
                     bot.network.logger.verbose {
                     bot.network.logger.verbose {
-                        "[Http] Uploading friend image: succeed at ${(image.inputSize.toDouble() / 1024 / time.inSeconds).roundToInt()} KiB/s"
+                        "[Http] Uploading friend image: succeed at ${(image.input.size.toDouble() / 1024 / time.inSeconds).roundToInt()} KiB/s"
                     }
                     }
 
 
                     /*
                     /*
@@ -151,6 +151,7 @@ internal class FriendImpl(
             }
             }
         }
         }
     } finally {
     } finally {
+        @Suppress("INVISIBLE_MEMBER", "INVISIBLE_REFERENCE")
         (image.input as? Closeable)?.close()
         (image.input as? Closeable)?.close()
     }
     }
 }
 }

+ 2 - 2
mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/contact/GroupImpl.kt

@@ -412,7 +412,7 @@ internal class GroupImpl(
                 uin = bot.id,
                 uin = bot.id,
                 groupCode = id,
                 groupCode = id,
                 md5 = image.md5,
                 md5 = image.md5,
-                size = image.inputSize
+                size = image.input.size.toInt()
             ).sendAndExpect()
             ).sendAndExpect()
 
 
             @Suppress("UNCHECKED_CAST") // bug
             @Suppress("UNCHECKED_CAST") // bug
@@ -432,7 +432,7 @@ internal class GroupImpl(
                         bot,
                         bot,
                         response.uploadIpList.zip(response.uploadPortList),
                         response.uploadIpList.zip(response.uploadPortList),
                         response.uKey,
                         response.uKey,
-                        image,
+                        image.input,
                         kind = "group image",
                         kind = "group image",
                         commandId = 2
                         commandId = 2
                     )
                     )

+ 2 - 1
mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/contact/MemberImpl.kt

@@ -118,7 +118,7 @@ internal class MemberImpl constructor(
                             newValue
                             newValue
                         ).sendWithoutExpect()
                         ).sendWithoutExpect()
                     }
                     }
-                    MemberCardChangeEvent(oldValue, newValue, this@MemberImpl, null).broadcast()
+                    MemberCardChangeEvent(oldValue, newValue, this@MemberImpl).broadcast()
                 }
                 }
             }
             }
         }
         }
@@ -205,6 +205,7 @@ internal class MemberImpl constructor(
 
 
             check(response.success) { "kick failed: ${response.ret}" }
             check(response.success) { "kick failed: ${response.ret}" }
 
 
+            @Suppress("INVISIBLE_MEMBER", "INVISIBLE_REFERENCE")
             group.members.delegate.removeIf { it.id == [email protected] }
             group.members.delegate.removeIf { it.id == [email protected] }
             MemberLeaveEvent.Kick(this@MemberImpl, null).broadcast()
             MemberLeaveEvent.Kick(this@MemberImpl, null).broadcast()
         }
         }

+ 3 - 3
mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/message/convension.kt

@@ -341,10 +341,10 @@ internal fun List<ImMsgBody.Elem>.joinToMessageChain(groupIdOrZero: Long, bot: B
 ="" a_actionData="" url=""/></msg>
 ="" a_actionData="" url=""/></msg>
                      */
                      */
                     /**
                     /**
-                     * [JsonMessage]
+                     * json?
                      */
                      */
                     1 -> @Suppress("DEPRECATION_ERROR")
                     1 -> @Suppress("DEPRECATION_ERROR")
-                    list.add(JsonMessage(content))
+                    list.add(ServiceMessage(1, content))
                     /**
                     /**
                      * [LongMessage], [ForwardMessage]
                      * [LongMessage], [ForwardMessage]
                      */
                      */
@@ -364,7 +364,7 @@ internal fun List<ImMsgBody.Elem>.joinToMessageChain(groupIdOrZero: Long, bot: B
                     else -> {
                     else -> {
                         if (element.richMsg.serviceId == 60 || content.startsWith("<?")) {
                         if (element.richMsg.serviceId == 60 || content.startsWith("<?")) {
                             @Suppress("DEPRECATION_ERROR") // bin comp
                             @Suppress("DEPRECATION_ERROR") // bin comp
-                            list.add(XmlMessage(element.richMsg.serviceId, content))
+                            list.add(ServiceMessage(element.richMsg.serviceId, content))
                         } else list.add(ServiceMessage(element.richMsg.serviceId, content))
                         } else list.add(ServiceMessage(element.richMsg.serviceId, content))
                     }
                     }
                 }
                 }

+ 4 - 0
mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/QQAndroidBotNetworkHandler.kt

@@ -7,6 +7,8 @@
  * https://github.com/mamoe/mirai/blob/master/LICENSE
  * https://github.com/mamoe/mirai/blob/master/LICENSE
  */
  */
 
 
+@file:Suppress("INVISIBLE_MEMBER", "INVISIBLE_REFERENCE")
+
 package net.mamoe.mirai.qqandroid.network
 package net.mamoe.mirai.qqandroid.network
 
 
 import kotlinx.atomicfu.AtomicRef
 import kotlinx.atomicfu.AtomicRef
@@ -44,6 +46,7 @@ import net.mamoe.mirai.qqandroid.utils.io.useBytes
 import net.mamoe.mirai.qqandroid.utils.retryCatching
 import net.mamoe.mirai.qqandroid.utils.retryCatching
 import net.mamoe.mirai.utils.*
 import net.mamoe.mirai.utils.*
 import kotlin.coroutines.CoroutineContext
 import kotlin.coroutines.CoroutineContext
+import kotlin.jvm.JvmField
 import kotlin.jvm.Volatile
 import kotlin.jvm.Volatile
 import kotlin.time.ExperimentalTime
 import kotlin.time.ExperimentalTime
 
 
@@ -204,6 +207,7 @@ internal class QQAndroidBotNetworkHandler(coroutineContext: CoroutineContext, bo
     private val _pendingEnabled = atomic(true)
     private val _pendingEnabled = atomic(true)
     internal val pendingEnabled get() = _pendingEnabled.value
     internal val pendingEnabled get() = _pendingEnabled.value
 
 
+    @JvmField
     @Volatile
     @Volatile
     internal var pendingIncomingPackets: LockFreeLinkedList<KnownPacketFactories.IncomingPacket<*>>? =
     internal var pendingIncomingPackets: LockFreeLinkedList<KnownPacketFactories.IncomingPacket<*>>? =
         LockFreeLinkedList()
         LockFreeLinkedList()

+ 9 - 9
mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/highway/HighwayHelper.kt

@@ -42,13 +42,12 @@ import kotlin.time.ExperimentalTime
 import kotlin.time.measureTime
 import kotlin.time.measureTime
 
 
 @OptIn(MiraiInternalAPI::class, InternalSerializationApi::class)
 @OptIn(MiraiInternalAPI::class, InternalSerializationApi::class)
-@Suppress("SpellCheckingInspection")
+@Suppress("SpellCheckingInspection", "INVISIBLE_REFERENCE", "INVISIBLE_MEMBER")
 internal suspend fun HttpClient.postImage(
 internal suspend fun HttpClient.postImage(
     htcmd: String,
     htcmd: String,
     uin: Long,
     uin: Long,
     groupcode: Long?,
     groupcode: Long?,
-    imageInput: Any, // Input from kotlinx.io, InputStream from kotlinx.io MPP, ByteReadChannel from ktor
-    inputSize: Long,
+    imageInput: ExternalImage.ReusableInput, // Input from kotlinx.io, InputStream from kotlinx.io MPP, ByteReadChannel from ktor
     uKeyHex: String
     uKeyHex: String
 ): Boolean = post<HttpStatusCode> {
 ): Boolean = post<HttpStatusCode> {
     url {
     url {
@@ -63,7 +62,7 @@ internal suspend fun HttpClient.postImage(
 
 
         parameters["term"] = "pc"
         parameters["term"] = "pc"
         parameters["ver"] = "5603"
         parameters["ver"] = "5603"
-        parameters["filesize"] = inputSize.toString()
+        parameters["filesize"] = imageInput.size.toString()
         parameters["range"] = 0.toString()
         parameters["range"] = 0.toString()
         parameters["ukey"] = uKeyHex
         parameters["ukey"] = uKeyHex
 
 
@@ -72,7 +71,7 @@ internal suspend fun HttpClient.postImage(
 
 
     body = object : OutgoingContent.WriteChannelContent() {
     body = object : OutgoingContent.WriteChannelContent() {
         override val contentType: ContentType = ContentType.Image.Any
         override val contentType: ContentType = ContentType.Image.Any
-        override val contentLength: Long = inputSize
+        override val contentLength: Long = imageInput.size
 
 
         @OptIn(MiraiExperimentalAPI::class)
         @OptIn(MiraiExperimentalAPI::class)
         override suspend fun writeTo(channel: ByteWriteChannel) {
         override suspend fun writeTo(channel: ByteWriteChannel) {
@@ -102,14 +101,15 @@ internal suspend fun HttpClient.postImage(
 
 
 @OptIn(MiraiInternalAPI::class, InternalSerializationApi::class)
 @OptIn(MiraiInternalAPI::class, InternalSerializationApi::class)
 internal object HighwayHelper {
 internal object HighwayHelper {
+    @Suppress("INVISIBLE_REFERENCE", "INVISIBLE_MEMBER")
     suspend fun uploadImageToServers(
     suspend fun uploadImageToServers(
         bot: QQAndroidBot,
         bot: QQAndroidBot,
         servers: List<Pair<Int, Int>>,
         servers: List<Pair<Int, Int>>,
         uKey: ByteArray,
         uKey: ByteArray,
-        image: ExternalImage,
+        image: ExternalImage.ReusableInput,
         kind: String,
         kind: String,
         commandId: Int
         commandId: Int
-    ) = uploadImageToServers(bot, servers, uKey, image.md5, image.input, image.inputSize, kind, commandId)
+    ) = uploadImageToServers(bot, servers, uKey, image.md5, image.input(), image.size, kind, commandId)
 
 
     @OptIn(ExperimentalTime::class)
     @OptIn(ExperimentalTime::class)
     suspend fun uploadImageToServers(
     suspend fun uploadImageToServers(
@@ -137,7 +137,7 @@ internal object HighwayHelper {
                 serverIp = ip,
                 serverIp = ip,
                 serverPort = port,
                 serverPort = port,
                 imageInput = input,
                 imageInput = input,
-                inputSize = inputSize.toInt(),
+                inputSize = inputSize,
                 fileMd5 = md5,
                 fileMd5 = md5,
                 ticket = uKey,
                 ticket = uKey,
                 commandId = commandId
                 commandId = commandId
@@ -156,7 +156,7 @@ internal object HighwayHelper {
         serverPort: Int,
         serverPort: Int,
         ticket: ByteArray,
         ticket: ByteArray,
         imageInput: Any,
         imageInput: Any,
-        inputSize: Int,
+        inputSize: Long,
         fileMd5: ByteArray,
         fileMd5: ByteArray,
         commandId: Int  // group=2, friend=1
         commandId: Int  // group=2, friend=1
     ) {
     ) {

+ 3 - 3
mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/highway/highway.kt

@@ -41,14 +41,14 @@ internal fun createImageDataPacketSequence(
     ticket: ByteArray,
     ticket: ByteArray,
 
 
     data: Any,
     data: Any,
-    dataSize: Int,
+    dataSize: Long,
     fileMd5: ByteArray,
     fileMd5: ByteArray,
     sizePerPacket: Int = ByteArrayPool.BUFFER_SIZE
     sizePerPacket: Int = ByteArrayPool.BUFFER_SIZE
 ): Flow<ByteReadPacket> {
 ): Flow<ByteReadPacket> {
     ByteArrayPool.checkBufferSize(sizePerPacket)
     ByteArrayPool.checkBufferSize(sizePerPacket)
     require(data is Input || data is InputStream || data is ByteReadChannel) { "unsupported data: ${data::class.simpleName}" }
     require(data is Input || data is InputStream || data is ByteReadChannel) { "unsupported data: ${data::class.simpleName}" }
     //   require(ticket.size == 128) { "bad uKey. Required size=128, got ${ticket.size}" }
     //   require(ticket.size == 128) { "bad uKey. Required size=128, got ${ticket.size}" }
-    require(data !is ByteReadPacket || data.remaining.toInt() == dataSize) { "bad input. given dataSize=$dataSize, but actual readRemaining=${(data as ByteReadPacket).remaining}" }
+    require(data !is ByteReadPacket) { "bad input. given dataSize=$dataSize, but actual readRemaining=${(data as ByteReadPacket).remaining}" }
 
 
     val flow = when (data) {
     val flow = when (data) {
         is ByteReadPacket -> data.chunkedFlow(sizePerPacket)
         is ByteReadPacket -> data.chunkedFlow(sizePerPacket)
@@ -82,7 +82,7 @@ internal fun createImageDataPacketSequence(
                     //   cacheAddr = 812157193,
                     //   cacheAddr = 812157193,
                     datalength = chunkedInput.bufferSize,
                     datalength = chunkedInput.bufferSize,
                     dataoffset = offset,
                     dataoffset = offset,
-                    filesize = dataSize.toLong(),
+                    filesize = dataSize,
                     serviceticket = ticket,
                     serviceticket = ticket,
                     md5 = MiraiPlatformUtils.md5(chunkedInput.buffer, 0, chunkedInput.bufferSize),
                     md5 = MiraiPlatformUtils.md5(chunkedInput.buffer, 0, chunkedInput.bufferSize),
                     fileMd5 = fileMd5,
                     fileMd5 = fileMd5,

+ 1 - 0
mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/packet/PacketFactory.kt

@@ -219,6 +219,7 @@ internal object KnownPacketFactories {
                     it as IncomingPacket<T>
                     it as IncomingPacket<T>
 
 
                     if (it.packetFactory is IncomingPacketFactory<T> && it.packetFactory.canBeCached && bot.network.pendingEnabled) {
                     if (it.packetFactory is IncomingPacketFactory<T> && it.packetFactory.canBeCached && bot.network.pendingEnabled) {
+                        @Suppress("INVISIBLE_MEMBER", "INVISIBLE_REFERENCE")
                         bot.network.pendingIncomingPackets?.addLast(it.also {
                         bot.network.pendingIncomingPackets?.addLast(it.also {
                             it.consumer = consumer
                             it.consumer = consumer
                             it.flag2 = flag2
                             it.flag2 = flag2

+ 3 - 5
mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/packet/chat/image/ImgStore.kt

@@ -17,6 +17,7 @@ import net.mamoe.mirai.qqandroid.network.protocol.data.proto.Cmd0x388
 import net.mamoe.mirai.qqandroid.network.protocol.packet.OutgoingPacket
 import net.mamoe.mirai.qqandroid.network.protocol.packet.OutgoingPacket
 import net.mamoe.mirai.qqandroid.network.protocol.packet.OutgoingPacketFactory
 import net.mamoe.mirai.qqandroid.network.protocol.packet.OutgoingPacketFactory
 import net.mamoe.mirai.qqandroid.network.protocol.packet.buildOutgoingUniPacket
 import net.mamoe.mirai.qqandroid.network.protocol.packet.buildOutgoingUniPacket
+import net.mamoe.mirai.qqandroid.network.protocol.packet.chat.toLongUnsigned
 import net.mamoe.mirai.qqandroid.utils.io.serialization.readProtoBuf
 import net.mamoe.mirai.qqandroid.utils.io.serialization.readProtoBuf
 import net.mamoe.mirai.qqandroid.utils.io.serialization.writeProtoBuf
 import net.mamoe.mirai.qqandroid.utils.io.serialization.writeProtoBuf
 import kotlin.random.Random
 import kotlin.random.Random
@@ -27,9 +28,6 @@ internal fun getRandomString(length: Int): String =
 
 
 private val defaultRanges: Array<CharRange> = arrayOf('a'..'z', 'A'..'Z', '0'..'9')
 private val defaultRanges: Array<CharRange> = arrayOf('a'..'z', 'A'..'Z', '0'..'9')
 
 
-internal fun getRandomString(length: Int, charRange: CharRange): String =
-    String(CharArray(length) { charRange.random() })
-
 internal fun getRandomString(length: Int, vararg charRanges: CharRange): String =
 internal fun getRandomString(length: Int, vararg charRanges: CharRange): String =
     String(CharArray(length) { charRanges[Random.Default.nextInt(0..charRanges.lastIndex)].random() })
     String(CharArray(length) { charRanges[Random.Default.nextInt(0..charRanges.lastIndex)].random() })
 
 
@@ -41,7 +39,7 @@ internal class ImgStore {
             uin: Long,
             uin: Long,
             groupCode: Long,
             groupCode: Long,
             md5: ByteArray,
             md5: ByteArray,
-            size: Long,
+            size: Int,
             picWidth: Int = 0, // not orthodox
             picWidth: Int = 0, // not orthodox
             picHeight: Int = 0, // not orthodox
             picHeight: Int = 0, // not orthodox
             picType: Int = 1000,
             picType: Int = 1000,
@@ -63,7 +61,7 @@ internal class ImgStore {
                             groupCode = groupCode,
                             groupCode = groupCode,
                             srcUin = uin,
                             srcUin = uin,
                             fileMd5 = md5,
                             fileMd5 = md5,
-                            fileSize = size,
+                            fileSize = size.toLongUnsigned(),
                             fileId = fileId,
                             fileId = fileId,
                             fileName = filename,
                             fileName = filename,
                             picWidth = picWidth,
                             picWidth = picWidth,

+ 3 - 0
mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/packet/chat/receive/MessageSvc.kt

@@ -223,6 +223,7 @@ internal class MessageSvc {
                                 // 新群
                                 // 新群
 
 
                                 val newGroup = msg.getNewGroup(bot) ?: return@mapNotNull null
                                 val newGroup = msg.getNewGroup(bot) ?: return@mapNotNull null
+                                @Suppress("INVISIBLE_MEMBER", "INVISIBLE_REFERENCE")
                                 bot.groups.delegate.addLast(newGroup)
                                 bot.groups.delegate.addLast(newGroup)
                                 return@mapNotNull BotJoinGroupEvent(newGroup)
                                 return@mapNotNull BotJoinGroupEvent(newGroup)
                             } else {
                             } else {
@@ -232,6 +233,7 @@ internal class MessageSvc {
                                     return@mapNotNull null
                                     return@mapNotNull null
                                 }
                                 }
 
 
+                                @Suppress("INVISIBLE_MEMBER", "INVISIBLE_REFERENCE")
                                 return@mapNotNull MemberJoinEvent.Invite(group.newMember(msg.getNewMemberInfo())
                                 return@mapNotNull MemberJoinEvent.Invite(group.newMember(msg.getNewMemberInfo())
                                     .also { group.members.delegate.addLast(it) })
                                     .also { group.members.delegate.addLast(it) })
                             }
                             }
@@ -245,6 +247,7 @@ internal class MessageSvc {
                             if (group.members.contains(msg.msgHead.authUin)) {
                             if (group.members.contains(msg.msgHead.authUin)) {
                                 return@mapNotNull null
                                 return@mapNotNull null
                             }
                             }
+                            @Suppress("INVISIBLE_MEMBER", "INVISIBLE_REFERENCE")
                             return@mapNotNull MemberJoinEvent.Active(group.newMember(msg.getNewMemberInfo())
                             return@mapNotNull MemberJoinEvent.Active(group.newMember(msg.getNewMemberInfo())
                                 .also { group.members.delegate.addLast(it) })
                                 .also { group.members.delegate.addLast(it) })
                         }
                         }

+ 5 - 4
mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid/network/protocol/packet/chat/receive/OnlinePush.kt

@@ -7,7 +7,7 @@
  * https://github.com/mamoe/mirai/blob/master/LICENSE
  * https://github.com/mamoe/mirai/blob/master/LICENSE
  */
  */
 
 
-@file:Suppress("EXPERIMENTAL_UNSIGNED_LITERALS", "EXPERIMENTAL_API_USAGE")
+@file:Suppress("EXPERIMENTAL_UNSIGNED_LITERALS", "EXPERIMENTAL_API_USAGE", "INVISIBLE_MEMBER", "INVISIBLE_REFERENCE")
 
 
 package net.mamoe.mirai.qqandroid.network.protocol.packet.chat.receive
 package net.mamoe.mirai.qqandroid.network.protocol.packet.chat.receive
 
 
@@ -87,7 +87,8 @@ internal class OnlinePush {
                 }
                 }
             }
             }
 
 
-            val group = bot.getGroupOrNull(pbPushMsg.msg.msgHead.groupInfo!!.groupCode) as GroupImpl? ?: return null // 机器人还正在进群
+            val group =
+                bot.getGroupOrNull(pbPushMsg.msg.msgHead.groupInfo!!.groupCode) as GroupImpl? ?: return null // 机器人还正在进群
             val sender = if (anonymous != null) {
             val sender = if (anonymous != null) {
                 group.newAnonymous(anonymous.anonNick.encodeToString())
                 group.newAnonymous(anonymous.anonNick.encodeToString())
             } else {
             } else {
@@ -113,7 +114,7 @@ internal class OnlinePush {
                     if (it != sender.nameCard) {
                     if (it != sender.nameCard) {
                         val origin = sender._nameCard
                         val origin = sender._nameCard
                         sender._nameCard = name
                         sender._nameCard = name
-                        MemberCardChangeEvent(origin, name, sender, sender).broadcast() // 不知道operator
+                        MemberCardChangeEvent(origin, name, sender).broadcast()
                     }
                     }
                 },
                 },
                 sender = sender,
                 sender = sender,
@@ -562,7 +563,7 @@ internal class OnlinePush {
                                 if (new == old) return@mapNotNull null
                                 if (new == old) return@mapNotNull null
                                 member._nameCard = new
                                 member._nameCard = new
 
 
-                                return@mapNotNull MemberCardChangeEvent(old, new, member, null)
+                                return@mapNotNull MemberCardChangeEvent(old, new, member)
                             }
                             }
                             2 -> {
                             2 -> {
                                 if (info.value.singleOrNull()?.toInt() != 0) {
                                 if (info.value.singleOrNull()?.toInt() != 0) {

+ 3 - 33
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/Bot.kt

@@ -15,7 +15,6 @@ package net.mamoe.mirai
 import kotlinx.coroutines.CoroutineName
 import kotlinx.coroutines.CoroutineName
 import kotlinx.coroutines.CoroutineScope
 import kotlinx.coroutines.CoroutineScope
 import kotlinx.coroutines.Job
 import kotlinx.coroutines.Job
-import kotlinx.coroutines.io.ByteReadChannel
 import kotlinx.coroutines.launch
 import kotlinx.coroutines.launch
 import net.mamoe.mirai.contact.*
 import net.mamoe.mirai.contact.*
 import net.mamoe.mirai.data.AddFriendResult
 import net.mamoe.mirai.data.AddFriendResult
@@ -29,7 +28,6 @@ import net.mamoe.mirai.network.LoginFailedException
 import net.mamoe.mirai.utils.*
 import net.mamoe.mirai.utils.*
 import kotlin.coroutines.CoroutineContext
 import kotlin.coroutines.CoroutineContext
 import kotlin.coroutines.EmptyCoroutineContext
 import kotlin.coroutines.EmptyCoroutineContext
-import kotlin.jvm.JvmName
 import kotlin.jvm.JvmStatic
 import kotlin.jvm.JvmStatic
 import kotlin.jvm.JvmSynthetic
 import kotlin.jvm.JvmSynthetic
 
 
@@ -56,6 +54,7 @@ abstract class Bot : CoroutineScope, LowLevelBotAPIAccessor, BotJavaFriendlyAPI(
         /**
         /**
          * 复制一份此时的 [Bot] 实例列表.
          * 复制一份此时的 [Bot] 实例列表.
          */
          */
+        @PlannedRemoval("1.2.0")
         @Deprecated("use botInstances instead", replaceWith = ReplaceWith("botInstances"))
         @Deprecated("use botInstances instead", replaceWith = ReplaceWith("botInstances"))
         @JvmStatic
         @JvmStatic
         val instances: List<WeakRef<Bot>>
         val instances: List<WeakRef<Bot>>
@@ -72,7 +71,7 @@ abstract class Bot : CoroutineScope, LowLevelBotAPIAccessor, BotJavaFriendlyAPI(
         /**
         /**
          * 遍历每一个 [Bot] 实例
          * 遍历每一个 [Bot] 实例
          */
          */
-        inline fun forEachInstance(block: (Bot) -> Unit) = BotImpl.forEachInstance(block)
+        fun forEachInstance(block: (Bot) -> Unit) = BotImpl.forEachInstance(block)
 
 
         /**
         /**
          * 获取一个 [Bot] 实例, 找不到则 [NoSuchElementException]
          * 获取一个 [Bot] 实例, 找不到则 [NoSuchElementException]
@@ -89,10 +88,6 @@ abstract class Bot : CoroutineScope, LowLevelBotAPIAccessor, BotJavaFriendlyAPI(
      */
      */
     abstract val context: Context
     abstract val context: Context
 
 
-    @PlannedRemoval("1.0.0")
-    @Deprecated("use id instead", replaceWith = ReplaceWith("id"))
-    abstract val uin: Long
-
     /**
     /**
      * QQ 号码. 实际类型为 uint
      * QQ 号码. 实际类型为 uint
      */
      */
@@ -113,7 +108,7 @@ abstract class Bot : CoroutineScope, LowLevelBotAPIAccessor, BotJavaFriendlyAPI(
     // region contacts
     // region contacts
 
 
     /**
     /**
-     * [QQ.id] 与 [Bot.uin] 相同的 [_lowLevelNewFriend] 实例
+     * [User.id] 与 [Bot.id] 相同的 [_lowLevelNewFriend] 实例
      */
      */
     abstract val selfQQ: Friend
     abstract val selfQQ: Friend
 
 
@@ -201,18 +196,6 @@ abstract class Bot : CoroutineScope, LowLevelBotAPIAccessor, BotJavaFriendlyAPI(
         originalMessage: MessageChain
         originalMessage: MessageChain
     ): OfflineMessageSource
     ): OfflineMessageSource
 
 
-    /**
-     * 获取图片下载链接并开始下载.
-     *
-     * @see ByteReadChannel.copyAndClose
-     * @see ByteReadChannel.copyTo
-     */
-    @PlannedRemoval("1.0.0")
-    @Deprecated("use your own Http clients, this is going to be removed in 1.0.0", level = DeprecationLevel.WARNING)
-    @MiraiExperimentalAPI
-    @JvmSynthetic
-    abstract suspend fun openChannel(image: Image): ByteReadChannel
-
     /**
     /**
      * 添加一个好友
      * 添加一个好友
      *
      *
@@ -313,19 +296,6 @@ abstract class Bot : CoroutineScope, LowLevelBotAPIAccessor, BotJavaFriendlyAPI(
      */
      */
     @MiraiInternalAPI
     @MiraiInternalAPI
     abstract val network: BotNetworkHandler
     abstract val network: BotNetworkHandler
-
-    @PlannedRemoval("1.0.0.")
-    @get:JvmName("getSelfQQ")
-    @Suppress("INAPPLICABLE_JVM_NAME", "DEPRECATION_ERROR")
-    @Deprecated("for binary compatibility", level = DeprecationLevel.HIDDEN)
-    val selfQQDeprecated: QQ
-        get() = selfQQ
-
-    @PlannedRemoval("1.0.0.")
-    @JvmName("getFriend")
-    @Suppress("INAPPLICABLE_JVM_NAME", "DEPRECATION_ERROR")
-    @Deprecated("for binary compatibility", level = DeprecationLevel.HIDDEN)
-    fun getFriendDeprecated(id: Long): QQ = this.getFriend(id)
 }
 }
 
 
 /**
 /**

+ 1 - 5
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/BotImpl.kt

@@ -46,10 +46,6 @@ abstract class BotImpl<N : BotNetworkHandler> constructor(
 
 
     override val context: Context by context.unsafeWeakRef()
     override val context: Context by context.unsafeWeakRef()
 
 
-    @Deprecated("use id instead", replaceWith = ReplaceWith("id"))
-    override val uin: Long
-        get() = this.id
-
     final override val logger: MiraiLogger by lazy { configuration.botLoggerSupplier(this) }
     final override val logger: MiraiLogger by lazy { configuration.botLoggerSupplier(this) }
 
 
     init {
     init {
@@ -60,7 +56,7 @@ abstract class BotImpl<N : BotNetworkHandler> constructor(
         @PublishedApi
         @PublishedApi
         internal val instances: LockFreeLinkedList<WeakRef<Bot>> = LockFreeLinkedList()
         internal val instances: LockFreeLinkedList<WeakRef<Bot>> = LockFreeLinkedList()
 
 
-        inline fun forEachInstance(block: (Bot) -> Unit) = instances.forEach {
+        fun forEachInstance(block: (Bot) -> Unit) = instances.forEach {
             it.get()?.let(block)
             it.get()?.let(block)
         }
         }
 
 

+ 8 - 80
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/contact/ContactList.kt

@@ -11,8 +11,9 @@
 
 
 package net.mamoe.mirai.contact
 package net.mamoe.mirai.contact
 
 
-import net.mamoe.mirai.utils.*
-import kotlin.jvm.JvmName
+import net.mamoe.mirai.utils.LockFreeLinkedList
+import net.mamoe.mirai.utils.asSequence
+import kotlin.jvm.JvmField
 
 
 
 
 /**
 /**
@@ -20,9 +21,8 @@ import kotlin.jvm.JvmName
  *
  *
  * @see ContactList.asSequence
  * @see ContactList.asSequence
  */
  */
-@OptIn(MiraiInternalAPI::class)
 @Suppress("unused")
 @Suppress("unused")
-class ContactList<C : Contact>(@MiraiInternalAPI("Implementation may change in future release") val delegate: LockFreeLinkedList<C>) :
+class ContactList<C : Contact> internal constructor(@JvmField internal val delegate: LockFreeLinkedList<C>) :
     Iterable<C> {
     Iterable<C> {
     operator fun get(id: Long): C =
     operator fun get(id: Long): C =
         delegate.asSequence().firstOrNull { it.id == id } ?: throw NoSuchElementException("Contact id $id")
         delegate.asSequence().firstOrNull { it.id == id } ?: throw NoSuchElementException("Contact id $id")
@@ -41,31 +41,6 @@ class ContactList<C : Contact>(@MiraiInternalAPI("Implementation may change in f
     override fun iterator(): Iterator<C> {
     override fun iterator(): Iterator<C> {
         return this.delegate.asSequence().iterator()
         return this.delegate.asSequence().iterator()
     }
     }
-
-    @PlannedRemoval("1.0.0")
-    @Suppress("PropertyName")
-    @get:JvmName("getIdContentString")
-    @Deprecated("for binary compatibility", level = DeprecationLevel.HIDDEN)
-    val _idContentString: String
-        get() = this.idContentString
-
-    @PlannedRemoval("1.0.0")
-    @Deprecated("for binary compatibility", level = DeprecationLevel.HIDDEN)
-    inline fun forEach(block: (C) -> Unit) = delegate.forEach(block)
-
-    @PlannedRemoval("1.0.0")
-    @Deprecated("for binary compatibility", level = DeprecationLevel.HIDDEN)
-    fun first(): C {
-        forEach { return it }
-        throw NoSuchElementException()
-    }
-
-    @PlannedRemoval("1.0.0")
-    @Deprecated("for binary compatibility", level = DeprecationLevel.HIDDEN)
-    fun firstOrNull(): C? {
-        forEach { return it }
-        return null
-    }
 }
 }
 
 
 /**
 /**
@@ -76,64 +51,17 @@ class ContactList<C : Contact>(@MiraiInternalAPI("Implementation may change in f
  * ```
  * ```
  */
  */
 val ContactList<*>.idContentString: String
 val ContactList<*>.idContentString: String
-    get() = "[" + @OptIn(MiraiInternalAPI::class) buildString { delegate.forEach { append(it.id).append(", ") } }.dropLast(
+    get() = "[" + buildString { delegate.forEach { append(it.id).append(", ") } }.dropLast(
         2
         2
     ) + "]"
     ) + "]"
 
 
 
 
-@MiraiInternalAPI
-operator fun <C : Contact> LockFreeLinkedList<C>.get(id: Long): C {
+internal operator fun <C : Contact> LockFreeLinkedList<C>.get(id: Long): C {
     forEach { if (it.id == id) return it }
     forEach { if (it.id == id) return it }
     throw NoSuchElementException("No such contact: $id")
     throw NoSuchElementException("No such contact: $id")
 }
 }
 
 
-@MiraiInternalAPI
-fun <C : Contact> LockFreeLinkedList<C>.getOrNull(id: Long): C? {
+internal fun <C : Contact> LockFreeLinkedList<C>.getOrNull(id: Long): C? {
     forEach { if (it.id == id) return it }
     forEach { if (it.id == id) return it }
     return null
     return null
-}
-
-@OptIn(MiraiInternalAPI::class)
-@PlannedRemoval("1.0.0")
-@Deprecated(
-    "use firstOrNull from stdlib",
-    replaceWith = ReplaceWith("this.asSequence().firstOrNull(filter)"),
-    level = DeprecationLevel.ERROR
-)
-inline fun <C : Contact> LockFreeLinkedList<C>.firstOrNull(filter: (C) -> Boolean): C? {
-    forEach { if (filter(it)) return it }
-    return null
-}
-
-@OptIn(MiraiInternalAPI::class)
-@PlannedRemoval("1.0.0")
-@Deprecated(
-    "use firstOrNull from stdlib",
-    replaceWith = ReplaceWith("firstOrNull(filter)"),
-    level = DeprecationLevel.ERROR
-)
-inline fun <C : Contact> LockFreeLinkedList<C>.filteringGetOrNull(filter: (C) -> Boolean): C? =
-    this.asSequence().firstOrNull(filter)
-
-@PlannedRemoval("1.0.0")
-@Deprecated("use Iterator.toList from stdlib", level = DeprecationLevel.HIDDEN)
-fun <E : Contact> ContactList<E>.toList(): List<E> = toMutableList()
-
-@PlannedRemoval("1.0.0")
-@Deprecated("use Iterator.toMutableList from stdlib", level = DeprecationLevel.HIDDEN)
-@OptIn(MiraiInternalAPI::class)
-fun <E : Contact> ContactList<E>.toMutableList(): MutableList<E> = this.delegate.toMutableList()
-
-@PlannedRemoval("1.0.0")
-@Deprecated("use Iterator.toSet from stdlib", level = DeprecationLevel.HIDDEN)
-fun <E : Contact> ContactList<E>.toSet(): Set<E> = toMutableSet()
-
-@PlannedRemoval("1.0.0")
-@Deprecated("use Iterator.toMutableSet from stdlib", level = DeprecationLevel.HIDDEN)
-@OptIn(MiraiInternalAPI::class)
-fun <E : Contact> ContactList<E>.toMutableSet(): MutableSet<E> = this.delegate.toMutableSet()
-
-@PlannedRemoval("1.0.0")
-@Deprecated("use Iterator.asSequence from stdlib", level = DeprecationLevel.HIDDEN)
-@OptIn(MiraiInternalAPI::class)
-fun <E : Contact> ContactList<E>.asSequence(): Sequence<E> = this.delegate.asSequence()
+}

+ 1 - 1
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/contact/Friend.kt

@@ -30,7 +30,7 @@ import kotlin.jvm.JvmSynthetic
  * 它不能被直接构造. 任何时候都应从 [Bot.getFriend] 或事件中获取.
  * 它不能被直接构造. 任何时候都应从 [Bot.getFriend] 或事件中获取.
  */
  */
 @Suppress("DEPRECATION_ERROR")
 @Suppress("DEPRECATION_ERROR")
-abstract class Friend : QQ(), CoroutineScope {
+abstract class Friend : User(), CoroutineScope {
     /**
     /**
      * 请求头像下载链接
      * 请求头像下载链接
      */
      */

+ 1 - 13
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/contact/Member.kt

@@ -19,10 +19,8 @@ import net.mamoe.mirai.message.MessageReceipt
 import net.mamoe.mirai.message.data.Message
 import net.mamoe.mirai.message.data.Message
 import net.mamoe.mirai.message.data.toMessage
 import net.mamoe.mirai.message.data.toMessage
 import net.mamoe.mirai.utils.MiraiInternalAPI
 import net.mamoe.mirai.utils.MiraiInternalAPI
-import net.mamoe.mirai.utils.PlannedRemoval
 import net.mamoe.mirai.utils.SinceMirai
 import net.mamoe.mirai.utils.SinceMirai
 import net.mamoe.mirai.utils.WeakRefProperty
 import net.mamoe.mirai.utils.WeakRefProperty
-import kotlin.jvm.JvmName
 import kotlin.jvm.JvmSynthetic
 import kotlin.jvm.JvmSynthetic
 import kotlin.time.Duration
 import kotlin.time.Duration
 import kotlin.time.ExperimentalTime
 import kotlin.time.ExperimentalTime
@@ -191,7 +189,7 @@ inline fun <R> Member.takeIfIsFriend(block: (Friend) -> R): R? {
 /**
 /**
  * 获取非空群名片或昵称.
  * 获取非空群名片或昵称.
  *
  *
- * 若 [群名片][Member.nameCard] 不为空则返回群名片, 为空则返回 [QQ.nick]
+ * 若 [群名片][Member.nameCard] 不为空则返回群名片, 为空则返回 [User.nick]
  */
  */
 val Member.nameCardOrNick: String get() = this.nameCard.takeIf { it.isNotEmpty() } ?: this.nick
 val Member.nameCardOrNick: String get() = this.nameCard.takeIf { it.isNotEmpty() } ?: this.nick
 
 
@@ -209,16 +207,6 @@ val User.nameCardOrNick: String
         else -> this.nick
         else -> this.nick
     }
     }
 
 
-/**
- * 判断改成员是否处于禁言状态.
- */
-@JvmName("isMuted2") // make compiler happy
-@Suppress("INVISIBLE_MEMBER", "INVISIBLE_REFERENCE")
[email protected] // val Member.isMuted 编译在 JVM 也会产生 `public boolean isMuted(Member receive)`
-@PlannedRemoval("1.0.0")
-@Deprecated("use property instead", ReplaceWith("this.isMuted"))
-inline fun Member.isMuted(): Boolean = this.isMuted
-
 /**
 /**
  * 判断群成员是否处于禁言状态.
  * 判断群成员是否处于禁言状态.
  */
  */

+ 0 - 74
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/contact/QQ.kt

@@ -1,74 +0,0 @@
-/*
- * Copyright 2020 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("EXPERIMENTAL_API_USAGE", "unused")
-
-package net.mamoe.mirai.contact
-
-import kotlinx.coroutines.CoroutineScope
-import net.mamoe.mirai.Bot
-import net.mamoe.mirai.event.events.EventCancelledException
-import net.mamoe.mirai.event.events.MessageSendEvent.FriendMessageSendEvent
-import net.mamoe.mirai.event.events.MessageSendEvent.GroupMessageSendEvent
-import net.mamoe.mirai.message.MessageReceipt
-import net.mamoe.mirai.message.data.Message
-import net.mamoe.mirai.utils.PlannedRemoval
-import kotlin.jvm.JvmSynthetic
-
-/**
- * QQ 对象.
- *
- * 自 0.39.0 起 mirai 引入 [User] 作为 [Friend] 和 [Member] 的父类,
- * 以备将来支持仅 [Friend] 可用的 API, 如设置备注.
- *
- * 所有 API 均有二进制兼容.
- *
- * 请根据实际情况, 使用 [Friend] 或 [User] 替代.
- */
-@PlannedRemoval("1.0.0")
-@Deprecated(
-    "use Friend or Person instead",
-    replaceWith = ReplaceWith("Friend", "net.mamoe.mirai.contact.Friend"),
-    level = DeprecationLevel.ERROR
-)
-@Suppress("DEPRECATION_ERROR")
-abstract class QQ : User(), CoroutineScope {
-    /**
-     * QQ 号码
-     */
-    abstract override val id: Long
-
-    /**
-     * 昵称
-     */
-    abstract override val nick: String
-
-    /**
-     * 头像下载链接
-     */
-    override val avatarUrl: String
-        get() = "http://q1.qlogo.cn/g?b=qq&nk=$id&s=640"
-
-    /**
-     * 向这个对象发送消息.
-     *
-     * 单条消息最大可发送 4500 字符或 50 张图片.
-     *
-     * @see FriendMessageSendEvent 发送好友信息事件, cancellable
-     * @see GroupMessageSendEvent  发送群消息事件. cancellable
-     *
-     * @throws EventCancelledException 当发送消息事件被取消时抛出
-     * @throws BotIsBeingMutedException 发送群消息时若 [Bot] 被禁言抛出
-     * @throws MessageTooLargeException 当消息过长时抛出
-     *
-     * @return 消息回执. 可进行撤回 ([MessageReceipt.recall])
-     */
-    @JvmSynthetic
-    abstract override suspend fun sendMessage(message: Message): MessageReceipt<QQ>
-}

+ 1 - 1
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/contact/javaFriendly.kt

@@ -27,4 +27,4 @@ expect abstract class ContactJavaFriendlyAPI internal constructor()
 @Suppress("DEPRECATION_ERROR")
 @Suppress("DEPRECATION_ERROR")
 @MiraiInternalAPI
 @MiraiInternalAPI
 @JavaFriendlyAPI
 @JavaFriendlyAPI
-expect abstract class MemberJavaFriendlyAPI internal constructor() : QQ // 将来会改为 User
+expect abstract class MemberJavaFriendlyAPI internal constructor() : User

+ 1 - 1
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/event/Event.kt

@@ -70,7 +70,7 @@ interface Event {
 abstract class AbstractEvent : Event {
 abstract class AbstractEvent : Event {
     @Suppress("WRONG_MODIFIER_CONTAINING_DECLARATION", "PropertyName")
     @Suppress("WRONG_MODIFIER_CONTAINING_DECLARATION", "PropertyName")
     @get:JvmSynthetic // so Java user won't see it
     @get:JvmSynthetic // so Java user won't see it
-    @Deprecated("", level = DeprecationLevel.HIDDEN)
+    @Deprecated("prohibit illegal overrides", level = DeprecationLevel.HIDDEN)
     final override val DoNotImplementThisClassButExtendAbstractEvent: Nothing
     final override val DoNotImplementThisClassButExtendAbstractEvent: Nothing
         get() = throw Error("Shouldn't be reached")
         get() = throw Error("Shouldn't be reached")
 
 

+ 0 - 75
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/event/MessageSubscribersBuilder.kt

@@ -22,8 +22,6 @@ import net.mamoe.mirai.message.FriendMessage
 import net.mamoe.mirai.message.GroupMessage
 import net.mamoe.mirai.message.GroupMessage
 import net.mamoe.mirai.message.TempMessage
 import net.mamoe.mirai.message.TempMessage
 import net.mamoe.mirai.message.data.*
 import net.mamoe.mirai.message.data.*
-import net.mamoe.mirai.utils.PlannedRemoval
-import kotlin.js.JsName
 import kotlin.jvm.JvmName
 import kotlin.jvm.JvmName
 import kotlin.jvm.JvmOverloads
 import kotlin.jvm.JvmOverloads
 import kotlin.jvm.JvmSynthetic
 import kotlin.jvm.JvmSynthetic
@@ -440,79 +438,6 @@ open class MessageSubscribersBuilder<M : ContactMessage, out Ret, R : RR, RR>(
         }
         }
         return stub
         return stub
     }
     }
-
-    /**
-     * 不考虑空格, [消息内容][Message.contentToString]以 [this] 开始则执行 [replier] 并将其返回值回复给发信对象.
-     * @param replier 若返回 [Message] 则直接发送; 若返回 [Unit] 则不回复; 其他类型则 [Any.toString] 后回复
-     */
-    @PlannedRemoval("1.0.0")
-    @Deprecated("use startsWith on your own", replaceWith = ReplaceWith("startsWith(this, true, true, replier)"))
-    open infix fun String.startsWithReply(replier: @MessageDsl suspend M.(String) -> Any?): Ret {
-        val toCheck = this.trimStart()
-        return content({ it.trim().startsWith(toCheck) }, {
-            executeAndReply(this) { replier(this, it.trim().removePrefix(toCheck)) }
-        })
-    }
-
-    @PlannedRemoval("1.0.0")
-    @Deprecated("for binary compatibility", level = DeprecationLevel.HIDDEN)
-    fun contains(message: Message, onEvent: MessageListener<M, R>): Ret {
-        return content({ this.message.any { it == message } }, onEvent)
-    }
-
-    @JvmName("case1")
-    @JsName("case1")
-    @PlannedRemoval("1.0.0")
-    @Deprecated("use String.invoke", level = DeprecationLevel.ERROR, replaceWith = ReplaceWith("this(block)"))
-    infix fun String.`->`(block: MessageListener<M, R>): Ret {
-        return this(block)
-    }
-
-    @PlannedRemoval("1.0.0")
-    @Deprecated("for binary compatibility", level = DeprecationLevel.HIDDEN)
-    fun containsAll(
-        vararg sub: String,
-        ignoreCase: Boolean = false,
-        trim: Boolean = true,
-        onEvent: MessageListener<M, R>
-    ): Ret = containsAllImpl(sub, ignoreCase = ignoreCase, trim = trim).invoke(onEvent)
-
-    @PlannedRemoval("1.0.0")
-    @Deprecated("for binary compatibility", level = DeprecationLevel.HIDDEN)
-    fun containsAny(
-        vararg sub: String,
-        ignoreCase: Boolean = false,
-        trim: Boolean = true,
-        onEvent: MessageListener<M, R>
-    ): Ret = containsAnyImpl(*sub, ignoreCase = ignoreCase, trim = trim).invoke(onEvent)
-
-
-    @PlannedRemoval("1.0.0")
-    @Deprecated("for binary compatibility", level = DeprecationLevel.HIDDEN)
-    fun sentBy(name: String, onEvent: MessageListener<M, R>): Ret =
-        content({ (this as? GroupMessage)?.senderName == name }, onEvent)
-
-
-    @PlannedRemoval("1.0.0")
-    @Deprecated("for binary compatibility", level = DeprecationLevel.HIDDEN)
-    fun sentByOperator(onEvent: MessageListener<M, R>): Ret =
-        content({ this is GroupMessage && this.sender.isOperator() }, onEvent)
-
-    @PlannedRemoval("1.0.0")
-    @Deprecated("for binary compatibility", level = DeprecationLevel.HIDDEN)
-    fun sentByAdministrator(onEvent: MessageListener<M, R>): Ret =
-        content({ this is GroupMessage && this.sender.isAdministrator() }, onEvent)
-
-    @PlannedRemoval("1.0.0")
-    @Deprecated("for binary compatibility", level = DeprecationLevel.HIDDEN)
-    fun sentByOwner(onEvent: MessageListener<M, R>): Ret =
-        content({ this is GroupMessage && this.sender.isOwner() }, onEvent)
-
-    @PlannedRemoval("1.0.0")
-    @Deprecated("for binary compatibility", level = DeprecationLevel.HIDDEN)
-    fun sentFrom(groupId: Long, onEvent: MessageListener<GroupMessage, R>): Ret =
-        content({ this is GroupMessage && this.group.id == groupId }) { onEvent(this as GroupMessage, it) }
-
 }
 }
 
 
 /**
 /**

+ 9 - 40
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/event/events/BotEvents.kt

@@ -25,7 +25,10 @@ import net.mamoe.mirai.message.data.Image
 import net.mamoe.mirai.message.data.MessageChain
 import net.mamoe.mirai.message.data.MessageChain
 import net.mamoe.mirai.message.data.MessageSource
 import net.mamoe.mirai.message.data.MessageSource
 import net.mamoe.mirai.qqandroid.network.Packet
 import net.mamoe.mirai.qqandroid.network.Packet
-import net.mamoe.mirai.utils.*
+import net.mamoe.mirai.utils.ExternalImage
+import net.mamoe.mirai.utils.MiraiExperimentalAPI
+import net.mamoe.mirai.utils.MiraiInternalAPI
+import net.mamoe.mirai.utils.SinceMirai
 import net.mamoe.mirai.utils.internal.runBlocking
 import net.mamoe.mirai.utils.internal.runBlocking
 import kotlin.jvm.JvmField
 import kotlin.jvm.JvmField
 import kotlin.jvm.JvmName
 import kotlin.jvm.JvmName
@@ -148,7 +151,7 @@ sealed class MessageRecallEvent : BotEvent, AbstractEvent() {
         override val messageInternalId: Int,
         override val messageInternalId: Int,
         override val messageTime: Int,
         override val messageTime: Int,
         /**
         /**
-         * 撤回操作人, 可能为 [Bot.uin] 或好友的 [QQ.id]
+         * 撤回操作人, 可能为 [Bot.uin] 或好友的 [User.id]
          */
          */
         val operator: Long
         val operator: Long
     ) : MessageRecallEvent(), Packet {
     ) : MessageRecallEvent(), Packet {
@@ -566,17 +569,8 @@ data class MemberCardChangeEvent(
      */
      */
     val new: String,
     val new: String,
 
 
-    override val member: Member,
-
-    /**
-     * 此事件无法确定操作人, 将在未来版本删除
-     */
-    @PlannedRemoval("1.0.0")
-    @Deprecated("operator is always unknown", level = DeprecationLevel.ERROR)
-    override val operator: Member?
-) : GroupMemberEvent, Packet, AbstractEvent(),
-    @Deprecated("operator is always unknown", level = DeprecationLevel.ERROR)
-    GroupOperableEvent
+    override val member: Member
+) : GroupMemberEvent, Packet, AbstractEvent()
 
 
 /**
 /**
  * 成员群头衔改动. 一定为群主操作
  * 成员群头衔改动. 一定为群主操作
@@ -660,16 +654,7 @@ data class FriendRemarkChangeEvent(
     override val bot: Bot,
     override val bot: Bot,
     val friend: Friend,
     val friend: Friend,
     val newName: String
     val newName: String
-) : BotEvent, Packet, AbstractEvent() {
-
-    @PlannedRemoval("1.0.0")
-    @Deprecated("", level = DeprecationLevel.HIDDEN)
-    @get:JvmSynthetic
-    @get:JvmName("getFriend")
-    @Suppress("INAPPLICABLE_JVM_NAME", "DEPRECATION_ERROR")
-    val friendDeprecated: QQ
-        get() = friend
-}
+) : BotEvent, Packet, AbstractEvent()
 
 
 /**
 /**
  * 成功添加了一个新好友的事件
  * 成功添加了一个新好友的事件
@@ -682,14 +667,6 @@ data class FriendAddEvent(
     val friend: Friend
     val friend: Friend
 ) : BotEvent, Packet, AbstractEvent() {
 ) : BotEvent, Packet, AbstractEvent() {
     override val bot: Bot get() = friend.bot
     override val bot: Bot get() = friend.bot
-
-    @PlannedRemoval("1.0.0")
-    @Deprecated("", level = DeprecationLevel.HIDDEN)
-    @get:JvmSynthetic
-    @get:JvmName("getFriend")
-    @Suppress("INAPPLICABLE_JVM_NAME", "DEPRECATION_ERROR")
-    val friendDeprecated: QQ
-        get() = friend
 }
 }
 
 
 /**
 /**
@@ -700,14 +677,6 @@ data class FriendDeleteEvent(
     val friend: Friend
     val friend: Friend
 ) : BotEvent, Packet, AbstractEvent() {
 ) : BotEvent, Packet, AbstractEvent() {
     override val bot: Bot get() = friend.bot
     override val bot: Bot get() = friend.bot
-
-    @PlannedRemoval("1.0.0")
-    @Deprecated("", level = DeprecationLevel.HIDDEN)
-    @get:JvmSynthetic
-    @get:JvmName("getFriend")
-    @Suppress("INAPPLICABLE_JVM_NAME", "DEPRECATION_ERROR")
-    val friendDeprecated: QQ
-        get() = friend
 }
 }
 
 
 /**
 /**
@@ -725,7 +694,7 @@ data class NewFriendRequestEvent(
      */
      */
     val message: String,
     val message: String,
     /**
     /**
-     * 请求人 [QQ.id]
+     * 请求人 [User.id]
      */
      */
     val fromId: Long,
     val fromId: Long,
     /**
     /**

+ 0 - 9
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/event/events/types.kt

@@ -15,8 +15,6 @@ import net.mamoe.mirai.contact.Group
 import net.mamoe.mirai.contact.Member
 import net.mamoe.mirai.contact.Member
 import net.mamoe.mirai.event.Event
 import net.mamoe.mirai.event.Event
 import net.mamoe.mirai.utils.MiraiExperimentalAPI
 import net.mamoe.mirai.utils.MiraiExperimentalAPI
-import kotlin.jvm.JvmName
-import kotlin.jvm.JvmSynthetic
 
 
 /**
 /**
  * 有关一个 [Bot] 的事件
  * 有关一个 [Bot] 的事件
@@ -90,11 +88,4 @@ interface FriendEvent : BotEvent {
     val friend: Friend
     val friend: Friend
     override val bot: Bot
     override val bot: Bot
         get() = friend.bot
         get() = friend.bot
-
-    @Deprecated("", level = DeprecationLevel.HIDDEN)
-    @get:JvmSynthetic
-    @get:JvmName("getFriend")
-    @Suppress("INAPPLICABLE_JVM_NAME", "DEPRECATION_ERROR")
-    val friendDeprecated: net.mamoe.mirai.contact.QQ
-        get() = friend
 }
 }

+ 0 - 3
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/event/select.kt

@@ -185,9 +185,6 @@ abstract class MessageSelectBuilder<M : ContactMessage, R> @PublishedApi interna
     @Deprecated("Using `reply` DSL in message selection is prohibited", level = DeprecationLevel.HIDDEN)
     @Deprecated("Using `reply` DSL in message selection is prohibited", level = DeprecationLevel.HIDDEN)
     override fun Regex.findingReply(replier: suspend M.(MatchResult) -> Any?) = error("prohibited")
     override fun Regex.findingReply(replier: suspend M.(MatchResult) -> Any?) = error("prohibited")
 
 
-    @Deprecated("Using `reply` DSL in message selection is prohibited", level = DeprecationLevel.HIDDEN)
-    override fun String.startsWithReply(replier: suspend M.(String) -> Any?) = error("prohibited")
-
     @Deprecated("Using `reply` DSL in message selection is prohibited", level = DeprecationLevel.HIDDEN)
     @Deprecated("Using `reply` DSL in message selection is prohibited", level = DeprecationLevel.HIDDEN)
     override fun String.endsWithReply(replier: suspend M.(String) -> Any?) = error("prohibited")
     override fun String.endsWithReply(replier: suspend M.(String) -> Any?) = error("prohibited")
 
 

+ 5 - 59
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/message/ContactMessage.kt

@@ -21,7 +21,6 @@ package net.mamoe.mirai.message
 import kotlinx.coroutines.Deferred
 import kotlinx.coroutines.Deferred
 import kotlinx.coroutines.TimeoutCancellationException
 import kotlinx.coroutines.TimeoutCancellationException
 import kotlinx.coroutines.async
 import kotlinx.coroutines.async
-import kotlinx.coroutines.io.ByteReadChannel
 import net.mamoe.mirai.Bot
 import net.mamoe.mirai.Bot
 import net.mamoe.mirai.contact.*
 import net.mamoe.mirai.contact.*
 import net.mamoe.mirai.event.*
 import net.mamoe.mirai.event.*
@@ -78,8 +77,9 @@ abstract class MessagePacketBase<out TSender : User, out TSubject : Contact> : P
     /**
     /**
      * 消息事件主体.
      * 消息事件主体.
      *
      *
-     * 对于好友消息, 这个属性为 [QQ] 的实例, 与 [sender] 引用相同;
-     * 对于群消息, 这个属性为 [Group] 的实例, 与 [GroupMessage.group] 引用相同
+     * - 对于好友消息, 这个属性为 [Friend] 的实例, 与 [sender] 引用相同;
+     * - 对于临时会话消息, 这个属性为 [Member] 的实例, 与 [sender] 引用相同;
+     * - 对于群消息, 这个属性为 [Group] 的实例, 与 [GroupMessage.group] 引用相同
      *
      *
      * 在回复消息时, 可通过 [subject] 作为回复对象
      * 在回复消息时, 可通过 [subject] 作为回复对象
      */
      */
@@ -89,7 +89,7 @@ abstract class MessagePacketBase<out TSender : User, out TSubject : Contact> : P
     /**
     /**
      * 发送人.
      * 发送人.
      *
      *
-     * 在好友消息时为 [QQ] 的实例, 在群消息时为 [Member] 的实例
+     * 在好友消息时为 [Friend] 的实例, 在群消息时为 [Member] 的实例
      */
      */
     @WeakRefProperty
     @WeakRefProperty
     abstract val sender: TSender
     abstract val sender: TSender
@@ -178,53 +178,7 @@ abstract class MessagePacketBase<out TSender : User, out TSubject : Contact> : P
      */
      */
     suspend inline fun Image.url(): String = bot.queryImageUrl(this@url)
     suspend inline fun Image.url(): String = bot.queryImageUrl(this@url)
 
 
-    /**
-     * 获取图片下载链接并开始下载.
-     *
-     * @see ByteReadChannel.copyAndClose
-     * @see ByteReadChannel.copyTo
-     */
-    @Suppress("DeprecatedCallableAddReplaceWith", "DEPRECATION")
-    @PlannedRemoval("1.0.0")
-    @Deprecated("use your own Http clients, this is going to be removed in 1.0.0", level = DeprecationLevel.WARNING)
-    suspend inline fun Image.channel(): ByteReadChannel = bot.openChannel(this)
     // endregion
     // endregion
-
-
-    @PlannedRemoval("1.0.0")
-    @Deprecated("use reply(String) for clear semantics", ReplaceWith("reply(this)"),
-        DeprecationLevel.ERROR)
-    @JvmName("reply1")
-    suspend inline fun String.reply(): MessageReceipt<TSubject> = reply(this)
-
-    @PlannedRemoval("1.0.0")
-    @Deprecated("use reply(String) for clear semantics", ReplaceWith("reply(this)"),
-        level = DeprecationLevel.ERROR)
-    @JvmName("reply1")
-    suspend inline fun Message.reply(): MessageReceipt<TSubject> = reply(this)
-
-    @Deprecated("for binary compatibility", level = DeprecationLevel.HIDDEN)
-    @get:JvmSynthetic
-    @get:JvmName("getSender")
-    @Suppress("DEPRECATION_ERROR", "INAPPLICABLE_JVM_NAME")
-    val senderDeprecated: QQ
-        get() = sender as QQ
-
-    @Suppress("DEPRECATION_ERROR")
-    @PlannedRemoval("1.0.0")
-    @Deprecated("removed",
-        level = DeprecationLevel.ERROR,
-        replaceWith = ReplaceWith("At(this as? Member ?: error(\"`QQ.at` can only be used in GroupMessage\"))",
-            "net.mamoe.mirai.message.data.At",
-            "net.mamoe.mirai.contact.Member"))
-    fun QQ.at(): At = At(this as? Member ?: error("`QQ.at` can only be used in GroupMessage"))
-
-    @PlannedRemoval("1.0.0")
-    @Deprecated("removed",
-        level = DeprecationLevel.ERROR,
-        replaceWith = ReplaceWith("(this@MessagePacketBase as? GroupMessage)?.group?.get(this.target) ?: error(\"`At.member` can only be used in GroupMessage\")"))
-    fun At.member(): Member = (this@MessagePacketBase as? GroupMessage)?.group?.get(this.target)
-        ?: error("`At.member` can only be used in GroupMessage")
 }
 }
 
 
 /**
 /**
@@ -427,12 +381,4 @@ inline fun <reified M : Message> ContactMessage.nextMessageContainingOrNullAsync
                 .takeIf { this.message.anyIsInstance<M>() }
                 .takeIf { this.message.anyIsInstance<M>() }
         }?.message?.firstIsInstance<M>()
         }?.message?.firstIsInstance<M>()
     }
     }
-}
-
-
-@PlannedRemoval("1.0.0")
-@Suppress("DEPRECATION")
-@Deprecated(level = DeprecationLevel.HIDDEN, message = "for binary compatibility")
-fun MessagePacket<*, *>.isContextIdenticalWith(another: MessagePacket<*, *>): Boolean {
-    return (this as ContactMessage).isContextIdenticalWith(another as ContactMessage)
-}
+}

+ 0 - 11
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/message/FriendMessage.kt

@@ -13,14 +13,11 @@ package net.mamoe.mirai.message
 
 
 import net.mamoe.mirai.Bot
 import net.mamoe.mirai.Bot
 import net.mamoe.mirai.contact.Friend
 import net.mamoe.mirai.contact.Friend
-import net.mamoe.mirai.contact.QQ
 import net.mamoe.mirai.event.BroadcastControllable
 import net.mamoe.mirai.event.BroadcastControllable
 import net.mamoe.mirai.message.data.MessageChain
 import net.mamoe.mirai.message.data.MessageChain
 import net.mamoe.mirai.message.data.MessageSource
 import net.mamoe.mirai.message.data.MessageSource
 import net.mamoe.mirai.message.data.OnlineMessageSource
 import net.mamoe.mirai.message.data.OnlineMessageSource
 import net.mamoe.mirai.message.data.source
 import net.mamoe.mirai.message.data.source
-import net.mamoe.mirai.utils.PlannedRemoval
-import net.mamoe.mirai.utils.currentTimeSeconds
 import net.mamoe.mirai.utils.getValue
 import net.mamoe.mirai.utils.getValue
 import net.mamoe.mirai.utils.unsafeWeakRef
 import net.mamoe.mirai.utils.unsafeWeakRef
 
 
@@ -32,14 +29,6 @@ class FriendMessage constructor(
     override val message: MessageChain,
     override val message: MessageChain,
     override val time: Int
     override val time: Int
 ) : ContactMessage(), BroadcastControllable {
 ) : ContactMessage(), BroadcastControllable {
-    @PlannedRemoval("1.0.0")
-    @Deprecated("", level = DeprecationLevel.HIDDEN)
-    constructor(sender: QQ, message: MessageChain) : this(sender as Friend, message, currentTimeSeconds.toInt())
-
-    @PlannedRemoval("1.0.0")
-    @Deprecated("", level = DeprecationLevel.HIDDEN)
-    constructor(sender: Friend, message: MessageChain) : this(sender, message, currentTimeSeconds.toInt())
-
     init {
     init {
         val source = message.getOrNull(MessageSource) ?: error("Cannot find MessageSource from message")
         val source = message.getOrNull(MessageSource) ?: error("Cannot find MessageSource from message")
         check(source is OnlineMessageSource.Incoming.FromFriend) { "source provided to a FriendMessage must be an instance of OnlineMessageSource.Incoming.FromFriend" }
         check(source is OnlineMessageSource.Incoming.FromFriend) { "source provided to a FriendMessage must be an instance of OnlineMessageSource.Incoming.FromFriend" }

+ 0 - 7
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/message/GroupMessage.kt

@@ -15,8 +15,6 @@ import net.mamoe.mirai.contact.Member
 import net.mamoe.mirai.contact.MemberPermission
 import net.mamoe.mirai.contact.MemberPermission
 import net.mamoe.mirai.event.Event
 import net.mamoe.mirai.event.Event
 import net.mamoe.mirai.message.data.*
 import net.mamoe.mirai.message.data.*
-import net.mamoe.mirai.utils.PlannedRemoval
-import net.mamoe.mirai.utils.currentTimeSeconds
 import net.mamoe.mirai.utils.getValue
 import net.mamoe.mirai.utils.getValue
 import net.mamoe.mirai.utils.unsafeWeakRef
 import net.mamoe.mirai.utils.unsafeWeakRef
 
 
@@ -31,11 +29,6 @@ class GroupMessage(
     override val message: MessageChain,
     override val message: MessageChain,
     override val time: Int
     override val time: Int
 ) : ContactMessage(), Event {
 ) : ContactMessage(), Event {
-    @PlannedRemoval("1.0.0")
-    @Deprecated("", level = DeprecationLevel.HIDDEN)
-    constructor(senderName: String, permission: MemberPermission, sender: Member, message: MessageChain) :
-            this(senderName, permission, sender, message, currentTimeSeconds.toInt())
-
     init {
     init {
         val source = message.getOrNull(MessageSource) ?: error("Cannot find MessageSource from message")
         val source = message.getOrNull(MessageSource) ?: error("Cannot find MessageSource from message")
         check(source is OnlineMessageSource.Incoming.FromGroup) { "source provided to a GroupMessage must be an instance of OnlineMessageSource.Incoming.FromGroup" }
         check(source is OnlineMessageSource.Incoming.FromGroup) { "source provided to a GroupMessage must be an instance of OnlineMessageSource.Incoming.FromGroup" }

+ 2 - 13
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/message/MessageReceipt.kt

@@ -19,7 +19,6 @@ import net.mamoe.mirai.message.data.*
 import net.mamoe.mirai.recallIn
 import net.mamoe.mirai.recallIn
 import net.mamoe.mirai.utils.MiraiExperimentalAPI
 import net.mamoe.mirai.utils.MiraiExperimentalAPI
 import net.mamoe.mirai.utils.MiraiInternalAPI
 import net.mamoe.mirai.utils.MiraiInternalAPI
-import net.mamoe.mirai.utils.PlannedRemoval
 import net.mamoe.mirai.utils.internal.runBlocking
 import net.mamoe.mirai.utils.internal.runBlocking
 import kotlin.coroutines.CoroutineContext
 import kotlin.coroutines.CoroutineContext
 import kotlin.coroutines.EmptyCoroutineContext
 import kotlin.coroutines.EmptyCoroutineContext
@@ -35,7 +34,7 @@ import kotlin.jvm.JvmSynthetic
  * @param target 消息发送对象
  * @param target 消息发送对象
  *
  *
  * @see Group.sendMessage 发送群消息, 返回回执(此对象)
  * @see Group.sendMessage 发送群消息, 返回回执(此对象)
- * @see QQ.sendMessage 发送群消息, 返回回执(此对象)
+ * @see User.sendMessage 发送群消息, 返回回执(此对象)
  * @see Member.sendMessage 发送临时消息, 返回回执(此对象)
  * @see Member.sendMessage 发送临时消息, 返回回执(此对象)
  *
  *
  * @see MessageReceipt.sourceId 源 id
  * @see MessageReceipt.sourceId 源 id
@@ -48,7 +47,7 @@ open class MessageReceipt<out C : Contact>(
      */
      */
     val source: OnlineMessageSource.Outgoing,
     val source: OnlineMessageSource.Outgoing,
     /**
     /**
-     * 发送目标, 为 [Group] 或 [QQ] 或 [Member]
+     * 发送目标, 为 [Group] 或 [Friend] 或 [Member]
      */
      */
     val target: C,
     val target: C,
 
 
@@ -89,16 +88,6 @@ open class MessageReceipt<out C : Contact>(
     fun __quoteBlockingForJava__(): QuoteReply {
     fun __quoteBlockingForJava__(): QuoteReply {
         return this.quote()
         return this.quote()
     }
     }
-
-
-    @PlannedRemoval("1.0.0")
-    @Deprecated("for binary compatibility", level = DeprecationLevel.HIDDEN)
-    @JvmSynthetic
-    @JavaFriendlyAPI
-    @JvmName("recall")
-    fun __recallInBlockingForJava__2(timeMillis: Long): Job {
-        return recallIn(timeMillis = timeMillis)
-    }
 }
 }
 
 
 /**
 /**

+ 3 - 6
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/message/TempMessage.kt

@@ -9,7 +9,9 @@ import net.mamoe.mirai.message.data.MessageChain
 import net.mamoe.mirai.message.data.MessageSource
 import net.mamoe.mirai.message.data.MessageSource
 import net.mamoe.mirai.message.data.OnlineMessageSource
 import net.mamoe.mirai.message.data.OnlineMessageSource
 import net.mamoe.mirai.message.data.source
 import net.mamoe.mirai.message.data.source
-import net.mamoe.mirai.utils.*
+import net.mamoe.mirai.utils.SinceMirai
+import net.mamoe.mirai.utils.getValue
+import net.mamoe.mirai.utils.unsafeWeakRef
 
 
 /**
 /**
  * 临时会话消息
  * 临时会话消息
@@ -20,11 +22,6 @@ class TempMessage(
     override val message: MessageChain,
     override val message: MessageChain,
     override val time: Int
     override val time: Int
 ) : ContactMessage(), BroadcastControllable {
 ) : ContactMessage(), BroadcastControllable {
-    @PlannedRemoval("1.0.0")
-    @Deprecated("", level = DeprecationLevel.HIDDEN)
-    constructor(sender: Member, message: MessageChain) :
-            this(sender, message, currentTimeSeconds.toInt())
-
     init {
     init {
         val source = message.getOrNull(MessageSource) ?: error("Cannot find MessageSource from message")
         val source = message.getOrNull(MessageSource) ?: error("Cannot find MessageSource from message")
         check(source is OnlineMessageSource.Incoming.FromTemp) { "source provided to a TempMessage must be an instance of OnlineMessageSource.Incoming.FromTemp" }
         check(source is OnlineMessageSource.Incoming.FromTemp) { "source provided to a TempMessage must be an instance of OnlineMessageSource.Incoming.FromTemp" }

+ 0 - 10
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/message/data/At.kt

@@ -17,7 +17,6 @@ package net.mamoe.mirai.message.data
 import net.mamoe.mirai.LowLevelAPI
 import net.mamoe.mirai.LowLevelAPI
 import net.mamoe.mirai.contact.Member
 import net.mamoe.mirai.contact.Member
 import net.mamoe.mirai.contact.nameCardOrNick
 import net.mamoe.mirai.contact.nameCardOrNick
-import net.mamoe.mirai.utils.MiraiInternalAPI
 import kotlin.jvm.JvmMultifileClass
 import kotlin.jvm.JvmMultifileClass
 import kotlin.jvm.JvmName
 import kotlin.jvm.JvmName
 import kotlin.jvm.JvmStatic
 import kotlin.jvm.JvmStatic
@@ -73,15 +72,6 @@ private constructor(val target: Long, val display: String) :
         return result
         return result
     }
     }
 
 
-
-    @OptIn(MiraiInternalAPI::class)
-    @Suppress("INAPPLICABLE_JVM_NAME", "EXPOSED_FUNCTION_RETURN_TYPE")
-    @Deprecated("for binary compatibility", level = DeprecationLevel.HIDDEN)
-    @JvmName("followedBy")
-    @JvmSynthetic
-    override fun followedBy1(tail: Message): CombinedMessage {
-        return followedByInternalForBinaryCompatibility(tail)
-    }
 }
 }
 
 
 /**
 /**

+ 4 - 22
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/message/data/Image.kt

@@ -94,6 +94,7 @@ expect interface Image : Message, MessageContent {
  * @property imageId 形如 `{01E9451B-70ED-EAE3-B37C-101F1EEBF5B5}.mirai` (后缀一定为 `".mirai"`)
  * @property imageId 形如 `{01E9451B-70ED-EAE3-B37C-101F1EEBF5B5}.mirai` (后缀一定为 `".mirai"`)
  * @see Image 查看更多说明
  * @see Image 查看更多说明
  */
  */
+@PlannedRemoval("1.2.0") // make internal
 @Suppress("DEPRECATION_ERROR")
 @Suppress("DEPRECATION_ERROR")
 // CustomFace
 // CustomFace
 @OptIn(MiraiInternalAPI::class)
 @OptIn(MiraiInternalAPI::class)
@@ -119,6 +120,7 @@ val Image.md5: ByteArray
  *
  *
  * [imageId] 形如 `/f8f1ab55-bf8e-4236-b55e-955848d7069f` (37 长度)  或 `/000000000-3814297509-BFB7027B9354B8F899A062061D74E206` (54 长度)
  * [imageId] 形如 `/f8f1ab55-bf8e-4236-b55e-955848d7069f` (37 长度)  或 `/000000000-3814297509-BFB7027B9354B8F899A062061D74E206` (54 长度)
  */ // NotOnlineImage
  */ // NotOnlineImage
+@PlannedRemoval("1.2.0") // make internal
 @Suppress("DEPRECATION_ERROR")
 @Suppress("DEPRECATION_ERROR")
 @OptIn(MiraiInternalAPI::class)
 @OptIn(MiraiInternalAPI::class)
 sealed class FriendImage : AbstractImage() {
 sealed class FriendImage : AbstractImage() {
@@ -157,17 +159,6 @@ val FRIEND_IMAGE_ID_REGEX_2 = Regex("""/[0-9]*-[0-9]*-[0-9a-fA-F]{32}""")
 // Java: MessageUtils.GROUP_IMAGE_ID_REGEX
 // Java: MessageUtils.GROUP_IMAGE_ID_REGEX
 val GROUP_IMAGE_ID_REGEX = Regex("""\{[0-9a-fA-F]{8}-([0-9a-fA-F]{4}-){3}[0-9a-fA-F]{12}\}\.mirai""")
 val GROUP_IMAGE_ID_REGEX = Regex("""\{[0-9a-fA-F]{8}-([0-9a-fA-F]{4}-){3}[0-9a-fA-F]{12}\}\.mirai""")
 
 
-/**
- * 在 `0.39.0` 前的图片的正则表示
- */
-@Suppress("RegExpRedundantEscape") // This is required on Android
-@Deprecated("Only for temporal use",
-    replaceWith = ReplaceWith("GROUP_IMAGE_ID_REGEX", "net.mamoe.mirai.message.data.GROUP_IMAGE_ID_REGEX"))
-@SinceMirai("0.39.2")
-@PlannedRemoval("1.0.0")
-// Java: MessageUtils.GROUP_IMAGE_ID_REGEX_OLD
-val GROUP_IMAGE_ID_REGEX_OLD = Regex("""\{[0-9a-fA-F]{8}-([0-9a-fA-F]{4}-){3}[0-9a-fA-F]{12}\}\..*""")
-
 /**
 /**
  * 通过 [Image.imageId] 构造一个 [Image] 以便发送.
  * 通过 [Image.imageId] 构造一个 [Image] 以便发送.
  * 这个图片必须是服务器已经存在的图片.
  * 这个图片必须是服务器已经存在的图片.
@@ -185,7 +176,6 @@ fun Image(imageId: String): OfflineImage = when {
     imageId matches FRIEND_IMAGE_ID_REGEX_1 -> OfflineFriendImage(imageId)
     imageId matches FRIEND_IMAGE_ID_REGEX_1 -> OfflineFriendImage(imageId)
     imageId matches FRIEND_IMAGE_ID_REGEX_2 -> OfflineFriendImage(imageId)
     imageId matches FRIEND_IMAGE_ID_REGEX_2 -> OfflineFriendImage(imageId)
     imageId matches GROUP_IMAGE_ID_REGEX -> OfflineGroupImage(imageId)
     imageId matches GROUP_IMAGE_ID_REGEX -> OfflineGroupImage(imageId)
-    imageId matches GROUP_IMAGE_ID_REGEX_OLD -> OfflineGroupImage(imageId)
     else -> throw IllegalArgumentException("Illegal imageId: $imageId. $ILLEGAL_IMAGE_ID_EXCEPTION_MESSAGE")
     else -> throw IllegalArgumentException("Illegal imageId: $imageId. $ILLEGAL_IMAGE_ID_EXCEPTION_MESSAGE")
 }
 }
 
 
@@ -279,7 +269,7 @@ data class OfflineGroupImage(
 ) : GroupImage(), OfflineImage {
 ) : GroupImage(), OfflineImage {
     init {
     init {
         @Suppress("DEPRECATION")
         @Suppress("DEPRECATION")
-        require(imageId matches GROUP_IMAGE_ID_REGEX || imageId matches GROUP_IMAGE_ID_REGEX_OLD) {
+        require(imageId matches GROUP_IMAGE_ID_REGEX) {
             "Illegal imageId. It must matches GROUP_IMAGE_ID_REGEX"
             "Illegal imageId. It must matches GROUP_IMAGE_ID_REGEX"
         }
         }
     }
     }
@@ -329,18 +319,10 @@ abstract class OnlineFriendImage : FriendImage(), OnlineImage
 // endregion
 // endregion
 
 
 
 
-@PlannedRemoval("1.0.0")
-@JvmSynthetic
-@Deprecated("for binary compatibility", level = DeprecationLevel.HIDDEN)
-@Suppress("FunctionName")
-@JsName("newImage")
-@JvmName("newImage")
-fun Image2(imageId: String): Image = Image(imageId)
-
-
 /**
 /**
  * 所有 [Image] 实现的基类.
  * 所有 [Image] 实现的基类.
  */
  */
+@PlannedRemoval("1.2.0") // make internal
 @Deprecated(
 @Deprecated(
     "This is internal API. Use Image instead",
     "This is internal API. Use Image instead",
     level = DeprecationLevel.HIDDEN, // so that others can't see this class
     level = DeprecationLevel.HIDDEN, // so that others can't see this class

+ 3 - 101
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/message/data/Message.kt

@@ -195,76 +195,6 @@ interface Message { // must be interface. Don't consider any changes.
 
 
     // `+ ""` will be resolved to `plus(String)` instead of `plus(CharSeq)`
     // `+ ""` will be resolved to `plus(String)` instead of `plus(CharSeq)`
     operator fun plus(another: CharSequence): MessageChain = this.followedBy(another.toString().toMessage())
     operator fun plus(another: CharSequence): MessageChain = this.followedBy(another.toString().toMessage())
-
-    //////////////////////////////////////
-    // FOR BINARY COMPATIBILITY UNTIL 1.0.0
-    //////////////////////////////////////
-
-    @PlannedRemoval("1.0.0")
-    @JvmSynthetic
-    @Deprecated(
-        "有歧义, 自行使用 contentToString() 比较",
-        ReplaceWith("this.contentToString() == other"),
-        DeprecationLevel.ERROR
-    )
-    infix fun eq(other: Message): Boolean = this.contentToString() == other.contentToString()
-
-    /**
-     * 将 [contentToString] 与 [other] 比较
-     */
-    @PlannedRemoval("1.0.0")
-    @JvmSynthetic
-    @Deprecated(
-        "有歧义, 自行使用 contentToString() 比较",
-        ReplaceWith("this.contentToString() == other"),
-        DeprecationLevel.ERROR
-    )
-    infix fun eq(other: String): Boolean = this.contentToString() == other
-
-    @PlannedRemoval("1.0.0")
-    @JvmSynthetic
-    @Deprecated(
-        "有歧义, 自行使用 contentToString() 比较",
-        ReplaceWith("this.contentToString() == other"),
-        DeprecationLevel.ERROR
-    )
-    operator fun contains(sub: String): Boolean = false
-
-    @PlannedRemoval("1.0.0")
-    @Suppress("INAPPLICABLE_JVM_NAME", "EXPOSED_FUNCTION_RETURN_TYPE")
-    @JvmName("followedBy")
-    @Deprecated("for binary compatibility", level = DeprecationLevel.HIDDEN)
-    @JvmSynthetic
-    fun followedBy1(tail: Message): CombinedMessage = this.followedByInternalForBinaryCompatibility(tail)
-
-    @PlannedRemoval("1.0.0")
-    @Suppress("INAPPLICABLE_JVM_NAME", "EXPOSED_FUNCTION_RETURN_TYPE")
-    @JvmName("plus")
-    @Deprecated("for binary compatibility", level = DeprecationLevel.HIDDEN)
-    @JvmSynthetic
-    fun plus1(another: Message): CombinedMessage = this.followedByInternalForBinaryCompatibility(another)
-
-    @PlannedRemoval("1.0.0")
-    @Suppress("INAPPLICABLE_JVM_NAME", "EXPOSED_FUNCTION_RETURN_TYPE")
-    @JvmName("plus")
-    @Deprecated("for binary compatibility", level = DeprecationLevel.HIDDEN)
-    @JvmSynthetic
-    fun plus1(another: SingleMessage): CombinedMessage = this.followedByInternalForBinaryCompatibility(another)
-
-    @PlannedRemoval("1.0.0")
-    @Suppress("INAPPLICABLE_JVM_NAME", "EXPOSED_FUNCTION_RETURN_TYPE")
-    @JvmName("plus")
-    @Deprecated("for binary compatibility", level = DeprecationLevel.HIDDEN)
-    @JvmSynthetic
-    fun plus1(another: String): CombinedMessage = this.followedByInternalForBinaryCompatibility(another.toMessage())
-
-    @PlannedRemoval("1.0.0")
-    @Suppress("INAPPLICABLE_JVM_NAME", "EXPOSED_FUNCTION_RETURN_TYPE")
-    @JvmName("plus")
-    @Deprecated("for binary compatibility", level = DeprecationLevel.HIDDEN)
-    @JvmSynthetic
-    fun plus1(another: CharSequence): CombinedMessage =
-        this.followedByInternalForBinaryCompatibility(another.toString().toMessage())
 }
 }
 
 
 
 
@@ -314,47 +244,19 @@ inline operator fun Message.times(count: Int): MessageChain = this.repeat(count)
 
 
 @Suppress("OverridingDeprecatedMember")
 @Suppress("OverridingDeprecatedMember")
 interface SingleMessage : Message {
 interface SingleMessage : Message {
-    @PlannedRemoval("1.0.0")
-    @JvmSynthetic
-    @Deprecated(
-        "有歧义, 自行使用 contentToString() 比较",
-        ReplaceWith("this.contentToString() == other"),
-        DeprecationLevel.ERROR
-    )
-    /* final */ override operator fun contains(sub: String): Boolean = sub in this.contentToString()
-
-    @PlannedRemoval("1.0.0")
-    @JvmSynthetic
-    @Deprecated(
-        "有歧义, 自行使用 contentToString() 比较",
-        ReplaceWith("this.contentToString() == other"),
-        DeprecationLevel.ERROR
-    )
-    /* final */ override infix fun eq(other: Message): Boolean = this.contentToString() == other.contentToString()
-
-    @PlannedRemoval("1.0.0")
-    @JvmSynthetic
-    @Deprecated(
-        "有歧义, 自行使用 contentToString() 比较",
-        ReplaceWith("this.contentToString() == other"),
-        DeprecationLevel.ERROR
-    )
-    /* final */ override infix fun eq(other: String): Boolean = this.contentToString() == other
-
-
-    @PlannedRemoval("1.1.0")
+    @PlannedRemoval("1.2.0")
     @JvmSynthetic
     @JvmSynthetic
     @SinceMirai("1.0.0")
     @SinceMirai("1.0.0")
     @Deprecated("for binary compatibility", level = DeprecationLevel.HIDDEN)
     @Deprecated("for binary compatibility", level = DeprecationLevel.HIDDEN)
     fun length(): Int = this.toString().length
     fun length(): Int = this.toString().length
 
 
-    @PlannedRemoval("1.1.0")
+    @PlannedRemoval("1.2.0")
     @JvmSynthetic
     @JvmSynthetic
     @SinceMirai("1.0.0")
     @SinceMirai("1.0.0")
     @Deprecated("for binary compatibility", level = DeprecationLevel.HIDDEN)
     @Deprecated("for binary compatibility", level = DeprecationLevel.HIDDEN)
     fun charAt(index: Int): Char = this.toString()[index]
     fun charAt(index: Int): Char = this.toString()[index]
 
 
-    @PlannedRemoval("1.1.0")
+    @PlannedRemoval("1.2.0")
     @JvmSynthetic
     @JvmSynthetic
     @SinceMirai("1.0.0")
     @SinceMirai("1.0.0")
     @Deprecated("for binary compatibility", level = DeprecationLevel.HIDDEN)
     @Deprecated("for binary compatibility", level = DeprecationLevel.HIDDEN)

+ 2 - 45
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/message/data/MessageChain.kt

@@ -15,7 +15,6 @@ package net.mamoe.mirai.message.data
 
 
 import net.mamoe.mirai.utils.MiraiExperimentalAPI
 import net.mamoe.mirai.utils.MiraiExperimentalAPI
 import net.mamoe.mirai.utils.MiraiInternalAPI
 import net.mamoe.mirai.utils.MiraiInternalAPI
-import net.mamoe.mirai.utils.PlannedRemoval
 import net.mamoe.mirai.utils.SinceMirai
 import net.mamoe.mirai.utils.SinceMirai
 import kotlin.js.JsName
 import kotlin.js.JsName
 import kotlin.jvm.JvmMultifileClass
 import kotlin.jvm.JvmMultifileClass
@@ -32,7 +31,7 @@ import kotlin.reflect.KProperty
  * @see asMessageChain 将单个 [Message] 转换为 [MessageChain]
  * @see asMessageChain 将单个 [Message] 转换为 [MessageChain]
  * @see asMessageChain 将 [Iterable] 或 [Sequence] 委托为 [MessageChain]
  * @see asMessageChain 将 [Iterable] 或 [Sequence] 委托为 [MessageChain]
  *
  *
- * @see foreachContent 遍历内容
+ * @see forEachContent 遍历内容
  *
  *
  * @see orNull 属性委托扩展
  * @see orNull 属性委托扩展
  * @see orElse 属性委托扩展
  * @see orElse 属性委托扩展
@@ -40,14 +39,6 @@ import kotlin.reflect.KProperty
  * @see flatten 扁平化
  * @see flatten 扁平化
  */
  */
 interface MessageChain : Message, Iterable<SingleMessage> {
 interface MessageChain : Message, Iterable<SingleMessage> {
-    @PlannedRemoval("1.0.0")
-    @Deprecated(
-        "有歧义, 自行使用 contentToString() 比较",
-        level = DeprecationLevel.ERROR,
-        replaceWith = ReplaceWith("this.contentToString().contains(sub)")
-    )
-    /* final */ override operator fun contains(sub: String): Boolean = this.contentToString().contains(sub)
-
     /**
     /**
      * 元素数量. [EmptyMessageChain] 不参加计数.
      * 元素数量. [EmptyMessageChain] 不参加计数.
      */
      */
@@ -96,20 +87,6 @@ interface MessageChain : Message, Iterable<SingleMessage> {
     fun `__forEach for Java__`(block: (Message) -> Unit) {
     fun `__forEach for Java__`(block: (Message) -> Unit) {
         this.forEach(block)
         this.forEach(block)
     }
     }
-
-    @PlannedRemoval("1.0.0")
-    @Deprecated("for binary compatibility", level = DeprecationLevel.HIDDEN)
-    @JvmSynthetic
-    @Suppress("FunctionName", "INAPPLICABLE_JVM_NAME")
-    @JvmName("get")
-    fun <M : Message> get2(key: Message.Key<M>): M = first(key)
-
-    @PlannedRemoval("1.0.0")
-    @Deprecated("for binary compatibility", level = DeprecationLevel.HIDDEN)
-    @JvmSynthetic
-    @Suppress("FunctionName", "INAPPLICABLE_JVM_NAME")
-    @JvmName("getOrNull")
-    fun <M : Message> getOrNull2(key: Message.Key<M>): M? = getOrNull(key)
 }
 }
 
 
 // region accessors
 // region accessors
@@ -128,12 +105,6 @@ inline fun MessageChain.forEachContent(block: (MessageContent) -> Unit) {
     }
     }
 }
 }
 
 
-@Deprecated("typo, use forEachContent",
-    level = DeprecationLevel.ERROR,
-    replaceWith = ReplaceWith("forEachContent(block)"))
-@JvmSynthetic
-inline fun MessageChain.foreachContent(block: (MessageContent) -> Unit) = forEachContent(block)
-
 /**
 /**
  * 如果每一个 [消息内容][MessageContent] 都满足 [block], 返回 `true`
  * 如果每一个 [消息内容][MessageContent] 都满足 [block], 返回 `true`
  */
  */
@@ -435,18 +406,4 @@ object EmptyMessageChain : MessageChain, Iterator<SingleMessage> {
     override fun iterator(): Iterator<SingleMessage> = this
     override fun iterator(): Iterator<SingleMessage> = this
     override fun hasNext(): Boolean = false
     override fun hasNext(): Boolean = false
     override fun next(): SingleMessage = throw NoSuchElementException("EmptyMessageChain is empty.")
     override fun next(): SingleMessage = throw NoSuchElementException("EmptyMessageChain is empty.")
-}
-
-/**
- * Null 的 [MessageChain].
- * 它不包含任何元素, 也没有创建任何 list.
- */
-@PlannedRemoval("1.0.0")
-@Deprecated("ambiguous. use `null` or EmptyMessageChain instead", level = DeprecationLevel.ERROR)
-object NullMessageChain : MessageChain {
-    override fun toString(): String = "NullMessageChain"
-    override fun contentToString(): String = ""
-    override val size: Int get() = 0
-    override fun equals(other: Any?): Boolean = other === this
-    override fun iterator(): MutableIterator<SingleMessage> = error("accessing NullMessageChain")
-}
+}

+ 4 - 28
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/message/data/MessageSource.kt

@@ -19,7 +19,10 @@ import net.mamoe.mirai.contact.*
 import net.mamoe.mirai.message.ContactMessage
 import net.mamoe.mirai.message.ContactMessage
 import net.mamoe.mirai.message.MessageReceipt
 import net.mamoe.mirai.message.MessageReceipt
 import net.mamoe.mirai.recallIn
 import net.mamoe.mirai.recallIn
-import net.mamoe.mirai.utils.*
+import net.mamoe.mirai.utils.LazyProperty
+import net.mamoe.mirai.utils.MiraiExperimentalAPI
+import net.mamoe.mirai.utils.MiraiInternalAPI
+import net.mamoe.mirai.utils.SinceMirai
 import kotlin.coroutines.CoroutineContext
 import kotlin.coroutines.CoroutineContext
 import kotlin.coroutines.EmptyCoroutineContext
 import kotlin.coroutines.EmptyCoroutineContext
 import kotlin.jvm.JvmMultifileClass
 import kotlin.jvm.JvmMultifileClass
@@ -279,34 +282,7 @@ sealed class OnlineMessageSource : MessageSource() {
             final override val target: Group get() = group
             final override val target: Group get() = group
             inline val group: Group get() = sender.group
             inline val group: Group get() = sender.group
         }
         }
-
-
-        //////////////////////////////////
-        //// FOR BINARY COMPATIBILITY ////
-        //////////////////////////////////
-
-
-        @PlannedRemoval("1.0.0")
-        @Deprecated("for binary compatibility until 1.0.0", level = DeprecationLevel.HIDDEN)
-        @get:JvmName("target")
-        @get:JvmSynthetic
-        final override val target2: Any
-            get() = target
     }
     }
-
-    @PlannedRemoval("1.0.0")
-    @Deprecated("for binary compatibility until 1.0.0", level = DeprecationLevel.HIDDEN)
-    @get:JvmName("target")
-    @get:JvmSynthetic
-    open val target2: Any
-        get() = target
-
-    @PlannedRemoval("1.0.0")
-    @Deprecated("for binary compatibility until 1.0.0", level = DeprecationLevel.HIDDEN)
-    @get:JvmName("sender")
-    @get:JvmSynthetic
-    open val sender2: Any
-        get() = sender
 }
 }
 
 
 /**
 /**

+ 1 - 1
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/message/data/PlainText.kt

@@ -29,7 +29,7 @@ data class PlainText(
     val content: String
     val content: String
 ) : MessageContent {
 ) : MessageContent {
 
 
-    @PlannedRemoval("1.1.0")
+    @PlannedRemoval("1.2.0")
     @Deprecated(
     @Deprecated(
         "use content instead for clearer semantics",
         "use content instead for clearer semantics",
         level = DeprecationLevel.WARNING,
         level = DeprecationLevel.WARNING,

+ 1 - 77
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/message/data/RichMessage.kt

@@ -14,7 +14,6 @@
 package net.mamoe.mirai.message.data
 package net.mamoe.mirai.message.data
 
 
 import net.mamoe.mirai.utils.MiraiExperimentalAPI
 import net.mamoe.mirai.utils.MiraiExperimentalAPI
-import net.mamoe.mirai.utils.PlannedRemoval
 import net.mamoe.mirai.utils.SinceMirai
 import net.mamoe.mirai.utils.SinceMirai
 import kotlin.annotation.AnnotationTarget.*
 import kotlin.annotation.AnnotationTarget.*
 import kotlin.jvm.JvmMultifileClass
 import kotlin.jvm.JvmMultifileClass
@@ -84,20 +83,6 @@ interface RichMessage : MessageContent {
                 }
                 }
             }
             }
 
 
-        @PlannedRemoval("1.0.0")
-        @JvmName("share")
-        @Deprecated(
-            "for binary compatibility", level = DeprecationLevel.HIDDEN
-        )
-        @Suppress("DEPRECATION_ERROR")
-        @MiraiExperimentalAPI
-        fun shareDeprecated(
-            url: String,
-            title: String? = null,
-            content: String? = null,
-            coverUrl: String? = null
-        ): XmlMessage = share(url, title, content, coverUrl) as XmlMessage
-
         override val typeName: String
         override val typeName: String
             get() = "RichMessage"
             get() = "RichMessage"
     }
     }
@@ -154,59 +139,6 @@ open class ServiceMessage(val serviceId: Int, final override val content: String
 }
 }
 
 
 
 
-/**
- * Json 消息.
- *
- * 由于 [serviceId] 不准确, 请使用 [ServiceMessage] 并手动指定 `serviceId`
- *
- * @see LightApp 一些 json 消息实际上是 [LightApp]
- */
-@PlannedRemoval("1.0.0")
-@Deprecated("use ServiceMessage with serviceId 1",
-    level = DeprecationLevel.ERROR,
-    replaceWith = ReplaceWith("ServiceMessage"))
-@Suppress("DEPRECATION_ERROR")
-@MiraiExperimentalAPI
-class JsonMessage
-@Deprecated("use ServiceMessage with serviceId 1",
-    level = DeprecationLevel.ERROR,
-    replaceWith = ReplaceWith("ServiceMessage(1, content)"))
-constructor(content: String) : ServiceMessage(1, content) {
-    @Suppress("DEPRECATION")
-    companion object Key : Message.Key<JsonMessage> {
-        override val typeName: String get() = "JsonMessage"
-    }
-}
-
-
-/**
- * XML 消息, 如分享, 卡片等.
- *
- * 由于 [serviceId] 不准确, 请使用 [ServiceMessage] 并手动指定 `serviceId`
- *
- * @param serviceId 目前未知, 一般为 60
- *
- * @see buildXmlMessage 使用 DSL 构造一个 XML 消息
- */
-@PlannedRemoval("1.0.0")
-@Deprecated("use ServiceMessage with serviceId 1",
-    level = DeprecationLevel.ERROR,
-    replaceWith = ReplaceWith("ServiceMessage"))
-@MiraiExperimentalAPI
-@Suppress("DEPRECATION_ERROR")
-@SinceMirai("0.27.0")
-class XmlMessage @MiraiExperimentalAPI("Maybe replaced with an enum")
-constructor(serviceId: Int = 60, content: String) : ServiceMessage(serviceId, content) {
-
-    @MiraiExperimentalAPI
-    @Deprecated("specify serviceId explicitly", replaceWith = ReplaceWith("XmlMessage(60, content)"))
-    constructor(content: String) : this(60, content)
-
-    companion object Key : Message.Key<XmlMessage> {
-        override val typeName: String get() = "XmlMessage"
-    }
-}
-
 /*
 /*
 commonElem=CommonElem#750141174 {
 commonElem=CommonElem#750141174 {
         businessType=0x00000001(1)
         businessType=0x00000001(1)
@@ -224,7 +156,7 @@ commonElem=CommonElem#750141174 {
 @SinceMirai("0.27.0")
 @SinceMirai("0.27.0")
 @MiraiExperimentalAPI
 @MiraiExperimentalAPI
 inline fun buildXmlMessage(serviceId: Int, block: @XmlMessageDsl XmlMessageBuilder.() -> Unit): ServiceMessage =
 inline fun buildXmlMessage(serviceId: Int, block: @XmlMessageDsl XmlMessageBuilder.() -> Unit): ServiceMessage =
-    XmlMessage(serviceId, XmlMessageBuilder().apply(block).text)
+    ServiceMessage(serviceId, XmlMessageBuilder().apply(block).text)
 
 
 @MiraiExperimentalAPI
 @MiraiExperimentalAPI
 @Target(CLASS, FUNCTION, TYPE)
 @Target(CLASS, FUNCTION, TYPE)
@@ -299,14 +231,6 @@ class XmlMessageBuilder(
 }
 }
 
 
 
 
-@JvmSynthetic
-@SinceMirai("0.27.0")
-@MiraiExperimentalAPI
-@Deprecated("specify serviceId explicitly", ReplaceWith("buildXmlMessage(60, block)"))
-inline fun buildXmlMessage(block: @XmlMessageDsl XmlMessageBuilder.() -> Unit): ServiceMessage =
-    buildXmlMessage(60, block)
-
-
 @SinceMirai("0.31.0")
 @SinceMirai("0.31.0")
 @MiraiExperimentalAPI
 @MiraiExperimentalAPI
 internal class LongMessage internal constructor(content: String, val resId: String) : ServiceMessage(35, content) {
 internal class LongMessage internal constructor(content: String, val resId: String) : ServiceMessage(35, content) {

+ 0 - 43
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/message/data/_HummerMessage.kt

@@ -1,43 +0,0 @@
-/*
- * Copyright 2020 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:JvmName("HummerMessageKt")
-@file:Suppress("NOTHING_TO_INLINE")
-
-package net.mamoe.mirai.message.data
-
-import net.mamoe.mirai.utils.PlannedRemoval
-import net.mamoe.mirai.utils.SinceMirai
-import kotlin.jvm.JvmName
-import kotlin.jvm.JvmSynthetic
-
-
-/*
-因为文件改名为做的兼容
- */
-
-@PlannedRemoval("1.0.0")
-@Deprecated("for binary compatibility", level = DeprecationLevel.HIDDEN)
-@JvmName("flash")
-@SinceMirai("0.33.0")
-inline fun Image.flash2(): FlashImage = FlashImage(this)
-
-@PlannedRemoval("1.0.0")
-@Deprecated("for binary compatibility", level = DeprecationLevel.HIDDEN)
-@JvmName("flash")
-@JvmSynthetic
-@SinceMirai("0.33.0")
-inline fun GroupImage.flash2(): GroupFlashImage = FlashImage(this) as GroupFlashImage
-
-@PlannedRemoval("1.0.0")
-@Deprecated("for binary compatibility", level = DeprecationLevel.HIDDEN)
-@JvmName("flash")
-@JvmSynthetic
-@SinceMirai("0.33.0")
-inline fun FriendImage.flash2(): FriendFlashImage = FlashImage(this) as FriendFlashImage

+ 0 - 45
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/message/data/_Message.kt

@@ -1,45 +0,0 @@
-/*
- * Copyright 2020 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:JvmName("MessageKt")
-@file:Suppress("NOTHING_TO_INLINE")
-
-package net.mamoe.mirai.message.data
-
-import net.mamoe.mirai.utils.PlannedRemoval
-import kotlin.jvm.JvmName
-
-
-/*
-因为文件改名为做的兼容
- */
-
-@PlannedRemoval("1.0.0")
-@Deprecated("for binary compatibility", level = DeprecationLevel.HIDDEN)
-@JvmName("isPlain")
-inline fun Message.isPlain2(): Boolean = this is PlainText
-
-@PlannedRemoval("1.0.0")
-@Deprecated("for binary compatibility", level = DeprecationLevel.HIDDEN)
-@JvmName("isNotPlain")
-inline fun Message.isNotPlain2(): Boolean = this !is PlainText
-
-@PlannedRemoval("1.0.0")
-@Deprecated("for binary compatibility", level = DeprecationLevel.HIDDEN)
-@JvmName("repeat")
-// inline: for future removal
-inline fun Message.repeat2(count: Int): MessageChain {
-    if (this is ConstrainSingle<*>) {
-        // fast-path
-        return this.asMessageChain()
-    }
-    return buildMessageChain(count) {
-        add(this@repeat2)
-    }
-}

+ 0 - 10
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/message/data/impl.kt

@@ -37,13 +37,6 @@ private fun Message.hasDuplicationOfConstrain(key: Message.Key<*>): Boolean {
     }
     }
 }
 }
 
 
-@OptIn(MiraiInternalAPI::class)
-@JvmSynthetic
-@Suppress("DEPRECATION_ERROR")
-internal fun Message.followedByInternalForBinaryCompatibility(tail: Message): CombinedMessage {
-    return CombinedMessage(EmptyMessageChain, this.followedBy(tail))
-}
-
 @JvmSynthetic
 @JvmSynthetic
 internal fun Message.contentEqualsImpl(another: Message, ignoreCase: Boolean): Boolean {
 internal fun Message.contentEqualsImpl(another: Message, ignoreCase: Boolean): Boolean {
     if (!this.contentToString().equals(another.contentToString(), ignoreCase = ignoreCase)) return false
     if (!this.contentToString().equals(another.contentToString(), ignoreCase = ignoreCase)) return false
@@ -220,9 +213,7 @@ internal fun <M : Message> MessageChain.firstOrNullImpl(key: Message.Key<M>): M?
     OnlineMessageSource.Incoming.FromGroup -> firstIsInstanceOrNull<OnlineMessageSource.Incoming.FromGroup>()
     OnlineMessageSource.Incoming.FromGroup -> firstIsInstanceOrNull<OnlineMessageSource.Incoming.FromGroup>()
     OnlineMessageSource.Incoming.FromFriend -> firstIsInstanceOrNull<OnlineMessageSource.Incoming.FromFriend>()
     OnlineMessageSource.Incoming.FromFriend -> firstIsInstanceOrNull<OnlineMessageSource.Incoming.FromFriend>()
     OnlineMessageSource -> firstIsInstanceOrNull<OnlineMessageSource>()
     OnlineMessageSource -> firstIsInstanceOrNull<OnlineMessageSource>()
-    XmlMessage -> firstIsInstanceOrNull<XmlMessage>()
     LongMessage -> firstIsInstanceOrNull()
     LongMessage -> firstIsInstanceOrNull()
-    JsonMessage -> firstIsInstanceOrNull<JsonMessage>()
     RichMessage -> firstIsInstanceOrNull<RichMessage>()
     RichMessage -> firstIsInstanceOrNull<RichMessage>()
     LightApp -> firstIsInstanceOrNull<LightApp>()
     LightApp -> firstIsInstanceOrNull<LightApp>()
     PokeMessage -> firstIsInstanceOrNull<PokeMessage>()
     PokeMessage -> firstIsInstanceOrNull<PokeMessage>()
@@ -364,7 +355,6 @@ internal fun calculateImageMd5ByImageId(imageId: String): ByteArray {
         imageId matches FRIEND_IMAGE_ID_REGEX_2 -> imageId.imageIdToMd5(imageId.skipToSecondHyphen() + 1)
         imageId matches FRIEND_IMAGE_ID_REGEX_2 -> imageId.imageIdToMd5(imageId.skipToSecondHyphen() + 1)
         imageId matches FRIEND_IMAGE_ID_REGEX_1 -> imageId.imageIdToMd5(1)
         imageId matches FRIEND_IMAGE_ID_REGEX_1 -> imageId.imageIdToMd5(1)
         imageId matches GROUP_IMAGE_ID_REGEX -> imageId.imageIdToMd5(1)
         imageId matches GROUP_IMAGE_ID_REGEX -> imageId.imageIdToMd5(1)
-        imageId matches GROUP_IMAGE_ID_REGEX_OLD -> imageId.imageIdToMd5(1)
 
 
         else -> error(
         else -> error(
             "illegal imageId: $imageId. $ILLEGAL_IMAGE_ID_EXCEPTION_MESSAGE"
             "illegal imageId: $imageId. $ILLEGAL_IMAGE_ID_EXCEPTION_MESSAGE"

+ 16 - 15
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/utils/ExternalImage.kt

@@ -22,8 +22,8 @@ import net.mamoe.mirai.contact.User
 import net.mamoe.mirai.message.MessageReceipt
 import net.mamoe.mirai.message.MessageReceipt
 import net.mamoe.mirai.message.data.Image
 import net.mamoe.mirai.message.data.Image
 import net.mamoe.mirai.message.data.sendTo
 import net.mamoe.mirai.message.data.sendTo
-import net.mamoe.mirai.message.data.toLongUnsigned
 import net.mamoe.mirai.utils.internal.asReusableInput
 import net.mamoe.mirai.utils.internal.asReusableInput
+import kotlin.jvm.JvmField
 import kotlin.jvm.JvmSynthetic
 import kotlin.jvm.JvmSynthetic
 
 
 /**
 /**
@@ -37,43 +37,44 @@ import kotlin.jvm.JvmSynthetic
 @OptIn(MiraiInternalAPI::class)
 @OptIn(MiraiInternalAPI::class)
 class ExternalImage internal constructor(
 class ExternalImage internal constructor(
     val md5: ByteArray,
     val md5: ByteArray,
-    @Suppress("EXPOSED_PROPERTY_TYPE_IN_CONSTRUCTOR")
-    @MiraiInternalAPI("unstable API")
-    val input: ReusableInput, // Input from kotlinx.io, InputStream from kotlinx.io MPP, ByteReadChannel from ktor
-    @MiraiInternalAPI("unstable API")
-    val inputSize: Int // dont be greater than Int.MAX
+    @JvmField
+    internal val input: ReusableInput // Input from kotlinx.io, InputStream from kotlinx.io MPP, ByteReadChannel from ktor
 ) {
 ) {
     @SinceMirai("1.0.0")
     @SinceMirai("1.0.0")
     internal interface ReusableInput {
     internal interface ReusableInput {
+        val md5: ByteArray
+        val size: Long
+
+        /**
+         * Create a input for once usage
+         */
         fun input(): Input
         fun input(): Input
     }
     }
 
 
 
 
     constructor(
     constructor(
         md5: ByteArray,
         md5: ByteArray,
-        input: ByteReadChannel,
-        inputSize: Long // dont be greater than Int.MAX
-    ) : this(md5, input.asReusableInput(), inputSize.coerceAtMost(Int.MAX_VALUE.toLongUnsigned()).toInt())
+        input: ByteReadChannel
+    ) : this(md5, input.asReusableInput())
 
 
     constructor(
     constructor(
         md5: ByteArray,
         md5: ByteArray,
-        input: Input,
-        inputSize: Long // dont be greater than Int.MAX
-    ) : this(md5, input.asReusableInput(), inputSize.coerceAtMost(Int.MAX_VALUE.toLongUnsigned()).toInt())
+        input: Input
+    ) : this(md5, input.asReusableInput())
 
 
     constructor(
     constructor(
         md5: ByteArray,
         md5: ByteArray,
         input: ByteReadPacket
         input: ByteReadPacket
-    ) : this(md5, input.asReusableInput(), input.remaining.coerceAtMost(Int.MAX_VALUE.toLongUnsigned()).toInt())
+    ) : this(md5, input.asReusableInput())
 
 
     @OptIn(InternalSerializationApi::class)
     @OptIn(InternalSerializationApi::class)
     constructor(
     constructor(
         md5: ByteArray,
         md5: ByteArray,
         input: InputStream
         input: InputStream
-    ) : this(md5, input.asReusableInput(), input.available())
+    ) : this(md5, input.asReusableInput())
 
 
     init {
     init {
-        require(inputSize < 30L * 1024 * 1024) { "file is too big. Maximum is about 20MB" }
+        require(input.size < 30L * 1024 * 1024) { "Image file is too big. Maximum is 30 MiB, but recommended to be 20 MiB" }
     }
     }
 
 
     companion object {
     companion object {

+ 9 - 20
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/utils/LockFreeLinkedList.kt

@@ -19,14 +19,12 @@ import kotlin.jvm.JvmOverloads
 /**
 /**
  * Collect all the elements into a [MutableList] then cast it as a [List]
  * Collect all the elements into a [MutableList] then cast it as a [List]
  */
  */
-@MiraiInternalAPI
-fun <E> LockFreeLinkedList<E>.toList(): List<E> = toMutableList()
+internal fun <E> LockFreeLinkedList<E>.toList(): List<E> = toMutableList()
 
 
 /**
 /**
  * Collect all the elements into a [MutableList].
  * Collect all the elements into a [MutableList].
  */
  */
-@MiraiInternalAPI
-fun <E> LockFreeLinkedList<E>.toMutableList(): MutableList<E> {
+internal fun <E> LockFreeLinkedList<E>.toMutableList(): MutableList<E> {
     val list = mutableListOf<E>()
     val list = mutableListOf<E>()
     this.forEach { list.add(it) }
     this.forEach { list.add(it) }
     return list
     return list
@@ -35,14 +33,12 @@ fun <E> LockFreeLinkedList<E>.toMutableList(): MutableList<E> {
 /**
 /**
  * Collect all the elements into a [MutableSet] then cast it as a [Set]
  * Collect all the elements into a [MutableSet] then cast it as a [Set]
  */
  */
-@MiraiInternalAPI
-fun <E> LockFreeLinkedList<E>.toSet(): Set<E> = toMutableSet()
+internal fun <E> LockFreeLinkedList<E>.toSet(): Set<E> = toMutableSet()
 
 
 /**
 /**
  * Collect all the elements into a [MutableSet].
  * Collect all the elements into a [MutableSet].
  */
  */
-@MiraiInternalAPI
-fun <E> LockFreeLinkedList<E>.toMutableSet(): MutableSet<E> {
+internal fun <E> LockFreeLinkedList<E>.toMutableSet(): MutableSet<E> {
     val list = mutableSetOf<E>()
     val list = mutableSetOf<E>()
     this.forEach { list.add(it) }
     this.forEach { list.add(it) }
     return list
     return list
@@ -53,15 +49,13 @@ fun <E> LockFreeLinkedList<E>.toMutableSet(): MutableSet<E> {
  *
  *
  * Note that the sequence is dynamic
  * Note that the sequence is dynamic
  */
  */
-@MiraiInternalAPI
-fun <E> LockFreeLinkedList<E>.asSequence(): Sequence<E> {
+internal fun <E> LockFreeLinkedList<E>.asSequence(): Sequence<E> {
     return generateSequence(head) { current: LockFreeLinkedListNode<E> ->
     return generateSequence(head) { current: LockFreeLinkedListNode<E> ->
         current.nextValidNode(until = tail).takeIf { it != tail }
         current.nextValidNode(until = tail).takeIf { it != tail }
     }.drop(1) // drop head, should be dropped lazily
     }.drop(1) // drop head, should be dropped lazily
         .map { it.nodeValue }
         .map { it.nodeValue }
 }
 }
 
 
-@OptIn(MiraiInternalAPI::class)
 internal fun <E> LockFreeLinkedListNode<E>.nextValidNode(until: LockFreeLinkedListNode<E>): LockFreeLinkedListNode<E> {
 internal fun <E> LockFreeLinkedListNode<E>.nextValidNode(until: LockFreeLinkedListNode<E>): LockFreeLinkedListNode<E> {
     var node: LockFreeLinkedListNode<E> = this.nextNode
     var node: LockFreeLinkedListNode<E> = this.nextNode
     while (node != until) {
     while (node != until) {
@@ -73,24 +67,21 @@ internal fun <E> LockFreeLinkedListNode<E>.nextValidNode(until: LockFreeLinkedLi
     return node
     return node
 }
 }
 
 
-@MiraiInternalAPI
-operator fun <E> LockFreeLinkedList<E>.iterator(): Iterator<E> {
+internal operator fun <E> LockFreeLinkedList<E>.iterator(): Iterator<E> {
     return asSequence().iterator()
     return asSequence().iterator()
 }
 }
 
 
 /**
 /**
  * 构建链表结构然后转为 [LockFreeLinkedList]
  * 构建链表结构然后转为 [LockFreeLinkedList]
  */
  */
-@MiraiInternalAPI
-fun <E> Iterable<E>.toLockFreeLinkedList(): LockFreeLinkedList<E> {
+internal fun <E> Iterable<E>.toLockFreeLinkedList(): LockFreeLinkedList<E> {
     return LockFreeLinkedList<E>().apply { addAll(this@toLockFreeLinkedList) }
     return LockFreeLinkedList<E>().apply { addAll(this@toLockFreeLinkedList) }
 }
 }
 
 
 /**
 /**
  * 构建链表结构然后转为 [LockFreeLinkedList]
  * 构建链表结构然后转为 [LockFreeLinkedList]
  */
  */
-@MiraiInternalAPI
-fun <E> Sequence<E>.toLockFreeLinkedList(): LockFreeLinkedList<E> {
+internal fun <E> Sequence<E>.toLockFreeLinkedList(): LockFreeLinkedList<E> {
     return LockFreeLinkedList<E>().apply { addAll(this@toLockFreeLinkedList) }
     return LockFreeLinkedList<E>().apply { addAll(this@toLockFreeLinkedList) }
 }
 }
 
 
@@ -100,9 +91,7 @@ fun <E> Sequence<E>.toLockFreeLinkedList(): LockFreeLinkedList<E> {
  * Modifying can be performed concurrently.
  * Modifying can be performed concurrently.
  * Iterating concurrency is guaranteed.
  * Iterating concurrency is guaranteed.
  */
  */
-@PlannedRemoval("1.0.0") // make internal
-@MiraiInternalAPI("This is unstable API and is going to be internal in 1.0.0")
-open class LockFreeLinkedList<E> {
+internal open class LockFreeLinkedList<E> {
     @PublishedApi
     @PublishedApi
     internal val tail: Tail<E> = Tail()
     internal val tail: Tail<E> = Tail()
 
 

+ 31 - 0
mirai-core/src/jvmMain/kotlin/net/mamoe/mirai/Mirai.kt

@@ -1,5 +1,11 @@
 package net.mamoe.mirai
 package net.mamoe.mirai
 
 
+import io.ktor.utils.io.ByteReadChannel
+import kotlinx.io.core.Input
+import net.mamoe.mirai.utils.ExternalImage
+import net.mamoe.mirai.utils.MiraiExperimentalAPI
+import net.mamoe.mirai.utils.internal.InputStream
+
 /**
 /**
  * Mirai 全局环境.
  * Mirai 全局环境.
  */
  */
@@ -9,6 +15,31 @@ actual object Mirai {
         set(value) {}
         set(value) {}
 
 
     actual interface FileCacheStrategy {
     actual interface FileCacheStrategy {
+        @MiraiExperimentalAPI
+        actual fun newImageCache(input: Input): ExternalImage
+
+        @MiraiExperimentalAPI
+        actual fun newImageCache(input: ByteReadChannel): ExternalImage
+
+        @MiraiExperimentalAPI
+        actual fun newImageCache(input: InputStream): ExternalImage
+
+        actual companion object Default : FileCacheStrategy {
+            @MiraiExperimentalAPI
+            actual override fun newImageCache(input: Input): ExternalImage {
+                TODO("Not yet implemented")
+            }
+
+            @MiraiExperimentalAPI
+            actual override fun newImageCache(input: ByteReadChannel): ExternalImage {
+                TODO("Not yet implemented")
+            }
+
+            @MiraiExperimentalAPI
+            actual override fun newImageCache(input: InputStream): ExternalImage {
+                TODO("Not yet implemented")
+            }
+        }
 
 
     }
     }
 
 

+ 1 - 1
mirai-core/src/jvmMain/kotlin/net/mamoe/mirai/contact/ContactJavaFriendlyAPI.kt

@@ -208,7 +208,7 @@ actual abstract class ContactJavaFriendlyAPI {
 @Suppress("INAPPLICABLE_JVM_NAME", "FunctionName", "unused", "unused", "DEPRECATION_ERROR")
 @Suppress("INAPPLICABLE_JVM_NAME", "FunctionName", "unused", "unused", "DEPRECATION_ERROR")
 @MiraiInternalAPI
 @MiraiInternalAPI
 @JavaFriendlyAPI
 @JavaFriendlyAPI
-actual abstract class MemberJavaFriendlyAPI : QQ() {
+actual abstract class MemberJavaFriendlyAPI : User() {
     private inline fun <R> runBlocking(crossinline block: suspend Member.() -> R): R {
     private inline fun <R> runBlocking(crossinline block: suspend Member.() -> R): R {
         @Suppress("CAST_NEVER_SUCCEEDS")
         @Suppress("CAST_NEVER_SUCCEEDS")
         return kotlinx.coroutines.runBlocking { block(this@MemberJavaFriendlyAPI as Member) }
         return kotlinx.coroutines.runBlocking { block(this@MemberJavaFriendlyAPI as Member) }

+ 0 - 47
mirai-core/src/jvmMain/kotlin/net/mamoe/mirai/message/MessagePacket.kt

@@ -93,51 +93,4 @@ actual abstract class MessagePacket<TSender : User, TSubject : Contact> actual c
     @JvmSynthetic
     @JvmSynthetic
     suspend inline fun File.sendAsImage(): MessageReceipt<TSubject> = sendAsImageTo(subject)
     suspend inline fun File.sendAsImage(): MessageReceipt<TSubject> = sendAsImageTo(subject)
     // endregion 发送图片 (扩展)
     // endregion 发送图片 (扩展)
-
-    // region 下载图片 (扩展)
-    @JvmSynthetic
-    suspend inline fun Image.downloadTo(file: File) = file.outputStream().use { downloadTo(it) }
-
-    /**
-     * 下载图片到 [output] 但不关闭这个 [output]
-     */
-    @JvmSynthetic
-    suspend inline fun Image.downloadTo(output: OutputStream) = channel().copyTo(output)
-
-    /**
-     * 下载图片到 [output] 并关闭这个 [output]
-     */
-    @JvmSynthetic
-    suspend inline fun Image.downloadAndClose(output: OutputStream) = channel().copyAndClose(output)
-
-    /**
-     * 下载图片到 [output] 但不关闭这个 [output]
-     */
-    @JvmSynthetic
-    suspend inline fun Image.downloadTo(output: Output) = channel().copyTo(output)
-
-    /**
-     * 下载图片到 [output] 并关闭这个 [output]
-     */
-    @JvmSynthetic
-    suspend inline fun Image.downloadAndClose(output: Output) = channel().copyAndClose(output)
-
-    /**
-     * 下载图片到 [output] 但不关闭这个 [output]
-     */
-    @JvmSynthetic
-    suspend inline fun Image.downloadTo(output: ByteWriteChannel) = channel().copyTo(output)
-
-    /**
-     * 下载图片到 [output] 并关闭这个 [output]
-     */
-    @JvmSynthetic
-    suspend inline fun Image.downloadAndClose(output: ByteWriteChannel) = channel().copyAndClose(output)
-
-    /*
-    suspend inline fun Image.downloadAsStream(): InputStream = channel().asInputStream()
-    suspend inline fun Image.downloadAsExternalImage(): ExternalImage = withContext(Dispatchers.IO) { downloadAsStream().toExternalImage() }
-    suspend inline fun Image.downloadAsBufferedImage(): BufferedImage = withContext(Dispatchers.IO) { ImageIO.read(downloadAsStream()) }
-     */
-    // endregion
 }
 }