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); } } }
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); }
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); } }
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); }
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); } }
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(); }
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); } } }
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); }
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); } }
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); } } } }
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); } } } }
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); }
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); }
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); } } }
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(); }
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); } }
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(); }
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); }
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); } }
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); } }
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); }
//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); } }
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); } }
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); }
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); } }
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); } }
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(); } }
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]); }
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); }
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); }