chore: run a full eslint

This commit is contained in:
Wesley F. Young
2024-08-10 19:58:31 +08:00
parent 5a5257294b
commit 87c3b24488
198 changed files with 8187 additions and 7744 deletions

View File

@@ -1,5 +1,5 @@
import { NodeIQQNTWrapperSession } from "@/core/wrapper/wrapper"; import { NodeIQQNTWrapperSession } from '@/core/wrapper/wrapper';
import { randomUUID } from "crypto"; import { randomUUID } from 'crypto';
interface Internal_MapKey { interface Internal_MapKey {
timeout: number; timeout: number;
@@ -23,7 +23,7 @@ export class LegacyNTEventWrapper {
constructor( constructor(
listenerMapping: Record<string, ListenerIBase>, listenerMapping: Record<string, ListenerIBase>,
wrapperSession: NodeIQQNTWrapperSession wrapperSession: NodeIQQNTWrapperSession,
) { ) {
this.listenerMapping = listenerMapping; this.listenerMapping = listenerMapping;
this.WrapperSession = wrapperSession; this.WrapperSession = wrapperSession;
@@ -37,7 +37,7 @@ export class LegacyNTEventWrapper {
{ {
get(target: any, prop: any, receiver: any) { get(target: any, prop: any, receiver: any) {
// console.log('get', prop, typeof target[prop]); // console.log('get', prop, typeof target[prop]);
if (typeof target[prop] === "undefined") { if (typeof target[prop] === 'undefined') {
// 如果方法不存在返回一个函数这个函数调用existentMethod // 如果方法不存在返回一个函数这个函数调用existentMethod
return (...args: any[]) => { return (...args: any[]) => {
current.dispatcherListener.apply(current, [ListenerMainName, prop, ...args]).then(); current.dispatcherListener.apply(current, [ListenerMainName, prop, ...args]).then();
@@ -46,17 +46,17 @@ export class LegacyNTEventWrapper {
// 如果方法存在,正常返回 // 如果方法存在,正常返回
return Reflect.get(target, prop, receiver); return Reflect.get(target, prop, receiver);
}, },
} },
); );
} }
createEventFunction<T extends (...args: any) => any>(eventName: string): T | undefined { createEventFunction<T extends (...args: any) => any>(eventName: string): T | undefined {
const eventNameArr = eventName.split("/"); const eventNameArr = eventName.split('/');
type eventType = { type eventType = {
[key: string]: () => { [key: string]: (...params: Parameters<T>) => Promise<ReturnType<T>> }; [key: string]: () => { [key: string]: (...params: Parameters<T>) => Promise<ReturnType<T>> };
}; };
if (eventNameArr.length > 1) { if (eventNameArr.length > 1) {
const serviceName = "get" + eventNameArr[0].replace("NodeIKernel", ""); const serviceName = 'get' + eventNameArr[0].replace('NodeIKernel', '');
const eventName = eventNameArr[1]; const eventName = eventNameArr[1];
//getNodeIKernelGroupListener,GroupService //getNodeIKernelGroupListener,GroupService
//console.log('2', eventName); //console.log('2', eventName);
@@ -71,13 +71,13 @@ export class LegacyNTEventWrapper {
} }
} }
createListenerFunction<T>(listenerMainName: string, uniqueCode: string = ""): T { createListenerFunction<T>(listenerMainName: string, uniqueCode: string = ''): T {
const ListenerType = this.listenerMapping![listenerMainName]; const ListenerType = this.listenerMapping![listenerMainName];
let Listener = this.listenerManager.get(listenerMainName + uniqueCode); let Listener = this.listenerManager.get(listenerMainName + uniqueCode);
if (!Listener && ListenerType) { if (!Listener && ListenerType) {
Listener = new ListenerType(this.createProxyDispatch(listenerMainName)); Listener = new ListenerType(this.createProxyDispatch(listenerMainName));
const ServiceSubName = listenerMainName.match(/^NodeIKernel(.*?)Listener$/)![1]; const ServiceSubName = listenerMainName.match(/^NodeIKernel(.*?)Listener$/)![1];
const Service = "NodeIKernel" + ServiceSubName + "Service/addKernel" + ServiceSubName + "Listener"; const Service = 'NodeIKernel' + ServiceSubName + 'Service/addKernel' + ServiceSubName + 'Listener';
const addfunc = this.createEventFunction<(listener: T) => number>(Service); const addfunc = this.createEventFunction<(listener: T) => number>(Service);
addfunc!(Listener as T); addfunc!(Listener as T);
//console.log(addfunc!(Listener as T)); //console.log(addfunc!(Listener as T));
@@ -104,7 +104,7 @@ export class LegacyNTEventWrapper {
} }
async callNoListenerEvent<EventType extends (...args: any[]) => Promise<any> | any>( async callNoListenerEvent<EventType extends (...args: any[]) => Promise<any> | any>(
EventName = "", EventName = '',
timeout: number = 3000, timeout: number = 3000,
...args: Parameters<EventType> ...args: Parameters<EventType>
) { ) {
@@ -113,7 +113,7 @@ export class LegacyNTEventWrapper {
let complete = false; let complete = false;
setTimeout(() => { setTimeout(() => {
if (!complete) { if (!complete) {
reject(new Error("NTEvent EventName:" + EventName + " timeout")); reject(new Error('NTEvent EventName:' + EventName + ' timeout'));
} }
}, timeout); }, timeout);
const retData = await EventFunc!(...args); const retData = await EventFunc!(...args);
@@ -123,13 +123,13 @@ export class LegacyNTEventWrapper {
} }
async RegisterListen<ListenerType extends (...args: any[]) => void>( async RegisterListen<ListenerType extends (...args: any[]) => void>(
ListenerName = "", ListenerName = '',
waitTimes = 1, waitTimes = 1,
timeout = 5000, timeout = 5000,
checker: (...args: Parameters<ListenerType>) => boolean checker: (...args: Parameters<ListenerType>) => boolean,
) { ) {
return new Promise<Parameters<ListenerType>>((resolve, reject) => { return new Promise<Parameters<ListenerType>>((resolve, reject) => {
const ListenerNameList = ListenerName.split("/"); const ListenerNameList = ListenerName.split('/');
const ListenerMainName = ListenerNameList[0]; const ListenerMainName = ListenerNameList[0];
const ListenerSubName = ListenerNameList[1]; const ListenerSubName = ListenerNameList[1];
const id = randomUUID(); const id = randomUUID();
@@ -137,7 +137,7 @@ export class LegacyNTEventWrapper {
let retData: Parameters<ListenerType> | undefined = undefined; let retData: Parameters<ListenerType> | undefined = undefined;
const databack = () => { const databack = () => {
if (complete == 0) { if (complete == 0) {
reject(new Error(" ListenerName:" + ListenerName + " timeout")); reject(new Error(' ListenerName:' + ListenerName + ' timeout'));
} else { } else {
resolve(retData!); resolve(retData!);
} }
@@ -166,12 +166,13 @@ export class LegacyNTEventWrapper {
this.createListenerFunction(ListenerMainName); this.createListenerFunction(ListenerMainName);
}); });
} }
async CallNormalEvent< async CallNormalEvent<
EventType extends (...args: any[]) => Promise<any>, EventType extends (...args: any[]) => Promise<any>,
ListenerType extends (...args: any[]) => void ListenerType extends (...args: any[]) => void
>( >(
EventName = "", EventName = '',
ListenerName = "", ListenerName = '',
waitTimes = 1, waitTimes = 1,
timeout: number = 3000, timeout: number = 3000,
checker: (...args: Parameters<ListenerType>) => boolean, checker: (...args: Parameters<ListenerType>) => boolean,
@@ -187,21 +188,21 @@ export class LegacyNTEventWrapper {
if (complete == 0) { if (complete == 0) {
reject( reject(
new Error( new Error(
"Timeout: NTEvent EventName:" + 'Timeout: NTEvent EventName:' +
EventName + EventName +
" ListenerName:" + ' ListenerName:' +
ListenerName + ListenerName +
" EventRet:\n" + ' EventRet:\n' +
JSON.stringify(retEvent, null, 4) + JSON.stringify(retEvent, null, 4) +
"\n" '\n',
) ),
); );
} else { } else {
resolve([retEvent as Awaited<ReturnType<EventType>>, ...retData!]); resolve([retEvent as Awaited<ReturnType<EventType>>, ...retData!]);
} }
}; };
const ListenerNameList = ListenerName.split("/"); const ListenerNameList = ListenerName.split('/');
const ListenerMainName = ListenerNameList[0]; const ListenerMainName = ListenerNameList[0];
const ListenerSubName = ListenerNameList[1]; const ListenerSubName = ListenerNameList[1];
@@ -231,7 +232,7 @@ export class LegacyNTEventWrapper {
this.createListenerFunction(ListenerMainName); this.createListenerFunction(ListenerMainName);
const EventFunc = this.createEventFunction<EventType>(EventName); const EventFunc = this.createEventFunction<EventType>(EventName);
retEvent = await EventFunc!(...(args as any[])); retEvent = await EventFunc!(...(args as any[]));
} },
); );
} }
} }

View File

@@ -1,5 +1,5 @@
import type { NodeIQQNTWrapperSession, WrapperNodeApi } from "@/core/wrapper/wrapper"; import type { NodeIQQNTWrapperSession, WrapperNodeApi } from '@/core/wrapper/wrapper';
import EventEmitter from "node:events"; import EventEmitter from 'node:events';
export type ListenerClassBase = Record<string, string>; export type ListenerClassBase = Record<string, string>;
@@ -12,9 +12,11 @@ export class NTEventChannel extends EventEmitter {
private wrapperApi: WrapperNodeApi; private wrapperApi: WrapperNodeApi;
private wrapperSession: NodeIQQNTWrapperSession; private wrapperSession: NodeIQQNTWrapperSession;
private listenerRefStorage = new Map<string, ListenerIBase>(); private listenerRefStorage = new Map<string, ListenerIBase>();
constructor(WrapperApi: WrapperNodeApi, WrapperSession: NodeIQQNTWrapperSession) { constructor(WrapperApi: WrapperNodeApi, WrapperSession: NodeIQQNTWrapperSession) {
super(); super();
this.on('error', () => { }); this.on('error', () => {
});
this.wrapperApi = WrapperApi; this.wrapperApi = WrapperApi;
this.wrapperSession = WrapperSession; this.wrapperSession = WrapperSession;
} }
@@ -31,7 +33,7 @@ export class NTEventChannel extends EventEmitter {
return (...args: any[]) => { return (...args: any[]) => {
current.dispatcherListener.apply(current, [ListenerMainName + '/' + prop, ...args]); current.dispatcherListener.apply(current, [ListenerMainName + '/' + prop, ...args]);
}; };
} },
}); });
} }
@@ -134,4 +136,5 @@ export class NTEventChannel extends EventEmitter {
}); });
} }
} }
//NTEvent2.0 //NTEvent2.0

View File

@@ -1,6 +1,8 @@
import path, { dirname } from "path"; import path, { dirname } from 'path';
import { fileURLToPath } from "url"; import { fileURLToPath } from 'url';
export const napcat_version = "2.0.0";
export const napcat_version = '2.0.0';
export class NapCatPathWrapper { export class NapCatPathWrapper {
binaryPath: string; binaryPath: string;
logsPath: string; logsPath: string;
@@ -8,7 +10,7 @@ export class NapCatPathWrapper {
constructor(mainPath: string = dirname(fileURLToPath(import.meta.url))) { constructor(mainPath: string = dirname(fileURLToPath(import.meta.url))) {
this.binaryPath = mainPath; this.binaryPath = mainPath;
this.logsPath = path.join(this.binaryPath, "logs"); this.logsPath = path.join(this.binaryPath, 'logs');
this.configPath = path.join(this.binaryPath, "config"); this.configPath = path.join(this.binaryPath, 'config');
} }
} }

View File

@@ -1,12 +1,14 @@
import path from 'node:path'; import path from 'node:path';
import fs from 'node:fs'; import fs from 'node:fs';
import type { NapCatCore } from '@/core'; import type { NapCatCore } from '@/core';
export class ConfigBase<T> { export class ConfigBase<T> {
public name: string = 'default_config'; public name: string = 'default_config';
private pathName: string | null = null; // 本次读取的文件路径 private pathName: string | null = null; // 本次读取的文件路径
coreContext: NapCatCore; coreContext: NapCatCore;
configPath: string; configPath: string;
config: { [key: string]: any } = {}; config: { [key: string]: any } = {};
constructor(coreContext: NapCatCore, configPath: string) { constructor(coreContext: NapCatCore, configPath: string) {
this.coreContext = coreContext; this.coreContext = coreContext;
this.configPath = configPath; this.configPath = configPath;
@@ -23,20 +25,24 @@ export class ConfigBase<T> {
fs.mkdirSync(configDir, { recursive: true }); fs.mkdirSync(configDir, { recursive: true });
return configDir; return configDir;
} }
getConfigPath(pathName: string | null): string { getConfigPath(pathName: string | null): string {
const suffix = pathName ? `_${pathName}` : ''; const suffix = pathName ? `_${pathName}` : '';
const filename = `${this.name}${suffix}.json`; const filename = `${this.name}${suffix}.json`;
return path.join(this.getConfigDir(), filename); return path.join(this.getConfigDir(), filename);
} }
read() { read() {
// 尝试加载当前账号配置 // 尝试加载当前账号配置
if (this.read_from_file(this.coreContext.selfInfo.uin, false)) return this; if (this.read_from_file(this.coreContext.selfInfo.uin, false)) return this;
// 尝试加载默认配置 // 尝试加载默认配置
return this.read_from_file('', true); return this.read_from_file('', true);
} }
getConfig(): T { getConfig(): T {
return this.config as T; return this.config as T;
} }
read_from_file(pathName: string, createIfNotExist: boolean) { read_from_file(pathName: string, createIfNotExist: boolean) {
const logger = this.coreContext.context.logger; const logger = this.coreContext.context.logger;
const configPath = this.getConfigPath(pathName); const configPath = this.getConfigPath(pathName);
@@ -46,8 +52,7 @@ export class ConfigBase<T> {
try { try {
fs.writeFileSync(configPath, JSON.stringify(this.config, this.getKeys(), 2)); fs.writeFileSync(configPath, JSON.stringify(this.config, this.getKeys(), 2));
logger.log(`配置文件${configPath}已创建\n如果修改此文件后需要重启 NapCat 生效`); logger.log(`配置文件${configPath}已创建\n如果修改此文件后需要重启 NapCat 生效`);
} } catch (e: any) {
catch (e: any) {
logger.logError(`创建配置文件 ${configPath} 时发生错误:`, e.message); logger.logError(`创建配置文件 ${configPath} 时发生错误:`, e.message);
} }
return this.config; return this.config;

View File

@@ -1,5 +1,6 @@
import { Peer } from '@/core'; import { Peer } from '@/core';
import crypto from 'crypto'; import crypto from 'crypto';
export class LimitedHashTable<K, V> { export class LimitedHashTable<K, V> {
private keyToValue: Map<K, V> = new Map(); private keyToValue: Map<K, V> = new Map();
private valueToKey: Map<V, K> = new Map(); private valueToKey: Map<V, K> = new Map();
@@ -8,6 +9,7 @@ export class LimitedHashTable<K, V> {
constructor(maxSize: number) { constructor(maxSize: number) {
this.maxSize = maxSize; this.maxSize = maxSize;
} }
resize(count: number) { resize(count: number) {
this.maxSize = count; this.maxSize = count;
} }
@@ -63,6 +65,7 @@ export class LimitedHashTable<K, V> {
getKeyList(): K[] { getKeyList(): K[] {
return Array.from(this.keyToValue.keys()); return Array.from(this.keyToValue.keys());
} }
//获取最近刚写入的几个值 //获取最近刚写入的几个值
getHeads(size: number): { key: K; value: V }[] | undefined { getHeads(size: number): { key: K; value: V }[] | undefined {
const keyList = this.getKeyList(); const keyList = this.getKeyList();
@@ -82,10 +85,12 @@ export class LimitedHashTable<K, V> {
class MessageUniqueWrapper { class MessageUniqueWrapper {
private msgDataMap: LimitedHashTable<string, number>; private msgDataMap: LimitedHashTable<string, number>;
private msgIdMap: LimitedHashTable<string, number>; private msgIdMap: LimitedHashTable<string, number>;
constructor(maxMap: number = 1000) { constructor(maxMap: number = 1000) {
this.msgIdMap = new LimitedHashTable<string, number>(maxMap); this.msgIdMap = new LimitedHashTable<string, number>(maxMap);
this.msgDataMap = new LimitedHashTable<string, number>(maxMap); this.msgDataMap = new LimitedHashTable<string, number>(maxMap);
} }
getRecentMsgIds(Peer: Peer, size: number): string[] { getRecentMsgIds(Peer: Peer, size: number): string[] {
const heads = this.msgIdMap.getHeads(size); const heads = this.msgIdMap.getHeads(size);
if (!heads) { if (!heads) {
@@ -95,6 +100,7 @@ class MessageUniqueWrapper {
const ret = data.filter((t) => t?.Peer.chatType === Peer.chatType && t?.Peer.peerUid === Peer.peerUid); const ret = data.filter((t) => t?.Peer.chatType === Peer.chatType && t?.Peer.peerUid === Peer.peerUid);
return ret.map((t) => t?.MsgId).filter((t) => t !== undefined); return ret.map((t) => t?.MsgId).filter((t) => t !== undefined);
} }
createMsg(peer: Peer, msgId: string): number | undefined { createMsg(peer: Peer, msgId: string): number | undefined {
const key = `${msgId}|${peer.chatType}|${peer.peerUid}`; const key = `${msgId}|${peer.chatType}|${peer.peerUid}`;
const hash = crypto.createHash('md5').update(key).digest(); const hash = crypto.createHash('md5').update(key).digest();
@@ -128,11 +134,13 @@ class MessageUniqueWrapper {
getShortIdByMsgId(msgId: string): number | undefined { getShortIdByMsgId(msgId: string): number | undefined {
return this.msgIdMap.getValue(msgId); return this.msgIdMap.getValue(msgId);
} }
getPeerByMsgId(msgId: string) { getPeerByMsgId(msgId: string) {
const shortId = this.msgIdMap.getValue(msgId); const shortId = this.msgIdMap.getValue(msgId);
if (!shortId) return undefined; if (!shortId) return undefined;
return this.getMsgIdAndPeerByShortId(shortId); return this.getMsgIdAndPeerByShortId(shortId);
} }
resize(maxSize: number): void { resize(maxSize: number): void {
this.msgIdMap.resize(maxSize); this.msgIdMap.resize(maxSize);
this.msgDataMap.resize(maxSize); this.msgDataMap.resize(maxSize);

View File

@@ -1,9 +1,9 @@
import path from "node:path"; import path from 'node:path';
import fs from "node:fs"; import fs from 'node:fs';
import { systemPlatform } from "@/common/utils/system"; import { systemPlatform } from '@/common/utils/system';
import { getDefaultQQVersionConfigInfo, getQQVersionConfigPath } from "./helper"; import { getDefaultQQVersionConfigInfo, getQQVersionConfigPath } from './helper';
import AppidTable from "@/core/external/appid.json"; import AppidTable from '@/core/external/appid.json';
import { LogWrapper } from "./log"; import { LogWrapper } from './log';
export class QQBasicInfoWrapper { export class QQBasicInfoWrapper {
QQMainPath: string | undefined; QQMainPath: string | undefined;
@@ -20,7 +20,7 @@ export class QQBasicInfoWrapper {
//基础目录获取 //基础目录获取
this.context = context; this.context = context;
this.QQMainPath = process.execPath; this.QQMainPath = process.execPath;
this.QQPackageInfoPath = path.join(path.dirname(this.QQMainPath), "resources", "app", "package.json"); this.QQPackageInfoPath = path.join(path.dirname(this.QQMainPath), 'resources', 'app', 'package.json');
this.QQVersionConfigPath = getQQVersionConfigPath(this.QQMainPath); this.QQVersionConfigPath = getQQVersionConfigPath(this.QQMainPath);
//基础信息获取 无快更则启用默认模板填充 //基础信息获取 无快更则启用默认模板填充
@@ -41,26 +41,28 @@ export class QQBasicInfoWrapper {
getFullQQVesion() { getFullQQVesion() {
const version = this.isQuickUpdate ? this.QQVersionConfig?.curVersion : this.QQPackageInfo?.version; const version = this.isQuickUpdate ? this.QQVersionConfig?.curVersion : this.QQPackageInfo?.version;
if(!version) throw new Error("QQ版本获取失败"); if (!version) throw new Error('QQ版本获取失败');
return version; return version;
} }
requireMinNTQQBuild(buildStr: string) { requireMinNTQQBuild(buildStr: string) {
const currentBuild = parseInt(this.getQQBuildStr() || "0"); const currentBuild = parseInt(this.getQQBuildStr() || '0');
if (currentBuild == 0) throw new Error("QQBuildStr获取失败"); if (currentBuild == 0) throw new Error('QQBuildStr获取失败');
return currentBuild >= parseInt(buildStr); return currentBuild >= parseInt(buildStr);
} }
//此方法不要直接使用 //此方法不要直接使用
getQUAInternal() { getQUAInternal() {
return systemPlatform === "linux" return systemPlatform === 'linux'
? `V1_LNX_NQ_${this.getFullQQVesion()}_${this.getQQBuildStr()}_GW_B` ? `V1_LNX_NQ_${this.getFullQQVesion()}_${this.getQQBuildStr()}_GW_B`
: `V1_WIN_NQ_${this.getFullQQVesion()}_${this.getQQBuildStr()}_GW_B`; : `V1_WIN_NQ_${this.getFullQQVesion()}_${this.getQQBuildStr()}_GW_B`;
} }
getAppidV2(): { appid: string; qua: string } { getAppidV2(): { appid: string; qua: string } {
const appidTbale = AppidTable as unknown as QQAppidTableType; const appidTbale = AppidTable as unknown as QQAppidTableType;
try { try {
const fullVersion = this.getFullQQVesion(); const fullVersion = this.getFullQQVesion();
if (!fullVersion) throw new Error("QQ版本获取失败"); if (!fullVersion) throw new Error('QQ版本获取失败');
const data = appidTbale[fullVersion]; const data = appidTbale[fullVersion];
if (data) { if (data) {
return data; return data;
@@ -70,9 +72,10 @@ export class QQBasicInfoWrapper {
} }
// 以下是兜底措施 // 以下是兜底措施
this.context.logger.log( this.context.logger.log(
`[QQ版本兼容性检测] ${this.getFullQQVesion()} 版本兼容性不佳,可能会导致一些功能无法正常使用` `[QQ版本兼容性检测] ${this.getFullQQVesion()} 版本兼容性不佳,可能会导致一些功能无法正常使用`,
); );
return { appid: systemPlatform === "linux" ? "537237950" : "537237765", qua: this.getQUAInternal() }; return { appid: systemPlatform === 'linux' ? '537237950' : '537237765', qua: this.getQUAInternal() };
} }
} }
export let QQBasicInfo: QQBasicInfoWrapper | undefined; export let QQBasicInfo: QQBasicInfoWrapper | undefined;

View File

@@ -1,10 +1,11 @@
import fs from 'fs'; import fs from 'fs';
import { encode, getDuration, getWavFileInfo, isWav, isSilk } from 'silk-wasm'; import { encode, getDuration, getWavFileInfo, isSilk, isWav } from 'silk-wasm';
import fsPromise from 'fs/promises'; import fsPromise from 'fs/promises';
import path from 'node:path'; import path from 'node:path';
import { randomUUID } from 'crypto'; import { randomUUID } from 'crypto';
import { spawn } from 'node:child_process'; import { spawn } from 'node:child_process';
import { LogWrapper } from './log'; import { LogWrapper } from './log';
export async function encodeSilk(filePath: string, TEMP_DIR: string, logger: LogWrapper) { export async function encodeSilk(filePath: string, TEMP_DIR: string, logger: LogWrapper) {
async function guessDuration(pttPath: string) { async function guessDuration(pttPath: string) {
const pttFileInfo = await fsPromise.stat(pttPath); const pttFileInfo = await fsPromise.stat(pttPath);
@@ -14,6 +15,7 @@ export async function encodeSilk(filePath: string, TEMP_DIR: string, logger: Log
logger.log('通过文件大小估算语音的时长:', duration); logger.log('通过文件大小估算语音的时长:', duration);
return duration; return duration;
} }
try { try {
const file = await fsPromise.readFile(filePath); const file = await fsPromise.readFile(filePath);
const pttPath = path.join(TEMP_DIR, randomUUID()); const pttPath = path.join(TEMP_DIR, randomUUID());
@@ -63,7 +65,7 @@ export async function encodeSilk(filePath: string, TEMP_DIR: string, logger: Log
return { return {
converted: true, converted: true,
path: pttPath, path: pttPath,
duration: silk.duration / 1000 duration: silk.duration / 1000,
}; };
} else { } else {
const silk = file; const silk = file;

View File

@@ -1,10 +1,9 @@
import fs from 'fs'; import fs from 'fs';
import fsPromise, { stat } from 'fs/promises'; import fsPromise, { stat } from 'fs/promises';
import crypto from 'crypto'; import crypto, { randomUUID } from 'crypto';
import util from 'util'; import util from 'util';
import path from 'node:path'; import path from 'node:path';
import * as fileType from 'file-type'; import * as fileType from 'file-type';
import { randomUUID } from 'crypto';
import { LogWrapper } from './log'; import { LogWrapper } from './log';
export function isGIF(path: string) { export function isGIF(path: string) {
@@ -33,6 +32,7 @@ export function checkFileReceived(path: string, timeout: number = 3000): Promise
check(); check();
}); });
} }
// 定义一个异步函数来检查文件是否存在 // 定义一个异步函数来检查文件是否存在
export async function checkFileReceived2(path: string, timeout: number = 3000): Promise<void> { export async function checkFileReceived2(path: string, timeout: number = 3000): Promise<void> {
// 使用 Promise.race 来同时进行文件状态检查和超时计时 // 使用 Promise.race 来同时进行文件状态检查和超时计时
@@ -67,11 +67,12 @@ async function checkFile(path: string): Promise<void> {
} }
// 如果文件存在则无需做任何事情Promise 解决resolve自身 // 如果文件存在则无需做任何事情Promise 解决resolve自身
} }
export async function file2base64(path: string) { export async function file2base64(path: string) {
const readFile = util.promisify(fs.readFile); const readFile = util.promisify(fs.readFile);
const result = { const result = {
err: '', err: '',
data: '' data: '',
}; };
try { try {
// 读取文件内容 // 读取文件内容
@@ -127,7 +128,7 @@ export async function httpDownload(options: string | HttpDownloadOptions): Promi
const chunks: Buffer[] = []; const chunks: Buffer[] = [];
let url: string; let url: string;
let headers: Record<string, string> = { let headers: Record<string, string> = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.71 Safari/537.36' 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.71 Safari/537.36',
}; };
if (typeof options === 'string') { if (typeof options === 'string') {
url = options; url = options;
@@ -172,7 +173,7 @@ export async function uri2local(TempDir: string, UriOrPath: string, fileName: st
fileName: '', fileName: '',
ext: '', ext: '',
path: '', path: '',
isLocal: false isLocal: false,
}; };
if (!fileName) fileName = randomUUID(); if (!fileName) fileName = randomUUID();
let filePath = path.join(TempDir, fileName);//临时目录 let filePath = path.join(TempDir, fileName);//临时目录
@@ -180,10 +181,12 @@ export async function uri2local(TempDir: string, UriOrPath: string, fileName: st
//区分path和uri //区分path和uri
try { try {
if (fs.existsSync(UriOrPath)) url = new URL('file://' + UriOrPath); if (fs.existsSync(UriOrPath)) url = new URL('file://' + UriOrPath);
} catch (error: any) { } } catch (error: any) {
}
try { try {
url = new URL(UriOrPath); url = new URL(UriOrPath);
} catch (error: any) { } } catch (error: any) {
}
//验证url //验证url
if (!url) { if (!url) {
@@ -237,8 +240,7 @@ export async function uri2local(TempDir: string, UriOrPath: string, fileName: st
} else { } else {
filePath = pathname; filePath = pathname;
} }
} } else {
else {
// 26702执行forword file文件操作 不应该在这里乱来 // 26702执行forword file文件操作 不应该在这里乱来
// const cache = await dbUtil.getFileCacheByName(uri); // const cache = await dbUtil.getFileCacheByName(uri);
// if (cache) { // if (cache) {

View File

@@ -1,9 +1,9 @@
import crypto from "node:crypto"; import crypto from 'node:crypto';
import path from "node:path"; import path from 'node:path';
import fs from "fs"; import fs from 'fs';
import * as fsPromise from "node:fs/promises"; import * as fsPromise from 'node:fs/promises';
import os from "node:os"; import os from 'node:os';
import { QQLevel } from "@/core"; import { QQLevel } from '@/core';
//下面这个类是用于将uid+msgid合并的类 //下面这个类是用于将uid+msgid合并的类
@@ -11,19 +11,20 @@ export class UUIDConverter {
static encode(highStr: string, lowStr: string): string { static encode(highStr: string, lowStr: string): string {
const high = BigInt(highStr); const high = BigInt(highStr);
const low = BigInt(lowStr); const low = BigInt(lowStr);
const highHex = high.toString(16).padStart(16, "0"); const highHex = high.toString(16).padStart(16, '0');
const lowHex = low.toString(16).padStart(16, "0"); const lowHex = low.toString(16).padStart(16, '0');
const combinedHex = highHex + lowHex; const combinedHex = highHex + lowHex;
const uuid = `${combinedHex.substring(0, 8)}-${combinedHex.substring(8, 12)}-${combinedHex.substring( const uuid = `${combinedHex.substring(0, 8)}-${combinedHex.substring(8, 12)}-${combinedHex.substring(
12, 12,
16 16,
)}-${combinedHex.substring(16, 20)}-${combinedHex.substring(20)}`; )}-${combinedHex.substring(16, 20)}-${combinedHex.substring(20)}`;
return uuid; return uuid;
} }
static decode(uuid: string): { high: string; low: string } { static decode(uuid: string): { high: string; low: string } {
const hex = uuid.replace(/-/g, ""); const hex = uuid.replace(/-/g, '');
const high = BigInt("0x" + hex.substring(0, 16)); const high = BigInt('0x' + hex.substring(0, 16));
const low = BigInt("0x" + hex.substring(16)); const low = BigInt('0x' + hex.substring(16));
return { high: high.toString(), low: low.toString() }; return { high: high.toString(), low: low.toString() };
} }
} }
@@ -34,27 +35,28 @@ export function sleep(ms: number): Promise<void> {
export function PromiseTimer<T>(promise: Promise<T>, ms: number): Promise<T> { export function PromiseTimer<T>(promise: Promise<T>, ms: number): Promise<T> {
const timeoutPromise = new Promise<T>((_, reject) => const timeoutPromise = new Promise<T>((_, reject) =>
setTimeout(() => reject(new Error("PromiseTimer: Operation timed out")), ms) setTimeout(() => reject(new Error('PromiseTimer: Operation timed out')), ms),
); );
return Promise.race([promise, timeoutPromise]); return Promise.race([promise, timeoutPromise]);
} }
export async function runAllWithTimeout<T>(tasks: Promise<T>[], timeout: number): Promise<T[]> { export async function runAllWithTimeout<T>(tasks: Promise<T>[], timeout: number): Promise<T[]> {
const wrappedTasks = tasks.map((task) => const wrappedTasks = tasks.map((task) =>
PromiseTimer(task, timeout).then( PromiseTimer(task, timeout).then(
(result) => ({ status: "fulfilled", value: result }), (result) => ({ status: 'fulfilled', value: result }),
(error) => ({ status: "rejected", reason: error }) (error) => ({ status: 'rejected', reason: error }),
) ),
); );
const results = await Promise.all(wrappedTasks); const results = await Promise.all(wrappedTasks);
return results return results
.filter((result) => result.status === "fulfilled") .filter((result) => result.status === 'fulfilled')
.map((result) => (result as { status: "fulfilled"; value: T }).value); .map((result) => (result as { status: 'fulfilled'; value: T }).value);
} }
export function getMd5(s: string) { export function getMd5(s: string) {
const h = crypto.createHash("md5"); const h = crypto.createHash('md5');
h.update(s); h.update(s);
return h.digest("hex"); return h.digest('hex');
} }
export function isNull(value: any) { export function isNull(value: any) {
@@ -64,15 +66,16 @@ export function isNull(value: any) {
export function isNumeric(str: string) { export function isNumeric(str: string) {
return /^\d+$/.test(str); return /^\d+$/.test(str);
} }
export function truncateString(obj: any, maxLength = 500) { export function truncateString(obj: any, maxLength = 500) {
if (obj !== null && typeof obj === "object") { if (obj !== null && typeof obj === 'object') {
Object.keys(obj).forEach((key) => { Object.keys(obj).forEach((key) => {
if (typeof obj[key] === "string") { if (typeof obj[key] === 'string') {
// 如果是字符串且超过指定长度,则截断 // 如果是字符串且超过指定长度,则截断
if (obj[key].length > maxLength) { if (obj[key].length > maxLength) {
obj[key] = obj[key].substring(0, maxLength) + "..."; obj[key] = obj[key].substring(0, maxLength) + '...';
} }
} else if (typeof obj[key] === "object") { } else if (typeof obj[key] === 'object') {
// 如果是对象或数组,则递归调用 // 如果是对象或数组,则递归调用
truncateString(obj[key], maxLength); truncateString(obj[key], maxLength);
} }
@@ -80,10 +83,11 @@ export function truncateString(obj: any, maxLength = 500) {
} }
return obj; return obj;
} }
export function isEqual(obj1: any, obj2: any) { export function isEqual(obj1: any, obj2: any) {
if (obj1 === obj2) return true; if (obj1 === obj2) return true;
if (obj1 == null || obj2 == null) return false; if (obj1 == null || obj2 == null) return false;
if (typeof obj1 !== "object" || typeof obj2 !== "object") return obj1 === obj2; if (typeof obj1 !== 'object' || typeof obj2 !== 'object') return obj1 === obj2;
const keys1 = Object.keys(obj1); const keys1 = Object.keys(obj1);
const keys2 = Object.keys(obj2); const keys2 = Object.keys(obj2);
@@ -95,35 +99,36 @@ export function isEqual(obj1: any, obj2: any) {
} }
return true; return true;
} }
export function getDefaultQQVersionConfigInfo(): QQVersionConfigType { export function getDefaultQQVersionConfigInfo(): QQVersionConfigType {
if (os.platform() === "linux") { if (os.platform() === 'linux') {
return { return {
baseVersion: "3.2.12-26702", baseVersion: '3.2.12-26702',
curVersion: "3.2.12-26702", curVersion: '3.2.12-26702',
prevVersion: "", prevVersion: '',
onErrorVersions: [], onErrorVersions: [],
buildId: "26702", buildId: '26702',
}; };
} }
return { return {
baseVersion: "9.9.15-26702", baseVersion: '9.9.15-26702',
curVersion: "9.9.15-26702", curVersion: '9.9.15-26702',
prevVersion: "", prevVersion: '',
onErrorVersions: [], onErrorVersions: [],
buildId: "26702", buildId: '26702',
}; };
} }
export function getQQVersionConfigPath(exePath: string = ""): string | undefined { export function getQQVersionConfigPath(exePath: string = ''): string | undefined {
let configVersionInfoPath; let configVersionInfoPath;
if (os.platform() !== "linux") { if (os.platform() !== 'linux') {
configVersionInfoPath = path.join(path.dirname(exePath), "resources", "app", "versions", "config.json"); configVersionInfoPath = path.join(path.dirname(exePath), 'resources', 'app', 'versions', 'config.json');
} else { } else {
const userPath = os.homedir(); const userPath = os.homedir();
const appDataPath = path.resolve(userPath, "./.config/QQ"); const appDataPath = path.resolve(userPath, './.config/QQ');
configVersionInfoPath = path.resolve(appDataPath, "./versions/config.json"); configVersionInfoPath = path.resolve(appDataPath, './versions/config.json');
} }
if (typeof configVersionInfoPath !== "string") { if (typeof configVersionInfoPath !== 'string') {
return undefined; return undefined;
} }
if (!fs.existsSync(configVersionInfoPath)) { if (!fs.existsSync(configVersionInfoPath)) {
@@ -153,6 +158,7 @@ export async function deleteOldFiles(directoryPath: string, daysThreshold: numbe
//console.error('Error deleting files:', error); //console.error('Error deleting files:', error);
} }
} }
export function calcQQLevel(level: QQLevel) { export function calcQQLevel(level: QQLevel) {
const { crownNum, sunNum, moonNum, starNum } = level; const { crownNum, sunNum, moonNum, starNum } = level;
return crownNum * 64 + sunNum * 16 + moonNum * 4 + starNum; return crownNum * 64 + sunNum * 16 + moonNum * 4 + starNum;

View File

@@ -2,6 +2,7 @@ import log4js, { Configuration } from 'log4js';
import { truncateString } from '@/common/utils/helper'; import { truncateString } from '@/common/utils/helper';
import path from 'node:path'; import path from 'node:path';
import chalk from 'chalk'; import chalk from 'chalk';
export enum LogLevel { export enum LogLevel {
DEBUG = 'debug', DEBUG = 'debug',
INFO = 'info', INFO = 'info',
@@ -9,6 +10,7 @@ export enum LogLevel {
ERROR = 'error', ERROR = 'error',
FATAL = 'fatal', FATAL = 'fatal',
} }
function getFormattedTimestamp() { function getFormattedTimestamp() {
const now = new Date(); const now = new Date();
const year = now.getFullYear(); const year = now.getFullYear();
@@ -20,6 +22,7 @@ function getFormattedTimestamp() {
const milliseconds = now.getMilliseconds().toString().padStart(3, '0'); const milliseconds = now.getMilliseconds().toString().padStart(3, '0');
return `${year}-${month}-${day}_${hours}-${minutes}-${seconds}.${milliseconds}`; return `${year}-${month}-${day}_${hours}-${minutes}-${seconds}.${milliseconds}`;
} }
export class LogWrapper { export class LogWrapper {
fileLogEnabled = true; fileLogEnabled = true;
consoleLogEnabled = true; consoleLogEnabled = true;
@@ -29,6 +32,7 @@ export class LogWrapper {
loggerDefault: log4js.Logger; loggerDefault: log4js.Logger;
// eslint-disable-next-line no-control-regex // eslint-disable-next-line no-control-regex
colorEscape = /\x1B[@-_][0-?]*[ -/]*[@-~]/g; colorEscape = /\x1B[@-_][0-?]*[ -/]*[@-~]/g;
constructor(logDir: string) { constructor(logDir: string) {
// logDir = path.join(path.resolve(__dirname), 'logs'); // logDir = path.join(path.resolve(__dirname), 'logs');
const filename = `${getFormattedTimestamp()}.log`; const filename = `${getFormattedTimestamp()}.log`;
@@ -41,22 +45,22 @@ export class LogWrapper {
maxLogSize: 10485760, // 日志文件的最大大小单位字节这里设置为10MB maxLogSize: 10485760, // 日志文件的最大大小单位字节这里设置为10MB
layout: { layout: {
type: 'pattern', type: 'pattern',
pattern: '%d{yyyy-MM-dd hh:mm:ss} [%p] %X{userInfo} | %m' pattern: '%d{yyyy-MM-dd hh:mm:ss} [%p] %X{userInfo} | %m',
} },
}, },
ConsoleAppender: { // 输出到控制台的appender ConsoleAppender: { // 输出到控制台的appender
type: 'console', type: 'console',
layout: { layout: {
type: 'pattern', type: 'pattern',
pattern: `%d{yyyy-MM-dd hh:mm:ss} [%[%p%]] ${chalk.magenta('%X{userInfo}')} | %m` pattern: `%d{yyyy-MM-dd hh:mm:ss} [%[%p%]] ${chalk.magenta('%X{userInfo}')} | %m`,
} },
} },
}, },
categories: { categories: {
default: { appenders: ['FileAppender', 'ConsoleAppender'], level: 'debug' }, // 默认情况下同时输出到文件和控制台 default: { appenders: ['FileAppender', 'ConsoleAppender'], level: 'debug' }, // 默认情况下同时输出到文件和控制台
file: { appenders: ['FileAppender'], level: 'debug' }, file: { appenders: ['FileAppender'], level: 'debug' },
console: { appenders: ['ConsoleAppender'], level: 'debug' } console: { appenders: ['ConsoleAppender'], level: 'debug' },
} },
}; };
log4js.configure(this.logConfig); log4js.configure(this.logConfig);
this.loggerConsole = log4js.getLogger('console'); this.loggerConsole = log4js.getLogger('console');
@@ -64,6 +68,7 @@ export class LogWrapper {
this.loggerDefault = log4js.getLogger('default'); this.loggerDefault = log4js.getLogger('default');
this.setLogSelfInfo({ nick: '', uin: '', uid: '' }); this.setLogSelfInfo({ nick: '', uin: '', uid: '' });
} }
setLogLevel(fileLogLevel: LogLevel, consoleLogLevel: LogLevel) { setLogLevel(fileLogLevel: LogLevel, consoleLogLevel: LogLevel) {
this.logConfig.categories.file.level = fileLogLevel; this.logConfig.categories.file.level = fileLogLevel;
this.logConfig.categories.console.level = consoleLogLevel; this.logConfig.categories.console.level = consoleLogLevel;
@@ -81,6 +86,7 @@ export class LogWrapper {
enableFileLog(enable: boolean) { enableFileLog(enable: boolean) {
this.fileLogEnabled = enable; this.fileLogEnabled = enable;
} }
enableConsoleLog(enable: boolean) { enableConsoleLog(enable: boolean) {
this.consoleLogEnabled = enable; this.consoleLogEnabled = enable;
} }
@@ -102,7 +108,6 @@ export class LogWrapper {
} }
_log(level: LogLevel, ...args: any[]) { _log(level: LogLevel, ...args: any[]) {
if (this.consoleLogEnabled) { if (this.consoleLogEnabled) {
this.loggerConsole[level](this.formatMsg(args)); this.loggerConsole[level](this.formatMsg(args));

View File

@@ -1,4 +1,4 @@
import { LogWrapper } from "./log"; import { LogWrapper } from './log';
export function proxyHandlerOf(logger: LogWrapper) { export function proxyHandlerOf(logger: LogWrapper) {
return { return {
@@ -12,7 +12,7 @@ export function proxyHandlerOf(logger: LogWrapper) {
} }
// 如果方法存在,正常返回 // 如果方法存在,正常返回
return Reflect.get(target, prop, receiver); return Reflect.get(target, prop, receiver);
} },
}; };
} }

View File

@@ -1,6 +1,7 @@
import https from 'node:https'; import https from 'node:https';
import http from 'node:http'; import http from 'node:http';
import { readFileSync } from 'node:fs'; import { readFileSync } from 'node:fs';
export class RequestUtil { export class RequestUtil {
// 适用于获取服务器下发cookies时获取仅GET // 适用于获取服务器下发cookies时获取仅GET
static async HttpsGetCookies(url: string): Promise<{ [key: string]: string }> { static async HttpsGetCookies(url: string): Promise<{ [key: string]: string }> {
@@ -27,7 +28,8 @@ export class RequestUtil {
resolve(cookies); resolve(cookies);
} }
}; };
res.on('data', () => { }); // Necessary to consume the stream res.on('data', () => {
}); // Necessary to consume the stream
res.on('end', () => { res.on('end', () => {
handleRedirect(res); handleRedirect(res);
}); });
@@ -50,9 +52,10 @@ export class RequestUtil {
} }
// 请求和回复都是JSON data传原始内容 自动编码json // 请求和回复都是JSON data传原始内容 自动编码json
static async HttpGetJson<T>(url: string, method: string = 'GET', data?: any, headers: { [key: string]: string } = {}, isJsonRet: boolean = true, isArgJson: boolean = true): Promise<T> { static async HttpGetJson<T>(url: string, method: string = 'GET', data?: any, headers: {
[key: string]: string
} = {}, isJsonRet: boolean = true, isArgJson: boolean = true): Promise<T> {
const option = new URL(url); const option = new URL(url);
const protocol = url.startsWith('https://') ? https : http; const protocol = url.startsWith('https://') ? https : http;
const options = { const options = {
@@ -60,7 +63,7 @@ export class RequestUtil {
port: option.port, port: option.port,
path: option.href, path: option.href,
method: method, method: method,
headers: headers headers: headers,
}; };
// headers: { // headers: {
// 'Content-Type': 'application/json', // 'Content-Type': 'application/json',
@@ -119,7 +122,7 @@ export class RequestUtil {
const formDataParts = [ const formDataParts = [
`------${boundary}\r\n`, `------${boundary}\r\n`,
`Content-Disposition: form-data; name="share_image"; filename="${filePath}"\r\n`, `Content-Disposition: form-data; name="share_image"; filename="${filePath}"\r\n`,
'Content-Type: ' + type + '\r\n\r\n' 'Content-Type: ' + type + '\r\n\r\n',
]; ];
const fileContent = readFileSync(filePath); const fileContent = readFileSync(filePath);
@@ -127,11 +130,11 @@ export class RequestUtil {
return Buffer.concat([ return Buffer.concat([
Buffer.from(formDataParts.join(''), 'utf8'), Buffer.from(formDataParts.join(''), 'utf8'),
fileContent, fileContent,
Buffer.from(footer, 'utf8') Buffer.from(footer, 'utf8'),
]); ]);
} }
static async uploadImageForOpenPlatform(filePath: string,cookies:string): Promise<string> { static async uploadImageForOpenPlatform(filePath: string, cookies: string): Promise<string> {
return new Promise(async (resolve, reject) => { return new Promise(async (resolve, reject) => {
type retType = { retcode: number, result?: { url: string } }; type retType = { retcode: number, result?: { url: string } };
try { try {
@@ -145,8 +148,8 @@ export class RequestUtil {
'Cookie': cookies, 'Cookie': cookies,
'Accept': '*/*', 'Accept': '*/*',
'Connection': 'keep-alive', 'Connection': 'keep-alive',
'Content-Type': 'multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW' 'Content-Type': 'multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW',
} },
}; };
const req = https.request(options, async (res) => { const req = https.request(options, async (res) => {
let responseBody = ''; let responseBody = '';

View File

@@ -17,7 +17,7 @@ try {
const invalidMacAddresses = new Set([ const invalidMacAddresses = new Set([
'00:00:00:00:00:00', '00:00:00:00:00:00',
'ff:ff:ff:ff:ff:ff', 'ff:ff:ff:ff:ff:ff',
'ac:de:48:00:11:22' 'ac:de:48:00:11:22',
]); ]);
function validateMacAddress(candidate: string): boolean { function validateMacAddress(candidate: string): boolean {

View File

@@ -2,7 +2,7 @@ import ffmpeg, { FfprobeStream } from 'fluent-ffmpeg';
import fs from 'fs'; import fs from 'fs';
import type { LogWrapper } from './log'; import type { LogWrapper } from './log';
export async function getVideoInfo(filePath: string,logger:LogWrapper) { export async function getVideoInfo(filePath: string, logger: LogWrapper) {
const size = fs.statSync(filePath).size; const size = fs.statSync(filePath).size;
return new Promise<{ return new Promise<{
width: number, width: number,
@@ -29,13 +29,14 @@ export async function getVideoInfo(filePath: string,logger:LogWrapper) {
time: parseInt(videoStream.duration!), time: parseInt(videoStream.duration!),
format: metadata.format.format_name!, format: metadata.format.format_name!,
size, size,
filePath filePath,
}); });
} }
}); });
}); });
} }
export function checkFfmpeg(newPath: string | null = null,logger:LogWrapper): Promise<boolean> {
export function checkFfmpeg(newPath: string | null = null, logger: LogWrapper): Promise<boolean> {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
logger.log('开始检查ffmpeg', newPath); logger.log('开始检查ffmpeg', newPath);
if (newPath) { if (newPath) {

View File

@@ -1,5 +1,3 @@
import { log } from "@/common/utils/log";
interface IDependsAdapter { interface IDependsAdapter {
onMSFStatusChange(arg1: number, arg2: number): void; onMSFStatusChange(arg1: number, arg2: number): void;

View File

@@ -1,12 +1,14 @@
import { InstanceContext, NapCatCore } from ".."; import { InstanceContext, NapCatCore } from '..';
export class NTQQCollectionApi { export class NTQQCollectionApi {
context: InstanceContext; context: InstanceContext;
core: NapCatCore; core: NapCatCore;
constructor(context: InstanceContext, core: NapCatCore) { constructor(context: InstanceContext, core: NapCatCore) {
this.context = context; this.context = context;
this.core = core; this.core = core;
} }
async createCollection(authorUin: string, authorUid: string, authorName: string, brief: string, rawData: string) { async createCollection(authorUin: string, authorUid: string, authorName: string, brief: string, rawData: string) {
const param = { const param = {
commInfo: { commInfo: {
@@ -18,11 +20,11 @@ export class NTQQCollectionApi {
strId: authorName, strId: authorName,
groupId: '0', groupId: '0',
groupName: '', groupName: '',
uid: authorUid uid: authorUid,
}, },
customGroupId: '0', customGroupId: '0',
createTime: Date.now().toString(), createTime: Date.now().toString(),
sequence: Date.now().toString() sequence: Date.now().toString(),
}, },
richMediaSummary: { richMediaSummary: {
originalUri: '', originalUri: '',
@@ -32,27 +34,28 @@ export class NTQQCollectionApi {
title: '', title: '',
brief: brief, brief: brief,
picList: [], picList: [],
contentType: 1 contentType: 1,
}, },
richMediaContent: { richMediaContent: {
rawData: rawData, rawData: rawData,
bizDataList: [], bizDataList: [],
picList: [], picList: [],
fileList: [] fileList: [],
}, },
need_share_url: false need_share_url: false,
}; };
return this.context.session.getCollectionService().createNewCollectionItem(param); return this.context.session.getCollectionService().createNewCollectionItem(param);
} }
async getAllCollection(category: number = 0, count: number = 50) { async getAllCollection(category: number = 0, count: number = 50) {
const param = { const param = {
category: category, category: category,
groupId: -1, groupId: -1,
forceSync: true, forceSync: true,
forceFromDb: false, forceFromDb: false,
timeStamp: "0", timeStamp: '0',
count: count, count: count,
searchDown: true searchDown: true,
}; };
return this.context.session.getCollectionService().getCollectionItemList(param); return this.context.session.getCollectionService().getCollectionItemList(param);
} }

View File

@@ -3,7 +3,11 @@ import {
CacheFileType, CacheFileType,
ChatCacheListItemBasic, ChatCacheListItemBasic,
ChatType, ChatType,
ElementType, IMAGE_HTTP_HOST, IMAGE_HTTP_HOST_NT, Peer, PicElement ElementType,
IMAGE_HTTP_HOST,
IMAGE_HTTP_HOST_NT,
Peer,
PicElement,
} from '@/core/entities'; } from '@/core/entities';
import path from 'path'; import path from 'path';
import fs from 'fs'; import fs from 'fs';
@@ -21,11 +25,13 @@ export class NTQQFileApi {
context: InstanceContext; context: InstanceContext;
core: NapCatCore; core: NapCatCore;
rkeyManager: RkeyManager; rkeyManager: RkeyManager;
constructor(context: InstanceContext, core: NapCatCore) { constructor(context: InstanceContext, core: NapCatCore) {
this.context = context; this.context = context;
this.core = core; this.core = core;
this.rkeyManager = new RkeyManager('http://napcat-sign.wumiao.wang:2082/rkey', this.context.logger); this.rkeyManager = new RkeyManager('http://napcat-sign.wumiao.wang:2082/rkey', this.context.logger);
} }
async getFileType(filePath: string) { async getFileType(filePath: string) {
return fileType.fileTypeFromFile(filePath); return fileType.fileTypeFromFile(filePath);
} }
@@ -37,9 +43,14 @@ export class NTQQFileApi {
async getFileSize(filePath: string): Promise<number> { async getFileSize(filePath: string): Promise<number> {
return await this.context.wrapper.util.getFileSize(filePath); return await this.context.wrapper.util.getFileSize(filePath);
} }
async getVideoUrl(peer: Peer, msgId: string, elementId: string) { async getVideoUrl(peer: Peer, msgId: string, elementId: string) {
return (await this.context.session.getRichMediaService().getVideoPlayUrlV2(peer, msgId, elementId, 0, { downSourceType: 1, triggerType: 1 })).urlResult.domainUrl; return (await this.context.session.getRichMediaService().getVideoPlayUrlV2(peer, msgId, elementId, 0, {
downSourceType: 1,
triggerType: 1,
})).urlResult.domainUrl;
} }
// 上传文件到QQ的文件夹 // 上传文件到QQ的文件夹
async uploadFile(filePath: string, elementType: ElementType = ElementType.PIC, elementSubType: number = 0) { async uploadFile(filePath: string, elementType: ElementType = ElementType.PIC, elementSubType: number = 0) {
// napCatCore.wrapper.util. // napCatCore.wrapper.util.
@@ -60,7 +71,7 @@ export class NTQQFileApi {
thumbSize: 0, thumbSize: 0,
needCreate: true, needCreate: true,
downloadType: 1, downloadType: 1,
file_uuid: '' file_uuid: '',
}); });
await this.copyFile(filePath, mediaPath!); await this.copyFile(filePath, mediaPath!);
const fileSize = await this.getFileSize(filePath); const fileSize = await this.getFileSize(filePath);
@@ -69,12 +80,14 @@ export class NTQQFileApi {
fileName, fileName,
path: mediaPath, path: mediaPath,
fileSize, fileSize,
ext ext,
}; };
} }
async downloadMediaByUuid() { async downloadMediaByUuid() {
//napCatCore.session.getRichMediaService().downloadFileForFileUuid(); //napCatCore.session.getRichMediaService().downloadFileForFileUuid();
} }
async downloadMedia(msgId: string, chatType: ChatType, peerUid: string, elementId: string, thumbPath: string, sourcePath: string, timeout = 1000 * 60 * 2, force: boolean = false) { async downloadMedia(msgId: string, chatType: ChatType, peerUid: string, elementId: string, thumbPath: string, sourcePath: string, timeout = 1000 * 60 * 2, force: boolean = false) {
//logDebug('receive downloadMedia task', msgId, chatType, peerUid, elementId, thumbPath, sourcePath, timeout, force); //logDebug('receive downloadMedia task', msgId, chatType, peerUid, elementId, thumbPath, sourcePath, timeout, force);
// 用于下载收到的消息中的图片等 // 用于下载收到的消息中的图片等
@@ -125,8 +138,8 @@ export class NTQQFileApi {
elementId: elementId, elementId: elementId,
thumbSize: 0, thumbSize: 0,
downloadType: 1, downloadType: 1,
filePath: thumbPath filePath: thumbPath,
} },
); );
let filePath = data[1].filePath; let filePath = data[1].filePath;
if (filePath.startsWith('\\')) { if (filePath.startsWith('\\')) {
@@ -135,7 +148,7 @@ export class NTQQFileApi {
//const downloadPath = sessionConfig.defaultFileDownloadPath; //const downloadPath = sessionConfig.defaultFileDownloadPath;
//logDebug('downloadPath', downloadPath); //logDebug('downloadPath', downloadPath);
//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
filePath = path.join("", filePath); filePath = path.join('', filePath);
// 下载路径是下载文件夹的相对路径 // 下载路径是下载文件夹的相对路径
} }
return filePath; return filePath;
@@ -152,6 +165,7 @@ export class NTQQFileApi {
}); });
}); });
} }
async addFileCache(peer: Peer, msgId: string, msgSeq: string, senderUid: string, elemId: string, elemType: string, fileSize: string, fileName: string) { async addFileCache(peer: Peer, msgId: string, msgSeq: string, senderUid: string, elemId: string, elemType: string, fileSize: string, fileName: string) {
let GroupData; let GroupData;
let BuddyData; let BuddyData;
@@ -162,15 +176,15 @@ export class NTQQFileApi {
isConf: false, isConf: false,
hasModifyConfGroupFace: true, hasModifyConfGroupFace: true,
hasModifyConfGroupName: true, hasModifyConfGroupName: true,
groupName: "NapCat.Cached", groupName: 'NapCat.Cached',
remark: "NapCat.Cached" remark: 'NapCat.Cached',
}]; }];
} else if (peer.chatType === ChatType.friend) { } else if (peer.chatType === ChatType.friend) {
BuddyData = [{ BuddyData = [{
category_name: 'NapCat.Cached', category_name: 'NapCat.Cached',
peerUid: peer.peerUid, peerUid: peer.peerUid,
peerUin: peer.peerUid, peerUin: peer.peerUid,
remark: 'NapCat.Cached' remark: 'NapCat.Cached',
}]; }];
} else { } else {
return undefined; return undefined;
@@ -204,14 +218,16 @@ export class NTQQFileApi {
fileName: fileName, fileName: fileName,
hits: [{ hits: [{
start: 12, start: 12,
end: 14 end: 14,
}] }],
} },
] ],
}); });
} }
async searchfile(keys: string[]) { async searchfile(keys: string[]) {
type EventType = NodeIKernelSearchService['searchFileWithKeywords']; type EventType = NodeIKernelSearchService['searchFileWithKeywords'];
interface OnListener { interface OnListener {
searchId: string, searchId: string,
hasMore: boolean, hasMore: boolean,
@@ -227,8 +243,7 @@ export class NTQQFileApi {
hasModifyConfGroupName: boolean, hasModifyConfGroupName: boolean,
groupName: string, groupName: string,
remark: string remark: string
}[] }[],
,
dataLineChatInfo: any[], dataLineChatInfo: any[],
tmpChatInfo: any[], tmpChatInfo: any[],
msgId: string, msgId: string,
@@ -250,6 +265,7 @@ export class NTQQFileApi {
}[] }[]
}[] }[]
} }
const Event = this.core.eventWrapper.createEventFunction<EventType>('NodeIKernelSearchService/searchFileWithKeywords'); const Event = this.core.eventWrapper.createEventFunction<EventType>('NodeIKernelSearchService/searchFileWithKeywords');
let id = ''; let id = '';
const Listener = this.core.eventWrapper.RegisterListen<(params: OnListener) => void> const Listener = this.core.eventWrapper.RegisterListen<(params: OnListener) => void>
@@ -257,12 +273,13 @@ export class NTQQFileApi {
'NodeIKernelSearchListener/onSearchFileKeywordsResult', 'NodeIKernelSearchListener/onSearchFileKeywordsResult',
1, 1,
20000, 20000,
(params) => id !== '' && params.searchId == id (params) => id !== '' && params.searchId == id,
); );
id = await Event!(keys, 12); id = await Event!(keys, 12);
const [ret] = (await Listener); const [ret] = (await Listener);
return ret; return ret;
} }
async getImageUrl(element: PicElement) { async getImageUrl(element: PicElement) {
if (!element) { if (!element) {
return ''; return '';
@@ -300,10 +317,12 @@ export class NTQQFileApi {
export class NTQQFileCacheApi { export class NTQQFileCacheApi {
context: InstanceContext; context: InstanceContext;
core: NapCatCore; core: NapCatCore;
constructor(context: InstanceContext, core: NapCatCore) { constructor(context: InstanceContext, core: NapCatCore) {
this.context = context; this.context = context;
this.core = core; this.core = core;
} }
async setCacheSilentScan(isSilent: boolean = true) { async setCacheSilentScan(isSilent: boolean = true) {
return ''; return '';
} }

View File

@@ -1,23 +1,27 @@
import { GetFileListParam, Peer, RawMessage, SendMessageElement } from '@/core/entities'; import { GetFileListParam, Peer, RawMessage, SendMessageElement } from '@/core/entities';
import { InstanceContext, NapCatCore, NTApiContext } from '@/core'; import { InstanceContext, NapCatCore } from '@/core';
import { onGroupFileInfoUpdateParamType } from '@/core/listeners'; import { onGroupFileInfoUpdateParamType } from '@/core/listeners';
import { GeneralCallResult } from '@/core/services/common'; import { GeneralCallResult } from '@/core/services/common';
export class NTQQMsgApi { export class NTQQMsgApi {
context: InstanceContext; context: InstanceContext;
core: NapCatCore; core: NapCatCore;
constructor(context: InstanceContext, core: NapCatCore) { constructor(context: InstanceContext, core: NapCatCore) {
this.context = context; this.context = context;
this.core = core; this.core = core;
} }
async FetchLongMsg(peer: Peer, msgId: string) { async FetchLongMsg(peer: Peer, msgId: string) {
return this.context.session.getMsgService().fetchLongMsg(peer, msgId); return this.context.session.getMsgService().fetchLongMsg(peer, msgId);
} }
async getMsgEmojiLikesList(peer: Peer, msgSeq: string, emojiId: string, emojiType: string, count: number = 20) { async getMsgEmojiLikesList(peer: Peer, msgSeq: string, emojiId: string, emojiType: string, count: number = 20) {
//console.log(peer, msgSeq, emojiId, emojiType, count); //console.log(peer, msgSeq, emojiId, emojiType, count);
//注意此处emojiType 可选值一般为1-2 2好像是unicode表情dec值 大部分情况 Taged M likiowa //注意此处emojiType 可选值一般为1-2 2好像是unicode表情dec值 大部分情况 Taged M likiowa
return this.context.session.getMsgService().getMsgEmojiLikesList(peer, msgSeq, emojiId, emojiType, "", false, 20); return this.context.session.getMsgService().getMsgEmojiLikesList(peer, msgSeq, emojiId, emojiType, '', false, 20);
} }
// napCatCore: NapCatCore | null = null; // napCatCore: NapCatCore | null = null;
// enum BaseEmojiType { // enum BaseEmojiType {
// NORMAL_EMOJI, // NORMAL_EMOJI,
@@ -33,14 +37,17 @@ export class NTQQMsgApi {
emojiId = emojiId.toString(); emojiId = emojiId.toString();
return this.context.session.getMsgService().setMsgEmojiLikes(peer, msgSeq, emojiId, emojiId.length > 3 ? '2' : '1', set); return this.context.session.getMsgService().setMsgEmojiLikes(peer, msgSeq, emojiId, emojiId.length > 3 ? '2' : '1', set);
} }
async getMultiMsg(peer: Peer, rootMsgId: string, parentMsgId: string): Promise<GeneralCallResult & { async getMultiMsg(peer: Peer, rootMsgId: string, parentMsgId: string): Promise<GeneralCallResult & {
msgList: RawMessage[] msgList: RawMessage[]
} | undefined> { } | undefined> {
return this.context.session.getMsgService().getMultiMsg(peer, rootMsgId, parentMsgId); return this.context.session.getMsgService().getMultiMsg(peer, rootMsgId, parentMsgId);
} }
async ForwardMsg(peer: Peer, msgIds: string[]) { async ForwardMsg(peer: Peer, msgIds: string[]) {
return this.context.session.getMsgService().forwardMsg(msgIds, peer, [peer], new Map()); return this.context.session.getMsgService().forwardMsg(msgIds, peer, [peer], new Map());
} }
async getLastestMsgByUids(peer: Peer, count: number = 20, isReverseOrder: boolean = false) { async getLastestMsgByUids(peer: Peer, count: number = 20, isReverseOrder: boolean = false) {
const ret = await this.context.session.getMsgService().queryMsgsWithFilterEx('0', '0', '0', { const ret = await this.context.session.getMsgService().queryMsgsWithFilterEx('0', '0', '0', {
chatInfo: peer, chatInfo: peer,
@@ -54,18 +61,22 @@ export class NTQQMsgApi {
}); });
return ret; return ret;
} }
async getMsgsByMsgId(peer: Peer | undefined, msgIds: string[] | undefined) { async getMsgsByMsgId(peer: Peer | undefined, msgIds: string[] | undefined) {
if (!peer) throw new Error('peer is not allowed'); if (!peer) throw new Error('peer is not allowed');
if (!msgIds) throw new Error('msgIds is not allowed'); if (!msgIds) throw new Error('msgIds is not allowed');
//Mlikiowa 参数不合规会导致NC异常崩溃 原因是TX未对进入参数判断 对应Android标记@NotNull AndroidJADX分析可得 //Mlikiowa 参数不合规会导致NC异常崩溃 原因是TX未对进入参数判断 对应Android标记@NotNull AndroidJADX分析可得
return await this.context.session.getMsgService().getMsgsByMsgId(peer, msgIds); return await this.context.session.getMsgService().getMsgsByMsgId(peer, msgIds);
} }
async getSingleMsg(peer: Peer, seq: string) { async getSingleMsg(peer: Peer, seq: string) {
return await this.context.session.getMsgService().getSingleMsg(peer, seq); return await this.context.session.getMsgService().getSingleMsg(peer, seq);
} }
async fetchFavEmojiList(num: number) { async fetchFavEmojiList(num: number) {
return this.context.session.getMsgService().fetchFavEmojiList("", num, true, true); return this.context.session.getMsgService().fetchFavEmojiList('', num, true, true);
} }
async queryMsgsWithFilterExWithSeq(peer: Peer, msgSeq: string) { async queryMsgsWithFilterExWithSeq(peer: Peer, msgSeq: string) {
const ret = await this.context.session.getMsgService().queryMsgsWithFilterEx('0', '0', msgSeq, { const ret = await this.context.session.getMsgService().queryMsgsWithFilterEx('0', '0', msgSeq, {
chatInfo: peer,//此处为Peer 为关键查询参数 没有啥也没有 by mlik iowa chatInfo: peer,//此处为Peer 为关键查询参数 没有啥也没有 by mlik iowa
@@ -79,12 +90,15 @@ export class NTQQMsgApi {
}); });
return ret; return ret;
} }
async getMsgsBySeqAndCount(peer: Peer, seq: string, count: number, desc: boolean, z: boolean) { async getMsgsBySeqAndCount(peer: Peer, seq: string, count: number, desc: boolean, z: boolean) {
return await this.context.session.getMsgService().getMsgsBySeqAndCount(peer, seq, count, desc, z); return await this.context.session.getMsgService().getMsgsBySeqAndCount(peer, seq, count, desc, z);
} }
async setMsgRead(peer: Peer) { async setMsgRead(peer: Peer) {
return this.context.session.getMsgService().setMsgRead(peer); return this.context.session.getMsgService().setMsgRead(peer);
} }
async getGroupFileList(GroupCode: string, params: GetFileListParam) { async getGroupFileList(GroupCode: string, params: GetFileListParam) {
const data = await this.core.eventWrapper.CallNormalEvent< const data = await this.core.eventWrapper.CallNormalEvent<
(GroupCode: string, params: GetFileListParam) => Promise<unknown>, (GroupCode: string, params: GetFileListParam) => Promise<unknown>,
@@ -99,20 +113,23 @@ export class NTQQMsgApi {
return true; return true;
}, },
GroupCode, GroupCode,
params params,
); );
return data[1].item; return data[1].item;
} }
async getMsgHistory(peer: Peer, msgId: string, count: number, isReverseOrder: boolean = false) { async getMsgHistory(peer: Peer, msgId: string, count: number, isReverseOrder: boolean = false) {
// 消息时间从旧到新 // 消息时间从旧到新
return this.context.session.getMsgService().getMsgsIncludeSelf(peer, msgId, count, isReverseOrder); return this.context.session.getMsgService().getMsgsIncludeSelf(peer, msgId, count, isReverseOrder);
} }
async recallMsg(peer: Peer, msgIds: string[]) { async recallMsg(peer: Peer, msgIds: string[]) {
await this.context.session.getMsgService().recallMsg({ await this.context.session.getMsgService().recallMsg({
chatType: peer.chatType, chatType: peer.chatType,
peerUid: peer.peerUid peerUid: peer.peerUid,
}, msgIds); }, msgIds);
} }
async sendMsgV2(peer: Peer, msgElements: SendMessageElement[], waitComplete = true, timeout = 10000) { async sendMsgV2(peer: Peer, msgElements: SendMessageElement[], waitComplete = true, timeout = 10000) {
function generateMsgId() { function generateMsgId() {
const timestamp = Math.floor(Date.now() / 1000); const timestamp = Math.floor(Date.now() / 1000);
@@ -120,9 +137,10 @@ export class NTQQMsgApi {
const buffer = Buffer.alloc(8); const buffer = Buffer.alloc(8);
buffer.writeUInt32BE(timestamp, 0); buffer.writeUInt32BE(timestamp, 0);
buffer.writeUInt32BE(random, 4); buffer.writeUInt32BE(random, 4);
const msgId = BigInt("0x" + buffer.toString('hex')).toString(); const msgId = BigInt('0x' + buffer.toString('hex')).toString();
return msgId; return msgId;
} }
// 此处有采用Hack方法 利用数据返回正确得到对应消息 // 此处有采用Hack方法 利用数据返回正确得到对应消息
// 与之前 Peer队列 MsgSeq队列 真正的MsgId并发不同 // 与之前 Peer队列 MsgSeq队列 真正的MsgId并发不同
// 谨慎采用 目前测试暂无问题 Developer.Mlikiowa // 谨慎采用 目前测试暂无问题 Developer.Mlikiowa
@@ -153,7 +171,7 @@ export class NTQQMsgApi {
msgId, msgId,
peer, peer,
msgElements, msgElements,
new Map() new Map(),
); );
const retMsg = data[1].find(msgRecord => { const retMsg = data[1].find(msgRecord => {
if (msgRecord.msgId === msgId) { if (msgRecord.msgId === msgId) {
@@ -162,9 +180,11 @@ export class NTQQMsgApi {
}); });
return retMsg; return retMsg;
} }
sendMsgEx(peer: Peer, msgElements: SendMessageElement[], waitComplete = true, timeout = 10000) { sendMsgEx(peer: Peer, msgElements: SendMessageElement[], waitComplete = true, timeout = 10000) {
//return NTQQMsgApi.sendMsgV1(peer, msgElements, waitComplete, timeout); //return NTQQMsgApi.sendMsgV1(peer, msgElements, waitComplete, timeout);
} }
async sendMsg(peer: Peer, msgElements: SendMessageElement[], waitComplete = true, timeout = 10000) { async sendMsg(peer: Peer, msgElements: SendMessageElement[], waitComplete = true, timeout = 10000) {
//唉? !我有个想法 //唉? !我有个想法
const msgId = await this.getMsgUnique(peer.chatType, await this.getServerTime()); const msgId = await this.getMsgUnique(peer.chatType, await this.getServerTime());
@@ -185,10 +205,10 @@ export class NTQQMsgApi {
} }
return false; return false;
}, },
"0", '0',
peer, peer,
msgElements, msgElements,
new Map() new Map(),
); );
const retMsg = data[1].find(msgRecord => { const retMsg = data[1].find(msgRecord => {
if (msgRecord.guildId === msgId) { if (msgRecord.guildId === msgId) {
@@ -197,27 +217,32 @@ export class NTQQMsgApi {
}); });
return retMsg; return retMsg;
} }
async getMsgUnique(chatType: number, time: string) { async getMsgUnique(chatType: number, time: string) {
if (this.context.basicInfoWrapper.requireMinNTQQBuild('26702')) { if (this.context.basicInfoWrapper.requireMinNTQQBuild('26702')) {
return this.context.session.getMsgService().generateMsgUniqueId(chatType, time); return this.context.session.getMsgService().generateMsgUniqueId(chatType, time);
} }
return this.context.session.getMsgService().getMsgUniqueId(time); return this.context.session.getMsgService().getMsgUniqueId(time);
} }
async getServerTime() { async getServerTime() {
return this.context.session.getMSFService().getServerTime(); return this.context.session.getMSFService().getServerTime();
} }
async getServerTimeV2() { async getServerTimeV2() {
return this.core.eventWrapper.callNoListenerEvent<() => string>('NodeIKernelMsgService/getServerTime', 5000); return this.core.eventWrapper.callNoListenerEvent<() => string>('NodeIKernelMsgService/getServerTime', 5000);
} }
async forwardMsg(srcPeer: Peer, destPeer: Peer, msgIds: string[]) { async forwardMsg(srcPeer: Peer, destPeer: Peer, msgIds: string[]) {
return this.context.session.getMsgService().forwardMsg(msgIds, srcPeer, [destPeer], new Map()); return this.context.session.getMsgService().forwardMsg(msgIds, srcPeer, [destPeer], new Map());
} }
async multiForwardMsg(srcPeer: Peer, destPeer: Peer, msgIds: string[]): Promise<RawMessage> { async multiForwardMsg(srcPeer: Peer, destPeer: Peer, msgIds: string[]): Promise<RawMessage> {
const msgInfos = msgIds.map(id => { const msgInfos = msgIds.map(id => {
return { msgId: id, senderShowName: this.core.selfInfo.nick }; return { msgId: id, senderShowName: this.core.selfInfo.nick };
}); });
const data = await this.core.eventWrapper.CallNormalEvent< const data = await this.core.eventWrapper.CallNormalEvent<
(msgInfo: typeof msgInfos, srcPeer: Peer, destPeer: Peer, comment: Array<any>, attr: Map<any, any>,) => Promise<unknown>, (msgInfo: typeof msgInfos, srcPeer: Peer, destPeer: Peer, comment: Array<any>, attr: Map<any, any>) => Promise<unknown>,
(msgList: RawMessage[]) => void (msgList: RawMessage[]) => void
>( >(
'NodeIKernelMsgService/multiForwardMsgWithComment', 'NodeIKernelMsgService/multiForwardMsgWithComment',
@@ -236,7 +261,7 @@ export class NTQQMsgApi {
srcPeer, srcPeer,
destPeer, destPeer,
[], [],
new Map() new Map(),
); );
for (const msg of data[1]) { for (const msg of data[1]) {
const arkElement = msg.elements.find(ele => ele.arkElement); const arkElement = msg.elements.find(ele => ele.arkElement);
@@ -253,6 +278,7 @@ export class NTQQMsgApi {
} }
throw new Error('转发消息超时'); throw new Error('转发消息超时');
} }
async markallMsgAsRead() { async markallMsgAsRead() {
return this.context.session.getMsgService().setAllC2CAndGroupMsgRead(); return this.context.session.getMsgService().setAllC2CAndGroupMsgRead();
} }

View File

@@ -277,7 +277,9 @@ export class NTQQUserApi {
} }
async getUinByUidV1(Uid: string) { async getUinByUidV1(Uid: string) {
const ret = await this.core.eventWrapper.callNoListenerEvent<(Uin: string[]) => Promise<{ uinInfo: Map<string, string> }>> const ret = await this.core.eventWrapper.callNoListenerEvent<(Uin: string[]) => Promise<{
uinInfo: Map<string, string>
}>>
('NodeIKernelUixConvertService/getUin', 5000, [Uid]); ('NodeIKernelUixConvertService/getUin', 5000, [Uid]);
let uin = ret.uinInfo.get(Uid); let uin = ret.uinInfo.get(Uid);
if (!uin) { if (!uin) {
@@ -317,6 +319,7 @@ export class NTQQUserApi {
return this.core.eventWrapper.callNoListenerEvent<(Uin: string) => Promise<UserDetailInfoByUin>> return this.core.eventWrapper.callNoListenerEvent<(Uin: string) => Promise<UserDetailInfoByUin>>
('NodeIKernelProfileService/getUserDetailInfoByUin', 5000, Uin); ('NodeIKernelProfileService/getUserDetailInfoByUin', 5000, Uin);
} }
async forceFetchClientKey() { async forceFetchClientKey() {
return await this.context.session.getTicketService().forceFetchClientKey(''); return await this.context.session.getTicketService().forceFetchClientKey('');
} }

View File

@@ -71,7 +71,7 @@ export class NTQQWebApi {
end: '40', end: '40',
sort: '1', sort: '1',
gc: GroupCode, gc: GroupCode,
bkn: this.getBknFromCookie(cookieObject) bkn: this.getBknFromCookie(cookieObject),
}).toString() }).toString()
}`, 'POST', '', { 'Cookie': this.cookieToString(cookieObject) }); }`, 'POST', '', { 'Cookie': this.cookieToString(cookieObject) });
if (!fastRet?.count || fastRet?.errcode !== 0 || !fastRet?.mems) { if (!fastRet?.count || fastRet?.errcode !== 0 || !fastRet?.mems) {
@@ -92,7 +92,7 @@ export class NTQQWebApi {
end: (i * 40).toString(), end: (i * 40).toString(),
sort: '1', sort: '1',
gc: GroupCode, gc: GroupCode,
bkn: this.getBknFromCookie(cookieObject) bkn: this.getBknFromCookie(cookieObject),
}).toString() }).toString()
}`, 'POST', '', { 'Cookie': this.cookieToString(cookieObject) }); }`, 'POST', '', { 'Cookie': this.cookieToString(cookieObject) });
retList.push(ret); retList.push(ret);

View File

@@ -1,16 +1,15 @@
import { NTApiContext, WrapperNodeApi } from "@/core/wrapper"; import { NTApiContext, WrapperNodeApi } from '@/core/wrapper';
import path from "node:path"; import path from 'node:path';
import fs from "node:fs"; import fs from 'node:fs';
import { InstanceContext } from "./wrapper"; import { InstanceContext } from './wrapper';
import { NTEventChannel } from "@/common/framework/event"; import { proxiedListenerOf } from '@/common/utils/proxy-handler';
import { proxiedListenerOf } from "@/common/utils/proxy-handler"; import { MsgListener, ProfileListener } from './listeners';
import { MsgListener, ProfileListener } from "./listeners"; import { SelfInfo, SelfStatusInfo } from './entities';
import { sleep } from "@/common/utils/helper"; import { LegacyNTEventWrapper } from '@/common/framework/event-legacy';
import { SelfInfo, LineDevice, SelfStatusInfo } from "./entities"; import { NTQQFileApi, NTQQFriendApi, NTQQGroupApi, NTQQMsgApi, NTQQSystemApi, NTQQUserApi, NTQQWebApi } from './apis';
import { LegacyNTEventWrapper } from "@/common/framework/event-legacy"; import os from 'node:os';
import { NTQQFileApi, NTQQFriendApi, NTQQGroupApi, NTQQMsgApi, NTQQSystemApi, NTQQUserApi, NTQQWebApi } from "./apis"; import { NTQQCollectionApi } from './apis/collection';
import os from "node:os";
import { NTQQCollectionApi } from "./apis/collection";
export enum NapCatCoreWorkingEnv { export enum NapCatCoreWorkingEnv {
Unknown = 0, Unknown = 0,
Shell = 1, Shell = 1,
@@ -36,6 +35,7 @@ export class NapCatCore {
NapCatTempPath: string; NapCatTempPath: string;
// runtime info, not readonly // runtime info, not readonly
selfInfo: SelfInfo; selfInfo: SelfInfo;
// 通过构造器递过去的 runtime info 应该尽量少 // 通过构造器递过去的 runtime info 应该尽量少
constructor(context: InstanceContext, selfInfo: SelfInfo) { constructor(context: InstanceContext, selfInfo: SelfInfo) {
this.selfInfo = selfInfo; this.selfInfo = selfInfo;
@@ -50,7 +50,7 @@ export class NapCatCore {
FriendApi: new NTQQFriendApi(this.context, this), FriendApi: new NTQQFriendApi(this.context, this),
MsgApi: new NTQQMsgApi(this.context, this), MsgApi: new NTQQMsgApi(this.context, this),
UserApi: new NTQQUserApi(this.context, this), UserApi: new NTQQUserApi(this.context, this),
GroupApi: new NTQQGroupApi(this.context, this) GroupApi: new NTQQGroupApi(this.context, this),
}; };
this.NapCatDataPath = path.join(this.dataPath, 'NapCat'); this.NapCatDataPath = path.join(this.dataPath, 'NapCat');
fs.mkdirSync(this.NapCatDataPath, { recursive: true }); fs.mkdirSync(this.NapCatDataPath, { recursive: true });
@@ -60,9 +60,11 @@ export class NapCatCore {
fs.mkdirSync(this.NapCatTempPath, { recursive: true }); fs.mkdirSync(this.NapCatTempPath, { recursive: true });
} }
} }
getApiContext() { getApiContext() {
return this.ApiContext; return this.ApiContext;
} }
get dataPath(): string { get dataPath(): string {
let result = this.context.wrapper.util.getNTUserDataInfoConfig(); let result = this.context.wrapper.util.getNTUserDataInfoConfig();
if (!result) { if (!result) {
@@ -76,11 +78,11 @@ export class NapCatCore {
async initNapCatCoreListeners() { async initNapCatCoreListeners() {
const msgListener = new MsgListener(); const msgListener = new MsgListener();
msgListener.onRecvMsg = (msg) => { msgListener.onRecvMsg = (msg) => {
console.log("RecvMsg", msg); console.log('RecvMsg', msg);
}; };
//await sleep(2500); //await sleep(2500);
this.context.session.getMsgService().addKernelMsgListener( this.context.session.getMsgService().addKernelMsgListener(
new this.context.wrapper.NodeIKernelMsgListener(proxiedListenerOf(msgListener, this.context.logger)) new this.context.wrapper.NodeIKernelMsgListener(proxiedListenerOf(msgListener, this.context.logger)),
); );
const profileListener = new ProfileListener(); const profileListener = new ProfileListener();
@@ -95,7 +97,7 @@ export class NapCatCore {
// } // }
}; };
this.context.session.getProfileService().addKernelProfileListener( this.context.session.getProfileService().addKernelProfileListener(
new this.context.wrapper.NodeIKernelProfileListener(proxiedListenerOf(profileListener, this.context.logger)) new this.context.wrapper.NodeIKernelProfileListener(proxiedListenerOf(profileListener, this.context.logger)),
); );
} }
} }

View File

@@ -12,12 +12,12 @@ export interface CacheScanResult {
string, // 「缓存数据」大小 string, // 「缓存数据」大小
string, // 「其他数据」大小 string, // 「其他数据」大小
string, // 未知 string, // 未知
] ];
} }
export interface ChatCacheList { export interface ChatCacheList {
pageCount: number; pageCount: number;
infos: ChatCacheListItem[] infos: ChatCacheListItem[];
} }
export interface ChatCacheListItem { export interface ChatCacheListItem {

View File

@@ -1,10 +1,12 @@
import { QQLevel, Sex } from './user'; import { QQLevel, Sex } from './user';
export enum GroupListUpdateType { export enum GroupListUpdateType {
REFRESHALL, REFRESHALL,
GETALL, GETALL,
MODIFIED, MODIFIED,
REMOVE REMOVE
} }
export interface Group { export interface Group {
groupCode: string, groupCode: string,
createTime?: string,//高版本才有 createTime?: string,//高版本才有
@@ -56,8 +58,8 @@ export interface GroupMember {
uid: string; // 加密的字符串 uid: string; // 加密的字符串
uin: string; // QQ号 uin: string; // QQ号
isRobot: boolean; isRobot: boolean;
sex?: Sex sex?: Sex;
qqLevel?: QQLevel qqLevel?: QQLevel;
isChangeRole: boolean; isChangeRole: boolean;
joinTime: string; joinTime: string;
lastSpeakTime: string; lastSpeakTime: string;

View File

@@ -5,22 +5,25 @@ export interface Peer {
peerUid: string; // 如果是群聊uid为群号私聊uid就是加密的字符串 peerUid: string; // 如果是群聊uid为群号私聊uid就是加密的字符串
guildId?: string; guildId?: string;
} }
export interface KickedOffLineInfo { export interface KickedOffLineInfo {
appId: number appId: number;
instanceId: number instanceId: number;
sameDevice: boolean sameDevice: boolean;
tipsDesc: string tipsDesc: string;
tipsTitle: string tipsTitle: string;
kickedType: number kickedType: number;
securityKickedType: number securityKickedType: number;
} }
export interface GetFileListParam { export interface GetFileListParam {
sortType: number sortType: number;
fileCount: number fileCount: number;
startIndex: number startIndex: number;
sortOrder: number sortOrder: number;
showOnlinedocFolder: number showOnlinedocFolder: number;
} }
export enum ElementType { export enum ElementType {
UNKNOWN = 0, UNKNOWN = 0,
TEXT = 1, TEXT = 1,
@@ -55,24 +58,29 @@ export enum ElementType {
RECOMMENDEDMSG = 43, RECOMMENDEDMSG = 43,
ACTIONBAR = 44 ACTIONBAR = 44
} }
export interface ActionBarElement { export interface ActionBarElement {
rows: InlineKeyboardRow[]; rows: InlineKeyboardRow[];
botAppid: string; botAppid: string;
} }
export interface SendActionBarElement { export interface SendActionBarElement {
elementType: ElementType.ACTIONBAR; elementType: ElementType.ACTIONBAR;
elementId: string; elementId: string;
actionBarElement: ActionBarElement; actionBarElement: ActionBarElement;
} }
export interface RecommendedMsgElement { export interface RecommendedMsgElement {
rows: InlineKeyboardRow[]; rows: InlineKeyboardRow[];
botAppid: string; botAppid: string;
} }
export interface SendRecommendedMsgElement { export interface SendRecommendedMsgElement {
elementType: ElementType.RECOMMENDEDMSG; elementType: ElementType.RECOMMENDEDMSG;
elementId: string; elementId: string;
recommendedMsgElement: RecommendedMsgElement; recommendedMsgElement: RecommendedMsgElement;
} }
export interface InlineKeyboardButton { export interface InlineKeyboardButton {
id: string; id: string;
label: string; label: string;
@@ -87,24 +95,29 @@ export interface InlineKeyboardButton {
atBotShowChannelList: boolean; atBotShowChannelList: boolean;
permissionType: number; permissionType: number;
} }
export interface InlineKeyboardRow { export interface InlineKeyboardRow {
buttons: InlineKeyboardButton[]; buttons: InlineKeyboardButton[];
} }
export interface TofuElementContent { export interface TofuElementContent {
color: string; color: string;
tittle: string; tittle: string;
} }
export interface TaskTopMsgElement { export interface TaskTopMsgElement {
msgTitle: string; msgTitle: string;
msgSummary: string; msgSummary: string;
iconUrl: string; iconUrl: string;
topMsgType: number; topMsgType: number;
} }
export interface SendTaskTopMsgElement { export interface SendTaskTopMsgElement {
elementType: ElementType.TASKTOPMSG; elementType: ElementType.TASKTOPMSG;
elementId: string; elementId: string;
taskTopMsgElement: TaskTopMsgElement; taskTopMsgElement: TaskTopMsgElement;
} }
export interface TofuRecordElement { export interface TofuRecordElement {
type: number; type: number;
busiid: string; busiid: string;
@@ -121,6 +134,7 @@ export interface TofuRecordElement {
msgtime: string; msgtime: string;
onscreennotify: boolean; onscreennotify: boolean;
} }
export interface SendTofuRecordElement { export interface SendTofuRecordElement {
elementType: ElementType.TOFURECORD; elementType: ElementType.TOFURECORD;
elementId: string; elementId: string;
@@ -140,14 +154,16 @@ export interface FaceBubbleElement {
buf: string; buf: string;
compatibleText: string; compatibleText: string;
text: string; text: string;
} };
} }
export interface SendFaceBubbleElement { export interface SendFaceBubbleElement {
elementType: ElementType.FACEBUBBLE; elementType: ElementType.FACEBUBBLE;
elementId: string; elementId: string;
faceBubbleElement: FaceBubbleElement; faceBubbleElement: FaceBubbleElement;
} }
export interface AvRecordElement { export interface AvRecordElement {
type: number; type: number;
time: string; time: string;
@@ -156,66 +172,78 @@ export interface AvRecordElement {
hasRead: boolean; hasRead: boolean;
extraType: number; extraType: number;
} }
export interface SendavRecordElement { export interface SendavRecordElement {
elementType: ElementType.AVRECORD; elementType: ElementType.AVRECORD;
elementId: string; elementId: string;
avRecordElement: AvRecordElement; avRecordElement: AvRecordElement;
} }
export interface YoloUserInfo { export interface YoloUserInfo {
uid: string; uid: string;
result: number; result: number;
rank: number; rank: number;
bizId: string bizId: string;
} }
export interface SendInlineKeyboardElement { export interface SendInlineKeyboardElement {
elementType: ElementType.INLINEKEYBOARD; elementType: ElementType.INLINEKEYBOARD;
elementId: string; elementId: string;
inlineKeyboardElement: { inlineKeyboardElement: {
rows: number; rows: number;
botAppid: string; botAppid: string;
} };
} }
export interface YoloGameResultElement { export interface YoloGameResultElement {
UserInfo: YoloUserInfo[]; UserInfo: YoloUserInfo[];
} }
export interface SendYoloGameResultElement { export interface SendYoloGameResultElement {
elementType: ElementType.YOLOGAMERESULT; elementType: ElementType.YOLOGAMERESULT;
yoloGameResultElement: YoloGameResultElement yoloGameResultElement: YoloGameResultElement;
} }
export interface GiphyElement { export interface GiphyElement {
id: string; id: string;
isClip: boolean; isClip: boolean;
width: number; width: number;
height: number; height: number;
} }
export interface SendGiphyElement { export interface SendGiphyElement {
elementType: ElementType.GIPHY; elementType: ElementType.GIPHY;
elementId: string; elementId: string;
giphyElement: GiphyElement; giphyElement: GiphyElement;
} }
export interface SendWalletElement { export interface SendWalletElement {
elementType: ElementType.UNKNOWN;//不做 设置位置 elementType: ElementType.UNKNOWN;//不做 设置位置
elementId: string; elementId: string;
walletElement: {} walletElement: Record<string, never>;
} }
export interface CalendarElement { export interface CalendarElement {
summary: string; summary: string;
msg: string; msg: string;
expireTimeMs: string; expireTimeMs: string;
schemaType: number; schemaType: number;
schema: string schema: string;
} }
export interface SendCalendarElement { export interface SendCalendarElement {
elementType: ElementType.CALENDAR; elementType: ElementType.CALENDAR;
elementId: string; elementId: string;
calendarElement: CalendarElement; calendarElement: CalendarElement;
} }
export interface SendliveGiftElement { export interface SendliveGiftElement {
elementType: ElementType.LIVEGIFT; elementType: ElementType.LIVEGIFT;
elementId: string; elementId: string;
liveGiftElement: {} liveGiftElement: Record<string, never>;
} }
export interface SendTextElement { export interface SendTextElement {
elementType: ElementType.TEXT; elementType: ElementType.TEXT;
elementId: string; elementId: string;
@@ -261,18 +289,20 @@ export enum PicSubType {
export interface SendPicElement { export interface SendPicElement {
elementType: ElementType.PIC; elementType: ElementType.PIC;
elementId: string; elementId: string;
picElement:PicElement picElement: PicElement;
} }
export interface ReplyElement { export interface ReplyElement {
replayMsgSeq: string; replayMsgSeq: string;
replayMsgId: string; replayMsgId: string;
senderUin: string; senderUin: string;
senderUinStr: string; senderUinStr: string;
} }
export interface SendReplyElement { export interface SendReplyElement {
elementType: ElementType.REPLY; elementType: ElementType.REPLY;
elementId: string; elementId: string;
replyElement: ReplyElement replyElement: ReplyElement;
} }
export interface SendFaceElement { export interface SendFaceElement {
@@ -285,27 +315,32 @@ export interface SendMarketFaceElement {
elementType: ElementType.MFACE; elementType: ElementType.MFACE;
marketFaceElement: MarketFaceElement; marketFaceElement: MarketFaceElement;
} }
export interface SendstructLongMsgElement { export interface SendstructLongMsgElement {
elementType: ElementType.STRUCTLONGMSG; elementType: ElementType.STRUCTLONGMSG;
elementId: string; elementId: string;
structLongMsgElement: StructLongMsgElement; structLongMsgElement: StructLongMsgElement;
} }
export interface StructLongMsgElement { export interface StructLongMsgElement {
xmlContent: string; xmlContent: string;
resId: string; resId: string;
} }
export interface SendactionBarElement { export interface SendactionBarElement {
elementType: ElementType.ACTIONBAR; elementType: ElementType.ACTIONBAR;
elementId: string; elementId: string;
actionBarElement: { actionBarElement: {
rows: number; rows: number;
botAppid: string; botAppid: string;
} };
} }
export interface ShareLocationElement { export interface ShareLocationElement {
text: string; text: string;
ext: string; ext: string;
} }
export interface sendShareLocationElement { export interface sendShareLocationElement {
elementType: ElementType.SHARELOCATION; elementType: ElementType.SHARELOCATION;
elementId: string; elementId: string;
@@ -327,7 +362,7 @@ export interface FileElement {
fileUuid?: string; fileUuid?: string;
fileSubId?: string; fileSubId?: string;
thumbFileSize?: number; thumbFileSize?: number;
fileBizId?: number fileBizId?: number;
} }
export interface SendFileElement { export interface SendFileElement {
@@ -353,6 +388,7 @@ export interface SendMarkdownElement {
elementId: string; elementId: string;
markdownElement: MarkdownElement; markdownElement: MarkdownElement;
} }
export type SendMessageElement = SendTextElement | SendPttElement | export type SendMessageElement = SendTextElement | SendPttElement |
SendPicElement | SendReplyElement | SendFaceElement | SendMarketFaceElement | SendFileElement | SendPicElement | SendReplyElement | SendFaceElement | SendMarketFaceElement | SendFileElement |
SendVideoElement | SendArkElement | SendMarkdownElement | sendShareLocationElement; SendVideoElement | SendArkElement | SendMarkdownElement | sendShareLocationElement;
@@ -364,6 +400,7 @@ export interface TextElement {
atTinyId: string; atTinyId: string;
atNtUid: string; atNtUid: string;
} }
export interface MessageElement { export interface MessageElement {
elementType: ElementType, elementType: ElementType,
elementId: string, elementId: string,
@@ -395,9 +432,10 @@ export interface MessageElement {
tofuRecordElement?: TofuRecordElement, tofuRecordElement?: TofuRecordElement,
taskTopMsgElement?: TaskTopMsgElement, taskTopMsgElement?: TaskTopMsgElement,
recommendedMsgElement?: RecommendedMsgElement, recommendedMsgElement?: RecommendedMsgElement,
actionBarElement?:ActionBarElement actionBarElement?: ActionBarElement
} }
export enum AtType { export enum AtType {
notAt = 0, notAt = 0,
atAll = 1, atAll = 1,
@@ -411,6 +449,7 @@ export enum ChatType {
temp = 100 temp = 100
} }
// 来自Android分析 // 来自Android分析
export enum ChatType2 { export enum ChatType2 {
KCHATTYPEADELIE = 42, KCHATTYPEADELIE = 42,
@@ -520,7 +559,7 @@ export interface GrayTipElement {
operatorRemark: string; operatorRemark: string;
operatorMemRemark?: string; operatorMemRemark?: string;
wording: string; // 自定义的撤回提示语 wording: string; // 自定义的撤回提示语
} };
aioOpGrayTipElement: TipAioOpGrayTipElement; aioOpGrayTipElement: TipAioOpGrayTipElement;
groupElement: TipGroupElement; groupElement: TipGroupElement;
xmlElement: { xmlElement: {
@@ -538,10 +577,12 @@ export enum FaceType {
normal2 = 2, // 新小黄脸, 从faceIndex 222开始 normal2 = 2, // 新小黄脸, 从faceIndex 222开始
dice = 3 // 骰子 dice = 3 // 骰子
} }
export enum FaceIndex { export enum FaceIndex {
dice = 358, dice = 358,
RPS = 359 // 石头剪刀布 RPS = 359 // 石头剪刀布
} }
export interface FaceElement { export interface FaceElement {
faceIndex: number; faceIndex: number;
faceType: FaceType; faceType: FaceType;
@@ -566,7 +607,7 @@ export interface VideoElement {
filePath: string; filePath: string;
fileName: string; fileName: string;
videoMd5?: string; videoMd5?: string;
thumbMd5?: string thumbMd5?: string;
fileTime?: number; // second fileTime?: number; // second
thumbSize?: number; // byte thumbSize?: number; // byte
fileFormat?: viedo_type; // 2表示mp4 参考下面条目 fileFormat?: viedo_type; // 2表示mp4 参考下面条目
@@ -586,6 +627,7 @@ export interface VideoElement {
import_rich_media_context?: null; import_rich_media_context?: null;
sourceVideoCodecFormat?: number; sourceVideoCodecFormat?: number;
} }
// export enum busiType{ // export enum busiType{
// public static final int CREATOR_SHARE_ADV_XWORLD = 21; // public static final int CREATOR_SHARE_ADV_XWORLD = 21;
// public static final int MINI_APP_MINI_GAME = 11; // public static final int MINI_APP_MINI_GAME = 11;
@@ -633,6 +675,7 @@ export enum viedo_type {
VIDEO_FORMAT_TS = 10, VIDEO_FORMAT_TS = 10,
VIDEO_FORMAT_WMV = 3, VIDEO_FORMAT_WMV = 3,
} }
export interface MarkdownElement { export interface MarkdownElement {
content: string; content: string;
} }
@@ -653,7 +696,7 @@ export interface InlineKeyboardElementRowButton {
isReply: false; isReply: false;
anchor: 0; anchor: 0;
enter: false; enter: false;
subscribeDataTemplateIds: [] subscribeDataTemplateIds: [];
} }
export interface InlineKeyboardElement { export interface InlineKeyboardElement {
@@ -673,6 +716,7 @@ export enum TipGroupElementType {
kicked = 3, // 被移出群 kicked = 3, // 被移出群
ban = 8 ban = 8
} }
// public final class MemberAddShowType { // public final class MemberAddShowType {
// public static final int KOTHERADD = 0; // public static final int KOTHERADD = 0;
// public static final int KOTHERADDBYOTHERQRCODE = 2; // public static final int KOTHERADDBYOTHERQRCODE = 2;
@@ -720,7 +764,7 @@ export interface TipGroupElement {
name: string; name: string;
role: GroupMemberRole role: GroupMemberRole
} }
} };
} }
export interface MultiForwardMsgElement { export interface MultiForwardMsgElement {
@@ -731,7 +775,7 @@ export interface MultiForwardMsgElement {
export interface RawMessage { export interface RawMessage {
parentMsgPeer: Peer; parentMsgPeer: Peer;
parentMsgIdList:string[]; parentMsgIdList: string[];
id?: number;//扩展字段 用于处理OB11 ID id?: number;//扩展字段 用于处理OB11 ID
guildId: string; guildId: string;
msgRandom: string; msgRandom: string;

View File

@@ -38,13 +38,14 @@ export interface GroupNotify {
}; };
postscript: string; // 加群用户填写的验证信息 postscript: string; // 加群用户填写的验证信息
repeatSeqs: []; repeatSeqs: [];
warningTips: string warningTips: string;
} }
export enum GroupRequestOperateTypes { export enum GroupRequestOperateTypes {
approve = 1, approve = 1,
reject = 2 reject = 2
} }
export enum BuddyReqType { export enum BuddyReqType {
KMEINITIATOR, KMEINITIATOR,
KPEERINITIATOR, KPEERINITIATOR,
@@ -61,6 +62,7 @@ export enum BuddyReqType {
KMSGINFO, KMSGINFO,
KMEINITIATORWAITPEERCONFIRM KMEINITIATORWAITPEERCONFIRM
} }
export interface FriendRequest { export interface FriendRequest {
isInitiator?: boolean; isInitiator?: boolean;
isDecide: boolean; isDecide: boolean;
@@ -78,21 +80,23 @@ export interface FriendRequestNotify {
unreadNums: number; unreadNums: number;
buddyReqs: FriendRequest[]; buddyReqs: FriendRequest[];
} }
export enum MemberExtSourceType { export enum MemberExtSourceType {
DEFAULTTYPE = 0, DEFAULTTYPE = 0,
TITLETYPE = 1, TITLETYPE = 1,
NEWGROUPTYPE = 2, NEWGROUPTYPE = 2,
} }
export interface GroupExtParam { export interface GroupExtParam {
groupCode: string groupCode: string;
seq: string seq: string;
beginUin: string beginUin: string;
dataTime: string dataTime: string;
uinList: Array<string> uinList: Array<string>;
uinNum: string uinNum: string;
groupType: string groupType: string;
richCardNameVer: string richCardNameVer: string;
sourceType: MemberExtSourceType sourceType: MemberExtSourceType;
memberExtFilter: { memberExtFilter: {
memberLevelInfoUin: number memberLevelInfoUin: number
memberLevelInfoPoint: number memberLevelInfoPoint: number
@@ -112,5 +116,5 @@ export interface GroupExtParam {
cmdUinFlagExt3Grocery: number cmdUinFlagExt3Grocery: number
memberIcon: number memberIcon: number
memberInfoSeq: number memberInfoSeq: number
} };
} }

View File

@@ -11,6 +11,7 @@ export interface CustomMusicSignPostData {
image?: string, image?: string,
singer?: string singer?: string
} }
export interface MiniAppLuaJsonType { export interface MiniAppLuaJsonType {
prompt: string, prompt: string,
title: string, title: string,
@@ -20,4 +21,4 @@ export interface MiniAppLuaJsonType {
tagIcon: string, tagIcon: string,
source: string, source: string,
sourcelogo: string, sourcelogo: string,
} }

View File

@@ -1,15 +1,17 @@
import { SelfInfo } from "./user"; import { SelfInfo } from './user';
export interface LineDevice { export interface LineDevice {
instanceId: number instanceId: number;
clientType: number clientType: number;
devUid: string devUid: string;
} }
export interface OBLineDevice { export interface OBLineDevice {
app_id: string; app_id: string;
device_name: string; device_name: string;
device_kind: string; device_kind: string;
} }
export interface CoreCache { export interface CoreCache {
selfInfo: SelfInfo, selfInfo: SelfInfo,
DeviceList: OBLineDevice[] DeviceList: OBLineDevice[]

View File

@@ -3,12 +3,14 @@ export enum Sex {
female = 2, female = 2,
unknown = 255, unknown = 255,
} }
export interface BuddyCategoryType { export interface BuddyCategoryType {
categoryId: number; categoryId: number;
categroyName: string; categroyName: string;
categroyMbCount: number; categroyMbCount: number;
buddyList: User[]; buddyList: User[];
} }
export interface CoreInfo { export interface CoreInfo {
uid: string; uid: string;
uin: string; uin: string;
@@ -173,20 +175,23 @@ export interface SimpleInfo {
otherFlags: any | null; otherFlags: any | null;
intimate: any | null; intimate: any | null;
} }
export interface FriendV2 extends SimpleInfo { export interface FriendV2 extends SimpleInfo {
categoryId?: number; categoryId?: number;
categroyName?: string; categroyName?: string;
} }
export interface SelfStatusInfo { export interface SelfStatusInfo {
uid: string uid: string;
status: number status: number;
extStatus: number extStatus: number;
termType: number termType: number;
netType: number netType: number;
iconType: number iconType: number;
customStatus: any customStatus: any;
setTime: string setTime: string;
} }
export interface UserDetailInfoListenerArg { export interface UserDetailInfoListenerArg {
uid: string; uid: string;
uin: string; uin: string;
@@ -194,6 +199,7 @@ export interface UserDetailInfoListenerArg {
commonExt: CommonExt; commonExt: CommonExt;
photoWall: PhotoWall; photoWall: PhotoWall;
} }
export interface ModifyProfileParams { export interface ModifyProfileParams {
nick: string, nick: string,
longNick: string, longNick: string,
@@ -212,11 +218,12 @@ export interface BuddyProfileLikeReq {
start: number; start: number;
limit: number; limit: number;
} }
export interface QQLevel { export interface QQLevel {
crownNum: number; crownNum: number;
sunNum: number; sunNum: number;
moonNum: number; moonNum: number;
starNum: number starNum: number;
} }
export interface User { export interface User {
@@ -228,7 +235,7 @@ export interface User {
remark?: string; remark?: string;
sex?: Sex; sex?: Sex;
qqLevel?: QQLevel; qqLevel?: QQLevel;
qid?: string qid?: string;
birthday_year?: number; birthday_year?: number;
birthday_month?: number; birthday_month?: number;
birthday_day?: number; birthday_day?: number;
@@ -239,7 +246,7 @@ export interface User {
homeTown?: string; //"0-0-0"; homeTown?: string; //"0-0-0";
makeFriendCareer?: number; makeFriendCareer?: number;
pos?: string; pos?: string;
eMail?: string eMail?: string;
phoneNum?: string; phoneNum?: string;
college?: string; college?: string;
country?: string; country?: string;
@@ -281,12 +288,14 @@ export interface SelfInfo extends User {
online?: boolean; online?: boolean;
} }
export interface Friend extends User { } export interface Friend extends User {
}
export enum BizKey { export enum BizKey {
KPRIVILEGEICON, KPRIVILEGEICON,
KPHOTOWALL KPHOTOWALL
} }
export interface UserDetailInfoByUinV2 { export interface UserDetailInfoByUinV2 {
result: number, result: number,
errMsg: string, errMsg: string,
@@ -298,6 +307,7 @@ export interface UserDetailInfoByUinV2 {
photoWall: null photoWall: null
} }
} }
export interface UserDetailInfoByUin { export interface UserDetailInfoByUin {
result: number, result: number,
errMsg: string, errMsg: string,

View File

@@ -21,41 +21,44 @@ export enum WebHonorType {
*/ */
EMOTION = 'emotion' EMOTION = 'emotion'
} }
export interface WebApiGroupMember { export interface WebApiGroupMember {
uin: number uin: number;
role: number role: number;
g: number g: number;
join_time: number join_time: number;
last_speak_time: number last_speak_time: number;
lv: { lv: {
point: number point: number
level: number level: number
} };
card: string card: string;
tags: string tags: string;
flag: number flag: number;
nick: string nick: string;
qage: number qage: number;
rm: number rm: number;
} }
export interface WebApiGroupMemberRet { export interface WebApiGroupMemberRet {
ec: number ec: number;
errcode: number errcode: number;
em: string em: string;
cache: number cache: number;
adm_num: number adm_num: number;
levelname: any levelname: any;
mems: WebApiGroupMember[] mems: WebApiGroupMember[];
count: number count: number;
svr_time: number svr_time: number;
max_count: number max_count: number;
search_count: number search_count: number;
extmode: number extmode: number;
} }
export interface WebApiGroupNoticeFeed { export interface WebApiGroupNoticeFeed {
u: number//发送者 u: number;//发送者
fid: string//fid fid: string;//fid
pubt: number//时间 pubt: number;//时间
msg: { msg: {
text: string text: string
text_face: string text_face: string
@@ -65,21 +68,22 @@ export interface WebApiGroupNoticeFeed {
w: string, w: string,
h: string h: string
}[] }[]
} };
type: number type: number;
fn: number fn: number;
cn: number cn: number;
vn: number vn: number;
settings: { settings: {
is_show_edit_card: number is_show_edit_card: number
remind_ts: number remind_ts: number
tip_window_type: number tip_window_type: number
confirm_required: number confirm_required: number
} };
read_num: number read_num: number;
is_read: number is_read: number;
is_all_confirm: number is_all_confirm: number;
} }
export interface WebApiGroupNoticeRet { export interface WebApiGroupNoticeRet {
ec: number ec: number
em: string em: string
@@ -100,26 +104,28 @@ export interface WebApiGroupNoticeRet {
svrt: number svrt: number
ad: number ad: number
} }
export interface GroupEssenceMsg { export interface GroupEssenceMsg {
group_code: string group_code: string;
msg_seq: number msg_seq: number;
msg_random: number msg_random: number;
sender_uin: string sender_uin: string;
sender_nick: string sender_nick: string;
sender_time: number sender_time: number;
add_digest_uin: string add_digest_uin: string;
add_digest_nick: string add_digest_nick: string;
add_digest_time: number add_digest_time: number;
msg_content: any[] msg_content: any[];
can_be_removed: true can_be_removed: true;
} }
export interface GroupEssenceMsgRet { export interface GroupEssenceMsgRet {
retcode: number retcode: number;
retmsg: string retmsg: string;
data: { data: {
msg_list: GroupEssenceMsg[] msg_list: GroupEssenceMsg[]
is_end: boolean is_end: boolean
group_role: number group_role: number
config_page_url: string config_page_url: string
} };
} }

View File

@@ -9,16 +9,18 @@ interface ServerRkeyData {
export class RkeyManager { export class RkeyManager {
serverUrl: string = ''; serverUrl: string = '';
logger: LogWrapper;
private rkeyData: ServerRkeyData = { private rkeyData: ServerRkeyData = {
group_rkey: '', group_rkey: '',
private_rkey: '', private_rkey: '',
expired_time: 0 expired_time: 0,
}; };
logger: LogWrapper;
constructor(serverUrl: string, logger: LogWrapper) { constructor(serverUrl: string, logger: LogWrapper) {
this.logger = logger; this.logger = logger;
this.serverUrl = serverUrl; this.serverUrl = serverUrl;
} }
async getRkey() { async getRkey() {
if (this.isExpired()) { if (this.isExpired()) {
try { try {
@@ -35,6 +37,7 @@ export class RkeyManager {
// console.log(`now: ${now}, expired_time: ${this.rkeyData.expired_time}`); // console.log(`now: ${now}, expired_time: ${this.rkeyData.expired_time}`);
return now > this.rkeyData.expired_time; return now > this.rkeyData.expired_time;
} }
async refreshRkey(): Promise<any> { async refreshRkey(): Promise<any> {
//刷新rkey //刷新rkey
this.rkeyData = await RequestUtil.HttpGetJson<ServerRkeyData>(this.serverUrl, 'GET'); this.rkeyData = await RequestUtil.HttpGetJson<ServerRkeyData>(this.serverUrl, 'GET');

View File

@@ -49,6 +49,7 @@ export class BuddyListener implements IBuddyListener {
onBuddyListChangedV2(arg: unknown): void { onBuddyListChangedV2(arg: unknown): void {
//throw new Error('Method not implemented.'); //throw new Error('Method not implemented.');
} }
onAddBuddyNeedVerify(arg: unknown) { onAddBuddyNeedVerify(arg: unknown) {
} }

View File

@@ -9,19 +9,25 @@ export interface IKernelFileAssistantListener {
onFileSearch(...args: unknown[]): unknown; onFileSearch(...args: unknown[]): unknown;
} }
export interface NodeIKernelFileAssistantListener extends IKernelFileAssistantListener { export interface NodeIKernelFileAssistantListener extends IKernelFileAssistantListener {
// eslint-disable-next-line @typescript-eslint/no-misused-new // eslint-disable-next-line @typescript-eslint/no-misused-new
new(adapter: IKernelFileAssistantListener): NodeIKernelFileAssistantListener; new(adapter: IKernelFileAssistantListener): NodeIKernelFileAssistantListener;
} }
export class KernelFileAssistantListener implements IKernelFileAssistantListener { export class KernelFileAssistantListener implements IKernelFileAssistantListener {
onFileStatusChanged(...args: unknown[]) { } onFileStatusChanged(...args: unknown[]) {
}
onSessionListChanged(...args: unknown[]) { } onSessionListChanged(...args: unknown[]) {
}
onSessionChanged(...args: unknown[]) { } onSessionChanged(...args: unknown[]) {
}
onFileListChanged(...args: unknown[]) { } onFileListChanged(...args: unknown[]) {
}
onFileSearch(...args: unknown[]) { } onFileSearch(...args: unknown[]) {
}
} }

View File

@@ -52,6 +52,7 @@ interface IGroupListener {
onJoinGroupNoVerifyFlag(...args: unknown[]): void; onJoinGroupNoVerifyFlag(...args: unknown[]): void;
onGroupArkInviteStateResult(...args: unknown[]): void; onGroupArkInviteStateResult(...args: unknown[]): void;
// 发现于Win 9.9.9 23159 // 发现于Win 9.9.9 23159
onGroupMemberLevelInfoChange(...args: unknown[]): void; onGroupMemberLevelInfoChange(...args: unknown[]): void;
} }
@@ -66,6 +67,7 @@ export class GroupListener implements IGroupListener {
onGroupMemberLevelInfoChange(...args: unknown[]): void { onGroupMemberLevelInfoChange(...args: unknown[]): void {
} }
onGetGroupBulletinListResult(...args: unknown[]) { onGetGroupBulletinListResult(...args: unknown[]) {
} }
@@ -146,6 +148,7 @@ export class DebugGroupListener implements IGroupListener {
onGroupMemberLevelInfoChange(...args: unknown[]): void { onGroupMemberLevelInfoChange(...args: unknown[]): void {
console.log('onGroupMemberLevelInfoChange:', ...args); console.log('onGroupMemberLevelInfoChange:', ...args);
} }
onGetGroupBulletinListResult(...args: unknown[]) { onGetGroupBulletinListResult(...args: unknown[]) {
console.log('onGetGroupBulletinListResult:', ...args); console.log('onGetGroupBulletinListResult:', ...args);
} }

View File

@@ -22,16 +22,18 @@ export interface OnRichMediaDownloadCompleteParams {
userTotalSpacePerDay: unknown | null, userTotalSpacePerDay: unknown | null,
userUsedSpacePerDay: unknown | null userUsedSpacePerDay: unknown | null
} }
export interface onGroupFileInfoUpdateParamType { export interface onGroupFileInfoUpdateParamType {
retCode: number retCode: number;
retMsg: string retMsg: string;
clientWording: string clientWording: string;
isEnd: boolean isEnd: boolean;
item: Array<any> item: Array<any>;
allFileCount: string allFileCount: string;
nextIndex: string nextIndex: string;
reqId: string reqId: string;
} }
// { // {
// sessionType: 1, // sessionType: 1,
// chatType: 100, // chatType: 100,
@@ -49,6 +51,7 @@ export interface TempOnRecvParams {
sig: string, sig: string,
} }
export interface IKernelMsgListener { export interface IKernelMsgListener {
onAddSendMsg(msgRecord: RawMessage): void; onAddSendMsg(msgRecord: RawMessage): void;
@@ -505,6 +508,7 @@ export class MsgListener implements IKernelMsgListener {
onRedTouchChanged(...args: unknown[]) { onRedTouchChanged(...args: unknown[]) {
} }
// 第一次发现于Win 9.9.9-23159 // 第一次发现于Win 9.9.9-23159
onBroadcastHelperProgerssUpdate(...args: unknown[]) { onBroadcastHelperProgerssUpdate(...args: unknown[]) {

View File

@@ -2,7 +2,9 @@ import { User, UserDetailInfoListenerArg } from '@/core/entities';
interface IProfileListener { interface IProfileListener {
onProfileSimpleChanged(...args: unknown[]): void; onProfileSimpleChanged(...args: unknown[]): void;
onUserDetailInfoChanged(arg: UserDetailInfoListenerArg): void; onUserDetailInfoChanged(arg: UserDetailInfoListenerArg): void;
onProfileDetailInfoChanged(profile: User): void; onProfileDetailInfoChanged(profile: User): void;
onStatusUpdate(...args: unknown[]): void; onStatusUpdate(...args: unknown[]): void;
@@ -21,6 +23,7 @@ export class ProfileListener implements IProfileListener {
onUserDetailInfoChanged(arg: UserDetailInfoListenerArg): void { onUserDetailInfoChanged(arg: UserDetailInfoListenerArg): void {
} }
onProfileSimpleChanged(...args: unknown[]) { onProfileSimpleChanged(...args: unknown[]) {
} }

View File

@@ -1,5 +1,3 @@
export interface IKernelRobotListener { export interface IKernelRobotListener {
onRobotFriendListChanged(...args: unknown[]): void; onRobotFriendListChanged(...args: unknown[]): void;
@@ -14,15 +12,15 @@ export interface NodeIKernelRobotListener extends IKernelRobotListener {
} }
export class KernelRobotListener implements IKernelRobotListener { export class KernelRobotListener implements IKernelRobotListener {
onRobotFriendListChanged(...args: unknown[]){ onRobotFriendListChanged(...args: unknown[]) {
} }
onRobotListChanged(...args: unknown[]){ onRobotListChanged(...args: unknown[]) {
} }
onRobotProfileChanged(...args: unknown[]){ onRobotProfileChanged(...args: unknown[]) {
} }
} }

View File

@@ -10,6 +10,7 @@ export interface IStorageCleanListener {
onChatCleanDone(args: unknown): void; onChatCleanDone(args: unknown): void;
} }
export interface NodeIKernelStorageCleanListener extends IStorageCleanListener { export interface NodeIKernelStorageCleanListener extends IStorageCleanListener {
// eslint-disable-next-line @typescript-eslint/no-misused-new // eslint-disable-next-line @typescript-eslint/no-misused-new
new(adapter: IStorageCleanListener): NodeIKernelStorageCleanListener; new(adapter: IStorageCleanListener): NodeIKernelStorageCleanListener;
@@ -27,6 +28,7 @@ export class StorageCleanListener implements IStorageCleanListener {
onCleanCacheStorageChanged(args: unknown) { onCleanCacheStorageChanged(args: unknown) {
} }
onFinishScan(args: unknown) { onFinishScan(args: unknown) {
} }

View File

@@ -1,5 +1,6 @@
export interface IKernelTicketListener { export interface IKernelTicketListener {
} }
export interface NodeIKernelTicketListener extends IKernelTicketListener { export interface NodeIKernelTicketListener extends IKernelTicketListener {
// eslint-disable-next-line @typescript-eslint/no-misused-new // eslint-disable-next-line @typescript-eslint/no-misused-new
new(adapter: IKernelTicketListener): NodeIKernelTicketListener; new(adapter: IKernelTicketListener): NodeIKernelTicketListener;

View File

@@ -1,4 +1,3 @@
export * from './NodeIKernelSessionListener'; export * from './NodeIKernelSessionListener';
export * from './NodeIKernelLoginListener'; export * from './NodeIKernelLoginListener';
export * from './NodeIKernelMsgListener'; export * from './NodeIKernelMsgListener';

View File

@@ -1,10 +1,11 @@
import { Friend } from '@/core/entities';
import { GeneralCallResult } from '@/core/services/common'; import { GeneralCallResult } from '@/core/services/common';
import { NodeIKernelBuddyListener } from '@/core/listeners'; import { NodeIKernelBuddyListener } from '@/core/listeners';
export enum BuddyListReqType { export enum BuddyListReqType {
KNOMAL, KNOMAL,
KLETTER KLETTER
} }
export interface NodeIKernelBuddyService { export interface NodeIKernelBuddyService {
// 26702 以上 // 26702 以上
getBuddyListV2(callFrom: string, reqType: BuddyListReqType): Promise<GeneralCallResult & { getBuddyListV2(callFrom: string, reqType: BuddyListReqType): Promise<GeneralCallResult & {
@@ -17,6 +18,7 @@ export interface NodeIKernelBuddyService {
buddyUids: Array<string> buddyUids: Array<string>
}> }>
}>; }>;
//26702 以上 //26702 以上
getBuddyListFromCache(callFrom: string): Promise<Array< getBuddyListFromCache(callFrom: string): Promise<Array<
{ {
@@ -27,6 +29,7 @@ export interface NodeIKernelBuddyService {
onlineCount: number,//在线数目 onlineCount: number,//在线数目
buddyUids: Array<string>//Uids buddyUids: Array<string>//Uids
}>>; }>>;
// 以下为原生方法 // 以下为原生方法
addKernelBuddyListener(listener: NodeIKernelBuddyListener): number; addKernelBuddyListener(listener: NodeIKernelBuddyListener): number;

View File

@@ -1,4 +1,4 @@
import { GeneralCallResult } from "./common"; import { GeneralCallResult } from './common';
export interface NodeIKernelCollectionService { export interface NodeIKernelCollectionService {
addKernelCollectionListener(...args: any[]): unknown;//needs 1 arguments addKernelCollectionListener(...args: any[]): unknown;//needs 1 arguments

View File

@@ -1,5 +1,7 @@
export interface NodeIKernelDbToolsService { export interface NodeIKernelDbToolsService {
depositDatabase(...args: unknown[]): unknown; depositDatabase(...args: unknown[]): unknown;
backupDatabase(...args: unknown[]): unknown; backupDatabase(...args: unknown[]): unknown;
retrieveDatabase(...args: unknown[]): unknown; retrieveDatabase(...args: unknown[]): unknown;
} }

View File

@@ -1,3 +1,3 @@
export interface NodeIKernelECDHService{ export interface NodeIKernelECDHService {
} }

View File

@@ -29,8 +29,10 @@ export interface NodeIKernelGroupService {
onlineFlag: string, onlineFlag: string,
realSpecialTitleFlag: number realSpecialTitleFlag: number
}): Promise<unknown>; }): Promise<unknown>;
//26702 //26702
getGroupMemberLevelInfo(groupCode: string): Promise<unknown>; getGroupMemberLevelInfo(groupCode: string): Promise<unknown>;
//26702 //26702
getGroupHonorList(groupCodes: Array<string>): unknown; getGroupHonorList(groupCodes: Array<string>): unknown;
@@ -45,6 +47,7 @@ export interface NodeIKernelGroupService {
errMsg: string, errMsg: string,
uids: Map<string, string> uids: Map<string, string>
}>; }>;
//26702(其实更早 但是我不知道) //26702(其实更早 但是我不知道)
checkGroupMemberCache(arrayList: Array<string>): Promise<unknown>; checkGroupMemberCache(arrayList: Array<string>): Promise<unknown>;
@@ -70,12 +73,20 @@ export interface NodeIKernelGroupService {
brief: string brief: string
} }
}): Promise<unknown>; }): Promise<unknown>;
//26702(其实更早 但是我不知道) //26702(其实更早 但是我不知道)
isEssenceMsg(Req: { groupCode: string, msgRandom: number, msgSeq: number }): Promise<unknown>; isEssenceMsg(Req: { groupCode: string, msgRandom: number, msgSeq: number }): Promise<unknown>;
//26702(其实更早 但是我不知道) //26702(其实更早 但是我不知道)
queryCachedEssenceMsg(Req: { groupCode: string, msgRandom: number, msgSeq: number }): Promise<unknown>; queryCachedEssenceMsg(Req: { groupCode: string, msgRandom: number, msgSeq: number }): Promise<unknown>;
//26702(其实更早 但是我不知道) //26702(其实更早 但是我不知道)
fetchGroupEssenceList(Req: { groupCode: string, pageStart: number, pageLimit: number }, Arg: unknown): Promise<unknown>; fetchGroupEssenceList(Req: {
groupCode: string,
pageStart: number,
pageLimit: number
}, Arg: unknown): Promise<unknown>;
//26702 //26702
getAllMemberList(groupCode: string, forceFetch: boolean): Promise<{ getAllMemberList(groupCode: string, forceFetch: boolean): Promise<{
errCode: number, errCode: number,
@@ -99,7 +110,8 @@ export interface NodeIKernelGroupService {
createMemberListScene(groupCode: string, scene: string): string; createMemberListScene(groupCode: string, scene: string): string;
destroyMemberListScene(SceneId:string): void; destroyMemberListScene(SceneId: string): void;
//About Arg (a) name: lastId 根据手Q来看为object {index:?(number),uid:string} //About Arg (a) name: lastId 根据手Q来看为object {index:?(number),uid:string}
getNextMemberList(sceneId: string, a: undefined, num: number): Promise<{ getNextMemberList(sceneId: string, a: undefined, num: number): Promise<{
errCode: number, errMsg: string, errCode: number, errMsg: string,
@@ -113,6 +125,7 @@ export interface NodeIKernelGroupService {
searchMember(sceneId: string, keywords: string[]): unknown; searchMember(sceneId: string, keywords: string[]): unknown;
getMemberInfo(group_id: string, uids: string[], forceFetch: boolean): Promise<GeneralCallResult>; getMemberInfo(group_id: string, uids: string[], forceFetch: boolean): Promise<GeneralCallResult>;
//getMemberInfo [ '56729xxxx', [ 'u_4Nj08cwW5Hxxxxx' ], true ] //getMemberInfo [ '56729xxxx', [ 'u_4Nj08cwW5Hxxxxx' ], true ]
kickMember(groupCode: string, memberUids: string[], refuseForever: boolean, kickReason: string): Promise<void>; kickMember(groupCode: string, memberUids: string[], refuseForever: boolean, kickReason: string): Promise<void>;
@@ -166,6 +179,7 @@ export interface NodeIKernelGroupService {
quitGroup(groupCode: string): void; quitGroup(groupCode: string): void;
destroyGroup(groupCode: string): void; destroyGroup(groupCode: string): void;
//获取单屏群通知列表 //获取单屏群通知列表
getSingleScreenNotifies(force: boolean, start_seq: string, num: number): Promise<GeneralCallResult>; getSingleScreenNotifies(force: boolean, start_seq: string, num: number): Promise<GeneralCallResult>;
@@ -238,6 +252,7 @@ export interface NodeIKernelGroupService {
msgRandom: number, msgRandom: number,
msgSeq: number msgSeq: number
}): Promise<unknown>; }): Promise<unknown>;
//需要提前判断是否存在 高版本新增 //需要提前判断是否存在 高版本新增
removeGroupEssence(param: { removeGroupEssence(param: {
groupCode: string groupCode: string

View File

@@ -44,8 +44,8 @@ export interface LoginListItem {
isAutoLogin: boolean; // 是否可以自动登录 isAutoLogin: boolean; // 是否可以自动登录
} }
export interface QuickLoginResult{ export interface QuickLoginResult {
result: string result: string;
loginErrorInfo: { loginErrorInfo: {
step: number, step: number,
errMsg: string, errMsg: string,
@@ -55,7 +55,7 @@ export interface QuickLoginResult{
jumpWord: string, jumpWord: string,
tipsTitle: string, tipsTitle: string,
tipsContent: string tipsContent: string
} };
} }
export interface NodeIKernelLoginService { export interface NodeIKernelLoginService {
@@ -63,6 +63,7 @@ export interface NodeIKernelLoginService {
new(): NodeIKernelLoginService; new(): NodeIKernelLoginService;
addKernelLoginListener(listener: NodeIKernelLoginListener): number; addKernelLoginListener(listener: NodeIKernelLoginListener): number;
removeKernelLoginListener(listener: number): void; removeKernelLoginListener(listener: number): void;
initConfig(config: LoginInitConfig): void; initConfig(config: LoginInitConfig): void;

View File

@@ -12,6 +12,7 @@ export interface QueryMsgsParams {
isReverseOrder: boolean, isReverseOrder: boolean,
isIncludeCurrent: boolean isIncludeCurrent: boolean
} }
export interface NodeIKernelMsgService { export interface NodeIKernelMsgService {
generateMsgUniqueId(chatType: number, time: string): string; generateMsgUniqueId(chatType: number, time: string): string;
@@ -107,6 +108,7 @@ export interface NodeIKernelMsgService {
forwardRichMsgInVist(...args: unknown[]): unknown; forwardRichMsgInVist(...args: unknown[]): unknown;
forwardFile(...args: unknown[]): unknown; forwardFile(...args: unknown[]): unknown;
//Array<Msg>, Peer from, Peer to //Array<Msg>, Peer from, Peer to
multiForwardMsg(...args: unknown[]): unknown; multiForwardMsg(...args: unknown[]): unknown;
@@ -179,9 +181,13 @@ export interface NodeIKernelMsgService {
appid: unknown appid: unknown
}): Promise<GeneralCallResult & { msgList: RawMessage[] }>; }): Promise<GeneralCallResult & { msgList: RawMessage[] }>;
getMsgsBySeqRange(peer: Peer, startSeq: string, endSeq: string): Promise<GeneralCallResult & { msgList: RawMessage[] }>; getMsgsBySeqRange(peer: Peer, startSeq: string, endSeq: string): Promise<GeneralCallResult & {
msgList: RawMessage[]
}>;
getMsgsBySeqAndCount(peer: Peer, seq: string, count: number, desc: boolean, unknownArg: boolean): Promise<GeneralCallResult & { msgList: RawMessage[] }>; getMsgsBySeqAndCount(peer: Peer, seq: string, count: number, desc: boolean, unknownArg: boolean): Promise<GeneralCallResult & {
msgList: RawMessage[]
}>;
getMsgsByMsgId(peer: Peer, ids: string[]): Promise<GeneralCallResult & { msgList: RawMessage[] }>; getMsgsByMsgId(peer: Peer, ids: string[]): Promise<GeneralCallResult & { msgList: RawMessage[] }>;
@@ -198,10 +204,17 @@ export interface NodeIKernelMsgService {
getMsgByClientSeqAndTime(peer: Peer, clientSeq: string, time: string): unknown; getMsgByClientSeqAndTime(peer: Peer, clientSeq: string, time: string): unknown;
getSourceOfReplyMsgByClientSeqAndTime(peer: Peer, clientSeq: string, time: string): unknown; getSourceOfReplyMsgByClientSeqAndTime(peer: Peer, clientSeq: string, time: string): unknown;
//cnt clientSeq?并不是吧
getMsgsByTypeFilter(peer: Peer, msgId: string, cnt: unknown, queryOrder: boolean, typeFilter: { type: number, subtype: Array<number> }): unknown;
getMsgsByTypeFilters(peer: Peer, msgId: string, cnt: unknown, queryOrder: boolean, typeFilters: Array<{ type: number, subtype: Array<number> }>): unknown; //cnt clientSeq?并不是吧
getMsgsByTypeFilter(peer: Peer, msgId: string, cnt: unknown, queryOrder: boolean, typeFilter: {
type: number,
subtype: Array<number>
}): unknown;
getMsgsByTypeFilters(peer: Peer, msgId: string, cnt: unknown, queryOrder: boolean, typeFilters: Array<{
type: number,
subtype: Array<number>
}>): unknown;
getMsgWithAbstractByFilterParam(...args: unknown[]): unknown; getMsgWithAbstractByFilterParam(...args: unknown[]): unknown;
@@ -247,6 +260,7 @@ export interface NodeIKernelMsgService {
queryMsgsWithFilterEx(msgId: string, msgTime: string, megSeq: string, param: QueryMsgsParams): Promise<GeneralCallResult & { queryMsgsWithFilterEx(msgId: string, msgTime: string, megSeq: string, param: QueryMsgsParams): Promise<GeneralCallResult & {
msgList: RawMessage[] msgList: RawMessage[]
}>; }>;
//queryMsgsWithFilterEx(this.$msgId, this.$msgTime, this.$msgSeq, this.$param) //queryMsgsWithFilterEx(this.$msgId, this.$msgTime, this.$msgSeq, this.$param)
queryFileMsgsDesktop(...args: unknown[]): unknown; queryFileMsgsDesktop(...args: unknown[]): unknown;
@@ -354,10 +368,12 @@ export interface NodeIKernelMsgService {
getFileThumbSavePathForSend(...args: unknown[]): unknown; getFileThumbSavePathForSend(...args: unknown[]): unknown;
getFileThumbSavePath(...args: unknown[]): unknown; getFileThumbSavePath(...args: unknown[]): unknown;
//猜测居多 //猜测居多
translatePtt2Text(MsgId: string, Peer: {}, MsgElement: {}): unknown; translatePtt2Text(MsgId: string, Peer: {}, MsgElement: {}): unknown;
setPttPlayedState(...args: unknown[]): unknown; setPttPlayedState(...args: unknown[]): unknown;
// NodeIQQNTWrapperSession fetchFavEmojiList [ // NodeIQQNTWrapperSession fetchFavEmojiList [
// "", // "",
// 48, // 48,
@@ -661,6 +677,7 @@ export interface NodeIKernelMsgService {
GetMsgSubType(a0: number, a1: number): unknown; GetMsgSubType(a0: number, a1: number): unknown;
setIKernelPublicAccountAdapter(...args: unknown[]): unknown; setIKernelPublicAccountAdapter(...args: unknown[]): unknown;
//tempChatGameSession有关 //tempChatGameSession有关
createUidFromTinyId(fromTinyId: string, toTinyId: string): unknown; createUidFromTinyId(fromTinyId: string, toTinyId: string): unknown;

View File

@@ -1,12 +1,17 @@
import { GeneralCallResult } from "./common"; import { GeneralCallResult } from './common';
//没扒干净 因为用不着 //没扒干净 因为用不着
export interface NodeIKernelNodeMiscService { export interface NodeIKernelNodeMiscService {
getMiniAppPath(): unknown; getMiniAppPath(): unknown;
setMiniAppVersion(version:string): unknown;
setMiniAppVersion(version: string): unknown;
wantWinScreenOCR(imagepath: string): Promise<GeneralCallResult>; wantWinScreenOCR(imagepath: string): Promise<GeneralCallResult>;
SendMiniAppMsg(arg1: string, arg2: string, arg3: string): unknown; SendMiniAppMsg(arg1: string, arg2: string, arg3: string): unknown;
startNewMiniApp(appfile: string, params: string): unknown; startNewMiniApp(appfile: string, params: string): unknown;
// 我的计划是转发给一个新程序避免吃掉Electron_AS_Node的环境 然后重写启动MiniApp 挂载相应JS脚本 这样有个问题 // 我的计划是转发给一个新程序避免吃掉Electron_AS_Node的环境 然后重写启动MiniApp 挂载相应JS脚本 这样有个问题
// 需要自己转发ipc参数 然后必须处在gui环境 且完成校验破解 才能实现发包 有点抽象了 // 需要自己转发ipc参数 然后必须处在gui环境 且完成校验破解 才能实现发包 有点抽象了
} }

View File

@@ -1,5 +1,4 @@
import { BuddyProfileLikeReq } from "../entities/user"; import { BuddyProfileLikeReq, GeneralCallResult } from '@/core';
import { GeneralCallResult } from "./common";
export interface NodeIKernelProfileLikeService { export interface NodeIKernelProfileLikeService {
addKernelProfileLikeListener(listener: NodeIKernelProfileLikeService): void; addKernelProfileLikeListener(listener: NodeIKernelProfileLikeService): void;
@@ -9,10 +8,10 @@ export interface NodeIKernelProfileLikeService {
setBuddyProfileLike(...args: unknown[]): { result: number, errMsg: string, succCounts: number }; setBuddyProfileLike(...args: unknown[]): { result: number, errMsg: string, succCounts: number };
getBuddyProfileLike(req: BuddyProfileLikeReq): Promise<GeneralCallResult & { getBuddyProfileLike(req: BuddyProfileLikeReq): Promise<GeneralCallResult & {
"info": { 'info': {
"userLikeInfos": Array<any>, 'userLikeInfos': Array<any>,
"friendMaxVotes": number, 'friendMaxVotes': number,
"start": number 'start': number
} }
}>; }>;

View File

@@ -1,11 +1,13 @@
import { AnyCnameRecord } from 'node:dns'; import { AnyCnameRecord } from 'node:dns';
import { BaseInfo, BizKey, CoreInfo, ModifyProfileParams, SimpleInfo, UserDetailInfoByUin } from '../entities'; import { BizKey, ModifyProfileParams, SimpleInfo, UserDetailInfoByUin } from '../entities';
import { NodeIKernelProfileListener } from '../listeners'; import { NodeIKernelProfileListener } from '../listeners';
import { GeneralCallResult } from '@/core/services/common'; import { GeneralCallResult } from '@/core/services/common';
export enum UserDetailSource { export enum UserDetailSource {
KDB, KDB,
KSERVER KSERVER
} }
export enum ProfileBizType { export enum ProfileBizType {
KALL, KALL,
KBASEEXTEND, KBASEEXTEND,
@@ -13,11 +15,13 @@ export enum ProfileBizType {
KQZONE, KQZONE,
KOTHER KOTHER
} }
export interface NodeIKernelProfileService { export interface NodeIKernelProfileService {
getUidByUin(callfrom: string, uin: Array<string>): Promise<Map<string,string>>;//uin->uid getUidByUin(callfrom: string, uin: Array<string>): Promise<Map<string, string>>;//uin->uid
getUinByUid(callfrom: string, uid: Array<string>): Promise<Map<string, string>>;
getUinByUid(callfrom: string, uid: Array<string>): Promise<Map<string,string>>;
// { // {
// coreInfo: CoreInfo, // coreInfo: CoreInfo,
// baseInfo: BaseInfo, // baseInfo: BaseInfo,
@@ -76,7 +80,7 @@ export interface NodeIKernelProfileService {
setRecommendImgFlag(...args: unknown[]): Promise<unknown>; setRecommendImgFlag(...args: unknown[]): Promise<unknown>;
getUserSimpleInfo(force: boolean, uids: string[],): Promise<unknown>; getUserSimpleInfo(force: boolean, uids: string[]): Promise<unknown>;
getUserDetailInfo(uid: string): Promise<unknown>; getUserDetailInfo(uid: string): Promise<unknown>;
@@ -91,6 +95,7 @@ export interface NodeIKernelProfileService {
startStatusPolling(isForceReset: boolean): Promise<unknown>; startStatusPolling(isForceReset: boolean): Promise<unknown>;
getSelfStatus(): Promise<unknown>; getSelfStatus(): Promise<unknown>;
// //
setdisableEmojiShortCuts(...args: unknown[]): unknown; setdisableEmojiShortCuts(...args: unknown[]): unknown;
@@ -98,6 +103,7 @@ export interface NodeIKernelProfileService {
//profileService.getCoreInfo("UserRemarkServiceImpl::getStrangerRemarkByUid", arrayList); //profileService.getCoreInfo("UserRemarkServiceImpl::getStrangerRemarkByUid", arrayList);
getCoreInfo(name: string, arg: any[]): unknown; getCoreInfo(name: string, arg: any[]): unknown;
//m429253e12.getOtherFlag("FriendListInfoCache_getKernelDataAndPutCache", new ArrayList<>()); //m429253e12.getOtherFlag("FriendListInfoCache_getKernelDataAndPutCache", new ArrayList<>());
isNull(): boolean; isNull(): boolean;
} }

View File

@@ -1,6 +1,7 @@
import { ChatType, Peer } from "../entities"; import { ChatType, Peer } from '../entities';
import { NodeIKernelRecentContactListener } from "../listeners/NodeIKernelRecentContactListener"; import { NodeIKernelRecentContactListener } from '../listeners/NodeIKernelRecentContactListener';
import { GeneralCallResult } from "./common"; import { GeneralCallResult } from './common';
export interface FSABRecentContactParams { export interface FSABRecentContactParams {
anchorPointContact: { anchorPointContact: {
contactId: string; contactId: string;
@@ -12,6 +13,7 @@ export interface FSABRecentContactParams {
count: number; count: number;
fetchOld: boolean; fetchOld: boolean;
} }
// { // {
// "anchorPointContact": { // "anchorPointContact": {
// "contactId": "", // "contactId": "",
@@ -34,7 +36,8 @@ export interface NodeIKernelRecentContactService {
enterOrExitMsgList(...args: unknown[]): unknown; // 1 arguments enterOrExitMsgList(...args: unknown[]): unknown; // 1 arguments
/*!---!*/getRecentContactListSnapShot(count: number): Promise<GeneralCallResult & { /*!---!*/
getRecentContactListSnapShot(count: number): Promise<GeneralCallResult & {
info: { info: {
errCode: number, errCode: number,
errMsg: string, errMsg: string,
@@ -55,7 +58,8 @@ export interface NodeIKernelRecentContactService {
jumpToSpecifyRecentContact(...args: unknown[]): unknown; // 1 arguments jumpToSpecifyRecentContact(...args: unknown[]): unknown; // 1 arguments
/*!---!*/fetchAndSubscribeABatchOfRecentContact(params: FSABRecentContactParams): unknown; // 1 arguments /*!---!*/
fetchAndSubscribeABatchOfRecentContact(params: FSABRecentContactParams): unknown; // 1 arguments
addRecentContact(peer: Peer): unknown; addRecentContact(peer: Peer): unknown;

View File

@@ -1,5 +1,6 @@
import { GetFileListParam, MessageElement, Peer, SendMessageElement } from "../entities"; import { GetFileListParam, MessageElement, Peer } from '../entities';
import { GeneralCallResult } from "./common"; import { GeneralCallResult } from './common';
export enum UrlFileDownloadType { export enum UrlFileDownloadType {
KUNKNOWN, KUNKNOWN,
KURLFILEDOWNLOADPRIVILEGEICON, KURLFILEDOWNLOADPRIVILEGEICON,
@@ -8,6 +9,7 @@ export enum UrlFileDownloadType {
KURLFILEDOWNLOADCOMMON, KURLFILEDOWNLOADCOMMON,
KURLFILEDOWNLOADINSTALLAPP KURLFILEDOWNLOADINSTALLAPP
} }
export enum RMBizTypeEnum { export enum RMBizTypeEnum {
KUNKNOWN, KUNKNOWN,
KC2CFILE, KC2CFILE,
@@ -25,6 +27,7 @@ export enum RMBizTypeEnum {
KGUILDPTT, KGUILDPTT,
KGUILDVIDEO KGUILDVIDEO
} }
export interface CommonFileInfo { export interface CommonFileInfo {
bizType: number; bizType: number;
chatType: number; chatType: number;
@@ -39,12 +42,13 @@ export interface CommonFileInfo {
msgTime: string; msgTime: string;
parent: string; parent: string;
peerUid: string; peerUid: string;
picThumbPath: Array<string> picThumbPath: Array<string>;
sha: string; sha: string;
sha3: string; sha3: string;
subId: string; subId: string;
uuid: string; uuid: string;
} }
export interface NodeIKernelRichMediaService { export interface NodeIKernelRichMediaService {
//getVideoPlayUrl(peer, msgId, elemId, videoCodecFormat, VideoRequestWay.KHAND, cb); //getVideoPlayUrl(peer, msgId, elemId, videoCodecFormat, VideoRequestWay.KHAND, cb);
// public enum VideoCodecFormatType { // public enum VideoCodecFormatType {
@@ -77,7 +81,10 @@ export interface NodeIKernelRichMediaService {
// public static final int KTRIGGERTYPEAUTO = 1; // public static final int KTRIGGERTYPEAUTO = 1;
// public static final int KTRIGGERTYPEMANUAL = 0; // public static final int KTRIGGERTYPEMANUAL = 0;
getVideoPlayUrlV2(peer: Peer, msgId: string, elemId: string, videoCodecFormat: number, exParams: { downSourceType: number, triggerType: number }): Promise<GeneralCallResult & { getVideoPlayUrlV2(peer: Peer, msgId: string, elemId: string, videoCodecFormat: number, exParams: {
downSourceType: number,
triggerType: number
}): Promise<GeneralCallResult & {
urlResult: { urlResult: {
v4IpUrl: [], v4IpUrl: [],
v6IpUrl: [], v6IpUrl: [],
@@ -127,7 +134,9 @@ export interface NodeIKernelRichMediaService {
//arg双端number //arg双端number
isFileExpired(arg: number): unknown; isFileExpired(arg: number): unknown;
deleteGroupFolder(GroupCode: string, FolderId: string): Promise<GeneralCallResult & { groupFileCommonResult: { retCode: number, retMsg: string, clientWording: string } }>; deleteGroupFolder(GroupCode: string, FolderId: string): Promise<GeneralCallResult & {
groupFileCommonResult: { retCode: number, retMsg: string, clientWording: string }
}>;
//参数与getVideoPlayUrlInVisit一样 //参数与getVideoPlayUrlInVisit一样
downloadRichMediaInVisit(arg: { downloadRichMediaInVisit(arg: {
@@ -144,8 +153,10 @@ export interface NodeIKernelRichMediaService {
ele: MessageElement, ele: MessageElement,
useHttps: boolean useHttps: boolean
}): unknown; }): unknown;
//arg3为“” //arg3为“”
downloadFileForModelId(peer: Peer, ModelId: string[], arg3: string): unknown; downloadFileForModelId(peer: Peer, ModelId: string[], arg3: string): unknown;
//第三个参数 Array<Type> //第三个参数 Array<Type>
// this.fileId = ""; // this.fileId = "";
// this.fileName = ""; // this.fileName = "";
@@ -165,7 +176,9 @@ export interface NodeIKernelRichMediaService {
downloadFileForFileInfo(fileInfo: CommonFileInfo[], savePath: string): unknown; downloadFileForFileInfo(fileInfo: CommonFileInfo[], savePath: string): unknown;
createGroupFolder(GroupCode: string, FolderName: string): Promise<GeneralCallResult & { resultWithGroupItem: { result: any, groupItem: Array<any> } }> createGroupFolder(GroupCode: string, FolderName: string): Promise<GeneralCallResult & {
resultWithGroupItem: { result: any, groupItem: Array<any> }
}>;
downloadFile(commonFile: CommonFileInfo, arg2: unknown, arg3: unknown, savePath: string): unknown; downloadFile(commonFile: CommonFileInfo, arg2: unknown, arg3: unknown, savePath: string): unknown;
@@ -218,6 +231,7 @@ export interface NodeIKernelRichMediaService {
sortType: number, sortType: number,
groupNames: Array<string> groupNames: Array<string>
}): Promise<unknown>; }): Promise<unknown>;
searchGroupFileByWord(arg1: unknown, arg2: unknown, arg3: unknown, arg4: unknown, arg5: unknown): unknown; searchGroupFileByWord(arg1: unknown, arg2: unknown, arg3: unknown, arg4: unknown, arg5: unknown): unknown;
deleteGroupFile(GroupCode: string, params: Array<number>, Files: Array<string>): Promise<GeneralCallResult & { deleteGroupFile(GroupCode: string, params: Array<number>, Files: Array<string>): Promise<GeneralCallResult & {
@@ -232,7 +246,10 @@ export interface NodeIKernelRichMediaService {
getScreenOCR(path: string): Promise<unknown>; getScreenOCR(path: string): Promise<unknown>;
batchGetGroupFileCount(Gids: Array<string>): Promise<GeneralCallResult & { groupCodes: Array<string>, groupFileCounts: Array<number> }>; batchGetGroupFileCount(Gids: Array<string>): Promise<GeneralCallResult & {
groupCodes: Array<string>,
groupFileCounts: Array<number>
}>;
queryPicDownloadSize(arg: unknown): unknown; queryPicDownloadSize(arg: unknown): unknown;

View File

@@ -1,4 +1,4 @@
import { NodeIKernelRobotListener } from "@/core/listeners"; import { NodeIKernelRobotListener } from '@/core/listeners';
export interface NodeIKernelRobotService { export interface NodeIKernelRobotService {
fetchGroupRobotStoreDiscovery(arg: unknown): unknown; fetchGroupRobotStoreDiscovery(arg: unknown): unknown;
@@ -29,7 +29,7 @@ export interface NodeIKernelRobotService {
setRobotPickTts(arg1: unknown, arg2: unknown): unknown; setRobotPickTts(arg1: unknown, arg2: unknown): unknown;
getRobotUinRange(data: any): Promise<{ response: { robotUinRanges: any } }> getRobotUinRange(data: any): Promise<{ response: { robotUinRanges: any } }>;
isNull(): boolean; isNull(): boolean;
} }

View File

@@ -1,4 +1,4 @@
import { ChatType } from "../entities"; import { ChatType } from '../entities';
export interface NodeIKernelSearchService { export interface NodeIKernelSearchService {
addKernelSearchListener(...args: any[]): unknown;// needs 1 arguments addKernelSearchListener(...args: any[]): unknown;// needs 1 arguments
@@ -90,8 +90,7 @@ export interface NodeIKernelSearchService {
hasModifyConfGroupName: boolean, hasModifyConfGroupName: boolean,
groupName: string, groupName: string,
remark: string remark: string
}> }>,
,
dataLineChatInfo: [], dataLineChatInfo: [],
tmpChatInfo: [], tmpChatInfo: [],
msgId: string, msgId: string,

View File

@@ -1,5 +1,5 @@
import { NodeIKernelStorageCleanListener } from "@/core/listeners"; import { NodeIKernelStorageCleanListener } from '@/core/listeners';
import { GeneralCallResult } from "./common"; import { GeneralCallResult } from './common';
export interface NodeIKernelStorageCleanService { export interface NodeIKernelStorageCleanService {

View File

@@ -1,4 +1,4 @@
import { forceFetchClientKeyRetType } from "./common"; import { forceFetchClientKeyRetType } from './common';
export interface NodeIKernelTicketService { export interface NodeIKernelTicketService {

View File

@@ -1,4 +1,4 @@
import { GeneralCallResult } from "./common"; import { GeneralCallResult } from './common';
export interface NodeIKernelTipOffService { export interface NodeIKernelTipOffService {
@@ -8,7 +8,9 @@ export interface NodeIKernelTipOffService {
tipOffSendJsData(args: unknown[]): Promise<unknown>;//2 tipOffSendJsData(args: unknown[]): Promise<unknown>;//2
getPskey(domainList: string[], nocache: boolean): Promise<GeneralCallResult & { domainPskeyMap: Map<string, string> }>;//2 getPskey(domainList: string[], nocache: boolean): Promise<GeneralCallResult & {
domainPskeyMap: Map<string, string>
}>;//2
tipOffSendJsData(args: unknown[]): Promise<unknown>;//2 tipOffSendJsData(args: unknown[]): Promise<unknown>;//2

View File

@@ -1,4 +1,4 @@
export interface NodeIKernelUnitedConfigService{ export interface NodeIKernelUnitedConfigService {
addKernelUnitedConfigListener(...args: any[]): unknown;// needs 1 arguments addKernelUnitedConfigListener(...args: any[]): unknown;// needs 1 arguments
removeKernelUnitedConfigListener(...args: any[]): unknown;// needs 1 arguments removeKernelUnitedConfigListener(...args: any[]): unknown;// needs 1 arguments

View File

@@ -1,4 +1,4 @@
import { MessageElement, Peer } from "../entities"; import { MessageElement, Peer } from '../entities';
export interface NodeIkernelTestPerformanceService { export interface NodeIkernelTestPerformanceService {
insertMsg(MsgParam: { insertMsg(MsgParam: {

View File

@@ -2,13 +2,15 @@ export enum GeneralCallResultStatus {
OK = 0, OK = 0,
// ERROR = 1, // ERROR = 1,
} }
export interface GeneralCallResult{
export interface GeneralCallResult {
result: GeneralCallResultStatus, result: GeneralCallResultStatus,
errMsg: string errMsg: string
} }
export interface forceFetchClientKeyRetType extends GeneralCallResult { export interface forceFetchClientKeyRetType extends GeneralCallResult {
url: string; url: string;
keyIndex: string; keyIndex: string;
clientKey: string; clientKey: string;
expireTime: string; expireTime: string;
} }

View File

@@ -1,10 +1,8 @@
import { LogWrapper } from "@/common/utils/log"; import { LogWrapper } from '@/common/utils/log';
import { QQBasicInfoWrapper } from "@/common/utils/QQBasicInfo"; import { QQBasicInfoWrapper } from '@/common/utils/QQBasicInfo';
import { NapCatCoreWorkingEnv } from "@/core"; import { NapCatCoreWorkingEnv, NodeIKernelLoginService, NodeIQQNTWrapperSession, WrapperNodeApi } from '@/core';
import { NodeIKernelLoginService } from '@/core'; import { NTQQFileApi, NTQQFriendApi, NTQQGroupApi, NTQQMsgApi, NTQQSystemApi, NTQQUserApi, NTQQWebApi } from '../apis';
import { WrapperNodeApi, NodeIQQNTWrapperSession } from "@/core"; import { NTQQCollectionApi } from '../apis/collection';
import { NTQQFileApi, NTQQFriendApi, NTQQGroupApi, NTQQMsgApi, NTQQSystemApi, NTQQUserApi, NTQQWebApi } from "../apis";
import { NTQQCollectionApi } from "../apis/collection";
import { NapCatPathWrapper } from '@/common/framework/napcat'; import { NapCatPathWrapper } from '@/common/framework/napcat';
export interface InstanceContext { export interface InstanceContext {

View File

@@ -1,7 +1,7 @@
import path from "node:path"; import path from 'node:path';
import fs from "node:fs"; import fs from 'node:fs';
import { PlatformType, VendorType, WrapperSessionInitConfig } from "./wrapper"; import { PlatformType, VendorType, WrapperSessionInitConfig } from './wrapper';
import { getMachineId, hostname, systemName, systemVersion } from "@/common/utils/system"; import { getMachineId, hostname, systemName, systemVersion } from '@/common/utils/system';
export async function genSessionConfig(QQVersionAppid: string, QQVersion: string, selfUin: string, selfUid: string, account_path: string): Promise<WrapperSessionInitConfig> { export async function genSessionConfig(QQVersionAppid: string, QQVersion: string, selfUin: string, selfUid: string, account_path: string): Promise<WrapperSessionInitConfig> {
const downloadPath = path.join(account_path, 'NapCat', 'temp'); const downloadPath = path.join(account_path, 'NapCat', 'temp');
@@ -11,7 +11,7 @@ export async function genSessionConfig(QQVersionAppid: string, QQVersion: string
selfUin, selfUin,
selfUid, selfUid,
desktopPathConfig: { desktopPathConfig: {
account_path // 可以通过NodeQQNTWrapperUtil().getNTUserDataInfoConfig()获取 account_path, // 可以通过NodeQQNTWrapperUtil().getNTUserDataInfoConfig()获取
}, },
clientVer: QQVersion, // 9.9.8-22355 clientVer: QQVersion, // 9.9.8-22355
a2: '', a2: '',
@@ -34,7 +34,7 @@ export async function genSessionConfig(QQVersionAppid: string, QQVersion: string
osVersion: '', osVersion: '',
bundleId: '', bundleId: '',
serverUrl: '', serverUrl: '',
fixedAfterHitKeys: [''] fixedAfterHitKeys: [''],
}, },
defaultFileDownloadPath: downloadPath, defaultFileDownloadPath: downloadPath,
deviceInfo: { deviceInfo: {
@@ -47,9 +47,9 @@ export async function genSessionConfig(QQVersionAppid: string, QQVersion: string
osVer: systemVersion, osVer: systemVersion,
vendorOsName: systemName, vendorOsName: systemName,
setMute: false, setMute: false,
vendorType: VendorType.KNOSETONIOS vendorType: VendorType.KNOSETONIOS,
}, },
deviceConfig: '{"appearance":{"isSplitViewMode":true},"msg":{}}' deviceConfig: '{"appearance":{"isSplitViewMode":true},"msg":{}}',
}; };
return config; return config;
} }

View File

@@ -1,43 +1,42 @@
import path from "node:path"; import { NodeIDependsAdapter, NodeIDispatcherAdapter, NodeIGlobalAdapter } from '../adapters';
import fs from "node:fs";
import { NodeIDependsAdapter, NodeIDispatcherAdapter, NodeIGlobalAdapter } from "../adapters";
import { import {
NodeIKernelSessionListener,
NodeIKernelMsgListener,
NodeIKernelLoginListener,
NodeIKernelBuddyListener, NodeIKernelBuddyListener,
NodeIKernelGroupListener, NodeIKernelGroupListener,
NodeIKernelLoginListener,
NodeIKernelMsgListener,
NodeIKernelProfileListener, NodeIKernelProfileListener,
} from "../listeners"; NodeIKernelSessionListener,
} from '../listeners';
import { import {
NodeIKernelLoginService, NodeIKernelAvatarService,
NodeIKernelMsgService,
NodeIKernelBuddyService, NodeIKernelBuddyService,
NodeIKernelGroupService, NodeIKernelGroupService,
NodeIKernelProfileService, NodeIKernelLoginService,
NodeIKernelMsgService,
NodeIKernelProfileLikeService, NodeIKernelProfileLikeService,
NodeIKernelProfileService,
NodeIKernelRichMediaService,
NodeIKernelTicketService, NodeIKernelTicketService,
NodeIKernelTipOffService, NodeIKernelTipOffService,
NodeIKernelRichMediaService, } from '../services';
NodeIKernelAvatarService, import { NodeIKernelStorageCleanService } from '../services/NodeIKernelStorageCleanService';
} from "../services"; import { NodeIKernelRobotService } from '../services/NodeIKernelRobotService';
import { NodeIKernelStorageCleanService } from "../services/NodeIKernelStorageCleanService"; import { NodeIKernelNodeMiscService } from '../services/NodeIKernelNodeMiscService';
import { NodeIKernelRobotService } from "../services/NodeIKernelRobotService"; import { NodeIKernelUixConvertService } from '../services/NodeIKernelUixConvertService';
import { NodeIKernelNodeMiscService } from "../services/NodeIKernelNodeMiscService"; import { NodeIKernelMsgBackupService } from '../services/NodeIKernelMsgBackupService';
import { NodeIKernelUixConvertService } from "../services/NodeIKernelUixConvertService"; import { NodeIKernelAlbumService } from '../services/NodeIKernelAlbumService';
import { NodeIKernelMsgBackupService } from "../services/NodeIKernelMsgBackupService"; import { NodeIKernelTianShuService } from '../services/NodeIKernelTianShuService';
import { NodeIKernelAlbumService } from "../services/NodeIKernelAlbumService"; import { NodeIKernelUnitedConfigService } from '../services/NodeIKernelUnitedConfigService';
import { NodeIKernelTianShuService } from "../services/NodeIKernelTianShuService"; import { NodeIKernelSearchService } from '../services/NodeIKernelSearchService';
import { NodeIKernelUnitedConfigService } from "../services/NodeIKernelUnitedConfigService"; import { NodeIKernelCollectionService } from '../services/NodeIKernelCollectionService';
import { NodeIKernelSearchService } from "../services/NodeIKernelSearchService"; import { NodeIKernelRecentContactService } from '../services/NodeIKernelRecentContactService';
import { NodeIKernelCollectionService } from "../services/NodeIKernelCollectionService"; import { NodeIKernelMSFService } from '../services/NodeIKernelMSFService';
import { NodeIKernelRecentContactService } from "../services/NodeIKernelRecentContactService"; import { NodeIkernelTestPerformanceService } from '../services/NodeIkernelTestPerformanceService';
import { NodeIKernelMSFService } from "../services/NodeIKernelMSFService"; import { NodeIKernelECDHService } from '../services/NodeIKernelECDHService';
import { NodeIkernelTestPerformanceService } from "../services/NodeIkernelTestPerformanceService";
import { NodeIKernelECDHService } from "../services/NodeIKernelECDHService";
export interface NodeQQNTWrapperUtil { export interface NodeQQNTWrapperUtil {
// eslint-disable-next-line @typescript-eslint/no-misused-new // eslint-disable-next-line @typescript-eslint/no-misused-new
new (): NodeQQNTWrapperUtil; new(): NodeQQNTWrapperUtil;
getNTUserDataInfoConfig(): string; getNTUserDataInfoConfig(): string;
@@ -110,7 +109,7 @@ export interface NodeQQNTWrapperUtil {
arg1: unknown, arg1: unknown,
arg2: unknown, arg2: unknown,
arg3: number, arg3: number,
arg4: number arg4: number,
): unknown; ): unknown;
reportCountIndicators( reportCountIndicators(
@@ -118,7 +117,7 @@ export interface NodeQQNTWrapperUtil {
arg1: Map<unknown, unknown>, arg1: Map<unknown, unknown>,
arg2: string, arg2: string,
arg3: number, arg3: number,
arg4: boolean arg4: boolean,
): unknown; ): unknown;
reportValueIndicators( reportValueIndicators(
@@ -126,7 +125,7 @@ export interface NodeQQNTWrapperUtil {
arg1: Map<unknown, unknown>, arg1: Map<unknown, unknown>,
arg2: string, arg2: string,
arg3: boolean, arg3: boolean,
arg4: number arg4: number,
): unknown; ): unknown;
checkNewUserDataSaveDirAvailable(arg0: string): unknown; checkNewUserDataSaveDirAvailable(arg0: string): unknown;
@@ -150,13 +149,13 @@ export interface NodeQQNTWrapperUtil {
export interface NodeIQQNTWrapperSession { export interface NodeIQQNTWrapperSession {
// eslint-disable-next-line @typescript-eslint/no-misused-new // eslint-disable-next-line @typescript-eslint/no-misused-new
new (): NodeIQQNTWrapperSession; new(): NodeIQQNTWrapperSession;
init( init(
wrapperSessionInitConfig: WrapperSessionInitConfig, wrapperSessionInitConfig: WrapperSessionInitConfig,
nodeIDependsAdapter: NodeIDependsAdapter, nodeIDependsAdapter: NodeIDependsAdapter,
nodeIDispatcherAdapter: NodeIDispatcherAdapter, nodeIDispatcherAdapter: NodeIDispatcherAdapter,
nodeIKernelSessionListener: NodeIKernelSessionListener nodeIKernelSessionListener: NodeIKernelSessionListener,
): void; ): void;
startNT(n: 0): void; startNT(n: 0): void;
@@ -270,7 +269,8 @@ export interface EnginInitDesktopConfig {
export interface NodeIQQNTWrapperEngine { export interface NodeIQQNTWrapperEngine {
// eslint-disable-next-line @typescript-eslint/no-misused-new // eslint-disable-next-line @typescript-eslint/no-misused-new
new (): NodeIQQNTWrapperEngine; new(): NodeIQQNTWrapperEngine;
initWithDeskTopConfig(config: EnginInitDesktopConfig, nodeIGlobalAdapter: NodeIGlobalAdapter): void; initWithDeskTopConfig(config: EnginInitDesktopConfig, nodeIGlobalAdapter: NodeIGlobalAdapter): void;
} }
@@ -292,6 +292,7 @@ export interface WrapperNodeApi {
NodeIKernelProfileService: NodeIKernelProfileService; NodeIKernelProfileService: NodeIKernelProfileService;
NodeIKernelProfileListener: NodeIKernelProfileListener; NodeIKernelProfileListener: NodeIKernelProfileListener;
} }
export enum PlatformType { export enum PlatformType {
KUNKNOWN, KUNKNOWN,
KANDROID, KANDROID,
@@ -299,12 +300,14 @@ export enum PlatformType {
KWINDOWS, KWINDOWS,
KMAC, KMAC,
} }
export enum DeviceType { export enum DeviceType {
KUNKNOWN, KUNKNOWN,
KPHONE, KPHONE,
KPAD, KPAD,
KCOMPUTER, KCOMPUTER,
} }
//推送类型 //推送类型
export enum VendorType { export enum VendorType {
KNOSETONIOS = 0, KNOSETONIOS = 0,
@@ -315,6 +318,7 @@ export enum VendorType {
KSUPPORTVIVOPUSH = 5, KSUPPORTVIVOPUSH = 5,
KUNSUPPORTANDROIDPUSH = 1, KUNSUPPORTANDROIDPUSH = 1,
} }
export interface WrapperSessionInitConfig { export interface WrapperSessionInitConfig {
selfUin: string; selfUin: string;
selfUid: string; selfUid: string;

View File

@@ -27,9 +27,9 @@ process.dlopen = (module, filename, flags = os.constants.dlopen.RTLD_LAZY) => {
if (args[ArgIndex] instanceof Object) { if (args[ArgIndex] instanceof Object) {
let HookArg = {}; let HookArg = {};
for (let ListenerName in args[ArgIndex]) { for (let ListenerName in args[ArgIndex]) {
HookArg[ListenerName] = function (...ListenerData) { HookArg[ListenerName] = function(...ListenerData) {
try { try {
if (ListenerName === "onSessionInitComplete") { if (ListenerName === 'onSessionInitComplete') {
//回调成功 //回调成功
initCallBack.forEach((cb) => cb(...ListenerData)); initCallBack.forEach((cb) => cb(...ListenerData));
clearHook(); clearHook();
@@ -110,15 +110,15 @@ async function fetchServices(timeout = 10000) {
pollForNTInitializationCheck(), pollForNTInitializationCheck(),
new Promise((resolve) => { new Promise((resolve) => {
setTimeout(() => resolve(false), timeout); setTimeout(() => resolve(false), timeout);
}) }),
]).then(result => result ? ]).then(result => result ?
{ wrapperSession, wrapperNodeApi, wrapperLoginService } : { wrapperSession, wrapperNodeApi, wrapperLoginService } :
Promise.reject() Promise.reject(),
); );
} }
async function NCInit() { async function NCInit() {
console.log("[NapCat] [Info] 开始初始化NapCat"); console.log('[NapCat] [Info] 开始初始化NapCat');
try { try {
const { wrapperSession, wrapperLoginService } = await fetchServices(); const { wrapperSession, wrapperLoginService } = await fetchServices();
@@ -127,7 +127,7 @@ async function NCInit() {
await NCoreInitFramework(wrapperSession, wrapperLoginService, registerInitCallback); await NCoreInitFramework(wrapperSession, wrapperLoginService, registerInitCallback);
//console.log("[NapCat] [Info] NapCat初始化完成"); //console.log("[NapCat] [Info] NapCat初始化完成");
} catch (error) { } catch (error) {
console.error("[NapCat] [Error] 初始化NapCat失败", error); console.error('[NapCat] [Error] 初始化NapCat失败', error);
} }
} }

View File

@@ -1,24 +1,23 @@
import { NapCatPathWrapper } from "@/common/framework/napcat"; import { NapCatPathWrapper } from '@/common/framework/napcat';
import { LogWrapper } from "@/common/utils/log"; import { LogWrapper } from '@/common/utils/log';
import { proxiedListenerOf } from "@/common/utils/proxy-handler"; import { proxiedListenerOf } from '@/common/utils/proxy-handler';
import { QQBasicInfoWrapper } from "@/common/utils/QQBasicInfo"; import { QQBasicInfoWrapper } from '@/common/utils/QQBasicInfo';
import { NapCatCore, NapCatCoreWorkingEnv, loadQQWrapper } from "@/core/core"; import { loadQQWrapper, NapCatCore, NapCatCoreWorkingEnv } from '@/core/core';
import { InstanceContext } from "@/core"; import { InstanceContext } from '@/core';
import { SelfInfo } from "@/core/entities"; import { SelfInfo } from '@/core/entities';
import { LoginListener } from "@/core/listeners"; import { LoginListener } from '@/core/listeners';
import { NodeIKernelLoginService } from "@/core/services"; import { NodeIKernelLoginService } from '@/core/services';
import { WrapperNodeApi, NodeIQQNTWrapperSession } from "@/core/wrapper/wrapper"; import { NodeIQQNTWrapperSession, WrapperNodeApi } from '@/core/wrapper/wrapper';
import { NapCatOneBot11Adapter } from "@/onebot/main"; import { NapCatOneBot11Adapter } from '@/onebot/main';
import { sleep } from "@/common/utils/helper";
//Framework ES入口文件 //Framework ES入口文件
export async function NCoreInitFramework( export async function NCoreInitFramework(
session: NodeIQQNTWrapperSession, session: NodeIQQNTWrapperSession,
loginService: NodeIKernelLoginService, loginService: NodeIKernelLoginService,
registerInitCallback: (callback: () => void) => void registerInitCallback: (callback: () => void) => void,
) { ) {
//在进入本层前是否登录未进行判断 //在进入本层前是否登录未进行判断
console.log("NapCat Framework App Loading..."); console.log('NapCat Framework App Loading...');
const pathWrapper = new NapCatPathWrapper(); const pathWrapper = new NapCatPathWrapper();
const logger = new LogWrapper(pathWrapper.logsPath); const logger = new LogWrapper(pathWrapper.logsPath);
const basicInfoWrapper = new QQBasicInfoWrapper({ logger }); const basicInfoWrapper = new QQBasicInfoWrapper({ logger });
@@ -62,7 +61,7 @@ export class NapCatFramework {
loginService: NodeIKernelLoginService, loginService: NodeIKernelLoginService,
selfInfo: SelfInfo, selfInfo: SelfInfo,
basicInfoWrapper: QQBasicInfoWrapper, basicInfoWrapper: QQBasicInfoWrapper,
pathWrapper: NapCatPathWrapper pathWrapper: NapCatPathWrapper,
) { ) {
this.context = { this.context = {
workingEnv: NapCatCoreWorkingEnv.Framework, workingEnv: NapCatCoreWorkingEnv.Framework,
@@ -71,7 +70,7 @@ export class NapCatFramework {
logger, logger,
loginService, loginService,
basicInfoWrapper, basicInfoWrapper,
pathWrapper pathWrapper,
}; };
this.core = new NapCatCore(this.context, selfInfo); this.core = new NapCatCore(this.context, selfInfo);
} }

View File

@@ -11,10 +11,12 @@ class BaseAction<PayloadType, ReturnDataType> {
private validate: undefined | ValidateFunction<any> = undefined; private validate: undefined | ValidateFunction<any> = undefined;
PayloadSchema: any = undefined; PayloadSchema: any = undefined;
OneBotContext: NapCatOneBot11Adapter; OneBotContext: NapCatOneBot11Adapter;
constructor(onebotContext:NapCatOneBot11Adapter,coreContext: NapCatCore) {
constructor(onebotContext: NapCatOneBot11Adapter, coreContext: NapCatCore) {
this.OneBotContext = onebotContext; this.OneBotContext = onebotContext;
this.CoreContext = coreContext; this.CoreContext = coreContext;
} }
protected async check(payload: PayloadType): Promise<BaseCheckResult> { protected async check(payload: PayloadType): Promise<BaseCheckResult> {
if (this.PayloadSchema) { if (this.PayloadSchema) {
this.validate = new Ajv({ allowUnionTypes: true }).compile(this.PayloadSchema); this.validate = new Ajv({ allowUnionTypes: true }).compile(this.PayloadSchema);
@@ -26,11 +28,11 @@ class BaseAction<PayloadType, ReturnDataType> {
}); });
return { return {
valid: false, valid: false,
message: errorMessages.join('\n') as string || '未知错误' message: errorMessages.join('\n') as string || '未知错误',
}; };
} }
return { return {
valid: true valid: true,
}; };
} }

View File

@@ -10,7 +10,7 @@ export class OB11Response {
data: data, data: data,
message: message, message: message,
wording: message, wording: message,
echo: null echo: null,
}; };
} }

View File

@@ -1,11 +1,12 @@
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';
const SchemaData = { const SchemaData = {
type: 'object', type: 'object',
properties: { properties: {
rawData: { type: 'string' }, rawData: { type: 'string' },
brief: { type: 'string' } brief: { type: 'string' },
}, },
required: ['brief', 'rawData'], required: ['brief', 'rawData'],
} as const satisfies JSONSchema; } as const satisfies JSONSchema;
@@ -15,12 +16,13 @@ type Payload = FromSchema<typeof SchemaData>;
export class CreateCollection extends BaseAction<Payload, any> { export class CreateCollection extends BaseAction<Payload, any> {
actionName = ActionName.CreateCollection; actionName = ActionName.CreateCollection;
PayloadSchema = SchemaData; PayloadSchema = SchemaData;
protected async _handle(payload: Payload) { protected async _handle(payload: Payload) {
return await this.CoreContext.getApiContext().CollectionApi.createCollection( return await this.CoreContext.getApiContext().CollectionApi.createCollection(
this.CoreContext.selfInfo.uin, this.CoreContext.selfInfo.uin,
this.CoreContext.selfInfo.uid, this.CoreContext.selfInfo.uid,
this.CoreContext.selfInfo.nick, this.CoreContext.selfInfo.nick,
payload.brief, payload.rawData payload.brief, payload.rawData,
); );
} }
} }

View File

@@ -1,11 +1,12 @@
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';
const SchemaData = { const SchemaData = {
type: 'object', type: 'object',
properties: { properties: {
count: { type: 'number' }, count: { type: 'number' },
} },
} as const satisfies JSONSchema; } as const satisfies JSONSchema;
type Payload = FromSchema<typeof SchemaData>; type Payload = FromSchema<typeof SchemaData>;
@@ -13,6 +14,7 @@ type Payload = FromSchema<typeof SchemaData>;
export class FetchCustomFace extends BaseAction<Payload, string[]> { export class FetchCustomFace extends BaseAction<Payload, string[]> {
actionName = ActionName.FetchCustomFace; actionName = ActionName.FetchCustomFace;
PayloadSchema = SchemaData; PayloadSchema = SchemaData;
protected async _handle(payload: Payload) { protected async _handle(payload: Payload) {
//48 可能正好是QQ需要的一个页面的数量 Tagged Mlikiowa //48 可能正好是QQ需要的一个页面的数量 Tagged Mlikiowa
const ret = await this.CoreContext.getApiContext().MsgApi.fetchFavEmojiList(payload.count || 48); const ret = await this.CoreContext.getApiContext().MsgApi.fetchFavEmojiList(payload.count || 48);

View File

@@ -12,9 +12,9 @@ const SchemaData = {
emojiId: { type: 'string' }, emojiId: { type: 'string' },
emojiType: { type: 'string' }, emojiType: { type: 'string' },
message_id: { type: ['string', 'number'] }, message_id: { type: ['string', 'number'] },
count: { type: 'number' } count: { type: 'number' },
}, },
required: ['emojiId', 'emojiType', 'message_id'] required: ['emojiId', 'emojiType', 'message_id'],
} as const satisfies JSONSchema; } as const satisfies JSONSchema;
type Payload = FromSchema<typeof SchemaData>; type Payload = FromSchema<typeof SchemaData>;
@@ -22,10 +22,11 @@ type Payload = FromSchema<typeof SchemaData>;
export class FetchEmojiLike extends BaseAction<Payload, any> { export class FetchEmojiLike extends BaseAction<Payload, any> {
actionName = ActionName.FetchEmojiLike; actionName = ActionName.FetchEmojiLike;
PayloadSchema = SchemaData; PayloadSchema = SchemaData;
protected async _handle(payload: Payload) { protected async _handle(payload: Payload) {
const NTQQMsgApi = this.CoreContext.getApiContext().MsgApi; const NTQQMsgApi = this.CoreContext.getApiContext().MsgApi;
const msgIdPeer = MessageUnique.getMsgIdAndPeerByShortId(parseInt(payload.message_id.toString())); const msgIdPeer = MessageUnique.getMsgIdAndPeerByShortId(parseInt(payload.message_id.toString()));
if(!msgIdPeer) throw new Error('消息不存在'); if (!msgIdPeer) throw new Error('消息不存在');
const msg = (await NTQQMsgApi.getMsgsByMsgId(msgIdPeer.Peer, [msgIdPeer.MsgId])).msgList[0]; const msg = (await NTQQMsgApi.getMsgsByMsgId(msgIdPeer.Peer, [msgIdPeer.MsgId])).msgList[0];
return await NTQQMsgApi.getMsgEmojiLikesList(msgIdPeer.Peer, msg.msgSeq, payload.emojiId, payload.emojiType, payload.count); return await NTQQMsgApi.getMsgEmojiLikesList(msgIdPeer.Peer, msg.msgSeq, payload.emojiId, payload.emojiType, payload.count);
} }

View File

@@ -1,4 +1,3 @@
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';
@@ -7,7 +6,7 @@ const SchemaData = {
type: 'object', type: 'object',
properties: { properties: {
category: { type: 'number' }, category: { type: 'number' },
count: { type: 'number' } count: { type: 'number' },
}, },
required: ['category', 'count'], required: ['category', 'count'],
} as const satisfies JSONSchema; } as const satisfies JSONSchema;
@@ -17,6 +16,7 @@ type Payload = FromSchema<typeof SchemaData>;
export class GetCollectionList extends BaseAction<Payload, any> { export class GetCollectionList extends BaseAction<Payload, any> {
actionName = ActionName.GetCollectionList; actionName = ActionName.GetCollectionList;
PayloadSchema = SchemaData; PayloadSchema = SchemaData;
protected async _handle(payload: Payload) { protected async _handle(payload: Payload) {
const NTQQCollectionApi = this.CoreContext.getApiContext().CollectionApi; const NTQQCollectionApi = this.CoreContext.getApiContext().CollectionApi;
return await NTQQCollectionApi.getAllCollection(payload.category, payload.count); return await NTQQCollectionApi.getAllCollection(payload.category, payload.count);

View File

@@ -1,4 +1,3 @@
import BaseAction from '../BaseAction'; import BaseAction from '../BaseAction';
import { ActionName } from '../types'; import { ActionName } from '../types';
import { OB11Constructor } from '@/onebot/helper/constructor'; import { OB11Constructor } from '@/onebot/helper/constructor';

View File

@@ -1,6 +1,5 @@
import BaseAction from '../BaseAction'; import BaseAction from '../BaseAction';
import { ActionName } from '../types'; import { ActionName } from '../types';
import { NTQQGroupApi } from '@/core/apis/group';
interface OB11GroupRequestNotify { interface OB11GroupRequestNotify {
group_id: number, group_id: number,

View File

@@ -1,7 +1,9 @@
import BaseAction from '../BaseAction'; import BaseAction from '../BaseAction';
import { ActionName } from '../types'; import { ActionName } from '../types';
export class GetProfileLike extends BaseAction<void, any> { export class GetProfileLike extends BaseAction<void, any> {
actionName = ActionName.GetProfileLike; actionName = ActionName.GetProfileLike;
protected async _handle(payload: void) { protected async _handle(payload: void) {
const NTQQUserApi = this.CoreContext.getApiContext().UserApi; const NTQQUserApi = this.CoreContext.getApiContext().UserApi;
const ret = await NTQQUserApi.getProfileLike(this.CoreContext.selfInfo.uid); const ret = await NTQQUserApi.getProfileLike(this.CoreContext.selfInfo.uid);

View File

@@ -1,6 +1,6 @@
import BaseAction from '../BaseAction'; import BaseAction from '../BaseAction';
import { ActionName } from '../types'; import { ActionName } from '../types';
import { NTQQUserApi } from '@/core/apis';
export class GetRobotUinRange extends BaseAction<void, Array<any>> { export class GetRobotUinRange extends BaseAction<void, Array<any>> {
actionName = ActionName.GetRobotUinRange; actionName = ActionName.GetRobotUinRange;

View File

@@ -9,7 +9,7 @@ const SchemaData = {
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>;
@@ -17,9 +17,10 @@ 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 NTQQSystemApi = this.CoreContext.getApiContext().SystemApi; const NTQQSystemApi = this.CoreContext.getApiContext().SystemApi;
const { path, isLocal, errMsg,success } = (await uri2local(this.CoreContext.NapCatTempPath,payload.image)); const { path, isLocal, errMsg, success } = (await uri2local(this.CoreContext.NapCatTempPath, payload.image));
if (!success) { if (!success) {
throw `OCR ${payload.image}失败,image字段可能格式不正确`; throw `OCR ${payload.image}失败,image字段可能格式不正确`;
} }
@@ -27,7 +28,8 @@ export class OCRImage extends BaseAction<Payload, any> {
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}失败`;
@@ -35,11 +37,13 @@ export class OCRImage extends BaseAction<Payload, any> {
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,8 +1,8 @@
import BaseAction from '../BaseAction'; import BaseAction from '../BaseAction';
import { ActionName, BaseCheckResult } from '../types'; import { ActionName, BaseCheckResult } from '../types';
import * as fs from 'node:fs'; import * as fs from 'node:fs';
import { NTQQUserApi } from '@/core/apis/user';
import { checkFileReceived, uri2local } from '@/common/utils/file'; import { checkFileReceived, uri2local } from '@/common/utils/file';
// import { log } from "../../../common/utils"; // import { log } from "../../../common/utils";
interface Payload { interface Payload {
@@ -12,6 +12,7 @@ interface Payload {
export default class SetGroupHeader extends BaseAction<Payload, any> { export default class SetGroupHeader extends BaseAction<Payload, any> {
actionName = ActionName.SetGroupHeader; actionName = ActionName.SetGroupHeader;
// 用不着复杂检测 // 用不着复杂检测
protected async check(payload: Payload): Promise<BaseCheckResult> { protected async check(payload: Payload): Promise<BaseCheckResult> {
if (!payload.file || typeof payload.file != 'string' || !payload.groupCode || typeof payload.groupCode != 'string') { if (!payload.file || typeof payload.file != 'string' || !payload.groupCode || typeof payload.groupCode != 'string') {
@@ -24,6 +25,7 @@ export default class SetGroupHeader extends BaseAction<Payload, any> {
valid: true, valid: true,
}; };
} }
protected async _handle(payload: Payload): Promise<any> { protected async _handle(payload: Payload): Promise<any> {
const NTQQGroupApi = this.CoreContext.getApiContext().GroupApi; const NTQQGroupApi = this.CoreContext.getApiContext().GroupApi;
const { path, isLocal, errMsg, success } = (await uri2local(this.CoreContext.NapCatTempPath, payload.file)); const { path, isLocal, errMsg, success } = (await uri2local(this.CoreContext.NapCatTempPath, payload.file));
@@ -34,7 +36,8 @@ export default class SetGroupHeader extends BaseAction<Payload, any> {
await checkFileReceived(path, 5000); // 文件不存在QQ会崩溃需要提前判断 await checkFileReceived(path, 5000); // 文件不存在QQ会崩溃需要提前判断
const ret = await NTQQGroupApi.setGroupAvatar(payload.groupCode, path); const ret = await NTQQGroupApi.setGroupAvatar(payload.groupCode, path);
if (!isLocal) { if (!isLocal) {
fs.unlink(path, () => { }); fs.unlink(path, () => {
});
} }
if (!ret) { if (!ret) {
throw `头像${payload.file}设置失败,api无返回`; throw `头像${payload.file}设置失败,api无返回`;
@@ -48,7 +51,8 @@ export default class SetGroupHeader extends BaseAction<Payload, any> {
return ret; return ret;
} else { } else {
if (!isLocal) { if (!isLocal) {
fs.unlink(path, () => { }); fs.unlink(path, () => {
});
} }
throw `头像${payload.file}设置失败,无法获取头像,文件可能不存在`; throw `头像${payload.file}设置失败,无法获取头像,文件可能不存在`;
} }

View File

@@ -1,7 +1,5 @@
import BaseAction from '../BaseAction'; import BaseAction from '../BaseAction';
import { ActionName } from '../types'; import { ActionName } from '../types';
import { NTQQUserApi } from '@/core/apis';
import { FromSchema, JSONSchema } from 'json-schema-to-ts'; import { FromSchema, JSONSchema } from 'json-schema-to-ts';
const SchemaData = { const SchemaData = {
@@ -9,7 +7,7 @@ const SchemaData = {
properties: { properties: {
longNick: { type: 'string' }, longNick: { type: 'string' },
}, },
required: [ 'longNick'], required: ['longNick'],
} as const satisfies JSONSchema; } as const satisfies JSONSchema;
type Payload = FromSchema<typeof SchemaData>; type Payload = FromSchema<typeof SchemaData>;
@@ -17,6 +15,7 @@ type Payload = FromSchema<typeof SchemaData>;
export class SetLongNick extends BaseAction<Payload, any> { export class SetLongNick extends BaseAction<Payload, any> {
actionName = ActionName.SetLongNick; actionName = ActionName.SetLongNick;
PayloadSchema = SchemaData; PayloadSchema = SchemaData;
protected async _handle(payload: Payload) { protected async _handle(payload: Payload) {
const NTQQUserApi = this.CoreContext.getApiContext().UserApi; const NTQQUserApi = this.CoreContext.getApiContext().UserApi;
const ret = await NTQQUserApi.setLongNick(payload.longNick); const ret = await NTQQUserApi.setLongNick(payload.longNick);

View File

@@ -1,6 +1,5 @@
import BaseAction from '../BaseAction'; import BaseAction from '../BaseAction';
import { ActionName, BaseCheckResult } from '../types'; import { ActionName } from '../types';
import { NTQQUserApi } from '@/core/apis';
import { FromSchema, JSONSchema } from 'json-schema-to-ts'; import { FromSchema, JSONSchema } from 'json-schema-to-ts';
// 设置在线状态 // 设置在线状态
@@ -9,7 +8,7 @@ const SchemaData = {
properties: { properties: {
status: { type: 'number' }, status: { type: 'number' },
extStatus: { type: 'number' }, extStatus: { type: 'number' },
batteryStatus: { type: 'number' } batteryStatus: { type: 'number' },
}, },
required: ['status', 'extStatus', 'batteryStatus'], required: ['status', 'extStatus', 'batteryStatus'],
} as const satisfies JSONSchema; } as const satisfies JSONSchema;
@@ -19,6 +18,7 @@ type Payload = FromSchema<typeof SchemaData>;
export class SetOnlineStatus extends BaseAction<Payload, null> { export class SetOnlineStatus extends BaseAction<Payload, null> {
actionName = ActionName.SetOnlineStatus; actionName = ActionName.SetOnlineStatus;
PayloadSchema = SchemaData; PayloadSchema = SchemaData;
protected async _handle(payload: Payload) { protected async _handle(payload: Payload) {
// 可设置状态 // 可设置状态
// { status: 10, extStatus: 1027, batteryStatus: 0 } // { status: 10, extStatus: 1027, batteryStatus: 0 }

View File

@@ -2,12 +2,14 @@ import BaseAction from '../BaseAction';
import { ActionName, BaseCheckResult } from '../types'; import { ActionName, BaseCheckResult } from '../types';
import * as fs from 'node:fs'; import * as fs from 'node:fs';
import { checkFileReceived, uri2local } from '@/common/utils/file'; import { checkFileReceived, uri2local } from '@/common/utils/file';
interface Payload { interface Payload {
file: string file: string;
} }
export default class SetAvatar extends BaseAction<Payload, null> { export default class SetAvatar extends BaseAction<Payload, null> {
actionName = ActionName.SetQQAvatar; actionName = ActionName.SetQQAvatar;
// 用不着复杂检测 // 用不着复杂检测
protected async check(payload: Payload): Promise<BaseCheckResult> { protected async check(payload: Payload): Promise<BaseCheckResult> {
if (!payload.file || typeof payload.file != 'string') { if (!payload.file || typeof payload.file != 'string') {
@@ -20,6 +22,7 @@ export default class SetAvatar extends BaseAction<Payload, null> {
valid: true, valid: true,
}; };
} }
protected async _handle(payload: Payload): Promise<null> { protected async _handle(payload: Payload): Promise<null> {
const NTQQUserApi = this.CoreContext.getApiContext().UserApi; const NTQQUserApi = this.CoreContext.getApiContext().UserApi;
const { path, isLocal, errMsg, success } = (await uri2local(this.CoreContext.NapCatTempPath, payload.file)); const { path, isLocal, errMsg, success } = (await uri2local(this.CoreContext.NapCatTempPath, payload.file));
@@ -30,7 +33,8 @@ export default class SetAvatar extends BaseAction<Payload, null> {
await checkFileReceived(path, 5000); // 文件不存在QQ会崩溃需要提前判断 await checkFileReceived(path, 5000); // 文件不存在QQ会崩溃需要提前判断
const ret = await NTQQUserApi.setQQAvatar(path); const ret = await NTQQUserApi.setQQAvatar(path);
if (!isLocal) { if (!isLocal) {
fs.unlink(path, () => { }); fs.unlink(path, () => {
});
} }
if (!ret) { if (!ret) {
throw `头像${payload.file}设置失败,api无返回`; throw `头像${payload.file}设置失败,api无返回`;
@@ -43,7 +47,8 @@ export default class SetAvatar extends BaseAction<Payload, null> {
} }
} else { } else {
if (!isLocal) { if (!isLocal) {
fs.unlink(path, () => { }); fs.unlink(path, () => {
});
} }
throw `头像${payload.file}设置失败,无法获取头像,文件可能不存在`; throw `头像${payload.file}设置失败,无法获取头像,文件可能不存在`;
} }

View File

@@ -1,4 +1,3 @@
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';
@@ -8,7 +7,7 @@ const SchemaData = {
properties: { properties: {
nick: { type: 'string' }, nick: { type: 'string' },
longNick: { type: 'string' }, longNick: { type: 'string' },
sex: { type: 'number' }//传Sex值建议传0 sex: { type: 'number' },//传Sex值建议传0
}, },
required: ['nick', 'longNick', 'sex'], required: ['nick', 'longNick', 'sex'],
} as const satisfies JSONSchema; } as const satisfies JSONSchema;
@@ -18,6 +17,7 @@ type Payload = FromSchema<typeof SchemaData>;
export class SetSelfProfile extends BaseAction<Payload, any | null> { export class SetSelfProfile extends BaseAction<Payload, any | null> {
actionName = ActionName.SetSelfProfile; actionName = ActionName.SetSelfProfile;
PayloadSchema = SchemaData; PayloadSchema = SchemaData;
protected async _handle(payload: Payload) { protected async _handle(payload: Payload) {
const NTQQUserApi = this.CoreContext.getApiContext().UserApi; const NTQQUserApi = this.CoreContext.getApiContext().UserApi;
const ret = await NTQQUserApi.modifySelfProfile({ const ret = await NTQQUserApi.modifySelfProfile({
@@ -25,7 +25,7 @@ export class SetSelfProfile extends BaseAction<Payload, any | null> {
longNick: payload.longNick, longNick: payload.longNick,
sex: payload.sex, sex: payload.sex,
birthday: { birthday_year: '', birthday_month: '', birthday_day: '' }, birthday: { birthday_year: '', birthday_month: '', birthday_day: '' },
location: undefined location: undefined,
}); });
return ret; return ret;
} }

View File

@@ -1,6 +1,5 @@
import BaseAction from '../BaseAction'; import BaseAction from '../BaseAction';
import { ActionName } from '../types'; import { ActionName } from '../types';
import { NTQQSystemApi } from '@/core/apis';
import { FromSchema, JSONSchema } from 'json-schema-to-ts'; import { FromSchema, JSONSchema } from 'json-schema-to-ts';
const SchemaData = { const SchemaData = {
@@ -8,8 +7,8 @@ const SchemaData = {
properties: { properties: {
words: { words: {
type: 'array', type: 'array',
items: { type: 'string' } items: { type: 'string' },
} },
}, },
required: ['words'], required: ['words'],
} as const satisfies JSONSchema; } as const satisfies JSONSchema;
@@ -19,6 +18,7 @@ type Payload = FromSchema<typeof SchemaData>;
export class TranslateEnWordToZn extends BaseAction<Payload, Array<any> | null> { export class TranslateEnWordToZn extends BaseAction<Payload, Array<any> | null> {
actionName = ActionName.TranslateEnWordToZn; actionName = ActionName.TranslateEnWordToZn;
PayloadSchema = SchemaData; PayloadSchema = SchemaData;
protected async _handle(payload: Payload) { protected async _handle(payload: Payload) {
const NTQQSystemApi = this.CoreContext.getApiContext().SystemApi; const NTQQSystemApi = this.CoreContext.getApiContext().SystemApi;
const ret = await NTQQSystemApi.translateEnWordToZn(payload.words); const ret = await NTQQSystemApi.translateEnWordToZn(payload.words);

View File

@@ -17,6 +17,7 @@ type Payload = FromSchema<typeof SchemaData>;
export class sharePeer extends BaseAction<Payload, any> { export class sharePeer extends BaseAction<Payload, any> {
actionName = ActionName.SharePeer; actionName = ActionName.SharePeer;
PayloadSchema = SchemaData; PayloadSchema = SchemaData;
protected async _handle(payload: Payload) { protected async _handle(payload: Payload) {
const NTQQUserApi = this.CoreContext.getApiContext().UserApi; const NTQQUserApi = this.CoreContext.getApiContext().UserApi;
const NTQQGroupApi = this.CoreContext.getApiContext().GroupApi; const NTQQGroupApi = this.CoreContext.getApiContext().GroupApi;
@@ -27,18 +28,21 @@ export class sharePeer extends BaseAction<Payload, any> {
} }
} }
} }
const SchemaDataGroupEx = { const SchemaDataGroupEx = {
type: 'object', type: 'object',
properties: { properties: {
group_id: { type: 'string' }, group_id: { type: 'string' },
}, },
required: ['group_id'] required: ['group_id'],
} as const satisfies JSONSchema; } as const satisfies JSONSchema;
type PayloadGroupEx = FromSchema<typeof SchemaDataGroupEx>; type PayloadGroupEx = FromSchema<typeof SchemaDataGroupEx>;
export class shareGroupEx extends BaseAction<PayloadGroupEx, any> { export class shareGroupEx extends BaseAction<PayloadGroupEx, any> {
actionName = ActionName.ShareGroupEx; actionName = ActionName.ShareGroupEx;
PayloadSchema = SchemaDataGroupEx; PayloadSchema = SchemaDataGroupEx;
protected async _handle(payload: PayloadGroupEx) { protected async _handle(payload: PayloadGroupEx) {
const NTQQGroupApi = this.CoreContext.getApiContext().GroupApi; const NTQQGroupApi = this.CoreContext.getApiContext().GroupApi;
return await NTQQGroupApi.getArkJsonGroupShare(payload.group_id); return await NTQQGroupApi.getArkJsonGroupShare(payload.group_id);

View File

@@ -1,13 +1,14 @@
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';
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>;
@@ -15,6 +16,7 @@ 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) {
const NTQQGroupApi = this.CoreContext.getApiContext().GroupApi; const NTQQGroupApi = this.CoreContext.getApiContext().GroupApi;
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,7 +1,6 @@
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';
const SchemaData = { const SchemaData = {
type: 'object', type: 'object',
@@ -9,7 +8,7 @@ const SchemaData = {
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>;
@@ -17,6 +16,7 @@ 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) {
const NTQQGroupApi = this.CoreContext.getApiContext().GroupApi; const NTQQGroupApi = this.CoreContext.getApiContext().GroupApi;
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

@@ -16,16 +16,18 @@ export interface GetFileResponse {
file_name?: string; file_name?: string;
base64?: string; base64?: string;
} }
const GetFileBase_PayloadSchema = { const GetFileBase_PayloadSchema = {
type: 'object', type: 'object',
properties: { properties: {
file: { type: 'string' } file: { type: 'string' },
}, },
required: ['file'] required: ['file'],
} as const satisfies JSONSchema; } as const satisfies JSONSchema;
export class GetFileBase extends BaseAction<GetFilePayload, GetFileResponse> { export class GetFileBase extends BaseAction<GetFilePayload, GetFileResponse> {
PayloadSchema: any = GetFileBase_PayloadSchema; PayloadSchema: any = GetFileBase_PayloadSchema;
private getElement(msg: RawMessage): { id: string, element: VideoElement | FileElement } { private getElement(msg: RawMessage): { id: string, element: VideoElement | FileElement } {
let element = msg.elements.find(e => e.fileElement); let element = msg.elements.find(e => e.fileElement);
if (!element) { if (!element) {
@@ -38,6 +40,7 @@ export class GetFileBase extends BaseAction<GetFilePayload, GetFileResponse> {
} }
return { id: element.elementId, element: element.fileElement }; return { id: element.elementId, element: element.fileElement };
} }
protected async _handle(payload: GetFilePayload): Promise<GetFileResponse> { protected async _handle(payload: GetFilePayload): Promise<GetFileResponse> {
const NTQQFriendApi = this.CoreContext.getApiContext().FriendApi; const NTQQFriendApi = this.CoreContext.getApiContext().FriendApi;
const NTQQUserApi = this.CoreContext.getApiContext().UserApi; const NTQQUserApi = this.CoreContext.getApiContext().UserApi;
@@ -87,7 +90,7 @@ export class GetFileBase extends BaseAction<GetFilePayload, GetFileResponse> {
file: downloadPath, file: downloadPath,
url: downloadPath, url: downloadPath,
file_size: fileSize, file_size: fileSize,
file_name: fileName file_name: fileName,
}; };
if (true/*enableLocalFile2Url*/) { if (true/*enableLocalFile2Url*/) {
try { try {
@@ -127,7 +130,7 @@ export class GetFileBase extends BaseAction<GetFilePayload, GetFileResponse> {
file: downloadPath, file: downloadPath,
url: downloadPath, url: downloadPath,
file_size: NTSearchNameResult[0].fileSize.toString(), file_size: NTSearchNameResult[0].fileSize.toString(),
file_name: NTSearchNameResult[0].fileName file_name: NTSearchNameResult[0].fileName,
}; };
if (true/*enableLocalFile2Url*/) { if (true/*enableLocalFile2Url*/) {
try { try {
@@ -207,20 +210,21 @@ const GetFile_PayloadSchema = {
type: 'object', type: 'object',
properties: { properties: {
file_id: { type: 'string' }, file_id: { type: 'string' },
file: { type: 'string' } file: { type: 'string' },
}, },
required: ['file_id'] required: ['file_id'],
} as const satisfies JSONSchema; } as const satisfies JSONSchema;
type GetFile_Payload_Internal = FromSchema<typeof GetFile_PayloadSchema>; type GetFile_Payload_Internal = FromSchema<typeof GetFile_PayloadSchema>;
interface GetFile_Payload extends GetFile_Payload_Internal { interface GetFile_Payload extends GetFile_Payload_Internal {
file: string file: string;
} }
export default class GetFile extends GetFileBase { export default class GetFile extends GetFileBase {
actionName = ActionName.GetFile; actionName = ActionName.GetFile;
PayloadSchema = GetFile_PayloadSchema; PayloadSchema = GetFile_PayloadSchema;
protected async _handle(payload: GetFile_Payload): Promise<GetFileResponse> { protected async _handle(payload: GetFile_Payload): Promise<GetFileResponse> {
payload.file = payload.file_id; payload.file = payload.file_id;
return super._handle(payload); return super._handle(payload);

View File

@@ -1,14 +1,13 @@
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';
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>;
@@ -16,6 +15,7 @@ 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 NTQQGroupApi = this.CoreContext.getApiContext().GroupApi; const NTQQGroupApi = this.CoreContext.getApiContext().GroupApi;
const ret = await NTQQGroupApi.GetGroupFileCount([payload.group_id?.toString()]); const ret = await NTQQGroupApi.GetGroupFileCount([payload.group_id?.toString()]);

View File

@@ -1,6 +1,7 @@
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';
const SchemaData = { const SchemaData = {
type: 'object', type: 'object',
properties: { properties: {
@@ -8,7 +9,7 @@ const SchemaData = {
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>;
@@ -16,6 +17,7 @@ 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) {
const NTQQMsgApi = this.CoreContext.getApiContext().MsgApi; const NTQQMsgApi = this.CoreContext.getApiContext().MsgApi;
const ret = await NTQQMsgApi.getGroupFileList(payload.group_id.toString(), { const ret = await NTQQMsgApi.getGroupFileList(payload.group_id.toString(), {
@@ -23,8 +25,10 @@ export class GetGroupFileList extends BaseAction<Payload, { FileList: Array<any>
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

@@ -2,7 +2,7 @@ import { GetFileBase, GetFilePayload, GetFileResponse } from './GetFile';
import { ActionName } from '../types'; import { ActionName } from '../types';
interface Payload extends GetFilePayload { interface Payload extends GetFilePayload {
out_format: 'mp3' | 'amr' | 'wma' | 'm4a' | 'spx' | 'ogg' | 'wav' | 'flac' out_format: 'mp3' | 'amr' | 'wma' | 'm4a' | 'spx' | 'ogg' | 'wav' | 'flac';
} }
export default class GetRecord extends GetFileBase { export default class GetRecord extends GetFileBase {

View File

@@ -1,13 +1,14 @@
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';
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>;
@@ -15,6 +16,7 @@ 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) {
const NTQQGroupApi = this.CoreContext.getApiContext().GroupApi; const NTQQGroupApi = this.CoreContext.getApiContext().GroupApi;
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

@@ -5,9 +5,11 @@ import { join as joinPath } from 'node:path';
import { calculateFileMD5, httpDownload } from '@/common/utils/file'; import { calculateFileMD5, httpDownload } from '@/common/utils/file';
import { randomUUID } from 'crypto'; import { randomUUID } from 'crypto';
import { FromSchema, JSONSchema } from 'json-schema-to-ts'; import { FromSchema, JSONSchema } from 'json-schema-to-ts';
interface FileResponse { interface FileResponse {
file: string; file: string;
} }
const SchemaData = { const SchemaData = {
type: 'object', type: 'object',
properties: { properties: {
@@ -18,9 +20,9 @@ const SchemaData = {
headers: { headers: {
type: ['string', 'array'], type: ['string', 'array'],
items: { items: {
type: 'string' type: 'string',
} },
} },
}, },
} as const satisfies JSONSchema; } as const satisfies JSONSchema;
@@ -29,6 +31,7 @@ type Payload = FromSchema<typeof SchemaData>;
export default class GoCQHTTPDownloadFile extends BaseAction<Payload, FileResponse> { export default class GoCQHTTPDownloadFile extends BaseAction<Payload, FileResponse> {
actionName = ActionName.GoCQHTTP_DownloadFile; actionName = ActionName.GoCQHTTP_DownloadFile;
PayloadSchema = SchemaData; PayloadSchema = SchemaData;
protected async _handle(payload: Payload): Promise<FileResponse> { protected async _handle(payload: Payload): Promise<FileResponse> {
const isRandomName = !payload.name; const isRandomName = !payload.name;
const name = payload.name || randomUUID(); const name = payload.name || randomUUID();

View File

@@ -1,8 +1,7 @@
import BaseAction from '../BaseAction'; import BaseAction from '../BaseAction';
import { OB11ForwardMessage, OB11Message, OB11MessageData } from '../../types'; import { OB11ForwardMessage, OB11Message, OB11MessageData } from '../../types';
import { NTQQMsgApi } from '@/core/apis';
import { OB11Constructor } from '../../helper/data'; import { OB11Constructor } from '../../helper/data';
import { ActionName, BaseCheckResult } from '../types'; import { ActionName } from '../types';
import { FromSchema, JSONSchema } from 'json-schema-to-ts'; import { FromSchema, JSONSchema } from 'json-schema-to-ts';
import { MessageUnique } from '@/common/utils/MessageUnique'; import { MessageUnique } from '@/common/utils/MessageUnique';
@@ -10,7 +9,7 @@ const SchemaData = {
type: 'object', type: 'object',
properties: { properties: {
message_id: { type: 'string' }, message_id: { type: 'string' },
id: { type: 'string' } id: { type: 'string' },
}, },
} as const satisfies JSONSchema; } as const satisfies JSONSchema;
@@ -23,6 +22,7 @@ interface Response {
export class GoCQHTTPGetForwardMsgAction extends BaseAction<Payload, any> { export class GoCQHTTPGetForwardMsgAction extends BaseAction<Payload, any> {
actionName = ActionName.GoCQHTTP_GetForwardMsg; actionName = ActionName.GoCQHTTP_GetForwardMsg;
PayloadSchema = SchemaData; PayloadSchema = SchemaData;
protected async _handle(payload: Payload): Promise<any> { protected async _handle(payload: Payload): Promise<any> {
const NTQQMsgApi = this.CoreContext.getApiContext().MsgApi; const NTQQMsgApi = this.CoreContext.getApiContext().MsgApi;
const msgId = payload.message_id || payload.id; const msgId = payload.message_id || payload.id;
@@ -40,8 +40,12 @@ export class GoCQHTTPGetForwardMsgAction extends BaseAction<Payload, any> {
} }
const msgList = data.msgList; const msgList = data.msgList;
const messages = await Promise.all(msgList.map(async msg => { const messages = await Promise.all(msgList.map(async msg => {
const resMsg = await OB11Constructor.message(this.CoreContext, msg, "array"); const resMsg = await OB11Constructor.message(this.CoreContext, msg, 'array');
resMsg.message_id = MessageUnique.createMsg({ guildId: '', chatType: msg.chatType, peerUid: msg.peerUid }, msg.msgId)!; resMsg.message_id = MessageUnique.createMsg({
guildId: '',
chatType: msg.chatType,
peerUid: msg.peerUid,
}, msg.msgId)!;
return resMsg; return resMsg;
})); }));
messages.map(msg => { messages.map(msg => {

View File

@@ -1,8 +1,7 @@
import BaseAction from '../BaseAction'; import BaseAction from '../BaseAction';
import { OB11Message, OB11User } from '../../types'; import { OB11Message } from '../../types';
import { ActionName } from '../types'; import { ActionName } from '../types';
import { ChatType, RawMessage } from '@/core/entities'; import { ChatType, RawMessage } from '@/core/entities';
import { NTQQMsgApi } from '@/core/apis/msg';
import { OB11Constructor } from '../../helper/data'; import { OB11Constructor } from '../../helper/data';
import { FromSchema, JSONSchema } from 'json-schema-to-ts'; import { FromSchema, JSONSchema } from 'json-schema-to-ts';
import { MessageUnique } from '@/common/utils/MessageUnique'; import { MessageUnique } from '@/common/utils/MessageUnique';
@@ -17,9 +16,9 @@ const SchemaData = {
user_id: { type: ['number', 'string'] }, user_id: { type: ['number', 'string'] },
message_seq: { type: 'number' }, message_seq: { type: 'number' },
count: { type: 'number' }, count: { type: 'number' },
reverseOrder: { type: 'boolean' } reverseOrder: { type: 'boolean' },
}, },
required: ['user_id'] required: ['user_id'],
} as const satisfies JSONSchema; } as const satisfies JSONSchema;
type Payload = FromSchema<typeof SchemaData>; type Payload = FromSchema<typeof SchemaData>;
@@ -27,6 +26,7 @@ type Payload = FromSchema<typeof SchemaData>;
export default class GetFriendMsgHistory extends BaseAction<Payload, Response> { export default class GetFriendMsgHistory extends BaseAction<Payload, Response> {
actionName = ActionName.GetFriendMsgHistory; actionName = ActionName.GetFriendMsgHistory;
PayloadSchema = SchemaData; PayloadSchema = SchemaData;
protected async _handle(payload: Payload): Promise<Response> { protected async _handle(payload: Payload): Promise<Response> {
const NTQQUserApi = this.CoreContext.getApiContext().UserApi; const NTQQUserApi = this.CoreContext.getApiContext().UserApi;
const NTQQMsgApi = this.CoreContext.getApiContext().MsgApi; const NTQQMsgApi = this.CoreContext.getApiContext().MsgApi;
@@ -53,7 +53,7 @@ export default class GetFriendMsgHistory extends BaseAction<Payload, Response> {
msg.id = MessageUnique.createMsg({ guildId: '', chatType: msg.chatType, peerUid: msg.peerUid }, msg.msgId); msg.id = MessageUnique.createMsg({ guildId: '', chatType: msg.chatType, peerUid: msg.peerUid }, msg.msgId);
})); }));
//转换消息 //转换消息
const ob11MsgList = await Promise.all(msgList.map(msg => OB11Constructor.message(this.CoreContext, msg, "array"))); const ob11MsgList = await Promise.all(msgList.map(msg => OB11Constructor.message(this.CoreContext, msg, 'array')));
return { 'messages': ob11MsgList }; return { 'messages': ob11MsgList };
} }
} }

View File

@@ -1,15 +1,15 @@
import BaseAction from '../BaseAction'; import BaseAction from '../BaseAction';
import { ActionName } from '../types'; import { ActionName } from '../types';
import { WebHonorType } from '@/core/entities'; import { WebHonorType } from '@/core/entities';
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: {
group_id: { type: [ 'number' , 'string' ] }, group_id: { type: ['number', 'string'] },
type: { enum: [WebHonorType.ALL, WebHonorType.EMOTION, WebHonorType.LEGEND, WebHonorType.PERFORMER, WebHonorType.STRONG_NEWBIE, WebHonorType.TALKATIVE] } type: { enum: [WebHonorType.ALL, WebHonorType.EMOTION, WebHonorType.LEGEND, WebHonorType.PERFORMER, WebHonorType.STRONG_NEWBIE, WebHonorType.TALKATIVE] },
}, },
required: ['group_id'] required: ['group_id'],
} as const satisfies JSONSchema; } as const satisfies JSONSchema;
// enum是不是有点抽象 // enum是不是有点抽象
type Payload = FromSchema<typeof SchemaData>; type Payload = FromSchema<typeof SchemaData>;
@@ -17,6 +17,7 @@ type Payload = FromSchema<typeof SchemaData>;
export class GetGroupHonorInfo extends BaseAction<Payload, Array<any>> { export class GetGroupHonorInfo extends BaseAction<Payload, Array<any>> {
actionName = ActionName.GetGroupHonorInfo; actionName = ActionName.GetGroupHonorInfo;
PayloadSchema = SchemaData; PayloadSchema = SchemaData;
protected async _handle(payload: Payload) { protected async _handle(payload: Payload) {
if (!payload.type) { if (!payload.type) {
payload.type = WebHonorType.ALL; payload.type = WebHonorType.ALL;

View File

@@ -5,6 +5,7 @@ import { ChatType, Peer, RawMessage } from '@/core/entities';
import { OB11Constructor } from '../../helper/data'; import { OB11Constructor } from '../../helper/data';
import { FromSchema, JSONSchema } from 'json-schema-to-ts'; import { FromSchema, JSONSchema } from 'json-schema-to-ts';
import { MessageUnique } from '@/common/utils/MessageUnique'; import { MessageUnique } from '@/common/utils/MessageUnique';
interface Response { interface Response {
messages: OB11Message[]; messages: OB11Message[];
} }
@@ -15,9 +16,9 @@ const SchemaData = {
group_id: { type: ['number', 'string'] }, group_id: { type: ['number', 'string'] },
message_seq: { type: 'number' }, message_seq: { type: 'number' },
count: { type: 'number' }, count: { type: 'number' },
reverseOrder: { type: 'boolean' } reverseOrder: { type: 'boolean' },
}, },
required: ['group_id'] required: ['group_id'],
} as const satisfies JSONSchema; } as const satisfies JSONSchema;
type Payload = FromSchema<typeof SchemaData>; type Payload = FromSchema<typeof SchemaData>;
@@ -25,6 +26,7 @@ type Payload = FromSchema<typeof SchemaData>;
export default class GoCQHTTPGetGroupMsgHistory extends BaseAction<Payload, Response> { export default class GoCQHTTPGetGroupMsgHistory extends BaseAction<Payload, Response> {
actionName = ActionName.GoCQHTTP_GetGroupMsgHistory; actionName = ActionName.GoCQHTTP_GetGroupMsgHistory;
PayloadSchema = SchemaData; PayloadSchema = SchemaData;
protected async _handle(payload: Payload): Promise<Response> { protected async _handle(payload: Payload): Promise<Response> {
const NTQQMsgApi = this.CoreContext.getApiContext().MsgApi; const NTQQMsgApi = this.CoreContext.getApiContext().MsgApi;
//处理参数 //处理参数
@@ -46,7 +48,7 @@ export default class GoCQHTTPGetGroupMsgHistory extends BaseAction<Payload, Resp
})); }));
//转换消息 //转换消息
const ob11MsgList = await Promise.all(msgList.map(msg => OB11Constructor.message(this.CoreContext, msg, "array"))); const ob11MsgList = await Promise.all(msgList.map(msg => OB11Constructor.message(this.CoreContext, msg, 'array')));
return { 'messages': ob11MsgList }; return { 'messages': ob11MsgList };
} }
} }

View File

@@ -7,7 +7,7 @@ const SchemaData = {
type: 'object', type: 'object',
properties: { properties: {
no_cache: { type: 'boolean' }, no_cache: { type: 'boolean' },
} },
} as const satisfies JSONSchema; } as const satisfies JSONSchema;
export class GetOnlineClient extends BaseAction<void, Array<any>> { export class GetOnlineClient extends BaseAction<void, Array<any>> {

View File

@@ -4,12 +4,13 @@ import { OB11Constructor } from '../../helper/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';
import { calcQQLevel } from '@/common/utils/helper'; import { calcQQLevel } from '@/common/utils/helper';
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>;
@@ -32,7 +33,7 @@ export default class GoCQHTTPGetStrangerInfo extends BaseAction<Payload, OB11Use
qid: extendData.info.qid, qid: extendData.info.qid,
level: extendData.info.qqLevel && calcQQLevel(extendData.info.qqLevel) || 0, level: extendData.info.qqLevel && calcQQLevel(extendData.info.qqLevel) || 0,
login_days: 0, login_days: 0,
uid: '' uid: '',
}; };
return ret; return ret;
} }

View File

@@ -3,15 +3,16 @@ import BaseAction from '../BaseAction';
import { ActionName } from '../types'; import { ActionName } from '../types';
import { QuickAction, QuickActionEvent } from '@/onebot/types'; import { QuickAction, QuickActionEvent } from '@/onebot/types';
interface Payload{ interface Payload {
context: QuickActionEvent, context: QuickActionEvent,
operation: QuickAction operation: QuickAction
} }
export class GoCQHTTPHandleQuickAction extends BaseAction<Payload, null>{ export class GoCQHTTPHandleQuickAction extends BaseAction<Payload, null> {
actionName = ActionName.GoCQHTTP_HandleQuickAction; actionName = ActionName.GoCQHTTP_HandleQuickAction;
protected async _handle(payload: Payload): Promise<null> { protected async _handle(payload: Payload): Promise<null> {
handleQuickOperation(this.CoreContext,payload.context, payload.operation).then().catch(this.CoreContext.context.logger.logError); handleQuickOperation(this.CoreContext, payload.context, payload.operation).then().catch(this.CoreContext.context.logger.logError);
return null; return null;
} }
} }

View File

@@ -1,6 +1,7 @@
import SendMsg, { normalize } from '../msg/SendMsg'; import SendMsg, { normalize } from '../msg/SendMsg';
import { OB11PostSendMsg } from '../../types'; import { OB11PostSendMsg } from '../../types';
import { ActionName } from '../types'; import { ActionName } from '../types';
// 未验证 // 未验证
export class GoCQHTTPSendForwardMsg extends SendMsg { export class GoCQHTTPSendForwardMsg extends SendMsg {
actionName = ActionName.GoCQHTTP_SendForwardMsg; actionName = ActionName.GoCQHTTP_SendForwardMsg;

View File

@@ -3,6 +3,7 @@ import BaseAction from '../BaseAction';
import { ActionName } from '../types'; import { ActionName } from '../types';
import { unlink } from 'node:fs'; import { unlink } from 'node:fs';
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: {
@@ -10,21 +11,27 @@ const SchemaData = {
content: { type: 'string' }, content: { type: 'string' },
image: { type: 'string' }, image: { type: 'string' },
pinned: { type: 'number' }, pinned: { type: 'number' },
confirmRequired: { type: 'number' } confirmRequired: { type: 'number' },
}, },
required: ['group_id', 'content'] required: ['group_id', 'content'],
} as const satisfies JSONSchema; } as const satisfies JSONSchema;
type Payload = FromSchema<typeof SchemaData>; type Payload = FromSchema<typeof SchemaData>;
export class SendGroupNotice extends BaseAction<Payload, null> { export class SendGroupNotice extends BaseAction<Payload, null> {
actionName = ActionName.GoCQHTTP_SendGroupNotice; actionName = ActionName.GoCQHTTP_SendGroupNotice;
protected async _handle(payload: Payload) { protected async _handle(payload: Payload) {
const NTQQGroupApi = this.CoreContext.getApiContext().GroupApi; const NTQQGroupApi = this.CoreContext.getApiContext().GroupApi;
let UploadImage: { id: string, width: number, height: number } | undefined = undefined; let UploadImage: { id: string, width: number, height: number } | undefined = undefined;
if (payload.image) { if (payload.image) {
//公告图逻辑 //公告图逻辑
const { errMsg, path, isLocal, success } = (await uri2local(this.CoreContext.NapCatTempPath,payload.image)); const {
errMsg,
path,
isLocal,
success,
} = (await uri2local(this.CoreContext.NapCatTempPath, payload.image));
if (!success) { if (!success) {
throw `群公告${payload.image}设置失败,image字段可能格式不正确`; throw `群公告${payload.image}设置失败,image字段可能格式不正确`;
} }
@@ -37,7 +44,8 @@ export class SendGroupNotice extends BaseAction<Payload, null> {
throw `群公告${payload.image}设置失败,图片上传失败`; throw `群公告${payload.image}设置失败,图片上传失败`;
} }
if (!isLocal) { if (!isLocal) {
unlink(path, () => { }); unlink(path, () => {
});
} }
UploadImage = ImageUploadResult.picInfo; UploadImage = ImageUploadResult.picInfo;
} }

View File

@@ -6,6 +6,7 @@ import { sendMsg } from '@/onebot/action/msg/SendMsg';
import { uri2local } from '@/common/utils/file'; import { uri2local } from '@/common/utils/file';
import { FromSchema, JSONSchema } from 'json-schema-to-ts'; import { FromSchema, JSONSchema } from 'json-schema-to-ts';
import { SendMsgElementConstructor } from '@/onebot/helper/msg'; import { SendMsgElementConstructor } from '@/onebot/helper/msg';
const SchemaData = { const SchemaData = {
type: 'object', type: 'object',
properties: { properties: {
@@ -13,9 +14,9 @@ const SchemaData = {
file: { type: 'string' }, file: { type: 'string' },
name: { type: 'string' }, name: { type: 'string' },
folder: { type: 'string' }, folder: { type: 'string' },
folder_id: { type: 'string' }//临时扩展 folder_id: { type: 'string' },//临时扩展
}, },
required: ['group_id', 'file', 'name'] required: ['group_id', 'file', 'name'],
} as const satisfies JSONSchema; } as const satisfies JSONSchema;
type Payload = FromSchema<typeof SchemaData>; type Payload = FromSchema<typeof SchemaData>;
@@ -23,6 +24,7 @@ type Payload = FromSchema<typeof SchemaData>;
export default class GoCQHTTPUploadGroupFile extends BaseAction<Payload, null> { export default class GoCQHTTPUploadGroupFile extends BaseAction<Payload, null> {
actionName = ActionName.GoCQHTTP_UploadGroupFile; actionName = ActionName.GoCQHTTP_UploadGroupFile;
PayloadSchema = SchemaData; PayloadSchema = SchemaData;
protected async _handle(payload: Payload): Promise<null> { protected async _handle(payload: Payload): Promise<null> {
let file = payload.file; let file = payload.file;
if (fs.existsSync(file)) { if (fs.existsSync(file)) {
@@ -33,7 +35,10 @@ export default class GoCQHTTPUploadGroupFile extends BaseAction<Payload, null> {
throw new Error(downloadResult.errMsg); throw new Error(downloadResult.errMsg);
} }
const sendFileEle: SendFileElement = await SendMsgElementConstructor.file(this.CoreContext, downloadResult.path, payload.name, payload.folder_id); const sendFileEle: SendFileElement = await SendMsgElementConstructor.file(this.CoreContext, downloadResult.path, payload.name, payload.folder_id);
await sendMsg(this.CoreContext, { chatType: ChatType.group, peerUid: payload.group_id.toString() }, [sendFileEle], [], true); await sendMsg(this.CoreContext, {
chatType: ChatType.group,
peerUid: payload.group_id.toString(),
}, [sendFileEle], [], true);
return null; return null;
} }
} }

Some files were not shown because too many files have changed in this diff Show More