/// <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. 2
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. 3
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. 4
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. 5
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. 6
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. 7
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. 8
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());
        }