消息外部函数

337阅读 0评论2010-06-29 toughie
分类:LINUX

message() 是 MudOS 中, 新设计的外部函数 (efun). 此函数的用途是使消息传递更简易, 并提供消息处理程序沟通的标准.

  以下是 message 的使用说明:

void message( mixed class, string message, mixed targets, mixed exclude );

无返回值 message( 混合 class, 字符串 message, 混合 targets, 混合 exclude );

  message() 调用任何接收消息之物件里面的 receive_message( 混合 class, 字符串 message ) 函数 (target 名单就是接收消息的物件).而 exclude 中列出不予接收消息的物件. 基本上, 这样会送消息给目标物件.

  message 就是要传达的消息字符串.

  class 是消息的种类 (给消息处理程序或其他程序分类用) 一些例子像是: combat (战斗)、shout (呐喊)、emergency (危急) 等等.

  target 是接收消息的物件名单. 可以是一个物件文件名称的字符串, 也可以是一个物件指针 (pointer), 亦可以是多个物件的文件名称或指针的数组 (array).

  exclude 是不可收到消息的物件名单. 可以是一个物件指针或是多个物件指针的数组.

  message() 函数最重要的地方应该是 class 参数. 如果能正确使用它, 您可以作出一个简单的耳罩以过滤消息, 或是让消息处理程序加以处理. class 定义了message 字符串消息的分类为何. 一开始简单的分类应包括 shout (呐喊)、say (谈话)、write (显示)、tell_object (给物件的消息) (tell_object 由模拟外部函数 (simul_efun) 中的 tell_object() 函数产生, 代替传统的外部函数).

  谈到这里, 您大概想要马上作出一个简单的耳罩功能 (过滤呐喊的功能). 在您的使用者 (玩家) 物件中, 您要有 receive_message() 函数. 以下是一个最简单的作法 (随您 mudlib 不同, 应作出一些修正以符合实际情况) :
void receive_message (string msg, mixed class) 
{
receive(msg);
}
  这样只是收到 message() 送来的所有的消息, 并原封不动显示给使用者. 但是, 您可以想到一个简单的耳罩:
/* 先初始化 muffle 数组的值, 以预防 muffle 没有东西时, 
让 member_array() 产生数组指向错误的消息. */

string *muffle = ({});

// 调用 muffle_class() 可以随时加上耳罩的种类.

int muffle_class ( string arg )
{
muffle += ({ arg });
}

/* receive_message() 是 message() 调用的消息处理函数.
在此检查 muffle 数组中是否有跟 class 相同的种类, 没有就放行. */

void receive_message ( string msg, string class )
{
if ( member_array( class, muffle ) == -1 ) receive(msg);
}
  您现在可以看到, 如果特定种类的消息被消音 (假设是「呐喊」), 则呐喊的消息永远不会显示出来, 其他种类的消息则正常显示.

  可是, 在传统的 mud 观念中, 并非所有使用 shout() 的消息都是呐喊. 譬如说, mud 系统管理员想对所有的使用者宣布 mud 将于五分钟后关闭. 如此一来, 可能会用 echo 指令. 而 echo 指令又使用 shout(). 如此导致使用呐喊耳罩的使用者听不见重要的消息. 这种情形表示消息还需要再分类. 所以, 我们乾脆把这种消息归类为新的 broadcast (广播) 分类. 而这种分类就用于每一个人都该听到的重要消息. 甚至应限制使用者使用广播耳罩.

  让我们看看另一个例子. 如果您对于塞满你萤幕的表情语句 (emotes) 感到厌烦的话, 该怎麽办? 要是有个表情消息的耳罩该有多好? 很显然, 我们需要把这些消息归类为 emote (表情). 现在您也许会想到: 「喂....我可不想在每次写这种表情指令的时候, 还要用那个超级复杂的 message() 函数。像 write() 和 say() 就很简单, 我宁愿用这些。」好吧, 我也同意您的话. 要对付这个问题, 我将一般会用到的消息种类写成个别的模拟外部函数 (simul_efun). 我新写了一个名为 emote() 的模拟外部函数, 让这些指令写起来要方便多了. 而emote() 函数使用 message() 传达 emote 种类的消息. 我不把程序给您, 以下是基本的概念:
varargs int emote (object emoter, 
string self_message, string other_message, mixed emotee,
string target_message, string modifier);
emoter - 作出表情的物件.
self_message - 作出表情的物件本身收到的消息.
other_message - 整个房间其他人收到的消息.
emotee - 传达表情消息的对象 (例如 kick huthar)
target_message - 对象收到的消息.
  modifier - 任何加在消息尾端的修饰词. (像是副词: smile happily, cheerfully 等等) - 这只有很复杂的表情指令用得到 (如果您想让一个表情指令能有多个修饰词的话). (译按: 这是英文的文法, 与中文文法不同)

  在此, 有些人可能会想到: 「好....你可以作出功能强大的多用途耳罩,厉害。不过这玩意儿看来没啥用处。」说得好, 目前您只能利用耳罩过滤一些消息而已. 有的人有办法写出聪明的消息处理程序, 才是下面介绍的 message() 真正好处. 以下是实际的作法:

  基本上, 要把传递给使用者的消息按照内容分类. 所以假设您有一个 combat 分类、一个 stat (语句) 分类、一个 room_description (房间描述) 分类、一个 help (求助资料) 分类. 在开始之前, 我们来写一个新的 receive_message().
int has_smart_client; 
void receive_message (string msg, string class)
{
if (member_array(class,muffle) == -1) {
if (has_smart_client) receive (class + " : " + msg);
else receive (msg);
}
}
  好. 我们来看看这些在作什么. 如果一个使用者物件定义了 has_smart_client > 0, 则所有的消息前面都会加上分类名称. 所以, 如果您想写一个聪明的消息处理程序分析所有的消息, 您可以把房间语句放在一个视窗里, 谈话放在另一个视窗, 战斗消息摆在另一个视窗, 以此类推. 您甚至可以摆一个状态列, 用来显示目前身处的房间名称 (因为您进入房间时, 收到一个 room_name (房间名称) 分类的消息). 您可以利用 heart_beat() 函数, 在状态列中显示目前的体力. 这些分类的消息都可以用这种方式显示给终端的使用者.

  您甚至可以使用此方法写出一个简单的图形介面的用户端程序. BSX 图形 mud 与用户端程序可以用 MudOS 的 message() 函数在内部工作. 您也可以传输一张小的点阵图案 (bitmap) 代替 BSX 的多边形线条绘图 (polygon-based line drawing). message() 的用途极广.

  但是以上所谈的事情之中, 至少有个大问题在里面. 既然每个人都要自己撰写程序处理这些消息, 也没有人写出这麽好的用户端程序 (client) 以发挥这些消息分类的长处. 一旦消息处理程序写出来了, 您的 mudlib 又凭什么保证能与此程序配合? 好吧, 这就是这份说明文件的重点所在. 我希望能概略介绍一个简单的消息协议让大家接受, 如果用户端程序哪一天真的写出来了, 只要您的 mudlib 符合以下的协议即可.

  消息协议:

  所有传递给聪明用户端程序的消息格式如下:

  "class:msg_length:msg"

  msg_len 是 msg 字符串的长度. 加上这个可以让用户端程序知道消息到底传送完毕了没.

  使用底下的分类清单, 使用户端程序分析并使用这些分类的消息.
say             使用 say 指令 
shout 使用 shout 指令
tell 使用 tell 指令
emote 表情指令
broadcast 对每一个人广播的消息
combat 普通的战斗消息
combat_self 使用者自己产生的战斗消息
combat_other 别人产生的战斗消息
combat_* 其他特定的战斗消息
room_description 房间或地点的长语句
room_name 房间的简短名称
inventory 您身上带着的东西
item_description 物品的语句
status 普通的状态消息
status_hp 目前的体力
status_sp 目前的法力
status_sobriety 目前的酒醉状况
status_* 其他的状态
score 普通的总评消息
score_exp 经验值
score_money 金钱或其他货币的数量
developer 对所有巫师或发展程序者广播
class_fighter 给全体战士的消息
class_mage 给全体法师的消息
class_thief 给全体贼的消息
class_priest 给全体主教的消息
class_* 给其他职业全体的消息
race_human 给全体人类的消息
race_elf 给全体精灵的消息
race_dwarf 给全体矮人的消息
race_* 给其他种族全体的消息

*** 其他内部的选项 ***
bitmap 普通的点阵图
bitmap_* 特定的点阵图
drawing 普通的绘图
drawing_* 特定类型的绘图
上一篇:中阶 LPC
下一篇:MUD中安全谈