【问题标题】:How to implement a command list for multiple users? [closed]如何为多个用户实现一个命令列表? [关闭]
【发布时间】:2020-02-02 14:02:47
【问题描述】:

我有一个命令列表,例如:

  • command1command2测试退出

我也有用户:

  • 管理员user1user2

我们的目标是让用户能够调用他们可用的命令。 例如,

  • admin - command1command2testexit
  • user1 - command1测试
  • user2 - command2

如果我在输入中有两个变量 - commandNameuserName,那么实现此功能的最佳方法是什么。

目前是在switch上完成的,但是对于扩容项目非常不方便。

【问题讨论】:

  • 您的问题质量不高,或者您的要求不明确或过于宽泛。你的目标是什么?你的困难是什么?到目前为止你做了什么?请尝试更好地解释您的问题、您的开发环境并分享更多代码或屏幕截图。为了帮助您改进查询的内容、标题和标签,请考虑阅读帮助中心的 How do I ask a good question
  • @OlivierRogier 在我看来,我清楚地解释了。感谢您的链接。我已经收到了很好的答案,并且正在努力实施。当我完成实施并且没有问题时,我将发送我的解决方案并将答案标记为已接受。
  • 在您看来,您可能已经清楚地解释了。有些人明白了,但你不说你在说什么。您没有指明任何标签。我们不知道你在说什么。就个人而言,我以为您在谈论 sql 命令,并且您想管理数据库访问 autorisatrions。而且您没有提供任何代码来表明您想要做什么或尝试过什么。所以你的问题不清楚。因此,阅读您所说的符合您要求的答案,现在很清楚,但您的问题不是编程问题。实际上,您的问题与 C# 无关。

标签: c# .net roles user-permissions restriction


【解决方案1】:

您的解决方案是权限。

  1. 创建角色并为其分配一组权限;
  2. 为您的用户分配角色并创建为特定用户添加额外权限的能力;
  3. 将您的命令处理程序拆分为不同的方法(没有开关!)并在开始执行命令时检查权限。

这是我认为命令处理程序应该是什么样子的伪代码:

public ExecutionResult ExecuteCommand1(User user, string[] arguments) {
   if(!user.HasPermission("admin.test.permission")) {
       return new ExecutionResult() {
           Error = true,
           Message = "You don't have permissions to execute that command!"
       };
   }

   user.GiveKarma(1337);

   return new ExecutionResult {
       Message = "Karma points were added!"
   };
}

权限标识符不应该是我的示例代码中的字符串。

你可以使用任何东西:字符串、枚举等等。

【讨论】:

  • 我的命令处理程序是由方法分隔的,我只是在 Switch 中调用它们。我的命令名和用户名是字符串。关于角色 - 1 个用户 1 个角色。我在想一个类似于 KeyValue - {commandName, commandMethod} 的列表,并且列表是 {userName, availableCommands},但在我看来这也不是一个好的解决方案。
  • 权限系统还不错。自定义 Minecraft 服务器正在使用它们,ejabberd 服务器正在使用它们。
  • TeamSpeak 也使用权限。这个方法看起来不错。谢谢。
  • @Des1re 请注意,stringly typed 使用字符串文字 ("admin.test.permission") 的方法很容易成为调试地狱,因为它很容易出错并且对重构不友好。如果您采用这条路线,请使用强类型。至少,为您的用户/命令声明常量,这样您就可以保持代码重构友好。
【解决方案2】:

您可以创建包含命令和用户访问命令的字典列表(或类似的命令进入 DB):

 var commandList = new Dictionary<string, Action>();
            commandList.Add("command1", () => { Console.WriteLine("command1 is executed"); });
            commandList.Add("command2", () => { Console.WriteLine("command2 is executed"); });
            commandList.Add("command3", () => { Console.WriteLine("command3 is executed"); });
            var listOfUserCommands = new Dictionary<string, List<string>>();
            listOfUserCommands.Add("user1", new List<string>() { "command1" });
            listOfUserCommands.Add("user2", new List<string>() { "command2", "command3" });

            var userName = "user1";
            var commandName = "command2";
            if (listOfUserCommands.ContainsKey(userName) && listOfUserCommands[userName].Contains(commandName))
            {
                commandList[commandName]();
            }

它可能会被修改为使用命令别名:

public interface IExecutionCommand
    {
        Action Action { set; get;}
        List<string> Aliases { set; get; }

    }
    public class ExecutionCommand1: IExecutionCommand
    {
        public Action Action { set; get; }
        public List<string> Aliases { set; get; }
        public ExecutionCommand1()
        {
            Action = () => { Console.WriteLine("command1 is executed"); };
            Aliases = new List<string>() { "cmd1" };
        }
    }
    public class ExecutionCommand2: IExecutionCommand
    {
        public Action Action { set; get; }
        public List<string> Aliases { set; get; }
        public ExecutionCommand2()
        {
            Action = () => { Console.WriteLine("command2 is executed"); };
            Aliases = new List<string>() { "cmd2" };
        }
    }
    public class ExecutionCommand3: IExecutionCommand
    {
        public Action Action { set; get; }
        public List<string> Aliases { set; get; }
        public ExecutionCommand3()
        {
            Action = () => { Console.WriteLine("command3 is executed"); };
            Aliases = new List<string>() { "cmd3" };
        }
    }
    public static void Main()
    {
        //_startScanning();
        var commandList = new List<IExecutionCommand>();
        commandList.Add(new ExecutionCommand1());
        commandList.Add(new ExecutionCommand2());
        commandList.Add(new ExecutionCommand3());
        var listOfUserCommands = new Dictionary<string, List<string>>();
        listOfUserCommands.Add("user1", new List<string>() { "cmd2" });
        listOfUserCommands.Add("user2", new List<string>() { "command1", "command3" });

        var userName = "user1";
        var commandName = "cmd2";

        if (listOfUserCommands.ContainsKey(userName) && listOfUserCommands[userName].Contains(commandName))
        {
            IExecutionCommand command = commandList.FirstOrDefault(x => x.Aliases.Contains(commandName));
            command?.Action();
        }
    }

【讨论】:

  • 我正在考虑这样的实现。感谢您提供漂亮的示例代码!
  • 您知道如何为命令创建别名吗?例如测试 -> 检查。只需像命令一样添加别名,其中名称是别名并调用相同的方法还是有其他方法?
  • 我添加了没有命令字典和命令别名的解决方案
【解决方案3】:

这就是我从 Oleg Bondarenko 的例子中得到的。解决方案并不完美,但突然有人需要它。

Dictionary<string, List<IExecutionCommand>> listOfUserCommands = new Dictionary<string, List<IExecutionCommand>>();

public interface IExecutionCommand
{
    Action Action { set; get; }
    List<string> Aliases { set; get; }
}

public class commandTest : IExecutionCommand
{
    public Action Action { set; get; }
    public List<string> Aliases { set; get; }
    public commandTest()
    {
        Action = () => { Console.WriteLine("command1 is executed"); };
        Aliases = new List<string>() { "test", "check", "tests" };
    }
}
public class commandEx2 : IExecutionCommand
{
    public Action Action { set; get; }
    public List<string> Aliases { set; get; }
    public commandEx2()
    {
        Action = () => { Console.WriteLine("command2 is executed"); };
        Aliases = new List<string>() { "cmd2" };
    }
}


private IExecutionCommand FindingCommandFromUser(string commandName, List<IExecutionCommand> commandList)
{
    foreach (IExecutionCommand command in commandList)
        if (command.Aliases.Contains(commandName))
            return command;
    return null;
}

public static void Main()
{
    listOfUserCommands.Add("user1",
                            new List<IExecutionCommand>()
                            {
                                    new commandTest(),
                                    new commandEx2()
                            });

    string userName = "user1";
    string commandName = "check";

    IExecutionCommand curCommand = null;

    if (listOfUserCommands.ContainsKey(userName) && ((curCommand = FindingCommandFromUser(commandName, listOfUserCommands[userName])) != null))
        curCommand.Action();
}

【讨论】:

  • 您可以只定义与用户相关的命令的名称(别名)而不是整个命令,然后按名称查找它们`var command = commandList.FirstOrDefault(x => x.Aliases.Contains(commandName))` .
  • 你能解释一下你的表达是如何工作的吗?我知道它取代了我的 FindingCommandFromUser?我不明白为什么要使用 FirstOrDefault?
  • 命令集合中可能没有具有搜索名称的单个命令,或者根本不显示。在第一种情况下,首先找到一个表达式,在第二种情况下,结果将为空。带条件的 FirstOrDefault 等于不带参数的 where 表达式和 FirstOrDefault() 对。有很好的例子docs.microsoft.com/en-us/dotnet/api/…
  • 感激不尽!现在我了解了 lambda 表达式的工作原理。这是一次有用的经历,我不知道没有他们我是如何生活的。
  • 没错,Linq 是 c# 中非常常用的工具。我很高兴能帮上忙
猜你喜欢
  • 2014-06-19
  • 1970-01-01
  • 1970-01-01
  • 2016-11-10
  • 2023-03-09
  • 2013-10-29
  • 2023-04-10
  • 2020-02-05
  • 1970-01-01
相关资源
最近更新 更多