diff --git a/lib/main.dart b/lib/main.dart index 59089c3..6f7553b 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -1,5 +1,4 @@ import 'package:nyxx/nyxx.dart'; -import 'package:swan/plugins/anti_siege/plugin.dart'; import 'package:swan/plugins/anti_spam/plugin.dart'; import 'package:swan/plugins/dartdoc/plugin.dart'; import 'package:swan/plugins/database/database.dart'; @@ -35,7 +34,6 @@ Future main() async { PasteFiles(), DartdocSearch(), AntiSpam(), - AntiSiege(), ], ), ); diff --git a/lib/plugins/anti_siege/plugin.dart b/lib/plugins/anti_siege/plugin.dart deleted file mode 100644 index c52291e..0000000 --- a/lib/plugins/anti_siege/plugin.dart +++ /dev/null @@ -1,150 +0,0 @@ -import 'package:collection/collection.dart'; -import 'package:drift/drift.dart'; -import 'package:nyxx/nyxx.dart'; -import 'package:swan/plugins/anti_spam/plugin.dart'; -import 'package:swan/plugins/base/messages.dart'; -import 'package:swan/plugins/base/plugin.dart'; -import 'package:swan/plugins/database/database.dart'; -import 'package:swan/plugins/database/plugin.dart'; -import 'package:swan/plugins/env/plugin.dart'; - -class AntiSiege extends BotPlugin { - @override - String get name => 'AntiSiege'; - - @override - String? buildHelpText(NyxxGateway client) { - return 'When enabled, users who join and have a low account age will be kicked or banned.\n\n' - 'To enable this plugin, set the appropriate channels: ' - '`${client.env.commandPrefix}anti-siege #mod-logs`\n' - 'To disable this plugin, use `${client.env.commandPrefix}anti-siege off`'; - } - - static const Duration _accountAgeThreshold = Duration(hours: 5); - - @override - void afterConnect(NyxxGateway client) { - super.afterConnect(client); - - client.onMessageCreate.listen((event) => _tryUpdateConfig(client, event)); - - client.onGuildMemberAdd.listen((event) async { - final guild = await event.guild.get(); - final member = await event.member.get(); - - final config = await client.db.antiSiegeConfig(guild.id.value).first; - if (config == null) return; - - final logChannel = await client.channels[Snowflake(config.logChannelId)] - .fetch() as TextChannel; - - final user = await member.user?.get(); - if (user == null) return; - if (user.isBot) return; - - final accountAge = DateTime.now().difference(user.id.timestamp); - - if (accountAge > _accountAgeThreshold) return; - - Role? role = guild.roleList.firstWhereOrNull((e) => e.name == 'early'); - role ??= await guild.roles.create( - RoleBuilder(name: 'early'), - ); - - await member.addRole(role.id); - await member.update( - MemberUpdateBuilder( - communicationDisabledUntil: - DateTime.now().add(const Duration(minutes: 60)).toUtc(), - ), - ); - - logger.info( - 'Muted ${user.id} for having an account younger than ${_accountAgeThreshold.inMinutes} minutes.', - ); - - await logChannel.sendMessage(MessageBuilder( - embeds: [ - EmbedBuilder( - color: DiscordColor.parseHexString('#03d7fc'), - title: 'Anti-Siege', - description: - 'Muted <@${user.id}> for having an account younger than ${_accountAgeThreshold.inMinutes} minutes.', - ), - ], - )); - }); - } - - void _tryUpdateConfig(NyxxGateway client, MessageCreateEvent event) async { - RegExp command = RegExp( - r'^' - '${client.env.commandPrefix}' - r'anti-siege\s+' - r'(?(<#(\d+)>)|off)?\s*' - r'$', - ); - - RegExpMatch? match = command.firstMatch(event.message.content); - - if (match == null) return; - - final member = await event.member?.get(); - if (member == null) return; - - final channel = await event.message.channel.get(); - if (channel is! GuildChannel) return; - - final guild = await event.guild?.get(); - if (guild == null) return; - - final permissions = await computePermissions(guild, channel, member); - if (!permissions.canManageGuild) return; - - try { - final String? mode = match.namedGroup('logs'); - if (mode == null || mode.isEmpty) { - logger.info('No log channel provided for anti-siege mode.'); - await (channel as TextChannel).sendMessage(MessageBuilder( - replyId: event.message.id, - content: 'Please provide a log channel.', - )); - return; - } - - if (mode == 'off') { - logger.info('Disabled anti-siege mode for ${guild.id}'); - client.db.deleteAntiSiegeConfig(guild.id.value); - await (channel as TextChannel).sendMessage(MessageBuilder( - replyId: event.message.id, - content: 'Disabled anti-siege mode.', - )); - return; - } - - Snowflake logChannelId = - Snowflake.parse(mode.substring(2, mode.length - 1)); - - client.db.setAntiSiegeConfig( - AntiSiegeConfigsCompanion.insert( - guildId: Value(guild.id.value), - logChannelId: logChannelId.value, - ), - ); - - logger.info( - 'Enabled anti-siege mode for ${guild.id}. log in $logChannelId'); - await (channel as TextChannel).sendMessage(MessageBuilder( - replyId: event.message.id, - content: - 'Enabled anti-siege mode. Logs will be sent to <#$logChannelId>', - )); - } on FormatException { - await (channel as TextChannel).sendMessage(MessageBuilder( - replyId: event.message.id, - content: "Couldn't parse channel IDs.", - )); - logger.warning('Failed to parse anti-siege config from:\n${event.link}'); - } - } -} diff --git a/lib/plugins/database/database.dart b/lib/plugins/database/database.dart index e9c6ec7..8460160 100644 --- a/lib/plugins/database/database.dart +++ b/lib/plugins/database/database.dart @@ -5,7 +5,7 @@ import 'package:drift/native.dart'; part 'database.g.dart'; -@DriftDatabase(tables: [AntiSpamConfigs, AntiSiegeConfigs]) +@DriftDatabase(tables: [AntiSpamConfigs]) class SwanDatabase extends _$SwanDatabase { SwanDatabase() : super( @@ -15,15 +15,6 @@ class SwanDatabase extends _$SwanDatabase { @override int get schemaVersion => 2; - @override - MigrationStrategy get migration => MigrationStrategy( - onUpgrade: (migrator, from, to) async { - if (from == 1) { - await migrator.createTable(antiSiegeConfigs); - } - }, - ); - Stream antiSpamConfig(int id) => (select(antiSpamConfigs)..where((tbl) => tbl.guildId.equals(id))) .watchSingleOrNull(); @@ -33,16 +24,6 @@ class SwanDatabase extends _$SwanDatabase { Future deleteAntiSpamConfig(int id) => (delete(antiSpamConfigs)..where((tbl) => tbl.guildId.equals(id))).go(); - - Stream antiSiegeConfig(int id) => - (select(antiSiegeConfigs)..where((tbl) => tbl.guildId.equals(id))) - .watchSingleOrNull(); - - Future setAntiSiegeConfig(AntiSiegeConfigsCompanion config) => - into(antiSiegeConfigs).insertOnConflictUpdate(config); - - Future deleteAntiSiegeConfig(int id) => - (delete(antiSiegeConfigs)..where((tbl) => tbl.guildId.equals(id))).go(); } class AntiSpamConfigs extends Table { @@ -53,11 +34,3 @@ class AntiSpamConfigs extends Table { IntColumn get warningChannelId => integer()(); IntColumn get rulesChannelId => integer()(); } - -class AntiSiegeConfigs extends Table { - @override - Set get primaryKey => {guildId}; - - IntColumn get guildId => integer()(); - IntColumn get logChannelId => integer()(); -} diff --git a/lib/plugins/database/database.g.dart b/lib/plugins/database/database.g.dart index 7347b15..dff95e3 100644 --- a/lib/plugins/database/database.g.dart +++ b/lib/plugins/database/database.g.dart @@ -220,191 +220,13 @@ class AntiSpamConfigsCompanion extends UpdateCompanion { } } -class $AntiSiegeConfigsTable extends AntiSiegeConfigs - with TableInfo<$AntiSiegeConfigsTable, AntiSiegeConfig> { - @override - final GeneratedDatabase attachedDatabase; - final String? _alias; - $AntiSiegeConfigsTable(this.attachedDatabase, [this._alias]); - static const VerificationMeta _guildIdMeta = - const VerificationMeta('guildId'); - @override - late final GeneratedColumn guildId = GeneratedColumn( - 'guild_id', aliasedName, false, - type: DriftSqlType.int, requiredDuringInsert: false); - static const VerificationMeta _logChannelIdMeta = - const VerificationMeta('logChannelId'); - @override - late final GeneratedColumn logChannelId = GeneratedColumn( - 'log_channel_id', aliasedName, false, - type: DriftSqlType.int, requiredDuringInsert: true); - @override - List get $columns => [guildId, logChannelId]; - @override - String get aliasedName => _alias ?? actualTableName; - @override - String get actualTableName => $name; - static const String $name = 'anti_siege_configs'; - @override - VerificationContext validateIntegrity(Insertable instance, - {bool isInserting = false}) { - final context = VerificationContext(); - final data = instance.toColumns(true); - if (data.containsKey('guild_id')) { - context.handle(_guildIdMeta, - guildId.isAcceptableOrUnknown(data['guild_id']!, _guildIdMeta)); - } - if (data.containsKey('log_channel_id')) { - context.handle( - _logChannelIdMeta, - logChannelId.isAcceptableOrUnknown( - data['log_channel_id']!, _logChannelIdMeta)); - } else if (isInserting) { - context.missing(_logChannelIdMeta); - } - return context; - } - - @override - Set get $primaryKey => {guildId}; - @override - AntiSiegeConfig map(Map data, {String? tablePrefix}) { - final effectivePrefix = tablePrefix != null ? '$tablePrefix.' : ''; - return AntiSiegeConfig( - guildId: attachedDatabase.typeMapping - .read(DriftSqlType.int, data['${effectivePrefix}guild_id'])!, - logChannelId: attachedDatabase.typeMapping - .read(DriftSqlType.int, data['${effectivePrefix}log_channel_id'])!, - ); - } - - @override - $AntiSiegeConfigsTable createAlias(String alias) { - return $AntiSiegeConfigsTable(attachedDatabase, alias); - } -} - -class AntiSiegeConfig extends DataClass implements Insertable { - final int guildId; - final int logChannelId; - const AntiSiegeConfig({required this.guildId, required this.logChannelId}); - @override - Map toColumns(bool nullToAbsent) { - final map = {}; - map['guild_id'] = Variable(guildId); - map['log_channel_id'] = Variable(logChannelId); - return map; - } - - AntiSiegeConfigsCompanion toCompanion(bool nullToAbsent) { - return AntiSiegeConfigsCompanion( - guildId: Value(guildId), - logChannelId: Value(logChannelId), - ); - } - - factory AntiSiegeConfig.fromJson(Map json, - {ValueSerializer? serializer}) { - serializer ??= driftRuntimeOptions.defaultSerializer; - return AntiSiegeConfig( - guildId: serializer.fromJson(json['guildId']), - logChannelId: serializer.fromJson(json['logChannelId']), - ); - } - @override - Map toJson({ValueSerializer? serializer}) { - serializer ??= driftRuntimeOptions.defaultSerializer; - return { - 'guildId': serializer.toJson(guildId), - 'logChannelId': serializer.toJson(logChannelId), - }; - } - - AntiSiegeConfig copyWith({int? guildId, int? logChannelId}) => - AntiSiegeConfig( - guildId: guildId ?? this.guildId, - logChannelId: logChannelId ?? this.logChannelId, - ); - @override - String toString() { - return (StringBuffer('AntiSiegeConfig(') - ..write('guildId: $guildId, ') - ..write('logChannelId: $logChannelId') - ..write(')')) - .toString(); - } - - @override - int get hashCode => Object.hash(guildId, logChannelId); - @override - bool operator ==(Object other) => - identical(this, other) || - (other is AntiSiegeConfig && - other.guildId == this.guildId && - other.logChannelId == this.logChannelId); -} - -class AntiSiegeConfigsCompanion extends UpdateCompanion { - final Value guildId; - final Value logChannelId; - const AntiSiegeConfigsCompanion({ - this.guildId = const Value.absent(), - this.logChannelId = const Value.absent(), - }); - AntiSiegeConfigsCompanion.insert({ - this.guildId = const Value.absent(), - required int logChannelId, - }) : logChannelId = Value(logChannelId); - static Insertable custom({ - Expression? guildId, - Expression? logChannelId, - }) { - return RawValuesInsertable({ - if (guildId != null) 'guild_id': guildId, - if (logChannelId != null) 'log_channel_id': logChannelId, - }); - } - - AntiSiegeConfigsCompanion copyWith( - {Value? guildId, Value? logChannelId}) { - return AntiSiegeConfigsCompanion( - guildId: guildId ?? this.guildId, - logChannelId: logChannelId ?? this.logChannelId, - ); - } - - @override - Map toColumns(bool nullToAbsent) { - final map = {}; - if (guildId.present) { - map['guild_id'] = Variable(guildId.value); - } - if (logChannelId.present) { - map['log_channel_id'] = Variable(logChannelId.value); - } - return map; - } - - @override - String toString() { - return (StringBuffer('AntiSiegeConfigsCompanion(') - ..write('guildId: $guildId, ') - ..write('logChannelId: $logChannelId') - ..write(')')) - .toString(); - } -} - abstract class _$SwanDatabase extends GeneratedDatabase { _$SwanDatabase(QueryExecutor e) : super(e); late final $AntiSpamConfigsTable antiSpamConfigs = $AntiSpamConfigsTable(this); - late final $AntiSiegeConfigsTable antiSiegeConfigs = - $AntiSiegeConfigsTable(this); @override Iterable> get allTables => allSchemaEntities.whereType>(); @override - List get allSchemaEntities => - [antiSpamConfigs, antiSiegeConfigs]; + List get allSchemaEntities => [antiSpamConfigs]; }