public async Task Warns(CommandContext ctx, [RemainingText] string suffix)
        {
            List <ulong> userIds = string.IsNullOrWhiteSpace(suffix) ?
                                   new List <ulong>()
            {
                ctx.User.Id
            } :
            Utils.GetIdListFromMessage(ctx.Message.MentionedUsers, suffix);

            if (userIds.Count == 0)
            {
                await CTX.RespondSanitizedAsync(ctx, "Please mention or type a user ID.");

                return;
            }
            if (ctx.Guild.Members.ContainsKey(userIds[0]))
            {
                RequireAdminAttribute adminCheck =
                    new RequireAdminAttribute("Only server admins are allowed to view warnings of other users.");
                if (ctx.User.Id != userIds[0] && !await adminCheck.ExecuteCheckAsync(ctx, false))
                {
                    return;
                }
                DiscordEmbedBuilder warnEmbed = Utils.BaseEmbedBuilder(ctx,
                                                                       $"Warnings for {ctx.Guild.Members[userIds[0]].DisplayName} ({userIds[0]})",
                                                                       ctx.Guild.Members[userIds[0]].AvatarUrl,
                                                                       null, ctx.Guild.Members[userIds[0]].Color);

                var warns = ShimakazeBot.DbCtx.GuildWarn.Where(g =>
                                                               g.UserId == userIds[0] && g.GuildId == ctx.Guild.Id
                                                               ).ToList();

                if (warns.Count() == 0)
                {
                    warnEmbed.WithDescription($"{ctx.Guild.Members[userIds[0]].DisplayName} has no warnings.");
                }
                else
                {
                    warns.ForEach(item => warnEmbed.AddField(item.TimeStamp.ToString(),
                                                             item.WarnMessage.Length > 1024 ? $"{item.WarnMessage.Take(1021)}..." : item.WarnMessage));
                }

                await CTX.RespondSanitizedAsync(ctx, null, false, warnEmbed);
            }
            else
            {
                int       id   = (int)userIds[0];
                GuildWarn warn = await ShimakazeBot.DbCtx.GuildWarn.FindAsync(id);

                if (warn != null)
                {
                    await CTX.RespondSanitizedAsync(ctx, $"{warn.TimeStamp} - {warn.WarnMessage}");
                }
                else
                {
                    await CTX.RespondSanitizedAsync(ctx, $"Unable to find member or ID **{id}**");
                }
            }
        }
        public async Task RemoveWarn(CommandContext ctx, [RemainingText] string suffix)
        {
            List <ulong> userIds = Utils.GetIdListFromMessage(ctx.Message.MentionedUsers, suffix);

            if (userIds.Count == 0)
            {
                await CTX.RespondSanitizedAsync(ctx, "Please mention, type a user ID or a warn ID.");

                return;
            }
            if (ctx.Guild.Members.ContainsKey(userIds[0]))
            {
                ShimakazeBot.DbCtx.GuildWarn.RemoveRange(ShimakazeBot.DbCtx.GuildWarn.Where(g =>
                                                                                            g.UserId == userIds[0] && g.GuildId == ctx.Guild.Id));

                await CTX.RespondSanitizedAsync(ctx, "Successfully removed all warnsings for " +
                                                $"**{ctx.Guild.Members[userIds[0]].DisplayName}**.");
            }
            else
            {
                int       id   = (int)userIds[0];
                GuildWarn warn = await ShimakazeBot.DbCtx.GuildWarn.FindAsync(id);

                if (warn != null)
                {
                    ShimakazeBot.DbCtx.GuildWarn.Remove(warn);
                    await ShimakazeBot.DbCtx.SaveChangesAsync();

                    await CTX.RespondSanitizedAsync(ctx, $"Successfully removed warning with ID **{id}**");
                }
                else
                {
                    await CTX.RespondSanitizedAsync(ctx, $"Unable to find member or ID **{id}**");
                }
            }
        }
        private async Task ModerateUser(CommandContext ctx, string suffix, ShimaConsts.ModerationType type)
        {
            int    userIndex    = string.IsNullOrWhiteSpace(suffix) ? -1 : suffix.IndexOf(" ");
            string userIdString = userIndex > 0 ? suffix.Substring(0, userIndex) : suffix;

            //get user to moderate
            List <ulong> userToModerateInList =
                Utils.GetIdListFromArray(ctx.Message.MentionedUsers, new string[] { userIdString });

            if (userToModerateInList.Count == 0)
            {
                await CTX.RespondSanitizedAsync(ctx,
                                                $"Please mention or type a user ID to {type.ToString().ToLower()}.");

                return;
            }
            ulong userToModerate = userToModerateInList[0];

            if (!ctx.Guild.Members.ContainsKey(userToModerate))
            {
                await CTX.RespondSanitizedAsync(ctx, $"Unable to find member with ID **{userToModerate}**");

                return;
            }

            DiscordMember exMember = ctx.Guild.Members[userToModerate];

            //get message
            string message = userIndex > 0 ? suffix.Substring(userIndex).TrimStart() : "";
            DiscordEmbedBuilder embed;

            //moderate
            switch (type)
            {
            case ShimaConsts.ModerationType.WARN:
                if (message.Length > 1024)
                {
                    await CTX.RespondSanitizedAsync(ctx, "Warning message must be under 1024 characters.");

                    return;
                }

                GuildWarn warn = (await ShimakazeBot.DbCtx.GuildWarn.AddAsync(new GuildWarn
                {
                    GuildId = ctx.Guild.Id,
                    UserId = userToModerate,
                    WarnMessage = message,
                    TimeStamp = DateTime.UtcNow
                })).Entity;
                await ShimakazeBot.DbCtx.SaveChangesAsync();

                embed = Utils.BaseEmbedBuilder(ctx,
                                               $"Added new warning for {exMember.DisplayName} ({userToModerate})",
                                               exMember.AvatarUrl,
                                               null, exMember.Color, $"warning ID: {warn.Id}");
                if (!string.IsNullOrWhiteSpace(message))
                {
                    embed.AddField("Message", message);
                }

                await CTX.RespondSanitizedAsync(ctx, null, false, embed);

                break;

            case ShimaConsts.ModerationType.KICK:
                try
                {
                    await exMember.RemoveAsync(message);

                    embed = Utils.BaseEmbedBuilder(ctx,
                                                   $"Kicked {exMember.DisplayName} ({userToModerate})",
                                                   exMember.AvatarUrl, null, exMember.Color);
                    if (!string.IsNullOrWhiteSpace(message))
                    {
                        embed.AddField("Reason", message);
                    }

                    await CTX.RespondSanitizedAsync(ctx, "Do you think they'll learn their lesson?", false, embed);
                }
                catch
                {
                    await CTX.RespondSanitizedAsync(ctx,
                                                    $"Failed to kick **{exMember.DisplayName}** ({userToModerate})");
                }
                break;

            case ShimaConsts.ModerationType.BAN:
                try
                {
                    await exMember.BanAsync(0, message);

                    embed = Utils.BaseEmbedBuilder(ctx,
                                                   $"Banned {exMember.DisplayName} ({userToModerate})",
                                                   exMember.AvatarUrl, null, exMember.Color);
                    if (!string.IsNullOrWhiteSpace(message))
                    {
                        embed.AddField("Reason", message);
                    }

                    await CTX.RespondSanitizedAsync(ctx, "Good riddance.", false, embed);
                }
                catch
                {
                    await CTX.RespondSanitizedAsync(ctx,
                                                    $"Failed to ban **{exMember.DisplayName}** ({userToModerate})");
                }
                break;
            }
        }