/// <inheritdoc/>
        public Task <EventResponseResult> RespondAsync(IGuildMembersChunk gatewayEvent, CancellationToken ct = default)
        {
            foreach (var member in gatewayEvent.Members)
            {
                if (!member.User.HasValue)
                {
                    continue;
                }

                var key = KeyHelpers.CreateGuildMemberKey(gatewayEvent.GuildID, member.User.Value !.ID);
                _cacheService.Cache(key, member);
            }

            if (!gatewayEvent.Presences.HasValue)
            {
                return(Task.FromResult(EventResponseResult.FromSuccess()));
            }

            foreach (var presence in gatewayEvent.Presences.Value !)
            {
                if (!presence.User.ID.HasValue)
                {
                    continue;
                }

                var key = KeyHelpers.CreatePresenceCacheKey(gatewayEvent.GuildID, presence.User.ID.Value);
                _cacheService.Cache(key, presence);
            }

            return(Task.FromResult(EventResponseResult.FromSuccess()));
        }
        /// <inheritdoc/>
        public Task <EventResponseResult> RespondAsync(IChannelUpdate gatewayEvent, CancellationToken ct = default)
        {
            var key = KeyHelpers.CreateChannelCacheKey(gatewayEvent.ID);

            _cacheService.Cache <IChannel>(key, gatewayEvent);

            return(Task.FromResult(EventResponseResult.FromSuccess()));
        }
        /// <inheritdoc/>
        public Task <EventResponseResult> RespondAsync(IGuildMemberRemove gatewayEvent, CancellationToken ct = default)
        {
            var key = KeyHelpers.CreateGuildMemberKey(gatewayEvent.GuildID, gatewayEvent.User.ID);

            _cacheService.Evict(key);

            return(Task.FromResult(EventResponseResult.FromSuccess()));
        }
        /// <inheritdoc/>
        public Task <EventResponseResult> RespondAsync(IGuildBanAdd gatewayEvent, CancellationToken ct = default)
        {
            var key = KeyHelpers.CreateGuildBanCacheKey(gatewayEvent.GuildID, gatewayEvent.User.ID);

            _cacheService.Cache <IBan>(key, new Ban(null, gatewayEvent.User));

            return(Task.FromResult(EventResponseResult.FromSuccess()));
        }
Esempio n. 5
0
        /// <inheritdoc/>
        public async Task <EventResponseResult> RespondAsync(IMessageCreate gatewayEvent, CancellationToken ct = default)
        {
            if (!gatewayEvent.Content.StartsWith('!'))
            {
                return(EventResponseResult.FromSuccess());
            }

            var statusCode = gatewayEvent.Content[1..];
        /// <inheritdoc/>
        public async Task <EventResponseResult> RespondAsync
        (
            IUnknownEvent?gatewayEvent,
            CancellationToken ct = default
        )
        {
            if (gatewayEvent is null)
            {
                return(EventResponseResult.FromSuccess());
            }

            using var jsonDocument = JsonDocument.Parse(gatewayEvent.Data);
            if (!jsonDocument.RootElement.TryGetProperty("t", out var eventTypeElement))
            {
                _log.LogWarning("Failed to find an event type on the given unknown event");
                return(EventResponseResult.FromSuccess());
            }

            if (!jsonDocument.RootElement.TryGetProperty("s", out var eventSequenceElement))
            {
                _log.LogWarning("Failed to find an event sequence on the given unknown event");
                return(EventResponseResult.FromSuccess());
            }

            var eventType = eventTypeElement.GetString();

            if (eventType is null)
            {
                return(EventResponseResult.FromError("The event type was null."));
            }

            var sequenceNumber = eventSequenceElement.GetInt64();
            var logTime        = $"{DateTime.UtcNow:u}";

            _log.LogInformation("Received an event of type \"{EventType}\"", eventType);

            var eventDirectory = Path.GetFullPath(eventType.ToUpperInvariant());

            if (!Directory.Exists(eventDirectory))
            {
                Directory.CreateDirectory(eventDirectory);
            }

            var filename = $"{logTime}.{sequenceNumber}.json";
            var filePath = Path.Combine(eventDirectory, filename);

            await using var file       = File.OpenWrite(filePath);
            await using var jsonWriter = new Utf8JsonWriter(file, new JsonWriterOptions
            {
                Indented = true
            });

            jsonDocument.WriteTo(jsonWriter);

            return(EventResponseResult.FromSuccess());
        }
Esempio n. 7
0
        private async Task <EventResponseResult> ReplyWithFailureAsync(Snowflake channel)
        {
            var failEmbed = new Embed(Description: "Dice rolling failed :(", Colour: Color.OrangeRed);

            var replyFail = await _channelAPI.CreateMessageAsync(channel, embed : failEmbed);

            return(!replyFail.IsSuccess
                ? EventResponseResult.FromError(replyFail)
                : EventResponseResult.FromSuccess());
        }
Esempio n. 8
0
        private async Task <EventResponseResult> ExecuteCommandAsync
        (
            string content,
            ICommandContext commandContext,
            CancellationToken ct = default
        )
        {
            // Strip off the prefix
            if (_options.Prefix is not null)
            {
                content = content.Substring
                          (
                    content.IndexOf(_options.Prefix, StringComparison.Ordinal) + _options.Prefix.Length
                          );
            }

            var additionalParameters = new object[] { commandContext };

            // Run any user-provided pre execution events
            var preExecution = await _eventCollector.RunPreExecutionEvents(commandContext, ct);

            if (!preExecution.IsSuccess)
            {
                return(EventResponseResult.FromError(preExecution));
            }

            // Run the actual command
            var executeResult = await _commandService.TryExecuteAsync
                                (
                content,
                _services,
                additionalParameters,
                ct : ct
                                );

            if (!executeResult.IsSuccess)
            {
                return(EventResponseResult.FromError(executeResult));
            }

            // Run any user-provided post execution events
            var postExecution = await _eventCollector.RunPostExecutionEvents
                                (
                commandContext,
                executeResult.InnerResult !,
                ct
                                );

            if (!postExecution.IsSuccess)
            {
                return(EventResponseResult.FromError(postExecution));
            }

            return(EventResponseResult.FromSuccess());
        }
Esempio n. 9
0
        /// <inheritdoc/>
        public Task <EventResponseResult> RespondAsync(IChannelDelete?gatewayEvent, CancellationToken ct = default)
        {
            if (gatewayEvent is null)
            {
                return(Task.FromResult(EventResponseResult.FromSuccess()));
            }

            var key = KeyHelpers.CreateChannelCacheKey(gatewayEvent.ID);

            _cacheService.Evict(key);

            return(Task.FromResult(EventResponseResult.FromSuccess()));
        }
Esempio n. 10
0
        /// <inheritdoc/>
        public Task <EventResponseResult> RespondAsync(IGuildCreate?gatewayEvent, CancellationToken ct = default)
        {
            if (gatewayEvent is null)
            {
                return(Task.FromResult(EventResponseResult.FromSuccess()));
            }

            var key = KeyHelpers.CreateGuildCacheKey(gatewayEvent.ID);

            _cacheService.Cache <IGuild>(key, gatewayEvent);

            return(Task.FromResult(EventResponseResult.FromSuccess()));
        }
        /// <inheritdoc/>
        public Task <EventResponseResult> RespondAsync(IGuildMemberAdd gatewayEvent, CancellationToken ct = default)
        {
            if (!gatewayEvent.User.HasValue)
            {
                return(Task.FromResult(EventResponseResult.FromSuccess()));
            }

            var key = KeyHelpers.CreateGuildMemberKey(gatewayEvent.GuildID, gatewayEvent.User.Value !.ID);

            _cacheService.Cache <IGuildMember>(key, gatewayEvent);

            return(Task.FromResult(EventResponseResult.FromSuccess()));
        }
Esempio n. 12
0
        /// <inheritdoc/>
        public async Task <EventResponseResult> RespondAsync
        (
            IMessageUpdate?gatewayEvent,
            CancellationToken ct = default
        )
        {
            if (gatewayEvent is null)
            {
                return(EventResponseResult.FromSuccess());
            }

            if (!gatewayEvent.Content.HasValue)
            {
                return(EventResponseResult.FromSuccess());
            }

            if (_options.Prefix is not null)
            {
                if (!gatewayEvent.Content.Value !.StartsWith(_options.Prefix))
                {
                    return(EventResponseResult.FromSuccess());
                }
            }

            if (!gatewayEvent.Author.HasValue)
            {
                return(EventResponseResult.FromSuccess());
            }

            var author = gatewayEvent.Author.Value !;

            if (author.IsBot.HasValue && author.IsBot.Value)
            {
                return(EventResponseResult.FromSuccess());
            }

            if (author.IsSystem.HasValue && author.IsSystem.Value)
            {
                return(EventResponseResult.FromSuccess());
            }

            var context = new MessageContext
                          (
                gatewayEvent.ChannelID.Value,
                author,
                gatewayEvent.ID.Value,
                gatewayEvent
                          );

            return(await ExecuteCommandAsync(gatewayEvent.Content.Value !, context, ct));
        }
        /// <inheritdoc/>
        public Task <EventResponseResult> RespondAsync(IGuildEmojisUpdate gatewayEvent, CancellationToken ct = default)
        {
            foreach (var emoji in gatewayEvent.Emojis)
            {
                if (emoji.ID is null)
                {
                    continue;
                }

                var key = KeyHelpers.CreateEmojiCacheKey(gatewayEvent.GuildID, emoji.ID.Value);
                _cacheService.Cache(key, emoji);
            }

            return(Task.FromResult(EventResponseResult.FromSuccess()));
        }
Esempio n. 14
0
        public async Task <IResult> PostHttpCatAsync([Description("The HTTP code.")] int httpCode)
        {
            var embedImage = new EmbedImage($"https://http.cat/{httpCode}");
            var embed      = new Embed(Image: embedImage);

            var reply = await _channelAPI.CreateMessageAsync
                        (
                _context.ChannelID,
                embed : embed,
                ct : this.CancellationToken
                        );

            return(!reply.IsSuccess
                ? EventResponseResult.FromError(reply)
                : EventResponseResult.FromSuccess());
        }
Esempio n. 15
0
        /// <inheritdoc />
        public async Task <EventResponseResult> RespondAsync(IMessageCreate gatewayEvent, CancellationToken ct = default)
        {
            if ((gatewayEvent.Author.IsBot.HasValue && gatewayEvent.Author.IsBot.Value) ||
                (gatewayEvent.Author.IsSystem.HasValue && gatewayEvent.Author.IsSystem.Value))
            {
                return(EventResponseResult.FromSuccess());
            }

            var replyResult = await _channelAPI.CreateMessageAsync
                              (
                gatewayEvent.ChannelID,
                gatewayEvent.Content,
                ct : ct
                              );

            return(replyResult.IsSuccess
                ? EventResponseResult.FromSuccess()
                : EventResponseResult.FromError(replyResult));
        }
Esempio n. 16
0
        private async Task <EventResponseResult> ReplyWithRollsAsync(Snowflake channel, RollResponse rollResponse)
        {
            var rolls = rollResponse.Dice
                        .GroupBy(d => d.Type)
                        .ToDictionary
                        (
                g => g.Key,
                g => g.Select(d => d.Value).Aggregate((a, b) => a + b)
                        );

            var fields = rolls.Select(kvp => new EmbedField(kvp.Key, kvp.Value.ToString(), true)).ToList();
            var embed  = new Embed("Rolls", Fields: fields, Colour: Color.LawnGreen);

            var replyRolls = await _channelAPI.CreateMessageAsync(channel, embed : embed);

            return(!replyRolls.IsSuccess
                ? EventResponseResult.FromError(replyRolls)
                : EventResponseResult.FromSuccess());
        }
Esempio n. 17
0
        /// <inheritdoc/>
        public Task <EventResponseResult> RespondAsync(IGuildMemberUpdate?gatewayEvent, CancellationToken ct = default)
        {
            if (gatewayEvent is null)
            {
                return(Task.FromResult(EventResponseResult.FromSuccess()));
            }

            var key = KeyHelpers.CreateGuildMemberKey(gatewayEvent.GuildID, gatewayEvent.User.ID);

            // Since this event isn't playing nice, we'll have to update by creating an object of our own.
            if (!_cacheService.TryGetValue <IGuildMember>(key, out var cachedInstance))
            {
                cachedInstance = new GuildMember
                                 (
                    new Optional <IUser>(gatewayEvent.User),
                    gatewayEvent.Nickname,
                    gatewayEvent.Roles,
                    gatewayEvent.JoinedAt,
                    gatewayEvent.PremiumSince,
                    false,
                    false,
Esempio n. 18
0
        public async Task <IResult> RollDiceAsync(string value)
        {
            var rollRequests = value.Split(' ', StringSplitOptions.RemoveEmptyEntries);

            if (rollRequests.Length == 0)
            {
                return(EventResponseResult.FromSuccess());
            }

            var getRolls = await GetRollsAsync(rollRequests);

            if (!getRolls.IsSuccess)
            {
                var replyWithFailure = await ReplyWithFailureAsync(_context.ChannelID);

                return(replyWithFailure.IsSuccess
                    ? EventResponseResult.FromError(getRolls)
                    : replyWithFailure);
            }

            var rollResponse = getRolls.Entity;

            return(await ReplyWithRollsAsync(_context.ChannelID, rollResponse));
        }
Esempio n. 19
0
 /// <inheritdoc />
 public Task <EventResponseResult> RespondAsync(IMessageCreate?gatewayEvent, CancellationToken ct = default)
 {
     return(Task.FromResult(EventResponseResult.FromSuccess()));
 }
Esempio n. 20
0
        /// <inheritdoc/>
        public async Task <EventResponseResult> RespondAsync
        (
            IMessageCreate?gatewayEvent,
            CancellationToken ct = default
        )
        {
            if (gatewayEvent is null)
            {
                return(EventResponseResult.FromSuccess());
            }

            if (_options.Prefix is not null)
            {
                if (!gatewayEvent.Content.StartsWith(_options.Prefix))
                {
                    return(EventResponseResult.FromSuccess());
                }
            }

            var author = gatewayEvent.Author;

            if (author.IsBot.HasValue && author.IsBot.Value)
            {
                return(EventResponseResult.FromSuccess());
            }

            if (author.IsSystem.HasValue && author.IsSystem.Value)
            {
                return(EventResponseResult.FromSuccess());
            }

            var context = new MessageContext
                          (
                gatewayEvent.ChannelID,
                author,
                gatewayEvent.ID,
                new PartialMessage
                (
                    gatewayEvent.ID,
                    gatewayEvent.ChannelID,
                    gatewayEvent.GuildID,
                    new Optional <IUser>(gatewayEvent.Author),
                    gatewayEvent.Member,
                    gatewayEvent.Content,
                    gatewayEvent.Timestamp,
                    gatewayEvent.EditedTimestamp,
                    gatewayEvent.IsTTS,
                    gatewayEvent.MentionsEveryone,
                    new Optional <IReadOnlyList <IUserMention> >(gatewayEvent.Mentions),
                    new Optional <IReadOnlyList <Snowflake> >(gatewayEvent.MentionedRoles),
                    gatewayEvent.MentionedChannels,
                    new Optional <IReadOnlyList <IAttachment> >(gatewayEvent.Attachments),
                    new Optional <IReadOnlyList <IEmbed> >(gatewayEvent.Embeds),
                    gatewayEvent.Reactions,
                    gatewayEvent.Nonce,
                    gatewayEvent.IsPinned,
                    gatewayEvent.WebhookID,
                    gatewayEvent.Type,
                    gatewayEvent.Activity,
                    gatewayEvent.Application,
                    gatewayEvent.MessageReference,
                    gatewayEvent.Flags
                )
                          );

            return(await ExecuteCommandAsync(gatewayEvent.Content, context, ct));
        }
Esempio n. 21
0
        /// <inheritdoc />
        public async Task <EventResponseResult> RespondAsync
        (
            IInteractionCreate?gatewayEvent,
            CancellationToken ct = default
        )
        {
            if (gatewayEvent is null)
            {
                return(EventResponseResult.FromSuccess());
            }

            if (!gatewayEvent.Data.HasValue)
            {
                return(EventResponseResult.FromSuccess());
            }

            if (!gatewayEvent.Member.User.HasValue)
            {
                return(EventResponseResult.FromSuccess());
            }

            // Signal Discord that we'll be handling this one asynchronously
            var response            = new InteractionResponse(InteractionResponseType.Acknowledge, default);
            var interactionResponse = await _interactionAPI.CreateInteractionResponseAsync
                                      (
                gatewayEvent.ID,
                gatewayEvent.Token,
                response,
                ct
                                      );

            if (!interactionResponse.IsSuccess)
            {
                return(EventResponseResult.FromError(interactionResponse));
            }

            var interactionData = gatewayEvent.Data.Value !;

            interactionData.UnpackInteraction(out var command, out var parameters);

            var context = new InteractionContext
                          (
                gatewayEvent.ChannelID,
                gatewayEvent.Member.User.Value !,
                gatewayEvent.Member,
                gatewayEvent.Token,
                gatewayEvent.ID,
                gatewayEvent.GuildID
                          );

            // Run any user-provided pre execution events
            var preExecution = await _eventCollector.RunPreExecutionEvents(context, ct);

            if (!preExecution.IsSuccess)
            {
                return(EventResponseResult.FromError(preExecution));
            }

            // Run the actual command
            var searchOptions = new TreeSearchOptions(StringComparison.OrdinalIgnoreCase);
            var executeResult = await _commandService.TryExecuteAsync
                                (
                command,
                parameters,
                _services,
                new object[] { context },
                searchOptions,
                ct
                                );

            if (!executeResult.IsSuccess)
            {
                return(EventResponseResult.FromError(executeResult));
            }

            // Run any user-provided post execution events
            var postExecution = await _eventCollector.RunPostExecutionEvents
                                (
                context,
                executeResult.InnerResult !,
                ct
                                );

            if (!postExecution.IsSuccess)
            {
                return(EventResponseResult.FromError(postExecution));
            }

            return(EventResponseResult.FromSuccess());
        }