import { OB11MessageData } from './types' const pattern = /\[CQ:(\w+)((,\w+=[^,\]]*)*)\]/ function unescape(source: string) { return String(source).replace(/[/g, '[').replace(/]/g, ']').replace(/,/g, ',').replace(/&/g, '&') } function from(source: string) { const capture = pattern.exec(source) if (!capture) return null const [, type, attrs] = capture const data: Record = {} attrs && attrs .slice(1) .split(',') .forEach((str) => { const index = str.indexOf('=') data[str.slice(0, index)] = unescape(str.slice(index + 1)) }) return { type, data, capture } } function h(type: string, data: any) { return { type, data, } } export function decodeCQCode(source: string): OB11MessageData[] { const elements: any[] = [] let result: ReturnType while ((result = from(source))) { const { type, data, capture } = result if (capture.index) { elements.push(h('text', { text: unescape(source.slice(0, capture.index)) })) } elements.push(h(type, data)) source = source.slice(capture.index + capture[0].length) } if (source) elements.push(h('text', { text: unescape(source) })) return elements } export function encodeCQCode(input: OB11MessageData) { const CQCodeEscapeText = (text: string) => { return text.replace(/\&/g, '&').replace(/\[/g, '[').replace(/\]/g, ']') } const CQCodeEscape = (text: string) => { return text.replace(/\&/g, '&').replace(/\[/g, '[').replace(/\]/g, ']').replace(/,/g, ',') } if (input.type === 'text') { return CQCodeEscapeText(input.data.text) } let result = '[CQ:' + input.type for (const [key, value] of Object.entries(input.data)) { if (value === undefined) { continue } try { const text = value.toString() result += `,${key}=${CQCodeEscape(text)}` } catch (error) { // If it can't be converted, skip this key-value pair } } result += ']' return result } // const result = parseCQCode("[CQ:at,qq=114514]早上好啊[CQ:image,file=http://baidu.com/1.jpg,type=show,id=40004]") // const result = parseCQCode("好好好") // console.log(JSON.stringify(result))