pymud 0.21.2a1__py3-none-any.whl → 0.21.2.post1__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/extras.py +132 -88
- pymud/pymud.py +25 -10
- pymud/session.py +0 -11
- {pymud-0.21.2a1.dist-info → pymud-0.21.2.post1.dist-info}/METADATA +8 -6
- {pymud-0.21.2a1.dist-info → pymud-0.21.2.post1.dist-info}/RECORD +9 -9
- {pymud-0.21.2a1.dist-info → pymud-0.21.2.post1.dist-info}/WHEEL +0 -0
- {pymud-0.21.2a1.dist-info → pymud-0.21.2.post1.dist-info}/entry_points.txt +0 -0
- {pymud-0.21.2a1.dist-info → pymud-0.21.2.post1.dist-info}/licenses/LICENSE.txt +0 -0
- {pymud-0.21.2a1.dist-info → pymud-0.21.2.post1.dist-info}/top_level.txt +0 -0
pymud/extras.py
CHANGED
@@ -1,9 +1,10 @@
|
|
1
1
|
# External Libraries
|
2
|
+
from functools import lru_cache
|
2
3
|
from unicodedata import east_asian_width
|
3
4
|
from wcwidth import wcwidth
|
4
5
|
from dataclasses import dataclass
|
5
|
-
import time, re, logging
|
6
|
-
|
6
|
+
import time, re, logging, linecache, os
|
7
|
+
from typing import Optional, List, Dict
|
7
8
|
from typing import Iterable, NamedTuple, Optional, Union, Tuple
|
8
9
|
from prompt_toolkit import ANSI
|
9
10
|
from prompt_toolkit.application import get_app
|
@@ -236,7 +237,7 @@ class VSplitWindow(Window):
|
|
236
237
|
below = total - upper - 1
|
237
238
|
|
238
239
|
#if isNotMargin:
|
239
|
-
if isinstance(self.content,
|
240
|
+
if isinstance(self.content, PyMudBufferControl):
|
240
241
|
b = self.content.buffer
|
241
242
|
if not b:
|
242
243
|
return y
|
@@ -276,33 +277,35 @@ class VSplitWindow(Window):
|
|
276
277
|
|
277
278
|
else:
|
278
279
|
# 有split window
|
279
|
-
|
280
|
-
lineno = start_lineno
|
281
|
-
while y < upper and lineno < line_count:
|
282
|
-
line = ui_content.get_line(lineno)
|
283
|
-
visible_line_to_row_col[y] = (lineno, horizontal_scroll)
|
284
|
-
x = 0
|
285
|
-
x, y = copy_line(line, lineno, x, y, is_input=True)
|
286
|
-
lineno += 1
|
287
|
-
y += 1
|
280
|
+
|
288
281
|
|
289
|
-
# x = 0
|
290
|
-
# x, y = copy_line([("","-"*width)], lineno, x, y, is_input=False)
|
291
|
-
# y += 1
|
292
282
|
|
293
|
-
#
|
283
|
+
# 先复制下半部分,倒序复制,确保即使有自动折行时,最后一行也保持在屏幕最底部
|
294
284
|
y = total
|
295
285
|
lineno = line_count
|
296
286
|
|
297
|
-
while y
|
287
|
+
while y > below and lineno >= 0:
|
298
288
|
lineno -= 1
|
299
289
|
# Take the next line and copy it in the real screen.
|
300
290
|
display_lines = ui_content.get_height_for_line(lineno, width, None)
|
301
291
|
y -= display_lines
|
292
|
+
if y <= below:
|
293
|
+
break
|
302
294
|
line = ui_content.get_line(lineno)
|
303
295
|
visible_line_to_row_col[y] = (lineno, horizontal_scroll)
|
304
296
|
copy_line(line, lineno, 0, y, is_input=True)
|
305
297
|
|
298
|
+
# 复制上半部分,正序复制,确保即使有自动折行时,第一行也保持在屏幕最顶部
|
299
|
+
y = -vertical_scroll_2
|
300
|
+
lineno = start_lineno
|
301
|
+
while y <= below and lineno < line_count:
|
302
|
+
line = ui_content.get_line(lineno)
|
303
|
+
visible_line_to_row_col[y] = (lineno, horizontal_scroll)
|
304
|
+
x = 0
|
305
|
+
x, y = copy_line(line, lineno, x, y, is_input=True)
|
306
|
+
lineno += 1
|
307
|
+
y += 1
|
308
|
+
|
306
309
|
# 最后复制分割线,若上下有由于折行额外占用的内容,都用分割线给覆盖掉
|
307
310
|
copy_line([("","-"*width)], -1, 0, upper + 1, is_input=False)
|
308
311
|
|
@@ -377,7 +380,7 @@ class VSplitWindow(Window):
|
|
377
380
|
if info is None:
|
378
381
|
return
|
379
382
|
|
380
|
-
if isinstance(self.content,
|
383
|
+
if isinstance(self.content, PyMudBufferControl):
|
381
384
|
b = self.content.buffer
|
382
385
|
if not b:
|
383
386
|
return
|
@@ -394,7 +397,7 @@ class VSplitWindow(Window):
|
|
394
397
|
if info is None:
|
395
398
|
return
|
396
399
|
|
397
|
-
if isinstance(self.content,
|
400
|
+
if isinstance(self.content, PyMudBufferControl):
|
398
401
|
b = self.content.buffer
|
399
402
|
if not b:
|
400
403
|
return
|
@@ -518,6 +521,7 @@ class EasternMenuContainer(MenuContainer):
|
|
518
521
|
|
519
522
|
return Window(FormattedTextControl(get_text_fragments), style="class:menu")
|
520
523
|
|
524
|
+
|
521
525
|
@dataclass
|
522
526
|
class SessionSelectionState:
|
523
527
|
start_row: int = -1
|
@@ -547,9 +551,53 @@ class SessionSelectionState:
|
|
547
551
|
return self.end_row - self.start_row + 1
|
548
552
|
else:
|
549
553
|
return 0
|
550
|
-
|
551
554
|
|
552
|
-
|
555
|
+
|
556
|
+
class BufferBase:
|
557
|
+
def __init__(self, name, newline = "\n", max_buffered_lines = 10000) -> None:
|
558
|
+
self.name = name
|
559
|
+
self.newline = newline
|
560
|
+
self.max_buffered_lines = max_buffered_lines
|
561
|
+
self.start_lineno = -1
|
562
|
+
self.selection = SessionSelectionState(-1, -1, -1, -1)
|
563
|
+
|
564
|
+
def clear(self):
|
565
|
+
pass
|
566
|
+
|
567
|
+
@property
|
568
|
+
def lineCount(self) -> int:
|
569
|
+
return 0
|
570
|
+
|
571
|
+
def getLine(self, lineno: int) -> str:
|
572
|
+
return ""
|
573
|
+
|
574
|
+
# 获取指定某行到某行的内容。当start未设置时,从首行开始。当end未设置时,到最后一行结束。
|
575
|
+
# 注意判断首位顺序逻辑,以及给定参数是否越界
|
576
|
+
def selection_range_at_line(self, lineno: int) -> Optional[Tuple[int, int]]:
|
577
|
+
if self.selection.is_valid():
|
578
|
+
if self.selection.rows > 1:
|
579
|
+
if lineno == self.selection.start_row:
|
580
|
+
return (self.selection.start_col, len(self.getLine(lineno)) - 1)
|
581
|
+
elif lineno == self.selection.end_row:
|
582
|
+
return (0, self.selection.end_col)
|
583
|
+
elif lineno > self.selection.start_row and lineno < self.selection.end_row:
|
584
|
+
return (0, len(self.getLine(lineno)) - 1)
|
585
|
+
|
586
|
+
elif self.selection.rows == 1:
|
587
|
+
if lineno == self.selection.start_row:
|
588
|
+
return (self.selection.start_col, self.selection.end_col)
|
589
|
+
|
590
|
+
return None
|
591
|
+
|
592
|
+
def exit_selection(self):
|
593
|
+
self.selection = SessionSelectionState(-1, -1, -1, -1)
|
594
|
+
|
595
|
+
def nosplit(self):
|
596
|
+
self.start_lineno = -1
|
597
|
+
get_app().invalidate()
|
598
|
+
|
599
|
+
|
600
|
+
class SessionBuffer(BufferBase):
|
553
601
|
def __init__(
|
554
602
|
self,
|
555
603
|
name,
|
@@ -557,13 +605,10 @@ class SessionBuffer:
|
|
557
605
|
max_buffered_lines = 10000,
|
558
606
|
) -> None:
|
559
607
|
|
560
|
-
|
561
|
-
|
562
|
-
self.
|
563
|
-
self.
|
564
|
-
self.max_buffered_lines = max_buffered_lines
|
565
|
-
self.selection = SessionSelectionState(-1, -1, -1, -1)
|
566
|
-
self.start_lineno = -1
|
608
|
+
super().__init__(name, newline, max_buffered_lines)
|
609
|
+
|
610
|
+
self._lines : List[str] = []
|
611
|
+
self._isnewline = True
|
567
612
|
|
568
613
|
def append(self, line: str):
|
569
614
|
"""
|
@@ -576,25 +621,25 @@ class SessionBuffer:
|
|
576
621
|
line = line.rstrip(self.newline)
|
577
622
|
newline_after_append = True
|
578
623
|
if not self.newline in line:
|
579
|
-
if self.
|
580
|
-
self.
|
624
|
+
if self._isnewline:
|
625
|
+
self._lines.append(line)
|
581
626
|
else:
|
582
|
-
self.
|
627
|
+
self._lines[-1] += line
|
583
628
|
|
584
629
|
else:
|
585
630
|
lines = line.split(self.newline)
|
586
|
-
if self.
|
587
|
-
self.
|
631
|
+
if self._isnewline:
|
632
|
+
self._lines.extend(lines)
|
588
633
|
else:
|
589
|
-
self.
|
590
|
-
self.
|
634
|
+
self._lines[-1] += lines[0]
|
635
|
+
self._lines.extend(lines[1:])
|
591
636
|
|
592
|
-
self.
|
637
|
+
self._isnewline = newline_after_append
|
593
638
|
|
594
639
|
## limit buffered lines
|
595
|
-
if len(self.
|
596
|
-
diff = self.
|
597
|
-
del self.
|
640
|
+
if len(self._lines) > self.max_buffered_lines:
|
641
|
+
diff = len(self._lines) - self.max_buffered_lines
|
642
|
+
del self._lines[:diff]
|
598
643
|
## adjust selection
|
599
644
|
if self.selection.start_row >= 0:
|
600
645
|
self.selection.start_row -= diff
|
@@ -603,68 +648,60 @@ class SessionBuffer:
|
|
603
648
|
get_app().invalidate()
|
604
649
|
|
605
650
|
def clear(self):
|
606
|
-
self.
|
651
|
+
self._lines.clear()
|
607
652
|
self.selection = SessionSelectionState(-1, -1, -1, -1)
|
608
653
|
|
609
654
|
get_app().invalidate()
|
610
655
|
|
611
|
-
def loadfile(self, filename, encoding = 'utf-8', errors = 'ignore'):
|
612
|
-
with open(filename, 'r', encoding = encoding, errors = errors) as fp:
|
613
|
-
lines = fp.readlines()
|
614
|
-
self.clear()
|
615
|
-
self.lines.extend(lines)
|
616
|
-
|
617
|
-
get_app().invalidate()
|
618
|
-
|
619
656
|
@property
|
620
657
|
def lineCount(self):
|
621
|
-
return len(self.
|
658
|
+
return len(self._lines)
|
622
659
|
|
623
|
-
def getLine(self, lineno):
|
624
|
-
if lineno < 0 or lineno >= len(self.
|
660
|
+
def getLine(self, lineno: int):
|
661
|
+
if lineno < 0 or lineno >= len(self._lines):
|
625
662
|
return ""
|
626
|
-
return self.
|
663
|
+
return self._lines[lineno]
|
627
664
|
|
628
|
-
# 获取指定某行到某行的内容。当start未设置时,从首行开始。当end未设置时,到最后一行结束。
|
629
|
-
# 注意判断首位顺序逻辑,以及给定参数是否越界
|
630
|
-
def getLines(self, start = None, end = None):
|
631
|
-
if start is None:
|
632
|
-
start = 0
|
633
|
-
if end is None:
|
634
|
-
end = len(self.lines) - 1
|
635
|
-
if start < 0:
|
636
|
-
start = 0
|
637
|
-
if end >= len(self.lines):
|
638
|
-
end = len(self.lines) - 1
|
639
|
-
if start > end:
|
640
|
-
return []
|
641
|
-
return self.lines[start:end+1]
|
642
|
-
|
643
|
-
def selection_range_at_line(self, lineno):
|
644
|
-
if self.selection.is_valid():
|
645
|
-
if self.selection.rows > 1:
|
646
|
-
if lineno == self.selection.start_row:
|
647
|
-
return (self.selection.start_col, len(self.lines[lineno]) - 1)
|
648
|
-
elif lineno == self.selection.end_row:
|
649
|
-
return (0, self.selection.end_col)
|
650
|
-
elif lineno > self.selection.start_row and lineno < self.selection.end_row:
|
651
|
-
return (0, len(self.lines[lineno]) - 1)
|
652
665
|
|
653
|
-
|
654
|
-
|
655
|
-
|
666
|
+
class LogFileBuffer(BufferBase):
|
667
|
+
def __init__(
|
668
|
+
self,
|
669
|
+
name,
|
670
|
+
filepath: Optional[str] = None,
|
671
|
+
) -> None:
|
656
672
|
|
657
|
-
|
673
|
+
super().__init__(name)
|
674
|
+
self._lines : Dict[int, str] = {}
|
675
|
+
self.loadfile(filepath)
|
676
|
+
|
677
|
+
def loadfile(self, filepath: Optional[str] = None):
|
678
|
+
if filepath and os.path.exists(filepath):
|
679
|
+
self.filepath = filepath
|
680
|
+
else:
|
681
|
+
self.filepath = None
|
658
682
|
|
659
|
-
def
|
660
|
-
self.
|
683
|
+
def clear(self):
|
684
|
+
self.filepath = None
|
661
685
|
|
662
|
-
|
663
|
-
|
664
|
-
|
686
|
+
@property
|
687
|
+
def lineCount(self):
|
688
|
+
if not self.filepath or not os.path.exists(self.filepath):
|
689
|
+
return 0
|
690
|
+
|
691
|
+
with open(self.filepath, 'r', encoding = 'utf-8', errors = 'ignore') as fp:
|
692
|
+
return sum(1 for _ in fp)
|
693
|
+
|
694
|
+
def getLine(self, lineno: int):
|
695
|
+
if not self.filepath or not os.path.exists(self.filepath):
|
696
|
+
return ""
|
697
|
+
|
698
|
+
return linecache.getline(self.filepath, lineno).rstrip(self.newline)
|
699
|
+
|
700
|
+
def __del__(self):
|
701
|
+
self._lines.clear()
|
665
702
|
|
666
|
-
class
|
667
|
-
def __init__(self, buffer: Optional[
|
703
|
+
class PyMudBufferControl(UIControl):
|
704
|
+
def __init__(self, buffer: Optional[BufferBase]) -> None:
|
668
705
|
self.buffer = buffer
|
669
706
|
|
670
707
|
# 为MUD显示进行校正的处理,包括对齐校正,换行颜色校正等
|
@@ -744,10 +781,14 @@ class SessionBufferControl(UIControl):
|
|
744
781
|
def get_line(i: int) -> StyleAndTextTuples:
|
745
782
|
line = buffer.getLine(i)
|
746
783
|
# 颜色校正
|
784
|
+
SEARCH_LINES = 10
|
747
785
|
thislinecolors = len(self.AVAI_COLOR_REGX.findall(line))
|
748
786
|
if thislinecolors == 0:
|
749
787
|
lineno = i - 1
|
750
|
-
|
788
|
+
search = 0
|
789
|
+
while lineno >= 0 and search < SEARCH_LINES:
|
790
|
+
search += 1
|
791
|
+
|
751
792
|
lastline = buffer.getLine(lineno)
|
752
793
|
allcolors = self.ALL_COLOR_REGX.findall(lastline)
|
753
794
|
|
@@ -883,6 +924,9 @@ class SessionBufferControl(UIControl):
|
|
883
924
|
else:
|
884
925
|
# Don't handle scroll events here.
|
885
926
|
return NotImplemented
|
927
|
+
else:
|
928
|
+
# Don't handle scroll events here.
|
929
|
+
return NotImplemented
|
886
930
|
|
887
931
|
# Not focused, but focusing on click events.
|
888
932
|
else:
|
pymud/pymud.py
CHANGED
@@ -9,7 +9,7 @@ from prompt_toolkit.buffer import Buffer
|
|
9
9
|
from prompt_toolkit.application import Application
|
10
10
|
from prompt_toolkit.filters import Condition
|
11
11
|
from prompt_toolkit.key_binding import KeyBindings
|
12
|
-
from prompt_toolkit.layout import ConditionalContainer, Float, VSplit, HSplit, Window, WindowAlign, ScrollbarMargin, NumberedMargin
|
12
|
+
from prompt_toolkit.layout import ConditionalContainer, Float, VSplit, HSplit, Window, WindowAlign, ScrollbarMargin, NumberedMargin, to_dimension
|
13
13
|
from prompt_toolkit.layout.layout import Layout
|
14
14
|
from prompt_toolkit.layout.controls import FormattedTextControl
|
15
15
|
from prompt_toolkit.layout.dimension import D
|
@@ -37,7 +37,7 @@ from prompt_toolkit.auto_suggest import AutoSuggestFromHistory
|
|
37
37
|
from wcwidth import wcwidth, wcswidth
|
38
38
|
|
39
39
|
from .objects import CodeBlock
|
40
|
-
from .extras import SessionBuffer,
|
40
|
+
from .extras import BufferBase, LogFileBuffer, SessionBuffer, PyMudBufferControl, EasternMenuContainer, VSplitWindow, DotDict, MenuItem
|
41
41
|
from .modules import Plugin
|
42
42
|
from .session import Session
|
43
43
|
from .settings import Settings
|
@@ -164,7 +164,7 @@ class PyMudApp:
|
|
164
164
|
self.logFileShown = '' # 记录页显示的记录文件名
|
165
165
|
#self.logSessionBuffer = SessionBuffer()
|
166
166
|
#self.logSessionBuffer.name = "LOGBUFFER"
|
167
|
-
self.logSessionBuffer =
|
167
|
+
self.logSessionBuffer = LogFileBuffer("LOGBUFFER")
|
168
168
|
|
169
169
|
self.load_plugins()
|
170
170
|
|
@@ -218,7 +218,7 @@ class PyMudApp:
|
|
218
218
|
show_cursor=False
|
219
219
|
)
|
220
220
|
|
221
|
-
self.consoleView =
|
221
|
+
self.consoleView = PyMudBufferControl(
|
222
222
|
buffer = None,
|
223
223
|
)
|
224
224
|
|
@@ -398,11 +398,26 @@ class PyMudApp:
|
|
398
398
|
else:
|
399
399
|
b = None
|
400
400
|
|
401
|
-
if isinstance(b,
|
401
|
+
if isinstance(b, BufferBase):
|
402
402
|
if lines < 0:
|
403
|
-
b.
|
404
|
-
|
405
|
-
|
403
|
+
if b.start_lineno < 0:
|
404
|
+
self.console._scroll_up()
|
405
|
+
b.start_lineno = b.lineCount - self.get_height() * 3 // 2
|
406
|
+
else:
|
407
|
+
b.start_lineno += lines
|
408
|
+
if b.start_lineno < 0:
|
409
|
+
b.start_lineno = 0
|
410
|
+
|
411
|
+
else:
|
412
|
+
if b.start_lineno < 0:
|
413
|
+
return
|
414
|
+
|
415
|
+
b.start_lineno += lines
|
416
|
+
|
417
|
+
if b.start_lineno >= b.lineCount - self.get_height():
|
418
|
+
b.start_lineno = -1
|
419
|
+
|
420
|
+
|
406
421
|
|
407
422
|
def page_up(self, event: KeyPressEvent) -> None:
|
408
423
|
"快捷键PageUp: 用于向上翻页。翻页页数为显示窗口行数的一半减去一行。"
|
@@ -644,7 +659,7 @@ class PyMudApp:
|
|
644
659
|
if os.path.exists(filename):
|
645
660
|
lock = threading.RLock()
|
646
661
|
lock.acquire()
|
647
|
-
self.logSessionBuffer.loadfile(filename
|
662
|
+
self.logSessionBuffer.loadfile(filename)
|
648
663
|
lock.release()
|
649
664
|
|
650
665
|
#self.logSessionBuffer.cursor_position = len(self.logSessionBuffer.text)
|
@@ -736,7 +751,7 @@ class PyMudApp:
|
|
736
751
|
|
737
752
|
elif self.showLog:
|
738
753
|
b = self.logSessionBuffer
|
739
|
-
b.exit_selection()
|
754
|
+
#b.exit_selection()
|
740
755
|
#b.cursor_position = len(b.text)
|
741
756
|
#b.start_lineno = -1
|
742
757
|
b.nosplit()
|
pymud/session.py
CHANGED
@@ -571,16 +571,6 @@ class Session:
|
|
571
571
|
self._line_count += 1
|
572
572
|
self.log.log(self.newline_cli)
|
573
573
|
|
574
|
-
def clear_half(self):
|
575
|
-
"""
|
576
|
-
清除半数缓冲。 **脚本中无需调用。**
|
577
|
-
|
578
|
-
半数的数量由 Settings.client['buffer_lines'] 确定,默认为5000行。
|
579
|
-
"""
|
580
|
-
# if (Settings.client["buffer_lines"] > 0) and (self._line_count >= 2 * Settings.client["buffer_lines"]) and self.buffer.document.is_cursor_at_the_end:
|
581
|
-
# self._line_count = self.buffer.clear_half()
|
582
|
-
pass
|
583
|
-
|
584
574
|
def feed_data(self, data) -> None:
|
585
575
|
"""
|
586
576
|
由协议对象调用,将收到的远程数据加入会话缓冲。永远只会传递1个字节的数据,以bytes形式。 **脚本中无需调用。**
|
@@ -695,7 +685,6 @@ class Session:
|
|
695
685
|
|
696
686
|
# 将数据写入缓存添加到此处
|
697
687
|
if len(self.display_line) > 0:
|
698
|
-
self.clear_half()
|
699
688
|
self.writetobuffer(self.display_line)
|
700
689
|
|
701
690
|
def set_exception(self, exc: Exception):
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: pymud
|
3
|
-
Version: 0.21.
|
3
|
+
Version: 0.21.2.post1
|
4
4
|
Summary: a MUD Client written in Python
|
5
5
|
Author-email: "newstart@pkuxkx" <crapex@hotmail.com>
|
6
6
|
Maintainer-email: "newstart@pkuxkx" <crapex@hotmail.com>
|
@@ -44,11 +44,11 @@ Dynamic: license-file
|
|
44
44
|
|
45
45
|
### 北大侠客行Mud (www.pkuxkx.net),最好的中文Mud游戏!
|
46
46
|
### PyMUD是我为了更好的玩北大侠客行,特意自行开发的MUD客户端。PyMUD具有以下特点:
|
47
|
-
+ 原生Python开发,除prompt-toolkit
|
47
|
+
+ 原生Python开发,除prompt-toolkit及其依赖库 wcwidth, pygment, pyperclip 外,不需要其他第三方库支持
|
48
48
|
+ 原生Python的asyncio实现的通信协议处理,支持async/await语法在脚本中直接应用,脚本实现的同步异步两种模式由你自己选择
|
49
|
-
+ 基于控制台的全屏UI界面设计,支持鼠标操作(Android
|
49
|
+
+ 基于控制台的全屏UI界面设计,支持鼠标操作(Android上支持触摸屏操作),极低资源需求,在单核1GB内存的Linux VPS上也可流畅运行
|
50
50
|
+ 支持分屏显示,在数据快速滚动的时候,上半屏保持不动,以确保不错过信息
|
51
|
-
+ 解决了99
|
51
|
+
+ 解决了99%情况下,北大侠客行中文对不齐,也就是看不清字符画的问题
|
52
52
|
+ 真正的支持多session会话,支持命令或鼠标切换会话
|
53
53
|
+ 原生支持多种服务器端编码方式,不论是GBK、BIG5、还是UTF-8
|
54
54
|
+ 支持NWAS、MTTS协商,支持GMCP、MSDP、MSSP协议
|
@@ -66,10 +66,12 @@ Dynamic: license-file
|
|
66
66
|
|
67
67
|
## 版本更新信息
|
68
68
|
|
69
|
-
### 0.
|
69
|
+
### 0.21.2 (2025-06-01)
|
70
70
|
|
71
71
|
+ 问题修复: 修复了当自动重连启动时,即使会话关闭了,也会自动重连的问题。
|
72
|
-
+ 实现调整:
|
72
|
+
+ 实现调整: 重写了专用的会话缓冲、记录缓冲与PyMud缓冲显示控制器,在prompt_toolkit的原Buffer和BufferControl的基础仅提供了PYMUD所需的基础功能,以降低内存占用。
|
73
|
+
经测试,当前内存基本稳定,视会话数量和脚本情况差异,维持在几百兆左右(500M以下),且不会有大幅波动。重写后,低配置的VPS也可以稳定运行PyMUD。
|
74
|
+
+ post1: 问题修复: 修复了当缓存行数超过规定值时,由于代码错误导致清屏的问题。
|
73
75
|
|
74
76
|
### 0.21.0 (2025-05-20)
|
75
77
|
|
@@ -2,7 +2,7 @@ pymud/__init__.py,sha256=oeHz0NM7_DwChCY8f_vQ_fBq0e_HoTd0cahCFwaavWE,806
|
|
2
2
|
pymud/__main__.py,sha256=lIOBiJmi8X-EWXVIx_OoxSgUZ0FYKlZI8hXVnLUYTJQ,61
|
3
3
|
pymud/decorators.py,sha256=XaxcZqHw4s44lC2EAgB5kZmbNvJnHGmpZnoW75tUeNY,9844
|
4
4
|
pymud/dialogs.py,sha256=4kHycr47UgKQUHGX-KMZvERuWViPjT4hNrGhbe4j-NU,7056
|
5
|
-
pymud/extras.py,sha256=
|
5
|
+
pymud/extras.py,sha256=FQKZWn7ZR9J4H-FjXzbF5sxOTUNZ3b7tWxWhHhywplg,36657
|
6
6
|
pymud/i18n.py,sha256=qLgvrmYhVfkTHKpbBR-LfYMOrGgi0skHrelbsj7ItbE,3034
|
7
7
|
pymud/logger.py,sha256=WCsfXVkgl63qdq1RQEDJBnM7U0S6u8TeORFSMhcoydI,5840
|
8
8
|
pymud/main.py,sha256=zaSjNhpbX3FMulKg-UNFrdiIJO8sOmmrUQrkPOalB-4,10224
|
@@ -10,14 +10,14 @@ pymud/modules.py,sha256=DoCregng5iAj_Hq_yUvRPreRTv2Ehb6sV6_4jfdbsik,11912
|
|
10
10
|
pymud/objects.py,sha256=ZOxNjlPD_d4jk5DMBcXgYcvkt9d8xZih0IQtQlA3f1Y,38668
|
11
11
|
pymud/pkuxkx.py,sha256=qDVry-Vd6MNui0NKWZFT52IpmP1sKS5Dz74EDY4tVGQ,14740
|
12
12
|
pymud/protocol.py,sha256=KNKJYj9HFRoUy-jigNfhiQdDOM_kRSJE17QFpBarQTg,48335
|
13
|
-
pymud/pymud.py,sha256=
|
14
|
-
pymud/session.py,sha256=
|
13
|
+
pymud/pymud.py,sha256=40hn5XyMH9mtjimx_zG7N2M6fAGciee1izO08jsfFzQ,53486
|
14
|
+
pymud/session.py,sha256=8sl8hdmq2jwNxj3bAAp5zTv8eNGBW-GOxNpGCuHKbAg,154603
|
15
15
|
pymud/settings.py,sha256=S2sBEM7YtaDOVu3UpGfHBaU7zSB3Zhs7w-Z7PtdS0WQ,7697
|
16
16
|
pymud/lang/i18n_chs.py,sha256=2cyaHHLwpYEBBwuQXyRTxa1opX53fTv1f8_QDQeGlC0,16836
|
17
17
|
pymud/lang/i18n_eng.py,sha256=jcPz6Y5UuxJBQLY_e8UnEF3GYTlnAD44C14Oj7sK-QI,45935
|
18
|
-
pymud-0.21.
|
19
|
-
pymud-0.21.
|
20
|
-
pymud-0.21.
|
21
|
-
pymud-0.21.
|
22
|
-
pymud-0.21.
|
23
|
-
pymud-0.21.
|
18
|
+
pymud-0.21.2.post1.dist-info/licenses/LICENSE.txt,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
|
19
|
+
pymud-0.21.2.post1.dist-info/METADATA,sha256=dBJD-AP44lsOfy-glrThVBKIcAA_mTbWvJUkNX2PEmE,45258
|
20
|
+
pymud-0.21.2.post1.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
21
|
+
pymud-0.21.2.post1.dist-info/entry_points.txt,sha256=diPUOtTkhgC1hVny7Cdg4aRhaHSynMQoraE7ZhJxUcw,37
|
22
|
+
pymud-0.21.2.post1.dist-info/top_level.txt,sha256=8Gp1eXjxixXjqhhti6tLCspV_8s9sNV3z5Em2_KRhD4,6
|
23
|
+
pymud-0.21.2.post1.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|