mirror of
https://github.com/NapNeko/NapCatQQ.git
synced 2025-07-19 12:03:37 +00:00
Compare commits
22 Commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
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.0",
|
||||||
"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.0",
|
||||||
"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);
|
||||||
});
|
});
|
||||||
|
@@ -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 };
|
||||||
|
@@ -209,7 +209,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;
|
||||||
}
|
}
|
||||||
|
@@ -1 +1 @@
|
|||||||
export const napCatVersion = '2.4.6';
|
export const napCatVersion = '2.5.0';
|
||||||
|
@@ -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,10 +32,6 @@ 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}个群组缓存完成`);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -266,6 +262,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 {
|
||||||
|
@@ -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;
|
||||||
};
|
};
|
||||||
|
@@ -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;
|
||||||
|
|
||||||
|
@@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -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
|
||||||
},
|
},
|
||||||
@@ -818,4 +819,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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -126,6 +126,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,
|
||||||
|
@@ -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.0', '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.0", "napcat-update-button", "secondary")
|
||||||
)
|
)
|
||||||
]),
|
]),
|
||||||
SettingList([
|
SettingList([
|
||||||
|
Reference in New Issue
Block a user