mirror of
https://github.com/mamoe/mirai.git
synced 2024-12-28 17:40:09 +08:00
Cleanup;
Use interface for JavaFriendly APIs; Deprecate event responder in Bot in the favor of their member functions; Deprecate `Bot.queryUrl(image: Image)`` in the favor of the extension `Image.queryUrl`
This commit is contained in:
parent
dc8945aa39
commit
46598d686c
@ -1,7 +1,6 @@
|
||||
package compatibility
|
||||
|
||||
import net.mamoe.mirai.message.data.*
|
||||
import net.mamoe.mirai.utils.MiraiInternalAPI
|
||||
import kotlin.test.Test
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
|
@ -15,7 +15,6 @@ import net.mamoe.mirai.Bot
|
||||
import net.mamoe.mirai.BotFactory
|
||||
import net.mamoe.mirai.utils.BotConfiguration
|
||||
import net.mamoe.mirai.utils.Context
|
||||
import net.mamoe.mirai.utils.MiraiInternalAPI
|
||||
|
||||
/**
|
||||
* QQ for Android
|
||||
|
@ -18,7 +18,6 @@ import kotlinx.io.core.*
|
||||
import kotlinx.io.pool.useInstance
|
||||
import net.mamoe.mirai.qqandroid.utils.ByteArrayPool
|
||||
import net.mamoe.mirai.qqandroid.utils.toReadPacket
|
||||
import net.mamoe.mirai.utils.MiraiInternalAPI
|
||||
import java.nio.ByteBuffer
|
||||
|
||||
@Suppress("DEPRECATION")
|
||||
|
@ -11,7 +11,6 @@ package net.mamoe.mirai.qqandroid.utils.cryptor
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import net.mamoe.mirai.qqandroid.utils.MiraiPlatformUtils.md5
|
||||
import net.mamoe.mirai.utils.MiraiInternalAPI
|
||||
import net.mamoe.mirai.utils.MiraiLogger
|
||||
import java.security.*
|
||||
import java.security.spec.ECGenParameterSpec
|
||||
|
@ -14,7 +14,6 @@ package net.mamoe.mirai.qqandroid
|
||||
import kotlinx.io.core.toByteArray
|
||||
import net.mamoe.mirai.qqandroid.utils.MiraiPlatformUtils
|
||||
import net.mamoe.mirai.utils.MiraiExperimentalAPI
|
||||
import net.mamoe.mirai.utils.MiraiInternalAPI
|
||||
import kotlin.jvm.JvmSynthetic
|
||||
|
||||
internal data class BotAccount(
|
||||
@ -22,7 +21,6 @@ internal data class BotAccount(
|
||||
internal val id: Long,
|
||||
@JvmSynthetic
|
||||
@MiraiExperimentalAPI
|
||||
@MiraiInternalAPI
|
||||
val passwordMd5: ByteArray // md5
|
||||
) {
|
||||
constructor(id: Long, passwordPlainText: String) : this(id, MiraiPlatformUtils.md5(passwordPlainText.toByteArray()))
|
||||
|
@ -17,7 +17,6 @@ import io.ktor.client.request.forms.MultiPartFormDataContent
|
||||
import io.ktor.client.request.forms.formData
|
||||
import kotlinx.coroutines.CoroutineName
|
||||
import kotlinx.coroutines.async
|
||||
import kotlinx.coroutines.io.ByteReadChannel
|
||||
import kotlinx.coroutines.withContext
|
||||
import kotlinx.serialization.UnstableDefault
|
||||
import kotlinx.serialization.json.Json
|
||||
@ -52,7 +51,6 @@ import net.mamoe.mirai.qqandroid.utils.encodeToString
|
||||
import net.mamoe.mirai.qqandroid.utils.io.serialization.toByteArray
|
||||
import net.mamoe.mirai.utils.*
|
||||
import kotlin.collections.asSequence
|
||||
import kotlin.contracts.ExperimentalContracts
|
||||
import kotlin.contracts.contract
|
||||
import kotlin.coroutines.CoroutineContext
|
||||
import kotlin.jvm.JvmSynthetic
|
||||
@ -60,7 +58,6 @@ import kotlin.math.absoluteValue
|
||||
import kotlin.random.Random
|
||||
import net.mamoe.mirai.qqandroid.network.protocol.data.jce.FriendInfo as JceFriendInfo
|
||||
|
||||
@OptIn(ExperimentalContracts::class)
|
||||
internal fun Bot.asQQAndroidBot(): QQAndroidBot {
|
||||
contract {
|
||||
returns() implies (this@asQQAndroidBot is QQAndroidBot)
|
||||
@ -776,10 +773,6 @@ internal abstract class QQAndroidBotBase constructor(
|
||||
|
||||
internal val EMPTY_BYTE_ARRAY = ByteArray(0)
|
||||
|
||||
@Suppress("DEPRECATION")
|
||||
internal expect fun io.ktor.utils.io.ByteReadChannel.toKotlinByteReadChannel(): ByteReadChannel
|
||||
|
||||
|
||||
private fun RichMessage.Templates.longMessage(brief: String, resId: String, timeSeconds: Long): RichMessage {
|
||||
val limited: String = if (brief.length > 30) {
|
||||
brief.take(30) + "…"
|
||||
|
@ -7,7 +7,7 @@
|
||||
* https://github.com/mamoe/mirai/blob/master/LICENSE
|
||||
*/
|
||||
|
||||
@file:OptIn(MiraiInternalAPI::class, LowLevelAPI::class)
|
||||
@file:OptIn(LowLevelAPI::class)
|
||||
@file:Suppress("EXPERIMENTAL_API_USAGE", "DEPRECATION_ERROR", "NOTHING_TO_INLINE")
|
||||
|
||||
package net.mamoe.mirai.qqandroid.contact
|
||||
@ -35,7 +35,10 @@ import net.mamoe.mirai.qqandroid.network.protocol.data.proto.Cmd0x352
|
||||
import net.mamoe.mirai.qqandroid.network.protocol.packet.chat.image.LongConn
|
||||
import net.mamoe.mirai.qqandroid.utils.MiraiPlatformUtils
|
||||
import net.mamoe.mirai.qqandroid.utils.toUHexString
|
||||
import net.mamoe.mirai.utils.*
|
||||
import net.mamoe.mirai.utils.ExternalImage
|
||||
import net.mamoe.mirai.utils.getValue
|
||||
import net.mamoe.mirai.utils.unsafeWeakRef
|
||||
import net.mamoe.mirai.utils.verbose
|
||||
import kotlin.contracts.ExperimentalContracts
|
||||
import kotlin.contracts.contract
|
||||
import kotlin.coroutines.CoroutineContext
|
||||
@ -84,7 +87,6 @@ internal class FriendImpl(
|
||||
}
|
||||
|
||||
@JvmSynthetic
|
||||
|
||||
override suspend fun uploadImage(image: ExternalImage): Image = try {
|
||||
@Suppress("INVISIBLE_MEMBER", "INVISIBLE_REFERENCE")
|
||||
if (image.input is net.mamoe.mirai.utils.internal.DeferredReusableInput) {
|
||||
|
@ -8,7 +8,7 @@
|
||||
*/
|
||||
|
||||
@file:Suppress("INAPPLICABLE_JVM_NAME", "DEPRECATION_ERROR", "INVISIBLE_MEMBER", "INVISIBLE_REFERENCE")
|
||||
@file:OptIn(MiraiInternalAPI::class, LowLevelAPI::class)
|
||||
@file:OptIn(LowLevelAPI::class)
|
||||
|
||||
package net.mamoe.mirai.qqandroid.contact
|
||||
|
||||
|
@ -6,7 +6,7 @@
|
||||
*
|
||||
* https://github.com/mamoe/mirai/blob/master/LICENSE
|
||||
*/
|
||||
@file: OptIn(MiraiExperimentalAPI::class, MiraiInternalAPI::class, LowLevelAPI::class, ExperimentalUnsignedTypes::class)
|
||||
@file:OptIn(LowLevelAPI::class)
|
||||
@file:Suppress("EXPERIMENTAL_API_USAGE")
|
||||
|
||||
package net.mamoe.mirai.qqandroid.message
|
||||
@ -24,8 +24,6 @@ import net.mamoe.mirai.qqandroid.network.protocol.data.proto.MsgComm
|
||||
import net.mamoe.mirai.qqandroid.utils.*
|
||||
import net.mamoe.mirai.qqandroid.utils.io.serialization.loadAs
|
||||
import net.mamoe.mirai.qqandroid.utils.io.serialization.toByteArray
|
||||
import net.mamoe.mirai.utils.MiraiExperimentalAPI
|
||||
import net.mamoe.mirai.utils.MiraiInternalAPI
|
||||
import kotlin.contracts.ExperimentalContracts
|
||||
import kotlin.contracts.InvocationKind
|
||||
import kotlin.contracts.contract
|
||||
@ -208,7 +206,6 @@ private val PB_RESERVE_FOR_PTT =
|
||||
private val PB_RESERVE_FOR_DOUTU = "78 00 90 01 01 F8 01 00 A0 02 00 C8 02 00".hexToBytes()
|
||||
private val PB_RESERVE_FOR_ELSE = "78 00 F8 01 00 C8 02 00".hexToBytes()
|
||||
|
||||
@OptIn(ExperimentalUnsignedTypes::class, MiraiInternalAPI::class)
|
||||
internal fun MsgComm.Msg.toMessageChain(
|
||||
bot: Bot,
|
||||
groupIdOrZero: Long,
|
||||
@ -242,7 +239,6 @@ internal fun MsgComm.Msg.toMessageChain(
|
||||
|
||||
// These two functions have difference method signature, don't combine.
|
||||
|
||||
@OptIn(ExperimentalUnsignedTypes::class, MiraiInternalAPI::class)
|
||||
internal fun ImMsgBody.SourceMsg.toMessageChain(bot: Bot, groupIdOrZero: Long): MessageChain {
|
||||
val elements = this.elems!!
|
||||
|
||||
|
@ -18,7 +18,6 @@ import net.mamoe.mirai.qqandroid.network.QQAndroidClient
|
||||
import net.mamoe.mirai.qqandroid.utils.io.encryptAndWrite
|
||||
import net.mamoe.mirai.qqandroid.utils.io.writeHex
|
||||
import net.mamoe.mirai.qqandroid.utils.io.writeIntLVPacket
|
||||
import net.mamoe.mirai.utils.MiraiInternalAPI
|
||||
|
||||
internal class OutgoingPacket constructor(
|
||||
name: String?,
|
||||
@ -232,7 +231,6 @@ internal inline fun BytePacketBuilder.writeSsoPacket(
|
||||
writeIntLVPacket(lengthOffset = { it + 4 }, builder = body)
|
||||
}
|
||||
|
||||
@OptIn(ExperimentalUnsignedTypes::class, MiraiInternalAPI::class)
|
||||
internal fun BytePacketBuilder.writeOicqRequestPacket(
|
||||
client: QQAndroidClient,
|
||||
encryptMethod: EncryptMethod,
|
||||
|
@ -47,7 +47,6 @@ import net.mamoe.mirai.qqandroid.utils.io.serialization.writeProtoBuf
|
||||
import net.mamoe.mirai.qqandroid.utils.read
|
||||
import net.mamoe.mirai.qqandroid.utils.soutv
|
||||
import net.mamoe.mirai.qqandroid.utils.toUHexString
|
||||
import net.mamoe.mirai.utils.MiraiInternalAPI
|
||||
import net.mamoe.mirai.utils.currentTimeSeconds
|
||||
import net.mamoe.mirai.utils.debug
|
||||
import net.mamoe.mirai.utils.warning
|
||||
@ -95,7 +94,6 @@ internal object MessageSvcPbGetMsg : OutgoingPacketFactory<MessageSvcPbGetMsg.Re
|
||||
/**
|
||||
* 不要直接 expect 这个 class. 它可能还没同步完成
|
||||
*/
|
||||
@MiraiInternalAPI
|
||||
open class Response(internal val syncFlagFromServer: MsgSvc.SyncFlag, delegate: List<Packet>) :
|
||||
AbstractEvent(),
|
||||
MultiPacket<Packet>,
|
||||
|
@ -8,10 +8,7 @@
|
||||
*/
|
||||
|
||||
@file:Suppress("INVISIBLE_MEMBER", "INVISIBLE_REFERENCE")
|
||||
@file:OptIn(MiraiInternalAPI::class,
|
||||
MiraiExperimentalAPI::class,
|
||||
JavaFriendlyAPI::class,
|
||||
ExperimentalUnsignedTypes::class)
|
||||
@file:OptIn(JavaFriendlyAPI::class)
|
||||
|
||||
package net.mamoe.mirai.qqandroid.network.protocol.packet.chat.receive
|
||||
|
||||
@ -35,8 +32,6 @@ import net.mamoe.mirai.qqandroid.network.protocol.packet.OutgoingPacket
|
||||
import net.mamoe.mirai.qqandroid.network.protocol.packet.buildResponseUniPacket
|
||||
import net.mamoe.mirai.qqandroid.utils.io.serialization.readProtoBuf
|
||||
import net.mamoe.mirai.qqandroid.utils.read
|
||||
import net.mamoe.mirai.utils.MiraiExperimentalAPI
|
||||
import net.mamoe.mirai.utils.MiraiInternalAPI
|
||||
|
||||
|
||||
internal object OnlinePushPbPushTransMsg :
|
||||
|
@ -9,10 +9,7 @@
|
||||
|
||||
@file:Suppress("INVISIBLE_MEMBER", "INVISIBLE_REFERENCE")
|
||||
@file:OptIn(
|
||||
MiraiInternalAPI::class,
|
||||
MiraiExperimentalAPI::class,
|
||||
JavaFriendlyAPI::class,
|
||||
ExperimentalUnsignedTypes::class
|
||||
JavaFriendlyAPI::class
|
||||
)
|
||||
|
||||
package net.mamoe.mirai.qqandroid.network.protocol.packet.chat.receive
|
||||
@ -54,8 +51,6 @@ import net.mamoe.mirai.qqandroid.utils.io.readString
|
||||
import net.mamoe.mirai.qqandroid.utils.io.serialization.*
|
||||
import net.mamoe.mirai.qqandroid.utils.read
|
||||
import net.mamoe.mirai.qqandroid.utils.toUHexString
|
||||
import net.mamoe.mirai.utils.MiraiExperimentalAPI
|
||||
import net.mamoe.mirai.utils.MiraiInternalAPI
|
||||
import net.mamoe.mirai.utils.currentTimeSeconds
|
||||
import net.mamoe.mirai.utils.debug
|
||||
|
||||
|
@ -1,7 +1,6 @@
|
||||
package net.mamoe.mirai.qqandroid.utils
|
||||
|
||||
import io.ktor.client.HttpClient
|
||||
import net.mamoe.mirai.utils.MiraiInternalAPI
|
||||
|
||||
internal expect object MiraiPlatformUtils {
|
||||
fun unzip(data: ByteArray, offset: Int = 0, length: Int = data.size - offset): ByteArray
|
||||
@ -22,7 +21,6 @@ internal expect object MiraiPlatformUtils {
|
||||
/**
|
||||
* Ktor HttpClient. 不同平台使用不同引擎.
|
||||
*/
|
||||
@MiraiInternalAPI
|
||||
val Http: HttpClient
|
||||
}
|
||||
|
||||
|
@ -14,7 +14,6 @@ import kotlinx.io.pool.useInstance
|
||||
import net.mamoe.mirai.qqandroid.utils.ByteArrayPool
|
||||
import net.mamoe.mirai.qqandroid.utils.toByteArray
|
||||
import net.mamoe.mirai.qqandroid.utils.toUHexString
|
||||
import net.mamoe.mirai.utils.MiraiInternalAPI
|
||||
import kotlin.experimental.and
|
||||
import kotlin.experimental.xor
|
||||
import kotlin.jvm.JvmStatic
|
||||
@ -33,7 +32,6 @@ internal class DecryptionFailedException : Exception {
|
||||
*
|
||||
* **注意**: 此为 Mirai 内部 API. 它可能会在任何时刻被改变.
|
||||
*/
|
||||
@MiraiInternalAPI
|
||||
internal object TEA {
|
||||
// TODO: 2020/2/28 使用 stream 式输入以避免缓存
|
||||
|
||||
|
@ -19,7 +19,6 @@ import kotlinx.io.core.*
|
||||
import net.mamoe.mirai.qqandroid.utils.ByteArrayPool
|
||||
import net.mamoe.mirai.qqandroid.utils.toReadPacket
|
||||
import net.mamoe.mirai.qqandroid.utils.toUHexString
|
||||
import net.mamoe.mirai.utils.MiraiInternalAPI
|
||||
import kotlin.contracts.InvocationKind
|
||||
import kotlin.contracts.contract
|
||||
import kotlin.jvm.JvmMultifileClass
|
||||
@ -59,7 +58,6 @@ internal inline fun TlvMap.getOrFail(tag: Int, lazyMessage: (tag: Int) -> String
|
||||
}
|
||||
|
||||
@Suppress("FunctionName")
|
||||
@MiraiInternalAPI
|
||||
internal inline fun Input._readTLVMap(tagSize: Int = 2, suppressDuplication: Boolean = true): TlvMap =
|
||||
_readTLVMap(true, tagSize, suppressDuplication)
|
||||
|
||||
|
@ -20,10 +20,8 @@ import net.mamoe.mirai.qqandroid.utils.ByteArrayPool
|
||||
import net.mamoe.mirai.qqandroid.utils.toReadPacket
|
||||
import net.mamoe.mirai.qqandroid.utils.toUHexString
|
||||
import net.mamoe.mirai.utils.DefaultLogger
|
||||
import net.mamoe.mirai.utils.MiraiInternalAPI
|
||||
import net.mamoe.mirai.utils.MiraiLoggerWithSwitch
|
||||
import net.mamoe.mirai.utils.withSwitch
|
||||
import kotlin.contracts.ExperimentalContracts
|
||||
import kotlin.contracts.InvocationKind
|
||||
import kotlin.contracts.contract
|
||||
|
||||
@ -35,7 +33,6 @@ internal inline fun ByteArray.debugPrintThis(name: String): ByteArray {
|
||||
return this
|
||||
}
|
||||
|
||||
@OptIn(ExperimentalContracts::class, MiraiInternalAPI::class)
|
||||
internal inline fun <R> Input.debugIfFail(
|
||||
name: String = "",
|
||||
onFail: (ByteArray) -> ByteReadPacket = { it.toReadPacket() },
|
||||
|
@ -16,7 +16,6 @@ import net.mamoe.mirai.BotFactory
|
||||
import net.mamoe.mirai.qqandroid.QQAndroid.Bot
|
||||
import net.mamoe.mirai.utils.BotConfiguration
|
||||
import net.mamoe.mirai.utils.Context
|
||||
import net.mamoe.mirai.utils.MiraiInternalAPI
|
||||
|
||||
/**
|
||||
* QQ for Android
|
||||
|
@ -20,167 +20,9 @@ import net.mamoe.mirai.qqandroid.utils.ByteArrayPool
|
||||
import net.mamoe.mirai.qqandroid.utils.toReadPacket
|
||||
import net.mamoe.mirai.utils.BotConfiguration
|
||||
import net.mamoe.mirai.utils.ContextImpl
|
||||
import net.mamoe.mirai.utils.MiraiInternalAPI
|
||||
import java.nio.ByteBuffer
|
||||
|
||||
|
||||
@Suppress("FunctionName")
|
||||
internal fun QQAndroidBot(account: BotAccount, configuration: BotConfiguration): QQAndroidBot =
|
||||
QQAndroidBot(ContextImpl(), account, configuration)
|
||||
@Suppress("DEPRECATION")
|
||||
internal actual fun ByteReadChannel.toKotlinByteReadChannel(): kotlinx.coroutines.io.ByteReadChannel {
|
||||
return object : kotlinx.coroutines.io.ByteReadChannel {
|
||||
override val availableForRead: Int
|
||||
get() = this@toKotlinByteReadChannel.availableForRead
|
||||
override val isClosedForRead: Boolean
|
||||
get() = this@toKotlinByteReadChannel.isClosedForRead
|
||||
override val isClosedForWrite: Boolean
|
||||
get() = this@toKotlinByteReadChannel.isClosedForWrite
|
||||
|
||||
@Suppress("DEPRECATION_ERROR", "OverridingDeprecatedMember")
|
||||
override var readByteOrder: ByteOrder
|
||||
get() = when (this@toKotlinByteReadChannel.readByteOrder) {
|
||||
io.ktor.utils.io.core.ByteOrder.BIG_ENDIAN -> ByteOrder.BIG_ENDIAN
|
||||
io.ktor.utils.io.core.ByteOrder.LITTLE_ENDIAN -> ByteOrder.LITTLE_ENDIAN
|
||||
}
|
||||
set(value) {
|
||||
this@toKotlinByteReadChannel.readByteOrder = when (value) {
|
||||
ByteOrder.BIG_ENDIAN -> io.ktor.utils.io.core.ByteOrder.BIG_ENDIAN
|
||||
ByteOrder.LITTLE_ENDIAN -> io.ktor.utils.io.core.ByteOrder.LITTLE_ENDIAN
|
||||
}
|
||||
}
|
||||
|
||||
@Suppress("DEPRECATION_ERROR", "DEPRECATION", "OverridingDeprecatedMember")
|
||||
override val totalBytesRead: Long
|
||||
get() = this@toKotlinByteReadChannel.totalBytesRead
|
||||
|
||||
override fun cancel(cause: Throwable?): Boolean = this@toKotlinByteReadChannel.cancel(cause)
|
||||
override suspend fun consumeEachBufferRange(visitor: ConsumeEachBufferVisitor) = this@toKotlinByteReadChannel.consumeEachBufferRange(visitor)
|
||||
override suspend fun discard(max: Long): Long = this@toKotlinByteReadChannel.discard(max)
|
||||
@Suppress("EXPERIMENTAL_API_USAGE", "EXPERIMENTAL_OVERRIDE")
|
||||
@ExperimentalIoApi
|
||||
override fun <R> lookAhead(visitor: LookAheadSession.() -> R): R {
|
||||
return this@toKotlinByteReadChannel.lookAhead l@{
|
||||
visitor(object : LookAheadSession{
|
||||
override fun consumed(n: Int) {
|
||||
return this@l.consumed(n)
|
||||
}
|
||||
override fun request(skip: Int, atLeast: Int): ByteBuffer? {
|
||||
return this@l.request(skip, atLeast)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@Suppress("EXPERIMENTAL_API_USAGE", "EXPERIMENTAL_OVERRIDE")
|
||||
@ExperimentalIoApi
|
||||
override suspend fun <R> lookAheadSuspend(visitor: suspend LookAheadSuspendSession.() -> R): R =
|
||||
this@toKotlinByteReadChannel.lookAheadSuspend l@{
|
||||
visitor(object : LookAheadSuspendSession {
|
||||
override suspend fun awaitAtLeast(n: Int): Boolean {
|
||||
return this@l.awaitAtLeast(n)
|
||||
}
|
||||
|
||||
override fun consumed(n: Int) {
|
||||
return this@l.consumed(n)
|
||||
}
|
||||
|
||||
override fun request(skip: Int, atLeast: Int): ByteBuffer? {
|
||||
return this@l.request(skip, atLeast)
|
||||
}
|
||||
|
||||
})
|
||||
}
|
||||
|
||||
override suspend fun read(min: Int, consumer: (ByteBuffer) -> Unit) =
|
||||
this@toKotlinByteReadChannel.read(min, consumer)
|
||||
|
||||
override suspend fun readAvailable(dst: ByteBuffer): Int = this@toKotlinByteReadChannel.readAvailable(dst)
|
||||
override suspend fun readAvailable(dst: ByteArray, offset: Int, length: Int): Int =
|
||||
this@toKotlinByteReadChannel.readAvailable(dst, offset, length)
|
||||
|
||||
override suspend fun readAvailable(dst: IoBuffer): Int {
|
||||
ByteArrayPool.useInstance {
|
||||
val read = this@toKotlinByteReadChannel.readAvailable(it, 0, it.size)
|
||||
dst.writeFully(it, 0, read)
|
||||
return read
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun readBoolean(): Boolean = this@toKotlinByteReadChannel.readBoolean()
|
||||
override suspend fun readByte(): Byte = this@toKotlinByteReadChannel.readByte()
|
||||
override suspend fun readDouble(): Double = this@toKotlinByteReadChannel.readDouble()
|
||||
override suspend fun readFloat(): Float = this@toKotlinByteReadChannel.readFloat()
|
||||
override suspend fun readFully(dst: ByteBuffer): Int {
|
||||
TODO("not implemented")
|
||||
}
|
||||
|
||||
override suspend fun readFully(dst: ByteArray, offset: Int, length: Int) =
|
||||
this@toKotlinByteReadChannel.readFully(dst, offset, length)
|
||||
|
||||
override suspend fun readFully(dst: IoBuffer, n: Int) {
|
||||
ByteArrayPool.useInstance {
|
||||
dst.writeFully(it, 0, this.readAvailable(it, 0, it.size))
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun readInt(): Int = this@toKotlinByteReadChannel.readInt()
|
||||
override suspend fun readLong(): Long = this@toKotlinByteReadChannel.readLong()
|
||||
override suspend fun readPacket(size: Int, headerSizeHint: Int): ByteReadPacket {
|
||||
return this@toKotlinByteReadChannel.readPacket(size, headerSizeHint).readBytes().toReadPacket()
|
||||
}
|
||||
|
||||
override suspend fun readRemaining(limit: Long, headerSizeHint: Int): ByteReadPacket {
|
||||
return this@toKotlinByteReadChannel.readRemaining(limit, headerSizeHint).readBytes().toReadPacket()
|
||||
}
|
||||
|
||||
@OptIn(ExperimentalIoApi::class)
|
||||
@ExperimentalIoApi
|
||||
override fun readSession(consumer: ReadSession.() -> Unit) {
|
||||
@Suppress("DEPRECATION")
|
||||
this@toKotlinByteReadChannel.readSession lambda@{
|
||||
consumer(object : ReadSession {
|
||||
override val availableForRead: Int
|
||||
get() = this@lambda.availableForRead
|
||||
|
||||
override fun discard(n: Int): Int = this@lambda.discard(n)
|
||||
|
||||
override fun request(atLeast: Int): IoBuffer? {
|
||||
val ioBuffer: io.ktor.utils.io.core.IoBuffer = this@lambda.request(atLeast) ?: return null
|
||||
val buffer = IoBuffer.Pool.borrow()
|
||||
val bytes = (ioBuffer as Input).readBytes()
|
||||
buffer.writeFully(bytes)
|
||||
return buffer
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun readShort(): Short = this@toKotlinByteReadChannel.readShort()
|
||||
|
||||
@Suppress("EXPERIMENTAL_OVERRIDE", "EXPERIMENTAL_API_USAGE")
|
||||
@ExperimentalIoApi
|
||||
override suspend fun readSuspendableSession(consumer: suspend SuspendableReadSession.() -> Unit) =
|
||||
this@toKotlinByteReadChannel.readSuspendableSession l@{
|
||||
consumer(object : SuspendableReadSession {
|
||||
override val availableForRead: Int
|
||||
get() = this@l.availableForRead
|
||||
|
||||
override suspend fun await(atLeast: Int): Boolean = this@l.await(atLeast)
|
||||
override fun discard(n: Int): Int = this@l.discard(n)
|
||||
override fun request(atLeast: Int): IoBuffer? {
|
||||
@Suppress("DuplicatedCode") val ioBuffer: io.ktor.utils.io.core.IoBuffer =
|
||||
this@l.request(atLeast) ?: return null
|
||||
val buffer = IoBuffer.Pool.borrow()
|
||||
val bytes = (ioBuffer as Input).readBytes()
|
||||
buffer.writeFully(bytes)
|
||||
return buffer
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
override suspend fun readUTF8Line(limit: Int): String? = this@toKotlinByteReadChannel.readUTF8Line(limit)
|
||||
override suspend fun <A : Appendable> readUTF8LineTo(out: A, limit: Int): Boolean =
|
||||
this@toKotlinByteReadChannel.readUTF8LineTo(out, limit)
|
||||
}
|
||||
}
|
||||
QQAndroidBot(ContextImpl(), account, configuration)
|
@ -10,7 +10,6 @@
|
||||
package net.mamoe.mirai.qqandroid.utils.cryptor
|
||||
|
||||
import net.mamoe.mirai.qqandroid.utils.MiraiPlatformUtils
|
||||
import net.mamoe.mirai.utils.MiraiInternalAPI
|
||||
import org.bouncycastle.jce.provider.BouncyCastleProvider
|
||||
import java.security.*
|
||||
import java.security.spec.ECGenParameterSpec
|
||||
|
@ -9,7 +9,6 @@ import net.mamoe.mirai.message.data.MessageChain
|
||||
import net.mamoe.mirai.message.data.MessageSource
|
||||
import net.mamoe.mirai.network.LoginFailedException
|
||||
import net.mamoe.mirai.utils.MiraiExperimentalAPI
|
||||
import net.mamoe.mirai.utils.MiraiInternalAPI
|
||||
import java.util.concurrent.Future
|
||||
import java.util.concurrent.TimeUnit
|
||||
import java.util.concurrent.TimeoutException
|
||||
@ -17,9 +16,8 @@ import java.util.concurrent.TimeoutException
|
||||
/**
|
||||
* [Bot] 中为了让 Java 使用者调用更方便的 API 列表.
|
||||
*/
|
||||
@MiraiInternalAPI
|
||||
@Suppress("FunctionName", "INAPPLICABLE_JVM_NAME", "unused")
|
||||
actual abstract class BotJavaFriendlyAPI actual constructor() {
|
||||
internal actual interface BotJavaFriendlyAPI actual constructor() {
|
||||
init {
|
||||
@Suppress("LeakingThis")
|
||||
assert(this is Bot)
|
||||
|
@ -23,17 +23,15 @@ import net.mamoe.mirai.message.data.Image
|
||||
import net.mamoe.mirai.message.data.Message
|
||||
import net.mamoe.mirai.message.uploadImage
|
||||
import net.mamoe.mirai.utils.ExternalImage
|
||||
import net.mamoe.mirai.utils.MiraiInternalAPI
|
||||
import net.mamoe.mirai.utils.OverFileSizeMaxException
|
||||
import java.io.File
|
||||
import java.io.InputStream
|
||||
import java.net.URL
|
||||
import java.util.concurrent.Future
|
||||
|
||||
@MiraiInternalAPI
|
||||
@JavaFriendlyAPI
|
||||
@Suppress("INAPPLICABLE_JVM_NAME", "FunctionName", "unused")
|
||||
actual abstract class ContactJavaFriendlyAPI {
|
||||
internal actual abstract class ContactJavaFriendlyAPI {
|
||||
|
||||
private inline fun <R> runBlocking(crossinline block: suspend Contact.() -> R): R {
|
||||
@Suppress("CAST_NEVER_SUCCEEDS")
|
||||
|
@ -46,8 +46,8 @@ suspend inline fun <B : Bot> B.alsoLogin(): B = also { login() }
|
||||
*
|
||||
* @see BotFactory 构造 [Bot] 的工厂, [Bot] 唯一的构造方式.
|
||||
*/
|
||||
@Suppress("INAPPLICABLE_JVM_NAME")
|
||||
abstract class Bot : CoroutineScope, LowLevelBotAPIAccessor, BotJavaFriendlyAPI(), ContactOrBot {
|
||||
@Suppress("INAPPLICABLE_JVM_NAME", "EXPOSED_SUPER_CLASS")
|
||||
abstract class Bot : CoroutineScope, LowLevelBotAPIAccessor, BotJavaFriendlyAPI, ContactOrBot {
|
||||
companion object {
|
||||
/**
|
||||
* 复制一份此时的 [Bot] 实例列表.
|
||||
@ -68,13 +68,21 @@ abstract class Bot : CoroutineScope, LowLevelBotAPIAccessor, BotJavaFriendlyAPI(
|
||||
/**
|
||||
* 遍历每一个 [Bot] 实例
|
||||
*/
|
||||
@JvmSynthetic
|
||||
fun forEachInstance(block: (Bot) -> Unit) = BotImpl.forEachInstance(block)
|
||||
|
||||
/**
|
||||
* 获取一个 [Bot] 实例, 找不到则 [NoSuchElementException]
|
||||
* 获取一个 [Bot] 实例, 无对应实例时抛出 [NoSuchElementException]
|
||||
*/
|
||||
@JvmStatic
|
||||
@Throws(NoSuchElementException::class)
|
||||
fun getInstance(qq: Long): Bot = BotImpl.getInstance(qq = qq)
|
||||
|
||||
/**
|
||||
* 获取一个 [Bot] 实例, 无对应实例时返回 `null`
|
||||
*/
|
||||
@JvmStatic
|
||||
fun getInstanceOrNull(qq: Long): Bot? = BotImpl.getInstanceOrNull(qq = qq)
|
||||
}
|
||||
|
||||
/**
|
||||
@ -173,6 +181,10 @@ abstract class Bot : CoroutineScope, LowLevelBotAPIAccessor, BotJavaFriendlyAPI(
|
||||
*
|
||||
* @see Image.queryUrl [Image] 的扩展函数
|
||||
*/
|
||||
@Deprecated(
|
||||
"use extension.",
|
||||
replaceWith = ReplaceWith("image.queryUrl()", imports = ["net.mamoe.mirai.message.data.queryUrl"])
|
||||
)
|
||||
@JvmSynthetic
|
||||
abstract suspend fun queryImageUrl(image: Image): String
|
||||
|
||||
@ -199,6 +211,7 @@ abstract class Bot : CoroutineScope, LowLevelBotAPIAccessor, BotJavaFriendlyAPI(
|
||||
*
|
||||
* @param event 好友验证的事件对象
|
||||
*/
|
||||
@Deprecated("use member function.", replaceWith = ReplaceWith("event.accept()"))
|
||||
@JvmSynthetic
|
||||
abstract suspend fun acceptNewFriendRequest(event: NewFriendRequestEvent)
|
||||
|
||||
@ -208,6 +221,7 @@ abstract class Bot : CoroutineScope, LowLevelBotAPIAccessor, BotJavaFriendlyAPI(
|
||||
* @param event 好友验证的事件对象
|
||||
* @param blackList 拒绝后是否拉入黑名单
|
||||
*/
|
||||
@Deprecated("use member function.", replaceWith = ReplaceWith("event.reject(blackList)"))
|
||||
@JvmSynthetic
|
||||
abstract suspend fun rejectNewFriendRequest(event: NewFriendRequestEvent, blackList: Boolean = false)
|
||||
|
||||
@ -216,6 +230,7 @@ abstract class Bot : CoroutineScope, LowLevelBotAPIAccessor, BotJavaFriendlyAPI(
|
||||
*
|
||||
* @param event 加群验证的事件对象
|
||||
*/
|
||||
@Deprecated("use member function.", replaceWith = ReplaceWith("event.accept()"))
|
||||
@JvmSynthetic
|
||||
abstract suspend fun acceptMemberJoinRequest(event: MemberJoinRequestEvent)
|
||||
|
||||
@ -225,6 +240,7 @@ abstract class Bot : CoroutineScope, LowLevelBotAPIAccessor, BotJavaFriendlyAPI(
|
||||
* @param event 加群验证的事件对象
|
||||
* @param blackList 拒绝后是否拉入黑名单
|
||||
*/
|
||||
@Deprecated("use member function.", replaceWith = ReplaceWith("event.reject(blackList)"))
|
||||
@JvmSynthetic
|
||||
abstract suspend fun rejectMemberJoinRequest(event: MemberJoinRequestEvent, blackList: Boolean = false)
|
||||
|
||||
@ -234,6 +250,7 @@ abstract class Bot : CoroutineScope, LowLevelBotAPIAccessor, BotJavaFriendlyAPI(
|
||||
* @param event 加群验证的事件对象
|
||||
* @param blackList 忽略后是否拉入黑名单
|
||||
*/
|
||||
@Deprecated("use member function.", replaceWith = ReplaceWith("event.ignore(blackList)"))
|
||||
@JvmSynthetic
|
||||
abstract suspend fun ignoreMemberJoinRequest(event: MemberJoinRequestEvent, blackList: Boolean = false)
|
||||
|
||||
@ -242,6 +259,7 @@ abstract class Bot : CoroutineScope, LowLevelBotAPIAccessor, BotJavaFriendlyAPI(
|
||||
*
|
||||
* @param event 邀请入群的事件对象
|
||||
*/
|
||||
@Deprecated("use member function.", replaceWith = ReplaceWith("event.accept"))
|
||||
@JvmSynthetic
|
||||
abstract suspend fun acceptInvitedJoinGroupRequest(event: BotInvitedJoinGroupRequestEvent)
|
||||
|
||||
@ -250,6 +268,7 @@ abstract class Bot : CoroutineScope, LowLevelBotAPIAccessor, BotJavaFriendlyAPI(
|
||||
*
|
||||
* @param event 邀请入群的事件对象
|
||||
*/
|
||||
@Deprecated("use member function.", replaceWith = ReplaceWith("event.ignore"))
|
||||
@JvmSynthetic
|
||||
abstract suspend fun ignoreInvitedJoinGroupRequest(event: BotInvitedJoinGroupRequestEvent)
|
||||
|
||||
|
@ -71,6 +71,17 @@ abstract class BotImpl<N : BotNetworkHandler> constructor(
|
||||
}
|
||||
throw NoSuchElementException(qq.toString())
|
||||
}
|
||||
|
||||
fun getInstanceOrNull(qq: Long): Bot? {
|
||||
instances.forEach {
|
||||
it.get()?.let { bot ->
|
||||
if (bot.id == qq) {
|
||||
return bot
|
||||
}
|
||||
}
|
||||
}
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
// region network
|
||||
|
@ -8,7 +8,7 @@
|
||||
*/
|
||||
|
||||
@file:Suppress("EXPERIMENTAL_API_USAGE", "NOTHING_TO_INLINE", "EXPERIMENTAL_OVERRIDE")
|
||||
@file:OptIn(MiraiInternalAPI::class, JavaFriendlyAPI::class)
|
||||
@file:OptIn(JavaFriendlyAPI::class)
|
||||
|
||||
package net.mamoe.mirai.contact
|
||||
|
||||
@ -25,7 +25,9 @@ import net.mamoe.mirai.message.MessageReceipt
|
||||
import net.mamoe.mirai.message.data.*
|
||||
import net.mamoe.mirai.recall
|
||||
import net.mamoe.mirai.recallIn
|
||||
import net.mamoe.mirai.utils.*
|
||||
import net.mamoe.mirai.utils.ExternalImage
|
||||
import net.mamoe.mirai.utils.OverFileSizeMaxException
|
||||
import net.mamoe.mirai.utils.WeakRefProperty
|
||||
import kotlin.coroutines.CoroutineContext
|
||||
import kotlin.coroutines.EmptyCoroutineContext
|
||||
import kotlin.jvm.JvmSynthetic
|
||||
@ -34,7 +36,8 @@ import kotlin.jvm.JvmSynthetic
|
||||
/**
|
||||
* 联系对象, 即可以与 [Bot] 互动的对象. 包含 [用户][User], 和 [群][Group].
|
||||
*/
|
||||
abstract class Contact : CoroutineScope, ContactJavaFriendlyAPI(), ContactOrBot {
|
||||
@Suppress("EXPOSED_SUPER_CLASS")
|
||||
abstract class Contact : ContactOrBot, CoroutineScope, ContactJavaFriendlyAPI {
|
||||
/**
|
||||
* 这个联系对象所属 [Bot].
|
||||
*/
|
||||
@ -100,7 +103,6 @@ abstract class Contact : CoroutineScope, ContactJavaFriendlyAPI(), ContactOrBot
|
||||
/**
|
||||
* @see Bot.recall
|
||||
*/
|
||||
@MiraiExperimentalAPI
|
||||
@JvmSynthetic
|
||||
suspend inline fun Contact.recall(source: MessageChain) = this.bot.recall(source)
|
||||
|
||||
@ -113,7 +115,6 @@ suspend inline fun Contact.recall(source: MessageSource) = this.bot.recall(sourc
|
||||
/**
|
||||
* @see Bot.recallIn
|
||||
*/
|
||||
@MiraiExperimentalAPI
|
||||
@JvmSynthetic
|
||||
inline fun Contact.recallIn(
|
||||
message: MessageChain,
|
||||
|
@ -22,8 +22,9 @@ import kotlin.jvm.JvmField
|
||||
* @see ContactList.asSequence
|
||||
*/
|
||||
@Suppress("unused")
|
||||
class ContactList<C : Contact> internal constructor(@JvmField internal val delegate: LockFreeLinkedList<C>) :
|
||||
Iterable<C>, Collection<C> {
|
||||
class ContactList<C : Contact>
|
||||
internal constructor(@JvmField internal val delegate: LockFreeLinkedList<C>) : Collection<C> {
|
||||
|
||||
operator fun get(id: Long): C =
|
||||
delegate.asSequence().firstOrNull { it.id == id } ?: throw NoSuchElementException("Contact id $id")
|
||||
|
||||
|
@ -33,11 +33,7 @@ import kotlin.jvm.JvmSynthetic
|
||||
*/
|
||||
@Suppress("DEPRECATION_ERROR")
|
||||
abstract class Friend : User(), CoroutineScope {
|
||||
/**
|
||||
* 请求头像下载链接
|
||||
*/
|
||||
// @MiraiExperimentalAPI
|
||||
//suspend fun queryAvatar(): AvatarLink
|
||||
|
||||
/**
|
||||
* QQ 号码
|
||||
*/
|
||||
|
@ -23,10 +23,7 @@ import net.mamoe.mirai.message.MessageReceipt
|
||||
import net.mamoe.mirai.message.data.Image
|
||||
import net.mamoe.mirai.message.data.Message
|
||||
import net.mamoe.mirai.message.data.toMessage
|
||||
import net.mamoe.mirai.utils.ExternalImage
|
||||
import net.mamoe.mirai.utils.MiraiExperimentalAPI
|
||||
import net.mamoe.mirai.utils.OverFileSizeMaxException
|
||||
import net.mamoe.mirai.utils.get
|
||||
import net.mamoe.mirai.utils.*
|
||||
import net.mamoe.mirai.utils.internal.runBlocking
|
||||
import kotlin.jvm.JvmName
|
||||
import kotlin.jvm.JvmStatic
|
||||
@ -103,6 +100,7 @@ abstract class Group : Contact(), CoroutineScope {
|
||||
* 获取群成员实例. 不存在时抛出 [kotlin.NoSuchElementException]
|
||||
* 当 [id] 为 [Bot.id] 时返回 [botAsMember]
|
||||
*/
|
||||
@Throws(NoSuchElementException::class)
|
||||
abstract operator fun get(id: Long): Member
|
||||
|
||||
/**
|
||||
|
@ -10,21 +10,18 @@
|
||||
package net.mamoe.mirai.contact
|
||||
|
||||
import net.mamoe.mirai.JavaFriendlyAPI
|
||||
import net.mamoe.mirai.utils.MiraiInternalAPI
|
||||
|
||||
/**
|
||||
* [Contact] 中为了让 `Java` 更容易调用的 API.
|
||||
* 不要用它作为一个类型, 只应使用其中的方法
|
||||
*/
|
||||
@MiraiInternalAPI
|
||||
@JavaFriendlyAPI
|
||||
expect abstract class ContactJavaFriendlyAPI internal constructor()
|
||||
internal expect interface ContactJavaFriendlyAPI
|
||||
|
||||
/**
|
||||
* [Member] 中为了让 `Java` 更容易调用的 API
|
||||
* 不要用它作为一个类型, 只应使用其中的方法
|
||||
*/
|
||||
@Suppress("DEPRECATION_ERROR")
|
||||
@MiraiInternalAPI
|
||||
@JavaFriendlyAPI
|
||||
expect abstract class MemberJavaFriendlyAPI internal constructor() : User
|
||||
internal expect interface MemberJavaFriendlyAPI
|
@ -32,9 +32,9 @@ import kotlin.time.ExperimentalTime
|
||||
* ## 与好友相关的操作
|
||||
* [Member.isFriend] 判断此成员是否为好友
|
||||
*/
|
||||
@Suppress("INAPPLICABLE_JVM_NAME")
|
||||
@Suppress("INAPPLICABLE_JVM_NAME", "EXPOSED_SUPER_CLASS")
|
||||
@OptIn(JavaFriendlyAPI::class)
|
||||
abstract class Member : MemberJavaFriendlyAPI() {
|
||||
abstract class Member : MemberJavaFriendlyAPI, User() {
|
||||
/**
|
||||
* 所在的群.
|
||||
*/
|
||||
|
@ -241,6 +241,7 @@ sealed class MemberLeaveEvent : GroupMemberEvent, AbstractEvent() {
|
||||
/**
|
||||
* [Bot] 被邀请加入一个群.
|
||||
*/
|
||||
@Suppress("DEPRECATION")
|
||||
data class BotInvitedJoinGroupRequestEvent internal constructor(
|
||||
override val bot: Bot,
|
||||
/**
|
||||
@ -283,6 +284,7 @@ data class BotInvitedJoinGroupRequestEvent internal constructor(
|
||||
/**
|
||||
* 一个账号请求加入群事件, [Bot] 在此群中是管理员或群主.
|
||||
*/
|
||||
@Suppress("DEPRECATION")
|
||||
data class MemberJoinRequestEvent internal constructor(
|
||||
override val bot: Bot,
|
||||
/**
|
||||
|
@ -6,7 +6,6 @@
|
||||
*
|
||||
* https://github.com/mamoe/mirai/blob/master/LICENSE
|
||||
*/
|
||||
@file:OptIn(MiraiInternalAPI::class)
|
||||
|
||||
package net.mamoe.mirai.event.internal
|
||||
|
||||
@ -16,7 +15,6 @@ import kotlinx.coroutines.sync.withLock
|
||||
import net.mamoe.mirai.event.*
|
||||
import net.mamoe.mirai.event.events.BotEvent
|
||||
import net.mamoe.mirai.utils.LockFreeLinkedList
|
||||
import net.mamoe.mirai.utils.MiraiInternalAPI
|
||||
import net.mamoe.mirai.utils.MiraiLogger
|
||||
import net.mamoe.mirai.utils.PlannedRemoval
|
||||
import kotlin.coroutines.CoroutineContext
|
||||
|
@ -9,14 +9,11 @@
|
||||
|
||||
package net.mamoe.mirai
|
||||
|
||||
import net.mamoe.mirai.utils.MiraiInternalAPI
|
||||
|
||||
/**
|
||||
* 表明这个 API 是为了让 Java 使用者调用更方便.
|
||||
*
|
||||
* 一般有一定的性能损失, 且不能在 JVM/Android 以外平台使用. 不要在 Kotlin 调用它.
|
||||
*/
|
||||
@MiraiInternalAPI
|
||||
@RequiresOptIn(level = RequiresOptIn.Level.ERROR)
|
||||
@Target(AnnotationTarget.PROPERTY, AnnotationTarget.FUNCTION, AnnotationTarget.TYPE, AnnotationTarget.CLASS)
|
||||
internal annotation class JavaFriendlyAPI
|
||||
@ -26,12 +23,10 @@ internal annotation class JavaFriendlyAPI
|
||||
*
|
||||
* **注意**: 不应该把这个类作为一个类型, 只应使用其中的方法
|
||||
*/
|
||||
@MiraiInternalAPI
|
||||
@Suppress("FunctionName", "INAPPLICABLE_JVM_NAME", "unused")
|
||||
expect abstract class BotJavaFriendlyAPI() { // 不要使用 interface, 会无法添加默认实现
|
||||
}
|
||||
internal expect interface BotJavaFriendlyAPI
|
||||
|
||||
// 保留多平台结构, 以避免在 Android 和 JVM 都定义这个类 ---- 这会造成代码重复.
|
||||
// 保留多平台结构, 以避免在 Android 和 JVM 都定义这个类
|
||||
// 待 https://youtrack.jetbrains.com/issue/KT-27801 实现后修改为 hierarchical MPP 架构
|
||||
|
||||
// 待 https://youtrack.jetbrains.com/issue/KT-36740 修复后添加 Future 相关 API 到 hierarchical MPP 架构中
|
@ -14,7 +14,6 @@
|
||||
"DECLARATION_CANT_BE_INLINED", "UNCHECKED_CAST", "NOTHING_TO_INLINE"
|
||||
)
|
||||
|
||||
@file:OptIn(MiraiInternalAPI::class)
|
||||
@file:JvmMultifileClass
|
||||
@file:JvmName("MessageEventKt")
|
||||
|
||||
@ -26,7 +25,10 @@ import net.mamoe.mirai.event.AbstractEvent
|
||||
import net.mamoe.mirai.event.events.BotEvent
|
||||
import net.mamoe.mirai.message.data.*
|
||||
import net.mamoe.mirai.qqandroid.network.Packet
|
||||
import net.mamoe.mirai.utils.*
|
||||
import net.mamoe.mirai.utils.ExternalImage
|
||||
import net.mamoe.mirai.utils.PlannedRemoval
|
||||
import net.mamoe.mirai.utils.sendTo
|
||||
import net.mamoe.mirai.utils.upload
|
||||
import kotlin.jvm.JvmMultifileClass
|
||||
import kotlin.jvm.JvmName
|
||||
import kotlin.jvm.JvmSynthetic
|
||||
@ -147,7 +149,7 @@ interface MessageEventExtensions<out TSender : User, out TSubject : Contact> :
|
||||
* @return "http://gchat.qpic.cn/gchatpic_new/..."
|
||||
*/
|
||||
@JvmSynthetic
|
||||
suspend inline fun Image.url(): String = bot.queryImageUrl(this@url)
|
||||
suspend inline fun Image.url(): String = this@url.queryUrl()
|
||||
}
|
||||
|
||||
/** 一个消息事件在各平台的相关扩展. 请使用 [MessageEventExtensions] */
|
||||
|
@ -10,12 +10,10 @@
|
||||
@file:JvmMultifileClass
|
||||
@file:JvmName("MessageUtils")
|
||||
@file:Suppress("unused", "NOTHING_TO_INLINE", "WRONG_MODIFIER_CONTAINING_DECLARATION", "INAPPLICABLE_JVM_NAME")
|
||||
@file:OptIn(MiraiInternalAPI::class)
|
||||
|
||||
package net.mamoe.mirai.message.data
|
||||
|
||||
import net.mamoe.mirai.JavaFriendlyAPI
|
||||
import net.mamoe.mirai.utils.MiraiInternalAPI
|
||||
import net.mamoe.mirai.utils.PlannedRemoval
|
||||
import kotlin.js.JsName
|
||||
import kotlin.jvm.JvmMultifileClass
|
||||
|
@ -124,7 +124,6 @@ abstract class BotNetworkHandler : CoroutineScope {
|
||||
}
|
||||
|
||||
@MiraiInternalAPI
|
||||
|
||||
suspend fun BotNetworkHandler.closeAndJoin(cause: Throwable? = null) {
|
||||
this.close(cause)
|
||||
this.supervisor.join()
|
||||
|
@ -21,9 +21,7 @@ import kotlin.annotation.AnnotationTarget.*
|
||||
@RequiresOptIn(level = RequiresOptIn.Level.ERROR)
|
||||
@Target(
|
||||
CLASS, TYPEALIAS, FUNCTION, PROPERTY, FIELD, CONSTRUCTOR,
|
||||
CLASS,
|
||||
FUNCTION,
|
||||
PROPERTY
|
||||
CLASS, FUNCTION, PROPERTY
|
||||
)
|
||||
annotation class MiraiInternalAPI(
|
||||
val message: String = ""
|
||||
|
@ -46,26 +46,17 @@ class ExternalImage internal constructor(
|
||||
const val defaultFormatName = "mirai"
|
||||
|
||||
|
||||
@MiraiExperimentalAPI
|
||||
fun generateUUID(md5: ByteArray): String {
|
||||
return "${md5[0, 3]}-${md5[4, 5]}-${md5[6, 7]}-${md5[8, 9]}-${md5[10, 15]}"
|
||||
}
|
||||
|
||||
@MiraiExperimentalAPI
|
||||
fun generateImageId(md5: ByteArray): String {
|
||||
return """{${generateUUID(md5)}}.$defaultFormatName"""
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* ImgType:
|
||||
* JPG: 1000
|
||||
* PNG: 1001
|
||||
* WEBP: 1002
|
||||
* BMP: 1005
|
||||
* GIG: 2000 // gig? gif?
|
||||
* APNG: 2001
|
||||
* SHARPP: 1004
|
||||
*/
|
||||
|
||||
override fun toString(): String {
|
||||
if (input is DeferredReusableInput) {
|
||||
if (!input.initialized) {
|
||||
@ -78,6 +69,17 @@ class ExternalImage internal constructor(
|
||||
internal fun calculateImageResourceId(): String = generateImageId(md5)
|
||||
}
|
||||
|
||||
/*
|
||||
* ImgType:
|
||||
* JPG: 1000
|
||||
* PNG: 1001
|
||||
* WEBP: 1002
|
||||
* BMP: 1005
|
||||
* GIG: 2000 // gig? gif?
|
||||
* APNG: 2001
|
||||
* SHARPP: 1004
|
||||
*/
|
||||
|
||||
/**
|
||||
* 将图片作为单独的消息发送给指定联系人
|
||||
*/
|
||||
|
@ -797,7 +797,7 @@ internal open class Tail<E> : LockFreeLinkedListNode<E>(null, null) {
|
||||
override val nodeValue: Nothing get() = error("Internal error: trying to get the value of a Tail")
|
||||
}
|
||||
|
||||
open class LockFreeLinkedListNode<E>(
|
||||
internal open class LockFreeLinkedListNode<E>(
|
||||
nextNode: LockFreeLinkedListNode<E>?,
|
||||
private val initialNodeValue: E?
|
||||
) {
|
||||
@ -858,18 +858,9 @@ open class LockFreeLinkedListNode<E>(
|
||||
|
||||
}
|
||||
|
||||
fun <E> LockFreeLinkedListNode<E>.isRemoved() = this.removed.value
|
||||
|
||||
@PublishedApi
|
||||
@Suppress("NOTHING_TO_INLINE")
|
||||
internal fun <E> LockFreeLinkedListNode<E>.isRemoved() = this.removed.value
|
||||
internal inline fun LockFreeLinkedListNode<*>.isValidElementNode(): Boolean = !isHead() && !isTail() && !isRemoved()
|
||||
|
||||
@PublishedApi
|
||||
@Suppress("NOTHING_TO_INLINE")
|
||||
internal inline fun LockFreeLinkedListNode<*>.isHead(): Boolean = this is Head
|
||||
|
||||
@PublishedApi
|
||||
@Suppress("NOTHING_TO_INLINE")
|
||||
internal inline fun LockFreeLinkedListNode<*>.isTail(): Boolean = this is Tail
|
||||
|
||||
// end region
|
@ -82,19 +82,18 @@ inline val Int.weeksToSeconds: Long
|
||||
inline val Int.monthsToSeconds: Long
|
||||
get() = this * 30.daysToSeconds
|
||||
|
||||
@MiraiExperimentalAPI
|
||||
@ExperimentalTime
|
||||
val Duration.asHumanReadable: String
|
||||
get() {
|
||||
val builder = StringBuilder()
|
||||
val days = toInt(DurationUnit.DAYS)
|
||||
val hours = toInt(DurationUnit.HOURS) % 24
|
||||
val minutes = toInt(DurationUnit.MINUTES) % 60
|
||||
val s = floor(toDouble(DurationUnit.SECONDS) % 60 * 1000) / 1000
|
||||
with(builder) {
|
||||
return buildString {
|
||||
if (days != 0) append("${days}d ")
|
||||
if (hours != 0) append("${hours}h ")
|
||||
if (minutes != 0) append("${minutes}min ")
|
||||
append("${s}s")
|
||||
}
|
||||
return builder.toString()
|
||||
}
|
||||
|
@ -16,21 +16,8 @@ import java.util.concurrent.TimeoutException
|
||||
/**
|
||||
* [Bot] 中为了让 Java 使用者调用更方便的 API 列表.
|
||||
*/
|
||||
@MiraiInternalAPI
|
||||
@Suppress("FunctionName", "INAPPLICABLE_JVM_NAME", "unused")
|
||||
actual abstract class BotJavaFriendlyAPI actual constructor() {
|
||||
init {
|
||||
@Suppress("LeakingThis")
|
||||
assert(this is Bot)
|
||||
}
|
||||
|
||||
private inline fun <R> runBlocking(crossinline block: suspend Bot.() -> R): R {
|
||||
return kotlinx.coroutines.runBlocking { block(this@BotJavaFriendlyAPI as Bot) }
|
||||
}
|
||||
|
||||
private inline fun <R> future(crossinline block: suspend Bot.() -> R): Future<R> {
|
||||
return (this as Bot).run { future { block() } }
|
||||
}
|
||||
internal actual interface BotJavaFriendlyAPI {
|
||||
|
||||
/**
|
||||
* 登录, 或重新登录.
|
||||
@ -151,6 +138,14 @@ actual abstract class BotJavaFriendlyAPI actual constructor() {
|
||||
}
|
||||
}
|
||||
|
||||
private inline fun <R> BotJavaFriendlyAPI.future(crossinline block: suspend Bot.() -> R): Future<R> {
|
||||
return (this as CoroutineScope).run { future { block(this as Bot) } }
|
||||
}
|
||||
|
||||
private inline fun <R> BotJavaFriendlyAPI.runBlocking(crossinline block: suspend Bot.() -> R): R {
|
||||
return kotlinx.coroutines.runBlocking { block(this@runBlocking as Bot) }
|
||||
}
|
||||
|
||||
@OptIn(ExperimentalCoroutinesApi::class)
|
||||
internal fun <R, C : CoroutineScope> C.future(block: suspend C.() -> R): Future<R> {
|
||||
val future = object : Future<R> {
|
||||
|
@ -22,7 +22,6 @@ import net.mamoe.mirai.message.data.Image
|
||||
import net.mamoe.mirai.message.data.Message
|
||||
import net.mamoe.mirai.message.uploadImage
|
||||
import net.mamoe.mirai.utils.ExternalImage
|
||||
import net.mamoe.mirai.utils.MiraiInternalAPI
|
||||
import net.mamoe.mirai.utils.OverFileSizeMaxException
|
||||
import java.awt.image.BufferedImage
|
||||
import java.io.File
|
||||
@ -30,21 +29,9 @@ import java.io.InputStream
|
||||
import java.net.URL
|
||||
import java.util.concurrent.Future
|
||||
|
||||
@MiraiInternalAPI
|
||||
@JavaFriendlyAPI
|
||||
@Suppress("INAPPLICABLE_JVM_NAME", "FunctionName", "unused")
|
||||
actual abstract class ContactJavaFriendlyAPI {
|
||||
|
||||
private inline fun <R> runBlocking(crossinline block: suspend Contact.() -> R): R {
|
||||
@Suppress("CAST_NEVER_SUCCEEDS")
|
||||
return kotlinx.coroutines.runBlocking { block(this@ContactJavaFriendlyAPI as Contact) }
|
||||
}
|
||||
|
||||
private inline fun <R> future(crossinline block: suspend Contact.() -> R): Future<R> {
|
||||
@Suppress("CAST_NEVER_SUCCEEDS")
|
||||
return (this as Contact).run { future { block() } }
|
||||
}
|
||||
|
||||
internal actual interface ContactJavaFriendlyAPI {
|
||||
/**
|
||||
* 向这个对象发送消息.
|
||||
*
|
||||
@ -65,6 +52,7 @@ actual abstract class ContactJavaFriendlyAPI {
|
||||
return runBlocking { sendMessage(message) }
|
||||
}
|
||||
|
||||
@Throws(EventCancelledException::class, IllegalStateException::class)
|
||||
@JvmName("sendMessage")
|
||||
open fun __sendMessageBlockingForJava__(message: String): MessageReceipt<Contact> {
|
||||
return runBlocking { sendMessage(message) }
|
||||
@ -205,19 +193,21 @@ actual abstract class ContactJavaFriendlyAPI {
|
||||
}
|
||||
}
|
||||
|
||||
@Suppress("INAPPLICABLE_JVM_NAME", "FunctionName", "unused", "unused", "DEPRECATION_ERROR")
|
||||
@MiraiInternalAPI
|
||||
@JavaFriendlyAPI
|
||||
actual abstract class MemberJavaFriendlyAPI : User() {
|
||||
private inline fun <R> runBlocking(crossinline block: suspend Member.() -> R): R {
|
||||
@Suppress("CAST_NEVER_SUCCEEDS")
|
||||
return kotlinx.coroutines.runBlocking { block(this@MemberJavaFriendlyAPI as Member) }
|
||||
}
|
||||
private inline fun <R> ContactJavaFriendlyAPI.runBlocking(crossinline block: suspend Contact.() -> R): R {
|
||||
@Suppress("CAST_NEVER_SUCCEEDS")
|
||||
return kotlinx.coroutines.runBlocking { block(this@runBlocking as Contact) }
|
||||
}
|
||||
|
||||
private inline fun <R> future(crossinline block: suspend Member.() -> R): Future<R> {
|
||||
@Suppress("CAST_NEVER_SUCCEEDS")
|
||||
return (this as Member).run { future { block() } }
|
||||
}
|
||||
@JavaFriendlyAPI
|
||||
private inline fun <R> ContactJavaFriendlyAPI.future(crossinline block: suspend Contact.() -> R): Future<R> {
|
||||
@Suppress("CAST_NEVER_SUCCEEDS")
|
||||
return (this as Contact).run { future { block() } }
|
||||
}
|
||||
|
||||
@Suppress("INAPPLICABLE_JVM_NAME", "FunctionName", "unused", "unused", "DEPRECATION_ERROR")
|
||||
@JavaFriendlyAPI
|
||||
internal actual interface MemberJavaFriendlyAPI {
|
||||
|
||||
|
||||
/**
|
||||
@ -340,4 +330,16 @@ actual abstract class MemberJavaFriendlyAPI : User() {
|
||||
*/
|
||||
@JvmName("kickAsync")
|
||||
open fun __kickAsyncForJava__(): Future<Unit> = __kickAsyncForJava__("")
|
||||
}
|
||||
|
||||
@JavaFriendlyAPI
|
||||
private inline fun <R> MemberJavaFriendlyAPI.future(crossinline block: suspend Member.() -> R): Future<R> {
|
||||
@Suppress("CAST_NEVER_SUCCEEDS")
|
||||
return (this as Member).run { future { block() } }
|
||||
}
|
||||
|
||||
@JavaFriendlyAPI
|
||||
private inline fun <R> MemberJavaFriendlyAPI.runBlocking(crossinline block: suspend Member.() -> R): R {
|
||||
@Suppress("CAST_NEVER_SUCCEEDS")
|
||||
return kotlinx.coroutines.runBlocking { block(this@runBlocking as Member) }
|
||||
}
|
@ -17,7 +17,6 @@ import kotlinx.coroutines.withContext
|
||||
import net.mamoe.mirai.event.Event
|
||||
import net.mamoe.mirai.event.Listener
|
||||
import net.mamoe.mirai.event.ListeningStatus
|
||||
import net.mamoe.mirai.utils.MiraiInternalAPI
|
||||
import java.util.function.Consumer
|
||||
import java.util.function.Function
|
||||
import kotlin.coroutines.EmptyCoroutineContext
|
||||
|
@ -7,8 +7,6 @@
|
||||
* https://github.com/mamoe/mirai/blob/master/LICENSE
|
||||
*/
|
||||
|
||||
@file:OptIn(MiraiInternalAPI::class)
|
||||
|
||||
package net.mamoe.mirai.event.internal
|
||||
|
||||
import net.mamoe.mirai.event.Event
|
||||
|
@ -11,7 +11,6 @@ package net.mamoe.mirai.event
|
||||
|
||||
import kotlinx.coroutines.*
|
||||
import net.mamoe.mirai.event.internal.GlobalEventListeners
|
||||
import net.mamoe.mirai.utils.MiraiInternalAPI
|
||||
import net.mamoe.mirai.utils.StepUtil
|
||||
import net.mamoe.mirai.utils.internal.runBlocking
|
||||
import java.util.concurrent.Executor
|
||||
|
Loading…
Reference in New Issue
Block a user