通信


除了在游戏世界中四处走动交谈,玩家可能还需要其他的通信形式。Evennia的通信系统可以提供这些功能。默认的Evennia实现了“类MUX”的频道系统,但你也可以修改它使它更好地符合你的要求。

通信主要依靠两种数据库对象:消息(Msg)和频道(Channel)。还有一种临时消息(TempMsg),它的API和消息类似,但没有和数据库相连。


消息

消息对象是Evennia通信的基本单元。消息的工作方式有点像电子邮件,它总有一个发送者(玩家)和一个或多个接收者。接收者可以是其他玩家,也可以是频道(见下文)。只要你喜欢,你还可以把玩家和频道同时列为接收者。

一旦创建,消息通常不会改变,它会一直保存在数据库中。因此可以对通信做记录,不仅在频道中,还可以让发送者或接收者在“邮箱”中保存所需的消息。

定义在消息上的属性
  • senders —— 这指向发送该消息的一个或多个玩家物体(通常是角色)。这也可以是外部连接,比如来自 IRC/IMC2 的消息(见下文)。发送者通常只有一个,但也可以是各种类型的组合。
  • receivers —— 发送消息的目标列表,可以是玩家物体(通常是角色)或频道。接收者可以是各种类型的组合。
  • header —— 最大128个字符。可以用来存储该消息的 mime 类型信息(如邮件或网页),但在游戏中你也可以拿它来存储主题行或其他想要传送的头部信息。作为索引字段,它也可以用于数据库的快速搜索。
  • message —— 发送的实际文本。
  • date_sent —— 消息的发送时间(自动创建)。
  • locks —— 定义
  • hide_from —— 这可以向指定的物体、玩家或频道屏蔽该消息。把它存储在数据库中主要是出于优化的考虑,可以快速过滤掉不需要发送给目标的消息。在游戏中不能设置这项内容,只能在代码中设置。
在代码中你可以使用 ev.create_message(或src.utils.create.create_message)创建新消息。


临时消息

src.comms.models 中有一个叫 TempMsg 的类,它模仿了消息的API但没有连接到数据库。在默认情况下不会使用它,但你可以在代码中用它发送非持久性的消息到需要信息对象的地方(如频道,见下一节的例子)。


频道

频道是类型类的实例,因此可以很容易地扩展或修改它们的功能。设置 settings.BASE_CHANNEL_TYPECLASS 可以更改Evennia所使用的频道类型类。

频道担当了消息的分发者。可以把它们看成是重新分配消息对象的“开关板”。在内部,它们有一个“监听器”对象列表,任何发送给频道的消息(或临时消息)都会被分发给所有频道的监听器。频道的可以限制哪些人能通过它们收听或发送消息。

在默认的Evennia中有三个默认频道 —— MUDinfo、MUDconnections和Public。前两个与服务器相关,供管理员使用,最后一个是开放给所有人聊天用的(所有新玩家在登录时都会自动加入它,可以用于解答问题)。默认创建的频道由 settings.CHANNEL_PUBLIC、settings.CHANNEL_MUDINFO 和 settings.CHANNEL_CONNECTINFO 指定。

你可以用 ev.create_channel(或src.utils.create.create_channel)创建新频道。

在代码中,可以用频道的 msg 或 tempmsg 方法向频道发消息:
 channel.msg(msgobj, header=None, senders=None, persistent=True)
参数 msgobj 可以是字符串,也可以是之前创建的消息或临时消息。如果是后一种,后面的关键字参数都会被忽略。如果 msgobj 是字符串,会和其它关键字结合在一起即时创建一个新的消息或临时消息,是消息还是临时消息取决于 persistent。频道通信中默认使用的是临时消息(即不保存到数据库)。
    #假定我们有一个“sender”对象和一个名为“mychan”的频道

    #发送并在数据库中存储消息
    from src.utils import create
    mymsg = create.create_message(sender, "Hello!", channels=[mychan])
    #直接使用消息对象,不需要其它关键字
    mychan.msg(mymsg)

    #向频道发送非持久性的消息
    mychan.msg("Hello!", senders=[sender])

    #将消息发送给列表,将它保存到数据库中
    #(请注意如果只有一个发送者而没有列表,
    #关键字senders是如何使用的)
    mychan.msg("Hello!", senders=sender, persistent=True)
有一个进阶注释:当玩家输入如 ooc Hello! 之类的东西时(其中 ooc 是频道的名称或别名),它会被Evennia当作系统命令来处理。通过用你自己的代码重新定义系统命令,你可以完全改变它的工作方式。详细信息请参见命令

定义在频道上的属性
  • key —— 频道的名称
  • aliases —— 频道的其它名称
  • desc —— 可选的频道说明(可以在列表中看到)
  • keep_log(布尔) —— 频道是否应该保存消息(默认)
  • locks —— 定义。频道通常用访问类型来控制发送、管理和监听的权限。


(原文:https://github.com/evennia/evennia/wiki/Communications    翻译:卢铱俊)