UNPKG

karin-plugin-teamspeak

Version:
207 lines (206 loc) 8.2 kB
import { QueryProtocol, TeamSpeak } from "ts3-nodejs-library"; import { config } from "../utils/index.js"; import karin, { logger, segment, app } from "node-karin"; import moment from "node-karin/moment"; import express from "node-karin/express"; const loggerPluginName = logger.chalk.hex("#90CAF9")(" ===== ts3 ===== "); logger.info(loggerPluginName + "初始化ts3插件"); let disNotifyNameList = []; class ts3 { teamspeak; connectTimer = 0; isReConnecting = false; //初始化 如果已经有连接了就关闭连接重新连接 init = async () => { const TS = config(); this.isReConnecting = false; disNotifyNameList = [TS.NICKNAME, ...TS.DIS_NOTIFY_NAME_LIST]; logger.info(loggerPluginName + "开始连接ts3服务器..."); if (this.teamspeak) { await this.quitTs(); } const _teamspeak = new TeamSpeak({ host: TS.HOST, protocol: QueryProtocol[TS.PROTOCOL], queryport: TS.QUERY_PORT, serverport: TS.SERVER_PORT, username: TS.USERNAME, password: TS.PASSWORD, nickname: TS.NICKNAME, }); _teamspeak.on("ready", async () => { logger.info(loggerPluginName + "ts3连接成功"); this.teamspeak = _teamspeak; }); _teamspeak.on("close", (e) => { logger.error(loggerPluginName + "ts3连接断开", e); this.handelReconnect(); }); _teamspeak.on("error", (err) => { logger.error(loggerPluginName + "ts3连接出错", err); this.handelReconnect(); }); _teamspeak.on("clientconnect", (e) => { if (!disNotifyNameList.includes(e.client.nickname)) { logger.info(loggerPluginName + e.client.nickname + "进入ts"); const msg = segment.text(e.client.nickname + "进入ts"); TS.NOTICE_GROUP_NO.forEach((groupNo) => { const contact = karin.contact("group", groupNo + ""); karin.sendMsg(karin.getBotAll()[1].account.selfId, contact, msg); }); } }); _teamspeak.on("clientdisconnect", (e) => { if (e.client) { if (!disNotifyNameList.includes(e.client.nickname)) { logger.info(loggerPluginName + e.client.nickname + "离开ts"); const msg = segment.text(e.client.nickname + "离开ts"); TS.NOTICE_GROUP_NO.forEach((groupNo) => { const contact = karin.contact("group", groupNo + ""); karin.sendMsg(karin.getBotAll()[1].account.selfId, contact, msg); }); } } }); }; //获取ts3服务器的所有对应频道的人 -- 并组装成文字可直接发 getAllChannelList = async () => { if (!this.teamspeak) { return; } //默认尝试使用渲染器,调用失败则表示未连接渲染器 let usePuppeteer = false; // try { // render.App() // } catch (error) { // usePuppeteer = false // } const TS = config(); const renderList = []; renderList.push(usePuppeteer ? `<h1>${TS.SERVER_NAME || TS.HOST}</h1>` : `====${TS.SERVER_NAME || TS.HOST}====`); renderList.push(usePuppeteer ? `<div class="tips">仅展示有人的频道</div>` : `仅展示有人的频道 `); if (!usePuppeteer) { //不渲染成图片就使用=====分割频道 renderList.push(`======`); } const channelList = await this.teamspeak.channelList(); //所有频道 let count = 0; for (let index = 0; index < channelList.length; index++) { const channel = channelList[index]; //频道 const allClient = await channel.getClients(); //在当前频道的人 //排除不显示的人 const clients = allClient.filter((c) => !disNotifyNameList.includes(c.nickname)); count += clients.length; if (clients.length == 0) continue; renderList.push(usePuppeteer ? `<ul>${channel.name}` : ` ${channel.name} `); for (let index = 0; index < clients.length; index++) { const client = clients[index]; const connectTimeSec = moment().diff(moment.unix(client.lastconnected), "second"); let connectTime = `(${Math.floor(connectTimeSec / 60)}:${Math.floor(connectTimeSec % 60)}) `; renderList.push(usePuppeteer ? `<li>${client.nickname} ${connectTime}</li>` : `- ${client.nickname} ${connectTime}`); } if (!usePuppeteer) { //不渲染成图片就使用=====分割频道 renderList.push(`======`); } else { renderList.push("</ul>"); } } renderList.splice(2, 0, usePuppeteer ? `<div class="count">当前频道内共有${count}人</div>` : `当前频道内共有${count}人`); return usePuppeteer ? renderList.join("") : renderList.join("\n"); }; //关闭连接 quitTs = async () => { if (this.teamspeak) { this.teamspeak.removeAllListeners(); this.teamspeak.quit(); this.teamspeak = undefined; } }; //重新连接 reconnectTs = async () => { if (this.teamspeak) { this.teamspeak.reconnect(config().RECONNECT_TIMER, 1000); } else { this.init(); } }; //重连逻辑 async handelReconnect() { const TS = config(); if (!this.teamspeak || this.isReConnecting) return; this.isReConnecting = true; logger.info(loggerPluginName + "重连中..."); try { await this.teamspeak.reconnect(TS.RECONNECT_TIMER, 1000); logger.info(loggerPluginName + "重连成功"); } catch (e) { logger.error(loggerPluginName + "连接TS3失败", e); } finally { this.isReConnecting = false; } } } const teamspeak3 = new ts3(); setTimeout(() => { //确保配置文件生成且正确保存 teamspeak3.init(); }, 1000); //获取ts3服务器内所有频道内在线人数 -- 给接口用 export const getAllUserList = async () => { if (teamspeak3.teamspeak) { let count = 0; const res = {}; const channelList = await teamspeak3.teamspeak.channelList().catch(() => { return []; }); //所有频道 for (let index = 0; index < channelList.length; index++) { const channel = channelList[index]; //频道 const allClient = await channel.getClients(); //在当前频道的人 //排除不显示的人 const clients = allClient.filter((c) => !disNotifyNameList.includes(c.nickname)); count += clients.length; res[channel.name] = clients.map((c) => { const connectTimeSec = moment().diff(moment.unix(c.lastconnected), "second"); let connectTime = `${Math.floor(connectTimeSec / 60)}:${Math.floor(connectTimeSec % 60)}`; return { nickName: c.nickname, //昵称 lastconnected: moment .unix(c.lastconnected) .format("YYYY-MM-DD HH:mm:ss"), //上次连接进来的时间 connectTime, //已经连接的时间 - 单位分:秒 }; }); } return { name: config().SERVER_NAME || config().HOST, res, count, }; } else { return null; } }; const router = express.Router(); router.get("/getAllUserList", async (req, res) => { const result = await getAllUserList(); res.send(result); }); //将路由挂载到express实例中 app.use("/api/teamspeak", router); export default teamspeak3;