Beispiel #1
0
    public PlayerRoleGroupTool(int funcID, int groupID) : base(FuncToolType.RoleGroup, funcID)
    {
        _config = RoleGroupConfig.get(groupID);

        evt        = new RoleGroupEvt();
        evt.funcID = funcID;
    }
Beispiel #2
0
 public void setGroupTool(PlayerRoleGroupTool tool)
 {
     _tool   = tool;
     _funcID = tool.getFuncID();
     _config = tool.getConfig();
     evt     = tool.evt;
     setPlayer(tool.me);
 }
Beispiel #3
0
        public List <Command> Init(IBotwinderClient iClient)
        {
            this.Client = iClient as BotwinderClient;
            List <Command> commands = new List <Command>();

// !getRole
            Command newCommand = new Command("getRole");

            newCommand.Type                = CommandType.Standard;
            newCommand.Description         = "Get a name, id and color of `roleID` or `roleName` parameter.";
            newCommand.RequiredPermissions = PermissionType.ServerOwner | PermissionType.Admin;
            newCommand.OnExecute          += async e => {
                guid              id         = 0;
                SocketRole        roleFromId = null;
                List <SocketRole> roles      = null;
                if (string.IsNullOrEmpty(e.TrimmedMessage) ||
                    (!(guid.TryParse(e.TrimmedMessage, out id) && (roleFromId = e.Server.Guild.GetRole(id)) != null) &&
                     !(roles = e.Server.Guild.Roles.Where(r => r.Name.ToLower().Contains(e.TrimmedMessage.ToLower())).ToList()).Any()))
                {
                    await e.SendReplySafe("Role not found.");

                    return;
                }

                if (roleFromId != null)
                {
                    roles = new List <SocketRole>();
                    roles.Add(roleFromId);
                }

                StringBuilder response = new StringBuilder();
                foreach (SocketRole role in roles)
                {
                    string hex = BitConverter.ToString(new byte[] { role.Color.R, role.Color.G, role.Color.B }).Replace("-", "");
                    response.AppendLine($"Role: `{role.Name}`\n  Id: `{role.Id}`\n  Position: `{role.Position}`\n  Color: `rgb({role.Color.R},{role.Color.G},{role.Color.B})` | `hex(#{hex})`");
                }

                await e.SendReplySafe(response.ToString());
            };
            commands.Add(newCommand);
            commands.Add(newCommand.CreateAlias("getrole"));

// !addEmojiRole
            newCommand                     = new Command("addEmojiRole");
            newCommand.Type                = CommandType.Standard;
            newCommand.Description         = "Add an emoji reaction assigned role to a message.";
            newCommand.RequiredPermissions = PermissionType.ServerOwner | PermissionType.Admin;
            newCommand.OnExecute          += async e => {
                if (e.MessageArgs == null || e.MessageArgs.Length < 3 || e.TrimmedMessage == "-h" || e.TrimmedMessage == "--help" || !guid.TryParse(e.MessageArgs[0], out guid messageId))
                {
                    await e.SendReplySafe($"Usage: `{e.Server.Config.CommandPrefix}{e.CommandId} <messageId> <emoji> <roleId or name expression>`");

                    return;
                }

                Match emoji = this.EmojiNameRegex.Match(e.MessageArgs[1]);
                if (!emoji.Success)
                {
                    await e.SendReplySafe("What emoji again?");

                    return;
                }

                SocketRole role = e.Server.GetRole(e.MessageArgs[2], out string response);
                if (role == null)
                {
                    await e.SendReplySafe(response);

                    return;
                }

                ServerContext        dbContext    = ServerContext.Create(this.Client.DbConnectionString);
                ReactionAssignedRole reactionRole = dbContext.ReactionAssignedRoles.FirstOrDefault(r => r.ServerId == e.Server.Id && r.MessageId == messageId && r.Emoji == emoji.Value);
                if (reactionRole == null)
                {
                    dbContext.ReactionAssignedRoles.Add(reactionRole = new ReactionAssignedRole()
                    {
                        ServerId  = e.Server.Id,
                        MessageId = messageId,
                        Emoji     = emoji.Value
                    });
                }
                else if (reactionRole.RoleId == role.Id)
                {
                    await e.SendReplySafe("Already exists.");

                    dbContext.Dispose();
                    return;
                }

                reactionRole.RoleId = role.Id;
                dbContext.SaveChanges();
                dbContext.Dispose();
                await e.SendReplySafe(response);
            };
            commands.Add(newCommand);

// !membersOf
            newCommand                     = new Command("membersOf");
            newCommand.Type                = CommandType.Standard;
            newCommand.Description         = "Display a list of members of a role.";
            newCommand.RequiredPermissions = PermissionType.ServerOwner | PermissionType.Admin;
            newCommand.OnExecute          += async e => {
                SocketRole role = e.Server.GetRole(e.TrimmedMessage, out string response);
                if (role == null)
                {
                    await e.SendReplySafe(response);

                    return;
                }

                await e.Server.Guild.DownloadUsersAsync();

                List <string> names = role.Members.Select(u => u.GetUsername()).ToList();
                names.Sort();

                response = names.Count == 0 ? "Nobody has this role." : $"Members of `{role.Name}` are:\n" + names.ToNamesList();
                await e.SendReplySafe(response);
            };
            commands.Add(newCommand);
            commands.Add(newCommand.CreateAlias("listMembers"));

// !createRole
            newCommand                     = new Command("createRole");
            newCommand.Type                = CommandType.Standard;
            newCommand.Description         = "Create a role with specified name.";
            newCommand.RequiredPermissions = PermissionType.ServerOwner | PermissionType.Admin;
            newCommand.OnExecute          += async e => {
                if (!e.Server.Guild.CurrentUser.GuildPermissions.ManageRoles)
                {
                    await e.Message.Channel.SendMessageSafe(ErrorPermissionsString);

                    return;
                }
                if (string.IsNullOrEmpty(e.TrimmedMessage))
                {
                    await e.SendReplySafe("What role? Name? Do you want me to come up with something silly or what?");

                    return;
                }

                RestRole role = await e.Server.Guild.CreateRoleAsync(e.TrimmedMessage, GuildPermissions.None);

                string response = $"Role created: `{role.Name}`\n  Id: `{role.Id}`";
                await e.SendReplySafe(response);
            };
            commands.Add(newCommand);

// !createRoles
            newCommand                     = new Command("createRoles");
            newCommand.Type                = CommandType.Standard;
            newCommand.Description         = "Create roles with specified names. List of whitespace delimited arguments, use quotes to use spaces.";
            newCommand.RequiredPermissions = PermissionType.ServerOwner | PermissionType.Admin;
            newCommand.OnExecute          += async e => {
                if (!e.Server.Guild.CurrentUser.GuildPermissions.ManageRoles)
                {
                    await e.Message.Channel.SendMessageSafe(ErrorPermissionsString);

                    return;
                }
                if (string.IsNullOrEmpty(e.TrimmedMessage))
                {
                    await e.SendReplySafe(e.Command.Description);

                    return;
                }

                StringBuilder response = new StringBuilder("Roles created:\n");

                for (int i = 0; i < e.MessageArgs.Length; i++)
                {
                    RestRole role = await e.Server.Guild.CreateRoleAsync(e.MessageArgs[i], GuildPermissions.None);

                    response.AppendLine($"`{role.Id}` | `{role.Name}`");
                }

                await e.SendReplySafe(response.ToString());
            };
            commands.Add(newCommand);

// !createPublicRoles
            newCommand                     = new Command("createPublicRoles");
            newCommand.Type                = CommandType.Standard;
            newCommand.Description         = "Create public roles with specified names. The first argument will be used as a name for the new role group, followed by a list of whitespace delimited arguments, use quotes to use spaces.";
            newCommand.RequiredPermissions = PermissionType.ServerOwner | PermissionType.Admin;
            newCommand.OnExecute          += async e => {
                if (!e.Server.Guild.CurrentUser.GuildPermissions.ManageRoles)
                {
                    await e.Message.Channel.SendMessageSafe(ErrorPermissionsString);

                    return;
                }
                if (e.MessageArgs.Length < 2)
                {
                    await e.SendReplySafe(e.Command.Description);

                    return;
                }

                StringBuilder response = new StringBuilder("Roles created:\n");

                Int64         groupId   = 1;
                ServerContext dbContext = ServerContext.Create(this.Client.DbConnectionString);
                IEnumerable <RoleGroupConfig> roleGroups = dbContext.PublicRoleGroups.Where(g => g.ServerId == e.Server.Id);
                foreach (RoleGroupConfig group in roleGroups)
                {
                    if (groupId < group.GroupId)
                    {
                        groupId = group.GroupId;
                    }
                }

                RoleGroupConfig roleGroup = new RoleGroupConfig()
                {
                    ServerId  = e.Server.Id,
                    GroupId   = groupId,
                    Name      = e.MessageArgs[0],
                    RoleLimit = 1
                };
                dbContext.PublicRoleGroups.Add(roleGroup);

                bool save = true;
                for (int i = 1; i < e.MessageArgs.Length; i++)
                {
                    try
                    {
                        RestRole role = await e.Server.Guild.CreateRoleAsync(e.MessageArgs[i], GuildPermissions.None);

                        RoleConfig roleConfig = new RoleConfig()
                        {
                            ServerId          = e.Server.Id,
                            RoleId            = role.Id,
                            PermissionLevel   = RolePermissionLevel.Public,
                            PublicRoleGroupId = groupId
                        };
                        dbContext.Roles.Add(roleConfig);

                        response.AppendLine($"`{role.Id}` | `{role.Name}`");
                    }
                    catch (Exception)
                    {
                        save = false;
                        response.AppendLine($"__Something went wrong__ :/");
                        break;
                    }
                }

                if (save)
                {
                    dbContext.SaveChanges();
                }
                dbContext.Dispose();

                await e.SendReplySafe(response.ToString());
            };
            commands.Add(newCommand);

// !createTempRole
            newCommand                     = new Command("createTempRole");
            newCommand.Type                = CommandType.Standard;
            newCommand.Description         = "`createTempRole name time` Create a role with specified name, which will be destroyed after specified time (e.g. `7d` or `12h` or `1d12h`)";
            newCommand.RequiredPermissions = PermissionType.ServerOwner | PermissionType.Admin;
            newCommand.OnExecute          += async e => {
                ServerContext dbContext  = ServerContext.Create(this.Client.DbConnectionString);
                RoleConfig    roleConfig = await CreateTempRole(e, dbContext);

                if (roleConfig != null)
                {
                    dbContext.SaveChanges();
                }
                dbContext.Dispose();
            };
            commands.Add(newCommand);

// !createTempPublicRole
            newCommand                     = new Command("createTempPublicRole");
            newCommand.Type                = CommandType.Standard;
            newCommand.Description         = "`createTempRole name time` Create a role with specified name, which will be destroyed after specified time (e.g. `7d` or `12h` or `1d12h`) This role will also become a public - use the `join` command to get it.";
            newCommand.RequiredPermissions = PermissionType.ServerOwner | PermissionType.Admin;
            newCommand.OnExecute          += async e => {
                ServerContext dbContext  = ServerContext.Create(this.Client.DbConnectionString);
                RoleConfig    roleConfig = await CreateTempRole(e, dbContext);

                if (roleConfig != null)
                {
                    roleConfig.PermissionLevel = RolePermissionLevel.Public;
                    dbContext.SaveChanges();
                }
                dbContext.Dispose();
            };
            commands.Add(newCommand);

// !createColourRoles
            newCommand                     = new Command("createColourRoles");
            newCommand.Type                = CommandType.Standard;
            newCommand.Description         = "Create 9 roles with various colours, you can find emoji representations of these colours in Valhalla - the Valkyrja support server.";
            newCommand.RequiredPermissions = PermissionType.ServerOwner | PermissionType.Admin;
            newCommand.OnExecute          += async e => {
                if (!e.Server.Guild.CurrentUser.GuildPermissions.ManageRoles)
                {
                    await e.SendReplySafe(ErrorPermissionsString);

                    return;
                }

                await e.Server.Guild.CreateRoleAsync("purple", GuildPermissions.None, new Color(180, 136, 209));

                await e.Server.Guild.CreateRoleAsync("pink", GuildPermissions.None, new Color(255, 183, 255));

                await e.Server.Guild.CreateRoleAsync("orange", GuildPermissions.None, new Color(255, 165, 105));

                await e.Server.Guild.CreateRoleAsync("lightOrange", GuildPermissions.None, new Color(255, 186, 158));

                await e.Server.Guild.CreateRoleAsync("lightYellow", GuildPermissions.None, new Color(223, 223, 133));

                await e.Server.Guild.CreateRoleAsync("yellow", GuildPermissions.None, new Color(201, 192, 67));

                await e.Server.Guild.CreateRoleAsync("blue", GuildPermissions.None, new Color(92, 221, 255));

                await e.Server.Guild.CreateRoleAsync("cyan", GuildPermissions.None, new Color(150, 232, 221));

                await e.Server.Guild.CreateRoleAsync("green", GuildPermissions.None, new Color(46, 204, 113));

                await e.SendReplySafe("I've created them roles, but you're gonna have to set them up yourself at <https://valkyrja.app/config> because I don't know the details!\n" +
                                      "_You can use my colour emojis to set them up as reaction assigned roles. Get them in Valhalla: https://discord.gg/XgVvkXx_");
            };
            commands.Add(newCommand);
            commands.Add(newCommand.CreateAlias("createColorRoles"));

// !removeStreamPermission
            newCommand                     = new Command("removeStreamPermission");
            newCommand.Type                = CommandType.Standard;
            newCommand.Description         = "Removes Stream permission from all the roles.";
            newCommand.RequiredPermissions = PermissionType.ServerOwner | PermissionType.Admin;
            newCommand.OnExecute          += async e => {
                if (!e.Server.Guild.CurrentUser.GuildPermissions.ManageRoles)
                {
                    await e.SendReplySafe("I ain't got the permissions.");

                    return;
                }

                int highestRolePosition = 0;
                foreach (SocketRole role in e.Server.Guild.Roles)
                {
                    if (role.Position > highestRolePosition)
                    {
                        highestRolePosition = role.Position;
                    }
                }

                if (e.Server.Guild.CurrentUser.Hierarchy < highestRolePosition)
                {
                    await e.SendReplySafe("I am not the top role in hierarchy. I really have to be on top to disable that thing on all the roles!");

                    return;
                }

                int    exceptions = 0;
                string response   = "Done with exceptions:\n";
                foreach (SocketRole role in e.Server.Guild.Roles.Where(r => r.Position < e.Server.Guild.CurrentUser.Hierarchy))
                {
                    try
                    {
                        await role.ModifyAsync(r => r.Permissions = new Optional <GuildPermissions>(role.Permissions.Modify(stream: false)));
                    }
                    catch (Exception)
                    {
                        response += $"`{role.Name}`\n";
                        if (++exceptions > 5)
                        {
                            response += "...and probably more...";
                            break;
                        }
                    }
                }

                if (exceptions == 0)
                {
                    response = "Done.";
                }

                await e.SendReplySafe(response);
            };
            commands.Add(newCommand);
            commands.Add(newCommand.CreateAlias("removeGolivePermission"));

            return(commands);
        }
Beispiel #4
0
        public async Task ReactionAssignedRoles(SocketReaction reaction, bool assignRoles)
        {
            Server server;

            if (!(reaction.Channel is SocketTextChannel channel) || !this.Client.Servers.ContainsKey(channel.Guild.Id) || (server = this.Client.Servers[channel.Guild.Id]) == null || server.Config == null)
            {
                return;
            }

            if (this.ReactionUsers.Contains(reaction.UserId))
            {
                return;
            }

            server.ReactionRolesLock.Wait();
            if (this.ReactionUsers.Contains(reaction.UserId))
            {
                server.ReactionRolesLock.Release();
                return;
            }
            this.ReactionUsers.Add(reaction.UserId);

            try
            {
                IEnumerable <ReactionAssignedRole> roles;
                roles = server.ReactionAssignedRoles.Where(r => r.MessageId == reaction.MessageId && r.Emoji == reaction.Emote.Name).ToList();

                if (roles.Any())
                {
                    IGuildUser user = null;
                    if (!reaction.User.IsSpecified || (user = reaction.User.Value as SocketGuildUser) == null)
                    {
                        user = server.Guild.GetUser(reaction.UserId);
                        if (user == null)
                        {
                            user = await this.Client.DiscordClient.Rest.GetGuildUserAsync(server.Id, reaction.UserId);
                        }
                        if (user == null)
                        {
                            this.ReactionUsers.Remove(reaction.UserId);
                            server.ReactionRolesLock.Release();
                            return;
                        }
                    }

                    string name = "unknown";
                    try
                    {
                        foreach (ReactionAssignedRole role in roles)
                        {
                            if (assignRoles == user.RoleIds.Any(rId => rId == role.RoleId))
                            {
                                continue;
                            }

                            IRole discordRole = server.Guild.GetRole(role.RoleId);
                            if (discordRole == null)
                            {
                                continue;
                            }

                            name = discordRole.Name;

                            if (!assignRoles)
                            {
                                await user.RemoveRoleAsync(discordRole);

                                this.ReactionUsers.Remove(reaction.UserId);
                                server.ReactionRolesLock.Release();
                                return;
                            }

                            //else...
                            Int64 groupId = server.Roles.ContainsKey(discordRole.Id) ? server.Roles[discordRole.Id].PublicRoleGroupId : 0;
                            if (groupId != 0)
                            {
                                List <guid> groupRoleIds = server.Roles.Where(r => r.Value.PermissionLevel == RolePermissionLevel.Public && r.Value.PublicRoleGroupId == groupId).Select(r => r.Value.RoleId).ToList();
                                int         userHasCount = user.RoleIds.Count(rId => groupRoleIds.Any(id => id == rId));

                                RoleGroupConfig groupConfig = null;
                                if (userHasCount > 0)
                                {
                                    ServerContext dbContext = ServerContext.Create(this.Client.DbConnectionString);
                                    groupConfig = dbContext.PublicRoleGroups.AsQueryable().FirstOrDefault(g => g.ServerId == server.Id && g.GroupId == groupId);
                                    dbContext.Dispose();

                                    while (userHasCount >= groupConfig.RoleLimit && groupRoleIds.Any())
                                    {
                                        IRole roleToRemove = server.Guild.GetRole(groupRoleIds.Last());
                                        groupRoleIds.Remove(groupRoleIds.Last());
                                        if (roleToRemove == null || user.RoleIds.All(rId => rId != roleToRemove.Id))
                                        {
                                            continue;
                                        }

                                        await user.RemoveRoleAsync(roleToRemove);

                                        try
                                        {
                                            if (await reaction.Channel.GetMessageAsync(reaction.MessageId) is SocketUserMessage sMsg)
                                            {
                                                await sMsg.RemoveReactionAsync(reaction.Emote, reaction.UserId);
                                            }
                                            if (await reaction.Channel.GetMessageAsync(reaction.MessageId) is RestUserMessage rMsg)
                                            {
                                                await rMsg.RemoveReactionAsync(reaction.Emote, reaction.UserId);
                                            }
                                        }
                                        catch (Exception e)
                                        {
                                            await this.HandleException(e, "Failed to remove reaction.", server.Id);
                                        }

                                        userHasCount--;
                                    }
                                }
                            }

                            await user.AddRoleAsync(discordRole);
                        }
                    }
                    catch (HttpException e)
                    {
                        await server.HandleHttpException(e, $"This happened in <#{channel.Id}> when trying to change reactions or assign roles based on emojis.");
                    }
                    catch (Exception e)
                    {
                        await this.HandleException(e, "Reaction Assigned Roles", server.Id);
                    }
                }
            }
            catch (Exception e)
            {
                await this.HandleException(e, "Reaction Assigned Roles", server.Id);
            }

            this.ReactionUsers.Remove(reaction.UserId);
            server.ReactionRolesLock.Release();
        }
Beispiel #5
0
        public List <Command> Init(IValkyrjaClient iClient)
        {
            this.Client = iClient as ValkyrjaClient;
            List <Command> commands = new List <Command>();

            this.Client.Events.UserJoined      += OnUserJoined;
            this.Client.Events.ReactionAdded   += OnReactionAdded;
            this.Client.Events.ReactionRemoved += OnReactionRemoved;

// !publicRoles
            Command newCommand = new Command("publicRoles");

            newCommand.Type                = CommandType.Standard;
            newCommand.Description         = "See what Public Roles can you join on this server.";
            newCommand.ManPage             = new ManPage("", "");
            newCommand.RequiredPermissions = PermissionType.Everyone;
            newCommand.OnExecute          += async e => {
                List <RoleConfig> publicRoles = e.Server.Roles.Values.Where(r => r.PermissionLevel == RolePermissionLevel.Public).ToList();
                if (publicRoles == null || publicRoles.Count == 0)
                {
                    await e.SendReplySafe(ErrorNoPublicRoles);

                    return;
                }

                ServerContext dbContext       = ServerContext.Create(this.Client.DbConnectionString);
                StringBuilder responseBuilder = new StringBuilder(e.Server.Localisation.GetString("role_publicroles_print", e.Server.Config.CommandPrefix));
                Dictionary <Int64, List <RoleConfig> > groupRoles   = new Dictionary <Int64, List <RoleConfig> >();
                Dictionary <Int64, RoleGroupConfig>    groupConfigs = dbContext.PublicRoleGroups.AsQueryable().Where(g => g.ServerId == e.Server.Id).ToDictionary(g => g.GroupId);
                dbContext.Dispose();

                foreach (RoleConfig roleConfig in publicRoles)
                {
                    SocketRole role = e.Server.Guild.GetRole(roleConfig.RoleId);
                    if (role == null)
                    {
                        continue;
                    }

                    if (!groupRoles.ContainsKey(roleConfig.PublicRoleGroupId))
                    {
                        List <RoleConfig> tempGroup = publicRoles.Where(r => r.PublicRoleGroupId == roleConfig.PublicRoleGroupId).ToList();
                        groupRoles.Add(roleConfig.PublicRoleGroupId, tempGroup);
                    }
                }

                string GetRoleNames(List <RoleConfig> roleConfigs)
                {
                    return(e.Server.Guild.Roles.Where(r => roleConfigs.Any(rc => rc.RoleId == r.Id))
                           .Select(r => r.Name).ToNames());
                }

                if (groupRoles.ContainsKey(0))
                {
                    responseBuilder.Append(GetRoleNames(groupRoles[0]));
                }

                foreach (KeyValuePair <Int64, List <RoleConfig> > groupRole in groupRoles)
                {
                    if (groupRole.Key == 0)
                    {
                        continue;
                    }

                    RoleGroupConfig groupConfig  = groupConfigs.ContainsKey(groupRole.Key) ? groupConfigs[groupRole.Key] : new RoleGroupConfig();
                    string          name         = string.IsNullOrEmpty(groupConfig.Name) ? ("Group #" + groupRole.Key.ToString()) : groupConfig.Name;
                    string          limitVerbose = groupConfig.RoleLimit == 0 ? "any" : groupConfig.RoleLimit.ToString();
                    responseBuilder.Append(e.Server.Localisation.GetString("role_publicroles_group", name, limitVerbose));

                    responseBuilder.Append(GetRoleNames(groupRole.Value));
                }

                await e.SendReplySafe(responseBuilder.ToString());
            };
            commands.Add(newCommand);

// !roleCounts
            newCommand                     = new Command("roleCounts");
            newCommand.Type                = CommandType.Standard;
            newCommand.Description         = "Get some numbers about public roles for specific group.";
            newCommand.ManPage             = new ManPage("<expression>", "`<expression>` - An expression using which to search for a role group.");
            newCommand.RequiredPermissions = PermissionType.Everyone;
            newCommand.OnExecute          += async e => {
                string expression = e.TrimmedMessage;

                ServerContext dbContext = ServerContext.Create(this.Client.DbConnectionString);
                IEnumerable <RoleGroupConfig> roleGroups  = dbContext.PublicRoleGroups.AsQueryable().Where(g => g.ServerId == e.Server.Id);
                IEnumerable <RoleGroupConfig> foundGroups = null;

                if (string.IsNullOrEmpty(expression) || (
                        !(foundGroups = roleGroups.Where(g => g.Name == expression)).Any() &&
                        !(foundGroups = roleGroups.Where(g => (g.Name?.ToLower() ?? "") == expression.ToLower())).Any() &&
                        !(foundGroups = roleGroups.Where(g => g.Name?.ToLower().Contains(expression.ToLower()) ?? false)).Any()))
                {
                    await e.SendReplySafe(ErrorGroupNotFound);

                    dbContext.Dispose();
                    return;
                }

                if (foundGroups.Count() > 1)
                {
                    await e.SendReplySafe(ErrorTooManyGroupsFound);

                    dbContext.Dispose();
                    return;
                }

                await e.Server.Guild.DownloadUsersAsync();

                Int64 groupId = foundGroups.First().GroupId;
                dbContext.Dispose();

                IEnumerable <guid>       roleIds  = e.Server.Roles.Values.Where(r => r.PublicRoleGroupId == groupId).Select(r => r.RoleId);
                IEnumerable <SocketRole> roles    = e.Server.Guild.Roles.Where(r => roleIds.Contains(r.Id));
                StringBuilder            response = new StringBuilder();
                foreach (SocketRole role in roles)
                {
                    response.AppendLine($"**{role.Name}**: `{role.Members.Count()}`");
                }

                await e.SendReplySafe(response.ToString());
            };
            commands.Add(newCommand);
            commands.Add(newCommand.CreateAlias("countGroup"));
            commands.Add(newCommand.CreateAlias("countRoles"));

// !join
            newCommand                     = new Command("join");
            newCommand.Type                = CommandType.Standard;
            newCommand.Description         = "Grab a public role for yourself.";
            newCommand.ManPage             = new ManPage("<expression>", "`<expression>` - An expression using which to search for a public role.");
            newCommand.RequiredPermissions = PermissionType.Everyone;
            newCommand.OnExecute          += async e => {
                if (!e.Server.Guild.CurrentUser.GuildPermissions.ManageRoles)
                {
                    await e.SendReplySafe(ErrorPermissionsString);

                    return;
                }

                if (string.IsNullOrEmpty(e.TrimmedMessage))
                {
                    await e.SendReplySafe(e.Command.ManPage.ToString(e.Server.Config.CommandPrefix + e.CommandId));

                    return;
                }

                List <RoleConfig> publicRoles = e.Server.Roles.Values.Where(r => r.PermissionLevel == RolePermissionLevel.Public).ToList();
                if (publicRoles == null || publicRoles.Count == 0)
                {
                    await e.SendReplySafe(ErrorNoPublicRoles);

                    return;
                }

                IEnumerable <SocketRole> roles      = e.Server.Guild.Roles.Where(r => publicRoles.Any(rc => rc.RoleId == r.Id));
                IEnumerable <SocketRole> foundRoles = null;
                if (!(foundRoles = roles.Where(r => r.Name == e.TrimmedMessage)).Any() &&
                    !(foundRoles = roles.Where(r => r.Name.ToLower() == e.TrimmedMessage.ToLower())).Any() &&
                    !(foundRoles = roles.Where(r => r.Name.ToLower().Contains(e.TrimmedMessage.ToLower()))).Any())
                {
                    await e.SendReplySafe(ErrorRoleNotFound);

                    return;
                }

                if (foundRoles.Count() > 1)
                {
                    await e.SendReplySafe(ErrorTooManyFound);

                    return;
                }

                RoleGroupConfig    groupConfig  = null;
                IEnumerable <guid> groupRoleIds = null;
                SocketRole         roleToAssign = foundRoles.First();
                Int64 groupId = publicRoles.First(r => r.RoleId == roleToAssign.Id).PublicRoleGroupId;

                if (groupId != 0)
                {
                    groupRoleIds = publicRoles.Where(r => r.PublicRoleGroupId == groupId).Select(r => r.RoleId);
                    int userHasCount = (e.Message.Author as SocketGuildUser).Roles.Count(r => groupRoleIds.Any(id => id == r.Id));

                    if (userHasCount > 0)
                    {
                        ServerContext dbContext = ServerContext.Create(this.Client.DbConnectionString);
                        groupConfig = dbContext.PublicRoleGroups.AsQueryable().FirstOrDefault(g => g.ServerId == e.Server.Id && g.GroupId == groupId);
                        dbContext.Dispose();

                        if (groupConfig != null && groupConfig.RoleLimit > 1 && userHasCount >= groupConfig.RoleLimit)
                        {
                            await e.SendReplySafe($"You can only have {groupConfig.RoleLimit} roles from the `{groupConfig.Name}` group.");

                            return;
                        }
                    }
                }

                bool   removed  = false;
                string response = e.Server.Localisation.GetString("role_join_done");
                try
                {
                    SocketGuildUser user = (e.Message.Author as SocketGuildUser);

                    if (groupRoleIds != null && (groupConfig == null || groupConfig.RoleLimit == 1))
                    {
                        foreach (guid id in groupRoleIds)
                        {
                            if (user.Roles.All(r => r.Id != id))
                            {
                                continue;
                            }

                            SocketRole roleToLeave = e.Server.Guild.GetRole(id);
                            if (roleToLeave == null)
                            {
                                continue;
                            }

                            await user.RemoveRoleAsync(roleToLeave);

                            removed = true;
                        }
                    }

                    await user.AddRoleAsync(roleToAssign);
                } catch (HttpException exception)
                {
                    await e.Server.HandleHttpException(exception, $"This happened in <#{e.Channel.Id}> when executing command `{e.CommandId}`");

                    response = Utils.HandleHttpException(exception);
                } catch (Exception exception)
                {
                    await this.Client.LogException(exception, e);

                    response = $"Unknown error, please poke <@{this.Client.GlobalConfig.AdminUserId}> to take a look x_x";
                }

                if (removed)
                {
                    response += e.Server.Localisation.GetString("role_join_exclusiveremoved");
                }

                await e.SendReplySafe(response);

                if (this.Client.Events.LogPublicRoleJoin != null)
                {
                    await this.Client.Events.LogPublicRoleJoin(e.Server, e.Message.Author as SocketGuildUser, roleToAssign.Name);
                }
            };
            commands.Add(newCommand);

// !leave
            newCommand                     = new Command("leave");
            newCommand.Type                = CommandType.Standard;
            newCommand.Description         = "Dispose of your public role.";
            newCommand.ManPage             = new ManPage("<expression>", "`<expression>` - An expression using which to search for a public role.");
            newCommand.RequiredPermissions = PermissionType.Everyone;
            newCommand.OnExecute          += async e => {
                if (!e.Server.Guild.CurrentUser.GuildPermissions.ManageRoles)
                {
                    await e.SendReplySafe(ErrorPermissionsString);

                    return;
                }

                if (string.IsNullOrEmpty(e.TrimmedMessage))
                {
                    await e.SendReplySafe(e.Command.ManPage.ToString(e.Server.Config.CommandPrefix + e.CommandId));

                    return;
                }

                List <RoleConfig> publicRoles = e.Server.Roles.Values.Where(r => r.PermissionLevel == RolePermissionLevel.Public).ToList();
                if (publicRoles == null || publicRoles.Count == 0)
                {
                    await e.SendReplySafe(ErrorNoPublicRoles);

                    return;
                }

                IEnumerable <SocketRole> roles      = e.Server.Guild.Roles.Where(r => publicRoles.Any(rc => rc.RoleId == r.Id));
                IEnumerable <SocketRole> foundRoles = null;
                if (!(foundRoles = roles.Where(r => r.Name == e.TrimmedMessage)).Any() &&
                    !(foundRoles = roles.Where(r => r.Name.ToLower() == e.TrimmedMessage.ToLower())).Any() &&
                    !(foundRoles = roles.Where(r => r.Name.ToLower().Contains(e.TrimmedMessage.ToLower()))).Any())
                {
                    await e.SendReplySafe(ErrorRoleNotFound);

                    return;
                }

                if (foundRoles.Count() > 1)
                {
                    await e.SendReplySafe(ErrorTooManyFound);

                    return;
                }

                string response = e.Server.Localisation.GetString("role_leave_done");
                try
                {
                    await(e.Message.Author as SocketGuildUser)?.RemoveRoleAsync(foundRoles.First());
                } catch (HttpException exception)
                {
                    await e.Server.HandleHttpException(exception, $"This happened in <#{e.Channel.Id}> when executing command `{e.CommandId}`");

                    response = Utils.HandleHttpException(exception);
                } catch (Exception exception)
                {
                    await this.Client.LogException(exception, e);

                    response = $"Unknown error, please poke <@{this.Client.GlobalConfig.AdminUserId}> to take a look x_x";
                }

                await e.SendReplySafe(response);

                if (this.Client.Events.LogPublicRoleLeave != null)
                {
                    await this.Client.Events.LogPublicRoleLeave(e.Server, e.Message.Author as SocketGuildUser, foundRoles.First().Name);
                }
            };
            commands.Add(newCommand);

// !memberRoles
            newCommand                     = new Command("memberRoles");
            newCommand.Type                = CommandType.Standard;
            newCommand.Description         = "See what Member Roles you can assign to others.";
            newCommand.ManPage             = new ManPage("", "");
            newCommand.RequiredPermissions = PermissionType.ServerOwner | PermissionType.Admin | PermissionType.Moderator | PermissionType.SubModerator;
            newCommand.OnExecute          += async e => {
                SocketGuildUser moderator = e.Message.Author as SocketGuildUser;
                if (moderator == null)
                {
                    await this.HandleException(new NullReferenceException("Message author is not a SocketGuildUser"), e.Message.Author.Id.ToString(), e.Server.Id);

                    return;
                }

                List <guid> memberRoles = e.Server.Roles.Values.Where(r => r.PermissionLevel == RolePermissionLevel.Member).Select(r => r.RoleId).ToList();
                memberRoles.AddRange(e.Server.CategoryMemberRoles.Where(rc => moderator.Roles.Any(r => r.Id == rc.ModRoleId)).Select(r => r.MemberRoleId));
                if (memberRoles == null || memberRoles.Count == 0)
                {
                    await e.SendReplySafe(ErrorNoMemberRoles);

                    return;
                }

                string response = e.Server.Localisation.GetString("role_memberroles_print",
                                                                  e.Server.Config.CommandPrefix,
                                                                  e.Server.Guild.Roles.Where(r => memberRoles.Any(rc => rc == r.Id)).Select(r => r.Name).ToNames()
                                                                  );

                await e.SendReplySafe(response);
            };
            commands.Add(newCommand);

// !promote
            newCommand                     = new Command("promote");
            newCommand.Type                = CommandType.Standard;
            newCommand.Description         = "Assign someone a member role.";
            newCommand.ManPage             = new ManPage("<@users> <expression>", "`<@users>` - User mention(s) (or IDs) whom to assign the member role.\n\n`<expression>` - An expression using which to search for a member role.");
            newCommand.RequiredPermissions = PermissionType.ServerOwner | PermissionType.Admin | PermissionType.Moderator | PermissionType.SubModerator;
            newCommand.OnExecute          += async e => {
                if (!e.Server.Guild.CurrentUser.GuildPermissions.ManageRoles)
                {
                    await e.SendReplySafe(ErrorPermissionsString);

                    return;
                }

                SocketGuildUser moderator = e.Message.Author as SocketGuildUser;
                if (moderator == null)
                {
                    await this.HandleException(new NullReferenceException("Message author is not a SocketGuildUser"), e.Message.Author.Id.ToString(), e.Server.Id);

                    return;
                }

                List <IGuildUser> users;
                if (string.IsNullOrEmpty(e.TrimmedMessage) || !(users = await this.Client.GetMentionedGuildUsers(e)).Any() || e.MessageArgs.Length <= users.Count)
                {
                    await e.SendReplySafe(e.Command.ManPage.ToString(e.Server.Config.CommandPrefix + e.CommandId));

                    return;
                }

                List <guid> memberRoles = e.Server.Roles.Values.Where(r => r.PermissionLevel == RolePermissionLevel.Member).Select(r => r.RoleId).ToList();
                memberRoles.AddRange(e.Server.CategoryMemberRoles.Where(rc => moderator.Roles.Any(r => r.Id == rc.ModRoleId)).Select(r => r.MemberRoleId));

                if (memberRoles == null || memberRoles.Count == 0)
                {
                    await e.SendReplySafe(ErrorNoMemberRoles);

                    return;
                }

                string expression = e.TrimmedMessage.Substring(e.TrimmedMessage.IndexOf(e.MessageArgs[users.Count]));

                IEnumerable <SocketRole> roles      = e.Server.Guild.Roles.Where(r => memberRoles.Any(rc => rc == r.Id));
                IEnumerable <SocketRole> foundRoles = null;
                if (!(foundRoles = roles.Where(r => r.Name == expression)).Any() &&
                    !(foundRoles = roles.Where(r => r.Name.ToLower() == expression.ToLower())).Any() &&
                    !(foundRoles = roles.Where(r => r.Name.ToLower().Contains(expression.ToLower()))).Any())
                {
                    await e.SendReplySafe(ErrorRoleNotFound);

                    return;
                }

                if (foundRoles.Count() > 1)
                {
                    await e.SendReplySafe(ErrorTooManyFound);

                    return;
                }

                string     response = e.Server.Localisation.GetString("role_promote_done");
                SocketRole role     = foundRoles.First();
                try
                {
                    foreach (IGuildUser user in users)
                    {
                        await user.AddRoleAsync(role);

                        if (this.Client.Events.LogPromote != null)
                        {
                            await this.Client.Events.LogPromote(e.Server, user, role.Name, e.Message.Author as SocketGuildUser);
                        }
                    }
                } catch (HttpException exception)
                {
                    await e.Server.HandleHttpException(exception, $"This happened in <#{e.Channel.Id}> when executing command `{e.CommandId}`");

                    response = Utils.HandleHttpException(exception);
                } catch (Exception exception)
                {
                    await this.Client.LogException(exception, e);

                    response = $"Unknown error, please poke <@{this.Client.GlobalConfig.AdminUserId}> to take a look x_x";
                }

                await e.SendReplySafe(response);
            };
            commands.Add(newCommand);

// !demote
            newCommand                     = new Command("demote");
            newCommand.Type                = CommandType.Standard;
            newCommand.Description         = "Remove a member role from someone.";
            newCommand.ManPage             = new ManPage("<@users> <expression>", "`<@users>` - User mention(s) (or IDs) whom to remove the member role.\n\n`<expression>` - An expression using which to search for a member role.");
            newCommand.RequiredPermissions = PermissionType.ServerOwner | PermissionType.Admin | PermissionType.Moderator | PermissionType.SubModerator;
            newCommand.OnExecute          += async e => {
                if (!e.Server.Guild.CurrentUser.GuildPermissions.ManageRoles)
                {
                    await e.SendReplySafe(ErrorPermissionsString);

                    return;
                }

                SocketGuildUser moderator = e.Message.Author as SocketGuildUser;
                if (moderator == null)
                {
                    await this.HandleException(new NullReferenceException("Message author is not a SocketGuildUser"), e.Message.Author.Id.ToString(), e.Server.Id);

                    return;
                }

                List <IGuildUser> users;
                if (string.IsNullOrEmpty(e.TrimmedMessage) || !(users = await this.Client.GetMentionedGuildUsers(e)).Any() || e.MessageArgs.Length <= users.Count)
                {
                    await e.SendReplySafe(e.Command.ManPage.ToString(e.Server.Config.CommandPrefix + e.CommandId));

                    return;
                }

                List <guid> memberRoles = e.Server.Roles.Values.Where(r => r.PermissionLevel == RolePermissionLevel.Member).Select(r => r.RoleId).ToList();
                memberRoles.AddRange(e.Server.CategoryMemberRoles.Where(rc => moderator.Roles.Any(r => r.Id == rc.ModRoleId)).Select(r => r.MemberRoleId));

                if (memberRoles == null || memberRoles.Count == 0)
                {
                    await e.SendReplySafe(ErrorNoMemberRoles);

                    return;
                }

                string expression = e.TrimmedMessage.Substring(e.TrimmedMessage.IndexOf(e.MessageArgs[users.Count]));

                IEnumerable <SocketRole> roles      = e.Server.Guild.Roles.Where(r => memberRoles.Any(rc => rc == r.Id));
                IEnumerable <SocketRole> foundRoles = null;
                if (!(foundRoles = roles.Where(r => r.Name == expression)).Any() &&
                    !(foundRoles = roles.Where(r => r.Name.ToLower() == expression.ToLower())).Any() &&
                    !(foundRoles = roles.Where(r => r.Name.ToLower().Contains(expression.ToLower()))).Any())
                {
                    await e.SendReplySafe(ErrorRoleNotFound);

                    return;
                }

                if (foundRoles.Count() > 1)
                {
                    await e.SendReplySafe(ErrorTooManyFound);

                    return;
                }

                SocketRole role     = foundRoles.First();
                string     response = e.Server.Localisation.GetString("role_demote_done");
                try
                {
                    foreach (IGuildUser user in users)
                    {
                        await user.RemoveRoleAsync(role);

                        if (this.Client.Events.LogDemote != null)
                        {
                            await this.Client.Events.LogDemote(e.Server, user, role.Name, e.Message.Author as SocketGuildUser);
                        }
                    }
                } catch (HttpException exception)
                {
                    await e.Server.HandleHttpException(exception, $"This happened in <#{e.Channel.Id}> when executing command `{e.CommandId}`");

                    response = Utils.HandleHttpException(exception);
                } catch (Exception exception)
                {
                    await this.Client.LogException(exception, e);

                    response = $"Unknown error, please poke <@{this.Client.GlobalConfig.AdminUserId}> to take a look x_x";
                }

                await e.SendReplySafe(response);
            };
            commands.Add(newCommand);

// !categoryMembers
            newCommand                     = new Command("categoryMembers");
            newCommand.Type                = CommandType.Standard;
            newCommand.Description         = "Configure category member roles.";
            newCommand.ManPage             = new ManPage("<add> <modRoleId> <memberRoleId> | <reset> <modRoleId> | <resetAll>", "`<add>` - An instruction to add the following roles as a moderator who can assign the member role.\n\n`<reset>` - An instruction to clear all the member roles associated with the specified moderator role ID.\n\n`<modRoleId>` - Moderator role ID to be added or reset. \n\n`<memberRoleId>` Member role ID to be added.");
            newCommand.RequiredPermissions = PermissionType.ServerOwner | PermissionType.Admin;
            newCommand.OnExecute          += async e => {
                string response = "Invalid arguments:\n" + e.Command.ManPage.ToString(e.Server.Config.CommandPrefix + e.CommandId);

                if (e.MessageArgs == null || e.MessageArgs.Length < 1)
                {
                    await e.SendReplySafe(response);

                    return;
                }

                guid modRoleId;
                IEnumerable <CategoryMemberRole> rolesToRemove;
                ServerContext dbContext = ServerContext.Create(this.Client.DbConnectionString);
                switch (e.MessageArgs[0].ToLower())
                {
                case "add":
                    if (!guid.TryParse(e.MessageArgs[1], out modRoleId) || !guid.TryParse(e.MessageArgs[2], out guid memberRoleId))
                    {
                        break;
                    }
                    dbContext.GetOrAddMemberRole(e.Server.Id, modRoleId, memberRoleId);
                    dbContext.SaveChanges();

                    response = "Sure.";
                    break;

                case "reset":
                    if (!guid.TryParse(e.MessageArgs[1], out modRoleId))
                    {
                        break;
                    }
                    rolesToRemove = dbContext.CategoryMemberRoles.AsQueryable().Where(r => r.ServerId == e.Server.Id && r.ModRoleId == modRoleId);
                    if (rolesToRemove.Any())
                    {
                        dbContext.CategoryMemberRoles.RemoveRange(rolesToRemove);
                        dbContext.SaveChanges();
                    }

                    response = "Sure.";
                    break;

                case "resetAll":
                    rolesToRemove = dbContext.CategoryMemberRoles.AsQueryable().Where(r => r.ServerId == e.Server.Id);
                    if (rolesToRemove.Any())
                    {
                        dbContext.CategoryMemberRoles.RemoveRange(rolesToRemove);
                        dbContext.SaveChanges();
                    }

                    response = "Sure.";
                    break;

                default:
                    break;
                }

                dbContext.Dispose();
                await e.SendReplySafe(response);
            };
            commands.Add(newCommand);

// !promoteEveryone
            newCommand                     = new Command("promoteEveryone");
            newCommand.Type                = CommandType.Operation;
            newCommand.Description         = "Assign everyone a role identified by it's ID. Use the `getRole` command to get the ID.";
            newCommand.ManPage             = new ManPage("<roleID>", "`<roleID>` - Specific Role ID of a role.");
            newCommand.RequiredPermissions = PermissionType.ServerOwner | PermissionType.Admin;
            newCommand.OnExecute          += async e => {
                if (!e.Server.Guild.CurrentUser.GuildPermissions.ManageRoles)
                {
                    await e.SendReplySafe(ErrorPermissionsString);

                    return;
                }

                SocketRole role = null;
                if (string.IsNullOrEmpty(e.TrimmedMessage) ||
                    !guid.TryParse(e.TrimmedMessage, out guid id) || id < int.MaxValue ||
                    (role = e.Server.Guild.Roles.FirstOrDefault(r => r.Id == id)) == null)
                {
                    await e.SendReplySafe(ErrorRoleNotFoundId);

                    return;
                }

                await e.SendReplySafe(PromoteEveryoneResponseString);

                await e.Server.Guild.DownloadUsersAsync();

                List <SocketGuildUser> users = e.Server.Guild.Users.ToList();

                int  i          = 0;
                int  count      = 0;
                int  exceptions = 0;
                bool canceled   = await e.Operation.While(() => i < users.Count, async() => {
                    try
                    {
                        SocketGuildUser user = users[i++];
                        if (user.Roles.Any(r => r.Id == role.Id))
                        {
                            return(false);
                        }

                        await user.AddRoleAsync(role);
                        count++;
                    }
                    catch (Exception)
                    {
                        if (++exceptions > 10)
                        {
                            return(true);
                        }
                    }

                    return(false);
                });

                if (canceled)
                {
                    return;
                }

                string response = exceptions > 10 ? ErrorPromoteEveryone : ($"Done! I've assigned `{role.Name}` to `{count}` member" + (count != 1 ? "s." : "."));
                await e.SendReplySafe(response);
            };
            commands.Add(newCommand);

// !demoteEveryone
            newCommand                     = new Command("demoteEveryone");
            newCommand.Type                = CommandType.Operation;
            newCommand.Description         = "Remove a role from everyone, identified by roleID. Use the `getRole` command to get the ID.";
            newCommand.ManPage             = new ManPage("<roleID>", "`<roleID>` - Specific Role ID of a role.");
            newCommand.RequiredPermissions = PermissionType.ServerOwner | PermissionType.Admin;
            newCommand.OnExecute          += async e => {
                if (!e.Server.Guild.CurrentUser.GuildPermissions.ManageRoles)
                {
                    await e.SendReplySafe(ErrorPermissionsString);

                    return;
                }

                SocketRole role = null;
                if (string.IsNullOrEmpty(e.TrimmedMessage) ||
                    !guid.TryParse(e.TrimmedMessage, out guid id) || id < int.MaxValue ||
                    (role = e.Server.Guild.Roles.FirstOrDefault(r => r.Id == id)) == null)
                {
                    await e.SendReplySafe(ErrorRoleNotFoundId);

                    return;
                }

                await e.SendReplySafe(DemoteEveryoneResponseString);

                await e.Server.Guild.DownloadUsersAsync();

                List <SocketGuildUser> users = e.Server.Guild.Users.ToList();

                int  i          = 0;
                int  count      = 0;
                int  exceptions = 0;
                bool canceled   = await e.Operation.While(() => i < users.Count, async() => {
                    try
                    {
                        SocketGuildUser user = users[i++];
                        if (!user.Roles.Any(r => r.Id == role.Id))
                        {
                            return(false);
                        }

                        await user.RemoveRoleAsync(role);
                        count++;
                    }
                    catch (Exception)
                    {
                        if (++exceptions > 10)
                        {
                            return(true);
                        }
                    }

                    return(false);
                });

                if (canceled)
                {
                    return;
                }

                string response = exceptions > 10 ? ErrorDemoteEveryone : ($"Done! I've removed `{role.Name}` from `{count}` member" + (count != 1 ? "s." : "."));
                await e.SendReplySafe(response);
            };
            commands.Add(newCommand);

// !countWithoutRoles
            newCommand                     = new Command("countWithoutRoles");
            newCommand.Type                = CommandType.Standard;
            newCommand.Description         = "Count how many users do not have any role.";
            newCommand.ManPage             = new ManPage("", "");
            newCommand.RequiredPermissions = PermissionType.ServerOwner | PermissionType.Admin;
            newCommand.OnExecute          += async e => {
                await e.SendReplySafe(WorkingOnItString);

                await e.Server.Guild.DownloadUsersAsync();

                int count = e.Server.Guild.Users.Count(u => !u.IsBot && u.Roles.All(r => r.Id == e.Server.Id));
                await e.SendReplySafe(string.Format(FoundCountString, count));
            };
            commands.Add(newCommand);

// !kickWithoutRoles
            newCommand                     = new Command("kickWithoutRoles");
            newCommand.Type                = CommandType.Operation;
            newCommand.Description         = "Kick all the users who do not have any role.";
            newCommand.ManPage             = new ManPage("", "");
            newCommand.RequiredPermissions = PermissionType.ServerOwner;
            newCommand.OnExecute          += async e => {
                if (!e.Server.Guild.CurrentUser.GuildPermissions.KickMembers)
                {
                    await e.SendReplySafe(ErrorPermissionsString);

                    return;
                }

                await e.SendReplySafe(WorkingOnItString);

                await e.Server.Guild.DownloadUsersAsync();

                List <SocketGuildUser> users = e.Server.Guild.Users.ToList();

                int  i          = 0;
                int  count      = 0;
                int  exceptions = 0;
                bool canceled   = await e.Operation.While(() => i < users.Count, async() => {
                    try
                    {
                        SocketGuildUser user = users[i++];
                        if (user.IsBot || e.Server.Guild.OwnerId == user.Id || user.Roles.Any(r => r.Id != e.Server.Id))
                        {
                            return(false);
                        }

                        await user.KickAsync();
                        count++;
                    }
                    catch (Exception)
                    {
                        if (++exceptions > 10)
                        {
                            return(true);
                        }
                    }

                    return(false);
                });

                if (canceled)
                {
                    return;
                }

                string response = exceptions > 10 ? ErrorKickWithoutRole : $"Done! I've kicked `{count}` members who had no roles! You know what to press to pay respects!";
                await e.SendReplySafe(response);
            };
            commands.Add(newCommand);


            return(commands);
        }
Beispiel #6
0
        public List <Command> Init(IBotwinderClient iClient)
        {
            this.Client = iClient as BotwinderClient;
            List <Command> commands = new List <Command>();

            this.Client.Events.UserJoined += OnUserJoined;

// !getRole
            Command newCommand = new Command("getRole");

            newCommand.Type                = CommandType.Standard;
            newCommand.Description         = "Get a name, id and color of `roleID` or `roleName` parameter.";
            newCommand.RequiredPermissions = PermissionType.ServerOwner | PermissionType.Admin;
            newCommand.OnExecute          += async e => {
                guid              id         = 0;
                SocketRole        roleFromId = null;
                List <SocketRole> roles      = null;
                if (string.IsNullOrEmpty(e.TrimmedMessage) ||
                    (!(guid.TryParse(e.TrimmedMessage, out id) && (roleFromId = e.Server.Guild.GetRole(id)) != null) &&
                     !(roles = e.Server.Guild.Roles.Where(r => r.Name.ToLower().Contains(e.TrimmedMessage.ToLower())).ToList()).Any()))
                {
                    await e.SendReplySafe("Role not found.");

                    return;
                }

                if (roleFromId != null)
                {
                    roles = new List <SocketRole>();
                    roles.Add(roleFromId);
                }

                StringBuilder response = new StringBuilder();
                foreach (SocketRole role in roles)
                {
                    string hex = BitConverter.ToString(new byte[] { role.Color.R, role.Color.G, role.Color.B }).Replace("-", "");
                    response.AppendLine($"Role: `{role.Name}`\n  Id: `{role.Id}`\n  Position: `{role.Position}`\n  Color: `rgb({role.Color.R},{role.Color.G},{role.Color.B})` | `hex(#{hex})`");
                }

                await e.SendReplySafe(response.ToString());
            };
            commands.Add(newCommand);
            commands.Add(newCommand.CreateAlias("getrole"));

// !membersOf
            newCommand                     = new Command("membersOf");
            newCommand.Type                = CommandType.Standard;
            newCommand.Description         = "Display a list of members of a role.";
            newCommand.RequiredPermissions = PermissionType.ServerOwner | PermissionType.Admin;
            newCommand.OnExecute          += async e => {
                string expression = e.TrimmedMessage;

                guid id = 0;
                IEnumerable <SocketRole> roles      = e.Server.Guild.Roles;
                IEnumerable <SocketRole> foundRoles = null;
                SocketRole role = null;

                if (!(guid.TryParse(expression, out id) && (role = e.Server.Guild.GetRole(id)) != null) &&
                    !(foundRoles = roles.Where(r => r.Name == expression)).Any() &&
                    !(foundRoles = roles.Where(r => r.Name.ToLower() == expression.ToLower())).Any() &&
                    !(foundRoles = roles.Where(r => r.Name.ToLower().Contains(expression.ToLower()))).Any())
                {
                    await e.SendReplySafe(ErrorRoleNotFound);

                    return;
                }

                if (foundRoles.Count() > 1)
                {
                    await e.SendReplySafe(ErrorTooManyFound);

                    return;
                }

                if (role == null)
                {
                    role = foundRoles.First();
                }

                await e.Server.Guild.DownloadUsersAsync();

                List <string> names = role.Members.Select(u => u.GetUsername()).ToList();
                names.Sort();

                string response = names.Count == 0 ? "Nobody has this role." : $"Members of `{role.Name}` are:\n" + names.ToNamesList();
                await e.SendReplySafe(response);
            };
            commands.Add(newCommand);
            commands.Add(newCommand.CreateAlias("listMembers"));

// !createRole
            newCommand                     = new Command("createRole");
            newCommand.Type                = CommandType.Standard;
            newCommand.Description         = "Create a role with specified name.";
            newCommand.RequiredPermissions = PermissionType.ServerOwner | PermissionType.Admin;
            newCommand.OnExecute          += async e => {
                if (!e.Server.Guild.CurrentUser.GuildPermissions.ManageRoles)
                {
                    await e.Message.Channel.SendMessageSafe(ErrorPermissionsString);

                    return;
                }
                if (string.IsNullOrEmpty(e.TrimmedMessage))
                {
                    await e.SendReplySafe("What role? Name? Do you want me to come up with something silly or what?");

                    return;
                }

                RestRole role = await e.Server.Guild.CreateRoleAsync(e.TrimmedMessage, GuildPermissions.None);

                string response = $"Role created: `{role.Name}`\n  Id: `{role.Id}`";
                await e.SendReplySafe(response);
            };
            commands.Add(newCommand);

// !createTempRole
            newCommand                     = new Command("createTempRole");
            newCommand.Type                = CommandType.Standard;
            newCommand.Description         = "`createTempRole name time` Create a role with specified name, which will be destroyed after specified time (e.g. `7d` or `12h` or `1d12h`)";
            newCommand.RequiredPermissions = PermissionType.ServerOwner | PermissionType.Admin;
            newCommand.OnExecute          += async e => {
                ServerContext dbContext  = ServerContext.Create(this.Client.DbConnectionString);
                RoleConfig    roleConfig = await CreateTempRole(e, dbContext);

                if (roleConfig != null)
                {
                    dbContext.SaveChanges();
                }
                dbContext.Dispose();
            };
            commands.Add(newCommand);

// !createTempPublicRole
            newCommand                     = new Command("createTempPublicRole");
            newCommand.Type                = CommandType.Standard;
            newCommand.Description         = "`createTempRole name time` Create a role with specified name, which will be destroyed after specified time (e.g. `7d` or `12h` or `1d12h`) This role will also become a public - use the `join` command to get it.";
            newCommand.RequiredPermissions = PermissionType.ServerOwner | PermissionType.Admin;
            newCommand.OnExecute          += async e => {
                ServerContext dbContext  = ServerContext.Create(this.Client.DbConnectionString);
                RoleConfig    roleConfig = await CreateTempRole(e, dbContext);

                if (roleConfig != null)
                {
                    roleConfig.PermissionLevel = RolePermissionLevel.Public;
                    dbContext.SaveChanges();
                }
                dbContext.Dispose();
            };
            commands.Add(newCommand);

// !publicRoles
            newCommand                     = new Command("publicRoles");
            newCommand.Type                = CommandType.Standard;
            newCommand.Description         = "See what Public Roles can you join on this server.";
            newCommand.RequiredPermissions = PermissionType.Everyone;
            newCommand.OnExecute          += async e => {
                List <RoleConfig> publicRoles = e.Server.Roles.Values.Where(r => r.PermissionLevel == RolePermissionLevel.Public).ToList();
                if (publicRoles == null || publicRoles.Count == 0)
                {
                    await e.SendReplySafe(ErrorNoPublicRoles);

                    return;
                }

                ServerContext dbContext       = ServerContext.Create(this.Client.DbConnectionString);
                StringBuilder responseBuilder = new StringBuilder(string.Format("You can use `{0}join` and `{0}leave` commands with these Public Roles: ", e.Server.Config.CommandPrefix));
                Dictionary <Int64, List <RoleConfig> > groupRoles   = new Dictionary <Int64, List <RoleConfig> >();
                Dictionary <Int64, RoleGroupConfig>    groupConfigs = dbContext.PublicRoleGroups.Where(g => g.ServerId == e.Server.Id).ToDictionary(g => g.GroupId);
                dbContext.Dispose();

                foreach (RoleConfig roleConfig in publicRoles)
                {
                    SocketRole role = e.Server.Guild.GetRole(roleConfig.RoleId);
                    if (role == null)
                    {
                        continue;
                    }

                    if (!groupRoles.ContainsKey(roleConfig.PublicRoleGroupId))
                    {
                        List <RoleConfig> tempGroup = publicRoles.Where(r => r.PublicRoleGroupId == roleConfig.PublicRoleGroupId).ToList();
                        groupRoles.Add(roleConfig.PublicRoleGroupId, tempGroup);
                    }
                }

                string GetRoleNames(List <RoleConfig> roleConfigs)
                {
                    return(e.Server.Guild.Roles.Where(r => roleConfigs.Any(rc => rc.RoleId == r.Id))
                           .Select(r => r.Name).ToNames());
                }

                if (groupRoles.ContainsKey(0))
                {
                    responseBuilder.Append(GetRoleNames(groupRoles[0]));
                }

                foreach (KeyValuePair <Int64, List <RoleConfig> > groupRole in groupRoles)
                {
                    if (groupRole.Key == 0)
                    {
                        continue;
                    }

                    RoleGroupConfig groupConfig = groupConfigs.ContainsKey(groupRole.Key) ? groupConfigs[groupRole.Key] : new RoleGroupConfig();
                    string          name        = string.IsNullOrEmpty(groupConfig.Name) ? ("Group #" + groupRole.Key.ToString()) : groupConfig.Name;
                    responseBuilder.Append($"\n\n**{name}** - you can join {groupConfig.RoleLimit} of these:\n");

                    responseBuilder.Append(GetRoleNames(groupRole.Value));
                }

                await e.SendReplySafe(responseBuilder.ToString());
            };
            commands.Add(newCommand);

// !roleCounts
            newCommand                     = new Command("roleCounts");
            newCommand.Type                = CommandType.Standard;
            newCommand.Description         = "Get some numbers about public roles for specific group.";
            newCommand.RequiredPermissions = PermissionType.Everyone;
            newCommand.OnExecute          += async e => {
                string expression = e.TrimmedMessage;

                ServerContext dbContext = ServerContext.Create(this.Client.DbConnectionString);
                IEnumerable <RoleGroupConfig> roleGroups  = dbContext.PublicRoleGroups.Where(g => g.ServerId == e.Server.Id);
                IEnumerable <RoleGroupConfig> foundGroups = null;

                if (string.IsNullOrEmpty(expression) || (
                        !(foundGroups = roleGroups.Where(g => g.Name == expression)).Any() &&
                        !(foundGroups = roleGroups.Where(g => (g.Name?.ToLower() ?? "") == expression.ToLower())).Any() &&
                        !(foundGroups = roleGroups.Where(g => g.Name?.ToLower().Contains(expression.ToLower()) ?? false)).Any()))
                {
                    await e.SendReplySafe(ErrorGroupNotFound);

                    dbContext.Dispose();
                    return;
                }

                if (foundGroups.Count() > 1)
                {
                    await e.SendReplySafe(ErrorTooManyGroupsFound);

                    dbContext.Dispose();
                    return;
                }

                await e.Server.Guild.DownloadUsersAsync();

                Int64 groupId = foundGroups.First().GroupId;
                dbContext.Dispose();

                IEnumerable <guid>       roleIds  = e.Server.Roles.Values.Where(r => r.PublicRoleGroupId == groupId).Select(r => r.RoleId);
                IEnumerable <SocketRole> roles    = e.Server.Guild.Roles.Where(r => roleIds.Contains(r.Id));
                StringBuilder            response = new StringBuilder();
                foreach (SocketRole role in roles)
                {
                    response.AppendLine($"**{role.Name}**: `{role.Members.Count()}`");
                }

                await e.SendReplySafe(response.ToString());
            };
            commands.Add(newCommand);
            commands.Add(newCommand.CreateAlias("countGroup"));
            commands.Add(newCommand.CreateAlias("countRoles"));

// !join
            newCommand                     = new Command("join");
            newCommand.Type                = CommandType.Standard;
            newCommand.Description         = "Use with parameter, name of a Role that you wish to join.";
            newCommand.RequiredPermissions = PermissionType.Everyone;
            newCommand.OnExecute          += async e => {
                if (!e.Server.Guild.CurrentUser.GuildPermissions.ManageRoles)
                {
                    await e.SendReplySafe(ErrorPermissionsString);

                    return;
                }

                if (string.IsNullOrEmpty(e.TrimmedMessage))
                {
                    await e.SendReplyUnsafe(e.Command.Description);

                    return;
                }

                List <RoleConfig> publicRoles = e.Server.Roles.Values.Where(r => r.PermissionLevel == RolePermissionLevel.Public).ToList();
                if (publicRoles == null || publicRoles.Count == 0)
                {
                    await e.SendReplySafe(ErrorNoPublicRoles);

                    return;
                }

                IEnumerable <SocketRole> roles      = e.Server.Guild.Roles.Where(r => publicRoles.Any(rc => rc.RoleId == r.Id));
                IEnumerable <SocketRole> foundRoles = null;
                if (!(foundRoles = roles.Where(r => r.Name == e.TrimmedMessage)).Any() &&
                    !(foundRoles = roles.Where(r => r.Name.ToLower() == e.TrimmedMessage.ToLower())).Any() &&
                    !(foundRoles = roles.Where(r => r.Name.ToLower().Contains(e.TrimmedMessage.ToLower()))).Any())
                {
                    await e.SendReplyUnsafe(ErrorRoleNotFound);

                    return;
                }

                if (foundRoles.Count() > 1)
                {
                    await e.SendReplyUnsafe(ErrorTooManyFound);

                    return;
                }

                RoleGroupConfig    groupConfig  = null;
                IEnumerable <guid> groupRoleIds = null;
                SocketRole         roleToAssign = foundRoles.First();
                Int64 groupId = publicRoles.First(r => r.RoleId == roleToAssign.Id).PublicRoleGroupId;

                if (groupId != 0)
                {
                    groupRoleIds = publicRoles.Where(r => r.PublicRoleGroupId == groupId).Select(r => r.RoleId);
                    int userHasCount = (e.Message.Author as SocketGuildUser).Roles.Count(r => groupRoleIds.Any(id => id == r.Id));

                    if (userHasCount > 0)
                    {
                        ServerContext dbContext = ServerContext.Create(this.Client.DbConnectionString);
                        groupConfig = dbContext.PublicRoleGroups.FirstOrDefault(g => g.ServerId == e.Server.Id && g.GroupId == groupId);
                        dbContext.Dispose();

                        if (groupConfig != null && groupConfig.RoleLimit > 1 && userHasCount >= groupConfig.RoleLimit)
                        {
                            await e.SendReplyUnsafe($"You can only have {groupConfig.RoleLimit} roles from the `{groupConfig.Name}` group.");

                            return;
                        }
                    }
                }

                bool   removed  = false;
                string response = "Done!";
                try
                {
                    SocketGuildUser user = (e.Message.Author as SocketGuildUser);

                    if (groupRoleIds != null && (groupConfig == null || groupConfig.RoleLimit == 1))
                    {
                        foreach (guid id in groupRoleIds)
                        {
                            if (user.Roles.All(r => r.Id != id))
                            {
                                continue;
                            }

                            SocketRole roleToLeave = e.Server.Guild.GetRole(id);
                            if (roleToLeave == null)
                            {
                                continue;
                            }

                            await user.RemoveRoleAsync(roleToLeave);

                            removed = true;
                        }
                    }

                    await user.AddRoleAsync(roleToAssign);
                } catch (Exception exception)
                {
                    if (exception is Discord.Net.HttpException ex && ex.HttpCode == System.Net.HttpStatusCode.Forbidden ||
                        exception.Message.Contains("Missing Access"))
                    {
                        response = "Something went wrong, I may not have server permissions to do that.\n(Hint: <http://i.imgur.com/T8MPvME.png>)";
                    }
Beispiel #7
0
        public List <Command> Init(IBotwinderClient iClient)
        {
            this.Client = iClient as BotwinderClient;
            List <Command> commands = new List <Command>();

            this.Client.Events.UserJoined      += OnUserJoined;
            this.Client.Events.ReactionAdded   += OnReactionAdded;
            this.Client.Events.ReactionRemoved += OnReactionRemoved;

// !publicRoles
            Command newCommand = new Command("publicRoles");

            newCommand.Type                = CommandType.Standard;
            newCommand.Description         = "See what Public Roles can you join on this server.";
            newCommand.RequiredPermissions = PermissionType.Everyone;
            newCommand.OnExecute          += async e => {
                List <RoleConfig> publicRoles = e.Server.Roles.Values.Where(r => r.PermissionLevel == RolePermissionLevel.Public).ToList();
                if (publicRoles == null || publicRoles.Count == 0)
                {
                    await e.SendReplySafe(ErrorNoPublicRoles);

                    return;
                }

                ServerContext dbContext       = ServerContext.Create(this.Client.DbConnectionString);
                StringBuilder responseBuilder = new StringBuilder(string.Format("You can use `{0}join` and `{0}leave` commands with these Public Roles: ", e.Server.Config.CommandPrefix));
                Dictionary <Int64, List <RoleConfig> > groupRoles   = new Dictionary <Int64, List <RoleConfig> >();
                Dictionary <Int64, RoleGroupConfig>    groupConfigs = dbContext.PublicRoleGroups.Where(g => g.ServerId == e.Server.Id).ToDictionary(g => g.GroupId);
                dbContext.Dispose();

                foreach (RoleConfig roleConfig in publicRoles)
                {
                    SocketRole role = e.Server.Guild.GetRole(roleConfig.RoleId);
                    if (role == null)
                    {
                        continue;
                    }

                    if (!groupRoles.ContainsKey(roleConfig.PublicRoleGroupId))
                    {
                        List <RoleConfig> tempGroup = publicRoles.Where(r => r.PublicRoleGroupId == roleConfig.PublicRoleGroupId).ToList();
                        groupRoles.Add(roleConfig.PublicRoleGroupId, tempGroup);
                    }
                }

                string GetRoleNames(List <RoleConfig> roleConfigs)
                {
                    return(e.Server.Guild.Roles.Where(r => roleConfigs.Any(rc => rc.RoleId == r.Id))
                           .Select(r => r.Name).ToNames());
                }

                if (groupRoles.ContainsKey(0))
                {
                    responseBuilder.Append(GetRoleNames(groupRoles[0]));
                }

                foreach (KeyValuePair <Int64, List <RoleConfig> > groupRole in groupRoles)
                {
                    if (groupRole.Key == 0)
                    {
                        continue;
                    }

                    RoleGroupConfig groupConfig = groupConfigs.ContainsKey(groupRole.Key) ? groupConfigs[groupRole.Key] : new RoleGroupConfig();
                    string          name        = string.IsNullOrEmpty(groupConfig.Name) ? ("Group #" + groupRole.Key.ToString()) : groupConfig.Name;
                    responseBuilder.Append($"\n\n**{name}** - you can join {groupConfig.RoleLimit} of these:\n");

                    responseBuilder.Append(GetRoleNames(groupRole.Value));
                }

                await e.SendReplySafe(responseBuilder.ToString());
            };
            commands.Add(newCommand);

// !roleCounts
            newCommand                     = new Command("roleCounts");
            newCommand.Type                = CommandType.Standard;
            newCommand.Description         = "Get some numbers about public roles for specific group.";
            newCommand.RequiredPermissions = PermissionType.Everyone;
            newCommand.OnExecute          += async e => {
                string expression = e.TrimmedMessage;

                ServerContext dbContext = ServerContext.Create(this.Client.DbConnectionString);
                IEnumerable <RoleGroupConfig> roleGroups  = dbContext.PublicRoleGroups.Where(g => g.ServerId == e.Server.Id);
                IEnumerable <RoleGroupConfig> foundGroups = null;

                if (string.IsNullOrEmpty(expression) || (
                        !(foundGroups = roleGroups.Where(g => g.Name == expression)).Any() &&
                        !(foundGroups = roleGroups.Where(g => (g.Name?.ToLower() ?? "") == expression.ToLower())).Any() &&
                        !(foundGroups = roleGroups.Where(g => g.Name?.ToLower().Contains(expression.ToLower()) ?? false)).Any()))
                {
                    await e.SendReplySafe(ErrorGroupNotFound);

                    dbContext.Dispose();
                    return;
                }

                if (foundGroups.Count() > 1)
                {
                    await e.SendReplySafe(ErrorTooManyGroupsFound);

                    dbContext.Dispose();
                    return;
                }

                await e.Server.Guild.DownloadUsersAsync();

                Int64 groupId = foundGroups.First().GroupId;
                dbContext.Dispose();

                IEnumerable <guid>       roleIds  = e.Server.Roles.Values.Where(r => r.PublicRoleGroupId == groupId).Select(r => r.RoleId);
                IEnumerable <SocketRole> roles    = e.Server.Guild.Roles.Where(r => roleIds.Contains(r.Id));
                StringBuilder            response = new StringBuilder();
                foreach (SocketRole role in roles)
                {
                    response.AppendLine($"**{role.Name}**: `{role.Members.Count()}`");
                }

                await e.SendReplySafe(response.ToString());
            };
            commands.Add(newCommand);
            commands.Add(newCommand.CreateAlias("countGroup"));
            commands.Add(newCommand.CreateAlias("countRoles"));

// !join
            newCommand                     = new Command("join");
            newCommand.Type                = CommandType.Standard;
            newCommand.Description         = "Use with parameter, name of a Role that you wish to join.";
            newCommand.RequiredPermissions = PermissionType.Everyone;
            newCommand.OnExecute          += async e => {
                if (!e.Server.Guild.CurrentUser.GuildPermissions.ManageRoles)
                {
                    await e.SendReplySafe(ErrorPermissionsString);

                    return;
                }

                if (string.IsNullOrEmpty(e.TrimmedMessage))
                {
                    await e.SendReplyUnsafe(e.Command.Description);

                    return;
                }

                List <RoleConfig> publicRoles = e.Server.Roles.Values.Where(r => r.PermissionLevel == RolePermissionLevel.Public).ToList();
                if (publicRoles == null || publicRoles.Count == 0)
                {
                    await e.SendReplySafe(ErrorNoPublicRoles);

                    return;
                }

                IEnumerable <SocketRole> roles      = e.Server.Guild.Roles.Where(r => publicRoles.Any(rc => rc.RoleId == r.Id));
                IEnumerable <SocketRole> foundRoles = null;
                if (!(foundRoles = roles.Where(r => r.Name == e.TrimmedMessage)).Any() &&
                    !(foundRoles = roles.Where(r => r.Name.ToLower() == e.TrimmedMessage.ToLower())).Any() &&
                    !(foundRoles = roles.Where(r => r.Name.ToLower().Contains(e.TrimmedMessage.ToLower()))).Any())
                {
                    await e.SendReplyUnsafe(ErrorRoleNotFound);

                    return;
                }

                if (foundRoles.Count() > 1)
                {
                    await e.SendReplyUnsafe(ErrorTooManyFound);

                    return;
                }

                RoleGroupConfig    groupConfig  = null;
                IEnumerable <guid> groupRoleIds = null;
                SocketRole         roleToAssign = foundRoles.First();
                Int64 groupId = publicRoles.First(r => r.RoleId == roleToAssign.Id).PublicRoleGroupId;

                if (groupId != 0)
                {
                    groupRoleIds = publicRoles.Where(r => r.PublicRoleGroupId == groupId).Select(r => r.RoleId);
                    int userHasCount = (e.Message.Author as SocketGuildUser).Roles.Count(r => groupRoleIds.Any(id => id == r.Id));

                    if (userHasCount > 0)
                    {
                        ServerContext dbContext = ServerContext.Create(this.Client.DbConnectionString);
                        groupConfig = dbContext.PublicRoleGroups.FirstOrDefault(g => g.ServerId == e.Server.Id && g.GroupId == groupId);
                        dbContext.Dispose();

                        if (groupConfig != null && groupConfig.RoleLimit > 1 && userHasCount >= groupConfig.RoleLimit)
                        {
                            await e.SendReplyUnsafe($"You can only have {groupConfig.RoleLimit} roles from the `{groupConfig.Name}` group.");

                            return;
                        }
                    }
                }

                bool   removed  = false;
                string response = "Done!";
                try
                {
                    SocketGuildUser user = (e.Message.Author as SocketGuildUser);

                    if (groupRoleIds != null && (groupConfig == null || groupConfig.RoleLimit == 1))
                    {
                        foreach (guid id in groupRoleIds)
                        {
                            if (user.Roles.All(r => r.Id != id))
                            {
                                continue;
                            }

                            SocketRole roleToLeave = e.Server.Guild.GetRole(id);
                            if (roleToLeave == null)
                            {
                                continue;
                            }

                            await user.RemoveRoleAsync(roleToLeave);

                            removed = true;
                        }
                    }

                    await user.AddRoleAsync(roleToAssign);
                } catch (Exception exception)
                {
                    if (exception is Discord.Net.HttpException ex && (ex.HttpCode == System.Net.HttpStatusCode.Forbidden || (ex.DiscordCode.HasValue && ex.DiscordCode.Value == 50013) || exception.Message.Contains("Missing Access") || exception.Message.Contains("Missing Permissions")))
                    {
                        response = "Something went wrong, I may not have server permissions to do that.\n(Hint: <http://i.imgur.com/T8MPvME.png>)";
                    }
Beispiel #8
0
        public List <Command> Init(IValkyrjaClient iClient)
        {
            this.Client = iClient as ValkyrjaClient;
            List <Command> commands = new List <Command>();

// !restrictAlert
            Command newCommand = new Command("restrictAlert");

            newCommand.Type                = CommandType.Standard;
            newCommand.Description         = "Restrict alert logging to search only one channel. Use with `set #channel` or `reset` argument.";
            newCommand.RequiredPermissions = PermissionType.ServerOwner | PermissionType.Admin;
            newCommand.ManPage             = new ManPage("<set #channel | reset>", "`<set #channel>` - Restrict the alert-logging to keep an eye only on this specific #channel.\n\n`<reset>` - Reset the restriction, alert-logging will keep an eye on all the channels.");
            newCommand.OnExecute          += async e => {
                string        response  = "";
                ServerContext dbContext = ServerContext.Create(this.Client.DbConnectionString);
                ServerConfig  config    = dbContext.ServerConfigurations.AsQueryable().FirstOrDefault(c => c.ServerId == e.Server.Id);
                if (string.IsNullOrEmpty(e.TrimmedMessage))
                {
                    response = "Invalid arguments.\n" + e.Command.ManPage.ToString(e.Server.Config.CommandPrefix + e.CommandId);
                }
                else if (config == null)
                {
                    response = "Server config was not found in the database. Please try again in a few minutes or contact support.";
                }
                else if (e.MessageArgs[0].ToLower() == "reset")
                {
                    config.AlertWhitelistId = 0;
                    response = "Done.";
                    dbContext.SaveChanges();
                }
                else if (e.MessageArgs.Length != 2 || e.MessageArgs[0].ToLower() != "set")
                {
                    response = "Invalid arguments.\n" + e.Command.ManPage.ToString(e.Server.Config.CommandPrefix + e.CommandId);
                }
                else if (e.MessageArgs.Length == 2 && guid.TryParse(e.MessageArgs[1].Trim('<', '#', '>'), out ulong channelid) && e.Server.Guild.GetChannel(channelid) != null)
                {
                    config.AlertWhitelistId = channelid;
                    response = "Done.";
                    dbContext.SaveChanges();
                }
                else
                {
                    response = "Channel not found.";
                }

                dbContext.Dispose();
                await e.SendReplySafe(response);
            };
            commands.Add(newCommand);

// !getRole
            newCommand                     = new Command("getRole");
            newCommand.Type                = CommandType.Standard;
            newCommand.Description         = "Get a name, id and color of `roleID` or `roleName` parameter.";
            newCommand.ManPage             = new ManPage("<RoleId | roleName>", "`<RoleId | roleName>` - Role to be displayed.");
            newCommand.RequiredPermissions = PermissionType.ServerOwner | PermissionType.Admin;
            newCommand.OnExecute          += async e => {
                guid              id         = 0;
                SocketRole        roleFromId = null;
                List <SocketRole> roles      = null;
                if (string.IsNullOrEmpty(e.TrimmedMessage) ||
                    (!(guid.TryParse(e.TrimmedMessage, out id) && (roleFromId = e.Server.Guild.GetRole(id)) != null) &&
                     !(roles = e.Server.Guild.Roles.Where(r => r.Name.ToLower().Contains(e.TrimmedMessage.ToLower())).ToList()).Any()))
                {
                    await e.SendReplySafe("Role not found.");

                    return;
                }

                if (roleFromId != null)
                {
                    roles = new List <SocketRole>();
                    roles.Add(roleFromId);
                }

                StringBuilder response = new StringBuilder();
                foreach (SocketRole role in roles)
                {
                    string hex = BitConverter.ToString(new byte[] { role.Color.R, role.Color.G, role.Color.B }).Replace("-", "");
                    response.AppendLine($"Role: `{role.Name}`\n  Id: `{role.Id}`\n  Position: `{role.Position}`\n  Color: `rgb({role.Color.R},{role.Color.G},{role.Color.B})` | `hex(#{hex})`");
                }

                await e.SendReplySafe(response.ToString());
            };
            commands.Add(newCommand);

// !membersOf
            newCommand                     = new Command("membersOf");
            newCommand.Type                = CommandType.Standard;
            newCommand.Description         = "Display a list of members of a role.";
            newCommand.ManPage             = new ManPage("<RoleId | roleName>", "`<RoleId | roleName>` - Members of this role will be printed.");
            newCommand.RequiredPermissions = PermissionType.ServerOwner | PermissionType.Admin;
            newCommand.OnExecute          += async e => {
                SocketRole role = e.Server.GetRole(e.TrimmedMessage, out string response);
                if (role == null)
                {
                    await e.SendReplySafe(response);

                    return;
                }

                await e.Server.Guild.DownloadUsersAsync();

                List <string> names = role.Members.Select(u => u.GetUsername()).ToList();
                names.Sort();

                response = names.Count == 0 ? "Nobody has this role." : $"Members of `{role.Name}` are:\n" + names.ToNamesList();
                await e.SendReplySafe(response);
            };
            commands.Add(newCommand);
            commands.Add(newCommand.CreateAlias("listMembers"));

// !createRole
            newCommand                     = new Command("createRole");
            newCommand.Type                = CommandType.Standard;
            newCommand.Description         = "Create a role with specified name.";
            newCommand.ManPage             = new ManPage("<roleName>", "`<roleName>` - Name of the new role.");
            newCommand.RequiredPermissions = PermissionType.ServerOwner | PermissionType.Admin;
            newCommand.OnExecute          += async e => {
                if (!e.Server.Guild.CurrentUser.GuildPermissions.ManageRoles)
                {
                    await e.Message.Channel.SendMessageSafe(ErrorPermissionsString);

                    return;
                }
                if (string.IsNullOrEmpty(e.TrimmedMessage))
                {
                    await e.SendReplySafe("What role? Name? Do you want me to come up with something silly or what?");

                    return;
                }

                RestRole role = await e.Server.Guild.CreateRoleAsync(e.TrimmedMessage, GuildPermissions.None);

                string response = $"Role created: `{role.Name}`\n  Id: `{role.Id}`";
                await e.SendReplySafe(response);
            };
            commands.Add(newCommand);

// !createRoles
            newCommand                     = new Command("createRoles");
            newCommand.Type                = CommandType.Standard;
            newCommand.Description         = "Create roles with specified names.";
            newCommand.ManPage             = new ManPage("<roleName1, roleName2, ...>", "`<roleName>` - Name of the new role. Use quotes if you want a name with multiple words/spaces.");
            newCommand.RequiredPermissions = PermissionType.ServerOwner | PermissionType.Admin;
            newCommand.OnExecute          += async e => {
                if (!e.Server.Guild.CurrentUser.GuildPermissions.ManageRoles)
                {
                    await e.Message.Channel.SendMessageSafe(ErrorPermissionsString);

                    return;
                }
                if (string.IsNullOrEmpty(e.TrimmedMessage))
                {
                    await e.SendReplySafe("Invalid arguments.\n" + e.Command.ManPage.ToString(e.Server.Config.CommandPrefix + e.CommandId));

                    return;
                }

                StringBuilder response = new StringBuilder("Roles created:\n");

                for (int i = 0; i < e.MessageArgs.Length; i++)
                {
                    RestRole role = await e.Server.Guild.CreateRoleAsync(e.MessageArgs[i], GuildPermissions.None);

                    response.AppendLine($"`{role.Id}` | `{role.Name}`");
                }

                await e.SendReplySafe(response.ToString());
            };
            commands.Add(newCommand);

// !createPublicRoles
            newCommand                     = new Command("createPublicRoles");
            newCommand.Type                = CommandType.Standard;
            newCommand.Description         = "Create public roles with specified names.";
            newCommand.ManPage             = new ManPage("<groupName> <roleName1, roleName2, ...>", "`<groupName>` - Name of the Role Group under which these roles will be created.\n\n`<roleName>` - Name of the new role. Use quotes if you want a name with multiple words/spaces.");
            newCommand.RequiredPermissions = PermissionType.ServerOwner | PermissionType.Admin;
            newCommand.OnExecute          += async e => {
                if (!e.Server.Guild.CurrentUser.GuildPermissions.ManageRoles)
                {
                    await e.Message.Channel.SendMessageSafe(ErrorPermissionsString);

                    return;
                }
                if (e.MessageArgs == null || e.MessageArgs.Length < 2)
                {
                    await e.SendReplySafe("Invalid arguments.\n" + e.Command.ManPage.ToString(e.Server.Config.CommandPrefix + e.CommandId));

                    return;
                }

                StringBuilder response = new StringBuilder("Roles created:\n");

                Int64         groupId   = 1;
                ServerContext dbContext = ServerContext.Create(this.Client.DbConnectionString);
                IEnumerable <RoleGroupConfig> roleGroups = dbContext.PublicRoleGroups.AsQueryable().Where(g => g.ServerId == e.Server.Id);
                foreach (RoleGroupConfig group in roleGroups)
                {
                    if (groupId < group.GroupId)
                    {
                        groupId = group.GroupId;
                    }
                }

                RoleGroupConfig roleGroup = new RoleGroupConfig()
                {
                    ServerId  = e.Server.Id,
                    GroupId   = groupId,
                    Name      = e.MessageArgs[0],
                    RoleLimit = 1
                };
                dbContext.PublicRoleGroups.Add(roleGroup);

                bool save = true;
                for (int i = 1; i < e.MessageArgs.Length; i++)
                {
                    try
                    {
                        RestRole role = await e.Server.Guild.CreateRoleAsync(e.MessageArgs[i], GuildPermissions.None);

                        RoleConfig roleConfig = new RoleConfig()
                        {
                            ServerId          = e.Server.Id,
                            RoleId            = role.Id,
                            PermissionLevel   = RolePermissionLevel.Public,
                            PublicRoleGroupId = groupId
                        };
                        dbContext.Roles.Add(roleConfig);

                        response.AppendLine($"`{role.Id}` | `{role.Name}`");
                    }
                    catch (Exception)
                    {
                        save = false;
                        response.AppendLine($"__Something went wrong__ :/");
                        break;
                    }
                }

                if (save)
                {
                    dbContext.SaveChanges();
                }
                dbContext.Dispose();

                await e.SendReplySafe(response.ToString());
            };
            commands.Add(newCommand);

// !prune
            newCommand                     = new Command("prune");
            newCommand.Type                = CommandType.Standard;
            newCommand.Description         = "Kicks out all the inactive members.";
            newCommand.ManPage             = new ManPage("<n> [roleIDs] [yes]", "`<n>` - Number of days of user inactivity.\n\n`[roleIDs]` - An optional, whitespace delimited list of role IDs to include in the prune.\n\n`[yes]` - If specified \"yes\" will actually prune, only returns the counts otherwise.");
            newCommand.RequiredPermissions = PermissionType.ServerOwner;
            newCommand.OnExecute          += async e => {
                int n = 0;
                if (e.MessageArgs == null || e.MessageArgs.Length < 1 || !int.TryParse(e.MessageArgs[0], out n))
                {
                    await e.SendReplySafe("Invalid Arguments.\n" + e.Command.ManPage.ToString(e.Server.Config.CommandPrefix + e.CommandId));

                    return;
                }
                bool   prune    = e.MessageArgs.Length > 1 && e.MessageArgs[e.MessageArgs.Length - 1].ToLower() == "yes";
                guid[] roleIDs  = e.MessageArgs.Length > 2 || (!prune && e.MessageArgs.Length > 1) ? e.MessageArgs.Skip(1).TakeWhile(r => guid.TryParse(r, out guid _)).Select(guid.Parse).ToArray() : null;
                string response = "";
                try
                {
                    int count = await e.Server.Guild.PruneUsersAsync(n, !prune, roleIDs);

                    response = prune ? $"I've kicked out `{count}` humans.\n_\\*waves*_" : $"I can kick out `{count}` humans. Should you wish to proceed, append `yes` to the command arguments (you can edit your message) as follows:\n `{e.Server.Config.CommandPrefix + e.CommandId} {e.TrimmedMessage} yes`";
                }
                catch (HttpException exception)
                {
                    await e.Server.HandleHttpException(exception, $"Command failed to prune users in <#{e.Channel.Id}>");

                    response = Utils.HandleHttpException(exception);
                }
                catch (Exception exception)
                {
                    await this.HandleException(exception, "Command prune", e.Server.Id);

                    response = "Unknown error.";
                }

                await e.SendReplySafe(response);
            };
            commands.Add(newCommand);

/*
 * // !createTempRole
 *                      newCommand = new Command("createTempRole");
 *                      newCommand.Type = CommandType.Standard;
 *                      newCommand.Description = "`createTempRole name time` Create a role with specified name, which will be destroyed after specified time (e.g. `7d` or `12h` or `1d12h`)";
 *                      newCommand.RequiredPermissions = PermissionType.ServerOwner | PermissionType.Admin;
 *                      newCommand.OnExecute += async e => {
 *                              ServerContext dbContext = ServerContext.Create(this.Client.DbConnectionString);
 *                              RoleConfig roleConfig = await CreateTempRole(e, dbContext);
 *                              if( roleConfig != null )
 *                                      dbContext.SaveChanges();
 *                              dbContext.Dispose();
 *                      };
 *                      commands.Add(newCommand);
 *
 * // !createTempPublicRole
 *                      newCommand = new Command("createTempPublicRole");
 *                      newCommand.Type = CommandType.Standard;
 *                      newCommand.Description = "`createTempRole name time` Create a role with specified name, which will be destroyed after specified time (e.g. `7d` or `12h` or `1d12h`) This role will also become a public - use the `join` command to get it.";
 *                      newCommand.RequiredPermissions = PermissionType.ServerOwner | PermissionType.Admin;
 *                      newCommand.OnExecute += async e => {
 *                              ServerContext dbContext = ServerContext.Create(this.Client.DbConnectionString);
 *                              RoleConfig roleConfig = await CreateTempRole(e, dbContext);
 *                              if( roleConfig != null )
 *                              {
 *                                      roleConfig.PermissionLevel = RolePermissionLevel.Public;
 *                                      dbContext.SaveChanges();
 *                              }
 *                              dbContext.Dispose();
 *                      };
 *                      commands.Add(newCommand);*/

// !createColourRoles
            newCommand                     = new Command("createColourRoles");
            newCommand.Type                = CommandType.Standard;
            newCommand.Description         = "Create 9 roles with various colours, you can find emoji representations of these colours in Valhalla - the Valkyrja support server.";
            newCommand.ManPage             = new ManPage("", "");
            newCommand.RequiredPermissions = PermissionType.ServerOwner | PermissionType.Admin;
            newCommand.OnExecute          += async e => {
                if (!e.Server.Guild.CurrentUser.GuildPermissions.ManageRoles)
                {
                    await e.SendReplySafe(ErrorPermissionsString);

                    return;
                }

                await e.Server.Guild.CreateRoleAsync("purple", GuildPermissions.None, new Color(180, 136, 209));

                await e.Server.Guild.CreateRoleAsync("pink", GuildPermissions.None, new Color(255, 183, 255));

                await e.Server.Guild.CreateRoleAsync("orange", GuildPermissions.None, new Color(255, 165, 105));

                await e.Server.Guild.CreateRoleAsync("lightOrange", GuildPermissions.None, new Color(255, 186, 158));

                await e.Server.Guild.CreateRoleAsync("lightYellow", GuildPermissions.None, new Color(223, 223, 133));

                await e.Server.Guild.CreateRoleAsync("yellow", GuildPermissions.None, new Color(201, 192, 67));

                await e.Server.Guild.CreateRoleAsync("blue", GuildPermissions.None, new Color(92, 221, 255));

                await e.Server.Guild.CreateRoleAsync("cyan", GuildPermissions.None, new Color(150, 232, 221));

                await e.Server.Guild.CreateRoleAsync("green", GuildPermissions.None, new Color(46, 204, 113));

                await e.SendReplySafe("I've created them roles, but you're gonna have to set them up yourself at <https://valkyrja.app/config> because I don't know the details!\n" +
                                      $"_You can use my colour emojis to set them up as reaction assigned roles. Get them in Valhalla: {GlobalConfig.DiscordInvite}_");
            };
            commands.Add(newCommand);
            commands.Add(newCommand.CreateAlias("createColorRoles"));

// !removeStreamPermission
            newCommand                     = new Command("removeStreamPermission");
            newCommand.Type                = CommandType.Standard;
            newCommand.Description         = "Removes Stream permission from all the roles.";
            newCommand.ManPage             = new ManPage("", "");
            newCommand.RequiredPermissions = PermissionType.ServerOwner | PermissionType.Admin;
            newCommand.OnExecute          += async e => {
                if (!e.Server.Guild.CurrentUser.GuildPermissions.ManageRoles)
                {
                    await e.SendReplySafe("I ain't got the permissions.");

                    return;
                }

                int highestRolePosition = 0;
                foreach (SocketRole role in e.Server.Guild.Roles)
                {
                    if (role.Position > highestRolePosition)
                    {
                        highestRolePosition = role.Position;
                    }
                }

                if (e.Server.Guild.CurrentUser.Hierarchy < highestRolePosition)
                {
                    await e.SendReplySafe("I am not the top role in hierarchy. I really have to be on top to disable that thing on all the roles!");

                    return;
                }

                int    exceptions = 0;
                string response   = "Done with exceptions:\n";
                foreach (SocketRole role in e.Server.Guild.Roles.Where(r => r.Position < e.Server.Guild.CurrentUser.Hierarchy))
                {
                    try
                    {
                        await role.ModifyAsync(r => r.Permissions = new Optional <GuildPermissions>(role.Permissions.Modify(stream: false)));
                    }
                    catch (Exception)
                    {
                        response += $"`{role.Name}`\n";
                        if (++exceptions > 5)
                        {
                            response += "...and probably more...";
                            break;
                        }
                    }
                }

                if (exceptions == 0)
                {
                    response = "Done.";
                }

                await e.SendReplySafe(response);
            };
            commands.Add(newCommand);
            commands.Add(newCommand.CreateAlias("removeGolivePermission"));

            return(commands);
        }