MrXiaoM/Overflow

消息中message_id类型解析问题

Closed this issue · 1 comments

问题描述

Onebot V11标准中,message_id的数据类型为number (int32),但是似乎Overflow在回复信息中会将其解析为uint32

复现

我的业务逻辑代码大致如下:

@OptIn(DelicateCoroutinesApi::class)
fun sendGroupsMessage(gm: GroupMessageEvent, message: String) {
    GlobalScope.launch {
        val chain = buildMessageChain {
            gm.message.quote()
            +PlainText(message)
        }
        gm.group.sendMessage(chain)
    }
}
GlobalEventChannel.subscribeAlways<GroupMessageEvent> {
    sendGroupsMessage(it, "XXXX")
}

就是一种通过GroupMessageEvent来回复信息的效果,回复使用者的信息并发送XXXX

大多数情况是正常的,有时候会报错

Onebot的log如下:

2024-04-01 10:27:55 D/Onebot: Client received <-- {"message_type":"group","sub_type":"normal","message_id":-964635551,"group_id":GID,"user_id":UID,"anonymous":null,"message":[{"type":"text","data":{"text":"XXX"}}],"raw_message":"XXX","font":0,"sender":{"user_id":UID,"nickname":"NICK","card":"CARD","sex":"unknown","age":0,"area":"","level":"100","role":"admin","title":""},"time":1711938475,"self_id":BOTID,"post_type":"message"}
2024-04-01 10:27:55 D/Onebot: Send to server --> {"action":"send_group_msg","params":{"group_id":GID,"message":[{"type":"reply","data":{"id":"3330331745"}},{"type":"text","data":{"text":"XXX"}},"auto_escape":false},"echo":264}
2024-04-01 10:27:55 D/Onebot: Client received <-- {"status":"failed","retcode":200,"data":null,"echo":264}

在这段日志实例中,message id -964635551在回复的时候被解析为了3330331745,目测应该是int32被解析为了uint32

Lagrange的日志也证明了这一点,超出int32范围:

warn: Lagrange.OneBot.Core.Operation.OperationService[0]
      Unexpected error encountered while handling message.
      System.OverflowException: Value was either too large or too small for an Int32.
         at System.Number.ThrowOverflowOrFormatException(ParsingStatus status, ReadOnlySpan`1 value, TypeCode type)
         at System.Int32.Parse(String s)
         at Lagrange.OneBot.Message.Entity.ReplySegment.Build(MessageBuilder builder, SegmentBase segment) in {PATH}\Lagrange.OneBot\Message\Entity\ReplySegment.cs:line 27
         at Lagrange.OneBot.Core.Operation.Message.MessageCommon.BuildMessages(MessageBuilder builder, List`1 segments) in {PATH}\Lagrange.OneBot\Core\Operation\Message\MessageCommon.cs:line 215
         at Lagrange.OneBot.Core.Operation.Message.MessageCommon.ParseChain(OneBotGroupMessage message) in {PATH}\Lagrange.OneBot\Core\Operation\Message\MessageCommon.cs:line 143
         at Lagrange.OneBot.Core.Operation.Message.SendGroupMessageOperation.HandleOperation(BotContext context, JsonNode payload) in {PATH}\Lagrange.OneBot\Core\Operation\Message\SendGroupMessageOperation.cs:line 19
         at Lagrange.OneBot.Core.Operation.OperationService.HandleOperation(MsgRecvEventArgs e) in {PATH}\Lagrange.OneBot\Core\Operation\OperationService.cs:line 58

Overflow 版本

213cf4d

其他组件版本

Mirai目录Libs:
mirai-console-2.16.0
mirai-console-terminal-2.16.0-all
overflow-core-all-2.16.0-213cf4d-SNAPSHOT-all
bcprov-jdk15on-1.64

Onebot实现:
Lagrange.OneBot (Commit:62f48c224a683f4721f1c94f58df5468663ac9d1)

系统日志

No response

网络日志

No response

补充信息

目前来说message_id在0到2147483647的时候是正常的,而且大多数message_id都小于2147483647,我这儿也就一个群里出现,因此表现形式是就那个群无法发送,且不清楚这个在OpenShamrock上是不是一样的表现(好像之前在OpenShamrock上没遇到过),因此提issue了

同样的该群的所有带回复的信息也无法获取,目测也是把回复的Reply的message id解析到了uint32(?),Overflow报错如下:

2024-04-01 11:12:54 W/stderr: Exception in thread "DefaultDispatcher-worker-7" java.lang.NumberFormatException: Invalid number format: '-960279562'
2024-04-01 11:12:54 W/stderr:   at kotlin.text.StringsKt__StringNumberConversionsKt.numberFormatError(StringNumberConversions.kt:203)
2024-04-01 11:12:54 W/stderr:   at kotlin.text.UStringsKt.toUInt(UStrings.kt:92)
2024-04-01 11:12:54 W/stderr:   at top.mrxiaom.overflow.internal.message.OnebotMessages.deserializeFromOneBotJson$overflow_core(OnebotMessages.kt:333)
2024-04-01 11:12:54 W/stderr:   at top.mrxiaom.overflow.internal.message.OnebotMessages.deserializeFromOneBot$overflow_core(OnebotMessages.kt:253)
2024-04-01 11:12:54 W/stderr:   at top.mrxiaom.overflow.internal.message.OnebotMessages.deserializeFromOneBot$overflow_core$default(OnebotMessages.kt:251)
2024-04-01 11:12:54 W/stderr:   at top.mrxiaom.overflow.internal.listener.GroupMessageListener.onMessage(group.kt:42)
2024-04-01 11:12:54 W/stderr:   at top.mrxiaom.overflow.internal.listener.GroupMessageListener.onMessage(group.kt:34)
2024-04-01 11:12:54 W/stderr:   at cn.evolvefield.onebot.client.listener.EventListenerKt.message(EventListener.kt:21)
2024-04-01 11:12:54 W/stderr:   at cn.evolvefield.onebot.client.handler.EventBus.onReceive(EventBus.kt:44)
2024-04-01 11:12:54 W/stderr:   at cn.evolvefield.onebot.client.connection.IAdapter$onReceiveMessage$1.invokeSuspend(IAdapter.kt:31)
2024-04-01 11:12:54 W/stderr:   at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
2024-04-01 11:12:54 W/stderr:   at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:106)
2024-04-01 11:12:54 W/stderr:   at kotlinx.coroutines.scheduling.CoroutineScheduler.runSafely(CoroutineScheduler.kt:570)
2024-04-01 11:12:54 W/stderr:   at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.executeTask(CoroutineScheduler.kt:750)
2024-04-01 11:12:54 W/stderr:   at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.runWorker(CoroutineScheduler.kt:677)
2024-04-01 11:12:54 W/stderr:   at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.run(CoroutineScheduler.kt:664)
2024-04-01 11:12:54 W/stderr:   Suppressed: kotlinx.coroutines.DiagnosticCoroutineContextException: [CoroutineName(overflow), StandaloneCoroutine{Cancelling}@2ca510dd, Dispatchers.Default]

刚刚看到代码了:

is QuoteReply -> when { // 忽略分片消息情况
// TODO: 待定,Lagrange.Core 中的 reply id 类型较混乱,写入的时候 uint.ToString(),读取的时候 (uint)int.Parse()
app.contains("lagrange") -> put("id", single.source.ids[0].toUInt().toString())
else -> put("id", single.source.ids[0].toString())
}

val id = when {
app.contains("lagrange") -> data["id"].string.toUInt().toInt()
else -> data["id"].string.toInt()
}

😨要不直接干成long得了,反正两边交互用的json(

既然 Lagrange 读有符号 int32,那把 Lagrange 兼容删掉就行了
另外,id 类型必须为 int,mirai 已经这么定义了,我不想写个缓存表来映射关系

草,把 issues ID 打错了