From 709a0744bd4b55a7b5d49aabd0fd0dd5de744ae2 Mon Sep 17 00:00:00 2001 From: Hao Guan <10684225+hguandl@users.noreply.github.com> Date: Tue, 3 Sep 2024 20:14:35 +0800 Subject: [PATCH 01/23] chore: refactor path config --- src/common/config-base.ts | 11 ++++++++--- src/common/helper.ts | 8 ++++++-- src/common/path.ts | 15 +++++++++------ src/common/qq-basic-info.ts | 25 ++++++++++++++++++------- src/core/index.ts | 6 ++++-- src/shell/napcat.ts | 19 +++++++++++-------- 6 files changed, 56 insertions(+), 28 deletions(-) diff --git a/src/common/config-base.ts b/src/common/config-base.ts index ce4070d1..79e44c85 100644 --- a/src/common/config-base.ts +++ b/src/common/config-base.ts @@ -22,9 +22,14 @@ export abstract class ConfigBase { } getConfigPath(pathName: string | undefined): string { - const suffix = pathName ? `_${pathName}` : ''; - const filename = `${this.name}${suffix}.json`; - return path.join(this.configPath, filename); + if (!pathName) { + const filename = `${this.name}.json`; + const mainPath = this.core.context.pathWrapper.binaryPath; + return path.join(mainPath, 'config', filename); + } else { + const filename = `${this.name}_${pathName}.json`; + return path.join(this.configPath, filename); + } } read(): T { diff --git a/src/common/helper.ts b/src/common/helper.ts index d0ee50a6..f4ad9812 100644 --- a/src/common/helper.ts +++ b/src/common/helper.ts @@ -37,7 +37,7 @@ export class FileNapCatOneBotUUID { if (!uuid.startsWith('NapCatOneBot|ModelIdFile|')) return undefined; const data = uuid.split('|'); if (data.length !== 6) return undefined; - const [, , chatType, peerUid, modelId,fileId] = data; + const [, , chatType, peerUid, modelId, fileId] = data; return { peer: { chatType: chatType as any, @@ -156,9 +156,13 @@ export function getDefaultQQVersionConfigInfo(): QQVersionConfigType { }; } +export function getQQPackageInfoPath(exePath: string = ''): string { + return path.join(path.dirname(exePath), 'resources', 'app', 'package.json'); +} + export function getQQVersionConfigPath(exePath: string = ''): string | undefined { let configVersionInfoPath; - if (os.platform() !== 'linux') { + if (os.platform() === 'win32') { configVersionInfoPath = path.join(path.dirname(exePath), 'resources', 'app', 'versions', 'config.json'); } else { const userPath = os.homedir(); diff --git a/src/common/path.ts b/src/common/path.ts index e154bb46..308bcfd5 100644 --- a/src/common/path.ts +++ b/src/common/path.ts @@ -1,6 +1,7 @@ import path, { dirname } from 'path'; import { fileURLToPath } from 'url'; import fs from 'fs'; +import os from 'os'; export class NapCatPathWrapper { binaryPath: string; @@ -11,17 +12,19 @@ export class NapCatPathWrapper { constructor(mainPath: string = dirname(fileURLToPath(import.meta.url))) { this.binaryPath = mainPath; - this.logsPath = path.join(this.binaryPath, 'logs'); - this.configPath = path.join(this.binaryPath, 'config'); - this.cachePath = path.join(this.binaryPath, 'cache'); + let writePath: string; + writePath = this.binaryPath; + this.logsPath = path.join(writePath, 'logs'); + this.configPath = path.join(writePath, 'config'); + this.cachePath = path.join(writePath, 'cache'); this.staticPath = path.join(this.binaryPath, 'static'); - if (fs.existsSync(this.logsPath)) { + if (!fs.existsSync(this.logsPath)) { fs.mkdirSync(this.logsPath, { recursive: true }); } - if (fs.existsSync(this.configPath)) { + if (!fs.existsSync(this.configPath)) { fs.mkdirSync(this.configPath, { recursive: true }); } - if (fs.existsSync(this.cachePath)) { + if (!fs.existsSync(this.cachePath)) { fs.mkdirSync(this.cachePath, { recursive: true }); } } diff --git a/src/common/qq-basic-info.ts b/src/common/qq-basic-info.ts index 4e063ee2..79556fab 100644 --- a/src/common/qq-basic-info.ts +++ b/src/common/qq-basic-info.ts @@ -1,7 +1,6 @@ -import path from 'node:path'; import fs from 'node:fs'; import { systemPlatform } from '@/common/system'; -import { getDefaultQQVersionConfigInfo, getQQVersionConfigPath } from './helper'; +import { getDefaultQQVersionConfigInfo, getQQPackageInfoPath, getQQVersionConfigPath } from './helper'; import AppidTable from '@/core/external/appid.json'; import { LogWrapper } from './log'; @@ -20,7 +19,7 @@ export class QQBasicInfoWrapper { //基础目录获取 this.context = context; this.QQMainPath = process.execPath; - this.QQPackageInfoPath = path.join(path.dirname(this.QQMainPath), 'resources', 'app', 'package.json'); + this.QQPackageInfoPath = getQQPackageInfoPath(this.QQMainPath); this.QQVersionConfigPath = getQQVersionConfigPath(this.QQMainPath); //基础信息获取 无快更则启用默认模板填充 @@ -53,9 +52,21 @@ export class QQBasicInfoWrapper { //此方法不要直接使用 getQUAInternal() { - return systemPlatform === 'linux' - ? `V1_LNX_NQ_${this.getFullQQVesion()}_${this.getQQBuildStr()}_GW_B` - : `V1_WIN_NQ_${this.getFullQQVesion()}_${this.getQQBuildStr()}_GW_B`; + switch (systemPlatform) { + case 'linux': + return `V1_LNX_${this.getFullQQVesion()}_${this.getQQBuildStr()}_GW_B`; + default: + return `V1_WIN_${this.getFullQQVesion()}_${this.getQQBuildStr()}_GW_B`; + } + } + + getAppidInternal() { + switch (systemPlatform) { + case 'linux': + return '537243600'; + default: + return '537243538'; + } } getAppidV2(): { appid: string; qua: string } { @@ -71,6 +82,6 @@ export class QQBasicInfoWrapper { // else this.context.logger.log(`[QQ版本兼容性检测] 获取Appid异常 请检测NapCat/QQNT是否正常`); this.context.logger.log(`[QQ版本兼容性检测] ${fullVersion} 版本兼容性不佳,可能会导致一些功能无法正常使用`,); - return { appid: systemPlatform === 'linux' ? '537243600' : '537243441', qua: this.getQUAInternal() }; + return { appid: this.getAppidInternal(), qua: this.getQUAInternal() }; } } diff --git a/src/core/index.ts b/src/core/index.ts index adc5e917..5fc2912e 100644 --- a/src/core/index.ts +++ b/src/core/index.ts @@ -42,9 +42,11 @@ export enum NapCatCoreWorkingEnv { } export function loadQQWrapper(QQVersion: string): WrapperNodeApi { - let wrapperNodePath = path.resolve(path.dirname(process.execPath), './resources/app/wrapper.node'); + let appPath; + appPath = path.resolve(path.dirname(process.execPath), './resources/app'); + let wrapperNodePath = path.resolve(appPath, 'wrapper.node'); if (!fs.existsSync(wrapperNodePath)) { - wrapperNodePath = path.join(path.dirname(process.execPath), `resources/app/versions/${QQVersion}/wrapper.node`); + wrapperNodePath = path.join(appPath, `versions/${QQVersion}/wrapper.node`); } const nativemodule: any = { exports: {} }; process.dlopen(nativemodule, wrapperNodePath); diff --git a/src/shell/napcat.ts b/src/shell/napcat.ts index 31857baa..044155df 100644 --- a/src/shell/napcat.ts +++ b/src/shell/napcat.ts @@ -49,12 +49,15 @@ export async function NCoreInitShell() { const session = new wrapper.NodeIQQNTWrapperSession(); // from get dataPath - let dataPath = wrapper.NodeQQNTWrapperUtil.getNTUserDataInfoConfig(); - if (!dataPath) { - dataPath = path.resolve(os.homedir(), './.config/QQ'); - fs.mkdirSync(dataPath, { recursive: true }); - } - const dataPathGlobal = path.resolve(dataPath, './nt_qq/global'); + const [dataPath, dataPathGlobal] = (() => { + let dataPath = wrapper.NodeQQNTWrapperUtil.getNTUserDataInfoConfig(); + if (!dataPath) { + dataPath = path.resolve(os.homedir(), './.config/QQ'); + fs.mkdirSync(dataPath, { recursive: true }); + } + const dataPathGlobal = path.resolve(dataPath, './nt_qq/global'); + return [dataPath, dataPathGlobal]; + })(); // from initConfig engine.initWithDeskTopConfig( @@ -115,7 +118,7 @@ export async function NCoreInitShell() { const realBase64 = pngBase64QrcodeData.replace(/^data:image\/\w+;base64,/, ''); const buffer = Buffer.from(realBase64, 'base64'); logger.logWarn('请扫描下面的二维码,然后在手Q上授权登录:'); - const qrcodePath = path.join(pathWrapper.binaryPath, 'qrcode.png'); + const qrcodePath = path.join(pathWrapper.cachePath, 'qrcode.png'); qrcode.generate(qrcodeUrl, { small: true }, (res) => { logger.logWarn([ '\n', @@ -191,7 +194,7 @@ export async function NCoreInitShell() { logger.log(`可用于快速登录的 QQ:\n${historyLoginList .map((u, index) => `${index + 1}. ${u.uin} ${u.nickName}`) .join('\n') - }`); + }`); } loginService.getQRCodePicture(); } From 7e96118cdce1a470baa0adf5f934fb7aafce6085 Mon Sep 17 00:00:00 2001 From: Hao Guan <10684225+hguandl@users.noreply.github.com> Date: Tue, 3 Sep 2024 20:17:10 +0800 Subject: [PATCH 02/23] feat: support macOS --- src/common/helper.ts | 10 +++++++++- src/common/path.ts | 6 +++++- src/common/qq-basic-info.ts | 6 +++++- src/core/external/appid.json | 4 ++++ src/core/index.ts | 6 +++++- src/shell/napcat.ts | 5 +++++ 6 files changed, 33 insertions(+), 4 deletions(-) diff --git a/src/common/helper.ts b/src/common/helper.ts index f4ad9812..693187fb 100644 --- a/src/common/helper.ts +++ b/src/common/helper.ts @@ -157,13 +157,21 @@ export function getDefaultQQVersionConfigInfo(): QQVersionConfigType { } export function getQQPackageInfoPath(exePath: string = ''): string { - return path.join(path.dirname(exePath), 'resources', 'app', 'package.json'); + if (os.platform() === 'darwin') { + return path.join(path.dirname(exePath), '..', 'Resources', 'app', 'package.json'); + } else { + return path.join(path.dirname(exePath), 'resources', 'app', 'package.json'); + } } export function getQQVersionConfigPath(exePath: string = ''): string | undefined { let configVersionInfoPath; if (os.platform() === 'win32') { configVersionInfoPath = path.join(path.dirname(exePath), 'resources', 'app', 'versions', 'config.json'); + } else if (os.platform() === 'darwin') { + const userPath = os.homedir(); + const appDataPath = path.resolve(userPath, './Library/Application Support/QQ'); + configVersionInfoPath = path.resolve(appDataPath, './versions/config.json'); } else { const userPath = os.homedir(); const appDataPath = path.resolve(userPath, './.config/QQ'); diff --git a/src/common/path.ts b/src/common/path.ts index 308bcfd5..b204cb20 100644 --- a/src/common/path.ts +++ b/src/common/path.ts @@ -13,7 +13,11 @@ export class NapCatPathWrapper { constructor(mainPath: string = dirname(fileURLToPath(import.meta.url))) { this.binaryPath = mainPath; let writePath: string; - writePath = this.binaryPath; + if (os.platform() === 'darwin') { + writePath = path.join(os.homedir(), 'Library', 'Application Support', 'QQ', 'NapCat'); + } else { + writePath = this.binaryPath; + } this.logsPath = path.join(writePath, 'logs'); this.configPath = path.join(writePath, 'config'); this.cachePath = path.join(writePath, 'cache'); diff --git a/src/common/qq-basic-info.ts b/src/common/qq-basic-info.ts index 79556fab..555f1195 100644 --- a/src/common/qq-basic-info.ts +++ b/src/common/qq-basic-info.ts @@ -54,7 +54,9 @@ export class QQBasicInfoWrapper { getQUAInternal() { switch (systemPlatform) { case 'linux': - return `V1_LNX_${this.getFullQQVesion()}_${this.getQQBuildStr()}_GW_B`; + return `V1_LNX_${this.getFullQQVesion()}_${this.getQQBuildStr()}_GW_B`; + case 'darwin': + return `V1_MAC_${this.getFullQQVesion()}_${this.getQQBuildStr()}_GW_B`; default: return `V1_WIN_${this.getFullQQVesion()}_${this.getQQBuildStr()}_GW_B`; } @@ -64,6 +66,8 @@ export class QQBasicInfoWrapper { switch (systemPlatform) { case 'linux': return '537243600'; + case 'darwin': + return '537243441'; default: return '537243538'; } diff --git a/src/core/external/appid.json b/src/core/external/appid.json index 9375e295..3f05c08b 100644 --- a/src/core/external/appid.json +++ b/src/core/external/appid.json @@ -6,5 +6,9 @@ "9.9.15-27597": { "appid": 537243441, "qua": "V1_WIN_NQ_9.9.15_27597_GW_B" + }, + "6.9.53-27597": { + "appid": 537243538, + "qua": "V1_MAC_NQ_6.9.53_27597_GW_B" } } diff --git a/src/core/index.ts b/src/core/index.ts index 5fc2912e..c6e9f0ea 100644 --- a/src/core/index.ts +++ b/src/core/index.ts @@ -43,7 +43,11 @@ export enum NapCatCoreWorkingEnv { export function loadQQWrapper(QQVersion: string): WrapperNodeApi { let appPath; - appPath = path.resolve(path.dirname(process.execPath), './resources/app'); + if (os.platform() === 'darwin') { + appPath = path.resolve(path.dirname(process.execPath), '../Resources/app'); + } else { + appPath = path.resolve(path.dirname(process.execPath), './resources/app'); + } let wrapperNodePath = path.resolve(appPath, 'wrapper.node'); if (!fs.existsSync(wrapperNodePath)) { wrapperNodePath = path.join(appPath, `versions/${QQVersion}/wrapper.node`); diff --git a/src/shell/napcat.ts b/src/shell/napcat.ts index 044155df..4beeded5 100644 --- a/src/shell/napcat.ts +++ b/src/shell/napcat.ts @@ -50,6 +50,11 @@ export async function NCoreInitShell() { // from get dataPath const [dataPath, dataPathGlobal] = (() => { + if (os.platform() === 'darwin') { + const userPath = os.homedir(); + const appDataPath = path.resolve(userPath, './Library/Application Support/QQ'); + return [appDataPath, path.join(appDataPath, 'global')]; + } let dataPath = wrapper.NodeQQNTWrapperUtil.getNTUserDataInfoConfig(); if (!dataPath) { dataPath = path.resolve(os.homedir(), './.config/QQ'); From 1d2e2b6e5c57ac265ee94a8d0dc7f6c4d2ef5069 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=89=8B=E7=93=9C=E4=B8=80=E5=8D=81=E9=9B=AA?= Date: Tue, 3 Sep 2024 21:33:48 +0800 Subject: [PATCH 03/23] release: 2.2.44 --- manifest.json | 2 +- package.json | 2 +- src/common/version.ts | 2 +- src/webui/ui/NapCat.ts | 2 +- static/assets/renderer.js | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/manifest.json b/manifest.json index 703bb7a5..82641257 100644 --- a/manifest.json +++ b/manifest.json @@ -4,7 +4,7 @@ "name": "NapCatQQ", "slug": "NapCat.Framework", "description": "高性能的 OneBot 11 协议实现", - "version": "2.2.43", + "version": "2.2.44", "icon": "./logo.png", "authors": [ { diff --git a/package.json b/package.json index 67b2d1e8..9b648b74 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "napcat", "private": true, "type": "module", - "version": "2.2.43", + "version": "2.2.44", "scripts": { "build:framework": "vite build --mode framework", "build:shell": "vite build --mode shell", diff --git a/src/common/version.ts b/src/common/version.ts index 2297647c..fa823d83 100644 --- a/src/common/version.ts +++ b/src/common/version.ts @@ -1 +1 @@ -export const napCatVersion = '2.2.43'; +export const napCatVersion = '2.2.44'; diff --git a/src/webui/ui/NapCat.ts b/src/webui/ui/NapCat.ts index 3bc0b62f..d7fb407a 100644 --- a/src/webui/ui/NapCat.ts +++ b/src/webui/ui/NapCat.ts @@ -30,7 +30,7 @@ async function onSettingWindowCreated(view: Element) { SettingItem( 'Napcat', undefined, - SettingButton('V2.2.43', 'napcat-update-button', 'secondary'), + SettingButton('V2.2.44', 'napcat-update-button', 'secondary'), ), ]), SettingList([ diff --git a/static/assets/renderer.js b/static/assets/renderer.js index 84aec789..ef5bbdc9 100644 --- a/static/assets/renderer.js +++ b/static/assets/renderer.js @@ -164,7 +164,7 @@ async function onSettingWindowCreated(view) { SettingItem( 'Napcat', void 0, - SettingButton("V2.2.43", "napcat-update-button", "secondary") + SettingButton("V2.2.44", "napcat-update-button", "secondary") ) ]), SettingList([ From 3ca959b7a631ed4a68a2525584c3b4b1aa5cd7ca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=89=8B=E7=93=9C=E4=B8=80=E5=8D=81=E9=9B=AA?= Date: Tue, 3 Sep 2024 21:51:16 +0800 Subject: [PATCH 04/23] docs: update --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index ab25c145..3c5e5e0e 100644 --- a/README.md +++ b/README.md @@ -9,6 +9,8 @@ NapCatQQ (aka 猫猫框架) 是现代化的基于 NTQQ 的 Bot 协议端实现 ## 猫猫技能 - [x] **高性能**:1K+ 群聊数目、20 线程并行发送消息毫无压力 - [x] **多种启动方式**:支持以无头、LiteLoader 插件、仅 QQ GUI 三种方式启动 +- [x] **多平台支持**: 支持Windows/Linux(可选Docker)/Android Termux覆盖全面 +- [x] **安装简单**: 支持一键脚本/程序自动部署/镜像部署等多种覆盖范围 - [x] **低占用**:无头模式占用资源极低,适合在服务器上运行 - [x] **超多接口**:实现大部分 OneBot 和 go-cqhttp 接口,超多扩展 API - [x] **WebUI**:自带 WebUI 支持,远程管理更加便捷 From c3eaae9d88e9551eb3270cca53b208e0037a9008 Mon Sep 17 00:00:00 2001 From: "Wesley F. Young" Date: Tue, 3 Sep 2024 23:45:51 +0800 Subject: [PATCH 05/23] chore: optimize imports --- src/core/apis/group.ts | 3 +-- src/onebot/action/go-cqhttp/CreateGroupFileFolder.ts | 1 + src/onebot/action/go-cqhttp/DeleteGroupFile.ts | 1 + src/onebot/action/go-cqhttp/GetGroupFilesByFolder.ts | 1 + src/onebot/index.ts | 5 +---- 5 files changed, 5 insertions(+), 6 deletions(-) diff --git a/src/core/apis/group.ts b/src/core/apis/group.ts index e051f061..0fbdc2fc 100644 --- a/src/core/apis/group.ts +++ b/src/core/apis/group.ts @@ -1,5 +1,4 @@ import { - ChatType, GeneralCallResult, Group, GroupMember, @@ -10,7 +9,7 @@ import { MemberExtSourceType, NapCatCore, } from '@/core'; -import { isNumeric, runAllWithTimeout } from '@/common/helper'; +import { isNumeric } from '@/common/helper'; import { LimitedHashTable } from '@/common/message-unique'; export class NTQQGroupApi { diff --git a/src/onebot/action/go-cqhttp/CreateGroupFileFolder.ts b/src/onebot/action/go-cqhttp/CreateGroupFileFolder.ts index eb298bf5..b2025589 100644 --- a/src/onebot/action/go-cqhttp/CreateGroupFileFolder.ts +++ b/src/onebot/action/go-cqhttp/CreateGroupFileFolder.ts @@ -1,6 +1,7 @@ import { FromSchema, JSONSchema } from 'json-schema-to-ts'; import BaseAction from '../BaseAction'; import { ActionName } from '../types'; + const SchemaData = { type: 'object', properties: { diff --git a/src/onebot/action/go-cqhttp/DeleteGroupFile.ts b/src/onebot/action/go-cqhttp/DeleteGroupFile.ts index 67bd1ee9..ee287a92 100644 --- a/src/onebot/action/go-cqhttp/DeleteGroupFile.ts +++ b/src/onebot/action/go-cqhttp/DeleteGroupFile.ts @@ -2,6 +2,7 @@ import { FromSchema, JSONSchema } from 'json-schema-to-ts'; import BaseAction from '../BaseAction'; import { ActionName } from '../types'; import { FileNapCatOneBotUUID } from '@/common/helper'; + const SchemaData = { type: 'object', properties: { diff --git a/src/onebot/action/go-cqhttp/GetGroupFilesByFolder.ts b/src/onebot/action/go-cqhttp/GetGroupFilesByFolder.ts index 2100c679..5f9c20f0 100644 --- a/src/onebot/action/go-cqhttp/GetGroupFilesByFolder.ts +++ b/src/onebot/action/go-cqhttp/GetGroupFilesByFolder.ts @@ -2,6 +2,7 @@ import { FromSchema, JSONSchema } from 'json-schema-to-ts'; import BaseAction from '../BaseAction'; import { ActionName } from '../types'; import { OB11Entities } from '@/onebot/entities'; + const SchemaData = { type: 'object', properties: { diff --git a/src/onebot/index.ts b/src/onebot/index.ts index 8efab1c3..c24bcea4 100644 --- a/src/onebot/index.ts +++ b/src/onebot/index.ts @@ -43,9 +43,6 @@ import { OB11FriendRecallNoticeEvent } from '@/onebot/event/notice/OB11FriendRec import { OB11GroupRecallNoticeEvent } from '@/onebot/event/notice/OB11GroupRecallNoticeEvent'; import { LRUCache } from '@/common/lru-cache'; import { NodeIKernelRecentContactListener } from '@/core/listeners/NodeIKernelRecentContactListener'; -import { SysMessage } from '@/core/proto/SysMessage'; -import { GreyTipWrapper } from '@/core/proto/GreyTipWrapper'; -import { EmojiLikeToOthersWrapper1 } from '@/core/proto/EmojiLikeToOthers'; //OneBot实现类 export class NapCatOneBot11Adapter { @@ -241,7 +238,7 @@ export class NapCatOneBot11Adapter { private initMsgListener() { const msgListener = new NodeIKernelMsgListener(); - msgListener.onRecvSysMsg = async msg => { + msgListener.onRecvSysMsg = async () => { // const sysMsg = SysMessage.fromBinary(Uint8Array.from(msg)); // if (sysMsg.msgSpec.length === 0) { // return; From 41a8dc840f9e886dec987d2fbb430696526a726d Mon Sep 17 00:00:00 2001 From: "Wesley F. Young" Date: Tue, 3 Sep 2024 23:54:46 +0800 Subject: [PATCH 06/23] chore: completely comment onRecvSysMsg --- src/onebot/index.ts | 52 +++++++++++++++++++++++---------------------- 1 file changed, 27 insertions(+), 25 deletions(-) diff --git a/src/onebot/index.ts b/src/onebot/index.ts index c24bcea4..4d9ec98c 100644 --- a/src/onebot/index.ts +++ b/src/onebot/index.ts @@ -238,33 +238,35 @@ export class NapCatOneBot11Adapter { private initMsgListener() { const msgListener = new NodeIKernelMsgListener(); + /* msgListener.onRecvSysMsg = async () => { - // const sysMsg = SysMessage.fromBinary(Uint8Array.from(msg)); - // if (sysMsg.msgSpec.length === 0) { - // return; - // } - // const { msgType, subType, subSubType } = sysMsg.msgSpec[0]; - // if (msgType === 732 && subType === 16 && subSubType === 16) { - // const greyTip = GreyTipWrapper.fromBinary(Uint8Array.from(sysMsg.bodyWrapper!.wrappedBody.slice(7))); - // if (greyTip.subTypeId === 36) { - // const emojiLikeToOthers = EmojiLikeToOthersWrapper1 - // .fromBinary(greyTip.rest) - // .wrapper! - // .body!; - // if (emojiLikeToOthers.attributes?.operation !== 1) { // Un-like - // return; - // } - // const eventOrEmpty = await this.apis.GroupApi.createGroupEmojiLikeEvent( - // greyTip.groupCode.toString(), - // await this.core.apis.UserApi.getUinByUidV2(emojiLikeToOthers.attributes!.senderUid), - // emojiLikeToOthers.msgSpec!.msgSeq.toString(), - // emojiLikeToOthers.attributes!.emojiId, - // ); - // // eslint-disable-next-line @typescript-eslint/no-unused-expressions - // eventOrEmpty && await this.networkManager.emitEvent(eventOrEmpty); - // } - // } + const sysMsg = SysMessage.fromBinary(Uint8Array.from(msg)); + if (sysMsg.msgSpec.length === 0) { + return; + } + const { msgType, subType, subSubType } = sysMsg.msgSpec[0]; + if (msgType === 732 && subType === 16 && subSubType === 16) { + const greyTip = GreyTipWrapper.fromBinary(Uint8Array.from(sysMsg.bodyWrapper!.wrappedBody.slice(7))); + if (greyTip.subTypeId === 36) { + const emojiLikeToOthers = EmojiLikeToOthersWrapper1 + .fromBinary(greyTip.rest) + .wrapper! + .body!; + if (emojiLikeToOthers.attributes?.operation !== 1) { // Un-like + return; + } + const eventOrEmpty = await this.apis.GroupApi.createGroupEmojiLikeEvent( + greyTip.groupCode.toString(), + await this.core.apis.UserApi.getUinByUidV2(emojiLikeToOthers.attributes!.senderUid), + emojiLikeToOthers.msgSpec!.msgSeq.toString(), + emojiLikeToOthers.attributes!.emojiId, + ); + // eslint-disable-next-line @typescript-eslint/no-unused-expressions + eventOrEmpty && await this.networkManager.emitEvent(eventOrEmpty); + } + } }; + */ msgListener.onInputStatusPush = async data => { const uin = await this.core.apis.UserApi.getUinByUidV2(data.fromUin); From 9898c2196d18596c57775ba2bb11ba40578bfcf4 Mon Sep 17 00:00:00 2001 From: "Wesley F. Young" Date: Wed, 4 Sep 2024 00:29:55 +0800 Subject: [PATCH 07/23] chore: optimize tsconfig.json --- tsconfig.json | 6 ------ 1 file changed, 6 deletions(-) diff --git a/tsconfig.json b/tsconfig.json index cc8bbfd0..66a54c36 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -25,12 +25,6 @@ "paths": { "@*": [ "./src*" - ], - "@/core": [ - "./src/core/index", - ], - "@/core/*": [ - "./src/core/*" ] } }, From 6a0d5924916e5798fc74ab347a01719506adb8d8 Mon Sep 17 00:00:00 2001 From: "Wesley F. Young" Date: Wed, 4 Sep 2024 10:04:33 +0800 Subject: [PATCH 08/23] chore: optimize vite.config.ts --- vite.config.ts | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/vite.config.ts b/vite.config.ts index 8db2538f..8268b14b 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -8,18 +8,11 @@ import babel from 'vite-plugin-babel'; //依赖排除 const external = ['silk-wasm', 'ws', 'express', 'fluent-ffmpeg', 'log4js', 'qrcode-terminal']; const nodeModules = [...builtinModules, builtinModules.map(m => `node:${m}`)].flat(); -function genCpModule(module: string) { - return { src: `./node_modules/${module}`, dest: `dist/node_modules/${module}`, flatten: false }; -} -let startScripts: string[] | undefined = undefined; +let startScripts: string[] | undefined; if (process.env.NAPCAT_BUILDSYS == 'linux') { - if (process.env.NAPCAT_BUILDARCH == 'x64') { - } startScripts = ['./script/napcat.sh']; } else if (process.env.NAPCAT_BUILDSYS == 'win32') { - if (process.env.NAPCAT_BUILDARCH == 'x64') { - } startScripts = ['./script/BootWay05.ps1', './script/dbghelp.dll', './script/BootWay05_init.bat', './script/BootWay05_run.bat', './script/BootWay05_run.utf8.bat', './script/KillQQ.bat']; } else { @@ -108,7 +101,7 @@ const ShellBaseConfig = () => defineConfig({ lib: { entry: 'src/shell/napcat.ts', formats: ['es'], - fileName: () => 'napcat.mjs', + fileName: 'napcat.mjs', }, rollupOptions: { external: [...nodeModules, ...external], @@ -132,7 +125,7 @@ const FrameworkBaseConfig = () => defineConfig({ lib: { entry: 'src/framework/napcat.ts', formats: ['es'], - fileName: () => 'napcat.mjs', + fileName: 'napcat.mjs', }, rollupOptions: { external: [...nodeModules, ...external], From d76a1305e7c8a129ed2d38fa89967fda01163569 Mon Sep 17 00:00:00 2001 From: "Wesley F. Young" Date: Wed, 4 Sep 2024 10:06:09 +0800 Subject: [PATCH 09/23] chore: optimize import --- src/onebot/action/OB11Response.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/onebot/action/OB11Response.ts b/src/onebot/action/OB11Response.ts index 2f7f4deb..3fecfbb4 100644 --- a/src/onebot/action/OB11Response.ts +++ b/src/onebot/action/OB11Response.ts @@ -1,6 +1,6 @@ import { OB11Return } from '../types'; -import { isNull } from '../../common/helper'; +import { isNull } from '@/common/helper'; export class OB11Response { static res(data: T, status: string, retcode: number, message: string = ''): OB11Return { From 4a11ebc9b91a5fa72275cd60a870e45cbc3c0cca Mon Sep 17 00:00:00 2001 From: "Wesley F. Young" Date: Wed, 4 Sep 2024 10:38:10 +0800 Subject: [PATCH 10/23] Revert "chore: optimize vite.config.ts" This reverts commit 6a0d5924916e5798fc74ab347a01719506adb8d8. --- vite.config.ts | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/vite.config.ts b/vite.config.ts index 8268b14b..8db2538f 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -8,11 +8,18 @@ import babel from 'vite-plugin-babel'; //依赖排除 const external = ['silk-wasm', 'ws', 'express', 'fluent-ffmpeg', 'log4js', 'qrcode-terminal']; const nodeModules = [...builtinModules, builtinModules.map(m => `node:${m}`)].flat(); +function genCpModule(module: string) { + return { src: `./node_modules/${module}`, dest: `dist/node_modules/${module}`, flatten: false }; +} -let startScripts: string[] | undefined; +let startScripts: string[] | undefined = undefined; if (process.env.NAPCAT_BUILDSYS == 'linux') { + if (process.env.NAPCAT_BUILDARCH == 'x64') { + } startScripts = ['./script/napcat.sh']; } else if (process.env.NAPCAT_BUILDSYS == 'win32') { + if (process.env.NAPCAT_BUILDARCH == 'x64') { + } startScripts = ['./script/BootWay05.ps1', './script/dbghelp.dll', './script/BootWay05_init.bat', './script/BootWay05_run.bat', './script/BootWay05_run.utf8.bat', './script/KillQQ.bat']; } else { @@ -101,7 +108,7 @@ const ShellBaseConfig = () => defineConfig({ lib: { entry: 'src/shell/napcat.ts', formats: ['es'], - fileName: 'napcat.mjs', + fileName: () => 'napcat.mjs', }, rollupOptions: { external: [...nodeModules, ...external], @@ -125,7 +132,7 @@ const FrameworkBaseConfig = () => defineConfig({ lib: { entry: 'src/framework/napcat.ts', formats: ['es'], - fileName: 'napcat.mjs', + fileName: () => 'napcat.mjs', }, rollupOptions: { external: [...nodeModules, ...external], From 43f7f9a3631dcf791dc65c7b3306a50b8a227456 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=89=8B=E7=93=9C=E4=B8=80=E5=8D=81=E9=9B=AA?= Date: Wed, 4 Sep 2024 12:37:23 +0800 Subject: [PATCH 11/23] build: test --- src/core/apis/user.ts | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/core/apis/user.ts b/src/core/apis/user.ts index 87a0cee1..7c7897cb 100644 --- a/src/core/apis/user.ts +++ b/src/core/apis/user.ts @@ -75,7 +75,6 @@ export class NTQQUserApi { (profile) => profile.uid === uid, ); const RetUser: User = { - ...profile.simpleInfo.coreInfo, ...profile.simpleInfo.status, ...profile.simpleInfo.vasInfo, ...profile.commonExt, @@ -83,17 +82,22 @@ export class NTQQUserApi { qqLevel: profile.commonExt?.qqLevel, age: profile.simpleInfo.baseInfo.age, pendantId: '', + ...profile.simpleInfo.coreInfo }; return RetUser; } async getUserDetailInfo(uid: string): Promise { - const retUser = await solveAsyncProblem(async (uid) => this.fetchUserDetailInfo(uid, UserDetailSource.KDB), uid); + let retUser = await solveAsyncProblem(async (uid) => this.fetchUserDetailInfo(uid, UserDetailSource.KDB), uid); if (retUser && retUser.uin !== '0') { return retUser; } this.context.logger.logDebug('[NapCat] [Mark] getUserDetailInfo Mode1 Failed.'); - return this.fetchUserDetailInfo(uid, UserDetailSource.KSERVER); + retUser = await this.fetchUserDetailInfo(uid, UserDetailSource.KSERVER); + if (retUser && retUser.uin === '0') { + retUser.uin = await this.core.apis.UserApi.getUidByUinV2(uid) ?? '0'; + } + return retUser; } async modifySelfProfile(param: ModifyProfileParams) { From 994ec5ac0f92c87a3f2174528587a2c1b4d54919 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=89=8B=E7=93=9C=E4=B8=80=E5=8D=81=E9=9B=AA?= Date: Wed, 4 Sep 2024 12:40:59 +0800 Subject: [PATCH 12/23] =?UTF-8?q?fix:=20=E6=9E=81=E7=AB=AF=E6=83=85?= =?UTF-8?q?=E5=86=B5=E4=B8=8Buin=E6=9A=B4=E6=AF=99=E7=9A=84=E6=83=85?= =?UTF-8?q?=E5=86=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- manifest.json | 2 +- package.json | 2 +- src/common/version.ts | 2 +- src/webui/ui/NapCat.ts | 2 +- static/assets/renderer.js | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/manifest.json b/manifest.json index 82641257..2b6a5f42 100644 --- a/manifest.json +++ b/manifest.json @@ -4,7 +4,7 @@ "name": "NapCatQQ", "slug": "NapCat.Framework", "description": "高性能的 OneBot 11 协议实现", - "version": "2.2.44", + "version": "2.2.45", "icon": "./logo.png", "authors": [ { diff --git a/package.json b/package.json index 9b648b74..b2201bf7 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "napcat", "private": true, "type": "module", - "version": "2.2.44", + "version": "2.2.45", "scripts": { "build:framework": "vite build --mode framework", "build:shell": "vite build --mode shell", diff --git a/src/common/version.ts b/src/common/version.ts index fa823d83..30549da0 100644 --- a/src/common/version.ts +++ b/src/common/version.ts @@ -1 +1 @@ -export const napCatVersion = '2.2.44'; +export const napCatVersion = '2.2.45'; diff --git a/src/webui/ui/NapCat.ts b/src/webui/ui/NapCat.ts index d7fb407a..ecdcdb4e 100644 --- a/src/webui/ui/NapCat.ts +++ b/src/webui/ui/NapCat.ts @@ -30,7 +30,7 @@ async function onSettingWindowCreated(view: Element) { SettingItem( 'Napcat', undefined, - SettingButton('V2.2.44', 'napcat-update-button', 'secondary'), + SettingButton('V2.2.45', 'napcat-update-button', 'secondary'), ), ]), SettingList([ diff --git a/static/assets/renderer.js b/static/assets/renderer.js index ef5bbdc9..d68408c6 100644 --- a/static/assets/renderer.js +++ b/static/assets/renderer.js @@ -164,7 +164,7 @@ async function onSettingWindowCreated(view) { SettingItem( 'Napcat', void 0, - SettingButton("V2.2.44", "napcat-update-button", "secondary") + SettingButton("V2.2.45", "napcat-update-button", "secondary") ) ]), SettingList([ From 8ff469974c81522de1aad9b2c3261bfac2b32d01 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=89=8B=E7=93=9C=E4=B8=80=E5=8D=81=E9=9B=AA?= Date: Wed, 4 Sep 2024 13:19:02 +0800 Subject: [PATCH 13/23] build: test2 --- src/core/apis/webapi.ts | 49 ++++++++++++++++--- .../action/go-cqhttp/SendGroupNotice.ts | 30 ++++++++++-- 2 files changed, 66 insertions(+), 13 deletions(-) diff --git a/src/core/apis/webapi.ts b/src/core/apis/webapi.ts index f7af0c91..9a0695ec 100644 --- a/src/core/apis/webapi.ts +++ b/src/core/apis/webapi.ts @@ -131,20 +131,53 @@ export class NTQQWebApi { // return await res.json(); // } - async setGroupNotice(GroupCode: string, Content: string) { + async setGroupNotice( + GroupCode: string, + Content: string, + pinned: number = 0, + type: number = 1, + is_show_edit_card: number = 1, + tip_window_type: number = 1, + confirm_required: number = 1, + picId: string = '', + imgWidth: number = 540, + imgHeight: number = 300, + ) { + interface SetNoticeRetSuccess { + ec: number; + em: string; + id: number; + ltsm: number; + new_fid: string; + read_only: number; + role: number; + srv_code: number; + } + const cookieObject = await this.core.apis.UserApi.getCookies('qun.qq.com'); - let ret: any = undefined; + try { - ret = await RequestUtil.HttpGetJson( - `https://web.qun.qq.com/cgi-bin/announce/add_qun_notice${new URLSearchParams({ + let settings = JSON.stringify({ + is_show_edit_card: is_show_edit_card, + tip_window_type: tip_window_type, + confirm_required: confirm_required + }); + const externalParam = { + pic: picId, + imgWidth: imgWidth.toString(), + imgHeight: imgHeight.toString(), + }; + let ret: SetNoticeRetSuccess = await RequestUtil.HttpGetJson( + `https://web.qun.qq.com/cgi-bin/announce/add_qun_notice?${new URLSearchParams({ bkn: this.getBknFromCookie(cookieObject), qid: GroupCode, text: Content, - pinned: '0', - type: '1', - settings: '{"is_show_edit_card":1,"tip_window_type":1,"confirm_required":1}', + pinned: pinned.toString(), + type: type.toString(), + settings: settings, + ...(picId === '' ? {} : externalParam) }).toString()}`, - 'GET', + 'POST', '', { 'Cookie': this.cookieToString(cookieObject) } ); diff --git a/src/onebot/action/go-cqhttp/SendGroupNotice.ts b/src/onebot/action/go-cqhttp/SendGroupNotice.ts index 63429fd6..74833007 100644 --- a/src/onebot/action/go-cqhttp/SendGroupNotice.ts +++ b/src/onebot/action/go-cqhttp/SendGroupNotice.ts @@ -11,7 +11,10 @@ const SchemaData = { content: { type: 'string' }, image: { type: 'string' }, pinned: { type: ['number', 'string'] }, + type: { type: ['number', 'string'] }, confirm_required: { type: ['number', 'string'] }, + is_show_edit_card: { type: ['number', 'string'] }, + tip_window_type: { type: ['number', 'string'] }, }, required: ['group_id', 'content'], } as const satisfies JSONSchema; @@ -22,6 +25,7 @@ export class SendGroupNotice extends BaseAction { actionName = ActionName.GoCQHTTP_SendGroupNotice; async _handle(payload: Payload) { + let UploadImage: { id: string, width: number, height: number } | undefined = undefined; if (payload.image) { //公告图逻辑 @@ -47,12 +51,28 @@ export class SendGroupNotice extends BaseAction { } UploadImage = ImageUploadResult.picInfo; } - const noticePinned = +(payload.pinned ?? 0); - const noticeConfirmRequired = +(payload.confirm_required ?? 0); - const publishGroupBulletinResult = await this.core.apis.GroupApi.publishGroupBulletin(payload.group_id.toString(), payload.content, UploadImage, noticePinned, noticeConfirmRequired); - if (publishGroupBulletinResult.result != 0) { - throw `设置群公告失败,错误信息:${publishGroupBulletinResult.errMsg}`; + const noticeType = +(payload.type ?? 1); + const noticePinned = +(payload.pinned ?? 0); + + const noticeShowEditCard = +(payload.is_show_edit_card ?? 0); + const noticeTipWindowType = +(payload.tip_window_type ?? 0); + const noticeConfirmRequired = +(payload.confirm_required ?? 1); + //const publishGroupBulletinResult = await this.core.apis.GroupApi.publishGroupBulletin(payload.group_id.toString(), payload.content, UploadImage, noticePinned, noticeConfirmRequired); + const publishGroupBulletinResult = await this.core.apis.WebApi.setGroupNotice( + payload.group_id.toString(), + payload.content, + noticePinned, + noticeType, + noticeShowEditCard, + noticeTipWindowType, + noticeConfirmRequired, + UploadImage?.id, + UploadImage?.width, + UploadImage?.height + ); + if (!publishGroupBulletinResult || publishGroupBulletinResult.ec != 0) { + throw `设置群公告失败,错误信息:${publishGroupBulletinResult?.em}`; } return null; } From 453feb847383870c632624a442bc45d48c2bfd90 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=89=8B=E7=93=9C=E4=B8=80=E5=8D=81=E9=9B=AA?= Date: Wed, 4 Sep 2024 13:21:40 +0800 Subject: [PATCH 14/23] release: 2.2.46 --- manifest.json | 2 +- package.json | 2 +- src/common/version.ts | 2 +- src/webui/ui/NapCat.ts | 2 +- static/assets/renderer.js | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/manifest.json b/manifest.json index 2b6a5f42..01315720 100644 --- a/manifest.json +++ b/manifest.json @@ -4,7 +4,7 @@ "name": "NapCatQQ", "slug": "NapCat.Framework", "description": "高性能的 OneBot 11 协议实现", - "version": "2.2.45", + "version": "2.2.46", "icon": "./logo.png", "authors": [ { diff --git a/package.json b/package.json index b2201bf7..4a34f75e 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "napcat", "private": true, "type": "module", - "version": "2.2.45", + "version": "2.2.46", "scripts": { "build:framework": "vite build --mode framework", "build:shell": "vite build --mode shell", diff --git a/src/common/version.ts b/src/common/version.ts index 30549da0..073fb870 100644 --- a/src/common/version.ts +++ b/src/common/version.ts @@ -1 +1 @@ -export const napCatVersion = '2.2.45'; +export const napCatVersion = '2.2.46'; diff --git a/src/webui/ui/NapCat.ts b/src/webui/ui/NapCat.ts index ecdcdb4e..e5ab2d16 100644 --- a/src/webui/ui/NapCat.ts +++ b/src/webui/ui/NapCat.ts @@ -30,7 +30,7 @@ async function onSettingWindowCreated(view: Element) { SettingItem( 'Napcat', undefined, - SettingButton('V2.2.45', 'napcat-update-button', 'secondary'), + SettingButton('V2.2.46', 'napcat-update-button', 'secondary'), ), ]), SettingList([ diff --git a/static/assets/renderer.js b/static/assets/renderer.js index d68408c6..ad823661 100644 --- a/static/assets/renderer.js +++ b/static/assets/renderer.js @@ -164,7 +164,7 @@ async function onSettingWindowCreated(view) { SettingItem( 'Napcat', void 0, - SettingButton("V2.2.45", "napcat-update-button", "secondary") + SettingButton("V2.2.46", "napcat-update-button", "secondary") ) ]), SettingList([ From 87332778e506c65bae8eb9119984eb9b064a9ed0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=89=8B=E7=93=9C=E4=B8=80=E5=8D=81=E9=9B=AA?= Date: Wed, 4 Sep 2024 13:26:38 +0800 Subject: [PATCH 15/23] docs: fix --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 3c5e5e0e..334d5e10 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ NapCatQQ (aka 猫猫框架) 是现代化的基于 NTQQ 的 Bot 协议端实现 ## 猫猫技能 - [x] **高性能**:1K+ 群聊数目、20 线程并行发送消息毫无压力 - [x] **多种启动方式**:支持以无头、LiteLoader 插件、仅 QQ GUI 三种方式启动 -- [x] **多平台支持**: 支持Windows/Linux(可选Docker)/Android Termux覆盖全面 +- [x] **多平台支持**: 支持Windows/Linux(可选Docker)/Android Termux/MacOs覆盖全全平台 - [x] **安装简单**: 支持一键脚本/程序自动部署/镜像部署等多种覆盖范围 - [x] **低占用**:无头模式占用资源极低,适合在服务器上运行 - [x] **超多接口**:实现大部分 OneBot 和 go-cqhttp 接口,超多扩展 API From ba12bc6c91140fc4cb94c3ec584ac8480a5433b6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=89=8B=E7=93=9C=E4=B8=80=E5=8D=81=E9=9B=AA?= Date: Wed, 4 Sep 2024 14:03:55 +0800 Subject: [PATCH 16/23] docs: fix --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 334d5e10..2a3cdc85 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ NapCatQQ (aka 猫猫框架) 是现代化的基于 NTQQ 的 Bot 协议端实现 ## 猫猫技能 - [x] **高性能**:1K+ 群聊数目、20 线程并行发送消息毫无压力 - [x] **多种启动方式**:支持以无头、LiteLoader 插件、仅 QQ GUI 三种方式启动 -- [x] **多平台支持**: 支持Windows/Linux(可选Docker)/Android Termux/MacOs覆盖全全平台 +- [x] **多平台支持**: 支持Windows/Linux(可选Docker)/Android Termux/MacOs覆盖全平台 - [x] **安装简单**: 支持一键脚本/程序自动部署/镜像部署等多种覆盖范围 - [x] **低占用**:无头模式占用资源极低,适合在服务器上运行 - [x] **超多接口**:实现大部分 OneBot 和 go-cqhttp 接口,超多扩展 API From d36a28fa813f42da65fee04188d58b7178a27d3b Mon Sep 17 00:00:00 2001 From: Seijo Cecilia Date: Wed, 4 Sep 2024 15:47:06 +0800 Subject: [PATCH 17/23] update: normalize log --- src/common/audio.ts | 19 ++++++++--------- src/common/config-base.ts | 8 +++---- src/common/qq-basic-info.ts | 28 ++++++++++++------------- src/common/video.ts | 9 ++++---- src/core/apis/file.ts | 2 +- src/core/helper/rkey.ts | 2 +- src/core/index.ts | 4 ++-- src/onebot/action/msg/SendMsg.ts | 8 +++---- src/onebot/api/msg.ts | 17 ++++++--------- src/onebot/index.ts | 8 +++---- src/onebot/network/active-http.ts | 6 +++--- src/onebot/network/active-websocket.ts | 20 +++++++++--------- src/onebot/network/passive-http.ts | 8 +++---- src/onebot/network/passive-websocket.ts | 16 +++++++------- src/shell/napcat.ts | 14 ++++++------- src/webui/index.ts | 9 ++++---- 16 files changed, 84 insertions(+), 94 deletions(-) diff --git a/src/common/audio.ts b/src/common/audio.ts index c37c3442..2de0fe30 100644 --- a/src/common/audio.ts +++ b/src/common/audio.ts @@ -12,7 +12,7 @@ export async function encodeSilk(filePath: string, TEMP_DIR: string, logger: Log let duration = pttFileInfo.size / 1024 / 3; // 3kb/s duration = Math.floor(duration); duration = Math.max(1, duration); - logger.log('通过文件大小估算语音的时长:', duration); + logger.logDebug('通过文件大小估算语音的时长:', duration); return duration; } @@ -20,7 +20,7 @@ export async function encodeSilk(filePath: string, TEMP_DIR: string, logger: Log const file = await fsPromise.readFile(filePath); const pttPath = path.join(TEMP_DIR, randomUUID()); if (!isSilk(file)) { - logger.log(`语音文件${filePath}需要转换成silk`); + logger.logDebug(`语音文件${filePath}需要转换成silk`); const _isWav = isWav(file); const pcmPath = pttPath + '.pcm'; let sampleRate = 0; @@ -30,7 +30,7 @@ export async function encodeSilk(filePath: string, TEMP_DIR: string, logger: Log const ffmpegPath = process.env.FFMPEG_PATH || 'ffmpeg'; const cp = spawn(ffmpegPath, ['-y', '-i', filePath, '-ar', '24000', '-ac', '1', '-f', 's16le', pcmPath]); cp.on('error', err => { - logger.log('FFmpeg处理转换出错: ', err.message); + logger.logError('ffmpeg 处理转换出错: ', err.message); return reject(err); }); cp.on('exit', (code, signal) => { @@ -38,12 +38,11 @@ export async function encodeSilk(filePath: string, TEMP_DIR: string, logger: Log if (code == null || EXIT_CODES.includes(code)) { sampleRate = 24000; const data = fs.readFileSync(pcmPath); - fs.unlink(pcmPath, (err) => { - }); + fs.unlinkSync(pcmPath); return resolve(data); } - logger.log(`FFmpeg exit: code=${code ?? 'unknown'} sig=${signal ?? 'unknown'}`); - reject(Error('FFmpeg处理转换失败')); + logger.logError(`ffmpeg 处理失败: code=${code ?? 'unknown'} sig=${signal ?? 'unknown'}`); + reject(Error(`ffmpeg 处理失败: code=${code ?? 'unknown'} sig=${signal ?? 'unknown'}`)); }); }); }; @@ -61,7 +60,7 @@ export async function encodeSilk(filePath: string, TEMP_DIR: string, logger: Log } const silk = await encode(input, sampleRate); fs.writeFileSync(pttPath, silk.data); - logger.log(`语音文件${filePath}转换成功!`, pttPath, '时长:', silk.duration); + logger.logDebug(`语音文件 ${filePath} 转换成功:`, pttPath, '时长:', silk.duration); return { converted: true, path: pttPath, @@ -69,11 +68,11 @@ export async function encodeSilk(filePath: string, TEMP_DIR: string, logger: Log }; } else { const silk = file; - let duration = 0; + let duration: number; try { duration = getDuration(silk) / 1000; } catch (e: any) { - logger.log('获取语音文件时长失败, 使用文件大小推测时长', filePath, e.stack); + logger.logWarn('获取语音文件时长失败, 使用文件大小推测时长', filePath, e.stack); duration = await guessDuration(filePath); } diff --git a/src/common/config-base.ts b/src/common/config-base.ts index 79e44c85..283c4c96 100644 --- a/src/common/config-base.ts +++ b/src/common/config-base.ts @@ -38,9 +38,9 @@ export abstract class ConfigBase { if (!fs.existsSync(configPath)) { try { fs.writeFileSync(configPath, fs.readFileSync(this.getConfigPath(undefined), 'utf-8')); - logger.log(`[Core] [Config] 配置文件创建成功!\n`); + logger.log(`配置文件 ${this.name} 创建成功\n`); } catch (e: any) { - logger.logError(`[Core] [Config] 创建配置文件时发生错误:`, e.message); + logger.logError(`创建配置文件 ${this.name} 时发生错误:`, e.message); } } try { @@ -49,9 +49,9 @@ export abstract class ConfigBase { return this.configData; } catch (e: any) { if (e instanceof SyntaxError) { - logger.logError(`[Core] [Config] 配置文件格式错误,请检查配置文件:`, e.message); + logger.logError(`配置文件 ${this.name} 格式错误, 请检查配置文件:`, e.message); } else { - logger.logError(`[Core] [Config] 读取配置文件时发生错误:`, e.message); + logger.logError(`读取配置文件 ${this.name} 时发生错误:`, e); } return {} as T; } diff --git a/src/common/qq-basic-info.ts b/src/common/qq-basic-info.ts index 555f1195..6fefd9e5 100644 --- a/src/common/qq-basic-info.ts +++ b/src/common/qq-basic-info.ts @@ -53,23 +53,23 @@ export class QQBasicInfoWrapper { //此方法不要直接使用 getQUAInternal() { switch (systemPlatform) { - case 'linux': - return `V1_LNX_${this.getFullQQVesion()}_${this.getQQBuildStr()}_GW_B`; - case 'darwin': - return `V1_MAC_${this.getFullQQVesion()}_${this.getQQBuildStr()}_GW_B`; - default: - return `V1_WIN_${this.getFullQQVesion()}_${this.getQQBuildStr()}_GW_B`; + case 'linux': + return `V1_LNX_${this.getFullQQVesion()}_${this.getQQBuildStr()}_GW_B`; + case 'darwin': + return `V1_MAC_${this.getFullQQVesion()}_${this.getQQBuildStr()}_GW_B`; + default: + return `V1_WIN_${this.getFullQQVesion()}_${this.getQQBuildStr()}_GW_B`; } } getAppidInternal() { switch (systemPlatform) { - case 'linux': - return '537243600'; - case 'darwin': - return '537243441'; - default: - return '537243538'; + case 'linux': + return '537243600'; + case 'darwin': + return '537243441'; + default: + return '537243538'; } } @@ -84,8 +84,8 @@ export class QQBasicInfoWrapper { } // else - this.context.logger.log(`[QQ版本兼容性检测] 获取Appid异常 请检测NapCat/QQNT是否正常`); - this.context.logger.log(`[QQ版本兼容性检测] ${fullVersion} 版本兼容性不佳,可能会导致一些功能无法正常使用`,); + this.context.logger.logWarn(`获取 AppID 异常, 使用备用 AppID. 请检测 NapCat/QQNT 是否正常`); + this.context.logger.logWarn(`${fullVersion} 版本兼容性不佳, 可能会导致一些功能无法正常使用`,); return { appid: this.getAppidInternal(), qua: this.getQUAInternal() }; } } diff --git a/src/common/video.ts b/src/common/video.ts index 559ef44c..3dd125a6 100644 --- a/src/common/video.ts +++ b/src/common/video.ts @@ -24,9 +24,9 @@ export async function getVideoInfo(filePath: string, logger: LogWrapper) { } else { const videoStream = metadata.streams.find((s: FfprobeStream) => s.codec_type === 'video'); if (videoStream) { - logger.log(`视频尺寸: ${videoStream.width}x${videoStream.height}`); + logger.logDebug(`视频尺寸: ${videoStream.width}x${videoStream.height}`); } else { - return reject(new Error('未找到视频流信息。')); + return reject(new Error('未找到视频流信息.')); } resolve({ width: videoStream.width!, height: videoStream.height!, @@ -42,17 +42,16 @@ export async function getVideoInfo(filePath: string, logger: LogWrapper) { export function checkFfmpeg(logger: LogWrapper, newPath: string | null = null): Promise { return new Promise((resolve) => { - logger.log('开始检查ffmpeg', newPath); + logger.logDebug('开始检查 ffmpeg', newPath); if (newPath) { ffmpeg.setFfmpegPath(newPath); } try { ffmpeg.getAvailableFormats((err: any) => { if (err) { - logger.log('ffmpeg is not installed or not found in PATH:', err); + logger.logWarn('未找到 ffmpeg', err); resolve(false); } else { - logger.log('ffmpeg is installed.'); resolve(true); } }); diff --git a/src/core/apis/file.ts b/src/core/apis/file.ts index 55fce983..df88b8d3 100644 --- a/src/core/apis/file.ts +++ b/src/core/apis/file.ts @@ -148,7 +148,7 @@ export class NTQQFileApi { try { videoInfo = await getVideoInfo(path, logger); } catch (e) { - logger.logError('获取视频信息失败,将使用默认值', e); + logger.logWarn('获取视频信息失败,将使用默认值', e); } const thumbPath = new Map(); const _thumbPath = await new Promise((resolve, reject) => { diff --git a/src/core/helper/rkey.ts b/src/core/helper/rkey.ts index dd7b5059..f8be4e51 100644 --- a/src/core/helper/rkey.ts +++ b/src/core/helper/rkey.ts @@ -26,7 +26,7 @@ export class RkeyManager { try { await this.refreshRkey(); } catch (e) { - this.logger.logError('获取rkey失败', e); + this.logger.logError('获取 rkey 失败', e); } } return this.rkeyData; diff --git a/src/core/index.ts b/src/core/index.ts index c6e9f0ea..bbf4e73e 100644 --- a/src/core/index.ts +++ b/src/core/index.ts @@ -119,9 +119,9 @@ export class NapCatCore { // Renamed from 'InitDataListener' async initNapCatCoreListeners() { const msgListener = new NodeIKernelMsgListener(); - msgListener.onKickedOffLine = (Info: KickedOffLineInfo) => { + msgListener.onKickedOffLine = (info: KickedOffLineInfo) => { // 下线通知 - this.context.logger.logError('[KickedOffLine] [' + Info.tipsTitle + '] ' + Info.tipsDesc); + this.context.logger.logError(`当前账户被强制下线: ${info.tipsTitle} ${info.tipsDesc}`); this.selfInfo.online = false; }; msgListener.onRecvMsg = (msgs) => { diff --git a/src/onebot/action/msg/SendMsg.ts b/src/onebot/action/msg/SendMsg.ts index c3c80509..44eda85c 100644 --- a/src/onebot/action/msg/SendMsg.ts +++ b/src/onebot/action/msg/SendMsg.ts @@ -148,7 +148,7 @@ export class SendMsg extends BaseAction { //对Mgsid和OB11ID混用情况兜底 const nodeMsg = MessageUnique.getMsgIdAndPeerByShortId(parseInt(nodeId)) || MessageUnique.getPeerByMsgId(nodeId); if (!nodeMsg) { - logger.logError('转发消息失败,未找到消息', nodeId); + logger.logError(`转发消息失败, 未找到消息 ${nodeId}`); continue; } nodeMsgIds.push(nodeMsg.MsgId); @@ -160,7 +160,7 @@ export class SendMsg extends BaseAction { const isNodeMsg = OB11Data.filter(e => e.type === OB11MessageDataType.node).length;//找到子转发消息 if (isNodeMsg !== 0) { if (isNodeMsg !== OB11Data.length) { - logger.logError('子消息中包含非node消息 跳过不合法部分'); + logger.logWarn('子消息中包含非 node 消息, 跳过不合法部分'); continue; } const nodeMsg = await this.handleForwardedNodes(selfPeer, OB11Data.filter(e => e.type === OB11MessageDataType.node)); @@ -256,12 +256,12 @@ export class SendMsg extends BaseAction { } if (sendElements.length === 0) { - logger.logDebug('需要clone的消息无法解析,将会忽略掉', msg); + logger.logWarn('需要 clone 的消息无法解析, 忽略: ', msg); } try { return await this.core.apis.MsgApi.sendMsg(selfPeer, sendElements, true); } catch (e) { - logger.logError(e, '克隆转发消息失败,将忽略本条消息', msg); + logger.logError('克隆转发消息失败, 将忽略本条消息', e, msg); } } } diff --git a/src/onebot/api/msg.ts b/src/onebot/api/msg.ts index 85689dba..63f53878 100644 --- a/src/onebot/api/msg.ts +++ b/src/onebot/api/msg.ts @@ -234,7 +234,7 @@ export class OneBotMsgApi { if (records.peerUin === '284840486') { return createReplyData(records.msgId); } - let replyMsg = (await this.core.apis.MsgApi.queryMsgsWithFilterExWithSeqV2(peer, element.replayMsgSeq, element.replyMsgTime, [element.senderUidStr])) + const replyMsg = (await this.core.apis.MsgApi.queryMsgsWithFilterExWithSeqV2(peer, element.replayMsgSeq, element.replyMsgTime, [element.senderUidStr])) .msgList.find(msg => msg.msgRandom === records.msgRandom); if (!replyMsg || records.msgRandom !== replyMsg.msgRandom) { @@ -591,25 +591,20 @@ export class OneBotMsgApi { // 保留, 直到...找到更好的解决方案 if (data.type === 'custom') { if (!data.url) { - this.core.context.logger.logError('自定义音卡缺少参数url'); - return undefined; + throw '自定义音乐卡片缺少参数 url'; } if (!data.audio) { - this.core.context.logger.logError('自定义音卡缺少参数audio'); - return undefined; + throw '自定义音乐卡片缺少参数 audio'; } if (!data.title) { - this.core.context.logger.logError('自定义音卡缺少参数title'); - return undefined; + throw '自定义音乐卡片缺少参数 title'; } } else { if (!['qq', '163'].includes(data.type)) { - this.core.context.logger.logError('音乐卡片type错误, 只支持qq、163、custom,当前type:', data.type); - return undefined; + throw `不支持的 type: ${data.type}`; } if (!data.id) { - this.core.context.logger.logError('音乐卡片缺少参数id'); - return undefined; + throw '音乐卡片缺少参数 id'; } } diff --git a/src/onebot/index.ts b/src/onebot/index.ts index 4d9ec98c..6dd5961a 100644 --- a/src/onebot/index.ts +++ b/src/onebot/index.ts @@ -87,7 +87,7 @@ export class NapCatOneBot11Adapter { selfInfo.nick = user.nick; this.context.logger.setLogSelfInfo(selfInfo); }).catch(this.context.logger.logError); - this.context.logger.log(`[Notice] [OneBot11] ${serviceInfo}`); + this.context.logger.log(`OneBot 服务状态: ${serviceInfo}`); //创建NetWork服务 if (ob11Config.http.enable) { @@ -128,7 +128,7 @@ export class NapCatOneBot11Adapter { await WebUiDataRuntime.setOnOB11ConfigChanged(async (newConfig: OB11Config) => { const prev = this.configLoader.configData; this.configLoader.save(newConfig); - this.context.logger.log(`OneBot11 配置更改:${JSON.stringify(prev)} -> ${JSON.stringify(newConfig)}`); + this.context.logger.logDebug(`OneBot11 配置更改: ${JSON.stringify(prev)} -> ${JSON.stringify(newConfig)}`); await this.reloadNetwork(prev, newConfig); }); } @@ -150,7 +150,7 @@ export class NapCatOneBot11Adapter { HTTP上报服务 ${now.http.enablePost ? '已启动' : '未启动'}, 上报地址: ${now.http.postUrls} WebSocket服务 ${now.ws.enable ? '已启动' : '未启动'}, ${now.ws.host}:${now.ws.port} WebSocket反向服务 ${now.reverseWs.enable ? '已启动' : '未启动'}, 反向地址: ${now.reverseWs.urls}`; - this.context.logger.log(`[Notice] [OneBot11] 热重载 ${serviceInfo}`); + this.context.logger.log(`热重载 - OneBot 服务状态: ${serviceInfo}`); // check difference in passive http (Http) if (prev.http.enable !== now.http.enable) { @@ -270,7 +270,7 @@ export class NapCatOneBot11Adapter { msgListener.onInputStatusPush = async data => { const uin = await this.core.apis.UserApi.getUinByUidV2(data.fromUin); - this.context.logger.log(`[Notice] [输入状态] ${uin} ${data.statusText}`); + this.context.logger.log(`${uin} 输入状态更新: ${data.statusText}`); await this.networkManager.emitEvent(new OB11InputStatusEvent( this.core, parseInt(uin), diff --git a/src/onebot/network/active-http.ts b/src/onebot/network/active-http.ts index 9992f6bf..0fee3d18 100644 --- a/src/onebot/network/active-http.ts +++ b/src/onebot/network/active-http.ts @@ -43,7 +43,7 @@ export class OB11ActiveHttpAdapter implements IOB11NetworkAdapter { resJson = await res.json(); //logDebug('新消息事件HTTP上报返回快速操作: ', JSON.stringify(resJson)); } catch (e) { - this.logger.logDebug('[OneBot] [Http Client] 新消息事件HTTP上报没有返回快速操作,不需要处理'); + this.logger.logDebug('新消息事件 HTTP 上报没有返回快速操作,不需要处理'); return; } try { @@ -51,10 +51,10 @@ export class OB11ActiveHttpAdapter implements IOB11NetworkAdapter { .handleQuickOperation(event as QuickActionEvent, resJson) .catch(this.logger.logError); } catch (e: any) { - this.logger.logError('[OneBot] [Http Client] 新消息事件HTTP上报返回快速操作失败', e); + this.logger.logError('新消息事件 HTTP 上报返回快速操作失败', e); } }).catch((e) => { - this.logger.logError('[OneBot] [Http Client] 新消息事件HTTP上报失败', e); + this.logger.logError('新消息事件 HTTP 上报失败', e); }); } diff --git a/src/onebot/network/active-websocket.ts b/src/onebot/network/active-websocket.ts index cf7ec602..c96b12a0 100644 --- a/src/onebot/network/active-websocket.ts +++ b/src/onebot/network/active-websocket.ts @@ -85,13 +85,13 @@ export class OB11ActiveWebSocketAdapter implements IOB11NetworkAdapter { this.connection?.pong(); }); this.connection.on('pong', () => { - //this.logger.logDebug('[OneBot] [WebSocket Client] 收到pong'); + //this.logger.logDebug('收到pong'); }); this.connection.on('open', () => { try { this.connectEvent(this.core); } catch (e) { - this.logger.logError('[OneBot] [WebSocket Client] 发送连接生命周期失败', e); + this.logger.logError('发送连接生命周期失败', e); } }); @@ -100,8 +100,8 @@ export class OB11ActiveWebSocketAdapter implements IOB11NetworkAdapter { }); this.connection.once('close', () => { if (!isClosedByError) { - this.logger.logError(`[OneBot] [WebSocket Client] 反向WebSocket (${this.url}) 连接意外关闭`); - this.logger.logError(`[OneBot] [WebSocket Client] 在 ${Math.floor(this.reconnectIntervalInMillis / 1000)} 秒后尝试重新连接`); + this.logger.logError(`反向WebSocket (${this.url}) 连接意外关闭`); + this.logger.logError(`在 ${Math.floor(this.reconnectIntervalInMillis / 1000)} 秒后尝试重新连接`); if (!this.isClosed) { this.connection = null; setTimeout(() => this.tryConnect(), this.reconnectIntervalInMillis); @@ -110,8 +110,8 @@ export class OB11ActiveWebSocketAdapter implements IOB11NetworkAdapter { }); this.connection.on('error', (err) => { isClosedByError = true; - this.logger.logError(`[OneBot] [WebSocket Client] 反向WebSocket (${this.url}) 连接错误`, err); - this.logger.logError(`[OneBot] [WebSocket Client] 在 ${Math.floor(this.reconnectIntervalInMillis / 1000)} 秒后尝试重新连接`); + this.logger.logError(`反向WebSocket (${this.url}) 连接错误`, err); + this.logger.logError(`在 ${Math.floor(this.reconnectIntervalInMillis / 1000)} 秒后尝试重新连接`); if (!this.isClosed) { this.connection = null; setTimeout(() => this.tryConnect(), this.reconnectIntervalInMillis); @@ -124,7 +124,7 @@ export class OB11ActiveWebSocketAdapter implements IOB11NetworkAdapter { try { this.checkStateAndReply(new OB11LifeCycleEvent(core, LifeCycleSubType.CONNECT)); } catch (e) { - this.logger.logError('[OneBot] [WebSocket Client] 发送生命周期失败', e); + this.logger.logError('发送生命周期失败', e); } } @@ -135,7 +135,7 @@ export class OB11ActiveWebSocketAdapter implements IOB11NetworkAdapter { try { receiveData = JSON.parse(message.toString()); echo = receiveData.echo; - this.logger.logDebug('[OneBot] [WebSocket Client] 收到正向Websocket消息', receiveData); + this.logger.logDebug('收到正向Websocket消息', receiveData); } catch (e) { this.checkStateAndReply(OB11Response.error('json解析失败,请检查数据格式', 1400, echo)); return; @@ -143,8 +143,8 @@ export class OB11ActiveWebSocketAdapter implements IOB11NetworkAdapter { receiveData.params = (receiveData?.params) ? receiveData.params : {};//兼容类型验证 const action = this.actions.get(receiveData.action); if (!action) { - this.logger.logError('[OneBot] [WebSocket Client] 发生错误', '不支持的api ' + receiveData.action); - this.checkStateAndReply(OB11Response.error('不支持的api ' + receiveData.action, 1404, echo)); + this.logger.logError('不支持的 api' + receiveData.action); + this.checkStateAndReply(OB11Response.error('不支持的 api ' + receiveData.action, 1404, echo)); return; } const retdata = await action.websocketHandle(receiveData.params, echo ?? ''); diff --git a/src/onebot/network/passive-http.ts b/src/onebot/network/passive-http.ts index 0a7b8367..6726d1d3 100644 --- a/src/onebot/network/passive-http.ts +++ b/src/onebot/network/passive-http.ts @@ -26,7 +26,7 @@ export class OB11PassiveHttpAdapter implements IOB11NetworkAdapter { open() { try { if (this.isOpen) { - this.core.context.logger.logError('Cannot open a closed HTTP server'); + this.core.context.logger.logError('Http 服务已经启动'); return; } if (!this.isOpen) { @@ -34,7 +34,7 @@ export class OB11PassiveHttpAdapter implements IOB11NetworkAdapter { this.isOpen = true; } } catch (e) { - this.core.context.logger.logError(`[OneBot] [HTTP Server Adapter] Boot Error: ${e}`); + this.core.context.logger.logError('Http 服务启动失败', e); } } @@ -67,7 +67,7 @@ export class OB11PassiveHttpAdapter implements IOB11NetworkAdapter { this.app.use((req, res) => this.handleRequest(req, res)); this.server.listen(this.port, () => { - this.core.context.logger.log(`[OneBot] [HTTP Server Adapter] Start On Port ${this.port}`); + this.core.context.logger.logDebug(`OneBot 11 Http 服务在 ${this.port} 上启动`); }); } @@ -85,7 +85,7 @@ export class OB11PassiveHttpAdapter implements IOB11NetworkAdapter { private async handleRequest(req: Request, res: Response) { if (!this.isOpen) { - this.core.context.logger.log(`[OneBot] [HTTP Server Adapter] Server is closed`); + this.core.context.logger.log(`OneBot 11 Http 服务已关闭`); return res.json(OB11Response.error('Server is closed', 200)); } diff --git a/src/onebot/network/passive-websocket.ts b/src/onebot/network/passive-websocket.ts index 70b2f371..8f4e5e2d 100644 --- a/src/onebot/network/passive-websocket.ts +++ b/src/onebot/network/passive-websocket.ts @@ -47,7 +47,7 @@ export class OB11PassiveWebSocketAdapter implements IOB11NetworkAdapter { //鉴权 this.authorize(token, wsClient, wsReq); this.connectEvent(core, wsClient); - wsClient.on('error', (err) => this.logger.log('[OneBot] [WebSocket Server] Client Error:', err.message)); + wsClient.on('error', (err) => this.logger.logError('OneBot 11 WS 客户端连接异常中断', err.message)); wsClient.on('message', (message) => { this.handleMessage(wsClient, message).then().catch(this.logger.logError); }); @@ -68,14 +68,14 @@ export class OB11PassiveWebSocketAdapter implements IOB11NetworkAdapter { await this.wsClientsMutex.runExclusive(async () => { this.wsClients.push(wsClient); }); - }).on('error', (err) => this.logger.log('[OneBot] [WebSocket Server] Server Error:', err.message)); + }).on('error', (err) => this.logger.logError('OneBot 11 WS 服务端错误', err.message)); } connectEvent(core: NapCatCore, wsClient: WebSocket) { try { this.checkStateAndReply(new OB11LifeCycleEvent(core, LifeCycleSubType.CONNECT), wsClient); } catch (e) { - this.logger.logError('[OneBot] [WebSocket Server] 发送生命周期失败', e); + this.logger.logError('WS 服务发送生命周期失败', e); } } @@ -89,15 +89,13 @@ export class OB11PassiveWebSocketAdapter implements IOB11NetworkAdapter { open() { if (this.isOpen) { - this.logger.logError('[OneBot] [WebSocket Server] Cannot open a opened WebSocket server'); - return; + throw 'WS 服务已经打开, 不能再次打开'; } if (this.hasBeenClosed) { - this.logger.logError('[OneBot] [WebSocket Server] Cannot open a WebSocket server that has been closed'); - return; + throw 'WS 服务已经关闭, 不能再次打开'; } const addressInfo = this.wsServer.address(); - this.logger.log('[OneBot] [WebSocket Server] Server Started', typeof (addressInfo) === 'string' ? addressInfo : addressInfo?.address + ':' + addressInfo?.port); + this.logger.logDebug('WS 服务启动', typeof (addressInfo) === 'string' ? addressInfo : addressInfo?.address + ':' + addressInfo?.port); this.isOpen = true; this.registerHeartBeat(); @@ -156,7 +154,7 @@ export class OB11PassiveWebSocketAdapter implements IOB11NetworkAdapter { receiveData.params = (receiveData?.params) ? receiveData.params : {};//兼容类型验证 const action = this.actions.get(receiveData.action); if (!action) { - this.logger.logError('[OneBot] [WebSocket Client] 发生错误', '不支持的api ' + receiveData.action); + this.logger.logError(`不支持的 api ${receiveData.action}`); this.checkStateAndReply(OB11Response.error('不支持的api ' + receiveData.action, 1404, echo), wsClient); return; } diff --git a/src/shell/napcat.ts b/src/shell/napcat.ts index 4beeded5..27ccb080 100644 --- a/src/shell/napcat.ts +++ b/src/shell/napcat.ts @@ -39,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: ` + napCatVersion); + logger.log(`NapCatQQ 版本: ` + napCatVersion); InitWebUi(logger, pathWrapper).then().catch(logger.logError); // from constructor @@ -125,20 +125,20 @@ export async function NCoreInitShell() { logger.logWarn('请扫描下面的二维码,然后在手Q上授权登录:'); const qrcodePath = path.join(pathWrapper.cachePath, 'qrcode.png'); qrcode.generate(qrcodeUrl, { small: true }, (res) => { - logger.logWarn([ + logger.log([ '\n', res, '二维码解码URL: ' + qrcodeUrl, '如果控制台二维码无法扫码,可以复制解码url到二维码生成网站生成二维码再扫码,也可以打开下方的二维码路径图片进行扫码。', ].join('\n')); fs.writeFile(qrcodePath, buffer, {}, () => { - logger.logWarn('二维码已保存到', qrcodePath); + logger.log(`二维码已保存到 ${qrcodePath}`); }); }); }; loginListener.onQRCodeSessionFailed = (errType: number, errCode: number, errMsg: string) => { //logger.logError('登录失败(onQRCodeSessionFailed)', errCode, errMsg); - logger.logError('[Core] [Login] Login Error,ErrCode: ', errCode, ' ErrMsg:', errMsg); + logger.logError(`二维码登录失败(${errCode} - ${errType}): ${errMsg}`); if (errType == 1 && errCode == 3) { // 二维码过期刷新 } @@ -146,7 +146,7 @@ export async function NCoreInitShell() { }; loginListener.onLoginFailed = (args) => { //logger.logError('登录失败(onLoginFailed)', args); - logger.logError('[Core] [Login] Login Error , ErrInfo: ', args); + logger.logError('登录失败', args); }; loginService.addKernelLoginListener(proxiedListenerOf(loginListener, logger) as any); @@ -190,7 +190,7 @@ export async function NCoreInitShell() { .catch(); }, 1000); } else { - logger.logError('快速登录失败,未找到该 QQ 历史登录记录,将使用二维码登录方式'); + logger.logError('快速登录失败, 未找到该 QQ 历史登录记录, 将使用二维码登录方式.'); loginService.getQRCodePicture(); } } else { @@ -199,7 +199,7 @@ export async function NCoreInitShell() { logger.log(`可用于快速登录的 QQ:\n${historyLoginList .map((u, index) => `${index + 1}. ${u.uin} ${u.nickName}`) .join('\n') - }`); + }`); } loginService.getQRCodePicture(); } diff --git a/src/webui/index.ts b/src/webui/index.ts index c0e660a1..34fe54cf 100644 --- a/src/webui/index.ts +++ b/src/webui/index.ts @@ -18,10 +18,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; } app.use(express.json()); @@ -37,8 +36,8 @@ export async function InitWebUi(logger: LogWrapper, pathWrapper: NapCatPathWrapp //挂载API接口 app.use(config.prefix + '/api', ALLRouter); app.listen(config.port, config.host, async () => { - log(`[NapCat] [WebUi] Current WebUi is running at http://${config.host}:${config.port}${config.prefix}`); - log(`[NapCat] [WebUi] Login URL is http://${config.host}:${config.port}${config.prefix}/webui`); - log(`[NapCat] [WebUi] Login Token is ${config.token}`); + logger.log(`[NapCat] [WebUi] Current WebUi is running at http://${config.host}:${config.port}${config.prefix}`); + logger.log(`[NapCat] [WebUi] Login URL is http://${config.host}:${config.port}${config.prefix}/webui`); + logger.log(`[NapCat] [WebUi] Login Token is ${config.token}`); }); } From 074ac15d0ff9b6f4981717d552aa75d41c50c119 Mon Sep 17 00:00:00 2001 From: Seijo Cecilia Date: Wed, 4 Sep 2024 15:50:23 +0800 Subject: [PATCH 18/23] rollback `unlink` -> `unlinkSync` --- src/common/audio.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/common/audio.ts b/src/common/audio.ts index 2de0fe30..80cc599e 100644 --- a/src/common/audio.ts +++ b/src/common/audio.ts @@ -38,7 +38,7 @@ export async function encodeSilk(filePath: string, TEMP_DIR: string, logger: Log if (code == null || EXIT_CODES.includes(code)) { sampleRate = 24000; const data = fs.readFileSync(pcmPath); - fs.unlinkSync(pcmPath); + fs.unlink(pcmPath, () => {}); return resolve(data); } logger.logError(`ffmpeg 处理失败: code=${code ?? 'unknown'} sig=${signal ?? 'unknown'}`); From 043d8a18612707663243046aeb164236291cf249 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=89=8B=E7=93=9C=E4=B8=80=E5=8D=81=E9=9B=AA?= Date: Wed, 4 Sep 2024 18:04:58 +0800 Subject: [PATCH 19/23] Revert "rollback `unlink` -> `unlinkSync`" This reverts commit 074ac15d0ff9b6f4981717d552aa75d41c50c119. --- src/common/audio.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/common/audio.ts b/src/common/audio.ts index 80cc599e..2de0fe30 100644 --- a/src/common/audio.ts +++ b/src/common/audio.ts @@ -38,7 +38,7 @@ export async function encodeSilk(filePath: string, TEMP_DIR: string, logger: Log if (code == null || EXIT_CODES.includes(code)) { sampleRate = 24000; const data = fs.readFileSync(pcmPath); - fs.unlink(pcmPath, () => {}); + fs.unlinkSync(pcmPath); return resolve(data); } logger.logError(`ffmpeg 处理失败: code=${code ?? 'unknown'} sig=${signal ?? 'unknown'}`); From ab824fb21984d32d0922dbcd7c34d7f504a64387 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=89=8B=E7=93=9C=E4=B8=80=E5=8D=81=E9=9B=AA?= Date: Wed, 4 Sep 2024 18:05:01 +0800 Subject: [PATCH 20/23] Revert "update: normalize log" This reverts commit d36a28fa813f42da65fee04188d58b7178a27d3b. --- src/common/audio.ts | 19 +++++++++-------- src/common/config-base.ts | 8 +++---- src/common/qq-basic-info.ts | 28 ++++++++++++------------- src/common/video.ts | 9 ++++---- src/core/apis/file.ts | 2 +- src/core/helper/rkey.ts | 2 +- src/core/index.ts | 4 ++-- src/onebot/action/msg/SendMsg.ts | 8 +++---- src/onebot/api/msg.ts | 17 +++++++++------ src/onebot/index.ts | 8 +++---- src/onebot/network/active-http.ts | 6 +++--- src/onebot/network/active-websocket.ts | 20 +++++++++--------- src/onebot/network/passive-http.ts | 8 +++---- src/onebot/network/passive-websocket.ts | 16 +++++++------- src/shell/napcat.ts | 14 ++++++------- src/webui/index.ts | 9 ++++---- 16 files changed, 94 insertions(+), 84 deletions(-) diff --git a/src/common/audio.ts b/src/common/audio.ts index 2de0fe30..c37c3442 100644 --- a/src/common/audio.ts +++ b/src/common/audio.ts @@ -12,7 +12,7 @@ export async function encodeSilk(filePath: string, TEMP_DIR: string, logger: Log let duration = pttFileInfo.size / 1024 / 3; // 3kb/s duration = Math.floor(duration); duration = Math.max(1, duration); - logger.logDebug('通过文件大小估算语音的时长:', duration); + logger.log('通过文件大小估算语音的时长:', duration); return duration; } @@ -20,7 +20,7 @@ export async function encodeSilk(filePath: string, TEMP_DIR: string, logger: Log const file = await fsPromise.readFile(filePath); const pttPath = path.join(TEMP_DIR, randomUUID()); if (!isSilk(file)) { - logger.logDebug(`语音文件${filePath}需要转换成silk`); + logger.log(`语音文件${filePath}需要转换成silk`); const _isWav = isWav(file); const pcmPath = pttPath + '.pcm'; let sampleRate = 0; @@ -30,7 +30,7 @@ export async function encodeSilk(filePath: string, TEMP_DIR: string, logger: Log const ffmpegPath = process.env.FFMPEG_PATH || 'ffmpeg'; const cp = spawn(ffmpegPath, ['-y', '-i', filePath, '-ar', '24000', '-ac', '1', '-f', 's16le', pcmPath]); cp.on('error', err => { - logger.logError('ffmpeg 处理转换出错: ', err.message); + logger.log('FFmpeg处理转换出错: ', err.message); return reject(err); }); cp.on('exit', (code, signal) => { @@ -38,11 +38,12 @@ export async function encodeSilk(filePath: string, TEMP_DIR: string, logger: Log if (code == null || EXIT_CODES.includes(code)) { sampleRate = 24000; const data = fs.readFileSync(pcmPath); - fs.unlinkSync(pcmPath); + fs.unlink(pcmPath, (err) => { + }); return resolve(data); } - logger.logError(`ffmpeg 处理失败: code=${code ?? 'unknown'} sig=${signal ?? 'unknown'}`); - reject(Error(`ffmpeg 处理失败: code=${code ?? 'unknown'} sig=${signal ?? 'unknown'}`)); + logger.log(`FFmpeg exit: code=${code ?? 'unknown'} sig=${signal ?? 'unknown'}`); + reject(Error('FFmpeg处理转换失败')); }); }); }; @@ -60,7 +61,7 @@ export async function encodeSilk(filePath: string, TEMP_DIR: string, logger: Log } const silk = await encode(input, sampleRate); fs.writeFileSync(pttPath, silk.data); - logger.logDebug(`语音文件 ${filePath} 转换成功:`, pttPath, '时长:', silk.duration); + logger.log(`语音文件${filePath}转换成功!`, pttPath, '时长:', silk.duration); return { converted: true, path: pttPath, @@ -68,11 +69,11 @@ export async function encodeSilk(filePath: string, TEMP_DIR: string, logger: Log }; } else { const silk = file; - let duration: number; + let duration = 0; try { duration = getDuration(silk) / 1000; } catch (e: any) { - logger.logWarn('获取语音文件时长失败, 使用文件大小推测时长', filePath, e.stack); + logger.log('获取语音文件时长失败, 使用文件大小推测时长', filePath, e.stack); duration = await guessDuration(filePath); } diff --git a/src/common/config-base.ts b/src/common/config-base.ts index 283c4c96..79e44c85 100644 --- a/src/common/config-base.ts +++ b/src/common/config-base.ts @@ -38,9 +38,9 @@ export abstract class ConfigBase { if (!fs.existsSync(configPath)) { try { fs.writeFileSync(configPath, fs.readFileSync(this.getConfigPath(undefined), 'utf-8')); - logger.log(`配置文件 ${this.name} 创建成功\n`); + logger.log(`[Core] [Config] 配置文件创建成功!\n`); } catch (e: any) { - logger.logError(`创建配置文件 ${this.name} 时发生错误:`, e.message); + logger.logError(`[Core] [Config] 创建配置文件时发生错误:`, e.message); } } try { @@ -49,9 +49,9 @@ export abstract class ConfigBase { return this.configData; } catch (e: any) { if (e instanceof SyntaxError) { - logger.logError(`配置文件 ${this.name} 格式错误, 请检查配置文件:`, e.message); + logger.logError(`[Core] [Config] 配置文件格式错误,请检查配置文件:`, e.message); } else { - logger.logError(`读取配置文件 ${this.name} 时发生错误:`, e); + logger.logError(`[Core] [Config] 读取配置文件时发生错误:`, e.message); } return {} as T; } diff --git a/src/common/qq-basic-info.ts b/src/common/qq-basic-info.ts index 6fefd9e5..555f1195 100644 --- a/src/common/qq-basic-info.ts +++ b/src/common/qq-basic-info.ts @@ -53,23 +53,23 @@ export class QQBasicInfoWrapper { //此方法不要直接使用 getQUAInternal() { switch (systemPlatform) { - case 'linux': - return `V1_LNX_${this.getFullQQVesion()}_${this.getQQBuildStr()}_GW_B`; - case 'darwin': - return `V1_MAC_${this.getFullQQVesion()}_${this.getQQBuildStr()}_GW_B`; - default: - return `V1_WIN_${this.getFullQQVesion()}_${this.getQQBuildStr()}_GW_B`; + case 'linux': + return `V1_LNX_${this.getFullQQVesion()}_${this.getQQBuildStr()}_GW_B`; + case 'darwin': + return `V1_MAC_${this.getFullQQVesion()}_${this.getQQBuildStr()}_GW_B`; + default: + return `V1_WIN_${this.getFullQQVesion()}_${this.getQQBuildStr()}_GW_B`; } } getAppidInternal() { switch (systemPlatform) { - case 'linux': - return '537243600'; - case 'darwin': - return '537243441'; - default: - return '537243538'; + case 'linux': + return '537243600'; + case 'darwin': + return '537243441'; + default: + return '537243538'; } } @@ -84,8 +84,8 @@ export class QQBasicInfoWrapper { } // else - this.context.logger.logWarn(`获取 AppID 异常, 使用备用 AppID. 请检测 NapCat/QQNT 是否正常`); - this.context.logger.logWarn(`${fullVersion} 版本兼容性不佳, 可能会导致一些功能无法正常使用`,); + this.context.logger.log(`[QQ版本兼容性检测] 获取Appid异常 请检测NapCat/QQNT是否正常`); + this.context.logger.log(`[QQ版本兼容性检测] ${fullVersion} 版本兼容性不佳,可能会导致一些功能无法正常使用`,); return { appid: this.getAppidInternal(), qua: this.getQUAInternal() }; } } diff --git a/src/common/video.ts b/src/common/video.ts index 3dd125a6..559ef44c 100644 --- a/src/common/video.ts +++ b/src/common/video.ts @@ -24,9 +24,9 @@ export async function getVideoInfo(filePath: string, logger: LogWrapper) { } else { const videoStream = metadata.streams.find((s: FfprobeStream) => s.codec_type === 'video'); if (videoStream) { - logger.logDebug(`视频尺寸: ${videoStream.width}x${videoStream.height}`); + logger.log(`视频尺寸: ${videoStream.width}x${videoStream.height}`); } else { - return reject(new Error('未找到视频流信息.')); + return reject(new Error('未找到视频流信息。')); } resolve({ width: videoStream.width!, height: videoStream.height!, @@ -42,16 +42,17 @@ export async function getVideoInfo(filePath: string, logger: LogWrapper) { export function checkFfmpeg(logger: LogWrapper, newPath: string | null = null): Promise { return new Promise((resolve) => { - logger.logDebug('开始检查 ffmpeg', newPath); + logger.log('开始检查ffmpeg', newPath); if (newPath) { ffmpeg.setFfmpegPath(newPath); } try { ffmpeg.getAvailableFormats((err: any) => { if (err) { - logger.logWarn('未找到 ffmpeg', err); + logger.log('ffmpeg is not installed or not found in PATH:', err); resolve(false); } else { + logger.log('ffmpeg is installed.'); resolve(true); } }); diff --git a/src/core/apis/file.ts b/src/core/apis/file.ts index df88b8d3..55fce983 100644 --- a/src/core/apis/file.ts +++ b/src/core/apis/file.ts @@ -148,7 +148,7 @@ export class NTQQFileApi { try { videoInfo = await getVideoInfo(path, logger); } catch (e) { - logger.logWarn('获取视频信息失败,将使用默认值', e); + logger.logError('获取视频信息失败,将使用默认值', e); } const thumbPath = new Map(); const _thumbPath = await new Promise((resolve, reject) => { diff --git a/src/core/helper/rkey.ts b/src/core/helper/rkey.ts index f8be4e51..dd7b5059 100644 --- a/src/core/helper/rkey.ts +++ b/src/core/helper/rkey.ts @@ -26,7 +26,7 @@ export class RkeyManager { try { await this.refreshRkey(); } catch (e) { - this.logger.logError('获取 rkey 失败', e); + this.logger.logError('获取rkey失败', e); } } return this.rkeyData; diff --git a/src/core/index.ts b/src/core/index.ts index bbf4e73e..c6e9f0ea 100644 --- a/src/core/index.ts +++ b/src/core/index.ts @@ -119,9 +119,9 @@ export class NapCatCore { // Renamed from 'InitDataListener' async initNapCatCoreListeners() { const msgListener = new NodeIKernelMsgListener(); - msgListener.onKickedOffLine = (info: KickedOffLineInfo) => { + msgListener.onKickedOffLine = (Info: KickedOffLineInfo) => { // 下线通知 - this.context.logger.logError(`当前账户被强制下线: ${info.tipsTitle} ${info.tipsDesc}`); + this.context.logger.logError('[KickedOffLine] [' + Info.tipsTitle + '] ' + Info.tipsDesc); this.selfInfo.online = false; }; msgListener.onRecvMsg = (msgs) => { diff --git a/src/onebot/action/msg/SendMsg.ts b/src/onebot/action/msg/SendMsg.ts index 44eda85c..c3c80509 100644 --- a/src/onebot/action/msg/SendMsg.ts +++ b/src/onebot/action/msg/SendMsg.ts @@ -148,7 +148,7 @@ export class SendMsg extends BaseAction { //对Mgsid和OB11ID混用情况兜底 const nodeMsg = MessageUnique.getMsgIdAndPeerByShortId(parseInt(nodeId)) || MessageUnique.getPeerByMsgId(nodeId); if (!nodeMsg) { - logger.logError(`转发消息失败, 未找到消息 ${nodeId}`); + logger.logError('转发消息失败,未找到消息', nodeId); continue; } nodeMsgIds.push(nodeMsg.MsgId); @@ -160,7 +160,7 @@ export class SendMsg extends BaseAction { const isNodeMsg = OB11Data.filter(e => e.type === OB11MessageDataType.node).length;//找到子转发消息 if (isNodeMsg !== 0) { if (isNodeMsg !== OB11Data.length) { - logger.logWarn('子消息中包含非 node 消息, 跳过不合法部分'); + logger.logError('子消息中包含非node消息 跳过不合法部分'); continue; } const nodeMsg = await this.handleForwardedNodes(selfPeer, OB11Data.filter(e => e.type === OB11MessageDataType.node)); @@ -256,12 +256,12 @@ export class SendMsg extends BaseAction { } if (sendElements.length === 0) { - logger.logWarn('需要 clone 的消息无法解析, 忽略: ', msg); + logger.logDebug('需要clone的消息无法解析,将会忽略掉', msg); } try { return await this.core.apis.MsgApi.sendMsg(selfPeer, sendElements, true); } catch (e) { - logger.logError('克隆转发消息失败, 将忽略本条消息', e, msg); + logger.logError(e, '克隆转发消息失败,将忽略本条消息', msg); } } } diff --git a/src/onebot/api/msg.ts b/src/onebot/api/msg.ts index 63f53878..85689dba 100644 --- a/src/onebot/api/msg.ts +++ b/src/onebot/api/msg.ts @@ -234,7 +234,7 @@ export class OneBotMsgApi { if (records.peerUin === '284840486') { return createReplyData(records.msgId); } - const replyMsg = (await this.core.apis.MsgApi.queryMsgsWithFilterExWithSeqV2(peer, element.replayMsgSeq, element.replyMsgTime, [element.senderUidStr])) + let replyMsg = (await this.core.apis.MsgApi.queryMsgsWithFilterExWithSeqV2(peer, element.replayMsgSeq, element.replyMsgTime, [element.senderUidStr])) .msgList.find(msg => msg.msgRandom === records.msgRandom); if (!replyMsg || records.msgRandom !== replyMsg.msgRandom) { @@ -591,20 +591,25 @@ export class OneBotMsgApi { // 保留, 直到...找到更好的解决方案 if (data.type === 'custom') { if (!data.url) { - throw '自定义音乐卡片缺少参数 url'; + this.core.context.logger.logError('自定义音卡缺少参数url'); + return undefined; } if (!data.audio) { - throw '自定义音乐卡片缺少参数 audio'; + this.core.context.logger.logError('自定义音卡缺少参数audio'); + return undefined; } if (!data.title) { - throw '自定义音乐卡片缺少参数 title'; + this.core.context.logger.logError('自定义音卡缺少参数title'); + return undefined; } } else { if (!['qq', '163'].includes(data.type)) { - throw `不支持的 type: ${data.type}`; + this.core.context.logger.logError('音乐卡片type错误, 只支持qq、163、custom,当前type:', data.type); + return undefined; } if (!data.id) { - throw '音乐卡片缺少参数 id'; + this.core.context.logger.logError('音乐卡片缺少参数id'); + return undefined; } } diff --git a/src/onebot/index.ts b/src/onebot/index.ts index 6dd5961a..4d9ec98c 100644 --- a/src/onebot/index.ts +++ b/src/onebot/index.ts @@ -87,7 +87,7 @@ export class NapCatOneBot11Adapter { selfInfo.nick = user.nick; this.context.logger.setLogSelfInfo(selfInfo); }).catch(this.context.logger.logError); - this.context.logger.log(`OneBot 服务状态: ${serviceInfo}`); + this.context.logger.log(`[Notice] [OneBot11] ${serviceInfo}`); //创建NetWork服务 if (ob11Config.http.enable) { @@ -128,7 +128,7 @@ export class NapCatOneBot11Adapter { await WebUiDataRuntime.setOnOB11ConfigChanged(async (newConfig: OB11Config) => { const prev = this.configLoader.configData; this.configLoader.save(newConfig); - this.context.logger.logDebug(`OneBot11 配置更改: ${JSON.stringify(prev)} -> ${JSON.stringify(newConfig)}`); + this.context.logger.log(`OneBot11 配置更改:${JSON.stringify(prev)} -> ${JSON.stringify(newConfig)}`); await this.reloadNetwork(prev, newConfig); }); } @@ -150,7 +150,7 @@ export class NapCatOneBot11Adapter { HTTP上报服务 ${now.http.enablePost ? '已启动' : '未启动'}, 上报地址: ${now.http.postUrls} WebSocket服务 ${now.ws.enable ? '已启动' : '未启动'}, ${now.ws.host}:${now.ws.port} WebSocket反向服务 ${now.reverseWs.enable ? '已启动' : '未启动'}, 反向地址: ${now.reverseWs.urls}`; - this.context.logger.log(`热重载 - OneBot 服务状态: ${serviceInfo}`); + this.context.logger.log(`[Notice] [OneBot11] 热重载 ${serviceInfo}`); // check difference in passive http (Http) if (prev.http.enable !== now.http.enable) { @@ -270,7 +270,7 @@ export class NapCatOneBot11Adapter { msgListener.onInputStatusPush = async data => { const uin = await this.core.apis.UserApi.getUinByUidV2(data.fromUin); - this.context.logger.log(`${uin} 输入状态更新: ${data.statusText}`); + this.context.logger.log(`[Notice] [输入状态] ${uin} ${data.statusText}`); await this.networkManager.emitEvent(new OB11InputStatusEvent( this.core, parseInt(uin), diff --git a/src/onebot/network/active-http.ts b/src/onebot/network/active-http.ts index 0fee3d18..9992f6bf 100644 --- a/src/onebot/network/active-http.ts +++ b/src/onebot/network/active-http.ts @@ -43,7 +43,7 @@ export class OB11ActiveHttpAdapter implements IOB11NetworkAdapter { resJson = await res.json(); //logDebug('新消息事件HTTP上报返回快速操作: ', JSON.stringify(resJson)); } catch (e) { - this.logger.logDebug('新消息事件 HTTP 上报没有返回快速操作,不需要处理'); + this.logger.logDebug('[OneBot] [Http Client] 新消息事件HTTP上报没有返回快速操作,不需要处理'); return; } try { @@ -51,10 +51,10 @@ export class OB11ActiveHttpAdapter implements IOB11NetworkAdapter { .handleQuickOperation(event as QuickActionEvent, resJson) .catch(this.logger.logError); } catch (e: any) { - this.logger.logError('新消息事件 HTTP 上报返回快速操作失败', e); + this.logger.logError('[OneBot] [Http Client] 新消息事件HTTP上报返回快速操作失败', e); } }).catch((e) => { - this.logger.logError('新消息事件 HTTP 上报失败', e); + this.logger.logError('[OneBot] [Http Client] 新消息事件HTTP上报失败', e); }); } diff --git a/src/onebot/network/active-websocket.ts b/src/onebot/network/active-websocket.ts index c96b12a0..cf7ec602 100644 --- a/src/onebot/network/active-websocket.ts +++ b/src/onebot/network/active-websocket.ts @@ -85,13 +85,13 @@ export class OB11ActiveWebSocketAdapter implements IOB11NetworkAdapter { this.connection?.pong(); }); this.connection.on('pong', () => { - //this.logger.logDebug('收到pong'); + //this.logger.logDebug('[OneBot] [WebSocket Client] 收到pong'); }); this.connection.on('open', () => { try { this.connectEvent(this.core); } catch (e) { - this.logger.logError('发送连接生命周期失败', e); + this.logger.logError('[OneBot] [WebSocket Client] 发送连接生命周期失败', e); } }); @@ -100,8 +100,8 @@ export class OB11ActiveWebSocketAdapter implements IOB11NetworkAdapter { }); this.connection.once('close', () => { if (!isClosedByError) { - this.logger.logError(`反向WebSocket (${this.url}) 连接意外关闭`); - this.logger.logError(`在 ${Math.floor(this.reconnectIntervalInMillis / 1000)} 秒后尝试重新连接`); + this.logger.logError(`[OneBot] [WebSocket Client] 反向WebSocket (${this.url}) 连接意外关闭`); + this.logger.logError(`[OneBot] [WebSocket Client] 在 ${Math.floor(this.reconnectIntervalInMillis / 1000)} 秒后尝试重新连接`); if (!this.isClosed) { this.connection = null; setTimeout(() => this.tryConnect(), this.reconnectIntervalInMillis); @@ -110,8 +110,8 @@ export class OB11ActiveWebSocketAdapter implements IOB11NetworkAdapter { }); this.connection.on('error', (err) => { isClosedByError = true; - this.logger.logError(`反向WebSocket (${this.url}) 连接错误`, err); - this.logger.logError(`在 ${Math.floor(this.reconnectIntervalInMillis / 1000)} 秒后尝试重新连接`); + this.logger.logError(`[OneBot] [WebSocket Client] 反向WebSocket (${this.url}) 连接错误`, err); + this.logger.logError(`[OneBot] [WebSocket Client] 在 ${Math.floor(this.reconnectIntervalInMillis / 1000)} 秒后尝试重新连接`); if (!this.isClosed) { this.connection = null; setTimeout(() => this.tryConnect(), this.reconnectIntervalInMillis); @@ -124,7 +124,7 @@ export class OB11ActiveWebSocketAdapter implements IOB11NetworkAdapter { try { this.checkStateAndReply(new OB11LifeCycleEvent(core, LifeCycleSubType.CONNECT)); } catch (e) { - this.logger.logError('发送生命周期失败', e); + this.logger.logError('[OneBot] [WebSocket Client] 发送生命周期失败', e); } } @@ -135,7 +135,7 @@ export class OB11ActiveWebSocketAdapter implements IOB11NetworkAdapter { try { receiveData = JSON.parse(message.toString()); echo = receiveData.echo; - this.logger.logDebug('收到正向Websocket消息', receiveData); + this.logger.logDebug('[OneBot] [WebSocket Client] 收到正向Websocket消息', receiveData); } catch (e) { this.checkStateAndReply(OB11Response.error('json解析失败,请检查数据格式', 1400, echo)); return; @@ -143,8 +143,8 @@ export class OB11ActiveWebSocketAdapter implements IOB11NetworkAdapter { receiveData.params = (receiveData?.params) ? receiveData.params : {};//兼容类型验证 const action = this.actions.get(receiveData.action); if (!action) { - this.logger.logError('不支持的 api' + receiveData.action); - this.checkStateAndReply(OB11Response.error('不支持的 api ' + receiveData.action, 1404, echo)); + this.logger.logError('[OneBot] [WebSocket Client] 发生错误', '不支持的api ' + receiveData.action); + this.checkStateAndReply(OB11Response.error('不支持的api ' + receiveData.action, 1404, echo)); return; } const retdata = await action.websocketHandle(receiveData.params, echo ?? ''); diff --git a/src/onebot/network/passive-http.ts b/src/onebot/network/passive-http.ts index 6726d1d3..0a7b8367 100644 --- a/src/onebot/network/passive-http.ts +++ b/src/onebot/network/passive-http.ts @@ -26,7 +26,7 @@ export class OB11PassiveHttpAdapter implements IOB11NetworkAdapter { open() { try { if (this.isOpen) { - this.core.context.logger.logError('Http 服务已经启动'); + this.core.context.logger.logError('Cannot open a closed HTTP server'); return; } if (!this.isOpen) { @@ -34,7 +34,7 @@ export class OB11PassiveHttpAdapter implements IOB11NetworkAdapter { this.isOpen = true; } } catch (e) { - this.core.context.logger.logError('Http 服务启动失败', e); + this.core.context.logger.logError(`[OneBot] [HTTP Server Adapter] Boot Error: ${e}`); } } @@ -67,7 +67,7 @@ export class OB11PassiveHttpAdapter implements IOB11NetworkAdapter { this.app.use((req, res) => this.handleRequest(req, res)); this.server.listen(this.port, () => { - this.core.context.logger.logDebug(`OneBot 11 Http 服务在 ${this.port} 上启动`); + this.core.context.logger.log(`[OneBot] [HTTP Server Adapter] Start On Port ${this.port}`); }); } @@ -85,7 +85,7 @@ export class OB11PassiveHttpAdapter implements IOB11NetworkAdapter { private async handleRequest(req: Request, res: Response) { if (!this.isOpen) { - this.core.context.logger.log(`OneBot 11 Http 服务已关闭`); + this.core.context.logger.log(`[OneBot] [HTTP Server Adapter] Server is closed`); return res.json(OB11Response.error('Server is closed', 200)); } diff --git a/src/onebot/network/passive-websocket.ts b/src/onebot/network/passive-websocket.ts index 8f4e5e2d..70b2f371 100644 --- a/src/onebot/network/passive-websocket.ts +++ b/src/onebot/network/passive-websocket.ts @@ -47,7 +47,7 @@ export class OB11PassiveWebSocketAdapter implements IOB11NetworkAdapter { //鉴权 this.authorize(token, wsClient, wsReq); this.connectEvent(core, wsClient); - wsClient.on('error', (err) => this.logger.logError('OneBot 11 WS 客户端连接异常中断', err.message)); + 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); }); @@ -68,14 +68,14 @@ export class OB11PassiveWebSocketAdapter implements IOB11NetworkAdapter { await this.wsClientsMutex.runExclusive(async () => { this.wsClients.push(wsClient); }); - }).on('error', (err) => this.logger.logError('OneBot 11 WS 服务端错误', err.message)); + }).on('error', (err) => this.logger.log('[OneBot] [WebSocket Server] Server Error:', err.message)); } connectEvent(core: NapCatCore, wsClient: WebSocket) { try { this.checkStateAndReply(new OB11LifeCycleEvent(core, LifeCycleSubType.CONNECT), wsClient); } catch (e) { - this.logger.logError('WS 服务发送生命周期失败', e); + this.logger.logError('[OneBot] [WebSocket Server] 发送生命周期失败', e); } } @@ -89,13 +89,15 @@ export class OB11PassiveWebSocketAdapter implements IOB11NetworkAdapter { open() { if (this.isOpen) { - throw 'WS 服务已经打开, 不能再次打开'; + this.logger.logError('[OneBot] [WebSocket Server] Cannot open a opened WebSocket server'); + return; } if (this.hasBeenClosed) { - throw 'WS 服务已经关闭, 不能再次打开'; + this.logger.logError('[OneBot] [WebSocket Server] Cannot open a WebSocket server that has been closed'); + return; } const addressInfo = this.wsServer.address(); - this.logger.logDebug('WS 服务启动', typeof (addressInfo) === 'string' ? addressInfo : addressInfo?.address + ':' + addressInfo?.port); + this.logger.log('[OneBot] [WebSocket Server] Server Started', typeof (addressInfo) === 'string' ? addressInfo : addressInfo?.address + ':' + addressInfo?.port); this.isOpen = true; this.registerHeartBeat(); @@ -154,7 +156,7 @@ export class OB11PassiveWebSocketAdapter implements IOB11NetworkAdapter { receiveData.params = (receiveData?.params) ? receiveData.params : {};//兼容类型验证 const action = this.actions.get(receiveData.action); if (!action) { - this.logger.logError(`不支持的 api ${receiveData.action}`); + this.logger.logError('[OneBot] [WebSocket Client] 发生错误', '不支持的api ' + receiveData.action); this.checkStateAndReply(OB11Response.error('不支持的api ' + receiveData.action, 1404, echo), wsClient); return; } diff --git a/src/shell/napcat.ts b/src/shell/napcat.ts index 27ccb080..4beeded5 100644 --- a/src/shell/napcat.ts +++ b/src/shell/napcat.ts @@ -39,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(`NapCatQQ 版本: ` + napCatVersion); + logger.log(`[NapCat] [Core] NapCat.Core Version: ` + napCatVersion); InitWebUi(logger, pathWrapper).then().catch(logger.logError); // from constructor @@ -125,20 +125,20 @@ export async function NCoreInitShell() { logger.logWarn('请扫描下面的二维码,然后在手Q上授权登录:'); const qrcodePath = path.join(pathWrapper.cachePath, 'qrcode.png'); qrcode.generate(qrcodeUrl, { small: true }, (res) => { - logger.log([ + logger.logWarn([ '\n', res, '二维码解码URL: ' + qrcodeUrl, '如果控制台二维码无法扫码,可以复制解码url到二维码生成网站生成二维码再扫码,也可以打开下方的二维码路径图片进行扫码。', ].join('\n')); fs.writeFile(qrcodePath, buffer, {}, () => { - logger.log(`二维码已保存到 ${qrcodePath}`); + logger.logWarn('二维码已保存到', qrcodePath); }); }); }; loginListener.onQRCodeSessionFailed = (errType: number, errCode: number, errMsg: string) => { //logger.logError('登录失败(onQRCodeSessionFailed)', errCode, errMsg); - logger.logError(`二维码登录失败(${errCode} - ${errType}): ${errMsg}`); + logger.logError('[Core] [Login] Login Error,ErrCode: ', errCode, ' ErrMsg:', errMsg); if (errType == 1 && errCode == 3) { // 二维码过期刷新 } @@ -146,7 +146,7 @@ export async function NCoreInitShell() { }; loginListener.onLoginFailed = (args) => { //logger.logError('登录失败(onLoginFailed)', args); - logger.logError('登录失败', args); + logger.logError('[Core] [Login] Login Error , ErrInfo: ', args); }; loginService.addKernelLoginListener(proxiedListenerOf(loginListener, logger) as any); @@ -190,7 +190,7 @@ export async function NCoreInitShell() { .catch(); }, 1000); } else { - logger.logError('快速登录失败, 未找到该 QQ 历史登录记录, 将使用二维码登录方式.'); + logger.logError('快速登录失败,未找到该 QQ 历史登录记录,将使用二维码登录方式'); loginService.getQRCodePicture(); } } else { @@ -199,7 +199,7 @@ export async function NCoreInitShell() { logger.log(`可用于快速登录的 QQ:\n${historyLoginList .map((u, index) => `${index + 1}. ${u.uin} ${u.nickName}`) .join('\n') - }`); + }`); } loginService.getQRCodePicture(); } diff --git a/src/webui/index.ts b/src/webui/index.ts index 34fe54cf..c0e660a1 100644 --- a/src/webui/index.ts +++ b/src/webui/index.ts @@ -18,9 +18,10 @@ 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) { - logger.log('[NapCat] [WebUi] Current WebUi is not run.'); + log('[NapCat] [WebUi] Current WebUi is not run.'); return; } app.use(express.json()); @@ -36,8 +37,8 @@ export async function InitWebUi(logger: LogWrapper, pathWrapper: NapCatPathWrapp //挂载API接口 app.use(config.prefix + '/api', ALLRouter); app.listen(config.port, config.host, async () => { - logger.log(`[NapCat] [WebUi] Current WebUi is running at http://${config.host}:${config.port}${config.prefix}`); - logger.log(`[NapCat] [WebUi] Login URL is http://${config.host}:${config.port}${config.prefix}/webui`); - logger.log(`[NapCat] [WebUi] Login Token is ${config.token}`); + log(`[NapCat] [WebUi] Current WebUi is running at http://${config.host}:${config.port}${config.prefix}`); + log(`[NapCat] [WebUi] Login URL is http://${config.host}:${config.port}${config.prefix}/webui`); + log(`[NapCat] [WebUi] Login Token is ${config.token}`); }); } From 48350be625de1d1985c56e5ba4f193e981a17b3b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=89=8B=E7=93=9C=E4=B8=80=E5=8D=81=E9=9B=AA?= Date: Wed, 4 Sep 2024 18:05:44 +0800 Subject: [PATCH 21/23] =?UTF-8?q?fix:=20=E8=BF=9B=E4=B8=80=E6=AD=A5?= =?UTF-8?q?=E7=AD=9B=E9=80=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/core/apis/group.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/apis/group.ts b/src/core/apis/group.ts index 0fbdc2fc..d4e02c8f 100644 --- a/src/core/apis/group.ts +++ b/src/core/apis/group.ts @@ -247,7 +247,7 @@ export class NTQQGroupApi { 'NodeIKernelGroupListener/onMemberInfoChange', 1, forced ? 5000 : 250, - (params) => params === GroupCode, + (params, _, members) => params === GroupCode && members.size > 0, ); const retData = await ( this.core.eventWrapper From 452c72d28034def79073f17dbdd6c5eed6e74fb4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=89=8B=E7=93=9C=E4=B8=80=E5=8D=81=E9=9B=AA?= Date: Wed, 4 Sep 2024 23:12:38 +0800 Subject: [PATCH 22/23] release: 2.2.47 --- launcher/NapCatWinBootHook.dll | Bin 0 -> 11264 bytes launcher/NapCatWinBootMain.exe | Bin 0 -> 22016 bytes launcher/launcher.bat | 40 +++++++++++++++++++++++++++++++++ launcher/loadNapCat.js | 5 +++++ launcher/patchNapCat.js | 1 + manifest.json | 2 +- package.json | 2 +- src/common/version.ts | 2 +- src/webui/ui/NapCat.ts | 2 +- static/assets/renderer.js | 2 +- vite.config.ts | 2 +- 11 files changed, 52 insertions(+), 6 deletions(-) create mode 100644 launcher/NapCatWinBootHook.dll create mode 100644 launcher/NapCatWinBootMain.exe create mode 100644 launcher/launcher.bat create mode 100644 launcher/loadNapCat.js create mode 100644 launcher/patchNapCat.js diff --git a/launcher/NapCatWinBootHook.dll b/launcher/NapCatWinBootHook.dll new file mode 100644 index 0000000000000000000000000000000000000000..ee797fc92bf6887017f045278b866fb48cc86898 GIT binary patch literal 11264 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 E0|xzek^lez literal 0 HcmV?d00001 diff --git a/launcher/NapCatWinBootMain.exe b/launcher/NapCatWinBootMain.exe new file mode 100644 index 0000000000000000000000000000000000000000..509927021df4ba7f8fcc1476b6dca313ba491e03 GIT binary patch literal 22016 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 2>&1 +if %errorLevel% == 0 ( + echo Administrator mode detected. +) else ( + echo Please run this script in administrator mode. + REM 以管理员权限启动脚本 并保留工作目录 + powershell -Command "Start-Process 'wt.exe' -ArgumentList 'cmd /c cd /d \"%cd%\" && \"%~f0\"' -Verb runAs" + exit +) + +set NAPCAT_PATCH_PATH=%cd%\patchNapCat.js +set NAPCAT_LOAD_PATH=%cd%\loadNapCat.js +set NAPCAT_INJECT_PATH=%cd%\NapCatWinBootHook.dll +set NAPCAT_LAUNCHER_PATH=%cd%\NapCatWinBootMain.exe +set NAPCAT_MAIN_PATH=%cd%\napcat.mjs +:loop_read +for /f "tokens=2*" %%a in ('reg query "HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\QQ" /v "UninstallString"') do ( + set RetString=%%b + goto :napcat_boot +) + +:napcat_boot +for %%a in (%RetString%) do ( + set "pathWithoutUninstall=%%~dpa" +) + +SET QQPath=%pathWithoutUninstall%QQ.exe + +REM 拿不到QQ路径则退出 +if not exist "%QQpath%" ( + echo provided QQ path is invalid: %QQpath% + pause + exit /b +) +set NAPCAT_MAIN_PATH=%NAPCAT_MAIN_PATH:\=/% +echo (async () =^> {await import("file:///%NAPCAT_MAIN_PATH%")})() > %NAPCAT_LOAD_PATH% + +"%NAPCAT_LAUNCHER_PATH%" "%QQPath%" "%NAPCAT_INJECT_PATH%" \ No newline at end of file diff --git a/launcher/loadNapCat.js b/launcher/loadNapCat.js new file mode 100644 index 00000000..81af5e6e --- /dev/null +++ b/launcher/loadNapCat.js @@ -0,0 +1,5 @@ +const path = require('path'); +const CurrentPath = path.dirname(__filename); +(async () => { + await import("file://" + path.join(CurrentPath, './napcat/napcat.mjs')); +})(); \ No newline at end of file diff --git a/launcher/patchNapCat.js b/launcher/patchNapCat.js new file mode 100644 index 00000000..83a04e1f --- /dev/null +++ b/launcher/patchNapCat.js @@ -0,0 +1 @@ +require('./launcher.node').load('external_index', module); \ No newline at end of file diff --git a/manifest.json b/manifest.json index 01315720..a01452e1 100644 --- a/manifest.json +++ b/manifest.json @@ -4,7 +4,7 @@ "name": "NapCatQQ", "slug": "NapCat.Framework", "description": "高性能的 OneBot 11 协议实现", - "version": "2.2.46", + "version": "2.2.47", "icon": "./logo.png", "authors": [ { diff --git a/package.json b/package.json index 4a34f75e..78d802a1 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "napcat", "private": true, "type": "module", - "version": "2.2.46", + "version": "2.2.47", "scripts": { "build:framework": "vite build --mode framework", "build:shell": "vite build --mode shell", diff --git a/src/common/version.ts b/src/common/version.ts index 073fb870..3c1caf38 100644 --- a/src/common/version.ts +++ b/src/common/version.ts @@ -1 +1 @@ -export const napCatVersion = '2.2.46'; +export const napCatVersion = '2.2.47'; diff --git a/src/webui/ui/NapCat.ts b/src/webui/ui/NapCat.ts index e5ab2d16..3f77f79b 100644 --- a/src/webui/ui/NapCat.ts +++ b/src/webui/ui/NapCat.ts @@ -30,7 +30,7 @@ async function onSettingWindowCreated(view: Element) { SettingItem( 'Napcat', undefined, - SettingButton('V2.2.46', 'napcat-update-button', 'secondary'), + SettingButton('V2.2.47', 'napcat-update-button', 'secondary'), ), ]), SettingList([ diff --git a/static/assets/renderer.js b/static/assets/renderer.js index ad823661..7df30e44 100644 --- a/static/assets/renderer.js +++ b/static/assets/renderer.js @@ -164,7 +164,7 @@ async function onSettingWindowCreated(view) { SettingItem( 'Napcat', void 0, - SettingButton("V2.2.46", "napcat-update-button", "secondary") + SettingButton("V2.2.47", "napcat-update-button", "secondary") ) ]), SettingList([ diff --git a/vite.config.ts b/vite.config.ts index 8db2538f..be7379ef 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -11,7 +11,6 @@ const nodeModules = [...builtinModules, builtinModules.map(m => `node:${m}`)].fl function genCpModule(module: string) { return { src: `./node_modules/${module}`, dest: `dist/node_modules/${module}`, flatten: false }; } - let startScripts: string[] | undefined = undefined; if (process.env.NAPCAT_BUILDSYS == 'linux') { if (process.env.NAPCAT_BUILDARCH == 'x64') { @@ -82,6 +81,7 @@ const ShellBaseConfigPlugin: PluginOption[] = [ { src: './src/core/external/napcat.json', dest: 'dist/config/' }, { src: './src/onebot/config/onebot11.json', dest: 'dist/config/' }, { src: './package.json', dest: 'dist' }, + { src: './launcher/', dest: 'dist', flatten: true }, // { src: './README.md', dest: 'dist' }, // { src: './logo.png', dest: 'dist/logs' }, ...(startScripts.map((startScript) => { From b415c1a6d1be1a9c8456ef5ab0e747fb1b16fd02 Mon Sep 17 00:00:00 2001 From: "Wesley F. Young" Date: Wed, 4 Sep 2024 23:26:55 +0800 Subject: [PATCH 23/23] fix: file encoding --- .editorconfig | 3 +++ launcher/launcher.bat | 4 +--- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/.editorconfig b/.editorconfig index 8e507935..e73bbcf5 100644 --- a/.editorconfig +++ b/.editorconfig @@ -17,5 +17,8 @@ charset = utf-8 indent_style = space indent_size = 4 +[*.bat] +charset = latin1 + # Unfortunately, EditorConfig doesn't support space configuration inside import braces directly. # You'll need to rely on your linter/formatter like ESLint or Prettier for that. diff --git a/launcher/launcher.bat b/launcher/launcher.bat index 19a3f935..965624b1 100644 --- a/launcher/launcher.bat +++ b/launcher/launcher.bat @@ -5,7 +5,6 @@ if %errorLevel% == 0 ( echo Administrator mode detected. ) else ( echo Please run this script in administrator mode. - REM 以管理员权限启动脚本 并保留工作目录 powershell -Command "Start-Process 'wt.exe' -ArgumentList 'cmd /c cd /d \"%cd%\" && \"%~f0\"' -Verb runAs" exit ) @@ -28,7 +27,6 @@ for %%a in (%RetString%) do ( SET QQPath=%pathWithoutUninstall%QQ.exe -REM 拿不到QQ路径则退出 if not exist "%QQpath%" ( echo provided QQ path is invalid: %QQpath% pause @@ -37,4 +35,4 @@ if not exist "%QQpath%" ( set NAPCAT_MAIN_PATH=%NAPCAT_MAIN_PATH:\=/% echo (async () =^> {await import("file:///%NAPCAT_MAIN_PATH%")})() > %NAPCAT_LOAD_PATH% -"%NAPCAT_LAUNCHER_PATH%" "%QQPath%" "%NAPCAT_INJECT_PATH%" \ No newline at end of file +"%NAPCAT_LAUNCHER_PATH%" "%QQPath%" "%NAPCAT_INJECT_PATH%"