mirror of
https://github.com/NapNeko/NapCatQQ.git
synced 2025-07-19 12:03:37 +00:00
Compare commits
51 Commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
67fb74d3c2 | ||
![]() |
dc04cfc1b3 | ||
![]() |
6b346ee1de | ||
![]() |
73b6d3be84 | ||
![]() |
1ff6ce2343 | ||
![]() |
c145935d46 | ||
![]() |
e9ede6924e | ||
![]() |
515a21761d | ||
![]() |
8d6397028b | ||
![]() |
7e74578312 | ||
![]() |
166c30fe2c | ||
![]() |
66c1bab629 | ||
![]() |
7ae8fd60c4 | ||
![]() |
96b5bec5ab | ||
![]() |
d9851493df | ||
![]() |
5548644aeb | ||
![]() |
e3fcd91b2d | ||
![]() |
58cd38c4a8 | ||
![]() |
f0e376d06b | ||
![]() |
3dc529edf4 | ||
![]() |
afcdd01c0d | ||
![]() |
1164877e9a | ||
![]() |
fe92a449ba | ||
![]() |
401b0e2bd0 | ||
![]() |
cf9c71fcc1 | ||
![]() |
15a2400069 | ||
![]() |
d68a39b49e | ||
![]() |
066ca22e24 | ||
![]() |
0418b926fe | ||
![]() |
be40bbdf40 | ||
![]() |
df4f42e79e | ||
![]() |
5f80058f70 | ||
![]() |
0cbe59052d | ||
![]() |
af28a26e37 | ||
![]() |
70c596df93 | ||
![]() |
748b51428c | ||
![]() |
8ad746397c | ||
![]() |
45baed2f9a | ||
![]() |
74185f2d33 | ||
![]() |
90a91e4105 | ||
![]() |
11aa3a0315 | ||
![]() |
0c2e39214f | ||
![]() |
d89620d7a6 | ||
![]() |
edf80775b7 | ||
![]() |
46e56ac726 | ||
![]() |
40b2f6bfd6 | ||
![]() |
911e4921e2 | ||
![]() |
1db9bb419d | ||
![]() |
c6241a94e3 | ||
![]() |
1cbf75ca36 | ||
![]() |
8f85c897c8 |
@@ -4,7 +4,7 @@
|
|||||||
"name": "NapCatQQ",
|
"name": "NapCatQQ",
|
||||||
"slug": "NapCat.Framework",
|
"slug": "NapCat.Framework",
|
||||||
"description": "高性能的 OneBot 11 协议实现",
|
"description": "高性能的 OneBot 11 协议实现",
|
||||||
"version": "2.4.6",
|
"version": "2.5.3",
|
||||||
"icon": "./logo.png",
|
"icon": "./logo.png",
|
||||||
"authors": [
|
"authors": [
|
||||||
{
|
{
|
||||||
|
@@ -2,7 +2,7 @@
|
|||||||
"name": "napcat",
|
"name": "napcat",
|
||||||
"private": true,
|
"private": true,
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"version": "2.4.6",
|
"version": "2.5.3",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"build:framework": "vite build --mode framework",
|
"build:framework": "vite build --mode framework",
|
||||||
"build:shell": "vite build --mode shell",
|
"build:shell": "vite build --mode shell",
|
||||||
|
@@ -1,4 +1,3 @@
|
|||||||
import fs from 'fs';
|
|
||||||
import fsPromise from 'fs/promises';
|
import fsPromise from 'fs/promises';
|
||||||
import path from 'node:path';
|
import path from 'node:path';
|
||||||
import { randomUUID } from 'crypto';
|
import { randomUUID } from 'crypto';
|
||||||
@@ -12,7 +11,7 @@ const FFMPEG_PATH = process.env.FFMPEG_PATH || 'ffmpeg';
|
|||||||
|
|
||||||
async function guessDuration(pttPath: string, logger: LogWrapper) {
|
async function guessDuration(pttPath: string, logger: LogWrapper) {
|
||||||
const pttFileInfo = await fsPromise.stat(pttPath);
|
const pttFileInfo = await fsPromise.stat(pttPath);
|
||||||
let duration = Math.max(1, Math.floor(pttFileInfo.size / 1024 / 3)); // 3kb/s
|
const duration = Math.max(1, Math.floor(pttFileInfo.size / 1024 / 3)); // 3kb/s
|
||||||
logger.log('通过文件大小估算语音的时长:', duration);
|
logger.log('通过文件大小估算语音的时长:', duration);
|
||||||
return duration;
|
return duration;
|
||||||
}
|
}
|
||||||
@@ -20,7 +19,7 @@ async function guessDuration(pttPath: string, logger: LogWrapper) {
|
|||||||
async function convert(filePath: string, pcmPath: string, logger: LogWrapper): Promise<Buffer> {
|
async function convert(filePath: string, pcmPath: string, logger: LogWrapper): Promise<Buffer> {
|
||||||
return new Promise<Buffer>((resolve, reject) => {
|
return new Promise<Buffer>((resolve, reject) => {
|
||||||
const cp = spawn(FFMPEG_PATH, ['-y', '-i', filePath, '-ar', '24000', '-ac', '1', '-f', 's16le', pcmPath]);
|
const cp = spawn(FFMPEG_PATH, ['-y', '-i', filePath, '-ar', '24000', '-ac', '1', '-f', 's16le', pcmPath]);
|
||||||
cp.on('error', err => {
|
cp.on('error', (err: Error) => {
|
||||||
logger.log('FFmpeg处理转换出错: ', err.message);
|
logger.log('FFmpeg处理转换出错: ', err.message);
|
||||||
reject(err);
|
reject(err);
|
||||||
});
|
});
|
||||||
@@ -41,12 +40,14 @@ async function convert(filePath: string, pcmPath: string, logger: LogWrapper): P
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
async function handleWavFile(file: Buffer, filePath: string, pcmPath: string, logger: LogWrapper): Promise<Buffer> {
|
async function handleWavFile(
|
||||||
|
file: Buffer, filePath: string, pcmPath: string, logger: LogWrapper
|
||||||
|
): Promise<{input: Buffer, sampleRate: number}> {
|
||||||
const { fmt } = getWavFileInfo(file);
|
const { fmt } = getWavFileInfo(file);
|
||||||
if (!ALLOW_SAMPLE_RATE.includes(fmt.sampleRate)) {
|
if (!ALLOW_SAMPLE_RATE.includes(fmt.sampleRate)) {
|
||||||
return await convert(filePath, pcmPath, logger);
|
return {input: await convert(filePath, pcmPath, logger), sampleRate: 24000};
|
||||||
}
|
}
|
||||||
return file;
|
return {input: file, sampleRate: fmt.sampleRate};
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function encodeSilk(filePath: string, TEMP_DIR: string, logger: LogWrapper) {
|
export async function encodeSilk(filePath: string, TEMP_DIR: string, logger: LogWrapper) {
|
||||||
@@ -56,8 +57,10 @@ export async function encodeSilk(filePath: string, TEMP_DIR: string, logger: Log
|
|||||||
if (!isSilk(file)) {
|
if (!isSilk(file)) {
|
||||||
logger.log(`语音文件${filePath}需要转换成silk`);
|
logger.log(`语音文件${filePath}需要转换成silk`);
|
||||||
const pcmPath = `${pttPath}.pcm`;
|
const pcmPath = `${pttPath}.pcm`;
|
||||||
const input = isWav(file) ? await handleWavFile(file, filePath, pcmPath, logger) : await convert(filePath, pcmPath, logger);
|
const { input, sampleRate } = isWav(file)
|
||||||
const silk = await encode(input, 24000);
|
? (await handleWavFile(file, filePath, pcmPath, logger))
|
||||||
|
: {input: await convert(filePath, pcmPath, logger), sampleRate: 24000};
|
||||||
|
const silk = await encode(input, sampleRate);
|
||||||
await fsPromise.writeFile(pttPath, silk.data);
|
await fsPromise.writeFile(pttPath, silk.data);
|
||||||
logger.log(`语音文件${filePath}转换成功!`, pttPath, '时长:', silk.duration);
|
logger.log(`语音文件${filePath}转换成功!`, pttPath, '时长:', silk.duration);
|
||||||
return {
|
return {
|
||||||
|
@@ -128,6 +128,7 @@ export async function httpDownload(options: string | HttpDownloadOptions): Promi
|
|||||||
let url: string;
|
let url: string;
|
||||||
let headers: Record<string, string> = {
|
let headers: Record<string, string> = {
|
||||||
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.71 Safari/537.36',
|
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.71 Safari/537.36',
|
||||||
|
'referer': typeof options === 'string' ? options : options.url,
|
||||||
};
|
};
|
||||||
if (typeof options === 'string') {
|
if (typeof options === 'string') {
|
||||||
url = options;
|
url = options;
|
||||||
@@ -242,7 +243,6 @@ export async function uri2local(dir: string, uri: string, filename: string | und
|
|||||||
const filenameTemp = tempName + fileExt;
|
const filenameTemp = tempName + fileExt;
|
||||||
const filePath = path.join(dir, filenameTemp);
|
const filePath = path.join(dir, filenameTemp);
|
||||||
fs.copyFileSync(HandledUri, filePath);
|
fs.copyFileSync(HandledUri, filePath);
|
||||||
//console.log('复制文件到临时文件', HandledUri, filePath);
|
|
||||||
return { success: true, errMsg: '', fileName: filename, ext: fileExt, path: filePath };
|
return { success: true, errMsg: '', fileName: filename, ext: fileExt, path: filePath };
|
||||||
}
|
}
|
||||||
//接下来都要有文件名
|
//接下来都要有文件名
|
||||||
@@ -250,7 +250,7 @@ export async function uri2local(dir: string, uri: string, filename: string | und
|
|||||||
if (UriType == FileUriType.Remote) {
|
if (UriType == FileUriType.Remote) {
|
||||||
const pathInfo = path.parse(decodeURIComponent(new URL(HandledUri).pathname));
|
const pathInfo = path.parse(decodeURIComponent(new URL(HandledUri).pathname));
|
||||||
if (pathInfo.name) {
|
if (pathInfo.name) {
|
||||||
let pathlen = 200 - dir.length - pathInfo.name.length;
|
const pathlen = 200 - dir.length - pathInfo.name.length;
|
||||||
filename = pathlen > 0 ? pathInfo.name.substring(0, pathlen) : pathInfo.name.substring(pathInfo.name.length, pathInfo.name.length - 10);//过长截断
|
filename = pathlen > 0 ? pathInfo.name.substring(0, pathlen) : pathInfo.name.substring(pathInfo.name.length, pathInfo.name.length - 10);//过长截断
|
||||||
if (pathInfo.ext) {
|
if (pathInfo.ext) {
|
||||||
filename += pathInfo.ext;
|
filename += pathInfo.ext;
|
||||||
@@ -260,7 +260,6 @@ export async function uri2local(dir: string, uri: string, filename: string | und
|
|||||||
const fileExt = path.extname(HandledUri).replace(/[/\\:*?"<>|]/g, '_').substring(0, 10);
|
const fileExt = path.extname(HandledUri).replace(/[/\\:*?"<>|]/g, '_').substring(0, 10);
|
||||||
const filePath = path.join(dir, tempName + fileExt);
|
const filePath = path.join(dir, tempName + fileExt);
|
||||||
const buffer = await httpDownload(HandledUri);
|
const buffer = await httpDownload(HandledUri);
|
||||||
//fs.writeFileSync(filePath, buffer);
|
|
||||||
//没有文件就创建
|
//没有文件就创建
|
||||||
fs.writeFileSync(filePath, buffer, { flag: 'wx' });
|
fs.writeFileSync(filePath, buffer, { flag: 'wx' });
|
||||||
return { success: true, errMsg: '', fileName: filename, ext: fileExt, path: filePath };
|
return { success: true, errMsg: '', fileName: filename, ext: fileExt, path: filePath };
|
||||||
|
@@ -163,8 +163,17 @@ export function isEqual(obj1: any, obj2: any) {
|
|||||||
export function getDefaultQQVersionConfigInfo(): QQVersionConfigType {
|
export function getDefaultQQVersionConfigInfo(): QQVersionConfigType {
|
||||||
if (os.platform() === 'linux') {
|
if (os.platform() === 'linux') {
|
||||||
return {
|
return {
|
||||||
baseVersion: '3.2.12-27597',
|
baseVersion: '3.2.12.27254',
|
||||||
curVersion: '3.2.12-27597',
|
curVersion: '3.2.12.27254',
|
||||||
|
prevVersion: '',
|
||||||
|
onErrorVersions: [],
|
||||||
|
buildId: '27254',
|
||||||
|
};
|
||||||
|
}
|
||||||
|
if (os.platform() === 'darwin') {
|
||||||
|
return {
|
||||||
|
baseVersion: '6.9.53.27597',
|
||||||
|
curVersion: '6.9.53.27597',
|
||||||
prevVersion: '',
|
prevVersion: '',
|
||||||
onErrorVersions: [],
|
onErrorVersions: [],
|
||||||
buildId: '27597',
|
buildId: '27597',
|
||||||
@@ -209,7 +218,8 @@ export function getQQVersionConfigPath(exePath: string = ''): string | undefined
|
|||||||
return configVersionInfoPath;
|
return configVersionInfoPath;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function calcQQLevel(level: QQLevel) {
|
export function calcQQLevel(level?: QQLevel) {
|
||||||
|
if (!level) return 0;
|
||||||
const { crownNum, sunNum, moonNum, starNum } = level;
|
const { crownNum, sunNum, moonNum, starNum } = level;
|
||||||
return crownNum * 64 + sunNum * 16 + moonNum * 4 + starNum;
|
return crownNum * 64 + sunNum * 16 + moonNum * 4 + starNum;
|
||||||
}
|
}
|
||||||
|
@@ -53,23 +53,23 @@ export class QQBasicInfoWrapper {
|
|||||||
//此方法不要直接使用
|
//此方法不要直接使用
|
||||||
getQUAInternal() {
|
getQUAInternal() {
|
||||||
switch (systemPlatform) {
|
switch (systemPlatform) {
|
||||||
case 'linux':
|
case 'linux':
|
||||||
return `V1_LNX_${this.getFullQQVesion()}_${this.getQQBuildStr()}_GW_B`;
|
return `V1_LNX_${this.getFullQQVesion()}_${this.getQQBuildStr()}_GW_B`;
|
||||||
case 'darwin':
|
case 'darwin':
|
||||||
return `V1_MAC_${this.getFullQQVesion()}_${this.getQQBuildStr()}_GW_B`;
|
return `V1_MAC_${this.getFullQQVesion()}_${this.getQQBuildStr()}_GW_B`;
|
||||||
default:
|
default:
|
||||||
return `V1_WIN_${this.getFullQQVesion()}_${this.getQQBuildStr()}_GW_B`;
|
return `V1_WIN_${this.getFullQQVesion()}_${this.getQQBuildStr()}_GW_B`;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
getAppidInternal() {
|
getAppidInternal() {
|
||||||
switch (systemPlatform) {
|
switch (systemPlatform) {
|
||||||
case 'linux':
|
case 'linux':
|
||||||
return '537243600';
|
return '537240795';
|
||||||
case 'darwin':
|
case 'darwin':
|
||||||
return '537243441';
|
return '537243538';
|
||||||
default:
|
default:
|
||||||
return '537243538';
|
return '537243441';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -1 +1 @@
|
|||||||
export const napCatVersion = '2.4.6';
|
export const napCatVersion = '2.5.3';
|
||||||
|
@@ -147,8 +147,17 @@ export class NTQQFileApi {
|
|||||||
} catch (e) {
|
} catch (e) {
|
||||||
logger.logError('获取视频信息失败,将使用默认值', e);
|
logger.logError('获取视频信息失败,将使用默认值', e);
|
||||||
}
|
}
|
||||||
let newFilePath = filePath + '.mp4';
|
|
||||||
fs.renameSync(filePath, newFilePath);
|
let fileExt = 'mp4';
|
||||||
|
try {
|
||||||
|
const tempExt = (await fileType.fileTypeFromFile(filePath))?.ext;
|
||||||
|
if (tempExt) fileExt = tempExt;
|
||||||
|
} catch (e) {
|
||||||
|
this.context.logger.logError('获取文件类型失败', e);
|
||||||
|
}
|
||||||
|
const newFilePath = filePath + '.' + fileExt;
|
||||||
|
fs.copyFileSync(filePath, newFilePath);
|
||||||
|
context.deleteAfterSentFiles.push(newFilePath);
|
||||||
filePath = newFilePath;
|
filePath = newFilePath;
|
||||||
const { fileName: _fileName, path, fileSize, md5 } = await this.core.apis.FileApi.uploadFile(filePath, ElementType.VIDEO);
|
const { fileName: _fileName, path, fileSize, md5 } = await this.core.apis.FileApi.uploadFile(filePath, ElementType.VIDEO);
|
||||||
if (fileSize === 0) {
|
if (fileSize === 0) {
|
||||||
@@ -188,11 +197,12 @@ export class NTQQFileApi {
|
|||||||
thumbPath.set(0, _thumbPath);
|
thumbPath.set(0, _thumbPath);
|
||||||
const thumbMd5 = _thumbPath ? await calculateFileMD5(_thumbPath) : '';
|
const thumbMd5 = _thumbPath ? await calculateFileMD5(_thumbPath) : '';
|
||||||
context.deleteAfterSentFiles.push(path);
|
context.deleteAfterSentFiles.push(path);
|
||||||
|
const uploadName = (fileName || _fileName).toLocaleLowerCase().endsWith('.' + fileExt.toLocaleLowerCase()) ? (fileName || _fileName) : (fileName || _fileName) + '.' + fileExt;
|
||||||
return {
|
return {
|
||||||
elementType: ElementType.VIDEO,
|
elementType: ElementType.VIDEO,
|
||||||
elementId: '',
|
elementId: '',
|
||||||
videoElement: {
|
videoElement: {
|
||||||
fileName: fileName || _fileName,
|
fileName: uploadName,
|
||||||
filePath: path,
|
filePath: path,
|
||||||
videoMd5: md5,
|
videoMd5: md5,
|
||||||
thumbMd5,
|
thumbMd5,
|
||||||
|
@@ -32,13 +32,15 @@ export class NTQQGroupApi {
|
|||||||
for (const group of this.groups) {
|
for (const group of this.groups) {
|
||||||
this.groupCache.set(group.groupCode, group);
|
this.groupCache.set(group.groupCode, group);
|
||||||
}
|
}
|
||||||
// let text = await this.context.session.getMsgService().sendSsoCmdReqByContend(
|
|
||||||
// 'LightAppSvc.mini_app_share.AdaptShareInfo',
|
|
||||||
// JSON.stringify({ data: 'test' }));
|
|
||||||
// console.log(text);
|
|
||||||
this.context.logger.logDebug(`加载${this.groups.length}个群组缓存完成`);
|
this.context.logger.logDebug(`加载${this.groups.length}个群组缓存完成`);
|
||||||
}
|
}
|
||||||
|
async getCoreAndBaseInfo(uids: string[]) {
|
||||||
|
return await this.core.eventWrapper.callNoListenerEvent(
|
||||||
|
'NodeIKernelProfileService/getCoreAndBaseInfo',
|
||||||
|
'nodeStore',
|
||||||
|
uids,
|
||||||
|
);
|
||||||
|
}
|
||||||
async fetchGroupEssenceList(groupCode: string) {
|
async fetchGroupEssenceList(groupCode: string) {
|
||||||
const pskey = (await this.core.apis.UserApi.getPSkey(['qun.qq.com'])).domainPskeyMap.get('qun.qq.com')!;
|
const pskey = (await this.core.apis.UserApi.getPSkey(['qun.qq.com'])).domainPskeyMap.get('qun.qq.com')!;
|
||||||
return this.context.session.getGroupService().fetchGroupEssenceList({
|
return this.context.session.getGroupService().fetchGroupEssenceList({
|
||||||
@@ -266,6 +268,23 @@ export class NTQQGroupApi {
|
|||||||
}
|
}
|
||||||
return member;
|
return member;
|
||||||
}
|
}
|
||||||
|
async searchGroup(groupCode: string) {
|
||||||
|
const [, ret] = await this.core.eventWrapper.callNormalEventV2(
|
||||||
|
'NodeIKernelSearchService/searchGroup',
|
||||||
|
'NodeIKernelSearchListener/onSearchGroupResult',
|
||||||
|
[{
|
||||||
|
keyWords: groupCode,
|
||||||
|
groupNum: 25,
|
||||||
|
exactSearch: false,
|
||||||
|
penetrate: ''
|
||||||
|
}],
|
||||||
|
(ret) => ret.result === 0,
|
||||||
|
(params) => !!params.groupInfos.find(g => g.groupCode === groupCode),
|
||||||
|
1,
|
||||||
|
5000
|
||||||
|
);
|
||||||
|
return ret.groupInfos.find(g => g.groupCode === groupCode);
|
||||||
|
}
|
||||||
async getGroupMemberEx(GroupCode: string, uid: string, forced = false, retry = 2) {
|
async getGroupMemberEx(GroupCode: string, uid: string, forced = false, retry = 2) {
|
||||||
const data = await solveAsyncProblem((eventWrapper: NTEventWrapper, GroupCode: string, uid: string, forced = false) => {
|
const data = await solveAsyncProblem((eventWrapper: NTEventWrapper, GroupCode: string, uid: string, forced = false) => {
|
||||||
return eventWrapper.callNormalEventV2(
|
return eventWrapper.callNormalEventV2(
|
||||||
|
@@ -94,6 +94,7 @@ export class NTQQMsgApi {
|
|||||||
pageLimit: 1,
|
pageLimit: 1,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
//@deprecated
|
||||||
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);
|
||||||
}
|
}
|
||||||
|
@@ -11,7 +11,13 @@ export class NTQQUserApi {
|
|||||||
this.context = context;
|
this.context = context;
|
||||||
this.core = core;
|
this.core = core;
|
||||||
}
|
}
|
||||||
|
//self_tind格式
|
||||||
|
async createUidFromTinyId(tinyId: string) {
|
||||||
|
return this.context.session.getMsgService().createUidFromTinyId(this.core.selfInfo.uin, tinyId);
|
||||||
|
}
|
||||||
|
async getStatusByUid(uid: string) {
|
||||||
|
return this.context.session.getProfileService().getStatus(uid);
|
||||||
|
}
|
||||||
async getProfileLike(uid: string) {
|
async getProfileLike(uid: string) {
|
||||||
return this.context.session.getProfileLikeService().getBuddyProfileLike({
|
return this.context.session.getProfileLikeService().getBuddyProfileLike({
|
||||||
friendUids: [uid],
|
friendUids: [uid],
|
||||||
@@ -24,7 +30,18 @@ export class NTQQUserApi {
|
|||||||
limit: 20,
|
limit: 20,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
async fetchOtherProfileLike(uid: string) {
|
||||||
|
return this.context.session.getProfileLikeService().getBuddyProfileLike({
|
||||||
|
friendUids: [uid],
|
||||||
|
basic: 1,
|
||||||
|
vote: 1,
|
||||||
|
favorite: 0,
|
||||||
|
userProfile: 0,
|
||||||
|
type: 1,
|
||||||
|
start: 0,
|
||||||
|
limit: 20,
|
||||||
|
});
|
||||||
|
}
|
||||||
async setLongNick(longNick: string) {
|
async setLongNick(longNick: string) {
|
||||||
return this.context.session.getProfileService().setLongNick(longNick);
|
return this.context.session.getProfileService().setLongNick(longNick);
|
||||||
}
|
}
|
||||||
|
@@ -959,3 +959,18 @@ export interface TmpChatInfo {
|
|||||||
sessionType: number;
|
sessionType: number;
|
||||||
sig: string;
|
sig: string;
|
||||||
}
|
}
|
||||||
|
export interface MsgReqType {
|
||||||
|
peer: Peer,
|
||||||
|
byType: number,
|
||||||
|
msgId: string,
|
||||||
|
msgSeq: string,
|
||||||
|
msgTime: string,
|
||||||
|
clientSeq: string,
|
||||||
|
cnt: number,
|
||||||
|
queryOrder: boolean,
|
||||||
|
includeSelf: boolean,
|
||||||
|
includeDeleteMsg: boolean,
|
||||||
|
extraCnt: number
|
||||||
|
}
|
||||||
|
//getMsgsIncludeSelf Peer必须 byType 1
|
||||||
|
//getMsgsWithMsgTimeAndClientSeqForC2C Peer必须 byType 3
|
@@ -216,7 +216,7 @@ export interface BuddyProfileLikeReq {
|
|||||||
userProfile: number;
|
userProfile: number;
|
||||||
type: number;
|
type: number;
|
||||||
start: number;
|
start: number;
|
||||||
limit: number;
|
limit?: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface QQLevel {
|
export interface QQLevel {
|
||||||
|
15
src/core/external/appid.json
vendored
15
src/core/external/appid.json
vendored
@@ -1,4 +1,14 @@
|
|||||||
{
|
{
|
||||||
|
|
||||||
|
"3.2.12-27254":{
|
||||||
|
"appid": 537240795,
|
||||||
|
"qua": "V1_LNX_NQ_3.2.12_27254_GW_B"
|
||||||
|
},
|
||||||
|
"9.9.15-27254":{
|
||||||
|
"appid": 537240709,
|
||||||
|
"qua": "V1_WIN_NQ_9.9.15_27254_GW_B"
|
||||||
|
},
|
||||||
|
|
||||||
"3.2.12-27597": {
|
"3.2.12-27597": {
|
||||||
"appid": 537243600,
|
"appid": 537243600,
|
||||||
"qua": "V1_LNX_NQ_3.2.12_27597_GW_B"
|
"qua": "V1_LNX_NQ_3.2.12_27597_GW_B"
|
||||||
@@ -10,5 +20,10 @@
|
|||||||
"6.9.53-27597": {
|
"6.9.53-27597": {
|
||||||
"appid": 537243538,
|
"appid": 537243538,
|
||||||
"qua": "V1_MAC_NQ_6.9.53_27597_GW_B"
|
"qua": "V1_MAC_NQ_6.9.53_27597_GW_B"
|
||||||
|
},
|
||||||
|
|
||||||
|
"9.9.15-28060":{
|
||||||
|
"appid": 537246092,
|
||||||
|
"qua": "V1_WIN_NQ_9.9.15_28060_GW_B"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -40,7 +40,7 @@ export class RkeyManager {
|
|||||||
|
|
||||||
async refreshRkey(): Promise<any> {
|
async refreshRkey(): Promise<any> {
|
||||||
//刷新rkey
|
//刷新rkey
|
||||||
for (let url of this.serverUrl) {
|
for (const url of this.serverUrl) {
|
||||||
try {
|
try {
|
||||||
this.rkeyData = await RequestUtil.HttpGetJson<ServerRkeyData>(url, 'GET');
|
this.rkeyData = await RequestUtil.HttpGetJson<ServerRkeyData>(url, 'GET');
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
@@ -145,7 +145,6 @@ export class NapCatCore {
|
|||||||
if (Info.status == 20) {
|
if (Info.status == 20) {
|
||||||
this.selfInfo.online = false;
|
this.selfInfo.online = false;
|
||||||
this.context.logger.log("账号状态变更为离线");
|
this.context.logger.log("账号状态变更为离线");
|
||||||
return;
|
|
||||||
} else {
|
} else {
|
||||||
this.selfInfo.online = true;
|
this.selfInfo.online = true;
|
||||||
}
|
}
|
||||||
|
97
src/core/listeners/NodeIKernelSearchListener.ts
Normal file
97
src/core/listeners/NodeIKernelSearchListener.ts
Normal file
@@ -0,0 +1,97 @@
|
|||||||
|
import { ChatType } from '@/core';
|
||||||
|
export interface SearchGroupInfo {
|
||||||
|
groupCode: string;
|
||||||
|
ownerUid: string;
|
||||||
|
groupFlag: number;
|
||||||
|
groupFlagExt: number;
|
||||||
|
maxMemberNum: number;
|
||||||
|
memberNum: number;
|
||||||
|
groupOption: number;
|
||||||
|
classExt: number;
|
||||||
|
groupName: string;
|
||||||
|
fingerMemo: string;
|
||||||
|
groupQuestion: string;
|
||||||
|
certType: number;
|
||||||
|
shutUpAllTimestamp: number;
|
||||||
|
shutUpMeTimestamp: number;
|
||||||
|
groupTypeFlag: number;
|
||||||
|
privilegeFlag: number;
|
||||||
|
groupSecLevel: number;
|
||||||
|
groupFlagExt3: number;
|
||||||
|
isConfGroup: number;
|
||||||
|
isModifyConfGroupFace: number;
|
||||||
|
isModifyConfGroupName: number;
|
||||||
|
noFigerOpenFlag: number;
|
||||||
|
noCodeFingerOpenFlag: number;
|
||||||
|
groupFlagExt4: number;
|
||||||
|
groupMemo: string;
|
||||||
|
cmdUinMsgSeq: number;
|
||||||
|
cmdUinJoinTime: number;
|
||||||
|
cmdUinUinFlag: number;
|
||||||
|
cmdUinMsgMask: number;
|
||||||
|
groupSecLevelInfo: number;
|
||||||
|
cmdUinPrivilege: number;
|
||||||
|
cmdUinFlagEx2: number;
|
||||||
|
appealDeadline: number;
|
||||||
|
remarkName: string;
|
||||||
|
isTop: boolean;
|
||||||
|
richFingerMemo: string;
|
||||||
|
groupAnswer: string;
|
||||||
|
joinGroupAuth: string;
|
||||||
|
isAllowModifyConfGroupName: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface GroupInfo {
|
||||||
|
groupCode: string;
|
||||||
|
searchGroupInfo: SearchGroupInfo;
|
||||||
|
privilege: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface GroupSearchResult {
|
||||||
|
keyWord: string;
|
||||||
|
errorCode: number;
|
||||||
|
groupInfos: GroupInfo[];
|
||||||
|
penetrate: string;
|
||||||
|
isEnd: boolean;
|
||||||
|
nextPos: number;
|
||||||
|
}
|
||||||
|
export interface NodeIKernelSearchListener {
|
||||||
|
|
||||||
|
onSearchGroupResult(params: GroupSearchResult): void;
|
||||||
|
|
||||||
|
onSearchFileKeywordsResult(params: {
|
||||||
|
searchId: string,
|
||||||
|
hasMore: boolean,
|
||||||
|
resultItems: {
|
||||||
|
chatType: ChatType,
|
||||||
|
buddyChatInfo: any[],
|
||||||
|
discussChatInfo: any[],
|
||||||
|
groupChatInfo: {
|
||||||
|
groupCode: string,
|
||||||
|
isConf: boolean,
|
||||||
|
hasModifyConfGroupFace: boolean,
|
||||||
|
hasModifyConfGroupName: boolean,
|
||||||
|
groupName: string,
|
||||||
|
remark: string
|
||||||
|
}[],
|
||||||
|
dataLineChatInfo: any[],
|
||||||
|
tmpChatInfo: any[],
|
||||||
|
msgId: string,
|
||||||
|
msgSeq: string,
|
||||||
|
msgTime: string,
|
||||||
|
senderUid: string,
|
||||||
|
senderNick: string,
|
||||||
|
senderRemark: string,
|
||||||
|
senderCard: string,
|
||||||
|
elemId: string,
|
||||||
|
elemType: number,
|
||||||
|
fileSize: string,
|
||||||
|
filePath: string,
|
||||||
|
fileName: string,
|
||||||
|
hits: {
|
||||||
|
start: number,
|
||||||
|
end: number
|
||||||
|
}[]
|
||||||
|
}[]
|
||||||
|
}): void;
|
||||||
|
}
|
@@ -1,39 +0,0 @@
|
|||||||
import { ChatType } from '@/core';
|
|
||||||
|
|
||||||
export interface NodeIKernelSearchListener_Polyfill {
|
|
||||||
onSearchFileKeywordsResult(params: {
|
|
||||||
searchId: string,
|
|
||||||
hasMore: boolean,
|
|
||||||
resultItems: {
|
|
||||||
chatType: ChatType,
|
|
||||||
buddyChatInfo: any[],
|
|
||||||
discussChatInfo: any[],
|
|
||||||
groupChatInfo: {
|
|
||||||
groupCode: string,
|
|
||||||
isConf: boolean,
|
|
||||||
hasModifyConfGroupFace: boolean,
|
|
||||||
hasModifyConfGroupName: boolean,
|
|
||||||
groupName: string,
|
|
||||||
remark: string
|
|
||||||
}[],
|
|
||||||
dataLineChatInfo: any[],
|
|
||||||
tmpChatInfo: any[],
|
|
||||||
msgId: string,
|
|
||||||
msgSeq: string,
|
|
||||||
msgTime: string,
|
|
||||||
senderUid: string,
|
|
||||||
senderNick: string,
|
|
||||||
senderRemark: string,
|
|
||||||
senderCard: string,
|
|
||||||
elemId: string,
|
|
||||||
elemType: number,
|
|
||||||
fileSize: string,
|
|
||||||
filePath: string,
|
|
||||||
fileName: string,
|
|
||||||
hits: {
|
|
||||||
start: number,
|
|
||||||
end: number
|
|
||||||
}[]
|
|
||||||
}[]
|
|
||||||
}): void;
|
|
||||||
}
|
|
@@ -9,7 +9,7 @@ export * from './NodeIKernelProfileListener';
|
|||||||
export * from './NodeIKernelTicketListener';
|
export * from './NodeIKernelTicketListener';
|
||||||
export * from './NodeIKernelStorageCleanListener';
|
export * from './NodeIKernelStorageCleanListener';
|
||||||
export * from './NodeIKernelFileAssistantListener';
|
export * from './NodeIKernelFileAssistantListener';
|
||||||
export * from './NodeIKernelSearchListener_Polyfill';
|
export * from './NodeIKernelSearchListener';
|
||||||
|
|
||||||
import type {
|
import type {
|
||||||
NodeIKernelBuddyListener,
|
NodeIKernelBuddyListener,
|
||||||
@@ -19,11 +19,11 @@ import type {
|
|||||||
NodeIKernelMsgListener,
|
NodeIKernelMsgListener,
|
||||||
NodeIKernelProfileListener,
|
NodeIKernelProfileListener,
|
||||||
NodeIKernelRobotListener,
|
NodeIKernelRobotListener,
|
||||||
NodeIKernelSearchListener_Polyfill,
|
|
||||||
NodeIKernelSessionListener,
|
NodeIKernelSessionListener,
|
||||||
NodeIKernelStorageCleanListener,
|
NodeIKernelStorageCleanListener,
|
||||||
NodeIKernelTicketListener,
|
NodeIKernelTicketListener,
|
||||||
} from '.';
|
} from '.';
|
||||||
|
import { NodeIKernelSearchListener } from './NodeIKernelSearchListener';
|
||||||
|
|
||||||
export type ListenerNamingMapping = {
|
export type ListenerNamingMapping = {
|
||||||
NodeIKernelSessionListener: NodeIKernelSessionListener;
|
NodeIKernelSessionListener: NodeIKernelSessionListener;
|
||||||
@@ -36,5 +36,5 @@ export type ListenerNamingMapping = {
|
|||||||
NodeIKernelTicketListener: NodeIKernelTicketListener;
|
NodeIKernelTicketListener: NodeIKernelTicketListener;
|
||||||
NodeIKernelStorageCleanListener: NodeIKernelStorageCleanListener;
|
NodeIKernelStorageCleanListener: NodeIKernelStorageCleanListener;
|
||||||
NodeIKernelFileAssistantListener: NodeIKernelFileAssistantListener;
|
NodeIKernelFileAssistantListener: NodeIKernelFileAssistantListener;
|
||||||
NodeIKernelSearchListener: NodeIKernelSearchListener_Polyfill;
|
NodeIKernelSearchListener: NodeIKernelSearchListener;
|
||||||
};
|
};
|
||||||
|
@@ -14,9 +14,15 @@ export interface LikeMsgType {
|
|||||||
detail: LikeDetailType;
|
detail: LikeDetailType;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ProfileLikeTipType {
|
export interface profileLikeSubTipType {
|
||||||
msg: LikeMsgType;
|
msg: LikeMsgType;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface ProfileLikeTipType {
|
||||||
|
msgType: number;
|
||||||
|
subType: number;
|
||||||
|
content: profileLikeSubTipType;
|
||||||
|
}
|
||||||
export interface SysMessageHeaderType {
|
export interface SysMessageHeaderType {
|
||||||
id: string;
|
id: string;
|
||||||
timestamp: number;
|
timestamp: number;
|
||||||
@@ -78,6 +84,12 @@ export const likeMsg = new pb.Type("likeMsg")
|
|||||||
.add(new pb.Field("time", 2, "int32"))
|
.add(new pb.Field("time", 2, "int32"))
|
||||||
.add(new pb.Field("detail", 3, "likeDetail"));
|
.add(new pb.Field("detail", 3, "likeDetail"));
|
||||||
|
|
||||||
export const profileLikeTip = new pb.Type("profileLikeTip")
|
export const profileLikeSubTip = new pb.Type("profileLikeSubTip")
|
||||||
.add(likeMsg)
|
.add(likeMsg)
|
||||||
.add(new pb.Field("msg", 14, "likeMsg"));
|
.add(new pb.Field("msg", 14, "likeMsg"))
|
||||||
|
|
||||||
|
export const profileLikeTip = new pb.Type("profileLikeTip")
|
||||||
|
.add(profileLikeSubTip)
|
||||||
|
.add(new pb.Field("msgType", 1, "int32"))
|
||||||
|
.add(new pb.Field("subType", 2, "int32"))
|
||||||
|
.add(new pb.Field("content", 203, "profileLikeSubTip"));
|
||||||
|
@@ -114,7 +114,7 @@ export interface NodeIKernelBuddyService {
|
|||||||
|
|
||||||
reportDoubtBuddyReqUnread(): void;
|
reportDoubtBuddyReqUnread(): void;
|
||||||
|
|
||||||
getBuddyRecommendContactArkJson(uid: string, phoneNumber: string): Promise<unknown>;
|
getBuddyRecommendContactArkJson(uid: string, phoneNumber: string): Promise<GeneralCallResult & { arkMsg: string }>;
|
||||||
|
|
||||||
isNull(): boolean;
|
isNull(): boolean;
|
||||||
}
|
}
|
||||||
|
@@ -1,7 +1,7 @@
|
|||||||
import { ElementType, MessageElement, Peer, RawMessage, SendMessageElement } from '@/core/entities';
|
import { ElementType, MessageElement, Peer, RawMessage, SendMessageElement } from '@/core/entities';
|
||||||
import { NodeIKernelMsgListener } from '@/core/listeners/NodeIKernelMsgListener';
|
import { NodeIKernelMsgListener } from '@/core/listeners/NodeIKernelMsgListener';
|
||||||
import { GeneralCallResult } from '@/core/services/common';
|
import { GeneralCallResult } from '@/core/services/common';
|
||||||
import { QueryMsgsParams, TmpChatInfoApi } from '../entities/msg';
|
import { MsgReqType, QueryMsgsParams, TmpChatInfoApi } from '../entities/msg';
|
||||||
|
|
||||||
export interface NodeIKernelMsgService {
|
export interface NodeIKernelMsgService {
|
||||||
|
|
||||||
@@ -147,12 +147,15 @@ export interface NodeIKernelMsgService {
|
|||||||
msgList: RawMessage[]
|
msgList: RawMessage[]
|
||||||
}>;
|
}>;
|
||||||
|
|
||||||
|
//@deprecated
|
||||||
getMsgs(peer: Peer, msgId: string, count: unknown, queryOrder: boolean): Promise<unknown>;
|
getMsgs(peer: Peer, msgId: string, count: unknown, queryOrder: boolean): Promise<unknown>;
|
||||||
|
|
||||||
|
//@deprecated
|
||||||
getMsgsIncludeSelf(peer: Peer, msgId: string, count: number, queryOrder: boolean): Promise<GeneralCallResult & {
|
getMsgsIncludeSelf(peer: Peer, msgId: string, count: number, queryOrder: boolean): Promise<GeneralCallResult & {
|
||||||
msgList: RawMessage[]
|
msgList: RawMessage[]
|
||||||
}>;
|
}>;
|
||||||
|
|
||||||
|
//@deprecated
|
||||||
getMsgsWithMsgTimeAndClientSeqForC2C(...args: unknown[]): Promise<GeneralCallResult & { msgList: RawMessage[] }>;
|
getMsgsWithMsgTimeAndClientSeqForC2C(...args: unknown[]): Promise<GeneralCallResult & { msgList: RawMessage[] }>;
|
||||||
|
|
||||||
getMsgsWithStatus(params: {
|
getMsgsWithStatus(params: {
|
||||||
@@ -168,7 +171,7 @@ export interface NodeIKernelMsgService {
|
|||||||
getMsgsBySeqRange(peer: Peer, startSeq: string, endSeq: string): Promise<GeneralCallResult & {
|
getMsgsBySeqRange(peer: Peer, startSeq: string, endSeq: string): Promise<GeneralCallResult & {
|
||||||
msgList: RawMessage[]
|
msgList: RawMessage[]
|
||||||
}>;
|
}>;
|
||||||
|
//@deprecated
|
||||||
getMsgsBySeqAndCount(peer: Peer, seq: string, count: number, desc: boolean, unknownArg: boolean): Promise<GeneralCallResult & {
|
getMsgsBySeqAndCount(peer: Peer, seq: string, count: number, desc: boolean, unknownArg: boolean): Promise<GeneralCallResult & {
|
||||||
msgList: RawMessage[]
|
msgList: RawMessage[]
|
||||||
}>;
|
}>;
|
||||||
@@ -179,6 +182,8 @@ export interface NodeIKernelMsgService {
|
|||||||
|
|
||||||
getMsgsBySeqList(peer: Peer, seqList: string[]): Promise<GeneralCallResult & { msgList: RawMessage[] }>;
|
getMsgsBySeqList(peer: Peer, seqList: string[]): Promise<GeneralCallResult & { msgList: RawMessage[] }>;
|
||||||
|
|
||||||
|
getMsgsExt(msgReq: MsgReqType): Promise<GeneralCallResult & { msgList: RawMessage[] }>;
|
||||||
|
|
||||||
getSingleMsg(Peer: Peer, msgSeq: string): Promise<GeneralCallResult & { msgList: RawMessage[] }>;
|
getSingleMsg(Peer: Peer, msgSeq: string): Promise<GeneralCallResult & { msgList: RawMessage[] }>;
|
||||||
|
|
||||||
getSourceOfReplyMsg(peer: Peer, MsgId: string, SourceSeq: string): unknown;
|
getSourceOfReplyMsg(peer: Peer, MsgId: string, SourceSeq: string): unknown;
|
||||||
@@ -318,7 +323,7 @@ export interface NodeIKernelMsgService {
|
|||||||
|
|
||||||
getFileThumbSavePath(...args: unknown[]): unknown;
|
getFileThumbSavePath(...args: unknown[]): unknown;
|
||||||
|
|
||||||
translatePtt2Text(msgId: string, peer: Peer, msgElement: unknown): unknown;
|
translatePtt2Text(msgId: string, peer: Peer, msgElement: MessageElement): unknown;
|
||||||
|
|
||||||
setPttPlayedState(...args: unknown[]): unknown;
|
setPttPlayedState(...args: unknown[]): unknown;
|
||||||
|
|
||||||
@@ -391,7 +396,12 @@ export interface NodeIKernelMsgService {
|
|||||||
|
|
||||||
getEmojiResourcePath(...args: unknown[]): unknown;
|
getEmojiResourcePath(...args: unknown[]): unknown;
|
||||||
|
|
||||||
JoinDragonGroupEmoji(JoinDragonGroupEmojiReq: any/*joinDragonGroupEmojiReq*/): unknown;
|
JoinDragonGroupEmoji(JoinDragonGroupEmojiReq: {
|
||||||
|
latestMsgSeq: string,
|
||||||
|
manageEmojiId: number,
|
||||||
|
manageMsgSeq: string,
|
||||||
|
peerContact: Peer
|
||||||
|
}): Promise<unknown>;
|
||||||
|
|
||||||
getMsgAbstracts(...args: unknown[]): unknown;
|
getMsgAbstracts(...args: unknown[]): unknown;
|
||||||
|
|
||||||
@@ -518,7 +528,7 @@ export interface NodeIKernelMsgService {
|
|||||||
|
|
||||||
canImportOldDbMsg(...args: unknown[]): unknown;
|
canImportOldDbMsg(...args: unknown[]): unknown;
|
||||||
|
|
||||||
setPowerStatus(z: boolean): unknown;
|
setPowerStatus(isPowerOn: boolean): unknown;
|
||||||
|
|
||||||
canProcessDataMigration(...args: unknown[]): unknown;
|
canProcessDataMigration(...args: unknown[]): unknown;
|
||||||
|
|
||||||
@@ -607,7 +617,7 @@ export interface NodeIKernelMsgService {
|
|||||||
setIKernelPublicAccountAdapter(...args: unknown[]): unknown;
|
setIKernelPublicAccountAdapter(...args: unknown[]): unknown;
|
||||||
|
|
||||||
//tempChatGameSession有关
|
//tempChatGameSession有关
|
||||||
createUidFromTinyId(fromTinyId: string, toTinyId: string): unknown;
|
createUidFromTinyId(fromTinyId: string, toTinyId: string): string;
|
||||||
|
|
||||||
dataMigrationGetDataAvaiableContactList(...args: unknown[]): unknown;
|
dataMigrationGetDataAvaiableContactList(...args: unknown[]): unknown;
|
||||||
|
|
||||||
|
@@ -1,4 +1,5 @@
|
|||||||
import { ChatType } from '../entities';
|
import { ChatType } from '../entities';
|
||||||
|
import { GeneralCallResult } from './common';
|
||||||
|
|
||||||
export interface NodeIKernelSearchService {
|
export interface NodeIKernelSearchService {
|
||||||
|
|
||||||
@@ -8,7 +9,12 @@ export interface NodeIKernelSearchService {
|
|||||||
|
|
||||||
searchStranger(unknown: string, searchStranger: unknown, searchParams: unknown): Promise<unknown>;
|
searchStranger(unknown: string, searchStranger: unknown, searchParams: unknown): Promise<unknown>;
|
||||||
|
|
||||||
searchGroup(...args: any[]): unknown;// needs 1 arguments
|
searchGroup(param: {
|
||||||
|
keyWords: string,
|
||||||
|
groupNum: number,
|
||||||
|
exactSearch: boolean,
|
||||||
|
penetrate: string
|
||||||
|
}): Promise<GeneralCallResult>;// needs 1 arguments
|
||||||
|
|
||||||
searchLocalInfo(keywords: string, unknown: number/*4*/): unknown;
|
searchLocalInfo(keywords: string, unknown: number/*4*/): unknown;
|
||||||
|
|
||||||
|
11
src/onebot/action/extends/FetchUserProfileLike.ts
Normal file
11
src/onebot/action/extends/FetchUserProfileLike.ts
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
import BaseAction from '../BaseAction';
|
||||||
|
import { ActionName } from '../types';
|
||||||
|
|
||||||
|
export class FetchUserProfileLike extends BaseAction<{ qq: number }, any> {
|
||||||
|
actionName = ActionName.FetchUserProfileLike;
|
||||||
|
|
||||||
|
async _handle(payload: { qq: number }) {
|
||||||
|
if (!payload.qq) throw new Error('qq is required');
|
||||||
|
return await this.core.apis.UserApi.getUidByUinV2(payload.qq.toString());
|
||||||
|
}
|
||||||
|
}
|
@@ -7,17 +7,18 @@ const SchemaData = {
|
|||||||
properties: {
|
properties: {
|
||||||
group_id: { type: ['string', 'number'] },
|
group_id: { type: ['string', 'number'] },
|
||||||
folder_id: { type: 'string' },
|
folder_id: { type: 'string' },
|
||||||
|
folder: { type: 'string' }
|
||||||
},
|
},
|
||||||
required: ['group_id', 'folder_id'],
|
required: ['group_id'],
|
||||||
} as const satisfies JSONSchema;
|
} as const satisfies JSONSchema;
|
||||||
|
|
||||||
type Payload = FromSchema<typeof SchemaData>;
|
type Payload = FromSchema<typeof SchemaData>;
|
||||||
|
|
||||||
export class DeleteGroupFileFolder extends BaseAction<Payload, any> {
|
export class DeleteGroupFileFolder extends BaseAction<Payload, any> {
|
||||||
actionName = ActionName.GoCQHTTP_DeleteGroupFileFolder;
|
actionName = ActionName.GoCQHTTP_DeleteGroupFileFolder;
|
||||||
payloadSchema = SchemaData;
|
payloadSchema = SchemaData;
|
||||||
async _handle(payload: Payload) {
|
async _handle(payload: Payload) {
|
||||||
return (await this.core.apis.GroupApi.DelGroupFileFolder(
|
return (await this.core.apis.GroupApi.DelGroupFileFolder(
|
||||||
payload.group_id.toString(), payload.folder_id)).groupFileCommonResult;
|
payload.group_id.toString(), payload.folder ?? payload.folder_id ?? '')).groupFileCommonResult;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -73,7 +73,7 @@ export default class GoCQHTTPDownloadFile extends BaseAction<Payload, FileRespon
|
|||||||
headers[headerItem] = '';
|
headers[headerItem] = '';
|
||||||
} else {
|
} else {
|
||||||
const key = headerItem.substring(0, spilt);
|
const key = headerItem.substring(0, spilt);
|
||||||
headers[key] = headerItem.substring(0, spilt + 1);
|
headers[key] = headerItem.substring(spilt + 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -8,9 +8,10 @@ const SchemaData = {
|
|||||||
properties: {
|
properties: {
|
||||||
group_id: { type: ['string', 'number'] },
|
group_id: { type: ['string', 'number'] },
|
||||||
folder_id: { type: 'string' },
|
folder_id: { type: 'string' },
|
||||||
|
folder: { type: 'string' },
|
||||||
file_count: { type: ['string', 'number'] },
|
file_count: { type: ['string', 'number'] },
|
||||||
},
|
},
|
||||||
required: ['group_id', 'folder_id'],
|
required: ['group_id'],
|
||||||
} as const satisfies JSONSchema;
|
} as const satisfies JSONSchema;
|
||||||
|
|
||||||
type Payload = FromSchema<typeof SchemaData>;
|
type Payload = FromSchema<typeof SchemaData>;
|
||||||
@@ -26,7 +27,7 @@ export class GetGroupFilesByFolder extends BaseAction<any, any> {
|
|||||||
startIndex: 0,
|
startIndex: 0,
|
||||||
sortOrder: 2,
|
sortOrder: 2,
|
||||||
showOnlinedocFolder: 0,
|
showOnlinedocFolder: 0,
|
||||||
folderId: payload.folder_id,
|
folderId: payload.folder ?? payload.folder_id ?? '',
|
||||||
}).catch(() => []);
|
}).catch(() => []);
|
||||||
return {
|
return {
|
||||||
files: ret.filter(item => item.fileInfo)
|
files: ret.filter(item => item.fileInfo)
|
||||||
|
@@ -21,24 +21,25 @@ export default class GoCQHTTPGetStrangerInfo extends BaseAction<Payload, OB11Use
|
|||||||
async _handle(payload: Payload): Promise<OB11User> {
|
async _handle(payload: Payload): Promise<OB11User> {
|
||||||
const user_id = payload.user_id.toString();
|
const user_id = payload.user_id.toString();
|
||||||
const extendData = await this.core.apis.UserApi.getUserDetailInfoByUin(user_id);
|
const extendData = await this.core.apis.UserApi.getUserDetailInfoByUin(user_id);
|
||||||
const uid = (await this.core.apis.UserApi.getUidByUinV2(user_id))!;
|
let uid = (await this.core.apis.UserApi.getUidByUinV2(user_id));
|
||||||
if (!uid || uid.indexOf('*') != -1) {
|
if (!uid) uid = extendData.detail.uid;
|
||||||
return {
|
const info = (await this.core.apis.UserApi.getUserDetailInfo(uid));
|
||||||
...extendData.detail.simpleInfo.coreInfo,
|
return {
|
||||||
...extendData.detail.commonExt,
|
user_id: parseInt(extendData.detail.uin) ?? 0,
|
||||||
...extendData.detail.simpleInfo.baseInfo,
|
uid: info.uid ?? uid,
|
||||||
...extendData.detail.simpleInfo.relationFlags,
|
nickname: extendData.detail.simpleInfo.coreInfo.nick,
|
||||||
...extendData.detail.simpleInfo.status,
|
age: extendData.detail.simpleInfo.baseInfo.age ?? info.age,
|
||||||
user_id: parseInt(extendData.detail.uin) || 0,
|
qid: extendData.detail.simpleInfo.baseInfo.qid,
|
||||||
nickname: extendData.detail.simpleInfo.coreInfo.nick,
|
qqLevel: calcQQLevel(extendData.detail.commonExt?.qqLevel ?? info.qqLevel),
|
||||||
sex: OB11UserSex.unknown,
|
sex: OB11Entities.sex(extendData.detail.simpleInfo.baseInfo.sex) ?? OB11UserSex.unknown,
|
||||||
age: extendData.detail.simpleInfo.baseInfo.age || 0,
|
long_nick: extendData.detail.simpleInfo.baseInfo.longNick ?? info.longNick,
|
||||||
qid: extendData.detail.simpleInfo.baseInfo.qid,
|
reg_time: extendData.detail.commonExt.regTime ?? info.regTime,
|
||||||
level: calcQQLevel(extendData.detail.commonExt?.qqLevel ?? 0) || 0,
|
is_vip: extendData.detail.simpleInfo.vasInfo?.svipFlag,
|
||||||
login_days: 0,
|
is_years_vip: extendData.detail.simpleInfo.vasInfo?.yearVipFlag,
|
||||||
};
|
vip_level: extendData.detail.simpleInfo.vasInfo?.vipLevel,
|
||||||
}
|
remark: extendData.detail.simpleInfo.coreInfo.remark ?? info.remark,
|
||||||
const data = { ...extendData, ...(await this.core.apis.UserApi.getUserDetailInfo(uid)) };
|
status: extendData.detail.simpleInfo.status?.status ?? info.status,
|
||||||
return OB11Entities.stranger(data);
|
login_days: 0,//失效
|
||||||
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -57,7 +57,6 @@ export class SendGroupNotice extends BaseAction<Payload, null> {
|
|||||||
const noticeShowEditCard = +(payload.is_show_edit_card ?? 0);
|
const noticeShowEditCard = +(payload.is_show_edit_card ?? 0);
|
||||||
const noticeTipWindowType = +(payload.tip_window_type ?? 0);
|
const noticeTipWindowType = +(payload.tip_window_type ?? 0);
|
||||||
const noticeConfirmRequired = +(payload.confirm_required ?? 1);
|
const noticeConfirmRequired = +(payload.confirm_required ?? 1);
|
||||||
//const publishGroupBulletinResult = await this.core.apis.GroupApi.publishGroupBulletin(payload.group_id.toString(), payload.content, UploadImage, noticePinned, noticeConfirmRequired);
|
|
||||||
const publishGroupBulletinResult = await this.core.apis.WebApi.setGroupNotice(
|
const publishGroupBulletinResult = await this.core.apis.WebApi.setGroupNotice(
|
||||||
payload.group_id.toString(),
|
payload.group_id.toString(),
|
||||||
payload.content,
|
payload.content,
|
||||||
@@ -71,7 +70,7 @@ export class SendGroupNotice extends BaseAction<Payload, null> {
|
|||||||
UploadImage?.height
|
UploadImage?.height
|
||||||
);
|
);
|
||||||
if (!publishGroupBulletinResult || publishGroupBulletinResult.ec != 0) {
|
if (!publishGroupBulletinResult || publishGroupBulletinResult.ec != 0) {
|
||||||
throw `设置群公告失败,错误信息:${publishGroupBulletinResult?.em}`;
|
throw new Error(`设置群公告失败,错误信息:${publishGroupBulletinResult?.em}`);
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@@ -37,11 +37,11 @@ export default class GoCQHTTPUploadGroupFile extends BaseAction<Payload, null> {
|
|||||||
if (!downloadResult.success) {
|
if (!downloadResult.success) {
|
||||||
throw new Error(downloadResult.errMsg);
|
throw new Error(downloadResult.errMsg);
|
||||||
}
|
}
|
||||||
let msgContext: MessageContext = {
|
const msgContext: MessageContext = {
|
||||||
peer: peer,
|
peer: peer,
|
||||||
deleteAfterSentFiles: []
|
deleteAfterSentFiles: []
|
||||||
}
|
};
|
||||||
const sendFileEle = await this.core.apis.FileApi.createValidSendFileElement(msgContext, downloadResult.path, payload.name, payload.folder_id);
|
const sendFileEle = await this.core.apis.FileApi.createValidSendFileElement(msgContext, downloadResult.path, payload.name, payload.folder ?? payload.folder_id);
|
||||||
await this.obContext.apis.MsgApi.sendMsgWithOb11UniqueId(peer, [sendFileEle], [], true);
|
await this.obContext.apis.MsgApi.sendMsgWithOb11UniqueId(peer, [sendFileEle], [], true);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@@ -45,13 +45,13 @@ export default class GoCQHTTPUploadPrivateFile extends BaseAction<Payload, null>
|
|||||||
throw new Error(downloadResult.errMsg);
|
throw new Error(downloadResult.errMsg);
|
||||||
}
|
}
|
||||||
|
|
||||||
let msgContext: MessageContext = {
|
const msgContext: MessageContext = {
|
||||||
peer: await createContext(this.core, {
|
peer: await createContext(this.core, {
|
||||||
user_id: payload.user_id.toString(),
|
user_id: payload.user_id.toString(),
|
||||||
group_id: undefined,
|
group_id: undefined,
|
||||||
}, ContextMode.Private),
|
}, ContextMode.Private),
|
||||||
deleteAfterSentFiles: []
|
deleteAfterSentFiles: []
|
||||||
}
|
};
|
||||||
const sendFileEle: SendFileElement = await this.core.apis.FileApi.createValidSendFileElement(msgContext, downloadResult.path, payload.name);
|
const sendFileEle: SendFileElement = await this.core.apis.FileApi.createValidSendFileElement(msgContext, downloadResult.path, payload.name);
|
||||||
await this.obContext.apis.MsgApi.sendMsgWithOb11UniqueId(await this.getPeer(payload), [sendFileEle], [], true);
|
await this.obContext.apis.MsgApi.sendMsgWithOb11UniqueId(await this.getPeer(payload), [sendFileEle], [], true);
|
||||||
return null;
|
return null;
|
||||||
|
@@ -20,7 +20,17 @@ class GetGroupInfo extends BaseAction<Payload, OB11Group> {
|
|||||||
|
|
||||||
async _handle(payload: Payload) {
|
async _handle(payload: Payload) {
|
||||||
const group = (await this.core.apis.GroupApi.getGroups()).find(e => e.groupCode == payload.group_id.toString());
|
const group = (await this.core.apis.GroupApi.getGroups()).find(e => e.groupCode == payload.group_id.toString());
|
||||||
if (!group) throw `群${payload.group_id}不存在`;
|
if (!group) {
|
||||||
|
const data = await this.core.apis.GroupApi.searchGroup(payload.group_id.toString());
|
||||||
|
if (!data) throw new Error('Group not found');
|
||||||
|
return {
|
||||||
|
...data.searchGroupInfo,
|
||||||
|
group_id: +payload.group_id,
|
||||||
|
group_name: data.searchGroupInfo.groupName,
|
||||||
|
member_count: data.searchGroupInfo.memberNum,
|
||||||
|
max_member_count: data.searchGroupInfo.maxMemberNum,
|
||||||
|
};
|
||||||
|
}
|
||||||
return OB11Entities.group(group);
|
return OB11Entities.group(group);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -3,6 +3,7 @@ import { OB11Entities } from '@/onebot/entities';
|
|||||||
import BaseAction from '../BaseAction';
|
import BaseAction from '../BaseAction';
|
||||||
import { ActionName } from '../types';
|
import { ActionName } from '../types';
|
||||||
import { FromSchema, JSONSchema } from 'json-schema-to-ts';
|
import { FromSchema, JSONSchema } from 'json-schema-to-ts';
|
||||||
|
import { calcQQLevel } from '@/common/helper';
|
||||||
|
|
||||||
const SchemaData = {
|
const SchemaData = {
|
||||||
type: 'object',
|
type: 'object',
|
||||||
@@ -22,7 +23,8 @@ class GetGroupMemberList extends BaseAction<Payload, OB11GroupMember[]> {
|
|||||||
async _handle(payload: Payload) {
|
async _handle(payload: Payload) {
|
||||||
const groupMembers = await this.core.apis.GroupApi.getGroupMembersV2(payload.group_id.toString());
|
const groupMembers = await this.core.apis.GroupApi.getGroupMembersV2(payload.group_id.toString());
|
||||||
const groupMembersArr = Array.from(groupMembers.values());
|
const groupMembersArr = Array.from(groupMembers.values());
|
||||||
|
let uids = groupMembersArr.map(item => item.uid);
|
||||||
|
//let CoreAndBase = await this.core.apis.GroupApi.getCoreAndBaseInfo(uids)
|
||||||
let _groupMembers = groupMembersArr.map(item => {
|
let _groupMembers = groupMembersArr.map(item => {
|
||||||
return OB11Entities.groupMember(payload.group_id.toString(), item);
|
return OB11Entities.groupMember(payload.group_id.toString(), item);
|
||||||
});
|
});
|
||||||
@@ -32,34 +34,38 @@ class GetGroupMemberList extends BaseAction<Payload, OB11GroupMember[]> {
|
|||||||
|
|
||||||
for (let i = 0, len = _groupMembers.length; i < len; i++) {
|
for (let i = 0, len = _groupMembers.length; i < len; i++) {
|
||||||
// 保证基础数据有这个 同时避免群管插件过于依赖这个杀了
|
// 保证基础数据有这个 同时避免群管插件过于依赖这个杀了
|
||||||
_groupMembers[i].join_time = date;
|
const Member = await this.core.apis.GroupApi.getGroupMember(payload.group_id.toString(), _groupMembers[i].user_id);
|
||||||
_groupMembers[i].last_sent_time = date;
|
_groupMembers[i].join_time = +(Member?.joinTime ?? date);
|
||||||
|
_groupMembers[i].last_sent_time = +(Member?.lastSpeakTime ?? date);
|
||||||
MemberMap.set(_groupMembers[i].user_id, _groupMembers[i]);
|
MemberMap.set(_groupMembers[i].user_id, _groupMembers[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const selfRole = groupMembers.get(this.core.selfInfo.uid)?.role;
|
const selfRole = groupMembers.get(this.core.selfInfo.uid)?.role;
|
||||||
const isPrivilege = selfRole === 3 || selfRole === 4;
|
const isPrivilege = selfRole === 3 || selfRole === 4;
|
||||||
|
|
||||||
_groupMembers.forEach(item => {
|
|
||||||
item.last_sent_time = date;
|
|
||||||
item.join_time = date;
|
|
||||||
});
|
|
||||||
|
|
||||||
if (isPrivilege) {
|
if (isPrivilege) {
|
||||||
const webGroupMembers = await this.core.apis.WebApi.getGroupMembers(payload.group_id.toString());
|
try {
|
||||||
for (let i = 0, len = webGroupMembers.length; i < len; i++) {
|
const webGroupMembers = await this.core.apis.WebApi.getGroupMembers(payload.group_id.toString());
|
||||||
if (!webGroupMembers[i]?.uin) {
|
for (let i = 0, len = webGroupMembers.length; i < len; i++) {
|
||||||
continue;
|
if (!webGroupMembers[i]?.uin) {
|
||||||
}
|
continue;
|
||||||
const MemberData = MemberMap.get(webGroupMembers[i]?.uin);
|
}
|
||||||
if (MemberData) {
|
const MemberData = MemberMap.get(webGroupMembers[i]?.uin);
|
||||||
MemberData.join_time = webGroupMembers[i]?.join_time;
|
if (MemberData) {
|
||||||
MemberData.last_sent_time = webGroupMembers[i]?.last_speak_time;
|
MemberData.join_time = webGroupMembers[i]?.join_time;
|
||||||
MemberData.qage = webGroupMembers[i]?.qage;
|
MemberData.last_sent_time = webGroupMembers[i]?.last_speak_time;
|
||||||
MemberData.level = webGroupMembers[i]?.lv.level.toString();
|
MemberData.qage = webGroupMembers[i]?.qage;
|
||||||
MemberMap.set(webGroupMembers[i]?.uin, MemberData);
|
MemberData.level = webGroupMembers[i]?.lv.level.toString();
|
||||||
|
MemberMap.set(webGroupMembers[i]?.uin, MemberData);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
} catch (e) {
|
||||||
|
const logger = this.core.context.logger;
|
||||||
|
logger.logError.bind(logger)('GetGroupMemberList', e);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_groupMembers = Array.from(MemberMap.values());
|
_groupMembers = Array.from(MemberMap.values());
|
||||||
|
@@ -68,8 +68,8 @@ import SetGroupPortrait from './go-cqhttp/SetGroupPortrait';
|
|||||||
import { FetchCustomFace } from './extends/FetchCustomFace';
|
import { FetchCustomFace } from './extends/FetchCustomFace';
|
||||||
import GoCQHTTPUploadPrivateFile from './go-cqhttp/UploadPrivateFile';
|
import GoCQHTTPUploadPrivateFile from './go-cqhttp/UploadPrivateFile';
|
||||||
import { FetchEmojiLike } from './extends/FetchEmojiLike';
|
import { FetchEmojiLike } from './extends/FetchEmojiLike';
|
||||||
|
import { FetchUserProfileLike } from './extends/FetchUserProfileLike';
|
||||||
import { NapCatCore } from '@/core';
|
import { NapCatCore } from '@/core';
|
||||||
|
|
||||||
import { NapCatOneBot11Adapter } from '@/onebot';
|
import { NapCatOneBot11Adapter } from '@/onebot';
|
||||||
import GetGuildProfile from './guild/GetGuildProfile';
|
import GetGuildProfile from './guild/GetGuildProfile';
|
||||||
import SetModelShow from './go-cqhttp/SetModelShow';
|
import SetModelShow from './go-cqhttp/SetModelShow';
|
||||||
@@ -85,6 +85,7 @@ import { GetGroupRootFiles } from '@/onebot/action/go-cqhttp/GetGroupRootFiles';
|
|||||||
import { GetGroupFilesByFolder } from '@/onebot/action/go-cqhttp/GetGroupFilesByFolder';
|
import { GetGroupFilesByFolder } from '@/onebot/action/go-cqhttp/GetGroupFilesByFolder';
|
||||||
import { GetGroupSystemMsg } from './system/GetSystemMsg';
|
import { GetGroupSystemMsg } from './system/GetSystemMsg';
|
||||||
|
|
||||||
|
|
||||||
export type ActionMap = Map<string, BaseAction<any, any>>;
|
export type ActionMap = Map<string, BaseAction<any, any>>;
|
||||||
|
|
||||||
export function createActionMap(obContext: NapCatOneBot11Adapter, core: NapCatCore): ActionMap {
|
export function createActionMap(obContext: NapCatOneBot11Adapter, core: NapCatCore): ActionMap {
|
||||||
@@ -178,6 +179,7 @@ export function createActionMap(obContext: NapCatOneBot11Adapter, core: NapCatCo
|
|||||||
new GetGroupFileSystemInfo(obContext, core),
|
new GetGroupFileSystemInfo(obContext, core),
|
||||||
new GetGroupFilesByFolder(obContext, core),
|
new GetGroupFilesByFolder(obContext, core),
|
||||||
new GetGroupSystemMsg(obContext, core),
|
new GetGroupSystemMsg(obContext, core),
|
||||||
|
new FetchUserProfileLike(obContext, core),
|
||||||
];
|
];
|
||||||
const actionMap = new Map();
|
const actionMap = new Map();
|
||||||
for (const action of actionHandlers) {
|
for (const action of actionHandlers) {
|
||||||
|
@@ -16,8 +16,8 @@ export interface InvalidCheckResult {
|
|||||||
export enum ActionName {
|
export enum ActionName {
|
||||||
// 以下为扩展napcat扩展
|
// 以下为扩展napcat扩展
|
||||||
Unknown = 'unknown',
|
Unknown = 'unknown',
|
||||||
SharePeer = 'ArkShareGroup',
|
SharePeer = 'ArkSharePeer',
|
||||||
ShareGroupEx = 'ArkSharePeer',
|
ShareGroupEx = 'ArkShareGroup',
|
||||||
RebootNormal = 'reboot_normal',//无快速登录重新启动
|
RebootNormal = 'reboot_normal',//无快速登录重新启动
|
||||||
GetRobotUinRange = 'get_robot_uin_range',
|
GetRobotUinRange = 'get_robot_uin_range',
|
||||||
SetOnlineStatus = 'set_online_status',
|
SetOnlineStatus = 'set_online_status',
|
||||||
@@ -118,4 +118,5 @@ export enum ActionName {
|
|||||||
DelGroupNotice = '_del_group_notice',
|
DelGroupNotice = '_del_group_notice',
|
||||||
GetGroupInfoEx = "get_group_info_ex",
|
GetGroupInfoEx = "get_group_info_ex",
|
||||||
GetGroupSystemMsg = 'get_group_system_msg',
|
GetGroupSystemMsg = 'get_group_system_msg',
|
||||||
|
FetchUserProfileLike = "fetch_user_profile_like",
|
||||||
}
|
}
|
||||||
|
@@ -142,22 +142,22 @@ export class OneBotGroupApi {
|
|||||||
//下面得改 上面也是错的grayTipElement.subElementType == GrayTipElementSubType.MEMBER_NEW_TITLE
|
//下面得改 上面也是错的grayTipElement.subElementType == GrayTipElementSubType.MEMBER_NEW_TITLE
|
||||||
const type = json.items[json.items.length - 1]?.txt;
|
const type = json.items[json.items.length - 1]?.txt;
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case "头衔": {
|
case "头衔": {
|
||||||
const memberUin = json.items[1].param[0];
|
const memberUin = json.items[1].param[0];
|
||||||
const title = json.items[3].txt;
|
const title = json.items[3].txt;
|
||||||
logger.logDebug('收到群成员新头衔消息', json);
|
logger.logDebug('收到群成员新头衔消息', json);
|
||||||
return new OB11GroupTitleEvent(
|
return new OB11GroupTitleEvent(
|
||||||
this.core,
|
this.core,
|
||||||
parseInt(msg.peerUid),
|
parseInt(msg.peerUid),
|
||||||
parseInt(memberUin),
|
parseInt(memberUin),
|
||||||
title,
|
title,
|
||||||
);
|
);
|
||||||
};
|
}
|
||||||
case "移出":
|
case "移出":
|
||||||
logger.logDebug('收到机器人被踢消息', json);
|
logger.logDebug('收到机器人被踢消息', json);
|
||||||
return;
|
return;
|
||||||
default:
|
default:
|
||||||
logger.logWarn('收到未知的灰条消息', json);
|
logger.logWarn('收到未知的灰条消息', json);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -34,6 +34,7 @@ import { RequestUtil } from '@/common/request';
|
|||||||
import fs from 'node:fs';
|
import fs from 'node:fs';
|
||||||
import fsPromise from 'node:fs/promises';
|
import fsPromise from 'node:fs/promises';
|
||||||
import { OB11FriendAddNoticeEvent } from '@/onebot/event/notice/OB11FriendAddNoticeEvent';
|
import { OB11FriendAddNoticeEvent } from '@/onebot/event/notice/OB11FriendAddNoticeEvent';
|
||||||
|
import { SysMessage, SysMessageType } from '@/core/proto/ProfileLike';
|
||||||
|
|
||||||
type RawToOb11Converters = {
|
type RawToOb11Converters = {
|
||||||
[Key in keyof MessageElement as Key extends `${string}Element` ? Key : never]: (
|
[Key in keyof MessageElement as Key extends `${string}Element` ? Key : never]: (
|
||||||
@@ -185,7 +186,7 @@ export class OneBotMsgApi {
|
|||||||
data: {
|
data: {
|
||||||
file: 'marketface',
|
file: 'marketface',
|
||||||
file_id: FileNapCatOneBotUUID.encode(peer, msg.msgId, elementWrapper.elementId, "." + _.key + ".jpg"),
|
file_id: FileNapCatOneBotUUID.encode(peer, msg.msgId, elementWrapper.elementId, "." + _.key + ".jpg"),
|
||||||
path: elementWrapper.elementId,
|
path: url,
|
||||||
url: url,
|
url: url,
|
||||||
file_unique: _.key
|
file_unique: _.key
|
||||||
},
|
},
|
||||||
@@ -465,7 +466,6 @@ export class OneBotMsgApi {
|
|||||||
sendMsg.data.summary,
|
sendMsg.data.summary,
|
||||||
sendMsg.data.sub_type,
|
sendMsg.data.sub_type,
|
||||||
);
|
);
|
||||||
context.deleteAfterSentFiles.push(sendPicElement.picElement.sourcePath);
|
|
||||||
return sendPicElement;
|
return sendPicElement;
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -607,6 +607,14 @@ export class OneBotMsgApi {
|
|||||||
}),
|
}),
|
||||||
|
|
||||||
[OB11MessageDataType.miniapp]: async () => undefined,
|
[OB11MessageDataType.miniapp]: async () => undefined,
|
||||||
|
|
||||||
|
[OB11MessageDataType.contact]: async ({ data }, context) => {
|
||||||
|
let arkJson = await this.core.apis.UserApi.getBuddyRecommendContactArkJson(data.qq, '');
|
||||||
|
return this.ob11ToRawConverters.json({
|
||||||
|
data: { data: arkJson.arkMsg },
|
||||||
|
type: OB11MessageDataType.json
|
||||||
|
}, context);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
constructor(obContext: NapCatOneBot11Adapter, core: NapCatCore) {
|
constructor(obContext: NapCatOneBot11Adapter, core: NapCatCore) {
|
||||||
@@ -629,7 +637,7 @@ export class OneBotMsgApi {
|
|||||||
if (element.grayTipElement.subElementType == NTGrayTipElementSubTypeV2.GRAYTIP_ELEMENT_SUBTYPE_XMLMSG) {
|
if (element.grayTipElement.subElementType == NTGrayTipElementSubTypeV2.GRAYTIP_ELEMENT_SUBTYPE_XMLMSG) {
|
||||||
//好友添加成功事件
|
//好友添加成功事件
|
||||||
if (element.grayTipElement.xmlElement.templId === '10229' && msg.peerUin !== '') {
|
if (element.grayTipElement.xmlElement.templId === '10229' && msg.peerUin !== '') {
|
||||||
return new OB11FriendAddNoticeEvent(this.core, parseInt(msg.peerUin));
|
return new OB11FriendAddNoticeEvent(this.core, parseInt(msg.peerUin) || Number(await this.core.apis.UserApi.getUinByUidV2(msg.peerUid)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -818,4 +826,38 @@ export class OneBotMsgApi {
|
|||||||
|
|
||||||
return { path, fileName: inputdata.name ?? fileName };
|
return { path, fileName: inputdata.name ?? fileName };
|
||||||
}
|
}
|
||||||
|
async parseSysMessage(msg: number[]) {
|
||||||
|
const sysMsg = SysMessage.decode(Uint8Array.from(msg)) as unknown as SysMessageType;
|
||||||
|
if (sysMsg.msgSpec.length === 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const { msgType, subType, subSubType } = sysMsg.msgSpec[0];
|
||||||
|
if (msgType === 528 && subType === 39 && subSubType === 39) {
|
||||||
|
if (!sysMsg.bodyWrapper) return;
|
||||||
|
const event = await this.obContext.apis.UserApi.parseLikeEvent(sysMsg.bodyWrapper.wrappedBody);
|
||||||
|
return event;
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
if (msgType === 732 && subType === 16 && subSubType === 16) {
|
||||||
|
const greyTip = GreyTipWrapper.fromBinary(Uint8Array.from(sysMsg.bodyWrapper!.wrappedBody.slice(7)));
|
||||||
|
if (greyTip.subTypeId === 36) {
|
||||||
|
const emojiLikeToOthers = EmojiLikeToOthersWrapper1
|
||||||
|
.fromBinary(greyTip.rest)
|
||||||
|
.wrapper!
|
||||||
|
.body!;
|
||||||
|
if (emojiLikeToOthers.attributes?.operation !== 1) { // Un-like
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const eventOrEmpty = await this.apis.GroupApi.createGroupEmojiLikeEvent(
|
||||||
|
greyTip.groupCode.toString(),
|
||||||
|
await this.core.apis.UserApi.getUinByUidV2(emojiLikeToOthers.attributes!.senderUid),
|
||||||
|
emojiLikeToOthers.msgSpec!.msgSeq.toString(),
|
||||||
|
emojiLikeToOthers.attributes!.emojiId,
|
||||||
|
);
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-unused-expressions
|
||||||
|
eventOrEmpty && await this.networkManager.emitEvent(eventOrEmpty);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -47,7 +47,7 @@ export class OneBotQuickActionApi {
|
|||||||
const peerContextMode = msg.message_type == 'private' ? ContextMode.Private : ContextMode.Group;
|
const peerContextMode = msg.message_type == 'private' ? ContextMode.Private : ContextMode.Group;
|
||||||
|
|
||||||
const peer: Peer = await createContext(this.core, {
|
const peer: Peer = await createContext(this.core, {
|
||||||
message: "",
|
message_type: undefined,
|
||||||
group_id: msg.group_id?.toString(),
|
group_id: msg.group_id?.toString(),
|
||||||
user_id: msg.user_id?.toString(),
|
user_id: msg.user_id?.toString(),
|
||||||
}, peerContextMode);
|
}, peerContextMode);
|
||||||
|
@@ -13,9 +13,10 @@ export class OneBotUserApi {
|
|||||||
this.core = core;
|
this.core = core;
|
||||||
}
|
}
|
||||||
async parseLikeEvent(wrappedBody: Uint8Array): Promise<OB11ProfileLikeEvent | undefined> {
|
async parseLikeEvent(wrappedBody: Uint8Array): Promise<OB11ProfileLikeEvent | undefined> {
|
||||||
const likeTip = profileLikeTip.decode(Uint8Array.from(wrappedBody.slice(12))) as unknown as ProfileLikeTipType;
|
const likeTip = profileLikeTip.decode(Uint8Array.from(wrappedBody)) as unknown as ProfileLikeTipType;
|
||||||
|
if (likeTip?.msgType !== 0 || likeTip?.subType !== 203) return;
|
||||||
this.core.context.logger.logDebug("收到点赞通知消息");
|
this.core.context.logger.logDebug("收到点赞通知消息");
|
||||||
const likeMsg = likeTip.msg;
|
const likeMsg = likeTip.content.msg;
|
||||||
if (!likeMsg) return;
|
if (!likeMsg) return;
|
||||||
const detail = likeMsg.detail;
|
const detail = likeMsg.detail;
|
||||||
if (!detail) return;
|
if (!detail) return;
|
||||||
|
@@ -48,7 +48,8 @@ export class OB11Entities {
|
|||||||
}[role];
|
}[role];
|
||||||
}
|
}
|
||||||
|
|
||||||
static sex(sex: Sex): OB11UserSex {
|
static sex(sex?: Sex): OB11UserSex {
|
||||||
|
if (!sex) return OB11UserSex.unknown;
|
||||||
return {
|
return {
|
||||||
[Sex.male]: OB11UserSex.male,
|
[Sex.male]: OB11UserSex.male,
|
||||||
[Sex.female]: OB11UserSex.female,
|
[Sex.female]: OB11UserSex.female,
|
||||||
@@ -126,6 +127,7 @@ export class OB11Entities {
|
|||||||
return {
|
return {
|
||||||
group_id: parseInt(peerId),
|
group_id: parseInt(peerId),
|
||||||
folder_id: folder.folderId,
|
folder_id: folder.folderId,
|
||||||
|
folder: folder.folderId,
|
||||||
folder_name: folder.folderName,
|
folder_name: folder.folderName,
|
||||||
create_time: folder.createTime,
|
create_time: folder.createTime,
|
||||||
creator: parseInt(folder.createUin),
|
creator: parseInt(folder.createUin),
|
||||||
|
@@ -238,39 +238,10 @@ export class NapCatOneBot11Adapter {
|
|||||||
|
|
||||||
private initMsgListener() {
|
private initMsgListener() {
|
||||||
const msgListener = new NodeIKernelMsgListener();
|
const msgListener = new NodeIKernelMsgListener();
|
||||||
msgListener.onRecvSysMsg = async (msg) => {
|
msgListener.onRecvSysMsg = (msg) => {
|
||||||
const sysMsg = SysMessage.decode(Uint8Array.from(msg)) as unknown as SysMessageType;
|
this.apis.MsgApi.parseSysMessage(msg).then((event) => {
|
||||||
if (sysMsg.msgSpec.length === 0) {
|
if (event) this.networkManager.emitEvent(event);
|
||||||
return;
|
}).catch(e => this.context.logger.logError('constructSysMessage error: ', e));
|
||||||
}
|
|
||||||
const { msgType, subType, subSubType } = sysMsg.msgSpec[0];
|
|
||||||
if (msgType === 528 && subType === 39 && subSubType === 39) {
|
|
||||||
if (!sysMsg.bodyWrapper) return;
|
|
||||||
let event = await this.apis.UserApi.parseLikeEvent(sysMsg.bodyWrapper.wrappedBody);
|
|
||||||
if (event) await this.networkManager.emitEvent(event);
|
|
||||||
};
|
|
||||||
/*
|
|
||||||
if (msgType === 732 && subType === 16 && subSubType === 16) {
|
|
||||||
const greyTip = GreyTipWrapper.fromBinary(Uint8Array.from(sysMsg.bodyWrapper!.wrappedBody.slice(7)));
|
|
||||||
if (greyTip.subTypeId === 36) {
|
|
||||||
const emojiLikeToOthers = EmojiLikeToOthersWrapper1
|
|
||||||
.fromBinary(greyTip.rest)
|
|
||||||
.wrapper!
|
|
||||||
.body!;
|
|
||||||
if (emojiLikeToOthers.attributes?.operation !== 1) { // Un-like
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const eventOrEmpty = await this.apis.GroupApi.createGroupEmojiLikeEvent(
|
|
||||||
greyTip.groupCode.toString(),
|
|
||||||
await this.core.apis.UserApi.getUinByUidV2(emojiLikeToOthers.attributes!.senderUid),
|
|
||||||
emojiLikeToOthers.msgSpec!.msgSeq.toString(),
|
|
||||||
emojiLikeToOthers.attributes!.emojiId,
|
|
||||||
);
|
|
||||||
// eslint-disable-next-line @typescript-eslint/no-unused-expressions
|
|
||||||
eventOrEmpty && await this.networkManager.emitEvent(eventOrEmpty);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
};
|
};
|
||||||
|
|
||||||
msgListener.onInputStatusPush = async data => {
|
msgListener.onInputStatusPush = async data => {
|
||||||
|
@@ -47,7 +47,7 @@ export class OB11PassiveWebSocketAdapter implements IOB11NetworkAdapter {
|
|||||||
}
|
}
|
||||||
//鉴权
|
//鉴权
|
||||||
this.authorize(token, wsClient, wsReq);
|
this.authorize(token, wsClient, wsReq);
|
||||||
let paramUrl = wsReq.url?.indexOf('?') !== -1 ? wsReq.url?.substring(0, wsReq.url?.indexOf('?')) : wsReq.url;
|
const paramUrl = wsReq.url?.indexOf('?') !== -1 ? wsReq.url?.substring(0, wsReq.url?.indexOf('?')) : wsReq.url;
|
||||||
const isEventConnect = paramUrl === '/event' || paramUrl === '' || paramUrl === '/';
|
const isEventConnect = paramUrl === '/event' || paramUrl === '' || paramUrl === '/';
|
||||||
if (isEventConnect) {
|
if (isEventConnect) {
|
||||||
this.connectEvent(core, wsClient);
|
this.connectEvent(core, wsClient);
|
||||||
|
@@ -1,4 +1,5 @@
|
|||||||
export interface OB11User {
|
export interface OB11User {
|
||||||
|
[key: string]: any;
|
||||||
user_id: number;
|
user_id: number;
|
||||||
nickname: string;
|
nickname: string;
|
||||||
remark?: string;
|
remark?: string;
|
||||||
@@ -81,6 +82,7 @@ export interface OB11GroupFile {
|
|||||||
export interface OB11GroupFileFolder {
|
export interface OB11GroupFileFolder {
|
||||||
group_id: number,
|
group_id: number,
|
||||||
folder_id: string,
|
folder_id: string,
|
||||||
|
folder: string,
|
||||||
folder_name: string,
|
folder_name: string,
|
||||||
create_time: number,
|
create_time: number,
|
||||||
creator: number,
|
creator: number,
|
||||||
|
@@ -62,6 +62,7 @@ export enum OB11MessageDataType {
|
|||||||
dice = 'dice',
|
dice = 'dice',
|
||||||
RPS = 'rps',
|
RPS = 'rps',
|
||||||
miniapp = 'miniapp',//json类
|
miniapp = 'miniapp',//json类
|
||||||
|
contact = 'contact',
|
||||||
Location = 'location'
|
Location = 'location'
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -81,10 +82,15 @@ export interface OB11MessageText {
|
|||||||
text: string, // 纯文本
|
text: string, // 纯文本
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
export interface OB11MessageContext {
|
||||||
|
type: OB11MessageDataType.contact,
|
||||||
|
data: {
|
||||||
|
qq: string,
|
||||||
|
}
|
||||||
|
}
|
||||||
export interface OB11MessageFileBase {
|
export interface OB11MessageFileBase {
|
||||||
data: {
|
data: {
|
||||||
file_unique?:string,
|
file_unique?: string,
|
||||||
path?: string;
|
path?: string;
|
||||||
thumb?: string;
|
thumb?: string;
|
||||||
name?: string;
|
name?: string;
|
||||||
@@ -198,7 +204,7 @@ export type OB11MessageData =
|
|||||||
OB11MessageAt | OB11MessageReply |
|
OB11MessageAt | OB11MessageReply |
|
||||||
OB11MessageImage | OB11MessageRecord | OB11MessageFile | OB11MessageVideo |
|
OB11MessageImage | OB11MessageRecord | OB11MessageFile | OB11MessageVideo |
|
||||||
OB11MessageNode | OB11MessageIdMusic | OB11MessageCustomMusic | OB11MessageJson |
|
OB11MessageNode | OB11MessageIdMusic | OB11MessageCustomMusic | OB11MessageJson |
|
||||||
OB11MessageDice | OB11MessageRPS | OB11MessageMarkdown | OB11MessageForward
|
OB11MessageDice | OB11MessageRPS | OB11MessageMarkdown | OB11MessageForward | OB11MessageContext
|
||||||
|
|
||||||
export interface OB11PostSendMsg {
|
export interface OB11PostSendMsg {
|
||||||
message_type?: 'private' | 'group'
|
message_type?: 'private' | 'group'
|
||||||
|
@@ -30,7 +30,7 @@ async function onSettingWindowCreated(view: Element) {
|
|||||||
SettingItem(
|
SettingItem(
|
||||||
'<span id="napcat-update-title">Napcat</span>',
|
'<span id="napcat-update-title">Napcat</span>',
|
||||||
undefined,
|
undefined,
|
||||||
SettingButton('V2.4.6', 'napcat-update-button', 'secondary'),
|
SettingButton('V2.5.3', 'napcat-update-button', 'secondary'),
|
||||||
),
|
),
|
||||||
]),
|
]),
|
||||||
SettingList([
|
SettingList([
|
||||||
|
@@ -164,7 +164,7 @@ async function onSettingWindowCreated(view) {
|
|||||||
SettingItem(
|
SettingItem(
|
||||||
'<span id="napcat-update-title">Napcat</span>',
|
'<span id="napcat-update-title">Napcat</span>',
|
||||||
void 0,
|
void 0,
|
||||||
SettingButton("V2.4.6", "napcat-update-button", "secondary")
|
SettingButton("V2.5.3", "napcat-update-button", "secondary")
|
||||||
)
|
)
|
||||||
]),
|
]),
|
||||||
SettingList([
|
SettingList([
|
||||||
|
Reference in New Issue
Block a user