import type { ParsedDanmu, ParserReply, ParserRequest } from './parser-types' export function getMode(key: number): number { switch (key) { case 1: case 2: case 3: return 0 case 4: return 2 case 5: return 1 default: return 0 } } export function bilibiliDanmuParseFromXml(xmlString: unknown): ParsedDanmu[] { if (typeof xmlString !== 'string') return [] const reg = /]*?p="(?

[^"]+)"[^>]*>(?.*?)<\/d>/gs const matches = xmlString.matchAll(reg) return Array.from(matches) .map((match) => { const attr = match.groups!.p!.split(',') if (attr.length >= 8) { const text = match.groups!.text! .trim() .replaceAll('"', '"') .replaceAll(''', '\'') .replaceAll('<', '<') .replaceAll('>', '>') .replaceAll('&', '&') return { text, time: Number(attr[0]), mode: getMode(Number(attr[1])), fontSize: Number(attr[2]), color: `#${Number(attr[3]).toString(16)}`, timestamp: Number(attr[4]), pool: Number(attr[5]), userID: attr[6]!, rowID: Number(attr[7]), } } else { return null } }) .filter(Boolean) as ParsedDanmu[] } export function onmessage({ data }: MessageEvent) { const { xml, id } = data const danmus = bilibiliDanmuParseFromXml(xml) globalThis.postMessage({ danmus, id } satisfies ParserReply) }