Exemplo n.º 1
0
        Task HandleReactionAsync(IMessageChannel channel,
                                 SocketReaction reaction,
                                 ReactionEvent eventType)
        {
            if (reaction.UserId != _discord.CurrentUser.Id)
            {
                _ = Task.Run(async() =>
                {
                    // retrieve message
                    if (!(await channel.GetMessageAsync(reaction.MessageId) is IUserMessage message))
                    {
                        return;
                    }

                    // retrieve user
                    if (!(await channel.GetUserAsync(reaction.UserId) is IUser user))
                    {
                        return;
                    }

                    // create context
                    var context = new ReactionContext
                    {
                        Client        = _discord,
                        Message       = message,
                        User          = user,
                        GuildSettings = _guildSettingsCache[message.Channel],
                        Reaction      = reaction,
                        Event         = eventType
                    };

                    try
                    {
                        foreach (var handler in _reactionHandlers)
                        {
                            if (await handler.TryHandleAsync(context))
                            {
                                HandledReactions.Increment();
                                break;
                            }
                        }
                    }
                    catch (Exception e)
                    {
                        await _errorReporter.ReportAsync(e, context, false);
                    }
                    finally
                    {
                        ReceivedReactions.Increment();
                    }
                });
            }

            return(Task.CompletedTask);
        }
Exemplo n.º 2
0
        public async Task <bool> TryCreateEventAsync(ulong guildId, ulong channelId, CurrencyEvent.Type type,
                                                     EventOptions opts, Func <CurrencyEvent.Type, EventOptions, long, EmbedBuilder> embed)
        {
            SocketGuild       g  = _client.GetGuild(guildId);
            SocketTextChannel ch = g?.GetChannel(channelId) as SocketTextChannel;

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

            ICurrencyEvent ce;

            if (type == CurrencyEvent.Type.Reaction)
            {
                ce = new ReactionEvent(_client, _cs, _bc, g, ch, opts, embed);
            }
            //else if (type == Event.Type.NotRaid)
            //{
            //    ce = new NotRaidEvent(_client, _cs, _bc, g, ch, opts, embed);
            //}
            else
            {
                return(false);
            }

            var added = _events.TryAdd(guildId, ce);

            if (added)
            {
                try
                {
                    ce.OnEnded += OnEventEnded;
                    await ce.StartEvent().ConfigureAwait(false);
                }
                catch (Exception ex)
                {
                    _log.Warn(ex);
                    _events.TryRemove(guildId, out ce);
                    return(false);
                }
            }
            return(added);
        }
Exemplo n.º 3
0
        public async Task <bool> TryCreateEventAsync(ulong guildId, ulong channelId, CurrencyEvent.Type type,
                                                     EventOptions opts, Func <CurrencyEvent.Type, EventOptions, long, EmbedBuilder> embed)
        {
            SocketGuild       g  = _client.GetGuild(guildId);
            SocketTextChannel ch = g?.GetChannel(channelId) as SocketTextChannel;

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

            ICurrencyEvent ce;

            if (type == CurrencyEvent.Type.Reaction)
            {
                ce = new ReactionEvent(_client, _cs, g, ch, opts, _configService.Data, embed);
            }
            else if (type == CurrencyEvent.Type.GameStatus)
            {
                ce = new GameStatusEvent(_client, _cs, g, ch, opts, embed);
            }
            else
            {
                return(false);
            }

            var added = _events.TryAdd(guildId, ce);

            if (added)
            {
                try
                {
                    ce.OnEnded += OnEventEnded;
                    await ce.StartEvent().ConfigureAwait(false);
                }
                catch (Exception ex)
                {
                    Log.Warning(ex, "Error starting event");
                    _events.TryRemove(guildId, out ce);
                    return(false);
                }
            }
            return(added);
        }
Exemplo n.º 4
0
        private async Task DiscordClient_ReactionChanged(Cacheable <IUserMessage, ulong> userMessage, ISocketMessageChannel channel, SocketReaction reaction, ReactionEvent eventType)
        {
            var message = await userMessage.GetOrDownloadAsync();

            if (message == null)
            {
                return;
            }

            var user = reaction.User.IsSpecified ? reaction.User.Value : await DiscordClient.Rest.GetUserAsync(reaction.UserId);

            if (user == null)
            {
                return;
            }

            var ownUser = DiscordClient.CurrentUser;
            var ownId   = ownUser.Id;

            if (user.Id == ownId)
            {
                return;
            }

            foreach (var reactionHandler in ReactionHandlers)
            {
                try
                {
                    bool reactionHandled = await reactionHandler.HandleReactionChangedAsync(message, reaction.Emote, user, eventType);

                    if (reactionHandled)
                    {
                        break;
                    }

                    if (eventType == ReactionEvent.Added)
                    {
                        reactionHandled = await reactionHandler.HandleReactionAddedAsync(message, reaction.Emote, user);
                    }
                    else
                    {
                        reactionHandled = await reactionHandler.HandleReactionRemovedAsync(message, reaction.Emote, user);
                    }

                    if (reactionHandled)
                    {
                        break;
                    }
                }
                catch (Exception e)
                {
                    Logger.LogError(
                        e,
                        "Reaction handler {0} threw an exception when handling reaction {1} added to message {2}.",
                        reactionHandler,
                        reaction.Emote.Name,
                        message.Id
                        );
                }
            }
        }
Exemplo n.º 5
0
        public async Task <bool> HandleReactionChangedAsync(IUserMessage message, IEmote reaction, IUser user, ReactionEvent eventType)
        {
            // Basic check to optimize number of queries to db
            if (!message.Content.StartsWith("**\n"))
            {
                return(false);
            }

            var channel = message.Channel as ITextChannel;

            using var dbContext = DatabaseFactory.Create();
            var data = await dbContext.RoleMenuMessageRoles.AsQueryable()
                       .Where(i =>
                              i.GuildId == channel.GuildId &&
                              i.ChannelId == channel.Id &&
                              i.MessageId == message.Id)
                       .ToArrayAsync();

            // check if message is role picker message
            if (data.Length == 0)
            {
                return(false);
            }

            var role = Array.Find(data, d => d.Emote == reaction.ToString());

            // Invalid reaction
            if (role == null)
            {
                await message.RemoveReactionAsync(reaction, user);

                return(true);
            }

            var guildRoles   = channel.Guild.Roles.Where(r => data.Any(e => r.Id == e.RoleId));
            var selectedRole = guildRoles.FirstOrDefault(r => r.Id == role.RoleId);

            // Role does not exists
            if (selectedRole == null)
            {
                // TODO Remove role from db
                return(true);
            }

            if (user is not IGuildUser guildUser)
            {
                await message.RemoveReactionAsync(reaction, user);

                return(true);
            }

            if (eventType == ReactionEvent.Removed)
            {
                await guildUser.RemoveRoleAsync(selectedRole);

                return(true);
            }

            // Remove roles when in exclusive mode
            if (dbContext.RoleMenuMessages.Any(m =>
                                               m.GuildId == channel.GuildId &&
                                               m.ChannelId == channel.Id &&
                                               m.MessageId == message.Id &&
                                               !m.CanSelectMultiple))
            {
                var removeReactions = message.Reactions
                                      .Where(kv => kv.Value.IsMe && kv.Key.ToString() != reaction.ToString())
                                      .Select(kv => kv.Key)
                                      .ToArray();

                await message.RemoveReactionsAsync(user, removeReactions);

                var removeRoles = guildRoles.Where(r => guildUser.RoleIds.Contains(r.Id));
                await guildUser.RemoveRolesAsync(removeRoles);
            }

            await guildUser.AddRoleAsync(selectedRole);

            return(true);
        }
        public async Task <bool> HandleReactionChangedAsync(IUserMessage message, IEmote reaction, IUser user, ReactionEvent eventType)
        {
            if (user.IsBot)
            {
                return(false);
            }

            if (await VoteService.ParseVoteCommand(message) is not VoteDefinition voteDefinition)
            {
                return(false);
            }

            if (voteDefinition.IsPastDeadline())
            {
                // vote already finished
                await message.RemoveReactionAsync(reaction, user);

                return(true);
            }

            if (!voteDefinition.Options.ContainsKey(reaction))
            {
                // not a vote option
                await message.RemoveReactionAsync(reaction, user);

                return(true);
            }

            var newText = VoteService.ComposeSummary(message, voteDefinition);
            await VoteService.UpdateVoteReplyAsync(message, newText);

            return(true);
        }
Exemplo n.º 7
0
 public void RemoveReactionEvent(ReactionEvent reactionEvent)
 {
     _reactionEvents.Remove(reactionEvent);
 }
Exemplo n.º 8
0
 public void AddReactionEvent(ReactionEvent reactionEvent)
 {
     _reactionEvents.Add(reactionEvent);
 }