diff --git a/config/config.sample.yaml b/config/config.sample.yaml index 43d5913ed6bd0399342f547a7eda40569272fd9c..40395063a94dca5e83ca0a6b72471a004fcfbcf3 100644 --- a/config/config.sample.yaml +++ b/config/config.sample.yaml @@ -102,6 +102,8 @@ limits: # echos = (Copies of a sent message may arrive from discord before we've # fininished handling it, causing us to echo it back to the room) discordSendDelay: 1500 + # Set a maximum of rooms to be bridged. + # roomCount: 20 ghosts: # Pattern for the ghosts nick, available is :nick, :username, :tag and :id nickPattern: ":nick" diff --git a/config/config.schema.yaml b/config/config.schema.yaml index 1a2381c30555576f136a816866adc3135a4888ae..9409bab4d4494e4347853b79d54c41c7fee95570 100644 --- a/config/config.schema.yaml +++ b/config/config.schema.yaml @@ -97,6 +97,8 @@ properties: type: "number" discordSendDelay: type: "number" + roomCount: + type: "number" channel: type: "object" properties: diff --git a/src/config.ts b/src/config.ts index 3747e66e2958926e905e41ae98985e157f124413..0d49c57983988b29aa97cb33a72be12132777d6d 100644 --- a/src/config.ts +++ b/src/config.ts @@ -141,6 +141,7 @@ export class DiscordBridgeConfigChannelDeleteOptions { class DiscordBridgeConfigLimits { public roomGhostJoinDelay: number = 6000; public discordSendDelay: number = 1500; + public roomCount: number = -1; } export class LoggingFile { diff --git a/src/matrixcommandhandler.ts b/src/matrixcommandhandler.ts index 61cedf68afbacd7e0efe0a6dd399e37456538f5e..da9d97fad47dd1b7e4f066e0cb037d1e54a9e21c 100644 --- a/src/matrixcommandhandler.ts +++ b/src/matrixcommandhandler.ts @@ -84,6 +84,14 @@ export class MatrixCommandHandler { if (!guildId || !channelId) { return "Invalid syntax. For more information try `!discord help bridge`"; } + if (await this.provisioner.RoomCountLimitReached(this.config.limits.roomCount)) { + log.info(`Room count limit (value: ${this.config.limits.roomCount}) reached: Rejecting command to bridge new matrix room ${event.room_id} to ${guildId}/${channelId}`); + await this.bridge.botIntent.sendText( + event.room_id, + `This bridge has reached its room limit of ${this.config.limits.roomCount}. Unbridge another room to allow for new connections.`, + "m.notice", + ); + } try { const discordResult = await this.discord.LookupRoom(guildId, channelId); const channel = discordResult.channel as Discord.TextChannel; diff --git a/src/provisioner.ts b/src/provisioner.ts index 54de31d4ce28d15abeb0121ffc15a06d61b41ea0..50c3fec03cf0a9bfbee121d2854ec685de39fb69 100644 --- a/src/provisioner.ts +++ b/src/provisioner.ts @@ -40,6 +40,15 @@ export class Provisioner { return this.roomStore.linkRooms(local, remote); } + /** + * Returns if the room count limit has been reached. + * This can be set by the bridge admin and prevents new rooms from being bridged. + * @returns Has the limit been reached? + */ + public async RoomCountLimitReached(limit: number): Promise<boolean> { + return limit >= 0 || limit >= await this.roomStore.countEntries(); + } + public async UnbridgeChannel(channel: Discord.TextChannel, rId?: string) { const roomsRes = await this.roomStore.getEntriesByRemoteRoomData({ discord_channel: channel.id,