mirror of
https://github.com/mamoe/mirai.git
synced 2025-03-13 06:30:13 +08:00
Add Time utils; Remove klock
This commit is contained in:
parent
cb083922d8
commit
03ca3b5fd1
@ -72,8 +72,6 @@ kotlin {
|
||||
api(kotlinx("coroutines-core-common", coroutinesVersion))
|
||||
api(kotlinx("serialization-runtime-common", serializationVersion))
|
||||
|
||||
api("com.soywiz.korlibs.klock:klock:$klockVersion")
|
||||
|
||||
api(ktor("http-cio", ktorVersion))
|
||||
api(ktor("http", ktorVersion))
|
||||
api(ktor("client-core-jvm", ktorVersion))
|
||||
|
@ -114,7 +114,7 @@ class Bot(val account: BotAccount, val logger: MiraiLogger, context: CoroutineCo
|
||||
logger.info("Reconnected successfully")
|
||||
return@launch
|
||||
} else {
|
||||
delay(configuration.reconnectPeriod.millisecondsLong)
|
||||
delay(configuration.reconnectPeriodMillis)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2,8 +2,7 @@
|
||||
|
||||
package net.mamoe.mirai.contact
|
||||
|
||||
import com.soywiz.klock.MonthSpan
|
||||
import com.soywiz.klock.TimeSpan
|
||||
import net.mamoe.mirai.utils.*
|
||||
import kotlin.time.Duration
|
||||
import kotlin.time.ExperimentalTime
|
||||
|
||||
@ -26,6 +25,10 @@ interface Member : QQ, Contact {
|
||||
*
|
||||
* @param durationSeconds 持续时间. 精确到秒. 范围区间表示为 `(0s, 30days]`. 超过范围则会抛出异常.
|
||||
* @return 若机器人无权限禁言这个群成员, 返回 `false`
|
||||
*
|
||||
* @see Int.minutesToSeconds
|
||||
* @see Int.hoursToSeconds
|
||||
* @see Int.daysToSeconds
|
||||
*/
|
||||
suspend fun mute(durationSeconds: Int): Boolean
|
||||
|
||||
@ -42,17 +45,6 @@ suspend inline fun Member.mute(duration: Duration): Boolean {
|
||||
return this.mute(duration.inSeconds.toInt())
|
||||
}
|
||||
|
||||
suspend inline fun Member.mute(duration: TimeSpan): Boolean {
|
||||
require(duration.days <= 30) { "duration must be at most 1 month" }
|
||||
require(duration.microseconds > 0) { "duration must be greater than 0 second" }
|
||||
return this.mute(duration.seconds.toInt())
|
||||
}
|
||||
|
||||
suspend inline fun Member.mute(duration: MonthSpan): Boolean {
|
||||
require(duration.totalMonths == 1) { "if you pass a MonthSpan, it must be 1 month" }
|
||||
return this.mute(duration.totalMonths * 30 * 24 * 3600)
|
||||
}
|
||||
|
||||
@ExperimentalUnsignedTypes
|
||||
suspend inline fun Member.mute(durationSeconds: UInt): Boolean {
|
||||
require(durationSeconds.toInt() <= 30 * 24 * 3600) { "duration must be at most 1 month" }
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
package net.mamoe.mirai.contact.data
|
||||
|
||||
import com.soywiz.klock.Date
|
||||
import io.ktor.util.date.GMTDate
|
||||
|
||||
/**
|
||||
* 个人资料
|
||||
@ -17,7 +17,7 @@ data class Profile(
|
||||
val zipCode: String?,
|
||||
val phone: String?,
|
||||
val gender: Gender,
|
||||
val birthday: Date?,
|
||||
val birthday: GMTDate?,
|
||||
val personalStatement: String?,// 个人说明
|
||||
val school: String?,
|
||||
val homepage: String?,
|
||||
|
@ -2,8 +2,6 @@
|
||||
|
||||
package net.mamoe.mirai.network
|
||||
|
||||
import com.soywiz.klock.TimeSpan
|
||||
import com.soywiz.klock.seconds
|
||||
import kotlinx.coroutines.*
|
||||
import kotlinx.io.core.ByteReadPacket
|
||||
import net.mamoe.mirai.*
|
||||
@ -26,16 +24,14 @@ import net.mamoe.mirai.utils.assertUnreachable
|
||||
import net.mamoe.mirai.utils.getGTK
|
||||
import net.mamoe.mirai.utils.internal.PositiveNumbers
|
||||
import net.mamoe.mirai.utils.internal.coerceAtLeastOrFail
|
||||
import net.mamoe.mirai.utils.secondsToMillis
|
||||
import kotlin.coroutines.coroutineContext
|
||||
|
||||
/**
|
||||
* 构造 [BotSession] 的捷径
|
||||
*/
|
||||
@Suppress("FunctionName", "NOTHING_TO_INLINE")
|
||||
internal inline fun TIMBotNetworkHandler.BotSession(
|
||||
sessionKey: SessionKey,
|
||||
socket: DataPacketSocketAdapter
|
||||
): BotSession = BotSession(bot, sessionKey, socket, this)
|
||||
internal inline fun TIMBotNetworkHandler.BotSession(): BotSession = BotSession(bot)
|
||||
|
||||
/**
|
||||
* 登录会话. 当登录完成后, 客户端会拿到 sessionKey.
|
||||
@ -47,10 +43,7 @@ internal inline fun TIMBotNetworkHandler.BotSession(
|
||||
*/
|
||||
@UseExperimental(MiraiInternalAPI::class)
|
||||
expect class BotSession internal constructor(
|
||||
bot: Bot,
|
||||
sessionKey: SessionKey,
|
||||
socket: DataPacketSocketAdapter,
|
||||
NetworkScope: CoroutineScope
|
||||
bot: Bot
|
||||
) : BotSessionBase
|
||||
|
||||
/**
|
||||
@ -59,11 +52,12 @@ expect class BotSession internal constructor(
|
||||
@MiraiInternalAPI
|
||||
// cannot be internal because of `public BotSession`
|
||||
abstract class BotSessionBase internal constructor(
|
||||
val bot: Bot,
|
||||
internal val sessionKey: SessionKey,
|
||||
val socket: DataPacketSocketAdapter,
|
||||
val NetworkScope: CoroutineScope
|
||||
val bot: Bot
|
||||
) {
|
||||
internal val sessionKey: SessionKey get() = bot.sessionKey
|
||||
val socket: DataPacketSocketAdapter get() = bot.network.socket
|
||||
val NetworkScope: CoroutineScope get() = bot.network
|
||||
|
||||
/**
|
||||
* Web api 使用
|
||||
*/
|
||||
@ -79,6 +73,29 @@ abstract class BotSessionBase internal constructor(
|
||||
*/
|
||||
val gtk: Int get() = _gtk
|
||||
|
||||
suspend inline fun Int.qq(): QQ = bot.getQQ(this.coerceAtLeastOrFail(0).toUInt())
|
||||
suspend inline fun Long.qq(): QQ = bot.getQQ(this.coerceAtLeastOrFail(0))
|
||||
suspend inline fun UInt.qq(): QQ = bot.getQQ(this)
|
||||
|
||||
suspend inline fun Int.group(): Group = bot.getGroup(this.coerceAtLeastOrFail(0).toUInt())
|
||||
suspend inline fun Long.group(): Group = bot.getGroup(this.coerceAtLeastOrFail(0))
|
||||
suspend inline fun UInt.group(): Group = bot.getGroup(GroupId(this))
|
||||
suspend inline fun GroupId.group(): Group = bot.getGroup(this)
|
||||
suspend inline fun GroupInternalId.group(): Group = bot.getGroup(this)
|
||||
|
||||
suspend fun Image.getLink(): ImageLink = when (this.id) {
|
||||
is ImageId0x06 -> FriendImagePacket.RequestImageLink(bot.qqAccount, bot.sessionKey, id).sendAndExpect<FriendImageLink>()
|
||||
is ImageId0x03 -> GroupImagePacket.RequestImageLink(bot.qqAccount, bot.sessionKey, id).sendAndExpect<GroupImageLink>().requireSuccess()
|
||||
else -> assertUnreachable()
|
||||
}
|
||||
|
||||
suspend inline fun Image.downloadAsByteArray(): ByteArray = getLink().downloadAsByteArray()
|
||||
suspend inline fun Image.download(): ByteReadPacket = getLink().download()
|
||||
|
||||
|
||||
|
||||
|
||||
// region internal
|
||||
|
||||
@Suppress("PropertyName")
|
||||
internal var _sKey: String = ""
|
||||
@ -115,12 +132,11 @@ abstract class BotSessionBase internal constructor(
|
||||
noinline handler: suspend (P) -> R
|
||||
): Deferred<R> {
|
||||
val deferred: CompletableDeferred<R> = CompletableDeferred(coroutineContext[Job])
|
||||
(bot.network as TIMBotNetworkHandler).addHandler(TemporaryPacketHandler(
|
||||
P::class, deferred, this@BotSessionBase as BotSession, checkSequence, coroutineContext + deferred
|
||||
).also {
|
||||
it.toSend(this)
|
||||
it.onExpect(handler)
|
||||
})
|
||||
(bot.network as TIMBotNetworkHandler)
|
||||
.addHandler(TemporaryPacketHandler(P::class, deferred, this@BotSessionBase as BotSession, checkSequence, coroutineContext + deferred).also {
|
||||
it.toSend(this)
|
||||
it.onExpect(handler)
|
||||
})
|
||||
return deferred
|
||||
}
|
||||
|
||||
@ -129,45 +145,19 @@ abstract class BotSessionBase internal constructor(
|
||||
|
||||
internal suspend inline fun <reified P : Packet, R> OutgoingPacket.sendAndExpect(
|
||||
checkSequence: Boolean = true,
|
||||
timeout: TimeSpan = 5.seconds,
|
||||
timeoutMillis: Long = 5.secondsToMillis,
|
||||
crossinline mapper: (P) -> R
|
||||
): R = withTimeout(timeout.millisecondsLong) { sendAndExpectAsync<P, R>(checkSequence) { mapper(it) }.await() }
|
||||
): R = withTimeout(timeoutMillis) { sendAndExpectAsync<P, R>(checkSequence) { mapper(it) }.await() }
|
||||
|
||||
internal suspend inline fun <reified P : Packet> OutgoingPacket.sendAndExpect(
|
||||
checkSequence: Boolean = true,
|
||||
timeout: TimeSpan = 5.seconds
|
||||
): P = withTimeout(timeout.millisecondsLong) { sendAndExpectAsync<P, P>(checkSequence) { it }.await() }
|
||||
timeoutMillist: Long = 5.secondsToMillis
|
||||
): P = withTimeout(timeoutMillist) { sendAndExpectAsync<P, P>(checkSequence) { it }.await() }
|
||||
|
||||
internal suspend inline fun OutgoingPacket.send() =
|
||||
(socket as TIMBotNetworkHandler.BotSocketAdapter).sendPacket(this)
|
||||
|
||||
|
||||
suspend inline fun Int.qq(): QQ = bot.getQQ(this.coerceAtLeastOrFail(0).toUInt())
|
||||
suspend inline fun Long.qq(): QQ = bot.getQQ(this.coerceAtLeastOrFail(0))
|
||||
suspend inline fun UInt.qq(): QQ = bot.getQQ(this)
|
||||
|
||||
suspend inline fun Int.group(): Group = bot.getGroup(this.coerceAtLeastOrFail(0).toUInt())
|
||||
suspend inline fun Long.group(): Group = bot.getGroup(this.coerceAtLeastOrFail(0))
|
||||
suspend inline fun UInt.group(): Group = bot.getGroup(GroupId(this))
|
||||
suspend inline fun GroupId.group(): Group = bot.getGroup(this)
|
||||
suspend inline fun GroupInternalId.group(): Group = bot.getGroup(this)
|
||||
|
||||
suspend fun Image.getLink(): ImageLink = when (this.id) {
|
||||
is ImageId0x06 -> FriendImagePacket.RequestImageLink(
|
||||
bot.qqAccount,
|
||||
bot.sessionKey,
|
||||
id
|
||||
).sendAndExpect<FriendImageLink>()
|
||||
is ImageId0x03 -> GroupImagePacket.RequestImageLink(
|
||||
bot.qqAccount,
|
||||
bot.sessionKey,
|
||||
id
|
||||
).sendAndExpect<GroupImageLink>().requireSuccess()
|
||||
else -> assertUnreachable()
|
||||
}
|
||||
|
||||
suspend inline fun Image.downloadAsByteArray(): ByteArray = getLink().downloadAsByteArray()
|
||||
suspend inline fun Image.download(): ByteReadPacket = getLink().download()
|
||||
// endregion
|
||||
}
|
||||
|
||||
|
||||
|
@ -20,7 +20,6 @@ import net.mamoe.mirai.network.protocol.tim.handler.TemporaryPacketHandler
|
||||
import net.mamoe.mirai.network.protocol.tim.packet.*
|
||||
import net.mamoe.mirai.network.protocol.tim.packet.login.*
|
||||
import net.mamoe.mirai.qqAccount
|
||||
import net.mamoe.mirai.utils.MiraiInternalAPI
|
||||
import net.mamoe.mirai.utils.OnlineStatus
|
||||
import net.mamoe.mirai.utils.currentBotConfiguration
|
||||
import net.mamoe.mirai.utils.io.*
|
||||
@ -197,7 +196,7 @@ internal class TIMBotNetworkHandler internal constructor(coroutineContext: Corou
|
||||
val expect = expectPacket<TouchPacket.TouchResponse>()
|
||||
launch { processReceive() }
|
||||
launch {
|
||||
if (withTimeoutOrNull(currentBotConfiguration().touchTimeout.millisecondsLong) { expect.join() } == null) {
|
||||
if (withTimeoutOrNull(currentBotConfiguration().touchTimeoutMillis) { expect.join() } == null) {
|
||||
loginResult.complete(LoginResult.TIMEOUT)
|
||||
}
|
||||
}
|
||||
@ -274,7 +273,7 @@ internal class TIMBotNetworkHandler internal constructor(coroutineContext: Corou
|
||||
bot.logger.error("Caught SendPacketInternalException: ${e.cause?.message}")
|
||||
}
|
||||
val configuration = currentBotConfiguration()
|
||||
delay(configuration.firstReconnectDelay.millisecondsLong)
|
||||
delay(configuration.firstReconnectDelayMillis)
|
||||
bot.tryReinitializeNetworkHandler(configuration, e)
|
||||
return@withContext
|
||||
} finally {
|
||||
@ -475,22 +474,22 @@ internal class TIMBotNetworkHandler internal constructor(coroutineContext: Corou
|
||||
BotLoginSucceedEvent(bot).broadcast()
|
||||
|
||||
|
||||
session = BotSession(sessionKey, socket)
|
||||
session = BotSession()
|
||||
|
||||
val configuration = currentBotConfiguration()
|
||||
heartbeatJob = this@TIMBotNetworkHandler.launch {
|
||||
while (socket.isOpen) {
|
||||
delay(configuration.heartbeatPeriod.millisecondsLong)
|
||||
delay(configuration.heartbeatPeriodMillis)
|
||||
with(session) {
|
||||
class HeartbeatTimeoutException : CancellationException("heartbeat timeout")
|
||||
|
||||
if (withTimeoutOrNull(configuration.heartbeatTimeout.millisecondsLong) {
|
||||
if (withTimeoutOrNull(configuration.heartbeatTimeoutMillis) {
|
||||
// FIXME: 2019/11/26 启动被挤掉线检测
|
||||
|
||||
HeartbeatPacket(bot.qqAccount, sessionKey).sendAndExpect<HeartbeatPacketResponse>()
|
||||
} == null) {
|
||||
bot.logger.warning("Heartbeat timed out")
|
||||
delay(configuration.firstReconnectDelay.millisecondsLong)
|
||||
delay(configuration.firstReconnectDelayMillis)
|
||||
bot.tryReinitializeNetworkHandler(configuration, HeartbeatTimeoutException())
|
||||
return@launch
|
||||
}
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
package net.mamoe.mirai.network.protocol.tim.packet.action
|
||||
|
||||
import com.soywiz.klock.Date
|
||||
import io.ktor.util.date.GMTDate
|
||||
import kotlinx.io.core.*
|
||||
import net.mamoe.mirai.contact.data.Gender
|
||||
import net.mamoe.mirai.contact.data.Profile
|
||||
@ -77,7 +77,7 @@ internal object RequestProfileDetailsPacket : SessionPacketFactory<RequestProfil
|
||||
else -> Gender.SECRET // 猜的
|
||||
//else -> error("Cannot determine gender, bad value of 0x4E29u: ${map[0x4729u]!![0].toUHexString()}")
|
||||
},
|
||||
birthday = map[0x4E3Fu]?.let { Date(it.toUInt().toInt()) },
|
||||
birthday = map[0x4E3Fu]?.let { GMTDate(it.toUInt().toLong()) },
|
||||
personalStatement = map[0x4E33u]?.encodeToString(),
|
||||
homepage = map[0x4E2Du]?.encodeToString(),
|
||||
company = map[0x5DC8u]?.encodeToString(),
|
||||
|
@ -2,9 +2,6 @@
|
||||
|
||||
package net.mamoe.mirai.network.protocol.tim.packet.event
|
||||
|
||||
import com.soywiz.klock.TimeSpan
|
||||
import com.soywiz.klock.seconds
|
||||
import com.soywiz.klock.toTimeString
|
||||
import kotlinx.io.core.ByteReadPacket
|
||||
import kotlinx.io.core.discardExact
|
||||
import kotlinx.io.core.readUInt
|
||||
@ -21,28 +18,28 @@ import net.mamoe.mirai.qqAccount
|
||||
@Suppress("unused", "MemberVisibilityCanBePrivate")
|
||||
class MemberMuteEvent(
|
||||
val member: Member,
|
||||
override val duration: TimeSpan,
|
||||
override val durationSeconds: Int,
|
||||
override val operator: Member
|
||||
) : MuteEvent() {
|
||||
override val group: Group get() = operator.group
|
||||
override fun toString(): String = "MemberMuteEvent(member=${member.id}, group=${group.id}, operator=${operator.id}, duration=${duration.toTimeString()}"
|
||||
override fun toString(): String = "MemberMuteEvent(member=${member.id}, group=${group.id}, operator=${operator.id}, duration=${durationSeconds}s"
|
||||
}
|
||||
|
||||
/**
|
||||
* 机器人被禁言事件
|
||||
*/
|
||||
class BeingMutedEvent(
|
||||
override val duration: TimeSpan,
|
||||
override val durationSeconds: Int,
|
||||
override val operator: Member
|
||||
) : MuteEvent() {
|
||||
override val group: Group get() = operator.group
|
||||
override fun toString(): String = "BeingMutedEvent(group=${group.id}, operator=${operator.id}, duration=${duration.toTimeString()}"
|
||||
override fun toString(): String = "BeingMutedEvent(group=${group.id}, operator=${operator.id}, duration=${durationSeconds}s"
|
||||
}
|
||||
|
||||
sealed class MuteEvent : EventOfMute() {
|
||||
abstract override val operator: Member
|
||||
abstract override val group: Group
|
||||
abstract val duration: TimeSpan
|
||||
abstract val durationSeconds: Int
|
||||
}
|
||||
// endregion
|
||||
|
||||
@ -124,12 +121,10 @@ internal object MemberMuteEventPacketParserAndHandler : KnownEventParserAndHandl
|
||||
MemberUnmuteEvent(group.getMember(memberQQ), operator)
|
||||
}
|
||||
} else {
|
||||
val duration = durationSeconds.seconds
|
||||
|
||||
if (memberQQ == bot.qqAccount) {
|
||||
BeingMutedEvent(duration, operator)
|
||||
BeingMutedEvent(durationSeconds, operator)
|
||||
} else {
|
||||
MemberMuteEvent(group.getMember(memberQQ), duration, operator)
|
||||
MemberMuteEvent(group.getMember(memberQQ), durationSeconds, operator)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,5 @@
|
||||
package net.mamoe.mirai.utils
|
||||
|
||||
import com.soywiz.klock.TimeSpan
|
||||
import com.soywiz.klock.seconds
|
||||
import kotlinx.io.core.IoBuffer
|
||||
import net.mamoe.mirai.Bot
|
||||
import net.mamoe.mirai.network.protocol.tim.packet.login.TouchPacket.TouchResponse
|
||||
@ -28,7 +26,7 @@ class BotConfiguration : CoroutineContext.Element {
|
||||
/**
|
||||
* 等待 [TouchResponse] 的时间
|
||||
*/
|
||||
var touchTimeout: TimeSpan = 2.seconds
|
||||
var touchTimeoutMillis: Long = 2.secondsToMillis
|
||||
/**
|
||||
* 是否使用随机的设备名.
|
||||
* 使用随机可以降低被封禁的风险, 但可能导致每次登录都需要输入验证码
|
||||
@ -38,20 +36,20 @@ class BotConfiguration : CoroutineContext.Element {
|
||||
/**
|
||||
* 心跳周期. 过长会导致被服务器断开连接.
|
||||
*/
|
||||
var heartbeatPeriod: TimeSpan = 60.seconds
|
||||
var heartbeatPeriodMillis: Long = 60.secondsToMillis
|
||||
/**
|
||||
* 每次心跳时等待结果的时间.
|
||||
* 一旦心跳超时, 整个网络服务将会重启 (将消耗约 1s). 除正在进行的任务 (如图片上传) 会被中断外, 事件和插件均不受影响.
|
||||
*/
|
||||
var heartbeatTimeout: TimeSpan = 2.seconds
|
||||
var heartbeatTimeoutMillis: Long = 2.secondsToMillis
|
||||
/**
|
||||
* 心跳失败后的第一次重连前的等待时间.
|
||||
*/
|
||||
var firstReconnectDelay: TimeSpan = 5.seconds
|
||||
var firstReconnectDelayMillis: Long = 5.secondsToMillis
|
||||
/**
|
||||
* 重连失败后, 继续尝试的每次等待时间
|
||||
*/
|
||||
var reconnectPeriod: TimeSpan = 60.seconds
|
||||
var reconnectPeriodMillis: Long = 60.secondsToMillis
|
||||
/**
|
||||
* 最多尝试多少次重连
|
||||
*/
|
||||
|
@ -2,13 +2,13 @@
|
||||
|
||||
package net.mamoe.mirai.utils
|
||||
|
||||
import com.soywiz.klock.DateTime
|
||||
import io.ktor.client.HttpClient
|
||||
import io.ktor.util.date.GMTDate
|
||||
|
||||
/**
|
||||
* 时间戳
|
||||
*/
|
||||
inline val currentTime: Long get() = DateTime.nowUnixLong()
|
||||
inline val currentTime: Long get() = GMTDate().timestamp
|
||||
|
||||
/**
|
||||
* 设备名
|
||||
|
@ -0,0 +1,33 @@
|
||||
package net.mamoe.mirai.utils
|
||||
|
||||
import kotlin.time.seconds
|
||||
|
||||
// 临时使用, 待 Kotlin Duration 稳定后使用 Duration.
|
||||
// 内联属性, 则将来删除这些 API 将不会导致二进制不兼容.
|
||||
|
||||
|
||||
inline val Int.secondsToMillis: Long get() = this * 1000L
|
||||
|
||||
inline val Int.minutesToMillis: Long get() = this * 60.secondsToMillis
|
||||
|
||||
inline val Int.hoursToMillis: Long get() = this * 60.minutesToMillis
|
||||
|
||||
inline val Int.daysToMillis: Long get() = this * 24.hoursToMillis
|
||||
|
||||
inline val Int.weeksToMillis: Long get() = this * 7.daysToMillis
|
||||
|
||||
inline val Int.monthsToMillis: Long get() = this * 30.daysToMillis
|
||||
|
||||
|
||||
|
||||
inline val Int.millisToSeconds: Long get() = (this / 1000).toLong()
|
||||
|
||||
inline val Int.minutesToSeconds: Long get() = (this * 60).toLong()
|
||||
|
||||
inline val Int.hoursToSeconds: Long get() = this * 60.minutesToSeconds
|
||||
|
||||
inline val Int.daysToSeconds: Long get() = this * 24.hoursToSeconds
|
||||
|
||||
inline val Int.weeksToSeconds: Long get() = this * 7.daysToSeconds
|
||||
|
||||
inline val Int.monthsToSeconds: Long get() = this * 30.daysToSeconds
|
@ -24,11 +24,8 @@ import javax.imageio.ImageIO
|
||||
@UseExperimental(MiraiInternalAPI::class)
|
||||
@Suppress("unused")
|
||||
actual class BotSession internal actual constructor(
|
||||
bot: Bot,
|
||||
sessionKey: SessionKey,
|
||||
socket: DataPacketSocketAdapter,
|
||||
NetworkScope: CoroutineScope
|
||||
) : BotSessionBase(bot, sessionKey, socket, NetworkScope) {
|
||||
bot: Bot
|
||||
) : BotSessionBase(bot) {
|
||||
|
||||
suspend inline fun Image.downloadAsStream(): InputStream = download().inputStream()
|
||||
suspend inline fun Image.downloadAsBufferedImage(): BufferedImage = withContext(IO) { downloadAsStream().use { ImageIO.read(it) } }
|
||||
|
@ -2,8 +2,6 @@
|
||||
|
||||
package demo.gentleman
|
||||
|
||||
import com.soywiz.klock.months
|
||||
import com.soywiz.klock.seconds
|
||||
import kotlinx.coroutines.Dispatchers.IO
|
||||
import kotlinx.coroutines.GlobalScope
|
||||
import kotlinx.coroutines.delay
|
||||
@ -14,7 +12,6 @@ import net.mamoe.mirai.BotAccount
|
||||
import net.mamoe.mirai.addFriend
|
||||
import net.mamoe.mirai.alsoLogin
|
||||
import net.mamoe.mirai.contact.MemberPermission
|
||||
import net.mamoe.mirai.contact.mute
|
||||
import net.mamoe.mirai.event.Subscribable
|
||||
import net.mamoe.mirai.event.subscribeAlways
|
||||
import net.mamoe.mirai.event.subscribeGroupMessages
|
||||
@ -70,12 +67,12 @@ suspend fun main() {
|
||||
|
||||
startsWith("mt2months") {
|
||||
val at: At by message
|
||||
at.member().mute(1.months)
|
||||
at.member().mute(1)
|
||||
}
|
||||
|
||||
startsWith("mute") {
|
||||
val at: At by message
|
||||
at.member().mute(30.seconds)
|
||||
at.member().mute(30)
|
||||
}
|
||||
|
||||
startsWith("unmute") {
|
||||
|
Loading…
Reference in New Issue
Block a user