public static async Task BulkDeleteEventHandlerAsync(TheGodfatherBot bot, MessageBulkDeleteEventArgs e) { if (e.Guild is null) { return; } if (!LoggingService.IsLogEnabledForGuild(bot, e.Guild.Id, out LoggingService logService, out LocalizedEmbedBuilder emb)) { return; } if (LoggingService.IsChannelExempted(bot, e.Guild, e.Channel, out GuildConfigService gcs)) { return; } emb.WithLocalizedTitle(DiscordEventType.MessagesBulkDeleted, "evt-msg-del-bulk", e.Channel); emb.AddLocalizedTitleField("str-count", e.Messages.Count, inline: true); using var ms = new MemoryStream(); using var sw = new StreamWriter(ms); foreach (DiscordMessage msg in e.Messages) { sw.WriteLine($"[{msg.Timestamp}] {msg.Author}"); sw.WriteLine(string.IsNullOrWhiteSpace(msg.Content) ? "?" : msg.Content); sw.WriteLine(msg.Attachments.Select(a => $"{a.FileName} ({a.FileSize})").JoinWith(", ")); sw.Flush(); } ms.Seek(0, SeekOrigin.Begin); DiscordChannel?chn = gcs.GetLogChannelForGuild(e.Guild); await(chn?.SendFileAsync($"{e.Channel.Name}-deleted-messages.txt", ms, embed: emb.Build()) ?? Task.CompletedTask); }
public static async Task MessageCreateEventHandlerAsync(TheGodfatherBot bot, MessageCreateEventArgs e) { if (e.Author.IsBot) { return; } if (e.Guild is null) { LogExt.Debug(bot.GetId(null), new[] { "DM message received from {User}:", "{Message}" }, e.Author, e.Message); return; } if (bot.Services.GetRequiredService <BlockingService>().IsBlocked(e.Guild.Id, e.Channel.Id, e.Author.Id)) { return; } if (string.IsNullOrWhiteSpace(e.Message?.Content)) { return; } if (!e.Message.Content.StartsWith(bot.Services.GetRequiredService <GuildConfigService>().GetGuildPrefix(e.Guild.Id))) { short rank = bot.Services.GetRequiredService <UserRanksService>().ChangeXp(e.Guild.Id, e.Author.Id); if (rank != 0) { LocalizationService ls = bot.Services.GetRequiredService <LocalizationService>(); LevelRole? lr = await bot.Services.GetRequiredService <LevelRoleService>().GetAsync(e.Guild.Id, rank); DiscordRole?levelRole = lr is { } ? e.Guild.GetRole(lr.RoleId) : null;
public static async Task <bool> SendFeedUpdateAsync(TheGodfatherBot shard, RssSubscription sub, SyndicationItem latest) { DiscordChannel?chn; try { chn = await shard.Client.GetShard(sub.GuildId).GetChannelAsync(sub.ChannelId); } catch (NotFoundException) { return(false); } if (chn is null) { return(false); } var emb = new LocalizedEmbedBuilder(shard.Services.GetRequiredService <LocalizationService>(), sub.GuildId); emb.WithTitle(latest.Title.Text); emb.WithUrl(sub.Feed.LastPostUrl); emb.WithColor(DiscordColor.Gold); emb.WithLocalizedTimestamp(latest.LastUpdatedTime > latest.PublishDate ? latest.LastUpdatedTime : latest.PublishDate); if (latest.Content is TextSyndicationContent content) { string?imageUrl = RedditService.GetImageUrl(content); if (imageUrl is { })
public static Task GuildAvailableEventHandlerAsync(TheGodfatherBot bot, GuildCreateEventArgs e) { LogExt.Information(bot.GetId(e.Guild.Id), "Available: {AvailableGuild}", e.Guild); GuildConfigService gcs = bot.Services.GetRequiredService <GuildConfigService>(); return(gcs.IsGuildRegistered(e.Guild.Id) ? Task.CompletedTask : gcs.RegisterGuildAsync(e.Guild.Id)); }
public static Task CommandErrorEventHandlerAsync(TheGodfatherBot bot, CommandErrorEventArgs e) { if (e.Exception is null) { return(Task.CompletedTask); } Exception ex = e.Exception; while (ex is AggregateException or TargetInvocationException && ex.InnerException is { })
public static Task ClientErrorEventHandlerAsync(TheGodfatherBot _, ClientErrorEventArgs e) { Exception ex = e.Exception; while (ex is AggregateException) { ex = ex.InnerException ?? ex; } Log.Error(ex, "Client errored: {EventName}", e.EventName); return(Task.CompletedTask); }
public static Task CommandExecutionEventHandler(TheGodfatherBot bot, CommandExecutionEventArgs e) { if (e.Command is null || e.Command.QualifiedName.StartsWith("help")) { return(Task.CompletedTask); } LogExt.Information( bot.GetId(e.Context.Guild?.Id), new[] { "Executed: {ExecutedCommand}", "{User}", "{Guild}", "{Channel}" }, e.Command.QualifiedName, e.Context.User, e.Context.Guild?.ToString() ?? "DM", e.Context.Channel ); return(Task.CompletedTask); }
public static async Task GuildCreateEventHandlerAsync(TheGodfatherBot bot, GuildCreateEventArgs e) { LogExt.Information(bot.GetId(e.Guild.Id), "Joined {NewGuild}", e.Guild); if (bot.Services.GetRequiredService <BlockingService>().IsGuildBlocked(e.Guild.Id)) { LogExt.Information(bot.GetId(e.Guild.Id), "{Guild} is blocked. Leaving...", e.Guild); await e.Guild.LeaveAsync(); return; } IReadOnlyCollection <DiscordMember> members = await e.Guild.GetAllMembersAsync(); int botCount = members.Where(m => m.IsBot).Count(); if (botCount > 25 || (members.Count - botCount < 0)) { LogExt.Information(bot.GetId(e.Guild.Id), "{Guild} is most likely a bot farm. Leaving and blocking...", e.Guild); await e.Guild.LeaveAsync(); await bot.Services.GetRequiredService <BlockingService>().BlockGuildAsync(e.Guild.Id, "Bot farm"); return; } await bot.Services.GetRequiredService <GuildConfigService>().RegisterGuildAsync(e.Guild.Id); DiscordChannel defChannel = e.Guild.GetDefaultChannel(); if (!defChannel.PermissionsFor(e.Guild.CurrentMember).HasPermission(Permissions.SendMessages)) { return; } string prefix = bot.Services.GetRequiredService <BotConfigService>().CurrentConfiguration.Prefix; string owners = bot.Client.CurrentApplication.Owners.Select(o => o.ToDiscriminatorString()).Humanize(", "); await defChannel.EmbedAsync( $"{Formatter.Bold("Thank you for adding me!")}\n\n" + $"{Emojis.SmallBlueDiamond} The default prefix for commands is {Formatter.Bold(prefix)}, but it can be changed " + $"via {Formatter.Bold("prefix")} command.\n" + $"{Emojis.SmallBlueDiamond} I advise you to run the configuration wizard for this guild in order to quickly configure " + $"functions like logging, notifications etc. The wizard can be invoked using {Formatter.Bold("config setup")} command.\n" + $"{Emojis.SmallBlueDiamond} You can use the {Formatter.Bold("help")} command as a guide, though it is recommended to " + $"read the documentation @ https://github.com/ivan-ristovic/the-godfather \n" + $"{Emojis.SmallBlueDiamond} If you have any questions or problems, feel free to use the {Formatter.Bold("report")} " + $"command in order to send a message to the bot owners ({owners}). Alternatively, you can create an issue on " + $"GitHub or join WorldMafia Discord server for quick support (https://worldmafia.net/discord)." , Emojis.Wave ); }
public static void FindAndRegister(TheGodfatherBot shard) { ListenerMethods = from t in Assembly.GetExecutingAssembly().GetTypes() from m in t.GetMethods() let a = m.GetCustomAttribute(typeof(AsyncEventListenerAttribute), inherit: true) where a is { } select new ListenerMethod(m, (AsyncEventListenerAttribute)a); foreach (ListenerMethod lm in ListenerMethods) { lm.Attribute.Register(shard, lm.Method); } }
public static async Task MessageReactionAddedEventHandlerAsync(TheGodfatherBot bot, MessageReactionAddEventArgs e) { if (e.Guild is null || e.Channel is null || e.Message is null) { return; } StarboardService ss = bot.Services.GetRequiredService <StarboardService>(); if (ss.IsStarboardEnabled(e.Guild.Id, out ulong cid, out string star) && cid != e.Channel.Id && e.Emoji.GetDiscordName() == star) { LogExt.Debug(bot.GetId(e.Guild.Id), "Reacted with star emoji: Message {MessageId}, {Guild}", e.Message.Id, e.Guild); ss.RegisterModifiedMessage(e.Guild.Id, e.Channel.Id, e.Message.Id); } ReactionRoleService rrs = bot.Services.GetRequiredService <ReactionRoleService>(); ReactionRole? rr = await rrs.GetAsync(e.Guild.Id, e.Emoji.GetDiscordName()); if (rr is { })
public static async Task GuildMemberJoinEventHandlerAsync(TheGodfatherBot bot, GuildMemberAddEventArgs e) { if (e.Guild is null) { return; } LogExt.Debug(bot.GetId(e.Guild.Id), "Member added: {Member} {Guild}", e.Member, e.Guild); GuildConfigService gcs = bot.Services.GetRequiredService <GuildConfigService>(); GuildConfig gcfg = await gcs.GetConfigAsync(e.Guild.Id); await Task.Delay(TimeSpan.FromSeconds(gcfg.AntiInstantLeaveSettings.Cooldown + 1)); if (e.Member.Guild is null) // User left in meantime { return; } // TODO move to service DiscordChannel?wchn = e.Guild.GetChannel(gcfg.WelcomeChannelId); if (wchn is { })
public static Task MessageReactionsClearedEventHandlerAsync(TheGodfatherBot bot, MessageReactionsClearEventArgs e) { if (e.Guild is null || e.Channel is null || e.Message is null || e.Message.Author == bot.Client.GetShard(e.Channel.Guild).CurrentUser) { return(Task.CompletedTask); } if (bot.Services.GetRequiredService <BlockingService>().IsChannelBlocked(e.Channel.Id)) { return(Task.CompletedTask); } if (e.Message.Author == bot.Client.CurrentUser && bot.Services.GetRequiredService <ChannelEventService>().IsEventRunningInChannel(e.Channel.Id)) { return(Task.CompletedTask); } if (!LoggingService.IsLogEnabledForGuild(bot, e.Guild.Id, out LoggingService logService, out LocalizedEmbedBuilder emb)) { return(Task.CompletedTask); } if (LoggingService.IsChannelExempted(bot, e.Guild, e.Channel, out _)) { return(Task.CompletedTask); } LocalizationService ls = bot.Services.GetRequiredService <LocalizationService>(); string jumplink = Formatter.MaskedUrl(ls.GetString(e.Guild.Id, "str-jumplink"), e.Message.JumpLink); emb.WithLocalizedTitle(DiscordEventType.MessageReactionsCleared, "evt-msg-reactions-clear", desc: jumplink); emb.AddLocalizedTitleField("str-location", e.Channel.Mention, inline: true); emb.AddLocalizedTitleField("str-author", e.Message.Author?.Mention, inline: true); return(logService.LogAsync(e.Channel.Guild, emb)); }
public static async Task GrantRolesAsync(this AutoRoleService service, TheGodfatherBot shard, DiscordGuild guild, DiscordMember member) { foreach (ulong rid in service.GetIds(guild.Id)) { DiscordRole?role = guild.GetRole(rid); if (role is { })
public static Task SocketOpenedEventHandlerAsync(TheGodfatherBot bot, SocketEventArgs _) { Log.Debug("Socket opened"); bot.Services.GetRequiredService <BotActivityService>().UptimeInformation.SocketStartTime = DateTimeOffset.Now; return(Task.CompletedTask); }
public static Task SocketClosedEventHandlerAsync(TheGodfatherBot bot, SocketCloseEventArgs e) { Log.Debug("Socket closed with code {Code}: {Message}", e.CloseCode, e.CloseMessage); return(Task.CompletedTask); }
public void Register(TheGodfatherBot bot, MethodInfo mi) { BotActivityService bas = bot.Services.GetRequiredService <BotActivityService>(); Task OnEventWithArgs(object _, object e) { if (!bas.IsBotListening) { return(Task.CompletedTask); } _ = Task.Run(async() => { try { await(Task) mi.Invoke(null, new object[] { bot, e }) !; } catch (Exception ex) { Log.Error(ex, "Listener threw an exception"); } }); return(Task.CompletedTask); } #region Event hooking switch (this.EventType) { case DiscordEventType.ChannelCreated: bot.Client.ChannelCreated += OnEventWithArgs; break; case DiscordEventType.ChannelDeleted: bot.Client.ChannelDeleted += OnEventWithArgs; break; case DiscordEventType.ChannelPinsUpdated: bot.Client.ChannelPinsUpdated += OnEventWithArgs; break; case DiscordEventType.ChannelUpdated: bot.Client.ChannelUpdated += OnEventWithArgs; break; case DiscordEventType.ClientErrored: bot.Client.ClientErrored += OnEventWithArgs; break; case DiscordEventType.CommandErrored: foreach (CommandsNextExtension cnext in bot.CNext.Values) { cnext.CommandErrored += OnEventWithArgs; } break; case DiscordEventType.CommandExecuted: foreach (CommandsNextExtension cnext in bot.CNext.Values) { cnext.CommandExecuted += OnEventWithArgs; } break; case DiscordEventType.DmChannelCreated: bot.Client.DmChannelCreated += OnEventWithArgs; break; case DiscordEventType.DmChannelDeleted: bot.Client.DmChannelDeleted += OnEventWithArgs; break; case DiscordEventType.GuildAvailable: bot.Client.GuildAvailable += OnEventWithArgs; break; case DiscordEventType.GuildBanAdded: bot.Client.GuildBanAdded += OnEventWithArgs; break; case DiscordEventType.GuildBanRemoved: bot.Client.GuildBanRemoved += OnEventWithArgs; break; case DiscordEventType.GuildCreated: bot.Client.GuildCreated += OnEventWithArgs; break; case DiscordEventType.GuildDeleted: bot.Client.GuildDeleted += OnEventWithArgs; break; case DiscordEventType.GuildDownloadCompleted: bot.Client.GuildDownloadCompleted += OnEventWithArgs; break; case DiscordEventType.GuildEmojisUpdated: bot.Client.GuildEmojisUpdated += OnEventWithArgs; break; case DiscordEventType.GuildIntegrationsUpdated: bot.Client.GuildIntegrationsUpdated += OnEventWithArgs; break; case DiscordEventType.GuildMemberAdded: bot.Client.GuildMemberAdded += OnEventWithArgs; break; case DiscordEventType.GuildMemberRemoved: bot.Client.GuildMemberRemoved += OnEventWithArgs; break; case DiscordEventType.GuildMemberUpdated: bot.Client.GuildMemberUpdated += OnEventWithArgs; break; case DiscordEventType.GuildMembersChunked: bot.Client.GuildMembersChunked += OnEventWithArgs; break; case DiscordEventType.GuildRoleCreated: bot.Client.GuildRoleCreated += OnEventWithArgs; break; case DiscordEventType.GuildRoleUpdated: bot.Client.GuildRoleUpdated += OnEventWithArgs; break; case DiscordEventType.GuildRoleDeleted: bot.Client.GuildRoleDeleted += OnEventWithArgs; break; case DiscordEventType.GuildUnavailable: bot.Client.GuildUnavailable += OnEventWithArgs; break; case DiscordEventType.GuildUpdated: bot.Client.GuildUpdated += OnEventWithArgs; break; case DiscordEventType.Heartbeated: bot.Client.Heartbeated += OnEventWithArgs; break; case DiscordEventType.InviteCreated: bot.Client.InviteCreated += OnEventWithArgs; break; case DiscordEventType.InviteDeleted: bot.Client.InviteDeleted += OnEventWithArgs; break; case DiscordEventType.MessageAcknowledged: foreach (DiscordClient client in bot.Client.ShardClients.Values) { client.MessageAcknowledged += OnEventWithArgs; } break; case DiscordEventType.MessagesBulkDeleted: bot.Client.MessagesBulkDeleted += OnEventWithArgs; break; case DiscordEventType.MessageCreated: bot.Client.MessageCreated += OnEventWithArgs; break; case DiscordEventType.MessageReactionAdded: bot.Client.MessageReactionAdded += OnEventWithArgs; break; case DiscordEventType.MessageReactionRemoved: bot.Client.MessageReactionRemoved += OnEventWithArgs; break; case DiscordEventType.MessageReactionRemovedEmoji: bot.Client.MessageReactionRemovedEmoji += OnEventWithArgs; break; case DiscordEventType.MessageReactionsCleared: bot.Client.MessageReactionsCleared += OnEventWithArgs; break; case DiscordEventType.MessageDeleted: bot.Client.MessageDeleted += OnEventWithArgs; break; case DiscordEventType.MessageUpdated: bot.Client.MessageUpdated += OnEventWithArgs; break; case DiscordEventType.PresenceUpdated: bot.Client.PresenceUpdated += OnEventWithArgs; break; case DiscordEventType.Ready: bot.Client.Ready += OnEventWithArgs; break; case DiscordEventType.Resumed: bot.Client.Resumed += OnEventWithArgs; break; case DiscordEventType.SocketClosed: bot.Client.SocketClosed += OnEventWithArgs; break; case DiscordEventType.SocketErrored: bot.Client.SocketErrored += OnEventWithArgs; break; case DiscordEventType.SocketOpened: bot.Client.SocketOpened += OnEventWithArgs; break; case DiscordEventType.TypingStarted: bot.Client.TypingStarted += OnEventWithArgs; break; case DiscordEventType.UnknownEvent: bot.Client.UnknownEvent += OnEventWithArgs; break; case DiscordEventType.UserSettingsUpdated: bot.Client.UserSettingsUpdated += OnEventWithArgs; break; case DiscordEventType.UserUpdated: bot.Client.UserUpdated += OnEventWithArgs; break; case DiscordEventType.VoiceServerUpdated: bot.Client.VoiceServerUpdated += OnEventWithArgs; break; case DiscordEventType.VoiceStateUpdated: bot.Client.VoiceStateUpdated += OnEventWithArgs; break; case DiscordEventType.WebhooksUpdated: bot.Client.WebhooksUpdated += OnEventWithArgs; break; default: Log.Warning("No logic for handling event type: {EventType}", Enum.GetName(typeof(DiscordEventType), this.EventType)); break; } #endregion }
public static Task SocketErroredEventHandlerAsync(TheGodfatherBot shard, SocketErrorEventArgs e) { Log.Debug(e.Exception, "Socket errored"); return(Task.CompletedTask); }
public static Task UnknownEventHandlerAsync(TheGodfatherBot shard, UnknownEventArgs e) { Log.Error("Unknown event ({UnknownEvent}) occured: {@UnknownEventJson}", e.EventName, e.Json); return(Task.CompletedTask); }
public static Task UserSettingsUpdatedEventHandlerAsync(TheGodfatherBot bot, UserSettingsUpdateEventArgs e) { Log.Information("User settings updated"); return(Task.CompletedTask); }
public static Task GuildDownloadCompletedEventHandlerAsync(TheGodfatherBot bot, GuildDownloadCompletedEventArgs e) { Log.Information("All guilds are now downloaded ({Count} total)", e.Guilds.Count); return(Task.CompletedTask); }
public static bool IsChannelExempted(TheGodfatherBot shard, DiscordGuild?guild, DiscordChannel channel, out GuildConfigService gcs) { gcs = shard.Services.GetRequiredService <GuildConfigService>(); return(guild is { } && gcs.IsChannelExempted(guild.Id, channel.Id, channel.ParentId));
public static Task GuildUnvailableEventHandlerAsync(TheGodfatherBot bot, GuildDeleteEventArgs e) { LogExt.Warning(bot.GetId(e.Guild.Id), "Unvailable: {UnvailableGuild}", e.Guild); return(Task.CompletedTask); }
public static bool IsLogEnabledForGuild(TheGodfatherBot shard, ulong gid, out LoggingService logService, out LocalizedEmbedBuilder emb) { logService = shard.Services.GetRequiredService <LoggingService>(); return(logService.IsLogEnabledFor(gid, out emb)); }