chore: fix indentation and semi in core

This commit is contained in:
Wesley F. Young 2024-08-09 14:09:42 +08:00
parent bd9ee62118
commit cfc68e70b6
31 changed files with 1776 additions and 1776 deletions

View File

@ -4,7 +4,7 @@ module.exports = {
'es2021': true, 'es2021': true,
'node': true 'node': true
}, },
'ignorePatterns': ['src/core/', 'src/core.lib/','src/proto/'], 'ignorePatterns': ['src/proto/'],
'extends': [ 'extends': [
'eslint:recommended', 'eslint:recommended',
'plugin:@typescript-eslint/recommended' 'plugin:@typescript-eslint/recommended'

View File

@ -1,142 +1,142 @@
import { Peer } from '@/core'; import { Peer } from '@/core';
import crypto from 'crypto'; import crypto from 'crypto';
export class LimitedHashTable<K, V> { export class LimitedHashTable<K, V> {
private keyToValue: Map<K, V> = new Map(); private keyToValue: Map<K, V> = new Map();
private valueToKey: Map<V, K> = new Map(); private valueToKey: Map<V, K> = new Map();
private maxSize: number; private maxSize: number;
constructor(maxSize: number) { constructor(maxSize: number) {
this.maxSize = maxSize; this.maxSize = maxSize;
} }
resize(count: number) { resize(count: number) {
this.maxSize = count; this.maxSize = count;
} }
set(key: K, value: V): void { set(key: K, value: V): void {
// const isExist = this.keyToValue.get(key); // const isExist = this.keyToValue.get(key);
// if (isExist && isExist === value) { // if (isExist && isExist === value) {
// return; // return;
// } // }
this.keyToValue.set(key, value); this.keyToValue.set(key, value);
this.valueToKey.set(value, key); this.valueToKey.set(value, key);
while (this.keyToValue.size !== this.valueToKey.size) { while (this.keyToValue.size !== this.valueToKey.size) {
console.log('keyToValue.size !== valueToKey.size Error Atom'); console.log('keyToValue.size !== valueToKey.size Error Atom');
this.keyToValue.clear(); this.keyToValue.clear();
this.valueToKey.clear(); this.valueToKey.clear();
}
// console.log('---------------');
// console.log(this.keyToValue);
// console.log(this.valueToKey);
// console.log('---------------');
while (this.keyToValue.size > this.maxSize || this.valueToKey.size > this.maxSize) {
//console.log(this.keyToValue.size > this.maxSize, this.valueToKey.size > this.maxSize);
const oldestKey = this.keyToValue.keys().next().value;
this.valueToKey.delete(this.keyToValue.get(oldestKey)!);
this.keyToValue.delete(oldestKey);
}
} }
// console.log('---------------');
// console.log(this.keyToValue);
// console.log(this.valueToKey);
// console.log('---------------');
while (this.keyToValue.size > this.maxSize || this.valueToKey.size > this.maxSize) {
//console.log(this.keyToValue.size > this.maxSize, this.valueToKey.size > this.maxSize);
const oldestKey = this.keyToValue.keys().next().value;
this.valueToKey.delete(this.keyToValue.get(oldestKey)!);
this.keyToValue.delete(oldestKey);
}
}
getValue(key: K): V | undefined { getValue(key: K): V | undefined {
return this.keyToValue.get(key); return this.keyToValue.get(key);
}
getKey(value: V): K | undefined {
return this.valueToKey.get(value);
}
deleteByValue(value: V): void {
const key = this.valueToKey.get(value);
if (key !== undefined) {
this.keyToValue.delete(key);
this.valueToKey.delete(value);
} }
}
deleteByKey(key: K): void { getKey(value: V): K | undefined {
const value = this.keyToValue.get(key); return this.valueToKey.get(value);
if (value !== undefined) {
this.keyToValue.delete(key);
this.valueToKey.delete(value);
} }
}
getKeyList(): K[] { deleteByValue(value: V): void {
return Array.from(this.keyToValue.keys()); const key = this.valueToKey.get(value);
} if (key !== undefined) {
//获取最近刚写入的几个值 this.keyToValue.delete(key);
getHeads(size: number): { key: K; value: V }[] | undefined { this.valueToKey.delete(value);
const keyList = this.getKeyList(); }
if (keyList.length === 0) {
return undefined;
} }
const result: { key: K; value: V }[] = [];
const listSize = Math.min(size, keyList.length); deleteByKey(key: K): void {
for (let i = 0; i < listSize; i++) { const value = this.keyToValue.get(key);
const key = keyList[listSize - i]; if (value !== undefined) {
result.push({ key, value: this.keyToValue.get(key)! }); this.keyToValue.delete(key);
this.valueToKey.delete(value);
}
}
getKeyList(): K[] {
return Array.from(this.keyToValue.keys());
}
//获取最近刚写入的几个值
getHeads(size: number): { key: K; value: V }[] | undefined {
const keyList = this.getKeyList();
if (keyList.length === 0) {
return undefined;
}
const result: { key: K; value: V }[] = [];
const listSize = Math.min(size, keyList.length);
for (let i = 0; i < listSize; i++) {
const key = keyList[listSize - i];
result.push({ key, value: this.keyToValue.get(key)! });
}
return result;
} }
return result;
}
} }
class MessageUniqueWrapper { class MessageUniqueWrapper {
private msgDataMap: LimitedHashTable<string, number>; private msgDataMap: LimitedHashTable<string, number>;
private msgIdMap: LimitedHashTable<string, number>; private msgIdMap: LimitedHashTable<string, number>;
constructor(maxMap: number = 1000) { constructor(maxMap: number = 1000) {
this.msgIdMap = new LimitedHashTable<string, number>(maxMap); this.msgIdMap = new LimitedHashTable<string, number>(maxMap);
this.msgDataMap = new LimitedHashTable<string, number>(maxMap); this.msgDataMap = new LimitedHashTable<string, number>(maxMap);
}
getRecentMsgIds(Peer: Peer, size: number): string[] {
const heads = this.msgIdMap.getHeads(size);
if (!heads) {
return [];
} }
const data = heads.map((t) => MessageUnique.getMsgIdAndPeerByShortId(t.value)); getRecentMsgIds(Peer: Peer, size: number): string[] {
const ret = data.filter((t) => t?.Peer.chatType === Peer.chatType && t?.Peer.peerUid === Peer.peerUid); const heads = this.msgIdMap.getHeads(size);
return ret.map((t) => t?.MsgId).filter((t) => t !== undefined); if (!heads) {
} return [];
createMsg(peer: Peer, msgId: string): number | undefined { }
const key = `${msgId}|${peer.chatType}|${peer.peerUid}`; const data = heads.map((t) => MessageUnique.getMsgIdAndPeerByShortId(t.value));
const hash = crypto.createHash('md5').update(key).digest(); const ret = data.filter((t) => t?.Peer.chatType === Peer.chatType && t?.Peer.peerUid === Peer.peerUid);
//设置第一个bit为0 保证shortId为正数 return ret.map((t) => t?.MsgId).filter((t) => t !== undefined);
hash[0] &= 0x7f; }
const shortId = hash.readInt32BE(0); createMsg(peer: Peer, msgId: string): number | undefined {
//减少性能损耗 const key = `${msgId}|${peer.chatType}|${peer.peerUid}`;
// const isExist = this.msgIdMap.getKey(shortId); const hash = crypto.createHash('md5').update(key).digest();
// if (isExist && isExist === msgId) { //设置第一个bit为0 保证shortId为正数
// return shortId; hash[0] &= 0x7f;
// } const shortId = hash.readInt32BE(0);
this.msgIdMap.set(msgId, shortId); //减少性能损耗
this.msgDataMap.set(key, shortId); // const isExist = this.msgIdMap.getKey(shortId);
return shortId; // if (isExist && isExist === msgId) {
} // return shortId;
// }
getMsgIdAndPeerByShortId(shortId: number): { MsgId: string; Peer: Peer } | undefined { this.msgIdMap.set(msgId, shortId);
const data = this.msgDataMap.getKey(shortId); this.msgDataMap.set(key, shortId);
if (data) { return shortId;
const [msgId, chatTypeStr, peerUid] = data.split('|');
const peer: Peer = {
chatType: parseInt(chatTypeStr),
peerUid,
guildId: '',
};
return { MsgId: msgId, Peer: peer };
} }
return undefined;
}
getShortIdByMsgId(msgId: string): number | undefined { getMsgIdAndPeerByShortId(shortId: number): { MsgId: string; Peer: Peer } | undefined {
return this.msgIdMap.getValue(msgId); const data = this.msgDataMap.getKey(shortId);
} if (data) {
getPeerByMsgId(msgId: string) { const [msgId, chatTypeStr, peerUid] = data.split('|');
const shortId = this.msgIdMap.getValue(msgId); const peer: Peer = {
if (!shortId) return undefined; chatType: parseInt(chatTypeStr),
return this.getMsgIdAndPeerByShortId(shortId); peerUid,
} guildId: '',
resize(maxSize: number): void { };
this.msgIdMap.resize(maxSize); return { MsgId: msgId, Peer: peer };
this.msgDataMap.resize(maxSize); }
} return undefined;
}
getShortIdByMsgId(msgId: string): number | undefined {
return this.msgIdMap.getValue(msgId);
}
getPeerByMsgId(msgId: string) {
const shortId = this.msgIdMap.getValue(msgId);
if (!shortId) return undefined;
return this.getMsgIdAndPeerByShortId(shortId);
}
resize(maxSize: number): void {
this.msgIdMap.resize(maxSize);
this.msgDataMap.resize(maxSize);
}
} }
export const MessageUnique: MessageUniqueWrapper = new MessageUniqueWrapper(); export const MessageUnique: MessageUniqueWrapper = new MessageUniqueWrapper();

View File

@ -14,16 +14,16 @@ export interface NodeIDependsAdapter extends IDependsAdapter {
} }
export class DependsAdapter implements IDependsAdapter { export class DependsAdapter implements IDependsAdapter {
onMSFStatusChange(arg1: number, arg2: number) { onMSFStatusChange(arg1: number, arg2: number) {
// console.log(arg1, arg2); // console.log(arg1, arg2);
// if (arg1 == 2 && arg2 == 2) { // if (arg1 == 2 && arg2 == 2) {
// log("NapCat丢失网络连接,请检查网络") // log("NapCat丢失网络连接,请检查网络")
// } // }
} }
onMSFSsoError(args: unknown) { onMSFSsoError(args: unknown) {
} }
getGroupCode(args: unknown) { getGroupCode(args: unknown) {
} }
} }

View File

@ -12,12 +12,12 @@ export interface NodeIDispatcherAdapter extends IDispatcherAdapter {
} }
export class DispatcherAdapter implements IDispatcherAdapter { export class DispatcherAdapter implements IDispatcherAdapter {
dispatchRequest(arg: unknown) { dispatchRequest(arg: unknown) {
} }
dispatchCall(arg: unknown) { dispatchCall(arg: unknown) {
} }
dispatchCallWithJson(arg: unknown) { dispatchCallWithJson(arg: unknown) {
} }
} }

View File

@ -22,27 +22,27 @@ export interface NodeIGlobalAdapter extends IGlobalAdapter {
} }
export class GlobalAdapter implements IGlobalAdapter { export class GlobalAdapter implements IGlobalAdapter {
onLog(...args: unknown[]) { onLog(...args: unknown[]) {
} }
onGetSrvCalTime(...args: unknown[]) { onGetSrvCalTime(...args: unknown[]) {
} }
onShowErrUITips(...args: unknown[]) { onShowErrUITips(...args: unknown[]) {
} }
fixPicImgType(...args: unknown[]) { fixPicImgType(...args: unknown[]) {
} }
getAppSetting(...args: unknown[]) { getAppSetting(...args: unknown[]) {
} }
onInstallFinished(...args: unknown[]) { onInstallFinished(...args: unknown[]) {
} }
onUpdateGeneralFlag(...args: unknown[]) { onUpdateGeneralFlag(...args: unknown[]) {
} }
onGetOfflineMsg(...args: unknown[]) { onGetOfflineMsg(...args: unknown[]) {
} }
} }

View File

@ -4,11 +4,11 @@ export class NTQQCollectionApi {
context: InstanceContext; context: InstanceContext;
core: NapCatCore; core: NapCatCore;
constructor(context: InstanceContext, core: NapCatCore) { constructor(context: InstanceContext, core: NapCatCore) {
this.context = context; this.context = context;
this.core = core; this.core = core;
} }
async createCollection(authorUin: string, authorUid: string, authorName: string, brief: string, rawData: string) { async createCollection(authorUin: string, authorUid: string, authorName: string, brief: string, rawData: string) {
let param = { const param = {
commInfo: { commInfo: {
bid: 1, bid: 1,
category: 2, category: 2,
@ -44,8 +44,8 @@ export class NTQQCollectionApi {
}; };
return this.context.session.getCollectionService().createNewCollectionItem(param); return this.context.session.getCollectionService().createNewCollectionItem(param);
} }
async getAllCollection(category: number = 0, count: number = 50) { async getAllCollection(category: number = 0, count: number = 50) {
let param = { const param = {
category: category, category: category,
groupId: -1, groupId: -1,
forceSync: true, forceSync: true,

View File

@ -1,9 +1,9 @@
import { import {
CacheFileListItem, CacheFileListItem,
CacheFileType, CacheFileType,
ChatCacheListItemBasic, ChatCacheListItemBasic,
ChatType, ChatType,
ElementType, IMAGE_HTTP_HOST, IMAGE_HTTP_HOST_NT, Peer, PicElement ElementType, IMAGE_HTTP_HOST, IMAGE_HTTP_HOST_NT, Peer, PicElement
} from '@/core/entities'; } from '@/core/entities';
import path from 'path'; import path from 'path';
import fs from 'fs'; import fs from 'fs';
@ -17,80 +17,80 @@ import { RkeyManager } from '../helper/rkey';
export class NTQQFileApi { export class NTQQFileApi {
context: InstanceContext; context: InstanceContext;
core: NapCatCore; core: NapCatCore;
rkeyManager: RkeyManager; rkeyManager: RkeyManager;
constructor(context: InstanceContext, core: NapCatCore) { constructor(context: InstanceContext, core: NapCatCore) {
this.context = context; this.context = context;
this.core = core; this.core = core;
this.rkeyManager = new RkeyManager('http://napcat-sign.wumiao.wang:2082/rkey', this.context.logger); this.rkeyManager = new RkeyManager('http://napcat-sign.wumiao.wang:2082/rkey', this.context.logger);
} }
async getFileType(filePath: string) { async getFileType(filePath: string) {
return fileType.fileTypeFromFile(filePath); return fileType.fileTypeFromFile(filePath);
} }
async copyFile(filePath: string, destPath: string) { async copyFile(filePath: string, destPath: string) {
await this.context.wrapper.util.copyFile(filePath, destPath); await this.context.wrapper.util.copyFile(filePath, destPath);
} }
async getFileSize(filePath: string): Promise<number> { async getFileSize(filePath: string): Promise<number> {
return await this.context.wrapper.util.getFileSize(filePath); return await this.context.wrapper.util.getFileSize(filePath);
} }
async getVideoUrl(peer: Peer, msgId: string, elementId: string) { async getVideoUrl(peer: Peer, msgId: string, elementId: string) {
return (await this.context.session.getRichMediaService().getVideoPlayUrlV2(peer, msgId, elementId, 0, { downSourceType: 1, triggerType: 1 })).urlResult.domainUrl; return (await this.context.session.getRichMediaService().getVideoPlayUrlV2(peer, msgId, elementId, 0, { downSourceType: 1, triggerType: 1 })).urlResult.domainUrl;
} }
// 上传文件到QQ的文件夹 // 上传文件到QQ的文件夹
async uploadFile(filePath: string, elementType: ElementType = ElementType.PIC, elementSubType: number = 0) { async uploadFile(filePath: string, elementType: ElementType = ElementType.PIC, elementSubType: number = 0) {
// napCatCore.wrapper.util. // napCatCore.wrapper.util.
const fileMd5 = await calculateFileMD5(filePath); const fileMd5 = await calculateFileMD5(filePath);
let ext: string = (await this.getFileType(filePath))?.ext as string || ''; let ext: string = (await this.getFileType(filePath))?.ext as string || '';
if (ext) { if (ext) {
ext = '.' + ext; ext = '.' + ext;
}
let fileName = `${path.basename(filePath)}`;
if (fileName.indexOf('.') === -1) {
fileName += ext;
}
const mediaPath = this.context.session.getMsgService().getRichMediaFilePathForGuild({
md5HexStr: fileMd5,
fileName: fileName,
elementType: elementType,
elementSubType,
thumbSize: 0,
needCreate: true,
downloadType: 1,
file_uuid: ''
});
await this.copyFile(filePath, mediaPath!);
const fileSize = await this.getFileSize(filePath);
return {
md5: fileMd5,
fileName,
path: mediaPath,
fileSize,
ext
};
} }
let fileName = `${path.basename(filePath)}`; async downloadMediaByUuid() {
if (fileName.indexOf('.') === -1) {
fileName += ext;
}
const mediaPath = this.context.session.getMsgService().getRichMediaFilePathForGuild({
md5HexStr: fileMd5,
fileName: fileName,
elementType: elementType,
elementSubType,
thumbSize: 0,
needCreate: true,
downloadType: 1,
file_uuid: ''
});
await this.copyFile(filePath, mediaPath!);
const fileSize = await this.getFileSize(filePath);
return {
md5: fileMd5,
fileName,
path: mediaPath,
fileSize,
ext
};
}
async downloadMediaByUuid() {
//napCatCore.session.getRichMediaService().downloadFileForFileUuid(); //napCatCore.session.getRichMediaService().downloadFileForFileUuid();
} }
async downloadMedia(msgId: string, chatType: ChatType, peerUid: string, elementId: string, thumbPath: string, sourcePath: string, timeout = 1000 * 60 * 2, force: boolean = false) { async downloadMedia(msgId: string, chatType: ChatType, peerUid: string, elementId: string, thumbPath: string, sourcePath: string, timeout = 1000 * 60 * 2, force: boolean = false) {
//logDebug('receive downloadMedia task', msgId, chatType, peerUid, elementId, thumbPath, sourcePath, timeout, force); //logDebug('receive downloadMedia task', msgId, chatType, peerUid, elementId, thumbPath, sourcePath, timeout, force);
// 用于下载收到的消息中的图片等 // 用于下载收到的消息中的图片等
if (sourcePath && fs.existsSync(sourcePath)) { if (sourcePath && fs.existsSync(sourcePath)) {
if (force) { if (force) {
try { try {
await fsPromises.unlink(sourcePath); await fsPromises.unlink(sourcePath);
} catch (e) { } catch (e) {
// //
}
} else {
return sourcePath;
}
} }
} else { const data = await this.core.eventWrapper.CallNormalEvent<
return sourcePath;
}
}
let data = await this.core.eventWrapper.CallNormalEvent<
( (
params: { params: {
fileModelId: string, fileModelId: string,
downloadSourceType: number, downloadSourceType: number,
triggerType: number, triggerType: number,
@ -103,111 +103,111 @@ export class NTQQFileApi {
filePath: string filePath: string
}) => Promise<unknown>, }) => Promise<unknown>,
(fileTransNotifyInfo: OnRichMediaDownloadCompleteParams) => void (fileTransNotifyInfo: OnRichMediaDownloadCompleteParams) => void
>( >(
'NodeIKernelMsgService/downloadRichMedia', 'NodeIKernelMsgService/downloadRichMedia',
'NodeIKernelMsgListener/onRichMediaDownloadComplete', 'NodeIKernelMsgListener/onRichMediaDownloadComplete',
1, 1,
timeout, timeout,
(arg: OnRichMediaDownloadCompleteParams) => { (arg: OnRichMediaDownloadCompleteParams) => {
if (arg.msgId === msgId) { if (arg.msgId === msgId) {
return true; return true;
}
return false;
},
{
fileModelId: '0',
downloadSourceType: 0,
triggerType: 1,
msgId: msgId,
chatType: chatType,
peerUid: peerUid,
elementId: elementId,
thumbSize: 0,
downloadType: 1,
filePath: thumbPath
}
);
let filePath = data[1].filePath;
if (filePath.startsWith('\\')) {
// log('filePath start with \\');
const downloadPath = sessionConfig.defaultFileDownloadPath;
//logDebug('downloadPath', downloadPath);
filePath = path.join(downloadPath, filePath);
// 下载路径是下载文件夹的相对路径
} }
return false; return filePath;
},
{
fileModelId: '0',
downloadSourceType: 0,
triggerType: 1,
msgId: msgId,
chatType: chatType,
peerUid: peerUid,
elementId: elementId,
thumbSize: 0,
downloadType: 1,
filePath: thumbPath
}
);
let filePath = data[1].filePath;
if (filePath.startsWith('\\')) {
// log('filePath start with \\');
const downloadPath = sessionConfig.defaultFileDownloadPath;
//logDebug('downloadPath', downloadPath);
filePath = path.join(downloadPath, filePath);
// 下载路径是下载文件夹的相对路径
} }
return filePath;
}
async getImageSize(filePath: string): Promise<ISizeCalculationResult | undefined> { async getImageSize(filePath: string): Promise<ISizeCalculationResult | undefined> {
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); resolve(dimensions);
} }
}); });
}); });
} }
async addFileCache(peer: Peer, msgId: string, msgSeq: string, senderUid: string, elemId: string, elemType: string, fileSize: string, fileName: string) { async addFileCache(peer: Peer, msgId: string, msgSeq: string, senderUid: string, elemId: string, elemType: string, fileSize: string, fileName: string) {
let GroupData; let GroupData;
let BuddyData; let BuddyData;
if (peer.chatType === ChatType.group) { if (peer.chatType === ChatType.group) {
GroupData = GroupData =
[{ [{
groupCode: peer.peerUid, groupCode: peer.peerUid,
isConf: false, isConf: false,
hasModifyConfGroupFace: true, hasModifyConfGroupFace: true,
hasModifyConfGroupName: true, hasModifyConfGroupName: true,
groupName: "NapCat.Cached", groupName: "NapCat.Cached",
remark: "NapCat.Cached" remark: "NapCat.Cached"
}]; }];
} else if (peer.chatType === ChatType.friend) { } else if (peer.chatType === ChatType.friend) {
BuddyData = [{ BuddyData = [{
category_name: 'NapCat.Cached', category_name: 'NapCat.Cached',
peerUid: peer.peerUid, peerUid: peer.peerUid,
peerUin: peer.peerUid, peerUin: peer.peerUid,
remark: 'NapCat.Cached' remark: 'NapCat.Cached'
}]; }];
} else { } else {
return undefined; return undefined;
}
return this.context.session.getSearchService().addSearchHistory({
type: 4,
contactList: [],
id: -1,
groupInfos: [],
msgs: [],
fileInfos: [
{
chatType: peer.chatType,
buddyChatInfo: BuddyData || [],
discussChatInfo: [],
groupChatInfo: GroupData || [],
dataLineChatInfo: [],
tmpChatInfo: [],
msgId: msgId,
msgSeq: msgSeq,
msgTime: Math.floor(Date.now() / 1000).toString(),
senderUid: senderUid,
senderNick: 'NapCat.Cached',
senderRemark: 'NapCat.Cached',
senderCard: 'NapCat.Cached',
elemId: elemId,
elemType: elemType,
fileSize: fileSize,
filePath: '',
fileName: fileName,
hits: [{
start: 12,
end: 14
}]
} }
]
}); return this.context.session.getSearchService().addSearchHistory({
} type: 4,
async searchfile(keys: string[]) { contactList: [],
id: -1,
groupInfos: [],
msgs: [],
fileInfos: [
{
chatType: peer.chatType,
buddyChatInfo: BuddyData || [],
discussChatInfo: [],
groupChatInfo: GroupData || [],
dataLineChatInfo: [],
tmpChatInfo: [],
msgId: msgId,
msgSeq: msgSeq,
msgTime: Math.floor(Date.now() / 1000).toString(),
senderUid: senderUid,
senderNick: 'NapCat.Cached',
senderRemark: 'NapCat.Cached',
senderCard: 'NapCat.Cached',
elemId: elemId,
elemType: elemType,
fileSize: fileSize,
filePath: '',
fileName: fileName,
hits: [{
start: 12,
end: 14
}]
}
]
});
}
async searchfile(keys: string[]) {
type EventType = NodeIKernelSearchService['searchFileWithKeywords']; type EventType = NodeIKernelSearchService['searchFileWithKeywords'];
interface OnListener { interface OnListener {
searchId: string, searchId: string,
@ -246,102 +246,102 @@ export class NTQQFileApi {
end: number end: number
}[] }[]
}[] }[]
}; }
const Event = this.core.eventWrapper.createEventFunction<EventType>('NodeIKernelSearchService/searchFileWithKeywords'); const Event = this.core.eventWrapper.createEventFunction<EventType>('NodeIKernelSearchService/searchFileWithKeywords');
let id = ''; let id = '';
const Listener = this.core.eventWrapper.RegisterListen<(params: OnListener) => void>('NodeIKernelSearchListener/onSearchFileKeywordsResult', 1, 20000, (params) => { const Listener = this.core.eventWrapper.RegisterListen<(params: OnListener) => void>('NodeIKernelSearchListener/onSearchFileKeywordsResult', 1, 20000, (params) => {
if (id !== '' && params.searchId == id) { if (id !== '' && params.searchId == id) {
return true return true;
} }
return false; return false;
}); });
id = await Event!(keys, 12); id = await Event!(keys, 12);
let [ret] = (await Listener); const [ret] = (await Listener);
return ret; return ret;
}
async getImageUrl(element: PicElement) {
if (!element) {
return '';
} }
const url: string = element.originImageUrl!; // 没有域名 async getImageUrl(element: PicElement) {
const md5HexStr = element.md5HexStr; if (!element) {
const fileMd5 = element.md5HexStr; return '';
const fileUuid = element.fileUuid;
if (url) {
let UrlParse = new URL(IMAGE_HTTP_HOST + url);//临时解析拼接
let imageAppid = UrlParse.searchParams.get('appid');
let isNewPic = imageAppid && ['1406', '1407'].includes(imageAppid);
if (isNewPic) {
let UrlRkey = UrlParse.searchParams.get('rkey');
if (UrlRkey) {
return IMAGE_HTTP_HOST_NT + url;
} }
const rkeyData = await this.rkeyManager.getRkey(); const url: string = element.originImageUrl!; // 没有域名
UrlRkey = imageAppid === '1406' ? rkeyData.private_rkey : rkeyData.group_rkey; const md5HexStr = element.md5HexStr;
return IMAGE_HTTP_HOST_NT + url + `${UrlRkey}`; const fileMd5 = element.md5HexStr;
} else { const fileUuid = element.fileUuid;
// 老的图片url不需要rkey
return IMAGE_HTTP_HOST + url; if (url) {
} const UrlParse = new URL(IMAGE_HTTP_HOST + url);//临时解析拼接
} else if (fileMd5 || md5HexStr) { const imageAppid = UrlParse.searchParams.get('appid');
// 没有url需要自己拼接 const isNewPic = imageAppid && ['1406', '1407'].includes(imageAppid);
return `${IMAGE_HTTP_HOST}/gchatpic_new/0/0-0-${(fileMd5 || md5HexStr)!.toUpperCase()}/0`; if (isNewPic) {
let UrlRkey = UrlParse.searchParams.get('rkey');
if (UrlRkey) {
return IMAGE_HTTP_HOST_NT + url;
}
const rkeyData = await this.rkeyManager.getRkey();
UrlRkey = imageAppid === '1406' ? rkeyData.private_rkey : rkeyData.group_rkey;
return IMAGE_HTTP_HOST_NT + url + `${UrlRkey}`;
} else {
// 老的图片url不需要rkey
return IMAGE_HTTP_HOST + url;
}
} else if (fileMd5 || md5HexStr) {
// 没有url需要自己拼接
return `${IMAGE_HTTP_HOST}/gchatpic_new/0/0-0-${(fileMd5 || md5HexStr)!.toUpperCase()}/0`;
}
this.context.logger.logDebug('图片url获取失败', element);
return '';
} }
this.context.logger.logDebug('图片url获取失败', element);
return '';
}
} }
export class NTQQFileCacheApi { export class NTQQFileCacheApi {
context: InstanceContext; context: InstanceContext;
core: NapCatCore; core: NapCatCore;
constructor(context: InstanceContext, core: NapCatCore) { constructor(context: InstanceContext, core: NapCatCore) {
this.context = context; this.context = context;
this.core = core; this.core = core;
} }
async setCacheSilentScan(isSilent: boolean = true) { async setCacheSilentScan(isSilent: boolean = true) {
return ''; return '';
} }
getCacheSessionPathList() { getCacheSessionPathList() {
return ''; return '';
} }
clearCache(cacheKeys: Array<string> = ['tmp', 'hotUpdate']) { clearCache(cacheKeys: Array<string> = ['tmp', 'hotUpdate']) {
// 参数未验证 // 参数未验证
return this.context.session.getStorageCleanService().clearCacheDataByKeys(cacheKeys); return this.context.session.getStorageCleanService().clearCacheDataByKeys(cacheKeys);
} }
addCacheScannedPaths(pathMap: object = {}) { addCacheScannedPaths(pathMap: object = {}) {
return this.context.session.getStorageCleanService().addCacheScanedPaths(pathMap); return this.context.session.getStorageCleanService().addCacheScanedPaths(pathMap);
} }
scanCache() { scanCache() {
//return (await this.context.session.getStorageCleanService().scanCache()).size; //return (await this.context.session.getStorageCleanService().scanCache()).size;
} }
getHotUpdateCachePath() { getHotUpdateCachePath() {
// 未实现 // 未实现
return ''; return '';
} }
getDesktopTmpPath() { getDesktopTmpPath() {
// 未实现 // 未实现
return ''; return '';
} }
getChatCacheList(type: ChatType, pageSize: number = 1000, pageIndex: number = 0) { getChatCacheList(type: ChatType, pageSize: number = 1000, pageIndex: number = 0) {
return this.context.session.getStorageCleanService().getChatCacheInfo(type, pageSize, 1, pageIndex); return this.context.session.getStorageCleanService().getChatCacheInfo(type, pageSize, 1, pageIndex);
} }
getFileCacheInfo(fileType: CacheFileType, pageSize: number = 1000, lastRecord?: CacheFileListItem) { getFileCacheInfo(fileType: CacheFileType, pageSize: number = 1000, lastRecord?: CacheFileListItem) {
const _lastRecord = lastRecord ? lastRecord : { fileType: fileType }; const _lastRecord = lastRecord ? lastRecord : { fileType: fileType };
//需要五个参数 //需要五个参数
//return napCatCore.session.getStorageCleanService().getFileCacheInfo(); //return napCatCore.session.getStorageCleanService().getFileCacheInfo();
} }
async clearChatCache(chats: ChatCacheListItemBasic[] = [], fileKeys: string[] = []) { async clearChatCache(chats: ChatCacheListItemBasic[] = [], fileKeys: string[] = []) {
return this.context.session.getStorageCleanService().clearChatCacheInfo(chats, fileKeys); return this.context.session.getStorageCleanService().clearChatCacheInfo(chats, fileKeys);
} }
} }

View File

@ -2,99 +2,99 @@ import { FriendV2, User } from '@/core/entities';
import { BuddyListReqType, InstanceContext, NapCatCore, NodeIKernelProfileService, OnBuddyChangeParams } from '@/core'; import { BuddyListReqType, InstanceContext, NapCatCore, NodeIKernelProfileService, OnBuddyChangeParams } from '@/core';
import { LimitedHashTable } from '@/common/utils/MessageUnique'; import { LimitedHashTable } from '@/common/utils/MessageUnique';
export class NTQQFriendApi { export class NTQQFriendApi {
context: InstanceContext; context: InstanceContext;
core: NapCatCore; core: NapCatCore;
constructor(context: InstanceContext, core: NapCatCore) { constructor(context: InstanceContext, core: NapCatCore) {
this.context = context; this.context = context;
this.core = core; this.core = core;
} }
async getBuddyV2(refresh = false): Promise<FriendV2[]> { async getBuddyV2(refresh = false): Promise<FriendV2[]> {
let uids: string[] = []; 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)); uids.push(...buddyListV2.data.flatMap(item => item.buddyUids));
const data = await this.core.eventWrapper.callNoListenerEvent<NodeIKernelProfileService['getCoreAndBaseInfo']>( const data = await this.core.eventWrapper.callNoListenerEvent<NodeIKernelProfileService['getCoreAndBaseInfo']>(
'NodeIKernelProfileService/getCoreAndBaseInfo', 5000, 'nodeStore', uids 'NodeIKernelProfileService/getCoreAndBaseInfo', 5000, 'nodeStore', uids
); );
return Array.from(data.values()); return Array.from(data.values());
} }
async getBuddyIdMapCache(refresh = false): Promise<LimitedHashTable<string, string>> { async getBuddyIdMapCache(refresh = false): Promise<LimitedHashTable<string, string>> {
return await this.getBuddyIdMap(refresh); return await this.getBuddyIdMap(refresh);
} }
async getBuddyIdMap(refresh = false): Promise<LimitedHashTable<string, string>> { async getBuddyIdMap(refresh = false): Promise<LimitedHashTable<string, string>> {
let uids: string[] = []; const uids: string[] = [];
let 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 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)); uids.push(...buddyListV2.data.flatMap(item => item.buddyUids));
const data = await this.core.eventWrapper.callNoListenerEvent<NodeIKernelProfileService['getCoreAndBaseInfo']>( const data = await this.core.eventWrapper.callNoListenerEvent<NodeIKernelProfileService['getCoreAndBaseInfo']>(
'NodeIKernelProfileService/getCoreAndBaseInfo', 5000, 'nodeStore', uids 'NodeIKernelProfileService/getCoreAndBaseInfo', 5000, 'nodeStore', uids
); );
data.forEach((value, key) => { data.forEach((value, key) => {
retMap.set(value.uin!, value.uid!); retMap.set(value.uin!, value.uid!);
});
//console.log('getBuddyIdMap', retMap.getValue);
return retMap;
}
async getBuddyV2ExWithCate(refresh = false) {
let uids: string[] = [];
let categoryMap: Map<string, any> = new Map();
const buddyService = this.context.session.getBuddyService();
const buddyListV2 = refresh ? (await buddyService.getBuddyListV2('0', BuddyListReqType.KNOMAL)).data : (await buddyService.getBuddyListV2('0', BuddyListReqType.KNOMAL)).data;
uids.push(
...buddyListV2.flatMap(item => {
item.buddyUids.forEach(uid => {
categoryMap.set(uid, { categoryId: item.categoryId, categroyName: item.categroyName });
}); });
return item.buddyUids //console.log('getBuddyIdMap', retMap.getValue);
})); return retMap;
const data = await this.core.eventWrapper.callNoListenerEvent<NodeIKernelProfileService['getCoreAndBaseInfo']>( }
'NodeIKernelProfileService/getCoreAndBaseInfo', 5000, 'nodeStore', uids async getBuddyV2ExWithCate(refresh = false) {
); const uids: string[] = [];
return Array.from(data).map(([key, value]) => { const categoryMap: Map<string, any> = new Map();
const category = categoryMap.get(key); const buddyService = this.context.session.getBuddyService();
return category ? { ...value, categoryId: category.categoryId, categroyName: category.categroyName } : value; const buddyListV2 = refresh ? (await buddyService.getBuddyListV2('0', BuddyListReqType.KNOMAL)).data : (await buddyService.getBuddyListV2('0', BuddyListReqType.KNOMAL)).data;
}); uids.push(
} ...buddyListV2.flatMap(item => {
async isBuddy(uid: string) { item.buddyUids.forEach(uid => {
return this.context.session.getBuddyService().isBuddy(uid); categoryMap.set(uid, { categoryId: item.categoryId, categroyName: item.categroyName });
} });
/** return item.buddyUids;
}));
const data = await this.core.eventWrapper.callNoListenerEvent<NodeIKernelProfileService['getCoreAndBaseInfo']>(
'NodeIKernelProfileService/getCoreAndBaseInfo', 5000, 'nodeStore', uids
);
return Array.from(data).map(([key, value]) => {
const category = categoryMap.get(key);
return category ? { ...value, categoryId: category.categoryId, categroyName: category.categroyName } : value;
});
}
async isBuddy(uid: string) {
return this.context.session.getBuddyService().isBuddy(uid);
}
/**
* @deprecated * @deprecated
* @param forced * @param forced
* @returns * @returns
*/ */
async getFriends(forced = false): Promise<User[]> { async getFriends(forced = false): Promise<User[]> {
let [_retData, _BuddyArg] = await this.core.eventWrapper.CallNormalEvent const [_retData, _BuddyArg] = await this.core.eventWrapper.CallNormalEvent
<(force: boolean) => Promise<any>, (arg: OnBuddyChangeParams) => void> <(force: boolean) => Promise<any>, (arg: OnBuddyChangeParams) => void>
( (
'NodeIKernelBuddyService/getBuddyList', 'NodeIKernelBuddyService/getBuddyList',
'NodeIKernelBuddyListener/onBuddyListChange', 'NodeIKernelBuddyListener/onBuddyListChange',
1, 1,
5000, 5000,
() => true, () => true,
forced forced
); );
const friends: User[] = []; const friends: User[] = [];
for (const categoryItem of _BuddyArg) { for (const categoryItem of _BuddyArg) {
for (const friend of categoryItem.buddyList) { for (const friend of categoryItem.buddyList) {
friends.push(friend); friends.push(friend);
} }
}
return friends;
} }
return friends;
}
async handleFriendRequest(flag: string, accept: boolean) { async handleFriendRequest(flag: string, accept: boolean) {
let data = flag.split('|'); const data = flag.split('|');
if (data.length < 2) { if (data.length < 2) {
return; return;
}
const friendUid = data[0];
const reqTime = data[1];
this.context.session.getBuddyService()?.approvalFriendRequest({
friendUid: friendUid,
reqTime: reqTime,
accept
});
} }
let friendUid = data[0];
let reqTime = data[1];
this.context.session.getBuddyService()?.approvalFriendRequest({
friendUid: friendUid,
reqTime: reqTime,
accept
});
}
} }

View File

@ -3,33 +3,33 @@ import { GeneralCallResult, InstanceContext, NapCatCore, NodeIKernelGroupService
import { runAllWithTimeout } from '@/common/utils/helper'; import { runAllWithTimeout } from '@/common/utils/helper';
import { NodeIKernelGroupListener } from '../listeners'; import { NodeIKernelGroupListener } from '../listeners';
export class NTQQGroupApi { export class NTQQGroupApi {
context: InstanceContext; context: InstanceContext;
core: NapCatCore; core: NapCatCore;
constructor(context: InstanceContext, core: NapCatCore) { constructor(context: InstanceContext, core: NapCatCore) {
this.context = context; this.context = context;
this.core = core; this.core = core;
} }
async 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);
} }
async getGroups(forced = false) { async getGroups(forced = false) {
type ListenerType = NodeIKernelGroupListener['onGroupListUpdate']; type ListenerType = NodeIKernelGroupListener['onGroupListUpdate'];
let [_retData, _updateType, groupList] = await this.core.eventWrapper.CallNormalEvent const [_retData, _updateType, groupList] = await this.core.eventWrapper.CallNormalEvent
<(force: boolean) => Promise<any>, ListenerType> <(force: boolean) => Promise<any>, ListenerType>
( (
'NodeIKernelGroupService/getGroupList', 'NodeIKernelGroupService/getGroupList',
'NodeIKernelGroupListener/onGroupListUpdate', 'NodeIKernelGroupListener/onGroupListUpdate',
1, 1,
5000, 5000,
(updateType) => true, (updateType) => true,
forced forced
); );
return groupList; return groupList;
} }
async getGroupMemberLastestSendTimeCache(GroupCode: string) { async getGroupMemberLastestSendTimeCache(GroupCode: string) {
return this.getGroupMemberLastestSendTime(GroupCode); return this.getGroupMemberLastestSendTime(GroupCode);
} }
/** /**
* QQ自带数据库获取群成员最后发言时间( ) * QQ自带数据库获取群成员最后发言时间( )
* @param GroupCode * @param GroupCode
* @returns Map<string, string> key: uin value: sendTime * @returns Map<string, string> key: uin value: sendTime
@ -39,128 +39,128 @@ export class NTQQGroupApi {
* console.log(uin, sendTime); * console.log(uin, sendTime);
* } * }
*/ */
async getGroupMemberLastestSendTime(GroupCode: string) { async getGroupMemberLastestSendTime(GroupCode: string) {
const getdata = async (uid: string) => { const getdata = async (uid: string) => {
let NTRet = await this.getLastestMsgByUids(GroupCode, [uid]); const NTRet = await this.getLastestMsgByUids(GroupCode, [uid]);
if (NTRet.result != 0 && NTRet.msgList.length < 1) { if (NTRet.result != 0 && NTRet.msgList.length < 1) {
return undefined; return undefined;
} }
return { sendUin: NTRet.msgList[0].senderUin, sendTime: NTRet.msgList[0].msgTime } return { sendUin: NTRet.msgList[0].senderUin, sendTime: NTRet.msgList[0].msgTime };
} };
let currentGroupMembers = groupMembers.get(GroupCode); const currentGroupMembers = groupMembers.get(GroupCode);
let PromiseData: Promise<({ const PromiseData: Promise<({
sendUin: string; sendUin: string;
sendTime: string; sendTime: string;
} | undefined)>[] = []; } | undefined)>[] = [];
let ret: Map<string, string> = new Map(); const ret: Map<string, string> = new Map();
if (!currentGroupMembers) { if (!currentGroupMembers) {
return ret; return ret;
}
for (const member of currentGroupMembers.values()) {
PromiseData.push(getdata(member.uid).catch(() => undefined));
}
const allRet = await runAllWithTimeout(PromiseData, 2500);
for (const PromiseDo of allRet) {
if (PromiseDo) {
ret.set(PromiseDo.sendUin, PromiseDo.sendTime);
}
}
return ret;
} }
for (let member of currentGroupMembers.values()) { async getLastestMsgByUids(GroupCode: string, uids: string[]) {
PromiseData.push(getdata(member.uid).catch(() => undefined)); const ret = await this.context.session.getMsgService().queryMsgsWithFilterEx('0', '0', '0', {
chatInfo: {
peerUid: GroupCode,
chatType: ChatType.group,
},
filterMsgType: [],
filterSendersUid: uids,
filterMsgToTime: '0',
filterMsgFromTime: '0',
isReverseOrder: false,
isIncludeCurrent: true,
pageLimit: 1,
});
return ret;
} }
let allRet = await runAllWithTimeout(PromiseData, 2500); async getGroupMemberAll(GroupCode: string, forced = false) {
for (let PromiseDo of allRet) { return this.context.session.getGroupService().getAllMemberList(GroupCode, forced);
if (PromiseDo) {
ret.set(PromiseDo.sendUin, PromiseDo.sendTime);
}
} }
return ret; async getLastestMsg(GroupCode: string, uins: string[]) {
} const uids: Array<string> = [];
async getLastestMsgByUids(GroupCode: string, uids: string[]) { for (const uin of uins) {
let ret = await this.context.session.getMsgService().queryMsgsWithFilterEx('0', '0', '0', { const uid = await this.core.getApiContext().UserApi.getUidByUin(uin);
chatInfo: { if (uid) {
peerUid: GroupCode, uids.push(uid);
chatType: ChatType.group, }
}, }
filterMsgType: [], const ret = await this.context.session.getMsgService().queryMsgsWithFilterEx('0', '0', '0', {
filterSendersUid: uids, chatInfo: {
filterMsgToTime: '0', peerUid: GroupCode,
filterMsgFromTime: '0', chatType: ChatType.group,
isReverseOrder: false, },
isIncludeCurrent: true, filterMsgType: [],
pageLimit: 1, filterSendersUid: uids,
}); filterMsgToTime: '0',
return ret; filterMsgFromTime: '0',
} isReverseOrder: false,
async getGroupMemberAll(GroupCode: string, forced = false) { isIncludeCurrent: true,
return this.context.session.getGroupService().getAllMemberList(GroupCode, forced); pageLimit: 1,
} });
async getLastestMsg(GroupCode: string, uins: string[]) { return ret;
let uids: Array<string> = [];
for (let uin of uins) {
let uid = await this.core.getApiContext().UserApi.getUidByUin(uin)
if (uid) {
uids.push(uid);
}
} }
let ret = await this.context.session.getMsgService().queryMsgsWithFilterEx('0', '0', '0', { async getGroupRecommendContactArkJson(GroupCode: string) {
chatInfo: { return this.context.session.getGroupService().getGroupRecommendContactArkJson(GroupCode);
peerUid: GroupCode, }
chatType: ChatType.group, async CreatGroupFileFolder(groupCode: string, folderName: string) {
}, return this.context.session.getRichMediaService().createGroupFolder(groupCode, folderName);
filterMsgType: [], }
filterSendersUid: uids, async DelGroupFile(groupCode: string, files: string[]) {
filterMsgToTime: '0', return this.context.session.getRichMediaService().deleteGroupFile(groupCode, [102], files);
filterMsgFromTime: '0', }
isReverseOrder: false, async DelGroupFileFolder(groupCode: string, folderId: string) {
isIncludeCurrent: true, return this.context.session.getRichMediaService().deleteGroupFolder(groupCode, folderId);
pageLimit: 1, }
}); async addGroupEssence(GroupCode: string, msgId: string) {
return ret;
}
async getGroupRecommendContactArkJson(GroupCode: string) {
return this.context.session.getGroupService().getGroupRecommendContactArkJson(GroupCode);
}
async CreatGroupFileFolder(groupCode: string, folderName: string) {
return this.context.session.getRichMediaService().createGroupFolder(groupCode, folderName);
}
async DelGroupFile(groupCode: string, files: string[]) {
return this.context.session.getRichMediaService().deleteGroupFile(groupCode, [102], files);
}
async DelGroupFileFolder(groupCode: string, folderId: string) {
return this.context.session.getRichMediaService().deleteGroupFolder(groupCode, folderId);
}
async addGroupEssence(GroupCode: string, msgId: string) {
// 代码没测过 // 代码没测过
// 需要 ob11msgid->msgId + (peer) -> msgSeq + msgRandom // 需要 ob11msgid->msgId + (peer) -> msgSeq + msgRandom
let MsgData = await this.context.session.getMsgService().getMsgsIncludeSelf({ chatType: 2, guildId: '', peerUid: GroupCode }, msgId, 1, false); const MsgData = await this.context.session.getMsgService().getMsgsIncludeSelf({ chatType: 2, guildId: '', peerUid: GroupCode }, msgId, 1, false);
let param = { const param = {
groupCode: GroupCode, groupCode: GroupCode,
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); -> 组出参数 // GetMsgByShoretID(ShoretID); -> MsgService.getMsgs(Peer,MsgId,1,false); -> 组出参数
return this.context.session.getGroupService().addGroupEssence(param); return this.context.session.getGroupService().addGroupEssence(param);
} }
async removeGroupEssence(GroupCode: string, msgId: string) { async removeGroupEssence(GroupCode: string, msgId: string) {
// 代码没测过 // 代码没测过
// 需要 ob11msgid->msgId + (peer) -> msgSeq + msgRandom // 需要 ob11msgid->msgId + (peer) -> msgSeq + msgRandom
let MsgData = await this.context.session.getMsgService().getMsgsIncludeSelf({ chatType: 2, guildId: '', peerUid: GroupCode }, msgId, 1, false); const MsgData = await this.context.session.getMsgService().getMsgsIncludeSelf({ chatType: 2, guildId: '', peerUid: GroupCode }, msgId, 1, false);
let param = { const param = {
groupCode: GroupCode, groupCode: GroupCode,
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); -> 组出参数 // GetMsgByShoretID(ShoretID); -> MsgService.getMsgs(Peer,MsgId,1,false); -> 组出参数
return this.context.session.getGroupService().removeGroupEssence(param); return this.context.session.getGroupService().removeGroupEssence(param);
} }
async getSingleScreenNotifies(num: number) { async getSingleScreenNotifies(num: number) {
let [_retData, _doubt, _seq, notifies] = await this.core.eventWrapper.CallNormalEvent const [_retData, _doubt, _seq, notifies] = await this.core.eventWrapper.CallNormalEvent
<(arg1: boolean, arg2: string, arg3: number) => Promise<any>, (doubt: boolean, seq: string, notifies: GroupNotify[]) => void> <(arg1: boolean, arg2: string, arg3: number) => Promise<any>, (doubt: boolean, seq: string, notifies: GroupNotify[]) => void>
( (
'NodeIKernelGroupService/getSingleScreenNotifies', 'NodeIKernelGroupService/getSingleScreenNotifies',
'NodeIKernelGroupListener/onGroupSingleScreenNotifies', 'NodeIKernelGroupListener/onGroupSingleScreenNotifies',
1, 1,
5000, 5000,
() => true, () => true,
false, false,
'', '',
num num
); );
return notifies; return notifies;
} }
async getGroupMemberV2(GroupCode: string, uid: string, forced = false) { async getGroupMemberV2(GroupCode: string, uid: string, forced = false) {
type ListenerType = NodeIKernelGroupListener['onMemberInfoChange']; type ListenerType = NodeIKernelGroupListener['onMemberInfoChange'];
type EventType = NodeIKernelGroupService['getMemberInfo']; type EventType = NodeIKernelGroupService['getMemberInfo'];
// NTEventDispatch.CreatListenerFunction('NodeIKernelGroupListener/onGroupMemberInfoUpdate', // NTEventDispatch.CreatListenerFunction('NodeIKernelGroupListener/onGroupMemberInfoUpdate',
@ -168,27 +168,27 @@ export class NTQQGroupApi {
const [ret, _groupCode, _changeType, _members] = await this.core.eventWrapper.CallNormalEvent const [ret, _groupCode, _changeType, _members] = await this.core.eventWrapper.CallNormalEvent
<EventType, ListenerType> <EventType, ListenerType>
( (
'NodeIKernelGroupService/getMemberInfo', 'NodeIKernelGroupService/getMemberInfo',
'NodeIKernelGroupListener/onMemberInfoChange', 'NodeIKernelGroupListener/onMemberInfoChange',
1, 1,
5000, 5000,
(groupCode: string, changeType: number, members: Map<string, GroupMember>) => { (groupCode: string, changeType: number, members: Map<string, GroupMember>) => {
return groupCode == GroupCode && members.has(uid); return groupCode == GroupCode && members.has(uid);
}, },
GroupCode, [uid], forced GroupCode, [uid], forced
); );
return _members.get(uid); return _members.get(uid);
}
async getGroupMembers(groupQQ: string, num = 3000): Promise<Map<string, GroupMember>> {
const groupService = this.context.session.getGroupService();
const sceneId = groupService.createMemberListScene(groupQQ, 'groupMemberList_MainWindow');
const result = await groupService.getNextMemberList(sceneId!, undefined, num);
if (result.errCode !== 0) {
throw ('获取群成员列表出错,' + result.errMsg);
} }
async getGroupMembers(groupQQ: string, num = 3000): Promise<Map<string, GroupMember>> {
const groupService = this.context.session.getGroupService();
const sceneId = groupService.createMemberListScene(groupQQ, 'groupMemberList_MainWindow');
const result = await groupService.getNextMemberList(sceneId!, undefined, num);
if (result.errCode !== 0) {
throw ('获取群成员列表出错,' + result.errMsg);
}
//logDebug(`获取群(${groupQQ})成员列表结果:`, `finish: ${result.result.finish}`); //, Array.from(result.result.infos.values())); //logDebug(`获取群(${groupQQ})成员列表结果:`, `finish: ${result.result.finish}`); //, Array.from(result.result.infos.values()));
return result.result.infos; return result.result.infos;
/* /*
console.log(sceneId); console.log(sceneId);
const result = await napCatCore.getGroupService().getNextMemberList(sceneId, num); const result = await napCatCore.getGroupService().getNextMemberList(sceneId, num);
@ -196,134 +196,134 @@ export class NTQQGroupApi {
return result; return result;
*/ */
} }
async getGroupNotifies() { async getGroupNotifies() {
// 获取管理员变更 // 获取管理员变更
// 加群通知,退出通知,需要管理员权限 // 加群通知,退出通知,需要管理员权限
} }
async GetGroupFileCount(Gids: Array<string>) { async GetGroupFileCount(Gids: Array<string>) {
return this.context.session.getRichMediaService().batchGetGroupFileCount(Gids); return this.context.session.getRichMediaService().batchGetGroupFileCount(Gids);
} }
async getGroupIgnoreNotifies() { async getGroupIgnoreNotifies() {
} }
async getArkJsonGroupShare(GroupCode: string) { async getArkJsonGroupShare(GroupCode: string) {
let ret = await this.core.eventWrapper.callNoListenerEvent const ret = await this.core.eventWrapper.callNoListenerEvent
<(GroupId: string) => Promise<GeneralCallResult & { arkJson: string }>>( <(GroupId: string) => Promise<GeneralCallResult & { arkJson: string }>>(
'NodeIKernelGroupService/getGroupRecommendContactArkJson', 'NodeIKernelGroupService/getGroupRecommendContactArkJson',
5000, 5000,
GroupCode GroupCode
); );
return ret.arkJson; return ret.arkJson;
} }
//需要异常处理 //需要异常处理
async uploadGroupBulletinPic(GroupCode: string, imageurl: string) { async uploadGroupBulletinPic(GroupCode: string, imageurl: string) {
const _Pskey = (await this.core.getApiContext().UserApi.getPSkey(['qun.qq.com'])).domainPskeyMap.get('qun.qq.com')!; const _Pskey = (await this.core.getApiContext().UserApi.getPSkey(['qun.qq.com'])).domainPskeyMap.get('qun.qq.com')!;
return this.context.session.getGroupService().uploadGroupBulletinPic(GroupCode, _Pskey, imageurl); return this.context.session.getGroupService().uploadGroupBulletinPic(GroupCode, _Pskey, imageurl);
} }
async handleGroupRequest(flag: string, operateType: GroupRequestOperateTypes, reason?: string) { async handleGroupRequest(flag: string, operateType: GroupRequestOperateTypes, reason?: string) {
let flagitem = flag.split('|'); const flagitem = flag.split('|');
let groupCode = flagitem[0]; const groupCode = flagitem[0];
let seq = flagitem[1]; const seq = flagitem[1];
let type = parseInt(flagitem[2]); const type = parseInt(flagitem[2]);
return this.context.session.getGroupService().operateSysNotify( return this.context.session.getGroupService().operateSysNotify(
false, false,
{ {
'operateType': operateType, // 2 拒绝 'operateType': operateType, // 2 拒绝
'targetMsg': { 'targetMsg': {
'seq': seq, // 通知序列号 'seq': seq, // 通知序列号
'type': type, 'type': type,
'groupCode': groupCode, 'groupCode': groupCode,
'postscript': reason || ' ' // 仅传空值可能导致处理失败,故默认给个空格 'postscript': reason || ' ' // 仅传空值可能导致处理失败,故默认给个空格
} }
}); });
} }
async quitGroup(groupQQ: string) { async quitGroup(groupQQ: string) {
return this.context.session.getGroupService().quitGroup(groupQQ); return this.context.session.getGroupService().quitGroup(groupQQ);
} }
async kickMember(groupQQ: string, kickUids: string[], refuseForever: boolean = false, kickReason: string = '') { async kickMember(groupQQ: string, kickUids: string[], refuseForever: boolean = false, kickReason: string = '') {
return this.context.session.getGroupService().kickMember(groupQQ, kickUids, refuseForever, kickReason); return this.context.session.getGroupService().kickMember(groupQQ, kickUids, refuseForever, kickReason);
} }
async banMember(groupQQ: string, memList: Array<{ uid: string, timeStamp: number }>) { async banMember(groupQQ: string, memList: Array<{ uid: string, timeStamp: number }>) {
// timeStamp为秒数, 0为解除禁言 // timeStamp为秒数, 0为解除禁言
return this.context.session.getGroupService().setMemberShutUp(groupQQ, memList); return this.context.session.getGroupService().setMemberShutUp(groupQQ, memList);
} }
async banGroup(groupQQ: string, shutUp: boolean) { async banGroup(groupQQ: string, shutUp: boolean) {
return this.context.session.getGroupService().setGroupShutUp(groupQQ, shutUp); return this.context.session.getGroupService().setGroupShutUp(groupQQ, shutUp);
} }
async setMemberCard(groupQQ: string, memberUid: string, cardName: string) { async setMemberCard(groupQQ: string, memberUid: string, cardName: string) {
return this.context.session.getGroupService().modifyMemberCardName(groupQQ, memberUid, cardName); return this.context.session.getGroupService().modifyMemberCardName(groupQQ, memberUid, cardName);
} }
async setMemberRole(groupQQ: string, memberUid: string, role: GroupMemberRole) { async setMemberRole(groupQQ: string, memberUid: string, role: GroupMemberRole) {
return this.context.session.getGroupService().modifyMemberRole(groupQQ, memberUid, role); return this.context.session.getGroupService().modifyMemberRole(groupQQ, memberUid, role);
} }
async setGroupName(groupQQ: string, groupName: string) { async setGroupName(groupQQ: string, groupName: string) {
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 setGroupTitle(groupQQ: string, uid: string, title: string) {
} }
async publishGroupBulletin(groupQQ: string, content: string, picInfo: { id: string, width: number, height: number } | undefined = undefined, pinned: number = 0, confirmRequired: number = 0,) { async publishGroupBulletin(groupQQ: string, content: string, picInfo: { id: string, width: number, height: number } | undefined = undefined, pinned: number = 0, confirmRequired: number = 0,) {
const _Pskey = (await this.core.getApiContext().UserApi.getPSkey(['qun.qq.com'])).domainPskeyMap.get('qun.qq.com'); const _Pskey = (await this.core.getApiContext().UserApi.getPSkey(['qun.qq.com'])).domainPskeyMap.get('qun.qq.com');
//text是content内容url编码 //text是content内容url编码
let data = { const data = {
text: encodeURI(content), text: encodeURI(content),
picInfo: picInfo, picInfo: picInfo,
oldFeedsId: '', oldFeedsId: '',
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) {
this.context.session.getGroupService().getGroupRemainAtTimes(GroupCode); this.context.session.getGroupService().getGroupRemainAtTimes(GroupCode);
} }
async getMemberExtInfo(groupCode: string, uin: string) { async getMemberExtInfo(groupCode: string, uin: string) {
// 仅NTQQ 9.9.11 24568测试 容易炸开谨慎使用 // 仅NTQQ 9.9.11 24568测试 容易炸开谨慎使用
return this.context.session.getGroupService().getMemberExtInfo( return this.context.session.getGroupService().getMemberExtInfo(
{ {
groupCode: groupCode, groupCode: groupCode,
sourceType: MemberExtSourceType.TITLETYPE, sourceType: MemberExtSourceType.TITLETYPE,
beginUin: '0', beginUin: '0',
dataTime: '0', dataTime: '0',
uinList: [uin], uinList: [uin],
uinNum: '', uinNum: '',
seq: '', seq: '',
groupType: '', groupType: '',
richCardNameVer: '', richCardNameVer: '',
memberExtFilter: { memberExtFilter: {
memberLevelInfoUin: 1, memberLevelInfoUin: 1,
memberLevelInfoPoint: 1, memberLevelInfoPoint: 1,
memberLevelInfoActiveDay: 1, memberLevelInfoActiveDay: 1,
memberLevelInfoLevel: 1, memberLevelInfoLevel: 1,
memberLevelInfoName: 1, memberLevelInfoName: 1,
levelName: 1, levelName: 1,
dataTime: 1, dataTime: 1,
userShowFlag: 1, userShowFlag: 1,
sysShowFlag: 1, sysShowFlag: 1,
timeToUpdate: 1, timeToUpdate: 1,
nickName: 1, nickName: 1,
specialTitle: 1, specialTitle: 1,
levelNameNew: 1, levelNameNew: 1,
userShowFlagNew: 1, userShowFlagNew: 1,
msgNeedField: 1, msgNeedField: 1,
cmdUinFlagExt3Grocery: 1, cmdUinFlagExt3Grocery: 1,
memberIcon: 1, memberIcon: 1,
memberInfoSeq: 1 memberInfoSeq: 1
} }
} }
); );
} }
} }

View File

@ -4,256 +4,256 @@ import { onGroupFileInfoUpdateParamType } from '@/core/listeners';
import { GeneralCallResult } from '@/core/services/common'; import { GeneralCallResult } from '@/core/services/common';
export class NTQQMsgApi { export class NTQQMsgApi {
context: InstanceContext; context: InstanceContext;
core: NapCatCore; core: NapCatCore;
constructor(context: InstanceContext, core: NapCatCore) { constructor(context: InstanceContext, core: NapCatCore) {
this.context = context; this.context = context;
this.core = core; this.core = core;
} }
async FetchLongMsg(peer: Peer, msgId: string) { async FetchLongMsg(peer: Peer, msgId: string) {
return this.context.session.getMsgService().fetchLongMsg(peer, msgId); return this.context.session.getMsgService().fetchLongMsg(peer, msgId);
} }
async getMsgEmojiLikesList(peer: Peer, msgSeq: string, emojiId: string, emojiType: string, count: number = 20) { async getMsgEmojiLikesList(peer: Peer, msgSeq: string, emojiId: string, emojiType: string, count: number = 20) {
//console.log(peer, msgSeq, emojiId, emojiType, count); //console.log(peer, msgSeq, emojiId, emojiType, count);
//注意此处emojiType 可选值一般为1-2 2好像是unicode表情dec值 大部分情况 Taged M likiowa //注意此处emojiType 可选值一般为1-2 2好像是unicode表情dec值 大部分情况 Taged M likiowa
return this.context.session.getMsgService().getMsgEmojiLikesList(peer, msgSeq, emojiId, emojiType, "", false, 20) return this.context.session.getMsgService().getMsgEmojiLikesList(peer, msgSeq, emojiId, emojiType, "", false, 20);
} }
// napCatCore: NapCatCore | null = null; // napCatCore: NapCatCore | null = null;
// enum BaseEmojiType { // enum BaseEmojiType {
// NORMAL_EMOJI, // NORMAL_EMOJI,
// SUPER_EMOJI, // SUPER_EMOJI,
// RANDOM_SUPER_EMOJI, // RANDOM_SUPER_EMOJI,
// CHAIN_SUPER_EMOJI, // CHAIN_SUPER_EMOJI,
// EMOJI_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
// 其实以官方文档为准是最好的https://bot.q.qq.com/wiki/develop/api-v2/openapi/emoji/model.html#EmojiType // 其实以官方文档为准是最好的https://bot.q.qq.com/wiki/develop/api-v2/openapi/emoji/model.html#EmojiType
emojiId = emojiId.toString(); emojiId = emojiId.toString();
return this.context.session.getMsgService().setMsgEmojiLikes(peer, msgSeq, emojiId, emojiId.length > 3 ? '2' : '1', set); return this.context.session.getMsgService().setMsgEmojiLikes(peer, msgSeq, emojiId, emojiId.length > 3 ? '2' : '1', set);
} }
async getMultiMsg(peer: Peer, rootMsgId: string, parentMsgId: string): Promise<GeneralCallResult & { async getMultiMsg(peer: Peer, rootMsgId: string, parentMsgId: string): Promise<GeneralCallResult & {
msgList: RawMessage[] msgList: RawMessage[]
} | undefined> { } | undefined> {
return this.context.session.getMsgService().getMultiMsg(peer, rootMsgId, parentMsgId); return this.context.session.getMsgService().getMultiMsg(peer, rootMsgId, parentMsgId);
} }
async ForwardMsg(peer: Peer, msgIds: string[]) { async ForwardMsg(peer: Peer, msgIds: string[]) {
return this.context.session.getMsgService().forwardMsg(msgIds, peer, [peer], new Map()); return this.context.session.getMsgService().forwardMsg(msgIds, peer, [peer], new Map());
} }
async getLastestMsgByUids(peer: Peer, count: number = 20, isReverseOrder: boolean = false) { async getLastestMsgByUids(peer: Peer, count: number = 20, isReverseOrder: boolean = false) {
let ret = await this.context.session.getMsgService().queryMsgsWithFilterEx('0', '0', '0', { const ret = await this.context.session.getMsgService().queryMsgsWithFilterEx('0', '0', '0', {
chatInfo: peer, chatInfo: peer,
filterMsgType: [], filterMsgType: [],
filterSendersUid: [], filterSendersUid: [],
filterMsgToTime: '0', filterMsgToTime: '0',
filterMsgFromTime: '0', filterMsgFromTime: '0',
isReverseOrder: isReverseOrder,//此参数有点离谱 注意不是本次查询的排序 而是全部消历史信息的排序 默认false 从新消息拉取到旧消息 isReverseOrder: isReverseOrder,//此参数有点离谱 注意不是本次查询的排序 而是全部消历史信息的排序 默认false 从新消息拉取到旧消息
isIncludeCurrent: true, isIncludeCurrent: true,
pageLimit: count, pageLimit: count,
}); });
return ret; return ret;
} }
async getMsgsByMsgId(peer: Peer | undefined, msgIds: string[] | undefined) { async getMsgsByMsgId(peer: Peer | undefined, msgIds: string[] | undefined) {
if (!peer) throw new Error('peer is not allowed'); if (!peer) throw new Error('peer is not allowed');
if (!msgIds) throw new Error('msgIds is not allowed'); if (!msgIds) throw new Error('msgIds is not allowed');
//Mlikiowa 参数不合规会导致NC异常崩溃 原因是TX未对进入参数判断 对应Android标记@NotNull AndroidJADX分析可得 //Mlikiowa 参数不合规会导致NC异常崩溃 原因是TX未对进入参数判断 对应Android标记@NotNull AndroidJADX分析可得
return await this.context.session.getMsgService().getMsgsByMsgId(peer, msgIds); return await this.context.session.getMsgService().getMsgsByMsgId(peer, msgIds);
} }
async getSingleMsg(peer: Peer, seq: string) { async getSingleMsg(peer: Peer, seq: string) {
return await this.context.session.getMsgService().getSingleMsg(peer, seq); return await this.context.session.getMsgService().getSingleMsg(peer, seq);
} }
async fetchFavEmojiList(num: number) { async fetchFavEmojiList(num: number) {
return this.context.session.getMsgService().fetchFavEmojiList("", num, true, true) return this.context.session.getMsgService().fetchFavEmojiList("", num, true, true);
} }
async queryMsgsWithFilterExWithSeq(peer: Peer, msgSeq: string) { async queryMsgsWithFilterExWithSeq(peer: Peer, msgSeq: string) {
let ret = await this.context.session.getMsgService().queryMsgsWithFilterEx('0', '0', msgSeq, { const ret = await this.context.session.getMsgService().queryMsgsWithFilterEx('0', '0', msgSeq, {
chatInfo: peer,//此处为Peer 为关键查询参数 没有啥也没有 by mlik iowa chatInfo: peer,//此处为Peer 为关键查询参数 没有啥也没有 by mlik iowa
filterMsgType: [], filterMsgType: [],
filterSendersUid: [], filterSendersUid: [],
filterMsgToTime: '0', filterMsgToTime: '0',
filterMsgFromTime: '0', filterMsgFromTime: '0',
isReverseOrder: false, isReverseOrder: false,
isIncludeCurrent: true, isIncludeCurrent: true,
pageLimit: 1, pageLimit: 1,
}); });
return ret; return ret;
} }
async getMsgsBySeqAndCount(peer: Peer, seq: string, count: number, desc: boolean, z: boolean) { async getMsgsBySeqAndCount(peer: Peer, seq: string, count: number, desc: boolean, z: boolean) {
return await this.context.session.getMsgService().getMsgsBySeqAndCount(peer, seq, count, desc, z); return await this.context.session.getMsgService().getMsgsBySeqAndCount(peer, seq, count, desc, z);
} }
async setMsgRead(peer: Peer) { async setMsgRead(peer: Peer) {
return this.context.session.getMsgService().setMsgRead(peer); return this.context.session.getMsgService().setMsgRead(peer);
} }
async getGroupFileList(GroupCode: string, params: GetFileListParam) { async getGroupFileList(GroupCode: string, params: GetFileListParam) {
let data = await this.core.eventWrapper.CallNormalEvent< const data = await this.core.eventWrapper.CallNormalEvent<
(GroupCode: string, params: GetFileListParam) => Promise<unknown>, (GroupCode: string, params: GetFileListParam) => Promise<unknown>,
(groupFileListResult: onGroupFileInfoUpdateParamType) => void (groupFileListResult: onGroupFileInfoUpdateParamType) => void
>( >(
'NodeIKernelRichMediaService/getGroupFileList', 'NodeIKernelRichMediaService/getGroupFileList',
'NodeIKernelMsgListener/onGroupFileInfoUpdate', 'NodeIKernelMsgListener/onGroupFileInfoUpdate',
1, 1,
5000, 5000,
(groupFileListResult: onGroupFileInfoUpdateParamType) => { (groupFileListResult: onGroupFileInfoUpdateParamType) => {
//Developer Mlikiowa Todo: 此处有问题 无法判断是否成功 //Developer Mlikiowa Todo: 此处有问题 无法判断是否成功
return true; return true;
}, },
GroupCode, GroupCode,
params params
); );
return data[1].item; return data[1].item;
} }
async getMsgHistory(peer: Peer, msgId: string, count: number, isReverseOrder: boolean = false) { async getMsgHistory(peer: Peer, msgId: string, count: number, isReverseOrder: boolean = false) {
// 消息时间从旧到新 // 消息时间从旧到新
return this.context.session.getMsgService().getMsgsIncludeSelf(peer, msgId, count, isReverseOrder); return this.context.session.getMsgService().getMsgsIncludeSelf(peer, msgId, count, isReverseOrder);
}
async recallMsg(peer: Peer, msgIds: string[]) {
await this.context.session.getMsgService().recallMsg({
chatType: peer.chatType,
peerUid: peer.peerUid
}, msgIds);
}
async sendMsgV2(peer: Peer, msgElements: SendMessageElement[], waitComplete = true, timeout = 10000) {
function generateMsgId() {
const timestamp = Math.floor(Date.now() / 1000);
const random = Math.floor(Math.random() * Math.pow(2, 32));
const buffer = Buffer.alloc(8);
buffer.writeUInt32BE(timestamp, 0);
buffer.writeUInt32BE(random, 4);
const msgId = BigInt("0x" + buffer.toString('hex')).toString();
return msgId;
} }
// 此处有采用Hack方法 利用数据返回正确得到对应消息 async recallMsg(peer: Peer, msgIds: string[]) {
// 与之前 Peer队列 MsgSeq队列 真正的MsgId并发不同 await this.context.session.getMsgService().recallMsg({
// 谨慎采用 目前测试暂无问题 Developer.Mlikiowa chatType: peer.chatType,
let msgId: string; peerUid: peer.peerUid
try { }, msgIds);
msgId = await this.getMsgUnique(peer.chatType, await this.getServerTime());
} catch (error) {
//if (!napCatCore.session.getMsgService()['generateMsgUniqueId'])
//兜底识别策略V2
msgId = generateMsgId().toString();
} }
let data = await this.core.eventWrapper.CallNormalEvent< async sendMsgV2(peer: Peer, msgElements: SendMessageElement[], waitComplete = true, timeout = 10000) {
function generateMsgId() {
const timestamp = Math.floor(Date.now() / 1000);
const random = Math.floor(Math.random() * Math.pow(2, 32));
const buffer = Buffer.alloc(8);
buffer.writeUInt32BE(timestamp, 0);
buffer.writeUInt32BE(random, 4);
const msgId = BigInt("0x" + buffer.toString('hex')).toString();
return msgId;
}
// 此处有采用Hack方法 利用数据返回正确得到对应消息
// 与之前 Peer队列 MsgSeq队列 真正的MsgId并发不同
// 谨慎采用 目前测试暂无问题 Developer.Mlikiowa
let msgId: string;
try {
msgId = await this.getMsgUnique(peer.chatType, await this.getServerTime());
} catch (error) {
//if (!napCatCore.session.getMsgService()['generateMsgUniqueId'])
//兜底识别策略V2
msgId = generateMsgId().toString();
}
const data = await this.core.eventWrapper.CallNormalEvent<
(msgId: string, peer: Peer, msgElements: SendMessageElement[], map: Map<any, any>) => Promise<unknown>, (msgId: string, peer: Peer, msgElements: SendMessageElement[], map: Map<any, any>) => Promise<unknown>,
(msgList: RawMessage[]) => void (msgList: RawMessage[]) => void
>( >(
'NodeIKernelMsgService/sendMsg', 'NodeIKernelMsgService/sendMsg',
'NodeIKernelMsgListener/onMsgInfoListUpdate', 'NodeIKernelMsgListener/onMsgInfoListUpdate',
1, 1,
timeout, timeout,
(msgRecords: RawMessage[]) => { (msgRecords: RawMessage[]) => {
for (let msgRecord of msgRecords) { for (const msgRecord of msgRecords) {
if (msgRecord.msgId === msgId && msgRecord.sendStatus === 2) { if (msgRecord.msgId === msgId && msgRecord.sendStatus === 2) {
return true; return true;
} }
} }
return false; return false;
}, },
msgId, msgId,
peer, peer,
msgElements, msgElements,
new Map() new Map()
); );
let retMsg = data[1].find(msgRecord => { const retMsg = data[1].find(msgRecord => {
if (msgRecord.msgId === msgId) { if (msgRecord.msgId === msgId) {
return true; return true;
} }
}); });
return retMsg; return retMsg;
} }
sendMsgEx(peer: Peer, msgElements: SendMessageElement[], waitComplete = true, timeout = 10000) { sendMsgEx(peer: Peer, msgElements: SendMessageElement[], waitComplete = true, timeout = 10000) {
//return NTQQMsgApi.sendMsgV1(peer, msgElements, waitComplete, timeout); //return NTQQMsgApi.sendMsgV1(peer, msgElements, waitComplete, timeout);
} }
async sendMsg(peer: Peer, msgElements: SendMessageElement[], waitComplete = true, timeout = 10000) { async sendMsg(peer: Peer, msgElements: SendMessageElement[], waitComplete = true, timeout = 10000) {
//唉? !我有个想法 //唉? !我有个想法
let msgId = await this.getMsgUnique(peer.chatType, await this.getServerTime()); const msgId = await this.getMsgUnique(peer.chatType, await this.getServerTime());
peer.guildId = msgId; peer.guildId = msgId;
let data = await this.core.eventWrapper.CallNormalEvent< const data = await this.core.eventWrapper.CallNormalEvent<
(msgId: string, peer: Peer, msgElements: SendMessageElement[], map: Map<any, any>) => Promise<unknown>, (msgId: string, peer: Peer, msgElements: SendMessageElement[], map: Map<any, any>) => Promise<unknown>,
(msgList: RawMessage[]) => void (msgList: RawMessage[]) => void
>( >(
'NodeIKernelMsgService/sendMsg', 'NodeIKernelMsgService/sendMsg',
'NodeIKernelMsgListener/onMsgInfoListUpdate', 'NodeIKernelMsgListener/onMsgInfoListUpdate',
1, 1,
timeout, timeout,
(msgRecords: RawMessage[]) => { (msgRecords: RawMessage[]) => {
for (let msgRecord of msgRecords) { for (const msgRecord of msgRecords) {
if (msgRecord.guildId === msgId && msgRecord.sendStatus === 2) { if (msgRecord.guildId === msgId && msgRecord.sendStatus === 2) {
return true; return true;
} }
} }
return false; return false;
}, },
"0", "0",
peer, peer,
msgElements, msgElements,
new Map() new Map()
); );
let retMsg = data[1].find(msgRecord => { const retMsg = data[1].find(msgRecord => {
if (msgRecord.guildId === msgId) { if (msgRecord.guildId === msgId) {
return true; return true;
} }
}); });
return retMsg; return retMsg;
}
async getMsgUnique(chatType: number, time: string) {
if (this.context.basicInfoWrapper.requireMinNTQQBuild('26702')) {
return this.context.session.getMsgService().generateMsgUniqueId(chatType, time);
} }
return this.context.session.getMsgService().getMsgUniqueId(time); async getMsgUnique(chatType: number, time: string) {
} if (this.context.basicInfoWrapper.requireMinNTQQBuild('26702')) {
async getServerTime() { return this.context.session.getMsgService().generateMsgUniqueId(chatType, time);
return this.context.session.getMSFService().getServerTime(); }
} return this.context.session.getMsgService().getMsgUniqueId(time);
async getServerTimeV2() { }
return this.core.eventWrapper.callNoListenerEvent<() => string>('NodeIKernelMsgService/getServerTime', 5000); async getServerTime() {
} return this.context.session.getMSFService().getServerTime();
async forwardMsg(srcPeer: Peer, destPeer: Peer, msgIds: string[]) { }
return this.context.session.getMsgService().forwardMsg(msgIds, srcPeer, [destPeer], new Map()); async getServerTimeV2() {
} return this.core.eventWrapper.callNoListenerEvent<() => string>('NodeIKernelMsgService/getServerTime', 5000);
async multiForwardMsg(srcPeer: Peer, destPeer: Peer, msgIds: string[]): Promise<RawMessage> { }
const msgInfos = msgIds.map(id => { async forwardMsg(srcPeer: Peer, destPeer: Peer, msgIds: string[]) {
return { msgId: id, senderShowName: this.core.selfInfo.nick }; return this.context.session.getMsgService().forwardMsg(msgIds, srcPeer, [destPeer], new Map());
}); }
let data = await this.core.eventWrapper.CallNormalEvent< async multiForwardMsg(srcPeer: Peer, destPeer: Peer, msgIds: string[]): Promise<RawMessage> {
const msgInfos = msgIds.map(id => {
return { msgId: id, senderShowName: this.core.selfInfo.nick };
});
const data = await this.core.eventWrapper.CallNormalEvent<
(msgInfo: typeof msgInfos, srcPeer: Peer, destPeer: Peer, comment: Array<any>, attr: Map<any, any>,) => Promise<unknown>, (msgInfo: typeof msgInfos, srcPeer: Peer, destPeer: Peer, comment: Array<any>, attr: Map<any, any>,) => Promise<unknown>,
(msgList: RawMessage[]) => void (msgList: RawMessage[]) => void
>( >(
'NodeIKernelMsgService/multiForwardMsgWithComment', 'NodeIKernelMsgService/multiForwardMsgWithComment',
'NodeIKernelMsgListener/onMsgInfoListUpdate', 'NodeIKernelMsgListener/onMsgInfoListUpdate',
1, 1,
5000, 5000,
(msgRecords: RawMessage[]) => { (msgRecords: RawMessage[]) => {
for (let msgRecord of msgRecords) { for (const msgRecord of msgRecords) {
if (msgRecord.peerUid == destPeer.peerUid && msgRecord.senderUid == this.core.selfInfo.uid) { if (msgRecord.peerUid == destPeer.peerUid && msgRecord.senderUid == this.core.selfInfo.uid) {
return true; return true;
} }
}
return false;
},
msgInfos,
srcPeer,
destPeer,
[],
new Map()
);
for (const msg of data[1]) {
const arkElement = msg.elements.find(ele => ele.arkElement);
if (!arkElement) {
continue;
}
const forwardData: any = JSON.parse(arkElement.arkElement.bytesData);
if (forwardData.app != 'com.tencent.multimsg') {
continue;
}
if (msg.peerUid == destPeer.peerUid && msg.senderUid == this.core.selfInfo.uid) {
return msg;
}
} }
return false; throw new Error('转发消息超时');
}, }
msgInfos, async markallMsgAsRead() {
srcPeer, return this.context.session.getMsgService().setAllC2CAndGroupMsgRead();
destPeer,
[],
new Map()
);
for (let msg of data[1]) {
const arkElement = msg.elements.find(ele => ele.arkElement);
if (!arkElement) {
continue;
}
const forwardData: any = JSON.parse(arkElement.arkElement.bytesData);
if (forwardData.app != 'com.tencent.multimsg') {
continue;
}
if (msg.peerUid == destPeer.peerUid && msg.senderUid == this.core.selfInfo.uid) {
return msg;
}
} }
throw new Error('转发消息超时');
}
async markallMsgAsRead() {
return this.context.session.getMsgService().setAllC2CAndGroupMsgRead();
}
} }

View File

@ -4,7 +4,7 @@ import { selfInfo } from '../data';
import { RequestUtil } from '@/common/utils/request'; import { RequestUtil } from '@/common/utils/request';
import { WebApi } from './webapi'; import { WebApi } from './webapi';
import { checkFileReceived, checkFileReceived2, uri2local } from '@/common/utils/file'; import { checkFileReceived, checkFileReceived2, uri2local } from '@/common/utils/file';
import fs from 'node:fs' import fs from 'node:fs';
import { sleep } from '@/common/utils/helper'; import { sleep } from '@/common/utils/helper';
export interface IdMusicSignPostData { export interface IdMusicSignPostData {
type: 'qq' | '163', type: 'qq' | '163',
@ -100,190 +100,190 @@ export interface MiniAppLuaJsonType {
sourcelogo: string, sourcelogo: string,
} }
export async function SignMiniApp(CardData: MiniAppLuaJsonType) { export async function SignMiniApp(CardData: MiniAppLuaJsonType) {
// { // {
// "app": "com.tencent.miniapp.lua", // "app": "com.tencent.miniapp.lua",
// "bizsrc": "tianxuan.imgJumpArk", // "bizsrc": "tianxuan.imgJumpArk",
// "view": "miniapp", // "view": "miniapp",
// "prompt": "hi! 这里有我的日常故事,只想讲给你听", // "prompt": "hi! 这里有我的日常故事,只想讲给你听",
// "config": { // "config": {
// "type": "normal", // "type": "normal",
// "forward": 1, // "forward": 1,
// "autosize": 0 // "autosize": 0
// }, // },
// "meta": { // "meta": {
// "miniapp": { // "miniapp": {
// "title": "hi! 这里有我的日常故事,只想讲给你听", // "title": "hi! 这里有我的日常故事,只想讲给你听",
// "preview": "https:\/\/tianquan.gtimg.cn\/qqAIAgent\/item\/7\/square.png", // "preview": "https:\/\/tianquan.gtimg.cn\/qqAIAgent\/item\/7\/square.png",
// "jumpUrl": "https:\/\/club.vip.qq.com\/transfer?open_kuikly_info=%7B%22version%22%3A%20%221%22%2C%22src_type%22%3A%20%22web%22%2C%22kr_turbo_display%22%3A%20%221%22%2C%22page_name%22%3A%20%22vas_ai_persona_moments%22%2C%22bundle_name%22%3A%20%22vas_ai_persona_moments%22%7D&page_name=vas_ai_persona_moments&enteranceId=share&robot_uin=3889008584", // "jumpUrl": "https:\/\/club.vip.qq.com\/transfer?open_kuikly_info=%7B%22version%22%3A%20%221%22%2C%22src_type%22%3A%20%22web%22%2C%22kr_turbo_display%22%3A%20%221%22%2C%22page_name%22%3A%20%22vas_ai_persona_moments%22%2C%22bundle_name%22%3A%20%22vas_ai_persona_moments%22%7D&page_name=vas_ai_persona_moments&enteranceId=share&robot_uin=3889008584",
// "tag": "QQ智能体", // "tag": "QQ智能体",
// "tagIcon": "https:\/\/tianquan.gtimg.cn\/shoal\/qqAIAgent\/3e9d70c9-d98c-45b8-80b4-79d82971b514.png", // "tagIcon": "https:\/\/tianquan.gtimg.cn\/shoal\/qqAIAgent\/3e9d70c9-d98c-45b8-80b4-79d82971b514.png",
// "source": "QQ智能体", // "source": "QQ智能体",
// "sourcelogo": "https:\/\/tianquan.gtimg.cn\/shoal\/qqAIAgent\/3e9d70c9-d98c-45b8-80b4-79d82971b514.png" // "sourcelogo": "https:\/\/tianquan.gtimg.cn\/shoal\/qqAIAgent\/3e9d70c9-d98c-45b8-80b4-79d82971b514.png"
// } // }
// } // }
// } // }
// token : function(url,skey){ // token : function(url,skey){
// var str = skey || cookie('skey') || cookie('rv2') || '', // var str = skey || cookie('skey') || cookie('rv2') || '',
// hash = 5381; // hash = 5381;
// if(url){ // if(url){
// var hostname = uri(url).hostname; // var hostname = uri(url).hostname;
// if(hostname.indexOf('qun.qq.com') > -1 || (hostname.indexOf('qzone.qq.com') > -1 && hostname.indexOf('qun.qzone.qq.com') === -1)){ // if(hostname.indexOf('qun.qq.com') > -1 || (hostname.indexOf('qzone.qq.com') > -1 && hostname.indexOf('qun.qzone.qq.com') === -1)){
// str = cookie('p_skey') || str; // str = cookie('p_skey') || str;
// } // }
// } // }
// for(var i = 0, len = str.length; i < len; ++i){ // for(var i = 0, len = str.length; i < len; ++i){
// hash += (hash << 5) + str.charAt(i).charCodeAt(); // hash += (hash << 5) + str.charAt(i).charCodeAt();
// } // }
// return hash & 0x7fffffff; // return hash & 0x7fffffff;
// }, // },
// //
// function signToken(skey: string) { // function signToken(skey: string) {
// let hash = 5381; // let hash = 5381;
// for (let i = 0, len = skey.length; i < len; ++i) { // for (let i = 0, len = skey.length; i < len; ++i) {
// hash += (hash << 5) + skey.charCodeAt(i); // hash += (hash << 5) + skey.charCodeAt(i);
// } // }
// return hash & 0x7fffffff; // return hash & 0x7fffffff;
// } // }
let signCard = { const signCard = {
"app": "com.tencent.miniapp.lua", "app": "com.tencent.miniapp.lua",
"bizsrc": "tianxuan.imgJumpArk", "bizsrc": "tianxuan.imgJumpArk",
"view": "miniapp", "view": "miniapp",
"prompt": CardData.prompt, "prompt": CardData.prompt,
"config": { "config": {
"type": "normal", "type": "normal",
"forward": 1, "forward": 1,
"autosize": 0 "autosize": 0
}, },
"meta": { "meta": {
"miniapp": { "miniapp": {
"title": CardData.title, "title": CardData.title,
"preview": (CardData.preview as string).replace(/\\/g, "\\/\\/"), "preview": (CardData.preview as string).replace(/\\/g, "\\/\\/"),
"jumpUrl": (CardData.jumpUrl as string).replace(/\\/g, "\\/\\/"), "jumpUrl": (CardData.jumpUrl as string).replace(/\\/g, "\\/\\/"),
"tag": CardData.tag, "tag": CardData.tag,
"tagIcon": (CardData.tagIcon as string).replace(/\\/g, "\\/\\/"), "tagIcon": (CardData.tagIcon as string).replace(/\\/g, "\\/\\/"),
"source": CardData.source, "source": CardData.source,
"sourcelogo": (CardData.sourcelogo as string).replace(/\\/g, "\\/\\/") "sourcelogo": (CardData.sourcelogo as string).replace(/\\/g, "\\/\\/")
} }
}
};
// let signCard = {
// "app": "com.tencent.eventshare.lua",
// "prompt": "Bot Test",
// "bizsrc": "tianxuan.business",
// "meta": {
// "eventshare": {
// "button1URL": "https://www.bilibili.com",
// "button1disable": false,
// "button1title": "点我前往",
// "button2URL": "",
// "button2disable": false,
// "button2title": "",
// "buttonNum": 1,
// "jumpURL": "https://www.bilibili.com",
// "preview": "https://tianquan.gtimg.cn/shoal/card/9930bc4e-4a92-4da3-814f-8094a2421d9c.png",
// "tag": "QQ集卡",
// "tagIcon": "https://tianquan.gtimg.cn/shoal/card/c034854b-102d-40be-a545-5ca90a7c49c9.png",
// "title": "Bot Test"
// }
// },
// "config": {
// "autosize": 0,
// "collect": 0,
// "ctime": 1716568575,
// "forward": 1,
// "height": 336,
// "reply": 0,
// "round": 1,
// "type": "normal",
// "width": 263
// },
// "view": "eventshare",
// "ver": "0.0.0.1"
// };
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;
const signurl = "https://h5.qzone.qq.com/v2/vip/tx/trpc/ark-share/GenNewSignedArk?g_tk=" + Bkn + "&ark=" + encodeURIComponent(JSON.stringify(signCard));
let signed_ark = "";
try {
const retData = await RequestUtil.HttpGetJson<{ code: number, data: { signed_ark: string } }>(signurl, 'GET', undefined, { Cookie: CookieValue });
//logDebug('MiniApp JSON 消息生成成功', retData);
signed_ark = retData.data.signed_ark;
} catch (error) {
logDebug('MiniApp JSON 消息生成失败', error);
} }
}; return signed_ark;
// let signCard = {
// "app": "com.tencent.eventshare.lua",
// "prompt": "Bot Test",
// "bizsrc": "tianxuan.business",
// "meta": {
// "eventshare": {
// "button1URL": "https://www.bilibili.com",
// "button1disable": false,
// "button1title": "点我前往",
// "button2URL": "",
// "button2disable": false,
// "button2title": "",
// "buttonNum": 1,
// "jumpURL": "https://www.bilibili.com",
// "preview": "https://tianquan.gtimg.cn/shoal/card/9930bc4e-4a92-4da3-814f-8094a2421d9c.png",
// "tag": "QQ集卡",
// "tagIcon": "https://tianquan.gtimg.cn/shoal/card/c034854b-102d-40be-a545-5ca90a7c49c9.png",
// "title": "Bot Test"
// }
// },
// "config": {
// "autosize": 0,
// "collect": 0,
// "ctime": 1716568575,
// "forward": 1,
// "height": 336,
// "reply": 0,
// "round": 1,
// "type": "normal",
// "width": 263
// },
// "view": "eventshare",
// "ver": "0.0.0.1"
// };
let 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;
let signurl = "https://h5.qzone.qq.com/v2/vip/tx/trpc/ark-share/GenNewSignedArk?g_tk=" + Bkn + "&ark=" + encodeURIComponent(JSON.stringify(signCard));
let signed_ark = "";
try {
let retData = await RequestUtil.HttpGetJson<{ code: number, data: { signed_ark: string } }>(signurl, 'GET', undefined, { Cookie: CookieValue });
//logDebug('MiniApp JSON 消息生成成功', retData);
signed_ark = retData.data.signed_ark;
} catch (error) {
logDebug('MiniApp JSON 消息生成失败', error);
}
return signed_ark;
} }
export async function SignMusicInternal(songname: string, singer: string, cover: string, songmid: string, songmusic: string) { export async function SignMusicInternal(songname: string, singer: string, cover: string, songmid: string, songmusic: string) {
//curl -X POST 'https://mqq.reader.qq.com/api/mqq/share/card?accessToken&_csrfToken&source=c0003' -H 'Content-Type: application/json' -H 'Cookie: uin=o10086' -d '{"app":"com.tencent.qqreader.share","config":{"ctime":1718634110,"forward":1,"token":"9a63343c32d5a16bcde653eb97faa25d","type":"normal"},"extra":{"app_type":1,"appid":100497308,"msg_seq":14386738075403815000.0,"uin":1733139081},"meta":{"music":{"action":"","android_pkg_name":"","app_type":1,"appid":100497308,"ctime":1718634110,"desc":"周杰伦","jumpUrl":"https://i.y.qq.com/v8/playsong.html?songmid=0039MnYb0qxYhV&type=0","musicUrl":"http://ws.stream.qqmusic.qq.com/http://isure6.stream.qqmusic.qq.com/M800002202B43Cq4V4.mp3?fromtag=810033622&guid=br_xzg&trace=23fe7bcbe2336bbf&uin=553&vkey=CF0F5CE8B0FA16F3001F8A88D877A217EB5E4F00BDCEF1021EB6C48969CA33C6303987AEECE9CC840122DD2F917A59D6130D8A8CA4577C87","preview":"https://y.qq.com/music/photo_new/T002R800x800M000000MkMni19ClKG.jpg","cover":"https://y.qq.com/music/photo_new/T002R800x800M000000MkMni19ClKG.jpg","sourceMsgId":"0","source_icon":"https://p.qpic.cn/qqconnect/0/app_100497308_1626060999/100?max-age=2592000&t=0","source_url":"","tag":"QQ音乐","title":"晴天","uin":10086}},"prompt":"[分享]晴天","ver":"0.0.0.1","view":"music"}' //curl -X POST 'https://mqq.reader.qq.com/api/mqq/share/card?accessToken&_csrfToken&source=c0003' -H 'Content-Type: application/json' -H 'Cookie: uin=o10086' -d '{"app":"com.tencent.qqreader.share","config":{"ctime":1718634110,"forward":1,"token":"9a63343c32d5a16bcde653eb97faa25d","type":"normal"},"extra":{"app_type":1,"appid":100497308,"msg_seq":14386738075403815000.0,"uin":1733139081},"meta":{"music":{"action":"","android_pkg_name":"","app_type":1,"appid":100497308,"ctime":1718634110,"desc":"周杰伦","jumpUrl":"https://i.y.qq.com/v8/playsong.html?songmid=0039MnYb0qxYhV&type=0","musicUrl":"http://ws.stream.qqmusic.qq.com/http://isure6.stream.qqmusic.qq.com/M800002202B43Cq4V4.mp3?fromtag=810033622&guid=br_xzg&trace=23fe7bcbe2336bbf&uin=553&vkey=CF0F5CE8B0FA16F3001F8A88D877A217EB5E4F00BDCEF1021EB6C48969CA33C6303987AEECE9CC840122DD2F917A59D6130D8A8CA4577C87","preview":"https://y.qq.com/music/photo_new/T002R800x800M000000MkMni19ClKG.jpg","cover":"https://y.qq.com/music/photo_new/T002R800x800M000000MkMni19ClKG.jpg","sourceMsgId":"0","source_icon":"https://p.qpic.cn/qqconnect/0/app_100497308_1626060999/100?max-age=2592000&t=0","source_url":"","tag":"QQ音乐","title":"晴天","uin":10086}},"prompt":"[分享]晴天","ver":"0.0.0.1","view":"music"}'
let signurl = 'https://mqq.reader.qq.com/api/mqq/share/card?accessToken&_csrfToken&source=c0003'; const signurl = 'https://mqq.reader.qq.com/api/mqq/share/card?accessToken&_csrfToken&source=c0003';
//let = "https://y.qq.com/music/photo_new/T002R800x800M000000MkMni19ClKG.jpg"; //let = "https://y.qq.com/music/photo_new/T002R800x800M000000MkMni19ClKG.jpg";
let signCard = { const signCard = {
app: "com.tencent.qqreader.share", app: "com.tencent.qqreader.share",
config: { config: {
ctime: 1718634110, ctime: 1718634110,
forward: 1, forward: 1,
token: "9a63343c32d5a16bcde653eb97faa25d", token: "9a63343c32d5a16bcde653eb97faa25d",
type: "normal" type: "normal"
}, },
extra: { extra: {
app_type: 1, app_type: 1,
appid: 100497308, appid: 100497308,
msg_seq: 14386738075403815000.0, msg_seq: 14386738075403815000.0,
uin: 1733139081 uin: 1733139081
}, },
meta: { meta: {
music: music:
{ {
action: "", action: "",
android_pkg_name: "", android_pkg_name: "",
app_type: 1, app_type: 1,
appid: 100497308, appid: 100497308,
ctime: 1718634110, ctime: 1718634110,
desc: singer, desc: singer,
jumpUrl: "https://i.y.qq.com/v8/playsong.html?songmid=" + songmid + "&type=0", jumpUrl: "https://i.y.qq.com/v8/playsong.html?songmid=" + songmid + "&type=0",
musicUrl: songmusic, musicUrl: songmusic,
preview: cover, preview: cover,
cover: cover, cover: cover,
sourceMsgId: "0", sourceMsgId: "0",
source_icon: "https://p.qpic.cn/qqconnect/0/app_100497308_1626060999/100?max-age=2592000&t=0", source_icon: "https://p.qpic.cn/qqconnect/0/app_100497308_1626060999/100?max-age=2592000&t=0",
source_url: "", source_url: "",
tag: "QQ音乐", tag: "QQ音乐",
title: songname, title: songname,
uin: 10086 uin: 10086
} }
}, },
prompt: "[分享]" + songname, prompt: "[分享]" + songname,
ver: "0.0.0.1", ver: "0.0.0.1",
view: "music" view: "music"
} };
//console.log(JSON.stringify(signCard, null, 2)); //console.log(JSON.stringify(signCard, null, 2));
let data = await RequestUtil.HttpGetJson<{ code: number, data: { arkResult: string } }> const data = await RequestUtil.HttpGetJson<{ code: number, data: { arkResult: string } }>
(signurl, 'POST', signCard, { 'Cookie': 'uin=o10086', 'Content-Type': 'application/json' }); (signurl, 'POST', signCard, { 'Cookie': 'uin=o10086', 'Content-Type': 'application/json' });
return data; return data;
} }
//注意处理错误 //注意处理错误
export async function CreateMusicThridWay0(id: string = '', mid: string = '') { export async function CreateMusicThridWay0(id: string = '', mid: string = '') {
if (mid == '') { if (mid == '') {
let MusicInfo = await RequestUtil.HttpGetJson const MusicInfo = await RequestUtil.HttpGetJson
<{ songinfo?: { data?: { track_info: { mid: string } } } }> <{ songinfo?: { data?: { track_info: { mid: string } } } }>
( (
'https://u.y.qq.com/cgi-bin/musicu.fcg?format=json&inCharset=utf8&outCharset=utf-8&notice=0&platform=yqq.json&needNewCode=0&data={"comm":{"ct":24,"cv":0},"songinfo":{"method":"get_song_detail_yqq","param":{"song_type":0,"song_mid":"","song_id":' + id + '},"module":"music.pf_song_detail_svr"}}', 'https://u.y.qq.com/cgi-bin/musicu.fcg?format=json&inCharset=utf8&outCharset=utf-8&notice=0&platform=yqq.json&needNewCode=0&data={"comm":{"ct":24,"cv":0},"songinfo":{"method":"get_song_detail_yqq","param":{"song_type":0,"song_mid":"","song_id":' + id + '},"module":"music.pf_song_detail_svr"}}',
'GET', 'GET',
undefined undefined
); );
mid = MusicInfo.songinfo?.data?.track_info.mid!; mid = MusicInfo.songinfo?.data?.track_info.mid!;
} }
//第三方接口 存在速率限制 现在勉强用 //第三方接口 存在速率限制 现在勉强用
let MusicReal = await RequestUtil.HttpGetJson const MusicReal = await RequestUtil.HttpGetJson
<{ code: number, data?: { name: string, singer: string, url: string, cover: string } }> <{ code: number, data?: { name: string, singer: string, url: string, cover: string } }>
('https://api.leafone.cn/api/qqmusic?id=' + mid + '&type=8', 'GET', undefined); ('https://api.leafone.cn/api/qqmusic?id=' + mid + '&type=8', 'GET', undefined);
//console.log(MusicReal); //console.log(MusicReal);
return { ...MusicReal.data, mid: mid }; return { ...MusicReal.data, mid: mid };
} }
export async function CreateMusicThridWay1(id: string = '', mid: string = '') { export async function CreateMusicThridWay1(id: string = '', mid: string = '') {
@ -302,7 +302,7 @@ export async function CreateMusicThridWay1(id: string = '', mid: string = '') {
//还有一处公告上传可以上传高质量图片 持久为qq域名 //还有一处公告上传可以上传高质量图片 持久为qq域名
export async function SignMusicWrapper(id: string = '') { export async function SignMusicWrapper(id: string = '') {
let MusicInfo = await CreateMusicThridWay0(id)!; const MusicInfo = await CreateMusicThridWay0(id)!;
let MusicCard = await SignMusicInternal(MusicInfo.name!, MusicInfo.singer!, MusicInfo.cover!, MusicInfo.mid!, "https://ws.stream.qqmusic.qq.com/" + MusicInfo.url!); const MusicCard = await SignMusicInternal(MusicInfo.name!, MusicInfo.singer!, MusicInfo.cover!, MusicInfo.mid!, "https://ws.stream.qqmusic.qq.com/" + MusicInfo.url!);
return MusicCard; return MusicCard;
} }

View File

@ -3,33 +3,33 @@
import { NTEventDispatch } from '@/common/utils/EventTask'; import { NTEventDispatch } from '@/common/utils/EventTask';
import { GeneralCallResult, NTQQFileApi, NTQQUserApi, napCatCore } from '@/core'; import { GeneralCallResult, NTQQFileApi, NTQQUserApi, napCatCore } from '@/core';
export class NTQQSystemApi { export class NTQQSystemApi {
async hasOtherRunningQQProcess() { async hasOtherRunningQQProcess() {
return napCatCore.util.hasOtherRunningQQProcess(); return napCatCore.util.hasOtherRunningQQProcess();
} }
async ORCImage(filePath: string) { async ORCImage(filePath: string) {
return napCatCore.session.getNodeMiscService().wantWinScreenOCR(filePath); return napCatCore.session.getNodeMiscService().wantWinScreenOCR(filePath);
} }
async translateEnWordToZn(words: string[]) { async translateEnWordToZn(words: string[]) {
return napCatCore.session.getRichMediaService().translateEnWordToZn(words); return napCatCore.session.getRichMediaService().translateEnWordToZn(words);
} }
//调用会超时 没灯用 (好像是通知listener的) onLineDev //调用会超时 没灯用 (好像是通知listener的) onLineDev
async getOnlineDev() { async getOnlineDev() {
return napCatCore.session.getMsgService().getOnLineDev(); return napCatCore.session.getMsgService().getOnLineDev();
} }
//1-2-162b9b42-65b9-4405-a8ed-2e256ec8aa50 //1-2-162b9b42-65b9-4405-a8ed-2e256ec8aa50
async getArkJsonCollection(cid: string) { async getArkJsonCollection(cid: string) {
let ret = await NTEventDispatch.CallNoListenerEvent const ret = await NTEventDispatch.CallNoListenerEvent
<(cid: string) => Promise<GeneralCallResult & { arkJson: string }>>( <(cid: string) => Promise<GeneralCallResult & { arkJson: string }>>(
'NodeIKernelCollectionService/collectionArkShare', 'NodeIKernelCollectionService/collectionArkShare',
5000, 5000,
'1717662698058' '1717662698058'
); );
return ret; return ret;
} }
async BootMiniApp(appfile: string, params: string) { async BootMiniApp(appfile: string, params: string) {
await napCatCore.session.getNodeMiscService().setMiniAppVersion('2.16.4'); await napCatCore.session.getNodeMiscService().setMiniAppVersion('2.16.4');
let c = await napCatCore.session.getNodeMiscService().getMiniAppPath(); const c = await napCatCore.session.getNodeMiscService().getMiniAppPath();
return napCatCore.session.getNodeMiscService().startNewMiniApp(appfile, params); return napCatCore.session.getNodeMiscService().startNewMiniApp(appfile, params);
} }
} }

View File

@ -110,78 +110,78 @@ export interface GroupEssenceMsgRet {
} }
} }
export class WebApi { export class WebApi {
async shareDigest(groupCode: string, msgSeq: string, msgRandom: string, targetGroupCode: string) { async shareDigest(groupCode: string, msgSeq: string, msgRandom: string, targetGroupCode: string) {
const CookiesObject = await NTQQUserApi.getCookies('qun.qq.com'); const CookiesObject = await NTQQUserApi.getCookies('qun.qq.com');
const CookieValue = Object.entries(CookiesObject).map(([key, value]) => `${key}=${value}`).join('; '); const CookieValue = Object.entries(CookiesObject).map(([key, value]) => `${key}=${value}`).join('; ');
const Bkn = this.genBkn(CookiesObject.skey); const Bkn = this.genBkn(CookiesObject.skey);
let ret: any = undefined; let ret: any = undefined;
const data = 'group_code=' + groupCode + '&msg_seq=' + msgSeq + '&msg_random=' + msgRandom + '&target_group_code=' + targetGroupCode; const data = 'group_code=' + groupCode + '&msg_seq=' + msgSeq + '&msg_random=' + msgRandom + '&target_group_code=' + targetGroupCode;
const url = 'https://qun.qq.com/cgi-bin/group_digest/share_digest?bkn=' + Bkn + "&" + data; const url = 'https://qun.qq.com/cgi-bin/group_digest/share_digest?bkn=' + Bkn + "&" + data;
//console.log(url); //console.log(url);
try { try {
ret = await RequestUtil.HttpGetText(url, 'GET', '', { 'Cookie': CookieValue }); ret = await RequestUtil.HttpGetText(url, 'GET', '', { 'Cookie': CookieValue });
return ret; return ret;
} catch (e) { } catch (e) {
return undefined; return undefined;
}
return undefined;
} }
return undefined;
}
@CacheClassFuncAsync(3600 * 1000, 'webapi_get_group_members') @CacheClassFuncAsync(3600 * 1000, 'webapi_get_group_members')
async getGroupEssenceMsg(GroupCode: string, page_start: string) { async getGroupEssenceMsg(GroupCode: string, page_start: string) {
const CookiesObject = await NTQQUserApi.getCookies('qun.qq.com'); const CookiesObject = await NTQQUserApi.getCookies('qun.qq.com');
const CookieValue = Object.entries(CookiesObject).map(([key, value]) => `${key}=${value}`).join('; '); const CookieValue = Object.entries(CookiesObject).map(([key, value]) => `${key}=${value}`).join('; ');
const Bkn = this.genBkn(CookiesObject.skey); const Bkn = this.genBkn(CookiesObject.skey);
const url = 'https://qun.qq.com/cgi-bin/group_digest/digest_list?bkn=' + Bkn + '&group_code=' + GroupCode + '&page_start=' + page_start + '&page_limit=20'; const url = 'https://qun.qq.com/cgi-bin/group_digest/digest_list?bkn=' + Bkn + '&group_code=' + GroupCode + '&page_start=' + page_start + '&page_limit=20';
let ret; let ret;
try { try {
ret = await RequestUtil.HttpGetJson<GroupEssenceMsgRet>(url, 'GET', '', { 'Cookie': CookieValue }); ret = await RequestUtil.HttpGetJson<GroupEssenceMsgRet>(url, 'GET', '', { 'Cookie': CookieValue });
} catch { } catch {
return undefined; return undefined;
}
//console.log(url, CookieValue);
if (ret.retcode !== 0) {
return undefined;
}
return ret;
} }
//console.log(url, CookieValue);
if (ret.retcode !== 0) {
return undefined;
}
return ret;
}
@CacheClassFuncAsync(3600 * 1000, 'webapi_get_group_members') @CacheClassFuncAsync(3600 * 1000, 'webapi_get_group_members')
async getGroupMembers(GroupCode: string, cached: boolean = true): Promise<WebApiGroupMember[]> { async getGroupMembers(GroupCode: string, cached: boolean = true): Promise<WebApiGroupMember[]> {
//logDebug('webapi 获取群成员', GroupCode); //logDebug('webapi 获取群成员', GroupCode);
let MemberData: Array<WebApiGroupMember> = new Array<WebApiGroupMember>(); const MemberData: Array<WebApiGroupMember> = new Array<WebApiGroupMember>();
try { try {
const CookiesObject = await NTQQUserApi.getCookies('qun.qq.com'); const CookiesObject = await NTQQUserApi.getCookies('qun.qq.com');
const CookieValue = Object.entries(CookiesObject).map(([key, value]) => `${key}=${value}`).join('; '); const CookieValue = Object.entries(CookiesObject).map(([key, value]) => `${key}=${value}`).join('; ');
const Bkn = this.genBkn(CookiesObject.skey); const Bkn = this.genBkn(CookiesObject.skey);
const retList: Promise<WebApiGroupMemberRet>[] = []; const retList: Promise<WebApiGroupMemberRet>[] = [];
const fastRet = await RequestUtil.HttpGetJson<WebApiGroupMemberRet>('https://qun.qq.com/cgi-bin/qun_mgr/search_group_members?st=0&end=40&sort=1&gc=' + GroupCode + '&bkn=' + Bkn, 'POST', '', { 'Cookie': CookieValue }); const fastRet = await RequestUtil.HttpGetJson<WebApiGroupMemberRet>('https://qun.qq.com/cgi-bin/qun_mgr/search_group_members?st=0&end=40&sort=1&gc=' + GroupCode + '&bkn=' + Bkn, 'POST', '', { 'Cookie': CookieValue });
if (!fastRet?.count || fastRet?.errcode !== 0 || !fastRet?.mems) { if (!fastRet?.count || fastRet?.errcode !== 0 || !fastRet?.mems) {
return []; return [];
} else { } else {
for (const key in fastRet.mems) { for (const key in fastRet.mems) {
MemberData.push(fastRet.mems[key]); MemberData.push(fastRet.mems[key]);
} }
}
//初始化获取PageNum
const PageNum = Math.ceil(fastRet.count / 40);
//遍历批量请求
for (let i = 2; i <= PageNum; i++) {
const ret: Promise<WebApiGroupMemberRet> = RequestUtil.HttpGetJson<WebApiGroupMemberRet>('https://qun.qq.com/cgi-bin/qun_mgr/search_group_members?st=' + (i - 1) * 40 + '&end=' + i * 40 + '&sort=1&gc=' + GroupCode + '&bkn=' + Bkn, 'POST', '', { 'Cookie': CookieValue });
retList.push(ret);
}
//批量等待
for (let i = 1; i <= PageNum; i++) {
const ret = await (retList[i]);
if (!ret?.count || ret?.errcode !== 0 || !ret?.mems) {
continue;
}
for (const key in ret.mems) {
MemberData.push(ret.mems[key]);
}
}
} catch {
return MemberData;
} }
//初始化获取PageNum
const PageNum = Math.ceil(fastRet.count / 40);
//遍历批量请求
for (let i = 2; i <= PageNum; i++) {
const ret: Promise<WebApiGroupMemberRet> = RequestUtil.HttpGetJson<WebApiGroupMemberRet>('https://qun.qq.com/cgi-bin/qun_mgr/search_group_members?st=' + (i - 1) * 40 + '&end=' + i * 40 + '&sort=1&gc=' + GroupCode + '&bkn=' + Bkn, 'POST', '', { 'Cookie': CookieValue });
retList.push(ret);
}
//批量等待
for (let i = 1; i <= PageNum; i++) {
const ret = await (retList[i]);
if (!ret?.count || ret?.errcode !== 0 || !ret?.mems) {
continue;
}
for (const key in ret.mems) {
MemberData.push(ret.mems[key]);
}
}
} catch {
return MemberData; return MemberData;
}
return MemberData;
} }
// public async addGroupDigest(groupCode: string, msgSeq: string) { // public async addGroupDigest(groupCode: string, msgSeq: string) {
// const url = `https://qun.qq.com/cgi-bin/group_digest/cancel_digest?random=665&X-CROSS-ORIGIN=fetch&group_code=${groupCode}&msg_seq=${msgSeq}&msg_random=444021292`; // const url = `https://qun.qq.com/cgi-bin/group_digest/cancel_digest?random=665&X-CROSS-ORIGIN=fetch&group_code=${groupCode}&msg_seq=${msgSeq}&msg_random=444021292`;
@ -194,170 +194,170 @@ export class WebApi {
// const res = await this.request(url); // const res = await this.request(url);
// return await res.json(); // return await res.json();
// } // }
async setGroupNotice(GroupCode: string, Content: string = '') { async setGroupNotice(GroupCode: string, Content: string = '') {
//https://web.qun.qq.com/cgi-bin/announce/add_qun_notice?bkn=${bkn} //https://web.qun.qq.com/cgi-bin/announce/add_qun_notice?bkn=${bkn}
//qid=${群号}&bkn=${bkn}&text=${内容}&pinned=0&type=1&settings={"is_show_edit_card":1,"tip_window_type":1,"confirm_required":1} //qid=${群号}&bkn=${bkn}&text=${内容}&pinned=0&type=1&settings={"is_show_edit_card":1,"tip_window_type":1,"confirm_required":1}
const CookiesObject = await NTQQUserApi.getCookies('qun.qq.com'); const CookiesObject = await NTQQUserApi.getCookies('qun.qq.com');
const CookieValue = Object.entries(CookiesObject).map(([key, value]) => `${key}=${value}`).join('; '); const CookieValue = Object.entries(CookiesObject).map(([key, value]) => `${key}=${value}`).join('; ');
const Bkn = this.genBkn(CookiesObject.skey); const Bkn = this.genBkn(CookiesObject.skey);
let ret: any = undefined; let ret: any = undefined;
const data = 'qid=' + GroupCode + '&bkn=' + Bkn + '&text=' + Content + '&pinned=0&type=1&settings={"is_show_edit_card":1,"tip_window_type":1,"confirm_required":1}'; const data = 'qid=' + GroupCode + '&bkn=' + Bkn + '&text=' + Content + '&pinned=0&type=1&settings={"is_show_edit_card":1,"tip_window_type":1,"confirm_required":1}';
const url = 'https://web.qun.qq.com/cgi-bin/announce/add_qun_notice?bkn=' + Bkn; const url = 'https://web.qun.qq.com/cgi-bin/announce/add_qun_notice?bkn=' + Bkn;
try { try {
ret = await RequestUtil.HttpGetJson<any>(url, 'GET', '', { 'Cookie': CookieValue }); ret = await RequestUtil.HttpGetJson<any>(url, 'GET', '', { 'Cookie': CookieValue });
return ret; return ret;
} catch (e) { } catch (e) {
return undefined; return undefined;
}
return undefined;
}
async getGrouptNotice(GroupCode: string): Promise<undefined | WebApiGroupNoticeRet> {
const CookiesObject = await NTQQUserApi.getCookies('qun.qq.com');
const CookieValue = Object.entries(CookiesObject).map(([key, value]) => `${key}=${value}`).join('; ');
const Bkn = this.genBkn(CookiesObject.skey);
let ret: WebApiGroupNoticeRet | undefined = undefined;
//console.log(CookieValue);
const url = 'https://web.qun.qq.com/cgi-bin/announce/get_t_list?bkn=' + Bkn + '&qid=' + GroupCode + '&ft=23&ni=1&n=1&i=1&log_read=1&platform=1&s=-1&n=20';
try {
ret = await RequestUtil.HttpGetJson<WebApiGroupNoticeRet>(url, 'GET', '', { 'Cookie': CookieValue });
if (ret?.ec !== 0) {
return undefined;
} }
return ret;
} catch (e) {
return undefined; return undefined;
}
return undefined;
} }
genBkn(sKey: string) { async getGrouptNotice(GroupCode: string): Promise<undefined | WebApiGroupNoticeRet> {
sKey = sKey || ''; const CookiesObject = await NTQQUserApi.getCookies('qun.qq.com');
let hash = 5381; const CookieValue = Object.entries(CookiesObject).map(([key, value]) => `${key}=${value}`).join('; ');
const Bkn = this.genBkn(CookiesObject.skey);
let ret: WebApiGroupNoticeRet | undefined = undefined;
//console.log(CookieValue);
const url = 'https://web.qun.qq.com/cgi-bin/announce/get_t_list?bkn=' + Bkn + '&qid=' + GroupCode + '&ft=23&ni=1&n=1&i=1&log_read=1&platform=1&s=-1&n=20';
try {
ret = await RequestUtil.HttpGetJson<WebApiGroupNoticeRet>(url, 'GET', '', { 'Cookie': CookieValue });
if (ret?.ec !== 0) {
return undefined;
}
return ret;
} catch (e) {
return undefined;
}
return undefined;
}
genBkn(sKey: string) {
sKey = sKey || '';
let hash = 5381;
for (let i = 0; i < sKey.length; i++) { for (let i = 0; i < sKey.length; i++) {
const code = sKey.charCodeAt(i); const code = sKey.charCodeAt(i);
hash = hash + (hash << 5) + code; hash = hash + (hash << 5) + code;
} }
return (hash & 0x7FFFFFFF).toString(); return (hash & 0x7FFFFFFF).toString();
} }
@CacheClassFuncAsync(3600 * 1000, 'GroupHonorInfo') @CacheClassFuncAsync(3600 * 1000, 'GroupHonorInfo')
async getGroupHonorInfo(groupCode: string, getType: WebHonorType) { async getGroupHonorInfo(groupCode: string, getType: WebHonorType) {
const CookiesObject = await NTQQUserApi.getCookies('qun.qq.com'); const CookiesObject = await NTQQUserApi.getCookies('qun.qq.com');
const CookieValue = Object.entries(CookiesObject).map(([key, value]) => `${key}=${value}`).join('; '); const CookieValue = Object.entries(CookiesObject).map(([key, value]) => `${key}=${value}`).join('; ');
const Bkn = WebApi.genBkn(CookiesObject.skey); const Bkn = WebApi.genBkn(CookiesObject.skey);
async function getDataInternal(Internal_groupCode: string, Internal_type: number) { async function getDataInternal(Internal_groupCode: string, Internal_type: number) {
let url = 'https://qun.qq.com/interactive/honorlist?gc=' + Internal_groupCode + '&type=' + Internal_type.toString(); const url = 'https://qun.qq.com/interactive/honorlist?gc=' + Internal_groupCode + '&type=' + Internal_type.toString();
let res = ''; let res = '';
let resJson; let resJson;
try { try {
res = await RequestUtil.HttpGetText(url, 'GET', '', { 'Cookie': CookieValue }); res = await RequestUtil.HttpGetText(url, 'GET', '', { 'Cookie': CookieValue });
const match = res.match(/window\.__INITIAL_STATE__=(.*?);/); const match = res.match(/window\.__INITIAL_STATE__=(.*?);/);
if (match) { if (match) {
resJson = JSON.parse(match[1].trim()); resJson = JSON.parse(match[1].trim());
} }
if (Internal_type === 1) { if (Internal_type === 1) {
return resJson?.talkativeList; return resJson?.talkativeList;
} else { } else {
return resJson?.actorList; return resJson?.actorList;
} }
} catch (e) { } catch (e) {
logDebug('获取当前群荣耀失败', url, e); logDebug('获取当前群荣耀失败', url, e);
}
return undefined;
} }
return undefined;
}
let HonorInfo: any = { group_id: groupCode }; const HonorInfo: any = { group_id: groupCode };
if (getType === WebHonorType.TALKACTIVE || getType === WebHonorType.ALL) { if (getType === WebHonorType.TALKACTIVE || getType === WebHonorType.ALL) {
try { try {
let RetInternal = await getDataInternal(groupCode, 1); const RetInternal = await getDataInternal(groupCode, 1);
if (!RetInternal) { if (!RetInternal) {
throw new Error('获取龙王信息失败'); throw new Error('获取龙王信息失败');
} }
HonorInfo.current_talkative = { HonorInfo.current_talkative = {
user_id: RetInternal[0]?.uin, user_id: RetInternal[0]?.uin,
avatar: RetInternal[0]?.avatar, avatar: RetInternal[0]?.avatar,
nickname: RetInternal[0]?.name, nickname: RetInternal[0]?.name,
day_count: 0, day_count: 0,
description: RetInternal[0]?.desc description: RetInternal[0]?.desc
} };
HonorInfo.talkative_list = []; HonorInfo.talkative_list = [];
for (const talkative_ele of RetInternal) { for (const talkative_ele of RetInternal) {
HonorInfo.talkative_list.push({ HonorInfo.talkative_list.push({
user_id: talkative_ele?.uin, user_id: talkative_ele?.uin,
avatar: talkative_ele?.avatar, avatar: talkative_ele?.avatar,
description: talkative_ele?.desc, description: talkative_ele?.desc,
day_count: 0, day_count: 0,
nickname: talkative_ele?.name nickname: talkative_ele?.name
}); });
} }
} catch (e) { } catch (e) {
logDebug(e); logDebug(e);
}
} }
} if (getType === WebHonorType.PERFROMER || getType === WebHonorType.ALL) {
if (getType === WebHonorType.PERFROMER || getType === WebHonorType.ALL) { try {
try { const RetInternal = await getDataInternal(groupCode, 2);
let RetInternal = await getDataInternal(groupCode, 2); if (!RetInternal) {
if (!RetInternal) { throw new Error('获取群聊之火失败');
throw new Error('获取群聊之火失败'); }
} HonorInfo.performer_list = [];
HonorInfo.performer_list = []; for (const performer_ele of RetInternal) {
for (const performer_ele of RetInternal) { HonorInfo.performer_list.push({
HonorInfo.performer_list.push({ user_id: performer_ele?.uin,
user_id: performer_ele?.uin, nickname: performer_ele?.name,
nickname: performer_ele?.name, avatar: performer_ele?.avatar,
avatar: performer_ele?.avatar, description: performer_ele?.desc
description: performer_ele?.desc });
}); }
} } catch (e) {
} catch (e) { logDebug(e);
logDebug(e); }
} }
} if (getType === WebHonorType.PERFROMER || getType === WebHonorType.ALL) {
if (getType === WebHonorType.PERFROMER || getType === WebHonorType.ALL) { try {
try { const RetInternal = await getDataInternal(groupCode, 3);
let RetInternal = await getDataInternal(groupCode, 3); if (!RetInternal) {
if (!RetInternal) { throw new Error('获取群聊炽焰失败');
throw new Error('获取群聊炽焰失败'); }
} HonorInfo.legend_list = [];
HonorInfo.legend_list = []; for (const legend_ele of RetInternal) {
for (const legend_ele of RetInternal) { HonorInfo.legend_list.push({
HonorInfo.legend_list.push({ user_id: legend_ele?.uin,
user_id: legend_ele?.uin, nickname: legend_ele?.name,
nickname: legend_ele?.name, avatar: legend_ele?.avatar,
avatar: legend_ele?.avatar, desc: legend_ele?.description
desc: legend_ele?.description });
}); }
} } catch (e) {
} catch (e) { logDebug('获取群聊炽焰失败', e);
logDebug('获取群聊炽焰失败', e); }
} }
} if (getType === WebHonorType.EMOTION || getType === WebHonorType.ALL) {
if (getType === WebHonorType.EMOTION || getType === WebHonorType.ALL) { try {
try { const RetInternal = await getDataInternal(groupCode, 6);
let RetInternal = await getDataInternal(groupCode, 6); if (!RetInternal) {
if (!RetInternal) { throw new Error('获取快乐源泉失败');
throw new Error('获取快乐源泉失败'); }
} HonorInfo.emotion_list = [];
HonorInfo.emotion_list = []; for (const emotion_ele of RetInternal) {
for (const emotion_ele of RetInternal) { HonorInfo.emotion_list.push({
HonorInfo.emotion_list.push({ user_id: emotion_ele?.uin,
user_id: emotion_ele?.uin, nickname: emotion_ele?.name,
nickname: emotion_ele?.name, avatar: emotion_ele?.avatar,
avatar: emotion_ele?.avatar, desc: emotion_ele?.description
desc: emotion_ele?.description });
}); }
} } catch (e) {
} catch (e) { logDebug('获取快乐源泉失败', e);
logDebug('获取快乐源泉失败', e); }
} }
} //冒尖小春笋好像已经被tx扬了
//冒尖小春笋好像已经被tx扬了 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

@ -45,17 +45,17 @@ export class NapCatCore {
MsgApi: new NTQQMsgApi(this.context,this), MsgApi: new NTQQMsgApi(this.context,this),
UserApi: new NTQQUserApi(this.context,this), UserApi: new NTQQUserApi(this.context,this),
GroupApi: new NTQQGroupApi(this.context,this) GroupApi: new NTQQGroupApi(this.context,this)
} };
} }
getApiContext() { getApiContext() {
return this.ApiContext; return this.ApiContext;
} }
// Renamed from 'InitDataListener' // Renamed from 'InitDataListener'
async initNapCatCoreListeners() { async initNapCatCoreListeners() {
let msgListener = new MsgListener(); const msgListener = new MsgListener();
msgListener.onRecvMsg = (msg) => { msgListener.onRecvMsg = (msg) => {
console.log("RecvMsg", msg); console.log("RecvMsg", msg);
} };
//await sleep(2500); //await sleep(2500);
this.context.session.getMsgService().addKernelMsgListener( this.context.session.getMsgService().addKernelMsgListener(
new this.context.wrapper.NodeIKernelMsgListener(proxiedListenerOf(msgListener, this.context.logger)) new this.context.wrapper.NodeIKernelMsgListener(proxiedListenerOf(msgListener, this.context.logger))

View File

@ -18,7 +18,7 @@ export interface CacheScanResult {
export interface ChatCacheList { export interface ChatCacheList {
pageCount: number; pageCount: number;
infos: ChatCacheListItem[] infos: ChatCacheListItem[]
}; }
export interface ChatCacheListItem { export interface ChatCacheListItem {
chatType: ChatType; chatType: ChatType;

View File

@ -3,4 +3,4 @@ export * from './group';
export * from './msg'; export * from './msg';
export * from './notify'; export * from './notify';
export * from './cache'; export * from './cache';
export * from './system' export * from './system';

View File

@ -504,7 +504,7 @@ export interface PicElement {
thumbPath: Map<number, string>; thumbPath: Map<number, string>;
originImageMd5?: string; originImageMd5?: string;
originImageUrl?: string; // http url, 没有hosthost是https://gchat.qpic.cn/, 带download参数的是https://multimedia.nt.qq.com.cn originImageUrl?: string; // http url, 没有hosthost是https://gchat.qpic.cn/, 带download参数的是https://multimedia.nt.qq.com.cn
}; }
export enum GrayTipElementSubType { export enum GrayTipElementSubType {
INVITE_NEW_MEMBER = 12, INVITE_NEW_MEMBER = 12,

View File

@ -1,4 +1,4 @@
import { SelfInfo } from "./user" import { SelfInfo } from "./user";
export interface LineDevice { export interface LineDevice {
instanceId: number instanceId: number
@ -13,4 +13,4 @@ export interface OBLineDevice {
export interface CoreCache { export interface CoreCache {
selfInfo: SelfInfo, selfInfo: SelfInfo,
DeviceList: OBLineDevice[] DeviceList: OBLineDevice[]
} }

View File

@ -8,35 +8,35 @@ interface ServerRkeyData {
} }
export class RkeyManager { export class RkeyManager {
serverUrl: string = ''; serverUrl: string = '';
private rkeyData: ServerRkeyData = { private rkeyData: ServerRkeyData = {
group_rkey: '', group_rkey: '',
private_rkey: '', private_rkey: '',
expired_time: 0 expired_time: 0
}; };
logger: LogWrapper; logger: LogWrapper;
constructor(serverUrl: string, logger: LogWrapper) { constructor(serverUrl: string, logger: LogWrapper) {
this.logger = logger; this.logger = logger;
this.serverUrl = serverUrl; this.serverUrl = serverUrl;
} }
async getRkey() { async getRkey() {
if (this.isExpired()) { if (this.isExpired()) {
try { try {
await this.refreshRkey(); await this.refreshRkey();
} catch (e) { } catch (e) {
this.logger.logError('获取rkey失败', e); this.logger.logError('获取rkey失败', e);
} }
}
return this.rkeyData;
} }
return this.rkeyData;
}
isExpired(): boolean { isExpired(): boolean {
const now = new Date().getTime() / 1000; const now = new Date().getTime() / 1000;
// console.log(`now: ${now}, expired_time: ${this.rkeyData.expired_time}`); // console.log(`now: ${now}, expired_time: ${this.rkeyData.expired_time}`);
return now > this.rkeyData.expired_time; return now > this.rkeyData.expired_time;
} }
async refreshRkey(): Promise<any> { async refreshRkey(): Promise<any> {
//刷新rkey //刷新rkey
this.rkeyData = await RequestUtil.HttpGetJson<ServerRkeyData>(this.serverUrl, 'GET'); this.rkeyData = await RequestUtil.HttpGetJson<ServerRkeyData>(this.serverUrl, 'GET');
} }
} }

View File

@ -2,4 +2,4 @@ export * from './core';
export * from './wrapper'; export * from './wrapper';
export * from './entities'; export * from './entities';
export * from './services'; export * from './services';
export * from './listeners' export * from './listeners';

View File

@ -46,57 +46,57 @@ export interface NodeIKernelBuddyListener extends IBuddyListener {
} }
export class BuddyListener implements IBuddyListener { export class BuddyListener implements IBuddyListener {
onBuddyListChangedV2(arg: unknown): void { onBuddyListChangedV2(arg: unknown): void {
//throw new Error('Method not implemented.'); //throw new Error('Method not implemented.');
} }
onAddBuddyNeedVerify(arg: unknown) { onAddBuddyNeedVerify(arg: unknown) {
} }
onAddMeSettingChanged(arg: unknown) { onAddMeSettingChanged(arg: unknown) {
} }
onAvatarUrlUpdated(arg: unknown) { onAvatarUrlUpdated(arg: unknown) {
} }
onBlockChanged(arg: unknown) { onBlockChanged(arg: unknown) {
} }
onBuddyDetailInfoChange(arg: unknown) { onBuddyDetailInfoChange(arg: unknown) {
} }
onBuddyInfoChange(arg: unknown) { onBuddyInfoChange(arg: unknown) {
} }
onBuddyListChange(arg: OnBuddyChangeParams): void { onBuddyListChange(arg: OnBuddyChangeParams): void {
} }
onBuddyRemarkUpdated(arg: unknown): void { onBuddyRemarkUpdated(arg: unknown): void {
} }
onBuddyReqChange(arg: FriendRequestNotify): void { onBuddyReqChange(arg: FriendRequestNotify): void {
} }
onBuddyReqUnreadCntChange(arg: unknown): void { onBuddyReqUnreadCntChange(arg: unknown): void {
} }
onCheckBuddySettingResult(arg: unknown): void { onCheckBuddySettingResult(arg: unknown): void {
} }
onDelBatchBuddyInfos(arg: unknown): void { onDelBatchBuddyInfos(arg: unknown): void {
} }
onDoubtBuddyReqChange(arg: unknown): void { onDoubtBuddyReqChange(arg: unknown): void {
} }
onDoubtBuddyReqUnreadNumChange(arg: unknown): void { onDoubtBuddyReqUnreadNumChange(arg: unknown): void {
} }
onNickUpdated(arg: unknown): void { onNickUpdated(arg: unknown): void {
} }
onSmartInfos(arg: unknown): void { onSmartInfos(arg: unknown): void {
} }
onSpacePermissionInfos(arg: unknown): void { onSpacePermissionInfos(arg: unknown): void {
} }
} }

View File

@ -15,13 +15,13 @@ export interface NodeIKernelFileAssistantListener extends IKernelFileAssistantLi
} }
export class KernelFileAssistantListener implements IKernelFileAssistantListener { export class KernelFileAssistantListener implements IKernelFileAssistantListener {
onFileStatusChanged(...args: unknown[]) { } onFileStatusChanged(...args: unknown[]) { }
onSessionListChanged(...args: unknown[]) { } onSessionListChanged(...args: unknown[]) { }
onSessionChanged(...args: unknown[]) { } onSessionChanged(...args: unknown[]) { }
onFileListChanged(...args: unknown[]) { } onFileListChanged(...args: unknown[]) { }
onFileSearch(...args: unknown[]) { } onFileSearch(...args: unknown[]) { }
} }

View File

@ -62,179 +62,179 @@ export interface NodeIKernelGroupListener extends IGroupListener {
} }
export class GroupListener implements IGroupListener { export class GroupListener implements IGroupListener {
// 发现于Win 9.9.9 23159 // 发现于Win 9.9.9 23159
onGroupMemberLevelInfoChange(...args: unknown[]): void { onGroupMemberLevelInfoChange(...args: unknown[]): void {
} }
onGetGroupBulletinListResult(...args: unknown[]) { onGetGroupBulletinListResult(...args: unknown[]) {
} }
onGroupAllInfoChange(...args: unknown[]) { onGroupAllInfoChange(...args: unknown[]) {
} }
onGroupBulletinChange(...args: unknown[]) { onGroupBulletinChange(...args: unknown[]) {
} }
onGroupBulletinRemindNotify(...args: unknown[]) { onGroupBulletinRemindNotify(...args: unknown[]) {
} }
onGroupArkInviteStateResult(...args: unknown[]) { onGroupArkInviteStateResult(...args: unknown[]) {
} }
onGroupBulletinRichMediaDownloadComplete(...args: unknown[]) { onGroupBulletinRichMediaDownloadComplete(...args: unknown[]) {
} }
onGroupConfMemberChange(...args: unknown[]) { onGroupConfMemberChange(...args: unknown[]) {
} }
onGroupDetailInfoChange(...args: unknown[]) { onGroupDetailInfoChange(...args: unknown[]) {
} }
onGroupExtListUpdate(...args: unknown[]) { onGroupExtListUpdate(...args: unknown[]) {
} }
onGroupFirstBulletinNotify(...args: unknown[]) { onGroupFirstBulletinNotify(...args: unknown[]) {
} }
onGroupListUpdate(updateType: GroupListUpdateType, groupList: Group[]) { onGroupListUpdate(updateType: GroupListUpdateType, groupList: Group[]) {
} }
onGroupNotifiesUpdated(dboubt: boolean, notifies: GroupNotify[]) { onGroupNotifiesUpdated(dboubt: boolean, notifies: GroupNotify[]) {
} }
onGroupBulletinRichMediaProgressUpdate(...args: unknown[]) { onGroupBulletinRichMediaProgressUpdate(...args: unknown[]) {
} }
onGroupNotifiesUnreadCountUpdated(...args: unknown[]) { onGroupNotifiesUnreadCountUpdated(...args: unknown[]) {
} }
onGroupSingleScreenNotifies(doubt: boolean, seq: string, notifies: GroupNotify[]) { onGroupSingleScreenNotifies(doubt: boolean, seq: string, notifies: GroupNotify[]) {
} }
onGroupsMsgMaskResult(...args: unknown[]) { onGroupsMsgMaskResult(...args: unknown[]) {
} }
onGroupStatisticInfoChange(...args: unknown[]) { onGroupStatisticInfoChange(...args: unknown[]) {
} }
onJoinGroupNotify(...args: unknown[]) { onJoinGroupNotify(...args: unknown[]) {
} }
onJoinGroupNoVerifyFlag(...args: unknown[]) { onJoinGroupNoVerifyFlag(...args: unknown[]) {
} }
onMemberInfoChange(groupCode: string, changeType: number, members: Map<string, GroupMember>) { onMemberInfoChange(groupCode: string, changeType: number, members: Map<string, GroupMember>) {
} }
onMemberListChange(arg: { onMemberListChange(arg: {
sceneId: string, sceneId: string,
ids: string[], ids: string[],
infos: Map<string, GroupMember>, // uid -> GroupMember infos: Map<string, GroupMember>, // uid -> GroupMember
finish: boolean, finish: boolean,
hasRobot: boolean hasRobot: boolean
}) { }) {
} }
onSearchMemberChange(...args: unknown[]) { onSearchMemberChange(...args: unknown[]) {
} }
onShutUpMemberListChanged(...args: unknown[]) { onShutUpMemberListChanged(...args: unknown[]) {
} }
} }
export class DebugGroupListener implements IGroupListener { export class DebugGroupListener implements IGroupListener {
onGroupMemberLevelInfoChange(...args: unknown[]): void { onGroupMemberLevelInfoChange(...args: unknown[]): void {
console.log('onGroupMemberLevelInfoChange:', ...args); console.log('onGroupMemberLevelInfoChange:', ...args);
} }
onGetGroupBulletinListResult(...args: unknown[]) { onGetGroupBulletinListResult(...args: unknown[]) {
console.log('onGetGroupBulletinListResult:', ...args); console.log('onGetGroupBulletinListResult:', ...args);
} }
onGroupAllInfoChange(...args: unknown[]) { onGroupAllInfoChange(...args: unknown[]) {
console.log('onGroupAllInfoChange:', ...args); console.log('onGroupAllInfoChange:', ...args);
} }
onGroupBulletinChange(...args: unknown[]) { onGroupBulletinChange(...args: unknown[]) {
console.log('onGroupBulletinChange:', ...args); console.log('onGroupBulletinChange:', ...args);
} }
onGroupBulletinRemindNotify(...args: unknown[]) { onGroupBulletinRemindNotify(...args: unknown[]) {
console.log('onGroupBulletinRemindNotify:', ...args); console.log('onGroupBulletinRemindNotify:', ...args);
} }
onGroupArkInviteStateResult(...args: unknown[]) { onGroupArkInviteStateResult(...args: unknown[]) {
console.log('onGroupArkInviteStateResult:', ...args); console.log('onGroupArkInviteStateResult:', ...args);
} }
onGroupBulletinRichMediaDownloadComplete(...args: unknown[]) { onGroupBulletinRichMediaDownloadComplete(...args: unknown[]) {
console.log('onGroupBulletinRichMediaDownloadComplete:', ...args); console.log('onGroupBulletinRichMediaDownloadComplete:', ...args);
} }
onGroupConfMemberChange(...args: unknown[]) { onGroupConfMemberChange(...args: unknown[]) {
console.log('onGroupConfMemberChange:', ...args); console.log('onGroupConfMemberChange:', ...args);
} }
onGroupDetailInfoChange(...args: unknown[]) { onGroupDetailInfoChange(...args: unknown[]) {
console.log('onGroupDetailInfoChange:', ...args); console.log('onGroupDetailInfoChange:', ...args);
} }
onGroupExtListUpdate(...args: unknown[]) { onGroupExtListUpdate(...args: unknown[]) {
console.log('onGroupExtListUpdate:', ...args); console.log('onGroupExtListUpdate:', ...args);
} }
onGroupFirstBulletinNotify(...args: unknown[]) { onGroupFirstBulletinNotify(...args: unknown[]) {
console.log('onGroupFirstBulletinNotify:', ...args); console.log('onGroupFirstBulletinNotify:', ...args);
} }
onGroupListUpdate(...args: unknown[]) { onGroupListUpdate(...args: unknown[]) {
console.log('onGroupListUpdate:', ...args); console.log('onGroupListUpdate:', ...args);
} }
onGroupNotifiesUpdated(...args: unknown[]) { onGroupNotifiesUpdated(...args: unknown[]) {
console.log('onGroupNotifiesUpdated:', ...args); console.log('onGroupNotifiesUpdated:', ...args);
} }
onGroupBulletinRichMediaProgressUpdate(...args: unknown[]) { onGroupBulletinRichMediaProgressUpdate(...args: unknown[]) {
console.log('onGroupBulletinRichMediaProgressUpdate:', ...args); console.log('onGroupBulletinRichMediaProgressUpdate:', ...args);
} }
onGroupNotifiesUnreadCountUpdated(...args: unknown[]) { onGroupNotifiesUnreadCountUpdated(...args: unknown[]) {
console.log('onGroupNotifiesUnreadCountUpdated:', ...args); console.log('onGroupNotifiesUnreadCountUpdated:', ...args);
} }
onGroupSingleScreenNotifies(doubt: boolean, seq: string, notifies: GroupNotify[]) { onGroupSingleScreenNotifies(doubt: boolean, seq: string, notifies: GroupNotify[]) {
console.log('onGroupSingleScreenNotifies:'); console.log('onGroupSingleScreenNotifies:');
} }
onGroupsMsgMaskResult(...args: unknown[]) { onGroupsMsgMaskResult(...args: unknown[]) {
console.log('onGroupsMsgMaskResult:', ...args); console.log('onGroupsMsgMaskResult:', ...args);
} }
onGroupStatisticInfoChange(...args: unknown[]) { onGroupStatisticInfoChange(...args: unknown[]) {
console.log('onGroupStatisticInfoChange:', ...args); console.log('onGroupStatisticInfoChange:', ...args);
} }
onJoinGroupNotify(...args: unknown[]) { onJoinGroupNotify(...args: unknown[]) {
console.log('onJoinGroupNotify:', ...args); console.log('onJoinGroupNotify:', ...args);
} }
onJoinGroupNoVerifyFlag(...args: unknown[]) { onJoinGroupNoVerifyFlag(...args: unknown[]) {
console.log('onJoinGroupNoVerifyFlag:', ...args); console.log('onJoinGroupNoVerifyFlag:', ...args);
} }
onMemberInfoChange(groupCode: string, changeType: number, members: Map<string, GroupMember>) { onMemberInfoChange(groupCode: string, changeType: number, members: Map<string, GroupMember>) {
console.log('onMemberInfoChange:', groupCode, changeType, members); console.log('onMemberInfoChange:', groupCode, changeType, members);
} }
onMemberListChange(...args: unknown[]) { onMemberListChange(...args: unknown[]) {
console.log('onMemberListChange:', ...args); console.log('onMemberListChange:', ...args);
} }
onSearchMemberChange(...args: unknown[]) { onSearchMemberChange(...args: unknown[]) {
console.log('onSearchMemberChange:', ...args); console.log('onSearchMemberChange:', ...args);
} }
onShutUpMemberListChanged(...args: unknown[]) { onShutUpMemberListChanged(...args: unknown[]) {
console.log('onShutUpMemberListChanged:', ...args); console.log('onShutUpMemberListChanged:', ...args);
} }
} }

View File

@ -40,60 +40,60 @@ export interface NodeIKernelLoginListener {
} }
export class LoginListener implements IKernelLoginListener { export class LoginListener implements IKernelLoginListener {
onLoginConnected(...args: any[]): void { onLoginConnected(...args: any[]): void {
} }
onLoginDisConnected(...args: any[]): void { onLoginDisConnected(...args: any[]): void {
} }
onLoginConnecting(...args: any[]): void { onLoginConnecting(...args: any[]): void {
} }
onQRCodeGetPicture(arg: { pngBase64QrcodeData: string, qrcodeUrl: string }): void { onQRCodeGetPicture(arg: { pngBase64QrcodeData: string, qrcodeUrl: string }): void {
// let base64Data: string = arg.pngBase64QrcodeData // let base64Data: string = arg.pngBase64QrcodeData
// base64Data = base64Data.split("data:image/png;base64,")[1] // base64Data = base64Data.split("data:image/png;base64,")[1]
// let buffer = Buffer.from(base64Data, 'base64') // let buffer = Buffer.from(base64Data, 'base64')
// console.log("onQRCodeGetPicture", arg); // console.log("onQRCodeGetPicture", arg);
} }
onQRCodeLoginPollingStarted(...args: any[]): void { onQRCodeLoginPollingStarted(...args: any[]): void {
} }
onQRCodeSessionUserScaned(...args: any[]): void { onQRCodeSessionUserScaned(...args: any[]): void {
} }
onQRCodeLoginSucceed(arg: QRCodeLoginSucceedResult): void { onQRCodeLoginSucceed(arg: QRCodeLoginSucceedResult): void {
} }
onQRCodeSessionFailed(...args: any[]): void { onQRCodeSessionFailed(...args: any[]): void {
} }
onLoginFailed(...args: any[]): void { onLoginFailed(...args: any[]): void {
} }
onLogoutSucceed(...args: any[]): void { onLogoutSucceed(...args: any[]): void {
} }
onLogoutFailed(...args: any[]): void { onLogoutFailed(...args: any[]): void {
} }
onUserLoggedIn(...args: any[]): void { onUserLoggedIn(...args: any[]): void {
} }
onQRCodeSessionQuickLoginFailed(...args: any[]): void { onQRCodeSessionQuickLoginFailed(...args: any[]): void {
} }
onPasswordLoginFailed(...args: any[]): void { onPasswordLoginFailed(...args: any[]): void {
} }
OnConfirmUnusualDeviceFailed(...args: any[]): void { OnConfirmUnusualDeviceFailed(...args: any[]): void {
} }
onQQLoginNumLimited(...args: any[]): void { onQQLoginNumLimited(...args: any[]): void {
} }
onLoginState(...args: any[]): void { onLoginState(...args: any[]): void {
} }
} }
export interface QRCodeLoginSucceedResult { export interface QRCodeLoginSucceedResult {

View File

@ -233,280 +233,280 @@ export interface NodeIKernelMsgListener extends IKernelMsgListener {
export class MsgListener implements IKernelMsgListener { export class MsgListener implements IKernelMsgListener {
onAddSendMsg(msgRecord: RawMessage) { onAddSendMsg(msgRecord: RawMessage) {
} }
onBroadcastHelperDownloadComplete(broadcastHelperTransNotifyInfo: unknown) { onBroadcastHelperDownloadComplete(broadcastHelperTransNotifyInfo: unknown) {
} }
onBroadcastHelperProgressUpdate(broadcastHelperTransNotifyInfo: unknown) { onBroadcastHelperProgressUpdate(broadcastHelperTransNotifyInfo: unknown) {
} }
onChannelFreqLimitInfoUpdate(contact: unknown, z: unknown, freqLimitInfo: unknown) { onChannelFreqLimitInfoUpdate(contact: unknown, z: unknown, freqLimitInfo: unknown) {
} }
onContactUnreadCntUpdate(hashMap: unknown) { onContactUnreadCntUpdate(hashMap: unknown) {
} }
onCustomWithdrawConfigUpdate(customWithdrawConfig: unknown) { onCustomWithdrawConfigUpdate(customWithdrawConfig: unknown) {
} }
onDraftUpdate(contact: unknown, arrayList: unknown, j2: unknown) { onDraftUpdate(contact: unknown, arrayList: unknown, j2: unknown) {
} }
onEmojiDownloadComplete(emojiNotifyInfo: unknown) { onEmojiDownloadComplete(emojiNotifyInfo: unknown) {
} }
onEmojiResourceUpdate(emojiResourceInfo: unknown) { onEmojiResourceUpdate(emojiResourceInfo: unknown) {
} }
onFeedEventUpdate(firstViewDirectMsgNotifyInfo: unknown) { onFeedEventUpdate(firstViewDirectMsgNotifyInfo: unknown) {
} }
onFileMsgCome(arrayList: unknown) { onFileMsgCome(arrayList: unknown) {
} }
onFirstViewDirectMsgUpdate(firstViewDirectMsgNotifyInfo: unknown) { onFirstViewDirectMsgUpdate(firstViewDirectMsgNotifyInfo: unknown) {
} }
onFirstViewGroupGuildMapping(arrayList: unknown) { onFirstViewGroupGuildMapping(arrayList: unknown) {
} }
onGrabPasswordRedBag(i2: unknown, str: unknown, i3: unknown, recvdOrder: unknown, msgRecord: unknown) { onGrabPasswordRedBag(i2: unknown, str: unknown, i3: unknown, recvdOrder: unknown, msgRecord: unknown) {
} }
onGroupFileInfoAdd(groupItem: unknown) { onGroupFileInfoAdd(groupItem: unknown) {
} }
onGroupFileInfoUpdate(groupFileListResult: onGroupFileInfoUpdateParamType) { onGroupFileInfoUpdate(groupFileListResult: onGroupFileInfoUpdateParamType) {
} }
onGroupGuildUpdate(groupGuildNotifyInfo: unknown) { onGroupGuildUpdate(groupGuildNotifyInfo: unknown) {
} }
onGroupTransferInfoAdd(groupItem: unknown) { onGroupTransferInfoAdd(groupItem: unknown) {
} }
onGroupTransferInfoUpdate(groupFileListResult: unknown) { onGroupTransferInfoUpdate(groupFileListResult: unknown) {
} }
onGuildInteractiveUpdate(guildInteractiveNotificationItem: unknown) { onGuildInteractiveUpdate(guildInteractiveNotificationItem: unknown) {
} }
onGuildMsgAbFlagChanged(guildMsgAbFlag: unknown) { onGuildMsgAbFlagChanged(guildMsgAbFlag: unknown) {
} }
onGuildNotificationAbstractUpdate(guildNotificationAbstractInfo: unknown) { onGuildNotificationAbstractUpdate(guildNotificationAbstractInfo: unknown) {
} }
onHitCsRelatedEmojiResult(downloadRelateEmojiResultInfo: unknown) { onHitCsRelatedEmojiResult(downloadRelateEmojiResultInfo: unknown) {
} }
onHitEmojiKeywordResult(hitRelatedEmojiWordsResult: unknown) { onHitEmojiKeywordResult(hitRelatedEmojiWordsResult: unknown) {
} }
onHitRelatedEmojiResult(relatedWordEmojiInfo: unknown) { onHitRelatedEmojiResult(relatedWordEmojiInfo: unknown) {
} }
onImportOldDbProgressUpdate(importOldDbMsgNotifyInfo: unknown) { onImportOldDbProgressUpdate(importOldDbMsgNotifyInfo: unknown) {
} }
onInputStatusPush(inputStatusInfo: unknown) { onInputStatusPush(inputStatusInfo: unknown) {
} }
onKickedOffLine(kickedInfo: unknown) { onKickedOffLine(kickedInfo: unknown) {
} }
onLineDev(arrayList: unknown) { onLineDev(arrayList: unknown) {
} }
onLogLevelChanged(j2: unknown) { onLogLevelChanged(j2: unknown) {
} }
onMsgAbstractUpdate(arrayList: unknown) { onMsgAbstractUpdate(arrayList: unknown) {
} }
onMsgBoxChanged(arrayList: unknown) { onMsgBoxChanged(arrayList: unknown) {
} }
onMsgDelete(contact: unknown, arrayList: unknown) { onMsgDelete(contact: unknown, arrayList: unknown) {
} }
onMsgEventListUpdate(hashMap: unknown) { onMsgEventListUpdate(hashMap: unknown) {
} }
onMsgInfoListAdd(arrayList: unknown) { onMsgInfoListAdd(arrayList: unknown) {
} }
onMsgInfoListUpdate(msgList: RawMessage[]) { onMsgInfoListUpdate(msgList: RawMessage[]) {
} }
onMsgQRCodeStatusChanged(i2: unknown) { onMsgQRCodeStatusChanged(i2: unknown) {
} }
onMsgRecall(i2: unknown, str: unknown, j2: unknown) { onMsgRecall(i2: unknown, str: unknown, j2: unknown) {
} }
onMsgSecurityNotify(msgRecord: unknown) { onMsgSecurityNotify(msgRecord: unknown) {
} }
onMsgSettingUpdate(msgSetting: unknown) { onMsgSettingUpdate(msgSetting: unknown) {
} }
onNtFirstViewMsgSyncEnd() { onNtFirstViewMsgSyncEnd() {
} }
onNtMsgSyncEnd() { onNtMsgSyncEnd() {
} }
onNtMsgSyncStart() { onNtMsgSyncStart() {
} }
onReadFeedEventUpdate(firstViewDirectMsgNotifyInfo: unknown) { onReadFeedEventUpdate(firstViewDirectMsgNotifyInfo: unknown) {
} }
onRecvGroupGuildFlag(i2: unknown) { onRecvGroupGuildFlag(i2: unknown) {
} }
onRecvMsg(arrayList: RawMessage[]) { onRecvMsg(arrayList: RawMessage[]) {
} }
onRecvMsgSvrRspTransInfo(j2: unknown, contact: unknown, i2: unknown, i3: unknown, str: unknown, bArr: unknown) { onRecvMsgSvrRspTransInfo(j2: unknown, contact: unknown, i2: unknown, i3: unknown, str: unknown, bArr: unknown) {
} }
onRecvOnlineFileMsg(arrayList: unknown) { onRecvOnlineFileMsg(arrayList: unknown) {
} }
onRecvS2CMsg(arrayList: unknown) { onRecvS2CMsg(arrayList: unknown) {
} }
onRecvSysMsg(arrayList: unknown) { onRecvSysMsg(arrayList: unknown) {
} }
onRecvUDCFlag(i2: unknown) { onRecvUDCFlag(i2: unknown) {
} }
onRichMediaDownloadComplete(fileTransNotifyInfo: OnRichMediaDownloadCompleteParams) { onRichMediaDownloadComplete(fileTransNotifyInfo: OnRichMediaDownloadCompleteParams) {
} }
onRichMediaProgerssUpdate(fileTransNotifyInfo: unknown) { onRichMediaProgerssUpdate(fileTransNotifyInfo: unknown) {
} }
onRichMediaUploadComplete(fileTransNotifyInfo: unknown) { onRichMediaUploadComplete(fileTransNotifyInfo: unknown) {
} }
onSearchGroupFileInfoUpdate(searchGroupFileResult: unknown) { onSearchGroupFileInfoUpdate(searchGroupFileResult: unknown) {
} }
onSendMsgError(j2: unknown, contact: unknown, i2: unknown, str: unknown) { onSendMsgError(j2: unknown, contact: unknown, i2: unknown, str: unknown) {
} }
onSysMsgNotification(i2: unknown, j2: unknown, j3: unknown, arrayList: unknown) { onSysMsgNotification(i2: unknown, j2: unknown, j3: unknown, arrayList: unknown) {
} }
onTempChatInfoUpdate(tempChatInfo: TempOnRecvParams) { onTempChatInfoUpdate(tempChatInfo: TempOnRecvParams) {
} }
onUnreadCntAfterFirstView(hashMap: unknown) { onUnreadCntAfterFirstView(hashMap: unknown) {
} }
onUnreadCntUpdate(hashMap: unknown) { onUnreadCntUpdate(hashMap: unknown) {
} }
onUserChannelTabStatusChanged(z: unknown) { onUserChannelTabStatusChanged(z: unknown) {
} }
onUserOnlineStatusChanged(z: unknown) { onUserOnlineStatusChanged(z: unknown) {
} }
onUserTabStatusChanged(arrayList: unknown) { onUserTabStatusChanged(arrayList: unknown) {
} }
onlineStatusBigIconDownloadPush(i2: unknown, j2: unknown, str: unknown) { onlineStatusBigIconDownloadPush(i2: unknown, j2: unknown, str: unknown) {
} }
onlineStatusSmallIconDownloadPush(i2: unknown, j2: unknown, str: unknown) { onlineStatusSmallIconDownloadPush(i2: unknown, j2: unknown, str: unknown) {
} }
// 第一次发现于Linux // 第一次发现于Linux
onUserSecQualityChanged(...args: unknown[]) { onUserSecQualityChanged(...args: unknown[]) {
} }
onMsgWithRichLinkInfoUpdate(...args: unknown[]) { onMsgWithRichLinkInfoUpdate(...args: unknown[]) {
} }
onRedTouchChanged(...args: unknown[]) { onRedTouchChanged(...args: unknown[]) {
} }
// 第一次发现于Win 9.9.9-23159 // 第一次发现于Win 9.9.9-23159
onBroadcastHelperProgerssUpdate(...args: unknown[]) { onBroadcastHelperProgerssUpdate(...args: unknown[]) {
} }
} }

View File

@ -18,26 +18,26 @@ export interface NodeIKernelProfileListener extends IProfileListener {
} }
export class ProfileListener implements IProfileListener { export class ProfileListener implements IProfileListener {
onUserDetailInfoChanged(arg: UserDetailInfoListenerArg): void { onUserDetailInfoChanged(arg: UserDetailInfoListenerArg): void {
} }
onProfileSimpleChanged(...args: unknown[]) { onProfileSimpleChanged(...args: unknown[]) {
} }
onProfileDetailInfoChanged(profile: User) { onProfileDetailInfoChanged(profile: User) {
} }
onStatusUpdate(...args: unknown[]) { onStatusUpdate(...args: unknown[]) {
} }
onSelfStatusChanged(...args: unknown[]) { onSelfStatusChanged(...args: unknown[]) {
} }
onStrangerRemarkChanged(...args: unknown[]) { onStrangerRemarkChanged(...args: unknown[]) {
} }
} }

View File

@ -32,7 +32,7 @@ export class KernelRecentContactListener implements IKernelRecentContactListener
onGuildDisplayRecentContactListChanged(...args: unknown[]) { onGuildDisplayRecentContactListChanged(...args: unknown[]) {
} }
onRecentContactListChanged(...args: unknown[]) { onRecentContactListChanged(...args: unknown[]) {

View File

@ -18,27 +18,27 @@ export interface NodeIKernelSessionListener extends ISessionListener {
} }
export class SessionListener implements ISessionListener { export class SessionListener implements ISessionListener {
onNTSessionCreate(args: unknown) { onNTSessionCreate(args: unknown) {
} }
onGProSessionCreate(args: unknown) { onGProSessionCreate(args: unknown) {
} }
onSessionInitComplete(args: unknown) { onSessionInitComplete(args: unknown) {
} }
onOpentelemetryInit(args: unknown) { onOpentelemetryInit(args: unknown) {
} }
onUserOnlineResult(args: unknown) { onUserOnlineResult(args: unknown) {
} }
onGetSelfTinyId(args: unknown) { onGetSelfTinyId(args: unknown) {
} }
} }

View File

@ -1,10 +1,10 @@
import { NodeIKernelGroupListener } from '@/core/listeners/NodeIKernelGroupListener'; import { NodeIKernelGroupListener } from '@/core/listeners/NodeIKernelGroupListener';
import { import {
GroupExtParam, GroupExtParam,
GroupMember, GroupMember,
GroupMemberRole, GroupMemberRole,
GroupNotifyTypes, GroupNotifyTypes,
GroupRequestOperateTypes, GroupRequestOperateTypes,
} from '@/core/entities'; } from '@/core/entities';
import { GeneralCallResult } from '@/core/services/common'; import { GeneralCallResult } from '@/core/services/common';
@ -171,7 +171,7 @@ export interface NodeIKernelGroupService {
clearGroupNotifies(groupCode: string): void; clearGroupNotifies(groupCode: string): void;
getGroupNotifiesUnreadCount(unknown: Boolean): Promise<GeneralCallResult>; getGroupNotifiesUnreadCount(unknown: boolean): Promise<GeneralCallResult>;
clearGroupNotifiesUnreadCount(groupCode: string): void; clearGroupNotifiesUnreadCount(groupCode: string): void;

View File

@ -13,4 +13,4 @@ export * from './NodeIKernelStorageCleanService';
export * from './NodeIKernelRobotService'; export * from './NodeIKernelRobotService';
export * from './NodeIKernelRichMediaService'; export * from './NodeIKernelRichMediaService';
export * from './NodeIKernelDbToolsService'; export * from './NodeIKernelDbToolsService';
export * from './NodeIKernelTipOffService' export * from './NodeIKernelTipOffService';

View File

@ -6,7 +6,7 @@ import { getMachineId, hostname, systemName, systemVersion } from "@/common/util
export async function genSessionConfig(QQVersionAppid: string, QQVersion: string, selfUin: string, selfUid: string, account_path: string): Promise<WrapperSessionInitConfig> { export async function genSessionConfig(QQVersionAppid: string, QQVersion: string, selfUin: string, selfUid: string, account_path: string): Promise<WrapperSessionInitConfig> {
const downloadPath = path.join(account_path, 'NapCat', 'temp'); const downloadPath = path.join(account_path, 'NapCat', 'temp');
fs.mkdirSync(downloadPath, { recursive: true }); fs.mkdirSync(downloadPath, { recursive: true });
let guid: string = await getMachineId();//26702 支持JS获取guid值 在LoginService中获取 TODO mlikiow a const guid: string = await getMachineId();//26702 支持JS获取guid值 在LoginService中获取 TODO mlikiow a
const config: WrapperSessionInitConfig = { const config: WrapperSessionInitConfig = {
selfUin, selfUin,
selfUid, selfUid,