pymud 0.20.0a2__py3-none-any.whl → 0.20.0a3__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 CHANGED
@@ -4,7 +4,8 @@ from .objects import CodeBlock, Alias, SimpleAlias, Trigger, SimpleTrigger, Comm
4
4
  from .extras import DotDict
5
5
  from .session import Session
6
6
  from .logger import Logger
7
+ from .main import main
7
8
 
8
9
  __all__ = [
9
- "PyMudApp", "Settings", "CodeBlock", "Alias", "SimpleAlias", "Trigger", "SimpleTrigger", "Command", "SimpleCommand", "Timer", "SimpleTimer", "GMCPTrigger", "Session", "PyMudApp", "DotDict", "Logger"
10
+ "PyMudApp", "Settings", "CodeBlock", "Alias", "SimpleAlias", "Trigger", "SimpleTrigger", "Command", "SimpleCommand", "Timer", "SimpleTimer", "GMCPTrigger", "Session", "PyMudApp", "DotDict", "Logger", "main"
10
11
  ]
pymud/__main__.py CHANGED
@@ -1,133 +1,4 @@
1
- import os, json, platform, shutil, logging, argparse
2
- from pathlib import Path
3
- from .pymud import main
4
- from .settings import Settings
5
-
6
- CFG_TEMPLATE = {
7
- "client": {
8
- "buffer_lines" : 5000, # 保留缓冲行数
9
-
10
- "interval" : 10, # 在自动执行中,两次命令输入中的间隔时间(ms)
11
- "auto_connect" : True, # 创建会话后,是否自动连接
12
- "auto_reconnect" : False, # 在会话异常断开之后,是否自动重连
13
- "var_autosave" : True, # 断开时自动保存会话变量
14
- "var_autoload" : True, # 初始化时自动加载会话变量
15
-
16
- "echo_input" : False,
17
- "beautify" : True, # 专门为解决控制台下PKUXKX字符画对不齐的问题
18
-
19
- "status_display" : 1, # 状态窗口显示情况设置,0-不显示,1-显示在下方,2-显示在右侧
20
- "status_height" : 4, # 下侧状态栏的高度
21
- "status_width" : 30, # 右侧状态栏的宽度
22
-
23
- },
24
- "sessions" : {
25
- "pkuxkx" : {
26
- "host" : "mud.pkuxkx.net",
27
- "port" : "8081",
28
- "encoding" : "utf8",
29
- "autologin" : "{0};{1}",
30
- "default_script": "examples",
31
- "chars" : {
32
- "display_title" : ["yourid", "yourpassword", ""],
33
- }
34
- }
35
- },
36
- "keys" : {
37
- "f3" : "#ig",
38
- "f4" : "#clear",
39
- "f11" : "#close",
40
- "f12" : "#exit",
41
- }
42
- }
43
-
44
- def init_pymud_env(args):
45
- print(f"欢迎使用PyMUD, 版本{Settings.__version__}. 使用PyMUD时, 建议建立一个新目录(任意位置),并将自己的脚本以及配置文件放到该目录下.")
46
- print("即将开始为首次运行初始化环境...")
47
-
48
- dir = args.dir
49
- if dir:
50
- print(f"你已经指定了创建脚本的目录为 {args.dir}")
51
- dir = Path(dir)
52
- else:
53
- dir = Path.home().joinpath('pkuxkx')
54
-
55
- system = platform.system().lower()
56
- dir_enter = input(f"检测到当前系统为 {system}, 请指定游戏脚本的目录(若目录不存在会自动创建),直接回车表示使用默认值 [{dir}]:")
57
- if dir_enter:
58
- dir = Path(dir_enter)
59
-
60
- if dir.exists() and dir.is_dir():
61
- print(f'检测到给定目录 {dir} 已存在,切换至此目录...')
62
- else:
63
- print(f'检测到给定目录 {dir} 不存在,正在创建并切换至目录...')
64
- dir.mkdir()
65
-
66
- os.chdir(dir)
67
-
68
- if os.path.exists('pymud.cfg'):
69
- print(f'检测到脚本目录下已存在pymud.cfg文件,将直接使用此文件进入PyMUD...')
70
- else:
71
- print(f'检测到脚本目录下不存在pymud.cfg文件,将使用默认内容创建该配置文件...')
72
- with open('pymud.cfg', mode = 'x') as fp:
73
- fp.writelines(json.dumps(CFG_TEMPLATE, indent = 4))
74
-
75
- if not os.path.exists('examples.py'):
76
- from pymud import pkuxkx
77
- module_dir = pkuxkx.__file__
78
- shutil.copyfile(module_dir, 'examples.py')
79
- print(f'已将样例脚本拷贝至脚本目录,并加入默认配置文件')
80
-
81
- print(f"后续可自行修改 {dir} 目录下的 pymud.cfg 文件以进行配置。")
82
- if system == "windows":
83
- print(f"后续运行PyMUD, 请在 {dir} 目录下键入命令: python -m pymud")
84
- else:
85
- print(f"后续运行PyMUD, 请在 {dir} 目录下键入命令: python3 -m pymud")
86
-
87
- input('所有内容已初始化完毕, 请按回车进入PyMUD.')
88
-
89
- module_entry(args)
90
-
91
- def module_entry(args):
92
- if args.debug:
93
- logging.basicConfig(level = logging.NOTSET,
94
- format = '%(asctime)s %(name)-12s %(levelname)-8s %(message)s',
95
- datefmt = '%m-%d %H:%M',
96
- filename = args.logfile,
97
- filemode = 'a' if args.filemode else 'w',
98
- encoding = "utf-8"
99
- )
100
-
101
- else:
102
- logging.basicConfig(level = logging.NOTSET,
103
- format = '%(asctime)s %(name)-12s: %(message)s',
104
- datefmt = '%m-%d %H:%M',
105
- handlers = [logging.NullHandler()],
106
- )
107
-
108
- cfg = "pymud.cfg"
109
- if os.path.exists(cfg):
110
- with open(cfg, "r", encoding="utf8", errors="ignore") as fp:
111
- cfg_data = json.load(fp)
112
- main(cfg_data)
113
- else:
114
- main()
115
-
1
+ from .main import main
116
2
 
117
3
  if __name__ == "__main__":
118
- parser = argparse.ArgumentParser(prog = "pymud", usage = "python -m pymud [-h] [-d] [-l logfile] [-a] {init} ...", description = "PyMUD命令行参数帮助")
119
- subparsers = parser.add_subparsers(help = 'init用于初始化运行环境')
120
-
121
- par_init = subparsers.add_parser('init', usage = "python -m pymud init [-h] [-d dir]", description = '初始化pymud运行环境, 包括建立脚本目录, 创建默认配置文件, 创建样例脚本等.')
122
- par_init.add_argument('-d', '--dir', dest = 'dir', metavar = 'dir', type = str, default = '', help = '指定构建脚本目录的名称, 不指定时会根据操作系统选择不同默认值')
123
- par_init.set_defaults(func = init_pymud_env)
124
-
125
- parser.add_argument('-d', '--debug', dest = 'debug', action = 'store_true', default = False, help = '指定以调试模式进入PyMUD。此时,系统log等级将设置为logging.NOTSET, 所有log数据均会被记录。默认不启用。')
126
- parser.add_argument('-l', '--logfile', dest = 'logfile', metavar = 'logfile', default = 'pymud.log', help = '指定调试模式下记录文件名,不指定时,默认为当前目录下的pymud.log')
127
- parser.add_argument('-a', '--appendmode', dest = 'filemode', action = 'store_true', default = True, help = '指定log文件的访问模式是否为append尾部添加模式,默认为True。当为False时,使用w模式,即每次运行清空之前记录')
128
-
129
- args=parser.parse_args()
130
- if hasattr(args, 'func'):
131
- args.func(args)
132
- else:
133
- module_entry(args)
4
+ main()
pymud/logger.py CHANGED
@@ -15,7 +15,7 @@ class Logger:
15
15
  :param raw: 记录带ANSI标记的原始内容,还是记录纯文本内容,默认为True,即记录带ANSI标记的原始内容。
16
16
  """
17
17
 
18
- _esc_regx = re.compile("\x1b\\[[\d;]+[abcdmz]", flags = re.IGNORECASE)
18
+ _esc_regx = re.compile(r"\x1b\[[\d;]+[abcdmz]", flags = re.IGNORECASE)
19
19
 
20
20
  def __init__(self, name, mode = 'a', encoding = "utf-8", errors = "ignore", raw = False):
21
21
  self._name = name
pymud/main.py ADDED
@@ -0,0 +1,141 @@
1
+ import os, sys, json, platform, shutil, logging, argparse
2
+ from pathlib import Path
3
+ from .pymud import PyMudApp
4
+ from .settings import Settings
5
+
6
+ CFG_TEMPLATE = {
7
+ "client": {
8
+ "buffer_lines" : 5000, # 保留缓冲行数
9
+
10
+ "interval" : 10, # 在自动执行中,两次命令输入中的间隔时间(ms)
11
+ "auto_connect" : True, # 创建会话后,是否自动连接
12
+ "auto_reconnect" : False, # 在会话异常断开之后,是否自动重连
13
+ "var_autosave" : True, # 断开时自动保存会话变量
14
+ "var_autoload" : True, # 初始化时自动加载会话变量
15
+
16
+ "echo_input" : False,
17
+ "beautify" : True, # 专门为解决控制台下PKUXKX字符画对不齐的问题
18
+
19
+ "status_display" : 1, # 状态窗口显示情况设置,0-不显示,1-显示在下方,2-显示在右侧
20
+ "status_height" : 4, # 下侧状态栏的高度
21
+ "status_width" : 30, # 右侧状态栏的宽度
22
+
23
+ },
24
+ "sessions" : {
25
+ "pkuxkx" : {
26
+ "host" : "mud.pkuxkx.net",
27
+ "port" : "8081",
28
+ "encoding" : "utf8",
29
+ "autologin" : "{0};{1}",
30
+ "default_script": "examples",
31
+ "chars" : {
32
+ "display_title" : ["yourid", "yourpassword", ""],
33
+ }
34
+ }
35
+ },
36
+ "keys" : {
37
+ "f3" : "#ig",
38
+ "f4" : "#clear",
39
+ "f11" : "#close",
40
+ "f12" : "#exit",
41
+ }
42
+ }
43
+
44
+ def init_pymud_env(args):
45
+ print(f"欢迎使用PyMUD, 版本{Settings.__version__}. 使用PyMUD时, 建议建立一个新目录(任意位置),并将自己的脚本以及配置文件放到该目录下.")
46
+ print("即将开始为首次运行初始化环境...")
47
+
48
+ dir = args.dir
49
+ if dir:
50
+ print(f"你已经指定了创建脚本的目录为 {args.dir}")
51
+ dir = Path(dir)
52
+ else:
53
+ dir = Path.home().joinpath('pkuxkx')
54
+
55
+ system = platform.system().lower()
56
+ dir_enter = input(f"检测到当前系统为 {system}, 请指定游戏脚本的目录(若目录不存在会自动创建),直接回车表示使用默认值 [{dir}]:")
57
+ if dir_enter:
58
+ dir = Path(dir_enter)
59
+
60
+ if dir.exists() and dir.is_dir():
61
+ print(f'检测到给定目录 {dir} 已存在,切换至此目录...')
62
+ else:
63
+ print(f'检测到给定目录 {dir} 不存在,正在创建并切换至目录...')
64
+ dir.mkdir()
65
+
66
+ os.chdir(dir)
67
+
68
+ if os.path.exists('pymud.cfg'):
69
+ print(f'检测到脚本目录下已存在pymud.cfg文件,将直接使用此文件进入PyMUD...')
70
+ else:
71
+ print(f'检测到脚本目录下不存在pymud.cfg文件,将使用默认内容创建该配置文件...')
72
+ with open('pymud.cfg', mode = 'x') as fp:
73
+ fp.writelines(json.dumps(CFG_TEMPLATE, indent = 4))
74
+
75
+ if not os.path.exists('examples.py'):
76
+ from pymud import pkuxkx
77
+ module_dir = pkuxkx.__file__
78
+ shutil.copyfile(module_dir, 'examples.py')
79
+ print(f'已将样例脚本拷贝至脚本目录,并加入默认配置文件')
80
+
81
+ print(f"后续可自行修改 {dir} 目录下的 pymud.cfg 文件以进行配置。")
82
+ if system == "windows":
83
+ print(f"后续运行PyMUD, 请在 {dir} 目录下键入命令: python -m pymud")
84
+ else:
85
+ print(f"后续运行PyMUD, 请在 {dir} 目录下键入命令: python3 -m pymud")
86
+
87
+ input('所有内容已初始化完毕, 请按回车进入PyMUD.')
88
+
89
+ startApp(args)
90
+
91
+ def startApp(args):
92
+ if args.debug:
93
+ logging.basicConfig(level = logging.NOTSET,
94
+ format = '%(asctime)s %(name)-12s %(levelname)-8s %(message)s',
95
+ datefmt = '%m-%d %H:%M',
96
+ filename = args.logfile,
97
+ filemode = 'a' if args.filemode else 'w',
98
+ encoding = "utf-8"
99
+ )
100
+
101
+ else:
102
+ logging.basicConfig(level = logging.NOTSET,
103
+ format = '%(asctime)s %(name)-12s: %(message)s',
104
+ datefmt = '%m-%d %H:%M',
105
+ handlers = [logging.NullHandler()],
106
+ )
107
+
108
+ startup_path = Path(args.startup_dir).resolve()
109
+ sys.path.append(f"{startup_path}")
110
+ os.chdir(startup_path)
111
+ cfg = startup_path.joinpath("pymud.cfg")
112
+ cfg_data = None
113
+ if os.path.exists(cfg):
114
+ with open(cfg, "r", encoding="utf8", errors="ignore") as fp:
115
+ cfg_data = json.load(fp)
116
+
117
+ app = PyMudApp(cfg_data)
118
+ app.run()
119
+
120
+ def main():
121
+ parser = argparse.ArgumentParser(prog = "pymud", description = "PyMUD命令行参数帮助")
122
+ subparsers = parser.add_subparsers(help = 'init用于初始化运行环境')
123
+
124
+ par_init = subparsers.add_parser('init', description = '初始化pymud运行环境, 包括建立脚本目录, 创建默认配置文件, 创建样例脚本等.')
125
+ par_init.add_argument('-d', '--dir', dest = 'dir', metavar = 'dir', type = str, default = '', help = '指定构建脚本目录的名称, 不指定时会根据操作系统选择不同默认值')
126
+ par_init.set_defaults(func = init_pymud_env)
127
+
128
+ parser.add_argument('-d', '--debug', dest = 'debug', action = 'store_true', default = False, help = '指定以调试模式进入PyMUD。此时,系统log等级将设置为logging.NOTSET, 所有log数据均会被记录。默认不启用。')
129
+ parser.add_argument('-l', '--logfile', dest = 'logfile', metavar = 'logfile', default = 'pymud.log', help = '指定调试模式下记录文件名,不指定时,默认为当前目录下的pymud.log')
130
+ parser.add_argument('-a', '--appendmode', dest = 'filemode', action = 'store_true', default = True, help = '指定log文件的访问模式是否为append尾部添加模式,默认为True。当为False时,使用w模式,即每次运行清空之前记录')
131
+ parser.add_argument('-s', '--startup_dir', dest = 'startup_dir', metavar = 'startup_dir', default = '.', help = '指定启动目录,默认为当前目录。使用该参数可以在任何目录下,通过指定脚本目录来启动')
132
+
133
+ args=parser.parse_args()
134
+
135
+ if hasattr(args, 'func'):
136
+ args.func(args)
137
+ else:
138
+ startApp(args)
139
+
140
+ if __name__ == "__main__":
141
+ main()
pymud/pymud.py CHANGED
@@ -318,8 +318,8 @@ class PyMudApp:
318
318
  ),
319
319
 
320
320
  MenuItem(
321
- "", # 增加一个空名称MenuItem,阻止右侧空白栏点击响应
322
- children=[]
321
+ "", # 增加一个空名称MenuItem,单机后焦点移动至命令行输入处,阻止右侧空白栏点击响应
322
+ handler = lambda : self.app.layout.focus(self.commandLine)
323
323
  )
324
324
  ],
325
325
  floats=[
@@ -340,34 +340,9 @@ class PyMudApp:
340
340
  ss = Settings.sessions
341
341
 
342
342
  for key, site in ss.items():
343
- host = site["host"]
344
- port = site["port"]
345
- encoding = site["encoding"]
346
- autologin = site["autologin"]
347
- scripts = list()
348
- default_script = site["default_script"]
349
-
350
- def_scripts = list()
351
- if isinstance(default_script, str):
352
- def_scripts.extend(default_script.split(","))
353
- elif isinstance(default_script, (list, tuple)):
354
- def_scripts.extend(default_script)
355
-
356
343
  menu = MenuItem(key)
357
- for name, info in site["chars"].items():
358
- after_connect = autologin.format(info[0], info[1])
359
- sess_scripts = list()
360
- sess_scripts.extend(def_scripts)
361
-
362
- if len(info) == 3:
363
- session_script = info[2]
364
- if session_script:
365
- if isinstance(session_script, str):
366
- sess_scripts.extend(session_script.split(","))
367
- elif isinstance(session_script, (list, tuple)):
368
- sess_scripts.extend(session_script)
369
-
370
- sub = MenuItem(name, handler = functools.partial(self.create_session, name, host, port, encoding, after_connect, sess_scripts, info[0]))
344
+ for name in site["chars"].keys():
345
+ sub = MenuItem(name, handler = functools.partial(self._quickHandleSession, key, name))
371
346
  menu.children.append(sub)
372
347
  menus.append(menu)
373
348
 
@@ -506,7 +481,7 @@ class PyMudApp:
506
481
  line = self.mudFormatProc.line_correction(b.document.current_line)
507
482
  start = max(0, scol)
508
483
  end = min(ecol, len(line))
509
- line_plain = re.sub("\x1b\\[[\d;]+[abcdmz]", "", line, flags = re.IGNORECASE).replace("\r", "").replace("\x00", "")
484
+ line_plain = re.sub(r"\x1b\[[\d;]+[abcdmz]", "", line, flags = re.IGNORECASE).replace("\r", "").replace("\x00", "")
510
485
  #line_plain = re.sub("\x1b\\[[^mz]+[mz]", "", line).replace("\r", "").replace("\x00", "")
511
486
  selection = line_plain[start:end]
512
487
  self.app.clipboard.set_text(selection)
@@ -518,7 +493,7 @@ class PyMudApp:
518
493
  lines = []
519
494
  for row in range(srow, erow + 1):
520
495
  line = b.document.lines[row]
521
- line_plain = re.sub("\x1b\\[[\d;]+[abcdmz]", "", line, flags = re.IGNORECASE).replace("\r", "").replace("\x00", "")
496
+ line_plain = re.sub(r"\x1b\[[\d;]+[abcdmz]", "", line, flags = re.IGNORECASE).replace("\r", "").replace("\x00", "")
522
497
  lines.append(line_plain)
523
498
 
524
499
  self.app.clipboard.set_text("\n".join(lines))
@@ -919,6 +894,50 @@ class PyMudApp:
919
894
  self.status_message = msg
920
895
  self.app.invalidate()
921
896
 
897
+ def _quickHandleSession(self, group, name):
898
+ '''
899
+ 根据指定的组名和会话角色名,从Settings内容,创建一个会话
900
+ '''
901
+ handled = False
902
+ if name in self.sessions.keys():
903
+ self.activate_session(name)
904
+ handled = True
905
+
906
+ else:
907
+ site = Settings.sessions[group]
908
+ if name in site["chars"].keys():
909
+ host = site["host"]
910
+ port = site["port"]
911
+ encoding = site["encoding"]
912
+ autologin = site["autologin"]
913
+ default_script = site["default_script"]
914
+
915
+ def_scripts = list()
916
+ if isinstance(default_script, str):
917
+ def_scripts.extend(default_script.split(","))
918
+ elif isinstance(default_script, (list, tuple)):
919
+ def_scripts.extend(default_script)
920
+
921
+ charinfo = site["chars"][name]
922
+
923
+ after_connect = autologin.format(charinfo[0], charinfo[1])
924
+ sess_scripts = list()
925
+ sess_scripts.extend(def_scripts)
926
+
927
+ if len(charinfo) == 3:
928
+ session_script = charinfo[2]
929
+ if session_script:
930
+ if isinstance(session_script, str):
931
+ sess_scripts.extend(session_script.split(","))
932
+ elif isinstance(session_script, (list, tuple)):
933
+ sess_scripts.extend(session_script)
934
+
935
+ self.create_session(name, host, port, encoding, after_connect, sess_scripts, charinfo[0])
936
+ handled = True
937
+
938
+ return handled
939
+
940
+
922
941
  def handle_session(self, *args):
923
942
  '''
924
943
  嵌入命令 #session 的执行函数,创建一个远程连接会话。
@@ -929,12 +948,18 @@ class PyMudApp:
929
948
  - 当不指定 Encoding: 时, 默认使用utf-8编码
930
949
  - 可以直接使用 #{名称} 切换会话和操作会话命令
931
950
 
951
+ - #session {group}.{name}
952
+ - 相当于直接点击菜单{group}下的{name}菜单来创建会话. 当该会话已存在时,切换到该会话
953
+
932
954
  参数:
933
955
  :name: 会话名称
934
956
  :host: 服务器域名或IP地址
935
957
  :port: 端口号
936
958
  :encoding: 编码格式,不指定时默认为 utf8
937
959
 
960
+ :group: 组名, 即配置文件中, sessions 字段下的某个关键字
961
+ :name: 会话快捷名称, 上述 group 关键字下的 chars 字段中的某个关键字
962
+
938
963
  示例:
939
964
  ``#session {名称} {宿主机} {端口} {编码}``
940
965
  创建一个远程连接会话,使用指定编码格式连接到远程宿主机的指定端口并保存为 {名称} 。其中,编码可以省略,此时使用Settings.server["default_encoding"]的值,默认为utf8
@@ -947,6 +972,9 @@ class PyMudApp:
947
972
  ``#newstart give miui gold``
948
973
  使名称为newstart的会话执行give miui gold指令,但不切换到该会话
949
974
 
975
+ ``#session pkuxkx.newstart``
976
+ 通过指定快捷配置创建会话,相当于点击 世界->pkuxkx->newstart 菜单创建会话。若该会话存在,则切换到该会话
977
+
950
978
  相关命令:
951
979
  - #close
952
980
  - #exit
@@ -954,8 +982,17 @@ class PyMudApp:
954
982
  '''
955
983
 
956
984
  nothandle = True
985
+ errmsg = "错误的#session命令"
986
+ if len(args) == 1:
987
+ host_session = args[0]
988
+ if '.' in host_session:
989
+ group, name = host_session.split('.')
990
+ nothandle = not self._quickHandleSession(group, name)
957
991
 
958
- if len(args) >= 3:
992
+ else:
993
+ errmsg = f'通过单一参数快速创建会话时,要使用 group.name 形式,如 #session pkuxkx.newstart'
994
+
995
+ elif len(args) >= 3:
959
996
  session_name = args[0]
960
997
  session_host = args[1]
961
998
  session_port = int(args[2])
@@ -968,7 +1005,7 @@ class PyMudApp:
968
1005
  nothandle = False
969
1006
 
970
1007
  if nothandle:
971
- self.set_status("错误的#session命令")
1008
+ self.set_status(errmsg)
972
1009
 
973
1010
  def enter_pressed(self, buffer: Buffer):
974
1011
  "命令行回车按键处理"
@@ -1162,21 +1199,6 @@ class PyMudApp:
1162
1199
  plugin.onSessionCreate(session)
1163
1200
 
1164
1201
 
1165
- def main(cfg_data = None):
1202
+ def startApp(cfg_data = None):
1166
1203
  app = PyMudApp(cfg_data)
1167
1204
  app.run()
1168
-
1169
- if __name__ == "__main__":
1170
-
1171
- cfg = "pymud.cfg"
1172
- import sys
1173
- args = sys.argv
1174
- if len(args) > 1:
1175
- cfg = args[1]
1176
-
1177
- if os.path.exists(cfg):
1178
- with open(cfg, "r", encoding="utf8", errors="ignore") as fp:
1179
- cfg_data = json.load(fp)
1180
- main(cfg_data)
1181
- else:
1182
- main()
pymud/session.py CHANGED
@@ -8,7 +8,7 @@ from logging.handlers import QueueHandler, QueueListener
8
8
  from .logger import Logger
9
9
  from .extras import SessionBuffer, DotDict, Plugin
10
10
  from .protocol import MudClientProtocol
11
- from .objects import Trigger, Alias, Command, Timer, SimpleAlias, SimpleTrigger, SimpleTimer, GMCPTrigger, CodeBlock, CodeLine
11
+ from .objects import BaseObject, Trigger, Alias, Command, Timer, SimpleAlias, SimpleTrigger, SimpleTimer, GMCPTrigger, CodeBlock, CodeLine
12
12
  from .settings import Settings
13
13
 
14
14
 
@@ -29,13 +29,14 @@ class Session:
29
29
 
30
30
  """
31
31
  #_esc_regx = re.compile("\x1b\\[[^mz]+[mz]")
32
- _esc_regx = re.compile("\x1b\\[[\d;]+[abcdmz]", flags = re.IGNORECASE)
32
+ _esc_regx = re.compile(r"\x1b\[[\d;]+[abcdmz]", flags = re.IGNORECASE)
33
33
 
34
34
  _sys_commands = (
35
35
  "help",
36
36
  "exit",
37
37
  "close",
38
38
  "connect", # 连接到服务器
39
+ "disconnect", # 从服务器断开连接
39
40
 
40
41
  "info", # 输出蓝色info
41
42
  "warning", # 输出黄色warning
@@ -89,6 +90,7 @@ class Session:
89
90
  "var" : "variable",
90
91
  "rep" : "repeat",
91
92
  "con" : "connect",
93
+ "dis" : "disconnect",
92
94
  "wa" : "wait",
93
95
  "mess": "message",
94
96
  "action": "trigger",
@@ -808,7 +810,7 @@ class Session:
808
810
  示例:
809
811
  .. code:: Python
810
812
 
811
- 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"))
813
+ session.addAlias(SimpleAlias(self.session, r"^cb\s(\S+)\s(\S+)", "#3 get %1 from jinnang;#wa 250;combine gem;#wa 250;pack gem", id = "ali_combine"))
812
814
  session.exec("cb j1a")
813
815
  """
814
816
  name = name or self.name
@@ -1141,31 +1143,100 @@ class Session:
1141
1143
 
1142
1144
  return counts
1143
1145
 
1144
- def _addObjects(self, objs: dict, cls: type):
1145
- if cls == Alias:
1146
- self._aliases.update(objs)
1147
- elif cls == Command:
1148
- self._commands.update(objs)
1149
- elif cls == Trigger:
1150
- self._triggers.update(objs)
1151
- elif cls == Timer:
1152
- self._timers.update(objs)
1153
- elif cls == GMCPTrigger:
1154
- self._gmcp.update(objs)
1155
-
1156
- def _addObject(self, obj, cls: type):
1157
- #if type(obj) == cls:
1158
- if isinstance(obj, cls):
1159
- if cls == Alias:
1160
- self._aliases[obj.id] = obj
1161
- elif cls == Command:
1162
- self._commands[obj.id] = obj
1163
- elif cls == Trigger:
1164
- self._triggers[obj.id] = obj
1165
- elif cls == Timer:
1166
- self._timers[obj.id] = obj
1167
- elif cls == GMCPTrigger:
1168
- self._gmcp[obj.id] = obj
1146
+ # def _addObjects(self, objs: dict, cls: type):
1147
+ # if cls == Alias:
1148
+ # self._aliases.update(objs)
1149
+ # elif cls == Command:
1150
+ # self._commands.update(objs)
1151
+ # elif cls == Trigger:
1152
+ # self._triggers.update(objs)
1153
+ # elif cls == Timer:
1154
+ # self._timers.update(objs)
1155
+ # elif cls == GMCPTrigger:
1156
+ # self._gmcp.update(objs)
1157
+
1158
+ def _addObjects(self, objs):
1159
+ if isinstance(objs, list) or isinstance(objs, tuple):
1160
+ for item in objs:
1161
+ self._addObject(item)
1162
+
1163
+ elif isinstance(objs, dict):
1164
+ for key, item in objs.items():
1165
+ if isinstance(item, BaseObject):
1166
+ if key != item.id:
1167
+ self.warning(f'对象 {item} 字典键值 {key} 与其id {item.id} 不一致,将丢弃键值,以其id添加到会话中...')
1168
+
1169
+ self._addObject(item)
1170
+
1171
+ # def _addObject(self, obj, cls: type):
1172
+ # #if type(obj) == cls:
1173
+ # if isinstance(obj, cls):
1174
+ # if cls == Alias:
1175
+ # self._aliases[obj.id] = obj
1176
+ # elif cls == Command:
1177
+ # self._commands[obj.id] = obj
1178
+ # elif cls == Trigger:
1179
+ # self._triggers[obj.id] = obj
1180
+ # elif cls == Timer:
1181
+ # self._timers[obj.id] = obj
1182
+ # elif cls == GMCPTrigger:
1183
+ # self._gmcp[obj.id] = obj
1184
+
1185
+ def _addObject(self, obj):
1186
+ if isinstance(obj, Alias):
1187
+ self._aliases[obj.id] = obj
1188
+ elif isinstance(obj, Command):
1189
+ self._commands[obj.id] = obj
1190
+ elif isinstance(obj, Trigger):
1191
+ self._triggers[obj.id] = obj
1192
+ elif isinstance(obj, Timer):
1193
+ self._timers[obj.id] = obj
1194
+ elif isinstance(obj, GMCPTrigger):
1195
+ self._gmcp[obj.id] = obj
1196
+
1197
+ def addObject(self, obj: BaseObject):
1198
+ """
1199
+ 向会话中增加单个对象,可直接添加 Alias, Trigger, GMCPTrigger, Command, Timer 或它们的子类
1200
+
1201
+ :param obj: 特定对象本身,可以为 Alias, Trigger, GMCPTrigger, Command, Timer 或其子类
1202
+
1203
+ 示例:
1204
+ .. code:: Python
1205
+
1206
+ class Configuration:
1207
+ def __init__(self, session):
1208
+ self.session = session
1209
+
1210
+ self.session.addObject(SimpleAlias(session, r'^gta$', 'get all'),)
1211
+ self.session.addObject(SimpleTrigger(session, r'^[> ]*你嘻嘻地笑了起来.+', 'haha'))
1212
+ self.session.addObject(SimpleTimer(session, 'xixi', timeout = 10))
1213
+
1214
+ """
1215
+ self._addObject(obj)
1216
+
1217
+ def addObjects(self, objs):
1218
+ """
1219
+ 向会话中增加多个对象,可直接添加 Alias, Trigger, GMCPTrigger, Command, Timer 或它们的子类的元组、列表或者字典(保持兼容性)
1220
+
1221
+ :param objs: 多个特定对象组成的元组、列表或者字典,可以为 Alias, Trigger, GMCPTrigger, Command, Timer 或其子类
1222
+
1223
+ 示例:
1224
+ .. code:: Python
1225
+
1226
+ class Configuration:
1227
+ def __init__(self, session):
1228
+ self.session = session
1229
+
1230
+ self.objs = [
1231
+ SimpleAlias(session, r'^gta$', 'get all;xixi'),
1232
+ SimpleTrigger(session, r'^[> ]*你嘻嘻地笑了起来.+', 'haha'),
1233
+ SimpleTimer(session, 'xixi', timeout = 10)
1234
+ ]
1235
+
1236
+ self.session.addObjects(self.objs)
1237
+
1238
+ """
1239
+ self._addObjects(objs)
1169
1240
 
1170
1241
  def _delObject(self, id, cls: type):
1171
1242
  if cls == Alias:
@@ -1175,16 +1246,103 @@ class Session:
1175
1246
  elif cls == Trigger:
1176
1247
  self._triggers.pop(id, None)
1177
1248
  elif cls == Timer:
1178
- self._timers.pop(id, None)
1249
+ timer = self._timers.pop(id, None)
1250
+ if isinstance(timer, Timer):
1251
+ timer.enabled = False
1179
1252
  elif cls == GMCPTrigger:
1180
1253
  self._gmcp.pop(id, None)
1181
1254
 
1255
+ # def _delObject(self, obj):
1256
+ # if isinstance(obj, Alias):
1257
+ # self._aliases.pop(obj.id, None)
1258
+ # elif isinstance(obj, Command):
1259
+ # self._commands.pop(obj.id, None)
1260
+ # elif isinstance(obj, Trigger):
1261
+ # self._triggers.pop(obj.id, None)
1262
+ # elif isinstance(obj, Timer):
1263
+ # self._timers.pop(obj.id, None)
1264
+ # elif isinstance(obj, GMCPTrigger):
1265
+ # self._gmcp.pop(obj.id, None)
1266
+
1182
1267
  def _delObjects(self, ids: Iterable, cls: type):
1183
1268
  "删除多个指定元素"
1184
1269
  for id in ids:
1185
1270
  self._delObject(id, cls)
1186
1271
 
1187
- def addAliases(self, alis: dict):
1272
+ def delObject(self, obj):
1273
+ """
1274
+ 从会话中移除一个对象,可直接删除 Alias, Trigger, GMCPTrigger, Command, Timer 或它们的子类本身
1275
+
1276
+ :param obj: 要删除的多个特定对象组成的元组、列表或者字典,可以为 Alias, Trigger, GMCPTrigger, Command, Timer 或其子类
1277
+
1278
+ 示例:
1279
+ .. code:: Python
1280
+
1281
+ class Configuration:
1282
+ def __init__(self, session):
1283
+ self.session = session
1284
+
1285
+ ali = Alias(session, "s", "south", id = "my_ali1")
1286
+
1287
+ # 以下几种方式均可将该别名添加到会话
1288
+ session.addObject(ali)
1289
+ session.addAlias(ali)
1290
+
1291
+ # 以下三种方式均可以删除该别名
1292
+ session.delObjec(ali)
1293
+ session.delAlias(ali)
1294
+ session.delAlias("my_ali1")
1295
+
1296
+ """
1297
+ if isinstance(obj, Alias):
1298
+ self._aliases.pop(obj.id, None)
1299
+ elif isinstance(obj, Command):
1300
+ self._commands.pop(obj.id, None)
1301
+ elif isinstance(obj, Trigger):
1302
+ self._triggers.pop(obj.id, None)
1303
+ elif isinstance(obj, Timer):
1304
+ timer = self._timers.pop(obj.id, None)
1305
+ if isinstance(timer, Timer):
1306
+ timer.enabled = False
1307
+ elif isinstance(obj, GMCPTrigger):
1308
+ self._gmcp.pop(obj.id, None)
1309
+
1310
+ def delObjects(self, objs):
1311
+ """
1312
+ 从会话中移除一组对象,可直接删除 Alias, Trigger, GMCPTrigger, Command, Timer 或它们的子类的元组、列表或者字典(保持兼容性)
1313
+
1314
+ :param objs: 要删除的对象本身,可以为 Alias, Trigger, GMCPTrigger, Command, Timer 或它们的子类
1315
+
1316
+ 示例:
1317
+
1318
+ .. code:: Python
1319
+
1320
+ class Configuration:
1321
+ def __init__(self, session):
1322
+ self.session = session
1323
+
1324
+ self.objs = [
1325
+ SimpleAlias(session, r'^gta$', 'get all;xixi'),
1326
+ SimpleTrigger(session, r'^[> ]*你嘻嘻地笑了起来.+', 'haha'),
1327
+ SimpleTimer(session, 'xixi', timeout = 10)
1328
+ ]
1329
+
1330
+ self.session.addObjects(self.objs)
1331
+
1332
+ def __unload__(self):
1333
+ "卸载本模块时,删除所有本模块添加的对象"
1334
+ self.session.delObjects(self.objs)
1335
+
1336
+ """
1337
+ if isinstance(objs, list) or isinstance(objs, tuple):
1338
+ for item in objs:
1339
+ self.delObject(item)
1340
+
1341
+ elif isinstance(objs, dict):
1342
+ for key, item in objs.items():
1343
+ self.delObject(item)
1344
+
1345
+ def addAliases(self, alis):
1188
1346
  """
1189
1347
  向会话中增加多个别名
1190
1348
 
@@ -1205,55 +1363,55 @@ class Session:
1205
1363
  self._aliases['my_ali2'] = SimpleAlias(self.session, "s", "south", id = "my_ali2")
1206
1364
  self.session.addAliases(self._aliases)
1207
1365
  """
1208
- self._addObjects(alis, Alias)
1366
+ self._addObjects(alis)
1209
1367
 
1210
- def addCommands(self, cmds: dict):
1368
+ def addCommands(self, cmds):
1211
1369
  """
1212
1370
  向会话中增加多个命令。使用方法与 addAliases 类似。
1213
1371
 
1214
1372
  :param cmds: 多个命令的字典。字典 key 应为每个命令的 id。
1215
1373
  """
1216
- self._addObjects(cmds, Command)
1374
+ self._addObjects(cmds)
1217
1375
 
1218
- def addTriggers(self, tris: dict):
1376
+ def addTriggers(self, tris):
1219
1377
  """
1220
1378
  向会话中增加多个触发器。使用方法与 addAliases 类似。
1221
1379
 
1222
1380
  :param tris: 多个触发器的字典。字典 key 应为每个触发器的 id。
1223
1381
  """
1224
- self._addObjects(tris, Trigger)
1382
+ self._addObjects(tris)
1225
1383
 
1226
- def addGMCPs(self, gmcps: dict):
1384
+ def addGMCPs(self, gmcps):
1227
1385
  """
1228
1386
  向会话中增加多个GMCPTrigger。使用方法与 addAliases 类似。
1229
1387
 
1230
1388
  :param gmcps: 多个GMCPTrigger的字典。字典 key 应为每个GMCPTrigger的 id。
1231
1389
  """
1232
- self._addObjects(gmcps, GMCPTrigger)
1390
+ self._addObjects(gmcps)
1233
1391
 
1234
- def addTimers(self, tis: dict):
1392
+ def addTimers(self, tis):
1235
1393
  """
1236
1394
  向会话中增加多个定时器。使用方法与 addAliases 类似。
1237
1395
 
1238
1396
  :param tis: 多个定时器的字典。字典 key 应为每个定时器的 id。
1239
1397
  """
1240
- self._addObjects(tis, Timer)
1398
+ self._addObjects(tis)
1241
1399
 
1242
- def addAlias(self, ali: Alias):
1400
+ def addAlias(self, ali):
1243
1401
  """
1244
1402
  向会话中增加一个别名。
1245
1403
 
1246
1404
  :param ali: 要增加的别名对象,应为 Alias 类型或其子类
1247
1405
  """
1248
- self._addObject(ali, Alias)
1406
+ self._addObject(ali)
1249
1407
 
1250
- def addCommand(self, cmd: Command):
1408
+ def addCommand(self, cmd):
1251
1409
  """
1252
1410
  向会话中增加一个命令。
1253
1411
 
1254
1412
  :param cmd: 要增加的命令对象,应为 Command 类型或其子类
1255
1413
  """
1256
- self._addObject(cmd, Command)
1414
+ self._addObject(cmd)
1257
1415
 
1258
1416
  def addTrigger(self, tri: Trigger):
1259
1417
  """
@@ -1261,7 +1419,7 @@ class Session:
1261
1419
 
1262
1420
  :param tri: 要增加的触发器对象,应为 Trigger 类型或其子类
1263
1421
  """
1264
- self._addObject(tri, Trigger)
1422
+ self._addObject(tri)
1265
1423
 
1266
1424
  def addTimer(self, ti: Timer):
1267
1425
  """
@@ -1269,7 +1427,7 @@ class Session:
1269
1427
 
1270
1428
  :param ti: 要增加的定时器对象,应为 Timer 类型或其子类
1271
1429
  """
1272
- self._addObject(ti, Timer)
1430
+ self._addObject(ti)
1273
1431
 
1274
1432
  def addGMCP(self, gmcp: GMCPTrigger):
1275
1433
  """
@@ -1278,7 +1436,7 @@ class Session:
1278
1436
  :param gmcp: 要增加的GMCP触发器对象,应为 GMCPTrigger 类型或其子类
1279
1437
  """
1280
1438
 
1281
- self._addObject(gmcp, GMCPTrigger)
1439
+ self._addObject(gmcp)
1282
1440
 
1283
1441
  def delAlias(self, ali):
1284
1442
  """
@@ -1397,7 +1555,7 @@ class Session:
1397
1555
  for ti in ti_s:
1398
1556
  self.delTimer(ti)
1399
1557
 
1400
- def delGMCP(self, gmcp: GMCPTrigger):
1558
+ def delGMCP(self, gmcp):
1401
1559
  """
1402
1560
  从会话中移除一个GMCP触发器,可接受 GMCPTrigger 对象或其的id。使用方法与 delAlias 类似
1403
1561
 
@@ -1713,6 +1871,7 @@ class Session:
1713
1871
  该函数不应该在代码中直接调用。
1714
1872
 
1715
1873
  相关命令:
1874
+ - #disconnect
1716
1875
  - #close
1717
1876
  - #exit
1718
1877
  '''
@@ -1734,6 +1893,18 @@ class Session:
1734
1893
 
1735
1894
  self.info("已经与服务器连接了 {}".format(time_msg))
1736
1895
 
1896
+ def handle_disconnect(self, code: CodeLine = None, *args, **kwargs):
1897
+ '''
1898
+ 嵌入命令 #disconnect / #dis 的执行函数,断开到远程服务器的连接(仅当远程服务器已连接时有效)。
1899
+ 该函数不应该在代码中直接调用。
1900
+
1901
+ 相关命令:
1902
+ - #connect
1903
+ - #close
1904
+ '''
1905
+
1906
+ self.disconnect()
1907
+
1737
1908
  def handle_variable(self, code: CodeLine = None, *args, **kwargs):
1738
1909
  '''
1739
1910
  嵌入命令 #variable / #var 的执行函数,操作会话变量。
@@ -1967,7 +2138,7 @@ class Session:
1967
2138
  self.info("创建Timer {} 成功: {}".format(ti.id, ti.__repr__()))
1968
2139
 
1969
2140
  def handle_alias(self, code: CodeLine = None, *args, **kwargs):
1970
- '''
2141
+ """
1971
2142
  嵌入命令 #alias / #ali 的执行函数,操作别名。该命令可以不带参数、带一个参数或者两个参数。
1972
2143
  该函数不应该在代码中直接调用。
1973
2144
 
@@ -1998,7 +2169,7 @@ class Session:
1998
2169
  - #trigger
1999
2170
  - #timer
2000
2171
  - #command
2001
- '''
2172
+ """
2002
2173
 
2003
2174
  self._handle_objs("Alias", self._aliases, *code.code[2:])
2004
2175
 
@@ -2393,10 +2564,11 @@ class Session:
2393
2564
  mod = self._modules[module_name]["module"]
2394
2565
  config = self._modules[module_name]["config"]
2395
2566
  if config:
2396
- if hasattr(config, "unload"):
2397
- unload = getattr(config, "unload", None)
2567
+ if hasattr(config, "__unload__") or hasattr(config, "unload"):
2568
+ unload = getattr(config, "__unload__", None) or getattr(config, "unload", None)
2398
2569
  if callable(unload):
2399
- unload(config)
2570
+ unload()
2571
+
2400
2572
  del config
2401
2573
  mod = importlib.reload(mod)
2402
2574
  if hasattr(mod, 'Configuration'):
@@ -2436,10 +2608,10 @@ class Session:
2436
2608
  mod = self._modules[module_name]["module"]
2437
2609
  config = self._modules[module_name]["config"]
2438
2610
  if config:
2439
- if hasattr(config, "unload"):
2440
- unload = getattr(config, "unload", None)
2611
+ if hasattr(config, "__unload__") or hasattr(config, "unload"):
2612
+ unload = getattr(config, "__unload__", None) or getattr(config, "unload", None)
2441
2613
  if callable(unload):
2442
- unload(config)
2614
+ unload()
2443
2615
 
2444
2616
  del config
2445
2617
  del mod
pymud/settings.py CHANGED
@@ -11,7 +11,7 @@ class Settings:
11
11
  "APP 名称, 默认PYMUD"
12
12
  __appdesc__ = "a MUD client written in Python"
13
13
  "APP 简要描述"
14
- __version__ = "0.20.0a2"
14
+ __version__ = "0.20.0"
15
15
  "APP 当前版本"
16
16
  __release__ = "2024-08-19"
17
17
  "APP 当前版本发布日期"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: pymud
3
- Version: 0.20.0a2
3
+ Version: 0.20.0a3
4
4
  Summary: a MUD Client written in Python
5
5
  Author-email: "newstart@pkuxkx" <crapex@crapex.cc>
6
6
  Maintainer-email: "newstart@pkuxkx" <crapex@crapex.cc>
@@ -694,6 +694,7 @@ Classifier: Programming Language :: Python :: 3.8
694
694
  Classifier: Programming Language :: Python :: 3.9
695
695
  Classifier: Programming Language :: Python :: 3.10
696
696
  Classifier: Programming Language :: Python :: 3.11
697
+ Classifier: Programming Language :: Python :: 3.12
697
698
  Classifier: Programming Language :: Python :: 3 :: Only
698
699
  Requires-Python: >=3.7
699
700
  Description-Content-Type: text/markdown
@@ -982,3 +983,15 @@ Requires-Dist: prompt-toolkit
982
983
  + 问题修复: 关闭会话时未关闭相关记录器,导致后续会话无法启动
983
984
  + 问题修复: MacOS下 python -m pymud init 创建目录报错的问题。同时,将所有系统上的默认目录均使用 ~/pkuxkx (影响windows)
984
985
  + 功能新增: Session类新增waitfor函数,用于执行一段代码后立即等待某个触发器的情况,简化原三行代码写法
986
+
987
+ ### 0.20.0 (2024-08-XX)
988
+ + 功能调整: 将模块主入口函数从__main__.py中移动到main.py中,以使可以在当前目录下,可直接使用pymud,也可使用python -m pymud启动
989
+ + 问题修复: 修复部分正则表达式书写错误问题
990
+ + 功能调整: Session类的addTriggers等方法接受的dict中,会将对象本身id作为会话处理id。当该id与key不一致时,会同时显示警告。
991
+ + 功能新增: Session类新增addObject, addObjects, delObject, delObjects用于操作别名、定时器、触发器、GMCP触发器、命令等对象。
992
+ + 功能新增: 主模块卸载现在既可以定义在__unload__方法中,也可以定义在unload方法中
993
+ + 问题修复: 修复原unload方法不能正确卸载的问题
994
+ + 功能新增: 命令行参数增加指定启动目录的功能,参数为 -s, --startup_dir。即可以从任意目录通过指定脚本目录方式启动PyMUD了。例如, PS C:\> pymud -s d:\prog\pkuxkx 相当于 PS D:\prog\pkuxk> pymud
995
+ + 功能新增: 增加 #disconnect, #dis 命令,可以使当前会话从服务器断开。相当于操作菜单 会话->断开连接
996
+ + 功能新增: #session 命令增加快捷创建会话功能,假如已有快捷菜单 世界->pkuxkx->newstart , 则可以通过 #session pkuxkx.newstart 直接创建该会话,效果等同于点击该菜单
997
+ + 功能调整: 点击菜单创建会话时,若会话已存在,则将该会话切换为当前会话
@@ -0,0 +1,18 @@
1
+ pymud/__init__.py,sha256=hvX7Ga2xPG9J3ZpxBLrC6BvrzUo-Dj26HsRKf41Brhw,533
2
+ pymud/__main__.py,sha256=hFzZjadLlcOuoLM7D8wFiFVO8mqF7vMuo9y-9xfIhRc,64
3
+ pymud/dialogs.py,sha256=D0ZtCeoBchF5eYzXumkOi3p-maCQZu4v9-wJgxQ790o,6500
4
+ pymud/extras.py,sha256=QwWwLavVtuXfg0Qb0f_040va1_kej27P-ZB_19HB6Qk,42422
5
+ pymud/logger.py,sha256=elYfbpvmKYJfB-rnPYZWY5r8ROu9yja9t-dBi1faRGc,5358
6
+ pymud/main.py,sha256=wpL1t88qcnYDq1vyguj2NOMpD9yVgZeuAJSMWEbDeiI,6532
7
+ pymud/objects.py,sha256=0aUc-PZfVSdYPEAamY0eO6k3P9wJcw6PNxfSE8eZZeE,38072
8
+ pymud/pkuxkx.py,sha256=vWXHU6GF0HQ0eWb3LmxFVRP0cKnigffCX7Z-LJvwVtw,11496
9
+ pymud/protocol.py,sha256=QfDXjlg2OcJXmVoXf_3mAemnYotRXDUlEZNQjhkfXdA,49106
10
+ pymud/pymud.py,sha256=N9WxaHDqqsTWIBG8UJ38gdMC_pQ30wphcN2LtT66eA4,49584
11
+ pymud/session.py,sha256=Ea5pqFFMQ1NWct51g3LCWpyVzM83puFzLhdE7I4WEy4,129768
12
+ pymud/settings.py,sha256=CRNpHl4RjOuQYzAIWyUEvOo7q-f4lo01X1v_CriHWO4,7145
13
+ pymud-0.20.0a3.dist-info/LICENSE.txt,sha256=IwGE9guuL-ryRPEKi6wFPI_zOhg7zDZbTYuHbSt_SAk,35823
14
+ pymud-0.20.0a3.dist-info/METADATA,sha256=rXogwgamQhQ1geFAq3eH-Vyi2m521g2vevHm9XEf3Rg,70341
15
+ pymud-0.20.0a3.dist-info/WHEEL,sha256=nCVcAvsfA9TDtwGwhYaRrlPhTLV9m-Ga6mdyDtuwK18,91
16
+ pymud-0.20.0a3.dist-info/entry_points.txt,sha256=diPUOtTkhgC1hVny7Cdg4aRhaHSynMQoraE7ZhJxUcw,37
17
+ pymud-0.20.0a3.dist-info/top_level.txt,sha256=8Gp1eXjxixXjqhhti6tLCspV_8s9sNV3z5Em2_KRhD4,6
18
+ pymud-0.20.0a3.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (72.2.0)
2
+ Generator: setuptools (73.0.0)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5
 
@@ -1,17 +0,0 @@
1
- pymud/__init__.py,sha256=Ep6JrWv2wwlLV5nI7F6BOA7Ei6yVgnxvhIRwFGPr2Oc,501
2
- pymud/__main__.py,sha256=vE5mi5WFyiUPGLfq-1sMrEpHoD2Vxiy5XXenmoXFA1c,6230
3
- pymud/dialogs.py,sha256=D0ZtCeoBchF5eYzXumkOi3p-maCQZu4v9-wJgxQ790o,6500
4
- pymud/extras.py,sha256=QwWwLavVtuXfg0Qb0f_040va1_kej27P-ZB_19HB6Qk,42422
5
- pymud/logger.py,sha256=39I_rFBU5MEiOTJyU7GAy9cY_MpYHKiXNgBhpokQrTA,5358
6
- pymud/objects.py,sha256=0aUc-PZfVSdYPEAamY0eO6k3P9wJcw6PNxfSE8eZZeE,38072
7
- pymud/pkuxkx.py,sha256=vWXHU6GF0HQ0eWb3LmxFVRP0cKnigffCX7Z-LJvwVtw,11496
8
- pymud/protocol.py,sha256=QfDXjlg2OcJXmVoXf_3mAemnYotRXDUlEZNQjhkfXdA,49106
9
- pymud/pymud.py,sha256=yAd6nz_ltM3B0fDwMGvaa-tpMlZycZEGJ5E4rZb9Nx4,48235
10
- pymud/session.py,sha256=Q1ylk9-5tZGI4maMfDRqzq8Ca6vzG4SivzjxfrpUk84,122932
11
- pymud/settings.py,sha256=3FDAgW97SEQfWb9HR6n2U-rQYKxclQXnfaRuo2o0ly0,7147
12
- pymud-0.20.0a2.dist-info/LICENSE.txt,sha256=IwGE9guuL-ryRPEKi6wFPI_zOhg7zDZbTYuHbSt_SAk,35823
13
- pymud-0.20.0a2.dist-info/METADATA,sha256=eFQxv8YNREut-zvVzsCf7uAfM3DAxFOi_vvX4uQITCA,68829
14
- pymud-0.20.0a2.dist-info/WHEEL,sha256=HiCZjzuy6Dw0hdX5R3LCFPDmFS4BWl8H-8W39XfmgX4,91
15
- pymud-0.20.0a2.dist-info/entry_points.txt,sha256=diPUOtTkhgC1hVny7Cdg4aRhaHSynMQoraE7ZhJxUcw,37
16
- pymud-0.20.0a2.dist-info/top_level.txt,sha256=8Gp1eXjxixXjqhhti6tLCspV_8s9sNV3z5Em2_KRhD4,6
17
- pymud-0.20.0a2.dist-info/RECORD,,