public async Task AliasAsync(CommandContext ctx,
                                         [Description("Player alias.")] string alias,
                                         [Description("Player IP.")] CustomIPFormat ip)
            {
                using (DatabaseContext db = this.Database.CreateContext()) {
                    DatabaseSwatPlayer player = db.SwatPlayers
                                                .Include(p => p.DbAliases)
                                                .Include(p => p.DbIPs)
                                                .AsEnumerable()
                                                .FirstOrDefault(p => p.IPs.Contains(ip.Content));
                    if (player is null)
                    {
                        throw new CommandFailedException($"A player with IP {Formatter.Bold(ip.Content)} is not present in the database!");
                    }

                    if (alias.Equals(player.Name, StringComparison.InvariantCultureIgnoreCase))
                    {
                        throw new InvalidCommandUsageException("Alias cannot be same as player's main name.");
                    }

                    if (!player.Aliases.Contains(alias))
                    {
                        player.DbAliases.Add(new DatabaseSwatPlayerAlias {
                            Alias = alias, PlayerId = player.Id
                        });
                    }
                    db.SwatPlayers.Update(player);
                    await db.SaveChangesAsync();

                    await this.InformAsync(ctx, $"Added an alias {Formatter.Bold(alias)} for player {Formatter.Bold(player.Name)}.", important : false);
                }
            }
 public static string Stringify(this DatabaseSwatPlayer p)
 {
     return($"{Formatter.Bold(p.Name)} {(p.IsBlacklisted ? " (BLACKLISTED)" : "")}\n" +
            string.Join(", ", p.Aliases) + "\n" +
            Formatter.BlockCode(string.Join('\n', p.IPs)) +
            Formatter.Italic(p.Info ?? "No info provided."));
 }
            public async Task DeleteAsync(CommandContext ctx,
                                          [Description("Player name.")] string name)
            {
                using (DatabaseContext db = this.Database.CreateContext()) {
                    DatabaseSwatPlayer player = db.SwatPlayers.FirstOrDefault(p => p.Name.Equals(name, StringComparison.InvariantCultureIgnoreCase));
                    if (!(player is null) && player.IsBlacklisted)
                    {
                        player.IsBlacklisted = false;
                        db.SwatPlayers.Update(player);
                    }
                    await db.SaveChangesAsync();

                    await this.InformAsync(ctx, $"Removed a ban entry for {Formatter.Bold(player.Name)}.", important : false);
                }
            }
            public async Task DeleteAsync(CommandContext ctx,
                                          [Description("IP.")] CustomIPFormat ip)
            {
                using (DatabaseContext db = this.Database.CreateContext()) {
                    DatabaseSwatPlayer player = db.SwatPlayers
                                                .Include(p => p.DbIPs)
                                                .FirstOrDefault(p => p.IPs.Contains(ip.Content));
                    if (!(player is null) && player.IsBlacklisted)
                    {
                        player.IsBlacklisted = false;
                        db.SwatPlayers.Update(player);
                    }
                    await db.SaveChangesAsync();
                }

                await this.InformAsync(ctx, $"Removed an IP ban rule for {Formatter.InlineCode(ip.Content)}.", important : false);
            }
            public async Task AddAsync(CommandContext ctx,
                                       [Description("Player name.")] string name,
                                       [RemainingText, Description("Reason for ban.")] string reason = null)
            {
                using (DatabaseContext db = this.Database.CreateContext()) {
                    DatabaseSwatPlayer player = db.SwatPlayers.FirstOrDefault(p => p.Name.Equals(name, StringComparison.InvariantCultureIgnoreCase));
                    if (player is null)
                    {
                        throw new CommandFailedException($"Player with name {Formatter.Bold(name)} is not present in the database!");
                    }
                    player.IsBlacklisted = true;
                    player.Info          = reason;
                    db.SwatPlayers.Update(player);
                    await db.SaveChangesAsync();

                    await this.InformAsync(ctx, $"Added a ban entry for {Formatter.Bold(player.Name)}.", important : false);
                }
            }
            public async Task AddAsync(CommandContext ctx,
                                       [Description("Player name.")] string name,
                                       [Description("IP.")] CustomIPFormat ip,
                                       [RemainingText, Description("Additional info.")] string info = null)
            {
                using (DatabaseContext db = this.Database.CreateContext()) {
                    DatabaseSwatPlayer player = db.SwatPlayers
                                                .Include(p => p.DbIPs)
                                                .Include(p => p.DbAliases)
                                                .AsEnumerable()
                                                .FirstOrDefault(p => p.Name.Equals(name, StringComparison.InvariantCultureIgnoreCase) || p.IPs.Contains(ip.Content));
                    if (player is null)
                    {
                        var toAdd = new DatabaseSwatPlayer {
                            Info          = info,
                            IsBlacklisted = false,
                            Name          = name
                        };
                        toAdd.DbIPs.Add(new DatabaseSwatPlayerIP {
                            PlayerId = toAdd.Id, IP = ip.Content
                        });
                        db.SwatPlayers.Add(toAdd);
                    }
                    else
                    {
                        if (player.Name != name && !player.Aliases.Contains(name))
                        {
                            player.DbAliases.Add(new DatabaseSwatPlayerAlias {
                                Alias = name, PlayerId = player.Id
                            });
                        }
                        if (!player.IPs.Contains(ip.Content))
                        {
                            player.DbIPs.Add(new DatabaseSwatPlayerIP {
                                PlayerId = player.Id, IP = ip.Content
                            });
                        }
                        db.SwatPlayers.Update(player);
                    }
                    await db.SaveChangesAsync();
                }

                await this.InformAsync(ctx, $"Added a database entry for {Formatter.Bold(name)} ({Formatter.InlineCode(ip.Content)})", important : false);
            }
            public async Task DeleteAsync(CommandContext ctx,
                                          [RemainingText, Description("Name.")] string name)
            {
                if (string.IsNullOrWhiteSpace(name))
                {
                    throw new CommandFailedException("Name missing or invalid.");
                }
                name = name.ToLowerInvariant();

                using (DatabaseContext db = this.Database.CreateContext()) {
                    DatabaseSwatPlayer player = db.SwatPlayers.FirstOrDefault(p => p.Name == name);
                    if (!(player is null))
                    {
                        db.SwatPlayers.Remove(player);
                        await db.SaveChangesAsync();
                    }
                }

                await this.InformAsync(ctx, $"Removed {Formatter.Bold(name)} from the database.", important : false);
            }
            public async Task AddAsync(CommandContext ctx,
                                       [Description("Player name.")] string name,
                                       [Description("IPs.")] params CustomIPFormat[] ips)
            {
                if (ips is null || !ips.Any())
                {
                    throw new InvalidCommandUsageException("You need to specify atleast one IP to add.");
                }

                using (DatabaseContext db = this.Database.CreateContext()) {
                    DatabaseSwatPlayer player = db.SwatPlayers.FirstOrDefault(p => p.Name == name);
                    if (player is null)
                    {
                        var toAdd = new DatabaseSwatPlayer {
                            IsBlacklisted = false,
                            Name          = name
                        };
                        foreach (string ip in ips.Select(i => i.Content))
                        {
                            toAdd.DbIPs.Add(new DatabaseSwatPlayerIP {
                                IP = ip, PlayerId = toAdd.Id
                            });
                        }
                        db.SwatPlayers.Add(toAdd);
                    }
                    else
                    {
                        foreach (string ip in ips.Select(i => i.Content))
                        {
                            player.DbIPs.Add(new DatabaseSwatPlayerIP {
                                IP = ip, PlayerId = player.Id
                            });
                        }
                        db.SwatPlayers.Update(player);
                    }
                    await db.SaveChangesAsync();
                }

                await this.InformAsync(ctx, $"Added a database entry for {Formatter.Bold(name)}", important : false);
            }
            public async Task DeleteAsync(CommandContext ctx,
                                          [Description("IP or range.")] CustomIPFormat ip)
            {
                using (DatabaseContext db = this.Database.CreateContext()) {
                    DatabaseSwatPlayer player = db.SwatPlayers.Include(p => p.DbIPs).FirstOrDefault(p => p.IPs.Contains(ip.Content));
                    if (!(player is null))
                    {
                        player.DbIPs.Remove(new DatabaseSwatPlayerIP {
                            IP = ip.Content, PlayerId = player.Id
                        });
                        if (player.DbIPs.Any())
                        {
                            db.SwatPlayers.Update(player);
                        }
                        else
                        {
                            db.SwatPlayers.Remove(player);
                        }
                    }
                    await db.SaveChangesAsync();
                }

                await this.InformAsync(ctx, $"Removed {Formatter.Bold(ip.Content)} from the database.", important : false);
            }
            public async Task AddAsync(CommandContext ctx,
                                       [Description("Player name.")] string name,
                                       [Description("IP.")] CustomIPFormat ip,
                                       [RemainingText, Description("Reason for ban.")] string reason = null)
            {
                using (DatabaseContext db = this.Database.CreateContext()) {
                    DatabaseSwatPlayer player = db.SwatPlayers.FirstOrDefault(p => p.Name.Equals(name, StringComparison.InvariantCultureIgnoreCase));
                    if (player is null)
                    {
                        db.SwatPlayers.Add(new DatabaseSwatPlayer {
                            Info          = reason,
                            IsBlacklisted = true
                        });
                    }
                    else
                    {
                        player.IsBlacklisted = true;
                        db.SwatPlayers.Update(player);
                    }
                    await db.SaveChangesAsync();
                }

                await this.InformAsync(ctx, $"Added a ban entry for {Formatter.Bold(name)} ({Formatter.InlineCode(ip.Content)})", important : false);
            }