예제 #1
0
 public void RemoveStargazers(StarboardEntry entry)
 {
     _starboardData.LockedRef(coll =>
     {
         coll.Delete($"{entry.GuildId}_{entry.StarboardMessageId}");
         coll.Delete($"{entry.GuildId}_{entry.StarredMessageId}");
     });
 }
예제 #2
0
        public void UpdateStargazers(StarboardEntry entry)
        {
            _starboardData.LockedRef(coll =>
            {
                coll.Upsert($"{entry.GuildId}_{entry.StarboardMessageId}", new StarboardDbEntry
                {
                    GuildId = entry.GuildId,
                    Key     = entry.StarboardMessageId,
                    Value   = entry
                });

                coll.Upsert($"{entry.GuildId}_{entry.StarredMessageId}", new StarboardDbEntry
                {
                    GuildId = entry.GuildId,
                    Key     = entry.StarredMessageId,
                    Value   = entry
                });
            });
        }
예제 #3
0
        public async Task HandleReactionAddAsync(Cacheable <IUserMessage, ulong> cachedMessage, Cacheable <IMessageChannel, ulong> cachedChannel, SocketReaction reaction)
        {
            var channel = await cachedChannel.GetOrDownloadAsync();

            if (!IsStarReaction(channel, reaction, out var starboard, out var starboardChannel) || reaction.User.IsSpecified && reaction.User.Value.IsBot)
            {
                return;
            }

            var guildId   = channel.Cast <IGuildChannel>().Guild.Id;
            var messageId = cachedMessage.Id;
            var starrerId = reaction.UserId;

            var message = await cachedMessage.GetOrDownloadAsync();

            if (_db.TryGetStargazers(guildId, messageId, out var entry))
            {
                using (await _starboardReadWriteLock.LockAsync(entry.StarredMessageId))
                {
                    // Add the star to the database
                    if (entry.Stargazers.TryAdd(starrerId, channel == starboardChannel ? StarTarget.StarboardMessage : StarTarget.OriginalMessage))
                    {
                        // Update message star count
                        await UpdateOrPostToStarboardAsync(starboard, message, entry);

                        _db.UpdateStargazers(entry);
                    }
                    else if (starboard.DeleteInvalidStars)
                    {
                        // Invalid star! Either the starboard post or the actual message already has a reaction by this user.
                        await message.RemoveReactionAsync(_starEmoji, reaction.UserId,
                                                          DiscordHelper.CreateRequestOptions(x =>
                                                                                             x.AuditLogReason = "Star reaction is invalid: User has already starred!"));
                    }
                }
            }
            else if (channel != starboardChannel) // Can't make a new starboard message for a post in the starboard channel!
            {
                using (await _starboardReadWriteLock.LockAsync(messageId))
                {
                    if (message.Reactions.FirstOrDefault(e => e.Key.Name == _starEmoji.Name).Value.ReactionCount >= starboard.StarsRequiredToPost)
                    {
                        // Create new star message!
                        entry = new StarboardEntry
                        {
                            GuildId            = guildId,
                            StarredMessageId   = messageId,
                            StarboardMessageId = 0, // is set in UpdateOrPostToStarboardAsync
                            Stargazers         =
                            {
                                [starrerId] = StarTarget.OriginalMessage
                            }
                        };

                        await UpdateOrPostToStarboardAsync(starboard, message, entry);
                    }

                    _db.UpdateStargazers(entry);
                }
            }
        }
예제 #4
0
        /// <summary>
        ///     Updates, posts, or deletes a message in the starboard in a guild.
        ///     Calls to this method should be synchronized to _messageWriteLock beforehand!
        /// </summary>
        /// <param name="starboard">The guild's starboard configuration</param>
        /// <param name="message">The message to star (must be from a <see cref="IGuildChannel"/>)</param>
        /// <param name="entry"></param>
        /// <returns></returns>
        private async Task UpdateOrPostToStarboardAsync(StarboardOptions starboard, IMessage message, StarboardEntry entry)
        {
            var starboardChannel = _client.GetChannel(starboard.StarboardChannel);

            if (!(starboardChannel is SocketTextChannel starboardTextChannel))
            {
                return;
            }

            if (entry.StarboardMessageId == 0)
            {
                if (entry.StarCount >= starboard.StarsRequiredToPost)
                {
                    // New message just reached star threshold, send it
                    var newMessage = await PostToStarboardAsync(message, entry.StarCount);

                    entry.StarboardMessageId = newMessage.Id;
                }
            }
            else
            {
                IMessage starboardMessage;
                try
                {
                    starboardMessage = await starboardTextChannel.GetMessageAsync(entry.StarboardMessageId);
                }
                catch (HttpException ex) when(ex.HttpCode == HttpStatusCode.NotFound)
                {
                    Logger.Debug(LogSource.Service, "Could not retrieve original star message in channel.");
                    return;
                }

                if (!(starboardMessage is IUserMessage starboardUserMessage))
                {
                    return;
                }

                if (entry.StarCount >= starboard.StarsRequiredToPost)
                {
                    // Update existing message
                    var targetMessage = $"{_starEmoji} {entry.StarCount}";
                    if (starboardMessage.Content != targetMessage)
                    {
                        await starboardUserMessage.ModifyAsync(e => e.Content = targetMessage);
                    }
                }
                else
                {
                    // Star count below the limit so delete the message if any
                    await starboardMessage.DeleteAsync();

                    entry.StarboardMessageId = 0;
                }
            }
        }
예제 #5
0
 public bool TryGetStargazers(ulong guildId, ulong messageId, [NotNullWhen(true)] out StarboardEntry entry)
 {
     entry = GetStargazersInternal(guildId, messageId)?.Value;
     return(entry != null);
 }