style: lint

This commit is contained in:
手瓜一十雪
2024-06-02 20:49:09 +08:00
parent 94f629585a
commit 0ff6edd546
24 changed files with 1678 additions and 1676 deletions

View File

@@ -1,181 +1,182 @@
import { NodeIKernelMsgListener } from "@/core"; import { NodeIKernelMsgListener } from '@/core';
import { NodeIQQNTWrapperSession } from "@/core/wrapper"; import { NodeIQQNTWrapperSession } from '@/core/wrapper';
import { randomUUID } from "crypto"; import { randomUUID } from 'crypto';
interface Internal_MapKey { interface Internal_MapKey {
timeout: number, timeout: number,
createtime: number, createtime: number,
func: Function func: (...arg: any[]) => any,
} }
export class ListenerClassBase { export class ListenerClassBase {
[key: string]: string; [key: string]: string;
} }
export interface ListenerIBase { export interface ListenerIBase {
// eslint-disable-next-line @typescript-eslint/no-misused-new // eslint-disable-next-line @typescript-eslint/no-misused-new
new(listener: any): ListenerClassBase; new(listener: any): ListenerClassBase;
} }
export class NTEventWrapper { export class NTEventWrapper {
private ListenerMap: { [key: string]: ListenerIBase } | undefined;//ListenerName-Unique -> Listener构造函数 private ListenerMap: { [key: string]: ListenerIBase } | undefined;//ListenerName-Unique -> Listener构造函数
private WrapperSession: NodeIQQNTWrapperSession | undefined;//WrapperSession private WrapperSession: NodeIQQNTWrapperSession | undefined;//WrapperSession
private ListenerManger: Map<string, ListenerClassBase> = new Map<string, ListenerClassBase>(); //ListenerName-Unique -> Listener实例 private ListenerManger: Map<string, ListenerClassBase> = new Map<string, ListenerClassBase>(); //ListenerName-Unique -> Listener实例
private EventTask = new Map<string, Map<string, Map<string, Internal_MapKey>>>();//tasks ListenerMainName -> ListenerSubName-> uuid -> {timeout,createtime,func} private EventTask = new Map<string, Map<string, Map<string, Internal_MapKey>>>();//tasks ListenerMainName -> ListenerSubName-> uuid -> {timeout,createtime,func}
constructor() { constructor() {
} }
createProxyDispatch(ListenerMainName: string) { createProxyDispatch(ListenerMainName: string) {
let current = this; // eslint-disable-next-line @typescript-eslint/no-this-alias
return new Proxy({}, { const current = this;
get(target: any, prop: any, receiver: any) { return new Proxy({}, {
// console.log('get', prop, typeof target[prop]); get(target: any, prop: any, receiver: any) {
if (typeof target[prop] === 'undefined') { // console.log('get', prop, typeof target[prop]);
// 如果方法不存在返回一个函数这个函数调用existentMethod if (typeof target[prop] === 'undefined') {
return (...args: any[]) => { // 如果方法不存在返回一个函数这个函数调用existentMethod
current.DispatcherListener.apply(current, [ListenerMainName, prop, ...args]).then(); return (...args: any[]) => {
}; current.DispatcherListener.apply(current, [ListenerMainName, prop, ...args]).then();
} };
// 如果方法存在,正常返回 }
return Reflect.get(target, prop, receiver); // 如果方法存在,正常返回
} return Reflect.get(target, prop, receiver);
}); }
} });
init({ ListenerMap, WrapperSession }: { ListenerMap: { [key: string]: typeof ListenerClassBase }, WrapperSession: NodeIQQNTWrapperSession }) { }
this.ListenerMap = ListenerMap; init({ ListenerMap, WrapperSession }: { ListenerMap: { [key: string]: typeof ListenerClassBase }, WrapperSession: NodeIQQNTWrapperSession }) {
this.WrapperSession = WrapperSession; this.ListenerMap = ListenerMap;
} this.WrapperSession = WrapperSession;
CreatEventFunction<T extends (...args: any) => any>(eventName: string): T | undefined { }
let eventNameArr = eventName.split('/'); CreatEventFunction<T extends (...args: any) => any>(eventName: string): T | undefined {
type eventType = { const eventNameArr = eventName.split('/');
[key: string]: () => { [key: string]: (...params: Parameters<T>) => Promise<ReturnType<T>> } type eventType = {
} [key: string]: () => { [key: string]: (...params: Parameters<T>) => Promise<ReturnType<T>> }
if (eventNameArr.length > 1) { }
let serviceName = 'get' + eventNameArr[0].replace('NodeIKernel', ''); if (eventNameArr.length > 1) {
let eventName = eventNameArr[1]; const serviceName = 'get' + eventNameArr[0].replace('NodeIKernel', '');
//getNodeIKernelGroupListener,GroupService const eventName = eventNameArr[1];
//console.log('2', eventName); //getNodeIKernelGroupListener,GroupService
let services = (this.WrapperSession as unknown as eventType)[serviceName](); //console.log('2', eventName);
let event = services[eventName]; const services = (this.WrapperSession as unknown as eventType)[serviceName]();
//重新绑定this let event = services[eventName];
event = event.bind(services); //重新绑定this
if (event) { event = event.bind(services);
return event as T; if (event) {
} return event as T;
return undefined; }
} return undefined;
}
}
CreatListenerFunction<T>(listenerMainName: string, uniqueCode: string = ""): T { }
let ListenerType = this.ListenerMap![listenerMainName]; CreatListenerFunction<T>(listenerMainName: string, uniqueCode: string = ''): T {
let Listener = this.ListenerManger.get(listenerMainName + uniqueCode); const ListenerType = this.ListenerMap![listenerMainName];
if (!Listener && ListenerType) { let Listener = this.ListenerManger.get(listenerMainName + uniqueCode);
Listener = new ListenerType(this.createProxyDispatch(listenerMainName)); if (!Listener && ListenerType) {
let ServiceSubName = listenerMainName.match(/^NodeIKernel(.*?)Listener$/)![1]; Listener = new ListenerType(this.createProxyDispatch(listenerMainName));
let Service = "NodeIKernel" + ServiceSubName + "Service/addKernel" + ServiceSubName + "Listener"; const ServiceSubName = listenerMainName.match(/^NodeIKernel(.*?)Listener$/)![1];
let addfunc = this.CreatEventFunction<(listener: T) => number>(Service); const Service = 'NodeIKernel' + ServiceSubName + 'Service/addKernel' + ServiceSubName + 'Listener';
addfunc!(Listener as T); const addfunc = this.CreatEventFunction<(listener: T) => number>(Service);
//console.log(addfunc!(Listener as T)); addfunc!(Listener as T);
this.ListenerManger.set(listenerMainName + uniqueCode, Listener); //console.log(addfunc!(Listener as T));
} this.ListenerManger.set(listenerMainName + uniqueCode, Listener);
return Listener as T; }
} return Listener as T;
//统一回调清理事件 }
async DispatcherListener(ListenerMainName: string, ListenerSubName: string, ...args: any[]) { //统一回调清理事件
//console.log(ListenerMainName, this.EventTask.get(ListenerMainName), ListenerSubName, this.EventTask.get(ListenerMainName)?.get(ListenerSubName)); async DispatcherListener(ListenerMainName: string, ListenerSubName: string, ...args: any[]) {
this.EventTask.get(ListenerMainName)?.get(ListenerSubName)?.forEach((task, uuid) => { //console.log(ListenerMainName, this.EventTask.get(ListenerMainName), ListenerSubName, this.EventTask.get(ListenerMainName)?.get(ListenerSubName));
//console.log(task.func, uuid, task.createtime, task.timeout); this.EventTask.get(ListenerMainName)?.get(ListenerSubName)?.forEach((task, uuid) => {
if (task.createtime + task.timeout < Date.now()) { //console.log(task.func, uuid, task.createtime, task.timeout);
this.EventTask.get(ListenerMainName)?.get(ListenerSubName)?.delete(uuid); if (task.createtime + task.timeout < Date.now()) {
return; this.EventTask.get(ListenerMainName)?.get(ListenerSubName)?.delete(uuid);
} return;
task.func(...args); }
}) task.func(...args);
} });
async CallNoListenerEvent<EventType extends (...args: any[]) => Promise<any>,>(EventName = '', timeout: number = 3000, ...args: Parameters<EventType>) { }
return new Promise<ReturnType<EventType>>(async (resolve, reject) => { async CallNoListenerEvent<EventType extends (...args: any[]) => Promise<any>,>(EventName = '', timeout: number = 3000, ...args: Parameters<EventType>) {
let EventFunc = this.CreatEventFunction<EventType>(EventName); return new Promise<ReturnType<EventType>>(async (resolve, reject) => {
let complete = false; const EventFunc = this.CreatEventFunction<EventType>(EventName);
let Timeouter = setTimeout(() => { let complete = false;
if (!complete) { const Timeouter = setTimeout(() => {
reject(new Error('NTEvent EventName:' + EventName + ' timeout')); if (!complete) {
} reject(new Error('NTEvent EventName:' + EventName + ' timeout'));
}, timeout); }
let retData = await EventFunc!(...args); }, timeout);
complete = true; const retData = await EventFunc!(...args);
resolve(retData); complete = true;
}); resolve(retData);
} });
async CallNormalEvent<EventType extends (...args: any[]) => Promise<any>, ListenerType extends (...args: any[]) => void>(EventName = '', ListenerName = '', waitTimes = 1, timeout: number = 3000, ...args: Parameters<EventType>) { }
return new Promise<[EventRet: Awaited<ReturnType<EventType>>, ...Parameters<ListenerType>]>(async (resolve, reject) => { async CallNormalEvent<EventType extends (...args: any[]) => Promise<any>, ListenerType extends (...args: any[]) => void>(EventName = '', ListenerName = '', waitTimes = 1, timeout: number = 3000, ...args: Parameters<EventType>) {
const id = randomUUID(); return new Promise<[EventRet: Awaited<ReturnType<EventType>>, ...Parameters<ListenerType>]>(async (resolve, reject) => {
let complete = 0; const id = randomUUID();
let retData: ArrayLike<Parameters<ListenerType>> | undefined = undefined; let complete = 0;
let retEvent: any = {}; let retData: ArrayLike<Parameters<ListenerType>> | undefined = undefined;
let databack = () => { let retEvent: any = {};
if (complete < waitTimes) { const databack = () => {
reject(new Error('NTEvent EventName:' + EventName + ' ListenerName:' + ListenerName + ' timeout')); if (complete < waitTimes) {
} else { reject(new Error('NTEvent EventName:' + EventName + ' ListenerName:' + ListenerName + ' timeout'));
} else {
resolve([retEvent as Awaited<ReturnType<EventType>>, ...(retData as Parameters<ListenerType>)]);
} resolve([retEvent as Awaited<ReturnType<EventType>>, ...(retData as Parameters<ListenerType>)]);
} }
let Timeouter = setTimeout(databack, timeout); };
const Timeouter = setTimeout(databack, timeout);
let ListenerNameList = ListenerName.split('/');
let ListenerMainName = ListenerNameList[0]; const ListenerNameList = ListenerName.split('/');
let ListenerSubName = ListenerNameList[1]; const ListenerMainName = ListenerNameList[0];
let eventCallbak = { const ListenerSubName = ListenerNameList[1];
timeout: timeout, const eventCallbak = {
createtime: Date.now(), timeout: timeout,
func: (...args: any[]) => { createtime: Date.now(),
complete++; func: (...args: any[]) => {
//console.log('func', ...args); complete++;
retData = args as ArrayLike<Parameters<ListenerType>>; //console.log('func', ...args);
if (complete >= waitTimes) { retData = args as ArrayLike<Parameters<ListenerType>>;
clearTimeout(Timeouter); if (complete >= waitTimes) {
databack(); clearTimeout(Timeouter);
} databack();
} }
} }
if (!this.EventTask.get(ListenerMainName)) { };
this.EventTask.set(ListenerMainName, new Map()); if (!this.EventTask.get(ListenerMainName)) {
} this.EventTask.set(ListenerMainName, new Map());
if (!(this.EventTask.get(ListenerMainName)?.get(ListenerSubName))) { }
this.EventTask.get(ListenerMainName)?.set(ListenerSubName, new Map()); if (!(this.EventTask.get(ListenerMainName)?.get(ListenerSubName))) {
} this.EventTask.get(ListenerMainName)?.set(ListenerSubName, new Map());
this.EventTask.get(ListenerMainName)?.get(ListenerSubName)?.set(id, eventCallbak); }
this.CreatListenerFunction(ListenerMainName); this.EventTask.get(ListenerMainName)?.get(ListenerSubName)?.set(id, eventCallbak);
let EventFunc = this.CreatEventFunction<EventType>(EventName); this.CreatListenerFunction(ListenerMainName);
retEvent = await EventFunc!(...args); const EventFunc = this.CreatEventFunction<EventType>(EventName);
}); retEvent = await EventFunc!(...args);
} });
} }
export const NTEventDispatch = new NTEventWrapper(); }
export const NTEventDispatch = new NTEventWrapper();
// 示例代码 快速创建事件
// let NTEvent = new NTEventWrapper(); // 示例代码 快速创建事件
// let TestEvent = NTEvent.CreatEventFunction<(force: boolean) => Promise<Number>>('NodeIKernelProfileLikeService/GetTest'); // let NTEvent = new NTEventWrapper();
// if (TestEvent) { // let TestEvent = NTEvent.CreatEventFunction<(force: boolean) => Promise<Number>>('NodeIKernelProfileLikeService/GetTest');
// TestEvent(true); // if (TestEvent) {
// } // TestEvent(true);
// }
// 示例代码 快速创建监听Listener类
// let NTEvent = new NTEventWrapper(); // 示例代码 快速创建监听Listener类
// NTEvent.CreatListenerFunction<NodeIKernelMsgListener>('NodeIKernelMsgListener', 'core') // let NTEvent = new NTEventWrapper();
// NTEvent.CreatListenerFunction<NodeIKernelMsgListener>('NodeIKernelMsgListener', 'core')
// 调用接口
//let NTEvent = new NTEventWrapper(); // 调用接口
//let ret = await NTEvent.CallNormalEvent<(force: boolean) => Promise<Number>, (data1: string, data2: number) => void>('NodeIKernelProfileLikeService/GetTest', 'NodeIKernelMsgListener/onAddSendMsg', 1, 3000, true); //let NTEvent = new NTEventWrapper();
//let ret = await NTEvent.CallNormalEvent<(force: boolean) => Promise<Number>, (data1: string, data2: number) => void>('NodeIKernelProfileLikeService/GetTest', 'NodeIKernelMsgListener/onAddSendMsg', 1, 3000, true);
// 注册监听 解除监听
// NTEventDispatch.RigisterListener('NodeIKernelMsgListener/onAddSendMsg','core',cb); // 注册监听 解除监听
// NTEventDispatch.UnRigisterListener('NodeIKernelMsgListener/onAddSendMsg','core'); // NTEventDispatch.RigisterListener('NodeIKernelMsgListener/onAddSendMsg','core',cb);
// NTEventDispatch.UnRigisterListener('NodeIKernelMsgListener/onAddSendMsg','core');
// let GetTest = NTEventDispatch.CreatEvent('NodeIKernelProfileLikeService/GetTest','NodeIKernelMsgListener/onAddSendMsg',Mode);
// GetTest('test'); // let GetTest = NTEventDispatch.CreatEvent('NodeIKernelProfileLikeService/GetTest','NodeIKernelMsgListener/onAddSendMsg',Mode);
// GetTest('test');
// always模式
// always模式
// NTEventDispatch.CreatEvent('NodeIKernelProfileLikeService/GetTest','NodeIKernelMsgListener/onAddSendMsg',Mode,(...args:any[])=>{ console.log(args) }); // NTEventDispatch.CreatEvent('NodeIKernelProfileLikeService/GetTest','NodeIKernelMsgListener/onAddSendMsg',Mode,(...args:any[])=>{ console.log(args) });

View File

@@ -1,145 +1,145 @@
import { logError, logDebug } from "@/common/utils/log"; import { logError, logDebug } from '@/common/utils/log';
type group_id = number; type group_id = number;
type user_id = number; type user_id = number;
class cacheNode<T> { class cacheNode<T> {
value: T; value: T;
groupId: group_id; groupId: group_id;
userId: user_id; userId: user_id;
prev: cacheNode<T> | null; prev: cacheNode<T> | null;
next: cacheNode<T> | null; next: cacheNode<T> | null;
timestamp: number; timestamp: number;
constructor(groupId: group_id, userId: user_id, value: T) { constructor(groupId: group_id, userId: user_id, value: T) {
this.groupId = groupId; this.groupId = groupId;
this.userId = userId; this.userId = userId;
this.value = value; this.value = value;
this.prev = null; this.prev = null;
this.next = null; this.next = null;
this.timestamp = Date.now(); this.timestamp = Date.now();
} }
} }
type cache<T> = { [key: group_id]: { [key: user_id]: cacheNode<T> } }; type cache<T> = { [key: group_id]: { [key: user_id]: cacheNode<T> } };
class LRU<T> { class LRU<T> {
private maxAge: number; private maxAge: number;
private maxSize: number; private maxSize: number;
private currentSize: number; private currentSize: number;
private cache: cache<T>; private cache: cache<T>;
private head: cacheNode<T> | null = null; private head: cacheNode<T> | null = null;
private tail: cacheNode<T> | null = null; private tail: cacheNode<T> | null = null;
private onFuncs: ((node: cacheNode<T>) => void)[] = []; private onFuncs: ((node: cacheNode<T>) => void)[] = [];
constructor(maxAge: number = 2e4, maxSize: number = 5e3) { constructor(maxAge: number = 2e4, maxSize: number = 5e3) {
this.maxAge = maxAge; this.maxAge = maxAge;
this.maxSize = maxSize; this.maxSize = maxSize;
this.cache = Object.create(null); this.cache = Object.create(null);
this.currentSize = 0; this.currentSize = 0;
if (maxSize == 0) return; if (maxSize == 0) return;
setInterval(() => this.removeExpired(), this.maxAge); setInterval(() => this.removeExpired(), this.maxAge);
} }
// 移除LRU节点 // 移除LRU节点
private removeLRUNode(node: cacheNode<T>) { private removeLRUNode(node: cacheNode<T>) {
logDebug( logDebug(
"removeLRUNode", 'removeLRUNode',
node.groupId, node.groupId,
node.userId, node.userId,
node.value, node.value,
this.currentSize this.currentSize
); );
node.prev = node.next = null; node.prev = node.next = null;
delete this.cache[node.groupId][node.userId]; delete this.cache[node.groupId][node.userId];
this.removeNode(node); this.removeNode(node);
this.onFuncs.forEach((func) => func(node)); this.onFuncs.forEach((func) => func(node));
this.currentSize--; this.currentSize--;
} }
public on(func: (node: cacheNode<T>) => void) { public on(func: (node: cacheNode<T>) => void) {
this.onFuncs.push(func); this.onFuncs.push(func);
} }
private removeExpired() { private removeExpired() {
const now = Date.now(); const now = Date.now();
let current = this.tail; let current = this.tail;
const nodesToRemove: cacheNode<T>[] = []; const nodesToRemove: cacheNode<T>[] = [];
let removedCount = 0; let removedCount = 0;
// 收集需要删除的节点 // 收集需要删除的节点
while (current && now - current.timestamp > this.maxAge) { while (current && now - current.timestamp > this.maxAge) {
nodesToRemove.push(current); nodesToRemove.push(current);
current = current.prev; current = current.prev;
removedCount++; removedCount++;
if (removedCount >= 100) break; if (removedCount >= 100) break;
} }
// 更新链表指向 // 更新链表指向
if (nodesToRemove.length > 0) { if (nodesToRemove.length > 0) {
const newTail = nodesToRemove[nodesToRemove.length - 1].prev; const newTail = nodesToRemove[nodesToRemove.length - 1].prev;
if (newTail) { if (newTail) {
newTail.next = null; newTail.next = null;
} else { } else {
this.head = null; this.head = null;
} }
this.tail = newTail; this.tail = newTail;
} }
nodesToRemove.forEach((node) => { nodesToRemove.forEach((node) => {
node.prev = node.next = null; node.prev = node.next = null;
delete this.cache[node.groupId][node.userId]; delete this.cache[node.groupId][node.userId];
this.currentSize--; this.currentSize--;
this.onFuncs.forEach((func) => func(node)); this.onFuncs.forEach((func) => func(node));
}); });
} }
private addNode(node: cacheNode<T>) { private addNode(node: cacheNode<T>) {
node.next = this.head; node.next = this.head;
if (this.head) this.head.prev = node; if (this.head) this.head.prev = node;
if (!this.tail) this.tail = node; if (!this.tail) this.tail = node;
this.head = node; this.head = node;
} }
private removeNode(node: cacheNode<T>) { private removeNode(node: cacheNode<T>) {
if (node.prev) node.prev.next = node.next; if (node.prev) node.prev.next = node.next;
if (node.next) node.next.prev = node.prev; if (node.next) node.next.prev = node.prev;
if (node === this.head) this.head = node.next; if (node === this.head) this.head = node.next;
if (node === this.tail) this.tail = node.prev; if (node === this.tail) this.tail = node.prev;
} }
private moveToHead(node: cacheNode<T>) { private moveToHead(node: cacheNode<T>) {
if (this.head === node) return; if (this.head === node) return;
this.removeNode(node); this.removeNode(node);
this.addNode(node); this.addNode(node);
node.prev = null; node.prev = null;
} }
public set(groupId: group_id, userId: user_id, value: T) { public set(groupId: group_id, userId: user_id, value: T) {
if (!this.cache[groupId]) { if (!this.cache[groupId]) {
this.cache[groupId] = Object.create(null); this.cache[groupId] = Object.create(null);
} }
const groupObject = this.cache[groupId]; const groupObject = this.cache[groupId];
if (groupObject[userId]) { if (groupObject[userId]) {
const node = groupObject[userId]; const node = groupObject[userId];
node.value = value; node.value = value;
node.timestamp = Date.now(); node.timestamp = Date.now();
this.moveToHead(node); this.moveToHead(node);
} else { } else {
const node = new cacheNode(groupId, userId, value); const node = new cacheNode(groupId, userId, value);
groupObject[userId] = node; groupObject[userId] = node;
this.currentSize++; this.currentSize++;
this.addNode(node); this.addNode(node);
if (this.currentSize > this.maxSize) { if (this.currentSize > this.maxSize) {
const tail = this.tail!; const tail = this.tail!;
this.removeLRUNode(tail); this.removeLRUNode(tail);
} }
} }
} }
} }
export default LRU; export default LRU;

File diff suppressed because it is too large Load Diff

View File

@@ -21,6 +21,7 @@ const invalidMacAddresses = new Set([
]); ]);
function validateMacAddress(candidate: string): boolean { function validateMacAddress(candidate: string): boolean {
// eslint-disable-next-line no-useless-escape
const tempCandidate = candidate.replace(/\-/g, ':').toLowerCase(); const tempCandidate = candidate.replace(/\-/g, ':').toLowerCase();
return !invalidMacAddresses.has(tempCandidate); return !invalidMacAddresses.has(tempCandidate);
} }

View File

@@ -14,7 +14,7 @@ export async function checkVersion(): Promise<string> {
try { try {
version = (await RequestUtil.HttpGetJson<{ version: string }>(url)).version; version = (await RequestUtil.HttpGetJson<{ version: string }>(url)).version;
} catch (e) { } catch (e) {
logDebug("检测更新异常",e); logDebug('检测更新异常',e);
} }
if (version) { if (version) {
resolve(version); resolve(version);

View File

@@ -1,46 +1,46 @@
import { DeviceList } from '@/onebot11/main'; import { DeviceList } from '@/onebot11/main';
import BaseAction from '../BaseAction'; import BaseAction from '../BaseAction';
import { ActionName } from '../types'; import { ActionName } from '../types';
import { FromSchema, JSONSchema } from 'json-schema-to-ts'; import { FromSchema, JSONSchema } from 'json-schema-to-ts';
import { checkFileReceived, uri2local } from '@/common/utils/file'; import { checkFileReceived, uri2local } from '@/common/utils/file';
import { NTQQSystemApi } from '@/core'; import { NTQQSystemApi } from '@/core';
import fs from 'fs'; import fs from 'fs';
const SchemaData = { const SchemaData = {
type: 'object', type: 'object',
properties: { properties: {
image: { type: 'string' }, image: { type: 'string' },
}, },
required: ['image'] required: ['image']
} as const satisfies JSONSchema; } as const satisfies JSONSchema;
type Payload = FromSchema<typeof SchemaData>; type Payload = FromSchema<typeof SchemaData>;
export class OCRImage extends BaseAction<Payload, any> { export class OCRImage extends BaseAction<Payload, any> {
actionName = ActionName.OCRImage; actionName = ActionName.OCRImage;
PayloadSchema = SchemaData; PayloadSchema = SchemaData;
protected async _handle(payload: Payload) { protected async _handle(payload: Payload) {
const { path, isLocal, errMsg } = (await uri2local(payload.image)); const { path, isLocal, errMsg } = (await uri2local(payload.image));
if (errMsg) { if (errMsg) {
throw `OCR ${payload.image}失败,image字段可能格式不正确`; throw `OCR ${payload.image}失败,image字段可能格式不正确`;
} }
if (path) { if (path) {
await checkFileReceived(path, 5000); // 文件不存在QQ会崩溃需要提前判断 await checkFileReceived(path, 5000); // 文件不存在QQ会崩溃需要提前判断
const ret = await NTQQSystemApi.ORCImage(path); const ret = await NTQQSystemApi.ORCImage(path);
if (!isLocal) { if (!isLocal) {
fs.unlink(path, () => { }); fs.unlink(path, () => { });
} }
if (!ret) { if (!ret) {
throw `OCR ${payload.file}失败`; throw `OCR ${payload.file}失败`;
} }
return ret.result; return ret.result;
} }
if (!isLocal) { if (!isLocal) {
fs.unlink(path, () => { }); fs.unlink(path, () => { });
} }
throw `OCR ${payload.file}失败,文件可能不存在`; throw `OCR ${payload.file}失败,文件可能不存在`;
} }
} }
export class IOCRImage extends OCRImage { export class IOCRImage extends OCRImage {
actionName = ActionName.IOCRImage; actionName = ActionName.IOCRImage;
} }

View File

@@ -1,23 +1,23 @@
import { FromSchema, JSONSchema } from 'json-schema-to-ts'; import { FromSchema, JSONSchema } from 'json-schema-to-ts';
import BaseAction from '../BaseAction'; import BaseAction from '../BaseAction';
import { ActionName } from '../types'; import { ActionName } from '../types';
import { NTQQGroupApi, NTQQMsgApi, NTQQUserApi } from '@/core/apis'; import { NTQQGroupApi, NTQQMsgApi, NTQQUserApi } from '@/core/apis';
const SchemaData = { const SchemaData = {
type: 'object', type: 'object',
properties: { properties: {
group_id: { type: ['string', 'number'] }, group_id: { type: ['string', 'number'] },
file_id: { type: 'string' }, file_id: { type: 'string' },
}, },
required: ['group_id', 'file_id'] required: ['group_id', 'file_id']
} as const satisfies JSONSchema; } as const satisfies JSONSchema;
type Payload = FromSchema<typeof SchemaData>; type Payload = FromSchema<typeof SchemaData>;
export class DelGroupFile extends BaseAction<Payload, any> { export class DelGroupFile extends BaseAction<Payload, any> {
actionName = ActionName.DelGroupFile; actionName = ActionName.DelGroupFile;
PayloadSchema = SchemaData; PayloadSchema = SchemaData;
protected async _handle(payload: Payload) { protected async _handle(payload: Payload) {
return await NTQQGroupApi.DelGroupFile(payload.group_id.toString(), [payload.file_id]); return await NTQQGroupApi.DelGroupFile(payload.group_id.toString(), [payload.file_id]);
} }
} }

View File

@@ -1,23 +1,23 @@
import { FromSchema, JSONSchema } from 'json-schema-to-ts'; import { FromSchema, JSONSchema } from 'json-schema-to-ts';
import BaseAction from '../BaseAction'; import BaseAction from '../BaseAction';
import { ActionName } from '../types'; import { ActionName } from '../types';
import { NTQQGroupApi, NTQQMsgApi, NTQQUserApi } from '@/core/apis'; import { NTQQGroupApi, NTQQMsgApi, NTQQUserApi } from '@/core/apis';
const SchemaData = { const SchemaData = {
type: 'object', type: 'object',
properties: { properties: {
group_id: { type: ['string', 'number'] }, group_id: { type: ['string', 'number'] },
folder_id: { type: 'string' }, folder_id: { type: 'string' },
}, },
required: ['group_id', 'folder_id'] required: ['group_id', 'folder_id']
} as const satisfies JSONSchema; } as const satisfies JSONSchema;
type Payload = FromSchema<typeof SchemaData>; type Payload = FromSchema<typeof SchemaData>;
export class DelGroupFileFolder extends BaseAction<Payload, any> { export class DelGroupFileFolder extends BaseAction<Payload, any> {
actionName = ActionName.DelGroupFileFolder; actionName = ActionName.DelGroupFileFolder;
PayloadSchema = SchemaData; PayloadSchema = SchemaData;
protected async _handle(payload: Payload) { protected async _handle(payload: Payload) {
return (await NTQQGroupApi.DelGroupFileFolder(payload.group_id.toString(), payload.folder_id)).groupFileCommonResult; return (await NTQQGroupApi.DelGroupFileFolder(payload.group_id.toString(), payload.folder_id)).groupFileCommonResult;
} }
} }

View File

@@ -1,23 +1,23 @@
import { FromSchema, JSONSchema } from 'json-schema-to-ts'; import { FromSchema, JSONSchema } from 'json-schema-to-ts';
import BaseAction from '../BaseAction'; import BaseAction from '../BaseAction';
import { ActionName } from '../types'; import { ActionName } from '../types';
import { NTQQGroupApi, NTQQUserApi } from '@/core/apis'; import { NTQQGroupApi, NTQQUserApi } from '@/core/apis';
const SchemaData = { const SchemaData = {
type: 'object', type: 'object',
properties: { properties: {
group_id: { type: ['string', 'number'] }, group_id: { type: ['string', 'number'] },
}, },
required: ['group_id'] required: ['group_id']
} as const satisfies JSONSchema; } as const satisfies JSONSchema;
type Payload = FromSchema<typeof SchemaData>; type Payload = FromSchema<typeof SchemaData>;
export class GetGroupFileCount extends BaseAction<Payload, { count: number }> { export class GetGroupFileCount extends BaseAction<Payload, { count: number }> {
actionName = ActionName.GetGroupFileCount; actionName = ActionName.GetGroupFileCount;
PayloadSchema = SchemaData; PayloadSchema = SchemaData;
protected async _handle(payload: Payload) { protected async _handle(payload: Payload) {
const ret = await NTQQGroupApi.GetGroupFileCount([payload.group_id?.toString()]); const ret = await NTQQGroupApi.GetGroupFileCount([payload.group_id?.toString()]);
return { count: ret.groupFileCounts[0] }; return { count: ret.groupFileCounts[0] };
} }
} }

View File

@@ -1,31 +1,31 @@
import { FromSchema, JSONSchema } from 'json-schema-to-ts'; import { FromSchema, JSONSchema } from 'json-schema-to-ts';
import BaseAction from '../BaseAction'; import BaseAction from '../BaseAction';
import { ActionName } from '../types'; import { ActionName } from '../types';
import { NTQQGroupApi, NTQQMsgApi, NTQQUserApi } from '@/core/apis'; import { NTQQGroupApi, NTQQMsgApi, NTQQUserApi } from '@/core/apis';
const SchemaData = { const SchemaData = {
type: 'object', type: 'object',
properties: { properties: {
group_id: { type: ['string', 'number'] }, group_id: { type: ['string', 'number'] },
start_index: { type: 'number' }, start_index: { type: 'number' },
file_count: { type: 'number' }, file_count: { type: 'number' },
}, },
required: ['group_id', 'start_index', 'file_count'] required: ['group_id', 'start_index', 'file_count']
} as const satisfies JSONSchema; } as const satisfies JSONSchema;
type Payload = FromSchema<typeof SchemaData>; type Payload = FromSchema<typeof SchemaData>;
export class GetGroupFileList extends BaseAction<Payload, { FileList: Array<any> }> { export class GetGroupFileList extends BaseAction<Payload, { FileList: Array<any> }> {
actionName = ActionName.GetGroupFileList; actionName = ActionName.GetGroupFileList;
PayloadSchema = SchemaData; PayloadSchema = SchemaData;
protected async _handle(payload: Payload) { protected async _handle(payload: Payload) {
let ret = await NTQQMsgApi.getGroupFileList(payload.group_id.toString(), { const ret = await NTQQMsgApi.getGroupFileList(payload.group_id.toString(), {
sortType: 1, sortType: 1,
fileCount: payload.file_count, fileCount: payload.file_count,
startIndex: payload.start_index, startIndex: payload.start_index,
sortOrder: 2, sortOrder: 2,
showOnlinedocFolder: 0 showOnlinedocFolder: 0
}).catch((e) => { return []; }); }).catch((e) => { return []; });
return { FileList: ret }; return { FileList: ret };
} }
} }

View File

@@ -1,23 +1,23 @@
import { FromSchema, JSONSchema } from 'json-schema-to-ts'; import { FromSchema, JSONSchema } from 'json-schema-to-ts';
import BaseAction from '../BaseAction'; import BaseAction from '../BaseAction';
import { ActionName } from '../types'; import { ActionName } from '../types';
import { NTQQGroupApi, NTQQMsgApi, NTQQUserApi } from '@/core/apis'; import { NTQQGroupApi, NTQQMsgApi, NTQQUserApi } from '@/core/apis';
const SchemaData = { const SchemaData = {
type: 'object', type: 'object',
properties: { properties: {
group_id: { type: ['string', 'number'] }, group_id: { type: ['string', 'number'] },
folder_name: { type: 'string' }, folder_name: { type: 'string' },
}, },
required: ['group_id', 'folder_name'] required: ['group_id', 'folder_name']
} as const satisfies JSONSchema; } as const satisfies JSONSchema;
type Payload = FromSchema<typeof SchemaData>; type Payload = FromSchema<typeof SchemaData>;
export class SetGroupFileFolder extends BaseAction<Payload, any> { export class SetGroupFileFolder extends BaseAction<Payload, any> {
actionName = ActionName.SetGroupFileFolder; actionName = ActionName.SetGroupFileFolder;
PayloadSchema = SchemaData; PayloadSchema = SchemaData;
protected async _handle(payload: Payload) { protected async _handle(payload: Payload) {
return (await NTQQGroupApi.CreatGroupFileFolder(payload.group_id.toString(), payload.folder_name)).resultWithGroupItem; return (await NTQQGroupApi.CreatGroupFileFolder(payload.group_id.toString(), payload.folder_name)).resultWithGroupItem;
} }
} }

View File

@@ -1,32 +1,32 @@
import BaseAction from '../BaseAction'; import BaseAction from '../BaseAction';
import { OB11User } from '../../types'; import { OB11User } from '../../types';
import { getUidByUin, uid2UinMap } from '@/core/data'; import { getUidByUin, uid2UinMap } from '@/core/data';
import { OB11Constructor } from '../../constructor'; import { OB11Constructor } from '../../constructor';
import { ActionName } from '../types'; import { ActionName } from '../types';
import { NTQQUserApi } from '@/core/apis/user'; import { NTQQUserApi } from '@/core/apis/user';
import { log, logDebug } from '@/common/utils/log'; import { log, logDebug } from '@/common/utils/log';
import { FromSchema, JSONSchema } from 'json-schema-to-ts'; import { FromSchema, JSONSchema } from 'json-schema-to-ts';
const SchemaData = { const SchemaData = {
type: 'object', type: 'object',
properties: { properties: {
user_id: { type: [ 'number' , 'string' ] }, user_id: { type: [ 'number' , 'string' ] },
}, },
required: ['user_id'] required: ['user_id']
} as const satisfies JSONSchema; } as const satisfies JSONSchema;
type Payload = FromSchema<typeof SchemaData>; type Payload = FromSchema<typeof SchemaData>;
export default class GoCQHTTPGetStrangerInfo extends BaseAction<Payload, OB11User> { export default class GoCQHTTPGetStrangerInfo extends BaseAction<Payload, OB11User> {
actionName = ActionName.GoCQHTTP_GetStrangerInfo; actionName = ActionName.GoCQHTTP_GetStrangerInfo;
protected async _handle(payload: Payload): Promise<OB11User> { protected async _handle(payload: Payload): Promise<OB11User> {
const user_id = payload.user_id.toString(); const user_id = payload.user_id.toString();
//logDebug('uidMaps', uidMaps); //logDebug('uidMaps', uidMaps);
const uid = getUidByUin(user_id); const uid = getUidByUin(user_id);
if (!uid) { if (!uid) {
throw new Error('查无此人'); throw new Error('查无此人');
} }
return OB11Constructor.stranger(await NTQQUserApi.getUserDetailInfo(uid)); return OB11Constructor.stranger(await NTQQUserApi.getUserDetailInfo(uid));
} }
} }

View File

@@ -1,65 +1,65 @@
import { OB11GroupMember } from '../../types'; import { OB11GroupMember } from '../../types';
import { getGroup, getGroupMember, groupMembers } from '@/core/data'; import { getGroup, getGroupMember, groupMembers } from '@/core/data';
import { OB11Constructor } from '../../constructor'; import { OB11Constructor } from '../../constructor';
import BaseAction from '../BaseAction'; import BaseAction from '../BaseAction';
import { ActionName } from '../types'; import { ActionName } from '../types';
import { NTQQUserApi } from '@/core/apis/user'; import { NTQQUserApi } from '@/core/apis/user';
import { log, logDebug } from '@/common/utils/log'; import { log, logDebug } from '@/common/utils/log';
import { isNull } from '../../../common/utils/helper'; import { isNull } from '../../../common/utils/helper';
import { WebApi } from '@/core/apis/webapi'; import { WebApi } from '@/core/apis/webapi';
import { NTQQGroupApi } from '@/core'; import { NTQQGroupApi } from '@/core';
import { FromSchema, JSONSchema } from 'json-schema-to-ts'; import { FromSchema, JSONSchema } from 'json-schema-to-ts';
// no_cache get时传字符串 // no_cache get时传字符串
const SchemaData = { const SchemaData = {
type: 'object', type: 'object',
properties: { properties: {
group_id: { type: ['number', 'string'] }, group_id: { type: ['number', 'string'] },
user_id: { type: ['number', 'string'] }, user_id: { type: ['number', 'string'] },
no_cache: { type: ['boolean', 'string'] }, no_cache: { type: ['boolean', 'string'] },
}, },
required: ['group_id', 'user_id'] required: ['group_id', 'user_id']
} as const satisfies JSONSchema; } as const satisfies JSONSchema;
type Payload = FromSchema<typeof SchemaData>; type Payload = FromSchema<typeof SchemaData>;
class GetGroupMemberInfo extends BaseAction<Payload, OB11GroupMember> { class GetGroupMemberInfo extends BaseAction<Payload, OB11GroupMember> {
actionName = ActionName.GetGroupMemberInfo; actionName = ActionName.GetGroupMemberInfo;
PayloadSchema = SchemaData; PayloadSchema = SchemaData;
protected async _handle(payload: Payload) { protected async _handle(payload: Payload) {
const group = await getGroup(payload.group_id.toString()); const group = await getGroup(payload.group_id.toString());
if (!group) { if (!group) {
throw (`群(${payload.group_id})不存在`); throw (`群(${payload.group_id})不存在`);
} }
const webGroupMembers = await WebApi.getGroupMembers(payload.group_id.toString()); const webGroupMembers = await WebApi.getGroupMembers(payload.group_id.toString());
if (payload.no_cache == true || payload.no_cache === 'true') { if (payload.no_cache == true || payload.no_cache === 'true') {
groupMembers.set(group.groupCode, await NTQQGroupApi.getGroupMembers(payload.group_id.toString())); groupMembers.set(group.groupCode, await NTQQGroupApi.getGroupMembers(payload.group_id.toString()));
} }
const member = await getGroupMember(payload.group_id.toString(), payload.user_id.toString()); const member = await getGroupMember(payload.group_id.toString(), payload.user_id.toString());
// log(member); // log(member);
if (member) { if (member) {
logDebug('获取群成员详细信息'); logDebug('获取群成员详细信息');
try { try {
const info = (await NTQQUserApi.getUserDetailInfo(member.uid)); const info = (await NTQQUserApi.getUserDetailInfo(member.uid));
logDebug('群成员详细信息结果', info); logDebug('群成员详细信息结果', info);
Object.assign(member, info); Object.assign(member, info);
} catch (e) { } catch (e) {
logDebug('获取群成员详细信息失败, 只能返回基础信息', e); logDebug('获取群成员详细信息失败, 只能返回基础信息', e);
} }
const retMember = OB11Constructor.groupMember(payload.group_id.toString(), member); const retMember = OB11Constructor.groupMember(payload.group_id.toString(), member);
for (let i = 0, len = webGroupMembers.length; i < len; i++) { for (let i = 0, len = webGroupMembers.length; i < len; i++) {
if (webGroupMembers[i]?.uin && webGroupMembers[i].uin === retMember.user_id) { if (webGroupMembers[i]?.uin && webGroupMembers[i].uin === retMember.user_id) {
retMember.join_time = webGroupMembers[i]?.join_time; retMember.join_time = webGroupMembers[i]?.join_time;
retMember.last_sent_time = webGroupMembers[i]?.last_speak_time; retMember.last_sent_time = webGroupMembers[i]?.last_speak_time;
retMember.qage = webGroupMembers[i]?.qage; retMember.qage = webGroupMembers[i]?.qage;
retMember.level = webGroupMembers[i]?.lv.level.toString(); retMember.level = webGroupMembers[i]?.lv.level.toString();
} }
} }
return retMember; return retMember;
} else { } else {
throw (`群(${payload.group_id})成员${payload.user_id}不存在`); throw (`群(${payload.group_id})成员${payload.user_id}不存在`);
} }
} }
} }
export default GetGroupMemberInfo; export default GetGroupMemberInfo;

View File

@@ -66,7 +66,7 @@ class GetGroupMemberList extends BaseAction<Payload, OB11GroupMember[]> {
} else if (ob11Config.GroupLocalTime.Record && ob11Config.GroupLocalTime.RecordList[0] === '-1' || ob11Config.GroupLocalTime.RecordList.includes(payload.group_id.toString())) { } else if (ob11Config.GroupLocalTime.Record && ob11Config.GroupLocalTime.RecordList[0] === '-1' || ob11Config.GroupLocalTime.RecordList.includes(payload.group_id.toString())) {
const _sendAndJoinRember = await dbUtil.getLastSentTimeAndJoinTime(TypeConvert.toNumber(payload.group_id)); const _sendAndJoinRember = await dbUtil.getLastSentTimeAndJoinTime(TypeConvert.toNumber(payload.group_id));
_sendAndJoinRember.forEach((element) => { _sendAndJoinRember.forEach((element) => {
let MemberData = MemberMap.get(element.user_id); const MemberData = MemberMap.get(element.user_id);
if (MemberData) { if (MemberData) {
MemberData.join_time = element.join_time; MemberData.join_time = element.join_time;
MemberData.last_sent_time = element.last_sent_time; MemberData.last_sent_time = element.last_sent_time;

View File

@@ -1,155 +1,155 @@
import GetMsg from './msg/GetMsg'; import GetMsg from './msg/GetMsg';
import GetLoginInfo from './system/GetLoginInfo'; import GetLoginInfo from './system/GetLoginInfo';
import GetFriendList from './user/GetFriendList'; import GetFriendList from './user/GetFriendList';
import GetGroupList from './group/GetGroupList'; import GetGroupList from './group/GetGroupList';
import GetGroupInfo from './group/GetGroupInfo'; import GetGroupInfo from './group/GetGroupInfo';
import GetGroupMemberList from './group/GetGroupMemberList'; import GetGroupMemberList from './group/GetGroupMemberList';
import GetGroupMemberInfo from './group/GetGroupMemberInfo'; import GetGroupMemberInfo from './group/GetGroupMemberInfo';
import SendGroupMsg from './group/SendGroupMsg'; import SendGroupMsg from './group/SendGroupMsg';
import SendPrivateMsg from './msg/SendPrivateMsg'; import SendPrivateMsg from './msg/SendPrivateMsg';
import SendMsg from './msg/SendMsg'; import SendMsg from './msg/SendMsg';
import DeleteMsg from './msg/DeleteMsg'; import DeleteMsg from './msg/DeleteMsg';
import BaseAction from './BaseAction'; import BaseAction from './BaseAction';
import GetVersionInfo from './system/GetVersionInfo'; import GetVersionInfo from './system/GetVersionInfo';
import CanSendRecord from './system/CanSendRecord'; import CanSendRecord from './system/CanSendRecord';
import CanSendImage from './system/CanSendImage'; import CanSendImage from './system/CanSendImage';
import GetStatus from './system/GetStatus'; import GetStatus from './system/GetStatus';
import { import {
GoCQHTTPSendForwardMsg, GoCQHTTPSendForwardMsg,
GoCQHTTPSendGroupForwardMsg, GoCQHTTPSendGroupForwardMsg,
GoCQHTTPSendPrivateForwardMsg GoCQHTTPSendPrivateForwardMsg
} from './go-cqhttp/SendForwardMsg'; } from './go-cqhttp/SendForwardMsg';
import GoCQHTTPGetStrangerInfo from './go-cqhttp/GetStrangerInfo'; import GoCQHTTPGetStrangerInfo from './go-cqhttp/GetStrangerInfo';
import SendLike from './user/SendLike'; import SendLike from './user/SendLike';
import SetGroupAddRequest from './group/SetGroupAddRequest'; import SetGroupAddRequest from './group/SetGroupAddRequest';
import SetGroupLeave from './group/SetGroupLeave'; import SetGroupLeave from './group/SetGroupLeave';
import GetGuildList from './group/GetGuildList'; import GetGuildList from './group/GetGuildList';
import Debug from '@/onebot11/action/extends/Debug'; import Debug from '@/onebot11/action/extends/Debug';
import SetFriendAddRequest from './user/SetFriendAddRequest'; import SetFriendAddRequest from './user/SetFriendAddRequest';
import SetGroupWholeBan from './group/SetGroupWholeBan'; import SetGroupWholeBan from './group/SetGroupWholeBan';
import SetGroupName from './group/SetGroupName'; import SetGroupName from './group/SetGroupName';
import SetGroupBan from './group/SetGroupBan'; import SetGroupBan from './group/SetGroupBan';
import SetGroupKick from './group/SetGroupKick'; import SetGroupKick from './group/SetGroupKick';
import SetGroupAdmin from './group/SetGroupAdmin'; import SetGroupAdmin from './group/SetGroupAdmin';
import SetGroupCard from './group/SetGroupCard'; import SetGroupCard from './group/SetGroupCard';
import GetImage from './file/GetImage'; import GetImage from './file/GetImage';
import GetRecord from './file/GetRecord'; import GetRecord from './file/GetRecord';
import { GoCQHTTPMarkMsgAsRead, MarkGroupMsgAsRead, MarkPrivateMsgAsRead } from './msg/MarkMsgAsRead'; import { GoCQHTTPMarkMsgAsRead, MarkGroupMsgAsRead, MarkPrivateMsgAsRead } from './msg/MarkMsgAsRead';
import CleanCache from './system/CleanCache'; import CleanCache from './system/CleanCache';
import GoCQHTTPUploadGroupFile from './go-cqhttp/UploadGroupFile'; import GoCQHTTPUploadGroupFile from './go-cqhttp/UploadGroupFile';
import { GetConfigAction, SetConfigAction } from '@/onebot11/action/extends/Config'; import { GetConfigAction, SetConfigAction } from '@/onebot11/action/extends/Config';
import GetGroupAddRequest from '@/onebot11/action/extends/GetGroupAddRequest'; import GetGroupAddRequest from '@/onebot11/action/extends/GetGroupAddRequest';
import SetQQAvatar from '@/onebot11/action/extends/SetQQAvatar'; import SetQQAvatar from '@/onebot11/action/extends/SetQQAvatar';
import GoCQHTTPDownloadFile from './go-cqhttp/DownloadFile'; import GoCQHTTPDownloadFile from './go-cqhttp/DownloadFile';
import GoCQHTTPGetGroupMsgHistory from './go-cqhttp/GetGroupMsgHistory'; import GoCQHTTPGetGroupMsgHistory from './go-cqhttp/GetGroupMsgHistory';
import GetFile from './file/GetFile'; import GetFile from './file/GetFile';
import { GoCQHTTPGetForwardMsgAction } from './go-cqhttp/GetForwardMsg'; import { GoCQHTTPGetForwardMsgAction } from './go-cqhttp/GetForwardMsg';
import GetFriendMsgHistory from './go-cqhttp/GetFriendMsgHistory'; import GetFriendMsgHistory from './go-cqhttp/GetFriendMsgHistory';
import { GetCookies } from './user/GetCookies'; import { GetCookies } from './user/GetCookies';
import { SetMsgEmojiLike } from '@/onebot11/action/msg/SetMsgEmojiLike'; import { SetMsgEmojiLike } from '@/onebot11/action/msg/SetMsgEmojiLike';
import { GetRobotUinRange } from './extends/GetRobotUinRange'; import { GetRobotUinRange } from './extends/GetRobotUinRange';
import { SetOnlineStatus } from './extends/SetOnlineStatus'; import { SetOnlineStatus } from './extends/SetOnlineStatus';
import { GetGroupNotice } from './group/GetGroupNotice'; import { GetGroupNotice } from './group/GetGroupNotice';
import { GetGroupEssence } from './group/GetGroupEssence'; import { GetGroupEssence } from './group/GetGroupEssence';
import { ForwardFriendSingleMsg, ForwardGroupSingleMsg } from '@/onebot11/action/msg/ForwardSingleMsg'; import { ForwardFriendSingleMsg, ForwardGroupSingleMsg } from '@/onebot11/action/msg/ForwardSingleMsg';
import { GetFriendWithCategory } from './extends/GetFriendWithCategory'; import { GetFriendWithCategory } from './extends/GetFriendWithCategory';
import { SendGroupNotice } from './go-cqhttp/SendGroupNotice'; import { SendGroupNotice } from './go-cqhttp/SendGroupNotice';
import { Reboot, RebootNormol } from './system/Reboot'; import { Reboot, RebootNormol } from './system/Reboot';
import { GetGroupHonorInfo } from './go-cqhttp/GetGroupHonorInfo'; import { GetGroupHonorInfo } from './go-cqhttp/GetGroupHonorInfo';
import { GoCQHTTPHandleQuickAction } from './go-cqhttp/QuickAction'; import { GoCQHTTPHandleQuickAction } from './go-cqhttp/QuickAction';
import { GetGroupSystemMsg } from './group/GetGroupSystemMsg'; import { GetGroupSystemMsg } from './group/GetGroupSystemMsg';
import { GetOnlineClient } from './go-cqhttp/GetOnlineClient'; import { GetOnlineClient } from './go-cqhttp/GetOnlineClient';
import { IOCRImage, OCRImage } from './extends/OCRImage'; import { IOCRImage, OCRImage } from './extends/OCRImage';
import { GetGroupFileCount } from './file/GetGroupFileCount'; import { GetGroupFileCount } from './file/GetGroupFileCount';
import { GetGroupFileList } from './file/GetGroupFileList'; import { GetGroupFileList } from './file/GetGroupFileList';
import { TranslateEnWordToZn } from './extends/TranslateEnWordToZn'; import { TranslateEnWordToZn } from './extends/TranslateEnWordToZn';
import { SetGroupFileFolder } from './file/SetGroupFileFolder'; import { SetGroupFileFolder } from './file/SetGroupFileFolder';
import { DelGroupFile } from './file/DelGroupFile'; import { DelGroupFile } from './file/DelGroupFile';
import { DelGroupFileFolder } from './file/DelGroupFileFolder'; import { DelGroupFileFolder } from './file/DelGroupFileFolder';
export const actionHandlers = [ export const actionHandlers = [
new RebootNormol(), new RebootNormol(),
new GetFile(), new GetFile(),
new Debug(), new Debug(),
new Reboot(), new Reboot(),
// new GetConfigAction(), // new GetConfigAction(),
// new SetConfigAction(), // new SetConfigAction(),
// new GetGroupAddRequest(), // new GetGroupAddRequest(),
// TranslateEnWordToZn = "translate_en2zh", // TranslateEnWordToZn = "translate_en2zh",
new ForwardFriendSingleMsg(), new ForwardFriendSingleMsg(),
new ForwardGroupSingleMsg(), new ForwardGroupSingleMsg(),
new MarkGroupMsgAsRead(), new MarkGroupMsgAsRead(),
new MarkPrivateMsgAsRead(), new MarkPrivateMsgAsRead(),
new SetQQAvatar(), new SetQQAvatar(),
new TranslateEnWordToZn(), new TranslateEnWordToZn(),
new GetGroupFileCount(), new GetGroupFileCount(),
new GetGroupFileList(), new GetGroupFileList(),
new SetGroupFileFolder(), new SetGroupFileFolder(),
new DelGroupFile(), new DelGroupFile(),
new DelGroupFileFolder(), new DelGroupFileFolder(),
// onebot11 // onebot11
new SendLike(), new SendLike(),
new GetMsg(), new GetMsg(),
new GetLoginInfo(), new GetLoginInfo(),
new GetFriendList(), new GetFriendList(),
new GetGroupList(), new GetGroupInfo(), new GetGroupList(), new GetGroupInfo(),
new GetGroupMemberList(), new GetGroupMemberInfo(), new GetGroupMemberList(), new GetGroupMemberInfo(),
new SendGroupMsg(), new SendPrivateMsg(), new SendMsg(), new SendGroupMsg(), new SendPrivateMsg(), new SendMsg(),
new DeleteMsg(), new DeleteMsg(),
new SetGroupAddRequest(), new SetGroupAddRequest(),
new SetFriendAddRequest(), new SetFriendAddRequest(),
new SetGroupLeave(), new SetGroupLeave(),
new GetVersionInfo(), new GetVersionInfo(),
new CanSendRecord(), new CanSendRecord(),
new CanSendImage(), new CanSendImage(),
new GetStatus(), new GetStatus(),
new SetGroupWholeBan(), new SetGroupWholeBan(),
new SetGroupBan(), new SetGroupBan(),
new SetGroupKick(), new SetGroupKick(),
new SetGroupAdmin(), new SetGroupAdmin(),
new SetGroupName(), new SetGroupName(),
new SetGroupCard(), new SetGroupCard(),
new GetImage(), new GetImage(),
new GetRecord(), new GetRecord(),
new SetMsgEmojiLike(), new SetMsgEmojiLike(),
// new CleanCache(), // new CleanCache(),
new GetCookies(), new GetCookies(),
// //
new SetOnlineStatus(), new SetOnlineStatus(),
new GetRobotUinRange(), new GetRobotUinRange(),
new GetFriendWithCategory(), new GetFriendWithCategory(),
//以下为go-cqhttp api //以下为go-cqhttp api
new GetOnlineClient(), new GetOnlineClient(),
new OCRImage(), new OCRImage(),
new IOCRImage(), new IOCRImage(),
new GetGroupHonorInfo(), new GetGroupHonorInfo(),
new SendGroupNotice(), new SendGroupNotice(),
new GetGroupNotice(), new GetGroupNotice(),
new GetGroupEssence(), new GetGroupEssence(),
new GoCQHTTPSendForwardMsg(), new GoCQHTTPSendForwardMsg(),
new GoCQHTTPSendGroupForwardMsg(), new GoCQHTTPSendGroupForwardMsg(),
new GoCQHTTPSendPrivateForwardMsg(), new GoCQHTTPSendPrivateForwardMsg(),
new GoCQHTTPGetStrangerInfo(), new GoCQHTTPGetStrangerInfo(),
new GoCQHTTPDownloadFile(), new GoCQHTTPDownloadFile(),
new GetGuildList(), new GetGuildList(),
new GoCQHTTPMarkMsgAsRead(), new GoCQHTTPMarkMsgAsRead(),
new GoCQHTTPUploadGroupFile(), new GoCQHTTPUploadGroupFile(),
new GoCQHTTPGetGroupMsgHistory(), new GoCQHTTPGetGroupMsgHistory(),
new GoCQHTTPGetForwardMsgAction(), new GoCQHTTPGetForwardMsgAction(),
new GetFriendMsgHistory(), new GetFriendMsgHistory(),
new GoCQHTTPHandleQuickAction(), new GoCQHTTPHandleQuickAction(),
new GetGroupSystemMsg() new GetGroupSystemMsg()
]; ];
function initActionMap() { function initActionMap() {
const actionMap = new Map<string, BaseAction<any, any>>(); const actionMap = new Map<string, BaseAction<any, any>>();
for (const action of actionHandlers) { for (const action of actionHandlers) {
actionMap.set(action.actionName, action); actionMap.set(action.actionName, action);
actionMap.set(action.actionName + '_async', action); actionMap.set(action.actionName + '_async', action);
actionMap.set(action.actionName + '_rate_limited', action); actionMap.set(action.actionName + '_rate_limited', action);
} }
return actionMap; return actionMap;
} }
export const actionMap = initActionMap(); export const actionMap = initActionMap();

View File

@@ -1,62 +1,62 @@
import BaseAction from '../BaseAction'; import BaseAction from '../BaseAction';
import { NTQQMsgApi } from '@/core/apis'; import { NTQQMsgApi } from '@/core/apis';
import { ChatType, Peer } from '@/core/entities'; import { ChatType, Peer } from '@/core/entities';
import { dbUtil } from '@/common/utils/db'; import { dbUtil } from '@/common/utils/db';
import { getUidByUin } from '@/core/data'; import { getUidByUin } from '@/core/data';
import { ActionName } from '../types'; import { ActionName } from '../types';
import { FromSchema, JSONSchema } from 'json-schema-to-ts'; import { FromSchema, JSONSchema } from 'json-schema-to-ts';
const SchemaData = { const SchemaData = {
type: 'object', type: 'object',
properties: { properties: {
message_id: { type: 'number' }, message_id: { type: 'number' },
group_id: { type: [ 'number' , 'string' ] }, group_id: { type: [ 'number' , 'string' ] },
user_id: { type: [ 'number' , 'string' ] } user_id: { type: [ 'number' , 'string' ] }
}, },
required: ['message_id'] required: ['message_id']
} as const satisfies JSONSchema; } as const satisfies JSONSchema;
type Payload = FromSchema<typeof SchemaData>; type Payload = FromSchema<typeof SchemaData>;
class ForwardSingleMsg extends BaseAction<Payload, null> { class ForwardSingleMsg extends BaseAction<Payload, null> {
protected async getTargetPeer(payload: Payload): Promise<Peer> { protected async getTargetPeer(payload: Payload): Promise<Peer> {
if (payload.user_id) { if (payload.user_id) {
const peerUid = getUidByUin(payload.user_id.toString()); const peerUid = getUidByUin(payload.user_id.toString());
if (!peerUid) { if (!peerUid) {
throw new Error(`无法找到私聊对象${payload.user_id}`); throw new Error(`无法找到私聊对象${payload.user_id}`);
} }
return { chatType: ChatType.friend, peerUid }; return { chatType: ChatType.friend, peerUid };
} }
return { chatType: ChatType.group, peerUid: payload.group_id!.toString() }; return { chatType: ChatType.group, peerUid: payload.group_id!.toString() };
} }
protected async _handle(payload: Payload): Promise<null> { protected async _handle(payload: Payload): Promise<null> {
const msg = await dbUtil.getMsgByShortId(payload.message_id); const msg = await dbUtil.getMsgByShortId(payload.message_id);
if (!msg) { if (!msg) {
throw new Error(`无法找到消息${payload.message_id}`); throw new Error(`无法找到消息${payload.message_id}`);
} }
const peer = await this.getTargetPeer(payload); const peer = await this.getTargetPeer(payload);
const ret = await NTQQMsgApi.forwardMsg( const ret = await NTQQMsgApi.forwardMsg(
{ {
chatType: msg.chatType, chatType: msg.chatType,
peerUid: msg.peerUid, peerUid: msg.peerUid,
}, },
peer, peer,
[msg.msgId], [msg.msgId],
); );
if (ret.result !== 0) { if (ret.result !== 0) {
throw new Error(`转发消息失败 ${ret.errMsg}`); throw new Error(`转发消息失败 ${ret.errMsg}`);
} }
return null; return null;
} }
} }
export class ForwardFriendSingleMsg extends ForwardSingleMsg { export class ForwardFriendSingleMsg extends ForwardSingleMsg {
PayloadSchema = SchemaData; PayloadSchema = SchemaData;
actionName = ActionName.ForwardFriendSingleMsg; actionName = ActionName.ForwardFriendSingleMsg;
} }
export class ForwardGroupSingleMsg extends ForwardSingleMsg { export class ForwardGroupSingleMsg extends ForwardSingleMsg {
PayloadSchema = SchemaData; PayloadSchema = SchemaData;
actionName = ActionName.ForwardGroupSingleMsg; actionName = ActionName.ForwardGroupSingleMsg;
} }

View File

@@ -1,252 +1,252 @@
import { OB11MessageData, OB11MessageDataType, OB11MessageFileBase } from '@/onebot11/types'; import { OB11MessageData, OB11MessageDataType, OB11MessageFileBase } from '@/onebot11/types';
import { import {
AtType, AtType,
CustomMusicSignPostData, CustomMusicSignPostData,
Group, Group,
IdMusicSignPostData, IdMusicSignPostData,
NTQQFileApi, NTQQFileApi,
SendArkElement, SendArkElement,
SendMessageElement, SendMessageElement,
SendMsgElementConstructor SendMsgElementConstructor
} from '@/core'; } from '@/core';
import { getGroupMember } from '@/core/data'; import { getGroupMember } from '@/core/data';
import { dbUtil } from '@/common/utils/db'; import { dbUtil } from '@/common/utils/db';
import { logDebug, logError } from '@/common/utils/log'; import { logDebug, logError } from '@/common/utils/log';
import { uri2local } from '@/common/utils/file'; import { uri2local } from '@/common/utils/file';
import { ob11Config } from '@/onebot11/config'; import { ob11Config } from '@/onebot11/config';
import { RequestUtil } from '@/common/utils/request'; import { RequestUtil } from '@/common/utils/request';
import fs from 'node:fs'; import fs from 'node:fs';
export type MessageContext = { export type MessageContext = {
group?: Group, group?: Group,
deleteAfterSentFiles: string[], deleteAfterSentFiles: string[],
} }
async function handleOb11FileLikeMessage( async function handleOb11FileLikeMessage(
{ data: { file, name: payloadFileName } }: OB11MessageFileBase, { data: { file, name: payloadFileName } }: OB11MessageFileBase,
{ deleteAfterSentFiles }: MessageContext { deleteAfterSentFiles }: MessageContext
) { ) {
let uri = file; let uri = file;
const cache = await dbUtil.getFileCacheByName(file); const cache = await dbUtil.getFileCacheByName(file);
if (cache) { if (cache) {
if (fs.existsSync(cache.path)) { if (fs.existsSync(cache.path)) {
uri = 'file://' + cache.path; uri = 'file://' + cache.path;
} else if (cache.url) { } else if (cache.url) {
uri = cache.url; uri = cache.url;
} else { } else {
const fileMsg = await dbUtil.getMsgByLongId(cache.msgId); const fileMsg = await dbUtil.getMsgByLongId(cache.msgId);
if (fileMsg) { if (fileMsg) {
cache.path = await NTQQFileApi.downloadMedia( cache.path = await NTQQFileApi.downloadMedia(
fileMsg.msgId, fileMsg.chatType, fileMsg.peerUid, fileMsg.msgId, fileMsg.chatType, fileMsg.peerUid,
cache.elementId, '', '' cache.elementId, '', ''
); );
uri = 'file://' + cache.path; uri = 'file://' + cache.path;
dbUtil.updateFileCache(cache); dbUtil.updateFileCache(cache);
} }
} }
logDebug('找到文件缓存', uri); logDebug('找到文件缓存', uri);
} }
const { path, isLocal, fileName, errMsg } = (await uri2local(uri)); const { path, isLocal, fileName, errMsg } = (await uri2local(uri));
if (errMsg) { if (errMsg) {
logError('文件下载失败', errMsg); logError('文件下载失败', errMsg);
throw Error('文件下载失败' + errMsg); throw Error('文件下载失败' + errMsg);
} }
if (!isLocal) { // 只删除http和base64转过来的文件 if (!isLocal) { // 只删除http和base64转过来的文件
deleteAfterSentFiles.push(path); deleteAfterSentFiles.push(path);
} }
return { path, fileName: payloadFileName || fileName }; return { path, fileName: payloadFileName || fileName };
} }
const _handlers: { const _handlers: {
[Key in OB11MessageDataType]: ( [Key in OB11MessageDataType]: (
sendMsg: Extract<OB11MessageData, { type: Key }>, sendMsg: Extract<OB11MessageData, { type: Key }>,
// This picks the correct message type out // This picks the correct message type out
// How great the type system of TypeScript is! // How great the type system of TypeScript is!
context: MessageContext context: MessageContext
) => SendMessageElement | undefined | Promise<SendMessageElement | undefined> ) => SendMessageElement | undefined | Promise<SendMessageElement | undefined>
} = { } = {
[OB11MessageDataType.text]: ({ data: { text } }) => SendMsgElementConstructor.text(text), [OB11MessageDataType.text]: ({ data: { text } }) => SendMsgElementConstructor.text(text),
[OB11MessageDataType.at]: async ({ data: { qq: atQQ } }, context) => { [OB11MessageDataType.at]: async ({ data: { qq: atQQ } }, context) => {
if (!context.group) return undefined; if (!context.group) return undefined;
if (atQQ === 'all') return SendMsgElementConstructor.at(atQQ, atQQ, AtType.atAll, '全体成员'); if (atQQ === 'all') return SendMsgElementConstructor.at(atQQ, atQQ, AtType.atAll, '全体成员');
// then the qq is a group member // then the qq is a group member
const atMember = await getGroupMember(context.group.groupCode, atQQ); const atMember = await getGroupMember(context.group.groupCode, atQQ);
return atMember ? return atMember ?
SendMsgElementConstructor.at(atQQ, atMember.uid, AtType.atUser, atMember.cardName || atMember.nick) : SendMsgElementConstructor.at(atQQ, atMember.uid, AtType.atUser, atMember.cardName || atMember.nick) :
undefined; undefined;
}, },
[OB11MessageDataType.reply]: async ({ data: { id } }) => { [OB11MessageDataType.reply]: async ({ data: { id } }) => {
const replyMsg = await dbUtil.getMsgByShortId(parseInt(id)); const replyMsg = await dbUtil.getMsgByShortId(parseInt(id));
return replyMsg ? return replyMsg ?
SendMsgElementConstructor.reply(replyMsg.msgSeq, replyMsg.msgId, replyMsg.senderUin!, replyMsg.senderUin!) : SendMsgElementConstructor.reply(replyMsg.msgSeq, replyMsg.msgId, replyMsg.senderUin!, replyMsg.senderUin!) :
undefined; undefined;
}, },
[OB11MessageDataType.face]: ({ data: { id } }) => SendMsgElementConstructor.face(parseInt(id)), [OB11MessageDataType.face]: ({ data: { id } }) => SendMsgElementConstructor.face(parseInt(id)),
[OB11MessageDataType.mface]: ({ [OB11MessageDataType.mface]: ({
data: { data: {
emoji_package_id, emoji_package_id,
emoji_id, emoji_id,
key, key,
summary summary
} }
}) => SendMsgElementConstructor.mface(emoji_package_id, emoji_id, key, summary), }) => SendMsgElementConstructor.mface(emoji_package_id, emoji_id, key, summary),
// File service // File service
[OB11MessageDataType.image]: async (sendMsg, context) => { [OB11MessageDataType.image]: async (sendMsg, context) => {
const PicEle = await SendMsgElementConstructor.pic( const PicEle = await SendMsgElementConstructor.pic(
(await handleOb11FileLikeMessage(sendMsg, context)).path, (await handleOb11FileLikeMessage(sendMsg, context)).path,
sendMsg.data.summary || '', sendMsg.data.summary || '',
sendMsg.data.subType || 0 sendMsg.data.subType || 0
); );
context.deleteAfterSentFiles.push(PicEle.picElement.sourcePath); context.deleteAfterSentFiles.push(PicEle.picElement.sourcePath);
return PicEle; return PicEle;
} }
, // currently not supported , // currently not supported
[OB11MessageDataType.file]: async (sendMsg, context) => { [OB11MessageDataType.file]: async (sendMsg, context) => {
const { path, fileName } = await handleOb11FileLikeMessage(sendMsg, context); const { path, fileName } = await handleOb11FileLikeMessage(sendMsg, context);
//logDebug('发送文件', path, fileName); //logDebug('发送文件', path, fileName);
const FileEle = await SendMsgElementConstructor.file(path, fileName); const FileEle = await SendMsgElementConstructor.file(path, fileName);
// 清除Upload的应该 // 清除Upload的应该
// context.deleteAfterSentFiles.push(fileName || FileEle.fileElement.filePath); // context.deleteAfterSentFiles.push(fileName || FileEle.fileElement.filePath);
return FileEle; return FileEle;
}, },
[OB11MessageDataType.video]: async (sendMsg, context) => { [OB11MessageDataType.video]: async (sendMsg, context) => {
const { path, fileName } = await handleOb11FileLikeMessage(sendMsg, context); const { path, fileName } = await handleOb11FileLikeMessage(sendMsg, context);
//logDebug('发送视频', path, fileName); //logDebug('发送视频', path, fileName);
let thumb = sendMsg.data.thumb; let thumb = sendMsg.data.thumb;
if (thumb) { if (thumb) {
const uri2LocalRes = await uri2local(thumb); const uri2LocalRes = await uri2local(thumb);
if (uri2LocalRes.success) thumb = uri2LocalRes.path; if (uri2LocalRes.success) thumb = uri2LocalRes.path;
} }
return SendMsgElementConstructor.video(path, fileName, thumb); return SendMsgElementConstructor.video(path, fileName, thumb);
}, },
[OB11MessageDataType.miniapp]: async ({ data: any }) => SendMsgElementConstructor.miniapp(), [OB11MessageDataType.miniapp]: async ({ data: any }) => SendMsgElementConstructor.miniapp(),
[OB11MessageDataType.voice]: async (sendMsg, context) => [OB11MessageDataType.voice]: async (sendMsg, context) =>
SendMsgElementConstructor.ptt((await handleOb11FileLikeMessage(sendMsg, context)).path), SendMsgElementConstructor.ptt((await handleOb11FileLikeMessage(sendMsg, context)).path),
[OB11MessageDataType.json]: ({ data: { data } }) => SendMsgElementConstructor.ark(data), [OB11MessageDataType.json]: ({ data: { data } }) => SendMsgElementConstructor.ark(data),
[OB11MessageDataType.dice]: ({ data: { result } }) => SendMsgElementConstructor.dice(result), [OB11MessageDataType.dice]: ({ data: { result } }) => SendMsgElementConstructor.dice(result),
[OB11MessageDataType.RPS]: ({ data: { result } }) => SendMsgElementConstructor.rps(result), [OB11MessageDataType.RPS]: ({ data: { result } }) => SendMsgElementConstructor.rps(result),
[OB11MessageDataType.markdown]: ({ data: { content } }) => SendMsgElementConstructor.markdown(content), [OB11MessageDataType.markdown]: ({ data: { content } }) => SendMsgElementConstructor.markdown(content),
[OB11MessageDataType.music]: async ({ data }) => { [OB11MessageDataType.music]: async ({ data }) => {
// 保留, 直到...找到更好的解决方案 // 保留, 直到...找到更好的解决方案
if (data.type === 'custom') { if (data.type === 'custom') {
if (!data.url) { if (!data.url) {
logError('自定义音卡缺少参数url'); logError('自定义音卡缺少参数url');
return undefined; return undefined;
} }
if (!data.audio) { if (!data.audio) {
logError('自定义音卡缺少参数audio'); logError('自定义音卡缺少参数audio');
return undefined; return undefined;
} }
if (!data.title) { if (!data.title) {
logError('自定义音卡缺少参数title'); logError('自定义音卡缺少参数title');
return undefined; return undefined;
} }
} else { } else {
if (!['qq', '163'].includes(data.type)) { if (!['qq', '163'].includes(data.type)) {
logError('音乐卡片type错误, 只支持qq、163、custom当前type:', data.type); logError('音乐卡片type错误, 只支持qq、163、custom当前type:', data.type);
return undefined; return undefined;
} }
if (!data.id) { if (!data.id) {
logError('音乐卡片缺少参数id'); logError('音乐卡片缺少参数id');
return undefined; return undefined;
} }
} }
let postData: IdMusicSignPostData | CustomMusicSignPostData; let postData: IdMusicSignPostData | CustomMusicSignPostData;
if (data.type === 'custom' && data.content) { if (data.type === 'custom' && data.content) {
const { content, ...others } = data; const { content, ...others } = data;
postData = { singer: content, ...others }; postData = { singer: content, ...others };
} else { } else {
postData = data; postData = data;
} }
const signUrl = ob11Config.musicSignUrl; const signUrl = ob11Config.musicSignUrl;
if (!signUrl) { if (!signUrl) {
throw Error('音乐消息签名地址未配置'); throw Error('音乐消息签名地址未配置');
} }
try { try {
const musicJson = await RequestUtil.HttpGetJson<any>(signUrl, 'POST', postData); const musicJson = await RequestUtil.HttpGetJson<any>(signUrl, 'POST', postData);
return SendMsgElementConstructor.ark(musicJson); return SendMsgElementConstructor.ark(musicJson);
} catch (e) { } catch (e) {
logError('生成音乐消息失败', e); logError('生成音乐消息失败', e);
} }
}, },
[OB11MessageDataType.node]: () => undefined, [OB11MessageDataType.node]: () => undefined,
[OB11MessageDataType.forward]: () => undefined, [OB11MessageDataType.forward]: () => undefined,
[OB11MessageDataType.xml]: () => undefined, [OB11MessageDataType.xml]: () => undefined,
[OB11MessageDataType.poke]: () => undefined, [OB11MessageDataType.poke]: () => undefined,
}; };
const handlers = <{ const handlers = <{
[Key in OB11MessageDataType]: ( [Key in OB11MessageDataType]: (
sendMsg: OB11MessageData, sendMsg: OB11MessageData,
context: MessageContext context: MessageContext
) => SendMessageElement | undefined | Promise<SendMessageElement | undefined> ) => SendMessageElement | undefined | Promise<SendMessageElement | undefined>
}>_handlers; }>_handlers;
export default async function createSendElements( export default async function createSendElements(
messageData: OB11MessageData[], messageData: OB11MessageData[],
group?: Group, group?: Group,
ignoreTypes: OB11MessageDataType[] = [] ignoreTypes: OB11MessageDataType[] = []
) { ) {
const sendElements: SendMessageElement[] = []; const sendElements: SendMessageElement[] = [];
const deleteAfterSentFiles: string[] = []; const deleteAfterSentFiles: string[] = [];
for (const sendMsg of messageData) { for (const sendMsg of messageData) {
if (ignoreTypes.includes(sendMsg.type)) { if (ignoreTypes.includes(sendMsg.type)) {
continue; continue;
} }
const callResult = await handlers[sendMsg.type]( const callResult = await handlers[sendMsg.type](
sendMsg, sendMsg,
{ group, deleteAfterSentFiles } { group, deleteAfterSentFiles }
); );
if (callResult) sendElements.push(callResult); if (callResult) sendElements.push(callResult);
} }
return { sendElements, deleteAfterSentFiles }; return { sendElements, deleteAfterSentFiles };
} }
export async function createSendElementsParallel( export async function createSendElementsParallel(
messageData: OB11MessageData[], messageData: OB11MessageData[],
group?: Group, group?: Group,
ignoreTypes: OB11MessageDataType[] = [] ignoreTypes: OB11MessageDataType[] = []
) { ) {
const deleteAfterSentFiles: string[] = []; const deleteAfterSentFiles: string[] = [];
const sendElements = <SendMessageElement[]>( const sendElements = <SendMessageElement[]>(
await Promise.all( await Promise.all(
messageData.map(async sendMsg => ignoreTypes.includes(sendMsg.type) ? messageData.map(async sendMsg => ignoreTypes.includes(sendMsg.type) ?
undefined : undefined :
handlers[sendMsg.type](sendMsg, { group, deleteAfterSentFiles })) handlers[sendMsg.type](sendMsg, { group, deleteAfterSentFiles }))
).then( ).then(
results => results.filter( results => results.filter(
element => element !== undefined element => element !== undefined
) )
) )
); );
return { sendElements, deleteAfterSentFiles }; return { sendElements, deleteAfterSentFiles };
} }

View File

@@ -14,7 +14,7 @@ async function cloneMsg(msg: RawMessage): Promise<RawMessage | undefined> {
peerUid: selfInfo.uid peerUid: selfInfo.uid
}; };
// logDebug('克隆的目标消息', msg); // logDebug('克隆的目标消息', msg);
const sendElements: SendMessageElement[] = []; const sendElements: SendMessageElement[] = [];

View File

@@ -1,91 +1,91 @@
export type BaseCheckResult = ValidCheckResult | InvalidCheckResult export type BaseCheckResult = ValidCheckResult | InvalidCheckResult
export interface ValidCheckResult { export interface ValidCheckResult {
valid: true valid: true
[k: string | number]: any [k: string | number]: any
} }
export interface InvalidCheckResult { export interface InvalidCheckResult {
valid: false valid: false
message: string message: string
[k: string | number]: any [k: string | number]: any
} }
export enum ActionName { export enum ActionName {
// 以下为扩展napcat扩展 // 以下为扩展napcat扩展
RebootNormol = 'reboot_normol',//无快速登录重新启动 RebootNormol = 'reboot_normol',//无快速登录重新启动
GetRobotUinRange = 'get_robot_uin_range', GetRobotUinRange = 'get_robot_uin_range',
SetOnlineStatus = 'set_online_status', SetOnlineStatus = 'set_online_status',
GetFriendsWithCategory = 'get_friends_with_category', GetFriendsWithCategory = 'get_friends_with_category',
GetGroupIgnoreAddRequest = 'get_group_ignore_add_request', GetGroupIgnoreAddRequest = 'get_group_ignore_add_request',
SetQQAvatar = 'set_qq_avatar', SetQQAvatar = 'set_qq_avatar',
GetConfig = 'get_config', GetConfig = 'get_config',
SetConfig = 'set_config', SetConfig = 'set_config',
Debug = 'debug', Debug = 'debug',
GetFile = 'get_file', GetFile = 'get_file',
ForwardFriendSingleMsg = 'forward_friend_single_msg', ForwardFriendSingleMsg = 'forward_friend_single_msg',
ForwardGroupSingleMsg = 'forward_group_single_msg', ForwardGroupSingleMsg = 'forward_group_single_msg',
TranslateEnWordToZn = "translate_en2zh", TranslateEnWordToZn = 'translate_en2zh',
GetGroupFileCount = "get_group_file_count", GetGroupFileCount = 'get_group_file_count',
GetGroupFileList = "get_group_file_list", GetGroupFileList = 'get_group_file_list',
SetGroupFileFolder = "set_group_file_folder", SetGroupFileFolder = 'set_group_file_folder',
DelGroupFile = "del_group_file", DelGroupFile = 'del_group_file',
DelGroupFileFolder = "del_group_file_folder", DelGroupFileFolder = 'del_group_file_folder',
// onebot 11 // onebot 11
Reboot = 'set_restart', Reboot = 'set_restart',
SendLike = 'send_like', SendLike = 'send_like',
GetLoginInfo = 'get_login_info', GetLoginInfo = 'get_login_info',
GetFriendList = 'get_friend_list', GetFriendList = 'get_friend_list',
GetGroupInfo = 'get_group_info', GetGroupInfo = 'get_group_info',
GetGroupList = 'get_group_list', GetGroupList = 'get_group_list',
GetGroupMemberInfo = 'get_group_member_info', GetGroupMemberInfo = 'get_group_member_info',
GetGroupMemberList = 'get_group_member_list', GetGroupMemberList = 'get_group_member_list',
GetMsg = 'get_msg', GetMsg = 'get_msg',
SendMsg = 'send_msg', SendMsg = 'send_msg',
SendGroupMsg = 'send_group_msg', SendGroupMsg = 'send_group_msg',
SendPrivateMsg = 'send_private_msg', SendPrivateMsg = 'send_private_msg',
DeleteMsg = 'delete_msg', DeleteMsg = 'delete_msg',
SetMsgEmojiLike = 'set_msg_emoji_like', SetMsgEmojiLike = 'set_msg_emoji_like',
SetGroupAddRequest = 'set_group_add_request', SetGroupAddRequest = 'set_group_add_request',
SetFriendAddRequest = 'set_friend_add_request', SetFriendAddRequest = 'set_friend_add_request',
SetGroupLeave = 'set_group_leave', SetGroupLeave = 'set_group_leave',
GetVersionInfo = 'get_version_info', GetVersionInfo = 'get_version_info',
GetStatus = 'get_status', GetStatus = 'get_status',
CanSendRecord = 'can_send_record', CanSendRecord = 'can_send_record',
CanSendImage = 'can_send_image', CanSendImage = 'can_send_image',
SetGroupKick = 'set_group_kick', SetGroupKick = 'set_group_kick',
SetGroupBan = 'set_group_ban', SetGroupBan = 'set_group_ban',
SetGroupWholeBan = 'set_group_whole_ban', SetGroupWholeBan = 'set_group_whole_ban',
SetGroupAdmin = 'set_group_admin', SetGroupAdmin = 'set_group_admin',
SetGroupCard = 'set_group_card', SetGroupCard = 'set_group_card',
SetGroupName = 'set_group_name', SetGroupName = 'set_group_name',
GetImage = 'get_image', GetImage = 'get_image',
GetRecord = 'get_record', GetRecord = 'get_record',
CleanCache = 'clean_cache', CleanCache = 'clean_cache',
GetCookies = 'get_cookies', GetCookies = 'get_cookies',
// 以下为go-cqhttp api // 以下为go-cqhttp api
GoCQHTTP_HandleQuickAction = '.handle_quick_operation', GoCQHTTP_HandleQuickAction = '.handle_quick_operation',
GetGroupHonorInfo = 'get_group_honor_info', GetGroupHonorInfo = 'get_group_honor_info',
GoCQHTTP_GetEssenceMsg = 'get_essence_msg_list', GoCQHTTP_GetEssenceMsg = 'get_essence_msg_list',
GoCQHTTP_SendGroupNotice = '_send_group_notice', GoCQHTTP_SendGroupNotice = '_send_group_notice',
GoCQHTTP_GetGroupNotice = '_get_group_notice', GoCQHTTP_GetGroupNotice = '_get_group_notice',
GoCQHTTP_SendForwardMsg = 'send_forward_msg', GoCQHTTP_SendForwardMsg = 'send_forward_msg',
GoCQHTTP_SendGroupForwardMsg = 'send_group_forward_msg', GoCQHTTP_SendGroupForwardMsg = 'send_group_forward_msg',
GoCQHTTP_SendPrivateForwardMsg = 'send_private_forward_msg', GoCQHTTP_SendPrivateForwardMsg = 'send_private_forward_msg',
GoCQHTTP_GetStrangerInfo = 'get_stranger_info', GoCQHTTP_GetStrangerInfo = 'get_stranger_info',
GoCQHTTP_MarkMsgAsRead = 'mark_msg_as_read', GoCQHTTP_MarkMsgAsRead = 'mark_msg_as_read',
GetGuildList = 'get_guild_list', GetGuildList = 'get_guild_list',
MarkPrivateMsgAsRead = 'mark_private_msg_as_read', MarkPrivateMsgAsRead = 'mark_private_msg_as_read',
MarkGroupMsgAsRead = 'mark_group_msg_as_read', MarkGroupMsgAsRead = 'mark_group_msg_as_read',
GoCQHTTP_UploadGroupFile = 'upload_group_file', GoCQHTTP_UploadGroupFile = 'upload_group_file',
GoCQHTTP_DownloadFile = 'download_file', GoCQHTTP_DownloadFile = 'download_file',
GoCQHTTP_GetGroupMsgHistory = 'get_group_msg_history', GoCQHTTP_GetGroupMsgHistory = 'get_group_msg_history',
GoCQHTTP_GetForwardMsg = 'get_forward_msg', GoCQHTTP_GetForwardMsg = 'get_forward_msg',
GetFriendMsgHistory = 'get_friend_msg_history', GetFriendMsgHistory = 'get_friend_msg_history',
GetGroupSystemMsg = 'get_group_system_msg', GetGroupSystemMsg = 'get_group_system_msg',
GetOnlineClient = "get_online_clients", GetOnlineClient = 'get_online_clients',
OCRImage = "ocr_image", OCRImage = 'ocr_image',
IOCRImage = ".ocr_image" IOCRImage = '.ocr_image'
} }

View File

@@ -25,10 +25,10 @@ export class GetCookies extends BaseAction<Payload, Response> {
if (!payload.domain) { if (!payload.domain) {
throw new Error('缺少参数 domain'); throw new Error('缺少参数 domain');
} }
if (payload.domain.endsWith("qzone.qq.com")) { if (payload.domain.endsWith('qzone.qq.com')) {
const _Skey = await NTQQUserApi.getSkey() as string; const _Skey = await NTQQUserApi.getSkey() as string;
// 兼容整个 *.qzone.qq.com // 兼容整个 *.qzone.qq.com
let data = (await NTQQUserApi.getQzoneCookies()); const data = (await NTQQUserApi.getQzoneCookies());
const Bkn = WebApi.genBkn(data.p_skey); const Bkn = WebApi.genBkn(data.p_skey);
const CookieValue = 'p_skey=' + data.p_skey + '; skey=' + data.skey + '; p_uin=o' + selfInfo.uin + '; uin=o' + selfInfo.uin; const CookieValue = 'p_skey=' + data.p_skey + '; skey=' + data.skey + '; p_uin=o' + selfInfo.uin + '; uin=o' + selfInfo.uin;
return { cookies: CookieValue }; return { cookies: CookieValue };

View File

@@ -15,6 +15,6 @@ export class OB11GroupIncreaseEvent extends OB11GroupNoticeEvent {
this.sub_type = subType; this.sub_type = subType;
if(ob11Config.GroupLocalTime.Record && (ob11Config.GroupLocalTime.RecordList[0] == '-1' || ob11Config.GroupLocalTime.RecordList.includes(groupId.toString()))) if(ob11Config.GroupLocalTime.Record && (ob11Config.GroupLocalTime.RecordList[0] == '-1' || ob11Config.GroupLocalTime.RecordList.includes(groupId.toString())))
dbUtil.insertJoinTime(groupId, userId, Math.floor(Date.now() / 1000)) dbUtil.insertJoinTime(groupId, userId, Math.floor(Date.now() / 1000));
} }
} }

View File

@@ -152,7 +152,7 @@ export class NapCatOnebot11 {
app_id: '0', app_id: '0',
device_name: device.deviceName, device_name: device.deviceName,
device_kind: 'none' device_kind: 'none'
}) });
// log('[设备列表] 设备名称: ' + device.deviceName); // log('[设备列表] 设备名称: ' + device.deviceName);
}); });
} }

16
src/vite-env.d.ts vendored
View File

@@ -1,9 +1,9 @@
/// <reference types="vite/client" /> /// <reference types="vite/client" />
interface ImportMetaEnv { interface ImportMetaEnv {
VITE_BUILD_TYPE: string VITE_BUILD_TYPE: string
} }
interface ImportMeta { interface ImportMeta {
readonly env: ImportMetaEnv readonly env: ImportMetaEnv
} }

View File

@@ -69,7 +69,7 @@ async function onSettingWindowCreated(view: Element) {
</div> </div>
<div class="q-input"> <div class="q-input">
<input id="config-ob11-http-secret" class="q-input__inner" data-config-key="ob11.http.secret" type="text" value="${ob11Config.http.secret <input id="config-ob11-http-secret" class="q-input__inner" data-config-key="ob11.http.secret" type="text" value="${ob11Config.http.secret
}" placeholder="未设置" /> }" placeholder="未设置" />
</div> </div>
</setting-item> </setting-item>
<setting-item data-direction="row"> <setting-item data-direction="row">