pymud 0.20.0__py3-none-any.whl → 0.20.0a1__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/__init__.py +1 -3
- pymud/__main__.py +138 -2
- pymud/dialogs.py +6 -11
- pymud/extras.py +73 -1
- pymud/logger.py +4 -10
- pymud/objects.py +14 -45
- pymud/pkuxkx.py +7 -4
- pymud/pymud.py +54 -92
- pymud/session.py +141 -376
- pymud/settings.py +1 -1
- {pymud-0.20.0.dist-info → pymud-0.20.0a1.dist-info}/METADATA +194 -225
- pymud-0.20.0a1.dist-info/RECORD +17 -0
- {pymud-0.20.0.dist-info → pymud-0.20.0a1.dist-info}/WHEEL +1 -1
- pymud/main.py +0 -142
- pymud/modules.py +0 -188
- pymud-0.20.0.dist-info/RECORD +0 -19
- {pymud-0.20.0.dist-info → pymud-0.20.0a1.dist-info}/LICENSE.txt +0 -0
- {pymud-0.20.0.dist-info → pymud-0.20.0a1.dist-info}/entry_points.txt +0 -0
- {pymud-0.20.0.dist-info → pymud-0.20.0a1.dist-info}/top_level.txt +0 -0
pymud/session.py
CHANGED
@@ -1,15 +1,14 @@
|
|
1
|
-
import asyncio, logging, re, math, os, pickle, datetime, importlib, importlib.util, sysconfig
|
1
|
+
import asyncio, logging, re, math, os, pickle, datetime, importlib, importlib.util, sysconfig
|
2
2
|
from collections.abc import Iterable
|
3
3
|
from collections import OrderedDict
|
4
4
|
import logging, queue
|
5
5
|
from logging import FileHandler
|
6
6
|
from logging.handlers import QueueHandler, QueueListener
|
7
|
-
|
7
|
+
|
8
8
|
from .logger import Logger
|
9
|
-
from .extras import SessionBuffer, DotDict
|
9
|
+
from .extras import SessionBuffer, DotDict, Plugin
|
10
10
|
from .protocol import MudClientProtocol
|
11
|
-
from .
|
12
|
-
from .objects import BaseObject, Trigger, Alias, Command, Timer, SimpleAlias, SimpleTrigger, SimpleTimer, GMCPTrigger, CodeBlock, CodeLine
|
11
|
+
from .objects import Trigger, Alias, Command, Timer, SimpleAlias, SimpleTrigger, SimpleTimer, GMCPTrigger, CodeBlock, CodeLine
|
13
12
|
from .settings import Settings
|
14
13
|
|
15
14
|
|
@@ -30,14 +29,13 @@ class Session:
|
|
30
29
|
|
31
30
|
"""
|
32
31
|
#_esc_regx = re.compile("\x1b\\[[^mz]+[mz]")
|
33
|
-
_esc_regx = re.compile(
|
32
|
+
_esc_regx = re.compile("\x1b\\[[\d;]+[abcdmz]", flags = re.IGNORECASE)
|
34
33
|
|
35
34
|
_sys_commands = (
|
36
35
|
"help",
|
37
36
|
"exit",
|
38
37
|
"close",
|
39
38
|
"connect", # 连接到服务器
|
40
|
-
"disconnect", # 从服务器断开连接
|
41
39
|
|
42
40
|
"info", # 输出蓝色info
|
43
41
|
"warning", # 输出黄色warning
|
@@ -91,7 +89,6 @@ class Session:
|
|
91
89
|
"var" : "variable",
|
92
90
|
"rep" : "repeat",
|
93
91
|
"con" : "connect",
|
94
|
-
"dis" : "disconnect",
|
95
92
|
"wa" : "wait",
|
96
93
|
"mess": "message",
|
97
94
|
"action": "trigger",
|
@@ -119,6 +116,9 @@ class Session:
|
|
119
116
|
self._events["connected"] = None
|
120
117
|
self._events["disconnected"] = None
|
121
118
|
|
119
|
+
self._loggers = dict()
|
120
|
+
self.log = self.getLogger(name)
|
121
|
+
|
122
122
|
self._auto_script = kwargs.get("scripts", None)
|
123
123
|
|
124
124
|
self._cmds_handler = dict() # 支持的命令的处理函数字典
|
@@ -142,13 +142,8 @@ class Session:
|
|
142
142
|
self._status_maker = None # 创建状态窗口的函数(属性)
|
143
143
|
self.display_line = ""
|
144
144
|
|
145
|
-
self._activetime = time.time()
|
146
|
-
|
147
145
|
self.initialize()
|
148
146
|
|
149
|
-
self._loggers = dict()
|
150
|
-
self.log = self.getLogger(name)
|
151
|
-
|
152
147
|
self.host = host
|
153
148
|
self.port = port
|
154
149
|
self.encoding = encoding or self.encoding
|
@@ -181,10 +176,6 @@ class Session:
|
|
181
176
|
if Settings.client["auto_connect"]:
|
182
177
|
self.open()
|
183
178
|
|
184
|
-
def __del__(self):
|
185
|
-
self.clean()
|
186
|
-
self.closeLoggers()
|
187
|
-
|
188
179
|
def initialize(self):
|
189
180
|
"初始化Session有关对象。 **无需脚本调用。**"
|
190
181
|
self._line_buffer = bytearray()
|
@@ -257,6 +248,11 @@ class Session:
|
|
257
248
|
if self.connected:
|
258
249
|
self.write_eof()
|
259
250
|
|
251
|
+
# 两次保存,删掉一次
|
252
|
+
# # 断开时自动保存变量数据
|
253
|
+
# if Settings.client["var_autosave"]:
|
254
|
+
# self.handle_save()
|
255
|
+
|
260
256
|
def onDisconnected(self, protocol):
|
261
257
|
"当从服务器连接断开时执行的操作。包括保存变量(若设置)、打印断开时间、执行自定义事件(若设置)等。"
|
262
258
|
# 断开时自动保存变量数据
|
@@ -294,15 +290,6 @@ class Session:
|
|
294
290
|
|
295
291
|
return dura
|
296
292
|
|
297
|
-
@property
|
298
|
-
def idletime(self) -> float:
|
299
|
-
"只读属性,返回当前会话空闲时间(即最后一次向服务器写入数据到现在的时间),以秒为单位。当服务器未连接时,返回-1"
|
300
|
-
idle = -1
|
301
|
-
if self._protocol and self._protocol.connected:
|
302
|
-
idle = time.time() - self._activetime
|
303
|
-
|
304
|
-
return idle
|
305
|
-
|
306
293
|
@property
|
307
294
|
def status_maker(self):
|
308
295
|
"""
|
@@ -389,15 +376,6 @@ class Session:
|
|
389
376
|
|
390
377
|
return logger
|
391
378
|
|
392
|
-
def closeLoggers(self):
|
393
|
-
"移除本会话所有相关Logger"
|
394
|
-
for name in self._loggers.keys():
|
395
|
-
if isinstance(self._loggers[name], Logger):
|
396
|
-
self._loggers[name].enabled = False
|
397
|
-
|
398
|
-
if name in self.application.loggers.keys():
|
399
|
-
self.application.loggers.pop(name)
|
400
|
-
|
401
379
|
@property
|
402
380
|
def modules(self) -> OrderedDict:
|
403
381
|
"""
|
@@ -764,7 +742,7 @@ class Session:
|
|
764
742
|
lines = line.split(self.seperator)
|
765
743
|
for ln in lines:
|
766
744
|
if Settings.client["echo_input"]:
|
767
|
-
self.writetobuffer(f"\x1b[32m{ln}\x1b[0m"
|
745
|
+
self.writetobuffer(f"\x1b[32m{ln}\x1b[0m")
|
768
746
|
else:
|
769
747
|
self.log.log(f"\x1b[32m{ln}\x1b[0m\n")
|
770
748
|
|
@@ -773,38 +751,15 @@ class Session:
|
|
773
751
|
|
774
752
|
else:
|
775
753
|
if Settings.client["echo_input"]:
|
776
|
-
self.writetobuffer(f"\x1b[32m{line}\x1b[0m"
|
754
|
+
self.writetobuffer(f"\x1b[32m{line}\x1b[0m")
|
777
755
|
else:
|
778
756
|
self.log.log(f"\x1b[32m{line}\x1b[0m\n")
|
779
757
|
|
780
758
|
cmd = line + self.newline
|
781
759
|
self.write(cmd.encode(self.encoding, Settings.server["encoding_errors"]))
|
782
|
-
|
783
|
-
self._activetime = time.time()
|
784
760
|
|
785
|
-
async def waitfor(self, line: str, awaitable, wait_time = 0.05) -> None:
|
786
|
-
"""
|
787
|
-
调用writline向服务器中写入一行后,等待到可等待对象再返回。
|
788
|
-
|
789
|
-
:param line: 使用writeline写入的行
|
790
|
-
:param awaitable: 等待的可等待对象
|
791
|
-
:param wait_time: 写入行前等待的延时,单位为s。默认0.05
|
792
|
-
|
793
|
-
由于异步的消息循环机制,如果在写入命令之后再创建可等待对象,则有可能服务器响应在可等待对象的创建之前
|
794
|
-
此时使用await就无法等待到可等待对象的响应,会导致任务出错。
|
795
|
-
一种解决方式是先创建可等待对象,然后写入命令,然后再等待可等待对象,但这种情况下需要写入三行代码,书写麻烦
|
796
|
-
因此该函数是用于简化此类使用时的写法。
|
797
|
-
|
798
|
-
示例:
|
799
|
-
await session.waitfor('a_cmd', self.create_task(a_tri.triggered()))
|
800
|
-
done, pending = await session.waitfor('a_cmd', asyncio.wait([self.create_task(a_tri.triggered()), self.create_task(b_tri.triggered())], return_when = 'FIRST_COMPLETED'))
|
801
|
-
"""
|
802
|
-
await asyncio.sleep(wait_time)
|
803
|
-
self.writeline(line)
|
804
|
-
return await awaitable
|
805
|
-
|
806
761
|
def exec(self, cmd: str, name = None, *args, **kwargs):
|
807
|
-
|
762
|
+
"""
|
808
763
|
在名称为name的会话中使用exec_command执行MUD命令。当不指定name时,在当前会话中执行。
|
809
764
|
|
810
765
|
- exec 与 writeline 都会向服务器写入数据。其差异在于,exec执行的内容,会先经过Alias处理和Command处理,实际向远程发送内容与cmd可以不一致。
|
@@ -819,7 +774,7 @@ class Session:
|
|
819
774
|
示例:
|
820
775
|
.. code:: Python
|
821
776
|
|
822
|
-
session.addAlias(SimpleAlias(self.session,
|
777
|
+
session.addAlias(SimpleAlias(self.session, "^cb\s(\S+)\s(\S+)", "#3 get %1 from jinnang;#wa 250;combine gem;#wa 250;pack gem", id = "ali_combine"))
|
823
778
|
session.exec("cb j1a")
|
824
779
|
"""
|
825
780
|
name = name or self.name
|
@@ -840,10 +795,12 @@ class Session:
|
|
840
795
|
name = name or self.name
|
841
796
|
if name in self.application.sessions.keys():
|
842
797
|
session = self.application.sessions[name]
|
843
|
-
|
798
|
+
await session.exec_command_async(cmd, *args, **kwargs)
|
844
799
|
else:
|
845
800
|
self.error(f"不存在名称为{name}的会话")
|
846
801
|
|
802
|
+
|
803
|
+
|
847
804
|
def exec_code(self, cl: CodeLine, *args, **kwargs):
|
848
805
|
"""
|
849
806
|
执行解析为CodeLine形式的MUD命令(必定为单个命令)。一般情况下,脚本中不应调用该方法,而应使用exec/exec_command。
|
@@ -917,7 +874,6 @@ class Session:
|
|
917
874
|
:param args: 保留兼容与扩展性所需
|
918
875
|
:param kwargs: 保留兼容与扩展性所需
|
919
876
|
"""
|
920
|
-
|
921
877
|
if cl.length == 0:
|
922
878
|
self.writeline("")
|
923
879
|
|
@@ -945,9 +901,9 @@ class Session:
|
|
945
901
|
else:
|
946
902
|
try:
|
947
903
|
cb = CodeBlock(sess_cmd)
|
948
|
-
|
904
|
+
await cb.async_execute(session, *args, **kwargs)
|
949
905
|
except Exception as e:
|
950
|
-
|
906
|
+
await session.exec_command_async(sess_cmd)
|
951
907
|
|
952
908
|
else:
|
953
909
|
if cmd in self._commands_alias.keys():
|
@@ -964,7 +920,7 @@ class Session:
|
|
964
920
|
|
965
921
|
else:
|
966
922
|
cmdtext, code = cl.expand(self, *args, **kwargs)
|
967
|
-
|
923
|
+
await self.exec_text_async(cmdtext)
|
968
924
|
|
969
925
|
def exec_text(self, cmdtext: str):
|
970
926
|
"""
|
@@ -1004,14 +960,14 @@ class Session:
|
|
1004
960
|
|
1005
961
|
异步调用时,该函数要等待对应的代码执行完毕后才会返回。可以用于确保命令执行完毕。
|
1006
962
|
"""
|
1007
|
-
|
963
|
+
|
1008
964
|
isNotCmd = True
|
1009
965
|
for command in self._commands.values():
|
1010
966
|
if isinstance(command, Command) and command.enabled:
|
1011
967
|
state = command.match(cmdtext)
|
1012
968
|
if state.result == Command.SUCCESS:
|
1013
969
|
# 命令的任务名称采用命令id,以便于后续查错
|
1014
|
-
|
970
|
+
await self.create_task(command.execute(cmdtext), name = "task-{0}".format(command.id))
|
1015
971
|
isNotCmd = False
|
1016
972
|
break
|
1017
973
|
|
@@ -1029,8 +985,6 @@ class Session:
|
|
1029
985
|
if notAlias:
|
1030
986
|
self.writeline(cmdtext)
|
1031
987
|
|
1032
|
-
return result
|
1033
|
-
|
1034
988
|
def exec_command(self, line: str, *args, **kwargs) -> None:
|
1035
989
|
"""
|
1036
990
|
在当前会话中执行MUD命令。多个命令可以用分隔符隔开。
|
@@ -1081,18 +1035,15 @@ class Session:
|
|
1081
1035
|
"""
|
1082
1036
|
|
1083
1037
|
## 以下为函数执行本体
|
1084
|
-
result = None
|
1085
1038
|
if (not "#" in line) and (not "@" in line) and (not "%" in line):
|
1086
1039
|
cmds = line.split(self.seperator)
|
1087
1040
|
for cmd in cmds:
|
1088
|
-
|
1041
|
+
await self.exec_text_async(cmd)
|
1089
1042
|
if Settings.client["interval"] > 0:
|
1090
1043
|
await asyncio.sleep(Settings.client["interval"] / 1000.0)
|
1091
1044
|
else:
|
1092
1045
|
cb = CodeBlock(line)
|
1093
|
-
|
1094
|
-
|
1095
|
-
return result
|
1046
|
+
await cb.async_execute(self)
|
1096
1047
|
|
1097
1048
|
def write_eof(self) -> None:
|
1098
1049
|
"""
|
@@ -1156,212 +1107,50 @@ class Session:
|
|
1156
1107
|
|
1157
1108
|
return counts
|
1158
1109
|
|
1159
|
-
|
1160
|
-
|
1161
|
-
|
1162
|
-
|
1163
|
-
|
1164
|
-
|
1165
|
-
|
1166
|
-
|
1167
|
-
|
1168
|
-
|
1169
|
-
|
1170
|
-
|
1171
|
-
def
|
1172
|
-
if
|
1173
|
-
|
1174
|
-
|
1175
|
-
|
1176
|
-
|
1177
|
-
|
1178
|
-
|
1179
|
-
|
1180
|
-
|
1181
|
-
|
1182
|
-
|
1183
|
-
|
1184
|
-
# def _addObject(self, obj, cls: type):
|
1185
|
-
# #if type(obj) == cls:
|
1186
|
-
# if isinstance(obj, cls):
|
1187
|
-
# if cls == Alias:
|
1188
|
-
# self._aliases[obj.id] = obj
|
1189
|
-
# elif cls == Command:
|
1190
|
-
# self._commands[obj.id] = obj
|
1191
|
-
# elif cls == Trigger:
|
1192
|
-
# self._triggers[obj.id] = obj
|
1193
|
-
# elif cls == Timer:
|
1194
|
-
# self._timers[obj.id] = obj
|
1195
|
-
# elif cls == GMCPTrigger:
|
1196
|
-
# self._gmcp[obj.id] = obj
|
1197
|
-
|
1198
|
-
def _addObject(self, obj):
|
1199
|
-
if isinstance(obj, Alias):
|
1200
|
-
self._aliases[obj.id] = obj
|
1201
|
-
elif isinstance(obj, Command):
|
1202
|
-
self._commands[obj.id] = obj
|
1203
|
-
elif isinstance(obj, Trigger):
|
1204
|
-
self._triggers[obj.id] = obj
|
1205
|
-
elif isinstance(obj, Timer):
|
1206
|
-
self._timers[obj.id] = obj
|
1207
|
-
elif isinstance(obj, GMCPTrigger):
|
1208
|
-
self._gmcp[obj.id] = obj
|
1209
|
-
|
1210
|
-
def addObject(self, obj: BaseObject):
|
1211
|
-
"""
|
1212
|
-
向会话中增加单个对象,可直接添加 Alias, Trigger, GMCPTrigger, Command, Timer 或它们的子类
|
1213
|
-
|
1214
|
-
:param obj: 特定对象本身,可以为 Alias, Trigger, GMCPTrigger, Command, Timer 或其子类
|
1215
|
-
|
1216
|
-
示例:
|
1217
|
-
.. code:: Python
|
1218
|
-
|
1219
|
-
class Configuration:
|
1220
|
-
def __init__(self, session):
|
1221
|
-
self.session = session
|
1222
|
-
|
1223
|
-
self.session.addObject(SimpleAlias(session, r'^gta$', 'get all'),)
|
1224
|
-
self.session.addObject(SimpleTrigger(session, r'^[> ]*你嘻嘻地笑了起来.+', 'haha'))
|
1225
|
-
self.session.addObject(SimpleTimer(session, 'xixi', timeout = 10))
|
1226
|
-
|
1227
|
-
"""
|
1228
|
-
self._addObject(obj)
|
1229
|
-
|
1230
|
-
def addObjects(self, objs):
|
1231
|
-
"""
|
1232
|
-
向会话中增加多个对象,可直接添加 Alias, Trigger, GMCPTrigger, Command, Timer 或它们的子类的元组、列表或者字典(保持兼容性)
|
1233
|
-
|
1234
|
-
:param objs: 多个特定对象组成的元组、列表或者字典,可以为 Alias, Trigger, GMCPTrigger, Command, Timer 或其子类
|
1235
|
-
|
1236
|
-
示例:
|
1237
|
-
.. code:: Python
|
1238
|
-
|
1239
|
-
class Configuration:
|
1240
|
-
def __init__(self, session):
|
1241
|
-
self.session = session
|
1242
|
-
|
1243
|
-
self.objs = [
|
1244
|
-
SimpleAlias(session, r'^gta$', 'get all;xixi'),
|
1245
|
-
SimpleTrigger(session, r'^[> ]*你嘻嘻地笑了起来.+', 'haha'),
|
1246
|
-
SimpleTimer(session, 'xixi', timeout = 10)
|
1247
|
-
]
|
1248
|
-
|
1249
|
-
self.session.addObjects(self.objs)
|
1250
|
-
|
1251
|
-
"""
|
1252
|
-
self._addObjects(objs)
|
1110
|
+
def _addObjects(self, objs: dict, cls: type):
|
1111
|
+
if cls == Alias:
|
1112
|
+
self._aliases.update(objs)
|
1113
|
+
elif cls == Command:
|
1114
|
+
self._commands.update(objs)
|
1115
|
+
elif cls == Trigger:
|
1116
|
+
self._triggers.update(objs)
|
1117
|
+
elif cls == Timer:
|
1118
|
+
self._timers.update(objs)
|
1119
|
+
elif cls == GMCPTrigger:
|
1120
|
+
self._gmcp.update(objs)
|
1121
|
+
|
1122
|
+
def _addObject(self, obj, cls: type):
|
1123
|
+
#if type(obj) == cls:
|
1124
|
+
if isinstance(obj, cls):
|
1125
|
+
if cls == Alias:
|
1126
|
+
self._aliases[obj.id] = obj
|
1127
|
+
elif cls == Command:
|
1128
|
+
self._commands[obj.id] = obj
|
1129
|
+
elif cls == Trigger:
|
1130
|
+
self._triggers[obj.id] = obj
|
1131
|
+
elif cls == Timer:
|
1132
|
+
self._timers[obj.id] = obj
|
1133
|
+
elif cls == GMCPTrigger:
|
1134
|
+
self._gmcp[obj.id] = obj
|
1253
1135
|
|
1254
1136
|
def _delObject(self, id, cls: type):
|
1255
1137
|
if cls == Alias:
|
1256
1138
|
self._aliases.pop(id, None)
|
1257
1139
|
elif cls == Command:
|
1258
|
-
|
1259
|
-
if isinstance(cmd, Command):
|
1260
|
-
cmd.reset()
|
1261
|
-
cmd.unload()
|
1262
|
-
cmd.__unload__()
|
1263
|
-
|
1140
|
+
self._commands.pop(id, None)
|
1264
1141
|
elif cls == Trigger:
|
1265
1142
|
self._triggers.pop(id, None)
|
1266
1143
|
elif cls == Timer:
|
1267
|
-
|
1268
|
-
if isinstance(timer, Timer):
|
1269
|
-
timer.enabled = False
|
1144
|
+
self._timers.pop(id, None)
|
1270
1145
|
elif cls == GMCPTrigger:
|
1271
1146
|
self._gmcp.pop(id, None)
|
1272
1147
|
|
1273
|
-
|
1274
1148
|
def _delObjects(self, ids: Iterable, cls: type):
|
1275
1149
|
"删除多个指定元素"
|
1276
1150
|
for id in ids:
|
1277
1151
|
self._delObject(id, cls)
|
1278
1152
|
|
1279
|
-
def
|
1280
|
-
"""
|
1281
|
-
从会话中移除一个对象,可直接删除 Alias, Trigger, GMCPTrigger, Command, Timer 或它们的子类本身
|
1282
|
-
|
1283
|
-
** 注 ** 现在 delObject 和 delObjects 使用结果相同,都可以清除单个对象、对个对象的list, tuple或dict, 可以有效防止代码写错
|
1284
|
-
|
1285
|
-
:param obj: 要删除的多个特定对象组成的元组、列表或者字典,可以为 Alias, Trigger, GMCPTrigger, Command, Timer 或其子类
|
1286
|
-
|
1287
|
-
示例:
|
1288
|
-
.. code:: Python
|
1289
|
-
|
1290
|
-
class Configuration:
|
1291
|
-
def __init__(self, session):
|
1292
|
-
self.session = session
|
1293
|
-
|
1294
|
-
ali = SimpleAlias(session, r'^gta$', 'get all', id = 'my_ali1')
|
1295
|
-
|
1296
|
-
# 以下几种方式均可将该别名添加到会话
|
1297
|
-
session.addObject(ali)
|
1298
|
-
session.addAlias(ali)
|
1299
|
-
|
1300
|
-
# 以下三种方式均可以删除该别名
|
1301
|
-
session.delObject(ali)
|
1302
|
-
session.delAlias(ali)
|
1303
|
-
session.delAlias("my_ali1")
|
1304
|
-
|
1305
|
-
"""
|
1306
|
-
if isinstance(obj, Alias):
|
1307
|
-
self._aliases.pop(obj.id, None)
|
1308
|
-
elif isinstance(obj, Command):
|
1309
|
-
obj.reset()
|
1310
|
-
obj.unload()
|
1311
|
-
obj.__unload__()
|
1312
|
-
self._commands.pop(obj.id, None)
|
1313
|
-
elif isinstance(obj, Trigger):
|
1314
|
-
self._triggers.pop(obj.id, None)
|
1315
|
-
elif isinstance(obj, Timer):
|
1316
|
-
obj.enabled = False
|
1317
|
-
self._timers.pop(obj.id, None)
|
1318
|
-
elif isinstance(obj, GMCPTrigger):
|
1319
|
-
self._gmcp.pop(obj.id, None)
|
1320
|
-
|
1321
|
-
elif isinstance(obj, (list, tuple, dict)):
|
1322
|
-
self.delObjects(obj)
|
1323
|
-
|
1324
|
-
def delObjects(self, objs):
|
1325
|
-
"""
|
1326
|
-
从会话中移除一组对象,可直接删除多个 Alias, Trigger, GMCPTrigger, Command, Timer
|
1327
|
-
|
1328
|
-
** 注 ** 现在 delObject 和 delObjects 使用结果相同,都可以清除单个对象、对个对象的list, tuple或dict, 可以有效防止代码写错
|
1329
|
-
|
1330
|
-
:param objs: 要删除的一组对象的元组、列表或者字典(保持兼容性),其中对象可以为 Alias, Trigger, GMCPTrigger, Command, Timer 或它们的子类
|
1331
|
-
|
1332
|
-
示例:
|
1333
|
-
|
1334
|
-
.. code:: Python
|
1335
|
-
|
1336
|
-
class Configuration:
|
1337
|
-
def __init__(self, session):
|
1338
|
-
self.session = session
|
1339
|
-
|
1340
|
-
self.objs = [
|
1341
|
-
SimpleAlias(session, r'^gta$', 'get all;xixi'),
|
1342
|
-
SimpleTrigger(session, r'^[> ]*你嘻嘻地笑了起来.+', 'haha'),
|
1343
|
-
SimpleTimer(session, 'xixi', timeout = 10)
|
1344
|
-
]
|
1345
|
-
|
1346
|
-
self.session.addObjects(self.objs)
|
1347
|
-
|
1348
|
-
def __unload__(self):
|
1349
|
-
"卸载本模块时,删除所有本模块添加的对象"
|
1350
|
-
self.session.delObjects(self.objs)
|
1351
|
-
|
1352
|
-
"""
|
1353
|
-
if isinstance(objs, list) or isinstance(objs, tuple):
|
1354
|
-
for item in objs:
|
1355
|
-
self.delObject(item)
|
1356
|
-
|
1357
|
-
elif isinstance(objs, dict):
|
1358
|
-
for key, item in objs.items():
|
1359
|
-
self.delObject(item)
|
1360
|
-
|
1361
|
-
elif isinstance(objs, BaseObject):
|
1362
|
-
self.delObject(objs)
|
1363
|
-
|
1364
|
-
def addAliases(self, alis):
|
1153
|
+
def addAliases(self, alis: dict):
|
1365
1154
|
"""
|
1366
1155
|
向会话中增加多个别名
|
1367
1156
|
|
@@ -1382,55 +1171,55 @@ class Session:
|
|
1382
1171
|
self._aliases['my_ali2'] = SimpleAlias(self.session, "s", "south", id = "my_ali2")
|
1383
1172
|
self.session.addAliases(self._aliases)
|
1384
1173
|
"""
|
1385
|
-
self._addObjects(alis)
|
1174
|
+
self._addObjects(alis, Alias)
|
1386
1175
|
|
1387
|
-
def addCommands(self, cmds):
|
1176
|
+
def addCommands(self, cmds: dict):
|
1388
1177
|
"""
|
1389
1178
|
向会话中增加多个命令。使用方法与 addAliases 类似。
|
1390
1179
|
|
1391
1180
|
:param cmds: 多个命令的字典。字典 key 应为每个命令的 id。
|
1392
1181
|
"""
|
1393
|
-
self._addObjects(cmds)
|
1182
|
+
self._addObjects(cmds, Command)
|
1394
1183
|
|
1395
|
-
def addTriggers(self, tris):
|
1184
|
+
def addTriggers(self, tris: dict):
|
1396
1185
|
"""
|
1397
1186
|
向会话中增加多个触发器。使用方法与 addAliases 类似。
|
1398
1187
|
|
1399
1188
|
:param tris: 多个触发器的字典。字典 key 应为每个触发器的 id。
|
1400
1189
|
"""
|
1401
|
-
self._addObjects(tris)
|
1190
|
+
self._addObjects(tris, Trigger)
|
1402
1191
|
|
1403
|
-
def addGMCPs(self, gmcps):
|
1192
|
+
def addGMCPs(self, gmcps: dict):
|
1404
1193
|
"""
|
1405
1194
|
向会话中增加多个GMCPTrigger。使用方法与 addAliases 类似。
|
1406
1195
|
|
1407
1196
|
:param gmcps: 多个GMCPTrigger的字典。字典 key 应为每个GMCPTrigger的 id。
|
1408
1197
|
"""
|
1409
|
-
self._addObjects(gmcps)
|
1198
|
+
self._addObjects(gmcps, GMCPTrigger)
|
1410
1199
|
|
1411
|
-
def addTimers(self, tis):
|
1200
|
+
def addTimers(self, tis: dict):
|
1412
1201
|
"""
|
1413
1202
|
向会话中增加多个定时器。使用方法与 addAliases 类似。
|
1414
1203
|
|
1415
1204
|
:param tis: 多个定时器的字典。字典 key 应为每个定时器的 id。
|
1416
1205
|
"""
|
1417
|
-
self._addObjects(tis)
|
1206
|
+
self._addObjects(tis, Timer)
|
1418
1207
|
|
1419
|
-
def addAlias(self, ali):
|
1208
|
+
def addAlias(self, ali: Alias):
|
1420
1209
|
"""
|
1421
1210
|
向会话中增加一个别名。
|
1422
1211
|
|
1423
1212
|
:param ali: 要增加的别名对象,应为 Alias 类型或其子类
|
1424
1213
|
"""
|
1425
|
-
self._addObject(ali)
|
1214
|
+
self._addObject(ali, Alias)
|
1426
1215
|
|
1427
|
-
def addCommand(self, cmd):
|
1216
|
+
def addCommand(self, cmd: Command):
|
1428
1217
|
"""
|
1429
1218
|
向会话中增加一个命令。
|
1430
1219
|
|
1431
1220
|
:param cmd: 要增加的命令对象,应为 Command 类型或其子类
|
1432
1221
|
"""
|
1433
|
-
self._addObject(cmd)
|
1222
|
+
self._addObject(cmd, Command)
|
1434
1223
|
|
1435
1224
|
def addTrigger(self, tri: Trigger):
|
1436
1225
|
"""
|
@@ -1438,7 +1227,7 @@ class Session:
|
|
1438
1227
|
|
1439
1228
|
:param tri: 要增加的触发器对象,应为 Trigger 类型或其子类
|
1440
1229
|
"""
|
1441
|
-
self._addObject(tri)
|
1230
|
+
self._addObject(tri, Trigger)
|
1442
1231
|
|
1443
1232
|
def addTimer(self, ti: Timer):
|
1444
1233
|
"""
|
@@ -1446,7 +1235,7 @@ class Session:
|
|
1446
1235
|
|
1447
1236
|
:param ti: 要增加的定时器对象,应为 Timer 类型或其子类
|
1448
1237
|
"""
|
1449
|
-
self._addObject(ti)
|
1238
|
+
self._addObject(ti, Timer)
|
1450
1239
|
|
1451
1240
|
def addGMCP(self, gmcp: GMCPTrigger):
|
1452
1241
|
"""
|
@@ -1455,7 +1244,7 @@ class Session:
|
|
1455
1244
|
:param gmcp: 要增加的GMCP触发器对象,应为 GMCPTrigger 类型或其子类
|
1456
1245
|
"""
|
1457
1246
|
|
1458
|
-
self._addObject(gmcp)
|
1247
|
+
self._addObject(gmcp, GMCPTrigger)
|
1459
1248
|
|
1460
1249
|
def delAlias(self, ali):
|
1461
1250
|
"""
|
@@ -1574,7 +1363,7 @@ class Session:
|
|
1574
1363
|
for ti in ti_s:
|
1575
1364
|
self.delTimer(ti)
|
1576
1365
|
|
1577
|
-
def delGMCP(self, gmcp):
|
1366
|
+
def delGMCP(self, gmcp: GMCPTrigger):
|
1578
1367
|
"""
|
1579
1368
|
从会话中移除一个GMCP触发器,可接受 GMCPTrigger 对象或其的id。使用方法与 delAlias 类似
|
1580
1369
|
|
@@ -1890,7 +1679,6 @@ class Session:
|
|
1890
1679
|
该函数不应该在代码中直接调用。
|
1891
1680
|
|
1892
1681
|
相关命令:
|
1893
|
-
- #disconnect
|
1894
1682
|
- #close
|
1895
1683
|
- #exit
|
1896
1684
|
'''
|
@@ -1912,18 +1700,6 @@ class Session:
|
|
1912
1700
|
|
1913
1701
|
self.info("已经与服务器连接了 {}".format(time_msg))
|
1914
1702
|
|
1915
|
-
def handle_disconnect(self, code: CodeLine = None, *args, **kwargs):
|
1916
|
-
'''
|
1917
|
-
嵌入命令 #disconnect / #dis 的执行函数,断开到远程服务器的连接(仅当远程服务器已连接时有效)。
|
1918
|
-
该函数不应该在代码中直接调用。
|
1919
|
-
|
1920
|
-
相关命令:
|
1921
|
-
- #connect
|
1922
|
-
- #close
|
1923
|
-
'''
|
1924
|
-
|
1925
|
-
self.disconnect()
|
1926
|
-
|
1927
1703
|
def handle_variable(self, code: CodeLine = None, *args, **kwargs):
|
1928
1704
|
'''
|
1929
1705
|
嵌入命令 #variable / #var 的执行函数,操作会话变量。
|
@@ -1962,7 +1738,7 @@ class Session:
|
|
1962
1738
|
else:
|
1963
1739
|
vars_simple[k] = v
|
1964
1740
|
|
1965
|
-
width = self.application.get_width()
|
1741
|
+
width = self.application.get_width()
|
1966
1742
|
|
1967
1743
|
title = f" VARIABLE LIST IN SESSION {self.name} "
|
1968
1744
|
left = (width - len(title)) // 2
|
@@ -1970,7 +1746,6 @@ class Session:
|
|
1970
1746
|
self.writetobuffer("="*left + title + "="*right, newline = True)
|
1971
1747
|
|
1972
1748
|
# print vars in simple, 每个变量占40格,一行可以多个变量
|
1973
|
-
# 这里可以考虑调整一下,默认40, 但如果一个变量值太长,则选择占两个位置
|
1974
1749
|
var_count = len(vars_simple)
|
1975
1750
|
var_per_line = (width - 2) // 40
|
1976
1751
|
lines = math.ceil(var_count / var_per_line)
|
@@ -1986,18 +1761,14 @@ class Session:
|
|
1986
1761
|
self.writetobuffer(" " * left_space)
|
1987
1762
|
line_vars = var_keys[start:end]
|
1988
1763
|
for var in line_vars:
|
1989
|
-
|
1990
|
-
vwidth = 22 - (wcswidth(repr) - len(repr))
|
1991
|
-
self.writetobuffer("{0} = {1}".format(var.rjust(20), repr.ljust(vwidth)))
|
1992
|
-
#self.writetobuffer("{0:>18} = {1:<19}".format(var, vars_simple[var].__repr__()))
|
1764
|
+
self.writetobuffer("{0:>18} = {1:<19}".format(var, vars_simple[var].__repr__()))
|
1993
1765
|
|
1994
1766
|
self.writetobuffer("", newline = True)
|
1995
1767
|
|
1996
1768
|
# print vars in complex, 每个变量占1行
|
1997
|
-
|
1998
|
-
for key in var_keys:
|
1769
|
+
for k, v in vars_complex.items():
|
1999
1770
|
self.writetobuffer(" " * left_space)
|
2000
|
-
self.writetobuffer("{0:>
|
1771
|
+
self.writetobuffer("{0:>18} = {1}".format(k, v.__repr__()), newline = True)
|
2001
1772
|
|
2002
1773
|
self.writetobuffer("="*width, newline = True)
|
2003
1774
|
|
@@ -2050,7 +1821,7 @@ class Session:
|
|
2050
1821
|
else:
|
2051
1822
|
vars_simple[k] = v
|
2052
1823
|
|
2053
|
-
width = self.application.get_width()
|
1824
|
+
width = self.application.get_width()
|
2054
1825
|
|
2055
1826
|
title = f" GLOBAL VARIABLES LIST "
|
2056
1827
|
left = (width - len(title)) // 2
|
@@ -2073,23 +1844,21 @@ class Session:
|
|
2073
1844
|
self.writetobuffer(" " * left_space)
|
2074
1845
|
line_vars = var_keys[start:end]
|
2075
1846
|
for var in line_vars:
|
2076
|
-
|
2077
|
-
vwidth = 22 - (wcswidth(repr) - len(repr))
|
2078
|
-
self.writetobuffer("{0} = {1}".format(var.rjust(20), repr.ljust(vwidth)))
|
1847
|
+
self.writetobuffer("{0:>18} = {1:<19}".format(var, vars_simple[var].__repr__()))
|
2079
1848
|
|
2080
1849
|
self.writetobuffer("", newline = True)
|
2081
1850
|
|
2082
1851
|
# print vars in complex, 每个变量占1行
|
2083
1852
|
for k, v in vars_complex.items():
|
2084
1853
|
self.writetobuffer(" " * left_space)
|
2085
|
-
self.writetobuffer("{0:>
|
1854
|
+
self.writetobuffer("{0:>18} = {1}".format(k, v.__repr__()), newline = True)
|
2086
1855
|
|
2087
1856
|
self.writetobuffer("="*width, newline = True)
|
2088
1857
|
|
2089
1858
|
elif len(args) == 1:
|
2090
1859
|
var = args[0]
|
2091
1860
|
if var in self.application.globals.keys():
|
2092
|
-
self.info("{0:>
|
1861
|
+
self.info("{0:>18} = {1:<19}".format(var, self.application.get_globals(var).__repr__()), "全局变量")
|
2093
1862
|
else:
|
2094
1863
|
self.info("全局空间不存在名称为 {} 的变量".format(var), "全局变量")
|
2095
1864
|
|
@@ -2164,7 +1933,7 @@ class Session:
|
|
2164
1933
|
self.info("创建Timer {} 成功: {}".format(ti.id, ti.__repr__()))
|
2165
1934
|
|
2166
1935
|
def handle_alias(self, code: CodeLine = None, *args, **kwargs):
|
2167
|
-
|
1936
|
+
'''
|
2168
1937
|
嵌入命令 #alias / #ali 的执行函数,操作别名。该命令可以不带参数、带一个参数或者两个参数。
|
2169
1938
|
该函数不应该在代码中直接调用。
|
2170
1939
|
|
@@ -2195,7 +1964,7 @@ class Session:
|
|
2195
1964
|
- #trigger
|
2196
1965
|
- #timer
|
2197
1966
|
- #command
|
2198
|
-
|
1967
|
+
'''
|
2199
1968
|
|
2200
1969
|
self._handle_objs("Alias", self._aliases, *code.code[2:])
|
2201
1970
|
|
@@ -2554,7 +2323,6 @@ class Session:
|
|
2554
2323
|
self._variables.clear()
|
2555
2324
|
self._tasks.clear()
|
2556
2325
|
|
2557
|
-
|
2558
2326
|
def load_module(self, module_names):
|
2559
2327
|
"""
|
2560
2328
|
模块加载函数。
|
@@ -2578,12 +2346,32 @@ class Session:
|
|
2578
2346
|
"加载指定名称模块"
|
2579
2347
|
try:
|
2580
2348
|
if module_name not in self._modules.keys():
|
2581
|
-
|
2349
|
+
mod = importlib.import_module(module_name)
|
2350
|
+
if hasattr(mod, 'Configuration'):
|
2351
|
+
config = mod.Configuration(self)
|
2352
|
+
self._modules[module_name] = {"module": mod, "config": config}
|
2353
|
+
self.info(f"主配置模块 {module_name} 加载完成.")
|
2354
|
+
else:
|
2355
|
+
self._modules[module_name] = {"module": mod, "config": None}
|
2356
|
+
self.info(f"子配置模块 {module_name} 加载完成.")
|
2582
2357
|
|
2583
2358
|
else:
|
2584
|
-
mod = self._modules[module_name]
|
2585
|
-
|
2586
|
-
|
2359
|
+
mod = self._modules[module_name]["module"]
|
2360
|
+
config = self._modules[module_name]["config"]
|
2361
|
+
if config:
|
2362
|
+
if hasattr(config, "unload"):
|
2363
|
+
unload = getattr(config, "unload", None)
|
2364
|
+
if callable(unload):
|
2365
|
+
unload(config)
|
2366
|
+
del config
|
2367
|
+
mod = importlib.reload(mod)
|
2368
|
+
if hasattr(mod, 'Configuration'):
|
2369
|
+
config = mod.Configuration(self)
|
2370
|
+
self._modules[module_name] = {"module": mod, "config": config}
|
2371
|
+
self.info(f"主配置模块 {module_name} 重新加载完成.")
|
2372
|
+
else:
|
2373
|
+
self._modules[module_name] = {"module": mod, "config": None}
|
2374
|
+
self.info(f"子配置模块 {module_name} 重新加载完成.")
|
2587
2375
|
|
2588
2376
|
except Exception as e:
|
2589
2377
|
import traceback
|
@@ -2609,11 +2397,20 @@ class Session:
|
|
2609
2397
|
self._unload_module(mod)
|
2610
2398
|
|
2611
2399
|
def _unload_module(self, module_name):
|
2612
|
-
"卸载指定名称模块。卸载支持需要模块的Configuration实现
|
2400
|
+
"卸载指定名称模块。卸载支持需要模块的Configuration实现__del__方法"
|
2613
2401
|
if module_name in self._modules.keys():
|
2614
|
-
mod = self._modules
|
2615
|
-
|
2616
|
-
|
2402
|
+
mod = self._modules[module_name]["module"]
|
2403
|
+
config = self._modules[module_name]["config"]
|
2404
|
+
if config:
|
2405
|
+
if hasattr(config, "unload"):
|
2406
|
+
unload = getattr(config, "unload", None)
|
2407
|
+
if callable(unload):
|
2408
|
+
unload(config)
|
2409
|
+
|
2410
|
+
del config
|
2411
|
+
del mod
|
2412
|
+
self._modules.pop(module_name)
|
2413
|
+
self.info(f"配置模块 {module_name} 已成功卸载.")
|
2617
2414
|
|
2618
2415
|
else:
|
2619
2416
|
self.warning(f"指定模块名称 {module_name} 并未加载.")
|
@@ -2627,9 +2424,9 @@ class Session:
|
|
2627
2424
|
:param module_names: 要重新加载的模块清单。为元组/列表时,卸载指定名称的系列模块,当名称为字符串时,卸载单个模块。当不指定时,重新加载所有已加载模块。
|
2628
2425
|
"""
|
2629
2426
|
if module_names is None:
|
2630
|
-
|
2631
|
-
|
2632
|
-
|
2427
|
+
self.clean()
|
2428
|
+
mods = list(self._modules.keys())
|
2429
|
+
self.load_module(mods)
|
2633
2430
|
|
2634
2431
|
self.info(f"所有配置模块全部重新加载完成.")
|
2635
2432
|
|
@@ -2637,17 +2434,14 @@ class Session:
|
|
2637
2434
|
for mod in module_names:
|
2638
2435
|
mod = mod.strip()
|
2639
2436
|
if mod in self._modules.keys():
|
2640
|
-
|
2641
|
-
if isinstance(module, ModuleInfo):
|
2642
|
-
module.reload()
|
2437
|
+
self.load_module(mod)
|
2643
2438
|
else:
|
2644
2439
|
self.warning(f"指定模块名称 {mod} 并未加载,无法重新加载.")
|
2645
2440
|
|
2646
2441
|
elif isinstance(module_names, str):
|
2647
2442
|
if module_names in self._modules.keys():
|
2648
|
-
|
2649
|
-
|
2650
|
-
module.reload()
|
2443
|
+
mod = module_names.strip()
|
2444
|
+
self.load_module(mod)
|
2651
2445
|
else:
|
2652
2446
|
self.warning(f"指定模块名称 {module_names} 并未加载,无法重新加载.")
|
2653
2447
|
|
@@ -2731,7 +2525,7 @@ class Session:
|
|
2731
2525
|
|
2732
2526
|
elif mod in self.plugins.keys():
|
2733
2527
|
self.application.reload_plugin(self.plugins[mod])
|
2734
|
-
|
2528
|
+
|
2735
2529
|
else:
|
2736
2530
|
self.warning(f"指定名称 {mod} 既未找到模块,也未找到插件,重新加载失败..")
|
2737
2531
|
|
@@ -2785,29 +2579,12 @@ class Session:
|
|
2785
2579
|
- #reload
|
2786
2580
|
'''
|
2787
2581
|
|
2788
|
-
|
2789
|
-
|
2790
|
-
|
2791
|
-
|
2792
|
-
|
2793
|
-
self.info("当前会话并未加载任何模块。", "MODULES")
|
2794
|
-
else:
|
2795
|
-
self.info(f"当前会话已加载 {count} 个模块,包括(按加载顺序排列):{list(self._modules.keys())}", "MODULES")
|
2582
|
+
count = len(self._modules.keys())
|
2583
|
+
if count == 0:
|
2584
|
+
self.info("当前会话并未加载任何模块。", "MODULES")
|
2585
|
+
else:
|
2586
|
+
self.info(f"当前会话已加载 {count} 个模块,包括(按加载顺序排列):{list(self._modules.keys())}", "MODULES")
|
2796
2587
|
|
2797
|
-
elif len(args) >= 1:
|
2798
|
-
modules = ",".join(args).split(",")
|
2799
|
-
for mod in modules:
|
2800
|
-
if mod in self._modules.keys():
|
2801
|
-
module = self._modules[mod]
|
2802
|
-
if isinstance(module, ModuleInfo):
|
2803
|
-
if module.ismainmodule:
|
2804
|
-
self.info(f"模块 {module.name} 中包含的配置包括: {', '.join(module.config.keys())}")
|
2805
|
-
else:
|
2806
|
-
self.info(f"模块 {module.name} 为子模块,不包含配置。")
|
2807
|
-
|
2808
|
-
else:
|
2809
|
-
self.info(f"本会话中不存在指定名称 {mod} 的模块,可能是尚未加载到本会话中")
|
2810
|
-
|
2811
2588
|
def handle_reset(self, code: CodeLine = None, *args, **kwargs):
|
2812
2589
|
'''
|
2813
2590
|
嵌入命令 #reset 的执行函数,复位全部脚本。该命令不带参数。
|
@@ -2827,8 +2604,7 @@ class Session:
|
|
2827
2604
|
|
2828
2605
|
def handle_save(self, code: CodeLine = None, *args, **kwargs):
|
2829
2606
|
'''
|
2830
|
-
嵌入命令 #save
|
2831
|
-
系统变量包括 %line, %copy 和 %raw 三个,临时变量是指变量名已下划线开头的变量
|
2607
|
+
嵌入命令 #save 的执行函数,保存当前会话变量(系统变量除外)至文件。该命令不带参数。
|
2832
2608
|
该函数不应该在代码中直接调用。
|
2833
2609
|
|
2834
2610
|
使用:
|
@@ -2849,10 +2625,10 @@ class Session:
|
|
2849
2625
|
with open(file, "wb") as fp:
|
2850
2626
|
saved = dict()
|
2851
2627
|
saved.update(self._variables)
|
2852
|
-
keys = list(saved.keys())
|
2853
|
-
for key in keys:
|
2854
|
-
|
2855
|
-
|
2628
|
+
# keys = list(saved.keys())
|
2629
|
+
# for key in keys:
|
2630
|
+
# if key.startswith("%"):
|
2631
|
+
# saved.pop(key)
|
2856
2632
|
saved.pop("%line", None)
|
2857
2633
|
saved.pop("%raw", None)
|
2858
2634
|
saved.pop("%copy", None)
|
@@ -2951,7 +2727,7 @@ class Session:
|
|
2951
2727
|
if name in self.plugins.keys():
|
2952
2728
|
plugin = self.plugins[name]
|
2953
2729
|
self.info(f"{plugin.desc['DESCRIPTION']}, 版本 {plugin.desc['VERSION']} 作者 {plugin.desc['AUTHOR']} 发布日期 {plugin.desc['RELEASE_DATE']}", f"PLUGIN {name}")
|
2954
|
-
self.writetobuffer(plugin.help
|
2730
|
+
self.writetobuffer(plugin.help)
|
2955
2731
|
|
2956
2732
|
def handle_replace(self, code: CodeLine = None, *args, **kwargs):
|
2957
2733
|
'''
|
@@ -3130,8 +2906,8 @@ class Session:
|
|
3130
2906
|
|
3131
2907
|
示例:
|
3132
2908
|
- ``#log`` : 在当前会话窗口列出所有记录器状态
|
3133
|
-
- ``#log start`` : 启动本会话默认记录器(记录器名为会话名)。该记录器以纯文本模式,将后续所有屏幕输出、键盘键入、命令输入等记录到
|
3134
|
-
- ``#log start -r`` : 启动本会话默认记录器。该记录器以raw模式,将后续所有屏幕输出、键盘键入、命令输入等记录到
|
2909
|
+
- ``#log start`` : 启动本会话默认记录器(记录器名为会话名)。该记录器以纯文本模式,将后续所有屏幕输出、键盘键入、命令输入等记录到 name.log 文件的后端
|
2910
|
+
- ``#log start -r`` : 启动本会话默认记录器。该记录器以raw模式,将后续所有屏幕输出、键盘键入、命令输入等记录到 name.log 文件的后端
|
3135
2911
|
- ``#log start chat`` : 启动名为 chat 的记录器。该记录器以纯文本模式,记录代码中调用过该记录器 .log 进行记录的信息
|
3136
2912
|
- ``#log stop`` : 停止本会话默认记录器(记录器名为会话名)。
|
3137
2913
|
|
@@ -3189,19 +2965,8 @@ class Session:
|
|
3189
2965
|
elif (args[0] == "show"):
|
3190
2966
|
if len(args) > 1 and not args[1].startswith('-'):
|
3191
2967
|
file = args[1]
|
3192
|
-
|
3193
|
-
|
3194
|
-
#self.info(f'file {filepath} exists, will be shown.')
|
3195
|
-
self.application.logFileShown = filepath
|
3196
|
-
self.application.showLogInTab()
|
3197
|
-
elif os.path.exists(os.path.join('./log', file)):
|
3198
|
-
filepath = os.path.abspath(os.path.join('./log', file))
|
3199
|
-
#self.info(f'file {filepath} exists, will be shown.')
|
3200
|
-
self.application.logFileShown = filepath
|
3201
|
-
self.application.showLogInTab()
|
3202
|
-
else:
|
3203
|
-
self.warning(f'指定记录文件 {file} 不存在!')
|
3204
|
-
|
2968
|
+
self.application.logFileShown = file
|
2969
|
+
self.application.showLogInTab()
|
3205
2970
|
else:
|
3206
2971
|
self.application.show_logSelectDialog()
|
3207
2972
|
|