public bool CanRun(Command command, User user, Channel channel, out string error) { error = null; if (channel.IsPrivate) return DefaultPermissionLevel <= DefaultPermChecker.GetPermissionLevel(user, channel); DynPermFullData data = DynPerms.GetPerms(channel.Server.Id); // apply default perms. bool retval = DefaultPermissionLevel <= DefaultPermChecker.GetPermissionLevel(user, channel); // if we do not have dynamic perms in place for the user's server, return the default perms. if (data == null || (!data.Perms.RolePerms.Any() && !data.Perms.UserPerms.Any())) return retval; /* Firsly do role checks. Lower entries override higher entries. To do that we have to iterate over the dict instead of using roles the user has as keys. */ foreach (var pair in data.Perms.RolePerms) { if (user.HasRole(pair.Key)) retval = EvaluatePerms(pair.Value, command, retval, channel, ref error); } // users override roles, do them next. DynamicPermissionBlock permBlock; if (data.Perms.UserPerms.TryGetValue(user.Id, out permBlock)) retval = EvaluatePerms(permBlock, command, retval, channel, ref error); return retval; }
public bool CanRun(Command command, User user, Channel channel, out string error) { error = null; if (channel.IsPrivate) return true; try { //is it a permission command? // if it is, check if the user has the correct role // if yes return true, if no return false if (command.Category == "Permissions") if (user.Server.IsOwner || user.HasRole(PermissionHelper.ValidateRole(user.Server, PermissionsHandler.GetServerPermissionsRoleName(user.Server)))) return true; else throw new Exception($"You don't have the necessary role (**{PermissionsHandler._permissionsDict[user.Server].PermissionsControllerRole}**) to change permissions."); var permissionType = PermissionsHandler.GetPermissionBanType(command, user, channel); string msg; switch (permissionType) { case PermissionsHandler.PermissionBanType.None: return true; case PermissionsHandler.PermissionBanType.ServerBanCommand: msg = $"**{command.Text}** command has been banned from use on this **server**."; break; case PermissionsHandler.PermissionBanType.ServerBanModule: msg = $"**{command.Category}** module has been banned from use on this **server**."; break; case PermissionsHandler.PermissionBanType.ChannelBanCommand: msg = $"**{command.Text}** command has been banned from use on this **channel**."; break; case PermissionsHandler.PermissionBanType.ChannelBanModule: msg = $"**{command.Category}** module has been banned from use on this **channel**."; break; case PermissionsHandler.PermissionBanType.RoleBanCommand: msg = $"You do not have a **role** which permits you the usage of **{command.Text}** command."; break; case PermissionsHandler.PermissionBanType.RoleBanModule: msg = $"You do not have a **role** which permits you the usage of **{command.Category}** module."; break; case PermissionsHandler.PermissionBanType.UserBanCommand: msg = $"{user.Mention}, You have been banned from using **{command.Text}** command."; break; case PermissionsHandler.PermissionBanType.UserBanModule: msg = $"{user.Mention}, You have been banned from using **{command.Category}** module."; break; default: return true; } if (PermissionsHandler._permissionsDict[user.Server].Verbose) //if verbose - print errors Task.Run(() => channel.SendMessage(msg)); return false; } catch (Exception ex) { if (PermissionsHandler._permissionsDict[user.Server].Verbose) //if verbose - print errors Task.Run(() => channel.SendMessage(ex.Message)); return false; } }
public bool CanRun(Command command, User user, Channel channel, out string error) { error = string.Empty; if (user.ServerPermissions.ManageRoles) return true; error = "You do not have a permission to manage roles."; return false; }
public CommandEventArgs(Message message, Command command, string commandText, int? permissions, string[] args) { Message = message; Command = command; CommandText = commandText; Permissions = permissions; Args = args; }
private string PrintCommandHelp(Command com) { var str = "`" + com.Text + "`"; foreach (var a in com.Aliases) str += ", `" + a + "`"; str += " **Description:** " + com.Description + "\n"; return str; }
private bool EvaluatePerms(DynamicPermissionBlock dynPerms, Command command, bool canRunState, Channel channel, ref string error) { string category = command.Category.ToLowerInvariant(); canRunState = EvalPermsExact(dynPerms.Allow.Modules, category, channel, canRunState, true, ref error); canRunState = EvalPermsExact(dynPerms.Deny.Modules, category, channel, canRunState, false, ref error); canRunState = EvalPermsCommands(dynPerms.Allow.Commands, command, channel, canRunState, true, ref error); canRunState = EvalPermsCommands(dynPerms.Deny.Commands, command, channel, canRunState, false, ref error); return canRunState; }
public bool CanRun(Command command, User user, Channel channel, out string error) { if (_filterType == FilterType.Unrestricted || _filterType == FilterType.AllowPrivate || _manager.HasChannel(channel)) { error = null; return true; } else { error = "This module is currently disabled."; return false; } }
internal CommandBuilder(CommandService service, Command command, string prefix = "", string category = "", IEnumerable<IPermissionChecker> initialChecks = null) { _service = service; _command = command; _command.Category = category; _params = new List<CommandParameter>(); if (initialChecks != null) _checks = new List<IPermissionChecker>(initialChecks); else _checks = new List<IPermissionChecker>(); _prefix = prefix; _aliases = new List<string>(); _allowRequiredParams = true; _areParamsClosed = false; }
private bool EvalPermsCommands(Dictionary<string, RestrictionData> dict, Command command, Channel channel, bool canRunState, bool setState, ref string error) { // check if full command exists in dict if (EvalPermsExact(dict, command.Text, channel, canRunState, setState, ref error) == setState) return setState; // check if any alias of command exists in dict foreach (string alias in command.Aliases) if (EvalPermsExact(dict, alias, channel, canRunState, setState, ref error) == setState) return setState; // look for group, don't bother with aliases here or the eval will take too long. foreach (var pair in dict) { if (command.Text.StartsWith(pair.Key) || pair.Key == "*") canRunState = EvalRestrictionData(pair.Value, channel, canRunState, setState, ref error); } return canRunState; }
public async Task CmdCooldown(IUserMessage imsg, Command command, int secs) { var channel = (ITextChannel)imsg.Channel; if (secs < 0 || secs > 3600) { await channel.SendMessageAsync("⚠️ Invalid second parameter. (Must be a number between 0 and 3600)").ConfigureAwait(false); return; } using (var uow = DbHandler.UnitOfWork()) { var config = uow.GuildConfigs.For(channel.Guild.Id); var localSet = commandCooldowns.GetOrAdd(channel.Guild.Id, new ConcurrentHashSet<CommandCooldown>()); config.CommandCooldowns.RemoveWhere(cc => cc.CommandName == command.Text.ToLowerInvariant()); localSet.RemoveWhere(cc => cc.CommandName == command.Text.ToLowerInvariant()); if (secs != 0) { var cc = new CommandCooldown() { CommandName = command.Text.ToLowerInvariant(), Seconds = secs, }; config.CommandCooldowns.Add(cc); localSet.Add(cc); } await uow.CompleteAsync().ConfigureAwait(false); } if (secs == 0) { var activeCds = activeCooldowns.GetOrAdd(channel.Guild.Id, new ConcurrentHashSet<ActiveCooldown>()); activeCds.RemoveWhere(ac => ac.Command == command.Text.ToLowerInvariant()); await channel.SendMessageAsync($"🚮 Command **{command}** has no coooldown now and all existing cooldowns have been cleared.").ConfigureAwait(false); } else await channel.SendMessageAsync($"✅ Command **{command}** now has a **{secs} {(secs == 1 ? "second" : "seconds")}** cooldown.").ConfigureAwait(false); }
public CommandBuilder(Command command) { _command = command; }
internal void AddCommand(Command command) { _allCommands.Add(command); //Get category CommandMap category; string categoryName = command.Category ?? ""; if (!_categories.TryGetValue(categoryName, out category)) { category = new CommandMap(null, "", ""); _categories.Add(categoryName, category); } //Add main command category.AddCommand(command.Text, command, false); _map.AddCommand(command.Text, command, false); //Add aliases foreach (var alias in command.Aliases) { category.AddCommand(alias, command, true); _map.AddCommand(alias, command, true); } }
private void ShowCommandHelpInternal(Command command, User user, Channel channel, StringBuilder output) { output.Append('`'); output.Append(command.Text); foreach (var param in command.Parameters) { switch (param.Type) { case ParameterType.Required: output.Append($" <{param.Name}>"); break; case ParameterType.Optional: output.Append($" [{param.Name}]"); break; case ParameterType.Multiple: output.Append(" [...]"); break; case ParameterType.Unparsed: output.Append(" [--]"); break; } } output.AppendLine("`"); output.AppendLine($"{command.Description ?? "No description."}"); if (command.Aliases.Any()) output.AppendLine($"Aliases: `" + string.Join("`, `", command.Aliases) + '`'); }
public Task ShowCommandHelp(Command command, User user, Channel channel, Channel replyChannel = null) { StringBuilder output = new StringBuilder(); string error; if (!command.CanRun(user, channel, out error)) output.AppendLine(error ?? "You do not have permission to access this command."); else ShowCommandHelpInternal(command, user, channel, output); return (replyChannel ?? channel).SendMessage(output.ToString()); }
public override Task<PreconditionResult> CheckPermissions(IUserMessage context, Command executingCommand, object moduleInstance) => Task.FromResult((NadekoBot.Credentials.IsOwner(context.Author) ? PreconditionResult.FromSuccess() : PreconditionResult.FromError("Not owner")));
public async Task SrvrCmd(IUserMessage imsg, Command command, PermissionAction action) { var channel = (ITextChannel)imsg.Channel; using (var uow = DbHandler.UnitOfWork()) { var newPerm = new Permission { PrimaryTarget = PrimaryPermissionType.Server, PrimaryTargetId = 0, SecondaryTarget = SecondaryPermissionType.Command, SecondaryTargetName = command.Text.ToLowerInvariant(), State = action.Value, }; var config = uow.GuildConfigs.SetNewRootPermission(channel.Guild.Id, newPerm); Cache.AddOrUpdate(channel.Guild.Id, new PermissionCache() { PermRole = config.PermissionRole, RootPermission = config.RootPermission, Verbose = config.VerbosePermissions }, (id, old) => { old.RootPermission = config.RootPermission; return old; }); await uow.CompleteAsync().ConfigureAwait(false); } await channel.SendMessageAsync($"{(action.Value ? "✅ Allowed" : "🆗 Denied")} usage of `{command.Text}` command on this server.").ConfigureAwait(false); }
public async Task ChnlCmd(IUserMessage imsg, Command command, PermissionAction action, [Remainder] ITextChannel chnl) { var channel = (ITextChannel)imsg.Channel; try { using (var uow = DbHandler.UnitOfWork()) { var newPerm = new Permission { PrimaryTarget = PrimaryPermissionType.Channel, PrimaryTargetId = chnl.Id, SecondaryTarget = SecondaryPermissionType.Command, SecondaryTargetName = command.Text.ToLowerInvariant(), State = action.Value, }; var config = uow.GuildConfigs.SetNewRootPermission(channel.Guild.Id, newPerm); Cache.AddOrUpdate(channel.Guild.Id, new PermissionCache() { PermRole = config.PermissionRole, RootPermission = config.RootPermission, Verbose = config.VerbosePermissions }, (id, old) => { old.RootPermission = config.RootPermission; return old; }); await uow.CompleteAsync().ConfigureAwait(false); } } catch (Exception ex) { Console.WriteLine(ex); } await channel.SendMessageAsync($"{(action.Value ? "✅ Allowed" : "🆗 Denied")} usage of `{command.Text}` command for `{chnl}` channel.").ConfigureAwait(false); }
public CommandEventArgs(Message message, Command command, string[] args) { Message = message; Command = command; _args = args; }
public CommandBuilder CreateCommand(string cmd) { var command = new Command(cmd); _commands.Add(command); return new CommandBuilder(command); }
internal void AddCommand(Command command) { _commands.Add(command); }
public CommandBuilder CreateCommand(string cmd) { string text; if (cmd != "") { if (_prefix != "") text = _prefix + ' ' + cmd; else text = cmd; } else { if (_prefix != "") text = _prefix; else throw new ArgumentOutOfRangeException(nameof(cmd)); } var command = new Command(text); command.MinPerms = _defaultMinPermissions; _plugin.AddCommand(command); return new CommandBuilder(command); }
private void AddCommand(int index, string[] parts, Command command, bool isAlias) { if (!command.IsHidden) _isVisible = true; if (index != parts.Length) { CommandMap nextGroup; string name = parts[index].ToLowerInvariant(); string fullName = string.Join(" ", parts, 0, index + 1); if (!_items.TryGetValue(name, out nextGroup)) { nextGroup = new CommandMap(this, name, fullName); _items.Add(name, nextGroup); _hasSubGroups = true; } nextGroup.AddCommand(index + 1, parts, command, isAlias); } else { _commands.Add(command); if (!isAlias) _hasNonAliases = true; } }
//TODO: Check support for escaping public static CommandErrorType? ParseArgs(string input, int startPos, Command command, out string[] args) { ParserPart currentPart = ParserPart.None; int startPosition = startPos; int endPosition = startPos; int inputLength = input.Length; bool isEscaped = false; var expectedArgs = command._parameters; List<string> argList = new List<string>(); CommandParameter parameter = null; args = null; if (input == "") return CommandErrorType.InvalidInput; while (endPosition < inputLength) { if (startPosition == endPosition && (parameter == null || parameter.Type != ParameterType.Multiple)) //Is first char of a new arg { if (argList.Count >= expectedArgs.Length) return CommandErrorType.BadArgCount; //Too many args parameter = expectedArgs[argList.Count]; if (parameter.Type == ParameterType.Unparsed) { argList.Add(input.Substring(startPosition)); break; } } char currentChar = input[endPosition++]; if (isEscaped) isEscaped = false; else if (currentChar == '\\') isEscaped = true; bool isWhitespace = IsWhiteSpace(currentChar); if (endPosition == startPosition + 1 && isWhitespace) //Has no text yet, and is another whitespace { startPosition = endPosition; continue; } switch (currentPart) { case ParserPart.None: if ((!isEscaped && currentChar == '\"')) { currentPart = ParserPart.DoubleQuotedParameter; startPosition = endPosition; } else if ((!isEscaped && currentChar == '\'')) { currentPart = ParserPart.QuotedParameter; startPosition = endPosition; } else if ((!isEscaped && isWhitespace) || endPosition >= inputLength) { int length = (isWhitespace ? endPosition - 1 : endPosition) - startPosition; if (length == 0) startPosition = endPosition; else { string temp = input.Substring(startPosition, length); argList.Add(temp); currentPart = ParserPart.None; startPosition = endPosition; } } break; case ParserPart.QuotedParameter: if ((!isEscaped && currentChar == '\'')) { string temp = input.Substring(startPosition, endPosition - startPosition - 1); argList.Add(temp); currentPart = ParserPart.None; startPosition = endPosition; } else if (endPosition >= inputLength) return CommandErrorType.InvalidInput; break; case ParserPart.DoubleQuotedParameter: if ((!isEscaped && currentChar == '\"')) { string temp = input.Substring(startPosition, endPosition - startPosition - 1); argList.Add(temp); currentPart = ParserPart.None; startPosition = endPosition; } else if (endPosition >= inputLength) return CommandErrorType.InvalidInput; break; } } //Unclosed quotes if (currentPart == ParserPart.QuotedParameter || currentPart == ParserPart.DoubleQuotedParameter) return CommandErrorType.InvalidInput; //Too few args for (int i = argList.Count; i < expectedArgs.Length; i++) { var param = expectedArgs[i]; switch (param.Type) { case ParameterType.Required: return CommandErrorType.BadArgCount; case ParameterType.Optional: case ParameterType.Unparsed: argList.Add(""); break; } } /*if (argList.Count > expectedArgs.Length) { if (expectedArgs.Length == 0 || expectedArgs[expectedArgs.Length - 1].Type != ParameterType.Multiple) return CommandErrorType.BadArgCount; }*/ args = argList.ToArray(); return null; }
public CommandBuilder CreateCommand(string cmd) { var command = new Command(CommandBuilder.AppendPrefix(_prefix, cmd)); return new CommandBuilder(_service, command, _prefix, _category, _checks); }
public bool CanRun(Command command, User user, Channel channel, out string error) { error = String.Empty; if (!NadekoBot.Ready) return false; if (channel.IsPrivate || channel.Server == null) return command.Category == "Help"; if (user == null) return false; if (ConfigHandler.IsUserBlacklisted(user.Id) || (!channel.IsPrivate && (ConfigHandler.IsServerBlacklisted(channel.Server.Id) || ConfigHandler.IsChannelBlacklisted(channel.Id)))) { return false; } try { if (timeBlackList.ContainsKey(user.Id)) return false; } catch { return false; } if (!channel.IsPrivate && !channel.Server.CurrentUser.GetPermissions(channel).SendMessages) { return false; } timeBlackList.TryAdd(user.Id, true); ServerPermissions perms; PermissionsHandler.PermissionsDict.TryGetValue(user.Server.Id, out perms); AddUserCooldown(user.Server.Id, user.Id, command.Text.ToLower()); if (commandCooldowns.Keys.Contains(user.Server.Id + ":" + command.Text.ToLower())) { if (perms?.Verbose == true) error = $"{user.Mention} You have a cooldown on that command."; return false; } try { //is it a permission command? // if it is, check if the user has the correct role // if yes return true, if no return false if (command.Category == "Permissions") { Discord.Role role = null; try { role = PermissionHelper.ValidateRole(user.Server, PermissionsHandler.GetServerPermissionsRoleName(user.Server)); } catch { } if (user.Server.Owner.Id == user.Id || (role != null && user.HasRole(role))) return true; throw new Exception($"You don't have the necessary role (**{(perms?.PermissionsControllerRole ?? "Nadeko")}**) to change permissions."); } var permissionType = PermissionsHandler.GetPermissionBanType(command, user, channel); string msg; if (permissionType == PermissionsHandler.PermissionBanType.ServerBanModule && command.Category.ToLower() == "nsfw") msg = $"**{command.Category}** module has been banned from use on this **server**.\nNSFW module is disabled by default. Server owner can type `;sm nsfw enable` to enable it."; else switch (permissionType) { case PermissionsHandler.PermissionBanType.None: return true; case PermissionsHandler.PermissionBanType.ServerBanCommand: msg = $"**{command.Text}** command has been banned from use on this **server**."; break; case PermissionsHandler.PermissionBanType.ServerBanModule: msg = $"**{command.Category}** module has been banned from use on this **server**."; break; case PermissionsHandler.PermissionBanType.ChannelBanCommand: msg = $"**{command.Text}** command has been banned from use on this **channel**."; break; case PermissionsHandler.PermissionBanType.ChannelBanModule: msg = $"**{command.Category}** module has been banned from use on this **channel**."; break; case PermissionsHandler.PermissionBanType.RoleBanCommand: msg = $"You do not have a **role** which permits you the usage of **{command.Text}** command."; break; case PermissionsHandler.PermissionBanType.RoleBanModule: msg = $"You do not have a **role** which permits you the usage of **{command.Category}** module."; break; case PermissionsHandler.PermissionBanType.UserBanCommand: msg = $"{user.Mention}, You have been banned from using **{command.Text}** command."; break; case PermissionsHandler.PermissionBanType.UserBanModule: msg = $"{user.Mention}, You have been banned from using **{command.Category}** module."; break; default: return true; } if (PermissionsHandler.PermissionsDict[user.Server.Id].Verbose) //if verbose - print errors error = msg; return false; } catch (Exception ex) { Console.WriteLine($"Exception in canrun: {ex}"); try { if (perms != null && perms.Verbose) //if verbose - print errors error = ex.Message; } catch (Exception ex2) { Console.WriteLine($"SERIOUS PERMISSION ERROR {ex2}\n\nUser:{user} Server: {user?.Server?.Name}/{user?.Server?.Id}"); } return false; } }
public static bool HasCooldown(Command cmd, IGuild guild, IUser user) { if (guild == null) return false; var cmdcds = CmdCdsCommands.commandCooldowns.GetOrAdd(guild.Id, new ConcurrentHashSet<CommandCooldown>()); CommandCooldown cdRule; if ((cdRule = cmdcds.FirstOrDefault(cc => cc.CommandName == cmd.Text.ToLowerInvariant())) != null) { var activeCdsForGuild = activeCooldowns.GetOrAdd(guild.Id, new ConcurrentHashSet<ActiveCooldown>()); if (activeCdsForGuild.FirstOrDefault(ac => ac.UserId == user.Id && ac.Command == cmd.Text.ToLowerInvariant()) != null) { return true; } else { activeCdsForGuild.Add(new ActiveCooldown() { UserId = user.Id, Command = cmd.Text.ToLowerInvariant(), }); var t = Task.Run(async () => { try { await Task.Delay(cdRule.Seconds * 1000); activeCdsForGuild.RemoveWhere(ac => ac.Command == cmd.Text.ToLowerInvariant() && ac.UserId == user.Id); } catch { } }); } } return false; }
private static string PrintCommandHelp(Command com) { var str = "`" + com.Text + "`"; str = com.Aliases.Aggregate(str, (current, a) => current + (", `" + a + "`")); str += " **Description:** " + com.Description + "\n"; return str; }
public void AddCommand(string text, Command command, bool isAlias) { AddCommand(0, text.Split(' '), command, isAlias); }
internal static PermissionBanType GetPermissionBanType(Command command, User user, Channel channel) { var server = user.Server; ServerPermissions serverPerms = PermissionsDict.GetOrAdd(server.Id, id => new ServerPermissions(id, server.Name)); bool val; Permissions perm; //server if (serverPerms.Permissions.Modules.TryGetValue(command.Category, out val) && val == false) return PermissionBanType.ServerBanModule; if (serverPerms.Permissions.Commands.TryGetValue(command.Text, out val) && val == false) return PermissionBanType.ServerBanCommand; //channel if (serverPerms.ChannelPermissions.TryGetValue(channel.Id, out perm) && perm.Modules.TryGetValue(command.Category, out val) && val == false) return PermissionBanType.ChannelBanModule; if (serverPerms.ChannelPermissions.TryGetValue(channel.Id, out perm) && perm.Commands.TryGetValue(command.Text, out val) && val == false) return PermissionBanType.ChannelBanCommand; //ROLE PART - TWO CASES // FIRST CASE: // IF EVERY ROLE USER HAS IS BANNED FROM THE MODULE, // THAT MEANS USER CANNOT RUN THIS COMMAND // IF AT LEAST ONE ROLE EXIST THAT IS NOT BANNED, // USER CAN RUN THE COMMAND var foundNotBannedRole = false; foreach (var role in user.Roles) { //if every role is banned from using the module -> rolebanmodule if (serverPerms.RolePermissions.TryGetValue(role.Id, out perm) && perm.Modules.TryGetValue(command.Category, out val) && val == false) continue; foundNotBannedRole = true; break; } if (!foundNotBannedRole) return PermissionBanType.RoleBanModule; // SECOND CASE: // IF EVERY ROLE USER HAS IS BANNED FROM THE COMMAND, // THAT MEANS USER CANNOT RUN THAT COMMAND // IF AT LEAST ONE ROLE EXISTS THAT IS NOT BANNED, // USER CAN RUN THE COMMAND foundNotBannedRole = false; foreach (var role in user.Roles) { //if every role is banned from using the module -> rolebanmodule if (serverPerms.RolePermissions.TryGetValue(role.Id, out perm) && perm.Commands.TryGetValue(command.Text, out val) && val == false) continue; else { foundNotBannedRole = true; break; } } if (!foundNotBannedRole) return PermissionBanType.RoleBanCommand; //user if (serverPerms.UserPermissions.TryGetValue(user.Id, out perm) && perm.Modules.TryGetValue(command.Category, out val) && val == false) return PermissionBanType.UserBanModule; if (serverPerms.UserPermissions.TryGetValue(user.Id, out perm) && perm.Commands.TryGetValue(command.Text, out val) && val == false) return PermissionBanType.UserBanCommand; return PermissionBanType.None; }
public CommandBuilder CreateCommand(string cmd) { var command = new Command(cmd != "" ? _prefix + ' ' + cmd : _prefix); command.MinPerms = _defaultMinPermissions; _client._commands.Add(command); return new CommandBuilder(command); }