Commit 3a8b2dd6 authored by Him188's avatar Him188

Fix MessageSource.id from offline quotations

parent 7f498604
......@@ -255,6 +255,10 @@ internal class OfflineMessageSourceImplBySourceMsg( // from others' quotation
override val bot: Bot,
groupIdOrZero: Long
) : OfflineMessageSource(), MessageSourceImpl {
init {
println(delegate._miraiContentToString())
}
override val kind: Kind get() = if (delegate.srcMsg == null) Kind.GROUP else Kind.FRIEND
private val isRecalled: AtomicBoolean = atomic(false)
......@@ -276,7 +280,7 @@ internal class OfflineMessageSourceImplBySourceMsg( // from others' quotation
override val id: Int
get() = delegate.pbReserve.loadAs(SourceMsg.ResvAttr.serializer()).origUids?.toInt()
?: error("在读取 OfflineMessageSourceImplBySourceMsg.id 时找不到 origUids, delegate=${delegate._miraiContentToString()}")
?: 0
// override val sourceMessage: MessageChain get() = delegate.toMessageChain()
override val fromId: Long get() = delegate.senderUin
......
......@@ -30,6 +30,7 @@ import net.mamoe.mirai.qqandroid.contact.GroupImpl
import net.mamoe.mirai.qqandroid.contact.QQImpl
import net.mamoe.mirai.qqandroid.contact.singleLine
import net.mamoe.mirai.qqandroid.event.PacketReceivedEvent
import net.mamoe.mirai.qqandroid.network.protocol.data.jce.StTroopNum
import net.mamoe.mirai.qqandroid.network.protocol.data.proto.MsgSvc
import net.mamoe.mirai.qqandroid.network.protocol.packet.*
import net.mamoe.mirai.qqandroid.network.protocol.packet.chat.GroupInfoImpl
......@@ -189,8 +190,7 @@ internal class QQAndroidBotNetworkHandler(bot: QQAndroidBot) : BotNetworkHandler
* Don't use concurrently
*/
suspend fun reloadFriendList() {
// 不要用 fun, 不要 join declaration, 不要用 val, 编译失败警告
logger.info("开始加载好友信息")
logger.info { "开始加载好友信息" }
var currentFriendCount = 0
var totalFriendCount: Short
while (true) {
......@@ -221,6 +221,58 @@ internal class QQAndroidBotNetworkHandler(bot: QQAndroidBot) : BotNetworkHandler
logger.info { "好友列表加载完成, 共 ${currentFriendCount}个" }
}
suspend fun StTroopNum.reloadGroup() {
retryCatching(3) {
bot.groups.delegate.addLast(
@Suppress("DuplicatedCode")
GroupImpl(
bot = bot,
coroutineContext = bot.coroutineContext,
id = groupCode,
groupInfo = bot._lowLevelQueryGroupInfo(groupCode).apply {
this as GroupInfoImpl
if (this.delegate.groupName == null) {
this.delegate.groupName = groupName
}
if (this.delegate.groupMemo == null) {
this.delegate.groupMemo = groupMemo
}
if (this.delegate.groupUin == null) {
this.delegate.groupUin = groupUin
}
this.delegate.groupCode = this@reloadGroup.groupCode
},
members = bot._lowLevelQueryGroupMemberList(
groupUin,
groupCode,
dwGroupOwnerUin
)
)
)
}.getOrThrow()
}
suspend fun reloadGroupList() {
logger.info { "开始加载群组列表与群成员列表" }
val troopListData = FriendList.GetTroopListSimplify(bot.client)
.sendAndExpect<FriendList.GetTroopListSimplify.Response>(retry = 3)
troopListData.groups.chunked(50).forEach { chunk ->
coroutineScope {
chunk.forEach {
launch {
retryCatching(3) { it.reloadGroup() }.getOrThrow()
}
}
}
}
logger.info { "群组列表与群成员加载完成, 共 ${troopListData.groups.size}个" }
}
@OptIn(MiraiExperimentalAPI::class, ExperimentalTime::class)
override suspend fun init(): Unit = coroutineScope {
check(bot.isActive) { "bot is dead therefore network can't init" }
......@@ -236,92 +288,16 @@ internal class QQAndroidBotNetworkHandler(bot: QQAndroidBot) : BotNetworkHandler
_pendingEnabled.value = true
}
supervisorScope {
this.launch { reloadFriendList() }
launch {
try {
logger.info("开始加载群组列表与群成员列表")
val troopListData = FriendList.GetTroopListSimplify(bot.client)
.sendAndExpect<FriendList.GetTroopListSimplify.Response>(retry = 3)
troopListData.groups.chunked(50).forEach { chunk ->
supervisorScope {
chunk.forEach { troopNum ->
// 别用 fun, 别 val, 编译失败警告
lateinit var loadGroup: suspend () -> Unit
loadGroup = suspend {
retryCatching(3) {
bot.groups.delegate.addLast(
@Suppress("DuplicatedCode")
(GroupImpl(
bot = bot,
coroutineContext = bot.coroutineContext,
id = troopNum.groupCode,
groupInfo = bot._lowLevelQueryGroupInfo(troopNum.groupCode).apply {
this as GroupInfoImpl
if (this.delegate.groupName == null) {
this.delegate.groupName = troopNum.groupName
}
if (this.delegate.groupMemo == null) {
this.delegate.groupMemo = troopNum.groupMemo
}
if (this.delegate.groupUin == null) {
this.delegate.groupUin = troopNum.groupUin
}
this.delegate.groupCode = troopNum.groupCode
},
members = bot._lowLevelQueryGroupMemberList(
troopNum.groupUin,
troopNum.groupCode,
troopNum.dwGroupOwnerUin
)
))
)
}.exceptionOrNull()?.let {
logger.error { "群${troopNum.groupCode}的列表拉取失败, 一段时间后将会重试" }
logger.error(it)
this@QQAndroidBotNetworkHandler.launch {
delay(10_000)
loadGroup()
}
}
Unit // 别删, 编译失败警告
}
launch {
loadGroup()
}
}
}
}
logger.info { "群组列表与群成员加载完成, 共 ${troopListData.groups.size}个" }
} catch (e: Exception) {
logger.error { "加载组信息失败|一般这是由于加载过于频繁导致/将以热加载方式加载群列表" }
logger.error(e)
}
}
coroutineScope {
launch { reloadFriendList() }
launch { reloadGroupList() }
}
runCatching {
withTimeoutOrNull(30000) {
lateinit var listener: Listener<PacketReceivedEvent>
listener = this.subscribeAlways {
if (it.packet is MessageSvc.PbGetMsg.GetMsgSuccess) {
listener.complete()
}
}
withTimeoutOrNull(30000) {
launch { subscribingGet<MessageSvc.PbGetMsg.GetMsgSuccess, Unit> { Unit } }
MessageSvc.PbGetMsg(bot.client, MsgSvc.SyncFlag.START, currentTimeSeconds).sendAndExpect<Packet>()
} ?: error("timeout syncing friend message history")
MessageSvc.PbGetMsg(bot.client, MsgSvc.SyncFlag.START, currentTimeSeconds).sendAndExpect<Packet>()
} ?: error("timeout syncing friend message history")
}.exceptionOrNull()?.let {
logger.error("exception while loading syncing friend message history: ${it.message}")
logger.error(it)
}
bot.firstLoginSucceed = true
_pendingEnabled.value = false
......@@ -568,11 +544,7 @@ internal class QQAndroidBotNetworkHandler(bot: QQAndroidBot) : BotNetworkHandler
check(bot.isActive) { "bot is dead therefore can't send any packet" }
check(this@QQAndroidBotNetworkHandler.isActive) { "network is dead therefore can't send any packet" }
logger.verbose("Send: ${this.commandName}")
withContext(this@QQAndroidBotNetworkHandler.coroutineContext + CoroutineName("Packet sender")) {
PacketLogger.debug { "Channel sending: $commandName" }
channel.send(delegate)
PacketLogger.debug { "Channel send done: $commandName" }
}
channel.send(delegate)
}
class TimeoutException(override val message: String?) : Exception()
......@@ -588,19 +560,13 @@ internal class QQAndroidBotNetworkHandler(bot: QQAndroidBot) : BotNetworkHandler
check(this@QQAndroidBotNetworkHandler.isActive) { "network is dead therefore can't send any packet" }
suspend fun doSendAndReceive(handler: PacketListener, data: Any, length: Int): E {
withTimeoutOrNull(3000) {
withContext(this@QQAndroidBotNetworkHandler.coroutineContext + CoroutineName("Packet sender")) {
PacketLogger.debug { "Channel sending: $commandName" }
when (data) {
is ByteArray -> channel.send(data, 0, length)
is ByteReadPacket -> channel.send(data)
else -> error("Internal error: unexpected data type: ${data::class.simpleName}")
}
PacketLogger.debug { "Channel send done: $commandName" }
}
} ?: throw TimeoutException("timeout sending packet $commandName")
when (data) {
is ByteArray -> channel.send(data, 0, length)
is ByteReadPacket -> channel.send(data)
else -> error("Internal error: unexpected data type: ${data::class.simpleName}")
}
logger.verbose("Send done: $commandName")
logger.verbose { "Send done: $commandName" }
@Suppress("UNCHECKED_CAST")
return withTimeoutOrNull(timeoutMillis) {
......
......@@ -23,6 +23,7 @@ import net.mamoe.mirai.contact.Member
import net.mamoe.mirai.contact.MemberPermission
import net.mamoe.mirai.contact.QQ
import net.mamoe.mirai.data.MemberInfo
import net.mamoe.mirai.event.Event
import net.mamoe.mirai.event.events.BotJoinGroupEvent
import net.mamoe.mirai.event.events.BotOfflineEvent
import net.mamoe.mirai.event.events.MemberJoinEvent
......@@ -116,7 +117,8 @@ internal class MessageSvc {
}
@OptIn(MiraiInternalAPI::class)
open class GetMsgSuccess(delegate: List<Packet>) : Response(MsgSvc.SyncFlag.STOP, delegate) {
open class GetMsgSuccess(delegate: List<Packet>) : Response(MsgSvc.SyncFlag.STOP, delegate), Event,
Packet.NoLog {
override fun toString(): String = "MessageSvc.PbGetMsg.GetMsgSuccess(messages=<Iterable>))"
}
......
......@@ -56,6 +56,8 @@ sealed class MessageSource : Message, MessageMetadata, ConstrainSingle<OnlineMes
/**
* 消息 id.
* 当 [OnlineMessageSource] 时为随机数.
* 当 [OfflineMessageSource] 时可能为 0, 取决于服务器是否提供这个值.
*/
abstract val id: Int // random
......@@ -235,7 +237,7 @@ inline fun MessageSource.isAboutGroup(): Boolean {
}
inline fun MessageSource.isAboutTemp(): Boolean {
return when(this) {
return when (this) {
is OnlineMessageSource -> subject is Member
is OfflineMessageSource -> kind == OfflineMessageSource.Kind.TEMP
}
......@@ -302,6 +304,12 @@ abstract class OfflineMessageSource : MessageSource() {
*/
abstract val kind: Kind
/**
* 消息 id.
* 服务器不一定提供 id. 因此此值可能为 0
*/
abstract override val id: Int
// final override fun toString(): String = "OfflineMessageSource(sender=$senderId, target=$targetId)"
}
......
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