home · contact · privacy
To differentiate between nickname from source and nickname in params, use 'sender...
authorChristian Heller <c.heller@plomlompom.de>
Tue, 19 Aug 2025 08:26:36 +0000 (10:26 +0200)
committerChristian Heller <c.heller@plomlompom.de>
Tue, 19 Aug 2025 08:26:36 +0000 (10:26 +0200)
ircplom/client.py

index c97855ab596aaea89dbface767466520798e128c..28064d04eaf3a9e4a8ae3981af95c98858ab3f0d 100644 (file)
@@ -48,6 +48,7 @@ class _MsgSource(Enum):
 class _MsgParam(Enum):
     ANY = auto()
     CHANNEL = auto()
+    NICKNAME = auto()
 
 
 class _MsgParseExpectation(NamedTuple):
@@ -78,7 +79,8 @@ _EXPECTATIONS: tuple[_MsgParseExpectation, ...] = (
    _MsgParseExpectation('JOIN', params=(_MsgParam.CHANNEL,),
                         source=_MsgSource.USER_ADDRESS),
    _MsgParseExpectation('MODE', 2, source=_MsgSource.USER_ADDRESS),
-   _MsgParseExpectation('NICK', 1, source=_MsgSource.USER_ADDRESS),
+   _MsgParseExpectation('NICK', params=(_MsgParam.NICKNAME,),
+                        source=_MsgSource.USER_ADDRESS),
    _MsgParseExpectation('NOTICE', 2, source=_MsgSource.USER_ADDRESS),
    _MsgParseExpectation('NOTICE', 2, source=_MsgSource.SERVER),
    _MsgParseExpectation('PART', params=(_MsgParam.CHANNEL,),
@@ -598,7 +600,7 @@ class Client(ABC, ClientQueueMixin):
                     continue
             elif ex.source is _MsgSource.USER_ADDRESS:
                 if (toks := msg.source_to_user_address):
-                    to_return['nickname'] = toks[0]
+                    to_return['sender'] = toks[0]
                 else:
                     continue
             len_params = len(msg.params)
@@ -614,12 +616,17 @@ class Client(ABC, ClientQueueMixin):
                             continue
                         to_return['ch_name'] = param
                         to_return['channel'] = self._db.chan(param)
-                    if exp_param is _MsgParam.ANY:
+                    elif exp_param is _MsgParam.NICKNAME:
+                        if param[0] in '~&@%+# ':
+                            continue
+                        to_return['nickname'] = param
+                    elif exp_param is _MsgParam.ANY:
                         to_return['params'] += [param]
-            elif ex.len_max_params:
-                if not ex.len_min_params <= len_params <= ex.len_max_params:
-                    continue
-            elif len_params != ex.len_min_params:
+            elif len_params < ex.len_min_params:
+                continue
+            elif ex.len_max_params and len_params > ex.len_max_params:
+                continue
+            elif (not ex.len_max_params) and len_params != ex.len_min_params:
                 continue
             return to_return
         return False
@@ -688,45 +695,45 @@ class Client(ABC, ClientQueueMixin):
         elif self._match_msg(msg, 'ERROR'):
             self.close()
         elif (ret := self._match_msg(msg, 'JOIN')):
-            log_msg = f'{ret["nickname"]} {msg.verb.lower()}s {ret["ch_name"]}'
+            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['nickname'] != self._db.nickname:
-                ret['channel'].append_completable('users', ret['nickname'],
+            if ret['sender'] != self._db.nickname:
+                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['nickname'] == self._db.nickname:
-            self.set_nick(msg.params[0], confirmed=True)
+                and ret['sender'] == self._db.nickname:
+            self.set_nick(ret['nickname'], confirmed=True)
         elif (ret := self._match_msg(msg, 'NOTICE'))\
                 and (msg.params[0] != '*' or not self._db.nickname):
-            kw = {'sender': ret['nickname'], 'scope': LogScope.CHAT
-                  } if 'nickname' in ret else {}
+            kw = {'sender': ret['sender'], 'scope': LogScope.CHAT
+                  } if 'sender' in ret else {}
             self._log(msg.params[-1], out=False, target=msg.params[0],
                       as_notice=True, **kw)
         elif (ret := self._match_msg(msg, 'PRIVMSG')) and msg.params[0] != '*':
-            kw = {'sender': ret['nickname'], 'scope': LogScope.CHAT
-                  } if 'nickname' in ret else {}
+            kw = {'sender': ret['sender'], 'scope': LogScope.CHAT
+                  } if 'sender' in ret else {}
             self._log(msg.params[-1], out=False, target=msg.params[0], **kw)
         elif (ret := self._match_msg(msg, 'PART')):
-            log_msg = f'{ret["nickname"]} {msg.verb.lower()}s {ret["ch_name"]}'
+            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['nickname'] == self._db.nickname:
+            if ret['sender'] == self._db.nickname:
                 self._db.del_chan(ret['ch_name'])
             else:
-                ret['channel'].remove_completable('users', ret['nickname'],
+                ret['channel'].remove_completable('users', ret['sender'],
                                                   stay_complete=True)
         elif (ret := self._match_msg(msg, 'PING')):
             self.send(IrcMessage(verb='PONG', params=tuple(ret['params'])))
         elif (ret := self._match_msg(msg, 'QUIT')):
             for chan_name in self._db.chan_names:
                 chan = self._db.chan(chan_name)
-                if ret['nickname'] in chan.users:
-                    chan.remove_completable('users', ret['nickname'],
+                if ret['sender'] in chan.users:
+                    chan.remove_completable('users', ret['sender'],
                                             stay_complete=True)
-                    self._log(f'{ret["nickname"]} quits: {ret["params"][0]}',
+                    self._log(f'{ret["sender"]} quits: {ret["params"][0]}',
                               scope=LogScope.CHAT, target=chan_name)
         else:
             self._log(f'PLEASE IMPLEMENT HANDLER FOR: {msg.raw}')