UNPKG

xincbot

Version:

A flexible QQ bot framework based on NapCat and node-napcat-ts

219 lines (218 loc) 10.7 kB
"use strict"; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || (function () { var ownKeys = function(o) { ownKeys = Object.getOwnPropertyNames || function (o) { var ar = []; for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k; return ar; }; return ownKeys(o); }; return function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); __setModuleDefault(result, mod); return result; }; })(); var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.Bot = void 0; const node_napcat_ts_1 = require("node-napcat-ts"); const logger_1 = require("./logger"); const config_1 = require("./config"); const plugin_manager_1 = require("./plugin-manager"); const path_1 = __importDefault(require("path")); const fs_1 = __importDefault(require("fs")); class Bot { client = null; lastHeartbeatTime = 0; botInfo = null; groups = []; friends = []; pluginManager = new plugin_manager_1.PluginManager(null, // 使用 null 断言 path_1.default.join(process.cwd(), 'data'), path_1.default.join(process.cwd(), 'config')); constructor() { // 注册进程退出处理 process.on('SIGINT', this.handleExit.bind(this)); process.on('SIGTERM', this.handleExit.bind(this)); // 修改错误处理,防止程序退出 process.on('uncaughtException', this.handleError.bind(this)); process.on('unhandledRejection', (reason) => { this.handleError(reason instanceof Error ? reason : new Error(String(reason))); }); } async start() { await config_1.configManager.validateAndPrompt(); const config = config_1.configManager.getConfig(); try { console.log(` ██╗ ██╗██╗███╗ ██╗ ██████╗██████╗ ██████╗ ████████╗ ╚██╗██╔╝██║████╗ ██║██╔════╝██╔══██╗██╔═══██╗╚══██╔══╝ ╚███╔╝ ██║██╔██╗ ██║██║ ██████╔╝██║ ██║ ██║ ██╔██╗ ██║██║╚██╗██║██║ ██╔══██╗██║ ██║ ██║ ██╔╝ ██╗██║██║ ╚████║╚██████╗██████╔╝╚██████╔╝ ██║ ╚═╝ ╚═╝╚═╝╚═╝ ╚═══╝ ╚═════╝╚═════╝ ╚═════╝ ╚═╝ `); logger_1.logger.info('正在连接到NapCat服务器...'); this.client = new node_napcat_ts_1.NCWebsocket({ host: config.host, port: config.port, protocol: 'ws' }); // 连接相关事件 this.client.on('socket.open', async () => { logger_1.logger.info('连接到NapCat服务器成功!'); try { if (!this.client) { throw new Error('WebSocket 客户端未初始化'); } this.botInfo = await this.client.get_login_info(); logger_1.logger.info(`欢迎! ${this.botInfo.nickname} 正在加载...`); // 获取群列表 this.groups = await this.client.get_group_list(); // 获取好友列表 this.friends = await this.client.get_friend_list(); logger_1.logger.info(`成功加载 ${this.groups.length} 个群, ${this.friends.length} 个好友.`); // 初始化插件管理器 this.pluginManager = new plugin_manager_1.PluginManager(this.client, path_1.default.join(process.cwd(), 'data'), path_1.default.join(process.cwd(), 'config')); // 先加载内置插件,再加载其他插件 await this.loadPlugins(); } catch (error) { logger_1.logger.error(`Failed to fetch initial data: ${error instanceof Error ? error.message : String(error)}`); } }); // 添加其他事件监听... this.setupEventListeners(); await this.client.connect(); logger_1.logger.info(`XincBot 已启动, 已登录为 ${config.host}:${config.port}`); } catch (error) { logger_1.logger.error(`XincBot 启动失败: ${error instanceof Error ? error.message : String(error)}`); process.exit(1); } } setupEventListeners() { if (!this.client) return; this.client.on('socket.error', (context) => { if ('errors' in context) { const errors = context.errors.filter(e => e !== null); if (errors.length > 0) { logger_1.logger.error(`连接错误: ${errors[0]?.code} - ${errors[0]?.syscall}`); } } }); this.client.on('socket.close', () => { logger_1.logger.warn('连接已关闭'); }); this.client.on('meta_event.heartbeat', (heartbeat) => { const now = Date.now(); if (now - this.lastHeartbeatTime >= 60000) { logger_1.logger.debug(`[心跳] 在线: ${heartbeat.status.online}`); this.lastHeartbeatTime = now; } }); // 添加消息事件监听 this.client.on('message.private.friend', async (msg) => { logger_1.logger.info(`[私聊好友] ${msg.sender.nickname}(${msg.user_id}): ${msg.raw_message}`); const originalQuickAction = msg.quick_action; msg.quick_action = async (reply) => { const result = await originalQuickAction(reply); const replyText = reply.map(msg => typeof msg === 'string' ? msg : msg.type === 'text' ? msg.data.text : `[${msg.type}]`).join(''); logger_1.logger.info(`发送成功: [私聊好友(${msg.user_id})] ${replyText}`); return result; }; }); this.client.on('message.private.group', async (msg) => { logger_1.logger.info(`[群聊] ${msg.sender.nickname}(${msg.user_id}): ${msg.raw_message}`); const originalQuickAction = msg.quick_action; msg.quick_action = async (reply) => { const result = await originalQuickAction(reply); const replyText = reply.map(msg => typeof msg === 'string' ? msg : msg.type === 'text' ? msg.data.text : `[${msg.type}]`).join(''); logger_1.logger.info(`发送成功: [群聊(${msg.user_id})] ${replyText}`); return result; }; }); this.client.on('message.group.normal', async (msg) => { logger_1.logger.info(`[群聊] ${msg.group_id} ${msg.sender.nickname}(${msg.user_id}): ${msg.raw_message}`); }); // 消息发送事件 this.client.on('message_sent.private.friend', (msg) => { logger_1.logger.info(`[私聊好友发送] 发送给 ${msg.user_id}: ${msg.raw_message}`); }); this.client.on('message_sent.private.group', (msg) => { logger_1.logger.info(`[群聊发送] 发送给 ${msg.user_id}: ${msg.raw_message}`); }); this.client.on('message_sent.group.normal', (msg) => { logger_1.logger.info(`[群聊发送] 发送给 ${msg.group_id}: ${msg.raw_message}`); }); } async handleExit() { logger_1.logger.info('收到退出信号, 正在关闭...'); await this.shutdown(); process.exit(0); } handleError(error) { console.error('未捕获错误:', error); // 记录错误但不退出 logger_1.logger.error(`未捕获错误: ${error.message}\n${error.stack}`); } async shutdown() { if (this.client) { logger_1.logger.info('正在断开与NapCat服务器的连接...'); this.client.disconnect(); this.client = null; } } async loadPlugins() { try { // 加载内置插件 await this.pluginManager.loadBuiltinPlugins(); // 加载配置中的插件 const config = config_1.configManager.getConfig(); for (const name of config.plugins) { try { const pluginPath = path_1.default.join(process.cwd(), 'plugins', name, 'index.ts'); if (!fs_1.default.existsSync(pluginPath)) { throw new Error(`插件 ${name} 未找到 at ${pluginPath}`); } // 添加时间戳来避免缓存 const plugin = (await Promise.resolve(`${`${pluginPath}?t=${Date.now()}`}`).then(s => __importStar(require(s)))).default; await this.pluginManager.loadPlugin(plugin); logger_1.logger.info(`加载插件: ${name}`); } catch (error) { logger_1.logger.error(`加载插件 ${name} 失败: ${error instanceof Error ? error.message : String(error)}`); } } } catch (error) { logger_1.logger.error(`加载插件失败: ${error instanceof Error ? error.message : String(error)}`); } } } exports.Bot = Bot; //# sourceMappingURL=bot.js.map