Skip to content

Commit 7337309

Browse files
authored
CommonClient: add more docstrings and comments #3821
1 parent 3205e9b commit 7337309

File tree

1 file changed

+27
-4
lines changed

1 file changed

+27
-4
lines changed

CommonClient.py

+27-4
Original file line numberDiff line numberDiff line change
@@ -45,10 +45,21 @@ def get_ssl_context():
4545

4646

4747
class ClientCommandProcessor(CommandProcessor):
48+
"""
49+
The Command Processor will parse every method of the class that starts with "_cmd_" as a command to be called
50+
when parsing user input, i.e. _cmd_exit will be called when the user sends the command "/exit".
51+
52+
The decorator @mark_raw can be imported from MultiServer and tells the parser to only split on the first
53+
space after the command i.e. "/exit one two three" will be passed in as method("one two three") with mark_raw
54+
and method("one", "two", "three") without.
55+
56+
In addition all docstrings for command methods will be displayed to the user on launch and when using "/help"
57+
"""
4858
def __init__(self, ctx: CommonContext):
4959
self.ctx = ctx
5060

5161
def output(self, text: str):
62+
"""Helper function to abstract logging to the CommonClient UI"""
5263
logger.info(text)
5364

5465
def _cmd_exit(self) -> bool:
@@ -164,13 +175,14 @@ def _cmd_ready(self):
164175
async_start(self.ctx.send_msgs([{"cmd": "StatusUpdate", "status": state}]), name="send StatusUpdate")
165176

166177
def default(self, raw: str):
178+
"""The default message parser to be used when parsing any messages that do not match a command"""
167179
raw = self.ctx.on_user_say(raw)
168180
if raw:
169181
async_start(self.ctx.send_msgs([{"cmd": "Say", "text": raw}]), name="send Say")
170182

171183

172184
class CommonContext:
173-
# Should be adjusted as needed in subclasses
185+
# The following attributes are used to Connect and should be adjusted as needed in subclasses
174186
tags: typing.Set[str] = {"AP"}
175187
game: typing.Optional[str] = None
176188
items_handling: typing.Optional[int] = None
@@ -429,7 +441,10 @@ async def get_username(self):
429441
self.auth = await self.console_input()
430442

431443
async def send_connect(self, **kwargs: typing.Any) -> None:
432-
""" send `Connect` packet to log in to server """
444+
"""
445+
Send a `Connect` packet to log in to the server,
446+
additional keyword args can override any value in the connection packet
447+
"""
433448
payload = {
434449
'cmd': 'Connect',
435450
'password': self.password, 'name': self.auth, 'version': Utils.version_tuple,
@@ -459,13 +474,15 @@ def cancel_autoreconnect(self) -> bool:
459474
return False
460475

461476
def slot_concerns_self(self, slot) -> bool:
477+
"""Helper function to abstract player groups, should be used instead of checking slot == self.slot directly."""
462478
if slot == self.slot:
463479
return True
464480
if slot in self.slot_info:
465481
return self.slot in self.slot_info[slot].group_members
466482
return False
467483

468484
def is_echoed_chat(self, print_json_packet: dict) -> bool:
485+
"""Helper function for filtering out messages sent by self."""
469486
return print_json_packet.get("type", "") == "Chat" \
470487
and print_json_packet.get("team", None) == self.team \
471488
and print_json_packet.get("slot", None) == self.slot
@@ -497,13 +514,14 @@ def on_user_say(self, text: str) -> typing.Optional[str]:
497514
"""Gets called before sending a Say to the server from the user.
498515
Returned text is sent, or sending is aborted if None is returned."""
499516
return text
500-
517+
501518
def on_ui_command(self, text: str) -> None:
502519
"""Gets called by kivy when the user executes a command starting with `/` or `!`.
503520
The command processor is still called; this is just intended for command echoing."""
504521
self.ui.print_json([{"text": text, "type": "color", "color": "orange"}])
505522

506523
def update_permissions(self, permissions: typing.Dict[str, int]):
524+
"""Internal method to parse and save server permissions from RoomInfo"""
507525
for permission_name, permission_flag in permissions.items():
508526
try:
509527
flag = Permission(permission_flag)
@@ -613,6 +631,7 @@ def on_deathlink(self, data: typing.Dict[str, typing.Any]) -> None:
613631
logger.info(f"DeathLink: Received from {data['source']}")
614632

615633
async def send_death(self, death_text: str = ""):
634+
"""Helper function to send a deathlink using death_text as the unique death cause string."""
616635
if self.server and self.server.socket:
617636
logger.info("DeathLink: Sending death to your friends...")
618637
self.last_death_link = time.time()
@@ -626,6 +645,7 @@ async def send_death(self, death_text: str = ""):
626645
}])
627646

628647
async def update_death_link(self, death_link: bool):
648+
"""Helper function to set Death Link connection tag on/off and update the connection if already connected."""
629649
old_tags = self.tags.copy()
630650
if death_link:
631651
self.tags.add("DeathLink")
@@ -635,7 +655,7 @@ async def update_death_link(self, death_link: bool):
635655
await self.send_msgs([{"cmd": "ConnectUpdate", "tags": self.tags}])
636656

637657
def gui_error(self, title: str, text: typing.Union[Exception, str]) -> typing.Optional["kvui.MessageBox"]:
638-
"""Displays an error messagebox"""
658+
"""Displays an error messagebox in the loaded Kivy UI. Override if using a different UI framework"""
639659
if not self.ui:
640660
return None
641661
title = title or "Error"
@@ -987,6 +1007,7 @@ async def console_loop(ctx: CommonContext):
9871007

9881008

9891009
def get_base_parser(description: typing.Optional[str] = None):
1010+
"""Base argument parser to be reused for components subclassing off of CommonClient"""
9901011
import argparse
9911012
parser = argparse.ArgumentParser(description=description)
9921013
parser.add_argument('--connect', default=None, help='Address of the multiworld host.')
@@ -1037,6 +1058,7 @@ async def main(args):
10371058
parser.add_argument("url", nargs="?", help="Archipelago connection url")
10381059
args = parser.parse_args(args)
10391060

1061+
# handle if text client is launched using the "archipelago://name:pass@host:port" url from webhost
10401062
if args.url:
10411063
url = urllib.parse.urlparse(args.url)
10421064
if url.scheme == "archipelago":
@@ -1048,6 +1070,7 @@ async def main(args):
10481070
else:
10491071
parser.error(f"bad url, found {args.url}, expected url in form of archipelago://archipelago.gg:38281")
10501072

1073+
# use colorama to display colored text highlighting on windows
10511074
colorama.init()
10521075

10531076
asyncio.run(main(args))

0 commit comments

Comments
 (0)