예제 #1
0
 public static async Task <DiscordEmbedBuilder> DisplayCards(DiscordChannel channel, Player player)
 {
     return(new DiscordEmbedBuilder
     {
         ThumbnailUrl = (await channel.SendFileAsync("top.png")).Attachments[0].Url,
         ImageUrl = (await channel.SendFileAsync($"{player.user.DisplayName}_hand.png")).Attachments[0].Url,
         Title = "Your hand and the last card played."
     });
 }
예제 #2
0
        public async Task Create(CommandContext e, [Description("Give the ID of the channel you wish to create from the !instance channels command.")] int channelID)
        {
            InstanceObject.ChannelTemplate template = RPClass.ChannelTemplates.FirstOrDefault(x => x.Id == channelID);
            if (template != null)
            {
                DiscordChannel c = await e.Guild.CreateChannelAsync(template.Name, ChannelType.Text, parent : RPClass.InstanceCategory);

                if (template.Content.Count > 0)
                {
                    foreach (string content in template.Content)
                    {
                        if (content.StartsWith("File:"))
                        {
                            await c.SendFileAsync(content.Split(':')[1]);
                        }
                        else
                        {
                            await c.SendMessageAsync(content);
                        }
                    }
                }
                await e.RespondAsync($"Channel: {template.Name} created - {c.Mention}");
            }
            else
            {
                await e.RespondAsync("Enter a valid channel ID.");
            }
        }
예제 #3
0
        public static async Task BulkDeleteEventHandlerAsync(TheGodfatherBot bot, MessageBulkDeleteEventArgs e)
        {
            if (e.Guild is null)
            {
                return;
            }

            if (!LoggingService.IsLogEnabledForGuild(bot, e.Guild.Id, out LoggingService logService, out LocalizedEmbedBuilder emb))
            {
                return;
            }

            if (LoggingService.IsChannelExempted(bot, e.Guild, e.Channel, out GuildConfigService gcs))
            {
                return;
            }

            emb.WithLocalizedTitle(DiscordEventType.MessagesBulkDeleted, "evt-msg-del-bulk", e.Channel);
            emb.AddLocalizedTitleField("str-count", e.Messages.Count, inline: true);
            using var ms = new MemoryStream();
            using var sw = new StreamWriter(ms);
            foreach (DiscordMessage msg in e.Messages)
            {
                sw.WriteLine($"[{msg.Timestamp}] {msg.Author}");
                sw.WriteLine(string.IsNullOrWhiteSpace(msg.Content) ? "?" : msg.Content);
                sw.WriteLine(msg.Attachments.Select(a => $"{a.FileName} ({a.FileSize})").JoinWith(", "));
                sw.Flush();
            }
            ms.Seek(0, SeekOrigin.Begin);
            DiscordChannel?chn = gcs.GetLogChannelForGuild(e.Guild);

            await(chn?.SendFileAsync($"{e.Channel.Name}-deleted-messages.txt", ms, embed: emb.Build()) ?? Task.CompletedTask);
        }
예제 #4
0
 public static Task SendMessageAsync(this DiscordChannel channel, string message, byte[]?attachment, string?filename)
 {
     if (!string.IsNullOrEmpty(filename) && attachment?.Length > 0)
     {
         return(channel.SendFileAsync(filename, new MemoryStream(attachment), message));
     }
     return(channel.SendMessageAsync(message));
 }
        public static async Task SendDisposableFileAsync(this DiscordChannel channel, string file_data, int deleteInMs = 10000)
        {
            var sentMessage = await channel.SendFileAsync(file_data);

            Task.Delay(deleteInMs).ContinueWith(async(arg) =>
            {
                await sentMessage.DeleteAsync();
            });
        }
예제 #6
0
        public static async Task SendSummary(Stats.Statistics stats, bool includeTimePlot)
        {
            try {
                Logger.Debug("Sending stats.");

                var time = DateTime.Now.TimeOfDay;

                var embed = new DiscordEmbedBuilder();
                embed.WithAuthor($"Summary for {DateTime.Now.Date.ToShortDateString()}");
                embed.AddField("Number of pulls", $"{stats.PullCount}");
                embed.AddField("Median pull", $"{stats.MedianPull}s");
                embed.AddField("Longest pull", $"{stats.LongestPull}s");
                embed.AddField("Time % spent on pulls", $"{Math.Round(stats.PercentageSpentOnPulls, 2)}%");
                embed.AddField("Time spent on pulls", $"{new TimeSpan(0, 0, stats.TimeSpentPulling):h\\:mm\\:ss}");
                embed.AddField($"Time spent on pulls past {_preset.settings.GreenThreshold}s", $"{new TimeSpan(0, 0, stats.TimeSpentPullingPastThreshold):h\\:mm\\:ss}");
                embed.WithColor(DiscordColor.White);
                embed.WithTimestamp(DateTime.Today + time);

                embed.Build();

                await Bot.SendMessageAsync(SummaryChannel, null, false, embed);

                await SummaryChannel.SendFileAsync("plot.png");

                if (includeTimePlot)
                {
                    await SummaryChannel.SendFileAsync("timePlot.png");
                }

                File.Delete("plot.png");
                if (includeTimePlot)
                {
                    File.Delete("timePlot.png");
                }

                Logger.Debug("Stats sent.");
            } catch (Exception e) {
                Logger.Error("Error while sending summary to Discord. Please make sure the summary channel ID is correct.", e);
            }
        }
예제 #7
0
        /// <summary>
        /// 디스코드 채널입니다. 그룹 채널일 수도, DM 채널일 수도 있습니다.
        /// </summary>
        /// <param name="channel">그룹 채널일 수도, DM 채널일 수도 있습니다.</param>
        /// <param name="messageQueue">메시지 큐에 태스크를 넣으면 메시지를 전송할 수 있습니다.</param>
        /// <param name="dispatcher">WPF 컨트롤을 다루기 위해 메인 스레드의 디스패쳐가 필요합니다.</param>
        internal protected DisboardChannel(DiscordChannel channel, ConcurrentQueue <Func <Task> > messageQueue, Dispatcher dispatcher)
        {
            Id = channel.Id;

            Send = (message, embed, emoji) => messageQueue.Enqueue(async() =>
            {
                var writtenMessage = await channel.SendMessageAsync(message, embed: embed);
                if (emoji != null)
                {
                    foreach (DiscordEmoji emoji in emoji)
                    {
                        await writtenMessage.CreateReactionAsync(emoji);
                    }
                }
            });
            SendImage = (stream, message, embed, emoji) => messageQueue.Enqueue(async() =>
            {
                var writtenMessage = await channel.SendFileAsync(stream, file_name: "image.png", content: message, embed: embed);
                if (emoji != null)
                {
                    foreach (DiscordEmoji emoji in emoji)
                    {
                        await writtenMessage.CreateReactionAsync(emoji);
                    }
                }
            });
            SendImages = (streams, message, embed, emoji) => messageQueue.Enqueue(async() =>
            {
                var writtenMessage = await channel.SendMultipleFilesAsync(streams.Enumerate().ToDictionary(_ => $"{_.index}.png", _ => _.elem), content: message, embed: embed);
                if (emoji != null)
                {
                    foreach (DiscordEmoji emoji in emoji)
                    {
                        await writtenMessage.CreateReactionAsync(emoji);
                    }
                }
            });

            string guildId = channel.GuildId == default ? "@me" : $"{channel.GuildId}";

            URL = $"https://discord.com/channels/{guildId}/{channel.Id}";

            Render = controlConstructor => dispatcher.Invoke(() => controlConstructor().Render());
        }
예제 #8
0
        public static void sendScreenshot()
        {
            Bitmap       screenShot = Screen.caputreScreen();
            MemoryStream stream     = new MemoryStream();

            screenShot.Save(stream, System.Drawing.Imaging.ImageFormat.Png);
            stream.Position = 0;
            string message = lines.ElementAt(rand.Next(3, lines.Count - 1));

            message = message.Replace("@User", user.Mention);
            if (Screen.isActiveWindowFullscreen())
            {
                message = message.Replace("@Game", "Game: " + Screen.getActiveWindowTitle());
            }
            else
            {
                message = message.Replace("@Game", "");
            }
            channel.SendFileAsync(stream, "screenshot.png", message);
        }
        public async Task <EventHandlerResult> HandleAddedRole(
            GuildMemberUpdateEventArgs eventArgs,
            ulong roleId,
            ulong channelId,
            string filePath,
            string message,
            ILogger?logger = null
            )
        {
            try
            {
                DiscordRole hornyJailRole = eventArgs.Guild.GetRole(roleId);
                if (eventArgs.RolesBefore.Contains(hornyJailRole) || !eventArgs.RolesAfter.Contains(hornyJailRole))
                {
                    return(EventHandlerResult.Continue);
                }
            }
            catch (Exception e)
            {
                logger?.LogWarning(e, "Couldn't get the role");
            }

            try
            {
                DiscordChannel channel = eventArgs.Guild.GetChannel(channelId);
                await channel.SendFileAsync(
                    filePath,
                    message
                    );
            }
            catch (Exception e)
            {
                logger?.LogError(e, "Failed to send welcome message to the channel");
            }

            return(EventHandlerResult.Continue);
        }
예제 #10
0
        private async Task Show()
        {
            var imagePath = Path.Combine(_tempPath, "main.png");
            var image     = new Bitmap(_size, _size);

            lock (_drawLock)
            {
                using (Graphics g = Graphics.FromImage(image))
                {
                    var back = new Bitmap(OldMaidImage.Instance._back);

                    var enemyY       = 0;
                    var player1Cards = Players[0].GetCardCount();
                    // if players cards total width is less than size, draw from center
                    if (player1Cards * _cardWidth < _size)
                    {
                        var startingOffset = (_size - player1Cards * _cardWidth) / 2;
                        for (var i = 0; i < player1Cards; ++i)
                        {
                            g.DrawImage(back, new Point(startingOffset + i * _cardWidth, enemyY));
                        }
                    }
                    else
                    {
                        var enemyXOffset = (_size - _cardWidth) / (player1Cards - 1);
                        for (var i = 0; i < player1Cards; ++i)
                        {
                            g.DrawImage(back, new Point(enemyXOffset * i, enemyY));
                        }
                    }

                    var myY          = _size - _cardHeight;
                    var player2Cards = Players[1].GetCardCount();
                    if (player2Cards * _cardWidth < _size)
                    {
                        var startingOffset = (_size - player2Cards * _cardWidth) / 2;
                        for (var i = 0; i < player2Cards; ++i)
                        {
                            g.DrawImage(back, new Point(startingOffset + i * _cardWidth, myY));
                        }
                    }
                    else
                    {
                        var myXOffset = (_size - _cardWidth) / (player2Cards - 1);
                        for (var i = 0; i < player2Cards; ++i)
                        {
                            g.DrawImage(back, new Point(myXOffset * i, myY));
                        }
                    }
                    g.DrawString($"{Players[0].Player.DisplayName}", _font, _solidBrush, new PointF(_size / 2, _cardHeight + _textOffset), _centerBold);
                    g.DrawString($"{Players[1].Player.DisplayName}", _font, _solidBrush, new PointF(_size / 2, _size - _cardHeight - _textOffset), _centerBold);
                    var centerMsg = GetCenterMsg();
                    g.DrawString(centerMsg, _font, _solidBrush, new PointF(_size / 2, _size / 2), _centerBold);
                    if (HasMatch)
                    {
                        var stringSize     = g.MeasureString(centerMsg, _font);
                        var cardSmallImage = GetColorSmall(PreviousCard);
                        g.DrawImage(cardSmallImage, new PointF(_size / 2 - stringSize.Width / 2 - cardSmallImage.Width, _size / 2 - cardSmallImage.Height / 2));
                        g.DrawImage(cardSmallImage, new PointF(_size / 2 + stringSize.Width / 2, _size / 2 - cardSmallImage.Height / 2));
                    }
                }
            }
            image.Save(imagePath, System.Drawing.Imaging.ImageFormat.Png);
            await _ch.SendFileAsync(imagePath).ConfigureAwait(false);
        }
예제 #11
0
        public void Start()
        {
            Task.Run(async() =>
            {
                var interactivity = _client.GetInteractivity();

                var board   = Show();
                var initMsg = $"A Reversi game has started between { _whitePlayer.Mention} and { _blackPlayer.Mention}!\n";
                initMsg    += $"Use 'help' for commands\n";
                await _ch.SendMessageAsync(initMsg).ConfigureAwait(false);
                var startMsg = $"{_blackPlayer.DisplayName}(Black) goes first!\n";
                await _ch.SendFileAsync(board, startMsg).ConfigureAwait(false);

                CurrentPlayer  = Piece.Black;
                var curPlayer  = _blackPlayer;
                var afk        = false;
                var hasMoved   = false;
                var cannotMove = false;
                while (true)
                {
                    if (hasMoved)
                    {
                        if (CurrentPlayer == Piece.Black)
                        {
                            CurrentPlayer = Piece.White;
                            curPlayer     = _whitePlayer;
                        }
                        else
                        {
                            CurrentPlayer = Piece.Black;
                            curPlayer     = _blackPlayer;
                        }
                        hasMoved = false;
                        // check here since currentPlayer changes here
                        if (HasEnded())
                        {
                            if (!cannotMove)
                            {
                                cannotMove = true;
                                hasMoved   = true;
                                continue;
                            }
                            CountPieces(out int blackPieces, out int whitePieces);
                            var msg = "Game has ended due to board full or no available moves!\n";
                            if (blackPieces > whitePieces)
                            {
                                msg += $"{_blackPlayer.DisplayName}(Black) has won the game!\n";
                            }
                            else if (whitePieces > blackPieces)
                            {
                                msg += $"{_whitePlayer.DisplayName}(White) has won the game!\n";
                            }
                            else
                            {
                                msg += "The game has drawn!\n";
                            }
                            msg  += $"{_blackPlayer.DisplayName}(Black) has {blackPieces} pieces against {_whitePlayer.DisplayName}(White)'s {whitePieces} pieces.";
                            board = Show();
                            await _ch.SendFileAsync(board).ConfigureAwait(false);
                            await Dispose(msg).ConfigureAwait(false);
                            break;
                        }
                        var colorMessage = CurrentPlayer == Piece.White ? "White" : "Black";
                        var showMsg      = $"{curPlayer.DisplayName}({colorMessage})'s turn to move.";
                        if (cannotMove)
                        {
                            showMsg    = $"The opponent has no available move!\n" + showMsg;
                            cannotMove = false;
                        }
                        board = Show();
                        await _ch.SendFileAsync(board, showMsg).ConfigureAwait(false);
                    }
                    var response = await interactivity.WaitForMessageAsync(x => (x.Author.Id == _whitePlayer.Id || x.Author.Id == _blackPlayer.Id) && x.ChannelId == _ch.Id).ConfigureAwait(false);
                    if (response.TimedOut)
                    {
                        await _ch.SendMessageAsync($"This channel will be deleted soon unless there is activity.").ConfigureAwait(false);
                        if (afk)
                        {
                            var msg = $"The channel has seen no activity for 10 minutes.\n";
                            await Dispose(msg).ConfigureAwait(false);
                            break;
                        }
                        afk = true;
                        continue;
                    }
                    afk         = false;
                    var command = response.Result.Content.Split(" ");
                    if (command.Length == 1)
                    {
                        if (command[0] == "help")
                        {
                            var helpMsg = $"Type 'help' for help, or 'resign' to resign game.\n";
                            helpMsg    += $"To place a piece, type the grid index. E.g d3\n";
                            helpMsg    += $"For detailed rules, click here: <https://en.wikipedia.org/wiki/Reversi#Rules>";
                            await _ch.SendMessageAsync(helpMsg).ConfigureAwait(false);
                        }
                        else if (command[0] == "resign")
                        {
                            var resignPlayer = response.Result.Author.Id == _blackPlayer.Id ? _blackPlayer.DisplayName : _whitePlayer.DisplayName;
                            var resignMsg    = $"{resignPlayer} has resigned the game!\n";
                            await Dispose(resignMsg).ConfigureAwait(false);
                            break;
                        }
                        else if (command[0] == "show")
                        {
                            board            = Show();
                            var colorMessage = CurrentPlayer == Piece.White ? "White" : "Black";
                            var showMsg      = $"{curPlayer.DisplayName}({colorMessage})'s turn to move.";
                            await _ch.SendFileAsync(board).ConfigureAwait(false);
                        }
                        else if (response.Result.Author.Id == curPlayer.Id)
                        {
                            try
                            {
                                var pos = TryStringToPoint(command[0]);
                                TryMove(pos);
                                hasMoved = true;
                            } catch (Exception e)
                            {
                                await _ch.SendMessageAsync(e.Message).ConfigureAwait(false);
                            }
                        }
                    }
                }
                await Dispose().ConfigureAwait(false);
            });
        }
예제 #12
0
        public async Task OnExecute(CommandContext command, [RemainingText] string commandArgs)
        {
            // Check if the user has permission to use this command.
            if (!Config.HasPermission(command.Member, "close"))
            {
                DiscordEmbed error = new DiscordEmbedBuilder
                {
                    Color       = DiscordColor.Red,
                    Description = "You do not have permission to use this command."
                };
                await command.RespondAsync("", false, error);

                command.Client.Logger.Log(LogLevel.Information, "User tried to use the close command but did not have permission.");
                return;
            }

            ulong  channelID   = command.Channel.Id;
            string channelName = command.Channel.Name;

            // Check if ticket exists in the database
            if (!Database.TryGetOpenTicket(channelID, out Database.Ticket ticket))
            {
                DiscordEmbed error = new DiscordEmbedBuilder
                {
                    Color       = DiscordColor.Red,
                    Description = "This channel is not a ticket."
                };
                await command.RespondAsync("", false, error);

                return;
            }

            // Build transcript
            try
            {
                await Transcriber.ExecuteAsync(command.Channel.Id.ToString(), ticket.id);
            }
            catch (Exception)
            {
                DiscordEmbed error = new DiscordEmbedBuilder
                {
                    Color       = DiscordColor.Red,
                    Description = "ERROR: Could not save transcript file. Aborting..."
                };
                await command.RespondAsync("", false, error);

                throw;
            }
            string filePath = Transcriber.GetPath(ticket.id);

            // Log it if the log channel exists
            DiscordChannel logChannel = command.Guild.GetChannel(Config.logChannel);

            if (logChannel != null)
            {
                DiscordEmbed logMessage = new DiscordEmbedBuilder
                {
                    Color       = DiscordColor.Green,
                    Description = "Ticket " + ticket.id.ToString("00000") + " closed by " + command.Member.Mention + ".\n",
                    Footer      = new DiscordEmbedBuilder.EmbedFooter {
                        Text = '#' + channelName
                    }
                };
                await logChannel.SendFileAsync(filePath, "", false, logMessage);
            }

            if (Config.closingNotifications)
            {
                DiscordEmbed message = new DiscordEmbedBuilder
                {
                    Color       = DiscordColor.Green,
                    Description = "Ticket " + ticket.id.ToString("00000") + " which you opened has now been closed, check the transcript for more info.\n",
                    Footer      = new DiscordEmbedBuilder.EmbedFooter {
                        Text = '#' + channelName
                    }
                };

                try
                {
                    DiscordMember staffMember = await command.Guild.GetMemberAsync(ticket.creatorID);

                    await staffMember.SendFileAsync(filePath, "", false, message);
                }
                catch (NotFoundException) { }
                catch (UnauthorizedException) { }
            }

            Database.ArchiveTicket(ticket);

            // Delete the channel and database entry
            await command.Channel.DeleteAsync("Ticket closed.");

            Database.DeleteOpenTicket(ticket.id);
        }
예제 #13
0
        public static async Task PostPrediction(long userId, DiscordChannel channel)
        {
            var context = new DiscordContext();

            SankakuImage imgToPost = null;

            Random rnd = new Random();

            var channelIDLong = Convert.ToInt64(channel.Id);

            var blacklistedTags =
                await context.SankakuTagBlacklist.Where(blackTag => blackTag.ChannelId == channelIDLong).Select(tag => tag.TagId).ToListAsync();

            var startDate = DateTime.Now - TimeSpan.FromDays(90);

            var trainedModel = Train(userId);

            int skip = 0;

            while (imgToPost == null)
            {
                //imgToPost = context.SankakuImage.Where(si => si.SankakuPost.Count == 0).Skip(skip).First();

                imgToPost = context.SankakuImage.Find(88415l);

                if (imgToPost == null)
                {
                    await ScrapeNewest();
                }

                List <MLSankakuPost> posts = new List <MLSankakuPost>();

                MLSankakuPost mlPost = new MLSankakuPost()
                {
                    //imgRating = imgToPost.Rating,
                    //score = Convert.ToSingle(imgToPost.Score),
                    //Tags = context.SankakuImageTag.Where(imageTag => imageTag.ImageId == imgToPost.Id).Select(tag => Convert.ToSingle(tag.TagId)).ToArray(),
                    Tags = 1,
                };

                posts.Add(mlPost);

                var prediction = trainedModel.Predict(posts, true);

                if (prediction.First().Score < 1)
                {
                    skip++;
                    imgToPost = null;
                }
            }

            DiscordEmbedBuilder builder = new DiscordEmbedBuilder()
            {
                Color = DiscordColor.Orange,
                Title = context.Puns.Skip(new Random().Next(context.Puns.Count() - 1)).First().Text
            };

            var link = HttpUtility.HtmlDecode(await GetOriginalImageLink(imgToPost.Id));

            var request = Helpers.CreateRequestWithHeaders(link);

            var response = request.GetResponse();

            SKImage img = SKImage.FromEncodedData(response.GetResponseStream());

            if (img.ColorType == SKColorType.Bgra8888)
            {
                //Bgra8888 needs an indexed Colortable, so convert it to Rgba8888 first
                var bitmap = new SKBitmap(new SKImageInfo(img.Width, img.Height, SKColorType.Rgba8888));
                var canvas = new SKCanvas(bitmap);
                canvas.DrawImage(img, 0, 0, null);
                canvas.Flush();
                img = SKImage.FromBitmap(bitmap);
            }

            var imageData = img.Encode(SKEncodedImageFormat.Jpeg, 75); //Encode in Jpeg instead of Webp because of IOS

            using (var outStream = imageData.AsStream())
            {
                var msg = await channel.SendFileAsync(outStream, builder.Title + ".jpeg",
                                                      embed : builder.Build());

                context.SankakuPost.Add(new Models.SankakuPost()
                {
                    Date      = DateTime.Now,
                    Image     = imgToPost,
                    MessageId = Convert.ToInt64(msg.Id)
                });

                await context.SaveChangesAsync();
            }
        }
예제 #14
0
        public static async Task PostRandom(DiscordChannel channel, int skip = 0)
        {
            var context = new DiscordContext();

            SankakuImage imgToPost = null;

            Random rnd = new Random(skip);

            var channelIDLong = Convert.ToInt64(channel.Id);

            var blacklistedTags =
                await context.SankakuTagBlacklist.Where(blackTag => blackTag.ChannelId == channelIDLong).Select(tag => tag.TagId).ToListAsync();

            var startDate = DateTime.Now - TimeSpan.FromDays(90);

            var viableImages = context.SankakuImage.Where(si => si.SankakuPost.Count == 0 && si.Score > 4 && si.RatingCount > 6);

            while (imgToPost == null)
            {
                var firstNotPostedPicture = viableImages.Where(si => !si.SankakuImageTag.Any(tag => blacklistedTags.Contains(tag.TagId)))
                                            .Skip(skip).First();

                if (firstNotPostedPicture == null)
                {
                    var oldestPostedPicture = viableImages.Where(si =>
                                                                 si.SankakuPost.OrderByDescending(post => post.Date).First().Date < startDate)
                                              .Skip(skip);
                }
                else
                {
                    imgToPost = firstNotPostedPicture;
                }

                if (imgToPost == null)
                {
                    await ScrapeNewest();
                }
            }

            DiscordEmbedBuilder builder = new DiscordEmbedBuilder()
            {
                Color = DiscordColor.SpringGreen,
                Title = context.Puns.Skip(rnd.Next(context.Puns.Count() - 1)).First().Text
            };

            var link = HttpUtility.HtmlDecode(await GetOriginalImageLink(imgToPost.Id));

            var request = Helpers.CreateRequestWithHeaders(link);

            var response = request.GetResponse();

            SKImage img = SKImage.FromEncodedData(response.GetResponseStream());

            if (img.ColorType == SKColorType.Bgra8888)
            {
                //Bgra8888 needs an indexed Colortable, so convert it to Rgba8888 first
                var bitmap = new SKBitmap(new SKImageInfo(img.Width, img.Height, SKColorType.Rgba8888));
                var canvas = new SKCanvas(bitmap);
                canvas.DrawImage(img, 0, 0, null);
                canvas.Flush();
                img = SKImage.FromBitmap(bitmap);
            }

            var imageData = img.Encode(SKEncodedImageFormat.Webp, 70);

            using (var outStream = imageData.AsStream())
            {
                var msg = await channel.SendFileAsync(outStream, builder.Title + ".webp",
                                                      embed : builder.Build());

                context.SankakuPost.Add(new Models.SankakuPost()
                {
                    Date      = DateTime.Now,
                    Image     = imgToPost,
                    MessageId = Convert.ToInt64(msg.Id)
                });

                await context.SaveChangesAsync();
            }
        }
예제 #15
0
        public async Task <bool> PostRandom(DiscordChannel channel, int skip = 0)
        {
            var context = new DiscordContext();

            var channelIDLong = Convert.ToInt64(channel.Id);

            var startDate = DateTime.Now - TimeSpan.FromDays(90);

            if (!_cachedImages.ContainsKey(channelIDLong))
            {
                Console.WriteLine($"Couldn't find cached Images for Channel {channelIDLong}");
                return(false);
            }

            var images = _cachedImages[Convert.ToInt64(channelIDLong)];

            var imgToPost = images.Where(cImg => !_postedImages.Contains(cImg)).Skip(skip).FirstOrDefault();

            if (imgToPost == 0)
            {
                await Console.Error.WriteLineAsync("Could not find a suitable Sankaku Image").ConfigureAwait(false);

                return(false);
            }

            DiscordEmbedBuilder builder = new DiscordEmbedBuilder()
            {
                Color = DiscordColor.SpringGreen,
                Title = context.Puns.Skip(Helpers.RandomGenerator.RandomInt(0, context.Puns.Count() - 1)).First().Text
            };

            var imageUri = await GetOriginalImageUrl(imgToPost).ConfigureAwait(false);

            if (imageUri == null)
            {
                return(false);
            }

            var link = HttpUtility.HtmlDecode(imageUri.AbsoluteUri);

            var response = await _httpClient.GetAsync(link);

            if (response.StatusCode != HttpStatusCode.OK)
            {
                await Console.Error.WriteLineAsync($"Could not get Image Link for {imgToPost}").ConfigureAwait(false);

                return(false);
            }

            var stream = await response.Content.ReadAsStreamAsync();

            Stream  outStream = null;
            string  extension = "";
            SKImage img       = SKImage.FromEncodedData(stream);

            if (img != null)
            {
                if (img.ColorType == SKColorType.Bgra8888 || img.ColorType == SKColorType.Gray8)
                {
                    //Convert Types, that need an indexed Colortable to a non-indexed Type
                    var bitmap = new SKBitmap(new SKImageInfo(img.Width, img.Height, SKColorType.Rgba8888));
                    var canvas = new SKCanvas(bitmap);
                    canvas.DrawImage(img, 0, 0, null);
                    canvas.Flush();
                    img = SKImage.FromBitmap(bitmap);
                }

                var imageData = img.Encode(SKEncodedImageFormat.Jpeg, 75);

                outStream = imageData.AsStream();

                extension = ".jpeg";
            }
            else
            {
                return(false);
            }

            if (outStream == null || outStream.Length == 0)
            {
                await Console.Error.WriteLineAsync($"Stream for SankakuImage ({imgToPost}) was 0 length or null").ConfigureAwait(false);

                return(false);
            }

            try
            {
                using (outStream)
                {
                    Console.WriteLine("SankakuBot: Sending File");
                    var msgTask = channel.SendFileAsync(outStream, Helpers.GetSafeFilename(builder.Title + extension),
                                                        embed: builder.Build());

                    msgTask.Wait(30000);

                    DiscordMessage msg = null;

                    if (msgTask.IsCompleted)
                    {
                        msg = await msgTask;
                    }
                    else
                    {
                        Console.WriteLine($"SankakuBot: Couldn't send File with name {Helpers.GetSafeFilename(builder.Title + extension)}");
                        outStream.Close();
                        await _client.ReconnectAsync(true);

                        return(false);
                    }

                    Console.WriteLine("SankakuBot: Finished Sending File");
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine("SankakuBot: Something went wrong while trying to send file");
                Console.WriteLine(ex.Message);
                Console.WriteLine(ex.InnerException);
            }
            finally
            {
                context.SankakuPost.Add(new SankakuPost()
                {
                    Date      = DateTime.Now,
                    ImageId   = imgToPost,
                    MessageId = -1
                });

                await context.SaveChangesAsync();

                _postedImages.Add(imgToPost);
            }

            return(true);
        }
예제 #16
0
        public async Task OnExecute(CommandContext command, [RemainingText] string commandArgs)
        {
            // Check if the user has permission to use this command.
            if (!Config.HasPermission(command.Member, "transcript"))
            {
                DiscordEmbed error = new DiscordEmbedBuilder
                {
                    Color       = DiscordColor.Red,
                    Description = "You do not have permission to use this command."
                };
                await command.RespondAsync("", false, error);

                command.Client.Logger.Log(LogLevel.Information, "User tried to use the transcript command but did not have permission.");
                return;
            }

            Database.Ticket ticket;
            string          strippedMessage = command.Message.Content.Replace(Config.prefix, "");

            string[] parsedMessage = strippedMessage.Replace("<@!", "").Replace("<@", "").Replace(">", "").Split();

            // If there are no arguments use current channel
            if (parsedMessage.Length < 2)
            {
                if (Database.TryGetOpenTicket(command.Channel.Id, out ticket))
                {
                    try
                    {
                        await Transcriber.ExecuteAsync(ticket.channelID.ToString(), ticket.id);
                    }
                    catch (Exception)
                    {
                        DiscordEmbed error = new DiscordEmbedBuilder
                        {
                            Color       = DiscordColor.Red,
                            Description = "ERROR: Could not save transcript file. Aborting..."
                        };
                        await command.RespondAsync("", false, error);

                        throw;
                    }
                }
                else
                {
                    DiscordEmbed error = new DiscordEmbedBuilder
                    {
                        Color       = DiscordColor.Red,
                        Description = "This channel is not a ticket."
                    };
                    await command.RespondAsync("", false, error);

                    return;
                }
            }
            else
            {
                // Check if argument is numerical, if not abort
                if (!uint.TryParse(parsedMessage[1], out uint ticketID))
                {
                    DiscordEmbed error = new DiscordEmbedBuilder
                    {
                        Color       = DiscordColor.Red,
                        Description = "Argument must be a number."
                    };
                    await command.RespondAsync("", false, error);

                    return;
                }

                // If the ticket is still open, generate a new fresh transcript
                if (Database.TryGetOpenTicketByID(ticketID, out ticket) && ticket?.creatorID == command.Member.Id)
                {
                    try
                    {
                        await Transcriber.ExecuteAsync(ticket.channelID.ToString(), ticket.id);
                    }
                    catch (Exception)
                    {
                        DiscordEmbed error = new DiscordEmbedBuilder
                        {
                            Color       = DiscordColor.Red,
                            Description = "ERROR: Could not save transcript file. Aborting..."
                        };
                        await command.RespondAsync("", false, error);

                        throw;
                    }
                }
                // If there is no open or closed ticket, send an error. If there is a closed ticket we will simply use the old transcript from when the ticket was closed.
                else if (!Database.TryGetClosedTicket(ticketID, out ticket) || (ticket?.creatorID != command.Member.Id && !Database.IsStaff(command.Member.Id)))
                {
                    DiscordEmbed error = new DiscordEmbedBuilder
                    {
                        Color       = DiscordColor.Red,
                        Description = "Could not find a closed ticket with that number which you opened." + (Config.HasPermission(command.Member, "list") ? "\n(Use the " + Config.prefix + "list command to see all your tickets)" : "")
                    };
                    await command.RespondAsync("", false, error);

                    return;
                }
            }

            string filePath = Transcriber.GetPath(ticket.id);

            // Log it if the log channel exists
            DiscordChannel logChannel = command.Guild.GetChannel(Config.logChannel);

            if (logChannel != null)
            {
                DiscordEmbed logMessage = new DiscordEmbedBuilder
                {
                    Color       = DiscordColor.Green,
                    Description = "Ticket " + ticket.id.ToString("00000") + " transcript generated by " + command.Member.Mention + ".\n",
                    Footer      = new DiscordEmbedBuilder.EmbedFooter {
                        Text = '#' + command.Channel.Name
                    }
                };
                await logChannel.SendFileAsync(filePath, "", false, logMessage);
            }

            try
            {
                // Send transcript privately
                DiscordEmbed directMessage = new DiscordEmbedBuilder
                {
                    Color       = DiscordColor.Green,
                    Description = "Transcript generated, " + command.Member.Mention + "!\n"
                };
                await command.Member.SendFileAsync(filePath, "", false, directMessage);

                // Respond to message directly
                DiscordEmbed response = new DiscordEmbedBuilder
                {
                    Color       = DiscordColor.Green,
                    Description = "Transcript sent, " + command.Member.Mention + "!\n"
                };
                await command.RespondAsync("", false, response);
            }
            catch (UnauthorizedException)
            {
                // Send transcript privately
                DiscordEmbed error = new DiscordEmbedBuilder
                {
                    Color       = DiscordColor.Red,
                    Description = "Not allowed to send direct message to you, " + command.Member.Mention + ", please check your privacy settings.\n"
                };
                await command.RespondAsync("", false, error);
            }
        }
예제 #17
0
        public async Task OnExecute(CommandContext command)
        {
            // Check if the user has permission to use this command.
            if (!Config.HasPermission(command.Member, "close"))
            {
                DiscordEmbed error = new DiscordEmbedBuilder
                {
                    Color       = DiscordColor.Red,
                    Description = "You do not have permission to use this command."
                };
                await command.RespondAsync("", false, error);

                command.Client.DebugLogger.LogMessage(LogLevel.Info, "SupportBoi", "User tried to use the close command but did not have permission.", DateTime.UtcNow);
                return;
            }

            ulong  channelID   = command.Channel.Id;
            string channelName = command.Channel.Name;

            // Check if ticket exists in the database
            if (!Database.TryGetOpenTicket(channelID, out Database.Ticket ticket))
            {
                DiscordEmbed error = new DiscordEmbedBuilder
                {
                    Color       = DiscordColor.Red,
                    Description = "This channel is not a ticket."
                };
                await command.RespondAsync("", false, error);

                return;
            }

            // Build transcript
            try
            {
                await Transcriber.ExecuteAsync(command.Channel.Id.ToString(), ticket.id);
            }
            catch (Exception)
            {
                DiscordEmbed error = new DiscordEmbedBuilder
                {
                    Color       = DiscordColor.Red,
                    Description = "ERROR: Could not save transcript file. Aborting..."
                };
                await command.RespondAsync("", false, error);

                throw;
            }
            string filePath = Transcriber.GetPath(ticket.id);

            // Log it if the log channel exists
            DiscordChannel logChannel = command.Guild.GetChannel(Config.logChannel);

            if (logChannel != null)
            {
                DiscordEmbed logMessage = new DiscordEmbedBuilder
                {
                    Color       = DiscordColor.Green,
                    Description = "Ticket " + ticket.id.ToString("00000") + " closed by " + command.Member.Mention + ".\n",
                    Footer      = new DiscordEmbedBuilder.EmbedFooter {
                        Text = '#' + channelName
                    }
                };
                await logChannel.SendFileAsync(filePath, "", false, logMessage);
            }

            if (Config.closingNotifications)
            {
                DiscordEmbed message = new DiscordEmbedBuilder
                {
                    Color       = DiscordColor.Green,
                    Description = "Ticket " + ticket.id.ToString("00000") + " which you opened has now been closed, check the transcript for more info.\n",
                    Footer      = new DiscordEmbedBuilder.EmbedFooter {
                        Text = '#' + channelName
                    }
                };

                try
                {
                    DiscordMember staffMember = await command.Guild.GetMemberAsync(ticket.creatorID);

                    DiscordMessage dm = await staffMember.SendFileAsync(filePath, "", false, message);

                    await dm.CreateReactionAsync(DiscordEmoji.FromName(command.Client, ":one:"));

                    await dm.CreateReactionAsync(DiscordEmoji.FromName(command.Client, ":two:"));

                    await dm.CreateReactionAsync(DiscordEmoji.FromName(command.Client, ":three:"));

                    await dm.CreateReactionAsync(DiscordEmoji.FromName(command.Client, ":four:"));

                    await dm.CreateReactionAsync(DiscordEmoji.FromName(command.Client, ":five:"));
                }
                catch (NotFoundException) { }
                catch (UnauthorizedException) { }
            }

            using (MySqlConnection c = Database.GetConnection())
            {
                // Create an entry in the ticket history database
                MySqlCommand archiveTicket = new MySqlCommand(@"INSERT INTO ticket_history (id, created_time, closed_time, creator_id, assigned_staff_id, summary, channel_id, rating) VALUES (@id, @created_time, now(), @creator_id, @assigned_staff_id, @summary, @channel_id, @rating);", c);
                archiveTicket.Parameters.AddWithValue("@id", ticket.id);
                archiveTicket.Parameters.AddWithValue("@created_time", ticket.createdTime);
                archiveTicket.Parameters.AddWithValue("@creator_id", ticket.creatorID);
                archiveTicket.Parameters.AddWithValue("@assigned_staff_id", ticket.assignedStaffID);
                archiveTicket.Parameters.AddWithValue("@summary", ticket.summary);
                archiveTicket.Parameters.AddWithValue("@channel_id", channelID);
                archiveTicket.Parameters.AddWithValue("@rating", 0);

                c.Open();
                archiveTicket.ExecuteNonQuery();

                // Delete the channel and database entry
                await command.Channel.DeleteAsync("Ticket closed.");

                MySqlCommand deletion = new MySqlCommand(@"DELETE FROM tickets WHERE channel_id=@channel_id", c);
                deletion.Parameters.AddWithValue("@channel_id", channelID);
                deletion.Prepare();
                deletion.ExecuteNonQuery();

                Sheets.DeleteTicketQueued(ticket.id);
            }
        }
예제 #18
0
        public async Task MoveMsgAsync(CommandContext ctx, [Description("The Channel to move to")] DiscordChannel channel, [Description("Amount of Messages to move")] int msg)
        {
            if (msg < 1)
            {
                return;
            }

            IReadOnlyList <DiscordMessage> messagesList = await ctx.Channel.GetMessagesAsync(limit : msg);

            List <DiscordMessage> messages = messagesList.OrderBy(m => m.Timestamp).ToList();

            int totalHeight = 0;

            List <MessagePicture> msgPicList = new List <MessagePicture>();

            int imgWidth = 600;

            using (Graphics calcGraphics = Graphics.FromImage(new Bitmap(1, 1)))
            {
                foreach (var cmsg in messages)
                {
                    var msgPic = new MessagePicture(cmsg, calcGraphics, imgWidth);
                    msgPicList.Add(msgPic);
                    totalHeight += msgPic.Height;
                }
            }

            Bitmap bmp = new Bitmap(imgWidth, totalHeight);

            using (Graphics graphics = Graphics.FromImage(bmp))
            {
                graphics.Clear(Color.FromArgb(54, 57, 63));
                graphics.SmoothingMode = SmoothingMode.HighSpeed;

                float cHeight = 0f;

                foreach (var msgPic in msgPicList)
                {
                    msgPic.AddToImg(graphics, cHeight, imgWidth);
                    cHeight += msgPic.Height;
                }
            }

            using (MemoryStream memory = new MemoryStream())
            {
                var qualityEncoder = Encoder.Quality;
                var quality        = (long)80;
                var ratio          = new EncoderParameter(qualityEncoder, quality);
                var codecParams    = new EncoderParameters(1);
                codecParams.Param[0] = ratio;
                var jpegCodecInfo = ImageCodecInfo.GetImageEncoders().First(e => e.MimeType == "image/jpeg");
                bmp.Save(memory, jpegCodecInfo, codecParams); // Save to JPG

                memory.Position = 0;

                await channel.SendFileAsync(memory, "ChatArchive.jpeg");
            }

            await ctx.Channel.DeleteMessagesAsync(messagesList);

            await ctx.RespondAsync($"I moved some Stuff to {channel.Mention}");
        }
예제 #19
0
            internal async Task Show()
            {
                var imagePath = Path.Combine(_parent._tempPath, $"{_index}.png");
                var image     = new Bitmap(_size, _size);

                lock (_parent._drawLock)
                {
                    if (IsDisposed)
                    {
                        return;
                    }
                    using (Graphics g = Graphics.FromImage(image))
                    {
                        var back = new Bitmap(OldMaidImage.Instance._back);

                        var enemyY       = 0;
                        var player1Cards = _parent.Players[1 - _index].GetCardCount();;
                        // if players cards total width is less than size, draw from center
                        for (var i = 0; i < player1Cards; ++i)
                        {
                            if (player1Cards * _cardWidth < _size)
                            {
                                var enemyStartingOffset = (_size - player1Cards * _cardWidth) / 2;
                                g.DrawImage(back, new Point(enemyStartingOffset + i * _cardWidth, enemyY));
                                g.DrawString($"{i + 1}", _font, _solidBrush, new Point(enemyStartingOffset + i * _cardWidth, enemyY + _cardHeight));
                            }
                            else
                            {
                                var enemyXOffset = (_size - _cardWidth) / (player1Cards - 1);
                                g.DrawImage(back, new Point(enemyXOffset * i, enemyY));
                                g.DrawString($"{i + 1}", _font, _solidBrush, new Point(enemyXOffset * i, enemyY + _cardHeight));
                            }
                        }

                        var myY = _size - _cardHeight;
                        for (var i = 0; i < Cards.Count; ++i)
                        {
                            var drawColor = GetColor(Cards[i]);
                            if (Cards.Count * _cardWidth < _size)
                            {
                                var myStartingOffset = (_size - Cards.Count * _cardWidth) / 2;
                                g.DrawImage(drawColor, new Point(myStartingOffset + i * _cardWidth, myY));
                            }
                            else
                            {
                                var myXOffset = (_size - _cardWidth) / (Cards.Count - 1);
                                g.DrawImage(drawColor, new Point(myXOffset * i, myY));
                            }
                        }
                        var centerMsg = _parent.GetCenterMsg(_index);
                        g.DrawString(centerMsg, _font, _solidBrush, new PointF(_size / 2, _size / 2), _centerBold);
                        if (_parent.HasMatch)
                        {
                            var stringSize     = g.MeasureString(centerMsg, _font);
                            var cardSmallImage = GetColorSmall(_parent.PreviousCard);
                            g.DrawImage(cardSmallImage, new PointF(_size / 2 - stringSize.Width / 2 - cardSmallImage.Width, _size / 2 - cardSmallImage.Height / 2));
                            g.DrawImage(cardSmallImage, new PointF(_size / 2 + stringSize.Width / 2, _size / 2 - cardSmallImage.Height / 2));
                        }
                    }
                }
                image.Save(imagePath, System.Drawing.Imaging.ImageFormat.Png);
                await _pCh.SendFileAsync(imagePath).ConfigureAwait(false);
            }
예제 #20
0
        public async Task <bool> PostRandom(DiscordChannel channel, int skip = 0)
        {
            using var discordContext = new DiscordContext();

            (Entities.Sankaku.Image Information, byte[] Data)? image = null;

            try
            {
                image = await GetImage(channel, skip);
            }
            catch (Exception)
            {
                return(false);
            }

            string extension = ".jpeg";

            switch (image.Value.Information.FileType)
            {
            case Entities.Sankaku.FileType.ImageGif:
                extension = ".gif";
                break;

            case Entities.Sankaku.FileType.ImageJpeg:
                extension = ".jpeg";
                break;

            case Entities.Sankaku.FileType.ImagePng:
                extension = ".png";
                break;
            }

            DiscordMessage msg = null;

            var outStream = new MemoryStream(image.Value.Data);

            DiscordEmbedBuilder builder = new DiscordEmbedBuilder()
            {
                Color = DiscordColor.SpringGreen,
                Title = discordContext.Puns.Skip(Helpers.RandomGenerator.RandomInt(0, discordContext.Puns.Count() - 1)).First().Text
            };

            try
            {
                if (outStream == null)
                {
                    Console.WriteLine("SankakuBot: Outstream was null");
                }

                Console.WriteLine($"SankakuBot: Sending File {Helpers.GetSafeFilename(builder.Title + extension)} to channel \"{channel.Name}\"");
                var msgTask = channel.SendFileAsync(Helpers.GetSafeFilename(builder.Title + extension), outStream, embed: builder.Build());

                int index = 0;
                while (!msgTask.IsCompleted && !msgTask.IsFaulted && index < 6000)
                {
                    await Task.Delay(5);
                }

                if (msgTask.IsCompleted)
                {
                    msg = await msgTask;
                }
                else
                {
                    Console.WriteLine($"SankakuBot: Couldn't send File with name {Helpers.GetSafeFilename(builder.Title + extension)}");
                    outStream.Close();
                    await _client.ReconnectAsync(true);
                }

                Console.WriteLine("SankakuBot: Finished Sending File");
            }
            catch (Exception ex)
            {
                Console.WriteLine("SankakuBot: Something went wrong while trying to send file");
                Console.WriteLine(ex.Message);
                Console.WriteLine(ex.InnerException);
            }
            finally
            {
                try
                {
                    var taskContext = new DiscordContext();

                    taskContext.SankakuPost.Add(new SankakuPost()
                    {
                        Date      = DateTime.Now,
                        ImageId   = image.Value.Information.Id,
                        MessageId = Convert.ToInt64(msg.Id)
                    });

                    await taskContext.SaveChangesAsync();

                    _postedImages.Add(image.Value.Information.Id);

                    outStream.Close();
                }
                catch (Exception ex)
                {
                    Console.WriteLine(ex);
                }
            }

            return(true);
        }
예제 #21
0
        private static async Task RunCommandAsync(DiscordMessage message, DiscordUser author, DiscordChannel channel, IEnumerable <string> commandSegments, string commandAlias, DiscordCommand command, DateTimeOffset start)
        {
            bool success = true;

            try
            {
                using (WamBotContext dbContext = new WamBotContext())
                {
                    await channel.TriggerTypingAsync();

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

                    CommandContext context = new CommandContext(commandSegments.ToArray(), message, Client)
                    {
                        Happiness = h,
                        _logger   = _loggerFactory.CreateLogger("Commands"),
                        UserData  = await dbContext.Users.FindOrCreateAsync(author.Id, () => new UserData(author))
                    };
                    CommandResult result = await command.RunCommand(commandSegments.ToArray(), context);

                    _appLogArea.WriteLine($"[{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 + "```";
                                }

                                _appLogArea.WriteLine($"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 = GetRequestTelemetry(author, channel, command, start, success ? "200" : "500", success);
                    foreach (var pair in result.InsightsData)
                    {
                        request.Properties.Add(pair);
                    }

                    TelemetryClient?.TrackRequest(request);

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

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

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

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

                HappinessData[author.Id] = (sbyte)((int)h - 1).Clamp(sbyte.MinValue, sbyte.MaxValue);
            }
            finally
            {
                if (command is IDisposable disp)
                {
                    disp.Dispose();
                }
            }
        }