Compare commits

..

21 Commits

Author SHA1 Message Date
手瓜一十雪
c05cc9dd02 feat: 迁移29927 2024-11-29 12:48:03 +08:00
手瓜一十雪
1a0da00f2d refactor: webui log 移除公网输出 2024-11-29 12:41:52 +08:00
手瓜一十雪
31b0c1d3d7 refactor: react webui 2024-11-29 12:22:25 +08:00
手瓜一十雪
53c1d40bcf refactor: logger bind (#577) 2024-11-28 20:55:28 +08:00
手瓜一十雪
97cacb4383 refactor: framework的操作性 2024-11-28 20:00:24 +08:00
Mlikiowa
e03905abaf release: v4.2.6 2024-11-28 07:28:33 +00:00
手瓜一十雪
06eba28b4c fux: #574 2024-11-28 15:28:09 +08:00
手瓜一十雪
bbfeac46dd Merge branch 'main' of https://github.com/NapNeko/NapCatQQ 2024-11-28 15:27:26 +08:00
手瓜一十雪
2fe4da094a fix 2024-11-28 15:14:01 +08:00
Mlikiowa
b454d8c0f9 release: v4.2.5 2024-11-28 07:07:10 +00:00
手瓜一十雪
1f9b5453cc fix: #573 2024-11-28 15:06:47 +08:00
Mlikiowa
3261791e99 release: v4.2.4 2024-11-28 03:00:35 +00:00
手瓜一十雪
3bb12e3f45 fix: #572 2024-11-28 10:56:57 +08:00
手瓜一十雪
1dc2f7e5a2 style: lint 2024-11-28 10:46:14 +08:00
手瓜一十雪
2531b08538 refactor: 提高解析兼容 2024-11-28 10:41:51 +08:00
手瓜一十雪
9fcfb5493c fix: #571 2024-11-28 10:27:04 +08:00
Mlikiowa
4576354c51 release: v4.2.3 2024-11-28 01:54:43 +00:00
手瓜一十雪
1dcf2ef0c6 fix: error handle 2024-11-28 09:53:50 +08:00
Mlikiowa
3642c65e8c release: v4.2.2 2024-11-27 12:39:03 +00:00
手瓜一十雪
40e105994a fix: pic size 2024-11-27 20:38:39 +08:00
Mlikiowa
f2ee973882 release: v4.2.1 2024-11-27 11:07:43 +00:00
33 changed files with 262 additions and 247 deletions

View File

@@ -34,7 +34,7 @@ NapCatQQ 是现代化的基于 NTQQ 的 Bot 协议端实现
## 回家旅途
[QQ Group](https://qm.qq.com/q/NWP25OeV0c)
[QQ Group](https://qm.qq.com/q/I6LU87a0Yq)
## 感谢他们
感谢 [Lagrange](https://github.com/LagrangeDev/Lagrange.Core) 对本项目的大力支持 参考部分代码 已获授权

Binary file not shown.

View File

@@ -1,9 +1,9 @@
{
"name": "qq-chat",
"version": "9.9.16-29456",
"verHash": "dd395162",
"linuxVersion": "3.2.13-29456",
"linuxVerHash": "e379390a",
"version": "9.9.16-29927",
"verHash": "3e273e30",
"linuxVersion": "3.2.13-29927",
"linuxVerHash": "833d113c",
"type": "module",
"private": true,
"description": "QQ",
@@ -18,7 +18,7 @@
"qd": "externals/devtools/cli/index.js"
},
"main": "./loadNapCat.js",
"buildVersion": "29456",
"buildVersion": "29927",
"isPureShell": true,
"isByteCodeShell": true,
"platform": "win32",

View File

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

View File

@@ -2,7 +2,7 @@
"name": "napcat",
"private": true,
"type": "module",
"version": "4.2.0",
"version": "4.2.6",
"scripts": {
"build:framework": "npm run build:webui && vite build --mode framework || exit 1",
"build:shell": "npm run build:webui && vite build --mode shell || exit 1",

View File

@@ -96,7 +96,7 @@ export async function encodeSilk(filePath: string, TEMP_DIR: string, logger: Log
};
}
} catch (error: any) {
logger.logError.bind(logger)('convert silk failed', error.stack);
logger.logError('convert silk failed', error.stack);
return {};
}
}

View File

@@ -33,27 +33,27 @@ export abstract class ConfigBase<T> {
}
read(copy_default: boolean = true): T {
const logger = this.core.context.logger;
const configPath = this.getConfigPath(this.core.selfInfo.uin);
if (!fs.existsSync(configPath) && copy_default) {
try {
fs.writeFileSync(configPath, fs.readFileSync(this.getConfigPath(undefined), 'utf-8'));
logger.log(`[Core] [Config] 配置文件创建成功!\n`);
this.core.context.logger.log(`[Core] [Config] 配置文件创建成功!\n`);
} catch (e: any) {
logger.logError.bind(logger)(`[Core] [Config] 创建配置文件时发生错误:`, e.message);
this.core.context.logger.logError(`[Core] [Config] 创建配置文件时发生错误:`, e.message);
}
} else if (!fs.existsSync(configPath) && !copy_default) {
fs.writeFileSync(configPath, '{}');
}
try {
this.configData = JSON.parse(fs.readFileSync(configPath, 'utf-8'));
logger.logDebug(`[Core] [Config] 配置文件${configPath}加载`, this.configData);
this.core.context.logger.logDebug(`[Core] [Config] 配置文件${configPath}加载`, this.configData);
return this.configData;
} catch (e: any) {
if (e instanceof SyntaxError) {
logger.logError.bind(logger)(`[Core] [Config] 配置文件格式错误,请检查配置文件:`, e.message);
this.core.context.logger.logError(`[Core] [Config] 配置文件格式错误,请检查配置文件:`, e.message);
} else {
logger.logError.bind(logger)(`[Core] [Config] 读取配置文件时发生错误:`, e.message);
this.core.context.logger.logError(`[Core] [Config] 读取配置文件时发生错误:`, e.message);
}
return {} as T;
}
@@ -61,14 +61,13 @@ export abstract class ConfigBase<T> {
save(newConfigData: T = this.configData) {
const logger = this.core.context.logger;
const selfInfo = this.core.selfInfo;
this.configData = newConfigData;
const configPath = this.getConfigPath(selfInfo.uin);
try {
fs.writeFileSync(configPath, JSON.stringify(newConfigData, this.getKeys(), 2));
} catch (e: any) {
logger.logError.bind(logger)(`保存配置文件 ${configPath} 时发生错误:`, e.message);
this.core.context.logger.logError(`保存配置文件 ${configPath} 时发生错误:`, e.message);
}
}
}

View File

@@ -190,16 +190,27 @@ export async function checkUriType(Uri: string) {
}, Uri);
if (LocalFileRet) return LocalFileRet;
const OtherFileRet = await solveProblem((uri: string) => {
//再判断是否是Http
if (uri.startsWith('http://') || uri.startsWith('https://')) {
// 再判断是否是Http
if (uri.startsWith('http:') || uri.startsWith('https:')) {
return { Uri: uri, Type: FileUriType.Remote };
}
//再判断是否是Base64
if (uri.startsWith('base64://')) {
// 再判断是否是Base64
if (uri.startsWith('base64:')) {
return { Uri: uri, Type: FileUriType.Base64 };
}
if (uri.startsWith('file://')) {
let filePath: string = uri.slice(7);
// 默认file://
if (uri.startsWith('file:')) {
// 兼容file:///
// file:///C:/1.jpg
if (uri.startsWith('file:///') && process.platform === 'win32') {
const filePath: string = uri.slice(8);
return { Uri: filePath, Type: FileUriType.Local };
}
// 处理默认规范
// file://C:\1.jpg
// file:///test/1.jpg
const filePath: string = uri.slice(7);
return { Uri: filePath, Type: FileUriType.Local };
}
if (uri.startsWith('data:')) {
@@ -235,7 +246,7 @@ export async function uri2local(dir: string, uri: string, filename: string | und
fs.copyFileSync(HandledUri, filePath);
return { success: true, errMsg: '', fileName: filename, ext: fileExt, path: filePath };
}
//接下来都要有文件名
if (UriType == FileUriType.Remote) {
const pathInfo = path.parse(decodeURIComponent(new URL(HandledUri).pathname));

View File

@@ -1 +1 @@
export const napCatVersion = '4.2.0';
export const napCatVersion = '4.2.6';

View File

@@ -41,7 +41,7 @@ export class NTQQFileApi {
this.rkeyManager = new RkeyManager([
'https://rkey.napneko.icu/rkeys'
],
this.context.logger
this.context.logger
);
}
@@ -142,7 +142,6 @@ export class NTQQFileApi {
}
async createValidSendVideoElement(context: SendMessageContext, filePath: string, fileName: string = '', diyThumbPath: string = ''): Promise<SendVideoElement> {
const logger = this.core.context.logger;
let videoInfo = {
width: 1920,
height: 1080,
@@ -152,9 +151,9 @@ export class NTQQFileApi {
filePath,
};
try {
videoInfo = await getVideoInfo(filePath, logger);
videoInfo = await getVideoInfo(filePath, this.context.logger);
} catch (e) {
logger.logError.bind(logger)('获取视频信息失败,将使用默认值', e);
this.context.logger.logError('获取视频信息失败,将使用默认值', e);
}
let fileExt = 'mp4';
@@ -162,7 +161,7 @@ export class NTQQFileApi {
const tempExt = (await fileType.fileTypeFromFile(filePath))?.ext;
if (tempExt) fileExt = tempExt;
} catch (e) {
this.context.logger.logError.bind(logger)('获取文件类型失败', e);
this.context.logger.logError('获取文件类型失败', e);
}
const newFilePath = filePath + '.' + fileExt;
fs.copyFileSync(filePath, newFilePath);
@@ -183,7 +182,7 @@ export class NTQQFileApi {
ffmpeg(filePath)
.on('error', (err) => {
try {
logger.logDebug('获取视频封面失败,使用默认封面', err);
this.context.logger.logDebug('获取视频封面失败,使用默认封面', err);
if (diyThumbPath) {
fsPromises.copyFile(diyThumbPath, thumbPath).then(() => {
resolve(thumbPath);
@@ -193,7 +192,7 @@ export class NTQQFileApi {
resolve(thumbPath);
}
} catch (error) {
logger.logError.bind(logger)('获取视频封面失败,使用默认封面失败', error);
this.context.logger.logError('获取视频封面失败,使用默认封面失败', error);
}
})
.screenshots({
@@ -230,6 +229,7 @@ export class NTQQFileApi {
}
async createValidSendPttElement(pttPath: string): Promise<SendPttElement> {
const { converted, path: silkPath, duration } = await encodeSilk(pttPath, this.core.NapCatTempPath, this.core.context.logger);
if (!silkPath) {
throw new Error('语音转换失败, 请检查语音文件是否正常');
@@ -239,8 +239,7 @@ export class NTQQFileApi {
throw new Error('文件异常大小为0');
}
if (converted) {
fsPromises.unlink(silkPath).then().catch(
(e) => this.context.logger.logError.bind(this.context.logger)('删除临时文件失败', e)
fsPromises.unlink(silkPath).then().catch((e) => this.context.logger.logError('删除临时文件失败', e)
);
}
return {
@@ -307,18 +306,18 @@ export class NTQQFileApi {
element.elementType === ElementType.FILE
) {
switch (element.elementType) {
case ElementType.PIC:
case ElementType.PIC:
element.picElement!.sourcePath = elementResults[elementIndex];
break;
case ElementType.VIDEO:
break;
case ElementType.VIDEO:
element.videoElement!.filePath = elementResults[elementIndex];
break;
case ElementType.PTT:
break;
case ElementType.PTT:
element.pttElement!.filePath = elementResults[elementIndex];
break;
case ElementType.FILE:
break;
case ElementType.FILE:
element.fileElement!.filePath = elementResults[elementIndex];
break;
break;
}
elementIndex++;
}
@@ -454,7 +453,7 @@ export class NTQQFileApi {
}
}
} catch (error: any) {
this.context.logger.logError.bind(this.context.logger)('获取rkey失败', error.message);
this.context.logger.logError('获取rkey失败', error.message);
}
if (!rkeyData.online_rkey) {
@@ -464,7 +463,7 @@ export class NTQQFileApi {
rkeyData.private_rkey = tempRkeyData.private_rkey;
rkeyData.online_rkey = tempRkeyData.expired_time > Date.now() / 1000;
} catch (e) {
this.context.logger.logError.bind(this.context.logger)('获取rkey失败 Fallback Old Mode', e);
this.context.logger.logError('获取rkey失败 Fallback Old Mode', e);
}
}

View File

@@ -27,7 +27,7 @@ export class NTQQGroupApi {
this.core = core;
}
async initApi() {
this.initCache().then().catch(this.context.logger.logError.bind(this.context.logger));
this.initCache().then().catch(e => this.context.logger.logError(e));
}
async initCache() {
this.groups = await this.getGroups();

View File

@@ -31,7 +31,7 @@ export class NTQQPacketApi {
await this.InitSendPacket(this.context.basicInfoWrapper.getFullQQVesion())
.then()
.catch((err) => {
this.logger.logError.bind(this.core.context.logger);
this.logger.logError(err);
this.errStack.push(err);
});
}

View File

@@ -3,12 +3,12 @@ import { PicType } from '../types';
export async function getFileTypeForSendType(picPath: string): Promise<PicType> {
const fileTypeResult = (await fileType.fileTypeFromFile(picPath))?.ext ?? 'jpg';
const picTypeMap: { [key: string]: PicType } = {
'webp': PicType.NEWPIC_WEBP,
//'webp': PicType.NEWPIC_WEBP,
'gif': PicType.NEWPIC_GIF,
'png': PicType.NEWPIC_APNG,
'jpg': PicType.NEWPIC_JPEG,
'jpeg': PicType.NEWPIC_JPEG,
'bmp': PicType.NEWPIC_BMP,
// 'png': PicType.NEWPIC_APNG,
// 'jpg': PicType.NEWPIC_JPEG,
// 'jpeg': PicType.NEWPIC_JPEG,
// 'bmp': PicType.NEWPIC_BMP,
};
return picTypeMap[fileTypeResult] ?? PicType.NEWPIC_JPEG;
}

View File

@@ -27,7 +27,6 @@ export class RkeyManager {
await this.refreshRkey();
} catch (e) {
throw new Error(`获取rkey失败: ${e}`);//外抛
//this.logger.logError.bind(this.logger)('获取rkey失败', e);
}
}
return this.rkeyData;
@@ -50,7 +49,7 @@ export class RkeyManager {
expired_time: temp.expired_time
};
} catch (e) {
this.logger.logError.bind(this.logger)(`[Rkey] Get Rkey ${url} Error `, e);
this.logger.logError(`[Rkey] Get Rkey ${url} Error `, e);
//是否为最后一个url
if (url === this.serverUrl[this.serverUrl.length - 1]) {
throw new Error(`获取rkey失败: ${e}`);//外抛

View File

@@ -127,7 +127,7 @@ export class NapCatCore {
await api.initApi();
}
}
this.initNapCatCoreListeners().then().catch(this.context.logger.logError.bind(this.context.logger));
this.initNapCatCoreListeners().then().catch((e) => this.context.logger.logError(e));
this.context.logger.setFileLogEnabled(
this.configLoader.configData.fileLog,
@@ -154,7 +154,7 @@ export class NapCatCore {
const msgListener = new NodeIKernelMsgListener();
msgListener.onKickedOffLine = (Info: KickedOffLineInfo) => {
// 下线通知
this.context.logger.logError.bind(this.context.logger)('[KickedOffLine] [' + Info.tipsTitle + '] ' + Info.tipsDesc);
this.context.logger.logError('[KickedOffLine] [' + Info.tipsTitle + '] ' + Info.tipsDesc);
this.selfInfo.online = false;
};
msgListener.onRecvMsg = (msgs) => {

View File

@@ -62,7 +62,7 @@ export const GroupChange = {
operatorUid: ProtoField(5, ScalarType.STRING, true),
increaseType: ProtoField(6, ScalarType.UINT32),
field7: ProtoField(7, ScalarType.BYTES, true),
}
};
export const PushMsgBody = {
responseHead: ProtoField(1, () => ResponseHead),

View File

@@ -1,6 +1,16 @@
//LiteLoader需要提供部分IPC接口以便于其他插件调用
const { ipcMain } = require('electron');
const napcat = require('./napcat.cjs');
const { shell } = require('electron');
ipcMain.handle('napcat_get_webtoken', async (event, arg) => {
return napcat.NCgetWebUiUrl();
});
ipcMain.on('open_external_url', (event, url) => {
shell.openExternal(url);
});
ipcMain.handle('napcat_get_reactweb', async (event, arg) => {
let url = new URL(await napcat.NCgetWebUiUrl());
let port = url.port;
let token = url.searchParams.get('token');
return `https://napcat.152710.xyz/web_login?back=http://127.0.0.1:${port}&token=${token}`;
});

View File

@@ -58,7 +58,7 @@ export async function NCoreInitFramework(
await loaderObject.core.initCore();
//启动WebUi
InitWebUi(logger, pathWrapper).then().catch(logger.logError.bind(logger));
InitWebUi(logger, pathWrapper).then().catch(e => logger.logError(e));
//初始化LLNC的Onebot实现
await new NapCatOneBot11Adapter(loaderObject.core, loaderObject.context, pathWrapper).InitOneBot();
}

View File

@@ -1,10 +1,14 @@
const { contextBridge } = require('electron');
const { ipcRenderer } = require('electron');
const { contextBridge, ipcRenderer } = require('electron');
const napcat = {
getWebUiUrl: async () => {
return ipcRenderer.invoke('napcat_get_webtoken');
},
openExternalUrl: async (url) => {
ipcRenderer.send('open_external_url', url);
},
getWebUiUrlReact: async () => {
return ipcRenderer.invoke('napcat_get_reactweb');
}
};
// 在window对象下导出只读对象
contextBridge.exposeInMainWorld('napcat', napcat);
contextBridge.exposeInMainWorld('napcat', napcat);

View File

@@ -1,27 +1,20 @@
export const onSettingWindowCreated = async (view) => {
// view.style.width = "100%";
// view.style.height = "100%";
// //添加iframe
// const iframe = document.createElement("iframe");
// iframe.src = await window.napcat.getWebUiUrl();
// iframe.width = "100%";
// iframe.height = "100%";
// iframe.style.border = "none";
// //去掉iframe滚动条
// //iframe.scrolling = "no";
// //有滚动条何尝不是一种美
// view.appendChild(iframe);
let webui = await window.napcat.getWebUiUrl();
let webuiReact = await window.napcat.getWebUiUrlReact();
view.innerHTML = `
<setting-section data-title="">
<setting-panel>
<setting-list data-direction="column">
<setting-item>
<setting-button data-type="primary" class="nc_openwebui">打开配置页面</setting-button>
<setting-button data-type="primary" class="nc_openwebui">在QQ内打开配置页面(VUE)</setting-button>
<setting-button data-type="primary" class="nc_openwebui_ex">在默认浏览器打开配置页面(VUE)</setting-button>
</setting-item>
<setting-item>
<setting-button data-type="primary" class="nc_openwebui_ex_react">在默认浏览器打开配置页面(React)</setting-button>
</setting-item>
<setting-item>
<div>
<setting-text>WebUi远程地址可以点击下方复制哦~</setting-text>
<setting-text class="nc_webui">WebUi</setting-text>
</div>
</setting-item>
@@ -29,8 +22,27 @@ export const onSettingWindowCreated = async (view) => {
</setting-panel>
</setting-section>
`;
view.querySelector('.nc_openwebui').addEventListener('click', () => {
window.open(webui, '_blank');
});
view.querySelector('.nc_openwebui_ex').addEventListener('click', () => {
window.napcat.openExternalUrl(webui);
});
view.querySelector('.nc_openwebui_ex_react').addEventListener('click', () => {
window.napcat.openExternalUrl(webuiReact);
});
view.querySelector('.nc_webui').innerText = webui;
};
// 添加点击复制功能
view.querySelector('.nc_webui').addEventListener('click', async () => {
try {
await navigator.clipboard.writeText(webui);
alert('WebUi URL 已复制到剪贴板');
} catch (err) {
console.error('复制到剪贴板失败: ', err);
}
});
};

View File

@@ -13,7 +13,7 @@ export class GoCQHTTPHandleQuickAction extends OneBotAction<Payload, null> {
async _handle(payload: Payload): Promise<null> {
this.obContext.apis.QuickActionApi
.handleQuickOperation(payload.context, payload.operation)
.catch(this.core.context.logger.logError.bind(this.core.context.logger));
.catch(e => this.core.context.logger.logError(e));
return null;
}
}

View File

@@ -162,11 +162,10 @@ export class SendMsg extends OneBotAction<OB11PostSendMsg, ReturnDataType> {
finallySendElements: SendArkElement,
res_id?: string
} | null> {
const logger = this.core.context.logger;
const packetMsg: PacketMsg[] = [];
for (const node of messageNodes) {
if (dp >= 3) {
logger.logWarn('转发消息深度超过3层将停止解析');
this.core.context.logger.logWarn('转发消息深度超过3层将停止解析');
break;
}
if (!node.data.id) {
@@ -191,29 +190,29 @@ export class SendMsg extends OneBotAction<OB11PostSendMsg, ReturnDataType> {
time: Number(node.data.time) || Date.now(),
msg: sendElements,
};
logger.logDebug(`handleForwardedNodesPacket[SendRaw] 开始转换 ${stringifyWithBigInt(packetMsgElements)}`);
this.core.context.logger.logDebug(`handleForwardedNodesPacket[SendRaw] 开始转换 ${stringifyWithBigInt(packetMsgElements)}`);
const transformedMsg = this.core.apis.PacketApi.pkt.msgConverter.rawMsgWithSendMsgToPacketMsg(packetMsgElements);
logger.logDebug(`handleForwardedNodesPacket[SendRaw] 转换为 ${stringifyWithBigInt(transformedMsg)}`);
this.core.context.logger.logDebug(`handleForwardedNodesPacket[SendRaw] 转换为 ${stringifyWithBigInt(transformedMsg)}`);
packetMsg.push(transformedMsg);
} else if (node.data.id) {
const id = node.data.id;
const nodeMsg = MessageUnique.getMsgIdAndPeerByShortId(+id) || MessageUnique.getPeerByMsgId(id);
if (!nodeMsg) {
logger.logError.bind(this.core.context.logger)('转发消息失败,未找到消息', id);
this.core.context.logger.logError('转发消息失败,未找到消息', id);
continue;
}
const msg = (await this.core.apis.MsgApi.getMsgsByMsgId(nodeMsg.Peer, [nodeMsg.MsgId])).msgList[0];
logger.logDebug(`handleForwardedNodesPacket[PureRaw] 开始转换 ${stringifyWithBigInt(msg)}`);
this.core.context.logger.logDebug(`handleForwardedNodesPacket[PureRaw] 开始转换 ${stringifyWithBigInt(msg)}`);
await this.core.apis.FileApi.downloadRawMsgMedia([msg]);
const transformedMsg = this.core.apis.PacketApi.pkt.msgConverter.rawMsgToPacketMsg(msg, msgPeer);
logger.logDebug(`handleForwardedNodesPacket[PureRaw] 转换为 ${stringifyWithBigInt(transformedMsg)}`);
this.core.context.logger.logDebug(`handleForwardedNodesPacket[PureRaw] 转换为 ${stringifyWithBigInt(transformedMsg)}`);
packetMsg.push(transformedMsg);
} else {
logger.logDebug(`handleForwardedNodesPacket 跳过元素 ${stringifyWithBigInt(node)}`);
this.core.context.logger.logDebug(`handleForwardedNodesPacket 跳过元素 ${stringifyWithBigInt(node)}`);
}
}
if (packetMsg.length === 0) {
logger.logWarn('handleForwardedNodesPacket 元素为空!');
this.core.context.logger.logWarn('handleForwardedNodesPacket 元素为空!');
return null;
}
const resid = await this.core.apis.PacketApi.pkt.operation.UploadForwardMsg(packetMsg, msgPeer.chatType === ChatType.KCHATTYPEGROUP ? +msgPeer.peerUid : 0);
@@ -253,14 +252,13 @@ export class SendMsg extends OneBotAction<OB11PostSendMsg, ReturnDataType> {
peerUid: this.core.selfInfo.uid,
};
let nodeMsgIds: string[] = [];
const logger = this.core.context.logger;
for (const messageNode of messageNodes) {
const nodeId = messageNode.data.id;
if (nodeId) {
// 对Msgid和OB11ID混用情况兜底
const nodeMsg = MessageUnique.getMsgIdAndPeerByShortId(parseInt(nodeId)) || MessageUnique.getPeerByMsgId(nodeId);
if (!nodeMsg) {
logger.logError.bind(this.core.context.logger)('转发消息失败,未找到消息', nodeId);
this.core.context.logger.logError('转发消息失败,未找到消息', nodeId);
continue;
}
nodeMsgIds.push(nodeMsg.MsgId);
@@ -272,7 +270,7 @@ export class SendMsg extends OneBotAction<OB11PostSendMsg, ReturnDataType> {
const isNodeMsg = OB11Data.filter(e => e.type === OB11MessageDataType.node).length;//找到子转发消息
if (isNodeMsg !== 0) {
if (isNodeMsg !== OB11Data.length) {
logger.logError.bind(this.core.context.logger)('子消息中包含非node消息 跳过不合法部分');
this.core.context.logger.logError('子消息中包含非node消息 跳过不合法部分');
continue;
}
const nodeMsg = await this.handleForwardedNodes(selfPeer, OB11Data.filter(e => e.type === OB11MessageDataType.node));
@@ -309,7 +307,7 @@ export class SendMsg extends OneBotAction<OB11PostSendMsg, ReturnDataType> {
}
});
} catch (e: any) {
logger.logDebug('生成转发消息节点失败', e?.stack);
this.core.context.logger.logDebug('生成转发消息节点失败', e?.stack);
}
}
}
@@ -320,7 +318,7 @@ export class SendMsg extends OneBotAction<OB11PostSendMsg, ReturnDataType> {
for (const msgId of nodeMsgIds) {
const nodeMsgPeer = MessageUnique.getPeerByMsgId(msgId);
if (!nodeMsgPeer) {
logger.logError.bind(this.core.context.logger)('转发消息失败,未找到消息', msgId);
this.core.context.logger.logError('转发消息失败,未找到消息', msgId);
continue;
}
const nodeMsg = (await this.core.apis.MsgApi.getMsgsByMsgId(nodeMsgPeer.Peer, [msgId])).msgList[0];
@@ -346,12 +344,12 @@ export class SendMsg extends OneBotAction<OB11PostSendMsg, ReturnDataType> {
}
if (retMsgIds.length === 0) throw Error('转发消息失败,生成节点为空');
try {
logger.logDebug('开发转发', srcPeer, destPeer, retMsgIds);
this.core.context.logger.logDebug('开发转发', srcPeer, destPeer, retMsgIds);
return {
message: await this.core.apis.MsgApi.multiForwardMsg(srcPeer!, destPeer, retMsgIds)
};
} catch (e: any) {
logger.logError.bind(this.core.context.logger)('forward failed', e?.stack);
this.core.context.logger.logError('forward failed', e?.stack);
return {
message: null
};
@@ -363,7 +361,6 @@ export class SendMsg extends OneBotAction<OB11PostSendMsg, ReturnDataType> {
chatType: ChatType.KCHATTYPEC2C,
peerUid: this.core.selfInfo.uid,
};
const logger = this.core.context.logger;
//msg 为待克隆消息
const sendElements: SendMessageElement[] = [];
@@ -372,12 +369,12 @@ export class SendMsg extends OneBotAction<OB11PostSendMsg, ReturnDataType> {
}
if (sendElements.length === 0) {
logger.logDebug('需要clone的消息无法解析将会忽略掉', msg);
this.core.context.logger.logDebug('需要clone的消息无法解析将会忽略掉', msg);
}
try {
return await this.core.apis.MsgApi.sendMsg(selfPeer, sendElements, true);
} catch (e: any) {
logger.logError.bind(this.core.context.logger)(e?.stack, '克隆转发消息失败,将忽略本条消息', msg);
this.core.context.logger.logError(e?.stack, '克隆转发消息失败,将忽略本条消息', msg);
}
}
}

View File

@@ -66,31 +66,31 @@ export class OneBotGroupApi {
return undefined;
}
async parseGroupIncreaseEvent(GroupCode: string, grayTipElement: GrayTipElement) {
this.core.context.logger.logDebug('收到新人被邀请进群消息', grayTipElement);
const xmlElement = grayTipElement.xmlElement;
if (xmlElement?.content) {
const regex = /jp="(\d+)"/g;
// async parseGroupIncreaseEvent(GroupCode: string, grayTipElement: GrayTipElement) {
// this.core.context.logger.logDebug('收到新人被邀请进群消息', grayTipElement);
// const xmlElement = grayTipElement.xmlElement;
// if (xmlElement?.content) {
// const regex = /jp="(\d+)"/g;
const matches = [];
let match = null;
// const matches = [];
// let match = null;
while ((match = regex.exec(xmlElement.content)) !== null) {
matches.push(match[1]);
}
if (matches.length === 2) {
const [inviter, invitee] = matches;
return new OB11GroupIncreaseEvent(
this.core,
parseInt(GroupCode),
parseInt(invitee),
parseInt(inviter),
'invite',
);
}
}
return undefined;
}
// while ((match = regex.exec(xmlElement.content)) !== null) {
// matches.push(match[1]);
// }
// if (matches.length === 2) {
// const [inviter, invitee] = matches;
// return new OB11GroupIncreaseEvent(
// this.core,
// parseInt(GroupCode),
// parseInt(invitee),
// parseInt(inviter),
// 'invite',
// );
// }
// }
// return undefined;
// }
// async parseGroupMemberIncreaseEvent(GroupCode: string, grayTipElement: GrayTipElement) {
// const groupElement = grayTipElement?.groupElement;
@@ -159,7 +159,7 @@ export class OneBotGroupApi {
}
const replyMsg = replyMsgList[0];
if (!replyMsg) {
this.core.context.logger.logError.bind(this.core.context.logger)('解析表情回应消息失败: 未找到回应消息');
this.core.context.logger.logError('解析表情回应消息失败: 未找到回应消息');
return undefined;
}
return new OB11GroupMsgEmojiLikeEvent(
@@ -304,9 +304,8 @@ export class OneBotGroupApi {
// 筛选出表情回应 事件
if (grayTipElement.xmlElement?.templId === '10382') {
return await this.obContext.apis.GroupApi.parseGroupEmojiLikeEventByGrayTip(msg.peerUid, grayTipElement);
} else {
return await this.obContext.apis.GroupApi.parseGroupIncreaseEvent(msg.peerUid, grayTipElement);
//return await this.obContext.apis.GroupApi.parseGroupIncreaseEvent(msg.peerUid, grayTipElement);
}
} else if (grayTipElement.subElementType == NTGrayTipElementSubTypeV2.GRAYTIP_ELEMENT_SUBTYPE_JSON) {
// 解析json事件
@@ -315,7 +314,7 @@ export class OneBotGroupApi {
} else if (grayTipElement.jsonGrayTipElement.busiId == JsonGrayBusiId.AIO_GROUP_ESSENCE_MSG_TIP) {
return await this.parseEssenceMsg(msg, grayTipElement.jsonGrayTipElement.jsonStr);
} else {
return await this.parseOtherJsonEvent(msg, grayTipElement.jsonGrayTipElement.jsonStr, this.core.context)
return await this.parseOtherJsonEvent(msg, grayTipElement.jsonGrayTipElement.jsonStr, this.core.context);
}
}
return undefined;

View File

@@ -130,7 +130,7 @@ export class OneBotMsgApi {
},
};
} catch (e: any) {
this.core.context.logger.logError.bind(this.core.context.logger)('获取图片url失败', e.stack);
this.core.context.logger.logError('获取图片url失败', e.stack);
return null;
}
},
@@ -213,7 +213,7 @@ export class OneBotMsgApi {
guildId: '',
};
if (!records || !element.replyMsgTime || !element.senderUidStr) {
this.core.context.logger.logError.bind(this.core.context.logger)('似乎是旧版客户端,获取不到引用的消息', element.replayMsgSeq);
this.core.context.logger.logError('似乎是旧版客户端,获取不到引用的消息', element.replayMsgSeq);
return null;
}
@@ -231,7 +231,7 @@ export class OneBotMsgApi {
let replyMsg = replyMsgList.find(msg => msg.msgRandom === records.msgRandom);
if (!replyMsg || records.msgRandom !== replyMsg.msgRandom) {
this.core.context.logger.logError.bind(this.core.context.logger)(
this.core.context.logger.logError(
'筛选结果,筛选消息失败,将使用Fallback-1 Seq: ',
element.replayMsgSeq,
',消息长度:',
@@ -242,7 +242,7 @@ export class OneBotMsgApi {
}
if (!replyMsg || records.msgRandom !== replyMsg.msgRandom) {
this.core.context.logger.logWarn.bind(this.core.context.logger)(
this.core.context.logger.logWarn(
'筛选消息失败,将使用Fallback-2 Seq:',
element.replayMsgSeq,
',消息长度:',
@@ -256,7 +256,7 @@ export class OneBotMsgApi {
// 丢弃该消息段
if (!replyMsg || records.msgRandom !== replyMsg.msgRandom) {
this.core.context.logger.logError.bind(this.core.context.logger)(
this.core.context.logger.logError(
'最终筛选结果,筛选消息失败,获取不到引用的消息 Seq: ',
element.replayMsgSeq,
',消息长度:',
@@ -458,7 +458,7 @@ export class OneBotMsgApi {
const sysFaces = faceConfig.sysface;
const face: any = sysFaces.find((systemFace) => systemFace.QSid === parsedFaceId.toString());
if (!face) {
this.core.context.logger.logError.bind(this.core.context.logger)('不支持的ID', id);
this.core.context.logger.logError('不支持的ID', id);
return undefined;
}
parsedFaceId = parseInt(parsedFaceId.toString());
@@ -581,20 +581,20 @@ export class OneBotMsgApi {
// 保留, 直到...找到更好的解决方案
if (data.id !== undefined) {
if (!['qq', '163', 'kugou', 'kuwo', 'migu'].includes(data.type)) {
this.core.context.logger.logError.bind(this.core.context.logger)('音乐卡片type错误, 只支持qq、163、kugou、kuwo、migu当前type:', data.type);
this.core.context.logger.logError('音乐卡片type错误, 只支持qq、163、kugou、kuwo、migu当前type:', data.type);
return undefined;
}
} else {
if (!['qq', '163', 'kugou', 'kuwo', 'migu', 'custom'].includes(data.type)) {
this.core.context.logger.logError.bind(this.core.context.logger)('音乐卡片type错误, 只支持qq、163、kugou、kuwo、migu、custom当前type:', data.type);
this.core.context.logger.logError('音乐卡片type错误, 只支持qq、163、kugou、kuwo、migu、custom当前type:', data.type);
return undefined;
}
if (!data.url) {
this.core.context.logger.logError.bind(this.core.context.logger)('自定义音卡缺少参数url');
this.core.context.logger.logError('自定义音卡缺少参数url');
return undefined;
}
if (!data.image) {
this.core.context.logger.logError.bind(this.core.context.logger)('自定义音卡缺少参数image');
this.core.context.logger.logError('自定义音卡缺少参数image');
return undefined;
}
}
@@ -618,7 +618,7 @@ export class OneBotMsgApi {
type: OB11MessageDataType.json
}, context);
} catch (e) {
this.core.context.logger.logError.bind(this.core.context.logger)('生成音乐消息失败', e);
this.core.context.logger.logError('生成音乐消息失败', e);
}
},
@@ -673,7 +673,7 @@ export class OneBotMsgApi {
if (grayTipElement.subElementType == NTGrayTipElementSubTypeV2.GRAYTIP_ELEMENT_SUBTYPE_JSON) {
if (grayTipElement.jsonGrayTipElement.busiId == 1061) {
const PokeEvent = await this.obContext.apis.FriendApi.parsePrivatePokeEvent(grayTipElement);
if (PokeEvent) { return PokeEvent };
if (PokeEvent) { return PokeEvent; };
} else if (grayTipElement.jsonGrayTipElement.busiId == 19324 && msg.peerUid !== '') {
return new OB11FriendAddNoticeEvent(this.core, Number(await this.core.apis.UserApi.getUinByUidV2(msg.peerUid)));
}
@@ -841,14 +841,14 @@ export class OneBotMsgApi {
}
private async convertArrayToStringMessage(originMsg: OB11Message): Promise<OB11Message> {
let msg = structuredClone(originMsg);
const msg = structuredClone(originMsg);
msg.message_format = 'string';
msg.message = msg.raw_message;
return msg;
}
async importArrayTostringMsg(originMsg: OB11Message) {
let msg = structuredClone(originMsg);
const msg = structuredClone(originMsg);
msg.message_format = 'string';
msg.message = msg.raw_message;
return msg;
@@ -907,7 +907,7 @@ export class OneBotMsgApi {
timeout += PredictTime;// 10S Basic Timeout + PredictTime( For File 512kb/s )
}
} catch (e) {
this.core.context.logger.logError.bind(this.core.context.logger)('发送消息计算预计时间异常', e);
this.core.context.logger.logError('发送消息计算预计时间异常', e);
}
const returnMsg = await this.core.apis.MsgApi.sendMsg(peer, sendElements, waitComplete, timeout);
if (!returnMsg) throw new Error('发送消息失败');
@@ -921,10 +921,10 @@ export class OneBotMsgApi {
deleteAfterSentFiles.forEach(file => {
try {
if (fs.existsSync(file)) {
fsPromise.unlink(file).then().catch(e => this.core.context.logger.logError.bind(this.core.context.logger)('发送消息删除文件失败', e));
fsPromise.unlink(file).then().catch(e => this.core.context.logger.logError('发送消息删除文件失败', e));
}
} catch (error) {
this.core.context.logger.logError.bind(this.core.context.logger)('发送消息删除文件失败', (error as Error).message)
this.core.context.logger.logError('发送消息删除文件失败', (error as Error).message);
}
});
}, 60000);
@@ -938,7 +938,7 @@ export class OneBotMsgApi {
) {
const realUri = inputdata.url || inputdata.file || inputdata.path || '';
if (realUri.length === 0) {
this.core.context.logger.logError.bind(this.core.context.logger)('文件消息缺少参数', inputdata);
this.core.context.logger.logError('文件消息缺少参数', inputdata);
throw Error('文件消息缺少参数');
}
const {
@@ -949,7 +949,7 @@ export class OneBotMsgApi {
} = (await uri2local(this.core.NapCatTempPath, realUri));
if (!success) {
this.core.context.logger.logError.bind(this.core.context.logger)('文件下载失败', errMsg);
this.core.context.logger.logError('文件下载失败', errMsg);
throw Error('文件下载失败' + errMsg);
}
@@ -959,29 +959,20 @@ export class OneBotMsgApi {
}
groupChangDecreseType2String(type: number): GroupDecreaseSubType {
switch (type) {
case 130:
return 'kick';
case 131:
return 'leave';
case 3:
return 'kick_me';
default:
return 'kick';
case 130:
return 'leave';
case 131:
return 'kick';
case 3:
return 'kick_me';
default:
return 'kick';
}
}
async parseSysMessage(msg: number[]) {
// Todo Refactor
// const sysMsg = decodeSysMessage(Uint8Array.from(msg));
// if (sysMsg.msgSpec.length === 0) {
// return;
// }
// const { msgType, subType, subSubType } = sysMsg.msgSpec[0];
// if (msgType === 528 && subType === 39 && subSubType === 39) {
// if (!sysMsg.bodyWrapper) return;
// return await this.obContext.apis.UserApi.parseLikeEvent(sysMsg.bodyWrapper.wrappedBody);
// }
let SysMessage = new NapProtoMsg(PushMsgBody).decode(Uint8Array.from(msg));
const SysMessage = new NapProtoMsg(PushMsgBody).decode(Uint8Array.from(msg));
if (SysMessage.contentHead.type == 33 && SysMessage.body?.msgContent) {
const groupChange = new NapProtoMsg(GroupChange).decode(SysMessage.body.msgContent);
console.log(JSON.stringify(groupChange));
@@ -994,15 +985,17 @@ export class OneBotMsgApi {
);
} else if (SysMessage.contentHead.type == 34 && SysMessage.body?.msgContent) {
const groupChange = new NapProtoMsg(GroupChange).decode(SysMessage.body.msgContent);
// console.log(JSON.stringify(groupChange),JSON.stringify(SysMessage));
return new OB11GroupDecreaseEvent(
this.core,
groupChange.groupUin,
+this.core.selfInfo.uin,
groupChange.memberUid ? +await this.core.apis.UserApi.getUinByUidV2(groupChange.memberUid) : 0,
groupChange.operatorUid ? +await this.core.apis.UserApi.getUinByUidV2(groupChange.operatorUid) : 0,
this.groupChangDecreseType2String(groupChange.decreaseType),
);
} else if (SysMessage.contentHead.type == 528 && SysMessage.contentHead.subType == 39 && SysMessage.body?.msgContent) {
return await this.obContext.apis.UserApi.parseLikeEvent(SysMessage.body?.msgContent);
}
/*
if (msgType === 732 && subType === 16 && subSubType === 16) {
const greyTip = GreyTipWrapper.fromBinary(Uint8Array.from(sysMsg.bodyWrapper!.wrappedBody.slice(7)));

View File

@@ -24,20 +24,19 @@ 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(logger.logError.bind(logger));
.catch(e => this.core.context.logger.logError(e));
}
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(logger.logError.bind(logger));
.catch(e => this.core.context.logger.logError(e));
} else if (groupRequest.request_type === 'group') {
await this.handleGroupRequest(groupRequest, quickAction)
.catch(logger.logError.bind(logger));
.catch(e => this.core.context.logger.logError(e));
}
}
}
@@ -51,7 +50,7 @@ export class OneBotQuickActionApi {
group_id: msg.group_id?.toString(),
user_id: msg.user_id?.toString(),
}, peerContextMode);
if (reply) {
// let group: Group | undefined;
let replyMessage: OB11MessageData[] = [];
@@ -78,7 +77,7 @@ export class OneBotQuickActionApi {
sendElements,
deleteAfterSentFiles,
} = await this.obContext.apis.MsgApi.createSendElements(replyMessage, peer);
this.obContext.apis.MsgApi.sendMsgWithOb11UniqueId(peer, sendElements, deleteAfterSentFiles, false).then().catch(this.core.context.logger.logError.bind(this.core.context.logger));
this.obContext.apis.MsgApi.sendMsgWithOb11UniqueId(peer, sendElements, deleteAfterSentFiles, false).then().catch(e => this.core.context.logger.logError(e));
}
}
@@ -88,13 +87,13 @@ export class OneBotQuickActionApi {
request.flag,
quickAction.approve ? NTGroupRequestOperateTypes.KAGREE : NTGroupRequestOperateTypes.KREFUSE,
quickAction.reason,
).catch(this.core.context.logger.logError.bind(this.core.context.logger));
).catch(e => this.core.context.logger.logError(e));
}
}
async handleFriendRequest(request: OB11FriendRequestEvent, quickAction: QuickActionFriendRequest) {
if (!isNull(quickAction.approve)) {
this.core.apis.FriendApi.handleFriendRequest(request.flag, !!quickAction.approve).then().catch(this.core.context.logger.logError.bind(this.core.context.logger));
this.core.apis.FriendApi.handleFriendRequest(request.flag, !!quickAction.approve).then().catch(e => this.core.context.logger.logError(e));
}
}
}

View File

@@ -13,7 +13,7 @@ export class OneBotUserApi {
}
async parseLikeEvent(wrappedBody: Uint8Array): Promise<OB11ProfileLikeEvent | undefined> {
const likeTip = decodeProfileLikeTip(Uint8Array.from(wrappedBody));
const likeTip = decodeProfileLikeTip(wrappedBody);
if (likeTip?.msgType !== 0 || likeTip?.subType !== 203) return;
this.core.context.logger.logDebug("收到点赞通知消息");
const likeMsg = likeTip.content.msg;

View File

@@ -105,7 +105,7 @@ export class NapCatOneBot11Adapter {
selfInfo.nick = user.nick;
this.context.logger.setLogSelfInfo(selfInfo);
})
.catch(this.context.logger.logError.bind(this.context.logger));
.catch(e => this.context.logger.logError(e));
const serviceInfo = await this.creatOneBotLog(ob11Config);
this.context.logger.log(`[Notice] [OneBot11] ${serviceInfo}`);
@@ -213,7 +213,7 @@ export class NapCatOneBot11Adapter {
if (networkChange === OB11NetworkReloadType.NetWorkClose) {
await this.networkManager.closeSomeAdaterWhenOpen([existingAdapter]);
}
} else if(adapterConfig.enable) {
} else if (adapterConfig.enable) {
const newAdapter = new adapterClass(adapterConfig.name, adapterConfig, this.core, this.actions);
await this.networkManager.registerAdapterAndOpen(newAdapter);
}
@@ -228,7 +228,7 @@ export class NapCatOneBot11Adapter {
if (event) this.networkManager.emitEvent(event);
})
.catch((e) =>
this.context.logger.logError.bind(this.context.logger)(
this.context.logger.logError(
'constructSysMessage error: ',
e,
'\n Parse Hex:',
@@ -260,29 +260,36 @@ export class NapCatOneBot11Adapter {
m.msgId
);
await this.emitMsg(m).catch((e) =>
this.context.logger.logError.bind(this.context.logger)('处理消息失败', e)
this.context.logger.logError('处理消息失败', e)
);
}
};
msgListener.onAddSendMsg = async (msg) => {
if (msg.sendStatus == SendStatusType.KSEND_STATUS_SENDING) {
await this.core.eventWrapper.registerListen('NodeIKernelMsgListener/onMsgInfoListUpdate', (msgList: RawMessage[]) => {
const report = msgList.find((e) =>
e.senderUin == this.core.selfInfo.uin && e.sendStatus == SendStatusType.KSEND_STATUS_SUCCESS && e.msgId === msg.msgId
);
return !!report;
}, 1, 300);
msg.id = MessageUnique.createUniqueMsgId(
{
chatType: msg.chatType,
peerUid: msg.peerUid,
guildId: '',
},
msg.msgId
);
//此时上报的seq不是对的 不过对onebot业务无影响
this.emitMsg(msg);
try {
if (msg.sendStatus == SendStatusType.KSEND_STATUS_SENDING) {
const [updatemsgs] = await this.core.eventWrapper.registerListen('NodeIKernelMsgListener/onMsgInfoListUpdate', (msgList: RawMessage[]) => {
const report = msgList.find((e) =>
e.senderUin == this.core.selfInfo.uin && e.sendStatus !== SendStatusType.KSEND_STATUS_SENDING && e.msgId === msg.msgId
);
return !!report;
}, 1, 10 * 60 * 1000);
// 10分钟 超时
const updatemsg = updatemsgs.find((e) => e.msgId === msg.msgId);
if (updatemsg?.sendStatus == SendStatusType.KSEND_STATUS_SUCCESS || updatemsg?.sendStatus == SendStatusType.KSEND_STATUS_SUCCESS_NOSEQ) {
updatemsg.id = MessageUnique.createUniqueMsgId(
{
chatType: updatemsg.chatType,
peerUid: updatemsg.peerUid,
guildId: '',
},
updatemsg.msgId
);
this.emitMsg(updatemsg);
}
}
} catch (error) {
this.context.logger.logError('处理发送消息失败', error);
}
};
msgListener.onMsgRecall = async (chatType: ChatType, uid: string, msgSeq: string) => {
@@ -291,10 +298,10 @@ export class NapCatOneBot11Adapter {
peerUid: uid,
guildId: ''
};
let msg = (await this.core.apis.MsgApi.queryMsgsWithFilterExWithSeq(peer, msgSeq)).msgList.find(e => e.msgType == NTMsgType.KMSGTYPEGRAYTIPS);
let element = msg?.elements[0];
const msg = (await this.core.apis.MsgApi.queryMsgsWithFilterExWithSeq(peer, msgSeq)).msgList.find(e => e.msgType == NTMsgType.KMSGTYPEGRAYTIPS);
const element = msg?.elements[0];
if (msg && element) {
let recallEvent = await this.emitRecallMsg(msg, element);
const recallEvent = await this.emitRecallMsg(msg, element);
try {
if (recallEvent) {
await this.networkManager.emitEvent(recallEvent);
@@ -303,12 +310,12 @@ export class NapCatOneBot11Adapter {
this.context.logger.logError('处理消息撤回失败', e);
}
}
}
};
msgListener.onKickedOffLine = async (kick) => {
const event = new BotOfflineEvent(this.core, kick.tipsTitle, kick.tipsDesc);
this.networkManager
.emitEvent(event)
.catch((e) => this.context.logger.logError.bind(this.context.logger)('处理Bot掉线失败', e));
.catch((e) => this.context.logger.logError('处理Bot掉线失败', e));
};
this.context.session.getMsgService().addKernelMsgListener(proxiedListenerOf(msgListener, this.context.logger));
}
@@ -397,7 +404,7 @@ export class NapCatOneBot11Adapter {
this.networkManager
.emitEvent(groupAdminNoticeEvent)
.catch((e) =>
this.context.logger.logError.bind(this.context.logger)('处理群管理员变动失败', e)
this.context.logger.logError('处理群管理员变动失败', e)
);
} else {
this.context.logger.logDebug(
@@ -433,7 +440,7 @@ export class NapCatOneBot11Adapter {
// this.networkManager
// .emitEvent(groupDecreaseEvent)
// .catch((e) =>
// this.context.logger.logError.bind(this.context.logger)('处理群成员退出失败', e)
// this.context.logger.logError('处理群成员退出失败', e)
// );
// // notify.status == 1 表示未处理 2表示处理完成
// } else
@@ -458,10 +465,10 @@ export class NapCatOneBot11Adapter {
this.networkManager
.emitEvent(groupRequestEvent)
.catch((e) =>
this.context.logger.logError.bind(this.context.logger)('处理加群请求失败', e)
this.context.logger.logError('处理加群请求失败', e)
);
} catch (e) {
this.context.logger.logError.bind(this.context.logger)(
this.context.logger.logError(
'获取加群人QQ号失败 Uid:',
notify.user1.uid,
e
@@ -483,7 +490,7 @@ export class NapCatOneBot11Adapter {
this.networkManager
.emitEvent(groupInviteEvent)
.catch((e) =>
this.context.logger.logError.bind(this.context.logger)('处理邀请本人加群失败', e)
this.context.logger.logError('处理邀请本人加群失败', e)
);
} else if (
notify.type == GroupNotifyMsgType.INVITED_NEED_ADMINI_STRATOR_PASS &&
@@ -501,7 +508,7 @@ export class NapCatOneBot11Adapter {
this.networkManager
.emitEvent(groupInviteEvent)
.catch((e) =>
this.context.logger.logError.bind(this.context.logger)('处理邀请本人加群失败', e)
this.context.logger.logError('处理邀请本人加群失败', e)
);
}
}
@@ -526,10 +533,10 @@ export class NapCatOneBot11Adapter {
this.networkManager
.emitEvent(groupAdminNoticeEvent)
.catch((e) =>
this.context.logger.logError.bind(this.context.logger)('处理群管理员变动失败', e)
this.context.logger.logError('处理群管理员变动失败', e)
);
existMember.isChangeRole = false;
this.context.logger.logDebug.bind(this.context.logger)('群管理员变动处理完毕');
this.context.logger.logDebug('群管理员变动处理完毕');
});
}
};
@@ -657,7 +664,7 @@ export class NapCatOneBot11Adapter {
private async emitRecallMsg(message: RawMessage, element: MessageElement) {
const peer: Peer = { chatType: message.chatType, peerUid: message.peerUid, guildId: '' };
let oriMessageId = MessageUnique.getShortIdByMsgId(message.msgId) ?? MessageUnique.createUniqueMsgId(peer, message.msgId);
const oriMessageId = MessageUnique.getShortIdByMsgId(message.msgId) ?? MessageUnique.createUniqueMsgId(peer, message.msgId);
if (message.chatType == ChatType.KCHATTYPEC2C) {
return await this.emitFriendRecallMsg(message, oriMessageId, element);
} else if (message.chatType == ChatType.KCHATTYPEGROUP) {
@@ -677,7 +684,7 @@ export class NapCatOneBot11Adapter {
private async emitGroupRecallMsg(message: RawMessage, oriMessageId: number, element: MessageElement) {
const operatorUid = element.grayTipElement?.revokeElement.operatorUid;
if (!operatorUid) return undefined;
let operatorId = message.senderUin ?? await this.core.apis.UserApi.getUinByUidV2(operatorUid);
const operatorId = message.senderUin ?? await this.core.apis.UserApi.getUinByUidV2(operatorUid);
return new OB11GroupRecallNoticeEvent(
this.core,
+message.peerUin,

View File

@@ -50,12 +50,12 @@ export class OB11ActiveHttpAdapter implements IOB11NetworkAdapter {
try {
this.obContext.apis.QuickActionApi
.handleQuickOperation(event as QuickActionEvent, resJson)
.catch(this.logger.logError.bind(this.logger));
.catch(e=>this.logger.logError(e));
} catch (e: any) {
this.logger.logError.bind(this.logger)('[OneBot] [Http Client] 新消息事件HTTP上报返回快速操作失败', e);
this.logger.logError('[OneBot] [Http Client] 新消息事件HTTP上报返回快速操作失败', e);
}
}).catch((e) => {
this.logger.logError.bind(this.logger)('[OneBot] [Http Client] 新消息事件HTTP上报失败', e);
this.logger.logError('[OneBot] [Http Client] 新消息事件HTTP上报失败', e);
});
}

View File

@@ -95,7 +95,7 @@ export class OB11ActiveWebSocketAdapter implements IOB11NetworkAdapter {
try {
this.connectEvent(this.core);
} catch (e) {
this.logger.logError.bind(this.logger)('[OneBot] [WebSocket Client] 发送连接生命周期失败', e);
this.logger.logError('[OneBot] [WebSocket Client] 发送连接生命周期失败', e);
}
});
@@ -104,8 +104,8 @@ export class OB11ActiveWebSocketAdapter implements IOB11NetworkAdapter {
});
this.connection.once('close', () => {
if (!isClosedByError) {
this.logger.logError.bind(this.logger)(`[OneBot] [WebSocket Client] 反向WebSocket (${this.config.url}) 连接意外关闭`);
this.logger.logError.bind(this.logger)(`[OneBot] [WebSocket Client] 在 ${Math.floor(this.config.reconnectInterval / 1000)} 秒后尝试重新连接`);
this.logger.logError(`[OneBot] [WebSocket Client] 反向WebSocket (${this.config.url}) 连接意外关闭`);
this.logger.logError(`[OneBot] [WebSocket Client] 在 ${Math.floor(this.config.reconnectInterval / 1000)} 秒后尝试重新连接`);
if (this.isEnable) {
this.connection = null;
setTimeout(() => this.tryConnect(), this.config.reconnectInterval);
@@ -114,8 +114,8 @@ export class OB11ActiveWebSocketAdapter implements IOB11NetworkAdapter {
});
this.connection.on('error', (err) => {
isClosedByError = true;
this.logger.logError.bind(this.logger)(`[OneBot] [WebSocket Client] 反向WebSocket (${this.config.url}) 连接错误`, err);
this.logger.logError.bind(this.logger)(`[OneBot] [WebSocket Client] 在 ${Math.floor(this.config.reconnectInterval / 1000)} 秒后尝试重新连接`);
this.logger.logError(`[OneBot] [WebSocket Client] 反向WebSocket (${this.config.url}) 连接错误`, err);
this.logger.logError(`[OneBot] [WebSocket Client] 在 ${Math.floor(this.config.reconnectInterval / 1000)} 秒后尝试重新连接`);
if (this.isEnable) {
this.connection = null;
setTimeout(() => this.tryConnect(), this.config.reconnectInterval);
@@ -128,7 +128,7 @@ export class OB11ActiveWebSocketAdapter implements IOB11NetworkAdapter {
try {
this.checkStateAndReply<any>(new OB11LifeCycleEvent(core, LifeCycleSubType.CONNECT));
} catch (e) {
this.logger.logError.bind(this.logger)('[OneBot] [WebSocket Client] 发送生命周期失败', e);
this.logger.logError('[OneBot] [WebSocket Client] 发送生命周期失败', e);
}
}
@@ -147,7 +147,7 @@ export class OB11ActiveWebSocketAdapter implements IOB11NetworkAdapter {
receiveData.params = (receiveData?.params) ? receiveData.params : {};// 兼容类型验证
const action = this.actions.get(receiveData.action);
if (!action) {
this.logger.logError.bind(this.logger)('[OneBot] [WebSocket Client] 发生错误', '不支持的Api ' + receiveData.action);
this.logger.logError('[OneBot] [WebSocket Client] 发生错误', '不支持的Api ' + receiveData.action);
this.checkStateAndReply<any>(OB11Response.error('不支持的Api ' + receiveData.action, 1404, echo));
return;
}

View File

@@ -102,7 +102,7 @@ export class OB11PassiveHttpAdapter implements IOB11NetworkAdapter {
if (req.path === '' || req.path === '/') {
const hello = OB11Response.ok({});
hello.message = 'NapCat4 Ss Running';
return res.json(hello)
return res.json(hello);
}
const actionName = req.path.split('/')[1];
const action = this.actions.get(actionName);

View File

@@ -51,7 +51,7 @@ export class OB11PassiveWebSocketAdapter implements IOB11NetworkAdapter {
wsClient.on('error', (err) => this.logger.log('[OneBot] [WebSocket Server] Client Error:', err.message));
wsClient.on('message', (message) => {
this.handleMessage(wsClient, message).then().catch(this.logger.logError.bind(this.logger));
this.handleMessage(wsClient, message).then().catch(e => this.logger.logError(e));
});
wsClient.on('ping', () => {
wsClient.pong();
@@ -85,7 +85,7 @@ export class OB11PassiveWebSocketAdapter implements IOB11NetworkAdapter {
try {
this.checkStateAndReply<any>(new OB11LifeCycleEvent(core, LifeCycleSubType.CONNECT), wsClient);
} catch (e) {
this.logger.logError.bind(this.logger)('[OneBot] [WebSocket Server] 发送生命周期失败', e);
this.logger.logError('[OneBot] [WebSocket Server] 发送生命周期失败', e);
}
}
@@ -99,7 +99,7 @@ export class OB11PassiveWebSocketAdapter implements IOB11NetworkAdapter {
open() {
if (this.isEnable) {
this.logger.logError.bind(this.logger)('[OneBot] [WebSocket Server] Cannot open a opened WebSocket server');
this.logger.logError('[OneBot] [WebSocket Server] Cannot open a opened WebSocket server');
return;
}
const addressInfo = this.wsServer.address();
@@ -116,9 +116,9 @@ export class OB11PassiveWebSocketAdapter implements IOB11NetworkAdapter {
this.isEnable = false;
this.wsServer.close((err) => {
if (err) {
this.logger.logError.bind(this.logger)('[OneBot] [WebSocket Server] Error closing server:', err.message);
this.logger.logError('[OneBot] [WebSocket Server] Error closing server:', err.message);
} else {
this.logger.log.bind(this.logger)('[OneBot] [WebSocket Server] Server Closed');
this.logger.log('[OneBot] [WebSocket Server] Server Closed');
}
});
@@ -179,7 +179,7 @@ export class OB11PassiveWebSocketAdapter implements IOB11NetworkAdapter {
receiveData.params = (receiveData?.params) ? receiveData.params : {};//兼容类型验证 不然类型校验爆炸
const action = this.actions.get(receiveData.action);
if (!action) {
this.logger.logError.bind(this.logger)('[OneBot] [WebSocket Client] 发生错误', '不支持的API ' + receiveData.action);
this.logger.logError('[OneBot] [WebSocket Client] 发生错误', '不支持的API ' + receiveData.action);
this.checkStateAndReply<any>(OB11Response.error('不支持的API ' + receiveData.action, 1404, echo), wsClient);
return;
}

View File

@@ -176,7 +176,7 @@ async function handleLogin(
}
logger.log('核心登录服务连接成功!');
loginService.getLoginList().then((res) => {
// 遍历 res.LocalLoginInfoList[x].isQuickLogin是否可以 res.LocalLoginInfoList[x].uin 转为string 加入string[] 最后遍历完成调用WebUiDataRuntime.setQQQuickLoginList
WebUiDataRuntime.setQQQuickLoginList(res.LocalLoginInfoList.filter((item) => item.isQuickLogin).map((item) => item.uin.toString()));
@@ -276,7 +276,7 @@ export async function NCoreInitShell() {
o3Service.addO3MiscListener(new NodeIO3MiscListener());
logger.log(`[NapCat] [Core] NapCat.Core Version: ` + napCatVersion);
InitWebUi(logger, pathWrapper).then().catch(logger.logError.bind(logger));
InitWebUi(logger, pathWrapper).then().catch(e => logger.logError(e));
const engine = wrapper.NodeIQQNTWrapperEngine.get();
const loginService = wrapper.NodeIKernelLoginService.get();
@@ -362,7 +362,7 @@ export class NapCatShell {
async InitNapCat() {
await this.core.initCore();
new NapCatOneBot11Adapter(this.core, this.context, this.context.pathWrapper).InitOneBot()
.catch(e => this.context.logger.logError.bind(this.context.logger)('初始化OneBot失败', e));
.catch(e => this.context.logger.logError('初始化OneBot失败', e));
}
}

View File

@@ -3,11 +3,8 @@
*/
import express from 'express';
import { LogWrapper } from '@/common/log';
import { NapCatPathWrapper } from '@/common/path';
import { RequestUtil } from '@/common/request';
import { WebUiConfigWrapper } from '@webapi/helper/config';
import { ALLRouter } from '@webapi/router';
import { cors } from '@webapi/middleware/cors';
@@ -29,10 +26,9 @@ export let webUiPathWrapper: NapCatPathWrapper;
export async function InitWebUi(logger: LogWrapper, pathWrapper: NapCatPathWrapper) {
webUiPathWrapper = pathWrapper;
WebUiConfig = new WebUiConfigWrapper();
const log = logger.log.bind(logger);
const config = await WebUiConfig.GetWebUIConfig();
if (config.port == 0) {
log('[NapCat] [WebUi] Current WebUi is not run.');
logger.log('[NapCat] [WebUi] Current WebUi is not run.');
return;
}
@@ -61,25 +57,15 @@ export async function InitWebUi(logger: LogWrapper, pathWrapper: NapCatPathWrapp
// ------------启动服务------------
app.listen(config.port, config.host, async () => {
// 启动后打印出相关地址
const port = config.port.toString(),
searchParams = { token: config.token },
path = `${config.prefix}/webui`;
// 打印日志地址、token
log(`[NapCat] [WebUi] Current WebUi is running at http://${config.host}:${config.port}${config.prefix}`);
log(`[NapCat] [WebUi] Login Token is ${config.token}`);
log(`[NapCat] [WebUi] WebUi User Panel Url: ${createUrl(config.host, port, path, searchParams)}`);
log(`[NapCat] [WebUi] WebUi Local Panel Url: ${createUrl('127.0.0.1', port, path, searchParams)}`);
// 获取公网地址
try {
const publishUrl = 'https://ip.011102.xyz/';
const data = await RequestUtil.HttpGetJson<{ IP: { IP: string } }>(publishUrl, 'GET', {}, {}, true, true);
log(`[NapCat] [WebUi] WebUi Publish Panel Url: ${createUrl(data.IP.IP, port, path, searchParams)}`);
} catch (err) {
logger.logError(`[NapCat] [WebUi] Get Publish Panel Url Error: ${err}`);
if (config.host !== '' && config.host !== '0.0.0.0') {
logger.log(`[NapCat] [WebUi] WebUi User Panel Url: ${createUrl(config.host, port, path, searchParams)}`);
logger.log(`[NapCat] [WebUi] WebUi User Panel Url: https://napcat.152710.xyz/web_login?back=http://${config.host}:${config.port}${config.prefix}&token=${config.token}`);
}
logger.log(`[NapCat] [WebUi] WebUi Local Panel Url: ${createUrl('127.0.0.1', port, path, searchParams)}`);
logger.log(`[NapCat] [WebUi] WebUi Local Panel Url: https://napcat.152710.xyz/web_login?back=http://127.0.0.1:${config.port}${config.prefix}&token=${config.token}`);
});
// ------------Over------------
}