diff --git a/prisma/schema.prisma b/prisma/schema.prisma index 4134f56..2f18948 100644 --- a/prisma/schema.prisma +++ b/prisma/schema.prisma @@ -45,6 +45,7 @@ model Instance { qqBotId Int? qqBot QqBot? @relation(fields: [qqBotId], references: [id], onDelete: Cascade) reportUrl String? + flags Int @default(0) } model QqBot { diff --git a/src/controllers/ConfigController.ts b/src/controllers/ConfigController.ts index e78d429..93e8960 100644 --- a/src/controllers/ConfigController.ts +++ b/src/controllers/ConfigController.ts @@ -12,6 +12,7 @@ import { } from 'icqq'; import Instance from '../models/Instance'; import { getLogger, Logger } from 'log4js'; +import { editFlags } from '../utils/flagControl'; export default class ConfigController { private readonly configService: ConfigService; @@ -48,6 +49,15 @@ export default class ConfigController { return false; } else if (message.isPrivate) { + switch (messageSplit[0]) { + case '/flag': + case '/flags': + messageSplit.shift(); + await message.reply({ + message: await editFlags(messageSplit, this.instance), + }); + return true; + } if (this.instance.workMode === 'personal') { switch (messageSplit[0]) { case '/addfriend': diff --git a/src/controllers/ForwardController.ts b/src/controllers/ForwardController.ts index 9db51d2..389975d 100644 --- a/src/controllers/ForwardController.ts +++ b/src/controllers/ForwardController.ts @@ -46,7 +46,7 @@ export default class ForwardController { const target = event.message_type === 'private' ? event.friend : event.group; const pair = this.instance.forwardPairs.find(target); if (!pair) return; - if (pair.flags & flags.DISABLE_Q2TG) return; + if ((pair.flags | this.instance.flags) & flags.DISABLE_Q2TG) return; // 如果是多张图片的话,是一整条消息,只过一次,所以不受这个判断影响 let existed = event.message_type === 'private' && await db.message.findFirst({ where: { @@ -102,7 +102,7 @@ export default class ForwardController { if (message.senderId?.eq(this.instance.botMe.id)) return true; const pair = this.instance.forwardPairs.find(message.chat); if (!pair) return false; - if (pair.flags & flags.DISABLE_TG2Q) return; + if ((pair.flags | this.instance.flags) & flags.DISABLE_TG2Q) return; const qqMessagesSent = await this.forwardService.forwardFromTelegram(message, pair); if (qqMessagesSent) { // 更新数据库 @@ -140,7 +140,7 @@ export default class ForwardController { private onQqGroupMemberIncrease = async (event: MemberIncreaseEvent) => { try { const pair = this.instance.forwardPairs.find(event.group); - if (pair?.flags & flags.DISABLE_JOIN_NOTICE) return false; + if ((pair?.flags | this.instance.flags) & flags.DISABLE_JOIN_NOTICE) return false; const avatar = await getAvatar(event.user_id); await pair.tg.sendMessage({ file: new CustomFile('avatar.png', avatar.length, '', avatar), @@ -156,7 +156,7 @@ export default class ForwardController { private onTelegramParticipant = async (event: Api.UpdateChannelParticipant) => { try { const pair = this.instance.forwardPairs.find(event.channelId); - if (pair?.flags & flags.DISABLE_JOIN_NOTICE) return false; + if ((pair?.flags | this.instance.flags) & flags.DISABLE_JOIN_NOTICE) return false; if ( !(event.newParticipant instanceof Api.ChannelParticipantAdmin) && !(event.newParticipant instanceof Api.ChannelParticipantCreator) && @@ -174,7 +174,7 @@ export default class ForwardController { private onQqPoke = async (event: FriendPokeEvent | GroupPokeEvent) => { const target = event.notice_type === 'friend' ? event.friend : event.group; const pair = this.instance.forwardPairs.find(target); - if (pair?.flags & flags.DISABLE_POKE) return; + if ((pair?.flags | this.instance.flags) & flags.DISABLE_POKE) return; let operatorName: string, targetName: string; if (target instanceof Friend) { if (event.operator_id === target.user_id) { diff --git a/src/controllers/InChatCommandsController.ts b/src/controllers/InChatCommandsController.ts index 48538a4..6f55a12 100644 --- a/src/controllers/InChatCommandsController.ts +++ b/src/controllers/InChatCommandsController.ts @@ -7,6 +7,7 @@ import { Api } from 'telegram'; import { Group } from 'icqq'; import RecoverMessageHelper from '../helpers/RecoverMessageHelper'; import flags from '../constants/flags'; +import { editFlags } from '../utils/flagControl'; export default class InChatCommandsController { private readonly service: InChatCommandsService; @@ -74,7 +75,7 @@ export default class InChatCommandsController { return true; } await message.reply({ - message: await this.service.editFlags(messageParts, pair), + message: await editFlags(messageParts, pair), }); return true; case '/refresh': diff --git a/src/helpers/inChatCommandsHelper.ts b/src/helpers/inChatCommandsHelper.ts deleted file mode 100644 index 07f5bb7..0000000 --- a/src/helpers/inChatCommandsHelper.ts +++ /dev/null @@ -1,14 +0,0 @@ -import flags from '../constants/flags'; - -export default { - displayFlag(flag: number) { - const enabled = []; - for (const name in flags) { - const value = flags[name] as any as number; - if (flag & value) { - enabled.push(name); - } - } - return ['0b' + flag.toString(2), ...enabled].join('\n'); - }, -}; diff --git a/src/models/Instance.ts b/src/models/Instance.ts index e93bd59..f244b45 100644 --- a/src/models/Instance.ts +++ b/src/models/Instance.ts @@ -32,6 +32,7 @@ export default class Instance { private _userSessionId = 0; private _qq: QqBot; private _reportUrl: string; + private _flags: number; private readonly log: Logger; @@ -84,6 +85,7 @@ export default class Instance { this._isSetup = dbEntry.isSetup; this._workMode = dbEntry.workMode; this._reportUrl = dbEntry.reportUrl; + this._flags = dbEntry.flags; } private async init(botToken?: string) { @@ -255,6 +257,10 @@ export default class Instance { return this._reportUrl; } + get flags() { + return this._flags; + } + set owner(owner: number) { this._owner = owner; db.instance.update({ @@ -309,10 +315,20 @@ export default class Instance { } set reportUrl(reportUrl: string) { + this._reportUrl = reportUrl; db.instance.update({ data: { reportUrl }, where: { id: this.id }, }) .then(() => this.log.trace(reportUrl)); } + + set flags(value) { + this._flags = value; + db.instance.update({ + data: { flags: value }, + where: { id: this.id }, + }) + .then(() => this.log.trace(value)); + } } diff --git a/src/services/DeleteMessageService.ts b/src/services/DeleteMessageService.ts index 54d9bf0..3865cfa 100644 --- a/src/services/DeleteMessageService.ts +++ b/src/services/DeleteMessageService.ts @@ -145,7 +145,7 @@ export default class DeleteMessageService { }, }); if (!message) return; - if (pair.flags & flags.NO_DELETE_MESSAGE) { + if ((pair.flags | this.instance.flags) & flags.NO_DELETE_MESSAGE) { await pair.tg.editMessages({ message: message.tgMsgId, text: `${message.tgMessageText}\n此消息已删除`, diff --git a/src/services/InChatCommandsService.ts b/src/services/InChatCommandsService.ts index 92933e4..4c91cf1 100644 --- a/src/services/InChatCommandsService.ts +++ b/src/services/InChatCommandsService.ts @@ -11,8 +11,6 @@ import db from '../models/db'; import { Friend, Group } from 'icqq'; import { format } from 'date-and-time'; import ZincSearch from 'zincsearch-node'; -import flags from '../constants/flags'; -import inChatCommandsHelper from '../helpers/inChatCommandsHelper'; export default class InChatCommandsService { private readonly log: Logger; @@ -147,35 +145,4 @@ export default class InChatCommandsService { }); return rpy.join('\n'); } - - public async editFlags(params: string[], pair: Pair) { - if (!params.length) { - return inChatCommandsHelper.displayFlag(pair.flags); - } - if (params.length !== 2) return '参数格式错误'; - - let operand = Number(params[1]); - if (isNaN(operand)) { - operand = flags[params[1].toUpperCase()]; - } - if (isNaN(operand)) return 'flag 格式错误'; - - switch (params[0]) { - case 'add': - case 'set': - pair.flags |= operand; - break; - case 'rm': - case 'remove': - case 'del': - case 'delete': - pair.flags &= ~operand; - break; - case 'put': - pair.flags = operand; - break; - } - - return inChatCommandsHelper.displayFlag(pair.flags); - } } diff --git a/src/utils/flagControl.ts b/src/utils/flagControl.ts new file mode 100644 index 0000000..dc8b009 --- /dev/null +++ b/src/utils/flagControl.ts @@ -0,0 +1,45 @@ +import flags from '../constants/flags'; +import { Pair } from '../models/Pair'; +import Instance from '../models/Instance'; + +const displayFlag = (flag: number) => { + const enabled = []; + for (const name in flags) { + const value = flags[name] as any as number; + if (flag & value) { + enabled.push(name); + } + } + return ['0b' + flag.toString(2), ...enabled].join('\n'); +}; + +export const editFlags = async (params: string[], target: Pair | Instance) => { + if (!params.length) { + return displayFlag(target.flags); + } + if (params.length !== 2) return '参数格式错误'; + + let operand = Number(params[1]); + if (isNaN(operand)) { + operand = flags[params[1].toUpperCase()]; + } + if (isNaN(operand)) return 'flag 格式错误'; + + switch (params[0]) { + case 'add': + case 'set': + target.flags |= operand; + break; + case 'rm': + case 'remove': + case 'del': + case 'delete': + target.flags &= ~operand; + break; + case 'put': + target.flags = operand; + break; + } + + return displayFlag(target.flags); +};