/// <summary> /// The handling method for when a user adds a reaction to the role assignment message. The bot will /// assign the associated role to the user if it's assignable. /// </summary> /// <param name="message">The message the user reacted to</param> /// <param name="channel">The channel the message/reaction are in</param> /// <param name="reaction">The reaction by the user</param> /// <returns></returns> private async Task OnReactionAdded(Cacheable <IUserMessage, ulong> messageCached, Cacheable <IMessageChannel, ulong> channelCached, SocketReaction reaction) { var message = await messageCached.GetOrDownloadAsync(); var channel = await channelCached.GetOrDownloadAsync(); var guildChannel = channel as SocketTextChannel; var guild = GuildRepo.Get(guildChannel.Guild.Id); var user = reaction.User.Value as SocketGuildUser; if (message.Id != guild.Settings.RoleAssignment.MessageId) { return; } var roleToAdd = guild.Settings.RoleAssignment.Roles.Find(r => r.Reaction == reaction.Emote.ToString()); // If a user adds an unknown reaction, just delete it. if (roleToAdd == null) { var guildMessage = await channel.GetMessageAsync(message.Id); await guildMessage.RemoveReactionAsync(reaction.Emote, user); return; } var discordRoleToAdd = guildChannel.Guild.GetRole(roleToAdd.RoleId); await user.AddRoleAsync(discordRoleToAdd); }
/// <summary> /// The handling method for when a user removes their reaction to the role assignment message. The bot will /// remove the associated role from the user if it's assignable. /// </summary> /// <param name="message">The message the user removed their reaction from</param> /// <param name="channel">The channel the message/reaction are in</param> /// <param name="reaction">The reaction removed by the user</param> /// <returns></returns> private async Task OnReactionRemoved(Cacheable <IUserMessage, ulong> messageCached, Cacheable <IMessageChannel, ulong> channelCached, SocketReaction reaction) { var message = await messageCached.GetOrDownloadAsync(); var channel = await channelCached.GetOrDownloadAsync(); var guildChannel = channel as SocketTextChannel; var guild = GuildRepo.Get(guildChannel.Guild.Id); if (message.Id != guild.Settings.RoleAssignment.MessageId) { return; } var roleToRemove = guild.Settings.RoleAssignment.Roles.Find(r => r.Reaction == reaction.Emote.ToString()); if (roleToRemove == null) { return; } var discordRoleToRemove = guildChannel.Guild.GetRole(roleToRemove.RoleId); if (discordRoleToRemove == null) { return; } var user = reaction.User.Value as SocketGuildUser; await user.RemoveRoleAsync(discordRoleToRemove); }
/// <summary> /// The handler for incoming messages. This will filter out non-commands and /// dispatch commands to the appropriate commands. /// </summary> /// <param name="message">The incoming message</param> /// <returns></returns> public async Task OnMessage(SocketMessage message) { // Only respond to human beings. if (message.Author.IsBot) { return; } var guildChannel = message.Channel as SocketGuildChannel; if (guildChannel is null) { return; } var guild = GuildRepo.Get(guildChannel.Guild.Id); if (guild == null || !message.Content.StartsWith(guild.Settings.Prefix)) { return; } var parts = message.Content.Split(); var commandName = parts[0].Substring(1); if (!Commands.ContainsKey(commandName)) { return; } var command = Commands[commandName]; await command.Run(message, string.Join(' ', parts.Skip(1))); }
/// <summary> /// Updates the assignment message with any potential changes to the assignable roles. /// </summary> /// <param name="discordGuild">The guild that is being operated on</param> /// <returns>The assignment message</returns> private async Task <IMessage> UpdateAssignerMessage(SocketGuild discordGuild) { var guild = GuildRepo.Get(discordGuild.Id); var assignerChannel = discordGuild.GetChannel(guild.Settings.RoleAssignment.ChannelId.Value) as SocketTextChannel; IUserMessage assignerMessage = assignerChannel.GetCachedMessage(guild.Settings.RoleAssignment.MessageId.Value) as SocketUserMessage; if (assignerMessage == null) { assignerMessage = await assignerChannel.GetMessageAsync(guild.Settings.RoleAssignment.MessageId.Value) as RestUserMessage; } // Search for any roles that may have been deleted without WhiffBot's knowledge // and delete those rows from the database. foreach (var role in guild.Settings.RoleAssignment.Roles) { if (discordGuild.GetRole(role.RoleId) == null) { GuildRepo.RemoveAssignableRole(guild.Id, role.RoleId); await assignerMessage.RemoveAllReactionsForEmoteAsync(role.Reaction.ToEmojiOrEmote()); guild = GuildRepo.Get(discordGuild.Id); } } var newContent = CreateAssignerMessage(discordGuild, guild.Settings.RoleAssignment); await assignerMessage.ModifyAsync(m => m.Content = newContent); return(assignerMessage); }
/// <summary> /// Creates a new assignment message for a guild. /// </summary> /// <param name="channel">The channel to create the assignment message in</param> /// <param name="guild">The stored guild information</param> /// <returns></returns> private async Task InitForGuild(SocketTextChannel channel, Guild guild) { var content = CreateAssignerMessage(channel.Guild, guild.Settings.RoleAssignment); var result = await channel.SendMessageAsync(content); await result.AddReactionsAsync(guild.Settings.RoleAssignment.Roles.Select(r => r.Reaction.ToEmojiOrEmote())); GuildRepo.SaveRoleAssignmentSettings(guild.Id, channel.Id, result.Id); }
private Task UpdateGuild(SocketGuild oldGuild, SocketGuild newGuild) { if (oldGuild.Name != newGuild.Name) { GuildRepo.UpdateGuildName(newGuild.Id, newGuild.Name); } return(Task.CompletedTask); }
/// <summary> /// The handling method for when a role is removed. This should remove the deleted role from the assigner message /// and remove any of the reactions for that role. /// </summary> /// <param name="role"></param> /// <returns></returns> private async Task OnRoleDeleted(SocketRole role) { var guild = GuildRepo.Get(role.Guild.Id); var roleToDelete = guild.Settings.RoleAssignment.Roles.Find(r => r.RoleId == role.Id); if (roleToDelete == null) { return; } await RemoveRole(role.Guild, guild, role); }
public void Start() { Log.ConsoleOUT("Start() called.").Wait(); #region Simple, Stupid DI Solution //Initialize simple DI solution. kernel = new StandardKernel(); kernel.Bind <IWARBOT, WARBOT>().ToConstant(this); kernel.Bind <IDiscordClient>().ToConstant(Client); kernel.Bind <ILog>().ToConstant(Log); kernel.Bind <IGuildConfigRepository>().ToConstant(GuildRepo); kernel.Bind <WarDB>().ToSelf().InThreadScope(); #endregion #region Create/Migration Database, if required. WarDB db = kernel.Get <WarDB>(); db.Migrate(); #endregion Quartz.Logging.LogProvider.SetCurrentLogProvider(new Util.QuartzLogProvider()); Jobs = new Implementation.QuartzJobScheduler(this); //Initialize the config repository with an instance of the WarDB from the DI container. GuildRepo.Initialize(this, db); //Initialize the commands. System.Collections.Generic.IEnumerable <ModuleInfo> discord_1 = commands.AddModulesAsync(typeof(Modules.Dialogs.MimicMeDialog).Assembly, kernel).Result; //Load the schedules to execute the war notifications. ScheduledJobs.ScheduleJobs(Jobs); //Attach basic events to the bot. The rest of the events will be attached after onReady is called. Client.Ready += Client_Ready; Client.ChannelDestroyed += Client_ChannelDestroyed; Client.Disconnected += Client_Disconnected; Client.JoinedGuild += Bot_GuildAdded; Client.GuildAvailable += Client_GuildAvailable; Client.LeftGuild += Bot_GuildDeleted; Client.Log += Client_Log; Client.MessageDeleted += Client_MessageDeleted_Poll; Client.MessageReceived += Client_MessageReceived; Client.ReactionAdded += Client_ReactionAdded; Client.ReactionRemoved += Client_ReactionRemoved; Client.RoleDeleted += Client_RoleDeleted; Client.UserJoined += Client_UserJoined; Client.UserLeft += Client_UserLeft; ////Login and start discord api. Client.LoginAsync(TokenType.Bot, Config.Discord_API_Token, true).Wait(); Client.StartAsync().Wait(); }
/// <summary> /// Removes a role from those that are assignable and updates the assignment mesasge accordingly. /// </summary> /// <param name="discordGuild">The guild being operated on</param> /// <param name="guild">The stored guild information</param> /// <param name="role">The role to remove</param> /// <returns></returns> private async Task RemoveRole(SocketGuild discordGuild, Guild guild, SocketRole role) { if (role == null) { return; } GuildRepo.RemoveAssignableRole(discordGuild.Id, role.Id); var message = await UpdateAssignerMessage(discordGuild); var emojiToRemove = guild.Settings.RoleAssignment.Roles.Find(r => r.RoleId == role.Id); await message.RemoveAllReactionsForEmoteAsync(emojiToRemove.Reaction.ToEmojiOrEmote()); }
/// <summary> /// The handling method for when a managing the assignment channel. Guild administrators /// can initialize the assignment, add assignable roles, or remove assignable roles. /// </summary> /// <param name="message">The message sent</param> /// <returns></returns> private async Task OnMessage(SocketMessage message) { // Only human administrators can manage the role assignment channel. if (message.Author.IsBot || !(message.Author as SocketGuildUser).GuildPermissions.Administrator) { return; } var channel = message.Channel as SocketTextChannel; if (channel == null) { return; } var guild = GuildRepo.Get(channel.Guild.Id); var parts = message.Content.Split(); if (parts[0] == $"{guild.Settings.Prefix}initRoleAssignment") { await InitForGuild(channel, guild); await channel.DeleteMessageAsync(message); return; } // Ignore any requests to add/remove roles if they aren't in the designated channel. if (guild.Settings.RoleAssignment.ChannelId != channel.Id) { return; } if (parts[0] == $"{guild.Settings.Prefix}addRole") { await AddNewRole(channel.Guild, guild, parts[1], message.MentionedRoles.FirstOrDefault()); } else if (parts[0] == $"{guild.Settings.Prefix}removeRole") { await RemoveRole(channel.Guild, guild, message.MentionedRoles.FirstOrDefault()); } else if (parts[0] == $"{guild.Settings.Prefix}updateMessage") { await UpdateAssignerMessage(channel.Guild); } await channel.DeleteMessageAsync(message); }
/// <summary> /// Adds a new role to the database and updates the assignment message to accept the new role. /// </summary> /// <param name="discordGuild">The guild being operated on</param> /// <param name="guild">The stored guild information</param> /// <param name="reaction">The reaction emote</param> /// <param name="role">The role to make assignable</param> /// <param name="messageToDelete">The sent message that should be deleted</param> /// <returns></returns> private async Task AddNewRole(SocketGuild discordGuild, Guild guild, string reaction, SocketRole role) { if ( string.IsNullOrWhiteSpace(reaction) || role == null || guild.Settings.RoleAssignment.Roles.Find(r => r.RoleId == role.Id) != null) { return; } GuildRepo.AddAssignableRole(discordGuild.Id, reaction, role.Id); var message = await UpdateAssignerMessage(discordGuild); await message.AddReactionAsync(reaction.ToEmojiOrEmote()); }
protected virtual void Dispose(bool disposing) { if (!disposedValue) { if (disposing) { _blacklist = null; _guild = null; _priority = null; _storedProcedure = null; _user = null; } disposedValue = true; } }
private Task InitGuild(SocketGuild discordGuild) { var guild = GuildRepo.Get(discordGuild.Id); if (guild == null) { GuildRepo.InitGuild(new Model.Guild { Id = discordGuild.Id, Name = discordGuild.Name }); } else { GuildRepo.UpdateGuildName(discordGuild.Id, discordGuild.Name); } return(Task.CompletedTask); }