diff --git a/main/src/client/OicqClient.ts b/main/src/client/OicqClient.ts index 578076f..f0b94a3 100644 --- a/main/src/client/OicqClient.ts +++ b/main/src/client/OicqClient.ts @@ -6,10 +6,8 @@ import { GroupMessageEvent, LogLevel, Platform, PrivateMessage, - PrivateMessageEvent, XmlElem, + PrivateMessageEvent, } from 'icqq'; -import Buffer from 'buffer'; -import { execSync } from 'child_process'; import random from '../utils/random'; import fs from 'fs'; import fsP from 'fs/promises'; @@ -18,7 +16,7 @@ import dataPath from '../helpers/dataPath'; import os from 'os'; import { Converter, Image, rand2uuid } from 'icqq/lib/message'; import { randomBytes } from 'crypto'; -import { escapeXml, gzip, timestamp } from 'icqq/lib/common'; +import { gzip, timestamp } from 'icqq/lib/common'; import { pb } from 'icqq/lib/core'; import env from '../models/env'; diff --git a/main/src/constants/commands.ts b/main/src/constants/commands.ts index 962fc37..a9c4c56 100644 --- a/main/src/constants/commands.ts +++ b/main/src/constants/commands.ts @@ -28,6 +28,10 @@ const personalPrivateCommands = [ command: 'login', description: '当 QQ 处于下线状态时,使用此命令重新登录 QQ', }), + new Api.BotCommand({ + command: 'flags', + description: 'WARNING: EXPERIMENTAL FEATURES AHEAD!', + }), ]; // 服务器零号实例的管理员 @@ -57,6 +61,10 @@ const inChatCommands = [ command: 'search', description: '搜索消息', }), + new Api.BotCommand({ + command: 'q', + description: '生成 QuotLy 图片', + }), ]; const groupInChatCommands = [ @@ -93,6 +101,10 @@ const personalInChatCommands = [ command: 'nick', description: '获取/设置群名片', }), + new Api.BotCommand({ + command: 'mute', + description: '设置 QQ 成员禁言', + }), ]; export default { diff --git a/main/src/controllers/AliveCheckController.ts b/main/src/controllers/AliveCheckController.ts index 2f3f3b6..4de2a83 100644 --- a/main/src/controllers/AliveCheckController.ts +++ b/main/src/controllers/AliveCheckController.ts @@ -20,11 +20,11 @@ export default class AliveCheckController { } await message.reply({ - message: this.genMessage(this.instance.id === 0 ? Instance.instances : [this.instance]), + message: await this.genMessage(this.instance.id === 0 ? Instance.instances : [this.instance]), }); }; - private genMessage(instances: Instance[]): string { + private async genMessage(instances: Instance[]): Promise { const boolToStr = (value: boolean) => { return value ? '好' : '坏'; }; @@ -35,13 +35,17 @@ export default class AliveCheckController { const tgBot = instance.tgBot; const tgUser = instance.tgUser; + const sign = await oicq.getSign('MessageSvc.PbSendMsg', 233, Buffer.alloc(10)); + const tgUserName = (tgUser.me.username || tgUser.me.usernames.length) ? '@' + (tgUser.me.username || tgUser.me.usernames[0].username) : tgUser.me.firstName; messageParts.push([ `Instance #${instance.id}`, `QQ ${instance.qqUin}\t` + - `${boolToStr(oicq.isOnline())}\t${oicq.stat.msg_cnt_per_min} msg/min`, + `${boolToStr(oicq.isOnline())}`, + + `签名服务器\t${boolToStr(sign.length > 0)}`, `TG @${tgBot.me.username}\t${boolToStr(tgBot.isOnline)}`, diff --git a/main/src/controllers/InChatCommandsController.ts b/main/src/controllers/InChatCommandsController.ts index 6f55a12..a092e6e 100644 --- a/main/src/controllers/InChatCommandsController.ts +++ b/main/src/controllers/InChatCommandsController.ts @@ -44,6 +44,13 @@ export default class InChatCommandsController { case '/poke': await this.service.poke(message, pair); return true; + case '/unmute': + messageParts.unshift('0'); + case '/mute': + if (this.instance.workMode !== 'personal' || !message.senderId?.eq(this.instance.owner)) return false; + if (!(pair.qq instanceof Group)) return true; + await this.service.mute(message, pair, messageParts); + return true; case '/forwardoff': pair.flags |= flags.DISABLE_Q2TG | flags.DISABLE_TG2Q; await message.reply({ message: '转发已禁用' }); @@ -85,7 +92,7 @@ export default class InChatCommandsController { return true; case '/nick': if (this.instance.workMode !== 'personal' || !message.senderId?.eq(this.instance.owner)) return false; - if (!(pair.qq instanceof Group)) return; + if (!(pair.qq instanceof Group)) return true; if (!params) { await message.reply({ message: `群名片:${pair.qq.pickMember(this.instance.qqUin, true).card}`, diff --git a/main/src/services/InChatCommandsService.ts b/main/src/services/InChatCommandsService.ts index 2679c43..fcd4b02 100644 --- a/main/src/services/InChatCommandsService.ts +++ b/main/src/services/InChatCommandsService.ts @@ -146,4 +146,73 @@ export default class InChatCommandsService { }); return rpy.join('\n'); } + + // 禁言 QQ 成员 + public async mute(message: Api.Message, pair: Pair, args: string[]) { + try { + const group = pair.qq as Group; + if(!(group.is_admin||group.is_owner)){ + await message.reply({ + message: '无管理员权限', + }); + return; + } + let target: number; + if (message.replyToMsgId) { + const dbEntry = await db.message.findFirst({ + where: { + tgChatId: pair.tgId, + tgMsgId: message.replyToMsgId, + }, + }); + if (dbEntry) { + target = Number(dbEntry.qqSenderId); + } + } + if (!target) { + await message.reply({ + message: '请回复一条消息', + }); + return; + } + if (!args.length) { + await message.reply({ + message: '请输入禁言的时间', + }); + return; + } + let time = Number(args[0]); + if (isNaN(time)) { + const unit = args[0].substring(args[0].length - 1, args[0].length); + time = Number(args[0].substring(0, args[0].length - 1)); + + switch (unit) { + case 'd': + time *= 24; + case 'h': + time *= 60; + case 'm': + time *= 60; + break; + default: + time = NaN; + } + } + if (isNaN(time)) { + await message.reply({ + message: '请输入正确的时间', + }); + return; + } + await group.muteMember(target, time); + await message.reply({ + message: '成功', + }); + } + catch (e) { + await message.reply({ + message: `错误\n${e.message}`, + }); + } + } }