Commit 03ca3b5f authored by Him188's avatar Him188

Add Time utils; Remove klock

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