mirror of
https://github.com/NapNeko/NapCatQQ.git
synced 2025-07-19 12:03:37 +00:00
Compare commits
27 Commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
f691320453 | ||
![]() |
be39fc3a21 | ||
![]() |
d2fafaf33a | ||
![]() |
27ae331352 | ||
![]() |
3f2dcfbacc | ||
![]() |
8565aee8b6 | ||
![]() |
f983add599 | ||
![]() |
030192afeb | ||
![]() |
c8b6a158f1 | ||
![]() |
e71f7849a7 | ||
![]() |
b64d1ff4ff | ||
![]() |
5a0028be26 | ||
![]() |
926d7deb43 | ||
![]() |
6384b50bae | ||
![]() |
9feb0f4b53 | ||
![]() |
43ec1b7cfd | ||
![]() |
05b7a59f8d | ||
![]() |
17e680f7af | ||
![]() |
035d256d4e | ||
![]() |
8939adf886 | ||
![]() |
027ffbffa6 | ||
![]() |
3cca06712b | ||
![]() |
2b9359dbf4 | ||
![]() |
c0f5d3bd2e | ||
![]() |
2a2d5382e1 | ||
![]() |
2e4986024c | ||
![]() |
8a9c605dae |
@@ -4,7 +4,7 @@
|
||||
"name": "NapCatQQ",
|
||||
"slug": "NapCat.Framework",
|
||||
"description": "高性能的 OneBot 11 协议实现",
|
||||
"version": "2.2.13",
|
||||
"version": "2.2.16",
|
||||
"icon": "./logo.png",
|
||||
"authors": [
|
||||
{
|
||||
|
@@ -2,7 +2,7 @@
|
||||
"name": "napcat",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"version": "2.2.13",
|
||||
"version": "2.2.16",
|
||||
"scripts": {
|
||||
"build:framework": "vite build --mode framework",
|
||||
"build:shell": "vite build --mode shell",
|
||||
|
2
script/KillQQ.bat
Normal file
2
script/KillQQ.bat
Normal file
@@ -0,0 +1,2 @@
|
||||
@echo off
|
||||
taskkill /f /im QQ.exe
|
@@ -10,7 +10,7 @@ export interface ListenerIBase {
|
||||
[key: string]: any;
|
||||
}
|
||||
|
||||
export class NTEventChannel extends EventEmitter {
|
||||
export class NTEventWrapperV2 extends EventEmitter {
|
||||
private wrapperApi: WrapperNodeApi;
|
||||
private wrapperSession: NodeIQQNTWrapperSession;
|
||||
private listenerRefStorage = new Map<string, ListenerIBase>();
|
@@ -11,7 +11,7 @@ interface InternalMapKey {
|
||||
|
||||
export type ListenerClassBase = Record<string, string>;
|
||||
|
||||
export class LegacyNTEventWrapper {
|
||||
export class NTEventWrapper {
|
||||
private WrapperSession: NodeIQQNTWrapperSession | undefined; //WrapperSession
|
||||
private listenerManager: Map<string, ListenerClassBase> = new Map<string, ListenerClassBase>(); //ListenerName-Unique -> Listener实例
|
||||
private EventTask = new Map<string, Map<string, Map<string, InternalMapKey>>>(); //tasks ListenerMainName -> ListenerSubName-> uuid -> {timeout,createtime,func}
|
@@ -1,5 +1,5 @@
|
||||
import log4js, { Configuration } from 'log4js';
|
||||
import { truncateString } from '@/common/utils/helper';
|
||||
import { truncateString } from '@/common/helper';
|
||||
import path from 'node:path';
|
||||
import chalk from 'chalk';
|
||||
import { AtType, ChatType, ElementType, MessageElement, RawMessage, SelfInfo } from '@/core';
|
@@ -2,8 +2,6 @@ import path, { dirname } from 'path';
|
||||
import { fileURLToPath } from 'url';
|
||||
import fs from 'fs';
|
||||
|
||||
export const napcat_version = '2.2.13';
|
||||
|
||||
export class NapCatPathWrapper {
|
||||
binaryPath: string;
|
||||
logsPath: string;
|
@@ -1,6 +1,6 @@
|
||||
import path from 'node:path';
|
||||
import fs from 'node:fs';
|
||||
import { systemPlatform } from '@/common/utils/system';
|
||||
import { systemPlatform } from '@/common/system';
|
||||
import { getDefaultQQVersionConfigInfo, getQQVersionConfigPath } from './helper';
|
||||
import AppidTable from '@/core/external/appid.json';
|
||||
import { LogWrapper } from './log';
|
||||
@@ -60,20 +60,17 @@ export class QQBasicInfoWrapper {
|
||||
|
||||
getAppidV2(): { appid: string; qua: string } {
|
||||
const appidTbale = AppidTable as unknown as QQAppidTableType;
|
||||
try {
|
||||
const fullVersion = this.getFullQQVesion();
|
||||
if (!fullVersion) throw new Error('QQ版本获取失败');
|
||||
const fullVersion = this.getFullQQVesion();
|
||||
if (fullVersion) {
|
||||
const data = appidTbale[fullVersion];
|
||||
if (data) {
|
||||
return data;
|
||||
}
|
||||
} catch (e) {
|
||||
this.context.logger.log(`[QQ版本兼容性检测] 获取Appid异常 请检测NapCat/QQNT是否正常`);
|
||||
}
|
||||
// 以下是兜底措施
|
||||
this.context.logger.log(
|
||||
`[QQ版本兼容性检测] ${this.getFullQQVesion()} 版本兼容性不佳,可能会导致一些功能无法正常使用`,
|
||||
);
|
||||
|
||||
// else
|
||||
this.context.logger.log(`[QQ版本兼容性检测] 获取Appid异常 请检测NapCat/QQNT是否正常`);
|
||||
this.context.logger.log(`[QQ版本兼容性检测] ${fullVersion} 版本兼容性不佳,可能会导致一些功能无法正常使用`,);
|
||||
return { appid: systemPlatform === 'linux' ? '537240795' : '537240709', qua: this.getQUAInternal() };
|
||||
}
|
||||
}
|
1
src/common/version.ts
Normal file
1
src/common/version.ts
Normal file
@@ -0,0 +1 @@
|
||||
export const napCatVersion = '2.2.16';
|
@@ -21,14 +21,13 @@ import { InstanceContext, NapCatCore } from '@/core';
|
||||
import * as fileType from 'file-type';
|
||||
import imageSize from 'image-size';
|
||||
import { ISizeCalculationResult } from 'image-size/dist/types/interface';
|
||||
import { NodeIKernelSearchService } from '../services/NodeIKernelSearchService';
|
||||
import { RkeyManager } from '../helper/rkey';
|
||||
import { calculateFileMD5, isGIF } from '@/common/utils/file';
|
||||
import { calculateFileMD5, isGIF } from '@/common/file';
|
||||
import pathLib from 'node:path';
|
||||
import { defaultVideoThumbB64, getVideoInfo } from '@/common/utils/video';
|
||||
import { defaultVideoThumbB64, getVideoInfo } from '@/common/video';
|
||||
import ffmpeg from 'fluent-ffmpeg';
|
||||
import fsnormal from 'node:fs';
|
||||
import { encodeSilk } from '@/common/utils/audio';
|
||||
import { encodeSilk } from '@/common/audio';
|
||||
|
||||
|
||||
export class NTQQFileApi {
|
||||
|
@@ -1,6 +1,6 @@
|
||||
import { FriendV2 } from '@/core/entities';
|
||||
import { BuddyListReqType, InstanceContext, NapCatCore, NodeIKernelProfileService } from '@/core';
|
||||
import { LimitedHashTable } from '@/common/utils/message-unique';
|
||||
import { BuddyListReqType, InstanceContext, NapCatCore } from '@/core';
|
||||
import { LimitedHashTable } from '@/common/message-unique';
|
||||
|
||||
export class NTQQFriendApi {
|
||||
context: InstanceContext;
|
||||
|
@@ -9,9 +9,8 @@ import {
|
||||
KickMemberV2Req,
|
||||
MemberExtSourceType,
|
||||
NapCatCore,
|
||||
NodeIKernelGroupService,
|
||||
} from '@/core';
|
||||
import { isNumeric, runAllWithTimeout, sleep } from '@/common/utils/helper';
|
||||
import { isNumeric, runAllWithTimeout } from '@/common/helper';
|
||||
|
||||
export class NTQQGroupApi {
|
||||
context: InstanceContext;
|
||||
@@ -23,17 +22,13 @@ export class NTQQGroupApi {
|
||||
constructor(context: InstanceContext, core: NapCatCore) {
|
||||
this.context = context;
|
||||
this.core = core;
|
||||
sleep(1000).then(() => {
|
||||
this.initCache().then().catch(context.logger.logError);
|
||||
});
|
||||
this.initCache().then().catch(context.logger.logError);
|
||||
}
|
||||
|
||||
async initCache() {
|
||||
this.groups = await this.getGroups();
|
||||
for (const group of this.groups) {
|
||||
this.groupCache.set(group.groupCode, group);
|
||||
const data = await this.getGroupMembers(group.groupCode, 3000);
|
||||
this.groupMemberCache.set(group.groupCode, data);
|
||||
}
|
||||
this.context.logger.logDebug(`加载${this.groups.length}个群组缓存完成`);
|
||||
}
|
||||
@@ -175,7 +170,7 @@ export class NTQQGroupApi {
|
||||
let members = this.groupMemberCache.get(groupCodeStr);
|
||||
if (!members) {
|
||||
try {
|
||||
members = await this.getGroupMembers(groupCodeStr);
|
||||
members = await this.getGroupMembersV2(groupCodeStr);
|
||||
// 更新群成员列表
|
||||
this.groupMemberCache.set(groupCodeStr, members);
|
||||
} catch (e) {
|
||||
@@ -196,7 +191,7 @@ export class NTQQGroupApi {
|
||||
|
||||
let member = getMember();
|
||||
if (!member) {
|
||||
members = await this.getGroupMembers(groupCodeStr);
|
||||
members = await this.getGroupMembersV2(groupCodeStr);
|
||||
member = getMember();
|
||||
}
|
||||
return member;
|
||||
@@ -307,7 +302,6 @@ export class NTQQGroupApi {
|
||||
}
|
||||
|
||||
async getGroupMemberV2(GroupCode: string, uid: string, forced = false) {
|
||||
type EventType = NodeIKernelGroupService['getMemberInfo'];
|
||||
const Listener = this.core.eventWrapper.registerListen(
|
||||
'NodeIKernelGroupListener/onMemberInfoChange',
|
||||
1,
|
||||
@@ -330,6 +324,38 @@ export class NTQQGroupApi {
|
||||
return member;
|
||||
}
|
||||
|
||||
async getGroupMembersV2(groupQQ: string, num = 3000): Promise<Map<string, GroupMember>> {
|
||||
const groupService = this.context.session.getGroupService();
|
||||
const sceneId = groupService.createMemberListScene(groupQQ, 'groupMemberList_MainWindow');
|
||||
const listener = this.core.eventWrapper.registerListen(
|
||||
'NodeIKernelGroupListener/onMemberListChange',
|
||||
1,
|
||||
500,
|
||||
(params) => params.sceneId === sceneId,
|
||||
);
|
||||
try {
|
||||
const [membersFromFunc, membersFromListener] = await Promise.allSettled([
|
||||
groupService.getNextMemberList(sceneId, undefined, num),
|
||||
listener,
|
||||
]);
|
||||
if (membersFromFunc.status === 'fulfilled' && membersFromListener.status === 'fulfilled') {
|
||||
return new Map([
|
||||
...membersFromFunc.value.result.infos,
|
||||
...membersFromListener.value[0].infos
|
||||
]);
|
||||
}
|
||||
if (membersFromFunc.status === 'fulfilled') {
|
||||
return membersFromFunc.value.result.infos;
|
||||
}
|
||||
if (membersFromListener.status === 'fulfilled') {
|
||||
return membersFromListener.value[0].infos;
|
||||
}
|
||||
throw new Error('获取群成员列表失败');
|
||||
} finally {
|
||||
groupService.destroyMemberListScene(sceneId);
|
||||
}
|
||||
}
|
||||
|
||||
async getGroupMembers(groupQQ: string, num = 3000): Promise<Map<string, GroupMember>> {
|
||||
const groupService = this.context.session.getGroupService();
|
||||
const sceneId = groupService.createMemberListScene(groupQQ, 'groupMemberList_MainWindow');
|
||||
|
@@ -3,6 +3,10 @@ import { InstanceContext, NapCatCore } from '@/core';
|
||||
import { GeneralCallResult } from '@/core/services/common';
|
||||
|
||||
export class NTQQMsgApi {
|
||||
// nt_qq//global//nt_data//Emoji//emoji-resource//sysface_res/apng/ 下可以看到所有QQ表情预览
|
||||
// nt_qq\global\nt_data\Emoji\emoji-resource\face_config.json 里面有所有表情的id, 自带表情id是QSid, 标准emoji表情id是QCid
|
||||
// 其实以官方文档为准是最好的,https://bot.q.qq.com/wiki/develop/api-v2/openapi/emoji/model.html#EmojiType
|
||||
|
||||
context: InstanceContext;
|
||||
core: NapCatCore;
|
||||
|
||||
@@ -10,7 +14,12 @@ export class NTQQMsgApi {
|
||||
this.context = context;
|
||||
this.core = core;
|
||||
}
|
||||
|
||||
async getAioFirstViewLatestMsgs(peer: Peer, MsgCount: number) {
|
||||
return this.context.session.getMsgService().getAioFirstViewLatestMsgs(peer, MsgCount);
|
||||
}
|
||||
async getLatestDbMsgs(peer: Peer, MsgCount: number) {
|
||||
return this.context.session.getMsgService().getLatestDbMsgs(peer, MsgCount);
|
||||
}
|
||||
async FetchLongMsg(peer: Peer, msgId: string) {
|
||||
return this.context.session.getMsgService().fetchLongMsg(peer, msgId);
|
||||
}
|
||||
|
@@ -1,4 +1,4 @@
|
||||
import { RequestUtil } from '@/common/utils/request';
|
||||
import { RequestUtil } from '@/common/request';
|
||||
import { MiniAppLuaJsonType } from '@/core';
|
||||
import { InstanceContext, NapCatCore } from '..';
|
||||
|
||||
|
@@ -1,4 +1,4 @@
|
||||
import { GeneralCallResult, InstanceContext, NapCatCore } from '@/core';
|
||||
import { InstanceContext, NapCatCore } from '@/core';
|
||||
|
||||
export class NTQQSystemApi {
|
||||
context: InstanceContext;
|
||||
|
@@ -1,8 +1,8 @@
|
||||
import type { ModifyProfileParams, User, UserDetailInfoByUinV2 } from '@/core/entities';
|
||||
import { RequestUtil } from '@/common/utils/request';
|
||||
import type { ModifyProfileParams, User } from '@/core/entities';
|
||||
import { RequestUtil } from '@/common/request';
|
||||
import { ProfileBizType, UserDetailSource } from '@/core/services';
|
||||
import { InstanceContext, NapCatCore } from '..';
|
||||
import { solveAsyncProblem } from '@/common/utils/helper';
|
||||
import { solveAsyncProblem } from '@/common/helper';
|
||||
|
||||
export class NTQQUserApi {
|
||||
context: InstanceContext;
|
||||
|
@@ -1,4 +1,4 @@
|
||||
import { RequestUtil } from '@/common/utils/request';
|
||||
import { RequestUtil } from '@/common/request';
|
||||
import {
|
||||
GroupEssenceMsgRet,
|
||||
InstanceContext,
|
||||
@@ -184,11 +184,8 @@ export class NTQQWebApi {
|
||||
const HonorInfo: any = { group_id: groupCode };
|
||||
|
||||
if (getType === WebHonorType.TALKATIVE || getType === WebHonorType.ALL) {
|
||||
try {
|
||||
const RetInternal = await getDataInternal(groupCode, 1);
|
||||
if (!RetInternal) {
|
||||
throw new Error('获取龙王信息失败');
|
||||
}
|
||||
const RetInternal = await getDataInternal(groupCode, 1);
|
||||
if (RetInternal) {
|
||||
HonorInfo.current_talkative = {
|
||||
user_id: RetInternal[0]?.uin,
|
||||
avatar: RetInternal[0]?.avatar,
|
||||
@@ -206,16 +203,13 @@ export class NTQQWebApi {
|
||||
nickname: talkative_ele?.name,
|
||||
});
|
||||
}
|
||||
} catch (e) {
|
||||
this.context.logger.logDebug(e);
|
||||
} else {
|
||||
this.context.logger.logError('获取龙王信息失败');
|
||||
}
|
||||
}
|
||||
if (getType === WebHonorType.PERFORMER || getType === WebHonorType.ALL) {
|
||||
try {
|
||||
const RetInternal = await getDataInternal(groupCode, 2);
|
||||
if (!RetInternal) {
|
||||
throw new Error('获取群聊之火失败');
|
||||
}
|
||||
const RetInternal = await getDataInternal(groupCode, 2);
|
||||
if (RetInternal) {
|
||||
HonorInfo.performer_list = [];
|
||||
for (const performer_ele of RetInternal) {
|
||||
HonorInfo.performer_list.push({
|
||||
@@ -225,16 +219,13 @@ export class NTQQWebApi {
|
||||
description: performer_ele?.desc,
|
||||
});
|
||||
}
|
||||
} catch (e) {
|
||||
this.context.logger.logDebug(e);
|
||||
} else {
|
||||
this.context.logger.logError('获取群聊之火失败');
|
||||
}
|
||||
}
|
||||
if (getType === WebHonorType.PERFORMER || getType === WebHonorType.ALL) {
|
||||
try {
|
||||
const RetInternal = await getDataInternal(groupCode, 3);
|
||||
if (!RetInternal) {
|
||||
throw new Error('获取群聊炽焰失败');
|
||||
}
|
||||
const RetInternal = await getDataInternal(groupCode, 3);
|
||||
if (RetInternal) {
|
||||
HonorInfo.legend_list = [];
|
||||
for (const legend_ele of RetInternal) {
|
||||
HonorInfo.legend_list.push({
|
||||
@@ -244,16 +235,13 @@ export class NTQQWebApi {
|
||||
desc: legend_ele?.description,
|
||||
});
|
||||
}
|
||||
} catch (e) {
|
||||
this.context.logger.logDebug('获取群聊炽焰失败', e);
|
||||
} else {
|
||||
this.context.logger.logError('获取群聊炽焰失败');
|
||||
}
|
||||
}
|
||||
if (getType === WebHonorType.EMOTION || getType === WebHonorType.ALL) {
|
||||
try {
|
||||
const RetInternal = await getDataInternal(groupCode, 6);
|
||||
if (!RetInternal) {
|
||||
throw new Error('获取快乐源泉失败');
|
||||
}
|
||||
const RetInternal = await getDataInternal(groupCode, 6);
|
||||
if (RetInternal) {
|
||||
HonorInfo.emotion_list = [];
|
||||
for (const emotion_ele of RetInternal) {
|
||||
HonorInfo.emotion_list.push({
|
||||
@@ -263,11 +251,11 @@ export class NTQQWebApi {
|
||||
desc: emotion_ele.description,
|
||||
});
|
||||
}
|
||||
} catch (e) {
|
||||
this.context.logger.logDebug('获取快乐源泉失败', e);
|
||||
} else {
|
||||
this.context.logger.logError('获取快乐源泉失败');
|
||||
}
|
||||
}
|
||||
//冒尖小春笋好像已经被tx扬了
|
||||
// 冒尖小春笋好像已经被tx扬了 R.I.P.
|
||||
if (getType === WebHonorType.EMOTION || getType === WebHonorType.ALL) {
|
||||
HonorInfo.strong_newbie_list = [];
|
||||
}
|
||||
|
@@ -2,15 +2,15 @@ import { NodeQQNTWrapperUtil, StableNTApiWrapper, WrapperNodeApi } from '@/core/
|
||||
import path from 'node:path';
|
||||
import fs from 'node:fs';
|
||||
import { InstanceContext } from './wrapper';
|
||||
import { proxiedListenerOf } from '@/common/utils/proxy-handler';
|
||||
import { proxiedListenerOf } from '@/common/proxy-handler';
|
||||
import { NodeIKernelGroupListener, NodeIKernelMsgListener, NodeIKernelProfileListener } from './listeners';
|
||||
import { DataSource, GroupMember, SelfInfo } from './entities';
|
||||
import { LegacyNTEventWrapper } from '@/common/framework/event-legacy';
|
||||
import { NTEventWrapper } from '@/common/event';
|
||||
import { NTQQFileApi, NTQQFriendApi, NTQQGroupApi, NTQQMsgApi, NTQQSystemApi, NTQQUserApi, NTQQWebApi } from './apis';
|
||||
import os from 'node:os';
|
||||
import { NTQQCollectionApi } from './apis/collection';
|
||||
import { NapCatConfigLoader } from './helper/config';
|
||||
import { LogLevel } from '@/common/utils/log';
|
||||
import { LogLevel } from '@/common/log';
|
||||
|
||||
export enum NapCatCoreWorkingEnv {
|
||||
Unknown = 0,
|
||||
@@ -31,7 +31,7 @@ export function loadQQWrapper(QQVersion: string): WrapperNodeApi {
|
||||
export class NapCatCore {
|
||||
readonly context: InstanceContext;
|
||||
readonly apis: StableNTApiWrapper;
|
||||
readonly eventWrapper: LegacyNTEventWrapper;
|
||||
readonly eventWrapper: NTEventWrapper;
|
||||
// readonly eventChannel: NTEventChannel;
|
||||
NapCatDataPath: string;
|
||||
NapCatTempPath: string;
|
||||
@@ -45,7 +45,7 @@ export class NapCatCore {
|
||||
this.selfInfo = selfInfo;
|
||||
this.context = context;
|
||||
this.util = this.context.wrapper.NodeQQNTWrapperUtil;
|
||||
this.eventWrapper = new LegacyNTEventWrapper(context.session);
|
||||
this.eventWrapper = new NTEventWrapper(context.session);
|
||||
this.apis = {
|
||||
FileApi: new NTQQFileApi(this.context, this),
|
||||
SystemApi: new NTQQSystemApi(this.context, this),
|
||||
@@ -130,12 +130,13 @@ export class NapCatCore {
|
||||
// 获取群成员
|
||||
}
|
||||
const sceneId = this.context.session.getGroupService().createMemberListScene(g.groupCode, 'groupMemberList_MainWindow');
|
||||
this.context.session.getGroupService().getNextMemberList(sceneId!, undefined, 3000).then( /* r => {
|
||||
this.context.session.getGroupService().getNextMemberList(sceneId, undefined, 3000).then( /* r => {
|
||||
// console.log(`get group ${g.groupCode} members`, r);
|
||||
// r.result.infos.forEach(member => {
|
||||
// });
|
||||
// groupMembers.set(g.groupCode, r.result.infos);
|
||||
} */);
|
||||
this.context.session.getGroupService().destroyMemberListScene(sceneId);
|
||||
});
|
||||
};
|
||||
groupListener.onMemberListChange = (arg) => {
|
||||
@@ -159,10 +160,8 @@ export class NapCatCore {
|
||||
} else {
|
||||
this.apis.GroupApi.groupMemberCache.set(groupCode, arg.infos);
|
||||
}
|
||||
// console.log('onMemberListChange', groupCode, arg);
|
||||
};
|
||||
groupListener.onMemberInfoChange = (groupCode, dataSource, members) => {
|
||||
//console.log('onMemberInfoChange', groupCode, changeType, members);
|
||||
if (dataSource === DataSource.LOCAL && members.get(this.selfInfo.uid)?.isDelete) {
|
||||
// 自身退群或者被踢退群 5s用于Api操作 之后不再出现
|
||||
setTimeout(() => {
|
||||
|
@@ -1,11 +1,9 @@
|
||||
import { ConfigBase } from '@/common/utils/config-base';
|
||||
import { ConfigBase } from '@/common/config-base';
|
||||
import napCatDefaultConfig from '@/core/external/napcat.json';
|
||||
import { NapCatCore } from '@/core';
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-declaration-merging
|
||||
export type NapCatConfig = typeof napCatDefaultConfig;
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-declaration-merging
|
||||
export class NapCatConfigLoader extends ConfigBase<NapCatConfig> {
|
||||
constructor(core: NapCatCore, configPath: string) {
|
||||
super('napcat', core, configPath);
|
||||
|
@@ -1,5 +1,5 @@
|
||||
import { LogWrapper } from '@/common/utils/log';
|
||||
import { RequestUtil } from '@/common/utils/request';
|
||||
import { LogWrapper } from '@/common/log';
|
||||
import { RequestUtil } from '@/common/request';
|
||||
|
||||
interface ServerRkeyData {
|
||||
group_rkey: string;
|
||||
|
@@ -1,6 +1,7 @@
|
||||
import { DataSource, Group, GroupListUpdateType, GroupMember, GroupNotify } from '@/core/entities';
|
||||
|
||||
export class NodeIKernelGroupListener {
|
||||
onGroupListInited(listEmpty: boolean): void { }
|
||||
// 发现于Win 9.9.9 23159
|
||||
onGroupMemberLevelInfoChange(...args: unknown[]): void {
|
||||
|
||||
|
@@ -19,10 +19,10 @@ import type {
|
||||
NodeIKernelMsgListener,
|
||||
NodeIKernelProfileListener,
|
||||
NodeIKernelRobotListener,
|
||||
NodeIKernelSearchListener_Polyfill,
|
||||
NodeIKernelSessionListener,
|
||||
NodeIKernelStorageCleanListener,
|
||||
NodeIKernelTicketListener,
|
||||
NodeIKernelSearchListener_Polyfill,
|
||||
} from '.';
|
||||
|
||||
export type ListenerNamingMapping = {
|
||||
|
@@ -167,11 +167,17 @@ export interface NodeIKernelMsgService {
|
||||
|
||||
getAllOnlineFileMsgs(...args: unknown[]): unknown;
|
||||
|
||||
getLatestDbMsgs(peer: Peer, cnt: number): Promise<unknown>;
|
||||
getLatestDbMsgs(peer: Peer, cnt: number): Promise<GeneralCallResult & {
|
||||
msgList: RawMessage[]
|
||||
}>;
|
||||
|
||||
getLastMessageList(peer: Peer[]): Promise<unknown>;
|
||||
getLastMessageList(peer: Peer[]): Promise<GeneralCallResult & {
|
||||
msgList: RawMessage[]
|
||||
}>;
|
||||
|
||||
getAioFirstViewLatestMsgs(peer: Peer, num: number): unknown;
|
||||
getAioFirstViewLatestMsgs(peer: Peer, num: number): Promise<GeneralCallResult & {
|
||||
msgList: RawMessage[]
|
||||
}>;
|
||||
|
||||
getMsgs(peer: Peer, msgId: string, count: unknown, queryOrder: boolean): Promise<unknown>;
|
||||
|
||||
@@ -512,11 +518,11 @@ export interface NodeIKernelMsgService {
|
||||
result: number,
|
||||
errMsg: string,
|
||||
emojiLikesList:
|
||||
Array<{
|
||||
tinyId: string,
|
||||
nickName: string,
|
||||
headUrl: string
|
||||
}>,
|
||||
Array<{
|
||||
tinyId: string,
|
||||
nickName: string,
|
||||
headUrl: string
|
||||
}>,
|
||||
cookie: string,
|
||||
isLastPage: boolean,
|
||||
isFirstPage: boolean
|
||||
|
@@ -1,6 +1,5 @@
|
||||
import { AnyCnameRecord } from 'node:dns';
|
||||
import { BizKey, ModifyProfileParams, SimpleInfo, UserDetailInfoByUin, UserDetailInfoByUinV2 } from '@/core';
|
||||
import { NodeIKernelProfileListener } from '@/core';
|
||||
import { BizKey, ModifyProfileParams, NodeIKernelProfileListener, SimpleInfo, UserDetailInfoByUinV2 } from '@/core';
|
||||
import { GeneralCallResult } from '@/core/services/common';
|
||||
|
||||
export enum UserDetailSource {
|
||||
|
@@ -20,6 +20,7 @@ export * from './NodeIKernelCollectionService';
|
||||
import type {
|
||||
NodeIKernelAvatarService,
|
||||
NodeIKernelBuddyService,
|
||||
NodeIKernelCollectionService,
|
||||
NodeIKernelDbToolsService,
|
||||
NodeIKernelFileAssistantService,
|
||||
NodeIKernelGroupService,
|
||||
@@ -30,11 +31,10 @@ import type {
|
||||
NodeIKernelProfileService,
|
||||
NodeIKernelRichMediaService,
|
||||
NodeIKernelRobotService,
|
||||
NodeIKernelSearchService,
|
||||
NodeIKernelStorageCleanService,
|
||||
NodeIKernelTicketService,
|
||||
NodeIKernelTipOffService,
|
||||
NodeIKernelSearchService,
|
||||
NodeIKernelCollectionService,
|
||||
} from '.';
|
||||
|
||||
export type ServiceNamingMapping = {
|
||||
|
@@ -1,9 +1,9 @@
|
||||
import { LogWrapper } from '@/common/utils/log';
|
||||
import { QQBasicInfoWrapper } from '@/common/utils/qq-basic-info';
|
||||
import { LogWrapper } from '@/common/log';
|
||||
import { QQBasicInfoWrapper } from '@/common/qq-basic-info';
|
||||
import { NapCatCoreWorkingEnv, NodeIKernelLoginService, NodeIQQNTWrapperSession, WrapperNodeApi } from '@/core';
|
||||
import { NTQQFileApi, NTQQFriendApi, NTQQGroupApi, NTQQMsgApi, NTQQSystemApi, NTQQUserApi, NTQQWebApi } from '../apis';
|
||||
import { NTQQCollectionApi } from '../apis/collection';
|
||||
import { NapCatPathWrapper } from '@/common/framework/napcat';
|
||||
import { NapCatPathWrapper } from '@/common/path';
|
||||
|
||||
export interface InstanceContext {
|
||||
readonly workingEnv: NapCatCoreWorkingEnv;
|
||||
|
@@ -1,7 +1,7 @@
|
||||
import path from 'node:path';
|
||||
import fs from 'node:fs';
|
||||
import { PlatformType, VendorType, WrapperSessionInitConfig } from './wrapper';
|
||||
import { getMachineId, hostname, systemName, systemVersion } from '@/common/utils/system';
|
||||
import { getMachineId, hostname, systemName, systemVersion } from '@/common/system';
|
||||
|
||||
export async function genSessionConfig(QQVersionAppid: string, QQVersion: string, selfUin: string, selfUid: string, account_path: string): Promise<WrapperSessionInitConfig> {
|
||||
const downloadPath = path.join(account_path, 'NapCat', 'temp');
|
||||
|
@@ -1,5 +1,4 @@
|
||||
import { NodeIDependsAdapter, NodeIDispatcherAdapter, NodeIGlobalAdapter } from '../adapters';
|
||||
import { NodeIKernelSessionListener } from '@/core';
|
||||
import {
|
||||
NodeIKernelAvatarService,
|
||||
NodeIKernelBuddyService,
|
||||
@@ -9,11 +8,12 @@ import {
|
||||
NodeIKernelProfileLikeService,
|
||||
NodeIKernelProfileService,
|
||||
NodeIKernelRichMediaService,
|
||||
NodeIKernelRobotService,
|
||||
NodeIKernelSessionListener,
|
||||
NodeIKernelStorageCleanService,
|
||||
NodeIKernelTicketService,
|
||||
NodeIKernelTipOffService,
|
||||
} from '@/core';
|
||||
import { NodeIKernelStorageCleanService } from '@/core';
|
||||
import { NodeIKernelRobotService } from '@/core';
|
||||
import { NodeIKernelNodeMiscService } from '../services/NodeIKernelNodeMiscService';
|
||||
import { NodeIKernelUixConvertService } from '../services/NodeIKernelUixConvertService';
|
||||
import { NodeIKernelMsgBackupService } from '../services/NodeIKernelMsgBackupService';
|
||||
|
@@ -1,7 +1,7 @@
|
||||
import { NapCatPathWrapper } from '@/common/framework/napcat';
|
||||
import { LogWrapper } from '@/common/utils/log';
|
||||
import { proxiedListenerOf } from '@/common/utils/proxy-handler';
|
||||
import { QQBasicInfoWrapper } from '@/common/utils/qq-basic-info';
|
||||
import { NapCatPathWrapper } from '@/common/path';
|
||||
import { LogWrapper } from '@/common/log';
|
||||
import { proxiedListenerOf } from '@/common/proxy-handler';
|
||||
import { QQBasicInfoWrapper } from '@/common/qq-basic-info';
|
||||
import { loadQQWrapper, NapCatCore, NapCatCoreWorkingEnv } from '@/core/core';
|
||||
import { InstanceContext } from '@/core';
|
||||
import { SelfInfo } from '@/core/entities';
|
||||
|
4
src/nekodoge/Readme.md
Normal file
4
src/nekodoge/Readme.md
Normal file
@@ -0,0 +1,4 @@
|
||||
# nekodoge
|
||||
此协议为替代QQ平台 OnebotV11长期不可靠问题
|
||||
|
||||
# 规划路线
|
0
src/nekodoge/api/index.ts
Normal file
0
src/nekodoge/api/index.ts
Normal file
0
src/nekodoge/event/index.ts
Normal file
0
src/nekodoge/event/index.ts
Normal file
0
src/nekodoge/helper/index.ts
Normal file
0
src/nekodoge/helper/index.ts
Normal file
0
src/nekodoge/index.ts
Normal file
0
src/nekodoge/index.ts
Normal file
18
src/nekodoge/network/socket.ts
Normal file
18
src/nekodoge/network/socket.ts
Normal file
@@ -0,0 +1,18 @@
|
||||
import { createServer } from 'node:net';
|
||||
export class NewAdapterNetwork {
|
||||
constructor(public host: number, public port: number) { }
|
||||
async open() {
|
||||
const server = createServer((socket) => {
|
||||
socket.on('data', (data) => {
|
||||
|
||||
});
|
||||
socket.on('end', () => {
|
||||
|
||||
});
|
||||
socket.on('connect', () => {
|
||||
|
||||
})
|
||||
});
|
||||
server.listen(this.port, this.host);
|
||||
}
|
||||
}
|
@@ -1,6 +1,6 @@
|
||||
import { OB11Return } from '../types';
|
||||
|
||||
import { isNull } from '../../common/utils/helper';
|
||||
import { isNull } from '../../common/helper';
|
||||
|
||||
export class OB11Response {
|
||||
static res<T>(data: T, status: string, retcode: number, message: string = ''): OB11Return<T> {
|
||||
|
@@ -2,7 +2,7 @@
|
||||
import { FromSchema, JSONSchema } from 'json-schema-to-ts';
|
||||
import BaseAction from '../BaseAction';
|
||||
import { ActionName } from '../types';
|
||||
import { MessageUnique } from '@/common/utils/message-unique';
|
||||
import { MessageUnique } from '@/common/message-unique';
|
||||
|
||||
const SchemaData = {
|
||||
type: 'object',
|
||||
|
@@ -1,7 +1,7 @@
|
||||
import BaseAction from '../BaseAction';
|
||||
import { ActionName } from '../types';
|
||||
import { FromSchema, JSONSchema } from 'json-schema-to-ts';
|
||||
import { checkFileReceived, uri2local } from '@/common/utils/file';
|
||||
import { checkFileReceived, uri2local } from '@/common/file';
|
||||
import fs from 'fs';
|
||||
|
||||
const SchemaData = {
|
||||
|
@@ -1,7 +1,7 @@
|
||||
import BaseAction from '../BaseAction';
|
||||
import { ActionName, BaseCheckResult } from '../types';
|
||||
import * as fs from 'node:fs';
|
||||
import { checkFileReceived, uri2local } from '@/common/utils/file';
|
||||
import { checkFileReceived, uri2local } from '@/common/file';
|
||||
|
||||
interface Payload {
|
||||
file: string;
|
||||
|
@@ -1,8 +1,8 @@
|
||||
import BaseAction from '../BaseAction';
|
||||
import fs from 'fs/promises';
|
||||
import { UUIDConverter } from '@/common/utils/helper';
|
||||
import { UUIDConverter } from '@/common/helper';
|
||||
import { ActionName } from '../types';
|
||||
import { ChatType, ElementType, FileElement, Peer, RawMessage, VideoElement } from '@/core/entities';
|
||||
import { ChatType, ElementType, Peer, RawMessage } from '@/core/entities';
|
||||
import { FromSchema, JSONSchema } from 'json-schema-to-ts';
|
||||
|
||||
export interface GetFilePayload {
|
||||
@@ -34,61 +34,55 @@ export class GetFileBase extends BaseAction<GetFilePayload, GetFileResponse> {
|
||||
const NTQQMsgApi = this.core.apis.MsgApi;
|
||||
const NTQQGroupApi = this.core.apis.GroupApi;
|
||||
const NTQQFileApi = this.core.apis.FileApi;
|
||||
let UuidData: {
|
||||
high: string;
|
||||
low: string;
|
||||
} | undefined;
|
||||
try {
|
||||
UuidData = UUIDConverter.decode(payload.file);
|
||||
if (UuidData) {
|
||||
const peerUin = UuidData.high;
|
||||
const msgId = UuidData.low;
|
||||
const isGroup: boolean = !!(await NTQQGroupApi.getGroups(false)).find(e => e.groupCode == peerUin);
|
||||
let peer: Peer | undefined;
|
||||
//识别Peer
|
||||
if (isGroup) {
|
||||
peer = { chatType: ChatType.KCHATTYPEGROUP, peerUid: peerUin };
|
||||
}
|
||||
const PeerUid = await NTQQUserApi.getUidByUinV2(peerUin);
|
||||
if (PeerUid) {
|
||||
const isBuddy = await NTQQFriendApi.isBuddy(PeerUid);
|
||||
if (isBuddy) {
|
||||
peer = { chatType: ChatType.KCHATTYPEC2C, peerUid: PeerUid };
|
||||
} else {
|
||||
peer = { chatType: ChatType.KCHATTYPETEMPC2CFROMGROUP, peerUid: PeerUid };
|
||||
}
|
||||
}
|
||||
if (!peer) {
|
||||
throw new Error('chattype not support');
|
||||
}
|
||||
const msgList = await NTQQMsgApi.getMsgsByMsgId(peer, [msgId]);
|
||||
if (msgList.msgList.length == 0) {
|
||||
throw new Error('msg not found');
|
||||
}
|
||||
const msg = msgList.msgList[0];
|
||||
const findEle = msg.elements.find(e => e.elementType == ElementType.VIDEO || e.elementType == ElementType.FILE || e.elementType == ElementType.PTT);
|
||||
if (!findEle) {
|
||||
throw new Error('element not found');
|
||||
}
|
||||
const downloadPath = await NTQQFileApi.downloadMedia(msgId, msg.chatType, msg.peerUid, findEle.elementId, '', '');
|
||||
const fileSize = findEle?.videoElement?.fileSize || findEle?.fileElement?.fileSize || findEle?.pttElement?.fileSize || '0';
|
||||
const fileName = findEle?.videoElement?.fileName || findEle?.fileElement?.fileName || findEle?.pttElement?.fileName || '';
|
||||
const res: GetFileResponse = {
|
||||
file: downloadPath,
|
||||
url: downloadPath,
|
||||
file_size: fileSize,
|
||||
file_name: fileName,
|
||||
};
|
||||
if (true/*enableLocalFile2Url*/ && downloadPath) {
|
||||
try {
|
||||
res.base64 = await fs.readFile(downloadPath, 'base64');
|
||||
} catch (e) {
|
||||
throw new Error('文件下载失败. ' + e);
|
||||
}
|
||||
}
|
||||
//不手动删除?文件持久化了
|
||||
return res;
|
||||
const uuidData = UUIDConverter.decode(payload.file);
|
||||
const peerUin = uuidData.high;
|
||||
const msgId = uuidData.low;
|
||||
const isGroup: boolean = !!(await NTQQGroupApi.getGroups(false)).find(e => e.groupCode == peerUin);
|
||||
let peer: Peer | undefined;
|
||||
//识别Peer
|
||||
if (isGroup) {
|
||||
peer = { chatType: ChatType.KCHATTYPEGROUP, peerUid: peerUin };
|
||||
}
|
||||
const PeerUid = await NTQQUserApi.getUidByUinV2(peerUin);
|
||||
if (PeerUid) {
|
||||
const isBuddy = await NTQQFriendApi.isBuddy(PeerUid);
|
||||
if (isBuddy) {
|
||||
peer = { chatType: ChatType.KCHATTYPEC2C, peerUid: PeerUid };
|
||||
} else {
|
||||
peer = { chatType: ChatType.KCHATTYPETEMPC2CFROMGROUP, peerUid: PeerUid };
|
||||
}
|
||||
}
|
||||
if (!peer) {
|
||||
throw new Error('chattype not support');
|
||||
}
|
||||
const msgList = await NTQQMsgApi.getMsgsByMsgId(peer, [msgId]);
|
||||
if (msgList.msgList.length == 0) {
|
||||
throw new Error('msg not found');
|
||||
}
|
||||
const msg = msgList.msgList[0];
|
||||
const findEle = msg.elements.find(e => e.elementType == ElementType.VIDEO || e.elementType == ElementType.FILE || e.elementType == ElementType.PTT);
|
||||
if (!findEle) {
|
||||
throw new Error('element not found');
|
||||
}
|
||||
const downloadPath = await NTQQFileApi.downloadMedia(msgId, msg.chatType, msg.peerUid, findEle.elementId, '', '');
|
||||
const fileSize = findEle?.videoElement?.fileSize || findEle?.fileElement?.fileSize || findEle?.pttElement?.fileSize || '0';
|
||||
const fileName = findEle?.videoElement?.fileName || findEle?.fileElement?.fileName || findEle?.pttElement?.fileName || '';
|
||||
const res: GetFileResponse = {
|
||||
file: downloadPath,
|
||||
url: downloadPath,
|
||||
file_size: fileSize,
|
||||
file_name: fileName,
|
||||
};
|
||||
if (/* enableLocalFile2Url && */ downloadPath) {
|
||||
try {
|
||||
res.base64 = await fs.readFile(downloadPath, 'base64');
|
||||
} catch (e) {
|
||||
throw new Error('文件下载失败. ' + e);
|
||||
}
|
||||
}
|
||||
//不手动删除?文件持久化了
|
||||
return res;
|
||||
} catch {
|
||||
this.core.context.logger.logDebug('GetFileBase Mode - 1 Error');
|
||||
}
|
||||
@@ -119,7 +113,7 @@ export class GetFileBase extends BaseAction<GetFilePayload, GetFileResponse> {
|
||||
file_size: NTSearchNameResult[0].fileSize.toString(),
|
||||
file_name: NTSearchNameResult[0].fileName,
|
||||
};
|
||||
if (true/*enableLocalFile2Url*/ && downloadPath) {
|
||||
if (/* enableLocalFile2Url && */ downloadPath) {
|
||||
try {
|
||||
res.base64 = await fs.readFile(downloadPath, 'base64');
|
||||
} catch (e) {
|
||||
@@ -130,66 +124,6 @@ export class GetFileBase extends BaseAction<GetFilePayload, GetFileResponse> {
|
||||
return res;
|
||||
}
|
||||
throw new Error('file not found');
|
||||
// let cache = await dbUtil.getFileCacheByName(payload.file);
|
||||
// if (!cache) {
|
||||
// cache = await dbUtil.getFileCacheByUuid(payload.file);
|
||||
// }
|
||||
// if (!cache) {
|
||||
// throw new Error('file not found');
|
||||
// }
|
||||
// const { enableLocalFile2Url } = ob11Config;
|
||||
// try {
|
||||
// await fs.access(cache.path, fs.constants.F_OK);
|
||||
// } catch (e) {
|
||||
// logDebug('local file not found, start download...');
|
||||
// // if (cache.url) {
|
||||
// // const downloadResult = await uri2local(cache.url);
|
||||
// // if (downloadResult.success) {
|
||||
// // cache.path = downloadResult.path;
|
||||
// // dbUtil.updateFileCache(cache).then();
|
||||
// // } else {
|
||||
// // throw new Error('file download failed. ' + downloadResult.errMsg);
|
||||
// // }
|
||||
// // } else {
|
||||
// // // 没有url的可能是私聊文件或者群文件,需要自己下载
|
||||
// // log('需要调用 NTQQ 下载文件api');
|
||||
// let peer = MessageUnique.getPeerByMsgId(cache.msgId);
|
||||
// let msg = await NTQQMsgApi.getMsgsByMsgId(peer?.Peer!,cache.msgId);
|
||||
// // log('文件 msg', msg);
|
||||
// if (msg) {
|
||||
// // 构建下载函数
|
||||
// const downloadPath = await NTQQFileApi.downloadMedia(msg.msgId, msg.chatType, msg.peerUid,
|
||||
// cache.elementId, '', '');
|
||||
// // await sleep(1000);
|
||||
|
||||
// // log('download result', downloadPath);
|
||||
// let peer = MessageUnique.getPeerByMsgId(cache.msgId);
|
||||
// msg = await NTQQMsgApi.getMsgsByMsgId(peer?.Peer!,cache.msgId);
|
||||
// // log('下载完成后的msg', msg);
|
||||
// cache.path = downloadPath!;
|
||||
// dbUtil.updateFileCache(cache).then();
|
||||
// // log('下载完成后的msg', msg);
|
||||
// // }
|
||||
// }
|
||||
|
||||
// }
|
||||
// // log('file found', cache);
|
||||
// const res: GetFileResponse = {
|
||||
// file: cache.path,
|
||||
// url: cache.url,
|
||||
// file_size: cache.size.toString(),
|
||||
// file_name: cache.name
|
||||
// };
|
||||
// if (enableLocalFile2Url) {
|
||||
// if (!cache.url) {
|
||||
// try {
|
||||
// res.base64 = await fs.readFile(cache.path, 'base64');
|
||||
// } catch (e) {
|
||||
// throw new Error('文件下载失败. ' + e);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//return res;
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -2,7 +2,7 @@ import BaseAction from '../BaseAction';
|
||||
import { ActionName } from '../types';
|
||||
import fs from 'fs';
|
||||
import { join as joinPath } from 'node:path';
|
||||
import { calculateFileMD5, httpDownload } from '@/common/utils/file';
|
||||
import { calculateFileMD5, httpDownload } from '@/common/file';
|
||||
import { randomUUID } from 'crypto';
|
||||
import { FromSchema, JSONSchema } from 'json-schema-to-ts';
|
||||
|
||||
|
@@ -2,7 +2,7 @@ import BaseAction from '../BaseAction';
|
||||
import { OB11ForwardMessage } from '@/onebot';
|
||||
import { ActionName } from '../types';
|
||||
import { FromSchema, JSONSchema } from 'json-schema-to-ts';
|
||||
import { MessageUnique } from '@/common/utils/message-unique';
|
||||
import { MessageUnique } from '@/common/message-unique';
|
||||
|
||||
const SchemaData = {
|
||||
type: 'object',
|
||||
|
@@ -1,9 +1,9 @@
|
||||
import BaseAction from '../BaseAction';
|
||||
import { OB11Message } from '@/onebot';
|
||||
import { ActionName } from '../types';
|
||||
import { ChatType, RawMessage } from '@/core/entities';
|
||||
import { ChatType } from '@/core/entities';
|
||||
import { FromSchema, JSONSchema } from 'json-schema-to-ts';
|
||||
import { MessageUnique } from '@/common/utils/message-unique';
|
||||
import { MessageUnique } from '@/common/message-unique';
|
||||
|
||||
interface Response {
|
||||
messages: OB11Message[];
|
||||
@@ -13,7 +13,7 @@ const SchemaData = {
|
||||
type: 'object',
|
||||
properties: {
|
||||
user_id: { type: ['number', 'string'] },
|
||||
message_seq: { type: 'number' },
|
||||
message_seq: { type: ['number', 'string'] },
|
||||
count: { type: ['number', 'string'] },
|
||||
reverseOrder: { type: ['boolean', 'string'] },
|
||||
},
|
||||
@@ -37,21 +37,19 @@ export default class GetFriendMsgHistory extends BaseAction<Payload, Response> {
|
||||
if (!uid) throw `记录${payload.user_id}不存在`;
|
||||
const friend = await NTQQFriendApi.isBuddy(uid);
|
||||
const peer = { chatType: friend ? ChatType.KCHATTYPEC2C : ChatType.KCHATTYPETEMPC2CFROMGROUP, peerUid: uid };
|
||||
|
||||
const hasMessageSeq = !payload.message_seq ? !!payload.message_seq : !(payload.message_seq?.toString() === '' || payload.message_seq?.toString() === '0');
|
||||
//拉取消息
|
||||
let msgList: RawMessage[];
|
||||
if (!payload.message_seq || payload.message_seq == 0) {
|
||||
msgList = (await NTQQMsgApi.getLastestMsgByUids(peer, MsgCount)).msgList;
|
||||
} else {
|
||||
const startMsgId = MessageUnique.getMsgIdAndPeerByShortId(payload.message_seq)?.MsgId;
|
||||
if (!startMsgId) throw `消息${payload.message_seq}不存在`;
|
||||
msgList = (await NTQQMsgApi.getMsgHistory(peer, startMsgId, MsgCount)).msgList;
|
||||
}
|
||||
const startMsgId = hasMessageSeq ? (MessageUnique.getMsgIdAndPeerByShortId(+payload.message_seq!)?.MsgId ?? payload.message_seq!.toString()) : '0';
|
||||
const msgList = hasMessageSeq ?
|
||||
(await NTQQMsgApi.getMsgHistory(peer, startMsgId, MsgCount)).msgList : (await NTQQMsgApi.getAioFirstViewLatestMsgs(peer, MsgCount)).msgList;
|
||||
if (msgList.length === 0) throw `消息${payload.message_seq}不存在`;
|
||||
//翻转消息
|
||||
if (isReverseOrder) msgList.reverse();
|
||||
//转换序号
|
||||
await Promise.all(msgList.map(async msg => {
|
||||
msg.id = MessageUnique.createMsg({ guildId: '', chatType: msg.chatType, peerUid: msg.peerUid }, msg.msgId);
|
||||
}));
|
||||
//转换消息
|
||||
//烘焙消息
|
||||
const ob11MsgList = (await Promise.all(
|
||||
msgList.map(msg => this.obContext.apis.MsgApi.parseMessage(msg)))
|
||||
).filter(msg => msg !== undefined);
|
||||
|
@@ -1,9 +1,9 @@
|
||||
import BaseAction from '../BaseAction';
|
||||
import { OB11Message } from '@/onebot';
|
||||
import { ActionName } from '../types';
|
||||
import { ChatType, Peer, RawMessage } from '@/core/entities';
|
||||
import { ChatType, Peer } from '@/core/entities';
|
||||
import { FromSchema, JSONSchema } from 'json-schema-to-ts';
|
||||
import { MessageUnique } from '@/common/utils/message-unique';
|
||||
import { MessageUnique } from '@/common/message-unique';
|
||||
|
||||
interface Response {
|
||||
messages: OB11Message[];
|
||||
@@ -13,7 +13,7 @@ const SchemaData = {
|
||||
type: 'object',
|
||||
properties: {
|
||||
group_id: { type: ['number', 'string'] },
|
||||
message_seq: { type: 'number' },
|
||||
message_seq: { type: ['number', 'string'] },
|
||||
count: { type: ['number', 'string'] },
|
||||
reverseOrder: { type: ['boolean', 'string'] },
|
||||
},
|
||||
@@ -32,21 +32,19 @@ export default class GoCQHTTPGetGroupMsgHistory extends BaseAction<Payload, Resp
|
||||
const isReverseOrder = typeof payload.reverseOrder === 'string' ? payload.reverseOrder === 'true' : !!payload.reverseOrder;
|
||||
const MsgCount = +(payload.count ?? 20);
|
||||
const peer: Peer = { chatType: ChatType.KCHATTYPEGROUP, peerUid: payload.group_id.toString() };
|
||||
const hasMessageSeq = !payload.message_seq ? !!payload.message_seq : !(payload.message_seq?.toString() === '' || payload.message_seq?.toString() === '0');
|
||||
//拉取消息
|
||||
let msgList: RawMessage[];
|
||||
if (!payload.message_seq || payload.message_seq == 0) {
|
||||
msgList = (await NTQQMsgApi.getLastestMsgByUids(peer, MsgCount)).msgList;
|
||||
} else {
|
||||
const startMsgId = MessageUnique.getMsgIdAndPeerByShortId(payload.message_seq)?.MsgId;
|
||||
if (!startMsgId) throw `消息${payload.message_seq}不存在`;
|
||||
msgList = (await NTQQMsgApi.getMsgHistory(peer, startMsgId, MsgCount)).msgList;
|
||||
}
|
||||
const startMsgId = hasMessageSeq ? (MessageUnique.getMsgIdAndPeerByShortId(+payload.message_seq!)?.MsgId ?? payload.message_seq!.toString()) : '0';
|
||||
const msgList = hasMessageSeq ?
|
||||
(await NTQQMsgApi.getMsgHistory(peer, startMsgId, MsgCount)).msgList : (await NTQQMsgApi.getAioFirstViewLatestMsgs(peer, MsgCount)).msgList;
|
||||
if (msgList.length === 0) throw `消息${payload.message_seq}不存在`;
|
||||
//翻转消息
|
||||
if (isReverseOrder) msgList.reverse();
|
||||
//转换序号
|
||||
await Promise.all(msgList.map(async msg => {
|
||||
msg.id = MessageUnique.createMsg({ guildId: '', chatType: msg.chatType, peerUid: msg.peerUid }, msg.msgId);
|
||||
}));
|
||||
|
||||
//转换消息
|
||||
//烘焙消息
|
||||
const ob11MsgList = (await Promise.all(
|
||||
msgList.map(msg => this.obContext.apis.MsgApi.parseMessage(msg)))
|
||||
).filter(msg => msg !== undefined);
|
||||
|
@@ -1,7 +1,7 @@
|
||||
import BaseAction from '../BaseAction';
|
||||
import { ActionName } from '../types';
|
||||
import { JSONSchema } from 'json-schema-to-ts';
|
||||
import { sleep } from '@/common/utils/helper';
|
||||
import { sleep } from '@/common/helper';
|
||||
|
||||
const SchemaData = {
|
||||
type: 'object',
|
||||
|
@@ -3,7 +3,7 @@ import { OB11User, OB11UserSex } from '@/onebot';
|
||||
import { OB11Entities } from '@/onebot/helper/entities';
|
||||
import { ActionName } from '../types';
|
||||
import { FromSchema, JSONSchema } from 'json-schema-to-ts';
|
||||
import { calcQQLevel } from '@/common/utils/helper';
|
||||
import { calcQQLevel } from '@/common/helper';
|
||||
|
||||
const SchemaData = {
|
||||
type: 'object',
|
||||
|
@@ -13,7 +13,7 @@ export class GoCQHTTPHandleQuickAction extends BaseAction<Payload, null> {
|
||||
async _handle(payload: Payload): Promise<null> {
|
||||
this.obContext.apis.QuickActionApi
|
||||
.handleQuickOperation(payload.context, payload.operation)
|
||||
.catch(this.core.context.logger.logError);
|
||||
.catch(this.core.context.logger.logError.bind(this.core.context.logger));
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
@@ -1,4 +1,4 @@
|
||||
import { checkFileReceived, uri2local } from '@/common/utils/file';
|
||||
import { checkFileReceived, uri2local } from '@/common/file';
|
||||
import BaseAction from '../BaseAction';
|
||||
import { ActionName } from '../types';
|
||||
import { unlink } from 'node:fs';
|
||||
@@ -11,7 +11,7 @@ const SchemaData = {
|
||||
content: { type: 'string' },
|
||||
image: { type: 'string' },
|
||||
pinned: { type: ['number', 'string'] },
|
||||
confirmRequired: { type: ['number', 'string'] },
|
||||
confirm_required: { type: ['number', 'string'] },
|
||||
},
|
||||
required: ['group_id', 'content'],
|
||||
} as const satisfies JSONSchema;
|
||||
@@ -27,7 +27,6 @@ export class SendGroupNotice extends BaseAction<Payload, null> {
|
||||
if (payload.image) {
|
||||
//公告图逻辑
|
||||
const {
|
||||
errMsg,
|
||||
path,
|
||||
isLocal,
|
||||
success,
|
||||
@@ -49,12 +48,12 @@ export class SendGroupNotice extends BaseAction<Payload, null> {
|
||||
}
|
||||
UploadImage = ImageUploadResult.picInfo;
|
||||
}
|
||||
let Notice_Pinned = +(payload.pinned ?? 0);
|
||||
let Notice_confirmRequired = +(payload.confirmRequired ?? 0);
|
||||
const PublishGroupBulletinResult = await NTQQGroupApi.publishGroupBulletin(payload.group_id.toString(), payload.content, UploadImage, Notice_Pinned, Notice_confirmRequired);
|
||||
const noticePinned = +(payload.pinned ?? 0);
|
||||
const noticeConfirmRequired = +(payload.confirm_required ?? 0);
|
||||
const publishGroupBulletinResult = await NTQQGroupApi.publishGroupBulletin(payload.group_id.toString(), payload.content, UploadImage, noticePinned, noticeConfirmRequired);
|
||||
|
||||
if (PublishGroupBulletinResult.result != 0) {
|
||||
throw `设置群公告失败,错误信息:${PublishGroupBulletinResult.errMsg}`;
|
||||
if (publishGroupBulletinResult.result != 0) {
|
||||
throw `设置群公告失败,错误信息:${publishGroupBulletinResult.errMsg}`;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
@@ -1,7 +1,7 @@
|
||||
import BaseAction from '../BaseAction';
|
||||
import { ActionName, BaseCheckResult } from '../types';
|
||||
import * as fs from 'node:fs';
|
||||
import { checkFileReceived, uri2local } from '@/common/utils/file';
|
||||
import { checkFileReceived, uri2local } from '@/common/file';
|
||||
|
||||
interface Payload {
|
||||
file: string,
|
||||
@@ -53,6 +53,5 @@ export default class SetGroupPortrait extends BaseAction<Payload, any> {
|
||||
}
|
||||
throw `头像${payload.file}设置失败,无法获取头像,文件可能不存在`;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
@@ -2,7 +2,7 @@ import BaseAction from '../BaseAction';
|
||||
import { ActionName } from '../types';
|
||||
import { ChatType } from '@/core/entities';
|
||||
import fs from 'fs';
|
||||
import { uri2local } from '@/common/utils/file';
|
||||
import { uri2local } from '@/common/file';
|
||||
import { FromSchema, JSONSchema } from 'json-schema-to-ts';
|
||||
|
||||
const SchemaData = {
|
||||
|
@@ -2,7 +2,7 @@ import BaseAction from '../BaseAction';
|
||||
import { ActionName } from '../types';
|
||||
import { ChatType, Peer, SendFileElement } from '@/core/entities';
|
||||
import fs from 'fs';
|
||||
import { uri2local } from '@/common/utils/file';
|
||||
import { uri2local } from '@/common/file';
|
||||
import { FromSchema, JSONSchema } from 'json-schema-to-ts';
|
||||
|
||||
const SchemaData = {
|
||||
|
@@ -1,7 +1,7 @@
|
||||
import BaseAction from '../BaseAction';
|
||||
import { ActionName } from '../types';
|
||||
import { FromSchema, JSONSchema } from 'json-schema-to-ts';
|
||||
import { MessageUnique } from '@/common/utils/message-unique';
|
||||
import { MessageUnique } from '@/common/message-unique';
|
||||
|
||||
const SchemaData = {
|
||||
type: 'object',
|
||||
|
@@ -22,7 +22,7 @@ class GetGroupMemberList extends BaseAction<Payload, OB11GroupMember[]> {
|
||||
async _handle(payload: Payload) {
|
||||
const NTQQGroupApi = this.core.apis.GroupApi;
|
||||
const NTQQWebApi = this.core.apis.WebApi;
|
||||
const groupMembers = await NTQQGroupApi.getGroupMembers(payload.group_id.toString());
|
||||
const groupMembers = await NTQQGroupApi.getGroupMembersV2(payload.group_id.toString());
|
||||
const groupMembersArr = Array.from(groupMembers.values());
|
||||
|
||||
let _groupMembers = groupMembersArr.map(item => {
|
||||
|
@@ -1,7 +1,7 @@
|
||||
import BaseAction from '../BaseAction';
|
||||
import { ActionName } from '../types';
|
||||
import { FromSchema, JSONSchema } from 'json-schema-to-ts';
|
||||
import { MessageUnique } from '@/common/utils/message-unique';
|
||||
import { MessageUnique } from '@/common/message-unique';
|
||||
|
||||
const SchemaData = {
|
||||
type: 'object',
|
||||
|
@@ -1,8 +1,7 @@
|
||||
import { ActionName } from '../types';
|
||||
import BaseAction from '../BaseAction';
|
||||
import { FromSchema, JSONSchema } from 'json-schema-to-ts';
|
||||
import { MessageUnique } from '@/common/utils/message-unique';
|
||||
import { NodeIKernelMsgListener } from '@/core';
|
||||
import { MessageUnique } from '@/common/message-unique';
|
||||
|
||||
const SchemaData = {
|
||||
type: 'object',
|
||||
|
@@ -2,7 +2,7 @@ import BaseAction from '../BaseAction';
|
||||
import { ChatType, Peer } from '@/core/entities';
|
||||
import { ActionName } from '../types';
|
||||
import { FromSchema, JSONSchema } from 'json-schema-to-ts';
|
||||
import { MessageUnique } from '@/common/utils/message-unique';
|
||||
import { MessageUnique } from '@/common/message-unique';
|
||||
|
||||
const SchemaData = {
|
||||
type: 'object',
|
||||
|
@@ -2,7 +2,7 @@ import { OB11Message } from '@/onebot';
|
||||
import BaseAction from '../BaseAction';
|
||||
import { ActionName } from '../types';
|
||||
import { FromSchema, JSONSchema } from 'json-schema-to-ts';
|
||||
import { MessageUnique } from '@/common/utils/message-unique';
|
||||
import { MessageUnique } from '@/common/message-unique';
|
||||
|
||||
|
||||
export type ReturnDataType = OB11Message
|
||||
|
@@ -7,7 +7,7 @@ import {
|
||||
} from '@/onebot/types';
|
||||
import { ActionName, BaseCheckResult } from '@/onebot/action/types';
|
||||
import { decodeCQCode } from '@/onebot/helper/cqcode';
|
||||
import { MessageUnique } from '@/common/utils/message-unique';
|
||||
import { MessageUnique } from '@/common/message-unique';
|
||||
import { ChatType, ElementType, NapCatCore, Peer, RawMessage, SendMessageElement } from '@/core';
|
||||
import BaseAction from '../BaseAction';
|
||||
|
||||
@@ -30,7 +30,7 @@ export function normalize(message: OB11MessageMixType, autoEscape = false): OB11
|
||||
) : Array.isArray(message) ? message : [message];
|
||||
}
|
||||
|
||||
async function createContext(core: NapCatCore, payload: OB11PostSendMsg, contextMode: ContextMode): Promise<Peer> {
|
||||
export async function createContext(core: NapCatCore, payload: OB11PostSendMsg, contextMode: ContextMode): Promise<Peer> {
|
||||
// This function determines the type of message by the existence of user_id / group_id,
|
||||
// not message_type.
|
||||
// This redundant design of Ob11 here should be blamed.
|
||||
|
@@ -1,7 +1,7 @@
|
||||
import { ActionName } from '../types';
|
||||
import BaseAction from '../BaseAction';
|
||||
import { FromSchema, JSONSchema } from 'json-schema-to-ts';
|
||||
import { MessageUnique } from '@/common/utils/message-unique';
|
||||
import { MessageUnique } from '@/common/message-unique';
|
||||
|
||||
const SchemaData = {
|
||||
type: 'object',
|
||||
|
@@ -1,6 +1,7 @@
|
||||
import BaseAction from '../BaseAction';
|
||||
import { ActionName } from '../types';
|
||||
import { napcat_version } from '@/common/framework/napcat';
|
||||
|
||||
import { napCatVersion } from '@/common/version';
|
||||
|
||||
export default class GetVersionInfo extends BaseAction<any, any> {
|
||||
actionName = ActionName.GetVersionInfo;
|
||||
@@ -9,7 +10,7 @@ export default class GetVersionInfo extends BaseAction<any, any> {
|
||||
return {
|
||||
app_name: 'NapCat.Onebot',
|
||||
protocol_version: 'v11',
|
||||
app_version: napcat_version,
|
||||
app_version: napCatVersion,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@@ -20,16 +20,12 @@ export default class SendLike extends BaseAction<Payload, null> {
|
||||
async _handle(payload: Payload): Promise<null> {
|
||||
const NTQQUserApi = this.core.apis.UserApi;
|
||||
//logDebug('点赞参数', payload);
|
||||
try {
|
||||
const qq = payload.user_id.toString();
|
||||
const uid: string = await NTQQUserApi.getUidByUinV2(qq) || '';
|
||||
const result = await NTQQUserApi.like(uid, parseInt(payload.times?.toString()) || 1);
|
||||
//logDebug('点赞结果', result);
|
||||
if (result.result !== 0) {
|
||||
throw Error(result.errMsg);
|
||||
}
|
||||
} catch (e) {
|
||||
throw `点赞失败 ${e}`;
|
||||
const qq = payload.user_id.toString();
|
||||
const uid: string = await NTQQUserApi.getUidByUinV2(qq) || '';
|
||||
const result = await NTQQUserApi.like(uid, parseInt(payload.times?.toString()) || 1);
|
||||
//logDebug('点赞结果', result);
|
||||
if (result.result !== 0) {
|
||||
throw `点赞失败 ${result.errMsg}`;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
@@ -5,7 +5,7 @@ import { OB11GroupIncreaseEvent } from '../event/notice/OB11GroupIncreaseEvent';
|
||||
import { OB11GroupDecreaseEvent } from '../event/notice/OB11GroupDecreaseEvent';
|
||||
import fastXmlParser from 'fast-xml-parser';
|
||||
import { OB11GroupMsgEmojiLikeEvent } from '../event/notice/OB11MsgEmojiLikeEvent';
|
||||
import { MessageUnique } from '@/common/utils/message-unique';
|
||||
import { MessageUnique } from '@/common/message-unique';
|
||||
|
||||
export class OneBotGroupApi {
|
||||
obContext: NapCatOneBot11Adapter;
|
||||
@@ -78,7 +78,7 @@ export class OneBotGroupApi {
|
||||
const NTQQGroupApi = this.core.apis.GroupApi;
|
||||
const groupElement = grayTipElement?.groupElement;
|
||||
if (!groupElement) return undefined;
|
||||
const member = await NTQQGroupApi.getGroupMemberV2(GroupCode, groupElement.memberUid);
|
||||
const member = await NTQQGroupApi.getGroupMember(GroupCode, groupElement.memberUid);
|
||||
const memberUin = member?.uin;
|
||||
const adminMember = await NTQQGroupApi.getGroupMember(GroupCode, groupElement.adminUid);
|
||||
if (memberUin) {
|
||||
@@ -89,8 +89,9 @@ export class OneBotGroupApi {
|
||||
parseInt(memberUin),
|
||||
parseInt(operatorUin),
|
||||
);
|
||||
} else {
|
||||
return undefined;
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
async parseGroupKickEvent(GroupCode: string, grayTipElement: GrayTipElement) {
|
||||
@@ -118,35 +119,33 @@ export class OneBotGroupApi {
|
||||
attributeNamePrefix: '',
|
||||
}).parse(grayTipElement.xmlElement.content);
|
||||
this.core.context.logger.logDebug('收到表情回应我的消息', emojiLikeData);
|
||||
try {
|
||||
const senderUin = emojiLikeData.gtip.qq.jp;
|
||||
const msgSeq = emojiLikeData.gtip.url.msgseq;
|
||||
const emojiId = emojiLikeData.gtip.face.id;
|
||||
const peer = {
|
||||
chatType: ChatType.KCHATTYPEGROUP,
|
||||
guildId: '',
|
||||
peerUid: GroupCode,
|
||||
};
|
||||
const replyMsgList = (await NTQQMsgApi.getMsgExBySeq(peer, msgSeq)).msgList;
|
||||
if (replyMsgList.length < 1) {
|
||||
return;
|
||||
}
|
||||
const replyMsg = replyMsgList.filter(e => e.msgSeq == msgSeq).sort((a, b) => parseInt(a.msgTime) - parseInt(b.msgTime))[0];
|
||||
//console.log("表情回应消息长度检测", msgSeq, replyMsg.elements);
|
||||
if (!replyMsg) throw new Error('找不到回应消息');
|
||||
return new OB11GroupMsgEmojiLikeEvent(
|
||||
this.core,
|
||||
parseInt(GroupCode),
|
||||
parseInt(senderUin),
|
||||
MessageUnique.getShortIdByMsgId(replyMsg.msgId)!,
|
||||
[{
|
||||
emoji_id: emojiId,
|
||||
count: 1,
|
||||
}],
|
||||
);
|
||||
} catch (e: any) {
|
||||
this.core.context.logger.logError('解析表情回应消息失败', e.stack);
|
||||
const senderUin = emojiLikeData.gtip.qq.jp;
|
||||
const msgSeq = emojiLikeData.gtip.url.msgseq;
|
||||
const emojiId = emojiLikeData.gtip.face.id;
|
||||
const peer = {
|
||||
chatType: ChatType.KCHATTYPEGROUP,
|
||||
guildId: '',
|
||||
peerUid: GroupCode,
|
||||
};
|
||||
const replyMsgList = (await NTQQMsgApi.getMsgExBySeq(peer, msgSeq)).msgList;
|
||||
if (replyMsgList.length < 1) {
|
||||
return;
|
||||
}
|
||||
return undefined;
|
||||
const replyMsg = replyMsgList.filter(e => e.msgSeq == msgSeq).sort((a, b) => parseInt(a.msgTime) - parseInt(b.msgTime))[0];
|
||||
//console.log("表情回应消息长度检测", msgSeq, replyMsg.elements);
|
||||
if (!replyMsg) {
|
||||
this.core.context.logger.logError('解析表情回应消息失败: 未找到回应消息');
|
||||
return undefined;
|
||||
}
|
||||
return new OB11GroupMsgEmojiLikeEvent(
|
||||
this.core,
|
||||
parseInt(GroupCode),
|
||||
parseInt(senderUin),
|
||||
MessageUnique.getShortIdByMsgId(replyMsg.msgId)!,
|
||||
[{
|
||||
emoji_id: emojiId,
|
||||
count: 1,
|
||||
}],
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@@ -1,5 +1,5 @@
|
||||
import { UUIDConverter } from '@/common/utils/helper';
|
||||
import { MessageUnique } from '@/common/utils/message-unique';
|
||||
import { UUIDConverter } from '@/common/helper';
|
||||
import { MessageUnique } from '@/common/message-unique';
|
||||
import {
|
||||
AtType,
|
||||
ChatType,
|
||||
@@ -27,8 +27,8 @@ import {
|
||||
import { OB11Entities } from '../helper';
|
||||
import { EventType } from '@/onebot/event/OB11BaseEvent';
|
||||
import { encodeCQCode } from '@/onebot/helper/cqcode';
|
||||
import { uri2local } from '@/common/utils/file';
|
||||
import { RequestUtil } from '@/common/utils/request';
|
||||
import { uri2local } from '@/common/file';
|
||||
import { RequestUtil } from '@/common/request';
|
||||
import fs from 'node:fs';
|
||||
import fsPromise from 'node:fs/promises';
|
||||
|
||||
|
@@ -13,9 +13,9 @@ import {
|
||||
import { ChatType, GroupRequestOperateTypes, NapCatCore, Peer } from '@/core';
|
||||
import { OB11FriendRequestEvent } from '@/onebot/event/request/OB11FriendRequest';
|
||||
import { OB11GroupRequestEvent } from '@/onebot/event/request/OB11GroupRequest';
|
||||
import { normalize } from '@/onebot/action/msg/SendMsg';
|
||||
import { isNull } from '@/common/utils/helper';
|
||||
|
||||
import { ContextMode, normalize } from '@/onebot/action/msg/SendMsg';
|
||||
import { isNull } from '@/common/helper';
|
||||
import { createContext } from '@/onebot/action/msg/SendMsg';
|
||||
export class OneBotQuickActionApi {
|
||||
constructor(
|
||||
public obContext: NapCatOneBot11Adapter,
|
||||
@@ -24,37 +24,34 @@ export class OneBotQuickActionApi {
|
||||
}
|
||||
|
||||
async handleQuickOperation(eventContext: QuickActionEvent, quickAction: QuickAction) {
|
||||
const logger = this.core.context.logger;
|
||||
if (eventContext.post_type === 'message') {
|
||||
await this.handleMsg(eventContext as OB11Message, quickAction)
|
||||
.catch(this.core.context.logger.logError);
|
||||
.catch(logger.logError.bind(logger));
|
||||
}
|
||||
if (eventContext.post_type === 'request') {
|
||||
const friendRequest = eventContext as OB11FriendRequestEvent;
|
||||
const groupRequest = eventContext as OB11GroupRequestEvent;
|
||||
if ((friendRequest).request_type === 'friend') {
|
||||
await this.handleFriendRequest(friendRequest, quickAction)
|
||||
.catch(this.core.context.logger.logError);
|
||||
.catch(logger.logError.bind(logger));
|
||||
} else if (groupRequest.request_type === 'group') {
|
||||
await this.handleGroupRequest(groupRequest, quickAction)
|
||||
.catch(this.core.context.logger.logError);
|
||||
.catch(logger.logError.bind(logger));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async handleMsg(msg: OB11Message, quickAction: QuickAction) {
|
||||
const reply = quickAction.reply;
|
||||
const peer: Peer = {
|
||||
chatType: ChatType.KCHATTYPEC2C,
|
||||
peerUid: await this.core.apis.UserApi.getUidByUinV2(msg.user_id.toString()) as string,
|
||||
};
|
||||
if (msg.message_type == 'private') {
|
||||
if (msg.sub_type === 'group') {
|
||||
peer.chatType = ChatType.KCHATTYPETEMPC2CFROMGROUP;
|
||||
}
|
||||
} else {
|
||||
peer.chatType = ChatType.KCHATTYPETEMPC2CFROMGROUP;
|
||||
peer.peerUid = msg.group_id!.toString();
|
||||
}
|
||||
const peerContextMode = msg.message_type == 'private' ? ContextMode.Private : ContextMode.Group;
|
||||
|
||||
const peer: Peer = await createContext(this.core, {
|
||||
message: "",
|
||||
group_id: msg.group_id?.toString(),
|
||||
user_id: msg.user_id?.toString(),
|
||||
}, peerContextMode);
|
||||
|
||||
if (reply) {
|
||||
// let group: Group | undefined;
|
||||
let replyMessage: OB11MessageData[] = [];
|
||||
|
@@ -1,4 +1,4 @@
|
||||
import { InstanceContext, NapCatCore } from '@/core';
|
||||
import { NapCatCore } from '@/core';
|
||||
|
||||
export enum EventType {
|
||||
META = 'meta_event',
|
||||
|
2
src/onebot/external/onebot11.json
vendored
2
src/onebot/external/onebot11.json
vendored
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"http": {
|
||||
"enable": false,
|
||||
"enable": true,
|
||||
"host": "",
|
||||
"port": 3000,
|
||||
"secret": "",
|
||||
|
@@ -1,4 +1,4 @@
|
||||
import { ConfigBase } from '@/common/utils/config-base';
|
||||
import { ConfigBase } from '@/common/config-base';
|
||||
import ob11DefaultConfig from '@/onebot/external/onebot11.json';
|
||||
import { NapCatCore } from '@/core';
|
||||
|
||||
|
@@ -1,4 +1,4 @@
|
||||
import { calcQQLevel } from '@/common/utils/helper';
|
||||
import { calcQQLevel } from '@/common/helper';
|
||||
import { Friend, FriendV2, Group, GroupMember, SelfInfo, Sex, User } from '@/core';
|
||||
import { OB11Group, OB11GroupMember, OB11GroupMemberRole, OB11User, OB11UserSex } from '../types';
|
||||
|
||||
|
@@ -7,9 +7,9 @@ import { OB11GroupDecreaseEvent } from '../event/notice/OB11GroupDecreaseEvent';
|
||||
import { OB11GroupUploadNoticeEvent } from '../event/notice/OB11GroupUploadNoticeEvent';
|
||||
import { OB11GroupPokeEvent } from '../event/notice/OB11PokeEvent';
|
||||
import { OB11GroupEssenceEvent } from '../event/notice/OB11GroupEssenceEvent';
|
||||
import { MessageUnique } from '@/common/utils/message-unique';
|
||||
import { MessageUnique } from '@/common/message-unique';
|
||||
import { OB11GroupTitleEvent } from '../event/notice/OB11GroupTitleEvent';
|
||||
import { NapCatCore, RawMessage, ChatType, NTGrayTipElementSubTypeV2, TipGroupElementType, Peer } from '@/core';
|
||||
import { ChatType, NapCatCore, NTGrayTipElementSubTypeV2, Peer, RawMessage, TipGroupElementType } from '@/core';
|
||||
|
||||
export async function NT2PrivateEvent(core: NapCatCore, obContext: NapCatOneBot11Adapter, msg: RawMessage): Promise<OB11BaseNoticeEvent | undefined> {
|
||||
if (msg.chatType !== ChatType.KCHATTYPEC2C) {
|
||||
|
@@ -1,17 +1,17 @@
|
||||
import {
|
||||
NodeIKernelBuddyListener,
|
||||
BuddyReqType,
|
||||
ChatType,
|
||||
DataSource,
|
||||
GroupMemberRole,
|
||||
GroupNotifyMsgStatus,
|
||||
GroupNotifyMsgType,
|
||||
InstanceContext,
|
||||
NodeIKernelMsgListener,
|
||||
NapCatCore,
|
||||
NodeIKernelBuddyListener,
|
||||
NodeIKernelGroupListener,
|
||||
NodeIKernelMsgListener,
|
||||
RawMessage,
|
||||
SendStatusType,
|
||||
GroupMemberRole,
|
||||
GroupNotifyMsgType,
|
||||
GroupNotifyMsgStatus,
|
||||
DataSource,
|
||||
NodeIKernelGroupListener,
|
||||
} from '@/core';
|
||||
import { OB11Config, OB11ConfigLoader } from '@/onebot/helper/config';
|
||||
import {
|
||||
@@ -21,7 +21,7 @@ import {
|
||||
OB11PassiveHttpAdapter,
|
||||
OB11PassiveWebSocketAdapter,
|
||||
} from '@/onebot/network';
|
||||
import { NapCatPathWrapper } from '@/common/framework/napcat';
|
||||
import { NapCatPathWrapper } from '@/common/path';
|
||||
import {
|
||||
OneBotFriendApi,
|
||||
OneBotGroupApi,
|
||||
@@ -33,15 +33,15 @@ import {
|
||||
import { ActionMap, createActionMap } from '@/onebot/action';
|
||||
import { WebUiDataRuntime } from '@/webui/src/helper/Data';
|
||||
import { OB11InputStatusEvent } from '@/onebot/event/notice/OB11InputStatusEvent';
|
||||
import { MessageUnique } from '@/common/utils/message-unique';
|
||||
import { proxiedListenerOf } from '@/common/utils/proxy-handler';
|
||||
import { MessageUnique } from '@/common/message-unique';
|
||||
import { proxiedListenerOf } from '@/common/proxy-handler';
|
||||
import { OB11FriendRequestEvent } from '@/onebot/event/request/OB11FriendRequest';
|
||||
import { OB11GroupAdminNoticeEvent } from '@/onebot/event/notice/OB11GroupAdminNoticeEvent';
|
||||
import { GroupDecreaseSubType, OB11GroupDecreaseEvent } from '@/onebot/event/notice/OB11GroupDecreaseEvent';
|
||||
import { OB11GroupRequestEvent } from '@/onebot/event/request/OB11GroupRequest';
|
||||
import { OB11FriendRecallNoticeEvent } from '@/onebot/event/notice/OB11FriendRecallNoticeEvent';
|
||||
import { OB11GroupRecallNoticeEvent } from '@/onebot/event/notice/OB11GroupRecallNoticeEvent';
|
||||
import { LRUCache } from '@/common/utils/lru-cache';
|
||||
import { LRUCache } from '@/common/lru-cache';
|
||||
import { NT2GroupEvent, NT2PrivateEvent } from './helper';
|
||||
import { NodeIKernelRecentContactListener } from '@/core/listeners/NodeIKernelRecentContactListener';
|
||||
|
||||
|
@@ -1,6 +1,6 @@
|
||||
import { IOB11NetworkAdapter, OB11EmitEventContent } from '@/onebot/network/index';
|
||||
import { createHmac } from 'crypto';
|
||||
import { LogWrapper } from '@/common/utils/log';
|
||||
import { LogWrapper } from '@/common/log';
|
||||
import { QuickAction, QuickActionEvent } from '../types';
|
||||
import { NapCatCore } from '@/core';
|
||||
import { NapCatOneBot11Adapter } from '..';
|
||||
|
@@ -4,7 +4,7 @@ import { OB11HeartbeatEvent } from '../event/meta/OB11HeartbeatEvent';
|
||||
import { NapCatCore } from '@/core';
|
||||
import { ActionName } from '@/onebot/action/types';
|
||||
import { OB11Response } from '@/onebot/action/OB11Response';
|
||||
import { LogWrapper } from '@/common/utils/log';
|
||||
import { LogWrapper } from '@/common/log';
|
||||
import { ActionMap } from '@/onebot/action';
|
||||
import { LifeCycleSubType, OB11LifeCycleEvent } from '../event/meta/OB11LifeCycleEvent';
|
||||
|
||||
@@ -142,7 +142,7 @@ export class OB11ActiveWebSocketAdapter implements IOB11NetworkAdapter {
|
||||
}
|
||||
receiveData.params = (receiveData?.params) ? receiveData.params : {};//兼容类型验证
|
||||
const retdata = await this.actions.get(receiveData.action)
|
||||
?.websocketHandle(receiveData.params, echo || '');
|
||||
?.websocketHandle(receiveData.params, echo ?? '');
|
||||
const packet = Object.assign({}, retdata);
|
||||
this.checkStateAndReply<any>(packet);
|
||||
} catch (e) {
|
||||
|
@@ -1,4 +1,3 @@
|
||||
import BaseAction from '@/onebot/action/BaseAction';
|
||||
import { OB11BaseEvent } from '@/onebot/event/OB11BaseEvent';
|
||||
import { OB11Message } from '@/onebot';
|
||||
import { ActionMap } from '@/onebot/action';
|
||||
|
@@ -5,7 +5,7 @@ import { Mutex } from 'async-mutex';
|
||||
import { OB11Response } from '../action/OB11Response';
|
||||
import { ActionName } from '../action/types';
|
||||
import { NapCatCore } from '@/core';
|
||||
import { LogWrapper } from '@/common/utils/log';
|
||||
import { LogWrapper } from '@/common/log';
|
||||
import { OB11HeartbeatEvent } from '../event/meta/OB11HeartbeatEvent';
|
||||
import { IncomingMessage } from 'http';
|
||||
import { ActionMap } from '@/onebot/action';
|
||||
@@ -155,7 +155,7 @@ export class OB11PassiveWebSocketAdapter implements IOB11NetworkAdapter {
|
||||
return;
|
||||
}
|
||||
receiveData.params = (receiveData?.params) ? receiveData.params : {};//兼容类型验证
|
||||
const retdata = await this.actions.get(receiveData.action)?.websocketHandle(receiveData.params, echo || '');
|
||||
const retdata = await this.actions.get(receiveData.action)?.websocketHandle(receiveData.params, echo ?? '');
|
||||
const packet = Object.assign({}, retdata);
|
||||
this.checkStateAndReply<any>(packet, wsClient);
|
||||
} catch (e) {
|
||||
|
@@ -1,9 +1,9 @@
|
||||
import type { SelfInfo } from '@/core/entities';
|
||||
|
||||
import { LogWrapper } from '@/common/utils/log';
|
||||
import { LogWrapper } from '@/common/log';
|
||||
import { NodeIKernelLoginListener, NodeIKernelSessionListener } from '@/core/listeners';
|
||||
import { NodeIDependsAdapter, NodeIDispatcherAdapter, NodeIGlobalAdapter } from '@/core/adapters';
|
||||
import { napcat_version, NapCatPathWrapper } from '@/common/framework/napcat';
|
||||
import { NapCatPathWrapper } from '@/common/path';
|
||||
import {
|
||||
InstanceContext,
|
||||
loadQQWrapper,
|
||||
@@ -12,10 +12,10 @@ import {
|
||||
NodeIQQNTWrapperSession,
|
||||
WrapperNodeApi,
|
||||
} from '@/core';
|
||||
import { QQBasicInfoWrapper } from '@/common/utils/qq-basic-info';
|
||||
import { hostname, systemVersion } from '@/common/utils/system';
|
||||
import { QQBasicInfoWrapper } from '@/common/qq-basic-info';
|
||||
import { hostname, systemVersion } from '@/common/system';
|
||||
import { genSessionConfig } from '@/core/wrapper/helper';
|
||||
import { proxiedListenerOf } from '@/common/utils/proxy-handler';
|
||||
import { proxiedListenerOf } from '@/common/proxy-handler';
|
||||
|
||||
import path from 'path';
|
||||
import fs from 'fs';
|
||||
@@ -26,6 +26,7 @@ import qrcode from 'qrcode-terminal';
|
||||
import { NapCatOneBot11Adapter } from '@/onebot';
|
||||
import { InitWebUi } from '@/webui';
|
||||
import { WebUiDataRuntime } from '@/webui/src/helper/Data';
|
||||
import { napCatVersion } from '@/common/version';
|
||||
|
||||
program.option('-q, --qq [number]', 'QQ号').parse(process.argv);
|
||||
const cmdOptions = program.opts();
|
||||
@@ -38,7 +39,7 @@ export async function NCoreInitShell() {
|
||||
const logger = new LogWrapper(pathWrapper.logsPath);
|
||||
const basicInfoWrapper = new QQBasicInfoWrapper({ logger });
|
||||
const wrapper = loadQQWrapper(basicInfoWrapper.getFullQQVesion());
|
||||
logger.log(`[NapCat] [Core] NapCat.Core Version: ` + napcat_version);
|
||||
logger.log(`[NapCat] [Core] NapCat.Core Version: ` + napCatVersion);
|
||||
InitWebUi(logger, pathWrapper).then().catch(logger.logError);
|
||||
|
||||
// from constructor
|
||||
@@ -190,7 +191,7 @@ export async function NCoreInitShell() {
|
||||
logger.log(`可用于快速登录的 QQ:\n${historyLoginList
|
||||
.map((u, index) => `${index + 1}. ${u.uin} ${u.nickName}`)
|
||||
.join('\n')
|
||||
}`);
|
||||
}`);
|
||||
}
|
||||
loginService.getQRCodePicture();
|
||||
}
|
||||
|
@@ -1,7 +1,7 @@
|
||||
import express from 'express';
|
||||
import { ALLRouter } from './src/router';
|
||||
import { LogWrapper } from '@/common/utils/log';
|
||||
import { NapCatPathWrapper } from '@/common/framework/napcat';
|
||||
import { LogWrapper } from '@/common/log';
|
||||
import { NapCatPathWrapper } from '@/common/path';
|
||||
import { WebUiConfigWrapper } from './src/helper/config';
|
||||
|
||||
const app = express();
|
||||
|
@@ -30,7 +30,7 @@ async function onSettingWindowCreated(view: Element) {
|
||||
SettingItem(
|
||||
'<span id="napcat-update-title">Napcat</span>',
|
||||
undefined,
|
||||
SettingButton('V2.2.13', 'napcat-update-button', 'secondary'),
|
||||
SettingButton('V2.2.16', 'napcat-update-button', 'secondary'),
|
||||
),
|
||||
]),
|
||||
SettingList([
|
||||
|
@@ -164,7 +164,7 @@ async function onSettingWindowCreated(view) {
|
||||
SettingItem(
|
||||
'<span id="napcat-update-title">Napcat</span>',
|
||||
void 0,
|
||||
SettingButton("V2.2.13", "napcat-update-button", "secondary")
|
||||
SettingButton("V2.2.16", "napcat-update-button", "secondary")
|
||||
)
|
||||
]),
|
||||
SettingList([
|
||||
|
@@ -20,9 +20,11 @@ if (process.env.NAPCAT_BUILDSYS == 'linux') {
|
||||
} else if (process.env.NAPCAT_BUILDSYS == 'win32') {
|
||||
if (process.env.NAPCAT_BUILDARCH == 'x64') {
|
||||
}
|
||||
startScripts = ['./script/BootWay05.ps1', './script/dbghelp.dll'];
|
||||
startScripts = ['./script/BootWay05.ps1', './script/dbghelp.dll',
|
||||
'./script/BootWay05_init.bat', './script/BootWay05_run.bat', './script/BootWay05_run.utf8.bat', './script/KillQQ.bat'];
|
||||
} else {
|
||||
startScripts = ['./script/BootWay05.ps1', './script/dbghelp.dll'];
|
||||
startScripts = ['./script/BootWay05.ps1', './script/dbghelp.dll',
|
||||
'./script/BootWay05_init.bat', './script/BootWay05_run.bat', './script/BootWay05_run.utf8.bat', './script/KillQQ.bat'];
|
||||
}
|
||||
const FrameworkBaseConfigPlugin: PluginOption[] = [
|
||||
// PreprocessorDirectives(),
|
||||
|
Reference in New Issue
Block a user