コード例 #1
0
        public async Task Rename(CommandContext ctx,
                                 [Description("A term to rename. Remember quotes if it contains spaces")] string oldTerm,
                                 [Description("New term. Again, quotes")] string newTerm)
        {
            oldTerm = oldTerm.ToLowerInvariant().StripQuotes();
            newTerm = newTerm.ToLowerInvariant().StripQuotes();
            using (var db = new BotDb())
            {
                var item = await db.Explanation.FirstOrDefaultAsync(e => e.Keyword == oldTerm).ConfigureAwait(false);

                if (item == null)
                {
                    await ctx.ReactWithAsync(Config.Reactions.Failure, $"Term `{oldTerm}` is not defined").ConfigureAwait(false);
                }
                else if (await db.Explanation.AnyAsync(e => e.Keyword == newTerm).ConfigureAwait(false))
                {
                    await ctx.ReactWithAsync(Config.Reactions.Failure, $"Term `{newTerm}` already defined, can't replace it with explanation for `{oldTerm}`").ConfigureAwait(false);
                }
                else
                {
                    item.Keyword = newTerm;
                    await db.SaveChangesAsync().ConfigureAwait(false);

                    await ctx.ReactWithAsync(Config.Reactions.Success, $"Renamed `{oldTerm}` to `{newTerm}`").ConfigureAwait(false);
                }
            }
        }
コード例 #2
0
ファイル: Invites.cs プロジェクト: 13xforever/discord-bot
        public async Task Rename(CommandContext ctx, [Description("Filter ID to rename")] int id, [RemainingText, Description("Custom server name")] string name)
        {
            if (string.IsNullOrEmpty(name))
            {
                await ctx.ReactWithAsync(Config.Reactions.Failure, "A name must be provided").ConfigureAwait(false);

                return;
            }

            await using var db = new BotDb();
            var invite = await db.WhitelistedInvites.FirstOrDefaultAsync(i => i.Id == id).ConfigureAwait(false);

            if (invite == null)
            {
                await ctx.ReactWithAsync(Config.Reactions.Failure, "Invalid filter ID").ConfigureAwait(false);

                return;
            }

            invite.Name = name;
            await db.SaveChangesAsync().ConfigureAwait(false);

            await ctx.ReactWithAsync(Config.Reactions.Success).ConfigureAwait(false);

            await List(ctx).ConfigureAwait(false);
        }
コード例 #3
0
            public async Task Users(CommandContext ctx, [Description("Optional number of items to show. Default is 10")] int number = 10)
            {
                try
                {
                    if (number < 1)
                    {
                        number = 10;
                    }
                    var table = new AsciiTable(
                        new AsciiColumn("Username", maxWidth: 24),
                        new AsciiColumn("User ID", disabled: !ctx.Channel.IsPrivate, alignToRight: true),
                        new AsciiColumn("Count", alignToRight: true),
                        new AsciiColumn("All time", alignToRight: true)
                        );
                    await using var db = new BotDb();
                    var query = from warn in db.Warning.AsEnumerable()
                                group warn by warn.DiscordId
                                into userGroup
                                let row = new { discordId = userGroup.Key, count = userGroup.Count(w => !w.Retracted), total = userGroup.Count() }
                    orderby row.count descending
                    select row;
                    foreach (var row in query.Take(number))
                    {
                        var username = await ctx.GetUserNameAsync(row.discordId).ConfigureAwait(false);

                        table.Add(username, row.discordId.ToString(), row.count.ToString(), row.total.ToString());
                    }
                    await ctx.SendAutosplitMessageAsync(new StringBuilder("Warning count per user:"******"SQL query for this command is broken at the moment", true).ConfigureAwait(false);
                }
            }
コード例 #4
0
        public static async Task MonitorAsync(DiscordClient client, bool once = false)
        {
            do
            {
                if (!once)
                {
                    await Task.Delay(Config.ForcedNicknamesRecheckTime, Config.Cts.Token).ConfigureAwait(false);
                }
                if (await Moderation.Audit.CheckLock.WaitAsync(0).ConfigureAwait(false))
                {
                    try
                    {
                        foreach (var guild in client.Guilds.Values)
                        {
                            try
                            {
                                if (!(guild.Permissions?.HasFlag(Permissions.ChangeNickname) ?? true))
                                {
                                    continue;
                                }

                                using var db = new BotDb();
                                var forcedNicknames = await db.ForcedNicknames
                                                      .Where(mem => mem.GuildId == guild.Id)
                                                      .ToListAsync()
                                                      .ConfigureAwait(false);

                                if (forcedNicknames.Count == 0)
                                {
                                    continue;
                                }

                                foreach (var forced in forcedNicknames)
                                {
                                    var member = client.GetMember(guild, forced.UserId);
                                    if (member?.DisplayName != forced.Nickname)
                                    {
                                        try
                                        {
                                            await member.ModifyAsync(mem => mem.Nickname = forced.Nickname).ConfigureAwait(false);

                                            Config.Log.Info($"Enforced nickname {forced.Nickname} for user {member.Id} ({member.Username}#{member.Discriminator})");
                                        }
                                        catch {}
                                    }
                                }
                            }
                            catch (Exception e)
                            {
                                Config.Log.Error(e);
                            }
                        }
                    }
                    finally
                    {
                        Moderation.Audit.CheckLock.Release();
                    }
                }
            } while (!Config.Cts.IsCancellationRequested && !once);
        }
コード例 #5
0
ファイル: Sudo.Fix.cs プロジェクト: guipleite/discord-bot
            public async Task Channels(CommandContext ctx)
            {
                try
                {
                    var @fixed = 0;
                    using (var db = new BotDb())
                    {
                        foreach (var warning in db.Warning)
                        {
                            var newReason = await FixChannelMentionAsync(ctx, warning.Reason).ConfigureAwait(false);

                            if (newReason != warning.Reason)
                            {
                                warning.Reason = newReason;
                                @fixed++;
                            }
                        }
                        await db.SaveChangesAsync().ConfigureAwait(false);
                    }
                    await ctx.RespondAsync($"Fixed {@fixed} records").ConfigureAwait(false);
                }
                catch (Exception e)
                {
                    Config.Log.Warn(e, "Couldn't fix channel mentions");
                    await ctx.RespondAsync("Failed to fix warning timestamps").ConfigureAwait(false);
                }
            }
コード例 #6
0
        public async Task Remove(CommandContext ctx, [Description("Trigger to remove"), RemainingText] string trigger)
        {
            if (string.IsNullOrWhiteSpace(trigger))
            {
                await ctx.ReactWithAsync(Config.Reactions.Failure, "No trigger was specified").ConfigureAwait(false);

                return;
            }

            using (var db = new BotDb())
            {
                var f = await db.Piracystring.FirstOrDefaultAsync(ps => ps.String.Equals(trigger, StringComparison.InvariantCultureIgnoreCase) && !ps.Disabled).ConfigureAwait(false);

                if (f == null)
                {
                    await ctx.ReactWithAsync(Config.Reactions.Failure, "Specified filter does not exist").ConfigureAwait(false);

                    return;
                }

                f.Disabled = true;
                await db.SaveChangesAsync(Config.Cts.Token).ConfigureAwait(false);
            }

            await ctx.ReactWithAsync(Config.Reactions.Success, "Trigger was removed").ConfigureAwait(false);

            var member = ctx.Member ?? ctx.Client.GetMember(ctx.User);
            await ctx.Client.ReportAsync("📴 Piracy filter removed", $"{member.GetMentionWithNickname()} removed 1 piracy filter: `{trigger.Sanitize()}`", null, ReportSeverity.Medium).ConfigureAwait(false);

            ContentFilter.RebuildMatcher();
        }
コード例 #7
0
        public async Task Add(CommandContext ctx, [RemainingText, Description("A plain string to match")] string trigger)
        {
            using (var db = new BotDb())
            {
                Piracystring filter;
                if (string.IsNullOrEmpty(trigger))
                {
                    filter = new Piracystring();
                }
                else
                {
                    filter = await db.Piracystring.FirstOrDefaultAsync(ps => ps.String == trigger && ps.Disabled).ConfigureAwait(false);

                    if (filter == null)
                    {
                        filter = new Piracystring {
                            String = trigger
                        }
                    }
                    ;
                    else
                    {
                        filter.Disabled = false;
                    }
                }
                var isNewFilter = filter.Id == default;
                if (isNewFilter)
                {
                    filter.Context = FilterContext.Chat | FilterContext.Log;
                    filter.Actions = FilterAction.RemoveContent | FilterAction.IssueWarning | FilterAction.SendMessage;
                }

                var(success, msg) = await EditFilterPropertiesAsync(ctx, db, filter).ConfigureAwait(false);

                if (success)
                {
                    if (isNewFilter)
                    {
                        await db.Piracystring.AddAsync(filter).ConfigureAwait(false);
                    }
                    await db.SaveChangesAsync().ConfigureAwait(false);

                    await msg.UpdateOrCreateMessageAsync(ctx.Channel, embed : FormatFilter(filter).WithTitle("Created a new content filter")).ConfigureAwait(false);

                    var member    = ctx.Member ?? ctx.Client.GetMember(ctx.User);
                    var reportMsg = $"{member.GetMentionWithNickname()} added a new content filter: `{filter.String.Sanitize()}`";
                    if (!string.IsNullOrEmpty(filter.ValidatingRegex))
                    {
                        reportMsg += $"\nValidation: `{filter.ValidatingRegex}`";
                    }
                    await ctx.Client.ReportAsync("🆕 Content filter created", reportMsg, null, ReportSeverity.Low).ConfigureAwait(false);

                    ContentFilter.RebuildMatcher();
                }
                else
                {
                    await msg.UpdateOrCreateMessageAsync(ctx.Channel, "Content filter creation aborted").ConfigureAwait(false);
                }
            }
        }
コード例 #8
0
        private static async Task <string> FuzzyMatchEventName(BotDb db, string eventName)
        {
            var knownEventNames = await db.EventSchedule.Select(e => e.EventName).Distinct().ToListAsync().ConfigureAwait(false);

            var(score, name) = knownEventNames.Select(n => (score: eventName.GetFuzzyCoefficientCached(n), name: n)).OrderByDescending(t => t.score).FirstOrDefault();
            return(score > 0.8 ? name : eventName);
        }
コード例 #9
0
        protected async Task Add(CommandContext ctx, string eventName = null)
        {
            var evt = new EventSchedule();

            var(success, msg) = await EditEventPropertiesAsync(ctx, evt, eventName).ConfigureAwait(false);

            if (success)
            {
                using (var db = new BotDb())
                {
                    await db.EventSchedule.AddAsync(evt).ConfigureAwait(false);

                    await db.SaveChangesAsync().ConfigureAwait(false);
                }
                await ctx.ReactWithAsync(Config.Reactions.Success).ConfigureAwait(false);

                if (LimitedToSpamChannel.IsSpamChannel(ctx.Channel))
                {
                    await msg.UpdateOrCreateMessageAsync(ctx.Channel, embed : FormatEvent(evt).WithTitle("Created new event schedule entry #" + evt.Id)).ConfigureAwait(false);
                }
                else
                {
                    await msg.UpdateOrCreateMessageAsync(ctx.Channel, "Added a new schedule entry").ConfigureAwait(false);
                }
            }
            else
            {
                await msg.UpdateOrCreateMessageAsync(ctx.Channel, "Event creation aborted").ConfigureAwait(false);
            }
        }
コード例 #10
0
ファイル: Explain.cs プロジェクト: MsDarkLow/discord-bot
        public async Task List(CommandContext ctx)
        {
            await ctx.TriggerTypingAsync().ConfigureAwait(false);

            using (var db = new BotDb())
            {
                var keywords = await db.Explanation.Select(e => e.Keyword).OrderBy(t => t).ToListAsync().ConfigureAwait(false);

                if (keywords.Count == 0)
                {
                    await ctx.RespondAsync("Nothing has been defined yet").ConfigureAwait(false);
                }
                else
                {
                    try
                    {
                        foreach (var embed in new EmbedPager().BreakInEmbeds(new DiscordEmbedBuilder {
                            Title = "Defined terms", Color = Config.Colors.Help
                        }, keywords))
                        {
                            await ctx.RespondAsync(embed : embed).ConfigureAwait(false);
                        }
                    }
                    catch (Exception e)
                    {
                        Config.Log.Error(e);
                    }
                }
            }
        }
コード例 #11
0
ファイル: Explain.cs プロジェクト: MsDarkLow/discord-bot
        public async Task Add(CommandContext ctx,
                              [Description("A term to explain. Quote it if it contains spaces")] string term,
                              [RemainingText, Description("Explanation text")] string explanation)
        {
            term = term.ToLowerInvariant().StripQuotes();
            if (string.IsNullOrEmpty(explanation))
            {
                await ctx.ReactWithAsync(Config.Reactions.Failure, "An explanation for the term must be provided").ConfigureAwait(false);
            }
            else
            {
                using (var db = new BotDb())
                {
                    if (await db.Explanation.AnyAsync(e => e.Keyword == term).ConfigureAwait(false))
                    {
                        await ctx.ReactWithAsync(Config.Reactions.Failure, $"`{term}` is already defined. Use `update` to update an existing term.").ConfigureAwait(false);
                    }
                    else
                    {
                        await db.Explanation.AddAsync(new Explanation { Keyword = term, Text = explanation }).ConfigureAwait(false);

                        await db.SaveChangesAsync().ConfigureAwait(false);

                        await ctx.ReactWithAsync(Config.Reactions.Success, $"`{term}` was successfully added").ConfigureAwait(false);
                    }
                }
            }
        }
コード例 #12
0
        protected override CommandQueueElement RunInternal()
        {
            // Read all messages
            FindAllMessagesCommand cmd = new FindAllMessagesCommand();

            cmd.Run();

            List <MessagesPage> messagePages = cmd.ParsedObjects.OfType <MessagesPage>().ToList();
            List <int>          messageIds   = messagePages.SelectMany(s => s.MessageIds).Select(s => s.Item1).ToList();

            HashSet <int> existing;

            using (BotDb db = new BotDb())
                existing = db.Messages.Where(s => messageIds.Contains(s.MessageId)).Select(s => s.MessageId).ToHashset();

            foreach (MessagesPage messagesPage in messagePages)
            {
                // Request each message
                foreach (Tuple <int, MessageType> message in messagesPage.MessageIds)
                {
                    if (existing.Contains(message.Item1))
                    {
                        // Already fetched
                        continue;
                    }

                    if (message.Item2 == MessageType.EspionageReport)
                    {
                        HttpRequestMessage req = Client.RequestBuilder.GetMessagePage(message.Item1, MessageTabType.FleetsEspionage);
                        AssistedIssue(req);
                    }
                }
            }
            return(null);
        }
コード例 #13
0
        internal static async Task <(Explanation explanation, string fuzzyMatch, double score)> LookupTerm(string term)
        {
            string      fuzzyMatch = null;
            double      coefficient;
            Explanation explanation;

            using (var db = new BotDb())
            {
                explanation = await db.Explanation.FirstOrDefaultAsync(e => e.Keyword == term).ConfigureAwait(false);

                if (explanation == null)
                {
                    var termList = await db.Explanation.Select(e => e.Keyword).ToListAsync().ConfigureAwait(false);

                    var bestSuggestion = termList.OrderByDescending(term.GetFuzzyCoefficientCached).First();
                    coefficient = term.GetFuzzyCoefficientCached(bestSuggestion);
                    explanation = await db.Explanation.FirstOrDefaultAsync(e => e.Keyword == bestSuggestion).ConfigureAwait(false);

                    fuzzyMatch = bestSuggestion;
                }
                else
                {
                    coefficient = 2.0;
                }
            }
            return(explanation, fuzzyMatch, coefficient);
        }
コード例 #14
0
            public async Task Text(CommandContext ctx, [RemainingText, Description("Term to remove")] string term)
            {
                term = term.ToLowerInvariant().StripQuotes();
                using (var db = new BotDb())
                {
                    var item = await db.Explanation.FirstOrDefaultAsync(e => e.Keyword == term).ConfigureAwait(false);

                    if (item == null)
                    {
                        await ctx.ReactWithAsync(Config.Reactions.Failure, $"Term `{term}` is not defined").ConfigureAwait(false);
                    }
                    else if (string.IsNullOrEmpty(item.Text))
                    {
                        await ctx.ReactWithAsync(Config.Reactions.Failure, $"Term `{term}` doesn't have any text").ConfigureAwait(false);
                    }
                    else if (string.IsNullOrEmpty(item.AttachmentFilename))
                    {
                        await RemoveExplanation(ctx, term).ConfigureAwait(false);
                    }
                    else
                    {
                        item.Text = "";
                        await db.SaveChangesAsync().ConfigureAwait(false);

                        await ctx.ReactWithAsync(Config.Reactions.Success, $"Removed explanation text for `{term}`").ConfigureAwait(false);
                    }
                }
            }
コード例 #15
0
            internal static void Restart(ulong channelId, string?restartMsg)
            {
                Config.Log.Info($"Saving channelId {channelId} into settings...");
                using var db = new BotDb();
                var ch = db.BotState.FirstOrDefault(k => k.Key == "bot-restart-channel");

                if (ch is null)
                {
                    ch = new BotState {
                        Key = "bot-restart-channel", Value = channelId.ToString()
                    };
                    db.BotState.Add(ch);
                }
                else
                {
                    ch.Value = channelId.ToString();
                }
                var msg = db.BotState.FirstOrDefault(k => k.Key == "bot-restart-msg");

                if (msg is null)
                {
                    msg = new BotState {
                        Key = "bot-restart-msg", Value = restartMsg
                    };
                    db.BotState.Add(msg);
                }
                else
                {
                    msg.Value = restartMsg;
                }
                db.SaveChanges();
                Config.TelemetryClient?.TrackEvent("Restart");
                RestartNoSaving();
            }
コード例 #16
0
        protected async Task Update(CommandContext ctx, int id, string eventName = null)
        {
            using var db = new BotDb();
            var evt = eventName == null
                ? db.EventSchedule.FirstOrDefault(e => e.Id == id)
                : db.EventSchedule.FirstOrDefault(e => e.Id == id && e.EventName == eventName);

            if (evt == null)
            {
                await ctx.ReactWithAsync(Config.Reactions.Failure, $"No event with id {id}").ConfigureAwait(false);

                return;
            }

            var(success, msg) = await EditEventPropertiesAsync(ctx, evt, eventName).ConfigureAwait(false);

            if (success)
            {
                await db.SaveChangesAsync().ConfigureAwait(false);

                if (LimitedToSpamChannel.IsSpamChannel(ctx.Channel))
                {
                    await msg.UpdateOrCreateMessageAsync(ctx.Channel, embed : FormatEvent(evt).WithTitle("Updated event schedule entry #" + evt.Id)).ConfigureAwait(false);
                }
                else
                {
                    await msg.UpdateOrCreateMessageAsync(ctx.Channel, "Updated the schedule entry").ConfigureAwait(false);
                }
            }
            else
            {
                await msg.UpdateOrCreateMessageAsync(ctx.Channel, "Event update aborted, changes weren't saved").ConfigureAwait(false);
            }
        }
コード例 #17
0
        public async Task Remove(CommandContext ctx, [Description("Filter IDs to remove, separated with spaces")] params int[] ids)
        {
            int removedFilters;
            var removedTriggers = new StringBuilder();

            using (var db = new BotDb())
            {
                foreach (var f in db.Piracystring.Where(ps => ids.Contains(ps.Id) && !ps.Disabled))
                {
                    f.Disabled = true;
                    removedTriggers.Append($"\n`{f.String.Sanitize()}`");
                }
                removedFilters = await db.SaveChangesAsync(Config.Cts.Token).ConfigureAwait(false);
            }

            if (removedFilters < ids.Length)
            {
                await ctx.RespondAsync("Some ids couldn't be removed.").ConfigureAwait(false);
            }
            else
            {
                await ctx.ReactWithAsync(Config.Reactions.Success, $"Trigger{StringUtils.GetSuffix(ids.Length)} successfully removed!").ConfigureAwait(false);

                var member     = ctx.Member ?? ctx.Client.GetMember(ctx.User);
                var s          = removedFilters == 1 ? "" : "s";
                var filterList = removedTriggers.ToString();
                if (removedFilters == 1)
                {
                    filterList = filterList.TrimStart();
                }
                await ctx.Client.ReportAsync($"📴 Piracy filter{s} removed", $"{member.GetMentionWithNickname()} removed {removedFilters} piracy filter{s}: {filterList}".Trim(EmbedPager.MaxDescriptionLength), null, ReportSeverity.Medium).ConfigureAwait(false);
            }
            ContentFilter.RebuildMatcher();
        }
コード例 #18
0
            public async Task Users(CommandContext ctx, [Description("Optional number of items to show. Default is 10")] int number = 10)
            {
                if (number < 1)
                {
                    number = 10;
                }
                var userIdColumn = ctx.Channel.IsPrivate ? $"{"User ID",-18} | " : "";
                var header       = $"{"User",-25} | {userIdColumn}Count";
                var result       = new StringBuilder("Warning count per user:"******"```")
                                   .AppendLine(header)
                                   .AppendLine("".PadLeft(header.Length, '-'));

                using (var db = new BotDb())
                {
                    var query = from warn in db.Warning
                                group warn by warn.DiscordId
                                into userGroup
                                let row = new { discordId = userGroup.Key, count = userGroup.Count() }
                    orderby row.count descending
                    select row;
                    foreach (var row in query.Take(number))
                    {
                        var username = await ctx.GetUserNameAsync(row.discordId).ConfigureAwait(false);

                        result.Append($"{username,-25} | ");
                        if (ctx.Channel.IsPrivate)
                        {
                            result.Append($"{row.discordId,-18} | ");
                        }
                        result.AppendLine($"{row.count,2}");
                    }
                }
                await ctx.SendAutosplitMessageAsync(result.Append("```")).ConfigureAwait(false);
            }
コード例 #19
0
        private async Task EditFilterCmd(CommandContext ctx, BotDb db, Piracystring filter)
        {
            var(success, msg) = await EditFilterPropertiesAsync(ctx, db, filter).ConfigureAwait(false);

            if (success)
            {
                await db.SaveChangesAsync().ConfigureAwait(false);

                await msg.UpdateOrCreateMessageAsync(ctx.Channel, embed : FormatFilter(filter).WithTitle("Updated content filter")).ConfigureAwait(false);

                var member    = ctx.Member ?? ctx.Client.GetMember(ctx.User);
                var reportMsg = $"{member.GetMentionWithNickname()} changed content filter: `{filter.String.Sanitize()}`";
                if (!string.IsNullOrEmpty(filter.ValidatingRegex))
                {
                    reportMsg += $"\nValidation: `{filter.ValidatingRegex}`";
                }
                await ctx.Client.ReportAsync("🆙 Content filter updated", reportMsg, null, ReportSeverity.Low).ConfigureAwait(false);

                ContentFilter.RebuildMatcher();
            }
            else
            {
                await msg.UpdateOrCreateMessageAsync(ctx.Channel, "Content filter update aborted").ConfigureAwait(false);
            }
        }
コード例 #20
0
        public static async Task RefreshAsync(DiscordClient client)
        {
            if (client == null)
            {
                return;
            }

            try
            {
                using var db = new BotDb();
                var status = await db.BotState.FirstOrDefaultAsync(s => s.Key == "bot-status-activity").ConfigureAwait(false);

                var txt = await db.BotState.FirstOrDefaultAsync(s => s.Key == "bot-status-text").ConfigureAwait(false);

                var msg = txt?.Value;
                if (Enum.TryParse(status?.Value ?? "Watching", true, out ActivityType activity) &&
                    !string.IsNullOrEmpty(msg))
                {
                    await client.UpdateStatusAsync(new DiscordActivity(msg, activity), UserStatus.Online).ConfigureAwait(false);
                }
            }
            catch (Exception e)
            {
                Config.Log.Error(e);
            }
        }
コード例 #21
0
            public async Task Users(CommandContext ctx, [Description("Optional number of items to show. Default is 10")] int number = 10)
            {
                var isMod = ctx.User.IsWhitelisted(ctx.Client, ctx.Guild);

                if (number < 1)
                {
                    number = 10;
                }
                var table = new AsciiTable(
                    new AsciiColumn("Username", maxWidth: 24),
                    new AsciiColumn("User ID", disabled: !ctx.Channel.IsPrivate, alignToRight: true),
                    new AsciiColumn("Count", alignToRight: true),
                    new AsciiColumn("All time", alignToRight: true)
                    );

                using (var db = new BotDb())
                {
                    var query = from warn in db.Warning
                                group warn by warn.DiscordId
                                into userGroup
                                let row = new { discordId = userGroup.Key, count = userGroup.Count(w => !w.Retracted), total = userGroup.Count() }
                    orderby row.count descending
                    select row;
                    foreach (var row in query.Take(number))
                    {
                        var username = await ctx.GetUserNameAsync(row.discordId).ConfigureAwait(false);

                        table.Add(username, row.discordId.ToString(), row.count.ToString(), row.total.ToString());
                    }
                }
                await ctx.SendAutosplitMessageAsync(new StringBuilder("Warning count per user:").Append(table)).ConfigureAwait(false);
            }
コード例 #22
0
        //note: be sure to pass a sanitized userName
        private static async Task ListUserWarningsAsync(DiscordClient client, DiscordMessage message, ulong userId, string userName, bool skipIfOne = true)
        {
            var channel = message.Channel;
            int count;

            using (var db = new BotDb())
                count = await db.Warning.CountAsync(w => w.DiscordId == userId).ConfigureAwait(false);
            if (count == 0)
            {
                await message.RespondAsync(userName + " has no warnings, is a standup citizen, and a pillar of this community").ConfigureAwait(false);

                return;
            }

            if (count == 1 && skipIfOne)
            {
                return;
            }

            const int maxWarningsInPublicChannel = 3;
            var       isPrivate     = channel.IsPrivate;
            var       isWhitelisted = client.GetMember(message.Author).IsWhitelisted();

            using (var db = new BotDb())
            {
                var totalWarningCount = db.Warning.Count(w => w.DiscordId == userId);
                var showCount         = Math.Min(maxWarningsInPublicChannel, totalWarningCount);
                var result            = new StringBuilder("Warning list for ").Append(userName);
                if (!isPrivate && !isWhitelisted && totalWarningCount > maxWarningsInPublicChannel)
                {
                    result.Append($" (last {showCount} of {totalWarningCount}, full list in DMs)");
                }
                result.AppendLine(":").AppendLine("```");
                var header = $"{"ID",-5} | {"Issued by",-15} | {"On date (UTC)",-20} | Reason";
                if (isPrivate)
                {
                    header += "          | Full reason";
                }
                result.AppendLine(header)
                .AppendLine("".PadLeft(header.Length, '-'));
                IQueryable <Warning> query = db.Warning.Where(w => w.DiscordId == userId).OrderByDescending(w => w.Id);
                if (!isPrivate && !isWhitelisted)
                {
                    query = query.Take(maxWarningsInPublicChannel);
                }
                foreach (var warning in query)
                {
                    var issuerName = warning.IssuerId == 0 ? "" : await client.GetUserNameAsync(channel, warning.IssuerId, isPrivate, "unknown mod").ConfigureAwait(false);

                    var timestamp = warning.Timestamp.HasValue ? new DateTime(warning.Timestamp.Value, DateTimeKind.Utc).ToString("u") : null;
                    result.Append($"{warning.Id:00000} | {issuerName,-15} | {timestamp,-20} | {warning.Reason}");
                    if (isPrivate)
                    {
                        result.Append(" | ").Append(warning.FullReason);
                    }
                    result.AppendLine();
                }
                await channel.SendAutosplitMessageAsync(result.Append("```")).ConfigureAwait(false);
            }
        }
コード例 #23
0
ファイル: Sudo.Fix.cs プロジェクト: guipleite/discord-bot
 public async Task Timestamps(CommandContext ctx)
 {
     try
     {
         var @fixed = 0;
         using (var db = new BotDb())
         {
             foreach (var warning in db.Warning)
             {
                 if (!string.IsNullOrEmpty(warning.FullReason))
                 {
                     var match = Timestamp.Match(warning.FullReason);
                     if (match.Success && DateTime.TryParse(match.Groups["date"].Value, out var timestamp))
                     {
                         warning.Timestamp  = timestamp.Ticks;
                         warning.FullReason = warning.FullReason.Substring(match.Groups["cutout"].Value.Length);
                         @fixed++;
                     }
                 }
             }
             await db.SaveChangesAsync().ConfigureAwait(false);
         }
         await ctx.RespondAsync($"Fixed {@fixed} records").ConfigureAwait(false);
     }
     catch (Exception e)
     {
         Config.Log.Warn(e, "Couldn't fix warning timestamps");
         await ctx.RespondAsync("Failed to fix warning timestamps").ConfigureAwait(false);
     }
 }
コード例 #24
0
        public static async Task <bool> IsWhitelistedAsync(DiscordInvite invite)
        {
            var code = string.IsNullOrWhiteSpace(invite.Code) ? null : invite.Code;
            var name = string.IsNullOrWhiteSpace(invite.Guild.Name) ? null : invite.Guild.Name;

            await using var db = new BotDb();
            var whitelistedInvite = await db.WhitelistedInvites.FirstOrDefaultAsync(i => i.GuildId == invite.Guild.Id);

            if (whitelistedInvite == null)
            {
                return(false);
            }

            if (name != null && name != whitelistedInvite.Name)
            {
                whitelistedInvite.Name = invite.Guild.Name;
            }
            if (string.IsNullOrEmpty(whitelistedInvite.InviteCode) && code != null)
            {
                whitelistedInvite.InviteCode = code;
            }
            await db.SaveChangesAsync().ConfigureAwait(false);

            return(true);
        }
コード例 #25
0
        private static void AppendPawStats(DiscordEmbedBuilder embed)
        {
            try
            {
                using var db = new BotDb();
                var kots   = db.Kot.Count();
                var doggos = db.Doggo.Count();
                if (kots == 0 && doggos == 0)
                {
                    return;
                }

                var diff = kots > doggos ? (double)kots / doggos - 1.0 : (double)doggos / kots - 1.0;
                var sign = double.IsNaN(diff) || (double.IsFinite(diff) && !double.IsNegative(diff) && diff < 0.05) ? ":" : (kots > doggos ? ">" : "<");
                var kot  = sign switch
                {
                    ">" => GoodKot[new Random().Next(GoodKot.Length)],
                    ":" => "🐱",
                    _ => MeanKot[new Random().Next(MeanKot.Length)]
                };
                embed.AddField("🐾 Stats", $"{kot} {kots - 1} {sign} {doggos - 1} 🐶", true);
            }
            catch (Exception e)
            {
                Config.Log.Warn(e);
            }
        }
コード例 #26
0
        public static async Task CleanupAsync(DiscordClient client)
        {
            while (!Config.Cts.IsCancellationRequested)
            {
                await using var db = new BotDb();
                foreach (var invite in db.WhitelistedInvites.Where(i => i.InviteCode != null))
                {
                    try
                    {
                        var result = await client.GetInviteByCodeAsync(invite.InviteCode).ConfigureAwait(false);

                        if (result?.IsRevoked == true)
                        {
                            invite.InviteCode = null;
                        }
                    }
                    catch (NotFoundException)
                    {
                        invite.InviteCode = null;
                        Config.Log.Info($"Removed invite code {invite.InviteCode} for server {invite.Name}");
                    }
                    catch (Exception e)
                    {
                        Config.Log.Debug(e);
                    }
                }
                await db.SaveChangesAsync(Config.Cts.Token).ConfigureAwait(false);

                await Task.Delay(TimeSpan.FromHours(1), Config.Cts.Token).ConfigureAwait(false);
            }
        }
コード例 #27
0
        public override void Run(List <DataObject> result)
        {
            List <MessageBase> messages = result.OfType <MessageBase>().ToList();

            if (!messages.Any())
            {
                return;
            }

            int[] messageIds = messages.Select(s => s.MessageId).ToArray();

            using (BotDb db = new BotDb())
            {
                HashSet <int> existing = db.Messages.Where(s => messageIds.Contains(s.MessageId)).Select(s => s.MessageId).ToHashset();

                foreach (MessageBase message in messages.Where(s => !existing.Contains(s.MessageId)))
                {
                    db.Messages.Add(new DbMessage
                    {
                        MessageId = message.MessageId,
                        Message   = message,
                        TabType   = message.TabType
                    });
                }

                db.SaveChanges();
            }
        }
コード例 #28
0
        public static async Task <Explanation> GetExplanationAsync(string term)
        {
            using var db = new BotDb();
            var result = await db.Explanation.FirstOrDefaultAsync(e => e.Keyword == term).ConfigureAwait(false);

            return(result ?? DefaultExplanation[term]);
        }
コード例 #29
0
            public async Task By(CommandContext ctx, ulong moderatorId, [Description("Optional number of items to show. Default is 10")] int number = 10)
            {
                if (number < 1)
                {
                    number = 10;
                }
                var table = new AsciiTable(
                    new AsciiColumn("ID", alignToRight: true),
                    new AsciiColumn("Username", maxWidth: 24),
                    new AsciiColumn("User ID", disabled: !ctx.Channel.IsPrivate, alignToRight: true),
                    new AsciiColumn("On date (UTC)"),
                    new AsciiColumn("Reason"),
                    new AsciiColumn("Context", disabled: !ctx.Channel.IsPrivate)
                    );

                await using var db = new BotDb();
                var query = from warn in db.Warning
                            where warn.IssuerId == moderatorId && !warn.Retracted
                            orderby warn.Id descending
                            select warn;

                foreach (var row in query.Take(number))
                {
                    var username = await ctx.GetUserNameAsync(row.DiscordId).ConfigureAwait(false);

                    var timestamp = row.Timestamp.HasValue ? new DateTime(row.Timestamp.Value, DateTimeKind.Utc).ToString("u") : "";
                    table.Add(row.Id.ToString(), username, row.DiscordId.ToString(), timestamp, row.Reason, row.FullReason);
                }
                var modName = await ctx.GetUserNameAsync(moderatorId, defaultName : "Unknown mod").ConfigureAwait(false);

                await ctx.SendAutosplitMessageAsync(new StringBuilder($"Recent warnings issued by {modName}:").Append(table)).ConfigureAwait(false);
            }
コード例 #30
0
        protected override CommandQueueElement RunInternal()
        {
            var resp = Client.IssueRequest(Client.RequestBuilder.GetOverviewPage());
            var info = resp.GetParsedSingle <OgamePageInfo>();

            int playerId = info.PlayerId;

            using (BotDb db = new BotDb())
            {
                try
                {
                    db.Planets.Where(p => p.PlayerId == playerId)
                    .Select(p => p.LocationId)
                    .AsEnumerable()
                    .Select(p => (Coordinate)p)
                    .Where(c => c.Type != Objects.Types.CoordinateType.Moon)
                    .ToList()
                    .ForEach(Scan);
                }
                catch (Exception ex)
                {
                    Logging.Logger.Instance.LogException(ex);
                }
            }


            return(null);
        }