背景:
阅读文章

server-side trigger

[日期:2007-05-11] 来源:  作者: [字体: ]


每当网络速度太慢而导致你的指令无法及时送出的时候,你一定会有
把机器砸掉的冲动,尤其是看到屏幕突然不动,等传过来的时候已经
在黄泉路上,实在是很不爽的一种事情.

基于这种考虑,我们提出server-side trigger的概念,即允许用户自
定义一些简单的trigger,在服务器对用户发出这些信息之前就有机会触发
这些trigger,执行一系列事先定义好的命令.

和server-side alias一起,client端可以变的更"瘦",最终能彻底淘汰
zmud是最好了,不过,相信80%的时候,zmud都是在用来快速走路和触发一些
简单的trigger,然后是timer.

这样一来,虽然比zmud还差些,不过也已经可以用个最破的telnet来舒服的玩
mud了,包括计划中的简单java-applet-client(当然是放在主页里面啦)

目前server-side trigger只支持子串匹配和正则表达式的匹配,还不能够
把匹配的变量取出来.

可以匹配带颜色的pattern

int help (object me)
{
        write(@HELP
指令格式 : trigger <触发信息> <触发后欲执行之命令>
 
当你从系统接收到<触发信息>的时候,可以让系统自动执行一个
或者一系列预先定义好的指令(可以是你定义的alias).
 
例如:
        'trigger 英俊男子身着布衣走了过来。 hi' 会在
        出现“英俊男子身着布衣走了过来。”的时候自动执行一个 "hi" 的指令。
        'trigger' 後不加参数则列出你所有的trigger。
        'trigger sc' 会消除 sc 这个trigger。 (如果你设定过这个trigger的话)
        'trigger on' 会打开trigger触发。
        'trigger off'会关闭trigger的触发。
        'trigger xxxx $gag' 会不显示所有包含xxxx的信息。比如敲这个指令
                        'trigger 流星雨 $gag',这样你就看不到他的一切话了。
        'trigger OnDisconnect quit' 会在你断线的时候自动执行 'quit' 指令,
                        当然也可以是别的指令
HELP
);
        return 1;
}


发信人: yeung (流星雨), 信区: Mud_Builder       
标  题: 程序实现(1)
发信站: BBS 水木清华站 (Mon Jul 26 07:02:02 1999)


/cmds/usr/trigger.c

// trigger.c
#include 

inherit F_CLEAN_UP;

int main(object me, string arg)
{
        int i;
        mapping trigger;
        string verb, replace, *vrbs,cname;

        if( !arg ) {
                trigger = me->query_all_trigger();
                if( !sizeof(trigger) ) {
                        write("你目前并没有设定任何 trigger。\n");
                        me->disable_trigger();
                } else  {
                        i = me->query_trigger_enabled();
                        me->disable_trigger();
                        write("你目前设定的 trigger 有:\n");
                        vrbs = keys(trigger);
                        for(i=0; i < sizeof(vrbs); i++)
                                printf("%-40s 将触发如下命令:  %s\n", vrbs[i]+NOR, trigger[vrbs[i]]);
                        write("\n你的触发器目前是"+(i?"打开的":"关闭的")+"。\n");
                        if( i ) me->enable_trigger();
                }
                return 1;
        }

        if( arg=="on" )
        {
                me->enable_trigger();
                write("打开trigger触发。\n");
                return 1;
        }
        if( arg=="off" )
        {
                me->disable_trigger();
                write("关闭trigger触发。\n");
                return 1;
        }                       
                cname = arg;
                cname = replace_string(cname, "$BLK$", BLK);
                cname = replace_string(cname, "$RED$", RED);
                cname = replace_string(cname, "$GRN$", GRN);
                cname = replace_string(cname, "$YEL$", YEL);
                cname = replace_string(cname, "$BLU$", BLU);
                cname = replace_string(cname, "$MAG$", MAG);
                cname = replace_string(cname, "$CYN$", CYN);
                cname = replace_string(cname, "$WHT$", WHT);
                cname = replace_string(cname, "$HIR$", HIR);
                cname = replace_string(cname, "$HIG$", HIG);
                cname = replace_string(cname, "$HIY$", HIY);
                cname = replace_string(cname, "$HIB$", HIB);
                cname = replace_string(cname, "$HIM$", HIM);
                cname = replace_string(cname, "$HIC$", HIC);
                cname = replace_string(cname, "$HIW$", HIW);
                cname = replace_string(cname, "$NOR$", NOR);         
                arg = cname;

        if( sscanf(arg, "%s %s", verb, replace)!=2 )
                me->set_trigger(arg, 0);
        else if( verb=="trigger" )
                return notify_fail("你不能将 \"trigger\" 指令设定为 pattern 。\n");
        else if( verb=="" )             
                return notify_fail("你要设什麽 trigger?\n");
        else
        {
                return me->set_trigger(verb, replace);
        }

        write("Ok.\n");
        return 1;
}

int help (object me)
{
        write(@HELP
指令格式 : trigger <触发信息> <触发后欲执行之命令>
 
当你从系统接收到<触发信息>的时候,可以让系统自动执行一个
或者一系列预先定义好的指令(可以是你定义的alias).
 
例如:
        'trigger 英俊男子身着布衣走了过来。 hi' 会在
        出现“英俊男子身着布衣走了过来。”的时候自动执行一个 "hi" 的指令。
        'trigger' 後不加参数则列出你所有的trigger。
        'trigger sc' 会消除 sc 这个trigger。 (如果你设定过这个trigger的话)
        'trigger on' 会打开trigger触发。
        'trigger off'会关闭trigger的触发。
        'trigger xxxx $gag' 会不显示所有包含xxxx的信息。比如敲这个指令
                        'trigger 流星雨 $gag',这样你就看不到他的一切话了。
        'trigger OnDisconnect quit' 会在你断线的时候自动执行 'quit' 指令,
                        当然也可以是别的指令
HELP
);
        return 1;
}

发信人: yeung (流星雨), 信区: Mud_Builder       
标  题: 程序实现(2)
发信站: BBS 水木清华站 (Mon Jul 26 07:03:21 1999)


/feature/trigger.c

#define MAX_TRIGGERS 10

mapping trigger;
static int      allow_trigger;

int set_trigger(string verb, string replace)
{
        if( !replace ) {
                if( mapp(trigger) ) map_delete(trigger, verb);
                return 1;
        } else {
                if( !mapp(trigger) ) trigger = ([ verb:replace ]);
                else if( sizeof(trigger) > MAX_TRIGGERS )
                        return notify_fail("您设定的 trigger 太多了,请先删掉一些不常用的。\n");
                else trigger[verb] = replace;
                return 1;
        }
}

mapping query_all_trigger()
{
        return trigger;
}

void disable_trigger()
{
        allow_trigger = 0;
}

void enable_trigger()
{
        allow_trigger = 1;
}

int query_trigger_enabled()
{
        return allow_trigger;
}

int fire_trigger(string pattern)
{
        string cmd,*patterns;
        int i,s;
        object me;
        
        if( !allow_trigger ) return 0;
        me = this_object();
        if( me->query_temp("parseing") ) return 0;
        if( !mapp(trigger) ) return 0;
        pattern = replace_string(pattern,"> ","");
        
        patterns = keys(trigger);
        s = sizeof(patterns);
        for(i=0;i < s;i++)
        {
        
                if( strsrch(pattern,patterns[i]) != -1 || regexp(pattern,patterns[i]) )
                {
                        cmd = trigger[patterns[i]];             
                        if( stringp(cmd) )
                        {
                                if( cmd == "$gag" ) return -999;
                                //防止有人用quit来避免死亡
                                me->check_status();
                                me->set_temp("parseing",1);             
                                tell_object(me,"触发指令:"+cmd+"\n");                  
                                me->fcommand( me->process_input(cmd) );
                                me->delete_temp("parseing");
                                return 1;
                        }       
                }
        }
        return 0;

}

发信人: yeung (流星雨), 信区: Mud_Builder       
标  题: 程序实现(3)
发信站: BBS 水木清华站 (Mon Jul 26 07:05:18 1999)


/include/globals.h的改动
加一个
#define F_TRIGGER "/feature/trigger"

/std/char.c的改动.
加一个
inherit F_TRIGGER;

/feature/message.c的改动

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( stringp(msg) )
        {
                //支持server-side trigger
                if( (this_object()->fire_trigger(msg)) == -999) return;
        }
        
        if( in_input(this_object()) || in_edit(this_object()) ) {
                if( sizeof(msg_buffer) < MAX_MSG_BUFFER )
                        msg_buffer += ({ msg });
        } else
                receive( msg );
}

发信人: yeung (流星雨), 信区: Mud_Builder       
标  题: 关于以上文档的声明
发信站: BBS 水木清华站 (Mon Jul 26 07:07:54 1999)


未经许可不得用于商业用途.
非盈利性组织可以基于GNU的精神随意修改及使用上述文档,但是请注明原作者.
作者:YEUNG 

尊重作者 转载请注明出处52mud.com

收藏 推荐 打印 | 录入:sbso | 阅读:
相关内容      
内容推送
52mud提供
一起回忆泥巴游戏QQ群68186072
52mud官方微信公众平台
热门评论