返回一个字符串数组?

时间:2014-02-10 14:51:48

标签: c# system server-side mmo

所以在我的游戏服务器上,我们有服务器端命令。我想知道是否可以改变这个

public string Command
{
    get { return "g"; }
}

这样的事情

public string Command
{
    get { return "g", "guild", "group"; }
}

这是命令接口代码

internal interface ICommand
{
    string Command { get; }
    int RequiredRank { get; }
    void Execute(Player player, string[] args);
}

这是命令处理程序的代码
第1部分:

ProcessCmd(x[0].Trim('/'), x.Skip(1).ToArray());

第2部分:

private void ProcessCmd(string cmd, string[] args)
{
    if (cmds == null)
    {
        cmds = new Dictionary<string, ICommand>();
        var t = typeof (ICommand);
        foreach (var i in t.Assembly.GetTypes())
            if (t.IsAssignableFrom(i) && i != t)
            {
                var instance = (ICommand) Activator.CreateInstance(i);
                cmds.Add(instance.Command, instance);
            }
    }

    ICommand command;
    if (!cmds.TryGetValue(cmd, out command))
    {
        psr.SendPacket(new TextPacket
        {
            BubbleTime = 0,
            Stars = -1,
            Name = "*Error*",
            Text = "Unknown Command!"
        });
        return;
    }
    try
    {
        ExecCmd(command, args);
    }
    catch (Exception e)
    {
        Console.Out.WriteLine(e);
        psr.SendPacket(new TextPacket
        {
            BubbleTime = 0,
            Stars = -1,
            Name = "*Error*",
            Text = "Error when executing the command!"
        });
    }
}

3 个答案:

答案 0 :(得分:3)

你想要这个:

public string[] Commands
{
    get { return new string[] {"g", "guild", "group"}; }
}

从这开始。它会产生你应该修复的错误,并且通过推进修复,你将重构一段很好的代码,比如ICommand接口。

答案 1 :(得分:0)

如果不允许更改界面,请使用分隔符。

public string Command
{
    get { return string.Join("|", "g", "guild", "group"); }
}

用法示例:

foreach ( var command in source.Command.Split('|') )
{
    ExecCmd(command, args);
}

答案 2 :(得分:0)

如果你的命令没有维护任何状态,并且基本上只包含一个方法(看起来像这样),我建议完全删除接口和类,只使用附加了一些元数据(属性)的简单函数。

通过删除一堆类,这将使您的代码更简单。

示例:

// simple attribute to mark functions as commands
class CommandAttribute : Attribute
{
    public string Name {get;private set;}
    public string[] Keys {get;private set;}
    public int Rank {get;private set;}

    public CommandAttribute(string name, int rank, params string[] keys)
    {
        Name = name;
        Keys = keys;
        Rank = rank;
    }
}

// example commands
[Command("Guild", 15, "g", "guild", "group")]
public static void Guild(Player player,string[] args)
{
    // do stuff
}

[Command("Something other", 5, "f", "foo", "foobar")]
public static void FooIt(Player player,string[] args)
{
    // do stuff
}

在程序集中查找这些函数也很简单:

delegate void CommandHandler(Player player, string[] args);

var commands = from t in Assembly.GetExecutingAssembly().GetTypes()
               from m in t.GetMethods(BindingFlags.Static|BindingFlags.Public)
               let attr = (CommandAttribute)m.GetCustomAttribute(typeof(CommandAttribute))
               where attr != null
               select new 
               {
                    attr,
                    function = Delegate.CreateDelegate(typeof(CommandHandler), m)
                };

// probably use some other data structure if you want to lookup attr.Name and attr.Rank, too
var cmds = new Dictionary<string, CommandHandler>();
foreach(var item in commands)
    foreach(var key in item.attr.Keys)
        cmds.Add(key, (CommandHandler)item.function);