如何通过字符串正确处理自定义命令

本文关键字:自定义 命令 正确处理 字符串 何通过 | 更新日期: 2023-09-27 18:36:55

简而言之:我正在为我正在开发的游戏制作服务器程序。为了控制服务器,我想使用命令。类似于"/服务器启动 5555"的内容。这些命令以字符串格式发送到服务器。这是我的代码:

ServerCommandsClass ServerCommands = new ServerCommandsClass();
Type Service = typeof(ServerCommandsClass);
MethodInfo method = Service.GetMethod(Signals[Count].MessageArray[0]);
List<object> ObjectList = new List<object>();
for (int i = 1; i < Signals[Count].MessageArray.Length; i++)
{
    ObjectList.Add(Signals[Count].MessageArray[i]);
}
string result = Convert.ToString(method.Invoke(ServerCommands, ObjectList.ToArray()));

它看起来很乱,因为它是...

基本上我得到的是一个存储新消息/命令的类(SignalClass)。首先,我确定消息是否为命令。如果是这样,则运行此代码。My MessageArray 使用 string.split 函数逐字包含消息。

这有效,但我觉得这是一个变通方法。

我想要的是一个命令基础设施(有点像在 Minecraft 中),它很容易适应我的需求。就像在《我的世界》中一样,你可以输入:"/tp 1000 64 1000"和"/tp someplayer 1000 64 1000"。在我的代码中,由于我的代码的限制,您不能。我必须创建一个新方法"tp2"或其他东西才能接受该额外参数。

我希望有人可以帮助我解决这个问题,因为它很烦人。

B.T.W.我使用 .Net 4.5.1 对此进行编程。如果我在某处有点含糊不清,请问我,我会澄清的。

迪翁·多克特

如何通过字符串正确处理自定义命令

当然可以,问题不在于您发布的代码,而在于您正在调用的方法。您要做的基本上是重载。

/tp x y z

/tp someplaya x y z

与 String.Substring(0) 和 String.Substring(0, 5) 没有什么不同。如果你抓住我的漂移。

所以,我想你的方法看起来像这样:

public static void Teleport(params object[])
{
   //here you validate your parameters and take decisions
   //e.g.
   //if(params[0] is String && params[1] is Int32)...
}

我的建议是:不要使用字符串。

如果必须,可以使用序列化。因此,您可以发送任何对象。此外,如果您的问题是您希望能够发送不同数量的参数(在这里很难猜测您在做什么)请使用 params-关键字

喜欢在

public void DoSomething (string command, params string[] paramters) {
// Whatever
}

我的两分钱同意,如果你的拆分字符使其成为命令,String.Split 会有点麻烦,所以我说使用 XML 结构;

<Command>
<CommandName value="">
<Arg1 value="">
<Arg2 value="">etc...
</Command>
此外,根据游戏的不同(

多人游戏连接到同一服务器?)使用多个端口,即使对于同一个客户端,您也可以将多个端口用于游戏中的不同功能(如果游戏足够复杂以保证这一点)。这将帮助您隔离命令逻辑。

但最终,您只能解析传入的命令,对于游戏的调试阶段,您可以使用有意义的字符串名称坚持使用,在部署之前,您可以将这些字符串名称减少到相同的几个字节。

至于确定用户的文本输入作为命令,像你有/tp命令,然后是String.Split,建议强制第一个参数是必需参数,然后是可选参数。在个人笔记中,键入的命令应该显示参数列表,然后用户"键入"以帮助他们

我告诉你一种我们在内部做到这一点的方法。我们做了一个名为RemoteInvoke的js进程。 它将采用一个命令和一个参数数组,并将它们发送到服务器。 然后,服务器将获取命令并通过反射查找方法,该方法为:

  1. 以命令命名
  2. 具有[RemoteInvocable]属性
  3. 是公开的
  4. 具有正确数量的参数,这些参数将进行类型匹配。

原因是当我想调用某些东西时,我会调用 RemoteInvoke,它会将参数发送到服务器。 要添加新命令,我可以这样做:

[RemoteInvocable]
public void Tp(double x, double y, double z)
{
    Tp("default", x, y, z);
}
[RemoteInvocable]
public void Tp(string location, double x, double y, double z)
{
   // whatever
}

关键是命令处理很棘手,但对于所有内容都是一样的 - 只是一堆反射和类型推断,但一旦完成添加新命令或多个具有相同名称和不同参数的命令是微不足道的。