让你的MUDLIB支持GMCP Extensions

MUD是一款上手难度比较高的游戏,很多玩家需要机器人的支持来玩游戏,在mudlet中可以提供官方的扩展,当玩家使用mudlet连接游戏时会自动下载更新,这就能玩很多骚操作了,比如提供官方的UI系统和脚本,当玩家连接时自动下载使用。

https://wiki.mudlet.org/w/Manual:GMCP_Extensions

自动安装包

MUDLET中支持自动安装Mudlet packages,要实现起来需要mud服务器在客户端连接后发送如下GMCP数据:

Client.GUI <package version>\n<url>

如:

Client.GUI 1562626892\nhttps://mudlet.reinosdeleyenda.es/RLMud_Config.zip

示例代码:


protected void init_gmcp()
{
    if (!this_player() || !has_gmcp(this_player()))
        return;
    efun::send_gmcp("Client.GUI 1562626892\nhttps://mudlet.reinosdeleyenda.es/RLMud_Config.zip");
}

或者发送如下格式的GMCP数据:

Client.GUI {
  "version": "<package version>",
  "url": "<url>"
}

如:

Client.GUI {
  "version": "39",
  "url": "http://www.stickmud.com/mudwww/StickMUDv39.mpackage"
}

当玩家连线游戏后,mudlet客户端会自动从url下载包并安装,如果版本有更新,也会自动更新。

自动安装地图

和包类似,使用以下格式发送GMCP到客户端:

Client.Map {
  "url": "https://..."
}

当玩家在mudlet中打开地图时会提示下载。

file

代码实现可参考炎黄MUD:

// https://gitee.com/mudren/yhmud/blob/master/feature/gmcp.c
#define GMCP_LOG 50

nosave string *gmcp_log = ({});

protected int dump_gmcp_log()
{
    write(implode(gmcp_log, "\n") + "\n");
    return 1;
}

private void log_gmcp(string msg)
{
    gmcp_log = gmcp_log[ < GMCP_LOG..] + ({msg});
}

void send_gmcp(string gmcp)
{
    efun::send_gmcp(gmcp);
}

varargs void sendGMCP(mapping data, mixed *modules...)
{
    if (!this_player() || !has_gmcp(this_player()))
        return;

    if (!mapp(data) || !sizeof(modules))
    {
        return;
    }
    else
    {
        string msg = implode(modules, ".");
        catch (msg += " " + json_encode(data));
        log_gmcp("Sending: " + msg);
        send_gmcp(msg);
    }
}

private void gmcp_enable()
{
    message("system", "<GMCP negotiation enabled>\n", this_object());
    sendGMCP((["mud_name":MUD_NAME]), "Core", "Hello");
}

protected void init_gmcp()
{
    if (!this_player() || !has_gmcp(this_player()))
        return;
    gmcp_enable();

    // Mudlet Client
    if (env("GUI"))
    {
        sendGMCP((["version":env("GUI.version"), "url":env("GUI.url")]), "Client", "GUI");
    }
    if (sizeof(env("Map")))
    {
        sendGMCP((["url":env("Map")]), "Client", "Map");
    }

    if (wizardp(this_player()))
    {
        add_action("dump_gmcp_log", "gmcp_log");
    }
}

// gmcp - provides an interface to GMCP data received from the client
void gmcp(string req)
{
    // todo 处理客户端请求
    log_gmcp("Received: " + req);
    // debug_message(req);
}

GMCP脚本

https://mudletwiki.pkuxkx.com/w/Manual:Supported_Protocols#GMCP

当服务器发送gmcp数据到客户端后,客户端可以事件触发,如:炎黄服务端会发送Char.Vitals给玩家,只用以下事件脚本即可自动触发:

file

  1. 新建一个脚本文件,如test_gmcp, 在这个脚本中定义一个同名函数test_gmcp(),注意一定要同名,这好像是mudlet中唯一一个对文件名有要求的地方,这样脚本会在事件触发时自动调用函数.
  2. 新增自定义事件,事件为指定的gmcp数据表,这样会在收到这个gmcp数据时触发事件

相关资料

京ICP备13031296号-4