pymud 0.20.4__py3-none-any.whl → 0.21.0__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 +7 -2
- pymud/decorators.py +234 -0
- pymud/dialogs.py +37 -31
- pymud/extras.py +7 -135
- pymud/i18n.py +63 -0
- pymud/lang/i18n_chs.py +227 -0
- pymud/lang/i18n_eng.py +851 -0
- pymud/logger.py +9 -4
- pymud/main.py +123 -44
- pymud/modules.py +104 -31
- pymud/objects.py +102 -98
- pymud/pkuxkx.py +267 -142
- pymud/protocol.py +15 -13
- pymud/pymud.py +80 -75
- pymud/session.py +582 -356
- pymud/settings.py +15 -2
- {pymud-0.20.4.dist-info → pymud-0.21.0.dist-info}/METADATA +118 -5
- pymud-0.21.0.dist-info/RECORD +23 -0
- {pymud-0.20.4.dist-info → pymud-0.21.0.dist-info}/WHEEL +1 -1
- pymud-0.20.4.dist-info/RECORD +0 -19
- {pymud-0.20.4.dist-info → pymud-0.21.0.dist-info}/entry_points.txt +0 -0
- {pymud-0.20.4.dist-info → pymud-0.21.0.dist-info}/licenses/LICENSE.txt +0 -0
- {pymud-0.20.4.dist-info → pymud-0.21.0.dist-info}/top_level.txt +0 -0
pymud/logger.py
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
import os, re, datetime, threading, pathlib
|
2
2
|
from queue import SimpleQueue, Empty
|
3
3
|
from pathlib import Path
|
4
|
-
|
4
|
+
from .settings import Settings
|
5
5
|
class Logger:
|
6
6
|
"""
|
7
7
|
PyMUD 的记录器类型,可用于会话中向文件记录数据。记录文件保存在当前目录下的 log 子目录中
|
@@ -57,6 +57,10 @@ class Logger:
|
|
57
57
|
now = datetime.datetime.now().strftime("%Y_%m_%d_%H_%M_%S")
|
58
58
|
filename = f"{self.name}.{now}.log"
|
59
59
|
|
60
|
+
else:
|
61
|
+
raise ValueError(Settings.gettext("exception_logmode_error", self._mode))
|
62
|
+
|
63
|
+
|
60
64
|
logdir = Path.cwd().joinpath('log')
|
61
65
|
if not logdir.exists() or not logdir.is_dir():
|
62
66
|
logdir.mkdir()
|
@@ -70,8 +74,9 @@ class Logger:
|
|
70
74
|
|
71
75
|
else:
|
72
76
|
self._queue.put_nowait(None)
|
73
|
-
self._thread
|
74
|
-
|
77
|
+
if self._thread:
|
78
|
+
self._thread.join()
|
79
|
+
self._thread = None
|
75
80
|
self._closeFile()
|
76
81
|
|
77
82
|
self._enabled = enabled
|
@@ -130,7 +135,7 @@ class Logger:
|
|
130
135
|
The thread will terminate if it sees a sentinel object in the queue.
|
131
136
|
"""
|
132
137
|
newline = True
|
133
|
-
while
|
138
|
+
while self._stream:
|
134
139
|
try:
|
135
140
|
data = self._queue.get(block = True)
|
136
141
|
if data:
|
pymud/main.py
CHANGED
@@ -1,26 +1,32 @@
|
|
1
|
-
import os, sys, json, platform, shutil, logging, argparse
|
1
|
+
import os, sys, json, platform, shutil, logging, argparse, locale
|
2
2
|
from pathlib import Path
|
3
3
|
from .pymud import PyMudApp
|
4
4
|
from .settings import Settings
|
5
5
|
|
6
6
|
CFG_TEMPLATE = {
|
7
|
+
"language" : "chs", # 语言设置,默认为简体中文
|
8
|
+
|
7
9
|
"client": {
|
8
10
|
"buffer_lines" : 5000, # 保留缓冲行数
|
9
11
|
|
10
12
|
"interval" : 10, # 在自动执行中,两次命令输入中的间隔时间(ms)
|
11
13
|
"auto_connect" : True, # 创建会话后,是否自动连接
|
12
14
|
"auto_reconnect" : False, # 在会话异常断开之后,是否自动重连
|
15
|
+
"reconnect_wait" : 15, # 自动重连等待的时间(秒数)
|
13
16
|
"var_autosave" : True, # 断开时自动保存会话变量
|
14
17
|
"var_autoload" : True, # 初始化时自动加载会话变量
|
15
18
|
|
16
|
-
"echo_input" : False,
|
17
19
|
"beautify" : True, # 专门为解决控制台下PKUXKX字符画对不齐的问题
|
20
|
+
"history_records" : 500,
|
18
21
|
|
22
|
+
"status_divider" : False, # 是否显示状态栏的分隔线
|
19
23
|
"status_display" : 1, # 状态窗口显示情况设置,0-不显示,1-显示在下方,2-显示在右侧
|
20
24
|
"status_height" : 4, # 下侧状态栏的高度
|
21
25
|
"status_width" : 30, # 右侧状态栏的宽度
|
26
|
+
|
22
27
|
|
23
28
|
},
|
29
|
+
|
24
30
|
"sessions" : {
|
25
31
|
"pkuxkx" : {
|
26
32
|
"host" : "mud.pkuxkx.net",
|
@@ -41,50 +47,123 @@ CFG_TEMPLATE = {
|
|
41
47
|
}
|
42
48
|
}
|
43
49
|
|
50
|
+
def detect_system_language():
|
51
|
+
"""
|
52
|
+
检测系统语言,返回中文或英文"
|
53
|
+
"""
|
54
|
+
lang = "chs"
|
55
|
+
try:
|
56
|
+
value = locale.getlocale()[0]
|
57
|
+
if value and (value.lower().startswith("zh") or value.lower().startswith("chinese")): # 中文
|
58
|
+
lang = "chs"
|
59
|
+
else:
|
60
|
+
lang = "eng"
|
61
|
+
except Exception as e:
|
62
|
+
# default is chs
|
63
|
+
pass
|
64
|
+
|
65
|
+
return lang
|
66
|
+
|
44
67
|
def init_pymud_env(args):
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
dir =
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
dir = Path(
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
68
|
+
system = "unknown"
|
69
|
+
lang = detect_system_language()
|
70
|
+
if lang == "chs":
|
71
|
+
print(f"欢迎使用PyMUD, 版本{Settings.__version__}. 使用PyMUD时, 建议建立一个新目录(任意位置),并将自己的脚本以及配置文件放到该目录下.")
|
72
|
+
print("即将开始为首次运行初始化环境...")
|
73
|
+
|
74
|
+
dir = args.dir
|
75
|
+
if dir:
|
76
|
+
if dir == ".":
|
77
|
+
dir_msg = "当前目录"
|
78
|
+
else:
|
79
|
+
dir_msg = f": {dir}"
|
80
|
+
print(f"你已经指定了创建脚本的目录为{dir_msg}")
|
81
|
+
dir = Path(dir)
|
82
|
+
else:
|
83
|
+
dir = Path.home().joinpath('pkuxkx')
|
84
|
+
|
85
|
+
system = platform.system().lower()
|
86
|
+
dir_enter = input(f"检测到当前系统为 {system}, 请指定游戏脚本的目录(若目录不存在会自动创建),直接回车表示使用默认值 [{dir}]:")
|
87
|
+
if dir_enter:
|
88
|
+
dir = Path(dir_enter)
|
89
|
+
|
90
|
+
if dir.exists() and dir.is_dir():
|
91
|
+
print(f'检测到给定目录 {dir} 已存在,切换至此目录...')
|
92
|
+
else:
|
93
|
+
print(f'检测到给定目录 {dir} 不存在,正在创建并切换至目录...')
|
94
|
+
dir.mkdir()
|
95
|
+
|
96
|
+
os.chdir(dir)
|
67
97
|
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
98
|
+
if os.path.exists('pymud.cfg'):
|
99
|
+
print(f'检测到脚本目录下已存在pymud.cfg文件,将直接使用此文件进入PyMUD...')
|
100
|
+
else:
|
101
|
+
print(f'检测到脚本目录下不存在pymud.cfg文件,将使用默认内容创建该配置文件...')
|
102
|
+
with open('pymud.cfg', mode = 'x') as fp:
|
103
|
+
fp.writelines(json.dumps(CFG_TEMPLATE, indent = 4))
|
104
|
+
|
105
|
+
if not os.path.exists('examples.py'):
|
106
|
+
from pymud import pkuxkx
|
107
|
+
module_dir = pkuxkx.__file__
|
108
|
+
shutil.copyfile(module_dir, 'examples.py')
|
109
|
+
print(f'已将样例脚本拷贝至脚本目录,并加入默认配置文件')
|
110
|
+
|
111
|
+
print(f"后续可自行修改 {dir} 目录下的 pymud.cfg 文件以进行配置。")
|
112
|
+
if system == "windows":
|
113
|
+
print(f"后续运行PyMUD, 请在 {dir} 目录下键入命令: python -m pymud,或直接使用快捷命令 pymud")
|
114
|
+
else:
|
115
|
+
print(f"后续运行PyMUD, 请在 {dir} 目录下键入命令: python3 -m pymud,或直接使用快捷命令 pymud")
|
86
116
|
|
87
|
-
|
117
|
+
input('所有内容已初始化完毕, 请按回车进入PyMUD.')
|
118
|
+
|
119
|
+
else:
|
120
|
+
print(f"Welcome to PyMUD, version {Settings.__version__}. When using pymud, it is suggested that a new folder should be created (in any place), and the cfg configuration and all the scripts have been placed in the directory.")
|
121
|
+
print("Starting to initialize the environment for the first time...")
|
122
|
+
dir = args.dir
|
123
|
+
if dir:
|
124
|
+
if dir == ".":
|
125
|
+
dir_msg = "current directory"
|
126
|
+
else:
|
127
|
+
dir_msg = f": {dir}"
|
128
|
+
print(f"You have specified the directory to create the script as {dir_msg}")
|
129
|
+
dir = Path(dir)
|
130
|
+
else:
|
131
|
+
dir = Path.home().joinpath('pkuxkx')
|
132
|
+
|
133
|
+
system = platform.system().lower()
|
134
|
+
dir_enter = input(f"Detected the current system is {system}, please specify the directory of the game script (if the directory does not exist, it will be automatically created), press Enter to use the default value [{dir}]:")
|
135
|
+
if dir_enter:
|
136
|
+
dir = Path(dir_enter)
|
137
|
+
|
138
|
+
if dir.exists() and dir.is_dir():
|
139
|
+
print(f'Detected that the given directory {dir} already exists, switching to this directory...')
|
140
|
+
else:
|
141
|
+
print(f'Detected that the given directory {dir} does not exist, creating and switching to the directory...')
|
142
|
+
dir.mkdir()
|
143
|
+
|
144
|
+
os.chdir(dir)
|
145
|
+
|
146
|
+
if os.path.exists('pymud.cfg'):
|
147
|
+
print(f'Detected that the pymud.cfg file already exists in the script directory, entering PyMUD directly using this file...')
|
148
|
+
else:
|
149
|
+
print(f'Detected that the pymud.cfg file does not exist in the script directory, creating the configuration file using the default content...')
|
150
|
+
with open('pymud.cfg', mode = 'x') as fp:
|
151
|
+
CFG_TEMPLATE["language"] = "eng"
|
152
|
+
fp.writelines(json.dumps(CFG_TEMPLATE, indent = 4))
|
153
|
+
|
154
|
+
if not os.path.exists('examples.py'):
|
155
|
+
from pymud import pkuxkx
|
156
|
+
module_dir = pkuxkx.__file__
|
157
|
+
shutil.copyfile(module_dir, 'examples.py')
|
158
|
+
print(f'The sample script has been copied to the script directory and added to the default configuration file')
|
159
|
+
|
160
|
+
print(f"Afterwards, you can modify the pymud.cfg file in the {dir} directory for configuration.")
|
161
|
+
if system == "windows":
|
162
|
+
print(f"Afterwards, please type the command 'python -m pymud' in the {dir} directory to run PyMUD, or use the shortcut command pymud")
|
163
|
+
else:
|
164
|
+
print(f"Afterwards, please type the command 'python3 -m pymud' in the {dir} directory to run PyMUD, or use the shortcut command pymud")
|
165
|
+
|
166
|
+
input('Press Enter to enter PyMUD.')
|
88
167
|
|
89
168
|
startApp(args)
|
90
169
|
|
@@ -123,7 +202,7 @@ def main():
|
|
123
202
|
subparsers = parser.add_subparsers(help = 'init用于初始化运行环境')
|
124
203
|
|
125
204
|
par_init = subparsers.add_parser('init', description = '初始化pymud运行环境, 包括建立脚本目录, 创建默认配置文件, 创建样例脚本等.')
|
126
|
-
par_init.add_argument('-d', '--dir', dest = 'dir', metavar = 'dir', type = str, default = '', help = '指定构建脚本目录的名称, 不指定时会根据操作系统选择不同默认值')
|
205
|
+
par_init.add_argument('-d', '--dir', dest = 'dir', metavar = 'dir', type = str, default = '.', help = '指定构建脚本目录的名称, 不指定时会根据操作系统选择不同默认值')
|
127
206
|
par_init.set_defaults(func = init_pymud_env)
|
128
207
|
|
129
208
|
parser.add_argument('-d', '--debug', dest = 'debug', action = 'store_true', default = False, help = '指定以调试模式进入PyMUD。此时,系统log等级将设置为logging.NOTSET, 所有log数据均会被记录。默认不启用。')
|
pymud/modules.py
CHANGED
@@ -1,9 +1,21 @@
|
|
1
1
|
|
2
|
-
import importlib, importlib.util
|
3
|
-
from abc import ABC, ABCMeta
|
2
|
+
import importlib, importlib.util, traceback
|
4
3
|
from typing import Any
|
5
|
-
from .
|
4
|
+
from .settings import Settings
|
5
|
+
from .extras import DotDict
|
6
|
+
from .decorators import exception, async_exception, PymudDecorator, print_exception
|
6
7
|
|
8
|
+
class PymudMeta(type):
|
9
|
+
def __new__(cls, name, bases, attrs):
|
10
|
+
decorator_funcs = {}
|
11
|
+
for name, value in attrs.items():
|
12
|
+
if hasattr(value, "__pymud_decorators__"):
|
13
|
+
decorator_funcs[value.__name__] = getattr(value, "__pymud_decorators__", [])
|
14
|
+
|
15
|
+
attrs["_decorator_funcs"] = decorator_funcs
|
16
|
+
|
17
|
+
return super().__new__(cls, name, bases, attrs)
|
18
|
+
|
7
19
|
class ModuleInfo:
|
8
20
|
"""
|
9
21
|
模块管理类。对加载的模块文件进行管理。该类型由Session类进行管理,无需人工创建和干预。
|
@@ -15,7 +27,9 @@ class ModuleInfo:
|
|
15
27
|
|
16
28
|
"""
|
17
29
|
def __init__(self, module_name: str, session):
|
18
|
-
|
30
|
+
from .session import Session
|
31
|
+
if isinstance(session, Session):
|
32
|
+
self.session = session
|
19
33
|
self._name = module_name
|
20
34
|
self._ismainmodule = False
|
21
35
|
self.load()
|
@@ -33,14 +47,19 @@ class ModuleInfo:
|
|
33
47
|
if (attr_name == "Configuration") or issubclass(attr, IConfig):
|
34
48
|
try:
|
35
49
|
self._config[f"{self.name}.{attr_name}"] = attr(self.session, reload = reload)
|
36
|
-
|
50
|
+
if not reload:
|
51
|
+
self.session.info(Settings.gettext("configuration_created", self.name, attr_name))
|
52
|
+
else:
|
53
|
+
self.session.info(Settings.gettext("configuration_recreated", self.name, attr_name))
|
54
|
+
|
37
55
|
except Exception as e:
|
38
56
|
result = False
|
39
|
-
self.session.error(
|
57
|
+
self.session.error(Settings.gettext("configuration_fail", self.name, attr_name, e))
|
40
58
|
self._ismainmodule = (self._config != {})
|
41
59
|
return result
|
42
60
|
|
43
61
|
def _unload(self):
|
62
|
+
from .objects import BaseObject, Command
|
44
63
|
for key, config in self._config.items():
|
45
64
|
if isinstance(config, Command):
|
46
65
|
# Command 对象在从会话中移除时,自动调用其 unload 系列方法,因此不能产生递归
|
@@ -65,21 +84,21 @@ class ModuleInfo:
|
|
65
84
|
def load(self):
|
66
85
|
"加载模块内容"
|
67
86
|
if self._load():
|
68
|
-
self.session.info(f"{'
|
87
|
+
self.session.info(f"{Settings.gettext('entity_module' if self.ismainmodule else 'non_entity_module')} {self.name} {Settings.gettext('load_ok')}")
|
69
88
|
else:
|
70
|
-
self.session.
|
89
|
+
self.session.info(f"{Settings.gettext('entity_module' if self.ismainmodule else 'non_entity_module')} {self.name} {Settings.gettext('load_fail')}")
|
71
90
|
|
72
91
|
def unload(self):
|
73
92
|
"卸载模块内容"
|
74
93
|
self._unload()
|
75
94
|
self._loaded = False
|
76
|
-
self.session.info(f"{'
|
95
|
+
self.session.info(f"{Settings.gettext('entity_module' if self.ismainmodule else 'non_entity_module')} {self.name} {Settings.gettext('unload_ok')}")
|
77
96
|
|
78
97
|
def reload(self):
|
79
98
|
"模块文件更新后调用,重新加载已加载的模块内容"
|
80
99
|
self._unload()
|
81
100
|
self._load(reload = True)
|
82
|
-
self.session.info(f"{'
|
101
|
+
self.session.info(f"{Settings.gettext('entity_module' if self.ismainmodule else 'non_entity_module')} {self.name} {Settings.gettext('reload_ok')}")
|
83
102
|
|
84
103
|
@property
|
85
104
|
def name(self):
|
@@ -101,22 +120,69 @@ class ModuleInfo:
|
|
101
120
|
"只读属性,区分是否主模块(即包含具体config的模块)"
|
102
121
|
return self._ismainmodule
|
103
122
|
|
104
|
-
class
|
123
|
+
class IConfigBase(metaclass = PymudMeta):
|
105
124
|
"""
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
在应用自动创建 IConfig 实例时,除 session 参数外,还会传递一个 reload 参数 (bool类型),表示是首次加载还是重新加载特性。
|
111
|
-
可以从kwargs 中获取该参数,并针对性的设计相应代码。例如,重新加载相关联的其他模块等。
|
125
|
+
用于支持对装饰器写法对象进行管理的基础类。
|
126
|
+
该类型相当于原来的IConfig类,唯一区别时,模块加载时,不会对本类型创建实例对象。
|
127
|
+
主要用于对插件中定义的Command提供装饰器写法支持,因为这些Command是在会话构建时创建,因此不能在模块加载时自动创建,也就不能继承自IConfig。
|
112
128
|
"""
|
113
129
|
def __init__(self, session, *args, **kwargs):
|
114
|
-
|
130
|
+
from .session import Session
|
131
|
+
from .objects import Alias, Trigger, Timer, GMCPTrigger
|
132
|
+
if isinstance(session, Session):
|
133
|
+
self.session = session
|
134
|
+
self.__inline_objects__ = DotDict()
|
135
|
+
|
136
|
+
if hasattr(self, "_decorator_funcs"):
|
137
|
+
deco_funcs = getattr(self, "_decorator_funcs")
|
138
|
+
for func_name, decorators in deco_funcs.items():
|
139
|
+
func = getattr(self, func_name)
|
140
|
+
for deco in decorators:
|
141
|
+
if isinstance(deco, PymudDecorator):
|
142
|
+
if deco.type == "alias":
|
143
|
+
#patterns = deco.kwargs.pop("patterns")
|
144
|
+
ali = Alias(self.session, *deco.args, **deco.kwargs, onSuccess = func)
|
145
|
+
self.__inline_objects__[ali.id] = ali
|
146
|
+
|
147
|
+
elif deco.type == "trigger":
|
148
|
+
#patterns = deco.kwargs.pop("patterns")
|
149
|
+
tri = Trigger(self.session, *deco.args, **deco.kwargs, onSuccess = func)
|
150
|
+
self.__inline_objects__[tri.id] = tri
|
151
|
+
|
152
|
+
elif deco.type == "timer":
|
153
|
+
tim = Timer(self.session, *deco.args, **deco.kwargs, onSuccess = func)
|
154
|
+
self.__inline_objects__[tim.id] = tim
|
155
|
+
|
156
|
+
elif deco.type == "gmcp":
|
157
|
+
gmcp = GMCPTrigger(self.session, name = deco.kwargs.get("id"), *deco.args, **deco.kwargs, onSuccess = func)
|
158
|
+
self.__inline_objects__[gmcp.id] = gmcp
|
115
159
|
|
116
160
|
def __unload__(self):
|
161
|
+
from .objects import BaseObject
|
117
162
|
if self.session:
|
118
|
-
self.session.
|
163
|
+
self.session.delObjects(self.__inline_objects__)
|
164
|
+
if isinstance(self, BaseObject):
|
165
|
+
self.session.delObject(self)
|
119
166
|
|
167
|
+
@property
|
168
|
+
def objs(self) -> DotDict:
|
169
|
+
"返回内联自动创建的对象字典"
|
170
|
+
return self.__inline_objects__
|
171
|
+
|
172
|
+
def obj(self, obj_id: str):
|
173
|
+
"根据对象ID返回内联自动创建的对象"
|
174
|
+
return self.__inline_objects__.get(obj_id, None) # type: ignore
|
175
|
+
|
176
|
+
class IConfig(IConfigBase):
|
177
|
+
"""
|
178
|
+
用于提示PyMUD应用是否自动创建该配置类型的基础类。
|
179
|
+
|
180
|
+
继承 IConfig 类型让应用自动管理该类型,唯一需要的是,构造函数中,仅存在一个必须指定的参数 Session。
|
181
|
+
|
182
|
+
在应用自动创建 IConfig 实例时,除 session 参数外,还会传递一个 reload 参数 (bool类型),表示是首次加载还是重新加载特性。
|
183
|
+
可以从kwargs 中获取该参数,并针对性的设计相应代码。例如,重新加载相关联的其他模块等。
|
184
|
+
"""
|
185
|
+
|
120
186
|
class Plugin:
|
121
187
|
"""
|
122
188
|
插件管理类。对加载的插件文件进行管理。该类型由PyMudApp进行管理,无需人工创建。
|
@@ -137,17 +203,17 @@ class Plugin:
|
|
137
203
|
"加载/重新加载插件对象"
|
138
204
|
#del self.modspec, self.mod
|
139
205
|
self.modspec = importlib.util.spec_from_file_location(self._plugin_file[:-3], self._plugin_loc)
|
140
|
-
self.
|
141
|
-
|
206
|
+
if self.modspec and self.modspec.loader:
|
207
|
+
self.mod = importlib.util.module_from_spec(self.modspec)
|
208
|
+
self.modspec.loader.exec_module(self.mod)
|
142
209
|
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
self._app_destroy = self._load_mod_function("PLUGIN_PYMUD_DESTROY")
|
210
|
+
self._app_init = self._load_mod_function("PLUGIN_PYMUD_START")
|
211
|
+
self._session_create = self._load_mod_function("PLUGIN_SESSION_CREATE")
|
212
|
+
self._session_destroy = self._load_mod_function("PLUGIN_SESSION_DESTROY")
|
213
|
+
self._app_destroy = self._load_mod_function("PLUGIN_PYMUD_DESTROY")
|
214
|
+
|
215
|
+
else:
|
216
|
+
raise FileNotFoundError(Settings.gettext("exception_plugin_file_not_found", self._plugin_file))
|
151
217
|
|
152
218
|
def _load_mod_function(self, func_name):
|
153
219
|
# 定义一个默认函数,当插件文件中未定义指定名称的函数时,返回该函数
|
@@ -191,7 +257,11 @@ class Plugin:
|
|
191
257
|
|
192
258
|
:param session: 新创建的会话对象实例
|
193
259
|
"""
|
194
|
-
|
260
|
+
try:
|
261
|
+
self._session_create(session)
|
262
|
+
except Exception as e:
|
263
|
+
print_exception(session, e)
|
264
|
+
|
195
265
|
|
196
266
|
def onSessionDestroy(self, session):
|
197
267
|
"""
|
@@ -199,7 +269,10 @@ class Plugin:
|
|
199
269
|
|
200
270
|
:param session: 所关闭的会话对象实例
|
201
271
|
"""
|
202
|
-
|
272
|
+
try:
|
273
|
+
self._session_destroy(session)
|
274
|
+
except Exception as e:
|
275
|
+
print_exception(session, e)
|
203
276
|
|
204
277
|
def onAppDestroy(self, app):
|
205
278
|
"""
|