mirror of
https://github.com/mamoe/mirai.git
synced 2025-01-09 18:00:33 +08:00
Add contracts
This commit is contained in:
parent
2697ac8fdb
commit
a9a0e62130
@ -19,6 +19,9 @@ import net.mamoe.mirai.utils.BotConfiguration
|
||||
import net.mamoe.mirai.utils.DefaultLogger
|
||||
import net.mamoe.mirai.utils.MiraiLogger
|
||||
import net.mamoe.mirai.utils.internal.coerceAtLeastOrFail
|
||||
import kotlin.contracts.ExperimentalContracts
|
||||
import kotlin.contracts.InvocationKind
|
||||
import kotlin.contracts.contract
|
||||
import kotlin.coroutines.CoroutineContext
|
||||
import kotlin.jvm.JvmOverloads
|
||||
|
||||
@ -228,29 +231,36 @@ Mirai 22:04:48 : Packet received: UnknownEventPacket(id=00 D6, identity=(2092749
|
||||
* @param lazyMessage 若需要验证请求时的验证消息.
|
||||
* @param lazyRemark 好友备注
|
||||
*/
|
||||
suspend fun ContactSystem.addFriend(id: UInt, lazyMessage: () -> String = { "" }, lazyRemark: () -> String = { "" }): AddFriendResult = bot.withSession {
|
||||
when (CanAddFriendPacket(bot.qqAccount, id, bot.sessionKey).sendAndExpect<CanAddFriendResponse>()) {
|
||||
is CanAddFriendResponse.AlreadyAdded -> AddFriendResult.ALREADY_ADDED
|
||||
is CanAddFriendResponse.Rejected -> AddFriendResult.REJECTED
|
||||
@UseExperimental(ExperimentalContracts::class)
|
||||
suspend fun ContactSystem.addFriend(id: UInt, lazyMessage: () -> String = { "" }, lazyRemark: () -> String = { "" }): AddFriendResult {
|
||||
contract {
|
||||
callsInPlace(lazyMessage, InvocationKind.AT_MOST_ONCE)
|
||||
callsInPlace(lazyRemark, InvocationKind.AT_MOST_ONCE)
|
||||
}
|
||||
return bot.withSession {
|
||||
when (CanAddFriendPacket(bot.qqAccount, id, bot.sessionKey).sendAndExpect<CanAddFriendResponse>()) {
|
||||
is CanAddFriendResponse.AlreadyAdded -> AddFriendResult.ALREADY_ADDED
|
||||
is CanAddFriendResponse.Rejected -> AddFriendResult.REJECTED
|
||||
|
||||
is CanAddFriendResponse.ReadyToAdd,
|
||||
is CanAddFriendResponse.RequireVerification -> {
|
||||
val key = RequestFriendAdditionKeyPacket(bot.qqAccount, id, sessionKey).sendAndExpect<RequestFriendAdditionKeyPacket.Response>().key
|
||||
AddFriendPacket(bot.qqAccount, id, sessionKey, lazyMessage(), lazyRemark(), key).sendAndExpect<AddFriendPacket.Response>()
|
||||
return AddFriendResult.WAITING_FOR_APPROVE
|
||||
}
|
||||
//这个做的是需要验证消息的情况, 不确定 ReadyToAdd 的是啥
|
||||
is CanAddFriendResponse.ReadyToAdd,
|
||||
is CanAddFriendResponse.RequireVerification -> {
|
||||
val key = RequestFriendAdditionKeyPacket(bot.qqAccount, id, sessionKey).sendAndExpect<RequestFriendAdditionKeyPacket.Response>().key
|
||||
AddFriendPacket(bot.qqAccount, id, sessionKey, lazyMessage(), lazyRemark(), key).sendAndExpect<AddFriendPacket.Response>()
|
||||
return AddFriendResult.WAITING_FOR_APPROVE
|
||||
}
|
||||
//这个做的是需要验证消息的情况, 不确定 ReadyToAdd 的是啥
|
||||
|
||||
// 似乎 RequireVerification 和 ReadyToAdd 判断错了. 需要重新检查一下
|
||||
// 似乎 RequireVerification 和 ReadyToAdd 判断错了. 需要重新检查一下
|
||||
|
||||
// TODO: 2019/11/11 需要验证问题的情况
|
||||
// TODO: 2019/11/11 需要验证问题的情况
|
||||
|
||||
/*is CanAddFriendResponse.ReadyToAdd -> {
|
||||
/*is CanAddFriendResponse.ReadyToAdd -> {
|
||||
// TODO: 2019/11/11 这不需要验证信息的情况
|
||||
|
||||
//AddFriendPacket(bot.qqAccount, id, bot.sessionKey, ).sendAndExpectAsync<AddFriendPacket.Response>().await()
|
||||
TODO()
|
||||
}*/
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -7,10 +7,14 @@ import net.mamoe.mirai.network.BotNetworkHandler
|
||||
import net.mamoe.mirai.network.BotSession
|
||||
import net.mamoe.mirai.network.protocol.tim.packet.OutgoingPacket
|
||||
import net.mamoe.mirai.network.protocol.tim.packet.login.LoginResult
|
||||
import net.mamoe.mirai.network.protocol.tim.packet.login.requireSuccess
|
||||
import net.mamoe.mirai.network.session
|
||||
import net.mamoe.mirai.utils.BotConfiguration
|
||||
import net.mamoe.mirai.utils.internal.PositiveNumbers
|
||||
import net.mamoe.mirai.utils.internal.coerceAtLeastOrFail
|
||||
import kotlin.contracts.ExperimentalContracts
|
||||
import kotlin.contracts.InvocationKind
|
||||
import kotlin.contracts.contract
|
||||
import kotlin.jvm.JvmOverloads
|
||||
|
||||
/*
|
||||
@ -43,7 +47,13 @@ inline val Bot.qqs: ContactList<QQ>
|
||||
* 以 [BotSession] 作为接收器 (receiver) 并调用 [block], 返回 [block] 的返回值.
|
||||
* 这个方法将能帮助使用在 [BotSession] 中定义的一些扩展方法, 如 [BotSession.sendAndExpectAsync]
|
||||
*/
|
||||
inline fun <R> Bot.withSession(block: BotSession.() -> R): R = with(this.network.session) { block() }
|
||||
@UseExperimental(ExperimentalContracts::class)
|
||||
inline fun <R> Bot.withSession(block: BotSession.() -> R): R {
|
||||
contract {
|
||||
callsInPlace(block, InvocationKind.EXACTLY_ONCE)
|
||||
}
|
||||
return with(this.network.session) { block() }
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送数据包
|
||||
@ -54,18 +64,43 @@ suspend inline fun Bot.sendPacket(packet: OutgoingPacket) = this.network.sendPac
|
||||
/**
|
||||
* 使用在默认配置基础上修改的配置进行登录
|
||||
*/
|
||||
suspend inline fun Bot.login(noinline configuration: BotConfiguration.() -> Unit): LoginResult = this.network.login(BotConfiguration().apply(configuration))
|
||||
@UseExperimental(ExperimentalContracts::class)
|
||||
suspend inline fun Bot.login(noinline configuration: BotConfiguration.() -> Unit): LoginResult {
|
||||
contract {
|
||||
callsInPlace(configuration, InvocationKind.EXACTLY_ONCE)
|
||||
}
|
||||
return this.network.login(BotConfiguration().apply(configuration))
|
||||
}
|
||||
|
||||
/**
|
||||
* 使用默认的配置 ([BotConfiguration.Default]) 登录
|
||||
*/
|
||||
suspend inline fun Bot.login(): LoginResult = this.network.login(BotConfiguration.Default)
|
||||
|
||||
/**
|
||||
* 使用默认的配置 ([BotConfiguration.Default]) 登录
|
||||
*/
|
||||
@UseExperimental(ExperimentalContracts::class)
|
||||
suspend inline fun Bot.alsoLogin(lazyMessageWhenLoginFailed: (LoginResult) -> String): Bot {
|
||||
contract {
|
||||
callsInPlace(lazyMessageWhenLoginFailed, InvocationKind.AT_MOST_ONCE)
|
||||
}
|
||||
return this.apply {
|
||||
login().requireSuccess(lazyMessageWhenLoginFailed)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加好友
|
||||
*/
|
||||
@UseExperimental(ExperimentalContracts::class)
|
||||
@JvmOverloads
|
||||
suspend inline fun Bot.addFriend(id: UInt, noinline lazyMessage: () -> String = { "" }): AddFriendResult = this.contacts.addFriend(id, lazyMessage)
|
||||
suspend inline fun Bot.addFriend(id: UInt, noinline lazyMessage: () -> String = { "" }, noinline lazyRemark: () -> String = { "" }): AddFriendResult {
|
||||
contract {
|
||||
callsInPlace(lazyMessage, InvocationKind.AT_MOST_ONCE)
|
||||
}
|
||||
return this.contacts.addFriend(id, lazyMessage, lazyRemark)
|
||||
}
|
||||
|
||||
/**
|
||||
* 取得机器人的 QQ 号
|
||||
|
@ -1,6 +1,9 @@
|
||||
package net.mamoe.mirai.network.protocol.tim.packet.login
|
||||
|
||||
import net.mamoe.mirai.network.protocol.tim.packet.login.LoginResult.SUCCESS
|
||||
import kotlin.contracts.ExperimentalContracts
|
||||
import kotlin.contracts.InvocationKind
|
||||
import kotlin.contracts.contract
|
||||
|
||||
/**
|
||||
* 登录结果. 除 [SUCCESS] 外均为失败.
|
||||
@ -56,7 +59,11 @@ enum class LoginResult {
|
||||
/**
|
||||
* 如果 [this] 不为 [LoginResult.SUCCESS] 就抛出消息为 [lazyMessage] 的 [IllegalStateException]
|
||||
*/
|
||||
fun LoginResult.requireSuccess(lazyMessage: (LoginResult) -> String) {
|
||||
@UseExperimental(ExperimentalContracts::class)
|
||||
inline fun LoginResult.requireSuccess(lazyMessage: (LoginResult) -> String) {
|
||||
contract {
|
||||
callsInPlace(lazyMessage, InvocationKind.AT_MOST_ONCE)
|
||||
}
|
||||
if (this != SUCCESS) error(lazyMessage(this))
|
||||
}
|
||||
|
||||
@ -86,5 +93,10 @@ fun LoginResult.requireSuccessOrNull(): Unit? =
|
||||
*
|
||||
* @return 成功时 [Unit], 失败时 `null`
|
||||
*/
|
||||
inline fun <R> LoginResult.ifFail(block: (LoginResult) -> R): R? =
|
||||
if (this != SUCCESS) block(this) else null
|
||||
@UseExperimental(ExperimentalContracts::class)
|
||||
inline fun <R> LoginResult.ifFail(block: (LoginResult) -> R): R? {
|
||||
contract {
|
||||
callsInPlace(block, InvocationKind.AT_MOST_ONCE)
|
||||
}
|
||||
return if (this != SUCCESS) block(this) else null
|
||||
}
|
||||
|
@ -16,7 +16,7 @@ fun <R> CoroutineScope.SuspendLazy(initializer: suspend () -> R): Lazy<Deferred<
|
||||
/**
|
||||
* 挂起初始化的 [lazy], 是属性不能 `suspend` 的替代品.
|
||||
*
|
||||
* 本对象代表值初始化时将会通过 [CoroutineScope.async] 运行 [initializer]
|
||||
* 本对象代表值初始化时将会通过 [CoroutineScope.async] 运行 [valueUpdater]
|
||||
*
|
||||
* [SuspendLazy] 是:
|
||||
* - 线程安全
|
||||
|
Loading…
Reference in New Issue
Block a user