曾经有玩家提过一个需求,想在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驱动,并显示编译信息给当前玩家。

通过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;
}

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