NapCatQQ/src/onebot11/cqcode.ts
2024-04-15 00:09:08 +08:00

79 lines
2.1 KiB
TypeScript

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<string, any> = {};
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<typeof from>;
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(data: OB11MessageData) {
const CQCodeEscapeText = (text: string) => {
return text.replace(/&/g, '&amp;')
.replace(/\[/g, '&#91;')
.replace(/\]/g, '&#93;');
};
const CQCodeEscape = (text: string) => {
return text.replace(/&/g, '&amp;')
.replace(/\[/g, '&#91;')
.replace(/\]/g, '&#93;')
.replace(/,/g, '&#44;');
};
if (data.type === 'text') {
return CQCodeEscapeText(data.data.text);
}
let result = '[CQ:' + data.type;
for (const name in data.data) {
const value = data.data[name];
result += `,${name}=${CQCodeEscape(value)}`;
}
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))