koishi-plugin-chat-patch 2.4.5 → 3.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +11 -3
- package/lib/api-handlers.d.ts +6 -1
- package/lib/config.d.ts +2 -0
- package/lib/file-manager.d.ts +102 -13
- package/lib/index.d.ts +17 -0
- package/lib/index.js +1364 -616
- package/lib/logger.d.ts +9 -0
- package/lib/message-handler.d.ts +14 -2
- package/lib/utils.d.ts +8 -3
- package/package.json +1 -1
- package/src/api-handlers.ts +115 -211
- package/src/config.ts +4 -0
- package/src/file-manager.ts +1236 -204
- package/src/index.ts +31 -105
- package/src/logger.ts +29 -0
- package/src/message-handler.ts +216 -154
- package/src/utils.ts +73 -35
package/src/index.ts
CHANGED
|
@@ -7,6 +7,7 @@ import { MessageHandler } from './message-handler'
|
|
|
7
7
|
import { FileManager } from './file-manager'
|
|
8
8
|
import { ApiHandlers } from './api-handlers'
|
|
9
9
|
import { Config } from './config'
|
|
10
|
+
import { createPluginLogger } from './logger'
|
|
10
11
|
import { Utils } from './utils'
|
|
11
12
|
|
|
12
13
|
export const name = 'chat-patch'
|
|
@@ -36,127 +37,50 @@ export const usage = `
|
|
|
36
37
|
export { Config } from './config'
|
|
37
38
|
|
|
38
39
|
export async function apply(ctx: Context, config: Config) {
|
|
39
|
-
const
|
|
40
|
-
|
|
41
|
-
const mediaDir = path.join(ctx.baseDir, 'data', 'chat-patch', 'persist-media', 'media')
|
|
42
|
-
if (require('node:fs').existsSync(mediaDir)) {
|
|
43
|
-
try {
|
|
44
|
-
const files = require('node:fs').readdirSync(mediaDir)
|
|
45
|
-
let deletedCount = 0
|
|
46
|
-
for (const file of files) {
|
|
47
|
-
const filePath = path.join(mediaDir, file)
|
|
48
|
-
try {
|
|
49
|
-
require('node:fs').unlinkSync(filePath)
|
|
50
|
-
deletedCount++
|
|
51
|
-
} catch (e) {
|
|
52
|
-
logger.warn('删除媒体文件失败:', filePath, e)
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
if (deletedCount > 0) {
|
|
56
|
-
logger.info(`启动时清理了 ${deletedCount} 个旧版本的媒体缓存文件`)
|
|
57
|
-
}
|
|
58
|
-
} catch (e) {
|
|
59
|
-
logger.warn('清理媒体文件夹失败:', e)
|
|
60
|
-
}
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
const fileManager = new FileManager(ctx, config)
|
|
64
|
-
const messageHandler = new MessageHandler(ctx, config, fileManager)
|
|
65
|
-
const apiHandlers = new ApiHandlers(ctx, config, fileManager, messageHandler)
|
|
66
|
-
const utils = new Utils(config, ctx)
|
|
40
|
+
const pluginLogger = createPluginLogger(ctx.logger('chat-patch'), config)
|
|
67
41
|
|
|
68
|
-
const
|
|
69
|
-
|
|
42
|
+
const fileManager = new FileManager(ctx, config, pluginLogger)
|
|
43
|
+
await fileManager.initialize()
|
|
70
44
|
|
|
71
|
-
const
|
|
72
|
-
const
|
|
73
|
-
|
|
74
|
-
if (originalCount !== cleanedCount) {
|
|
75
|
-
fileManager.writeChatDataToFile(cleanedData)
|
|
76
|
-
}
|
|
45
|
+
const messageHandler = new MessageHandler(ctx, config, fileManager, pluginLogger)
|
|
46
|
+
const apiHandlers = new ApiHandlers(ctx, config, fileManager, messageHandler, pluginLogger)
|
|
47
|
+
const utils = new Utils(config, ctx)
|
|
77
48
|
|
|
78
|
-
|
|
79
|
-
if (config.loggerinfo) {
|
|
80
|
-
(logger.info as (...args: any[]) => void)(...args)
|
|
81
|
-
}
|
|
82
|
-
}
|
|
49
|
+
const metadata = await fileManager.readMetadataOnly()
|
|
83
50
|
|
|
84
|
-
logInfo('
|
|
85
|
-
机器人数量: Object.keys(
|
|
86
|
-
频道数量: Object.keys(
|
|
87
|
-
total + Object.keys(
|
|
88
|
-
|
|
89
|
-
|
|
51
|
+
pluginLogger.logInfo('插件加载完成,元数据统计:', {
|
|
52
|
+
机器人数量: Object.keys(metadata.bots).length,
|
|
53
|
+
频道数量: Object.keys(metadata.channels).reduce((total, botId) =>
|
|
54
|
+
total + Object.keys(metadata.channels[botId] || {}).length, 0),
|
|
55
|
+
置顶机器人数量: metadata.pinnedBots.length,
|
|
56
|
+
置顶频道数量: metadata.pinnedChannels.length
|
|
90
57
|
})
|
|
91
58
|
|
|
92
59
|
ctx.on('message', (session) => {
|
|
93
60
|
if (utils.isPlatformBlocked(session.platform || 'unknown')) return
|
|
94
61
|
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
ctx.console.broadcast('chat-message-event', {
|
|
98
|
-
type: 'message',
|
|
99
|
-
selfId: session.selfId,
|
|
100
|
-
platform: session.platform || 'unknown',
|
|
101
|
-
channelId: session.channelId,
|
|
102
|
-
messageId: session.event?.message?.id || `msg-${timestamp}`,
|
|
103
|
-
content: session.content || '',
|
|
104
|
-
userId: session.userId || 'unknown',
|
|
105
|
-
username: session.username || session.userId || 'unknown',
|
|
106
|
-
avatar: session.event?.user?.avatar,
|
|
107
|
-
timestamp: timestamp,
|
|
108
|
-
isDirect: session.isDirect,
|
|
109
|
-
elements: utils.cleanBase64Content(session.elements, false),
|
|
110
|
-
bot: {
|
|
111
|
-
avatar: session.bot.user?.avatar,
|
|
112
|
-
name: session.bot.user?.name,
|
|
113
|
-
}
|
|
114
|
-
})
|
|
115
|
-
|
|
116
|
-
messageHandler.recordUserMessage(session, timestamp)
|
|
62
|
+
messageHandler.recordUserMessage(session, Date.now())
|
|
117
63
|
})
|
|
118
64
|
|
|
119
65
|
ctx.on('before-send', (session) => {
|
|
120
66
|
if (utils.isPlatformBlocked(session.platform || 'unknown')) return
|
|
121
67
|
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
ctx.console.broadcast('chat-bot-message-event', {
|
|
125
|
-
type: 'bot-message',
|
|
126
|
-
selfId: session.selfId,
|
|
127
|
-
platform: session.platform || 'unknown',
|
|
128
|
-
channelId: session.channelId,
|
|
129
|
-
messageId: `bot-msg-${timestamp}`,
|
|
130
|
-
content: session.content || '',
|
|
131
|
-
userId: session.selfId,
|
|
132
|
-
username: session.bot.user?.name || `Bot-${session.selfId}`,
|
|
133
|
-
avatar: session.bot.user?.avatar,
|
|
134
|
-
timestamp: timestamp,
|
|
135
|
-
sending: true,
|
|
136
|
-
elements: utils.cleanBase64Content(session.event?.message?.elements, true),
|
|
137
|
-
bot: {
|
|
138
|
-
avatar: session.bot.user?.avatar,
|
|
139
|
-
name: session.bot.user?.name,
|
|
140
|
-
}
|
|
141
|
-
})
|
|
142
|
-
|
|
143
|
-
messageHandler.recordBotMessage(session, timestamp)
|
|
68
|
+
messageHandler.recordBotMessage(session, Date.now())
|
|
144
69
|
})
|
|
145
70
|
|
|
146
|
-
|
|
147
|
-
|
|
71
|
+
let cleanupDelayTimer: (() => void) | undefined
|
|
72
|
+
let cleanupInterval: (() => void) | undefined
|
|
148
73
|
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
const cleanedData = fileManager.cleanExcessMessages(data)
|
|
74
|
+
ctx.on('ready', async () => {
|
|
75
|
+
pluginLogger.logInfo('插件启动完成,开始监听消息')
|
|
152
76
|
|
|
153
|
-
|
|
154
|
-
|
|
77
|
+
// 延后清理,避免和 Koishi 刚 ready 时的资源竞争。
|
|
78
|
+
cleanupDelayTimer = ctx.setTimeout(() => {
|
|
79
|
+
void fileManager.cleanupExcessMessagesInStorage()
|
|
80
|
+
}, 15000)
|
|
155
81
|
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
logInfo('定期清理完成,清理了', originalCount - cleanedCount, '条超量消息')
|
|
159
|
-
}
|
|
82
|
+
cleanupInterval = ctx.setInterval(() => {
|
|
83
|
+
void fileManager.cleanupExcessMessagesInStorage()
|
|
160
84
|
}, 300000)
|
|
161
85
|
})
|
|
162
86
|
|
|
@@ -168,8 +92,10 @@ export async function apply(ctx: Context, config: Config) {
|
|
|
168
92
|
})
|
|
169
93
|
|
|
170
94
|
ctx.on('dispose', () => {
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
95
|
+
cleanupDelayTimer?.()
|
|
96
|
+
cleanupInterval?.()
|
|
97
|
+
messageHandler.dispose()
|
|
98
|
+
void fileManager.dispose()
|
|
99
|
+
pluginLogger.logInfo('插件已卸载,所有待处理的消息已写入')
|
|
174
100
|
})
|
|
175
101
|
}
|
package/src/logger.ts
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { Logger } from 'koishi'
|
|
2
|
+
|
|
3
|
+
import { Config } from './config'
|
|
4
|
+
|
|
5
|
+
export interface PluginLogger {
|
|
6
|
+
logInfo(...args: unknown[]): void
|
|
7
|
+
info(...args: unknown[]): void
|
|
8
|
+
warn(...args: unknown[]): void
|
|
9
|
+
error(...args: unknown[]): void
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export function createPluginLogger(logger: Logger, config: Pick<Config, 'loggerinfo'>): PluginLogger {
|
|
13
|
+
return {
|
|
14
|
+
logInfo(...args: unknown[]) {
|
|
15
|
+
if (config.loggerinfo) {
|
|
16
|
+
Reflect.apply(logger.info, logger, args)
|
|
17
|
+
}
|
|
18
|
+
},
|
|
19
|
+
info(...args: unknown[]) {
|
|
20
|
+
Reflect.apply(logger.info, logger, args)
|
|
21
|
+
},
|
|
22
|
+
warn(...args: unknown[]) {
|
|
23
|
+
Reflect.apply(logger.warn, logger, args)
|
|
24
|
+
},
|
|
25
|
+
error(...args: unknown[]) {
|
|
26
|
+
Reflect.apply(logger.error, logger, args)
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
}
|