Commit 19ca01b4 authored by Him188's avatar Him188

BroadcastControllable

parent 1eb31031
......@@ -9,6 +9,7 @@ import net.mamoe.mirai.Bot.ContactSystem
import net.mamoe.mirai.contact.*
import net.mamoe.mirai.network.BotNetworkHandler
import net.mamoe.mirai.network.protocol.tim.TIMBotNetworkHandler
import net.mamoe.mirai.network.protocol.tim.packet.action.AddFriendPacket
import net.mamoe.mirai.network.protocol.tim.packet.action.CanAddFriendPacket
import net.mamoe.mirai.network.protocol.tim.packet.action.CanAddFriendResponse
import net.mamoe.mirai.network.protocol.tim.packet.login.LoginResult
......@@ -66,7 +67,7 @@ class Bot(val account: BotAccount, val logger: MiraiLogger) {
instances.add(this)
}
override fun toString(): String = "Bot{qq=${account.id}}"
override fun toString(): String = "Bot(${account.id})"
/**
* [关闭][BotNetworkHandler.close]网络处理器, 取消所有运行在 [BotNetworkHandler] 下的协程.
......@@ -158,19 +159,46 @@ class Bot(val account: BotAccount, val logger: MiraiLogger) {
}
}
suspend fun ContactSystem.canAddFriend(id: UInt): CanAddFriendResponse =
bot.withSession {
CanAddFriendPacket(bot.qqAccount, id, bot.sessionKey).sendAndExpect<CanAddFriendResponse>().await()
@Suppress("ClassName")
sealed class AddFriendResult {
open class SUCCESS internal constructor() : AddFriendResult() {
companion object : SUCCESS()
override fun toString(): String = "AddFriendResult(Success)"
}
/**
* 对方拒绝添加好友
*/
object REJECTED : AddFriendResult() {
override fun toString(): String = "AddFriendResult(Rejected)"
}
/**
* 这个人已经是好友
*/
object ALREADY_ADDED : SUCCESS() {
override fun toString(): String = "AddFriendResult(AlreadyAdded)"
}
}
/**
* 添加一个好友
*
* @param lazyMessage 若需要验证请求时的验证消息.
*/
suspend fun ContactSystem.addFriend(id: UInt, lazyMessage: () -> String = { "" }): Boolean = when (this.canAddFriend(id)) {
is CanAddFriendResponse.AlreadyAdded -> false
is CanAddFriendResponse.Rejected -> false
is CanAddFriendResponse.RequireVerification -> TODO()
is CanAddFriendResponse.ReadyToAdd -> TODO()
suspend fun ContactSystem.addFriend(id: UInt, lazyMessage: () -> String = { "" }): AddFriendResult = bot.withSession {
when (CanAddFriendPacket(bot.qqAccount, id, bot.sessionKey).sendAndExpect<CanAddFriendResponse>().await()) {
is CanAddFriendResponse.AlreadyAdded -> AddFriendResult.ALREADY_ADDED
is CanAddFriendResponse.Rejected -> AddFriendResult.REJECTED
is CanAddFriendResponse.RequireVerification -> {
TODO()
}
is CanAddFriendResponse.ReadyToAdd -> {
AddFriendPacket(bot.qqAccount, id, bot.sessionKey).sendAndExpect<AddFriendPacket.AddFriendResponse>().await()
TODO()
}
}
}
......@@ -6,7 +6,6 @@ import net.mamoe.mirai.contact.*
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.action.CanAddFriendResponse
import net.mamoe.mirai.network.protocol.tim.packet.login.LoginResult
import net.mamoe.mirai.network.session
import net.mamoe.mirai.utils.BotConfiguration
......@@ -62,16 +61,11 @@ suspend inline fun Bot.login(noinline configuration: BotConfiguration.() -> Unit
*/
suspend inline fun Bot.login(): LoginResult = this.network.login(BotConfiguration.Default)
/**
* 得到可否添加这个人为好友
*/
suspend inline fun Bot.canAddFriend(id: UInt): CanAddFriendResponse = this.contacts.canAddFriend(id)
/**
* 添加好友
*/
@JvmOverloads
suspend inline fun Bot.addFriend(id: UInt, noinline lazyMessage: () -> String = { "" }) = this.contacts.addFriend(id, lazyMessage)
suspend inline fun Bot.addFriend(id: UInt, noinline lazyMessage: () -> String = { "" }): AddFriendResult = this.contacts.addFriend(id, lazyMessage)
/**
* 取得机器人的 QQ 号
......
......@@ -97,4 +97,12 @@ object EventScope : CoroutineScope {
EventDispatcher + CoroutineExceptionHandler { _, e ->
MiraiLogger.error("An exception is thrown in EventScope", e)
}
}
/**
* 可控制是否需要广播这个事件包
*/
interface BroadcastControllable : Subscribable {
val shouldBroadcast: Boolean
get() = true
}
\ No newline at end of file
......@@ -242,7 +242,7 @@ internal class TIMBotNetworkHandler internal constructor(override inline val bot
when (packet) {
is Cancellable -> if ((packet as Cancellable).broadcast(coroutineContext).cancelled) return
is Subscribable -> packet.broadcast(coroutineContext)
is Subscribable -> if ((packet as? BroadcastControllable)?.shouldBroadcast != false) packet.broadcast(coroutineContext)
}
// Remove first to release the lock
......
......@@ -4,12 +4,12 @@ package net.mamoe.mirai.network.protocol.tim.packet.action
import kotlinx.io.core.ByteReadPacket
import kotlinx.io.core.discardExact
import kotlinx.io.core.readUByte
import kotlinx.io.core.readUInt
import kotlinx.io.core.readUShort
import net.mamoe.mirai.contact.QQ
import net.mamoe.mirai.network.BotNetworkHandler
import net.mamoe.mirai.network.protocol.tim.TIMProtocol
import net.mamoe.mirai.network.protocol.tim.packet.*
import net.mamoe.mirai.network.protocol.tim.packet.action.CanAddFriendResponse.State
import net.mamoe.mirai.network.protocol.tim.packet.event.EventPacket
import net.mamoe.mirai.utils.io.*
......@@ -98,49 +98,55 @@ object CanAddFriendPacket : SessionPacketFactory<CanAddFriendResponse>() {
writeQQ(qq)
}
override suspend fun ByteReadPacket.decode(id: PacketId, sequenceId: UShort, handler: BotNetworkHandler<*>): CanAddFriendResponse =
CanAddFriendResponse().apply {
if (remaining > 20) {//todo check
state = State.ALREADY_ADDED
return@apply
}
qq = readUInt()
override suspend fun ByteReadPacket.decode(id: PacketId, sequenceId: UShort, handler: BotNetworkHandler<*>): CanAddFriendResponse = with(handler.bot) {
if (remaining > 20) {//todo check
return CanAddFriendResponse.AlreadyAdded(readUInt().qq())
}
val qq: QQ = readUInt().qq()
state = when (val state = readUShort().toUInt()) {
0x00u -> State.NOT_REQUIRE_VERIFICATION
0x01u -> State.REQUIRE_VERIFICATION//需要验证信息
0x99u -> State.ALREADY_ADDED
return when (val state = readUByte().toUInt()) {
0x00u -> CanAddFriendResponse.ReadyToAdd(qq)
0x01u -> CanAddFriendResponse.RequireVerification(qq)
0x99u -> CanAddFriendResponse.AlreadyAdded(qq)
0x03u,
0x04u -> State.FAILED
else -> throw IllegalStateException(state.toString())
}
0x03u,
0x04u -> CanAddFriendResponse.Rejected(qq)
else -> error(state.toString())
}
}
}
class CanAddFriendResponse : EventPacket {
var qq: UInt = 0u
lateinit var state: State
enum class State {
/**
* 已经添加
*/
ALREADY_ADDED,
/**
* 需要验证信息
*/
REQUIRE_VERIFICATION,
/**
* 不需要验证信息
*/
NOT_REQUIRE_VERIFICATION,
/**
* 对方拒绝添加
*/
FAILED,
}
sealed class CanAddFriendResponse : EventPacket {
abstract val qq: QQ
/**
* 已经添加
*/
data class AlreadyAdded(
override val qq: QQ
) : CanAddFriendResponse()
/**
* 需要验证信息
*/
data class RequireVerification(
override val qq: QQ
) : CanAddFriendResponse()
/**
* 不需要验证信息
*/
data class ReadyToAdd(
override val qq: QQ
) : CanAddFriendResponse()
/**
* 对方拒绝添加
*/
data class Rejected(
override val qq: QQ
) : CanAddFriendResponse()
}
......
......@@ -10,6 +10,7 @@ import net.mamoe.mirai.contact.Contact
import net.mamoe.mirai.contact.Group
import net.mamoe.mirai.contact.MemberPermission
import net.mamoe.mirai.contact.QQ
import net.mamoe.mirai.event.BroadcastControllable
import net.mamoe.mirai.event.events.BotEvent
import net.mamoe.mirai.getGroup
import net.mamoe.mirai.getQQ
......@@ -143,7 +144,12 @@ data class FriendMessage(
val previous: Boolean,
override val sender: QQ,
override val message: MessageChain
) : MessagePacket<QQ>() {
) : MessagePacket<QQ>(), BroadcastControllable {
/**
* 是否应被自动广播. 此为内部 API
*/
override val shouldBroadcast: Boolean get() = !previous
override val subject: QQ get() = sender
}
......
......@@ -7,6 +7,7 @@ import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import net.mamoe.mirai.Bot
import net.mamoe.mirai.BotAccount
import net.mamoe.mirai.addFriend
import net.mamoe.mirai.event.Subscribable
import net.mamoe.mirai.event.subscribeAlways
import net.mamoe.mirai.event.subscribeMessages
......@@ -69,6 +70,10 @@ suspend fun main() {
}
}
startsWith("添加好友", removePrefix = true) {
reply(bot.addFriend(it.toUInt()).toString())
}
}
bot.network.awaitDisconnection()//等到直到断开连接
......
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