pymud 0.21.0a5__py3-none-any.whl → 0.21.2__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
pymud/session.py CHANGED
@@ -6,7 +6,7 @@ from prompt_toolkit.utils import get_cwidth
6
6
  from wcwidth import wcswidth, wcwidth
7
7
  from typing import Union, Optional, Any, List, Tuple, Dict, Type
8
8
  from .logger import Logger
9
- from .extras import SessionBuffer, DotDict
9
+ from .extras import DotDict, SessionBuffer
10
10
  from .protocol import MudClientProtocol
11
11
  from .modules import ModuleInfo, Plugin
12
12
  from .objects import BaseObject, Trigger, Alias, Command, Timer, SimpleAlias, SimpleTrigger, SimpleTimer, GMCPTrigger, CodeBlock, CodeLine
@@ -139,7 +139,7 @@ class Session:
139
139
 
140
140
  self.last_command = ""
141
141
 
142
- self.buffer = SessionBuffer()
142
+ self.buffer = SessionBuffer(self.name, newline = self.newline_cli, max_buffered_lines = Settings.client["buffer_lines"])
143
143
  self.buffer_pos_end = 0 # 标注最后位置光标指针
144
144
  self.buffer_pos_view = 0 # 标注查看位置光标指针
145
145
  self.buffer_pos_view_line = -1
@@ -218,7 +218,8 @@ class Session:
218
218
 
219
219
  def open(self):
220
220
  "创建到远程服务器的连接,同步方式。通过调用异步connect方法实现。"
221
- asyncio.ensure_future(self.connect(), loop = self.loop)
221
+ #asyncio.ensure_future(self.connect(), loop = self.loop)
222
+ self.create_task(self.connect())
222
223
 
223
224
  async def connect(self):
224
225
  "创建到远程服务器的连接,异步非阻塞方式。"
@@ -243,7 +244,8 @@ class Session:
243
244
 
244
245
  if Settings.client["auto_reconnect"]:
245
246
  wait = Settings.client.get("reconnect_wait", 15)
246
- asyncio.ensure_future(self.reconnect(wait), loop = self.loop)
247
+ #asyncio.ensure_future(self.reconnect(wait), loop = self.loop)
248
+ self.create_task(self.reconnect(wait))
247
249
 
248
250
  async def reconnect(self, timeout: float = 15):
249
251
  """
@@ -287,7 +289,8 @@ class Session:
287
289
 
288
290
  if Settings.client["auto_reconnect"]:
289
291
  wait = Settings.client.get("reconnect_wait", 15)
290
- asyncio.ensure_future(self.reconnect(wait), loop = self.loop)
292
+ #asyncio.ensure_future(self.reconnect(wait), loop = self.loop)
293
+ self.create_task(self.reconnect(wait))
291
294
 
292
295
  @property
293
296
  def connected(self) -> bool:
@@ -555,14 +558,16 @@ class Session:
555
558
  :param data: 写入的数据, 应为 str 类型
556
559
  :param newline: 是否额外增加换行符
557
560
  """
558
- self.buffer.insert_text(data)
561
+ #self.buffer.insert_text(data)
562
+ self.buffer.append(data)
559
563
  self.log.log(data)
560
564
 
561
565
  if len(data) > 0 and (data[-1] == "\n"):
562
566
  self._line_count += 1
563
567
 
564
568
  if newline:
565
- self.buffer.insert_text(self.newline_cli)
569
+ #self.buffer.insert_text(self.newline_cli)
570
+ self.buffer.append(self.newline_cli)
566
571
  self._line_count += 1
567
572
  self.log.log(self.newline_cli)
568
573
 
@@ -572,8 +577,9 @@ class Session:
572
577
 
573
578
  半数的数量由 Settings.client['buffer_lines'] 确定,默认为5000行。
574
579
  """
575
- if (Settings.client["buffer_lines"] > 0) and (self._line_count >= 2 * Settings.client["buffer_lines"]) and self.buffer.document.is_cursor_at_the_end:
576
- self._line_count = self.buffer.clear_half()
580
+ # if (Settings.client["buffer_lines"] > 0) and (self._line_count >= 2 * Settings.client["buffer_lines"]) and self.buffer.document.is_cursor_at_the_end:
581
+ # self._line_count = self.buffer.clear_half()
582
+ pass
577
583
 
578
584
  def feed_data(self, data) -> None:
579
585
  """
@@ -1200,31 +1206,31 @@ class Session:
1200
1206
  :return: 5个整数的列表,依次表示改组内操作的 别名,触发器,命令,定时器,GMCP 的个数
1201
1207
  """
1202
1208
  counts = [0, 0, 0, 0, 0]
1203
- if (Alias == types) or (isinstance(types, Union[List, Tuple]) and (Alias in types)):
1209
+ if (Alias == types) or (isinstance(types, (list, tuple)) and (Alias in types)):
1204
1210
  for ali in self._aliases.values():
1205
1211
  if isinstance(ali, Alias) and ((ali.group == group) or (subgroup and ali.group.startswith(group + "."))):
1206
1212
  ali.enabled = enabled
1207
1213
  counts[0] += 1
1208
1214
 
1209
- if (Trigger == types) or (isinstance(types, Union[List, Tuple]) and (Trigger in types)):
1215
+ if (Trigger == types) or (isinstance(types, (list, tuple)) and (Trigger in types)):
1210
1216
  for tri in self._triggers.values():
1211
1217
  if isinstance(tri, Trigger) and ((tri.group == group) or (subgroup and tri.group.startswith(group + "."))):
1212
1218
  tri.enabled = enabled
1213
1219
  counts[1] += 1
1214
1220
 
1215
- if (Command == types) or (isinstance(types, Union[List, Tuple]) and (Command in types)):
1221
+ if (Command == types) or (isinstance(types, (list, tuple)) and (Command in types)):
1216
1222
  for cmd in self._commands.values():
1217
1223
  if isinstance(cmd, Command) and ((cmd.group == group) or (subgroup and cmd.group.startswith(group + "."))):
1218
1224
  cmd.enabled = enabled
1219
1225
  counts[2] += 1
1220
1226
 
1221
- if (Timer == types) or (isinstance(types, Union[List, Tuple]) and (Timer in types)):
1227
+ if (Timer == types) or (isinstance(types, (list, tuple)) and (Timer in types)):
1222
1228
  for tmr in self._timers.values():
1223
1229
  if isinstance(tmr, Timer) and ((tmr.group == group) or (subgroup and tmr.group.startswith(group + "."))):
1224
1230
  tmr.enabled = enabled
1225
1231
  counts[3] += 1
1226
1232
 
1227
- if (GMCPTrigger == types) or (isinstance(types, Union[List, Tuple]) and (GMCPTrigger in types)):
1233
+ if (GMCPTrigger == types) or (isinstance(types, (list, tuple)) and (GMCPTrigger in types)):
1228
1234
  for gmcp in self._gmcp.values():
1229
1235
  if isinstance(gmcp, GMCPTrigger) and ((gmcp.group == group) or (subgroup and gmcp.group.startswith(group + "."))):
1230
1236
  gmcp.enabled = enabled
@@ -1232,6 +1238,46 @@ class Session:
1232
1238
 
1233
1239
  return counts
1234
1240
 
1241
+ def deleteGroup(self, group: str, subgroup = True, types: Union[Type, Union[Tuple, List]] = (Alias, Trigger, Command, Timer, GMCPTrigger)):
1242
+ """
1243
+ 删除Group中所有对象, 返回组内各对象个数。
1244
+
1245
+ :param group: 组名,即各对象的 group 属性的值
1246
+ :param subgroup: 是否对子组同时生效,默认为True。子组是指名称在父组名之后的用.xxx命名的组。例如, 组 group1.group2 是 group1 的子组。
1247
+ :param types: 要删除的对象类型,默认为 (Alias, Trigger, Command, Timer, GMCPTrigger)。
1248
+ 可以指定为单个类型,也可以指定为类型列表或元组。
1249
+ 若指定为单个类型,则只删除该类型的对象。
1250
+ 若指定为类型列表或元组,则删除该类型列表或元组中的所有类型的对象。
1251
+ :return: 5个整数的列表,依次表示改组内操作的 别名,触发器,命令,定时器,GMCP 的个数
1252
+ """
1253
+ counts = [0, 0, 0, 0, 0]
1254
+ if (Alias == types) or (isinstance(types, (list, tuple)) and (Alias in types)):
1255
+ ali_ids = [ali.id for ali in self._aliases.values() if isinstance(ali, Alias) and ((ali.group == group) or (subgroup and ali.group.startswith(group + ".")))]
1256
+ self.delAliases(ali_ids)
1257
+ counts[0] = len(ali_ids)
1258
+
1259
+ if (Trigger == types) or (isinstance(types, (list, tuple)) and (Trigger in types)):
1260
+ tri_ids = [tri.id for tri in self._triggers.values() if isinstance(tri, Trigger) and ((tri.group == group) or (subgroup and tri.group.startswith(group + ".")))]
1261
+ self.delTriggers(tri_ids)
1262
+ counts[1] = len(tri_ids)
1263
+
1264
+ if (Command == types) or (isinstance(types, (list, tuple)) and (Command in types)):
1265
+ cmd_ids = [cmd.id for cmd in self._commands.values() if isinstance(cmd, Command) and ((cmd.group == group) or (subgroup and cmd.group.startswith(group + ".")))]
1266
+ self.delCommands(cmd_ids)
1267
+ counts[2] = len(cmd_ids)
1268
+
1269
+ if (Timer == types) or (isinstance(types, (list, tuple)) and (Timer in types)):
1270
+ tmr_ids = [tmr.id for tmr in self._timers.values() if isinstance(tmr, Timer) and ((tmr.group == group) or (subgroup and tmr.group.startswith(group + ".")))]
1271
+ self.delTimers(tmr_ids)
1272
+ counts[3] = len(tmr_ids)
1273
+
1274
+ if (GMCPTrigger == types) or (isinstance(types, (list, tuple)) and (GMCPTrigger in types)):
1275
+ gmcp_ids = [gmcp.id for gmcp in self._gmcp.values() if isinstance(gmcp, GMCPTrigger) and ((gmcp.group == group) or (subgroup and gmcp.group.startswith(group + ".")))]
1276
+ self.delGMCPs(gmcp_ids)
1277
+ counts[4] = len(gmcp_ids)
1278
+
1279
+ return counts
1280
+
1235
1281
  def _addObjects(self, objs: Union[Union[List[BaseObject], Tuple[BaseObject]], Dict[str, BaseObject]]):
1236
1282
  if isinstance(objs, list) or isinstance(objs, tuple):
1237
1283
  for item in objs:
@@ -2230,30 +2276,70 @@ class Session:
2230
2276
  self.application.set_globals(args[0], val)
2231
2277
  self.info(Settings.gettext("msg_object_value_setted", Settings.gettext("globalvar"), args[0], val.__repr__()))
2232
2278
 
2233
- def _handle_objs(self, name: str, objs: dict, *args):
2234
- if len(args) == 0:
2279
+ @exception
2280
+ def _handle_objs(self, type: Type, objs: dict, *args):
2281
+ if len(args) <= 1:
2282
+ if len(args) == 0:
2283
+ display_objs = objs
2284
+ title = f" {type.__name__.upper()} LIST IN SESSION {self.name} "
2285
+ else:
2286
+ arg = args[0]
2287
+ if arg.startswith(">"):
2288
+ arg = arg[1:]
2289
+ title = f" {type.__name__.upper()} LIST IN GROUP <{arg.upper()}> AND ITS SUBGROUPS IN SESSION {self.name} "
2290
+ display_objs = {obj.id: obj for obj in objs.values() if (obj.group == arg) or obj.group.startswith(f"{arg}.")}
2291
+ elif arg.startswith("="):
2292
+ arg = arg[1:]
2293
+ title = f" {type.__name__.upper()} LIST IN GROUP <{arg.upper()}> IN SESSION {self.name} "
2294
+ display_objs = {obj.id: obj for obj in objs.values() if (obj.group == arg)}
2295
+ else:
2296
+ title = f" {type.__name__.upper()} LIST OF ID <{arg.upper()}> IN SESSION {self.name} "
2297
+ display_objs = {obj.id: obj for obj in objs.values() if (obj.id == arg)}
2298
+
2235
2299
  width = self.application.get_width()
2236
-
2237
- title = f" {name.upper()} LIST IN SESSION {self.name} "
2300
+
2238
2301
  left = (width - len(title)) // 2
2239
2302
  right = width - len(title) - left
2303
+ self.writetobuffer("", newline = True)
2240
2304
  self.writetobuffer("="*left + title + "="*right, newline = True)
2241
2305
 
2242
- for id in sorted(objs.keys()):
2306
+ for id in sorted(display_objs.keys()):
2243
2307
  self.writetobuffer(" %r" % objs[id], newline = True)
2244
2308
 
2245
2309
  self.writetobuffer("="*width, newline = True)
2246
2310
 
2247
- elif len(args) == 1:
2248
- if args[0] in objs.keys():
2249
- obj = objs[args[0]]
2250
- self.info(obj.__detailed__())
2251
- else:
2252
- self.warning(Settings.gettext("msg_object_not_exists", args[0], name))
2253
-
2254
2311
  elif len(args) == 2:
2255
- # 当第一个参数为对象obj名称时,对对象进行处理
2256
- if args[0] in objs.keys():
2312
+ if args[0].startswith(">"):
2313
+ group = args[0][1:]
2314
+ if args[1] == "on":
2315
+ cnt =self.enableGroup(group, True, True, type)
2316
+ cnt_total = sum(cnt)
2317
+ self.info(Settings.gettext("msg_group_objects_enabled", group, cnt_total, type.__name__))
2318
+ elif args[1] == "off":
2319
+ cnt =self.enableGroup(group, False, True, type)
2320
+ cnt_total = sum(cnt)
2321
+ self.info(Settings.gettext("msg_group_objects_disabled", group, cnt_total, type.__name__))
2322
+ elif args[1] == "del":
2323
+ cnt =self.deleteGroup(group, True, type)
2324
+ cnt_total = sum(cnt)
2325
+ self.info(Settings.gettext("msg_group_objects_deleted", group, cnt_total, type.__name__))
2326
+
2327
+ elif args[0].startswith("="):
2328
+ group = args[0][1:]
2329
+ if args[1] == "on":
2330
+ cnt =self.enableGroup(group, True, False, type)
2331
+ cnt_total = sum(cnt)
2332
+ self.info(Settings.gettext("msg_group_objects_enabled", group, cnt_total, type.__name__))
2333
+ elif args[1] == "off":
2334
+ cnt =self.enableGroup(group, False, False, type)
2335
+ cnt_total = sum(cnt)
2336
+ self.info(Settings.gettext("msg_group_objects_disabled", group, cnt_total, type.__name__))
2337
+ elif args[1] == "del":
2338
+ cnt =self.deleteGroup(group, False, type)
2339
+ cnt_total = sum(cnt)
2340
+ self.info(Settings.gettext("msg_group_objects_deleted", group, cnt_total, type.__name__))
2341
+
2342
+ elif args[0] in objs.keys():
2257
2343
  obj = objs[args[0]]
2258
2344
  if args[1] == "on":
2259
2345
  obj.enabled = True
@@ -2270,23 +2356,22 @@ class Session:
2270
2356
  objs.pop(args[0])
2271
2357
  self.info(Settings.gettext("msg_object_deleted", obj.__repr__()))
2272
2358
  else:
2273
- self.error(Settings.gettext("msg_invalid_param", name.lower()))
2359
+ self.error(Settings.gettext("msg_invalid_param", type.__name__.lower()))
2274
2360
 
2275
2361
  else:
2276
2362
  pattern, code = args[0], args[1]
2277
2363
  if (len(pattern)>=2) and (pattern[0] == '{') and (pattern[-1] == '}'):
2278
2364
  pattern = pattern[1:-1]
2279
2365
 
2280
- name = name.lower()
2281
- if name == "alias":
2366
+ if type == Alias:
2282
2367
  ali = SimpleAlias(self, pattern, code)
2283
2368
  self.addAlias(ali)
2284
2369
  self.info(Settings.gettext("msg_alias_created", ali.id, ali.__repr__()))
2285
- elif name == "trigger":
2370
+ elif type == Trigger:
2286
2371
  tri = SimpleTrigger(self, pattern, code)
2287
2372
  self.addTrigger(tri)
2288
2373
  self.info(Settings.gettext("msg_trigger_created", tri.id, tri.__repr__()))
2289
- elif name == "timer":
2374
+ elif type == Timer:
2290
2375
  if pattern.isnumeric():
2291
2376
  timeout = float(pattern)
2292
2377
  if timeout > 0:
@@ -2304,10 +2389,14 @@ class Session:
2304
2389
  - #ali {ali_id}: 显示本会话中id为{ali_id}的别名信息
2305
2390
  - #ali {ali_id} {on/off/del}: 使能/禁用/删除本会话中id为{ali_id}的别名
2306
2391
  - #ali {pattern} {code}: 创建一个新别名,匹配为{pattern},匹配时执行{code}
2392
+ - #ali [>=]{groupname}: 显示本会话中组名为{groupname}(当为=时)及其子组(当为>时)的所有别名
2393
+ - #ali [>=]{groupname} {on/off/del}: 使能/禁用/删除本会话中组名为groupname(当为=时)及其子组(当为>时)的所有别名
2307
2394
  - 别名的code中,可以使用%line代表行,%1~%9代表捕获信息
2308
2395
 
2309
2396
  参数:
2310
2397
  :ali_id: 别名Alias的id
2398
+ :>/=: 二者选择其一,标记第二个参数为组名,且指定是否包含子组。当为=时,表示仅指定组,当为>时,表示指定组及其子组。
2399
+ :groupname: 组名,即 alias 的 group 属性
2311
2400
  :on: 使能
2312
2401
  :off: 禁用
2313
2402
  :del: 删除
@@ -2317,9 +2406,13 @@ class Session:
2317
2406
  示例:
2318
2407
  - ``#ali`` : 无参数, 打印列出当前会话中所有的别名清单
2319
2408
  - ``#ali my_ali`` : 一个参数, 列出id为my_ali的Alias对象的详细信息
2409
+ - ``#ali =mygroup`` : 一个参数,列出所有 group 名为 "mygroup" 的 Alias 对象的详细信息
2410
+ - ``#ali >mygroup`` : 一个参数,列出所有 group 名为 "mygroup" 或以 "mygroup." 开头的下级组(子组,比如 mygroup.subgroup1, mygroup.subgroup2 等)内的 Alias 对象的详细信息
2320
2411
  - ``#ali my_ali on`` : 两个参数,启用id为my_ali的Alias对象(enabled = True)
2321
2412
  - ``#ali my_ali off`` : 两个参数, 禁用id为my_ali的Alias对象(enabled = False)
2322
2413
  - ``#ali my_ali del`` : 两个参数,删除id为my_ali的Alias对象
2414
+ - ``#ali =mygroup on`` : 两个参数,启用所有 group 名为 "mygroup" 的 Alias 对象
2415
+ - ``#ali >mygroup off`` : 两个参数,禁用所有 group 名为 "mygroup" 或以 "mygroup." 开头的下级组(子组,比如 mygroup.subgroup1, mygroup.subgroup2 等)内的 Alias 对象
2323
2416
  - ``#ali {^gp\s(.+)$} {get %1 from corpse}`` : 两个参数,新增创建一个Alias对象。使用时, ``gp gold = get gold from corpse``
2324
2417
 
2325
2418
  相关命令:
@@ -2328,7 +2421,7 @@ class Session:
2328
2421
  - #command
2329
2422
  """
2330
2423
 
2331
- self._handle_objs("Alias", self._aliases, *code.code[2:])
2424
+ self._handle_objs(Alias, self._aliases, *code.code[2:])
2332
2425
 
2333
2426
  def handle_timer(self, code: CodeLine, *args, **kwargs):
2334
2427
  '''
@@ -2339,11 +2432,15 @@ class Session:
2339
2432
  - #ti: 显示本会话所有定时器
2340
2433
  - #ti {ti_id}: 显示本会话中id为{ti_id}的定时器信息
2341
2434
  - #ti {ti_id} {on/off/del}: 使能/禁用/删除本会话中id为{ti_id}的定时器
2435
+ - #ti [>=]{groupname}: 显示本会话中组名为{groupname}(当为=时)及其子组(当为>时)的所有定时器
2436
+ - #ti [>=]{groupname} {on/off/del}: 使能/禁用/删除本会话中组名为groupname(当为=时)及其子组(当为>时)的所有定时器
2342
2437
  - #ti {second} {code}: 创建一个新定时器,定时间隔为{second}秒,定时器到时间执行{code}
2343
2438
  - PyMUD支持同时任意多个定时器。
2344
2439
 
2345
2440
  参数:
2346
2441
  :ti_id: 定时器Timer的id
2442
+ :>/=: 二者选择其一,标记第二个参数为组名,且指定是否包含子组。当为=时,表示仅指定组,当为>时,表示指定组及其子组。
2443
+ :groupname: 组名,即 timer 的 group 属性
2347
2444
  :on: 使能
2348
2445
  :off: 禁用
2349
2446
  :del: 删除
@@ -2353,9 +2450,13 @@ class Session:
2353
2450
  示例:
2354
2451
  - ``#ti``: 无参数, 打印列出当前会话中所有的定时器清单
2355
2452
  - ``#ti my_timer``: 一个参数, 列出id为my_timer的Timer对象的详细信息
2453
+ - ``#ti =mygroup``: 一个参数,列出所有 group 名为 "mygroup" 的 Timer 对象的详细信息
2454
+ - ``#ti >mygroup``: 一个参数,列出所有 group 名为 "mygroup" 或以 "mygroup." 开头的下级组(子组,比如 mygroup.subgroup1, mygroup.subgroup2 等)内的 Timer 对象的详细信息
2356
2455
  - ``#ti my_timer on``: 两个参数,启用id为my_timer的Timer对象(enabled = True)
2357
2456
  - ``#ti my_timer off``: 两个参数, 禁用id为my_timer的Timer对象(enabled = False)
2358
2457
  - ``#ti my_timer del``: 两个参数,删除id为my_timer的Timer对象
2458
+ - ``#ti =mygroup on``: 两个参数,启用所有 group 名为 "mygroup" 的 Timer 对象
2459
+ - ``#ti >mygroup off``: 两个参数,禁用所有 group 名为 "mygroup" 或以 "mygroup." 开头的下级组(子组,比如 mygroup.subgroup1, mygroup.subgroup2 等)内的 Timer 对象
2359
2460
  - ``#ti 100 {drink jiudai;#wa 200;eat liang}``: 两个参数,新增创建一个Timer对象。每隔100s,自动执行一次喝酒袋吃干粮。
2360
2461
 
2361
2462
  相关命令:
@@ -2364,7 +2465,7 @@ class Session:
2364
2465
  - #command
2365
2466
  '''
2366
2467
 
2367
- self._handle_objs("Timer", self._timers, *code.code[2:])
2468
+ self._handle_objs(Timer, self._timers, *code.code[2:])
2368
2469
 
2369
2470
  def handle_command(self, code: CodeLine, *args, **kwargs):
2370
2471
  '''
@@ -2375,10 +2476,14 @@ class Session:
2375
2476
  - #cmd: 显示本会话所有命令(Command及其子类)
2376
2477
  - #cmd {cmd_id}: 显示本会话中id为{cmd_id}的命令信息
2377
2478
  - #cmd {cmd_id} {on/off/del}: 使能/禁用/删除本会话中id为{cmd_id}的命令
2479
+ - #cmd [>=]{groupname}: 显示本会话中组名为{groupname}(当为=时)及其子组(当为>时)的所有命令
2480
+ - #cmd [>=]{groupname} {on/off/del}: 使能/禁用/删除本会话中组名为groupname(当为=时)及其子组(当为>时)的所有命令
2378
2481
  - 由于命令的特殊性,其只能使用脚本代码创建
2379
2482
 
2380
2483
  参数:
2381
2484
  :cmd_id: 命令Command的id
2485
+ :>/=: 二者选择其一,标记第二个参数为组名,且指定是否包含子组。当为=时,表示仅指定组,当为>时,表示指定组及其子组。
2486
+ :groupname: 组名,即 command 的 group 属性
2382
2487
  :on: 使能
2383
2488
  :off: 禁用
2384
2489
  :del: 删除
@@ -2386,9 +2491,13 @@ class Session:
2386
2491
  示例:
2387
2492
  - ``#cmd`` : 无参数, 打印列出当前会话中所有的命令清单
2388
2493
  - ``#cmd my_cmd`` : 一个参数, 列出id为my_cmd的Command对象的详细信息
2494
+ - ``#cmd =mygroup`` : 一个参数,列出所有 group 名为 "mygroup" 的 Command 对象的详细信息
2495
+ - ``#cmd >mygroup`` : 一个参数,列出所有 group 名为 "mygroup" 或以 "mygroup." 开头的下级组(子组,比如 mygroup.subgroup1, mygroup.subgroup2 等)内的 Command 对象的详细信息
2389
2496
  - ``#cmd my_cmd on`` : 两个参数,启用id为my_cmd的Command对象(enabled = True)
2390
2497
  - ``#cmd my_cmd off`` : 两个参数, 禁用id为my_cmd的Command对象(enabled = False)
2391
2498
  - ``#cmd my_cmd del`` : 两个参数,删除id为my_cmd的Command对象
2499
+ - ``#cmd =mygroup on`` : 两个参数,启用所有 group 名为 "mygroup" 的 Command 对象
2500
+ - ``#cmd >mygroup off`` : 两个参数,禁用所有 group 名为 "mygroup" 或以 "mygroup." 开头的下级组(子组,比如 mygroup.subgroup1, mygroup.subgroup2 等)内的 Command 对象
2392
2501
 
2393
2502
  相关命令:
2394
2503
  - #alias
@@ -2396,7 +2505,7 @@ class Session:
2396
2505
  - #timer
2397
2506
  '''
2398
2507
 
2399
- self._handle_objs("Command", self._commands, *code.code[2:])
2508
+ self._handle_objs(Command, self._commands, *code.code[2:])
2400
2509
 
2401
2510
  def handle_trigger(self, code: CodeLine, *args, **kwargs):
2402
2511
  '''
@@ -2407,11 +2516,15 @@ class Session:
2407
2516
  - #tri: 显示本会话所有触发器
2408
2517
  - #tri {tri_id}: 显示本会话中id为{tri_id}的触发器信息
2409
2518
  - #tri {tri_id} {on/off/del}: 使能/禁用/删除本会话中id为{tri_id}的触发器
2519
+ - #tri [>=]{groupname}: 显示本会话中组名为{groupname}(当为=时)及其子组(当为>时)的所有触发器
2520
+ - #tri [>=]{groupname} {on/off/del}: 使能/禁用/删除本会话中组名为groupname(当为=时)及其子组(当为>时)的所有触发器
2410
2521
  - #tri {pattern} {code}: 创建一个新触发器,匹配为{pattern},匹配时执行{code}
2411
2522
  - 触发器的code中,可以使用%line代表行,%1~%9代表捕获信息
2412
2523
 
2413
2524
  参数:
2414
2525
  :tri_id: 触发器Trigger的id
2526
+ :[>=]: 二者选择其一,标记第二个参数为组名,且指定是否包含子组。当为=时,表示仅指定组,当为>时,表示指定组及其子组。
2527
+ :groupname: 组名,即 trigger 的 group 属性
2415
2528
  :on: 使能
2416
2529
  :off: 禁用
2417
2530
  :del: 删除
@@ -2421,9 +2534,13 @@ class Session:
2421
2534
  示例:
2422
2535
  - ``#tri``: 无参数, 打印列出当前会话中所有的触发器清单
2423
2536
  - ``#tri my_tri``: 一个参数, 列出id为my_tri的Trigger对象的详细信息
2537
+ - ``#tri =mygroup``: 一个参数,列出所有 group 名为 "mygroup" 的 Trigger 对象的详细信息
2538
+ - ``#tri >mygroup``: 一个参数,列出所有 group 名为 "mygroup" 或以 "mygroup." 开头的下级组(子组,比如 mygroup.subgroup1, mygroup.subgroup2 等)内的 Trigger 对象的详细信息
2424
2539
  - ``#tri my_tri on``: 两个参数,启用id为my_tri的Trigger对象(enabled = True)
2425
2540
  - ``#tri my_tri off``: 两个参数, 禁用id为my_tri的Trigger对象(enabled = False)
2426
2541
  - ``#tri my_tri del``: 两个参数,删除id为my_tri的Trigger对象
2542
+ - ``#tri =mygroup on``: 两个参数,启用所有 group 名为 "mygroup" 的 Trigger 对象
2543
+ - ``#tri >mygroup off``: 两个参数,禁用所有 group 名为 "mygroup" 或以 "mygroup." 开头的下级组(子组,比如 mygroup.subgroup1, mygroup.subgroup2 等)内的 Trigger 对象
2427
2544
  - ``#tri {^[> ]*段誉脚下一个不稳.+} {get duan}``: 两个参数,新增创建一个Trigger对象。当段誉被打倒的时刻把他背起来。
2428
2545
 
2429
2546
  相关命令:
@@ -2432,7 +2549,7 @@ class Session:
2432
2549
  - #command
2433
2550
  '''
2434
2551
 
2435
- self._handle_objs("Trigger", self._triggers, *code.code[2:])
2552
+ self._handle_objs(Trigger, self._triggers, *code.code[2:])
2436
2553
 
2437
2554
  def handle_task(self, code: Optional[CodeLine] = None, *args, **kwargs):
2438
2555
  '''
@@ -2462,16 +2579,17 @@ class Session:
2462
2579
 
2463
2580
  使用:
2464
2581
  - #ig: 切换触发器全局使能/禁用状态
2465
- - #t+ {group}: 使能{group}组内的所有对象,包括别名、触发器、命令、定时器、GMCPTrigger等
2466
- - #t- {group}: 禁用{group}组内的所有对象,包括别名、触发器、命令、定时器、GMCPTrigger等
2582
+ - #t+ [>=]{group}: 使能{group}组内的所有对象,包括别名、触发器、命令、定时器、GMCPTrigger等
2583
+ - #t- [>=]{group}: 禁用{group}组内的所有对象,包括别名、触发器、命令、定时器、GMCPTrigger等
2467
2584
 
2468
2585
  参数:
2469
- :group: 组名
2586
+ :group: 组名。可以在组名前带 '=', '>' 表示对当前组生效或对当前组及子组同时生效。当省略 >/= 时,相当于 =,即仅对当前组生效。
2470
2587
 
2471
2588
  示例:
2472
2589
  - ``#ig``: 切换全局触发器的使能/禁用状态。为禁用时,状态栏右下角会显示“全局已禁用”
2473
2590
  - ``#t+ mygroup``: 使能名称为 mygroup 的组内的所有对象,包括别名、触发器、命令、定时器、GMCPTrigger等
2474
2591
  - ``#t- mygroup``: 禁用名称为 mygroup 的组内的所有对象,包括别名、触发器、命令、定时器、GMCPTrigger等
2592
+ - ``#t+ >mygroup``: 使能名称为 mygroup 的组及子组(所有以 mygroup. 开头的其他组,如 mygroup.subgroup)内的所有对象,包括别名、触发器、命令、定时器、GMCPTrigger等
2475
2593
 
2476
2594
  注意:
2477
2595
  使用#t+/#t-调用时,相当于enableGroup传递的默认参数,即subgroup为True, 且types为所有类型。
@@ -2495,7 +2613,15 @@ class Session:
2495
2613
  return
2496
2614
 
2497
2615
  groupname = code.code[2]
2498
- cnts = self.enableGroup(groupname)
2616
+ # 组名支持=, >两种,分别代表仅当前组组,当前组及子组
2617
+ # #t+、t-不指定 >, =时,按 = 处理
2618
+ if groupname.startswith(">"):
2619
+ cnts = self.enableGroup(groupname[1:])
2620
+ elif groupname.startswith("="):
2621
+ cnts = self.enableGroup(groupname[1:], subgroup = False)
2622
+ else:
2623
+ cnts = self.enableGroup(groupname, subgroup = False)
2624
+
2499
2625
  self.info(Settings.gettext("msg_group_enabled", groupname, *cnts))
2500
2626
 
2501
2627
  elif cmd == "t-":
@@ -2504,7 +2630,13 @@ class Session:
2504
2630
  return
2505
2631
 
2506
2632
  groupname = code.code[2]
2507
- cnts = self.enableGroup(groupname, False)
2633
+ if groupname.startswith(">"):
2634
+ cnts = self.enableGroup(groupname[1:], False)
2635
+ elif groupname.startswith("="):
2636
+ cnts = self.enableGroup(groupname[1:], False, subgroup = False)
2637
+ else:
2638
+ cnts = self.enableGroup(groupname, False)
2639
+
2508
2640
  self.info(Settings.gettext("msg_group_disabled", groupname, *cnts))
2509
2641
 
2510
2642
  def handle_repeat(self, code: Optional[CodeLine] = None, *args, **kwargs):
@@ -2562,10 +2694,14 @@ class Session:
2562
2694
  - #gmcp: 显示本会话所有GMCPTrigger
2563
2695
  - #gmcp {gmcp_key}: 显示本会话中name为{gmcp_key}的GMCPTrigger信息
2564
2696
  - #gmcp {gmcp_key} {on/off/del}: 使能/禁用/删除本会话中name为{gmcp_key}的GMCPTrigger
2697
+ - #gmcp [>=]{groupname}: 显示本会话中组名为{groupname}(当为=时)及其子组(当为>时)的所有GMCPTrigger
2698
+ - #gmcp [>=]{groupname} {on/off/del}: 使能/禁用/删除本会话中group为{groupname}的GMCPTrigger
2565
2699
  - 由于GMCPTrigger的特殊性,其只能使用脚本代码创建
2566
2700
 
2567
2701
  参数:
2568
2702
  :gmcp_key: GMCPTrigger的关键字name
2703
+ :>/=: 二者选择其一,标记第二个参数为组名,且指定是否包含子组。当为=时,表示仅指定组,当为>时,表示指定组及其子组。
2704
+ :groupname: 组名,即 gmcp 的 group 属性。虽然GMCP大概率不会使用group,但仍支持此功能。
2569
2705
  :on: 使能
2570
2706
  :off: 禁用
2571
2707
  :del: 删除
@@ -2583,7 +2719,7 @@ class Session:
2583
2719
  - #timer
2584
2720
  '''
2585
2721
 
2586
- self._handle_objs("GMCPs", self._gmcp, *code.code[2:])
2722
+ self._handle_objs(GMCPTrigger, self._gmcp, *code.code[2:])
2587
2723
 
2588
2724
  def handle_message(self, code: CodeLine, *args, **kwargs):
2589
2725
  '''
@@ -3018,7 +3154,7 @@ class Session:
3018
3154
  - #cls: 清空当前会话缓冲及显示
3019
3155
  '''
3020
3156
 
3021
- self.buffer.text = ""
3157
+ self.buffer.clear()
3022
3158
 
3023
3159
  @exception
3024
3160
  def handle_test(self, code: CodeLine, *args, **kwargs):
pymud/settings.py CHANGED
@@ -15,7 +15,7 @@ class Settings:
15
15
  "APP 简要描述"
16
16
  __version__ = importlib.metadata.version("pymud")
17
17
  "APP 当前版本"
18
- __release__ = "2025-05-20"
18
+ __release__ = "2025-05-27"
19
19
  "APP 当前版本发布日期"
20
20
  __author__ = "本牛(newstart)@北侠"
21
21
  "APP 作者"