1
0
Fork 1
mirror of https://github.com/TeamOctolings/Octobot.git synced 2025-01-31 09:09:00 +03:00

now fully configurable :D

This commit is contained in:
l1ttleO 2021-12-16 00:07:04 +05:00
parent 270fba5c3c
commit 1c9caf6d75
Signed by: Octol1ttle
GPG key ID: B77C34313AEE1FFF
11 changed files with 221 additions and 71 deletions

View file

@ -45,18 +45,29 @@ public static class Boyfriend {
try { try {
config = await JsonSerializer.DeserializeAsync<GuildConfig>(openStream) ?? throw new Exception(); config = await JsonSerializer.DeserializeAsync<GuildConfig>(openStream) ?? throw new Exception();
} catch (JsonException) { } catch (JsonException) {
config = new GuildConfig(guild.Id, "ru", "!", false); config = new GuildConfig(guild.Id, "ru", "!", false, true, true, 0, 0, 0);
} }
GuildConfigDictionary.Add(guild.Id, config); GuildConfigDictionary.Add(guild.Id, config);
} }
} }
public static GuildConfig GetGuildConfig(IGuild guild) { public static GuildConfig GetGuildConfig(IGuild guild) {
GuildConfig toReturn; var toReturn = GuildConfigDictionary.ContainsKey(guild.Id) ? GuildConfigDictionary[guild.Id]
toReturn = GuildConfigDictionary.ContainsKey(guild.Id) ? GuildConfigDictionary[guild.Id] : new GuildConfig(guild.Id, "ru", "!", false, true, true, 0, 0, 0);
: new GuildConfig(guild.Id, "ru", "!", false);
if (toReturn.Id != guild.Id) throw new Exception(); if (toReturn.Id != guild.Id) throw new Exception();
return toReturn; return toReturn;
} }
public static IGuild FindGuild(ITextChannel channel) {
foreach (var guild in Client.Guilds) {
if (guild.Channels.Any(x => x == channel)) return guild;
}
throw new Exception("Не удалось найти сервер по каналу!");
}
public static void ThrowFatal(Exception e) {
throw e;
}
} }

View file

@ -12,13 +12,14 @@ public class BanModule : ModuleBase<SocketCommandContext> {
[Command("ban")] [Command("ban")]
[Summary("Банит пользователя")] [Summary("Банит пользователя")]
[Alias("бан")] [Alias("бан")]
public async Task Run(string user, string durationString, [Remainder]string reason) { public async Task Run(string user, [Remainder]string reason) {
TimeSpan duration; TimeSpan duration;
try { try {
duration = TimeSpan.Parse(durationString); var reasonArray = reason.Split();
duration = Utils.GetTimeSpan(reasonArray[0]);
reason = string.Join(" ", reasonArray.Skip(1));
} catch (Exception e) when (e is ArgumentNullException or FormatException or OverflowException) { } catch (Exception e) when (e is ArgumentNullException or FormatException or OverflowException) {
duration = TimeSpan.FromMilliseconds(-1); duration = TimeSpan.FromMilliseconds(-1);
reason = durationString + reason;
} }
var author = Context.Guild.GetUser(Context.User.Id); var author = Context.Guild.GetUser(Context.User.Id);
var toBan = await Utils.ParseUser(user); var toBan = await Utils.ParseUser(user);
@ -35,8 +36,8 @@ public class BanModule : ModuleBase<SocketCommandContext> {
var guildBanMessage = $"({author.Username}#{author.Discriminator}) {reason}"; var guildBanMessage = $"({author.Username}#{author.Discriminator}) {reason}";
await guild.AddBanAsync(toBan, 0, guildBanMessage); await guild.AddBanAsync(toBan, 0, guildBanMessage);
var notification = $"{authorMention} банит {toBan.Mention} за {Utils.WrapInline(reason)}"; var notification = $"{authorMention} банит {toBan.Mention} за {Utils.WrapInline(reason)}";
await Utils.SilentSendAsync(guild.GetSystemChannelAsync().Result, notification); await Utils.SilentSendAsync(await guild.GetSystemChannelAsync(), notification);
await Utils.SilentSendAsync(Utils.GetAdminLogChannel(), notification); await Utils.SilentSendAsync(await Utils.GetAdminLogChannel(guild), notification);
var task = new Task(() => UnbanModule.UnbanUser(guild, guild.GetCurrentUserAsync().Result, toBan, var task = new Task(() => UnbanModule.UnbanUser(guild, guild.GetCurrentUserAsync().Result, toBan,
"Время наказания истекло")); "Время наказания истекло"));
await Utils.StartDelayed(task, duration, () => guild.GetBanAsync(toBan).Result != null); await Utils.StartDelayed(task, duration, () => guild.GetBanAsync(toBan).Result != null);

View file

@ -23,7 +23,7 @@ public class ClearModule : ModuleBase<SocketCommandContext> {
default: { default: {
var messages = await channel.GetMessagesAsync(toDelete + 1).FlattenAsync(); var messages = await channel.GetMessagesAsync(toDelete + 1).FlattenAsync();
await channel.DeleteMessagesAsync(messages); await channel.DeleteMessagesAsync(messages);
await Utils.GetAdminLogChannel().SendMessageAsync( await Utils.SilentSendAsync(await Utils.GetAdminLogChannel(Context.Guild),
$"{Context.User.Mention} удаляет {toDelete + 1} сообщений в канале " + $"{Context.User.Mention} удаляет {toDelete + 1} сообщений в канале " +
$"{Utils.MentionChannel(Context.Channel.Id)}"); $"{Utils.MentionChannel(Context.Channel.Id)}");
break; break;

View file

@ -14,13 +14,13 @@ public class KickModule : ModuleBase<SocketCommandContext> {
[Alias("кик")] [Alias("кик")]
public async Task Run(string user, [Remainder]string reason) { public async Task Run(string user, [Remainder]string reason) {
var author = Context.Guild.GetUser(Context.User.Id); var author = Context.Guild.GetUser(Context.User.Id);
var toKick = Utils.ParseMember(Context.Guild, user).Result; var toKick = await Utils.ParseMember(Context.Guild, user);
await CommandHandler.CheckPermissions(author, GuildPermission.KickMembers); await CommandHandler.CheckPermissions(author, GuildPermission.KickMembers);
await CommandHandler.CheckInteractions(author, toKick); await CommandHandler.CheckInteractions(author, toKick);
KickMember(Context.Guild, Context.Guild.GetUser(Context.User.Id), toKick, reason); KickMember(Context.Guild, Context.Guild.GetUser(Context.User.Id), toKick, reason);
} }
private static async void KickMember(IGuild guild, IGuildUser author, IGuildUser toKick, string reason) { private static async void KickMember(IGuild guild, IUser author, IGuildUser toKick, string reason) {
var authorMention = author.Mention; var authorMention = author.Mention;
await Utils.SendDirectMessage(toKick, $"Тебя кикнул {authorMention} на сервере {guild.Name} за " + await Utils.SendDirectMessage(toKick, $"Тебя кикнул {authorMention} на сервере {guild.Name} за " +
$"{Utils.WrapInline(reason)}"); $"{Utils.WrapInline(reason)}");
@ -28,7 +28,7 @@ public class KickModule : ModuleBase<SocketCommandContext> {
var guildKickMessage = $"({author.Username}#{author.Discriminator}) {reason}"; var guildKickMessage = $"({author.Username}#{author.Discriminator}) {reason}";
await toKick.KickAsync(guildKickMessage); await toKick.KickAsync(guildKickMessage);
var notification = $"{authorMention} выгоняет {toKick.Mention} за {Utils.WrapInline(reason)}"; var notification = $"{authorMention} выгоняет {toKick.Mention} за {Utils.WrapInline(reason)}";
await Utils.SilentSendAsync(guild.GetSystemChannelAsync().Result, notification); await Utils.SilentSendAsync(await guild.GetSystemChannelAsync(), notification);
await Utils.SilentSendAsync(Utils.GetAdminLogChannel(), notification); await Utils.SilentSendAsync(await Utils.GetAdminLogChannel(guild), notification);
} }
} }

View file

@ -12,16 +12,21 @@ public class MuteModule : ModuleBase<SocketCommandContext> {
[Command("mute")] [Command("mute")]
[Summary("Глушит пользователя")] [Summary("Глушит пользователя")]
[Alias("мут")] [Alias("мут")]
public async Task Run(string user, string durationString, [Remainder]string reason) { public async Task Run(string user, [Remainder]string reason) {
TimeSpan duration; TimeSpan duration;
try { try {
duration = TimeSpan.Parse(durationString); var reasonArray = reason.Split();
duration = Utils.GetTimeSpan(reasonArray[0]);
reason = string.Join(" ", reasonArray.Skip(1));
} catch (Exception e) when (e is ArgumentNullException or FormatException or OverflowException) { } catch (Exception e) when (e is ArgumentNullException or FormatException or OverflowException) {
duration = TimeSpan.FromMilliseconds(-1); duration = TimeSpan.FromMilliseconds(-1);
reason = durationString + reason;
} }
var author = Context.Guild.GetUser(Context.User.Id); var author = Context.Guild.GetUser(Context.User.Id);
var toMute = await Utils.ParseMember(Context.Guild, user); var toMute = await Utils.ParseMember(Context.Guild, user);
if (toMute.RoleIds.Any(x => x == Utils.GetMuteRole(Context.Guild).Id))
throw new Exception("Участник уже заглушен!");
if (Boyfriend.GetGuildConfig(Context.Guild).RolesRemovedOnMute.ContainsKey(toMute.Id))
throw new Exception("Кто-то убрал роль мута самостоятельно!");
await CommandHandler.CheckPermissions(author, GuildPermission.ManageMessages, GuildPermission.ManageRoles); await CommandHandler.CheckPermissions(author, GuildPermission.ManageMessages, GuildPermission.ManageRoles);
await CommandHandler.CheckInteractions(author, toMute); await CommandHandler.CheckInteractions(author, toMute);
MuteMember(Context.Guild, Context.Guild.GetUser(Context.User.Id), toMute, duration, reason); MuteMember(Context.Guild, Context.Guild.GetUser(Context.User.Id), toMute, duration, reason);
@ -32,17 +37,25 @@ public class MuteModule : ModuleBase<SocketCommandContext> {
await CommandHandler.CheckPermissions(author, GuildPermission.ManageMessages, GuildPermission.ManageRoles); await CommandHandler.CheckPermissions(author, GuildPermission.ManageMessages, GuildPermission.ManageRoles);
var authorMention = author.Mention; var authorMention = author.Mention;
var role = Utils.GetMuteRole(guild); var role = Utils.GetMuteRole(guild);
if (Boyfriend.GetGuildConfig(guild).RemoveRolesOnMute) { var config = Boyfriend.GetGuildConfig(guild);
foreach (var roleId in toMute.RoleIds) {
await toMute.RemoveRoleAsync(roleId);
} if (config.RemoveRolesOnMute) {
var rolesRemoved = new List<ulong>();
try {
foreach (var roleId in toMute.RoleIds) {
if (roleId == guild.Id) continue;
await toMute.RemoveRoleAsync(roleId);
rolesRemoved.Add(roleId);
}
} catch (NullReferenceException) {}
config.RolesRemovedOnMute.Add(toMute.Id, rolesRemoved);
config.Save();
} }
await toMute.AddRoleAsync(role); await toMute.AddRoleAsync(role);
var notification = $"{authorMention} глушит {toMute.Mention} за {Utils.WrapInline(reason)}"; var notification = $"{authorMention} глушит {toMute.Mention} за {Utils.WrapInline(reason)}";
await Utils.SilentSendAsync(guild.GetSystemChannelAsync().Result, notification); await Utils.SilentSendAsync(await guild.GetSystemChannelAsync(), notification);
await Utils.SilentSendAsync(Utils.GetAdminLogChannel(), notification); await Utils.SilentSendAsync(await Utils.GetAdminLogChannel(guild), notification);
var task = new Task(() => UnmuteModule.UnmuteMember(guild, guild.GetCurrentUserAsync().Result, toMute, var task = new Task(() => UnmuteModule.UnmuteMember(guild, guild.GetCurrentUserAsync().Result, toMute,
"Время наказания истекло")); "Время наказания истекло"));
await Utils.StartDelayed(task, duration, () => toMute.RoleIds.Any(x => x == role.Id)); await Utils.StartDelayed(task, duration, () => toMute.RoleIds.Any(x => x == role.Id));

View file

@ -1,4 +1,5 @@
using Discord.Commands; using Discord;
using Discord.Commands;
// ReSharper disable UnusedType.Global // ReSharper disable UnusedType.Global
// ReSharper disable UnusedMember.Global // ReSharper disable UnusedMember.Global
@ -10,37 +11,105 @@ public class SettingsModule : ModuleBase<SocketCommandContext> {
[Summary("Настраивает бота")] [Summary("Настраивает бота")]
[Alias("config", "настройки", "конфиг")] [Alias("config", "настройки", "конфиг")]
public async Task Run([Remainder] string s = "") { public async Task Run([Remainder] string s = "") {
await CommandHandler.CheckPermissions(Context.Guild.GetUser(Context.User.Id), GuildPermission.ManageGuild);
var config = Boyfriend.GetGuildConfig(Context.Guild); var config = Boyfriend.GetGuildConfig(Context.Guild);
var sArray = s.Split(" "); var sArray = s.Split(" ");
var guild = Context.Guild;
if (s == "") { if (s == "") {
var nl = Environment.NewLine; var nl = Environment.NewLine;
await Context.Channel.SendMessageAsync($"Текущие настройки:{nl}Язык: `{config.Lang}`" + var adminLogChannel = guild.GetTextChannel(config.AdminLogChannel);
$"{nl}Префикс: `{config.Prefix}`" + var admin = adminLogChannel == null ? "Не указан" : adminLogChannel.Mention;
$"{nl}Удалять роли при муте: " + var botLogChannel = guild.GetTextChannel(config.BotLogChannel);
$"{(config.RemoveRolesOnMute ? "Да" : "Нет")}"); var bot = botLogChannel == null ? "Не указан" : botLogChannel.Mention;
var muteRole = guild.GetRole(config.MuteRole);
var mute = muteRole == null ? "Не указана" : muteRole.Mention;
var toSend = $"Текущие настройки:{nl}" +
$"Язык (`lang`): `{config.Lang}`{nl}" +
$"Префикс (`prefix`): `{config.Prefix}`{nl}" +
$"Удалять роли при муте (`removeRolesOnMute`): {YesOrNo(config.RemoveRolesOnMute)}{nl}" +
"Использовать канал системных сообщений для уведомлений (`useSystemChannel`): " +
$"{YesOrNo(config.UseSystemChannel)}{nl}" +
$"Отправлять приветствия (`sendWelcomeMessages`): {YesOrNo(config.UseSystemChannel)}{nl}" +
$"Роль мута (`muteRole`): {mute}{nl}" +
$"Канал админ-уведомлений (`adminLogChannel`): " +
$"{admin}{nl}" +
$"Канал бот-уведомлений (`botLogChannel`): " +
$"{bot}";
await Utils.SilentSendAsync(Context.Channel as ITextChannel ?? throw new Exception(), toSend);
return; return;
} }
if (sArray[0].ToLower() == "lang") { var setting = sArray[0].ToLower();
if (sArray[1].ToLower() != "ru") throw new Exception("Язык не поддерживается!"); var value = sArray[1].ToLower();
config.Lang = sArray[1].ToLower();
ITextChannel? channel;
try {
channel = await Utils.ParseChannel(value) as ITextChannel;
} catch (FormatException) {
channel = null;
} }
IRole? role;
try {
role = Utils.ParseRole(guild, value);
}
catch (FormatException) {
role = null;
}
if (sArray[0].ToLower() == "prefix") var boolValue = ParseBool(sArray[1]);
config.Prefix = sArray[1];
if (sArray[0].ToLower() == "removerolesonmute") { switch (setting) {
try { case "lang" when sArray[1].ToLower() != "ru":
config.RemoveRolesOnMute = bool.Parse(sArray[1].ToLower()); throw new Exception("Язык не поддерживается!");
} catch (FormatException) { case "lang":
await Context.Channel.SendMessageAsync("Неверный параметр! Требуется `true` или `false`"); config.Lang = value;
return; break;
} case "prefix":
config.Prefix = value;
break;
case "removerolesonmute":
config.RemoveRolesOnMute = boolValue ??
throw new Exception("Неверный параметр! Требуется `true` или `false");
break;
case "usesystemchannel":
config.UseSystemChannel = boolValue ??
throw new Exception("Неверный параметр! Требуется `true` или `false");
break;
case "sendwelcomemessages":
config.SendWelcomeMessages = boolValue ??
throw new Exception("Неверный параметр! Требуется `true` или `false");
break;
case "adminlogchannel":
config.AdminLogChannel = Convert.ToUInt64((channel ??
throw new Exception("Указан недействительный канал!"))
.Id);
break;
case "botlogchannel":
config.BotLogChannel = Convert.ToUInt64((channel ??
throw new Exception("Указан недействительный канал!"))
.Id);
break;
case "muterole":
config.MuteRole = Convert.ToUInt64((role ?? throw new Exception("Указана недействительная роль!"))
.Id);
break;
} }
config.Save(); config.Save();
await Context.Channel.SendMessageAsync("Настройки успешно обновлены!"); await Context.Channel.SendMessageAsync("Настройки успешно обновлены!");
} }
private static bool? ParseBool(string toParse) {
try {
return bool.Parse(toParse.ToLower());
} catch (FormatException) {
return null;
}
}
private static string YesOrNo(bool isYes) {
return isYes ? "Да" : "Нет";
}
} }

View file

@ -11,12 +11,11 @@ public class UnbanModule : ModuleBase<SocketCommandContext> {
[Command("unban")] [Command("unban")]
[Summary("Возвращает пользователя из бана")] [Summary("Возвращает пользователя из бана")]
[Alias("разбан")] [Alias("разбан")]
public Task Run(string user, [Remainder] string reason) { public async Task Run(string user, [Remainder] string reason) {
var toUnban = Utils.ParseUser(user).Result; var toUnban = await Utils.ParseUser(user);
if (Context.Guild.GetBanAsync(toUnban.Id) == null) if (Context.Guild.GetBanAsync(toUnban.Id) == null)
throw new Exception("Пользователь не забанен!"); throw new Exception("Пользователь не забанен!");
UnbanUser(Context.Guild, Context.Guild.GetUser(Context.User.Id), toUnban, reason); UnbanUser(Context.Guild, Context.Guild.GetUser(Context.User.Id), toUnban, reason);
return Task.CompletedTask;
} }
public static async void UnbanUser(IGuild guild, IGuildUser author, IUser toUnban, string reason) { public static async void UnbanUser(IGuild guild, IGuildUser author, IUser toUnban, string reason) {
@ -24,7 +23,7 @@ public class UnbanModule : ModuleBase<SocketCommandContext> {
var authorMention = author.Mention; var authorMention = author.Mention;
var notification = $"{authorMention} возвращает из бана {toUnban.Mention} за {Utils.WrapInline(reason)}"; var notification = $"{authorMention} возвращает из бана {toUnban.Mention} за {Utils.WrapInline(reason)}";
await guild.RemoveBanAsync(toUnban); await guild.RemoveBanAsync(toUnban);
await Utils.SilentSendAsync(guild.GetSystemChannelAsync().Result, notification); await Utils.SilentSendAsync(await guild.GetSystemChannelAsync(), notification);
await Utils.SilentSendAsync(Utils.GetAdminLogChannel(), notification); await Utils.SilentSendAsync(await Utils.GetAdminLogChannel(guild), notification);
} }
} }

View file

@ -12,12 +12,17 @@ public class UnmuteModule : ModuleBase<SocketCommandContext> {
[Summary("Возвращает пользователя из мута")] [Summary("Возвращает пользователя из мута")]
[Alias("размут")] [Alias("размут")]
public async Task Run(string user, [Remainder] string reason) { public async Task Run(string user, [Remainder] string reason) {
var toUnmute = Utils.ParseMember(Context.Guild, user).Result; var toUnmute = await Utils.ParseMember(Context.Guild, user);
var author = Context.Guild.GetUser(Context.User.Id); var author = Context.Guild.GetUser(Context.User.Id);
await CommandHandler.CheckPermissions(author, GuildPermission.ManageMessages, GuildPermission.ManageRoles); await CommandHandler.CheckPermissions(author, GuildPermission.ManageMessages, GuildPermission.ManageRoles);
await CommandHandler.CheckInteractions(author, toUnmute); await CommandHandler.CheckInteractions(author, toUnmute);
if (toUnmute.RoleIds.All(x => x != Utils.GetMuteRole(Context.Guild).Id)) if (toUnmute.RoleIds.All(x => x != Utils.GetMuteRole(Context.Guild).Id)) {
throw new Exception("Пользователь не в муте!"); var rolesRemoved = Boyfriend.GetGuildConfig(Context.Guild).RolesRemovedOnMute;
if (!rolesRemoved.ContainsKey(toUnmute.Id)) throw new Exception("Пользователь не в муте!");
rolesRemoved.Remove(toUnmute.Id);
throw new Exception("Пользователь не в муте, но я нашёл и удалил запись о его удалённых ролях!");
}
UnmuteMember(Context.Guild, Context.Guild.GetUser(Context.User.Id), toUnmute, reason); UnmuteMember(Context.Guild, Context.Guild.GetUser(Context.User.Id), toUnmute, reason);
} }
@ -26,7 +31,16 @@ public class UnmuteModule : ModuleBase<SocketCommandContext> {
var authorMention = author.Mention; var authorMention = author.Mention;
var notification = $"{authorMention} возвращает из мута {toUnmute.Mention} за {Utils.WrapInline(reason)}"; var notification = $"{authorMention} возвращает из мута {toUnmute.Mention} за {Utils.WrapInline(reason)}";
await toUnmute.RemoveRoleAsync(Utils.GetMuteRole(guild)); await toUnmute.RemoveRoleAsync(Utils.GetMuteRole(guild));
await Utils.SilentSendAsync(guild.GetSystemChannelAsync().Result, notification); var config = Boyfriend.GetGuildConfig(guild);
await Utils.SilentSendAsync(Utils.GetAdminLogChannel(), notification);
if (config.RolesRemovedOnMute.ContainsKey(toUnmute.Id)) {
foreach (var roleId in config.RolesRemovedOnMute[toUnmute.Id]) {
await toUnmute.AddRoleAsync(roleId);
}
config.RolesRemovedOnMute.Remove(toUnmute.Id);
}
await Utils.SilentSendAsync(await guild.GetSystemChannelAsync(), notification);
await Utils.SilentSendAsync(await Utils.GetAdminLogChannel(guild), notification);
} }
} }

View file

@ -19,23 +19,27 @@ public class EventHandler {
await Commands.AddModulesAsync(Assembly.GetEntryAssembly(), null); await Commands.AddModulesAsync(Assembly.GetEntryAssembly(), null);
} }
[Obsolete("Stop hard-coding things!")] private static async Task ReadyEvent() {
private async Task ReadyEvent() {
if (_client.GetChannel(618044439939645444) is not IMessageChannel botLogChannel)
throw new Exception("Invalid bot log channel");
await botLogChannel.SendMessageAsync($"{Utils.GetBeep()}Я запустился! (C#)");
await Boyfriend.SetupGuildConfigs(); await Boyfriend.SetupGuildConfigs();
foreach (var guild in Boyfriend.Client.Guilds) {
var channel = guild.GetTextChannel(Boyfriend.GetGuildConfig(guild).BotLogChannel);
if (channel == null) continue;
await channel.SendMessageAsync($"{Utils.GetBeep()}Я запустился! (C#)");
}
} }
private static async Task MessageDeletedEvent(Cacheable<IMessage, ulong> message, private static async Task MessageDeletedEvent(Cacheable<IMessage, ulong> message,
Cacheable<IMessageChannel, ulong> channel) { Cacheable<IMessageChannel, ulong> channel) {
var msg = message.Value; var msg = message.Value;
var toSend = msg == null var toSend = msg == null
? "Удалено сообщение в канале {Utils.MentionChannel(channel.Id)}, но я забыл что там было" ? $"Удалено сообщение в канале {Utils.MentionChannel(channel.Id)}, но я забыл что там было"
: $"Удалено сообщение от {msg.Author.Mention} в канале " + : $"Удалено сообщение от {msg.Author.Mention} в канале " +
$"{Utils.MentionChannel(channel.Id)}: {Environment.NewLine}{Utils.Wrap(msg.Content)}"; $"{Utils.MentionChannel(channel.Id)}: {Environment.NewLine}{Utils.Wrap(msg.Content)}";
await Utils.SilentSendAsync(Utils.GetAdminLogChannel(), toSend); try {
await Utils.SilentSendAsync(await Utils.GetAdminLogChannel(
Boyfriend.FindGuild(channel.Value as ITextChannel)), toSend);
} catch (ArgumentException) {}
} }
private static async Task MessageReceivedEvent(SocketMessage messageParam) { private static async Task MessageReceivedEvent(SocketMessage messageParam) {
@ -46,15 +50,17 @@ public class EventHandler {
if ((message.MentionedUsers.Count > 3 || message.MentionedRoles.Count > 2) if ((message.MentionedUsers.Count > 3 || message.MentionedRoles.Count > 2)
&& !user.GuildPermissions.MentionEveryone) && !user.GuildPermissions.MentionEveryone)
BanModule.BanUser(guild, guild.GetCurrentUserAsync().Result, user, TimeSpan.FromMilliseconds(-1), BanModule.BanUser(guild, await guild.GetCurrentUserAsync(), user, TimeSpan.FromMilliseconds(-1),
"Более 3-ёх упоминаний в одном сообщении"); "Более 3-ёх упоминаний в одном сообщении");
var prevs = await message.Channel.GetMessagesAsync(3).FlattenAsync(); var prevs = await message.Channel.GetMessagesAsync(3).FlattenAsync();
var prevsArray = prevs as IMessage[] ?? prevs.ToArray(); var prevsArray = prevs as IMessage[] ?? prevs.ToArray();
var prev = prevsArray[1].Content; var prev = prevsArray[1].Content;
var prevFailsafe = prevsArray[2].Content; var prevFailsafe = prevsArray[2].Content;
if (message.Channel is not ITextChannel channel) throw new Exception();
if (!(message.HasStringPrefix(Boyfriend.GetGuildConfig(guild).Prefix, ref argPos) if (!(message.HasStringPrefix(Boyfriend.GetGuildConfig(guild).Prefix, ref argPos)
|| message.HasMentionPrefix(Boyfriend.Client.CurrentUser, ref argPos)) || message.HasMentionPrefix(Boyfriend.Client.CurrentUser, ref argPos))
|| user == await Boyfriend.FindGuild(channel).GetCurrentUserAsync()
|| user.IsBot && message.Content.Contains(prev) || message.Content.Contains(prevFailsafe)) || user.IsBot && message.Content.Contains(prev) || message.Content.Contains(prevFailsafe))
return; return;
@ -73,7 +79,10 @@ public class EventHandler {
: $"Отредактировано сообщение от {msg.Author.Mention} " + : $"Отредактировано сообщение от {msg.Author.Mention} " +
$"в канале {Utils.MentionChannel(channel.Id)}." + $"в канале {Utils.MentionChannel(channel.Id)}." +
$"{nl}До:{nl}{Utils.Wrap(msg.Content)}{nl}После:{nl}{Utils.Wrap(messageSocket.Content)}"; $"{nl}До:{nl}{Utils.Wrap(msg.Content)}{nl}После:{nl}{Utils.Wrap(messageSocket.Content)}";
await Utils.SilentSendAsync(Utils.GetAdminLogChannel(), toSend); try {
await Utils.SilentSendAsync(await Utils.GetAdminLogChannel(Boyfriend.FindGuild(channel as ITextChannel)),
toSend);
} catch (ArgumentException) {}
} }
private static async Task UserJoinedEvent(SocketGuildUser user) { private static async Task UserJoinedEvent(SocketGuildUser user) {

View file

@ -7,12 +7,25 @@ public class GuildConfig {
public string Lang { get; set; } public string Lang { get; set; }
public string Prefix { get; set; } public string Prefix { get; set; }
public bool RemoveRolesOnMute { get; set; } public bool RemoveRolesOnMute { get; set; }
public bool UseSystemChannel { get; set; }
public bool SendWelcomeMessages { get; set; }
public ulong MuteRole { get; set; }
public ulong AdminLogChannel { get; set; }
public ulong BotLogChannel { get; set; }
public Dictionary<ulong, List<ulong>> RolesRemovedOnMute { get; set; }
public GuildConfig(ulong id, string lang, string prefix, bool removeRolesOnMute) { public GuildConfig(ulong id, string lang, string prefix, bool removeRolesOnMute, bool useSystemChannel,
bool sendWelcomeMessages, ulong muteRole, ulong adminLogChannel, ulong botLogChannel) {
Id = id; Id = id;
Lang = lang; Lang = lang;
Prefix = prefix; Prefix = prefix;
RemoveRolesOnMute = removeRolesOnMute; RemoveRolesOnMute = removeRolesOnMute;
UseSystemChannel = useSystemChannel;
SendWelcomeMessages = sendWelcomeMessages;
MuteRole = muteRole;
AdminLogChannel = adminLogChannel;
BotLogChannel = botLogChannel;
RolesRemovedOnMute = new Dictionary<ulong, List<ulong>>();
} }
public async void Save() { public async void Save() {

View file

@ -1,4 +1,5 @@
using System.Text.RegularExpressions; using System.Globalization;
using System.Text.RegularExpressions;
using Discord; using Discord;
using Discord.Net; using Discord.Net;
@ -6,15 +7,16 @@ namespace Boyfriend;
public static class Utils { public static class Utils {
public static string GetBeep() { public static string GetBeep() {
var letters = new[] { "а", "о", "и"}; var letters = new[] {"а", "о", "и"};
return $"Б{letters[new Random().Next(3)]}п! "; return $"Б{letters[new Random().Next(3)]}п! ";
} }
[Obsolete("Stop hard-coding things!")] public static async Task<ITextChannel> GetAdminLogChannel(IGuild guild) {
public static ITextChannel GetAdminLogChannel() { var adminLogChannel = await ParseChannel(Boyfriend.GetGuildConfig(guild).AdminLogChannel.ToString());
if (Boyfriend.Client.GetChannel(870929165141032971) is not ITextChannel adminLogChannel) if (adminLogChannel is ITextChannel channel)
throw new Exception("Invalid admin log channel"); return channel;
return adminLogChannel;
throw new Exception("Неверный канал админ-логов для гильдии " + guild.Id);
} }
public static string Wrap(string original) { public static string Wrap(string original) {
@ -50,6 +52,14 @@ public static class Utils {
return await guild.GetUserAsync(ParseMention(mention)); return await guild.GetUserAsync(ParseMention(mention));
} }
public static async Task<IChannel> ParseChannel(string mention) {
return await Boyfriend.Client.GetChannelAsync(ParseMention(mention));
}
public static IRole ParseRole(IGuild guild, string mention) {
return guild.GetRole(ParseMention(mention));
}
public static async Task SendDirectMessage(IUser user, string toSend) { public static async Task SendDirectMessage(IUser user, string toSend) {
try { try {
await user.SendMessageAsync(toSend); await user.SendMessageAsync(toSend);
@ -60,12 +70,23 @@ public static class Utils {
} }
public static IRole GetMuteRole(IGuild guild) { public static IRole GetMuteRole(IGuild guild) {
var role = guild.Roles.FirstOrDefault(x => x.Name.ToLower() is "заключённый" or "muted"); var role = guild.Roles.FirstOrDefault(x => x.Id == Boyfriend.GetGuildConfig(guild).MuteRole);
if (role == null) throw new Exception("Не удалось найти роль мута"); if (role == null) throw new Exception("Требуется указать роль мута в настройках!");
return role; return role;
} }
public static async Task SilentSendAsync(ITextChannel channel, string text) { public static async Task SilentSendAsync(ITextChannel channel, string text) {
await channel.SendMessageAsync(text, false, null, null, AllowedMentions.None); try {
await channel.SendMessageAsync(text, false, null, null, AllowedMentions.None);
} catch (ArgumentException) {}
}
private static readonly string[] Formats = {
"%d'd'%h'h'%m'm'%s's'", "%d'd'%h'h'%m'm'", "%d'd'%h'h'%s's'", "%d'd'%h'h'", "%d'd'%m'm'%s's'", "%d'd'%m'm'",
"%d'd'%s's'", "%d'd'", "%h'h'%m'm'%s's'", "%h'h'%m'm'", "%h'h'%s's'", "%h'h'", "%m'm'%s's'", "%m'm'", "%s's'"
};
public static TimeSpan GetTimeSpan(string from) {
return TimeSpan.ParseExact(from.ToLowerInvariant(), Formats,
CultureInfo.InvariantCulture);
} }
} }