Merge branch 'rainbowcat' into feat/webui

This commit is contained in:
Clansty 2024-02-29 23:32:24 +08:00
commit 3dfdabd7ab
No known key found for this signature in database
GPG Key ID: 3A6BE8BAF2EDE134
5 changed files with 98 additions and 8 deletions

View File

@ -6,10 +6,8 @@ import {
GroupMessageEvent, GroupMessageEvent,
LogLevel, LogLevel,
Platform, PrivateMessage, Platform, PrivateMessage,
PrivateMessageEvent, XmlElem, PrivateMessageEvent,
} from 'icqq'; } from 'icqq';
import Buffer from 'buffer';
import { execSync } from 'child_process';
import random from '../utils/random'; import random from '../utils/random';
import fs from 'fs'; import fs from 'fs';
import fsP from 'fs/promises'; import fsP from 'fs/promises';
@ -18,7 +16,7 @@ import dataPath from '../helpers/dataPath';
import os from 'os'; import os from 'os';
import { Converter, Image, rand2uuid } from 'icqq/lib/message'; import { Converter, Image, rand2uuid } from 'icqq/lib/message';
import { randomBytes } from 'crypto'; 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 { pb } from 'icqq/lib/core';
import env from '../models/env'; import env from '../models/env';

View File

@ -28,6 +28,10 @@ const personalPrivateCommands = [
command: 'login', command: 'login',
description: '当 QQ 处于下线状态时,使用此命令重新登录 QQ', description: '当 QQ 处于下线状态时,使用此命令重新登录 QQ',
}), }),
new Api.BotCommand({
command: 'flags',
description: 'WARNING: EXPERIMENTAL FEATURES AHEAD!',
}),
]; ];
// 服务器零号实例的管理员 // 服务器零号实例的管理员
@ -57,6 +61,10 @@ const inChatCommands = [
command: 'search', command: 'search',
description: '搜索消息', description: '搜索消息',
}), }),
new Api.BotCommand({
command: 'q',
description: '生成 QuotLy 图片',
}),
]; ];
const groupInChatCommands = [ const groupInChatCommands = [
@ -93,6 +101,10 @@ const personalInChatCommands = [
command: 'nick', command: 'nick',
description: '获取/设置群名片', description: '获取/设置群名片',
}), }),
new Api.BotCommand({
command: 'mute',
description: '设置 QQ 成员禁言',
}),
]; ];
export default { export default {

View File

@ -20,11 +20,11 @@ export default class AliveCheckController {
} }
await message.reply({ 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<string> {
const boolToStr = (value: boolean) => { const boolToStr = (value: boolean) => {
return value ? '好' : '坏'; return value ? '好' : '坏';
}; };
@ -35,13 +35,17 @@ export default class AliveCheckController {
const tgBot = instance.tgBot; const tgBot = instance.tgBot;
const tgUser = instance.tgUser; const tgUser = instance.tgUser;
const sign = await oicq.getSign('MessageSvc.PbSendMsg', 233, Buffer.alloc(10));
const tgUserName = (tgUser.me.username || tgUser.me.usernames.length) ? const tgUserName = (tgUser.me.username || tgUser.me.usernames.length) ?
'@' + (tgUser.me.username || tgUser.me.usernames[0].username) : tgUser.me.firstName; '@' + (tgUser.me.username || tgUser.me.usernames[0].username) : tgUser.me.firstName;
messageParts.push([ messageParts.push([
`Instance #${instance.id}`, `Instance #${instance.id}`,
`QQ <code>${instance.qqUin}</code>\t` + `QQ <code>${instance.qqUin}</code>\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)}`, `TG @${tgBot.me.username}\t${boolToStr(tgBot.isOnline)}`,

View File

@ -44,6 +44,13 @@ export default class InChatCommandsController {
case '/poke': case '/poke':
await this.service.poke(message, pair); await this.service.poke(message, pair);
return true; 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': case '/forwardoff':
pair.flags |= flags.DISABLE_Q2TG | flags.DISABLE_TG2Q; pair.flags |= flags.DISABLE_Q2TG | flags.DISABLE_TG2Q;
await message.reply({ message: '转发已禁用' }); await message.reply({ message: '转发已禁用' });
@ -85,7 +92,7 @@ export default class InChatCommandsController {
return true; return true;
case '/nick': case '/nick':
if (this.instance.workMode !== 'personal' || !message.senderId?.eq(this.instance.owner)) return false; 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) { if (!params) {
await message.reply({ await message.reply({
message: `群名片:<i>${pair.qq.pickMember(this.instance.qqUin, true).card}</i>`, message: `群名片:<i>${pair.qq.pickMember(this.instance.qqUin, true).card}</i>`,

View File

@ -146,4 +146,73 @@ export default class InChatCommandsService {
}); });
return rpy.join('\n'); 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: '<i>无管理员权限</i>',
});
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: '<i>请回复一条消息</i>',
});
return;
}
if (!args.length) {
await message.reply({
message: '<i>请输入禁言的时间</i>',
});
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: '<i>请输入正确的时间</i>',
});
return;
}
await group.muteMember(target, time);
await message.reply({
message: '<i>成功</i>',
});
}
catch (e) {
await message.reply({
message: `<i>错误</i>\n${e.message}`,
});
}
}
} }