在MUD游戏中执行外部指令或脚本(如python脚本)的方法

曾经有玩家提过一个需求,想在MUD游戏中调用操作系统的指令或脚本,如何实现?

其实实现起来很简单,因为驱动提供了一个efun external_start

这个外部函数在PACKAGE_EXTERNAL中,fluffos v2019.20220507-3以后的版本默认开启支持,而以前的版本默认没有开启,需要在驱动编译时开启:

cmake -DPACKAGE_EXTERNAL=ON .. && make -j4 install

为了系统安全,驱动仅可调用在运行时配置文件中设置的指令,具体配置如下:

external_cmd_1 : /usr/bin/bash
external_cmd_2 : /usr/bin/python
external_cmd_3 : /usr/bin/curl
external_cmd_4 : C:\ProgramData\chocolatey\bin\curl.exe

注意:external_cmd_x 最多可设置100条(编号x最大值为100),序号不要求连续。

提示:使用bash脚本,你可以无限制的调用系统指令。

以上我们指定了3条命令,第4条为windows系统下示例,下面使用external_start函数来执行指令,语法如下:

int external_start(int, string | string *, string | function, string | function, string | function | void);

第一个参数指定了要调用的指令在运行时配置文件中的编号,第二个参数为传给指令的参数,后面三个参数为socket回调函数。

示例,我们新建一条指令bash.c,通过指令来调用系统脚本编译fluffos驱动,代码如下:

nosave object receiver;

mixed read_cb(int fd, string arg)
{
    tell_object(receiver, arg);
}

mixed write_cb(mixed *arg...)
{
    debug_message(sprintf("write_cb : %O", arg));
}

mixed close_cb(int fd)
{
    socket_close(fd);
}

int main(object me, string arg)
{
    receiver = me;
#if efun_defined(external_start)
    external_start(1, arg || "/root/fluffos/build.sh", "read_cb", "write_cb", "close_cb");
#else
    write("不支持 external_start\n");
#endif
    return 1;
}

这里我们在游戏中调用/root/fluffos/build.sh脚本,脚本示例如下:

#!/bin/bash

cd /root/fluffos/ && git pull
rm -rf build && mkdir build && cd build
cmake -DPACKAGE_EXTERNAL=ON .. && make -j4 install

当我们在游戏中运行指令bash时,就会自动执行脚本重新编译fluffos驱动,并显示编译信息给当前玩家。

file


通过external_start我们可以方便的调用curl指令实现http通信,这要比自己在代码中通过socket实现要简单的多。

新加一个指令curl示例代码:

mapping fd_to_msg;
mapping fd_to_obj;

void on_read(int fd, string msg) {
  fd_to_msg[fd] += sprintf("%s", msg);
}

void on_write(int fd) {
  debug_message(sprintf("on_write: %d \n", fd));
}

void on_close(int fd) {
  tell_object(fd_to_obj[fd], fd_to_msg[fd]);
  map_delete(fd_to_msg, fd);
  map_delete(fd_to_obj, fd);
}

int main(object me, string arg)
{
  int fd;
  int CURL_CMD = 3;
  if(__ARCH__ == "Microsoft Windows") CURL_CMD = 4;

  if (!arg) arg = "";
  fd = external_start(CURL_CMD, arg, "on_read", "on_write", "on_close");

  if (!fd_to_msg) {
    fd_to_msg = ([]);
  }
  if (!fd_to_obj) {
    fd_to_obj = ([]);
  }

  fd_to_msg[fd] = "";
  fd_to_obj[fd] = me;

  return 1;
}

file

使用CURL在MUD游戏开发中的具体项目案例猜字迷游戏

NPC出字迷由玩家猜,字迷是由API提供的,游戏通过curl发起请求调用API获取数据,把题目显示给玩家,对比玩家回答结果判断正误并给于奖励。

file

  1. 通用命令行模块:https://gitee.com/mudcore/mudcore/blob/master/inherit/CMD.c
  2. 猜字迷游戏功能:https://gitee.com/mudren/yhmud/blob/master/u/mudren/npc/LiSouci.c
  3. 用Python脚本发邮件示例:https://bbs.mud.ren/threads/323
京ICP备13031296号-4