mxp功能的实现

fluffos中实现mxp功能

直接放代码了:

"/feature/mxp.c"

#include <mxp.h>

private nosave mapping mxp_version_info;
private nosave mapping mxp_support_info;

public mixed QueryMXP(){
if(!this_player()) return 0;
return has_mxp(this_player());
}

public void init_mxp() {

 if (!interactive() || !QueryMXP())
        return;
  mxp_version_info = ([]);
  mxp_support_info = ([ MXP_SUPPORT_ENABLED: ({}), MXP_SUPPORT_DISABLED: ({}) ]);
  efun::write(process_mxp(MXPTAG("!-- Set up MXP elements --"), QueryMXP()));
  efun::write(process_mxp(MXPTAG("!ELEMENT RNum FLAG=\"RoomNum\" ATT=\"id\" EMPTY"), QueryMXP()));
  efun::write(process_mxp(MXPTAG("!ELEMENT RName FLAG=\"RoomName\""), QueryMXP()));
  efun::write(process_mxp(MXPTAG("!ELEMENT RDesc FLAG=\"RoomDesc\""), QueryMXP()));
  efun::write(process_mxp(MXPTAG("!ELEMENT RExits FLAG=\"RoomExit\""), QueryMXP()));
  efun::write(process_mxp(MXPTAG("!ELEMENT Prompt FLAG=\"Prompt\""), QueryMXP()));
  efun::write(process_mxp(MXPTAG("!ELEMENT Ex \"<send>\""), QueryMXP()));

}

public void SetMXPVersion(mapping m) {
  if (!mxp_version_info)
    mxp_version_info = ([]);
  mxp_version_info = m;
}

public void SetEnabledMXPSupportInfo(string *s) {
  if (!mxp_support_info)
    mxp_support_info = ([]);
  mxp_support_info[MXP_SUPPORT_ENABLED] = s;
}

public void SetDisabledMXPSupportInfo(string *s ) {
  if (!mxp_support_info)
    mxp_support_info = ([]);
  mxp_support_info[MXP_SUPPORT_DISABLED] = s;
}

public mapping QueryMXPVersion() {
  return mxp_version_info || ([]);
}

public mapping QueryMXPSupportInfo() {
  return mxp_support_info || ([ MXP_SUPPORT_ENABLED: ({}), MXP_SUPPORT_DISABLED: ({}) ]);
}

"/adm/simul_efun/process_mxp.c"

#ifndef MXP_H
#include <mxp.h>
#endif

/*
**   Function: process_mxp
**
**    Purpose: Process MXP.
**
** Parameters: string msg, the msg to transform
**
**    Returns: string
*/

public string process_mxp(string msg, int does_mxp) {
    int line = 0;
    int length = 0;
    int i = 0;
    int inTag = 0;
    int inEntity = 0;

    string *original_lines = explode(msg, "\n");
    string *processed_lines = allocate(sizeof(original_lines));
    if(!does_mxp) return msg;

    for (line = 0; line < sizeof(original_lines); line++) {
    processed_lines[line] = does_mxp ? MXPMODE(1) : "";

        length = sizeof(original_lines[line]);

        for (i = 0; i < length; i++) {
            if (inTag) { /* in a tag, eg. <send> */
                if (original_lines[line][i..i] == MXP_END) {
                    inTag = 0;

                    if (does_mxp) {
                        processed_lines[line] += ">";
                    }
                } else if (does_mxp) { /* copy tag only when MXP does_mxp */
                    processed_lines[line] += original_lines[line][i..i];
                }
            } else if (inEntity) { /* in a tag, eg. <send> */
                if (does_mxp) { /* copy tag only when MXP does_mxp */
                    processed_lines[line] += original_lines[line][i..i];
                }

                if (original_lines[line][i..i] == ";") {
                    inEntity = 0;
                }
            } else {
                if (original_lines[line][i..i] == MXP_BEG) {
                    inTag = 1;

                    if (does_mxp) {
                        processed_lines[line] += "<";
                    }
                } else if (original_lines[line][i..i] == MXP_END) { /* should not get this case */
                    processed_lines[line] += ">";
                } else if (original_lines[line][i..i] == MXP_AMP) {
                    inEntity = 1;

                    if (does_mxp) {
                        processed_lines[line] += "<";
                    }
                } else if (does_mxp) {
                    if (original_lines[line][i..i] == "<") {
                        processed_lines[line] += "&lt;";
                    } else if (original_lines[line][i..i] == ">") {
                        processed_lines[line] += "&gt;";
                    } else if (original_lines[line][i..i] == "&") {
                        processed_lines[line] += "&amp;";
                    } else if (original_lines[line][i..i] == "\"") {
                        processed_lines[line] += "&quot;";
                    } else {
                        processed_lines[line] += original_lines[line][i..i];
                    }
                } else { /* not MXP - just copy character */
                    processed_lines[line] += original_lines[line][i..i];
                }
            }
        }
    }
    return implode(processed_lines, "\n");
}

以上sefun需要在simul_efun.c中#include "/adm/simul_efun/process_mxp.c"

"/feature/message.c"

// message.c

#include <ansi.h>
#include <dbase.h>
#include <mxp.h>

#define MAX_MSG_BUFFER 500
#define TOMXP (int)this_object()->QueryMXP()
nosave string *msg_buffer = ({});

void receive_message(string msgclass, string msg)
{
    string subclass, *ch;

    if( !interactive(this_object()) ) {
        this_object()->relay_message(msgclass, msg);
        return;
    }

    if( sscanf(msgclass, "%s:%s", subclass, msgclass)==2 ) {
        switch(subclass) {
            case "channel":
                if( !pointerp(ch = query("channels"))
                ||  member_array(msgclass, ch)==-1 )
                    return;
                break;
            case "outdoor":
                if( !environment() || !environment()->query("outdoors") )
                    return;
                break;
            default:
                error("Message: Invalid Subclass " + subclass + ".\n");
        }
    }

    if( query_temp("block_msg/all") || query_temp("block_msg/" + msgclass) )
        return;

    if( in_input(this_object()) || in_edit(this_object()) ) {
        if( sizeof(msg_buffer) < MAX_MSG_BUFFER )
            msg_buffer += ({ msg });
    } else
        receive( process_mxp(msg, TOMXP) );
}

void write_prompt()
{
    if( sizeof(msg_buffer) ) {
        receive(BOLD "[输入时暂存讯息]\n" NOR);
        for(int i=0; i<(sizeof(msg_buffer)>MAX_MSG_BUFFER?  MAX_MSG_BUFFER:sizeof(msg_buffer)); i++)
            receive(msg_buffer[i]);
        msg_buffer = ({});
    }
         receive(process_mxp(sprintf("%s%s%s", MXPTAG("Prompt"), "> ", MXPTAG("/Prompt")), TOMXP));
}

void receive_snoop(string msg)
{
    receive("%" + msg);
}

"/include/mxp.h"

#ifndef MXP_H
#define MXP_H

#define MXP_SUPPORT_ENABLED  "mxp_enabled_features"
#define MXP_SUPPORT_DISABLED "mxp_disabled_features"

/* strings */

#define MXP_BEG "\x03"
#define MXP_END "\x04"
#define MXP_AMP "\x05"

/* characters */

#define MXP_BEGc '\x03'
#define MXP_ENDc '\x04'
#define MXP_AMPc '\x05'

/* constructs an MXP tag with < and > around it */

#define MXPTAG(arg) sprintf("%s%s%s", MXP_BEG, arg, MXP_END)

#define ESC1 "\x1B"  /* esc character */

#define MXPMODE(arg) sprintf("%s[%dz", ESC1, arg)

#endif // MXP_H

cmds look.c 中需要改造部分如下:

int look_room(object me, object env) {
    int i;
    object *inv;
    mapping exits;
    string /*roomdesc,*/ str, *dirs;

    if(!env) {
        write("你的四周灰蒙蒙地一片,什麽也没有。\n");
        return 1;
    }

   str=sprintf( "%s - %s\n", env->query("short"), wizardp(me)? file_name(env)+sprintf(" - (%d,%d,%d)",env->query("coor/x"), env->query("coor/y"),env->query("coor/z")): sprintf("(%d,%d,%d)",env->query("coor/x"), env->query("coor/y"),env->query("coor/z")));
   str=MXPTAG("RDesc")+str+MXPTAG("/RDesc");
   write(str);
   if( me->query("env/show_way")  && ! me->query("env/brief"))
   realtime_map(me, env);
    // room descriptions.
    str = sprintf( "    %s%s",
            env->long(),
            env->query("outdoors")? NATURE_D->outdoor_room_description() : "" );
       str=MXPTAG("RDesc")+str+MXPTAG("/RDesc");
    // exits.
    if(mapp(exits = env->query("exits"))) {
        dirs = keys(exits);
        for(i=0; i<sizeof(dirs); i++) {
            if((int)env->query_door(dirs[i], "status") & DOOR_CLOSED ) {
                dirs[i] = 0;
            }
        }
        dirs -= ({ 0 });
        if(sizeof(dirs)==0) {
            str += "    这里没有任何明显的出路。\n";
        } else if(sizeof(dirs)==1) {
               str += "    这里唯一的出口是 " + BOLD +MXPTAG("RExits")+MXPTAG("Ex")+ dirs[0]+MXPTAG("/Ex")+ MXPTAG("/RExits") + NOR + "。\n";
        } else {
            dirs = map(dirs, (: MXPTAG("Ex") + $1 + MXPTAG("/Ex") :));
            str += sprintf("    这里明显的出口是 " + BOLD + "%s" + NOR + 
                    " 和 " + BOLD + "%s" + NOR + "。\n",
                    MXPTAG("RExits")+implode(dirs[0..sizeof(dirs)-2], "、")+ MXPTAG("/RExits"), MXPTAG("RExits")+dirs[sizeof(dirs)-1]+MXPTAG("/RExits"));

        }
    } else {
        str += "    这里没有任何明显的出路。\n";
    }

    // all things in the room.
    inv = all_inventory(env);
    if (!env->query("brief_objects"))
    for(i=0; i<sizeof(inv); i++) {
        if(inv[i]==me || inv[i]->query("no_shown") || !me->visible(inv[i])) {
            continue;
        }
        if (inv[i]->query_temp("team_name"))
            str += "  " + inv[i]->short() + WHT" < "+inv[i]->query_temp("team_name")+" >\n"NOR;
        else 
            str += "  " + inv[i]->short() + "\n";

    }
     str=MXPTAG("RDesc")+str+MXPTAG("/RDesc");

    write(str);
    return 1;
}

"/adm/daemons/logind.c"

//  enter_world 部分 `exec(user, ob);` 后增加
user->init_mxp();

user object 中 inherit "feature/mxp";

#include <origin.h>
#include <user.h>
#include <room.h>
#include <ansi.h>

inherit CHARACTER;
inherit F_MASTER;
inherit F_AUTOLOAD;
inherit F_SAVE;
inherit "feature/mxp";

nosave int last_age_set;

void autosave();

void create() {
    ::create();
    set_name("使用者物件", ({ "user object", "user", "object" }) );
}
京ICP备13031296号-4