功能新增: 各类对象的group属性,新增组、子组概念,用于快速成组操作对象。组可以包括子组,子组可以再包括子组。 组名以点号.分隔,例如:group1.subgroup1.subsubgroup1。组的层级没有限制。 组的概念可以用于快速处理多个对象,例如启用/禁用一组对象、删除一组对象等。例如,以下几个组的关系:
功能新增: 新增了deleteGroup函数,用于删除指定的对象组。可同时指定组名、是否包含子组名、有效类型范围。函数定义和示例代码如下:
def deleteGroup(self, group: str, subgroup = True, types: Union[Type, Union[Tuple, List]] = (Alias, Trigger, Command, Timer, GMCPTrigger)): pass # 各参数含义: # group: 要删除的组名,可以是完整的组名,也可以是部分组名。例如:"group1" 或 "group1.subgroup1" 等。 # subgroup: 是否包含子组。如果为True,则删除指定组及其所有子组的对象。如果为False,则仅删除指定组的对象,不包括子组。 # types: 要删除的对象类型范围。可以是单个类型,也可以是类型的元组或列表。例如:Trigger, Alias, Command, Timer, GMCPTrigger 等。 # 示例代码: # 删除所有属于group1的Trigger和Alias对象,包括子组如 group1.subgroup1 和 group1.subgroup2 等 self.session.deleteGroup("group1", True, [Trigger, Alias]) # 删除所有属于group1的Trigger对象,但不包括子组 self.session.deleteGroup("group1", False, [Trigger])
功能新增: 对 #trigger, #alias, #timer, #gmcp, #command, #t+, #t- 等命令新增了组处理选项,用于对整组对象进行处理。各命令的语法格式类似。 处理组时,组名应以大于号>或者等于号=开头,紧跟组名(无空格)。当使用>时,表示操作针对当前组及所有所属子组,当使用=时,表示操作仅针对当前组。 例如下面代码:
#t+ >group1 表示启用所有属于group1以及其子组的所有可管理对象,包括Trigger、Alias、Command、Timer、GMCPTrigger #t- =group1.subgroup1 表示禁用所有仅属于group1.subgroup1的Trigger、Alias、Command、Timer、GMCPTrigger等对象 #tri >group1 off 表示禁用所有属于group1以及其子组的Trigger对象 #ali =group1.subgroup1 on 表示启用所有仅属于group1.subgroup1的Alias对象
功能新增: 调整了enableGroup处理,可以通过组名支持子组操作,也可以指定有效类型范围。例如下面代码:
class MyTestConfig(IConfig): def __init__(self, session, *args, **kwargs): self._objs = [ Trigger(session, "tri1", group = "group1"), Trigger(session, "tri2", group = "group1.subgroup1"), Trigger(session, "tri3", group = "group1.subgroup2"), Alias(session, "alias1", group = "group1"), Alias(session, "alias2", group = "group1.subgroup1"), Timer(session, 5, group = "group1.subgroup1") ] #以下调用可以同时禁用上述6个对象,因为 group1.subgroup1 和 group1.subgroup2 都属于 group1 的子组 session.enableGroup("group1", False) #以下调用可以同时仅启用触发器tri1和别名alias1,因为通过subgroup参数限定了不传递到子组 session.enableGroup("group1", True, subgroup = False) # 以下调用可以同时禁用对应发器和别名,但不禁用定时器,因为通过types参数指定了有效范围: session.enableGroup("group1.subgroup1", False, types = [Trigger, Alias])
功能新增: 增加了多处异常追踪提示。在模块或插件的脚本中发生错误时,均会打印错误追踪信息,方便定位错误。
功能新增: 新增了两个装饰器,@exception和@async_exception,用于捕获异常并调用session.error进行显示。@exception用于捕获同步异常,@async_exception用于捕获异步异常。参考如下:
from pymud import Command, Trigger, IConfig, exception, async_exception class MyCustomCommand(Command, IConfig): @exception def a_sync_routine(self, args: list[str]): # 这里的代码抛出的异常会被self.session.error捕获并显示 something_that_may_raise_an_exception() @async_exception async def execute(self, args: list[str]): # 这里的代码抛出的异常会被self.session.error捕获并显示 await something_that_may_raise_another_exception() # 上述代码相当于以下代码 class MyCustomCommand(Command, IConfig): def a_sync_routine(self, args: list[str]): try: something_that_may_raise_an_exception() except Exception as e: self.session.error(error_msg_of_e) async def execute(self, args: list[str]): try: await something_that_may_raise_another_exception() except Exception as e: self.session.error(error_msg_of_e)
功能新增: Session类新增waitfor函数,用于执行一段代码后立即等待某个触发器的情况,简化原三行代码写法
# 原来为确保await triggered的任务在输入前等待,有时候需要这么写: task = self.create_task(self.tri1.triggered()) await asyncio.sleep(0.05) self.session.writeline('dazuo') await task # 现在可以一句话简写: await self.session.waitfor('dazuo', self.create_task(self.tri1.triggered()))
功能调整: Session类的addTriggers等方法接受的dict中,会将对象本身id作为会话处理id。当该id与key不一致时,会同时显示警告。
功能新增: Session类新增addObject, addObjects, delObject, delObjects用于操作别名、定时器、触发器、GMCP触发器、命令等对象。
# 所有对象均可以使用 delObject 直接从会话中移除,会自动根据对象类型推断,无需通过函数名区分 session.delObject(self.tri1) session.delObject(self.ali1) session.delObject(self.timer1) objs = [ Trigger(session, xxx, xxx), Alias(session, xxx), SimpleCommand(session, xxx), Timer(session, xxx), GMCPTrigger(session, xxx) ] session.delObjects(objs) # 可以直接从会话中移除一个数组中的所有对象,会自动判断对象类别
功能新增: Session类型新增idletime属性,可以获取本会话发呆秒数(float类型)。当会话处于未连接状态时,返回 -1。可以利用定时器,在其中检测 idletime 值,以在机器人出错后处理恢复
本版对模块功能进行了整体调整,支持加载/卸载/重载/预加载多个模块,具体内容如下:
一个新的修改后的pymud.cfg示例如下
{ "sessions": { "pkuxkx" : { "host" : "mud.pkuxkx.net", "port" : "8081", "encoding" : "utf8", "autologin" : "{0};{1}", "default_script": ["pkuxkx.common", "pkuxkx.commands", "pkuxkx.main"], "chars" : { "char1": ["yourid1", "yourpassword1"], "char2": ["yourid2", "yourpassword2", "pkuxkx.wudang"], "char3": ["yourid3", "yourpassword3", "pkuxkx.wudang,pkuxkx.lingwu"], "char4": ["yourid4", "yourpassword4", ["pkuxkx.shaolin","pkuxkx.lingwu"]] } } } }
问题修复:修复enableGroup中定时器处的bug
功能新增:新增插件(Plugins)功能。将自动读取pymud模块目录的plugins子目录以及当前脚本目录的plugins子目录下的.py文件,若发现遵照插件规范脚本,将自动加载该模块到pymud。可以使用#plugins查看所有被加载的插件,可以直接带参数插件名(如#plugins myplugin)查看插件的详细信息(自动打印插件的doc属性,即写在文件最前面的字符串常量)插件文件中必须有以下定义:
名称 | 类型 | 状态 | 含义 |
---|---|---|---|
PLUGIN_NAME | str | 必须有 | 插件唯一名称 |
PLUGIN_DESC | dict | 必须有 | 插件描述信息的详情,必要关键字包含VERSION(版本)、AUTHOR(作者)、RELEASE_DATE(发布日期)、DESCRIPTION(简要描述) |
PLUGIN_PYMUD_START | func(app) | 函数定义必须有,函数体可以为空 | PyMUD自动读取并加载插件时自动调用的函数, app为PyMudApp(PyMUD管理类)。该函数仅会在程序运行时,自动加载一次 |
PLUGIN_SESSION_CREATE | func(session) | 函数定义必须有,函数体可以为空 | 在会话中加载插件时自动调用的函数, session为加载插件的会话。该函数在每一个会话创建时均被自动加载一次 |
PLUGIN_SESSION_DESTROY | func(session) | 函数定义必须有,函数体可以为空 | 在会话中卸载插件时自动调用的函数, session为卸载插件的会话。卸载在每一个会话关闭时均被自动运行一次。 |
PLUGIN_PYMUD_DESTROY | func(app) | 函数定义必须有,函数体可以为空 | 在PyMUD程序退出时自动调用的函数, app为PyMUD管理类。该函数仅会在程序运行时,自动卸载一次 |
首次发布到pip。