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/objects.py CHANGED
@@ -11,7 +11,9 @@ from .settings import Settings
11
11
 
12
12
  class CodeLine:
13
13
  """
14
- PyMUD中可执行的代码块(单行)"""
14
+ PyMUD中可执行的代码块(单行),不应由脚本直接调用。
15
+ 若脚本需要生成自己的代码块,应使用 CodeBlock。
16
+ """
15
17
 
16
18
  @classmethod
17
19
  def create_line(cls, line: str):
@@ -150,7 +152,11 @@ class CodeLine:
150
152
 
151
153
  class CodeBlock:
152
154
  """
153
- PyMUD中可以执行的代码块(最终使用,单行或多行)
155
+ PyMUD中可以执行的代码块,可以进行命令、别名检测,以及完成变量替代。
156
+
157
+ 但一般情况下,不需要手动创建 CodeBlock 对象,而是在 SimpleTrigger, SimpleAlias 等类型中直接使用字符串进行创建。或者在命令行输入文本将自动创建。
158
+
159
+ :param code: 代码块的代码本身。可以单行、多行、以及多层代码块
154
160
  """
155
161
 
156
162
  @classmethod
@@ -221,9 +227,36 @@ class CodeBlock:
221
227
 
222
228
  @property
223
229
  def syncmode(self):
230
+ """
231
+ 只读属性: 同步模式。在创建代码块时,根据代码内容自动判定模式。
232
+
233
+ 该属性有四个可能值
234
+ - ``dontcare``: 同步异步均可,既不存在强制同步命令,也不存在强制异步命令
235
+ - ``sync``: 强制同步,仅存在强制同步模式命令及其他非同步异步命令
236
+ - ``async``: 强制异步,仅存在强制异步模式命令及其他非同步异步命令
237
+ - ``conflict``: 模式冲突,同时存在强制同步和强制异步命令
238
+
239
+ 强制同步模式命令包括:
240
+ - #gag
241
+ - #replace
242
+
243
+ 强制异步模式命令包括:
244
+ - #wait
245
+ """
246
+
224
247
  return self.__syncmode
225
248
 
226
249
  def execute(self, session, *args, **kwargs):
250
+ """
251
+ 执行该 CodeBlock。执行前判断 syncmode。
252
+ - 仅当 syncmode 为 sync 时,才使用同步方式执行。
253
+ - 当 syncmode 为其他值时,均使用异步方式执行
254
+ - 当 syncmode 为 conflict 时,同步命令失效,并打印警告
255
+
256
+ :param session: 命令执行的会话实例
257
+ :param args: 兼容与扩展所需,用于变量替代及其他用途
258
+ :param kwargs: 兼容与扩展所需,用于变量替代及其他用途
259
+ """
227
260
  sync = kwargs.get("sync", None)
228
261
  if sync == None:
229
262
  if self.syncmode in ("dontcare", "async"):
@@ -231,7 +264,7 @@ class CodeBlock:
231
264
  elif self.syncmode == "sync":
232
265
  sync = True
233
266
  elif self.syncmode == "conflict":
234
- session.warning("该命令中同时存在强制同步命令和强制异步命令,将使用异步执行,同步命令将实效。")
267
+ session.warning("该命令中同时存在强制同步命令和强制异步命令,将使用异步执行,同步命令将失效。")
235
268
  sync = False
236
269
 
237
270
  if sync:
@@ -242,6 +275,9 @@ class CodeBlock:
242
275
  session.create_task(self.async_execute(session, *args, **kwargs))
243
276
 
244
277
  async def async_execute(self, session, *args, **kwargs):
278
+ """
279
+ 以异步方式执行该 CodeBlock。参数与 execute 相同。
280
+ """
245
281
  for code in self.codes:
246
282
  if isinstance(code, CodeLine):
247
283
  await code.async_execute(session, *args, **kwargs)
@@ -252,9 +288,28 @@ class CodeBlock:
252
288
  session.clean_finished_tasks()
253
289
 
254
290
  class BaseObject:
255
- """MUD会话支持的对象基类"""
291
+ """
292
+ MUD会话支持的对象基类。
293
+
294
+ :param session: 所属会话对象
295
+ :param args: 兼容与扩展所需
296
+ :param kwargs: 兼容与扩展所需
297
+
298
+ kwargs支持的关键字:
299
+ :id: 唯一ID。不指定时,默认使用 __abbr__ + UniqueID 来生成
300
+ :group: 所属的组名。不指定时,默认使用空字符串
301
+ :enabled: 使能状态。不指定时,默认使用 True
302
+ :priority: 优先级,越小优先级越高。不指定时,默认使用 100
303
+ :timeout: 超时时间,单位为秒。不指定时,默认使用 10
304
+ :sync: 同步模式。不指定时,默认为 True
305
+ :oneShot: 仅执行一次标识。不指定时,默认为 False
306
+ :onSuccess: 成功时的同步回调函数。不指定时,默认使用 self.onSuccess
307
+ :onFailure: 失败时的同步回调函数。不指定时,默认使用 self.onFailure
308
+ :onTimeout: 超时时的同步回调函数。不指定时,默认使用 self.onTimeout
309
+ """
256
310
 
257
311
  State = namedtuple("State", ("result", "id", "line", "wildcards"))
312
+
258
313
  NOTSET = N = -1
259
314
  FAILURE = F = 0
260
315
  SUCCESS = S = 1
@@ -262,6 +317,8 @@ class BaseObject:
262
317
  ABORT = A = 3
263
318
 
264
319
  __abbr__ = "obj"
320
+ "内部缩写代码前缀"
321
+
265
322
  def __init__(self, session, *args, **kwargs):
266
323
  self.session = session
267
324
  self._enabled = True # give a default value
@@ -286,7 +343,7 @@ class BaseObject:
286
343
 
287
344
  @property
288
345
  def enabled(self):
289
- "使能或取消使能本对象"
346
+ "可读写属性,使能或取消使能本对象"
290
347
  return self._enabled
291
348
 
292
349
  @enabled.setter
@@ -305,16 +362,6 @@ class BaseObject:
305
362
  "超时后执行的默认回调函数"
306
363
  self.log.debug(f"{self} 缺省超时回调函数被执行.")
307
364
 
308
- def expandInnerVariables(self, input: str):
309
- "内部变量扩展。使用内部变量应直接使用python格式化方式: {0} 以此之类"
310
- # TODO: 后续设计
311
- pass
312
-
313
- def expandOutterVariables(self, input: str):
314
- "外部变量扩展。使用外部变量,应使用@varname格式,且前后有空格表示"
315
- # TODO: 后续设计
316
- pass
317
-
318
365
  def debug(self, msg):
319
366
  "在logging中记录debug信息"
320
367
  self.log.debug(msg)
@@ -348,8 +395,14 @@ class BaseObject:
348
395
 
349
396
  class GMCPTrigger(BaseObject):
350
397
  """
351
- 支持GMCP收到数据的处理,可以类似于Trigger的使用用法
352
- GMCP必定以指定name为触发,触发时,其值直接传递给对象本身
398
+ GMCP触发器 GMCPTrigger 类型,继承自 BaseObject。
399
+
400
+ GMCP触发器处于基于 GMCP 协议的数据,其使用方法类似于 Trigger 对象
401
+
402
+ 但 GMCPTrigger 必定以指定name为触发,触发时,其值直接传递给对象本身
403
+
404
+ :param session: 本对象所属的会话
405
+ :param name: 触发对应的 GMCP 的 name
353
406
  """
354
407
  def __init__(self, session, name, *args, **kwargs):
355
408
  self.event = asyncio.Event()
@@ -364,6 +417,9 @@ class GMCPTrigger(BaseObject):
364
417
  self.event.clear()
365
418
 
366
419
  async def triggered(self):
420
+ """
421
+ 异步触发的可等待函数。其使用方法和 Trigger.triggered() 类似,且参数与返回值均与之兼容。
422
+ """
367
423
  self.reset()
368
424
  await self.event.wait()
369
425
  state = BaseObject.State(True, self.id, self.line, self.value)
@@ -388,7 +444,21 @@ class GMCPTrigger(BaseObject):
388
444
  return f'<{self.__class__.__name__}> name = "{self.id}" value = "{self.value}" group = "{self.group}" enabled = {self.enabled} '
389
445
 
390
446
  class MatchObject(BaseObject):
391
- "支持匹配内容的对象,包括Alias, Trigger, Command, Module等等"
447
+ """
448
+ 支持匹配内容的对象,包括Alias, Trigger, Command 等对象以及其子类对象。继承自 BaseObject
449
+
450
+ :param session: 同 BaseObject , 本对象所属的会话
451
+ :param patterns: 用于匹配的模式。详见 patterns 属性
452
+ :param args: 兼容与扩展所需
453
+ :param kwargs: 兼容与扩展所需
454
+
455
+ MatchObject 新增了部分 kwargs 关键字,包括:
456
+ :ignoreCase: 忽略大小写,默认为 False
457
+ :isRegExp: 是否是正则表达式,默认为 True
458
+ :keepEval: 是否持续匹配,默认为 False
459
+ :raw: 是否匹配含有VT100 ANSI标记的原始数据,默认为 False
460
+ """
461
+
392
462
  __abbr__ = "mob"
393
463
  def __init__(self, session, patterns, *args, **kwargs):
394
464
  self.ignoreCase = kwargs.get("ignoreCase", False) # 忽略大小写,非默认
@@ -410,6 +480,14 @@ class MatchObject(BaseObject):
410
480
 
411
481
  @property
412
482
  def patterns(self):
483
+ """
484
+ 可读写属性, 本对象的匹配模式。该属性可以在运行时动态更改,改后即时生效。
485
+
486
+ - 构造函数中的 patterns 用于指定初始的匹配模式。
487
+ - 该属性支持字符串和其他可迭代对象(如元组、列表)两种形式。
488
+ - 当为字符串时,使用单行匹配模式
489
+ - 当为可迭代对象时,使用多行匹配模式。多行的行数由可迭代对象所确定。
490
+ """
413
491
  return self._patterns
414
492
 
415
493
  @patterns.setter
@@ -437,7 +515,7 @@ class MatchObject(BaseObject):
437
515
  self._mline = 0
438
516
 
439
517
  def reset(self):
440
- "复位事件,用于async执行"
518
+ "复位事件,用于async执行未等待结果时,对事件的复位"
441
519
  self.event.clear()
442
520
 
443
521
  def set(self):
@@ -445,6 +523,14 @@ class MatchObject(BaseObject):
445
523
  self.event.set()
446
524
 
447
525
  def match(self, line: str, docallback = True) -> BaseObject.State:
526
+ """
527
+ 匹配函数。由 Session 调用。
528
+
529
+ :param line: 匹配的数据行
530
+ :param docallback: 匹配成功后是否执行回调函数,默认为 True
531
+
532
+ :return: BaseObject.State 类型,一个包含 result, id, name, line, wildcards 的命名元组对象
533
+ """
448
534
  result = self.NOTSET
449
535
 
450
536
  if not self.multiline: # 非多行
@@ -513,7 +599,11 @@ class MatchObject(BaseObject):
513
599
  return state
514
600
 
515
601
  async def matched(self) -> BaseObject.State:
516
- "异步等待匹配,返回BaseObject.state"
602
+ """
603
+ 匹配函数的异步模式,等待匹配成功之后才返回。返回值 BaseObject.state
604
+
605
+ 异步匹配模式用于 Trigger 的异步模式以及 Command 的匹配中。
606
+ """
517
607
  # 等待,再复位
518
608
  try:
519
609
  self.reset()
@@ -528,11 +618,22 @@ class MatchObject(BaseObject):
528
618
  return f'<{self.__class__.__name__}> id = "{self.id}" group = "{self.group}" enabled = {self.enabled} patterns = "{self.patterns}"'
529
619
 
530
620
  class Alias(MatchObject):
531
- """别名,实现方式-MatchObject"""
621
+ """
622
+ 别名 Alias 类型,继承自 MatchObject。
623
+
624
+ 其内涵与 MatchObject 完全相同,仅对缩写进行了覆盖。
625
+ """
626
+
532
627
  __abbr__ = "ali"
533
628
 
534
629
  class SimpleAlias(Alias):
535
- "简单Alias,使用类似Zmud方法的处理方式"
630
+ """
631
+ 简单别名 SimpleAlias 类型,继承自 Alias, 包含了 Alias 的全部功能, 并使用 CodeBlock 对象创建了 onSuccess 的使用场景。
632
+
633
+ :param session: 本对象所属的会话, 同 MatchObject
634
+ :param patterns: 匹配模式,同 MatchObject
635
+ :param code: str, 当匹配成功时执行的代码, 使用 CodeBlock 进行实现
636
+ """
536
637
 
537
638
  def __init__(self, session, patterns, code, *args, **kwargs):
538
639
  self._code = code
@@ -540,6 +641,7 @@ class SimpleAlias(Alias):
540
641
  super().__init__(session, patterns, *args, **kwargs)
541
642
 
542
643
  def onSuccess(self, id, line, wildcards):
644
+ "覆盖了基类的默认 onSuccess方法,使用 CodeBlock 执行构造函数中传入的 code 参数"
543
645
  self._codeblock.execute(self.session, id = id, line = line, wildcards = wildcards)
544
646
 
545
647
  def __detailed__(self) -> str:
@@ -549,7 +651,12 @@ class SimpleAlias(Alias):
549
651
  return self.__detailed__()
550
652
 
551
653
  class Trigger(MatchObject):
552
- """触发器,实现方式-MatchObject"""
654
+ """
655
+ 触发器 Trigger 类型,继承自 MatchObject。
656
+
657
+ 其内涵与 MatchObject 完全相同,仅对缩写进行了覆盖,并增写了 triggered 异步方法。
658
+ """
659
+
553
660
  __abbr__ = "tri"
554
661
 
555
662
  def __init__(self, session, patterns, *args, **kwargs):
@@ -557,6 +664,11 @@ class Trigger(MatchObject):
557
664
  self._task = None
558
665
 
559
666
  async def triggered(self):
667
+ """
668
+ 异步触发的可等待函数。内部通过 MatchObject.matched 实现
669
+
670
+ 差异在于对创建的 matched 任务进行了管理。
671
+ """
560
672
  if isinstance(self._task, asyncio.Task) and (not self._task.done()):
561
673
  self._task.cancel()
562
674
 
@@ -564,7 +676,13 @@ class Trigger(MatchObject):
564
676
  return await self._task
565
677
 
566
678
  class SimpleTrigger(Trigger):
567
- "简单Trigger,使用类似Zmud方法的处理方式"
679
+ """
680
+ 简单别名 SimpleTrigger 类型,继承自 Trigger, 包含了 Trigger 的全部功能, 并使用 CodeBlock 对象创建了 onSuccess 的使用场景。
681
+
682
+ :param session: 本对象所属的会话, 同 MatchObject
683
+ :param patterns: 匹配模式,同 MatchObject
684
+ :param code: str, 当匹配成功时执行的代码, 使用 CodeBlock 进行实现
685
+ """
568
686
 
569
687
  def __init__(self, session, patterns, code, *args, **kwargs):
570
688
  self._code = code
@@ -572,6 +690,8 @@ class SimpleTrigger(Trigger):
572
690
  super().__init__(session, patterns, *args, **kwargs)
573
691
 
574
692
  def onSuccess(self, id, line, wildcards):
693
+ "覆盖了基类的默认 onSuccess方法,使用 CodeBlock 执行构造函数中传入的 code 参数"
694
+
575
695
  raw = self.session.getVariable("%raw")
576
696
  self._codeblock.execute(self.session, id = id, line = line, raw = raw, wildcards = wildcards)
577
697
 
@@ -582,19 +702,42 @@ class SimpleTrigger(Trigger):
582
702
  return self.__detailed__()
583
703
 
584
704
  class Command(MatchObject):
585
- """命令,实现方式-MatchObject"""
705
+ """
706
+ 命令 Command 类型,继承自 MatchObject。
707
+ 命令是 PYMUD 的最大特色,它是一组归纳了同步/异步执行、等待响应、处理的集成对象。
708
+ 要使用命令,不能直接使用 Command 类型,应总是继承并使用其子类,务必覆盖基类的 execute 方法。
709
+
710
+ 有关 Command 的使用帮助,请查看帮助页面
711
+
712
+ :param session: 本对象所属的会话
713
+ :param patterns: 匹配模式
714
+ """
586
715
  __abbr__ = "cmd"
587
716
  def __init__(self, session, patterns, *args, **kwargs):
588
717
  super().__init__(session, patterns, sync = False, *args, **kwargs)
589
718
  self._tasks = set()
590
719
 
591
720
  def create_task(self, coro, *args, name = None):
721
+ """
722
+ 创建并管理任务。由 Command 创建的任务,同时也被 Session 所管理。
723
+ 其内部是调用 asyncio.create_task 进行任务创建。
724
+
725
+ :param coro: 任务包含的协程或可等待对象
726
+ :param name: 任务名称, Python 3.10 才支持的参数
727
+ """
592
728
  task = self.session.create_task(coro, *args, name)
593
729
  task.add_done_callback(self._tasks.discard)
594
730
  self._tasks.add(task)
595
731
  return task
596
732
 
597
733
  def remove_task(self, task: asyncio.Task, msg = None):
734
+ """
735
+ 取消任务并从管理任务清单中移除。由 Command 取消和移除的任务,同时也被 Session 所取消和移除。
736
+
737
+ :param task: 要取消的任务
738
+ :param msg: 取消任务时提供的消息, Python 3.10 才支持的参数
739
+ """
740
+
598
741
  result = self.session.remove_task(task, msg)
599
742
  self._tasks.discard(task)
600
743
  # if task in self._tasks:
@@ -602,20 +745,44 @@ class Command(MatchObject):
602
745
  return result
603
746
 
604
747
  def reset(self):
748
+ """
749
+ 复位命令,并取消和清除所有本对象管理的任务。
750
+ """
751
+
605
752
  super().reset()
606
753
 
607
- for task in self._tasks:
754
+ for task in list(self._tasks):
608
755
  if isinstance(task, asyncio.Task) and (not task.done()):
609
- task.cancel()
756
+ self.remove_task(task)
610
757
 
611
758
  async def execute(self, cmd, *args, **kwargs):
759
+ """
760
+ 命令调用的入口函数。该函数由 Session 进行自动调用。
761
+ 通过 ``Session.exec`` 系列方法调用的命令,最终是执行该命令的 execute 方法。
762
+
763
+ 子类必须实现并覆盖该方法。
764
+ """
612
765
  self.reset()
613
766
  return
614
767
 
615
768
  class SimpleCommand(Command):
769
+ """
770
+ 对命令的基本应用进行了基础封装的一种可以直接使用的命令类型,继承自 Command。
771
+
772
+ SimpleCommand 并不能理解为 “简单” 命令,因为其使用并不简单。
773
+ 只有在熟练使用 Command 建立自己的命令子类之后,对于某些场景的应用才可以简化代码使用 SimpleCommand 类型。
774
+
775
+ :param session: 本对象所属的会话
776
+ :param patterns: 匹配模式
777
+ :param succ_tri: 代表成功的响应触发器清单,可以为单个触发器,或一组触发器,必须指定
778
+
779
+ kwargs关键字参数特殊支持:
780
+ :fail_tri: 代表失败的响应触发器清单,可以为单个触发器,或一组触发器,可以为 None
781
+ :retry_tri: 代表重试的响应触发器清单,可以为单个触发器,或一组触发器,可以为 None
782
+ """
783
+
616
784
  MAX_RETRY = 20
617
785
 
618
- """简单命令"""
619
786
  def __init__(self, session, patterns, succ_tri, *args, **kwargs):
620
787
  super().__init__(session, patterns, succ_tri, *args, **kwargs)
621
788
  self._succ_tris = list()
@@ -646,6 +813,16 @@ class SimpleCommand(Command):
646
813
  self._retry_tris.append(retry_tri)
647
814
 
648
815
  async def execute(self, cmd, *args, **kwargs):
816
+ """
817
+ 覆盖基类的 execute 方法, SimpleCommand 的默认实现。
818
+
819
+ :param cmd: 执行时输入的实际指令
820
+
821
+ kwargs接受指定以下参数,在执行中进行一次调用:
822
+ :onSuccess: 成功时的回调
823
+ :onFailure: 失败时的回调
824
+ :onTimeout: 超时时的回调
825
+ """
649
826
  self.reset()
650
827
  # 0. check command
651
828
  cmd = cmd or self.patterns
@@ -665,14 +842,12 @@ class SimpleCommand(Command):
665
842
  for tr in self._retry_tris:
666
843
  tr.reset()
667
844
  tasklist.append(self.session.create_task(tr.triggered()))
668
-
845
+
846
+ await asyncio.sleep(0.1)
669
847
  self.session.writeline(cmd)
670
-
848
+
671
849
  done, pending = await asyncio.wait(tasklist, timeout = self.timeout, return_when = "FIRST_COMPLETED")
672
850
 
673
- # 任务完成后增加0.1s等待(不应该等待)
674
- # await asyncio.sleep(0.1)
675
-
676
851
  tasks_done = list(done)
677
852
 
678
853
  tasks_pending = list(pending)
@@ -725,7 +900,18 @@ class SimpleCommand(Command):
725
900
  return result
726
901
 
727
902
  class Timer(BaseObject):
728
- "PYMUD定时器"
903
+ """
904
+ 定时器 Timer 类型,继承自 MatchObject。PYMUD 支持同时任意多个定时器。
905
+
906
+ :param session: 对象所属会话
907
+
908
+ Timer 中使用的 kwargs 均继承自 BaseObject,包括:
909
+ - id: 标识
910
+ - group: 组名
911
+ - enabled: 使能状态
912
+ - timeout: 定时时间
913
+ - onSuccess: 定时到期执行的函数
914
+ """
729
915
  __abbr__ = "ti"
730
916
 
731
917
  def __init__(self, session, *args, **kwargs):
@@ -737,6 +923,7 @@ class Timer(BaseObject):
737
923
  self.reset()
738
924
 
739
925
  def startTimer(self):
926
+ "启动定时器"
740
927
  if not isinstance(self._task, asyncio.Task):
741
928
  self._halt = False
742
929
  self._task = asyncio.create_task(self.onTimerTask())
@@ -744,7 +931,8 @@ class Timer(BaseObject):
744
931
  asyncio.ensure_future(self._task)
745
932
 
746
933
  async def onTimerTask(self):
747
- # 定时任务,修改为一直循环
934
+ "定时任务的调用方法,脚本中无需调用"
935
+
748
936
  while self._enabled:
749
937
  await asyncio.sleep(self.timeout)
750
938
 
@@ -754,15 +942,6 @@ class Timer(BaseObject):
754
942
  if self.oneShot or self._halt:
755
943
  break
756
944
 
757
- # if self.enabled:
758
- # await asyncio.sleep(self.timeout)
759
- # if callable(self._onSuccess):
760
- # self._onSuccess(self.id)
761
-
762
- # if self.oneShot:
763
- # self.enabled = False
764
- # else:
765
- # await asyncio.create_task(self.onTimerTask())
766
945
 
767
946
  def reset(self):
768
947
  "复位定时器,清除所创建的定时任务"
@@ -777,6 +956,7 @@ class Timer(BaseObject):
777
956
 
778
957
  @property
779
958
  def enabled(self):
959
+ "可读写属性,定时器使能状态"
780
960
  return self._enabled
781
961
 
782
962
  @enabled.setter
@@ -794,12 +974,19 @@ class Timer(BaseObject):
794
974
  return self.__detailed__()
795
975
 
796
976
  class SimpleTimer(Timer):
977
+ """
978
+ 简单定时器 SimpleTimer 类型,继承自 Timer, 包含了 Timer 的全部功能, 并使用 CodeBlock 对象创建了 onSuccess 的使用场景。
979
+
980
+ :param session: 本对象所属的会话, 同 MatchObject
981
+ :param code: str, 当定时任务到期时执行的代码, 使用 CodeBlock 实现
982
+ """
797
983
  def __init__(self, session, code, *args, **kwargs):
798
984
  self._code = code
799
985
  self._codeblock = CodeBlock(code)
800
986
  super().__init__(session, *args, **kwargs)
801
987
 
802
988
  def onSuccess(self, id):
989
+ "覆盖了基类的默认 onSuccess方法,使用 CodeBlock 执行构造函数中传入的 code 参数"
803
990
  self._codeblock.execute(self.session, id = id)
804
991
 
805
992
  def __detailed__(self) -> str:
pymud/protocol.py CHANGED
@@ -127,10 +127,10 @@ class MudClientProtocol(Protocol):
127
127
 
128
128
  def __init__(self, session, *args, **kwargs) -> None:
129
129
  """
130
- MUD客户端协议实现, 参数包括: \n
131
- + session: 管理protocol的会话 \n
132
- 除此之外,还可以接受的命名参数包括: \n
133
- + onConnected: 当连接建立时的回调,包含2个参数: MudClientProtocol本身,以及生成的传输Transport对象 \n
130
+ MUD客户端协议实现, 参数包括:
131
+ + session: 管理protocol的会话
132
+ 除此之外,还可以接受的命名参数包括:
133
+ + onConnected: 当连接建立时的回调,包含2个参数: MudClientProtocol本身,以及生成的传输Transport对象
134
134
  + onDisconnected: 当连接断开时的回调,包含1个参数: MudClientProtocol本身
135
135
  """
136
136