Skip to content

Commit a8c77e5

Browse files
committed
fix: 优化细节
1 parent c06db40 commit a8c77e5

11 files changed

Lines changed: 94 additions & 82 deletions

File tree

‎example/app.ts‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
import('mioki').then(({ start }) => start({ cwd: __dirname }))
1+
require('mioki').start({ cwd: __dirname })

‎example/package.json‎

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,11 @@
11
{
22
"name": "bot",
33
"private": true,
4-
"type": "module",
54
"dependencies": {
65
"mioki": "workspace:*"
76
},
87
"scripts": {
9-
"start": "bun app.ts"
8+
"start": "node app.ts"
109
},
1110
"mioki": {
1211
"prefix": "~",
@@ -20,12 +19,12 @@
2019
],
2120
"log_level": "info",
2221
"plugins_dir": "../plugins",
23-
"online_push": true,
22+
"online_push": false,
2423
"napcat": {
2524
"protocol": "ws",
2625
"port": 3333,
2726
"host": "localhost",
2827
"token": "cdc93b212524c0c0a0a162f1edec347a"
2928
}
3029
}
31-
}
30+
}

‎packages/mioki/src/actions.ts‎

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
import crypto from 'node:crypto'
2+
import { logger } from './logger'
3+
import * as utils from './utils'
24
import { segment } from 'napcat-sdk'
35
import { botConfig } from './config'
4-
import * as utils from './utils'
56

67
import type { NapCat, Sendable } from 'napcat-sdk'
78

@@ -15,12 +16,12 @@ export async function noticeGroups(
1516
delay = 1000,
1617
): Promise<void> {
1718
if (!bot.isOnline()) {
18-
bot.logger.error('发送失败,Bot 不在线')
19+
logger.error('发送失败,Bot 不在线')
1920
return
2021
}
2122

2223
if (!message) {
23-
bot.logger.warn('消息内容为空')
24+
logger.warn('消息内容为空')
2425
return
2526
}
2627

@@ -42,12 +43,12 @@ export async function noticeFriends(
4243
delay = 1000,
4344
): Promise<void> {
4445
if (!bot.isOnline) {
45-
bot.logger.error('发送失败,Bot 不在线')
46+
logger.error('发送失败,Bot 不在线')
4647
return
4748
}
4849

4950
if (!message) {
50-
bot.logger.warn('消息内容为空')
51+
logger.warn('消息内容为空')
5152
return
5253
}
5354

@@ -80,12 +81,12 @@ export async function noticeOwners(bot: NapCat, message?: Sendable | null, delay
8081
*/
8182
export async function noticeMainOwner(bot: NapCat, message?: Sendable | null): Promise<void> {
8283
if (!bot.isOnline()) {
83-
bot.logger.error('发送失败,Bot 不在线')
84+
logger.error('发送失败,Bot 不在线')
8485
return
8586
}
8687

8788
if (!message) {
88-
bot.logger.warn('消息内容为空')
89+
logger.warn('消息内容为空')
8990
return
9091
}
9192

@@ -152,7 +153,7 @@ export async function runWithErrorHandler(
152153
try {
153154
await noticeMainOwner(bot, '发送失败,可能被风控,请检查签名状态。')
154155
} catch {
155-
bot.logger.error('发送失败,可能被风控,请检查签名状态。')
156+
logger.error('发送失败,可能被风控,请检查签名状态。')
156157
}
157158
}
158159
}

‎packages/mioki/src/config.ts‎

Lines changed: 4 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import fs from 'node:fs'
22
import path from 'node:path'
3-
import { dayjs, isNumber, unique } from './utils'
3+
import { logger } from './logger'
4+
import { isNumber, unique } from './utils'
45

56
import type { LogLevel } from 'napcat-sdk'
67

@@ -69,15 +70,15 @@ export const updateBotConfig = async (draftFn: (config: MiokiConfig) => any): Pr
6970

7071
writePackageJson(pkg)
7172

72-
console.log(`>>> 检测到配置变动,已同步至 package.json 文件`)
73+
logger.info(`检测到配置变动,已同步至 package.json 文件`)
7374
}
7475

7576
/**
7677
* 更新机器人根目录
7778
*/
7879
export const updateBotCWD = (root: string): void => {
7980
BOT_CWD.value = root
80-
console.log(`>>> 机器人根目录已设置为 ${root}`)
81+
logger.info(`机器人根目录已设置为 ${root}`)
8182
}
8283

8384
/**
@@ -124,11 +125,3 @@ export const hasRight = (id: number | { sender: { user_id: number } } | { user_i
124125
* 是否在 PM2 中运行
125126
*/
126127
export const isInPm2: boolean = Boolean('pm_id' in process.env || 'PM2_USAGE' in process.env)
127-
128-
/**
129-
* 获取日志文件名
130-
*/
131-
export function getLogFilePath(uin: number, platformName: string): string {
132-
const startTime = dayjs().format('YYYY-MM-DD_HH-mm-ss')
133-
return path.join(BOT_CWD.value, `logs/${uin}_${platformName}_${startTime}.log`)
134-
}

‎packages/mioki/src/logger.ts‎

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import fs from 'node:fs'
22
import path from 'node:path'
33
import { dayjs } from './utils'
4-
import { BOT_CWD } from './config'
4+
import { BOT_CWD, botConfig } from './config'
55
import { stripAnsi, ColorName, colors } from 'consola/utils'
66
import { createConsola, LogLevels, ConsolaInstance } from 'consola/core'
77

@@ -16,6 +16,8 @@ const LEVEL_MAP: Record<number, { name: string; color: ColorName }> = {
1616
5: { name: 'TRACE', color: 'gray' },
1717
}
1818

19+
export const logger: ConsolaInstance = getMiokiLogger(botConfig.log_level || 'info')
20+
1921
/**
2022
* 获取日志文件名
2123
*/
@@ -24,7 +26,7 @@ export function getLogFilePath(type: string = ''): string {
2426
return path.join(BOT_CWD.value, `logs/${startTime}${type ? '.' + type : ''}.log`)
2527
}
2628

27-
export const getMiokiLogger = (level: LogLevel): ConsolaInstance => {
29+
export function getMiokiLogger(level: LogLevel): ConsolaInstance {
2830
const logDir = path.join(BOT_CWD.value, 'logs')
2931

3032
if (!fs.existsSync(logDir)) {

‎packages/mioki/src/plugin.ts‎

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import fs from 'node:fs'
22
import path from 'node:path'
33
import nodeCron from 'node-cron'
44
import { hrtime } from 'node:process'
5+
import { colors } from 'consola/utils'
56

67
import * as utilsExports from './utils'
78
import * as configExports from './config'
@@ -11,7 +12,6 @@ import * as servicesExports from './services'
1112
import type { EventMap, NapCat } from 'napcat-sdk'
1213
import type { ScheduledTask, TaskContext } from 'node-cron'
1314
import type { ConsolaInstance } from 'consola/core'
14-
import { colors } from 'consola/utils'
1515

1616
type Num = 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9
1717

@@ -222,7 +222,7 @@ export async function enablePlugin(
222222
runtimePlugins.delete(name)
223223
} catch (err: any) {
224224
throw new Error(
225-
`>>> 禁用插件 [${colors.bold(colors.yellow(typeDesc))}]${colors.bold(colors.yellow(name))}@${colors.bold(colors.yellow(version))} 失败: ${err?.message}`,
225+
`禁用插件 [${colors.yellow(typeDesc)}]${colors.yellow(`${name}@${version}`)} 失败: ${err?.message}`,
226226
)
227227
}
228228
},
@@ -232,11 +232,11 @@ export async function enablePlugin(
232232
const time = Math.round(Number(end - start)) / 1_000_000
233233

234234
bot.logger.info(
235-
`>>> 启用插件 ${colors.bold(colors.yellow(`[${typeDesc}]`))}${colors.bold(colors.yellow(`${name}@${version}`))} => 耗时 ${colors.bold(colors.green(time.toFixed(2)))} ms`,
235+
`启用插件 ${colors.yellow(`[${typeDesc}]`)}${colors.yellow(`${name}@${version}`)} => 耗时 ${colors.green(time.toFixed(2))} ms`,
236236
)
237237
} catch (e: any) {
238238
throw new Error(
239-
`>>> 启用插件 ${colors.bold(colors.yellow(`[${typeDesc}]`))}${colors.bold(colors.yellow(`${name}@${version}`))} 失败: ${e?.message}`,
239+
`启用插件 ${colors.yellow(`[${typeDesc}]`)}${colors.yellow(`${name}@${version}`)} 失败: ${e?.message}`,
240240
)
241241
}
242242

‎packages/mioki/src/start.ts‎

Lines changed: 42 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,12 @@ import { NapCat } from 'napcat-sdk'
66
import { version } from '../package.json'
77
import * as utils from './utils'
88
import * as actions from './actions'
9-
import { getMiokiLogger } from './logger'
10-
import { BUILTIN_PLUGINS } from './builtins'
9+
import { logger } from './logger'
1110
import { colors } from 'consola/utils'
11+
import { BUILTIN_PLUGINS } from './builtins'
1212
import { enablePlugin, ensurePluginDir, getAbsPluginDir, runtimePlugins } from './plugin'
1313

1414
import type { MiokiPlugin } from './plugin'
15-
1615
export interface StartOptions {
1716
cwd?: string
1817
}
@@ -26,46 +25,61 @@ export async function start(options: StartOptions = {}): Promise<void> {
2625

2726
process.title = `mioki v${version}`
2827

29-
const logger = getMiokiLogger(cfg.botConfig.log_level || 'info')
3028
const plugin_dir = getAbsPluginDir()
3129

32-
logger.info(`>>> -> ${colors.bold(colors.cyan('mioki'))} ${colors.bold(colors.green(`v${version}`))} <-`)
33-
logger.info(`>>> ${colors.yellow(colors.underline(`基于 NapCat 的 TypeScript 🤖️ 机器人框架。`))}`)
34-
logger.info(`>>> ${colors.italic(`作者: Viki <hi@viki.moe> (https://github.com/vikiboss)`)}`)
35-
logger.info(`>>> ${colors.italic(`协议: Licensed under MIT License.`)}`)
36-
logger.info(`>>> ${colors.cyan(`GitHub: https://github.com/vikiboss/mioki`)}`)
37-
logger.info('>>> ----------------------------------------')
38-
logger.info(`>>> 工作目录: ${colors.bold(colors.blue(cfg.BOT_CWD.value))}`)
39-
logger.info(`>>> 插件目录: ${colors.bold(colors.blue(plugin_dir))}`)
30+
logger.info(colors.dim('='.repeat(40)))
31+
logger.info(`欢迎使用 ${colors.bold(colors.cyan('mioki'))} ${colors.bold(colors.green(`v${version}`))}`)
32+
logger.info(colors.yellow(colors.underline(`一个基于 NapCat 和 TypeScript 的QQ 机器人框架`)))
33+
logger.info(colors.cyan(`轻量 * 跨平台 * 体验 * 热重载 * 继承 KiviBot`))
34+
logger.info(colors.dim('='.repeat(40)))
35+
logger.info(colors.dim(colors.italic(`作者: Viki <hi@viki.moe> (https://github.com/vikiboss)`)))
36+
logger.info(colors.dim(colors.italic(`仓库: https://github.com/vikiboss/mioki`)))
37+
logger.info(colors.dim(colors.italic(`文档: https://mioki.viki.moe/docs`)))
38+
logger.info(colors.dim('='.repeat(40)))
39+
logger.info(`${colors.dim('工作目录: ')}${colors.blue(cfg.BOT_CWD.value)}`)
40+
logger.info(`${colors.dim('插件目录: ')}${colors.blue(plugin_dir)}`)
41+
logger.info(`${colors.dim('配置文件: ')}${colors.blue(`${cfg.BOT_CWD.value}/package.json`)}`)
42+
logger.info(colors.dim('='.repeat(40)))
43+
44+
const { protocol = 'ws', port = 6700, host = 'localhost', token } = cfg.botConfig.napcat || {}
45+
46+
logger.info(`开始连接 NapCat 实例: ${colors.green(`${protocol}://${host}:${port}`)}`)
4047

4148
const napcat = new NapCat({
42-
...cfg.botConfig.napcat,
49+
token,
50+
protocol,
51+
host,
52+
port,
4353
logger,
4454
})
4555

46-
napcat.on('napcat.connected', async ({ user_id, nickname }) => {
47-
logger.info(`>>> 已连接到 NapCat: ${colors.bold(colors.green(nickname))}(${colors.bold(colors.green(user_id))})`)
56+
napcat.on('ws.close', () => {
57+
logger.error('连接已关闭,请确保 NapCat 实例正常运行及 token 配置正确')
58+
})
59+
60+
napcat.on('napcat.connected', async ({ user_id, nickname, app_name, app_version }) => {
61+
logger.info(`已连接到 NapCat 实例: ${colors.green(`${app_name}-v${app_version}-${nickname}(${user_id})`)}`)
4862

4963
let lastNoticeTime = 0
5064

5165
process.on('uncaughtException', async (err: any) => {
5266
const msg = utils.stringifyError(err)
53-
napcat.logger.error(`>>> uncaughtException, 出错了: ${msg}`)
67+
napcat.logger.error(`uncaughtException, 出错了: ${msg}`)
5468
if (Date.now() - lastNoticeTime < 1_000) return
5569
lastNoticeTime = Date.now()
5670
await actions.noticeMainOwner(napcat, `mioki 发生未捕获异常:\n\n${msg}`).catch(() => {
57-
napcat.logger.error('>>> 发送未捕获异常通知失败')
71+
napcat.logger.error('发送未捕获异常通知失败')
5872
})
5973
})
6074

6175
process.on('unhandledRejection', async (err: any) => {
6276
const msg = utils.stringifyError(err)
63-
napcat.logger.error(`>>> unhandledRejection, 出错了: ${msg}`)
77+
napcat.logger.error(`unhandledRejection, 出错了: ${msg}`)
6478
if (Date.now() - lastNoticeTime < 1_000) return
6579
lastNoticeTime = Date.now()
6680
const date = new Date().toLocaleString()
6781
await actions.noticeMainOwner(napcat, `【${date}】\n\nmioki 发生未处理异常:\n\n${msg}`).catch(() => {
68-
napcat.logger.error('>>> 发送未处理异常通知失败')
82+
napcat.logger.error('发送未处理异常通知失败')
6983
})
7084
})
7185

@@ -75,7 +89,7 @@ export async function start(options: StartOptions = {}): Promise<void> {
7589
.map((p) => ({ dirName: p, absPath: path.resolve(plugin_dir, p) }))
7690
.filter((p) => {
7791
if (!fs.existsSync(p.absPath)) {
78-
napcat.logger.warn(`>>> 插件 ${colors.bold(colors.red(p.dirName))} 不存在,已忽略`)
92+
napcat.logger.warn(`插件 ${colors.red(p.dirName)} 不存在,已忽略`)
7993
return false
8094
}
8195

@@ -89,7 +103,7 @@ export async function start(options: StartOptions = {}): Promise<void> {
89103
const plugin = (await utils.jiti.import(absPath, { default: true })) as MiokiPlugin
90104

91105
if (plugin.name !== dirName) {
92-
const tip = `>>> 插件目录名 [${colors.bold(colors.yellow(dirName))}] 和插件声明的 name [${colors.bold(colors.yellow(plugin.name))}] 不一致,可能导致重载异常,请修改一致后重启。`
106+
const tip = `插件目录名 [${colors.yellow(dirName)}] 和插件声明的 name [${colors.yellow(plugin.name)}] 不一致,可能导致重载异常,请修改一致后重启。`
93107
napcat.logger.warn(tip)
94108
actions.noticeMainOwner(napcat, tip)
95109
}
@@ -106,7 +120,7 @@ export async function start(options: StartOptions = {}): Promise<void> {
106120
const sortedUserPlugins = userPlugins.toSorted((prev, next) => (prev.priority ?? 100) - (next.priority ?? 100))
107121

108122
if (failedImportPlugins.length) {
109-
const tip = `>>> ${colors.bold(colors.red(failedImportPlugins.length))} 个插件加载失败: \n\n${failedImportPlugins.map(([dirName, err]) => `${dirName}: ${err}`).join('\n\n')}`
123+
const tip = `${colors.red(failedImportPlugins.length)} 个插件加载失败: \n\n${failedImportPlugins.map(([dirName, err]) => `${dirName}: ${err}`).join('\n\n')}`
110124
napcat.logger.warn(tip)
111125
actions.noticeMainOwner(napcat, tip)
112126
}
@@ -128,7 +142,7 @@ export async function start(options: StartOptions = {}): Promise<void> {
128142

129143
try {
130144
// 加载内置插件
131-
napcat.logger.info(`>>> 加载内置插件: ${BUILTIN_PLUGINS.map((p) => colors.bold(colors.cyan(p.name))).join(', ')}`)
145+
napcat.logger.info(`加载内置插件: ${BUILTIN_PLUGINS.map((p) => colors.cyan(p.name)).join(', ')}`)
132146
await Promise.all(BUILTIN_PLUGINS.map((p) => enablePlugin(napcat, p, 'builtin')))
133147

134148
// 按优先级分组并行加载用户插件,相同优先级的插件可以并行加载
@@ -146,7 +160,7 @@ export async function start(options: StartOptions = {}): Promise<void> {
146160
} catch (e: any) {
147161
napcat.logger.error(e?.message)
148162
await actions.noticeMainOwner(napcat, e?.message).catch(() => {
149-
napcat.logger.error('>>> 发送插件启用失败通知失败')
163+
napcat.logger.error('发送插件启用失败通知失败')
150164
})
151165
}
152166

@@ -156,18 +170,18 @@ export async function start(options: StartOptions = {}): Promise<void> {
156170

157171
const failedInfo =
158172
failedCount > 0
159-
? `${colors.bold(colors.red(failedCount))} 个失败 (导入 ${colors.bold(colors.red(failedImportPlugins.length))},启用 ${colors.bold(colors.red(failedEnablePlugins.length))})。`
173+
? `${colors.red(failedCount)} 个失败 (导入 ${colors.red(failedImportPlugins.length)},启用 ${colors.red(failedEnablePlugins.length)})`
160174
: ''
161175

162176
napcat.logger.info(
163-
`>>> 成功加载了 ${colors.bold(colors.green(runtimePlugins.size))} 个插件。${failedInfo ? failedInfo : ''}总耗时 ${colors.bold(colors.green(costTime.toFixed(2)))} ms`,
177+
`成功加载了 ${colors.green(runtimePlugins.size)} 个插件,${failedInfo ? failedInfo : ''}总耗时 ${colors.green(costTime.toFixed(2))} 毫秒`,
164178
)
165179

166-
napcat.logger.info(colors.bold(colors.green(`>>> mioki v${version} 启动完成!祝您使用愉快!🎉️`)))
180+
napcat.logger.info(colors.green(`mioki v${version} 启动完成,祝您使用愉快 🎉️`))
167181

168182
if (cfg.botConfig.online_push) {
169183
await actions.noticeMainOwner(napcat, `✅ mioki v${version} 已就绪`).catch((err) => {
170-
napcat.logger.error(`>>> 发送就绪通知失败: ${utils.stringifyError(err)}`)
184+
napcat.logger.error(`发送就绪通知失败: ${utils.stringifyError(err)}`)
171185
})
172186
}
173187
})

‎packages/mioki/src/utils.ts‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ export { default as mri } from 'mri'
2727
export { default as path } from 'node:path'
2828
export { default as dayjs } from 'dayjs'
2929
export { default as dedent } from 'dedent'
30+
export { colors, stripAnsi, box, colorize } from 'consola/utils'
3031
export { default as systemInfo } from 'systeminformation'
3132

3233
export const ChromeUA = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) Chrome/131.0.0.0'
@@ -560,7 +561,7 @@ export async function getQuoteMessage(
560561
resolve(cacheMsg)
561562
} else if (Date.now() - start > timeout) {
562563
clearInterval(timer)
563-
throw new Error(`>>> 获取引用消息超时 ${timeout}, Key: ${key}`)
564+
throw new Error(`获取引用消息超时 ${timeout}, Key: ${key}`)
564565
}
565566
}, 100)
566567
})

0 commit comments

Comments
 (0)