Compare commits

..

19 Commits

Author SHA1 Message Date
手瓜一十雪
77505a6f5b release: 2.2.31 2024-09-01 09:31:59 +08:00
手瓜一十雪
19c729aa23 chore: appid 2024-09-01 09:30:38 +08:00
Wesley F. Young
595888128a release: 2.2.30 2024-08-31 23:43:01 +08:00
手瓜一十雪
51589d0eae fix: 群精华上限修改 2024-08-31 22:11:18 +08:00
Wesley F. Young
f1643ac549 fix: get file way 01 get by msg & seq id 2024-08-31 20:30:42 +08:00
手瓜一十雪
3f24461612 feat: support 27597 2024-08-31 19:01:25 +08:00
Wesley F. Young
b5deb198de refactor: inline all NTQQXxxApi uses 2024-08-31 16:00:03 +08:00
Wesley F. Young
78452cf6a9 chore: clean code for webapi.ts 2024-08-31 14:18:11 +08:00
Wesley F. Young
4b4a784f56 chore: clean code for user.ts 2024-08-31 14:11:22 +08:00
Wesley F. Young
3e53cbcf8f chore: clean code for system.ts 2024-08-31 14:09:25 +08:00
Wesley F. Young
f34740f1f0 chore: clean code for group.ts 2024-08-31 14:07:48 +08:00
Wesley F. Young
b406bdfc37 chore: clean code for group.ts 2024-08-31 14:02:36 +08:00
Wesley F. Young
03c056702c chore: clean code for friend.ts 2024-08-31 13:53:30 +08:00
Wesley F. Young
9c5f3f1946 chore: clean code for collection.ts 2024-08-31 13:37:22 +08:00
Wesley F. Young
b50d7c24e7 refactor: move CacheApi to cache.ts 2024-08-31 13:36:21 +08:00
Wesley F. Young
f05cf68945 chore: clean code for file.ts 2024-08-31 13:35:29 +08:00
Alen
efc1875e35 release: 2.2.29 2024-08-31 12:53:50 +08:00
Alen
df063e6762 Merge pull request #326 from cnxysoft/upmain
fix: 群成员信息
2024-08-31 11:55:56 +08:00
Alen
e5c55b4339 fix: 群成员信息 2024-08-31 11:53:07 +08:00
85 changed files with 418 additions and 764 deletions

View File

@@ -4,7 +4,7 @@
"name": "NapCatQQ", "name": "NapCatQQ",
"slug": "NapCat.Framework", "slug": "NapCat.Framework",
"description": "高性能的 OneBot 11 协议实现", "description": "高性能的 OneBot 11 协议实现",
"version": "2.2.28", "version": "2.2.31",
"icon": "./logo.png", "icon": "./logo.png",
"authors": [ "authors": [
{ {

View File

@@ -2,7 +2,7 @@
"name": "napcat", "name": "napcat",
"private": true, "private": true,
"type": "module", "type": "module",
"version": "2.2.28", "version": "2.2.31",
"scripts": { "scripts": {
"build:framework": "vite build --mode framework", "build:framework": "vite build --mode framework",
"build:shell": "vite build --mode shell", "build:shell": "vite build --mode shell",

View File

@@ -138,19 +138,19 @@ export function isEqual(obj1: any, obj2: any) {
export function getDefaultQQVersionConfigInfo(): QQVersionConfigType { export function getDefaultQQVersionConfigInfo(): QQVersionConfigType {
if (os.platform() === 'linux') { if (os.platform() === 'linux') {
return { return {
baseVersion: '3.2.12-27254', baseVersion: '3.2.12-27597',
curVersion: '3.2.12-27254', curVersion: '3.2.12-27597',
prevVersion: '', prevVersion: '',
onErrorVersions: [], onErrorVersions: [],
buildId: '27254', buildId: '27597',
}; };
} }
return { return {
baseVersion: '9.9.15-27391', baseVersion: '9.9.15-27597',
curVersion: '9.9.15-27391', curVersion: '9.9.15-27597',
prevVersion: '', prevVersion: '',
onErrorVersions: [], onErrorVersions: [],
buildId: '27391', buildId: '27597',
}; };
} }

View File

@@ -71,6 +71,6 @@ export class QQBasicInfoWrapper {
// else // else
this.context.logger.log(`[QQ版本兼容性检测] 获取Appid异常 请检测NapCat/QQNT是否正常`); this.context.logger.log(`[QQ版本兼容性检测] 获取Appid异常 请检测NapCat/QQNT是否正常`);
this.context.logger.log(`[QQ版本兼容性检测] ${fullVersion} 版本兼容性不佳,可能会导致一些功能无法正常使用`,); this.context.logger.log(`[QQ版本兼容性检测] ${fullVersion} 版本兼容性不佳,可能会导致一些功能无法正常使用`,);
return { appid: systemPlatform === 'linux' ? '537240795' : '537240709', qua: this.getQUAInternal() }; return { appid: systemPlatform === 'linux' ? '537243600' : '537243441', qua: this.getQUAInternal() };
} }
} }

View File

@@ -1 +1 @@
export const napCatVersion = '2.2.28'; export const napCatVersion = '2.2.31';

View File

@@ -16,7 +16,8 @@ export async function getVideoInfo(filePath: string, logger: LogWrapper) {
filePath: string filePath: string
}>((resolve, reject) => { }>((resolve, reject) => {
const ffmpegPath = process.env.FFMPEG_PATH; const ffmpegPath = process.env.FFMPEG_PATH;
ffmpegPath && ffmpeg.setFfmpegPath(ffmpegPath); if (ffmpegPath)
ffmpeg.setFfmpegPath(ffmpegPath);
ffmpeg(filePath).ffprobe((err: any, metadata: ffmpeg.FfprobeData) => { ffmpeg(filePath).ffprobe((err: any, metadata: ffmpeg.FfprobeData) => {
if (err) { if (err) {
reject(err); reject(err);

63
src/core/apis/cache.ts Normal file
View File

@@ -0,0 +1,63 @@
import {
CacheFileListItem,
CacheFileType,
ChatCacheListItemBasic,
ChatType,
InstanceContext,
NapCatCore,
} from '@/core';
export class NTQQCacheApi {
context: InstanceContext;
core: NapCatCore;
constructor(context: InstanceContext, core: NapCatCore) {
this.context = context;
this.core = core;
}
async setCacheSilentScan(isSilent: boolean = true) {
return '';
}
getCacheSessionPathList() {
return '';
}
clearCache(cacheKeys: Array<string> = ['tmp', 'hotUpdate']) {
// 参数未验证
return this.context.session.getStorageCleanService().clearCacheDataByKeys(cacheKeys);
}
addCacheScannedPaths(pathMap: object = {}) {
return this.context.session.getStorageCleanService().addCacheScanedPaths(pathMap);
}
scanCache() {
//return (await this.context.session.getStorageCleanService().scanCache()).size;
}
getHotUpdateCachePath() {
// 未实现
return '';
}
getDesktopTmpPath() {
// 未实现
return '';
}
getChatCacheList(type: ChatType, pageSize: number = 1000, pageIndex: number = 0) {
return this.context.session.getStorageCleanService().getChatCacheInfo(type, pageSize, 1, pageIndex);
}
getFileCacheInfo(fileType: CacheFileType, pageSize: number = 1000, lastRecord?: CacheFileListItem) {
// const _lastRecord = lastRecord ? lastRecord : { fileType: fileType };
// 需要五个参数
// return napCatCore.session.getStorageCleanService().getFileCacheInfo();
}
async clearChatCache(chats: ChatCacheListItemBasic[] = [], fileKeys: string[] = []) {
return this.context.session.getStorageCleanService().clearChatCacheInfo(chats, fileKeys);
}
}

View File

@@ -10,7 +10,7 @@ export class NTQQCollectionApi {
} }
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 = { return this.context.session.getCollectionService().createNewCollectionItem({
commInfo: { commInfo: {
bid: 1, bid: 1,
category: 2, category: 2,
@@ -43,12 +43,11 @@ export class NTQQCollectionApi {
fileList: [], fileList: [],
}, },
need_share_url: false, need_share_url: false,
}; });
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 = { return this.context.session.getCollectionService().getCollectionItemList({
category: category, category: category,
groupId: -1, groupId: -1,
forceSync: true, forceSync: true,
@@ -56,7 +55,6 @@ export class NTQQCollectionApi {
timeStamp: '0', timeStamp: '0',
count: count, count: count,
searchDown: true, searchDown: true,
}; });
return this.context.session.getCollectionService().getCollectionItemList(param);
} }
} }

View File

@@ -1,7 +1,4 @@
import { import {
CacheFileListItem,
CacheFileType,
ChatCacheListItemBasic,
ChatType, ChatType,
ElementType, ElementType,
IMAGE_HTTP_HOST, IMAGE_HTTP_HOST,
@@ -26,10 +23,8 @@ import { calculateFileMD5, isGIF } from '@/common/file';
import pathLib from 'node:path'; import pathLib from 'node:path';
import { defaultVideoThumbB64, getVideoInfo } from '@/common/video'; import { defaultVideoThumbB64, getVideoInfo } from '@/common/video';
import ffmpeg from 'fluent-ffmpeg'; import ffmpeg from 'fluent-ffmpeg';
import fsnormal from 'node:fs';
import { encodeSilk } from '@/common/audio'; import { encodeSilk } from '@/common/audio';
export class NTQQFileApi { export class NTQQFileApi {
context: InstanceContext; context: InstanceContext;
core: NapCatCore; core: NapCatCore;
@@ -41,10 +36,6 @@ export class NTQQFileApi {
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) {
return fileType.fileTypeFromFile(filePath);
}
async copyFile(filePath: string, destPath: string) { async copyFile(filePath: string, destPath: string) {
await this.core.util.copyFile(filePath, destPath); await this.core.util.copyFile(filePath, destPath);
} }
@@ -60,18 +51,15 @@ export class NTQQFileApi {
})).urlResult.domainUrl; })).urlResult.domainUrl;
} }
// 上传文件到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.
const fileMd5 = await calculateFileMD5(filePath); const fileMd5 = await calculateFileMD5(filePath);
let ext: string = (await this.getFileType(filePath))?.ext as string || ''; const extOrEmpty = (await fileType.fileTypeFromFile(filePath))?.ext;
if (ext) { const ext = extOrEmpty ? `.${extOrEmpty}` : '';
ext = '.' + ext;
}
let fileName = `${path.basename(filePath)}`; let fileName = `${path.basename(filePath)}`;
if (fileName.indexOf('.') === -1) { if (fileName.indexOf('.') === -1) {
fileName += ext; fileName += ext;
} }
const mediaPath = this.context.session.getMsgService().getRichMediaFilePathForGuild({ const mediaPath = this.context.session.getMsgService().getRichMediaFilePathForGuild({
md5HexStr: fileMd5, md5HexStr: fileMd5,
fileName: fileName, fileName: fileName,
@@ -82,6 +70,7 @@ export class NTQQFileApi {
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);
return { return {
@@ -93,11 +82,7 @@ export class NTQQFileApi {
}; };
} }
async createValidSendFileElement( async createValidSendFileElement(filePath: string, fileName: string = '', folderId: string = '',): Promise<SendFileElement> {
filePath: string,
fileName: string = '',
folderId: string = '',
): Promise<SendFileElement> {
const { const {
fileName: _fileName, fileName: _fileName,
path, path,
@@ -118,55 +103,36 @@ export class NTQQFileApi {
}; };
} }
async createValidSendPicElement( async createValidSendPicElement(picPath: string, summary: string = '', subType: 0 | 1 = 0,): Promise<SendPicElement> {
picPath: string, const { md5, fileName, path, fileSize } = await this.core.apis.FileApi.uploadFile(picPath, ElementType.PIC, subType);
summary: string = '',
subType: 0 | 1 = 0,
): Promise<SendPicElement> {
const {
md5,
fileName,
path,
fileSize,
} = await this.core.apis.FileApi.uploadFile(picPath, ElementType.PIC, subType);
if (fileSize === 0) { if (fileSize === 0) {
throw new Error('文件异常大小为0'); throw new Error('文件异常大小为0');
} }
const imageSize = await this.core.apis.FileApi.getImageSize(picPath); const imageSize = await this.core.apis.FileApi.getImageSize(picPath);
const picElement: any = {
md5HexStr: md5,
fileSize: fileSize.toString(),
picWidth: imageSize?.width,
picHeight: imageSize?.height,
fileName: fileName,
sourcePath: path,
original: true,
picType: isGIF(picPath) ? PicType.gif : PicType.jpg,
picSubType: subType,
fileUuid: '',
fileSubId: '',
thumbFileSize: 0,
summary,
};
return { return {
elementType: ElementType.PIC, elementType: ElementType.PIC,
elementId: '', elementId: '',
picElement, picElement: {
md5HexStr: md5,
fileSize: fileSize.toString(),
picWidth: imageSize.width,
picHeight: imageSize.height,
fileName: fileName,
sourcePath: path,
original: true,
picType: isGIF(picPath) ? PicType.gif : PicType.jpg,
picSubType: subType,
fileUuid: '',
fileSubId: '',
thumbFileSize: 0,
summary,
} as PicElement,
}; };
} }
async createValidSendVideoElement( async createValidSendVideoElement(filePath: string, fileName: string = '', diyThumbPath: string = ''): Promise<SendVideoElement> {
filePath: string,
fileName: string = '',
diyThumbPath: string = '',
): Promise<SendVideoElement> {
const logger = this.core.context.logger; const logger = this.core.context.logger;
const { const { fileName: _fileName, path, fileSize, md5 } = await this.core.apis.FileApi.uploadFile(filePath, ElementType.VIDEO);
fileName: _fileName,
path,
fileSize,
md5,
} = await this.core.apis.FileApi.uploadFile(filePath, ElementType.VIDEO);
if (fileSize === 0) { if (fileSize === 0) {
throw new Error('文件异常大小为0'); throw new Error('文件异常大小为0');
} }
@@ -182,9 +148,10 @@ export class NTQQFileApi {
try { try {
videoInfo = await getVideoInfo(path, logger); videoInfo = await getVideoInfo(path, logger);
} catch (e) { } catch (e) {
logger.logError('获取视频信息失败', e); logger.logError('获取视频信息失败,将使用默认值', e);
} }
const createThumb = new Promise<string | undefined>((resolve, reject) => { const thumbPath = new Map();
const _thumbPath = await new Promise<string | undefined>((resolve, reject) => {
const thumbFileName = `${md5}_0.png`; const thumbFileName = `${md5}_0.png`;
const thumbPath = pathLib.join(thumb, thumbFileName); const thumbPath = pathLib.join(thumb, thumbFileName);
ffmpeg(filePath) ffmpeg(filePath)
@@ -195,7 +162,7 @@ export class NTQQFileApi {
resolve(thumbPath); resolve(thumbPath);
}).catch(reject); }).catch(reject);
} else { } else {
fsnormal.writeFileSync(thumbPath, Buffer.from(defaultVideoThumbB64, 'base64')); fs.writeFileSync(thumbPath, Buffer.from(defaultVideoThumbB64, 'base64'));
resolve(thumbPath); resolve(thumbPath);
} }
}) })
@@ -204,31 +171,14 @@ export class NTQQFileApi {
filename: thumbFileName, filename: thumbFileName,
folder: thumb, folder: thumb,
size: videoInfo.width + 'x' + videoInfo.height, size: videoInfo.width + 'x' + videoInfo.height,
}).on('end', () => { })
.on('end', () => {
resolve(thumbPath); resolve(thumbPath);
}); });
}); });
const thumbPath = new Map();
const _thumbPath = await createThumb;
const thumbSize = _thumbPath ? (await fsPromises.stat(_thumbPath)).size : 0; const thumbSize = _thumbPath ? (await fsPromises.stat(_thumbPath)).size : 0;
// log("生成缩略图", _thumbPath)
thumbPath.set(0, _thumbPath); thumbPath.set(0, _thumbPath);
const thumbMd5 = _thumbPath ? await calculateFileMD5(_thumbPath) : ''; const thumbMd5 = _thumbPath ? await calculateFileMD5(_thumbPath) : '';
// "fileElement": {
// "fileMd5": "",
// "fileName": "1.mp4",
// "filePath": "C:\\Users\\nanae\\OneDrive\\Desktop\\1.mp4",
// "fileSize": "1847007",
// "picHeight": 1280,
// "picWidth": 720,
// "picThumbPath": {},
// "file10MMd5": "",
// "fileSha": "",
// "fileSha3": "",
// "fileUuid": "",
// "fileSubId": "",
// "thumbFileSize": 750
// }
return { return {
elementType: ElementType.VIDEO, elementType: ElementType.VIDEO,
elementId: '', elementId: '',
@@ -243,28 +193,12 @@ export class NTQQFileApi {
thumbWidth: videoInfo.width, thumbWidth: videoInfo.width,
thumbHeight: videoInfo.height, thumbHeight: videoInfo.height,
fileSize: '' + fileSize, fileSize: '' + fileSize,
// fileFormat: videotype
// fileUuid: "",
// transferStatus: 0,
// progress: 0,
// invalidState: 0,
// fileSubId: "",
// fileBizId: null,
// originVideoMd5: "",
// fileFormat: 2,
// import_rich_media_context: null,
// sourceVideoCodecFormat: 2
}, },
}; };
} }
async createValidSendPttElement(pttPath: string): Promise<SendPttElement> { async createValidSendPttElement(pttPath: string): Promise<SendPttElement> {
const { const { converted, path: silkPath, duration } = await encodeSilk(pttPath, this.core.NapCatTempPath, this.core.context.logger);
converted,
path: silkPath,
duration,
} = await encodeSilk(pttPath, this.core.NapCatTempPath, this.core.context.logger);
// 生成语音 Path: silkPath Time: duration
if (!silkPath) { if (!silkPath) {
throw new Error('语音转换失败, 请检查语音文件是否正常'); throw new Error('语音转换失败, 请检查语音文件是否正常');
} }
@@ -283,7 +217,6 @@ export class NTQQFileApi {
filePath: path, filePath: path,
md5HexStr: md5, md5HexStr: md5,
fileSize: fileSize, fileSize: fileSize,
// duration: Math.max(1, Math.round(fileSize / 1024 / 3)), // 一秒钟大概是3kb大小, 小于1秒的按1秒算
duration: duration ?? 1, duration: duration ?? 1,
formatType: 1, formatType: 1,
voiceType: 1, voiceType: 1,
@@ -299,9 +232,6 @@ export class NTQQFileApi {
}; };
} }
async downloadMediaByUuid() {
//napCatCore.session.getRichMediaService().downloadFileForFileUuid();
}
async downloadFileForModelId(peer: Peer, modelId: string, unknown: string, timeout = 1000 * 60 * 2) { async downloadFileForModelId(peer: Peer, modelId: string, unknown: string, timeout = 1000 * 60 * 2) {
const [, fileTransNotifyInfo] = await this.core.eventWrapper.callNormalEventV2( const [, fileTransNotifyInfo] = await this.core.eventWrapper.callNormalEventV2(
'NodeIKernelRichMediaService/downloadFileForModelId', 'NodeIKernelRichMediaService/downloadFileForModelId',
@@ -314,6 +244,7 @@ export class NTQQFileApi {
); );
return fileTransNotifyInfo.filePath; return fileTransNotifyInfo.filePath;
} }
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);
// 用于下载收到的消息中的图片等 // 用于下载收到的消息中的图片等
@@ -328,7 +259,7 @@ export class NTQQFileApi {
return sourcePath; return sourcePath;
} }
} }
const [, fileTransNotifyInfo] = await this.core.eventWrapper.callNormalEventV2( const [, completeRetData] = await this.core.eventWrapper.callNormalEventV2(
'NodeIKernelMsgService/downloadRichMedia', 'NodeIKernelMsgService/downloadRichMedia',
'NodeIKernelMsgListener/onRichMediaDownloadComplete', 'NodeIKernelMsgListener/onRichMediaDownloadComplete',
[{ [{
@@ -348,29 +279,20 @@ export class NTQQFileApi {
1, 1,
timeout, timeout,
); );
const msg = await this.core.apis.MsgApi.getMsgsByMsgId({ return completeRetData.filePath;
guildId: '',
chatType: chatType,
peerUid: peerUid,
}, [msgId]);
const mixElement = msg.msgList.find((msg) => msg.msgId === msgId)?.elements.find((e) => e.elementId === elementId);
const mixElementInner = mixElement?.videoElement ?? mixElement?.fileElement ?? mixElement?.pttElement ?? mixElement?.picElement;
let realPath = mixElementInner?.filePath;
if (!realPath) {
const picThumbPath: Map<number, string> = (mixElementInner as any)?.picThumbPath;
const picThumbPathList = Array.from(picThumbPath.values());
if (picThumbPathList.length > 0) realPath = picThumbPathList[0];
}
return realPath;
} }
async getImageSize(filePath: string): Promise<ISizeCalculationResult | undefined> { async getImageSize(filePath: string): Promise<ISizeCalculationResult> {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
imageSize(filePath, (err, dimensions) => { imageSize(filePath, (err, dimensions) => {
if (err) { if (err) {
reject(err); reject(err);
} else { } else {
resolve(dimensions); if (!dimensions) {
reject(new Error('获取图片尺寸失败'));
} else {
resolve(dimensions);
}
} }
}); });
}); });
@@ -443,11 +365,8 @@ export class NTQQFileApi {
'NodeIKernelFileAssistantListener/onFileSearch', 'NodeIKernelFileAssistantListener/onFileSearch',
[ [
keys, keys,
{ { resultType: 2, pageLimit: 1 },
resultType: 2, randomResultId,
pageLimit: 1,
},
randomResultId
], ],
(ret) => { (ret) => {
searchId = ret; searchId = ret;
@@ -463,7 +382,7 @@ export class NTQQFileApi {
fileSize: number = 1024576, fileSize: number = 1024576,
estimatedTime: number = (fileSize * 1000 / 1024576) + 5000, estimatedTime: number = (fileSize * 1000 / 1024576) + 5000,
) { ) {
const [, ret] = await this.core.eventWrapper.callNormalEventV2( const [, fileData] = await this.core.eventWrapper.callNormalEventV2(
'NodeIKernelFileAssistantService/downloadFile', 'NodeIKernelFileAssistantService/downloadFile',
'NodeIKernelFileAssistantListener/onFileStatusChanged', 'NodeIKernelFileAssistantListener/onFileStatusChanged',
[[fileId]], [[fileId]],
@@ -472,7 +391,7 @@ export class NTQQFileApi {
1, 1,
estimatedTime, // estimate 1MB/s estimatedTime, // estimate 1MB/s
); );
return ret.filePath!; return fileData.filePath!;
} }
async getImageUrl(element: PicElement) { async getImageUrl(element: PicElement) {
@@ -482,20 +401,19 @@ export class NTQQFileApi {
const url: string = element.originImageUrl!; // 没有域名 const url: string = element.originImageUrl!; // 没有域名
const md5HexStr = element.md5HexStr; const md5HexStr = element.md5HexStr;
const fileMd5 = element.md5HexStr; const fileMd5 = element.md5HexStr;
// const fileUuid = element.fileUuid;
if (url) { if (url) {
const UrlParse = new URL(IMAGE_HTTP_HOST + url);//临时解析拼接 const parsedUrl = new URL(IMAGE_HTTP_HOST + url);//临时解析拼接
const imageAppid = UrlParse.searchParams.get('appid'); const imageAppid = parsedUrl.searchParams.get('appid');
const isNewPic = imageAppid && ['1406', '1407'].includes(imageAppid); const isNTFlavoredPic = imageAppid && ['1406', '1407'].includes(imageAppid);
if (isNewPic) { if (isNTFlavoredPic) {
let UrlRkey = UrlParse.searchParams.get('rkey'); let rkey = parsedUrl.searchParams.get('rkey');
if (UrlRkey) { if (rkey) {
return IMAGE_HTTP_HOST_NT + url; return IMAGE_HTTP_HOST_NT + url;
} }
const rkeyData = await this.rkeyManager.getRkey(); const rkeyData = await this.rkeyManager.getRkey();
UrlRkey = imageAppid === '1406' ? rkeyData.private_rkey : rkeyData.group_rkey; rkey = imageAppid === '1406' ? rkeyData.private_rkey : rkeyData.group_rkey;
return IMAGE_HTTP_HOST_NT + url + `${UrlRkey}`; return IMAGE_HTTP_HOST_NT + url + `${rkey}`;
} else { } else {
// 老的图片url不需要rkey // 老的图片url不需要rkey
return IMAGE_HTTP_HOST + url; return IMAGE_HTTP_HOST + url;
@@ -509,57 +427,3 @@ export class NTQQFileApi {
} }
} }
export class NTQQFileCacheApi {
context: InstanceContext;
core: NapCatCore;
constructor(context: InstanceContext, core: NapCatCore) {
this.context = context;
this.core = core;
}
async setCacheSilentScan(isSilent: boolean = true) {
return '';
}
getCacheSessionPathList() {
return '';
}
clearCache(cacheKeys: Array<string> = ['tmp', 'hotUpdate']) {
// 参数未验证
return this.context.session.getStorageCleanService().clearCacheDataByKeys(cacheKeys);
}
addCacheScannedPaths(pathMap: object = {}) {
return this.context.session.getStorageCleanService().addCacheScanedPaths(pathMap);
}
scanCache() {
//return (await this.context.session.getStorageCleanService().scanCache()).size;
}
getHotUpdateCachePath() {
// 未实现
return '';
}
getDesktopTmpPath() {
// 未实现
return '';
}
getChatCacheList(type: ChatType, pageSize: number = 1000, pageIndex: number = 0) {
return this.context.session.getStorageCleanService().getChatCacheInfo(type, pageSize, 1, pageIndex);
}
getFileCacheInfo(fileType: CacheFileType, pageSize: number = 1000, lastRecord?: CacheFileListItem) {
// const _lastRecord = lastRecord ? lastRecord : { fileType: fileType };
// 需要五个参数
// return napCatCore.session.getStorageCleanService().getFileCacheInfo();
}
async clearChatCache(chats: ChatCacheListItemBasic[] = [], fileKeys: string[] = []) {
return this.context.session.getStorageCleanService().clearChatCacheInfo(chats, fileKeys);
}
}

View File

@@ -16,47 +16,42 @@ export class NTQQFriendApi {
// } // }
} }
async getBuddyV2(refresh = false): Promise<FriendV2[]> { async getBuddyV2SimpleInfoMap(refresh = false) {
const uids: string[] = [];
const buddyService = this.context.session.getBuddyService(); const buddyService = this.context.session.getBuddyService();
const buddyListV2 = refresh ? await buddyService.getBuddyListV2('0', BuddyListReqType.KNOMAL) : await buddyService.getBuddyListV2('0', BuddyListReqType.KNOMAL); const buddyListV2 = refresh ? await buddyService.getBuddyListV2('0', BuddyListReqType.KNOMAL) : await buddyService.getBuddyListV2('0', BuddyListReqType.KNOMAL);
uids.push(...buddyListV2.data.flatMap(item => item.buddyUids)); const uids = buddyListV2.data.flatMap(item => item.buddyUids);
const data = await this.core.eventWrapper.callNoListenerEvent( return await this.core.eventWrapper.callNoListenerEvent(
'NodeIKernelProfileService/getCoreAndBaseInfo', 'nodeStore', uids, 'NodeIKernelProfileService/getCoreAndBaseInfo',
'nodeStore',
uids,
); );
return Array.from(data.values()); }
async getBuddyV2(refresh = false): Promise<FriendV2[]> {
return Array.from((await this.getBuddyV2SimpleInfoMap(refresh)).values());
} }
async getBuddyIdMap(refresh = false): Promise<LimitedHashTable<string, string>> { async getBuddyIdMap(refresh = false): Promise<LimitedHashTable<string, string>> {
const uids: string[] = [];
const retMap: LimitedHashTable<string, string> = new LimitedHashTable<string, string>(5000); const retMap: LimitedHashTable<string, string> = new LimitedHashTable<string, string>(5000);
const buddyService = this.context.session.getBuddyService(); const data = await this.getBuddyV2SimpleInfoMap(refresh);
const buddyListV2 = refresh ? await buddyService.getBuddyListV2('0', BuddyListReqType.KNOMAL) : await buddyService.getBuddyListV2('0', BuddyListReqType.KNOMAL); data.forEach((value) => retMap.set(value.uin!, value.uid!));
uids.push(...buddyListV2.data.flatMap(item => item.buddyUids));
const data = await this.core.eventWrapper.callNoListenerEvent(
'NodeIKernelProfileService/getCoreAndBaseInfo', 'nodeStore', uids,
);
data.forEach((value) => {
retMap.set(value.uin!, value.uid!);
});
//console.log('getBuddyIdMap', retMap.getValue);
return retMap; return retMap;
} }
async getBuddyV2ExWithCate(refresh = false) { async getBuddyV2ExWithCate(refresh = false) {
const uids: string[] = [];
const categoryMap: Map<string, any> = new Map(); const categoryMap: Map<string, any> = new Map();
const buddyService = this.context.session.getBuddyService(); const buddyService = this.context.session.getBuddyService();
const buddyListV2 = refresh ? (await buddyService.getBuddyListV2('0', BuddyListReqType.KNOMAL)).data : (await buddyService.getBuddyListV2('0', BuddyListReqType.KNOMAL)).data; const buddyListV2 = refresh ? (await buddyService.getBuddyListV2('0', BuddyListReqType.KNOMAL)).data : (await buddyService.getBuddyListV2('0', BuddyListReqType.KNOMAL)).data;
uids.push( const uids = buddyListV2.flatMap(item => {
...buddyListV2.flatMap(item => { item.buddyUids.forEach(uid => {
item.buddyUids.forEach(uid => { categoryMap.set(uid, { categoryId: item.categoryId, categoryName: item.categroyName });
categoryMap.set(uid, { categoryId: item.categoryId, categoryName: item.categroyName }); });
}); return item.buddyUids;
return item.buddyUids; });
}));
const data = await this.core.eventWrapper.callNoListenerEvent( const data = await this.core.eventWrapper.callNoListenerEvent(
'NodeIKernelProfileService/getCoreAndBaseInfo', 'nodeStore', uids, 'NodeIKernelProfileService/getCoreAndBaseInfo',
'nodeStore',
uids,
); );
return buddyListV2.map(category => ({ return buddyListV2.map(category => ({
categoryId: category.categoryId, categoryId: category.categoryId,

View File

@@ -34,17 +34,20 @@ export class NTQQGroupApi {
} }
this.context.logger.logDebug(`加载${this.groups.length}个群组缓存完成`); this.context.logger.logDebug(`加载${this.groups.length}个群组缓存完成`);
} }
async fetchGroupEssenceList(groupCode: string) { async fetchGroupEssenceList(groupCode: string) {
const pskey = (await this.core.apis.UserApi.getPSkey(['qun.qq.com'])).domainPskeyMap.get('qun.qq.com')!; const pskey = (await this.core.apis.UserApi.getPSkey(['qun.qq.com'])).domainPskeyMap.get('qun.qq.com')!;
return this.context.session.getGroupService().fetchGroupEssenceList({ return this.context.session.getGroupService().fetchGroupEssenceList({
groupCode: groupCode, groupCode: groupCode,
pageStart: 0, pageStart: 0,
pageLimit: 300 pageLimit: 300,
}, pskey); }, pskey);
} }
async clearGroupNotifiesUnreadCount(unk: boolean) { async clearGroupNotifiesUnreadCount(unk: boolean) {
return this.context.session.getGroupService().clearGroupNotifiesUnreadCount(unk); return this.context.session.getGroupService().clearGroupNotifiesUnreadCount(unk);
} }
async setGroupAvatar(gc: string, filePath: string) { async setGroupAvatar(gc: string, filePath: string) {
return this.context.session.getGroupService().setHeader(gc, filePath); return this.context.session.getGroupService().setHeader(gc, filePath);
} }
@@ -57,6 +60,7 @@ export class NTQQGroupApi {
); );
return groupList; return groupList;
} }
async getGroupExtFE0Info(GroupCode: string[], forced = true) { async getGroupExtFE0Info(GroupCode: string[], forced = true) {
return this.context.session.getGroupService().getGroupExt0xEF0Info( return this.context.session.getGroupService().getGroupExt0xEF0Info(
GroupCode, GroupCode,
@@ -93,11 +97,12 @@ export class NTQQGroupApi {
showPlayTogetherSwitch: 1, showPlayTogetherSwitch: 1,
starId: 1, starId: 1,
todoSeq: 1, todoSeq: 1,
viewedMsgDisappearTime: 1 viewedMsgDisappearTime: 1,
}, },
forced forced,
); );
} }
async getGroup(groupCode: string, forced = false) { async getGroup(groupCode: string, forced = false) {
let group = this.groupCache.get(groupCode.toString()); let group = this.groupCache.get(groupCode.toString());
if (!group) { if (!group) {
@@ -120,24 +125,13 @@ export class NTQQGroupApi {
return this.getGroupMemberLatestSendTime(GroupCode, uids); return this.getGroupMemberLatestSendTime(GroupCode, uids);
} }
/**
* 通过QQ自带数据库获取群成员最后发言时间(仅返回有效数据 且消耗延迟大 需要进行缓存)
* @param GroupCode 群号
* @param uids QQ号
* @returns Map<string, string> key: uin value: sendTime
* @example
* let ret = await NTQQGroupApi.getGroupMemberLastestSendTime('123456');
* for (let [uin, sendTime] of ret) {
* console.log(uin, sendTime);
* }
*/
async getGroupMemberLatestSendTime(GroupCode: string, uids: string[]) { async getGroupMemberLatestSendTime(GroupCode: string, uids: string[]) {
const getdata = async (uid: string) => { const getData = async (uid: string) => {
const NTRet = await this.getLatestMsgByUids(GroupCode, [uid]); const msgListWrapper = await this.getLatestMsgByUids(GroupCode, [uid]);
if (NTRet.result != 0 && NTRet.msgList.length < 1) { if (msgListWrapper.result !== 0 && msgListWrapper.msgList.length < 1) {
return undefined; return undefined;
} }
return { sendUin: NTRet.msgList[0].senderUin, sendTime: NTRet.msgList[0].msgTime }; return { sendUin: msgListWrapper.msgList[0].senderUin, sendTime: msgListWrapper.msgList[0].msgTime };
}; };
const PromiseData: Promise<({ const PromiseData: Promise<({
sendUin: string; sendUin: string;
@@ -145,7 +139,7 @@ export class NTQQGroupApi {
} | undefined)>[] = []; } | undefined)>[] = [];
const ret: Map<string, string> = new Map(); const ret: Map<string, string> = new Map();
for (const uid of uids) { for (const uid of uids) {
PromiseData.push(getdata(uid).catch(() => undefined)); PromiseData.push(getData(uid).catch(() => undefined));
} }
const allRet = await runAllWithTimeout(PromiseData, 2500); const allRet = await runAllWithTimeout(PromiseData, 2500);
for (const PromiseDo of allRet) { for (const PromiseDo of allRet) {
@@ -249,8 +243,7 @@ export class NTQQGroupApi {
} }
async addGroupEssence(GroupCode: string, msgId: string) { async addGroupEssence(GroupCode: string, msgId: string) {
// 代码没测过 // 需要 ob11msgId -> msgId + (peer) -> msgSeq + msgRandom
// 需要 ob11msgid->msgId + (peer) -> msgSeq + msgRandom
const MsgData = await this.context.session.getMsgService().getMsgsIncludeSelf({ const MsgData = await this.context.session.getMsgService().getMsgsIncludeSelf({
chatType: 2, chatType: 2,
guildId: '', guildId: '',
@@ -261,7 +254,7 @@ export class NTQQGroupApi {
msgRandom: parseInt(MsgData.msgList[0].msgRandom), msgRandom: parseInt(MsgData.msgList[0].msgRandom),
msgSeq: parseInt(MsgData.msgList[0].msgSeq), msgSeq: parseInt(MsgData.msgList[0].msgSeq),
}; };
// GetMsgByShoretID(ShoretID); -> MsgService.getMsgs(Peer,MsgId,1,false); -> 组出参数 // GetMsgByShortID(shortID); -> MsgService.getMsgs(Peer,MsgId,1,false); -> 组出参数
return this.context.session.getGroupService().addGroupEssence(param); return this.context.session.getGroupService().addGroupEssence(param);
} }
@@ -270,8 +263,8 @@ export class NTQQGroupApi {
} }
async deleteGroupBulletin(GroupCode: string, noticeId: string) { async deleteGroupBulletin(GroupCode: string, noticeId: string) {
const _Pskey = (await this.core.apis.UserApi.getPSkey(['qun.qq.com'])).domainPskeyMap.get('qun.qq.com')!; const psKey = (await this.core.apis.UserApi.getPSkey(['qun.qq.com'])).domainPskeyMap.get('qun.qq.com')!;
return this.context.session.getGroupService().deleteGroupBulletin(GroupCode, _Pskey, noticeId); return this.context.session.getGroupService().deleteGroupBulletin(GroupCode, psKey, noticeId);
} }
async quitGroupV2(GroupCode: string, needDeleteLocalMsg: boolean) { async quitGroupV2(GroupCode: string, needDeleteLocalMsg: boolean) {
@@ -282,18 +275,17 @@ export class NTQQGroupApi {
//应该是直接返回不需要Listener的 未经测试 需测试再发布 //应该是直接返回不需要Listener的 未经测试 需测试再发布
return this.context.session.getGroupService().quitGroupV2(param); return this.context.session.getGroupService().quitGroupV2(param);
} }
async removeGroupEssenceBySeq(GroupCode: string, msgRandom: string, msgSeq: string) { async removeGroupEssenceBySeq(GroupCode: string, msgRandom: string, msgSeq: string) {
const param = { const param = {
groupCode: GroupCode, groupCode: GroupCode,
msgRandom: parseInt(msgRandom), msgRandom: parseInt(msgRandom),
msgSeq: parseInt(msgSeq), msgSeq: parseInt(msgSeq),
}; };
// GetMsgByShoretID(ShoretID); -> MsgService.getMsgs(Peer,MsgId,1,false); -> 组出参数
return this.context.session.getGroupService().removeGroupEssence(param); return this.context.session.getGroupService().removeGroupEssence(param);
} }
async removeGroupEssence(GroupCode: string, msgId: string) { async removeGroupEssence(GroupCode: string, msgId: string) {
// 代码没测过
// 需要 ob11msgid->msgId + (peer) -> msgSeq + msgRandom
const MsgData = await this.context.session.getMsgService().getMsgsIncludeSelf({ const MsgData = await this.context.session.getMsgService().getMsgsIncludeSelf({
chatType: 2, chatType: 2,
guildId: '', guildId: '',
@@ -304,7 +296,6 @@ export class NTQQGroupApi {
msgRandom: parseInt(MsgData.msgList[0].msgRandom), msgRandom: parseInt(MsgData.msgList[0].msgRandom),
msgSeq: parseInt(MsgData.msgList[0].msgSeq), msgSeq: parseInt(MsgData.msgList[0].msgSeq),
}; };
// GetMsgByShoretID(ShoretID); -> MsgService.getMsgs(Peer,MsgId,1,false); -> 组出参数
return this.context.session.getGroupService().removeGroupEssence(param); return this.context.session.getGroupService().removeGroupEssence(param);
} }
@@ -361,7 +352,7 @@ export class NTQQGroupApi {
if (membersFromFunc.status === 'fulfilled' && membersFromListener.status === 'fulfilled') { if (membersFromFunc.status === 'fulfilled' && membersFromListener.status === 'fulfilled') {
return new Map([ return new Map([
...membersFromFunc.value.result.infos, ...membersFromFunc.value.result.infos,
...membersFromListener.value[0].infos ...membersFromListener.value[0].infos,
]); ]);
} }
if (membersFromFunc.status === 'fulfilled') { if (membersFromFunc.status === 'fulfilled') {
@@ -386,19 +377,6 @@ export class NTQQGroupApi {
this.context.logger.logDebug(`获取群(${groupQQ})成员列表结果:`, `members: ${result.result.infos.size}`); //, Array.from(result.result.infos.values())); this.context.logger.logDebug(`获取群(${groupQQ})成员列表结果:`, `members: ${result.result.infos.size}`); //, Array.from(result.result.infos.values()));
return result.result.infos; return result.result.infos;
/*
console.log(sceneId);
const result = await napCatCore.getGroupService().getNextMemberList(sceneId, num);
console.log(result);
return result;
*/
}
async getGroupNotifies() {
// 获取管理员变更
// 加群通知,退出通知,需要管理员权限
} }
async getGroupFileCount(Gids: Array<string>) { async getGroupFileCount(Gids: Array<string>) {
@@ -470,19 +448,12 @@ export class NTQQGroupApi {
return this.context.session.getGroupService().modifyGroupName(groupQQ, groupName, false); return this.context.session.getGroupService().modifyGroupName(groupQQ, groupName, false);
} }
// 头衔不可用
/*
async setGroupTitle(groupQQ: string, uid: string, title: string) {
}
*/
async publishGroupBulletin(groupQQ: string, content: string, picInfo: { async publishGroupBulletin(groupQQ: string, content: string, picInfo: {
id: string, id: string,
width: number, width: number,
height: number height: number
} | undefined = undefined, pinned: number = 0, confirmRequired: number = 0) { } | undefined = undefined, pinned: number = 0, confirmRequired: number = 0) {
const _Pskey = (await this.core.apis.UserApi.getPSkey(['qun.qq.com'])).domainPskeyMap.get('qun.qq.com'); const psKey = (await this.core.apis.UserApi.getPSkey(['qun.qq.com'])).domainPskeyMap.get('qun.qq.com');
//text是content内容url编码 //text是content内容url编码
const data = { const data = {
text: encodeURI(content), text: encodeURI(content),
@@ -491,7 +462,7 @@ export class NTQQGroupApi {
pinned: pinned, pinned: pinned,
confirmRequired: confirmRequired, confirmRequired: confirmRequired,
}; };
return this.context.session.getGroupService().publishGroupBulletin(groupQQ, _Pskey!, data); return this.context.session.getGroupService().publishGroupBulletin(groupQQ, psKey!, data);
} }
async getGroupRemainAtTimes(GroupCode: string) { async getGroupRemainAtTimes(GroupCode: string) {

View File

@@ -5,4 +5,5 @@ export * from './msg';
export * from './user'; export * from './user';
export * from './webapi'; export * from './webapi';
export * from './sign'; export * from './sign';
export * from './system'; export * from './system';
export * from './cache';

View File

@@ -14,12 +14,15 @@ export class NTQQMsgApi {
this.context = context; this.context = context;
this.core = core; this.core = core;
} }
async getAioFirstViewLatestMsgs(peer: Peer, MsgCount: number) { async getAioFirstViewLatestMsgs(peer: Peer, MsgCount: number) {
return this.context.session.getMsgService().getAioFirstViewLatestMsgs(peer, MsgCount); return this.context.session.getMsgService().getAioFirstViewLatestMsgs(peer, MsgCount);
} }
async getLatestDbMsgs(peer: Peer, MsgCount: number) { async getLatestDbMsgs(peer: Peer, MsgCount: number) {
return this.context.session.getMsgService().getLatestDbMsgs(peer, MsgCount); return this.context.session.getMsgService().getLatestDbMsgs(peer, MsgCount);
} }
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);
} }
@@ -29,19 +32,10 @@ export class NTQQMsgApi {
} }
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);
//注意此处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, count); return this.context.session.getMsgService().getMsgEmojiLikesList(peer, msgSeq, emojiId, emojiType, '', false, count);
} }
// napCatCore: NapCatCore | null = null;
// enum BaseEmojiType {
// NORMAL_EMOJI,
// SUPER_EMOJI,
// RANDOM_SUPER_EMOJI,
// CHAIN_SUPER_EMOJI,
// EMOJI_EMOJI
// }
async setEmojiLike(peer: Peer, msgSeq: string, emojiId: string, set: boolean = true) { async setEmojiLike(peer: Peer, msgSeq: string, emojiId: string, set: boolean = true) {
// nt_qq//global//nt_data//Emoji//emoji-resource//sysface_res/apng/ 下可以看到所有QQ表情预览 // nt_qq//global//nt_data//Emoji//emoji-resource//sysface_res/apng/ 下可以看到所有QQ表情预览
// nt_qq\global\nt_data\Emoji\emoji-resource\face_config.json 里面有所有表情的id, 自带表情id是QSid, 标准emoji表情id是QCid // nt_qq\global\nt_data\Emoji\emoji-resource\face_config.json 里面有所有表情的id, 自带表情id是QSid, 标准emoji表情id是QCid
@@ -60,7 +54,7 @@ export class NTQQMsgApi {
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 getLatestMsgByUids(peer: Peer, count: number = 20, isReverseOrder: boolean = false) {
return await this.context.session.getMsgService().queryMsgsWithFilterEx('0', '0', '0', { return await this.context.session.getMsgService().queryMsgsWithFilterEx('0', '0', '0', {
chatInfo: peer, chatInfo: peer,
filterMsgType: [], filterMsgType: [],
@@ -76,7 +70,7 @@ export class NTQQMsgApi {
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);
} }
@@ -90,7 +84,7 @@ export class NTQQMsgApi {
async queryMsgsWithFilterExWithSeq(peer: Peer, msgSeq: string) { async queryMsgsWithFilterExWithSeq(peer: Peer, msgSeq: string) {
return await this.context.session.getMsgService().queryMsgsWithFilterEx('0', '0', msgSeq, { return await this.context.session.getMsgService().queryMsgsWithFilterEx('0', '0', msgSeq, {
chatInfo: peer,//此处为Peer 为关键查询参数 没有啥也没有 by mlik iowa chatInfo: peer,
filterMsgType: [], filterMsgType: [],
filterSendersUid: [], filterSendersUid: [],
filterMsgToTime: '0', filterMsgToTime: '0',
@@ -134,10 +128,7 @@ export class NTQQMsgApi {
params, params,
], ],
() => true, () => true,
( /* groupFileListResult: GroupFileInfoUpdateParamType */) => { () => true, // Todo: 应当通过 groupFileListResult 判断
//Developer Mlikiowa Todo: 此处有问题 无法判断是否成功
return true;
},
1, 1,
5000, 5000,
); );
@@ -157,14 +148,6 @@ export class NTQQMsgApi {
} }
async PrepareTempChat(toUserUid: string, GroupCode: string, nickname: string) { async PrepareTempChat(toUserUid: string, GroupCode: string, nickname: string) {
//By Jadx/Ida Mlikiowa
const TempGameSession = {
nickname: '',
gameAppId: '',
selfTinyId: '',
peerRoleId: '',
peerOpenId: '',
};
return this.context.session.getMsgService().prepareTempChat({ return this.context.session.getMsgService().prepareTempChat({
chatType: ChatType.KCHATTYPETEMPC2CFROMGROUP, chatType: ChatType.KCHATTYPETEMPC2CFROMGROUP,
peerUid: toUserUid, peerUid: toUserUid,
@@ -173,7 +156,13 @@ export class NTQQMsgApi {
sig: '', sig: '',
selfPhone: '', selfPhone: '',
selfUid: this.core.selfInfo.uid, selfUid: this.core.selfInfo.uid,
gameSession: TempGameSession, gameSession: {
nickname: '',
gameAppId: '',
selfTinyId: '',
peerRoleId: '',
peerOpenId: '',
},
}); });
} }
@@ -182,7 +171,7 @@ export class NTQQMsgApi {
} }
async sendMsg(peer: Peer, msgElements: SendMessageElement[], waitComplete = true, timeout = 10000) { async sendMsg(peer: Peer, msgElements: SendMessageElement[], waitComplete = true, timeout = 10000) {
//唉? !我有个想法 //唉?!我有个想法
if (peer.chatType === ChatType.KCHATTYPETEMPC2CFROMGROUP && peer.guildId && peer.guildId !== '') { if (peer.chatType === ChatType.KCHATTYPETEMPC2CFROMGROUP && peer.guildId && peer.guildId !== '') {
const member = await this.core.apis.GroupApi.getGroupMember(peer.guildId, peer.peerUid!); const member = await this.core.apis.GroupApi.getGroupMember(peer.guildId, peer.peerUid!);
if (member) { if (member) {
@@ -212,11 +201,7 @@ export class NTQQMsgApi {
1, 1,
timeout, timeout,
); );
return msgList.find(msgRecord => { return msgList.find(msgRecord => msgRecord.guildId === msgId);
if (msgRecord.guildId === msgId) {
return true;
}
});
} }
async generateMsgUniqueId(chatType: number, time: string) { async generateMsgUniqueId(chatType: number, time: string) {
@@ -246,14 +231,10 @@ export class NTQQMsgApi {
new Map(), new Map(),
], ],
() => true, () => true,
(msgRecords) => { (msgRecords) => msgRecords.some(
for (const msgRecord of msgRecords) { msgRecord => msgRecord.peerUid === destPeer.peerUid
if (msgRecord.peerUid == destPeer.peerUid && msgRecord.senderUid == this.core.selfInfo.uid) { && msgRecord.senderUid === this.core.selfInfo.uid
return true; ),
}
}
return false;
},
); );
for (const msg of msgList) { for (const msg of msgList) {
const arkElement = msg.elements.find(ele => ele.arkElement); const arkElement = msg.elements.find(ele => ele.arkElement);
@@ -271,7 +252,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

@@ -13,7 +13,7 @@ export class NTQQSystemApi {
return this.core.util.hasOtherRunningQQProcess(); return this.core.util.hasOtherRunningQQProcess();
} }
async ORCImage(filePath: string) { async ocrImage(filePath: string) {
return this.context.session.getNodeMiscService().wantWinScreenOCR(filePath); return this.context.session.getNodeMiscService().wantWinScreenOCR(filePath);
} }
@@ -21,20 +21,16 @@ export class NTQQSystemApi {
return this.context.session.getRichMediaService().translateEnWordToZn(words); return this.context.session.getRichMediaService().translateEnWordToZn(words);
} }
//调用会超时 没灯用 (好像是通知listener的) onLineDev
async getOnlineDev() { async getOnlineDev() {
return this.context.session.getMsgService().getOnLineDev(); return this.context.session.getMsgService().getOnLineDev();
} }
//1-2-162b9b42-65b9-4405-a8ed-2e256ec8aa50
async getArkJsonCollection(cid: string) { async getArkJsonCollection(cid: string) {
return await this.core.eventWrapper.callNoListenerEvent('NodeIKernelCollectionService/collectionArkShare', '1717662698058'); return await this.core.eventWrapper.callNoListenerEvent('NodeIKernelCollectionService/collectionArkShare', '1717662698058');
} }
async BootMiniApp(appfile: string, params: string) { async bootMiniApp(appFile: string, params: string) {
await this.context.session.getNodeMiscService().setMiniAppVersion('2.16.4'); await this.context.session.getNodeMiscService().setMiniAppVersion('2.16.4');
// const c = await this.context.session.getNodeMiscService().getMiniAppPath(); return this.context.session.getNodeMiscService().startNewMiniApp(appFile, params);
return this.context.session.getNodeMiscService().startNewMiniApp(appfile, params);
} }
} }

View File

@@ -15,9 +15,7 @@ export class NTQQUserApi {
async getProfileLike(uid: string) { async getProfileLike(uid: string) {
return this.context.session.getProfileLikeService().getBuddyProfileLike({ return this.context.session.getProfileLikeService().getBuddyProfileLike({
friendUids: [ friendUids: [uid],
uid,
],
basic: 1, basic: 1,
vote: 1, vote: 1,
favorite: 0, favorite: 0,
@@ -63,41 +61,6 @@ export class NTQQUserApi {
return this.context.session.getGroupService().setHeader(gc, filePath); return this.context.session.getGroupService().setHeader(gc, filePath);
} }
async fetchUserDetailInfos(uids: string[]) {
// TODO: 26702 以上使用新接口 .Dev MliKiowa
const retData: User[] = [];
const [_retData, _retListener] = await this.core.eventWrapper.callNormalEventV2(
'NodeIKernelProfileService/fetchUserDetailInfo',
'NodeIKernelProfileListener/onUserDetailInfoChanged',
[
'BuddyProfileStore',
uids,
UserDetailSource.KSERVER,
[ProfileBizType.KALL],
],
() => true,
(profile) => {
if (uids.includes(profile.uid)) {
const RetUser: User = {
...profile.simpleInfo.coreInfo,
...profile.simpleInfo.status,
...profile.simpleInfo.vasInfo,
...profile.commonExt,
...profile.simpleInfo.baseInfo,
qqLevel: profile.commonExt.qqLevel,
pendantId: '',
};
retData.push(RetUser);
return true;
}
return false;
},
uids.length,
);
return retData;
}
async fetchUserDetailInfo(uid: string, mode: UserDetailSource = UserDetailSource.KDB) { async fetchUserDetailInfo(uid: string, mode: UserDetailSource = UserDetailSource.KDB) {
const [_retData, profile] = await this.core.eventWrapper.callNormalEventV2( const [_retData, profile] = await this.core.eventWrapper.callNormalEventV2(
'NodeIKernelProfileService/fetchUserDetailInfo', 'NodeIKernelProfileService/fetchUserDetailInfo',
@@ -156,7 +119,6 @@ export class NTQQUserApi {
version: 0, version: 0,
aioKeywordVersion: 0, aioKeywordVersion: 0,
}); });
// console.log(robotUinRanges?.response?.robotUinRanges);
return robotUinRanges?.response?.robotUinRanges; return robotUinRanges?.response?.robotUinRanges;
} }
@@ -170,7 +132,7 @@ export class NTQQUserApi {
//需要异常处理 //需要异常处理
async getSkey(): Promise<string | undefined> { async getSKey(): Promise<string | undefined> {
const ClientKeyData = await this.forceFetchClientKey(); const ClientKeyData = await this.forceFetchClientKey();
if (ClientKeyData.result !== 0) { if (ClientKeyData.result !== 0) {
throw new Error('getClientKey Error'); throw new Error('getClientKey Error');
@@ -181,7 +143,7 @@ export class NTQQUserApi {
const cookies: { [key: string]: string; } = await RequestUtil.HttpsGetCookies(requestUrl); const cookies: { [key: string]: string; } = await RequestUtil.HttpsGetCookies(requestUrl);
const skey = cookies['skey']; const skey = cookies['skey'];
if (!skey) { if (!skey) {
throw new Error('getSkey Skey is Empty'); throw new Error('SKey is Empty');
} }
return skey; return skey;
} }
@@ -194,8 +156,8 @@ export class NTQQUserApi {
if (uid) return uid; if (uid) return uid;
uid = (await this.context.session.getUixConvertService().getUid([Uin])).uidInfo.get(Uin); uid = (await this.context.session.getUixConvertService().getUid([Uin])).uidInfo.get(Uin);
if (uid) return uid; if (uid) return uid;
const unveifyUid = (await this.getUserDetailInfoByUinV2(Uin)).detail.uid;//从QQ Native 特殊转换 const unverifiedUid = (await this.getUserDetailInfoByUinV2(Uin)).detail.uid;//从QQ Native 特殊转换
if (unveifyUid.indexOf('*') == -1) uid = unveifyUid; if (unverifiedUid.indexOf('*') == -1) uid = unverifiedUid;
//if (uid) return uid; //if (uid) return uid;
return uid; return uid;
} }
@@ -231,7 +193,10 @@ export class NTQQUserApi {
} }
async getUserDetailInfoByUinV2(Uin: string) { async getUserDetailInfoByUinV2(Uin: string) {
return await this.core.eventWrapper.callNoListenerEvent('NodeIKernelProfileService/getUserDetailInfoByUin', Uin); return await this.core.eventWrapper.callNoListenerEvent(
'NodeIKernelProfileService/getUserDetailInfoByUin',
Uin
);
} }
async forceFetchClientKey() { async forceFetchClientKey() {

View File

@@ -26,8 +26,7 @@ export class NTQQWebApi {
msg_seq: msgSeq, msg_seq: msgSeq,
msg_random: msgRandom, msg_random: msgRandom,
target_group_code: targetGroupCode, target_group_code: targetGroupCode,
}).toString() }).toString()}`;
}`;
try { try {
return RequestUtil.HttpGetText(url, 'GET', '', { 'Cookie': this.cookieToString(cookieObject) }); return RequestUtil.HttpGetText(url, 'GET', '', { 'Cookie': this.cookieToString(cookieObject) });
} catch (e) { } catch (e) {
@@ -35,16 +34,12 @@ export class NTQQWebApi {
} }
} }
async getGroupEssenceMsgAll(GroupCode: string) { async getGroupEssenceMsgAll(GroupCode: string) {
let ret: GroupEssenceMsgRet[] = []; const ret: GroupEssenceMsgRet[] = [];
for (let i = 0; i < 4; i++) { for (let i = 0; i < 20; i++) {
let data = await this.getGroupEssenceMsg(GroupCode, i, 50); const data = await this.getGroupEssenceMsg(GroupCode, i, 50);
if (!data) break; if (!data) break;
if (data.data.is_end) {
ret.push(data);
break;
}
ret.push(data); ret.push(data);
if (data.data.is_end) break;
} }
return ret; return ret;
} }
@@ -55,19 +50,18 @@ export class NTQQWebApi {
page_start: page_start.toString(), page_start: page_start.toString(),
page_limit: page_limit.toString(), page_limit: page_limit.toString(),
group_code: GroupCode, group_code: GroupCode,
}).toString() }).toString()}`;
}`;
let ret;
try { try {
ret = await RequestUtil.HttpGetJson<GroupEssenceMsgRet> const ret = await RequestUtil.HttpGetJson<GroupEssenceMsgRet>(
(url, 'GET', '', { 'Cookie': this.cookieToString(cookieObject) }); url,
'GET',
'',
{ 'Cookie': this.cookieToString(cookieObject) }
);
return ret.retcode === 0 ? ret : undefined;
} catch { } catch {
return undefined; return undefined;
} }
if (ret.retcode !== 0) {
return undefined;
}
return ret;
} }
async getGroupMembers(GroupCode: string, cached: boolean = true): Promise<WebApiGroupMember[]> { async getGroupMembers(GroupCode: string, cached: boolean = true): Promise<WebApiGroupMember[]> {
@@ -75,15 +69,18 @@ export class NTQQWebApi {
const memberData: Array<WebApiGroupMember> = new Array<WebApiGroupMember>(); const memberData: Array<WebApiGroupMember> = new Array<WebApiGroupMember>();
const cookieObject = await this.core.apis.UserApi.getCookies('qun.qq.com'); const cookieObject = await this.core.apis.UserApi.getCookies('qun.qq.com');
const retList: Promise<WebApiGroupMemberRet>[] = []; const retList: Promise<WebApiGroupMemberRet>[] = [];
const fastRet = await RequestUtil.HttpGetJson<WebApiGroupMemberRet> const fastRet = await RequestUtil.HttpGetJson<WebApiGroupMemberRet>(
(`https://qun.qq.com/cgi-bin/qun_mgr/search_group_members?${new URLSearchParams({ `https://qun.qq.com/cgi-bin/qun_mgr/search_group_members?${new URLSearchParams({
st: '0', st: '0',
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) {
return []; return [];
} else { } else {
@@ -95,15 +92,18 @@ export class NTQQWebApi {
const PageNum = Math.ceil(fastRet.count / 40); const PageNum = Math.ceil(fastRet.count / 40);
//遍历批量请求 //遍历批量请求
for (let i = 2; i <= PageNum; i++) { for (let i = 2; i <= PageNum; i++) {
const ret = RequestUtil.HttpGetJson<WebApiGroupMemberRet> const ret = RequestUtil.HttpGetJson<WebApiGroupMemberRet>(
(`https://qun.qq.com/cgi-bin/qun_mgr/search_group_members?${new URLSearchParams({ `https://qun.qq.com/cgi-bin/qun_mgr/search_group_members?${new URLSearchParams({
st: ((i - 1) * 40).toString(), st: ((i - 1) * 40).toString(),
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);
} }
//批量等待 //批量等待
@@ -135,16 +135,19 @@ export class NTQQWebApi {
const cookieObject = await this.core.apis.UserApi.getCookies('qun.qq.com'); const cookieObject = await this.core.apis.UserApi.getCookies('qun.qq.com');
let ret: any = undefined; let ret: any = undefined;
try { try {
ret = await RequestUtil.HttpGetJson<any> ret = await RequestUtil.HttpGetJson<any>(
(`https://web.qun.qq.com/cgi-bin/announce/add_qun_notice${new URLSearchParams({ `https://web.qun.qq.com/cgi-bin/announce/add_qun_notice${new URLSearchParams({
bkn: this.getBknFromCookie(cookieObject), bkn: this.getBknFromCookie(cookieObject),
qid: GroupCode, qid: GroupCode,
text: Content, text: Content,
pinned: '0', pinned: '0',
type: '1', type: '1',
settings: '{"is_show_edit_card":1,"tip_window_type":1,"confirm_required":1}', settings: '{"is_show_edit_card":1,"tip_window_type":1,"confirm_required":1}',
}).toString() }).toString()}`,
}`, 'GET', '', { 'Cookie': this.cookieToString(cookieObject) }); 'GET',
'',
{ 'Cookie': this.cookieToString(cookieObject) }
);
return ret; return ret;
} catch (e) { } catch (e) {
return undefined; return undefined;
@@ -153,16 +156,24 @@ export class NTQQWebApi {
async getGroupNotice(GroupCode: string): Promise<undefined | WebApiGroupNoticeRet> { async getGroupNotice(GroupCode: string): Promise<undefined | WebApiGroupNoticeRet> {
const cookieObject = await this.core.apis.UserApi.getCookies('qun.qq.com'); const cookieObject = await this.core.apis.UserApi.getCookies('qun.qq.com');
let ret: WebApiGroupNoticeRet | undefined = undefined;
try { try {
const url = 'https://web.qun.qq.com/cgi-bin/announce/get_t_list?bkn=' + const ret = await RequestUtil.HttpGetJson<WebApiGroupNoticeRet>(
this.getBknFromCookie(cookieObject) + '&qid=' + GroupCode + '&ft=23&ni=1&n=1&i=1&log_read=1&platform=1&s=-1&n=20'; `https://web.qun.qq.com/cgi-bin/announce/get_t_list?${new URLSearchParams({
bkn: this.getBknFromCookie(cookieObject),
ret = await RequestUtil.HttpGetJson<WebApiGroupNoticeRet>(url, 'GET', '', { 'Cookie': this.cookieToString(cookieObject) }); qid: GroupCode,
if (ret?.ec !== 0) { ft: '23',
return undefined; ni: '1',
} n: '1',
return ret; i: '1',
log_read: '1',
platform: '1',
s: '-1',
}).toString()}&n=20`,
'GET',
'',
{ 'Cookie': this.cookieToString(cookieObject) }
);
return ret?.ec === 0 ? ret : undefined;
} catch (e) { } catch (e) {
return undefined; return undefined;
} }
@@ -171,14 +182,17 @@ export class NTQQWebApi {
async getGroupHonorInfo(groupCode: string, getType: WebHonorType) { async getGroupHonorInfo(groupCode: string, getType: WebHonorType) {
const cookieObject = await this.core.apis.UserApi.getCookies('qun.qq.com'); const cookieObject = await this.core.apis.UserApi.getCookies('qun.qq.com');
const getDataInternal = async (Internal_groupCode: string, Internal_type: number) => { const getDataInternal = async (Internal_groupCode: string, Internal_type: number) => {
const url = `https://qun.qq.com/interactive/honorlist?${new URLSearchParams({
gc: Internal_groupCode,
type: Internal_type.toString(),
}).toString()
}`;
let resJson; let resJson;
try { try {
const res = await RequestUtil.HttpGetText(url, 'GET', '', { 'Cookie': this.cookieToString(cookieObject) }); const res = await RequestUtil.HttpGetText(
`https://qun.qq.com/interactive/honorlist?${new URLSearchParams({
gc: Internal_groupCode,
type: Internal_type.toString(),
}).toString()}`,
'GET',
'',
{ 'Cookie': this.cookieToString(cookieObject) }
);
const match = /window\.__INITIAL_STATE__=(.*?);/.exec(res); const match = /window\.__INITIAL_STATE__=(.*?);/.exec(res);
if (match) { if (match) {
resJson = JSON.parse(match[1].trim()); resJson = JSON.parse(match[1].trim());
@@ -189,7 +203,7 @@ export class NTQQWebApi {
return resJson?.actorList; return resJson?.actorList;
} }
} catch (e) { } catch (e) {
this.context.logger.logDebug('获取当前群荣耀失败', url, e); this.context.logger.logDebug('获取当前群荣耀失败', e);
} }
return undefined; return undefined;
}; };
@@ -268,10 +282,12 @@ export class NTQQWebApi {
this.context.logger.logError('获取快乐源泉失败'); this.context.logger.logError('获取快乐源泉失败');
} }
} }
// 冒尖小春笋好像已经被tx扬了 R.I.P. // 冒尖小春笋好像已经被tx扬了 R.I.P.
if (getType === WebHonorType.EMOTION || getType === WebHonorType.ALL) { if (getType === WebHonorType.EMOTION || getType === WebHonorType.ALL) {
HonorInfo.strong_newbie_list = []; HonorInfo.strong_newbie_list = [];
} }
return HonorInfo; return HonorInfo;
} }

View File

@@ -1,34 +1,10 @@
{ {
"3.2.12-27187": { "3.2.12-27597": {
"appid": 537240645, "appid": 537243600,
"qua": "V1_LNX_NQ_3.2.12_27187_GW_B" "qua": "V1_LNX_NQ_3.2.12_27597_GW_B"
}, },
"3.2.12-27206": { "9.9.15-27597": {
"appid": 537240645, "appid": 537243441,
"qua": "V1_LNX_NQ_3.2.12_27206_GW_B" "qua": "V1_WIN_NQ_9.9.15_27597_GW_B"
},
"3.2.12-27254": {
"appid": 537240795,
"qua": "V1_LNX_NQ_3.2.12_27254_GW_B"
},
"9.9.15-27187": {
"appid": 537240610,
"qua": "V1_WIN_NQ_9.9.15_27187_GW_B"
},
"9.9.15-27206": {
"appid": 537240610,
"qua": "V1_WIN_NQ_9.9.15_27206_GW_B"
},
"9.9.15-27254": {
"appid": 537240709,
"qua": "V1_WIN_NQ_9.9.15_27254_GW_B"
},
"9.9.15-27333": {
"appid": 537240709,
"qua": "V1_WIN_NQ_9.9.15_27333_GW_B"
},
"9.9.15-27391": {
"appid": 537240709,
"qua": "V1_WIN_NQ_9.9.15_27333_GW_B"
} }
} }

View File

@@ -1,4 +0,0 @@
# nekodoge
此协议为替代QQ平台 OnebotV11长期不可靠问题
# 规划路线

View File

View File

@@ -1,19 +0,0 @@
import { createServer } from 'node:net';
export class NewAdapterNetwork {
constructor(public host: number, public port: number) { }
async open() {
const server = createServer((socket) => {
socket.on('data', (data) => {
});
socket.on('end', () => {
});
socket.on('connect', () => {
});
});
server.listen(this.port, this.host);
}
}

View File

@@ -24,10 +24,9 @@ export class FetchEmojiLike extends BaseAction<Payload, any> {
payloadSchema = SchemaData; payloadSchema = SchemaData;
async _handle(payload: Payload) { async _handle(payload: Payload) {
const NTQQMsgApi = this.core.apis.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 this.core.apis.MsgApi.getMsgsByMsgId(msgIdPeer.Peer, [msgIdPeer.MsgId])).msgList[0];
return await NTQQMsgApi.getMsgEmojiLikesList(msgIdPeer.Peer, msg.msgSeq, payload.emojiId, payload.emojiType, +(payload.count ?? 20)); return await this.core.apis.MsgApi.getMsgEmojiLikesList(msgIdPeer.Peer, msg.msgSeq, payload.emojiId, payload.emojiType, +(payload.count ?? 20));
} }
} }

View File

@@ -18,7 +18,6 @@ export class GetCollectionList extends BaseAction<Payload, any> {
payloadSchema = SchemaData; payloadSchema = SchemaData;
async _handle(payload: Payload) { async _handle(payload: Payload) {
const NTQQCollectionApi = this.core.apis.CollectionApi; return await this.core.apis.CollectionApi.getAllCollection(parseInt(payload.category.toString()), +(payload.count ?? 1));
return await NTQQCollectionApi.getAllCollection(parseInt(payload.category.toString()), +(payload.count ?? 1));
} }
} }

View File

@@ -17,8 +17,6 @@ export class GetGroupInfoEx extends BaseAction<Payload, any> {
payloadSchema = SchemaData; payloadSchema = SchemaData;
async _handle(payload: Payload) { async _handle(payload: Payload) {
const NTQQGroupApi = this.core.apis.GroupApi; return (await this.core.apis.GroupApi.getGroupExtFE0Info([payload.group_id.toString()])).result.groupExtInfos.get(payload.group_id.toString());
const groupInfoEx = (await NTQQGroupApi.getGroupExtFE0Info([payload.group_id.toString()])).result.groupExtInfos.get(payload.group_id.toString());
return groupInfoEx;
} }
} }

View File

@@ -5,11 +5,10 @@ export class GetProfileLike extends BaseAction<void, any> {
actionName = ActionName.GetProfileLike; actionName = ActionName.GetProfileLike;
async _handle(payload: void) { async _handle(payload: void) {
const NTQQUserApi = this.core.apis.UserApi; const ret = await this.core.apis.UserApi.getProfileLike(this.core.selfInfo.uid);
const ret = await NTQQUserApi.getProfileLike(this.core.selfInfo.uid);
const listdata: any[] = ret.info.userLikeInfos[0].favoriteInfo.userInfos; const listdata: any[] = ret.info.userLikeInfos[0].favoriteInfo.userInfos;
for (let i = 0; i < listdata.length; i++) { for (let i = 0; i < listdata.length; i++) {
listdata[i].uin = parseInt((await NTQQUserApi.getUinByUidV2(listdata[i].uid)) || ''); listdata[i].uin = parseInt((await this.core.apis.UserApi.getUinByUidV2(listdata[i].uid)) || '');
} }
return listdata; return listdata;
} }

View File

@@ -5,7 +5,6 @@ export class GetRobotUinRange extends BaseAction<void, Array<any>> {
actionName = ActionName.GetRobotUinRange; actionName = ActionName.GetRobotUinRange;
async _handle(payload: void) { async _handle(payload: void) {
const NTQQUserApi = this.core.apis.UserApi; return await this.core.apis.UserApi.getRobotUinRange();
return await NTQQUserApi.getRobotUinRange();
} }
} }

View File

@@ -19,14 +19,13 @@ export class OCRImage extends BaseAction<Payload, any> {
payloadSchema = SchemaData; payloadSchema = SchemaData;
async _handle(payload: Payload) { async _handle(payload: Payload) {
const NTQQSystemApi = this.core.apis.SystemApi;
const { path, isLocal, success } = (await uri2local(this.core.NapCatTempPath, payload.image)); const { path, isLocal, success } = (await uri2local(this.core.NapCatTempPath, payload.image));
if (!success) { if (!success) {
throw `OCR ${payload.image}失败,image字段可能格式不正确`; throw `OCR ${payload.image}失败,image字段可能格式不正确`;
} }
if (path) { if (path) {
await checkFileReceived(path, 5000); // 文件不存在QQ会崩溃需要提前判断 await checkFileReceived(path, 5000); // 文件不存在QQ会崩溃需要提前判断
const ret = await NTQQSystemApi.ORCImage(path); const ret = await this.core.apis.SystemApi.ocrImage(path);
if (!isLocal) { if (!isLocal) {
fs.unlink(path, () => { fs.unlink(path, () => {
}); });

View File

@@ -19,8 +19,6 @@ export class SetInputStatus extends BaseAction<Payload, any> {
actionName = ActionName.SetInputStatus; actionName = ActionName.SetInputStatus;
async _handle(payload: Payload) { async _handle(payload: Payload) {
const NTQQUserApi = this.core.apis.UserApi;
const NTQQMsgApi = this.core.apis.MsgApi;
let peer: Peer; let peer: Peer;
if (payload.group_id) { if (payload.group_id) {
peer = { peer = {
@@ -28,7 +26,7 @@ export class SetInputStatus extends BaseAction<Payload, any> {
peerUid: payload.group_id, peerUid: payload.group_id,
}; };
} else if (payload.user_id) { } else if (payload.user_id) {
const uid = await NTQQUserApi.getUidByUinV2(payload.user_id); const uid = await this.core.apis.UserApi.getUidByUinV2(payload.user_id);
if (!uid) throw new Error('uid is empty'); if (!uid) throw new Error('uid is empty');
peer = { peer = {
chatType: ChatType.KCHATTYPEC2C, chatType: ChatType.KCHATTYPEC2C,
@@ -38,6 +36,6 @@ export class SetInputStatus extends BaseAction<Payload, any> {
throw new Error('请指定 group_id 或 user_id'); throw new Error('请指定 group_id 或 user_id');
} }
return await NTQQMsgApi.sendShowInputStatusReq(peer, parseInt(payload.eventType)); return await this.core.apis.MsgApi.sendShowInputStatusReq(peer, parseInt(payload.eventType));
} }
} }

View File

@@ -17,8 +17,6 @@ export class SetLongNick extends BaseAction<Payload, any> {
payloadSchema = SchemaData; payloadSchema = SchemaData;
async _handle(payload: Payload) { async _handle(payload: Payload) {
const NTQQUserApi = this.core.apis.UserApi; return await this.core.apis.UserApi.setLongNick(payload.longNick);
const ret = await NTQQUserApi.setLongNick(payload.longNick);
return ret;
} }
} }

View File

@@ -20,8 +20,7 @@ export class SetOnlineStatus extends BaseAction<Payload, null> {
payloadSchema = SchemaData; payloadSchema = SchemaData;
async _handle(payload: Payload) { async _handle(payload: Payload) {
const NTQQUserApi = this.core.apis.UserApi; const ret = await this.core.apis.UserApi.setSelfOnlineStatus(
const ret = await NTQQUserApi.setSelfOnlineStatus(
parseInt(payload.status.toString()), parseInt(payload.status.toString()),
parseInt(payload.ext_status.toString()), parseInt(payload.ext_status.toString()),
parseInt(payload.battery_status.toString()), parseInt(payload.battery_status.toString()),

View File

@@ -24,14 +24,13 @@ export default class SetAvatar extends BaseAction<Payload, null> {
} }
async _handle(payload: Payload): Promise<null> { async _handle(payload: Payload): Promise<null> {
const NTQQUserApi = this.core.apis.UserApi; const { path, isLocal, success } = (await uri2local(this.core.NapCatTempPath, payload.file));
const { path, isLocal, errMsg, success } = (await uri2local(this.core.NapCatTempPath, payload.file));
if (!success) { if (!success) {
throw `头像${payload.file}设置失败,file字段可能格式不正确`; throw `头像${payload.file}设置失败,file字段可能格式不正确`;
} }
if (path) { if (path) {
await checkFileReceived(path, 5000); // 文件不存在QQ会崩溃需要提前判断 await checkFileReceived(path, 5000); // 文件不存在QQ会崩溃需要提前判断
const ret = await NTQQUserApi.setQQAvatar(path); const ret = await this.core.apis.UserApi.setQQAvatar(path);
if (!isLocal) { if (!isLocal) {
fs.unlink(path, () => { fs.unlink(path, () => {
}); });

View File

@@ -19,12 +19,10 @@ export class SharePeer extends BaseAction<Payload, any> {
payloadSchema = SchemaData; payloadSchema = SchemaData;
async _handle(payload: Payload) { async _handle(payload: Payload) {
const NTQQUserApi = this.core.apis.UserApi;
const NTQQGroupApi = this.core.apis.GroupApi;
if (payload.group_id) { if (payload.group_id) {
return await NTQQGroupApi.getGroupRecommendContactArkJson(payload.group_id); return await this.core.apis.GroupApi.getGroupRecommendContactArkJson(payload.group_id);
} else if (payload.user_id) { } else if (payload.user_id) {
return await NTQQUserApi.getBuddyRecommendContactArkJson(payload.user_id, payload.phoneNumber || ''); return await this.core.apis.UserApi.getBuddyRecommendContactArkJson(payload.user_id, payload.phoneNumber || '');
} }
} }
} }
@@ -44,7 +42,6 @@ export class ShareGroupEx extends BaseAction<PayloadGroupEx, any> {
payloadSchema = SchemaDataGroupEx; payloadSchema = SchemaDataGroupEx;
async _handle(payload: PayloadGroupEx) { async _handle(payload: PayloadGroupEx) {
const NTQQGroupApi = this.core.apis.GroupApi; return await this.core.apis.GroupApi.getArkJsonGroupShare(payload.group_id);
return await NTQQGroupApi.getArkJsonGroupShare(payload.group_id);
} }
} }

View File

@@ -20,8 +20,7 @@ export class TranslateEnWordToZn extends BaseAction<Payload, Array<any> | null>
payloadSchema = SchemaData; payloadSchema = SchemaData;
async _handle(payload: Payload) { async _handle(payload: Payload) {
const NTQQSystemApi = this.core.apis.SystemApi; const ret = await this.core.apis.SystemApi.translateEnWordToZn(payload.words);
const ret = await NTQQSystemApi.translateEnWordToZn(payload.words);
if (ret.result !== 0) { if (ret.result !== 0) {
throw new Error('翻译失败'); throw new Error('翻译失败');
} }

View File

@@ -18,7 +18,6 @@ export class DelGroupFile extends BaseAction<Payload, any> {
payloadSchema = SchemaData; payloadSchema = SchemaData;
async _handle(payload: Payload) { async _handle(payload: Payload) {
const NTQQGroupApi = this.core.apis.GroupApi; return await this.core.apis.GroupApi.DelGroupFile(payload.group_id.toString(), [payload.file_id]);
return await NTQQGroupApi.DelGroupFile(payload.group_id.toString(), [payload.file_id]);
} }
} }

View File

@@ -18,7 +18,7 @@ export class DelGroupFileFolder extends BaseAction<Payload, any> {
payloadSchema = SchemaData; payloadSchema = SchemaData;
async _handle(payload: Payload) { async _handle(payload: Payload) {
const NTQQGroupApi = this.core.apis.GroupApi; return (await this.core.apis.GroupApi.DelGroupFileFolder(
return (await NTQQGroupApi.DelGroupFileFolder(payload.group_id.toString(), payload.folder_id)).groupFileCommonResult; payload.group_id.toString(), payload.folder_id)).groupFileCommonResult;
} }
} }

View File

@@ -28,15 +28,12 @@ export class GetFileBase extends BaseAction<GetFilePayload, GetFileResponse> {
payloadSchema: any = GetFileBase_PayloadSchema; payloadSchema: any = GetFileBase_PayloadSchema;
async _handle(payload: GetFilePayload): Promise<GetFileResponse> { async _handle(payload: GetFilePayload): Promise<GetFileResponse> {
const NTQQMsgApi = this.core.apis.MsgApi;
const NTQQFileApi = this.core.apis.FileApi;
//接收消息标记模式 //接收消息标记模式
const contextMsgFile = FileNapCatOneBotUUID.decode(payload.file); const contextMsgFile = FileNapCatOneBotUUID.decode(payload.file);
if (contextMsgFile) { if (contextMsgFile) {
const { peer, msgId, elementId } = contextMsgFile; const { peer, msgId, elementId } = contextMsgFile;
const downloadPath = await NTQQFileApi.downloadMedia(msgId, peer.chatType, peer.peerUid, elementId, '', ''); const downloadPath = await this.core.apis.FileApi.downloadMedia(msgId, peer.chatType, peer.peerUid, elementId, '', '');
const mixElement = (await NTQQMsgApi.getMsgsByMsgId(peer, [msgId]))?.msgList const mixElement = (await this.core.apis.MsgApi.getMsgsByMsgId(peer, [msgId]))?.msgList
.find(msg => msg.msgId === msgId)?.elements.find(e => e.elementId === elementId); .find(msg => msg.msgId === msgId)?.elements.find(e => e.elementId === elementId);
const mixElementInner = mixElement?.videoElement ?? mixElement?.fileElement ?? mixElement?.pttElement ?? mixElement?.picElement; const mixElementInner = mixElement?.videoElement ?? mixElement?.fileElement ?? mixElement?.pttElement ?? mixElement?.picElement;
if (!mixElementInner) throw new Error('element not found'); if (!mixElementInner) throw new Error('element not found');
@@ -64,7 +61,7 @@ export class GetFileBase extends BaseAction<GetFilePayload, GetFileResponse> {
const contextModelIdFile = FileNapCatOneBotUUID.decodeModelId(payload.file); const contextModelIdFile = FileNapCatOneBotUUID.decodeModelId(payload.file);
if (contextModelIdFile) { if (contextModelIdFile) {
const { peer, modelId } = contextModelIdFile; const { peer, modelId } = contextModelIdFile;
const downloadPath = await NTQQFileApi.downloadFileForModelId(peer, modelId, ''); const downloadPath = await this.core.apis.FileApi.downloadFileForModelId(peer, modelId, '');
const res: GetFileResponse = { const res: GetFileResponse = {
file: downloadPath, file: downloadPath,
url: downloadPath, url: downloadPath,
@@ -83,9 +80,9 @@ export class GetFileBase extends BaseAction<GetFilePayload, GetFileResponse> {
} }
//搜索名字模式 //搜索名字模式
const searchResult = (await NTQQFileApi.searchForFile([payload.file])); const searchResult = (await this.core.apis.FileApi.searchForFile([payload.file]));
if (searchResult) { if (searchResult) {
const downloadPath = await NTQQFileApi.downloadFileById(searchResult.id, parseInt(searchResult.fileSize)); const downloadPath = await this.core.apis.FileApi.downloadFileById(searchResult.id, parseInt(searchResult.fileSize));
const res: GetFileResponse = { const res: GetFileResponse = {
file: downloadPath, file: downloadPath,
url: downloadPath, url: downloadPath,

View File

@@ -21,14 +21,13 @@ export class GetGroupFileList extends BaseAction<Payload, { FileList: Array<any>
payloadSchema = SchemaData; payloadSchema = SchemaData;
async _handle(payload: Payload) { async _handle(payload: Payload) {
const NTQQMsgApi = this.core.apis.MsgApi;
let param = {}; let param = {};
if (payload.folder_id) { if (payload.folder_id) {
param = { param = {
folderId: payload.folder_id.toString(), folderId: payload.folder_id.toString(),
}; };
} }
const ret = await NTQQMsgApi.getGroupFileList(payload.group_id.toString(), { const ret = await this.core.apis.MsgApi.getGroupFileList(payload.group_id.toString(), {
sortType: 1, sortType: 1,
fileCount: +payload.file_count, fileCount: +payload.file_count,
startIndex: +payload.start_index, startIndex: +payload.start_index,

View File

@@ -18,7 +18,6 @@ export class SetGroupFileFolder extends BaseAction<Payload, any> {
payloadSchema = SchemaData; payloadSchema = SchemaData;
async _handle(payload: Payload) { async _handle(payload: Payload) {
const NTQQGroupApi = this.core.apis.GroupApi; return (await this.core.apis.GroupApi.CreatGroupFileFolder(payload.group_id.toString(), payload.folder_name)).resultWithGroupItem;
return (await NTQQGroupApi.CreatGroupFileFolder(payload.group_id.toString(), payload.folder_name)).resultWithGroupItem;
} }
} }

View File

@@ -19,7 +19,6 @@ export class GoCQHTTPGetForwardMsgAction extends BaseAction<Payload, any> {
payloadSchema = SchemaData; payloadSchema = SchemaData;
async _handle(payload: Payload): Promise<any> { async _handle(payload: Payload): Promise<any> {
const NTQQMsgApi = this.core.apis.MsgApi;
const msgId = payload.message_id || payload.id; const msgId = payload.message_id || payload.id;
if (!msgId) { if (!msgId) {
throw Error('message_id is required'); throw Error('message_id is required');
@@ -29,7 +28,7 @@ export class GoCQHTTPGetForwardMsgAction extends BaseAction<Payload, any> {
if (!rootMsg) { if (!rootMsg) {
throw Error('msg not found'); throw Error('msg not found');
} }
const data = await NTQQMsgApi.getMultiMsg(rootMsg.Peer, rootMsg.MsgId, rootMsg.MsgId); const data = await this.core.apis.MsgApi.getMultiMsg(rootMsg.Peer, rootMsg.MsgId, rootMsg.MsgId);
if (!data || data.result !== 0) { if (!data || data.result !== 0) {
throw Error('找不到相关的聊天记录' + data?.errMsg); throw Error('找不到相关的聊天记录' + data?.errMsg);
} }

View File

@@ -27,21 +27,17 @@ export default class GetFriendMsgHistory extends BaseAction<Payload, Response> {
payloadSchema = SchemaData; payloadSchema = SchemaData;
async _handle(payload: Payload): Promise<Response> { async _handle(payload: Payload): Promise<Response> {
const NTQQUserApi = this.core.apis.UserApi;
const NTQQMsgApi = this.core.apis.MsgApi;
const NTQQFriendApi = this.core.apis.FriendApi;
//处理参数 //处理参数
const uid = await NTQQUserApi.getUidByUinV2(payload.user_id.toString()); const uid = await this.core.apis.UserApi.getUidByUinV2(payload.user_id.toString());
const MsgCount = +(payload.count ?? 20); const MsgCount = +(payload.count ?? 20);
const isReverseOrder = typeof payload.reverseOrder === 'string' ? payload.reverseOrder === 'true' : !!payload.reverseOrder; const isReverseOrder = typeof payload.reverseOrder === 'string' ? payload.reverseOrder === 'true' : !!payload.reverseOrder;
if (!uid) throw `记录${payload.user_id}不存在`; if (!uid) throw `记录${payload.user_id}不存在`;
const friend = await NTQQFriendApi.isBuddy(uid); const friend = await this.core.apis.FriendApi.isBuddy(uid);
const peer = { chatType: friend ? ChatType.KCHATTYPEC2C : ChatType.KCHATTYPETEMPC2CFROMGROUP, peerUid: uid }; const peer = { chatType: friend ? ChatType.KCHATTYPEC2C : ChatType.KCHATTYPETEMPC2CFROMGROUP, peerUid: uid };
const hasMessageSeq = !payload.message_seq ? !!payload.message_seq : !(payload.message_seq?.toString() === '' || payload.message_seq?.toString() === '0'); const hasMessageSeq = !payload.message_seq ? !!payload.message_seq : !(payload.message_seq?.toString() === '' || payload.message_seq?.toString() === '0');
//拉取消息
const startMsgId = hasMessageSeq ? (MessageUnique.getMsgIdAndPeerByShortId(+payload.message_seq!)?.MsgId ?? payload.message_seq!.toString()) : '0'; const startMsgId = hasMessageSeq ? (MessageUnique.getMsgIdAndPeerByShortId(+payload.message_seq!)?.MsgId ?? payload.message_seq!.toString()) : '0';
const msgList = hasMessageSeq ? const msgList = hasMessageSeq ?
(await NTQQMsgApi.getMsgHistory(peer, startMsgId, MsgCount)).msgList : (await NTQQMsgApi.getAioFirstViewLatestMsgs(peer, MsgCount)).msgList; (await this.core.apis.MsgApi.getMsgHistory(peer, startMsgId, MsgCount)).msgList : (await this.core.apis.MsgApi.getAioFirstViewLatestMsgs(peer, MsgCount)).msgList;
if (msgList.length === 0) throw `消息${payload.message_seq}不存在`; if (msgList.length === 0) throw `消息${payload.message_seq}不存在`;
//翻转消息 //翻转消息
if (isReverseOrder) msgList.reverse(); if (isReverseOrder) msgList.reverse();

View File

@@ -22,7 +22,6 @@ export class GetGroupHonorInfo extends BaseAction<Payload, Array<any>> {
if (!payload.type) { if (!payload.type) {
payload.type = WebHonorType.ALL; payload.type = WebHonorType.ALL;
} }
const NTQQWebApi = this.core.apis.WebApi; return await this.core.apis.WebApi.getGroupHonorInfo(payload.group_id.toString(), payload.type);
return await NTQQWebApi.getGroupHonorInfo(payload.group_id.toString(), payload.type);
} }
} }

View File

@@ -27,7 +27,6 @@ export default class GoCQHTTPGetGroupMsgHistory extends BaseAction<Payload, Resp
payloadSchema = SchemaData; payloadSchema = SchemaData;
async _handle(payload: Payload): Promise<Response> { async _handle(payload: Payload): Promise<Response> {
const NTQQMsgApi = this.core.apis.MsgApi;
//处理参数 //处理参数
const isReverseOrder = typeof payload.reverseOrder === 'string' ? payload.reverseOrder === 'true' : !!payload.reverseOrder; const isReverseOrder = typeof payload.reverseOrder === 'string' ? payload.reverseOrder === 'true' : !!payload.reverseOrder;
const MsgCount = +(payload.count ?? 20); const MsgCount = +(payload.count ?? 20);
@@ -36,7 +35,7 @@ export default class GoCQHTTPGetGroupMsgHistory extends BaseAction<Payload, Resp
//拉取消息 //拉取消息
const startMsgId = hasMessageSeq ? (MessageUnique.getMsgIdAndPeerByShortId(+payload.message_seq!)?.MsgId ?? payload.message_seq!.toString()) : '0'; const startMsgId = hasMessageSeq ? (MessageUnique.getMsgIdAndPeerByShortId(+payload.message_seq!)?.MsgId ?? payload.message_seq!.toString()) : '0';
const msgList = hasMessageSeq ? const msgList = hasMessageSeq ?
(await NTQQMsgApi.getMsgHistory(peer, startMsgId, MsgCount)).msgList : (await NTQQMsgApi.getAioFirstViewLatestMsgs(peer, MsgCount)).msgList; (await this.core.apis.MsgApi.getMsgHistory(peer, startMsgId, MsgCount)).msgList : (await this.core.apis.MsgApi.getAioFirstViewLatestMsgs(peer, MsgCount)).msgList;
if (msgList.length === 0) throw `消息${payload.message_seq}不存在`; if (msgList.length === 0) throw `消息${payload.message_seq}不存在`;
//翻转消息 //翻转消息
if (isReverseOrder) msgList.reverse(); if (isReverseOrder) msgList.reverse();

View File

@@ -15,8 +15,7 @@ export class GetOnlineClient extends BaseAction<void, Array<any>> {
async _handle(payload: void) { async _handle(payload: void) {
//注册监听 //注册监听
const NTQQSystemApi = this.core.apis.SystemApi; this.core.apis.SystemApi.getOnlineDev();
NTQQSystemApi.getOnlineDev();
await sleep(500); await sleep(500);
return []; return [];

View File

@@ -19,10 +19,9 @@ export default class GoCQHTTPGetStrangerInfo extends BaseAction<Payload, OB11Use
actionName = ActionName.GoCQHTTP_GetStrangerInfo; actionName = ActionName.GoCQHTTP_GetStrangerInfo;
async _handle(payload: Payload): Promise<OB11User> { async _handle(payload: Payload): Promise<OB11User> {
const NTQQUserApi = this.core.apis.UserApi;
const user_id = payload.user_id.toString(); const user_id = payload.user_id.toString();
const extendData = await NTQQUserApi.getUserDetailInfoByUinV2(user_id); const extendData = await this.core.apis.UserApi.getUserDetailInfoByUinV2(user_id);
const uid = (await NTQQUserApi.getUidByUinV2(user_id))!; const uid = (await this.core.apis.UserApi.getUidByUinV2(user_id))!;
if (!uid || uid.indexOf('*') != -1) { if (!uid || uid.indexOf('*') != -1) {
return { return {
...extendData.detail.simpleInfo.coreInfo, ...extendData.detail.simpleInfo.coreInfo,
@@ -38,7 +37,7 @@ export default class GoCQHTTPGetStrangerInfo extends BaseAction<Payload, OB11Use
login_days: 0, login_days: 0,
}; };
} }
const data = { ...extendData, ...(await NTQQUserApi.getUserDetailInfo(uid)) }; const data = { ...extendData, ...(await this.core.apis.UserApi.getUserDetailInfo(uid)) };
return OB11Entities.stranger(data); return OB11Entities.stranger(data);
} }
} }

View File

@@ -22,7 +22,6 @@ export class SendGroupNotice extends BaseAction<Payload, null> {
actionName = ActionName.GoCQHTTP_SendGroupNotice; actionName = ActionName.GoCQHTTP_SendGroupNotice;
async _handle(payload: Payload) { async _handle(payload: Payload) {
const NTQQGroupApi = this.core.apis.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) {
//公告图逻辑 //公告图逻辑
@@ -38,7 +37,7 @@ export class SendGroupNotice extends BaseAction<Payload, null> {
throw `群公告${payload.image}设置失败,获取资源失败`; throw `群公告${payload.image}设置失败,获取资源失败`;
} }
await checkFileReceived(path, 5000); // 文件不存在QQ会崩溃需要提前判断 await checkFileReceived(path, 5000); // 文件不存在QQ会崩溃需要提前判断
const ImageUploadResult = await NTQQGroupApi.uploadGroupBulletinPic(payload.group_id.toString(), path); const ImageUploadResult = await this.core.apis.GroupApi.uploadGroupBulletinPic(payload.group_id.toString(), path);
if (ImageUploadResult.errCode != 0) { if (ImageUploadResult.errCode != 0) {
throw `群公告${payload.image}设置失败,图片上传失败`; throw `群公告${payload.image}设置失败,图片上传失败`;
} }
@@ -50,7 +49,7 @@ export class SendGroupNotice extends BaseAction<Payload, null> {
} }
const noticePinned = +(payload.pinned ?? 0); const noticePinned = +(payload.pinned ?? 0);
const noticeConfirmRequired = +(payload.confirm_required ?? 0); const noticeConfirmRequired = +(payload.confirm_required ?? 0);
const publishGroupBulletinResult = await NTQQGroupApi.publishGroupBulletin(payload.group_id.toString(), payload.content, UploadImage, noticePinned, noticeConfirmRequired); const publishGroupBulletinResult = await this.core.apis.GroupApi.publishGroupBulletin(payload.group_id.toString(), payload.content, UploadImage, noticePinned, noticeConfirmRequired);
if (publishGroupBulletinResult.result != 0) { if (publishGroupBulletinResult.result != 0) {
throw `设置群公告失败,错误信息:${publishGroupBulletinResult.errMsg}`; throw `设置群公告失败,错误信息:${publishGroupBulletinResult.errMsg}`;

View File

@@ -25,14 +25,13 @@ export default class SetGroupPortrait extends BaseAction<Payload, any> {
} }
async _handle(payload: Payload): Promise<any> { async _handle(payload: Payload): Promise<any> {
const NTQQGroupApi = this.core.apis.GroupApi; const { path, isLocal, success } = (await uri2local(this.core.NapCatTempPath, payload.file));
const { path, isLocal, errMsg, success } = (await uri2local(this.core.NapCatTempPath, payload.file));
if (!success) { if (!success) {
throw `头像${payload.file}设置失败,file字段可能格式不正确`; throw `头像${payload.file}设置失败,file字段可能格式不正确`;
} }
if (path) { if (path) {
await checkFileReceived(path, 5000); // 文件不存在QQ会崩溃需要提前判断 await checkFileReceived(path, 5000); // 文件不存在QQ会崩溃需要提前判断
const ret = await NTQQGroupApi.setGroupAvatar(payload.group_id.toString(), path) as any; const ret = await this.core.apis.GroupApi.setGroupAvatar(payload.group_id.toString(), path) as any;
if (!isLocal) { if (!isLocal) {
fs.unlink(path, () => { fs.unlink(path, () => {
}); });

View File

@@ -19,10 +19,9 @@ export class SetQQProfile extends BaseAction<Payload, any | null> {
payloadSchema = SchemaData; payloadSchema = SchemaData;
async _handle(payload: Payload) { async _handle(payload: Payload) {
const NTQQUserApi = this.core.apis.UserApi;
const self = this.core.selfInfo; const self = this.core.selfInfo;
const OldProfile = await NTQQUserApi.getUserDetailInfo(self.uid); const OldProfile = await this.core.apis.UserApi.getUserDetailInfo(self.uid);
return await NTQQUserApi.modifySelfProfile({ return await this.core.apis.UserApi.modifySelfProfile({
nick: payload.nickname, nick: payload.nickname,
longNick: (payload?.personal_note ?? OldProfile?.longNick) || '', longNick: (payload?.personal_note ?? OldProfile?.longNick) || '',
sex: parseInt(payload?.sex ? payload?.sex.toString() : OldProfile?.sex!.toString()), sex: parseInt(payload?.sex ? payload?.sex.toString() : OldProfile?.sex!.toString()),

View File

@@ -22,14 +22,12 @@ export default class GoCQHTTPUploadPrivateFile extends BaseAction<Payload, null>
payloadSchema = SchemaData; payloadSchema = SchemaData;
async getPeer(payload: Payload): Promise<Peer> { async getPeer(payload: Payload): Promise<Peer> {
const NTQQUserApi = this.core.apis.UserApi;
const NTQQFriendApi = this.core.apis.FriendApi;
if (payload.user_id) { if (payload.user_id) {
const peerUid = await NTQQUserApi.getUidByUinV2(payload.user_id.toString()); const peerUid = await this.core.apis.UserApi.getUidByUinV2(payload.user_id.toString());
if (!peerUid) { if (!peerUid) {
throw `私聊${payload.user_id}不存在`; throw `私聊${payload.user_id}不存在`;
} }
const isBuddy = await NTQQFriendApi.isBuddy(peerUid); const isBuddy = await this.core.apis.FriendApi.isBuddy(peerUid);
return { chatType: isBuddy ? ChatType.KCHATTYPEC2C : ChatType.KCHATTYPETEMPC2CFROMGROUP, peerUid }; return { chatType: isBuddy ? ChatType.KCHATTYPEC2C : ChatType.KCHATTYPETEMPC2CFROMGROUP, peerUid };
} }
throw new Error('缺少参数 user_id'); throw new Error('缺少参数 user_id');

View File

@@ -18,16 +18,14 @@ export default class DelEssenceMsg extends BaseAction<Payload, any> {
payloadSchema = SchemaData; payloadSchema = SchemaData;
async _handle(payload: Payload): Promise<any> { async _handle(payload: Payload): Promise<any> {
const NTQQGroupApi = this.core.apis.GroupApi;
const msg = MessageUnique.getMsgIdAndPeerByShortId(+payload.message_id); const msg = MessageUnique.getMsgIdAndPeerByShortId(+payload.message_id);
const NTQQWebApi = this.core.apis.WebApi;
if (!msg) { if (!msg) {
const data = NTQQGroupApi.essenceLRU.getValue(+payload.message_id); const data = this.core.apis.GroupApi.essenceLRU.getValue(+payload.message_id);
if(!data) throw new Error('消息不存在'); if(!data) throw new Error('消息不存在');
const { msg_seq, msg_random, group_id } = JSON.parse(data) as { msg_seq: string, msg_random: string, group_id: string }; const { msg_seq, msg_random, group_id } = JSON.parse(data) as { msg_seq: string, msg_random: string, group_id: string };
return await NTQQGroupApi.removeGroupEssenceBySeq(group_id, msg_seq, msg_random); return await this.core.apis.GroupApi.removeGroupEssenceBySeq(group_id, msg_seq, msg_random);
} }
return await NTQQGroupApi.removeGroupEssence( return await this.core.apis.GroupApi.removeGroupEssence(
msg.Peer.peerUid, msg.Peer.peerUid,
msg.MsgId, msg.MsgId,
); );

View File

@@ -19,9 +19,8 @@ export class DelGroupNotice extends BaseAction<Payload, any> {
payloadSchema = SchemaData; payloadSchema = SchemaData;
async _handle(payload: Payload) { async _handle(payload: Payload) {
const NTQQGroupApi = this.core.apis.GroupApi;
const group = payload.group_id.toString(); const group = payload.group_id.toString();
const noticeId = payload.notice_id; const noticeId = payload.notice_id;
return await NTQQGroupApi.deleteGroupBulletin(group, noticeId); return await this.core.apis.GroupApi.deleteGroupBulletin(group, noticeId);
} }
} }

View File

@@ -31,9 +31,7 @@ export class GetGroupEssence extends BaseAction<Payload, any> {
} }
async _handle(payload: Payload) { async _handle(payload: Payload) {
const NTQQWebApi = this.core.apis.WebApi; const msglist = (await this.core.apis.WebApi.getGroupEssenceMsgAll(payload.group_id.toString())).flatMap((e) => e.data.msg_list);
const NTQQGroupApi = this.core.apis.GroupApi;
const msglist = (await NTQQWebApi.getGroupEssenceMsgAll(payload.group_id.toString())).flatMap((e) => e.data.msg_list);
if (!msglist) { if (!msglist) {
throw new Error('获取失败'); throw new Error('获取失败');
} }
@@ -65,7 +63,7 @@ export class GetGroupEssence extends BaseAction<Payload, any> {
//设置第一个bit为0 保证shortId为正数 //设置第一个bit为0 保证shortId为正数
hash[0] &= 0x7f; hash[0] &= 0x7f;
const shortId = hash.readInt32BE(0); const shortId = hash.readInt32BE(0);
NTQQGroupApi.essenceLRU.set(shortId, msgTempData); this.core.apis.GroupApi.essenceLRU.set(shortId, msgTempData);
return { return {
msg_seq: msg.msg_seq, msg_seq: msg.msg_seq,
msg_random: msg.msg_random, msg_random: msg.msg_random,

View File

@@ -16,21 +16,19 @@ export class GetGroupIgnoredNotifies extends BaseAction<void, any> {
actionName = ActionName.GetGroupIgnoredNotifies; actionName = ActionName.GetGroupIgnoredNotifies;
async _handle(payload: void) { async _handle(payload: void) {
const NTQQUserApi = this.core.apis.UserApi; const ignoredNotifies = await this.core.apis.GroupApi.getSingleScreenNotifies(true, 10);
const NTQQGroupApi = this.core.apis.GroupApi;
const ignoredNotifies = await NTQQGroupApi.getSingleScreenNotifies(true, 10);
const retData: any = { const retData: any = {
join_requests: await Promise.all( join_requests: await Promise.all(
ignoredNotifies ignoredNotifies
.filter(notify => notify.type === 7) .filter(notify => notify.type === 7)
.map(async SSNotify => ({ .map(async SSNotify => ({
request_id: SSNotify.seq, request_id: SSNotify.seq,
requester_uin: await NTQQUserApi.getUinByUidV2(SSNotify.user1?.uid), requester_uin: await this.core.apis.UserApi.getUinByUidV2(SSNotify.user1?.uid),
requester_nick: SSNotify.user1?.nickName, requester_nick: SSNotify.user1?.nickName,
group_id: SSNotify.group?.groupCode, group_id: SSNotify.group?.groupCode,
group_name: SSNotify.group?.groupName, group_name: SSNotify.group?.groupName,
checked: SSNotify.status !== GroupNotifyMsgStatus.KUNHANDLE, checked: SSNotify.status !== GroupNotifyMsgStatus.KUNHANDLE,
actor: await NTQQUserApi.getUinByUidV2(SSNotify.user2?.uid) || 0, actor: await this.core.apis.UserApi.getUinByUidV2(SSNotify.user2?.uid) || 0,
}))), }))),
}; };

View File

@@ -19,8 +19,7 @@ class GetGroupInfo extends BaseAction<Payload, OB11Group> {
payloadSchema = SchemaData; payloadSchema = SchemaData;
async _handle(payload: Payload) { async _handle(payload: Payload) {
const NTQQGroupApi = this.core.apis.GroupApi; const group = (await this.core.apis.GroupApi.getGroups()).find(e => e.groupCode == payload.group_id.toString());
const group = (await NTQQGroupApi.getGroups()).find(e => e.groupCode == payload.group_id.toString());
if (!group) throw `${payload.group_id}不存在`; if (!group) throw `${payload.group_id}不存在`;
return OB11Entities.group(group); return OB11Entities.group(group);
} }

View File

@@ -2,7 +2,6 @@ import { OB11Group } from '@/onebot';
import { OB11Entities } from '@/onebot/entities'; import { OB11Entities } from '@/onebot/entities';
import BaseAction from '../BaseAction'; import BaseAction from '../BaseAction';
import { ActionName } from '../types'; import { ActionName } from '../types';
import { Group } from '@/core/entities';
import { FromSchema, JSONSchema } from 'json-schema-to-ts'; import { FromSchema, JSONSchema } from 'json-schema-to-ts';
// no_cache get时传字符串 // no_cache get时传字符串
const SchemaData = { const SchemaData = {
@@ -19,9 +18,9 @@ class GetGroupList extends BaseAction<Payload, OB11Group[]> {
payloadSchema = SchemaData; payloadSchema = SchemaData;
async _handle(payload: Payload) { async _handle(payload: Payload) {
const NTQQGroupApi = this.core.apis.GroupApi; return OB11Entities.groups(
const groupList: Group[] = await NTQQGroupApi.getGroups(typeof payload.no_cache === 'string' ? payload.no_cache === 'true' : !!payload.no_cache); await this.core.apis.GroupApi.getGroups(
return OB11Entities.groups(groupList); typeof payload.no_cache === 'string' ? payload.no_cache === 'true' : !!payload.no_cache));
} }
} }

View File

@@ -22,27 +22,25 @@ class GetGroupMemberInfo extends BaseAction<Payload, OB11GroupMember> {
payloadSchema = SchemaData; payloadSchema = SchemaData;
async _handle(payload: Payload) { async _handle(payload: Payload) {
const NTQQUserApi = this.core.apis.UserApi;
const NTQQGroupApi = this.core.apis.GroupApi;
const isNocache = typeof payload.no_cache === 'string' ? payload.no_cache === 'true' : !!payload.no_cache; const isNocache = typeof payload.no_cache === 'string' ? payload.no_cache === 'true' : !!payload.no_cache;
const uid = await NTQQUserApi.getUidByUinV2(payload.user_id.toString()); const uid = await this.core.apis.UserApi.getUidByUinV2(payload.user_id.toString());
if (!uid) throw new Error(`Uin2Uid Error ${payload.user_id}不存在`); if (!uid) throw new Error(`Uin2Uid Error ${payload.user_id}不存在`);
const [member, info] = await Promise.allSettled([ const [member, info] = await Promise.allSettled([
NTQQGroupApi.getGroupMemberV2(payload.group_id.toString(), uid, isNocache), this.core.apis.GroupApi.getGroupMemberV2(payload.group_id.toString(), uid, isNocache),
NTQQUserApi.getUserDetailInfo(uid), this.core.apis.UserApi.getUserDetailInfo(uid),
]); ]);
if (member.status !== 'fulfilled') throw new Error(`群(${payload.group_id})成员${payload.user_id}不存在 ${member.reason}`); if (member.status !== 'fulfilled') throw new Error(`群(${payload.group_id})成员${payload.user_id}获取失败 ${member.reason}`);
if (!member.value) throw new Error(`群(${payload.group_id})成员${payload.user_id}不存在`);
if (info.status === 'fulfilled') { if (info.status === 'fulfilled') {
this.core.context.logger.logDebug('群成员详细信息结果', info.value); Object.assign(member.value, info.value);
Object.assign(member, info.value);
} else { } else {
this.core.context.logger.logDebug(`获取群成员详细信息失败, 只能返回基础信息 ${info.reason}`); this.core.context.logger.logDebug(`获取群成员详细信息失败, 只能返回基础信息 ${info.reason}`);
} }
const date = Math.round(Date.now() / 1000); const date = Math.round(Date.now() / 1000);
const retMember = OB11Entities.groupMember(payload.group_id.toString(), member.value as GroupMember); const retMember = OB11Entities.groupMember(payload.group_id.toString(), member.value as GroupMember);
const Member = await this.core.apis.GroupApi.getGroupMember(payload.group_id.toString(), retMember.user_id); const Member = await this.core.apis.GroupApi.getGroupMember(payload.group_id.toString(), retMember.user_id);
retMember.last_sent_time = parseInt(Member?.lastSpeakTime || date.toString()); retMember.last_sent_time = parseInt(Member?.lastSpeakTime ?? date.toString());
retMember.join_time = parseInt(Member?.joinTime || date.toString()); retMember.join_time = parseInt(Member?.joinTime ?? date.toString());
return retMember; return retMember;
} }
} }

View File

@@ -20,9 +20,7 @@ class GetGroupMemberList extends BaseAction<Payload, OB11GroupMember[]> {
payloadSchema = SchemaData; payloadSchema = SchemaData;
async _handle(payload: Payload) { async _handle(payload: Payload) {
const NTQQGroupApi = this.core.apis.GroupApi; const groupMembers = await this.core.apis.GroupApi.getGroupMembersV2(payload.group_id.toString());
const NTQQWebApi = this.core.apis.WebApi;
const groupMembers = await NTQQGroupApi.getGroupMembersV2(payload.group_id.toString());
const groupMembersArr = Array.from(groupMembers.values()); const groupMembersArr = Array.from(groupMembers.values());
let _groupMembers = groupMembersArr.map(item => { let _groupMembers = groupMembersArr.map(item => {
@@ -48,7 +46,7 @@ class GetGroupMemberList extends BaseAction<Payload, OB11GroupMember[]> {
}); });
if (isPrivilege) { if (isPrivilege) {
const webGroupMembers = await NTQQWebApi.getGroupMembers(payload.group_id.toString()); const webGroupMembers = await this.core.apis.WebApi.getGroupMembers(payload.group_id.toString());
for (let i = 0, len = webGroupMembers.length; i < len; i++) { for (let i = 0, len = webGroupMembers.length; i < len; i++) {
if (!webGroupMembers[i]?.uin) { if (!webGroupMembers[i]?.uin) {
continue; continue;

View File

@@ -34,10 +34,8 @@ export class GetGroupNotice extends BaseAction<Payload, GroupNotice[]> {
payloadSchema = SchemaData; payloadSchema = SchemaData;
async _handle(payload: Payload) { async _handle(payload: Payload) {
const NTQQWebApi = this.core.apis.WebApi;
const group = payload.group_id.toString(); const group = payload.group_id.toString();
const ret = await NTQQWebApi.getGroupNotice(group); const ret = await this.core.apis.WebApi.getGroupNotice(group);
if (!ret) { if (!ret) {
throw new Error('获取公告失败'); throw new Error('获取公告失败');
} }

View File

@@ -18,12 +18,11 @@ export default class SetEssenceMsg extends BaseAction<Payload, any> {
payloadSchema = SchemaData; payloadSchema = SchemaData;
async _handle(payload: Payload): Promise<any> { async _handle(payload: Payload): Promise<any> {
const NTQQGroupApi = this.core.apis.GroupApi;
const msg = MessageUnique.getMsgIdAndPeerByShortId(parseInt(payload.message_id.toString())); const msg = MessageUnique.getMsgIdAndPeerByShortId(parseInt(payload.message_id.toString()));
if (!msg) { if (!msg) {
throw new Error('msg not found'); throw new Error('msg not found');
} }
return await NTQQGroupApi.addGroupEssence( return await this.core.apis.GroupApi.addGroupEssence(
msg.Peer.peerUid, msg.Peer.peerUid,
msg.MsgId, msg.MsgId,
); );

View File

@@ -20,10 +20,9 @@ export default class SetGroupAddRequest extends BaseAction<Payload, null> {
payloadSchema = SchemaData; payloadSchema = SchemaData;
async _handle(payload: Payload): Promise<null> { async _handle(payload: Payload): Promise<null> {
const NTQQGroupApi = this.core.apis.GroupApi;
const flag = payload.flag.toString(); const flag = payload.flag.toString();
const approve = payload.approve?.toString() !== 'false'; const approve = payload.approve?.toString() !== 'false';
await NTQQGroupApi.handleGroupRequest(flag, await this.core.apis.GroupApi.handleGroupRequest(flag,
approve ? GroupRequestOperateTypes.approve : GroupRequestOperateTypes.reject, approve ? GroupRequestOperateTypes.approve : GroupRequestOperateTypes.reject,
payload.reason ?? ' ', payload.reason ?? ' ',
); );

View File

@@ -21,11 +21,9 @@ export default class SetGroupAdmin extends BaseAction<Payload, null> {
async _handle(payload: Payload): Promise<null> { async _handle(payload: Payload): Promise<null> {
const enable = typeof payload.enable === 'string' ? payload.enable === 'true' : !!payload.enable; const enable = typeof payload.enable === 'string' ? payload.enable === 'true' : !!payload.enable;
const NTQQGroupApi = this.core.apis.GroupApi; const uid = await this.core.apis.UserApi.getUidByUinV2(payload.user_id.toString());
const NTQQUserApi = this.core.apis.UserApi;
const uid = await NTQQUserApi.getUidByUinV2(payload.user_id.toString());
if (!uid) throw new Error('get Uid Error'); if (!uid) throw new Error('get Uid Error');
await NTQQGroupApi.setMemberRole(payload.group_id.toString(), uid, enable ? GroupMemberRole.admin : GroupMemberRole.normal); await this.core.apis.GroupApi.setMemberRole(payload.group_id.toString(), uid, enable ? GroupMemberRole.admin : GroupMemberRole.normal);
return null; return null;
} }
} }

View File

@@ -19,11 +19,9 @@ export default class SetGroupBan extends BaseAction<Payload, null> {
payloadSchema = SchemaData; payloadSchema = SchemaData;
async _handle(payload: Payload): Promise<null> { async _handle(payload: Payload): Promise<null> {
const NTQQGroupApi = this.core.apis.GroupApi; const uid = await this.core.apis.UserApi.getUidByUinV2(payload.user_id.toString());
const NTQQUserApi = this.core.apis.UserApi;
const uid = await NTQQUserApi.getUidByUinV2(payload.user_id.toString());
if (!uid) throw new Error('uid error'); if (!uid) throw new Error('uid error');
await NTQQGroupApi.banMember(payload.group_id.toString(), await this.core.apis.GroupApi.banMember(payload.group_id.toString(),
[{ uid: uid, timeStamp: parseInt(payload.duration.toString()) }]); [{ uid: uid, timeStamp: parseInt(payload.duration.toString()) }]);
return null; return null;
} }

View File

@@ -19,9 +19,8 @@ export default class SetGroupCard extends BaseAction<Payload, null> {
payloadSchema = SchemaData; payloadSchema = SchemaData;
async _handle(payload: Payload): Promise<null> { async _handle(payload: Payload): Promise<null> {
const NTQQGroupApi = this.core.apis.GroupApi; const member = await this.core.apis.GroupApi.getGroupMember(payload.group_id.toString(), payload.user_id.toString());
const member = await NTQQGroupApi.getGroupMember(payload.group_id.toString(), payload.user_id.toString()); if (member) await this.core.apis.GroupApi.setMemberCard(payload.group_id.toString(), member.uid, payload.card || '');
member && await NTQQGroupApi.setMemberCard(payload.group_id.toString(), member.uid, payload.card || '');
return null; return null;
} }
} }

View File

@@ -20,12 +20,10 @@ export default class SetGroupKick extends BaseAction<Payload, null> {
payloadSchema = SchemaData; payloadSchema = SchemaData;
async _handle(payload: Payload): Promise<null> { async _handle(payload: Payload): Promise<null> {
const NTQQGroupApi = this.core.apis.GroupApi;
const NTQQUserApi = this.core.apis.UserApi;
const rejectReq = payload.reject_add_request?.toString() == 'true'; const rejectReq = payload.reject_add_request?.toString() == 'true';
const uid = await NTQQUserApi.getUidByUinV2(payload.user_id.toString()); const uid = await this.core.apis.UserApi.getUidByUinV2(payload.user_id.toString());
if (!uid) throw new Error('get Uid Error'); if (!uid) throw new Error('get Uid Error');
await NTQQGroupApi.kickMember(payload.group_id.toString(), [uid], rejectReq); await this.core.apis.GroupApi.kickMember(payload.group_id.toString(), [uid], rejectReq);
return null; return null;
} }
} }

View File

@@ -17,7 +17,6 @@ export default class SetGroupLeave extends BaseAction<Payload, any> {
payloadSchema = SchemaData; payloadSchema = SchemaData;
async _handle(payload: Payload): Promise<any> { async _handle(payload: Payload): Promise<any> {
const NTQQGroupApi = this.core.apis.GroupApi; await this.core.apis.GroupApi.quitGroup(payload.group_id.toString());
await NTQQGroupApi.quitGroup(payload.group_id.toString());
} }
} }

View File

@@ -17,8 +17,7 @@ export default class SetGroupName extends BaseAction<Payload, null> {
payloadSchema = SchemaData; payloadSchema = SchemaData;
async _handle(payload: Payload): Promise<null> { async _handle(payload: Payload): Promise<null> {
const NTQQGroupApi = this.core.apis.GroupApi; await this.core.apis.GroupApi.setGroupName(payload.group_id.toString(), payload.group_name);
await NTQQGroupApi.setGroupName(payload.group_id.toString(), payload.group_name);
return null; return null;
} }
} }

View File

@@ -19,8 +19,7 @@ export default class SetGroupWholeBan extends BaseAction<Payload, null> {
async _handle(payload: Payload): Promise<null> { async _handle(payload: Payload): Promise<null> {
const enable = payload.enable?.toString() !== 'false'; const enable = payload.enable?.toString() !== 'false';
const NTQQGroupApi = this.core.apis.GroupApi; await this.core.apis.GroupApi.banGroup(payload.group_id.toString(), enable);
await NTQQGroupApi.banGroup(payload.group_id.toString(), enable);
return null; return null;
} }
} }

View File

@@ -23,7 +23,6 @@ class DeleteMsg extends BaseAction<Payload, void> {
payloadSchema = SchemaData; payloadSchema = SchemaData;
async _handle(payload: Payload) { async _handle(payload: Payload) {
const NTQQMsgApi = this.core.apis.MsgApi;
const msg = MessageUnique.getMsgIdAndPeerByShortId(Number(payload.message_id)); const msg = MessageUnique.getMsgIdAndPeerByShortId(Number(payload.message_id));
if (msg) { if (msg) {
const ret = this.core.eventWrapper.registerListen( const ret = this.core.eventWrapper.registerListen(
@@ -34,7 +33,7 @@ class DeleteMsg extends BaseAction<Payload, void> {
).catch(() => new Promise<undefined>((resolve) => { ).catch(() => new Promise<undefined>((resolve) => {
resolve(undefined); resolve(undefined);
})); }));
await NTQQMsgApi.recallMsg(msg.Peer, [msg.MsgId]); await this.core.apis.MsgApi.recallMsg(msg.Peer, [msg.MsgId]);
const data = await ret; const data = await ret;
if (!data) { if (!data) {
//throw new Error('Recall failed'); //throw new Error('Recall failed');

View File

@@ -18,9 +18,8 @@ type Payload = FromSchema<typeof SchemaData>;
class ForwardSingleMsg extends BaseAction<Payload, null> { class ForwardSingleMsg extends BaseAction<Payload, null> {
protected async getTargetPeer(payload: Payload): Promise<Peer> { protected async getTargetPeer(payload: Payload): Promise<Peer> {
const NTQQUserApi = this.core.apis.UserApi;
if (payload.user_id) { if (payload.user_id) {
const peerUid = await NTQQUserApi.getUidByUinV2(payload.user_id.toString()); const peerUid = await this.core.apis.UserApi.getUidByUinV2(payload.user_id.toString());
if (!peerUid) { if (!peerUid) {
throw new Error(`无法找到私聊对象${payload.user_id}`); throw new Error(`无法找到私聊对象${payload.user_id}`);
} }
@@ -30,13 +29,12 @@ class ForwardSingleMsg extends BaseAction<Payload, null> {
} }
async _handle(payload: Payload): Promise<null> { async _handle(payload: Payload): Promise<null> {
const NTQQMsgApi = this.core.apis.MsgApi;
const msg = MessageUnique.getMsgIdAndPeerByShortId(parseInt(payload.message_id.toString())); const msg = MessageUnique.getMsgIdAndPeerByShortId(parseInt(payload.message_id.toString()));
if (!msg) { if (!msg) {
throw new Error(`无法找到消息${payload.message_id}`); throw new Error(`无法找到消息${payload.message_id}`);
} }
const peer = await this.getTargetPeer(payload); const peer = await this.getTargetPeer(payload);
const ret = await NTQQMsgApi.forwardMsg(msg.Peer, const ret = await this.core.apis.MsgApi.forwardMsg(msg.Peer,
peer, peer,
[msg.MsgId], [msg.MsgId],
); );

View File

@@ -22,7 +22,6 @@ class GetMsg extends BaseAction<Payload, OB11Message> {
payloadSchema = SchemaData; payloadSchema = SchemaData;
async _handle(payload: Payload) { async _handle(payload: Payload) {
const NTQQMsgApi = this.core.apis.MsgApi;
// log("history msg ids", Object.keys(msgHistory)); // log("history msg ids", Object.keys(msgHistory));
if (!payload.message_id) { if (!payload.message_id) {
throw Error('参数message_id不能为空'); throw Error('参数message_id不能为空');
@@ -33,7 +32,7 @@ class GetMsg extends BaseAction<Payload, OB11Message> {
throw new Error('消息不存在'); throw new Error('消息不存在');
} }
const peer = { guildId: '', peerUid: msgIdWithPeer?.Peer.peerUid, chatType: msgIdWithPeer.Peer.chatType }; const peer = { guildId: '', peerUid: msgIdWithPeer?.Peer.peerUid, chatType: msgIdWithPeer.Peer.chatType };
const msg = await NTQQMsgApi.getMsgsByMsgId( const msg = await this.core.apis.MsgApi.getMsgsByMsgId(
peer, peer,
[msgIdWithPeer?.MsgId || payload.message_id.toString()]); [msgIdWithPeer?.MsgId || payload.message_id.toString()]);
const retMsg = await this.obContext.apis.MsgApi.parseMessage(msg.msgList[0], 'array'); const retMsg = await this.obContext.apis.MsgApi.parseMessage(msg.msgList[0], 'array');

View File

@@ -15,14 +15,12 @@ type PlayloadType = FromSchema<typeof SchemaData>;
class MarkMsgAsRead extends BaseAction<PlayloadType, null> { class MarkMsgAsRead extends BaseAction<PlayloadType, null> {
async getPeer(payload: PlayloadType): Promise<Peer> { async getPeer(payload: PlayloadType): Promise<Peer> {
const NTQQUserApi = this.core.apis.UserApi;
const NTQQFriendApi = this.core.apis.FriendApi;
if (payload.user_id) { if (payload.user_id) {
const peerUid = await NTQQUserApi.getUidByUinV2(payload.user_id.toString()); const peerUid = await this.core.apis.UserApi.getUidByUinV2(payload.user_id.toString());
if (!peerUid) { if (!peerUid) {
throw `私聊${payload.user_id}不存在`; throw `私聊${payload.user_id}不存在`;
} }
const isBuddy = await NTQQFriendApi.isBuddy(peerUid); const isBuddy = await this.core.apis.FriendApi.isBuddy(peerUid);
return { chatType: isBuddy ? ChatType.KCHATTYPEC2C : ChatType.KCHATTYPETEMPC2CFROMGROUP, peerUid }; return { chatType: isBuddy ? ChatType.KCHATTYPEC2C : ChatType.KCHATTYPETEMPC2CFROMGROUP, peerUid };
} }
if (!payload.group_id) { if (!payload.group_id) {
@@ -32,9 +30,7 @@ class MarkMsgAsRead extends BaseAction<PlayloadType, null> {
} }
async _handle(payload: PlayloadType): Promise<null> { async _handle(payload: PlayloadType): Promise<null> {
const NTQQMsgApi = this.core.apis.MsgApi; const ret = await this.core.apis.MsgApi.setMsgRead(await this.getPeer(payload));
// 调用API
const ret = await NTQQMsgApi.setMsgRead(await this.getPeer(payload));
if (ret.result != 0) { if (ret.result != 0) {
throw new Error('设置已读失败,' + ret.errMsg); throw new Error('设置已读失败,' + ret.errMsg);
} }
@@ -70,8 +66,7 @@ export class MarkAllMsgAsRead extends BaseAction<Payload, null> {
actionName = ActionName._MarkAllMsgAsRead; actionName = ActionName._MarkAllMsgAsRead;
async _handle(payload: Payload): Promise<null> { async _handle(payload: Payload): Promise<null> {
const NTQQMsgApi = this.core.apis.MsgApi; await this.core.apis.MsgApi.markAllMsgAsRead();
await NTQQMsgApi.markallMsgAsRead();
return null; return null;
} }
} }

View File

@@ -34,9 +34,6 @@ export async function createContext(core: NapCatCore, payload: OB11PostSendMsg,
// This function determines the type of message by the existence of user_id / group_id, // This function determines the type of message by the existence of user_id / group_id,
// not message_type. // not message_type.
// This redundant design of Ob11 here should be blamed. // This redundant design of Ob11 here should be blamed.
const NTQQFriendApi = core.apis.FriendApi;
const NTQQUserApi = core.apis.UserApi;
const NTQQMsgApi = core.apis.MsgApi;
if ((contextMode === ContextMode.Group || contextMode === ContextMode.Normal) && payload.group_id) { if ((contextMode === ContextMode.Group || contextMode === ContextMode.Normal) && payload.group_id) {
return { return {
chatType: ChatType.KCHATTYPEGROUP, chatType: ChatType.KCHATTYPEGROUP,
@@ -44,11 +41,11 @@ export async function createContext(core: NapCatCore, payload: OB11PostSendMsg,
}; };
} }
if ((contextMode === ContextMode.Private || contextMode === ContextMode.Normal) && payload.user_id) { if ((contextMode === ContextMode.Private || contextMode === ContextMode.Normal) && payload.user_id) {
const Uid = await NTQQUserApi.getUidByUinV2(payload.user_id.toString()); const Uid = await core.apis.UserApi.getUidByUinV2(payload.user_id.toString());
if (!Uid) throw new Error('无法获取用户信息'); if (!Uid) throw new Error('无法获取用户信息');
const isBuddy = await NTQQFriendApi.isBuddy(Uid); const isBuddy = await core.apis.FriendApi.isBuddy(Uid);
if (!isBuddy) { if (!isBuddy) {
const ret = await NTQQMsgApi.getTempChatInfo(ChatType.KCHATTYPETEMPC2CFROMGROUP, Uid); const ret = await core.apis.MsgApi.getTempChatInfo(ChatType.KCHATTYPETEMPC2CFROMGROUP, Uid);
if (ret.tmpChatInfo?.groupCode) { if (ret.tmpChatInfo?.groupCode) {
return { return {
chatType: ChatType.KCHATTYPETEMPC2CFROMGROUP, chatType: ChatType.KCHATTYPETEMPC2CFROMGROUP,
@@ -139,7 +136,6 @@ export class SendMsg extends BaseAction<OB11PostSendMsg, ReturnDataType> {
} }
private async handleForwardedNodes(destPeer: Peer, messageNodes: OB11MessageNode[]): Promise<RawMessage | null> { private async handleForwardedNodes(destPeer: Peer, messageNodes: OB11MessageNode[]): Promise<RawMessage | null> {
const NTQQMsgApi = this.core.apis.MsgApi;
const selfPeer = { const selfPeer = {
chatType: ChatType.KCHATTYPEC2C, chatType: ChatType.KCHATTYPEC2C,
peerUid: this.core.selfInfo.uid, peerUid: this.core.selfInfo.uid,
@@ -206,7 +202,7 @@ export class SendMsg extends BaseAction<OB11PostSendMsg, ReturnDataType> {
logger.logError('转发消息失败,未找到消息', msgId); logger.logError('转发消息失败,未找到消息', msgId);
continue; continue;
} }
const nodeMsg = (await NTQQMsgApi.getMsgsByMsgId(nodeMsgPeer.Peer, [msgId])).msgList[0]; const nodeMsg = (await this.core.apis.MsgApi.getMsgsByMsgId(nodeMsgPeer.Peer, [msgId])).msgList[0];
srcPeer = srcPeer ?? { chatType: nodeMsg.chatType, peerUid: nodeMsg.peerUid }; srcPeer = srcPeer ?? { chatType: nodeMsg.chatType, peerUid: nodeMsg.peerUid };
if (srcPeer.peerUid !== nodeMsg.peerUid) { if (srcPeer.peerUid !== nodeMsg.peerUid) {
needSendSelf = true; needSendSelf = true;
@@ -230,7 +226,7 @@ export class SendMsg extends BaseAction<OB11PostSendMsg, ReturnDataType> {
if (retMsgIds.length === 0) throw Error('转发消息失败,生成节点为空'); if (retMsgIds.length === 0) throw Error('转发消息失败,生成节点为空');
try { try {
logger.logDebug('开发转发', srcPeer, destPeer, retMsgIds); logger.logDebug('开发转发', srcPeer, destPeer, retMsgIds);
return await NTQQMsgApi.multiForwardMsg(srcPeer!, destPeer, retMsgIds); return await this.core.apis.MsgApi.multiForwardMsg(srcPeer!, destPeer, retMsgIds);
} catch (e) { } catch (e) {
logger.logError('forward failed', e); logger.logError('forward failed', e);
return null; return null;
@@ -243,9 +239,7 @@ export class SendMsg extends BaseAction<OB11PostSendMsg, ReturnDataType> {
peerUid: this.core.selfInfo.uid, peerUid: this.core.selfInfo.uid,
}; };
const logger = this.core.context.logger; const logger = this.core.context.logger;
const NTQQMsgApi = this.core.apis.MsgApi;
//msg 为待克隆消息 //msg 为待克隆消息
const sendElements: SendMessageElement[] = []; const sendElements: SendMessageElement[] = [];
for (const element of msg.elements) { for (const element of msg.elements) {
@@ -256,7 +250,7 @@ export class SendMsg extends BaseAction<OB11PostSendMsg, ReturnDataType> {
logger.logDebug('需要clone的消息无法解析将会忽略掉', msg); logger.logDebug('需要clone的消息无法解析将会忽略掉', msg);
} }
try { try {
return await NTQQMsgApi.sendMsg(selfPeer, sendElements, true); return await this.core.apis.MsgApi.sendMsg(selfPeer, sendElements, true);
} catch (e) { } catch (e) {
logger.logError(e, '克隆转发消息失败,将忽略本条消息', msg); logger.logError(e, '克隆转发消息失败,将忽略本条消息', msg);
} }

View File

@@ -19,7 +19,6 @@ export class SetMsgEmojiLike extends BaseAction<Payload, any> {
payloadSchema = SchemaData; payloadSchema = SchemaData;
async _handle(payload: Payload) { async _handle(payload: Payload) {
const NTQQMsgApi = this.core.apis.MsgApi;
const msg = MessageUnique.getMsgIdAndPeerByShortId(parseInt(payload.message_id.toString())); const msg = MessageUnique.getMsgIdAndPeerByShortId(parseInt(payload.message_id.toString()));
if (!msg) { if (!msg) {
throw new Error('msg not found'); throw new Error('msg not found');
@@ -27,10 +26,10 @@ export class SetMsgEmojiLike extends BaseAction<Payload, any> {
if (!payload.emoji_id) { if (!payload.emoji_id) {
throw new Error('emojiId not found'); throw new Error('emojiId not found');
} }
const msgData = (await NTQQMsgApi.getMsgsByMsgId(msg.Peer, [msg.MsgId])).msgList; const msgData = (await this.core.apis.MsgApi.getMsgsByMsgId(msg.Peer, [msg.MsgId])).msgList;
if (!msgData || msgData.length == 0 || !msgData[0].msgSeq) { if (!msgData || msgData.length == 0 || !msgData[0].msgSeq) {
throw new Error('find msg by msgid error'); throw new Error('find msg by msgid error');
} }
return await NTQQMsgApi.setEmojiLike(msg.Peer, msgData[0].msgSeq, payload.emoji_id.toString(), true); return await this.core.apis.MsgApi.setEmojiLike(msg.Peer, msgData[0].msgSeq, payload.emoji_id.toString(), true);
} }
} }

View File

@@ -22,52 +22,10 @@ export class GetCookies extends BaseAction<Payload, Response> {
payloadSchema = SchemaData; payloadSchema = SchemaData;
async _handle(payload: Payload) { async _handle(payload: Payload) {
const NTQQUserApi = this.core.apis.UserApi; const cookiesObject = await this.core.apis.UserApi.getCookies(payload.domain);
const NTQQWebApi = this.core.apis.WebApi;
// if (!payload.domain) {
// throw new Error('缺少参数 domain');
// }
// if (payload.domain.endsWith('qzone.qq.com')) {
// // 兼容整个 *.qzone.qq.com
// const data = (await NTQQUserApi.getQzoneCookies());
// const Bkn = WebApi.genBkn(data.p_skey);
// const CookieValue = 'p_skey=' + data.p_skey + '; skey=' + data.skey + '; p_uin=o' + selfInfo.uin + '; uin=o' + selfInfo.uin;
// return { cookies: CookieValue };
// }
// // 取Skey
// // 先NodeIKernelTicketService.forceFetchClientKey('')
// // 返回值
// // {
// // result: 0,
// // errMsg: '',
// // url: '',
// // keyIndex: '19',
// // clientKey: 'clientKey',
// // expireTime: '7200'
// // }
// // request https://ssl.ptlogin2.qq.com/jump?ptlang=1033&clientuin=1627126029&clientkey=key
// // &u1=https%3A%2F%2Fh5.qzone.qq.com%2Fqqnt%2Fqzoneinpcqq%2Ffriend%3Frefresh%3D0%26clientuin%3D0%26darkMode%3D0&keyindex=keyIndex
// const _PSkey = (await NTQQUserApi.getPSkey([payload.domain]))[payload.domain];
// // 取Pskey
// // NodeIKernelTipOffService.getPskey([ 'qun.qq.com' ], true )
// // {
// // domainPskeyMap: 0,
// // errMsg: 'success',
// // domainPskeyMap: Map(1) {
// // 'qun.qq.com' => 'pskey'
// // }
// // }
// if (!_PSkey || !_Skey) {
// throw new Error('获取Cookies失败');
// }
// const cookies = `p_skey=${_PSkey}; skey=${_Skey}; p_uin=o${selfInfo.uin}; uin=o${selfInfo.uin}`;
// return {
// cookies
// };
const cookiesObject = await NTQQUserApi.getCookies(payload.domain);
//把获取到的cookiesObject转换成 k=v; 格式字符串拼接在一起 //把获取到的cookiesObject转换成 k=v; 格式字符串拼接在一起
const cookies = Object.entries(cookiesObject).map(([key, value]) => `${key}=${value}`).join('; '); const cookies = Object.entries(cookiesObject).map(([key, value]) => `${key}=${value}`).join('; ');
const bkn = cookiesObject?.skey ? NTQQWebApi.getBknFromCookie(cookiesObject) : ''; const bkn = cookiesObject?.skey ? this.core.apis.WebApi.getBknFromCookie(cookiesObject) : '';
return { cookies, bkn }; return { cookies, bkn };
} }
} }

View File

@@ -19,7 +19,6 @@ export default class GetFriendList extends BaseAction<Payload, OB11User[]> {
async _handle(payload: Payload) { async _handle(payload: Payload) {
//全新逻辑 //全新逻辑
const NTQQFriendApi = this.core.apis.FriendApi; return OB11Entities.friendsV2(await this.core.apis.FriendApi.getBuddyV2(typeof payload.no_cache === 'string' ? payload.no_cache === 'true' : !!payload.no_cache));
return OB11Entities.friendsV2(await NTQQFriendApi.getBuddyV2(typeof payload.no_cache === 'string' ? payload.no_cache === 'true' : !!payload.no_cache));
} }
} }

View File

@@ -16,11 +16,9 @@ export default class GetRecentContact extends BaseAction<Payload, any> {
payloadSchema = SchemaData; payloadSchema = SchemaData;
async _handle(payload: Payload) { async _handle(payload: Payload) {
const NTQQUserApi = this.core.apis.UserApi; const ret = await this.core.apis.UserApi.getRecentContactListSnapShot(+(payload.count || 10));
const NTQQMsgApi = this.core.apis.MsgApi;
const ret = await NTQQUserApi.getRecentContactListSnapShot(+(payload.count || 10));
return await Promise.all(ret.info.changedList.map(async (t) => { return await Promise.all(ret.info.changedList.map(async (t) => {
const FastMsg = await NTQQMsgApi.getMsgsByMsgId({ chatType: t.chatType, peerUid: t.peerUid }, [t.msgId]); const FastMsg = await this.core.apis.MsgApi.getMsgsByMsgId({ chatType: t.chatType, peerUid: t.peerUid }, [t.msgId]);
if (FastMsg.msgList.length > 0) { if (FastMsg.msgList.length > 0) {
//扩展ret.info.changedList //扩展ret.info.changedList
const lastestMsg = await this.obContext.apis.MsgApi.parseMessage(FastMsg.msgList[0], 'array'); const lastestMsg = await this.obContext.apis.MsgApi.parseMessage(FastMsg.msgList[0], 'array');

View File

@@ -18,11 +18,10 @@ export default class SendLike extends BaseAction<Payload, null> {
payloadSchema = SchemaData; payloadSchema = SchemaData;
async _handle(payload: Payload): Promise<null> { async _handle(payload: Payload): Promise<null> {
const NTQQUserApi = this.core.apis.UserApi;
//logDebug('点赞参数', payload); //logDebug('点赞参数', payload);
const qq = payload.user_id.toString(); const qq = payload.user_id.toString();
const uid: string = await NTQQUserApi.getUidByUinV2(qq) || ''; const uid: string = await this.core.apis.UserApi.getUidByUinV2(qq) || '';
const result = await NTQQUserApi.like(uid, parseInt(payload.times?.toString()) || 1); const result = await this.core.apis.UserApi.like(uid, parseInt(payload.times?.toString()) || 1);
//logDebug('点赞结果', result); //logDebug('点赞结果', result);
if (result.result !== 0) { if (result.result !== 0) {
throw `点赞失败 ${result.errMsg}`; throw `点赞失败 ${result.errMsg}`;

View File

@@ -19,9 +19,8 @@ export default class SetFriendAddRequest extends BaseAction<Payload, null> {
payloadSchema = SchemaData; payloadSchema = SchemaData;
async _handle(payload: Payload): Promise<null> { async _handle(payload: Payload): Promise<null> {
const NTQQFriendApi = this.core.apis.FriendApi;
const approve = payload.approve?.toString() !== 'false'; const approve = payload.approve?.toString() !== 'false';
await NTQQFriendApi.handleFriendRequest(payload.flag, approve); await this.core.apis.FriendApi.handleFriendRequest(payload.flag, approve);
return null; return null;
} }
} }

View File

@@ -14,7 +14,6 @@ export class OneBotFriendApi {
//使用前预先判断 busiId 1061 //使用前预先判断 busiId 1061
async parsePrivatePokeEvent(grayTipElement: GrayTipElement) { async parsePrivatePokeEvent(grayTipElement: GrayTipElement) {
const NTQQUserApi = this.core.apis.UserApi;
const json = JSON.parse(grayTipElement.jsonGrayTipElement.jsonStr); const json = JSON.parse(grayTipElement.jsonGrayTipElement.jsonStr);
let pokedetail: any[] = json.items; let pokedetail: any[] = json.items;
//筛选item带有uid的元素 //筛选item带有uid的元素
@@ -23,8 +22,8 @@ export class OneBotFriendApi {
if (pokedetail.length == 2) { if (pokedetail.length == 2) {
return new OB11FriendPokeEvent( return new OB11FriendPokeEvent(
this.core, this.core,
parseInt((await NTQQUserApi.getUinByUidV2(pokedetail[0].uid))!), parseInt((await this.core.apis.UserApi.getUinByUidV2(pokedetail[0].uid))!),
parseInt((await NTQQUserApi.getUinByUidV2(pokedetail[1].uid))!), parseInt((await this.core.apis.UserApi.getUinByUidV2(pokedetail[1].uid))!),
pokedetail, pokedetail,
); );
} }

View File

@@ -30,16 +30,13 @@ export class OneBotGroupApi {
} }
async parseGroupEvent(msg: RawMessage) { async parseGroupEvent(msg: RawMessage) {
const NTQQGroupApi = this.core.apis.GroupApi;
const NTQQUserApi = this.core.apis.UserApi;
const NTQQMsgApi = this.core.apis.MsgApi;
const logger = this.core.context.logger; const logger = this.core.context.logger;
if (msg.chatType !== ChatType.KCHATTYPEGROUP) { if (msg.chatType !== ChatType.KCHATTYPEGROUP) {
return; return;
} }
//log("group msg", msg); //log("group msg", msg);
if (msg.senderUin && msg.senderUin !== '0') { if (msg.senderUin && msg.senderUin !== '0') {
const member = await NTQQGroupApi.getGroupMember(msg.peerUid, msg.senderUin); const member = await this.core.apis.GroupApi.getGroupMember(msg.peerUid, msg.senderUin);
if (member && member.cardName !== msg.sendMemberName) { if (member && member.cardName !== msg.sendMemberName) {
const newCardName = msg.sendMemberName || ''; const newCardName = msg.sendMemberName || '';
const event = new OB11GroupCardEvent(this.core, parseInt(msg.peerUid), parseInt(msg.senderUin), newCardName, member.cardName); const event = new OB11GroupCardEvent(this.core, parseInt(msg.peerUid), parseInt(msg.senderUin), newCardName, member.cardName);
@@ -58,7 +55,7 @@ export class OneBotGroupApi {
const BanEvent = await this.obContext.apis.GroupApi.parseGroupBanEvent(msg.peerUid, element.grayTipElement); const BanEvent = await this.obContext.apis.GroupApi.parseGroupBanEvent(msg.peerUid, element.grayTipElement);
if (BanEvent) return BanEvent; if (BanEvent) return BanEvent;
} else if (groupElement.type == TipGroupElementType.kicked) { } else if (groupElement.type == TipGroupElementType.kicked) {
NTQQGroupApi.quitGroup(msg.peerUid).then(); this.core.apis.GroupApi.quitGroup(msg.peerUid).then();
try { try {
const KickEvent = await this.obContext.apis.GroupApi.parseGroupKickEvent(msg.peerUid, element.grayTipElement); const KickEvent = await this.obContext.apis.GroupApi.parseGroupKickEvent(msg.peerUid, element.grayTipElement);
if (KickEvent) return KickEvent; if (KickEvent) return KickEvent;
@@ -110,8 +107,8 @@ export class OneBotGroupApi {
return new OB11GroupPokeEvent( return new OB11GroupPokeEvent(
this.core, this.core,
parseInt(msg.peerUid), parseInt(msg.peerUid),
parseInt((await NTQQUserApi.getUinByUidV2(poke_uid[0].uid))!), parseInt((await this.core.apis.UserApi.getUinByUidV2(poke_uid[0].uid))!),
parseInt((await NTQQUserApi.getUinByUidV2(poke_uid[1].uid))!), parseInt((await this.core.apis.UserApi.getUinByUidV2(poke_uid[1].uid))!),
pokedetail, pokedetail,
); );
} }
@@ -127,7 +124,7 @@ export class OneBotGroupApi {
chatType: ChatType.KCHATTYPEGROUP, chatType: ChatType.KCHATTYPEGROUP,
peerUid: Group, peerUid: Group,
}; };
const msgData = await NTQQMsgApi.getMsgsBySeqAndCount(Peer, msgSeq.toString(), 1, true, true); const msgData = await this.core.apis.MsgApi.getMsgsBySeqAndCount(Peer, msgSeq.toString(), 1, true, true);
const msgList = (await this.core.apis.WebApi.getGroupEssenceMsgAll(Group)).flatMap((e) => e.data.msg_list); const msgList = (await this.core.apis.WebApi.getGroupEssenceMsgAll(Group)).flatMap((e) => e.data.msg_list);
const realMsg = msgList.find((e) => e.msg_seq.toString() == msgSeq); const realMsg = msgList.find((e) => e.msg_seq.toString() == msgSeq);
return new OB11GroupEssenceEvent( return new OB11GroupEssenceEvent(
@@ -158,7 +155,6 @@ export class OneBotGroupApi {
async parseGroupBanEvent(GroupCode: string, grayTipElement: GrayTipElement) { async parseGroupBanEvent(GroupCode: string, grayTipElement: GrayTipElement) {
const groupElement = grayTipElement?.groupElement; const groupElement = grayTipElement?.groupElement;
const NTQQGroupApi = this.core.apis.GroupApi;
if (!groupElement?.shutUp) return undefined; if (!groupElement?.shutUp) return undefined;
const memberUid = groupElement.shutUp!.member.uid; const memberUid = groupElement.shutUp!.member.uid;
const adminUid = groupElement.shutUp!.admin.uid; const adminUid = groupElement.shutUp!.admin.uid;
@@ -166,14 +162,14 @@ export class OneBotGroupApi {
let duration = parseInt(groupElement.shutUp!.duration); let duration = parseInt(groupElement.shutUp!.duration);
const subType: 'ban' | 'lift_ban' = duration > 0 ? 'ban' : 'lift_ban'; const subType: 'ban' | 'lift_ban' = duration > 0 ? 'ban' : 'lift_ban';
if (memberUid) { if (memberUid) {
memberUin = (await NTQQGroupApi.getGroupMember(GroupCode, memberUid))?.uin || ''; memberUin = (await this.core.apis.GroupApi.getGroupMember(GroupCode, memberUid))?.uin || '';
} else { } else {
memberUin = '0'; // 0表示全员禁言 memberUin = '0'; // 0表示全员禁言
if (duration > 0) { if (duration > 0) {
duration = -1; duration = -1;
} }
} }
const adminUin = (await NTQQGroupApi.getGroupMember(GroupCode, adminUid))?.uin; const adminUin = (await this.core.apis.GroupApi.getGroupMember(GroupCode, adminUid))?.uin;
if (memberUin && adminUin) { if (memberUin && adminUin) {
return new OB11GroupBanEvent( return new OB11GroupBanEvent(
this.core, this.core,
@@ -215,12 +211,11 @@ export class OneBotGroupApi {
} }
async parseGroupMemberIncreaseEvent(GroupCode: string, grayTipElement: GrayTipElement) { async parseGroupMemberIncreaseEvent(GroupCode: string, grayTipElement: GrayTipElement) {
const NTQQGroupApi = this.core.apis.GroupApi;
const groupElement = grayTipElement?.groupElement; const groupElement = grayTipElement?.groupElement;
if (!groupElement) return undefined; if (!groupElement) return undefined;
const member = await NTQQGroupApi.getGroupMember(GroupCode, groupElement.memberUid); const member = await this.core.apis.GroupApi.getGroupMember(GroupCode, groupElement.memberUid);
const memberUin = member?.uin; const memberUin = member?.uin;
const adminMember = await NTQQGroupApi.getGroupMember(GroupCode, groupElement.adminUid); const adminMember = await this.core.apis.GroupApi.getGroupMember(GroupCode, groupElement.adminUid);
if (memberUin) { if (memberUin) {
const operatorUin = adminMember?.uin || memberUin; const operatorUin = adminMember?.uin || memberUin;
return new OB11GroupIncreaseEvent( return new OB11GroupIncreaseEvent(
@@ -235,11 +230,9 @@ export class OneBotGroupApi {
} }
async parseGroupKickEvent(GroupCode: string, grayTipElement: GrayTipElement) { async parseGroupKickEvent(GroupCode: string, grayTipElement: GrayTipElement) {
const NTQQGroupApi = this.core.apis.GroupApi;
const NTQQUserApi = this.core.apis.UserApi;
const groupElement = grayTipElement?.groupElement; const groupElement = grayTipElement?.groupElement;
if (!groupElement) return undefined; if (!groupElement) return undefined;
const adminUin = (await NTQQGroupApi.getGroupMember(GroupCode, groupElement.adminUid))?.uin || (await NTQQUserApi.getUidByUinV2(groupElement.adminUid)); const adminUin = (await this.core.apis.GroupApi.getGroupMember(GroupCode, groupElement.adminUid))?.uin || (await this.core.apis.UserApi.getUidByUinV2(groupElement.adminUid));
if (adminUin) { if (adminUin) {
return new OB11GroupDecreaseEvent( return new OB11GroupDecreaseEvent(
this.core, this.core,

View File

@@ -106,12 +106,13 @@ export class OneBotMsgApi {
peerUid: msg.peerUid, peerUid: msg.peerUid,
guildId: '', guildId: '',
}; };
const encodedFileId = FileNapCatOneBotUUID.encode(peer, msg.msgId, elementWrapper.elementId);
return { return {
type: OB11MessageDataType.image, type: OB11MessageDataType.image,
data: { data: {
file: element.fileName, file: encodedFileId,
sub_type: element.picSubType, sub_type: element.picSubType,
file_id: FileNapCatOneBotUUID.encode(peer, msg.msgId, elementWrapper.elementId), file_id: encodedFileId,
url: await this.core.apis.FileApi.getImageUrl(element), url: await this.core.apis.FileApi.getImageUrl(element),
file_size: element.fileSize, file_size: element.fileSize,
}, },
@@ -212,7 +213,6 @@ export class OneBotMsgApi {
}, },
replyElement: async (element, msg) => { replyElement: async (element, msg) => {
const NTQQMsgApi = this.core.apis.MsgApi;
const records = msg.records.find(msgRecord => msgRecord.msgId === element?.sourceMsgIdInRecords); const records = msg.records.find(msgRecord => msgRecord.msgId === element?.sourceMsgIdInRecords);
const peer = { const peer = {
chatType: msg.chatType, chatType: msg.chatType,
@@ -237,17 +237,17 @@ export class OneBotMsgApi {
let replyMsg: RawMessage | undefined; let replyMsg: RawMessage | undefined;
// Attempt 1 // Attempt 1
replyMsg = (await NTQQMsgApi.getMsgsBySeqAndCount(peer,element.replayMsgSeq, 1, true, true)) replyMsg = (await this.core.apis.MsgApi.getMsgsBySeqAndCount(peer,element.replayMsgSeq, 1, true, true))
.msgList .msgList
.find(msg => msg.msgRandom === records.msgRandom); .find(msg => msg.msgRandom === records.msgRandom);
if (!replyMsg || records.msgRandom !== replyMsg.msgRandom) { if (!replyMsg || records.msgRandom !== replyMsg.msgRandom) {
// Attempt 2 // Attempt 2
replyMsg = (await NTQQMsgApi.getSingleMsg(peer, element.replayMsgSeq)).msgList[0]; replyMsg = (await this.core.apis.MsgApi.getSingleMsg(peer, element.replayMsgSeq)).msgList[0];
if (!replyMsg || records.msgRandom !== replyMsg.msgRandom) { if (!replyMsg || records.msgRandom !== replyMsg.msgRandom) {
// Attempt 3 // Attempt 3
const replyMsgList = (await NTQQMsgApi.getMsgExBySeq(peer, records.msgSeq)).msgList; const replyMsgList = (await this.core.apis.MsgApi.getMsgExBySeq(peer, records.msgSeq)).msgList;
if (replyMsgList.length < 1) { if (replyMsgList.length < 1) {
this.core.context.logger.logError('回复消息消息验证失败', element.replayMsgSeq); this.core.context.logger.logError('回复消息消息验证失败', element.replayMsgSeq);
return null; return null;
@@ -261,20 +261,19 @@ export class OneBotMsgApi {
}, },
videoElement: async (element, msg, elementWrapper) => { videoElement: async (element, msg, elementWrapper) => {
const NTQQFileApi = this.core.apis.FileApi;
const peer = { const peer = {
chatType: msg.chatType, chatType: msg.chatType,
peerUid: msg.peerUid, peerUid: msg.peerUid,
guildId: '', guildId: '',
}; };
//读取视频链接并兜底 //读取视频链接并兜底
let videoUrlWrappers: Awaited<ReturnType<typeof NTQQFileApi.getVideoUrl>> | undefined; let videoUrlWrappers: Awaited<ReturnType<typeof this.core.apis.FileApi.getVideoUrl>> | undefined;
if (msg.peerUin === '284840486') { if (msg.peerUin === '284840486') {
//TODO: 合并消息内部 应该进行特殊处理 可能需要重写peer 待测试与研究 Mlikiowa Tagged //TODO: 合并消息内部 应该进行特殊处理 可能需要重写peer 待测试与研究 Mlikiowa Tagged
} }
try { try {
videoUrlWrappers = await NTQQFileApi.getVideoUrl({ videoUrlWrappers = await this.core.apis.FileApi.getVideoUrl({
chatType: msg.chatType, chatType: msg.chatType,
peerUid: msg.peerUid, peerUid: msg.peerUid,
guildId: '0', guildId: '0',
@@ -300,7 +299,7 @@ export class OneBotMsgApi {
videoDownUrl = element.filePath; videoDownUrl = element.filePath;
} }
await NTQQFileApi.addFileCache( await this.core.apis.FileApi.addFileCache(
{ {
peerUid: msg.peerUid, peerUid: msg.peerUid,
chatType: msg.chatType, chatType: msg.chatType,
@@ -359,7 +358,6 @@ export class OneBotMsgApi {
}, },
multiForwardMsgElement: async (_, msg) => { multiForwardMsgElement: async (_, msg) => {
const NTQQMsgApi = this.core.apis.MsgApi;
const message_data: OB11MessageForward = { const message_data: OB11MessageForward = {
data: {} as any, data: {} as any,
type: OB11MessageDataType.forward, type: OB11MessageDataType.forward,
@@ -376,7 +374,7 @@ export class OneBotMsgApi {
msg.parentMsgIdList.push(msg.msgId); msg.parentMsgIdList.push(msg.msgId);
//let parentMsgId = msg.parentMsgIdList[msg.parentMsgIdList.length - 2 < 0 ? 0 : msg.parentMsgIdList.length - 2]; //let parentMsgId = msg.parentMsgIdList[msg.parentMsgIdList.length - 2 < 0 ? 0 : msg.parentMsgIdList.length - 2];
//加入自身MsgId //加入自身MsgId
const multiMsgs = (await NTQQMsgApi.getMultiMsg(parentMsgPeer, msg.parentMsgIdList[0], msg.msgId))?.msgList; const multiMsgs = (await this.core.apis.MsgApi.getMultiMsg(parentMsgPeer, msg.parentMsgIdList[0], msg.msgId))?.msgList;
//拉取下级消息 //拉取下级消息
if (!multiMsgs) return null; if (!multiMsgs) return null;
//拉取失败则跳过 //拉取失败则跳过
@@ -446,15 +444,13 @@ export class OneBotMsgApi {
if (!context.peer || context.peer.chatType == ChatType.KCHATTYPEC2C) return undefined; if (!context.peer || context.peer.chatType == ChatType.KCHATTYPEC2C) return undefined;
if (atQQ === 'all') return at(atQQ, atQQ, AtType.atAll, '全体成员'); if (atQQ === 'all') return at(atQQ, atQQ, AtType.atAll, '全体成员');
const NTQQGroupApi = this.core.apis.GroupApi; const atMember = await this.core.apis.GroupApi.getGroupMember(context.peer.peerUid, atQQ);
const NTQQUserApi = this.core.apis.UserApi;
const atMember = await NTQQGroupApi.getGroupMember(context.peer.peerUid, atQQ);
if (atMember) { if (atMember) {
return at(atQQ, atMember.uid, AtType.atUser, atMember.nick || atMember.cardName); return at(atQQ, atMember.uid, AtType.atUser, atMember.nick || atMember.cardName);
} }
const uid = await NTQQUserApi.getUidByUinV2(`${atQQ}`); const uid = await this.core.apis.UserApi.getUidByUinV2(`${atQQ}`);
if (!uid) throw new Error('Get Uid Error'); if (!uid) throw new Error('Get Uid Error');
const info = await NTQQUserApi.getUserDetailInfo(uid); const info = await this.core.apis.UserApi.getUserDetailInfo(uid);
return at(atQQ, uid, AtType.atUser, info.nick || ''); return at(atQQ, uid, AtType.atUser, info.nick || '');
}, },
@@ -464,8 +460,7 @@ export class OneBotMsgApi {
this.core.context.logger.logWarn('回复消息不存在', id); this.core.context.logger.logWarn('回复消息不存在', id);
return undefined; return undefined;
} }
const NTQQMsgApi = this.core.apis.MsgApi; const replyMsg = (await this.core.apis.MsgApi.getMsgsByMsgId(
const replyMsg = (await NTQQMsgApi.getMsgsByMsgId(
replyMsgM.Peer, [replyMsgM.MsgId])).msgList[0]; replyMsgM.Peer, [replyMsgM.MsgId])).msgList[0];
return replyMsg ? return replyMsg ?
{ {
@@ -710,9 +705,6 @@ export class OneBotMsgApi {
if (msg.senderUin == '0' || msg.senderUin == '') return; if (msg.senderUin == '0' || msg.senderUin == '') return;
if (msg.peerUin == '0' || msg.peerUin == '') return; if (msg.peerUin == '0' || msg.peerUin == '') return;
//跳过空消息 //跳过空消息
const NTQQGroupApi = this.core.apis.GroupApi;
const NTQQUserApi = this.core.apis.UserApi;
const NTQQMsgApi = this.core.apis.MsgApi;
const resMsg: OB11Message = { const resMsg: OB11Message = {
self_id: parseInt(this.core.selfInfo.uin), self_id: parseInt(this.core.selfInfo.uin),
user_id: parseInt(msg.senderUin!), user_id: parseInt(msg.senderUin!),
@@ -736,18 +728,18 @@ export class OneBotMsgApi {
if (msg.chatType == ChatType.KCHATTYPEGROUP) { if (msg.chatType == ChatType.KCHATTYPEGROUP) {
resMsg.sub_type = 'normal'; // 这里go-cqhttp是group而onebot11标准是normal, 蛋疼 resMsg.sub_type = 'normal'; // 这里go-cqhttp是group而onebot11标准是normal, 蛋疼
resMsg.group_id = parseInt(msg.peerUin); resMsg.group_id = parseInt(msg.peerUin);
let member = await NTQQGroupApi.getGroupMember(msg.peerUin, msg.senderUin); let member = await this.core.apis.GroupApi.getGroupMember(msg.peerUin, msg.senderUin);
if (!member) member = await NTQQGroupApi.getGroupMember(msg.peerUin, msg.senderUin); if (!member) member = await this.core.apis.GroupApi.getGroupMember(msg.peerUin, msg.senderUin);
if (member) { if (member) {
resMsg.sender.role = OB11Entities.groupMemberRole(member.role); resMsg.sender.role = OB11Entities.groupMemberRole(member.role);
resMsg.sender.nickname = member.nick; resMsg.sender.nickname = member.nick;
} }
} else if (msg.chatType == ChatType.KCHATTYPEC2C) { } else if (msg.chatType == ChatType.KCHATTYPEC2C) {
resMsg.sub_type = 'friend'; resMsg.sub_type = 'friend';
resMsg.sender.nickname = (await NTQQUserApi.getUserDetailInfo(msg.senderUid)).nick; resMsg.sender.nickname = (await this.core.apis.UserApi.getUserDetailInfo(msg.senderUid)).nick;
} else if (msg.chatType == ChatType.KCHATTYPETEMPC2CFROMGROUP) { } else if (msg.chatType == ChatType.KCHATTYPETEMPC2CFROMGROUP) {
resMsg.sub_type = 'group'; resMsg.sub_type = 'group';
const ret = await NTQQMsgApi.getTempChatInfo(ChatType.KCHATTYPETEMPC2CFROMGROUP, msg.senderUid); const ret = await this.core.apis.MsgApi.getTempChatInfo(ChatType.KCHATTYPETEMPC2CFROMGROUP, msg.senderUid);
if (ret.result === 0) { if (ret.result === 0) {
resMsg.group_id = parseInt(ret.tmpChatInfo!.groupCode); resMsg.group_id = parseInt(ret.tmpChatInfo!.groupCode);
resMsg.sender.nickname = ret.tmpChatInfo!.fromNick; resMsg.sender.nickname = ret.tmpChatInfo!.fromNick;

View File

@@ -77,7 +77,6 @@ export class NapCatOneBot11Adapter {
} }
async InitOneBot() { async InitOneBot() {
const NTQQUserApi = this.core.apis.UserApi;
const selfInfo = this.core.selfInfo; const selfInfo = this.core.selfInfo;
const ob11Config = this.configLoader.configData; const ob11Config = this.configLoader.configData;
@@ -87,7 +86,7 @@ export class NapCatOneBot11Adapter {
WebSocket服务 ${ob11Config.ws.enable ? '已启动' : '未启动'}, ${ob11Config.ws.host}:${ob11Config.ws.port} WebSocket服务 ${ob11Config.ws.enable ? '已启动' : '未启动'}, ${ob11Config.ws.host}:${ob11Config.ws.port}
WebSocket反向服务 ${ob11Config.reverseWs.enable ? '已启动' : '未启动'}, 反向地址: ${ob11Config.reverseWs.urls}`; WebSocket反向服务 ${ob11Config.reverseWs.enable ? '已启动' : '未启动'}, 反向地址: ${ob11Config.reverseWs.urls}`;
NTQQUserApi.getUserDetailInfo(selfInfo.uid).then(user => { this.core.apis.UserApi.getUserDetailInfo(selfInfo.uid).then(user => {
selfInfo.nick = user.nick; selfInfo.nick = user.nick;
this.context.logger.setLogSelfInfo(selfInfo); this.context.logger.setLogSelfInfo(selfInfo);
}).catch(this.context.logger.logError); }).catch(this.context.logger.logError);
@@ -341,12 +340,6 @@ export class NapCatOneBot11Adapter {
this.core.apis.FriendApi.clearBuddyReqUnreadCnt(); this.core.apis.FriendApi.clearBuddyReqUnreadCnt();
for (let i = 0; i < reqs.unreadNums; i++) { for (let i = 0; i < reqs.unreadNums; i++) {
const req = reqs.buddyReqs[i]; const req = reqs.buddyReqs[i];
//req.isBuddy === false是单向好友 null为常规情况
// if (req.isBuddy === false && ) {
// const NTQQFriendApi = this.core.apis.FriendApi;
// await NTQQFriendApi.handleFriendRequest(req.friendUid + '|' + req.reqTime, true);
// }
if (!!req.isInitiator || (req.isDecide && req.reqType !== BuddyReqType.KMEINITIATORWAITPEERCONFIRM)) { if (!!req.isInitiator || (req.isDecide && req.reqType !== BuddyReqType.KMEINITIATORWAITPEERCONFIRM)) {
continue; continue;
} }

View File

@@ -30,7 +30,7 @@ async function onSettingWindowCreated(view: Element) {
SettingItem( SettingItem(
'<span id="napcat-update-title">Napcat</span>', '<span id="napcat-update-title">Napcat</span>',
undefined, undefined,
SettingButton('V2.2.28', 'napcat-update-button', 'secondary'), SettingButton('V2.2.31', 'napcat-update-button', 'secondary'),
), ),
]), ]),
SettingList([ SettingList([

View File

@@ -164,7 +164,7 @@ async function onSettingWindowCreated(view) {
SettingItem( SettingItem(
'<span id="napcat-update-title">Napcat</span>', '<span id="napcat-update-title">Napcat</span>',
void 0, void 0,
SettingButton("V2.2.28", "napcat-update-button", "secondary") SettingButton("V2.2.31", "napcat-update-button", "secondary")
) )
]), ]),
SettingList([ SettingList([