Skip to content

Commit e6cea1e

Browse files
authored
Merge pull request #743 from LLOneBot/dev
chore: update version to 7.12.4
2 parents 122da98 + 9bd79af commit e6cea1e

13 files changed

Lines changed: 519 additions & 124 deletions

File tree

doc/更新日志.txt

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,11 @@
1+
V7.12.4
2+
更新时间 2026-04-25
3+
4+
* OneBot 修复发送合并转发包含 `reply` 消息段时可能无法查看合并转发内消息
5+
* OneBot 修复 get_stranger_info API 偶现报错
6+
* Milky 修复临时会话没有上报消息撤回事件
7+
8+
=================
19
V7.12.3
210
更新时间 2026-04-24
311

package-dist.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
{"name":"llonebot-dist","version":"7.12.3","type":"module","description":"","main":"llbot.js","author":"linyuchen","repository":{"type":"git","url":"https://github.com/LLOneBot/LuckyLilliaBot"}}
1+
{"name":"llonebot-dist","version":"7.12.4","type":"module","description":"","main":"llbot.js","author":"linyuchen","repository":{"type":"git","url":"https://github.com/LLOneBot/LuckyLilliaBot"}}

package.json

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -31,15 +31,15 @@
3131
"compare-versions": "^6.1.1",
3232
"cordis": "^4.0.0-rc.3",
3333
"cosmokit": "^1.8.1",
34-
"fast-xml-parser": "^5.7.1",
34+
"fast-xml-parser": "^5.7.2",
3535
"file-type": "^22.0.1",
3636
"fluent-ffmpeg": "^2.1.3",
3737
"get-port": "^7.2.0",
38-
"hono": "^4.12.14",
38+
"hono": "^4.12.15",
3939
"image-size": "^2.0.2",
4040
"json5": "^2.2.3",
4141
"minato": "^4.0.1",
42-
"nodemailer": "^8.0.5",
42+
"nodemailer": "^8.0.6",
4343
"qrcode": "^1.5.4",
4444
"schemastery": "^3.18.0",
4545
"sift": "^17.1.3",
@@ -56,9 +56,9 @@
5656
"ts-case-convert": "^2.1.0",
5757
"tsx": "^4.21.0",
5858
"typescript": "^6.0.3",
59-
"vite": "^8.0.9",
59+
"vite": "^8.0.10",
6060
"vite-plugin-cp": "^6.0.3",
61-
"vitest": "^4.1.4"
61+
"vitest": "^4.1.5"
6262
},
6363
"packageManager": "yarn@4.14.1"
6464
}

src/main/pmhq/mixins/user.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ export function UserMixin<T extends new (...args: any[]) => PMHQBase>(Base: T) {
4040
qid: bytes[27394]?.toString() ?? '',
4141
level: numbers[105],
4242
regTime: numbers[20026] ?? 0,
43-
longNick: bytes[102].toString(),
43+
longNick: bytes[102]?.toString() ?? '',
4444
city: bytes[20020]?.toString() ?? '',
4545
country: bytes[20003]?.toString() ?? '',
4646
birthdayYear: (bytes[20031]?.[0] << 8) | bytes[20031]?.[1],

src/milky/adapter.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import {
2222
transformPrivateMessageEvent,
2323
transformOlpushEvent,
2424
transformTempMessageCreated,
25+
transformTempMessageDeleted,
2526
} from './transform/event'
2627
import { ChatType } from '@/ntqqapi/types'
2728
import { noop } from 'cosmokit'
@@ -165,6 +166,11 @@ export class MilkyAdapter extends Service {
165166
if (eventData) {
166167
this.emitEvent('message_recall', eventData)
167168
}
169+
} else if (message.chatType === ChatType.TempC2CFromGroup) {
170+
const eventData = await transformTempMessageDeleted(this.ctx, message)
171+
if (eventData) {
172+
this.emitEvent('message_recall', eventData)
173+
}
168174
}
169175
})
170176

src/milky/transform/event.ts

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,29 @@ export async function transformTempMessageCreated(
7575
}
7676
}
7777

78+
/**
79+
* Transform NTQQ message-deleted event to Milky message_recall event (temp)
80+
*/
81+
export async function transformTempMessageDeleted(
82+
ctx: Context,
83+
message: RawMessage
84+
): Promise<MilkyEventTypes['message_recall'] | null> {
85+
try {
86+
const revokeElement = message.elements[0].grayTipElement!.revokeElement!
87+
return {
88+
message_scene: 'temp',
89+
peer_id: Number(message.peerUin),
90+
message_seq: Number(message.msgSeq),
91+
sender_id: Number(message.senderUin),
92+
operator_id: Number(message.senderUin),
93+
display_suffix: revokeElement.wording,
94+
}
95+
} catch (error) {
96+
ctx.logger.error('Failed to transform temp message deleted event:', error)
97+
return null
98+
}
99+
}
100+
78101
/**
79102
* Transform NTQQ message-deleted event to Milky message_recall event (private)
80103
*/
@@ -89,7 +112,7 @@ export async function transformPrivateMessageDeleted(
89112
peer_id: Number(message.peerUin),
90113
message_seq: Number(message.msgSeq),
91114
sender_id: Number(message.senderUin),
92-
operator_id: Number(await ctx.ntUserApi.getUinByUid(revokeElement.operatorUid)),
115+
operator_id: Number(message.senderUin),
93116
display_suffix: revokeElement.wording,
94117
}
95118
} catch (error) {
@@ -107,12 +130,18 @@ export async function transformGroupMessageDeleted(
107130
): Promise<MilkyEventTypes['message_recall'] | null> {
108131
try {
109132
const revokeElement = message.elements[0].grayTipElement!.revokeElement!
133+
let operatorUin
134+
if (revokeElement.operatorUid === revokeElement.origMsgSenderUid) {
135+
operatorUin = message.senderUin
136+
} else {
137+
operatorUin = await ctx.ntUserApi.getUinByUid(revokeElement.operatorUid)
138+
}
110139
return {
111140
message_scene: 'group',
112141
peer_id: Number(message.peerUin),
113142
message_seq: Number(message.msgSeq),
114143
sender_id: Number(message.senderUin),
115-
operator_id: Number(await ctx.ntUserApi.getUinByUid(revokeElement.operatorUid)),
144+
operator_id: Number(operatorUin),
116145
display_suffix: revokeElement.wording,
117146
}
118147
} catch (error) {

src/ntqqapi/types/msg.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -396,7 +396,8 @@ export enum FaceIndex {
396396
}
397397

398398
export enum FaceType {
399-
Normal = 1, // 普通小黄脸表情
399+
Old = 1, // 普通小黄脸表情
400+
Normal = 2, // 常规表情
400401
Super = 3, // 超级表情
401402
Poke = 5 // 戳一戳,窗口抖动那种,私聊才有
402403
}

src/onebot11/connect/ws.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ class OB11WebSocket {
7878
if (emitEvent && socket.readyState === WebSocket.OPEN) {
7979
socket.send(JSON.stringify(event))
8080
const eventName = event.getSummaryEventName()
81-
this.ctx.logger.info('WebSocket 事件上报', socket.url ?? '', eventName)
81+
this.ctx.logger.info('WebSocket 事件上报', eventName)
8282
}
8383
})
8484
}
@@ -116,7 +116,7 @@ class OB11WebSocket {
116116
}
117117
socket.send(JSON.stringify(data))
118118
if ('post_type' in data) {
119-
this.ctx.logger.info('WebSocket 事件上报', socket.url ?? '', data.post_type)
119+
this.ctx.logger.info('WebSocket 事件上报', data.post_type)
120120
}
121121
}
122122

src/onebot11/entities.ts

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -268,15 +268,19 @@ export namespace OB11Entities {
268268
): Promise<OB11FriendRecallNoticeEvent | OB11GroupRecallNoticeEvent> {
269269
const revokeElement = msg.elements[0].grayTipElement!.revokeElement!
270270
if (msg.chatType === ChatType.Group) {
271-
const operator = await ctx.ntGroupApi.getGroupMember(msg.peerUid, revokeElement.operatorUid)
272-
let uin = msg.senderUin
273-
if (uin === '0' || !uin) {
274-
uin = await ctx.ntUserApi.getUinByUid(revokeElement.origMsgSenderUid)
271+
let operatorUin
272+
if (revokeElement.operatorUid === revokeElement.origMsgSenderUid) {
273+
operatorUin = msg.senderUin
274+
} else {
275+
operatorUin = await ctx.ntUserApi.getUinByUid(revokeElement.operatorUid)
276+
}
277+
if (msg.senderUin === '0' || !msg.senderUin) {
278+
ctx.logger.warn(`发生异常 senderUin: ${msg.senderUin}`)
275279
}
276280
return new OB11GroupRecallNoticeEvent(
277281
Number(msg.peerUid),
278-
Number(uin),
279-
Number(operator.uin || msg.senderUin),
282+
Number(msg.senderUin),
283+
Number(operatorUin),
280284
shortId,
281285
)
282286
}

src/onebot11/helper/createMultiMessage.ts

Lines changed: 64 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import { OB11MessageData, OB11MessageDataType, OB11MessageNode } from '../types'
33
import { Msg, Media } from '@/ntqqapi/proto'
44
import { handleOb11RichMedia, message2List } from './createMessage'
55
import { selfInfo } from '@/common/globalVars'
6-
import { ChatType, ElementType, Peer, RichMediaUploadCompleteNotify } from '@/ntqqapi/types'
6+
import { ChatType, ElementType, FaceType, Peer, RichMediaUploadCompleteNotify } from '@/ntqqapi/types'
77
import { deflateSync } from 'node:zlib'
88
import faceConfig from '@/ntqqapi/helper/face_config.json'
99
import { InferProtoModelInput } from '@saltify/typeproto'
@@ -16,7 +16,7 @@ import { isNonNullable } from 'cosmokit'
1616
const MAX_FORWARD_DEPTH = 3
1717

1818
export class MessageEncoder {
19-
static support = ['text', 'face', 'image', 'forward', 'node', 'video', 'file', 'at']
19+
static support = ['text', 'face', 'image', 'forward', 'node', 'video', 'file', 'at', 'reply']
2020
results: InferProtoModelInput<typeof Msg.Message>[]
2121
children: InferProtoModelInput<typeof Msg.Elem>[]
2222
content?: Buffer
@@ -414,6 +414,68 @@ export class MessageEncoder {
414414
}
415415
})
416416
this.preview += str
417+
} else if (type === OB11MessageDataType.Reply) {
418+
const msgInfo = await this.ctx.store.getMsgInfoByShortId(+data.id)
419+
if (!msgInfo) {
420+
throw new Error(`消息 ${data.id} 不存在`)
421+
}
422+
const res = await this.ctx.ntMsgApi.getMsgsByMsgId(msgInfo.peer, [msgInfo.msgId])
423+
if (res.msgList.length === 0) {
424+
throw new Error(`无法获取消息 ${data.id} 的内容`)
425+
}
426+
const msg = res.msgList[0]
427+
const elems: InferProtoModelInput<typeof Msg.Elem>[] = []
428+
for (const element of msg.elements) {
429+
if (element.elementType === ElementType.Text) {
430+
elems.push({
431+
text: {
432+
str: element.textElement!.content
433+
}
434+
})
435+
} else if (element.elementType === ElementType.Pic) {
436+
elems.push({
437+
text: {
438+
str: element.picElement!.summary
439+
}
440+
})
441+
} else if (element.elementType === ElementType.Video) {
442+
elems.push({
443+
text: {
444+
str: '[视频]'
445+
}
446+
})
447+
} else if (element.elementType === ElementType.Face) {
448+
const { faceType, faceIndex, faceText } = element.faceElement!
449+
if (faceType === FaceType.Old || faceType === FaceType.Normal) {
450+
elems.push({
451+
face: {
452+
index: faceIndex
453+
}
454+
})
455+
} else {
456+
elems.push({
457+
text: {
458+
str: faceText
459+
}
460+
})
461+
}
462+
} else if (element.elementType === ElementType.File) {
463+
elems.push({
464+
text: {
465+
str: '[文件]'
466+
}
467+
})
468+
}
469+
}
470+
this.children.push({
471+
srcMsg: {
472+
origSeqs: [+msg.msgSeq],
473+
senderUin: +msg.senderUin,
474+
time: +msg.msgTime,
475+
elems: elems.map(e => Msg.Elem.encode(e)),
476+
toUin: 0
477+
}
478+
})
417479
}
418480
}
419481

0 commit comments

Comments
 (0)