public static async Task OnWarn(IModeratorEventArgs warnArgs) { var currentSettings = await DatabaseQueries.GetFirstForServerAsync <WarnSetting>(warnArgs.Server.ServerId); if (currentSettings == null) { return; } List <WarnedUser> currentWarnings = await DatabaseQueries.GetAllForServerAndUserAsync <WarnedUser>(warnArgs.ActionedUser.Id, warnArgs.Server.ServerId); int warnCount = currentWarnings.Count; SocketGuildUser guildUser = ConfigProperties.Client.GetGuild(warnArgs.ActionedUser.Id).GetUser(warnArgs.ActionedUser.Id); int?muteNum = currentSettings.Mute; int?kickNum = currentSettings.Kick; int?shadowbanNum = currentSettings.Shadowban; int?banNum = currentSettings.Ban; if (warnCount == banNum) { var ban = new Ban(); try { await ban.AutoBanUserAsync(guildUser, "User has been automatically banned due to " + $"reaching the specified warning threshold for bans " + $"({warnCount} warnings)."); await ConsoleLogger.LogAsync($"User [{guildUser} | {guildUser.Id}] has been " + $"automatically banned in guild " + $"[{guildUser.Guild} | {guildUser.Guild.Id}]", LogLvl.DEBUG); } catch (Exception e) { await ConsoleLogger.LogAsync($"An attempt was made to auto-ban a user " + $"who hit the warn threshold for this event " + $"to take place. This failed due to an exception.\n" + $"Exception Message: {e.Message}\n" + $"Inner Exception Message: {e.InnerException?.Message}\n" + $"Guild: {warnArgs.Server.ServerId}", LogLvl.WARN); } return; } if (warnCount == shadowbanNum) { var shadowban = new Shadowban(); try { await shadowban.AutoShadowbanUserAsync(guildUser); await ConsoleLogger.LogAsync($"User [{guildUser} | {guildUser.Id}] has been " + $"automatically shadowbanned in guild " + $"[{guildUser.Guild} | {guildUser.Guild.Id}]", LogLvl.DEBUG); } catch (Exception e) { await ConsoleLogger.LogAsync($"An attempt was made to auto-shadowban a user " + $"who hit the warn threshold for this event " + $"to take place. This failed due to an exception.\n" + $"Exception Message: {e.Message}\n" + $"Inner Exception Message: {e.InnerException?.Message}\n" + $"Guild: {warnArgs.Server.ServerId}", LogLvl.WARN); } return; } if (warnCount == kickNum) { var kick = new Kick(); try { await kick.AutoKickUserAsync(guildUser, $"User has been automatically kicked due to " + $"reaching the specified warning threshold for kicks " + $"({warnCount} warnings)."); await ConsoleLogger.LogAsync($"User [{guildUser} | {guildUser.Id}] has been " + $"automatically kicked in guild " + $"[{guildUser.Guild} | {guildUser.Guild.Id}]", LogLvl.DEBUG); } catch (Exception e) { await ConsoleLogger.LogAsync($"An attempt was made to auto-kick a user " + $"who hit the warn threshold for this event " + $"to take place. This failed due to an exception.\n" + $"Exception Message: {e.Message}\n" + $"Inner Exception Message: {e.InnerException?.Message}\n" + $"Guild: {warnArgs.Server.ServerId}", LogLvl.WARN); } return; } if (warnCount == muteNum) { var mute = new Mute(); try { await mute.AutoMute(guildUser); await ConsoleLogger.LogAsync($"User [{guildUser} | {guildUser.Id}] has been " + $"automatically muted in guild " + $"[{guildUser.Guild} | {guildUser.Guild.Id}]", LogLvl.DEBUG); } catch (Exception e) { await ConsoleLogger.LogAsync($"An attempt was made to auto-mute a user " + $"who hit the warn threshold for this event " + $"to take place. This failed due to an exception.\n" + $"Exception Message: {e.Message}\n" + $"Inner Exception Message: {e.InnerException?.Message}\n" + $"Guild: {warnArgs.Server.ServerId}", LogLvl.WARN); } } }
private static async Task ActionUsers(IEnumerable <ulong> userIds, ulong guildId, string action) { Server server = await DatabaseQueries.GetOrCreateServerAsync(guildId); SocketGuild guild = ConfigProperties.Client.GetGuild(guildId); var guildUsers = new List <SocketGuildUser>(); foreach (ulong userId in userIds) { SocketGuildUser guildUser = guild.GetUser(userId); if (guildUser != null) { guildUsers.Add(guildUser); } } if (guildUsers.Count == 0) { await ConsoleLogger.LogAsync($"The antiraid service was triggered in guild: {guild.Id} " + "but no guild users were found from the provided set of IDs!", LogLvl.WARN); return; } KaguyaEvents.TriggerRaid(new AntiRaidEventArgs(guildUsers, guild, action)); // We need to message the actioned users, if applicable, before actioning. if (!string.IsNullOrWhiteSpace(server.AntiraidPunishmentDirectMessage)) { foreach (SocketGuildUser guildUser in guildUsers) { // content must be inside the foreach because of how we modify it below // on a per-user basis. string content = server.AntiraidPunishmentDirectMessage; var embed = new KaguyaEmbedBuilder(EmbedColor.ORANGE) { Title = "Kaguya Anti-Raid Notification", Description = content }; var sb = new StringBuilder(content); sb = sb.Replace("{USERNAME}", guildUser.UsernameAndDescriminator()); sb = sb.Replace("{USERMENTION}", guildUser.Mention); sb = sb.Replace("{SERVER}", guild.Name); sb = sb.Replace("{PUNISHMENT}", FormattedAntiraidPunishment(action.ToLower())); embed.Description = sb.ToString(); try { await guildUser.SendEmbedAsync(embed); } catch (HttpException httpEx) { await ConsoleLogger.LogAsync( $"Tried to send user {guildUser.Id} a custom anti-raid DM notification " + $"from guild [Name: {guild.Name} | ID: {guild.Id}] but failed to do so due to " + $"an Http Exception (Failure Reason: {httpEx.Reason})", LogLvl.WARN); } catch (Exception ex) { await ConsoleLogger.LogAsync(ex, $"An unexpected error occurred when attempting to send user {guildUser.Id} a custom " + $"anti-raid DM notification from guild [Name: {guild.Name} | ID: {guild.Id}].\n"); } } } switch (server.AntiRaid.Action.ToLower()) { case "mute": var mute = new Mute(); foreach (SocketGuildUser user in guildUsers) { try { await mute.AutoMute(user); } catch (Exception) { await ConsoleLogger.LogAsync("Attempted to auto-mute user " + $"{user.ToString() ?? "NULL"} as " + "part of the antiraid service, but " + "an exception was thrown!!", LogLvl.ERROR); } } break; case "kick": var kick = new Kick(); foreach (SocketGuildUser user in guildUsers) { try { await kick.AutoKickUserAsync(user, "Kaguya Anti-Raid protection."); } catch (Exception) { await ConsoleLogger.LogAsync("Attempted to auto-kick user " + $"{user.ToString() ?? "NULL"} as " + "part of the antiraid service, but " + "an exception was thrown!!", LogLvl.ERROR); } } break; case "shadowban": var sb = new Shadowban(); foreach (SocketGuildUser user in guildUsers) { try { await sb.AutoShadowbanUserAsync(user); } catch (Exception) { await ConsoleLogger.LogAsync("Attempted to auto-shadowban user " + $"{user.ToString() ?? "NULL"} as " + "part of the antiraid service, but " + "an exception was thrown!!", LogLvl.ERROR); } } break; case "ban": var ban = new Ban(); foreach (SocketGuildUser user in guildUsers) { try { await ban.AutoBanUserAsync(user, "Kaguya Anti-Raid protection."); } catch (Exception) { await ConsoleLogger.LogAsync("Attempted to auto-ban user " + $"{user.ToString() ?? "NULL"} as " + "part of the antiraid service, but " + "an exception was thrown!!", LogLvl.ERROR); } } break; default: await ConsoleLogger.LogAsync("Antiraid service triggered, but no users actioned. " + "Antiraid action string is different than expected. " + "Expected \"mute\" \"kick\" \"shadowban\" OR \"ban\". " + $"Received: '{action.ToLower()}'. " + $"Guild: {guildId}.", LogLvl.ERROR); break; } await ConsoleLogger.LogAsync($"Antiraid: Successfully actioned {guildUsers.Count:N0} users in guild {guild.Id}.", LogLvl.INFO); }