public async Task Set(ulong messageId, IEmote emote, IRole role) { if (!Permissions.IsAdministratorOrBotOwner(Context)) { await Context.ApplyResultReaction(CommandResult.FailedUserPermission).ConfigureAwait(false); return; } if (!(await Permissions.CanBotManageRoles(Context).ConfigureAwait(false))) { await Context.ApplyResultReaction(CommandResult.FailedBotPermission).ConfigureAwait(false); return; } var link = _links.FirstOrDefault(l => ulong.TryParse(l.Value, out ulong value) && value == messageId); if (link == null) { await Context.ApplyResultReaction(CommandResult.Failed).ConfigureAwait(false); return; } // Verify that the link does not exist yet var linkValue = $"{((emote as Emote)?.Id)?.ToString() ?? emote.Name}={role.Id}"; if (null != link.Links.FirstOrDefault(l => string.Equals(l.Identity, linkValue, StringComparison.CurrentCultureIgnoreCase))) { await Context.ApplyResultReaction(CommandResult.Failed).ConfigureAwait(false); return; } link.Links.Add(new LinkItem() { Identity = linkValue, Link = link }); await Ditto.Database.WriteAsync(uow => { uow.Links.UpdateRange(link); }); // Find the message and react with said emote. var message = await GetMessageAsync(link.Guild, messageId, link.Channel).ConfigureAwait(false); if (message != null) { await message.AddReactionAsync(emote).ConfigureAwait(false); } await Context.ApplyResultReaction(CommandResult.Success).ConfigureAwait(false); }
public async Task New(ulong messageId) { if (!Permissions.IsAdministratorOrBotOwner(Context)) { await Context.ApplyResultReaction(CommandResult.FailedUserPermission).ConfigureAwait(false); return; } if (!(await Permissions.CanBotManageRoles(Context).ConfigureAwait(false))) { await Context.ApplyResultReaction(CommandResult.FailedBotPermission).ConfigureAwait(false); return; } IUserMessage message = await GetMessageAsync(Context.Guild, messageId).ConfigureAwait(false); var textChannel = message?.Channel as ITextChannel; // Verify message found if (message == null || textChannel == null) { await Context.ApplyResultReaction(CommandResult.Failed).ConfigureAwait(false); return; } // Verify reaction permissions var channelPermissions = (await Context.Guild.GetCurrentUserAsync().ConfigureAwait(false))?.GetPermissions(textChannel); if (channelPermissions?.AddReactions != true) { await Context.ApplyResultReaction(CommandResult.FailedBotPermission).ConfigureAwait(false); return; } // Add link var link = await LinkUtility.TryAddLinkAsync(LinkType.RoleMenu, textChannel, messageId.ToString()).ConfigureAwait(false); if (link == null) { await Context.ApplyResultReaction(CommandResult.Failed).ConfigureAwait(false); return; } // Add the link to our collection. _links.Add(link); // Handle link var result = await HandleLinkAsync(link).ConfigureAwait(false); await Context.ApplyResultReaction(result == true?CommandResult.Success : CommandResult.Failed).ConfigureAwait(false); }
private static async Task <bool> HandleLinkAsync(Link link) { IUserMessage message = null; if (ulong.TryParse(link.Value, out ulong messageId)) { message = await GetMessageAsync(link.Guild, messageId, link.Channel).ConfigureAwait(false); } if (message == null) { return(false); } // Handle message Ditto.ReactionHandler.Remove(message); var funcReaction = new Func <Discord.WebSocket.SocketReaction, bool, Task>(async(Discord.WebSocket.SocketReaction r, bool added) => { try { if (r.User.Value?.IsBot != true) { var link = _links.FirstOrDefault(l => ulong.TryParse(l.Value, out ulong value) && value == r.MessageId); if (link != null) { // Use the ID or Unicode value depending on the type. LinkItem linkItem = r.Emote is Emote guildEmote ? link.Links.FirstOrDefault(l => ulong.TryParse(l.Identity.Split('=', System.StringSplitOptions.RemoveEmptyEntries).FirstOrDefault(), out ulong value) && value == guildEmote.Id) : link.Links.FirstOrDefault(l => string.Equals(r.Emote.Name, l.Identity.Split('=', System.StringSplitOptions.RemoveEmptyEntries).FirstOrDefault(), StringComparison.CurrentCultureIgnoreCase)); if (linkItem != null && ulong.TryParse(linkItem.Identity.Split('=', System.StringSplitOptions.RemoveEmptyEntries).LastOrDefault(), out ulong roleId)) { var role = link.Guild.GetRole(roleId); if (role != null) { if (await Permissions.CanBotManageRoles(link.Guild).ConfigureAwait(false)) { if (r.User.Value is IGuildUser guildUser) { try { // Add or remove the role from the user. bool success = false; if (added) { if (!guildUser.RoleIds.Contains(role.Id)) { await guildUser.AddRoleAsync(role).ConfigureAwait(false); success = true; } } else { if (guildUser.RoleIds.Contains(role.Id)) { await guildUser.RemoveRoleAsync(role).ConfigureAwait(false); success = true; } } // Attempt to send the user a DM message, after setting the roles for better error handling. if (success) { try { var dmChannel = await guildUser.CreateDMChannelAsync().ConfigureAwait(false); if (dmChannel != null) { if (added) { await dmChannel.SendMessageAsync($"**{link.Guild.Name}**: You have given yourself the role `{role.Name}`!").ConfigureAwait(false); } else { await dmChannel.SendMessageAsync($"**{link.Guild.Name}**: You have removed the role `{role.Name}` from yourself!").ConfigureAwait(false); } } } catch { } } } catch (Exception ex) { Log.Warn($"Role menu: Could not adjust role of user '{r.User.Value.Username}' | {ex}"); } } else { Log.Warn($"Role menu: Could not find user '{r.User.Value.Username}'."); } } else { Log.Warn($"Role menu: Cannot modify roles in guild <{link.Guild.Name}:{link.Guild.Id}>."); } } } } } } catch (Exception ex) { Log.Error($"Huh | {ex}"); } }); return(Ditto.ReactionHandler.Add(message, r => funcReaction(r, true), r => funcReaction(r, false))); }