示例#1
0
        private static async Task ReactionAdded(Cacheable <IUserMessage, ulong> message, ISocketMessageChannel messageChannel, SocketReaction reaction)
        {
            // Skip if the reaction is from ourselves
            if (reaction.UserId == DiscordClient.CurrentUser.Id)
            {
                return;
            }

            // Acquire the semaphore
            await InteractiveMessageSemaphore.WaitAsync();

            // Check if this will match an interactive message
            // TODO a better way?
            IEnumerable <InteractiveMessage> messages = ActiveInteractiveMessages.Where(x => x.MessageId == message.Id).ToList();

            // Release the semaphore
            InteractiveMessageSemaphore.Release();

            // TODO a better way?
            foreach (InteractiveMessage interactiveMessage in messages)
            {
                try
                {
                    await interactiveMessage.ReactionAdded(reaction);
                }
                catch (Exception e)
                {
                    await DiscordUtil.SendErrorMessageByException(null, messageChannel, reaction.User.Value, $"in {interactiveMessage.GetType().Name}.ReactionAdded()", e);
                }
            }
        }
示例#2
0
        public static async Task SendInteractiveMessageAsync(ISocketMessageChannel channel, InteractiveMessage message)
        {
            // Acquire the semaphore
            await InteractiveMessageSemaphore.WaitAsync();

            // Send the initial message
            await message.SendInitialMessage(channel);

            // Add this to the active messages
            ActiveInteractiveMessages.Add(message);

            // Release the semaphore
            InteractiveMessageSemaphore.Release();
        }
示例#3
0
        public static async Task DeactivateInteractiveMessage(InteractiveMessage message, bool isBecauseInactive = false)
        {
            // Acquire the semaphore
            await InteractiveMessageSemaphore.WaitAsync();

            // Check if this message is inactive
            if (!message.IsActive)
            {
                goto done;
            }

            // Set as inactive
            message.IsActive = false;

            // Add this to the active messages
            bool isSuccess = ActiveInteractiveMessages.Remove(message);

            // Clear all reactions if needed
            if (isSuccess)
            {
                await message.ClearReactions();
            }

            // Get a Language if possible
            IGuildChannel guildChannel = message.Channel as IGuildChannel;
            Language      language     = guildChannel != null?DiscordUtil.GetDefaultLanguage(guildChannel.Guild, guildChannel) : Language.EnglishUS;

            // Modify the message to say that it has timed out if needed
            if (isBecauseInactive)
            {
                await message.TargetMessage.ModifyAsync(p =>
                {
                    p.Content = null;
                    p.Embed   = new EmbedBuilder()
                                .WithTitle(Localizer.Localize("discord.interactive_timeout.title", language))
                                .WithDescription(Localizer.Localize("discord.interactive_timeout.description", language))
                                .Build();
                });
            }

done:
            // Release the semaphore
            InteractiveMessageSemaphore.Release();
        }
示例#4
0
        public static async Task DeactivateInactiveInteractiveThings()
        {
            // Get the maximum timeout
            int timeout = Configuration.LoadedConfiguration.DiscordConfig.InteractiveMessageTimeout;

            // Get the comparison time
            DateTime now = DateTime.Now;

            // Acquire the flow semaphore
            await InteractiveFlowSemaphore.WaitAsync();

            // Get all inactive flows
            List <InteractiveFlow> inactiveFlows = ActiveInteractiveFlows.Where(f => f.CurrentInteractiveMessage.LastValidActivity.AddMinutes(timeout) < now).ToList();

            // Release the semaphore
            InteractiveFlowSemaphore.Release();

            // Deactivate all
            foreach (InteractiveFlow flow in inactiveFlows)
            {
                await DeactivateInteractiveFlow(flow, true);
            }

            // Acquire the message semaphore
            await InteractiveMessageSemaphore.WaitAsync();

            // Get all inactive messages
            List <InteractiveMessage> inactiveMessages = ActiveInteractiveMessages.Where(m => m.LastValidActivity.AddMinutes(timeout) < now).ToList();

            // Release the semaphore
            InteractiveMessageSemaphore.Release();

            // Deactivate all
            foreach (InteractiveMessage message in inactiveMessages)
            {
                await DeactivateInteractiveMessage(message, true);
            }
        }
示例#5
0
        private static async Task MessageReceived(SocketMessage socketMessage)
        {
            // Skip if this is not a real user
            if (socketMessage.Source == MessageSource.Webhook || socketMessage.Source == MessageSource.System)
            {
                return;
            }

            // Skip bots that aren't QA
            if (socketMessage.Source == MessageSource.Bot && socketMessage.Author.Id != 563718045806362642)
            {
                return;
            }

            // Get the SocketUserMessage
            SocketUserMessage userMessage = socketMessage as SocketUserMessage;

            // Create the CommandContext
            SocketCommandContext commandContext = new SocketCommandContext(DiscordClient, userMessage);

            // Ignore empty messages and bots
            if (commandContext.Message == null || commandContext.Message.Content.Length == 0)
            {
                return;
            }

            // Check if this message has a command
            int commandPosition = 0;

            if (userMessage.HasStringPrefix(Configuration.LoadedConfiguration.DiscordConfig.CommandPrefix, ref commandPosition))
            {
                // Trigger typing
                //await commandContext.Channel.TriggerTypingAsync();

                // Execute the command
                IResult result = await CommandService.ExecuteAsync(commandContext, commandPosition, null);

                if (!result.IsSuccess)
                {
                    switch (result.Error)
                    {
                    case CommandError.UnknownCommand:
                        //await DiscordUtil.SendErrorMessageByLocalizedDescription(commandContext.Guild, commandContext.Channel, "discord.error.unknown_command");
                        //
                        //break;

                        return;     // ignore

                    case CommandError.BadArgCount:
                        await DiscordUtil.SendErrorMessageByLocalizedDescription(commandContext.Guild, commandContext.Channel, "discord.error.bad_arguments");

                        break;

                    case CommandError.UnmetPrecondition:
                        // Get the PreconditionResult
                        PreconditionResult preconditionResult = (PreconditionResult)result;

                        // Check if the error reason contains a localizable
                        string description = result.ErrorReason;
                        if (result.ErrorReason.StartsWith("~loc"))
                        {
                            // Localize the error reason
                            await DiscordUtil.SendErrorMessageByLocalizedDescription(commandContext.Guild, commandContext.Channel, description.Split(',')[1]);
                        }
                        else
                        {
                            // Localize the error reason
                            await DiscordUtil.SendErrorMessageByDescription(commandContext.Guild, commandContext.Channel, result.ErrorReason);
                        }

                        break;

                    case CommandError.Exception:
                        // Get the IResult as an ExecuteResult
                        ExecuteResult executeResult = (ExecuteResult)result;

                        // Send the error message
                        await DiscordUtil.SendErrorMessageByException(commandContext.Guild, commandContext.Channel, commandContext.User, $"with command``{userMessage.Content}``", executeResult.Exception);

                        break;

                    default:
                        // Get the type
                        string type = (result.Error != null) ? result.Error.Value.GetType().Name : "Unknown";

                        // Send the error message
                        await DiscordUtil.SendErrorMessageByTypeAndMessage(commandContext.Guild, commandContext.Channel, type, result.ErrorReason);

                        break;
                    }
                }
                else
                {
                    // Declare a variable to hold the length
                    int length;

                    // Get the index of the first space
                    int spaceIdx = userMessage.Content.IndexOf(' ');

                    // Check if there is no space
                    if (spaceIdx == -1)
                    {
                        // Default to the command string length
                        length = userMessage.Content.Length - commandPosition;
                    }
                    else
                    {
                        // Get the length of the string in between the space and the command
                        length = spaceIdx - commandPosition;
                    }

                    // Get the command
                    string command = userMessage.Content.Substring(commandPosition, length);

                    // Check if this is not command stats
                    if (command != "commandstats")
                    {
                        // Increment this command in the statistics
                        Configuration.LoadedConfiguration.DiscordConfig.CommandStatistics.AddOrUpdate(command, 1, (cmd, val) => val + 1);
                    }
                }
            }
            else
            {
                // Acquire the semaphore
                await InteractiveMessageSemaphore.WaitAsync();

                // Check if this will match an interactive message
                // TODO a better way?
                IEnumerable <InteractiveMessage> messages = ActiveInteractiveMessages.Where(x => x.Channel.Id == socketMessage.Channel.Id &&
                                                                                            x.User.Id == socketMessage.Author.Id).ToList();

                // Release the semaphore
                InteractiveMessageSemaphore.Release();

                foreach (InteractiveMessage interactiveMessage in messages)
                {
                    try
                    {
                        await interactiveMessage.TextMessageReceived(socketMessage);
                    }
                    catch (Exception e)
                    {
                        await DiscordUtil.SendErrorMessageByException(commandContext.Guild, commandContext.Channel, commandContext.User, $"in {interactiveMessage.GetType().Name}.TextMessageReceived()", e);
                    }
                }
            }
        }