Esempio n. 1
0
        private async Task HandleBadRequest(DiscordMessage message, DiscordUser author, DiscordChannel channel, IEnumerable <string> commandSegments, string commandAlias, BaseDiscordCommand command, DateTimeOffset start)
        {
            LogMessage?.Invoke(this, $"[{message.Channel.Guild?.Name ?? message.Channel.Name}] {command.Name} does not take {commandSegments.Count()} arguments.");
            _telemetryClient?.TrackRequest(InternalTools.GetRequestTelemetry(author, channel, command, start, "400", false));

            if (command.Usage != null)
            {
                await InternalTools.SendTemporaryMessage(message, author, channel, $"```\r\n{commandAlias} usage: {_config.Prefix}{commandAlias} [{command.Usage}]\r\n```");
            }
        }
Esempio n. 2
0
        private async Task ExecuteCommandAsync(DiscordMessage message, DiscordUser author, DiscordChannel channel, IEnumerable <string> commandSegments, string commandAlias, BaseDiscordCommand command, DateTimeOffset start)
        {
            try
            {
                LogMessage?.Invoke(this, ($"[{message.Channel.Guild?.Name ?? message.Channel.Name}] Found {command.Name} command!"));
                _processedMessageIds.Add(message.Id);
                if (command.ArgumentCountPrecidate(commandSegments.Count()))
                {
                    if (InternalTools.CheckPermissions(_discordClient, channel.Guild?.CurrentMember ?? _discordClient.CurrentUser, channel, command))
                    {
                        if (InternalTools.CheckPermissions(_discordClient, author, channel, command))
                        {
                            LogMessage?.Invoke(this, ($"[{message.Channel.Guild?.Name ?? message.Channel.Name}] Running command \"{command.Name}\" asynchronously."));
                            new Task(async() => await RunCommandAsync(message, author, channel, commandSegments, commandAlias, command, start)).Start();
                        }
                        else
                        {
                            LogMessage?.Invoke(this, ($"[{message.Channel.Guild?.Name ?? message.Channel.Name}] Attempt to run command without correct user permissions."));
                            await InternalTools.SendTemporaryMessage(message, author, channel, $"Oi! You're not allowed to run that command! F**k off!");

                            _telemetryClient?.TrackRequest(InternalTools.GetRequestTelemetry(author, channel, command, start, "401", false));
                        }
                    }
                    else
                    {
                        LogMessage?.Invoke(this, ($"[{message.Channel.Guild?.Name ?? message.Channel.Name}] Attempt to run command without correct bot permissions."));
                        await InternalTools.SendTemporaryMessage(message, author, channel, $"Sorry! I don't have permission to run that command in this server! Contact an admin/mod for more info.");

                        _telemetryClient?.TrackRequest(InternalTools.GetRequestTelemetry(author, channel, command, start, "403", false));
                    }
                }
                else
                {
                    await HandleBadRequest(message, author, channel, commandSegments, commandAlias, command, start);
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex);
            }
        }
Esempio n. 3
0
        private async Task RunCommandAsync(DiscordMessage message, DiscordUser author, DiscordChannel channel, IEnumerable <string> commandSegments, string commandAlias, BaseDiscordCommand command, DateTimeOffset start)
        {
            bool success = true;

            try
            {
                await channel.TriggerTypingAsync();

                command = InstantateDiscordCommand(command.GetType());
                _config.Happiness.TryGetValue(author.Id, out sbyte h);

                CommandContext context = new CommandContext(commandSegments.ToArray(), message, _discordClient)
                {
                    Happiness = h,
                    _logger   = _loggerFactory.CreateLogger("Commands")
                };


                context.AdditionalData["botContext"] = this;
                string[]      cmdsegarr = commandSegments.ToArray();
                CommandResult result    = await command.RunCommand(cmdsegarr, context);

                LogMessage?.Invoke(this, ($"[{message.Channel.Guild?.Name ?? message.Channel.Name}] \"{command.Name}\" returned ReturnType.{result.ReturnType}."));
                if (result.ReturnType != ReturnType.None)
                {
                    if (result.ReturnType == ReturnType.Text && result.ResultText.Length > 2000)
                    {
                        for (int i = 0; i < result.ResultText.Length; i += 1993)
                        {
                            string str = result.ResultText.Substring(i, Math.Min(1993, result.ResultText.Length - i));
                            if (result.ResultText.StartsWith("```") && !str.StartsWith("```"))
                            {
                                str = "```" + str;
                            }
                            if (result.ResultText.EndsWith("```") && !str.EndsWith("```"))
                            {
                                str = str + "```";
                            }

                            LogMessage?.Invoke(this, ($"Chunking message to {str.Length} chars"));
                            await channel.SendMessageAsync(str);

                            await Task.Delay(2000);
                        }
                    }
                    else
                    {
                        if (!string.IsNullOrWhiteSpace(result.Attachment))
                        {
                            await channel.SendFileAsync(result.Attachment, result.ResultText, embed : result.ResultEmbed);
                        }
                        else if (result.Stream != null || result.ReturnType == ReturnType.File)
                        {
                            if (result.Stream.Length <= 8 * 1024 * 1024)
                            {
                                await channel.SendFileAsync(result.Stream, result.FileName, result.ResultText, false, result.ResultEmbed);
                            }
                            else
                            {
                                await channel.SendMessageAsync("This command has resulted in an attachment that is over 8MB in size and cannot be sent.");
                            }
                        }
                        else
                        {
                            await channel.SendMessageAsync(result.ResultText, embed : result.ResultEmbed);
                        }
                    }
                }


                RequestTelemetry request = InternalTools.GetRequestTelemetry(author, channel, command, start, success ? "200" : "500", success);
                foreach (var pair in result.InsightsData)
                {
                    request.Properties.Add(pair);
                }

                _telemetryClient?.TrackRequest(request);

                _config.Happiness[author.Id] = (sbyte)((int)(context.Happiness).Clamp(sbyte.MinValue, sbyte.MaxValue));
            }
            catch (BadArgumentsException ex)
            {
                Console.WriteLine(ex);
                await HandleBadRequest(message, author, channel, commandSegments, commandAlias, command, start);
            }
            catch (CommandException ex)
            {
                Console.WriteLine(ex);
                await channel.SendMessageAsync(ex.Message);

                _telemetryClient?.TrackRequest(InternalTools.GetRequestTelemetry(author, channel, command, start, "400", false));
            }
            catch (ArgumentOutOfRangeException ex)
            {
                Console.WriteLine(ex);
                await channel.SendMessageAsync("Hey there! That's gonna cause some issues, no thanks!!");

                _telemetryClient?.TrackRequest(InternalTools.GetRequestTelemetry(author, channel, command, start, "400", false));
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex);
                success = false;
                ManageException(message, author, channel, ex, command);

                sbyte h = 0;
                _config.Happiness?.TryGetValue(author.Id, out h);

                _config.Happiness[author.Id] = (sbyte)((int)h - 1).Clamp(sbyte.MinValue, sbyte.MaxValue);
            }
            finally
            {
                if (command is IDisposable disp)
                {
                    disp.Dispose();
                }
            }
        }
Esempio n. 4
0
        private async Task ProcessMessage(DiscordMessage message, DiscordUser author, DiscordChannel channel)
        {
            try
            {
                DateTimeOffset startTime = DateTimeOffset.Now;
                if (!string.IsNullOrWhiteSpace(message?.Content) && !author.IsBot && !author.IsCurrent && !_processedMessageIds.Contains(message.Id))
                {
                    if (message.Content.ToLower().StartsWith(_config.Prefix.ToLower()))
                    {
                        LogMessage?.Invoke(this, ($"[{message.Channel.Guild?.Name ?? message.Channel.Name}] Found command prefix, parsing..."));
                        IEnumerable <string> commandSegments = Strings.SplitCommandLine(message.Content.Substring(_config.Prefix.Length));

                        foreach (IParseExtension extenstion in _parseExtensions)
                        {
                            commandSegments = extenstion.Parse(commandSegments, channel);
                        }

                        if (commandSegments.Any())
                        {
                            string commandAlias = commandSegments.First().ToLower();
                            IEnumerable <BaseDiscordCommand> foundCommands = _commands.Where(c => c?.Aliases?.Any(a => a.ToLower() == commandAlias) == true);
                            BaseDiscordCommand commandToRun = foundCommands.FirstOrDefault();
                            if (commandToRun != null)
                            {
                                if (foundCommands.Count() == 1)
                                {
                                    await ExecuteCommandAsync(message, author, channel, commandSegments.Skip(1), commandAlias, commandToRun, startTime);
                                }
                                else if (commandSegments.Count() >= 2)
                                {
                                    foundCommands = _assemblyCommands.FirstOrDefault(c => c.Key.Name.ToLowerInvariant() == commandAlias)
                                                    .Value?.Where(c => c.Aliases.Contains(commandSegments.ElementAt(1).ToLower()));

                                    if (foundCommands != null && foundCommands.Count() == 1)
                                    {
                                        await ExecuteCommandAsync(message, author, channel, commandSegments.Skip(2), commandAlias, foundCommands.First(), startTime);
                                    }
                                    else
                                    {
                                        if (commandToRun != null)
                                        {
                                            await ExecuteCommandAsync(message, author, channel, commandSegments.Skip(1), commandAlias, foundCommands.First(), startTime);
                                        }
                                        else
                                        {
                                            LogMessage?.Invoke(this, ($"[{message.Channel.Guild?.Name ?? message.Channel.Name}] Unable to find command with alias \"{commandAlias}\"."));
                                            await InternalTools.SendTemporaryMessage(message, author, channel, $"```\r\n{commandAlias}: command not found!\r\n```");

                                            _telemetryClient?.TrackRequest(InternalTools.GetRequestTelemetry(author, channel, null, startTime, "404", false));
                                        }
                                    }
                                }
                                else if (commandToRun != null)
                                {
                                    await ExecuteCommandAsync(message, author, channel, commandSegments.Skip(1), commandAlias, foundCommands.First(), startTime);
                                }
                            }
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex);
            }
        }