Exemple #1
0
        static async Task MainAsync(string[] _)
        {
            var json = "";

            using (var fs = File.OpenRead("config.json"))
                using (var sr = new StreamReader(fs, new UTF8Encoding(false)))
                    json = await sr.ReadToEndAsync();

            cfgjson = JsonConvert.DeserializeObject <ConfigJson>(json);

            var keys = cfgjson.WordListList.Keys;

            foreach (string key in keys)
            {
                var listOutput = File.ReadAllLines($"Lists/{key}");
                cfgjson.WordListList[key].Words = listOutput;
            }

            string redisHost;

            if (Environment.GetEnvironmentVariable("REDIS_DOCKER_OVERRIDE") != null)
            {
                redisHost = "redis";
            }
            else
            {
                redisHost = cfgjson.Redis.Host;
            }
            redis = ConnectionMultiplexer.Connect($"{redisHost}:{cfgjson.Redis.Port}");
            db    = redis.GetDatabase();
            db.KeyDelete("messages");

            discord = new DiscordClient(new DiscordConfiguration
            {
                Token           = cfgjson.Core.Token,
                TokenType       = TokenType.Bot,
                MinimumLogLevel = Microsoft.Extensions.Logging.LogLevel.Debug,
                Intents         = DiscordIntents.All
            });

#pragma warning disable CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed
            async Task OnReady(DiscordClient client, ReadyEventArgs e)
            {
                Console.WriteLine($"Logged in as {client.CurrentUser.Username}#{client.CurrentUser.Discriminator}");
                logChannel = await discord.GetChannelAsync(cfgjson.LogChannel);

                Mutes.CheckMutesAsync();
                ModCmds.CheckBansAsync();
            }

            async Task MessageCreated(DiscordClient client, MessageCreateEventArgs e)
            {
                if (e.Channel.IsPrivate || e.Guild.Id != cfgjson.ServerID || e.Author.IsBot)
                {
                    return;
                }

                if (processedMessages.Contains(e.Message.Id))
                {
                    return;
                }
                else
                {
                    processedMessages.Add(e.Message.Id);
                }

                DiscordMember member = await e.Guild.GetMemberAsync(e.Author.Id);

                if (Warnings.GetPermLevel(member) >= ServerPermLevel.TrialMod)
                {
                    return;
                }


                bool match = false;

                // Matching word list
                var wordListKeys = cfgjson.WordListList.Keys;

                foreach (string key in wordListKeys)
                {
                    if (CheckForNaughtyWords(e.Message.Content, cfgjson.WordListList[key]))
                    {
                        try
                        {
                            e.Message.DeleteAsync();
                            DiscordChannel logChannel = await discord.GetChannelAsync(Program.cfgjson.LogChannel);

                            var embed = new DiscordEmbedBuilder()
                                        .WithDescription(e.Message.Content)
                                        .WithColor(new DiscordColor(0xf03916))
                                        .WithTimestamp(e.Message.Timestamp)
                                        .WithFooter(
                                $"User ID: {e.Author.Id}",
                                null
                                )
                                        .WithAuthor(
                                $"{e.Author.Username}#{e.Author.Discriminator} in #{e.Channel.Name}",
                                null,
                                e.Author.AvatarUrl
                                );
                            logChannel.SendMessageAsync($"{cfgjson.Emoji.Denied} Deleted infringing message by {e.Author.Mention} in {e.Channel.Mention}:", false, embed);
                        }
                        catch
                        {
                            // still warn anyway
                        }

                        match = true;
                        string         reason = cfgjson.WordListList[key].Reason;
                        DiscordMessage msg    = await e.Channel.SendMessageAsync($"{cfgjson.Emoji.Denied} {e.Message.Author.Mention} was warned: **{reason.Replace("`", "\\`").Replace("*", "\\*")}**");

                        Warnings.GiveWarningAsync(e.Message.Author, discord.CurrentUser, reason, contextLink: Warnings.MessageLink(msg), e.Channel);
                        return;
                    }
                    if (match)
                    {
                        return;
                    }
                }

                if (match)
                {
                    return;
                }

                // Mass emoji
                if (e.Message.MentionedUsers.Count >= cfgjson.MassMentionThreshold)
                {
                    DiscordChannel logChannel = await discord.GetChannelAsync(Program.cfgjson.LogChannel);

                    try
                    {
                        e.Message.DeleteAsync();
                        var embed = new DiscordEmbedBuilder()
                                    .WithDescription(e.Message.Content)
                                    .WithColor(new DiscordColor(0xf03916))
                                    .WithTimestamp(e.Message.Timestamp)
                                    .WithFooter(
                            $"User ID: {e.Author.Id}",
                            null
                            )
                                    .WithAuthor(
                            $"{e.Author.Username}#{e.Author.Discriminator} in #{e.Channel.Name}",
                            null,
                            e.Author.AvatarUrl
                            );
                        logChannel.SendMessageAsync($"{cfgjson.Emoji.Denied} Deleted infringing message by {e.Author.Mention} in {e.Channel.Mention}:", false, embed);
                    }
                    catch
                    {
                        // still warn anyway
                    }

                    string         reason = "Mass mentions";
                    DiscordMessage msg    = await e.Channel.SendMessageAsync($"{cfgjson.Emoji.Denied} {e.Message.Author.Mention} was warned: **{reason.Replace("`", "\\`").Replace("*", "\\*")}**");

                    await Warnings.GiveWarningAsync(e.Message.Author, discord.CurrentUser, reason, contextLink : Warnings.MessageLink(msg), e.Channel);

                    return;
                }

                // Unapproved invites
                if (Warnings.GetPermLevel(member) < (ServerPermLevel)cfgjson.InviteTierRequirement)
                {
                    string inviteExclusion = "microsoft";
                    if (cfgjson.InviteExclusion != null)
                    {
                        inviteExclusion = cfgjson.InviteExclusion;
                    }

                    string checkedMessage = e.Message.Content.Replace($"discord.gg/{inviteExclusion}", "").Replace($"discord.com/invite/{inviteExclusion}", "");

                    if (checkedMessage.Contains("discord.gg/") || checkedMessage.Contains("discord.com/invite/"))
                    {
                        try
                        {
                            e.Message.DeleteAsync();
                            var embed = new DiscordEmbedBuilder()
                                        .WithDescription(e.Message.Content)
                                        .WithColor(new DiscordColor(0xf03916))
                                        .WithTimestamp(e.Message.Timestamp)
                                        .WithFooter(
                                $"User ID: {e.Author.Id}",
                                null
                                )
                                        .WithAuthor(
                                $"{e.Author.Username}#{e.Author.Discriminator} in #{e.Channel.Name}",
                                null,
                                e.Author.AvatarUrl
                                );
                            logChannel.SendMessageAsync($"{cfgjson.Emoji.Denied} Deleted infringing message by {e.Author.Mention} in {e.Channel.Mention}:", false, embed);
                        }
                        catch
                        {
                            // still warn anyway
                        }
                        string         reason = "Sent an invite";
                        DiscordMessage msg    = await e.Channel.SendMessageAsync($"{Program.cfgjson.Emoji.Denied} {e.Message.Author.Mention} was warned: **{reason.Replace("`", "\\`").Replace("*", "\\*")}**");

                        await Warnings.GiveWarningAsync(e.Message.Author, discord.CurrentUser, reason, contextLink : Warnings.MessageLink(msg), e.Channel);

                        return;
                    }
                }

                // Mass emoji
                if (!cfgjson.UnrestrictedEmojiChannels.Contains(e.Message.ChannelId) && e.Message.Content.Length >= cfgjson.MassEmojiThreshold)
                {
                    char[] tempArray = e.Message.Content.Replace("🏻", "").Replace("🏼", "").Replace("🏽", "").Replace("🏾", "").Replace("🏿", "").ToCharArray();
                    int    pos       = 0;
                    foreach (char c in tempArray)
                    {
                        if (c == '™' || c == '®' || c == '©')
                        {
                            tempArray[pos] = ' ';
                        }
                        if (c == '\u200d')
                        {
                            tempArray[pos]     = ' ';
                            tempArray[pos + 1] = ' ';
                        }
                        ++pos;
                    }
                    string input = new string(tempArray);

                    var matches = emoji_rx.Matches(input);
                    if (matches.Count > cfgjson.MassEmojiThreshold)
                    {
                        e.Message.DeleteAsync();
                        string         reason = "Mass emoji";
                        DiscordMessage msg    = await e.Channel.SendMessageAsync($"{Program.cfgjson.Emoji.Denied} {e.Message.Author.Mention} was warned: **{reason.Replace("`", "\\`").Replace("*", "\\*")}**");

                        await Warnings.GiveWarningAsync(e.Message.Author, discord.CurrentUser, reason, contextLink : Warnings.MessageLink(msg), e.Channel);

                        return;
                    }
                }
            }

            async Task GuildMemberAdded(DiscordClient client, GuildMemberAddEventArgs e)
            {
                if (e.Guild.Id != cfgjson.ServerID)
                {
                    return;
                }

                if (await db.HashExistsAsync("mutes", e.Member.Id))
                {
                    // todo: store per-guild
                    DiscordRole mutedRole = e.Guild.GetRole(cfgjson.MutedRole);
                    await e.Member.GrantRoleAsync(mutedRole);
                }
            }

            discord.Ready            += OnReady;
            discord.MessageCreated   += MessageCreated;
            discord.GuildMemberAdded += GuildMemberAdded;


            commands = discord.UseCommandsNext(new CommandsNextConfiguration
            {
                StringPrefixes = cfgjson.Core.Prefixes
            });;

            commands.RegisterCommands <Warnings>();
            commands.RegisterCommands <MuteCmds>();
            commands.RegisterCommands <UserRoleCmds>();
            commands.RegisterCommands <ModCmds>();

            await discord.ConnectAsync();

            while (true)
            {
                await Task.Delay(60000);

                Mutes.CheckMutesAsync();
                ModCmds.CheckBansAsync();
#pragma warning restore CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed
            }
        }
Exemple #2
0
        static async Task MainAsync(string[] _)
        {
            var json = "";

            using (var fs = File.OpenRead("config.json"))
                using (var sr = new StreamReader(fs, new UTF8Encoding(false)))
                    json = await sr.ReadToEndAsync();

            cfgjson = JsonConvert.DeserializeObject <ConfigJson>(json);

            string redisHost;

            if (Environment.GetEnvironmentVariable("REDIS_DOCKER_OVERRIDE") != null)
            {
                redisHost = "redis";
            }
            else
            {
                redisHost = cfgjson.Redis.Host;
            }
            redis = ConnectionMultiplexer.Connect($"{redisHost}:{cfgjson.Redis.Port}");
            db    = redis.GetDatabase();
            db.KeyDelete("messages");

            discord = new DiscordClient(new DiscordConfiguration
            {
                Token                 = cfgjson.Core.Token,
                TokenType             = TokenType.Bot,
                UseInternalLogHandler = true,
                LogLevel              = LogLevel.Debug
            });

#pragma warning disable CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed
            discord.Ready += async e =>
            {
                Console.WriteLine($"Logged in as {e.Client.CurrentUser.Username}#{e.Client.CurrentUser.Discriminator}");
                logChannel = await discord.GetChannelAsync(cfgjson.LogChannel);

                await Task.Delay(4000);

                Mutes.CheckMutesAsync();
            };

            discord.GuildMemberAdded += async e =>
            {
                if (e.Guild.Id != cfgjson.ServerID)
                {
                    return;
                }

                if (await db.HashExistsAsync("mutes", e.Member.Id))
                {
                    // todo: store per-guild
                    DiscordRole mutedRole = e.Guild.GetRole(cfgjson.MutedRole);
                    await e.Member.GrantRoleAsync(mutedRole);
                }
            };

            commands = discord.UseCommandsNext(new CommandsNextConfiguration
            {
                StringPrefixes = cfgjson.Core.Prefixes
            });;

            commands.RegisterCommands <Warnings>();
            commands.RegisterCommands <MuteCmds>();

            await discord.ConnectAsync();

            while (true)
            {
                await Task.Delay(60000);

                Mutes.CheckMutesAsync();
#pragma warning restore CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed
            }
        }