每当网络速度太慢而导致你的指令无法及时送出的时候,你一定会有
把机器砸掉的冲动,尤其是看到屏幕突然不动,等传过来的时候已经
在黄泉路上,实在是很不爽的一种事情.
基于这种考虑,我们提出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