訊息處理函式 (message document)


message() 訊息處理函式


message() 是 MudOS 中, 新設計的外部函式 (efun). 此函式的用途是使訊息傳遞更簡易, 並提供訊息處理程式溝通的標準.

以下是 message 的使用說明:


語法: 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 不同, 應作出一些修正以符合實際情況) :

這樣只是收到 message()  送來的所有的訊息, 並原封不動顯示給使用者. 但是, 您可以想到一個簡單的耳罩:

/* 先初始化 muffle 陣列的值, 以預防 muffle 沒有東西時, 讓 member_array() 產生陣列指向錯誤的訊息. */

// 呼叫 muffle_class() 可以隨時加上耳罩的種類. /* receive_message() 是 message() 呼叫的訊息處理函式. 在此檢查 muffle 陣列中是否有跟 class 相同的種類, 沒有就放行. */
  您現在可以看到, 如果特定種類的訊息被消音 (假設是「吶喊」), 則吶喊的訊息永遠不會顯示出來, 其他種類的訊息則正常顯示.

可是, 在傳統的 mud 觀念中, 並非所有使用 shout() 的訊息都是吶喊. 譬如說, mud 系統管理者想對所有的使用者宣佈 mud 將於五分鐘後關閉. 如此一來, 可能會用 echo 指令. 而 echo 指令又使用 shout(). 如此導致使用吶喊耳罩的使用者聽不見重要的訊息. 這種情形表示訊息還需要再分類. 所以, 我們乾脆把這種訊息歸類為新的 broadcast (廣播) 分類. 而這種分類就用於每一個人都該聽到的重要訊息. 甚至應限制使用者使用廣播耳罩.

讓我們看看另一個例子. 如果您對於塞滿你螢幕的表情敘述 (emotes) 感到厭煩的話, 該怎麼辦 ? 要是有個表情訊息的耳罩該有多好 ? 很顯然, 我們需要把這些訊息歸類為 emote (表情).  現在您也許會想到: 「喂....我可不想在每次寫這種表情指令的時候, 還要用那個超級複雜的 message() 函式。像 write() 和 say() 就很簡單, 我寧願用這些。」好吧, 我也同意您的話. 要對付這個問
題, 我將一般會用到的訊息種類寫成個別的模擬外部函式 (simul_efun) . 我新寫了一個名為 emote() 的模擬外部函式, 讓這些指令寫起來要方便多了. 而emote() 函式使用 message() 傳達 emote 種類的訊息. 我不把程式給您, 以下是基本的概念:

emoter - 作出表情的物件.
self_message - 作出表情的物件本身收到的訊息.
other_message -  整個房間其他人收到的訊息.
emotee - 傳達表情訊息的對象 (例如 kick huthar)
target_message - 對象收到的訊息.
string modifier - 任何加在訊息尾端的修飾詞. (像是副詞: smile happily, cheerfully  等等) - 這只有很複雜的表情指令用得到 (如果您想讓一個表情指令能有多個修飾詞的話). (譯按: 這是英文的文法, 與中文文法不同)

在此, 有些人可能會想到: 「好....你可以作出功能強大的多用途耳罩,厲害。不過這玩意兒看來沒啥用處。」說得好, 目前您只能利用耳罩過濾一些訊息而已. 有的人有辦法寫出聰明的訊息處理程式, 才是下面介紹的 message() 真正好處. 以下是實際的作法:

基本上, 要把送給使用者的訊息按照內容分類. 所以假設您有一個 combat 分類、一個 stat (敘述) 分類、一個 room_description (房間描述) 分類、一個 help (求助資料) 分類. 在開始之前, 我們來寫一個新的 receive_message().

好. 我們來看看這些在作什麼. 如果一個使用者物件定義了 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_*  特定型態的繪圖


翻譯: Spock @ FF 97.Aug.8.

回到上一頁