编码工具


Evennia附带了许多实用工具,可以帮你完成常见的编码任务。其中一些是命令接口组成部分,但大多数可以在文件夹 src/utils/ 中找到。它们在服务器中广泛使用,也可以在你编写游戏时给你不少帮助。以下只列出了一部分内容,更多资源在 src/utils/ 目录下(尤其是 src/utils/utils.py)。


搜索

搜索对象是一项常用功能,最常见的是用在命令内部。在所有物体上都定义有 search 方法,用起来很方便。它可以用来搜索处在同一位置的物体以及调用者内部包含的物体。
    obj = self.caller.search(objname)
给出关键字参数 global_search=True 可以将搜索范围扩大到整个数据库。别名也同样会用于匹配搜索。在默认的命令集中可以看到很多使用该功能的例子。

如果你想在代码中搜索物体,可以使用 src.utils.search 中的函数。你可以通过快捷方式 ev.search_* 来访问它们。
    from ev import search_object
    obj = search_object(objname)
utils.search 包含了搜索数据库的相关方法,它们只是 Django 数据库搜索方法的快捷方式,如ObjectDB.objects.search()。

注意:如果你是一个 Django 高手,你可能想要直接使用 Django 的数据库搜索功能(如 filter、get 等)。请记住,这样的操作会返回Django模型,而Evennia的管理方法会返回类型类。dbobj.typeclass 和 typeclass.dbobj 很容易转换,但是你要记住有这个区别。如果你坚持使用Evennia的搜索方法,返回的总是类型类。


创建

除了在游戏中使用建造命令(如 @Create 等),你也可以用代码直接创建所有的Evennia游戏实体(比如在定义新的创建命令时)。这必须用 src.utils.create 或其快捷方式 ev.create_* 来完成,这些函数会负责创建所有幕后的东西,如类型类系统及其他的复杂东西。使用原始的 Django 直接创建数据库实例是不行的。

例子:
    import ev
    # 
    myobj = ev.create_objects("game.gamesrc.objects.myobj.MyObj",  key="MyObj")
    myscr = ev.create_script("game.gamesrc.scripts.myscripts.MyScript", obj=myobj)
    help = ev.create_help_entry("Emoting", "Emoting means that ...")
    msg = ev.create_message(senderobj, [receiverobj], "Hello ...")
    chan = ev.create_channel("news")
    player = ev.create_player("Henry", "henry@test.com", "H@passwd")
所有这些创建函数都带有许多参数用以定义创建的实体。更多信息请见 src/utils/create.py。


日志

通常你可以使用Python的print语句在终端显示内容(如果你在启动Evennia时使用 -i 开关开启了交互模式)。但这只能用于调试,想要真正的输出应该使用 logger,在交互模式下它会输出到终端,其它情况下则会记录到日志文件。
    from ev import logger
    #
    logger.log_errmsg("这是个错误!")
    logger.log_warnmsg("这是个警告!")
    logger.log_infomsg("这是普通信息。")
    logger.log_depmsg("这个功能已经被废弃了。")
有一种特殊的日志消息类型 log_trace(),它可在回溯内部使用,可以将回溯消息记录到日志中而无需关闭服务器。
    try:
        # [某段会失败的代码。。。]
    except Exception:
        logger.log_trace("这段文字会被添加到回溯信息中。")
最后是 log_file 记录,它可以用于输出任意的日志信息。它是经过优化的,使用了多线程以减少开销,所以你可以用它来记录庞大的用户日志,而不必担心磁盘写入的延迟。
 logger.log_file(message, filename="mylog.log")
日志会记录在 game/logs 目录中。如果文件已存在,则会将新内容添加到最后面。时间戳的格式和普通的Evennia日志相同,会自动添加到每个条目上。如果没有指定文件名,则会输出到文件 game/logs/game.log 中。


inherits_from()

这个函数有两个参数:一个待检测的对象和一个父类。如果对象是从父类继承的则返回true(不管它们间隔多远。它不同于Python内置的is_instance()只能判断直接的依赖关系)。这个函数的参数可以是类、实例、指向类的python路径、及它们的任何组合。

请注意,Python代码是可以处理鸭子类型的,但在Evennia中,作为一种识别的方法,有时需要检查某个对象是否是从特定的类型类继承的。比如有一个类型类 Animal(动物),它有一个子类 Felines(猫科),这个子类又是 HouseCat(家猫)的父类。也许还有一堆其他的动物种类,如马和狗。用 inherits_from 可以一步就检查出所有的动物:
    from ev import utils
    if (utils.inherits_from(obj, "game.gamesrc.objects.animals.Animal"):
        obj.msg("门卫在门口拦住了你,他说:“不允许会说话的动物进入。”")


delay()


这是对 Twisted 的 deferred 结构的简单包装。它要等待指定的秒数才会返回,并且会用指定的参数触发回调。这是一个微小的、轻量级的(非持久性的)脚本替用品。与脚本不同,它的时间精度可以达到亚秒级(虽然通常你不会用到这个功能)。


一些文本工具

在文字游戏中,你自然会做大量的文本处理工作。以下是从 src/utils/utils.py(快捷方式为 ev.utils)中选出的部分文本工具。通常,在你准备设计自己的解决工具之前,最好能先看看这里的内容。

fill()
它会将文本填充到指定宽度的区域中(移动文字使每行都一样宽)。它还能处理缩进。(目前无法正确处理中文——译者)
    outtxt = fill(intxt, width=78, indent=4)

crop()
这个函数可以截断一行很长的文字,并加上后缀以表示这一行内容实际没有结束。它可以用在列表中,在这种情况下多行显示可能会把格式弄乱。(目前无法正确处理中文——译者)
    intxt = "这是我们想裁剪的很长的文字。"
    outtxt = crop(intxt, width=20, suffix="[...]")
    # 现在 outtxt 是 "这是我们想[...]"

dedent()
它可以解决一个看似简单的文本问题:去除缩进。它可以让整个段落左移,而不会影响任何其它格式。一个常见用途是处理python代码中的三重引号字符串,它们会保留代码中的缩进,而且人们在写代码时为了便于阅读,通常不会将字符串左移到最边上。
    # python需要有指定的缩进
        intxt = """
        这是一段示例文字,在左边
        留有很多的空白。
                它本身还带有
                缩进。"""
        outtxt = dedent(intxt)
        # 现在outtxt会移向左边
        # 但内部的缩进会被保留。
dedent通常用于显示文字(比如帮助系统用它调整帮助项目)。

time_format()
这个函数将数字作为秒数输入,并将其转换为格式化的文本输出,包括天、小时等信息。如果想显示某件事务的持续时间,这会很有用的。通过 style 关键字,可以选择4种不同的输出风格:
  • style 0 - 5d:45m:12s (标准的冒号输出)
  • style 1 - 5d (只显示最长的时间单位)
  • style 2 - 5 days, 45 minutes (全格式,忽略秒)
  • style 3 - 5 days, 45 minutes, 12 seconds (全格式,带有秒)

文本转换()
Evennia提供了两个实用函数,可将文本转换为正确的编码:to_str() 和 to_unicode()。与Python内置的 str() 和 unicode() 操作不同,Evennia的转换函数会使用 ENCODINGS 的设置,而且会尽量通过日志反馈错误,而不是产生回溯。更多信息请见这里

用ascii码文本制作表格
EvTable类(src/utils/evtable.py),可用来创建正确格式的文本表格。还有一个EvForm类(src/utils/evform.py),它可以从文件读取固定格式的文本模版,用以创建各种复杂的ascii布局。evtable 和 evform 都有很多的选项和参数,查看模块的头部以获取帮助信息。

Evennia还包含了第三方的PrettyTable模块。PrettyTable是过时的用法,已被EvTable取代,因为它不能很好地处理ANSI颜色。PrettyTable可以在 src/utils/prettytable/ 找到。相关说明请看它的主页。


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