home · contact · privacy
Also differentiate _MsgSource.USER_ADDRESS towards a _ME.
authorChristian Heller <c.heller@plomlompom.de>
Tue, 19 Aug 2025 10:08:07 +0000 (12:08 +0200)
committerChristian Heller <c.heller@plomlompom.de>
Tue, 19 Aug 2025 10:08:07 +0000 (12:08 +0200)
ircplom/client.py

index 28064d04eaf3a9e4a8ae3981af95c98858ab3f0d..26f9b17c205f383d10040440e3f8f51015abd2c9 100644 (file)
@@ -42,6 +42,7 @@ _NUMERICS_TO_IGNORE = (
 class _MsgSource(Enum):
     NONE = auto()
     USER_ADDRESS = auto()
+    USER_ADDRESS_ME = auto()
     SERVER = auto()
 
 
@@ -49,6 +50,7 @@ class _MsgParam(Enum):
     ANY = auto()
     CHANNEL = auto()
     NICKNAME = auto()
+    NICKNAME_ME = auto()
 
 
 class _MsgParseExpectation(NamedTuple):
@@ -76,13 +78,18 @@ _EXPECTATIONS: tuple[_MsgParseExpectation, ...] = (
    _MsgParseExpectation('CAP', 3, 15, source=_MsgSource.SERVER),
    _MsgParseExpectation('ERROR', params=(_MsgParam.ANY,),
                         source=_MsgSource.NONE),
+   _MsgParseExpectation('JOIN', params=(_MsgParam.CHANNEL,),
+                        source=_MsgSource.USER_ADDRESS_ME),
    _MsgParseExpectation('JOIN', params=(_MsgParam.CHANNEL,),
                         source=_MsgSource.USER_ADDRESS),
-   _MsgParseExpectation('MODE', 2, source=_MsgSource.USER_ADDRESS),
+   _MsgParseExpectation('MODE', params=(_MsgParam.NICKNAME_ME, _MsgParam.ANY),
+                        source=_MsgSource.USER_ADDRESS_ME),
    _MsgParseExpectation('NICK', params=(_MsgParam.NICKNAME,),
-                        source=_MsgSource.USER_ADDRESS),
+                        source=_MsgSource.USER_ADDRESS_ME),
    _MsgParseExpectation('NOTICE', 2, source=_MsgSource.USER_ADDRESS),
    _MsgParseExpectation('NOTICE', 2, source=_MsgSource.SERVER),
+   _MsgParseExpectation('PART', params=(_MsgParam.CHANNEL,),
+                        source=_MsgSource.USER_ADDRESS_ME),
    _MsgParseExpectation('PART', params=(_MsgParam.CHANNEL,),
                         source=_MsgSource.USER_ADDRESS),
    _MsgParseExpectation('PART', params=(_MsgParam.CHANNEL, _MsgParam.ANY),
@@ -598,9 +605,14 @@ class Client(ABC, ClientQueueMixin):
             elif ex.source is _MsgSource.SERVER:
                 if not msg.source_is_server(self._db.hostname):
                     continue
-            elif ex.source is _MsgSource.USER_ADDRESS:
+            elif ex.source in {_MsgSource.USER_ADDRESS,
+                               _MsgSource.USER_ADDRESS_ME}:
                 if (toks := msg.source_to_user_address):
                     to_return['sender'] = toks[0]
+                    if ex.source is _MsgSource.USER_ADDRESS_ME:
+                        if not self._db.nickname == toks[0]:
+                            continue
+                        to_return['sender_me'] = to_return['sender']
                 else:
                     continue
             len_params = len(msg.params)
@@ -616,10 +628,15 @@ class Client(ABC, ClientQueueMixin):
                             continue
                         to_return['ch_name'] = param
                         to_return['channel'] = self._db.chan(param)
-                    elif exp_param is _MsgParam.NICKNAME:
+                    elif exp_param in {_MsgParam.NICKNAME,
+                                       _MsgParam.NICKNAME_ME}:
                         if param[0] in '~&@%+# ':
                             continue
                         to_return['nickname'] = param
+                        if exp_param is _MsgParam.NICKNAME_ME:
+                            if param != self._db.nickname:
+                                continue
+                        to_return['nickname_me'] = to_return['nickname']
                     elif exp_param is _MsgParam.ANY:
                         to_return['params'] += [param]
             elif len_params < ex.len_min_params:
@@ -697,14 +714,12 @@ class Client(ABC, ClientQueueMixin):
         elif (ret := self._match_msg(msg, 'JOIN')):
             log_msg = f'{ret["sender"]} {msg.verb.lower()}s {ret["ch_name"]}'
             self._log(log_msg, scope=LogScope.CHAT, target=ret['ch_name'])
-            if ret['sender'] != self._db.nickname:
+            if 'sender_me' not in ret:
                 ret['channel'].append_completable('users', ret['sender'],
                                                   stay_complete=True)
-        elif self._match_msg(msg, 'MODE')\
-                and msg.params[0] == self._db.nickname:
-            self._db.user_modes = msg.params[1]
-        elif (ret := self._match_msg(msg, 'NICK'))\
-                and ret['sender'] == self._db.nickname:
+        elif (ret := self._match_msg(msg, 'MODE')):
+            self._db.user_modes = ret['params'][0]
+        elif (ret := self._match_msg(msg, 'NICK')):
             self.set_nick(ret['nickname'], confirmed=True)
         elif (ret := self._match_msg(msg, 'NOTICE'))\
                 and (msg.params[0] != '*' or not self._db.nickname):
@@ -720,7 +735,7 @@ class Client(ABC, ClientQueueMixin):
             log_msg = f'{ret["sender"]} {msg.verb.lower()}s {ret["ch_name"]}'
             log_msg += f': {ret["params"][0]}' if ret['params'] else ''
             self._log(log_msg, scope=LogScope.CHAT, target=ret['ch_name'])
-            if ret['sender'] == self._db.nickname:
+            if 'sender_me' in ret:
                 self._db.del_chan(ret['ch_name'])
             else:
                 ret['channel'].remove_completable('users', ret['sender'],