Adapt for server time difference, let MessageSource.time refer to server time. Fixes 1519

This commit is contained in:
Him188 2021-09-04 21:30:20 +08:00
parent 5188d88483
commit 238ec52eea
7 changed files with 75 additions and 13 deletions

View File

@ -149,7 +149,8 @@ public sealed class MessageSource : Message, MessageMetadata, ConstrainSingle {
/**
* 发送时间时间戳, 单位为秒.
*
* 时间戳可能来自服务器, 也可能来自 mirai, 且无法保证两者时间同步.
* 2.8.0 , 时间戳为服务器时区 (UTC+8).
* 2.8.0 以前, 时间戳可能来自服务器 (UTC+8), 也可能来自 mirai (本地), 且无法保证两者时间同步.
*/
public abstract val time: Int

View File

@ -0,0 +1,30 @@
/*
* Copyright 2019-2021 Mamoe Technologies and contributors.
*
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
* Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
*
* https://github.com/mamoe/mirai/blob/dev/LICENSE
*/
package net.mamoe.mirai.utils
public interface Clock {
public fun currentTimeMillis(): Long
public fun currentTimeSeconds(): Long
public object SystemDefault : Clock {
override fun currentTimeMillis(): Long = net.mamoe.mirai.utils.currentTimeMillis()
override fun currentTimeSeconds(): Long = net.mamoe.mirai.utils.currentTimeSeconds()
}
}
public fun Clock.adjusted(diffMillis: Long): Clock = AdjustedClock(this, diffMillis)
public class AdjustedClock(
private val clock: Clock,
private val diffMillis: Long,
) : Clock {
override fun currentTimeMillis(): Long = clock.currentTimeMillis() + diffMillis
override fun currentTimeSeconds(): Long = (clock.currentTimeMillis() + diffMillis) / 1000
}

View File

@ -232,6 +232,7 @@ internal open class QQAndroidBot constructor(
return ConcurrentComponentStorage {
set(BotClientHolder, BotClientHolderImpl(bot, networkLogger.subLogger("BotClientHolder")))
set(SyncController, SyncControllerImpl())
set(ClockHolder, ClockHolder())
}.withFallback(defaultBotLevelComponents)
}

View File

@ -19,6 +19,7 @@ import net.mamoe.mirai.internal.getMiraiImpl
import net.mamoe.mirai.internal.message.*
import net.mamoe.mirai.internal.network.Packet
import net.mamoe.mirai.internal.network.QQAndroidClient
import net.mamoe.mirai.internal.network.components.ClockHolder.Companion.clock
import net.mamoe.mirai.internal.network.components.MessageSvcSyncer
import net.mamoe.mirai.internal.network.handler.logger
import net.mamoe.mirai.internal.network.notice.group.GroupMessageProcessor.SendGroupMessageReceipt
@ -399,7 +400,7 @@ internal open class GroupSendMessageHandler(
providedSequenceIds = intArrayOf(receipt.sequenceId),
sender = bot,
target = contact,
time = currentTimeSeconds().toInt(),
time = bot.clock.server.currentTimeSeconds().toInt(),
originalMessage = finalMessage
)
}

View File

@ -0,0 +1,23 @@
/*
* Copyright 2019-2021 Mamoe Technologies and contributors.
*
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
* Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
*
* https://github.com/mamoe/mirai/blob/dev/LICENSE
*/
package net.mamoe.mirai.internal.network.components
import net.mamoe.mirai.internal.QQAndroidBot
import net.mamoe.mirai.internal.network.component.ComponentKey
import net.mamoe.mirai.utils.Clock
internal class ClockHolder {
val local: Clock get() = Clock.SystemDefault
var server: Clock = local
companion object : ComponentKey<ClockHolder> {
val QQAndroidBot.clock get() = components[ClockHolder]
}
}

View File

@ -23,6 +23,7 @@ import net.mamoe.mirai.internal.contact.uin
import net.mamoe.mirai.internal.message.*
import net.mamoe.mirai.internal.network.Packet
import net.mamoe.mirai.internal.network.QQAndroidClient
import net.mamoe.mirai.internal.network.components.ClockHolder.Companion.clock
import net.mamoe.mirai.internal.network.components.SyncController.Companion.syncController
import net.mamoe.mirai.internal.network.components.SyncController.Companion.syncCookie
import net.mamoe.mirai.internal.network.protocol.data.proto.ImMsgBody
@ -35,7 +36,6 @@ import net.mamoe.mirai.internal.network.protocol.packet.buildOutgoingUniPacket
import net.mamoe.mirai.internal.utils.io.serialization.readProtoBuf
import net.mamoe.mirai.internal.utils.io.serialization.writeProtoBuf
import net.mamoe.mirai.message.data.*
import net.mamoe.mirai.utils.currentTimeSeconds
import net.mamoe.mirai.utils.getRandomUnsignedInt
import java.util.concurrent.atomic.AtomicReference
import kotlin.contracts.InvocationKind
@ -215,7 +215,7 @@ internal object MessageSvcPbSendMsg : OutgoingPacketFactory<MessageSvcPbSendMsg.
internalIds = randIds.get(),
sender = client.bot,
target = target,
time = currentTimeSeconds().toInt(),
time = client.bot.clock.server.currentTimeSeconds().toInt(),
sequenceIds = sequenceIds.get(),
originalMessage = message,
),
@ -275,7 +275,7 @@ internal object MessageSvcPbSendMsg : OutgoingPacketFactory<MessageSvcPbSendMsg.
internalIds = randIds.get(),
sender = client.bot,
target = targetFriend,
time = currentTimeSeconds().toInt(),
time = client.bot.clock.server.currentTimeSeconds().toInt(),
sequenceIds = sequenceIds.get(),
originalMessage = message,
),
@ -400,7 +400,7 @@ internal object MessageSvcPbSendMsg : OutgoingPacketFactory<MessageSvcPbSendMsg.
internalIds = randIds.get(),
sender = client.bot,
target = targetGroup,
time = currentTimeSeconds().toInt(),
time = client.bot.clock.server.currentTimeSeconds().toInt(),
originalMessage = message, //,
// sourceMessage = message
),
@ -488,7 +488,7 @@ internal inline fun MessageSvcPbSendMsg.createToTemp(
internalIds = intArrayOf(Random.nextInt().absoluteValue),
sender = client.bot,
target = member,
time = currentTimeSeconds().toInt(),
time = client.bot.clock.server.currentTimeSeconds().toInt(),
sequenceIds = intArrayOf(client.atomicNextMessageSequenceId()),
originalMessage = message,
)

View File

@ -27,9 +27,12 @@ import net.mamoe.mirai.internal.contact.appId
import net.mamoe.mirai.internal.contact.createOtherClient
import net.mamoe.mirai.internal.message.contextualBugReportException
import net.mamoe.mirai.internal.network.*
import net.mamoe.mirai.internal.network.components.ClockHolder
import net.mamoe.mirai.internal.network.components.ContactCacheService
import net.mamoe.mirai.internal.network.components.ContactUpdater
import net.mamoe.mirai.internal.network.components.ServerList
import net.mamoe.mirai.internal.network.getRandomByteArray
import net.mamoe.mirai.internal.network.handler.logger
import net.mamoe.mirai.internal.network.handler.selector.NetworkException
import net.mamoe.mirai.internal.network.impl.netty.HeartbeatFailedException
import net.mamoe.mirai.internal.network.protocol.data.jce.*
@ -41,10 +44,7 @@ import net.mamoe.mirai.internal.utils.NetworkType
import net.mamoe.mirai.internal.utils._miraiContentToString
import net.mamoe.mirai.internal.utils.io.serialization.*
import net.mamoe.mirai.internal.utils.toIpV4Long
import net.mamoe.mirai.utils.BotConfiguration
import net.mamoe.mirai.utils.currentTimeMillis
import net.mamoe.mirai.utils.encodeToString
import net.mamoe.mirai.utils.toReadPacket
import net.mamoe.mirai.utils.*
@Suppress("EnumEntryName", "unused")
internal enum class RegPushReason {
@ -150,11 +150,17 @@ internal class StatSvc {
override suspend fun ByteReadPacket.decode(bot: QQAndroidBot): Response {
val packet = readUniPacket(SvcRespRegister.serializer())
packet.iHelloInterval.let {
return Response(packet)
}
override suspend fun QQAndroidBot.handle(packet: Response) {
packet.origin.iHelloInterval.let {
bot.configuration.statHeartbeatPeriodMillis = it.times(1000).toLong()
}
return Response(packet)
val diffMillis = packet.origin.serverTime - currentTimeMillis()
bot.components[ClockHolder].server = Clock.SystemDefault.adjusted(diffMillis)
bot.network.logger.info { "Server time updated, diff: ${diffMillis}ms=${diffMillis.millisToHumanReadableString()}" }
}
fun online(