public async Task SyncBans(DiscordGuild guild)
        {
            var syncedBans = await redis.GetAsync <List <ulong> >(RedisKeyNaming.SyncedInfractions);

            foreach (var bannedUser in syncedBans)
            {
                await guild.BanMemberAsync(bannedUser, 0, "Synced with the database which contains all reported users (banned)");

                await Task.Delay(TimeSpan.FromSeconds(3));
            }
        }
        private async void Detection_FakeMuteExploitDetected(AbuseTracker detectedUser, DiscordUser user)
        {
            if (!resetTask?.IsCompleted ?? false)
            {
                return;
            }

            await Logger.Warning("Exploit", $"Detected {detectedUser.UserID} speaking while muted for {(DateTime.Now - detectedUser.FirstHit)?.TotalSeconds} seconds.");

            // We put this on its own thread since it shouldn't interrupt any of this code
            resetTask = Task.Run(async() => await Cooldown(detectedUser));

            if (!config.BanDetectedUsers)
            {
                return;
            }

            var member = await guild.GetMemberAsync(detectedUser.UserID);

            try
            {
                await member.SendMessageAsync($"You have been banned from {guild.Name} because you were detected using a voice chat exploit.\n\n" +
                                              "If you believe this is an error, please contact the server administrators.");
            }
            catch (Exception e)
            {
                await Logger.Warning("Exploit", $"Unable to send a DM to {member.DisplayName}#{member.Discriminator} [{detectedUser.UserID}]: {e.Message}");
            }

            try
            {
                await guild.BanMemberAsync(member, 0, $"{client.CurrentUser.Username}: Detected abuse of the Fake Mute exploit");
            }
            catch (Exception e)
            {
                await Logger.Error("Exploit", $"Unable to ban {member.DisplayName}#{member.Discriminator} [{detectedUser.UserID}]: {e.Message}");
            }
        }
Beispiel #3
0
        public static async Task <bool> BanFromServerAsync(ulong targetUserId, string reason, ulong moderatorId, DiscordGuild guild, int deleteDays = 7, DiscordChannel channel = null, TimeSpan banDuration = default, bool appealable = false)
        {
            DiscordUser naughtyUser = await Program.discord.GetUserAsync(targetUserId);

            bool           permaBan   = false;
            DiscordChannel logChannel = await Program.discord.GetChannelAsync(Program.cfgjson.LogChannel);

            DiscordRole   mutedRole  = guild.GetRole(Program.cfgjson.MutedRole);
            DateTime?     expireTime = DateTime.Now + banDuration;
            DiscordMember moderator  = await guild.GetMemberAsync(moderatorId);

            if (banDuration == default)
            {
                permaBan   = true;
                expireTime = null;
            }

            MemberPunishment newBan = new MemberPunishment()
            {
                MemberId   = targetUserId,
                ModId      = moderatorId,
                ServerId   = guild.Id,
                ExpireTime = expireTime
            };

            await Program.db.HashSetAsync("bans", targetUserId, JsonConvert.SerializeObject(newBan));

            try
            {
                DiscordMember targetMember = await guild.GetMemberAsync(targetUserId);

                if (permaBan)
                {
                    if (appealable)
                    {
                        await targetMember.SendMessageAsync($"{Program.cfgjson.Emoji.Banned} You have been banned from **{guild.Name}**!\nReason: **{reason}**\nYou can appeal the ban here: https://msft.chat/member/#ban-appeal-process");
                    }
                    else
                    {
                        await targetMember.SendMessageAsync($"{Program.cfgjson.Emoji.Banned} You have been permanently banned from **{guild.Name}**!\nReason: **{reason}**");
                    }
                }
                else
                {
                    await targetMember.SendMessageAsync($"{Program.cfgjson.Emoji.Banned} You have been banned from **{guild.Name}** for {Warnings.TimeToPrettyFormat(banDuration, false)}!\nReason: **{reason}**");
                }
            }
            catch
            {
                // A DM failing to send isn't important.
            }

            try
            {
                await guild.BanMemberAsync(targetUserId, deleteDays, reason);

                if (permaBan)
                {
                    await logChannel.SendMessageAsync($"{Program.cfgjson.Emoji.Banned} <@{targetUserId}> was permanently banned by `{moderator.Username}#{moderator.Discriminator}` (`{moderatorId}`).\nReason: **{reason}**");
                }
                else
                {
                    await logChannel.SendMessageAsync($"{Program.cfgjson.Emoji.Banned} <@{targetUserId}> was banned for {Warnings.TimeToPrettyFormat(banDuration, false)} by `{moderator.Username}#{moderator.Discriminator}` (`{moderatorId}`).\nReason: **{reason}**");
                }
            }
            catch
            {
                return(false);
            }
            return(true);
        }
Beispiel #4
0
        public static async Task WarnUserAsync(DiscordUser user, DiscordUser admin, DiscordGuild server, DiscordChannel channel, string reason, bool automsg)
        {
            DB.ServerRanks    WarnedUserStats = DB.DBLists.ServerRanks.FirstOrDefault(f => server.Id == f.Server_ID && user.Id == f.User_ID);
            DB.ServerSettings ServerSettings  = DB.DBLists.ServerSettings.FirstOrDefault(f => server.Id == f.ID_Server);

            if (WarnedUserStats == null)
            {
                AddUserToServerRanks(user, server);
            }

            DiscordMember member = null;

            try
            {
                member = await server.GetMemberAsync(user.Id);
            }
            catch (Exception)
            {
                await channel.SendMessageAsync($"{user.Username} is no longer in the server.");
            }

            string              modinfo = "";
            StringBuilder       SB = new();
            decimal             uid = user.Id, aid = admin.Id;
            bool                kick = false, ban = false;
            DiscordEmbedBuilder embed;

            if (ServerSettings.WKB_Log != 0)
            {
                DiscordChannel modlog = server.GetChannel(Convert.ToUInt64(ServerSettings.WKB_Log));
                if (WarnedUserStats is null) // creates new entry in DB (Followers set to default value)
                {
                    DB.ServerRanks newEntry = new()
                    {
                        Server_ID     = server.Id,
                        Ban_Count     = 0,
                        Kick_Count    = 0,
                        Warning_Level = 1,
                        User_ID       = user.Id
                    };
                    DB.DBLists.InsertServerRanks(newEntry);
                    WarnedUserStats = newEntry;
                }
                else
                {
                    WarnedUserStats.Warning_Level++;
                    if (WarnedUserStats.Followers <= 1000 * WarnedUserStats.Warning_Level)
                    {
                        WarnedUserStats.Followers = 0;
                    }
                    else
                    {
                        WarnedUserStats.Followers -= (1000 * WarnedUserStats.Warning_Level);
                    }
                    DB.DBLists.UpdateServerRanks(WarnedUserStats);
                }

                DB.Warnings newWarning = new()
                {
                    Reason    = reason,
                    Active    = true,
                    Date      = DateTime.Now.ToString("yyyy-MM-dd"),
                    Admin_ID  = aid,
                    User_ID   = uid,
                    Server_ID = server.Id,
                    Type      = "warning"
                };
                DB.DBLists.InsertWarnings(newWarning);

                int warning_count = DB.DBLists.Warnings.Count(w => w.User_ID == user.Id && w.Server_ID == server.Id && w.Type == "warning");

                SB.AppendLine($"You have been warned by <@{admin.Id}>.\n**Warning Reason:**\t{reason}\n**Warning Level:** {WarnedUserStats.Warning_Level}\n**Server:** {server.Name}");
                embed = new DiscordEmbedBuilder
                {
                    Color  = new DiscordColor(0xf90707),
                    Author = new DiscordEmbedBuilder.EmbedAuthor
                    {
                        IconUrl = user.AvatarUrl,
                        Name    = $"{user.Username} ({user.Id})"
                    },
                    Description = $"**Warned user:**\t{user.Mention}\n**Warning level:**\t {WarnedUserStats.Warning_Level}\t**Warning count:**\t {warning_count}\n**Warned by**\t{admin.Username}\n**Reason:** {reason}"
                };
                if (WarnedUserStats.Warning_Level > 4)
                {
                    SB.AppendLine($"You have been banned from **{server.Name}** by {admin.Mention} for exceeding the warning level threshold(4).");
                    ban = true;
                }
                else if (WarnedUserStats.Warning_Level > 2 && WarnedUserStats.Warning_Level < 5)
                {
                    SB.AppendLine($"You have been kicked from **{server.Name}** by {admin.Mention} for exceeding the warning level threshold(2).");
                    kick = true;
                }

                if (automsg)
                {
                    SB.Append("*This warning is given out by a bot, contact an admin if you think this is a mistake*");
                }
                else
                {
                    SB.Append($"*(This is an automated message, use the `{Program.CFGJson.CommandPrefix}modmail` feature if you want to report a mistake.)*");
                }

                try
                {
                    await member.SendMessageAsync(SB.ToString());
                }
                catch
                {
                    modinfo = $":exclamation:{user.Mention} could not be contacted via DM. Reason not sent";
                }

                if (kick && member != null)
                {
                    await member.RemoveAsync("Exceeded warning limit!");
                }
                if (ban && user != null)
                {
                    await server.BanMemberAsync(user.Id, 0, "Exceeded warning limit!");
                }

                await modlog.SendMessageAsync(modinfo, embed : embed);

                DiscordMessage info = await channel.SendMessageAsync($"{user.Username}, Has been warned!");

                await Task.Delay(10000).ContinueWith(t => info.DeleteAsync());
            }
            else
            {
                await channel.SendMessageAsync("This server has not set up this feature!");
            }
        }
Beispiel #5
0
        public async Task CreateInfraction(DiscordGuild guild, DiscordChannel channel, DiscordClient client, DiscordMember moderator, DiscordMember suspect, string reason, InfractionType infractionType)
        {
            var suspectLeft = guild.GetMemberAsync(suspect.Id).Result == null;
            var embed       = new Embed();
            var owners      = client.CurrentApplication.Owners;
            var verb        = infractionType.ToInfractionString().ToLowerInvariant();
            var action      = infractionType.ToActionString().ToLowerInvariant();

            var isSuspectAdministrator = false;
            var isModerator            = await redis.IsModerator(guild.Id, moderator);

            var isAdministrator = moderator.Roles.Any(role => role.Permissions.HasPermission(Permissions.Administrator));

            if (!isModerator && isAdministrator)
            {
                isModerator = true;
            }

            if (isModerator)
            {
                if (!suspectLeft)
                {
                    if (suspect.Roles.Any(role => role.Permissions.HasPermission(Permissions.Administrator)))
                    {
                        isSuspectAdministrator = true;
                    }

                    if (moderator == suspect)
                    {
                        await channel.SendMessageAsync($"You can not {verb} yourself!");
                    }
                    else if (owners.Any(x => x.Id == suspect.Id))
                    {
                        await channel.SendMessageAsync($"You can not {verb} {suspect.Username}!");
                    }
                    else if (suspect.IsOwner)
                    {
                        await channel.SendMessageAsync($"You can not {verb} the owner!");
                    }
                    else if (isSuspectAdministrator)
                    {
                        await channel.SendMessageAsync($"You can not {verb} a administrator!");
                    }
                    else if (await redis.IsModerator(guild.Id, suspect))
                    {
                        var guildData = await redis.GetAsync <Guild>(RedisKeyNaming.Guild(guild.Id));

                        switch (infractionType)
                        {
                        case InfractionType.Ban:
                        case InfractionType.Kick:
                            await channel.SendMessageAsync($"You can not {verb} a moderator!");

                            break;

                        case InfractionType.Warning:
                        {
                            if (!guildData.AllowWarnModerators)
                            {
                                await channel.SendMessageAsync($"You can not {verb} a moderator! [Disabled]");
                            }

                            break;
                        }

                        case InfractionType.Mute:
                        {
                            if (!guildData.AllowMuteModerators)
                            {
                                await channel.SendMessageAsync($"You can not {verb} a moderator! [Disabled]");
                            }

                            break;
                        }
                        }
                    }
                    else
                    {
                        var userData = await redis.InitUser(suspect.Id);

                        userData.Infractions.Add(new Infraction()
                        {
                            Id                = ++userData.InfractionId,
                            ModeratorId       = moderator.Id,
                            ModeratorUsername = moderator.GetUsertag(),
                            GuildId           = guild.Id,
                            InfractionType    = infractionType,
                            Reason            = reason,
                            Date              = DateTimeOffset.UtcNow
                        });

                        await redis.ReplaceAsync <User>(RedisKeyNaming.User(suspect.Id), userData);

                        var description = new StringBuilder().AppendLine($"Moderator: {moderator.GetUsertag()} {Formatter.InlineCode($"{moderator.Id}")}")
                                          .AppendLine($"Reason: {reason}");


                        description.AppendLine("User left the server already!");
                        embed = new Embed()
                        {
                            Title       = $"{suspect.Username} has been {action}!",
                            Description = description.ToString(),
                            Footer      = new EmbedFooter()
                            {
                                Text = $"Infractions: {userData.Infractions.Count}"
                            }
                        };

                        await channel.SendEmbedMessageAsync(embed);

                        embed.Title = $"You have been {action} on {guild.Name}";
                        await suspect.SendEmbedMessageAsync(embed);


                        switch (infractionType)
                        {
                        case InfractionType.Kick:
                            await suspect.RemoveAsync(reason);

                            break;

                        case InfractionType.Ban:
                            await guild.BanMemberAsync(suspect.Id, 7, reason);

                            break;
                        }
                    }
                }
                else
                {
                    var suspectedUser = await client.GetUserAsync(suspect.Id);

                    var userData = await redis.InitUser(suspectedUser.Id);

                    userData.Infractions.Add(new Infraction()
                    {
                        Id                = ++userData.InfractionId,
                        ModeratorId       = moderator.Id,
                        ModeratorUsername = moderator.GetUsertag(),
                        GuildId           = guild.Id,
                        InfractionType    = infractionType,
                        Reason            = reason,
                        Date              = DateTimeOffset.UtcNow
                    });

                    await redis.ReplaceAsync <User>(RedisKeyNaming.User(suspectedUser.Id), userData);

                    var description = new StringBuilder().AppendLine($"Moderator: {moderator.GetUsertag()} {Formatter.InlineCode($"{moderator.Id}")}")
                                      .AppendLine($"Reason: {reason}")
                                      .AppendLine("User left the server already!");

                    embed = new Embed()
                    {
                        Title       = $"{suspect.Username} has been {action}!",
                        Description = description.ToString(),
                        Footer      = new EmbedFooter()
                        {
                            Text = $"Infractions: {userData.Infractions.Count}"
                        }
                    };

                    await channel.SendEmbedMessageAsync(embed);

                    switch (infractionType)
                    {
                    case InfractionType.Kick:
                        await channel.SendMessageAsync("Suspect already left");

                        break;

                    case InfractionType.Ban:
                        await guild.BanMemberAsync(suspectedUser.Id);

                        break;
                    }
                }
            }
            else
            {
                await channel.SendMessageAsync("You are not a moderator of this server.");
            }
        }