diff --git a/mirai-core-api/src/commonMain/kotlin/message/data/MessageSource.kt b/mirai-core-api/src/commonMain/kotlin/message/data/MessageSource.kt index b8da6eeff..900c358cb 100644 --- a/mirai-core-api/src/commonMain/kotlin/message/data/MessageSource.kt +++ b/mirai-core-api/src/commonMain/kotlin/message/data/MessageSource.kt @@ -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 diff --git a/mirai-core-utils/src/commonMain/kotlin/Clock.kt b/mirai-core-utils/src/commonMain/kotlin/Clock.kt new file mode 100644 index 000000000..3894d3380 --- /dev/null +++ b/mirai-core-utils/src/commonMain/kotlin/Clock.kt @@ -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 +} \ No newline at end of file diff --git a/mirai-core/src/commonMain/kotlin/QQAndroidBot.kt b/mirai-core/src/commonMain/kotlin/QQAndroidBot.kt index efbea31d6..d82e8731a 100644 --- a/mirai-core/src/commonMain/kotlin/QQAndroidBot.kt +++ b/mirai-core/src/commonMain/kotlin/QQAndroidBot.kt @@ -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) } diff --git a/mirai-core/src/commonMain/kotlin/contact/SendMessageHandler.kt b/mirai-core/src/commonMain/kotlin/contact/SendMessageHandler.kt index 22bc3171d..3e5d73adc 100644 --- a/mirai-core/src/commonMain/kotlin/contact/SendMessageHandler.kt +++ b/mirai-core/src/commonMain/kotlin/contact/SendMessageHandler.kt @@ -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 ) } diff --git a/mirai-core/src/commonMain/kotlin/network/components/ClockComponent.kt b/mirai-core/src/commonMain/kotlin/network/components/ClockComponent.kt new file mode 100644 index 000000000..b962acf37 --- /dev/null +++ b/mirai-core/src/commonMain/kotlin/network/components/ClockComponent.kt @@ -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 { + val QQAndroidBot.clock get() = components[ClockHolder] + } +} \ No newline at end of file diff --git a/mirai-core/src/commonMain/kotlin/network/protocol/packet/chat/receive/MessageSvc.PbSendMsg.kt b/mirai-core/src/commonMain/kotlin/network/protocol/packet/chat/receive/MessageSvc.PbSendMsg.kt index bcf57243d..b7eb59066 100644 --- a/mirai-core/src/commonMain/kotlin/network/protocol/packet/chat/receive/MessageSvc.PbSendMsg.kt +++ b/mirai-core/src/commonMain/kotlin/network/protocol/packet/chat/receive/MessageSvc.PbSendMsg.kt @@ -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