pymud 0.19.3__py3-none-any.whl → 0.19.3.post2__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 +0 -1
- pymud/extras.py +59 -51
- pymud/objects.py +231 -44
- pymud/protocol.py +4 -4
- pymud/pymud.py +101 -28
- pymud/session.py +662 -92
- pymud/settings.py +1 -1
- {pymud-0.19.3.dist-info → pymud-0.19.3.post2.dist-info}/LICENSE.txt +674 -674
- {pymud-0.19.3.dist-info → pymud-0.19.3.post2.dist-info}/METADATA +10 -2
- pymud-0.19.3.post2.dist-info/RECORD +16 -0
- pymud-0.19.3.dist-info/RECORD +0 -16
- {pymud-0.19.3.dist-info → pymud-0.19.3.post2.dist-info}/WHEEL +0 -0
- {pymud-0.19.3.dist-info → pymud-0.19.3.post2.dist-info}/entry_points.txt +0 -0
- {pymud-0.19.3.dist-info → pymud-0.19.3.post2.dist-info}/top_level.txt +0 -0
pymud/pymud.py
CHANGED
@@ -54,7 +54,7 @@ class PyMudApp:
|
|
54
54
|
|
55
55
|
PyMudApp对象不需要手动创建,在命令行中执行 ``python -m pymud`` 时会自动创建对象实例。
|
56
56
|
|
57
|
-
|
57
|
+
参数:
|
58
58
|
- ``cfg_data``: 替代配置数据,由本地pymud.cfg文件读取,用于覆盖settings.py中的默认Settings数据
|
59
59
|
|
60
60
|
可替代字典: 含义请查阅 `应用配置及本地化 <settings.html>`_
|
@@ -143,6 +143,7 @@ class PyMudApp:
|
|
143
143
|
self.load_plugins()
|
144
144
|
|
145
145
|
def initUI(self):
|
146
|
+
"""初始化UI界面"""
|
146
147
|
self.style = Style.from_dict(Settings.styles)
|
147
148
|
self.status_message = ""
|
148
149
|
self.showHistory = False
|
@@ -323,7 +324,7 @@ class PyMudApp:
|
|
323
324
|
)
|
324
325
|
|
325
326
|
def create_world_menus(self):
|
326
|
-
"
|
327
|
+
"创建世界子菜单,其中根据本地pymud.cfg中的有关配置创建会话有关子菜单"
|
327
328
|
menus = []
|
328
329
|
menus.append(MenuItem(Settings.text["new_session"], handler = self.act_new))
|
329
330
|
menus.append(MenuItem("-", disabled=True))
|
@@ -378,26 +379,30 @@ class PyMudApp:
|
|
378
379
|
b.cursor_down(lines)
|
379
380
|
|
380
381
|
def page_up(self, event: KeyPressEvent) -> None:
|
382
|
+
"快捷键PageUp: 用于向上翻页。翻页页数为显示窗口行数的一半减去一行。"
|
381
383
|
#lines = (self.app.output.get_size().rows - 5) // 2 - 1
|
382
384
|
lines = self.get_height() // 2 - 1
|
383
385
|
self.scroll(-1 * lines)
|
384
386
|
|
385
387
|
def page_down(self, event: KeyPressEvent) -> None:
|
388
|
+
"快捷键PageDown: 用于向下翻页。翻页页数为显示窗口行数的一半减去一行。"
|
386
389
|
#lines = (self.app.output.get_size().rows - 5) // 2 - 1
|
387
390
|
lines = self.get_height() // 2 - 1
|
388
391
|
self.scroll(lines)
|
389
392
|
|
390
393
|
def custom_key_press(self, event: KeyPressEvent):
|
394
|
+
"自定义快捷键功能实现,根据keys字典配置在当前会话执行指定指令"
|
391
395
|
if (len(event.key_sequence) == 1) and (event.key_sequence[-1].key in Settings.keys.keys()):
|
392
396
|
cmd = Settings.keys[event.key_sequence[-1].key]
|
393
397
|
if self.current_session:
|
394
398
|
self.current_session.exec_command(cmd)
|
395
399
|
|
396
400
|
def hide_history(self, event: KeyPressEvent) -> None:
|
397
|
-
"""关闭历史行显示"""
|
401
|
+
"""快捷键Ctrl+Z: 关闭历史行显示"""
|
398
402
|
self.act_nosplit()
|
399
403
|
|
400
404
|
def copy_selection(self, event: KeyPressEvent)-> None:
|
405
|
+
"""快捷键Ctrl+C/Ctrl+R: 复制选择内容。根据按键不同选择文本复制方式和RAW复制方式"""
|
401
406
|
if event.key_sequence[-1].key == Keys.ControlC:
|
402
407
|
self.copy()
|
403
408
|
elif event.key_sequence[-1].key == Keys.ControlR:
|
@@ -412,7 +417,7 @@ class PyMudApp:
|
|
412
417
|
b.delete_before_cursor(1)
|
413
418
|
|
414
419
|
def complete_autosuggest(self, event: KeyPressEvent):
|
415
|
-
"""自动完成建议"""
|
420
|
+
"""快捷键右箭头→: 自动完成建议"""
|
416
421
|
b = event.current_buffer
|
417
422
|
if b.cursor_position == len(b.text):
|
418
423
|
s = b.auto_suggest.get_suggestion(b, b.document)
|
@@ -422,6 +427,7 @@ class PyMudApp:
|
|
422
427
|
b.cursor_right()
|
423
428
|
|
424
429
|
def change_session(self, event: KeyPressEvent):
|
430
|
+
"""快捷键Ctrl+左右箭头: 切换会话"""
|
425
431
|
if self.current_session:
|
426
432
|
current = self.current_session.name
|
427
433
|
keys = list(self.sessions.keys())
|
@@ -439,6 +445,7 @@ class PyMudApp:
|
|
439
445
|
self.activate_session(new_key)
|
440
446
|
|
441
447
|
def toggle_mousesupport(self, event: KeyPressEvent):
|
448
|
+
"""快捷键F2: 切换鼠标支持状态。用于远程连接时本地复制命令执行操作"""
|
442
449
|
self._mouse_support = not self._mouse_support
|
443
450
|
if self._mouse_support:
|
444
451
|
self.app.renderer.output.enable_mouse_support()
|
@@ -446,6 +453,13 @@ class PyMudApp:
|
|
446
453
|
self.app.renderer.output.disable_mouse_support()
|
447
454
|
|
448
455
|
def copy(self, raw = False):
|
456
|
+
"""
|
457
|
+
复制会话中的选中内容
|
458
|
+
|
459
|
+
:param raw: 指定采取文本模式还是ANSI格式模式
|
460
|
+
|
461
|
+
``注意: 复制的内容仅存在于运行环境的剪贴板中。若使用ssh远程,该复制命令不能访问本地剪贴板。``
|
462
|
+
"""
|
449
463
|
b = self.consoleView.buffer
|
450
464
|
if b.selection_state:
|
451
465
|
srow, scol = b.document.translate_index_to_position(b.selection_state.original_cursor_position)
|
@@ -504,6 +518,17 @@ class PyMudApp:
|
|
504
518
|
self.set_status("未选中任何内容...")
|
505
519
|
|
506
520
|
def create_session(self, name, host, port, encoding = None, after_connect = None, scripts = None, userid = None):
|
521
|
+
"""
|
522
|
+
创建一个会话。菜单或者#session命令均调用本函数执行创建会话。
|
523
|
+
|
524
|
+
:param name: 会话名称
|
525
|
+
:param host: 服务器域名或IP地址
|
526
|
+
:param port: 端口号
|
527
|
+
:param encoding: 服务器编码
|
528
|
+
:param after_connect: 连接后要向服务器发送的内容,用来实现自动登录功能
|
529
|
+
:param scripts: 要加载的脚本清单
|
530
|
+
:param userid: 自动登录的ID(获取自cfg文件中的定义,绑定到菜单),将以该值在该会话中创建一个名为id的变量
|
531
|
+
"""
|
507
532
|
result = False
|
508
533
|
encoding = encoding or Settings.server["default_encoding"]
|
509
534
|
|
@@ -534,7 +559,7 @@ class PyMudApp:
|
|
534
559
|
self.app.invalidate()
|
535
560
|
|
536
561
|
def close_session(self):
|
537
|
-
"
|
562
|
+
"关闭当前会话。若当前会话处于连接状态,将弹出对话框以确认。"
|
538
563
|
async def coroutine():
|
539
564
|
if self.current_session:
|
540
565
|
if self.current_session.connected:
|
@@ -570,6 +595,7 @@ class PyMudApp:
|
|
570
595
|
# 菜单选项操作 - 开始
|
571
596
|
|
572
597
|
def act_new(self):
|
598
|
+
"菜单: 创建新会话"
|
573
599
|
async def coroutine():
|
574
600
|
dlgNew = NewSessionDialog()
|
575
601
|
result = await self.show_dialog_as_float(dlgNew)
|
@@ -580,14 +606,17 @@ class PyMudApp:
|
|
580
606
|
asyncio.ensure_future(coroutine())
|
581
607
|
|
582
608
|
def act_connect(self):
|
609
|
+
"菜单: 连接/重新连接"
|
583
610
|
if self.current_session:
|
584
611
|
self.current_session.handle_connect()
|
585
612
|
|
586
613
|
def act_discon(self):
|
614
|
+
"菜单: 断开连接"
|
587
615
|
if self.current_session:
|
588
616
|
self.current_session.disconnect()
|
589
617
|
|
590
618
|
def act_nosplit(self):
|
619
|
+
"菜单: 取消分屏"
|
591
620
|
if self.current_session:
|
592
621
|
s = self.current_session
|
593
622
|
b = s.buffer
|
@@ -595,39 +624,42 @@ class PyMudApp:
|
|
595
624
|
b.cursor_position = len(b.text)
|
596
625
|
|
597
626
|
def act_close_session(self):
|
627
|
+
"菜单: 关闭当前会话"
|
598
628
|
self.close_session()
|
599
629
|
|
600
630
|
def act_echoinput(self):
|
631
|
+
"菜单: 显示/隐藏输入指令"
|
601
632
|
val = not Settings.client["echo_input"]
|
602
633
|
Settings.client["echo_input"] = val
|
603
634
|
if self.current_session:
|
604
635
|
self.current_session.info(f"回显输入命令被设置为:{'打开' if val else '关闭'}")
|
605
636
|
|
606
637
|
def act_autoreconnect(self):
|
638
|
+
"菜单: 打开/关闭自动重连"
|
607
639
|
val = not Settings.client["auto_reconnect"]
|
608
640
|
Settings.client["auto_reconnect"] = val
|
609
641
|
if self.current_session:
|
610
642
|
self.current_session.info(f"自动重连被设置为:{'打开' if val else '关闭'}")
|
611
643
|
|
612
644
|
def act_copy(self):
|
613
|
-
"
|
645
|
+
"菜单: 复制纯文本"
|
614
646
|
self.copy()
|
615
647
|
|
616
648
|
def act_copyraw(self):
|
617
|
-
"复制ANSI
|
649
|
+
"菜单: 复制(ANSI)"
|
618
650
|
self.copy(raw = True)
|
619
651
|
|
620
652
|
def act_clearsession(self):
|
621
|
-
"
|
653
|
+
"菜单: 清空会话内容"
|
622
654
|
self.consoleView.buffer.text = ""
|
623
655
|
|
624
656
|
def act_reload(self):
|
625
|
-
"
|
657
|
+
"菜单: 重新加载脚本配置"
|
626
658
|
if self.current_session:
|
627
659
|
self.current_session.handle_reload()
|
628
660
|
|
661
|
+
# 暂未实现该功能
|
629
662
|
def act_change_layout(self, layout):
|
630
|
-
"更改状态窗口显示"
|
631
663
|
#if isinstance(layout, STATUS_DISPLAY):
|
632
664
|
self.status_display = layout
|
633
665
|
#self.console_frame.body.reset()
|
@@ -642,45 +674,54 @@ class PyMudApp:
|
|
642
674
|
self.app.invalidate()
|
643
675
|
|
644
676
|
def act_exit(self):
|
645
|
-
"
|
677
|
+
"""菜单: 退出"""
|
646
678
|
async def coroutine():
|
679
|
+
con_sessions = list()
|
647
680
|
for session in self.sessions.values():
|
648
681
|
if session.connected:
|
649
|
-
|
650
|
-
|
651
|
-
|
652
|
-
|
682
|
+
con_sessions.append(session.name)
|
683
|
+
|
684
|
+
if len(con_sessions) > 0:
|
685
|
+
dlgQuery = QueryDialog(HTML('<b fg="red">程序退出警告</b>'), HTML('<style fg="red">尚有 {0} 个会话 {1} 还处于连接状态,确认要关闭?</style>'.format(len(con_sessions), ", ".join(con_sessions))))
|
686
|
+
result = await self.show_dialog_as_float(dlgQuery)
|
687
|
+
if result:
|
688
|
+
for ss_name in con_sessions:
|
689
|
+
ss = self.sessions[ss_name]
|
690
|
+
ss.disconnect()
|
653
691
|
|
654
692
|
# 增加延时等待确保会话关闭
|
655
|
-
while
|
693
|
+
while ss.connected:
|
656
694
|
await asyncio.sleep(0.1)
|
657
695
|
|
658
696
|
for plugin in self._plugins.values():
|
659
697
|
if isinstance(plugin, Plugin):
|
660
|
-
plugin.onSessionDestroy(
|
698
|
+
plugin.onSessionDestroy(ss)
|
661
699
|
|
662
|
-
|
663
|
-
|
700
|
+
else:
|
701
|
+
return
|
664
702
|
|
665
703
|
self.app.exit()
|
666
704
|
|
667
705
|
asyncio.ensure_future(coroutine())
|
668
706
|
|
669
707
|
def act_about(self):
|
670
|
-
"
|
708
|
+
"菜单: 关于"
|
671
709
|
dialog_about = WelcomeDialog(True)
|
672
710
|
self.show_dialog(dialog_about)
|
673
711
|
|
674
712
|
# 菜单选项操作 - 完成
|
675
713
|
|
676
714
|
def get_input_prompt(self):
|
715
|
+
"命令输入行提示符"
|
677
716
|
return HTML(Settings.text["input_prompt"])
|
678
717
|
|
679
718
|
def btn_title_clicked(self, name, mouse_event: MouseEvent):
|
719
|
+
"顶部会话标签点击切换鼠标事件"
|
680
720
|
if mouse_event.event_type == MouseEventType.MOUSE_UP:
|
681
721
|
self.activate_session(name)
|
682
722
|
|
683
723
|
def get_frame_title(self):
|
724
|
+
"顶部会话标题选项卡"
|
684
725
|
if len(self.sessions.keys()) == 0:
|
685
726
|
return Settings.__appname__ + " " + Settings.__version__
|
686
727
|
|
@@ -704,12 +745,14 @@ class PyMudApp:
|
|
704
745
|
return title_formatted_list[:-1]
|
705
746
|
|
706
747
|
def get_statusbar_text(self):
|
748
|
+
"状态栏内容"
|
707
749
|
return [
|
708
750
|
("class:status", " "),
|
709
751
|
("class:status", self.status_message),
|
710
752
|
]
|
711
753
|
|
712
754
|
def get_statusbar_right_text(self):
|
755
|
+
"状态栏右侧内容"
|
713
756
|
con_str, mouse_support, tri_status = "", "", ""
|
714
757
|
if not self._mouse_support:
|
715
758
|
mouse_support = "鼠标已禁用 "
|
@@ -743,6 +786,7 @@ class PyMudApp:
|
|
743
786
|
return "{}{}{} {} {} ".format(mouse_support, tri_status, con_str, Settings.__appname__, Settings.__version__)
|
744
787
|
|
745
788
|
def get_statuswindow_text(self):
|
789
|
+
"状态窗口: status_maker 的内容"
|
746
790
|
text = ""
|
747
791
|
if self.current_session:
|
748
792
|
text = self.current_session.get_status()
|
@@ -750,6 +794,11 @@ class PyMudApp:
|
|
750
794
|
return text
|
751
795
|
|
752
796
|
def set_status(self, msg):
|
797
|
+
"""
|
798
|
+
在状态栏中上显示消息。可在代码中调用
|
799
|
+
|
800
|
+
:param msg: 要显示的消息
|
801
|
+
"""
|
753
802
|
self.status_message = msg
|
754
803
|
self.app.invalidate()
|
755
804
|
|
@@ -759,15 +808,15 @@ class PyMudApp:
|
|
759
808
|
该函数不应该在代码中直接调用。
|
760
809
|
|
761
810
|
使用:
|
762
|
-
- #session {
|
811
|
+
- #session {name} {host} {port} {encoding}
|
763
812
|
- 当不指定 Encoding: 时, 默认使用utf-8编码
|
764
813
|
- 可以直接使用 #{名称} 切换会话和操作会话命令
|
765
814
|
|
766
815
|
参数:
|
767
|
-
:
|
768
|
-
:
|
769
|
-
:
|
770
|
-
:
|
816
|
+
:name: 会话名称
|
817
|
+
:host: 服务器域名或IP地址
|
818
|
+
:port: 端口号
|
819
|
+
:encoding: 编码格式,不指定时默认为 utf8
|
771
820
|
|
772
821
|
示例:
|
773
822
|
``#session {名称} {宿主机} {端口} {编码}``
|
@@ -805,6 +854,7 @@ class PyMudApp:
|
|
805
854
|
self.set_status("错误的#session命令")
|
806
855
|
|
807
856
|
def enter_pressed(self, buffer: Buffer):
|
857
|
+
"命令行回车按键处理"
|
808
858
|
cmd_line = buffer.text
|
809
859
|
space_index = cmd_line.find(" ")
|
810
860
|
|
@@ -846,26 +896,46 @@ class PyMudApp:
|
|
846
896
|
|
847
897
|
@property
|
848
898
|
def globals(self):
|
899
|
+
"""
|
900
|
+
全局变量,快捷点访问器
|
901
|
+
用于替代get_globals与set_globals函数的调用
|
902
|
+
"""
|
849
903
|
return self._globals
|
850
904
|
|
851
905
|
def get_globals(self, name, default = None):
|
852
|
-
"
|
906
|
+
"""
|
907
|
+
获取PYMUD全局变量
|
908
|
+
|
909
|
+
:param name: 全局变量名称
|
910
|
+
:param default: 当全局变量不存在时的返回值
|
911
|
+
"""
|
853
912
|
if name in self._globals.keys():
|
854
913
|
return self._globals[name]
|
855
914
|
else:
|
856
915
|
return default
|
857
916
|
|
858
917
|
def set_globals(self, name, value):
|
859
|
-
"
|
918
|
+
"""
|
919
|
+
设置PYMUD全局变量
|
920
|
+
|
921
|
+
:param name: 全局变量名称
|
922
|
+
:param value: 全局变量值。值可以为任何类型。
|
923
|
+
"""
|
860
924
|
self._globals[name] = value
|
861
925
|
|
862
926
|
def del_globals(self, name):
|
863
|
-
"
|
927
|
+
"""
|
928
|
+
移除一个PYMUD全局变量
|
929
|
+
移除全局变量是从字典中删除该变量,而不是将其设置为None
|
930
|
+
|
931
|
+
:param name: 全局变量名称
|
932
|
+
"""
|
864
933
|
if name in self._globals.keys():
|
865
934
|
self._globals.pop(name)
|
866
935
|
|
867
936
|
@property
|
868
937
|
def plugins(self):
|
938
|
+
"所有已加载的插件列表,快捷点访问器"
|
869
939
|
return self._plugins
|
870
940
|
|
871
941
|
def show_message(self, title, text, modal = True):
|
@@ -898,9 +968,11 @@ class PyMudApp:
|
|
898
968
|
return result
|
899
969
|
|
900
970
|
async def run_async(self):
|
971
|
+
"以异步方式运行本程序"
|
901
972
|
await self.app.run_async()
|
902
973
|
|
903
974
|
def run(self):
|
975
|
+
"运行本程序"
|
904
976
|
self.app.run()
|
905
977
|
#asyncio.run(self.run_async())
|
906
978
|
|
@@ -923,6 +995,7 @@ class PyMudApp:
|
|
923
995
|
# plugins 处理
|
924
996
|
#####################################
|
925
997
|
def load_plugins(self):
|
998
|
+
"加载插件。将加载pymud包的plugins目录下插件,以及当前目录的plugins目录下插件"
|
926
999
|
# 首先加载系统目录下的插件
|
927
1000
|
current_dir = os.path.dirname(__file__)
|
928
1001
|
plugins_dir = os.path.join(current_dir, "plugins")
|