Commit 46598d68 authored by Him188's avatar Him188

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`
parent dc8945aa
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
......
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)
}
}
\ No newline at end of file
QQAndroidBot(ContextImpl(), account, configuration)
\ No newline at end of file
......@@ -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
\ No newline at end of file
internal expect interface MemberJavaFriendlyAPI
\ No newline at end of file
......@@ -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 架构中
\ No newline at end of file
......@@ -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
\ No newline at end of file
......@@ -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) }
}
\ No newline at end of file
......@@ -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
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment