📄 message_doc.html
字号:
<HTML>
<HEAD>
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=bg2312">
<META NAME="Author" CONTENT="Spock">
<META NAME="GENERATOR" CONTENT="Mozilla/4.01 [en] (Win95; I) [Netscape]">
<TITLE>MudOS v21c2 参考文件 - concepts - message_doc</TITLE>
</HEAD>
<BODY TEXT="#CCFFFF" BGCOLOR="#000000" LINK="#33FF33" VLINK="#FF0000" ALINK="#33CCFF" BACKGROUND="../../image/ff/fftitleback.jpg" NOSAVE>
<CENTER>
<H1>
<FONT COLOR="#FF99FF">消息处理函数 (message document)</FONT></H1></CENTER>
<CENTER>
<HR WIDTH="100%"></CENTER>
<CENTER><FONT COLOR="#FFFFCC">message() 消息处理函数</FONT></CENTER>
<HR WIDTH="100%">
<BR>message() 是 MudOS 中, 新设计的外部函数 (efun). 此函数的用途是使消息传递更简易,
并提供消息处理程序沟通的标准.
<P>以下是 message 的使用说明:
<BR>
<HR WIDTH="100%">语法:
<UL><FONT COLOR="#FFCC99">void message( mixed class, string message, mixed
targets, mixed exclude);</FONT>
<P><FONT COLOR="#FFCC99">无返回值 message( 混合 class, 字符串 message, 混合
targets, 混合 exclude );</FONT></UL>
message() 调用任何接收消息之物件里面的 receive_message( 混合 class, 字符串
message ) 函数 (target 名单就是接收消息的物件).而 exclude 中列出不予接收消息的物件.
基本上, 这样会送消息给目标物件.
<P>message 就是要传达的消息字符串.
<P>class 是消息的种类 (给消息处理程序或其他程序分类用) 一些例子像是: combat
(战斗)、shout (呐喊)、emergency (危急) 等等.
<P>target 是接收消息的物件名单. 可以是一个物件文件名称的字符串, 也可以是一个物件指针
(pointer), 亦可以是多个物件的文件名称或指针的数组 (array).
<P>exclude 是不可收到消息的物件名单. 可以是一个物件指针或是多个物件指针的数组.
<BR>
<HR WIDTH="100%">
<BR>message() 函数最重要的地方应该是 class 参数. 如果能正确使用它, 您可以作出一个简单的耳罩以过滤消息,
或是让消息处理程序加以处理. class 定义了message 字符串消息的分类为何. 一开始简单的分类应包括
shout (呐喊)、say (谈话)、write (显示)、tell_object (给物件的消息) (tell_object
由模拟外部函数 (simul_efun) 中的 tell_object() 函数产生, 代替传统的外部函数).
<P>谈到这里, 您大概想要马上作出一个简单的耳罩功能 (过滤呐喊的功能). 在您的使用者
(玩家) 物件中, 您要有 receive_message() 函数. 以下是一个最简单的作法 (随您
mudlib 不同, 应作出一些修正以符合实际情况) :
<UL><FONT COLOR="#99FF99">void receive_message (string msg, mixed class)</FONT>
<BR><FONT COLOR="#99FF99">{</FONT>
<UL><FONT COLOR="#99FF99">receive(msg);</FONT></UL>
<FONT COLOR="#99FF99">}</FONT></UL>
这样只是收到 message() 送来的所有的消息, 并原封不动显示给使用者. 但是,
您可以想到一个简单的耳罩:
<P>/* 先初始化 muffle 数组的值, 以预防 muffle 没有东西时, 让 member_array()
产生数组指向错误的消息. */
<UL><FONT COLOR="#99FF99">string *muffle = ({});</FONT></UL>
// 调用 muffle_class() 可以随时加上耳罩的种类.
<UL><FONT COLOR="#99FF99">int muffle_class ( string arg )</FONT>
<BR><FONT COLOR="#99FF99">{</FONT>
<UL><FONT COLOR="#99FF99">muffle += ({ arg });</FONT></UL>
<FONT COLOR="#99FF99">}</FONT></UL>
/* receive_message() 是 message() 调用的消息处理函数. 在此检查 muffle 数组中是否有跟
class 相同的种类, 没有就放行. */
<BR>
<UL><FONT COLOR="#99FF99">void receive_message ( string msg, string class
)</FONT>
<BR><FONT COLOR="#99FF99">{</FONT>
<UL><FONT COLOR="#99FF99">if ( member_array( class, muffle ) == -1 )</FONT>
<UL><FONT COLOR="#99FF99">receive(msg);</FONT></UL>
</UL>
<FONT COLOR="#99FF99">}</FONT></UL>
您现在可以看到, 如果特定种类的消息被消音 (假设是「呐喊」), 则呐喊的消息永远不会显示出来,
其他种类的消息则正常显示.
<P>可是, 在传统的 mud 观念中, 并非所有使用 shout() 的消息都是呐喊. 譬如说,
mud 系统管理员想对所有的使用者宣布 mud 将于五分钟后关闭. 如此一来, 可能会用
echo 指令. 而 echo 指令又使用 shout(). 如此导致使用呐喊耳罩的使用者听不见重要的消息.
这种情形表示消息还需要再分类. 所以, 我们乾脆把这种消息归类为新的 broadcast
(广播) 分类. 而这种分类就用于每一个人都该听到的重要消息. 甚至应限制使用者使用广播耳罩.
<P>让我们看看另一个例子. 如果您对于塞满你萤幕的表情语句 (emotes) 感到厌烦的话,
该怎麽办 ? 要是有个表情消息的耳罩该有多好 ? 很显然, 我们需要把这些消息归类为
emote (表情). 现在您也许会想到: 「喂....我可不想在每次写这种表情指令的时候,
还要用那个超级复杂的 message() 函数。像 write() 和 say() 就很简单, 我宁愿用这些。」好吧,
我也同意您的话. 要对付这个问
<BR>题, 我将一般会用到的消息种类写成个别的模拟外部函数 (simul_efun) . 我新写了一个名为
emote() 的模拟外部函数, 让这些指令写起来要方便多了. 而emote() 函数使用
message() 传达 emote 种类的消息. 我不把程序给您, 以下是基本的概念:
<UL><FONT COLOR="#99FF99">varargs int emote (object emoter, string self_message,
string</FONT>
<UL><FONT COLOR="#99FF99">other_message, mixed emotee, string target_message,
string modifier);</FONT></UL>
</UL>
emoter - 作出表情的物件.
<BR>self_message - 作出表情的物件本身收到的消息.
<BR>other_message - 整个房间其他人收到的消息.
<BR>emotee - 传达表情消息的对象 (例如 kick huthar)
<BR>target_message - 对象收到的消息.
<BR>string modifier - 任何加在消息尾端的修饰词. (像是副词: smile happily,
cheerfully 等等) - 这只有很复杂的表情指令用得到 (如果您想让一个表情指令能有多个修饰词的话).
(译按: 这是英文的文法, 与中文文法不同)
<P>在此, 有些人可能会想到: 「好....你可以作出功能强大的多用途耳罩,厉害。不过这玩意儿看来没啥用处。」说得好,
目前您只能利用耳罩过滤一些消息而已. 有的人有办法写出聪明的消息处理程序,
才是下面介绍的 message() 真正好处. 以下是实际的作法:
<P>基本上, 要把传递给使用者的消息按照内容分类. 所以假设您有一个 combat 分类、一个
stat (语句) 分类、一个 room_description (房间描述) 分类、一个 help (求助资料)
分类. 在开始之前, 我们来写一个新的 receive_message().
<UL><FONT COLOR="#99FF99">int has_smart_client;</FONT>
<P><FONT COLOR="#99FF99">void receive_message (string msg, string class)</FONT>
<BR><FONT COLOR="#99FF99">{</FONT>
<UL><FONT COLOR="#99FF99">if (member_array(class,muffle) == -1) {</FONT>
<UL><FONT COLOR="#99FF99">if (has_smart_client)</FONT>
<UL><FONT COLOR="#99FF99">receive (class + " : " + msg);</FONT></UL>
<FONT COLOR="#99FF99">else</FONT>
<UL><FONT COLOR="#99FF99">receive (msg);</FONT></UL>
</UL>
<FONT COLOR="#99FF99">}</FONT></UL>
<FONT COLOR="#99FF99">}</FONT></UL>
好. 我们来看看这些在作什么. 如果一个使用者物件定义了 has_smart_client >
0, 则所有的消息前面都会加上分类名称. 所以, 如果您想写一个聪明的消息处理程序分析所有的消息,
您可以把房间语句放在一个视窗里, 谈话放在另一个视窗, 战斗消息摆在另一个视窗,
以此类推. 您甚至可以摆一个状态列, 用来显示目前身处的房间名称 (因为您进入房间时,
收到一个 room_name (房间名称) 分类的消息) . 您可以利用 heart_beat() 函数,
在状态列中显示目前的体力. 这些分类的消息都可以用这种方式显示给终端的使用者.
<P>您甚至可以使用此方法写出一个简单的图形介面的用户端程序. BSX 图形 mud
与用户端程序可以用 MudOS 的 message() 函数在内部工作. 您也可以传输一张小的点阵图案
(bitmap) 代替 BSX 的多边形线条绘图 (polygon-based line drawing). message()
的用途极广.
<P>但是以上所谈的事情之中, 至少有个大问题在里面. 既然每个人都要自己撰写程序处理这些消息,
也没有人写出这麽好的用户端程序 (client) 以发挥这些消息分类的长处. 一旦消息处理程序写出来了,
您的 mudlib 又凭什么保证能与此程序配合 ? 好吧, 这就是这份说明文件的重点所在.
我希望能概略介绍一个简单的消息协议让大家接受, 如果用户端程序哪一天真的写出来了,
只要您的 mudlib 符合以下的协议即可.
<P>消息协议:
<P>所有传递给聪明用户端程序的消息格式如下:
<P>"class:msg_length:msg"
<P>msg_len 是 msg 字符串的长度. 加上这个可以让用户端程序知道消息到底传送完毕了没.
<P>使用底下的分类清单, 使用户端程序分析并使用这些分类的消息.
<P>say 使用 say 指令
<BR>shout 使用 shout 指令
<BR>tell 使用 tell 指令
<BR>emote 表情指令
<BR>broadcast 对每一个人广播的消息
<BR>combat 普通的战斗消息
<BR>combat_self 使用者自己产生的战斗消息
<BR>combat_other 别人产生的战斗消息
<BR>combat_* 其他特定的战斗消息
<BR>room_description 房间或地点的长语句
<BR>room_name 房间的简短名称
<BR>inventory 您身上带着的东西
<BR>item_description 物品的语句
<BR>status 普通的状态消息
<BR>status_hp 目前的体力
<BR>status_sp 目前的法力
<BR>status_sobriety 目前的酒醉状况
<BR>status_* 其他的状态
<BR>score 普通的总评消息
<BR>score_exp 经验值
<BR>score_money 金钱或其他货币的数量
<BR>developer 对所有巫师或发展程序者广播
<BR>class_fighter 给全体战士的消息
<BR>class_mage 给全体法师的消息
<BR>class_thief 给全体贼的消息
<BR>class_priest 给全体主教的消息
<BR>class_* 给其他职业全体的消息
<BR>race_human 给全体人类的消息
<BR>race_elf 给全体精灵的消息
<BR>race_dwarf 给全体矮人的消息
<BR>race_* 给其他种族全体的消息
<P>*** 其他内部的选项 ***
<BR>bitmap 普通的点阵图
<BR>bitmap_* 特定的点阵图
<BR>drawing 普通的绘图
<BR>drawing_* 特定类型的绘图
<P>
<HR WIDTH="100%">
<CENTER><FONT COLOR="#FFFFCC">翻译: Spock @ FF 97.Aug.8.</FONT></CENTER>
<CENTER>
<HR WIDTH="100%"></CENTER>
<CENTER><A HREF="../concepts_index.html">回到上一页</A></CENTER>
<CENTER>
<HR WIDTH="100%"></CENTER>
</BODY>
</HTML>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -