feat: 表情包优化

This commit is contained in:
Wxw-Gu
2026-07-27 17:55:11 +08:00
parent e93e4554d7
commit 95e517eca5
2 changed files with 41 additions and 15 deletions
+20 -2
View File
@@ -236,9 +236,27 @@ function listSourceMessages(
: msgType
if ([3, 42, 43, 47, 48, 49, 50, 10000, 10002].includes(inferredMsgType)) {
try {
const parsed =
inferredMsgType === 47
const isQuotePayload = /<refermsg\b/i.test(content)
const hasStickerHints =
/<(?:emoji|sticker|emoticon)\b/i.test(content) ||
[
'emoji_md5',
'emojiMd5',
'emoji_cdn_url',
'emojiCdnUrl',
'packed_info_data',
'packed_info',
'reserved0',
'Reserved0',
'WCDB_CT_reserved0'
].some((key) => Boolean(msg[key]))
const rowSticker =
inferredMsgType === 47 || (inferredMsgType === 49 && !isQuotePayload && hasStickerHints)
? parseStickerMessageFromRow(msg, content)
: undefined
const parsed =
rowSticker?.type === 'sticker'
? rowSticker
: parseMessageContent(content, inferredMsgType)
if (parsed.type === 'system') {
content = parsed.content
+21 -13
View File
@@ -21,6 +21,18 @@ export class StickerService {
const normalizedMd5 = this.normalizeMd5(md5)
let url = String(cdnUrl || '').trim()
const cacheKey =
normalizedMd5 || (url ? crypto.createHash('md5').update(url).digest('hex') : '')
if (cacheKey) {
const cached = await this.readCached(cacheKey)
if (cached) return { success: true, data: cached }
}
if (normalizedMd5 && this.wcdb4Client) {
const wechatCached = await this.readWechatEmoticonCache(normalizedMd5)
if (wechatCached) return { success: true, data: wechatCached }
}
if (!url && normalizedMd5 && this.wcdb4Client) {
url = this.wcdb4Client.resolveEmoticonCdnUrl(normalizedMd5) || ''
if (!url) {
@@ -32,30 +44,26 @@ export class StickerService {
return { success: false, error: '未找到表情包 CDN URL' }
}
const cacheKey = normalizedMd5 || crypto.createHash('md5').update(url).digest('hex')
const cached = await this.readCached(cacheKey)
if (cached) return { success: true, data: cached }
const resolvedCacheKey = cacheKey || crypto.createHash('md5').update(url).digest('hex')
if (normalizedMd5 && this.wcdb4Client) {
const wechatCached = await this.readWechatEmoticonCache(normalizedMd5)
if (wechatCached) return { success: true, data: wechatCached }
}
const pending = downloadCache.get(cacheKey)
const pending = downloadCache.get(resolvedCacheKey)
if (pending) return pending
const task = this.downloadToDataUrl(url, cacheKey)
downloadCache.set(cacheKey, task)
const task = this.downloadToDataUrl(url, resolvedCacheKey)
downloadCache.set(resolvedCacheKey, task)
try {
return await task
} finally {
downloadCache.delete(cacheKey)
downloadCache.delete(resolvedCacheKey)
}
}
private async readCached(cacheKey: string): Promise<string | null> {
const extensions = ['.gif', '.png', '.webp', '.jpg', '.jpeg']
const cacheDirs = [this.cacheDir, path.join(os.homedir(), 'Documents', 'WechatExplorer', 'Emojis')]
const cacheDirs = [
this.cacheDir,
path.join(os.homedir(), 'Documents', 'WechatExplorer', 'Emojis')
]
for (const cacheDir of cacheDirs) {
for (const ext of extensions) {
const filePath = path.join(cacheDir, `${cacheKey}${ext}`)