home · contact · privacy
Handle NICK changes of other users in channels.
authorChristian Heller <c.heller@plomlompom.de>
Tue, 19 Aug 2025 12:47:30 +0000 (14:47 +0200)
committerChristian Heller <c.heller@plomlompom.de>
Tue, 19 Aug 2025 12:47:30 +0000 (14:47 +0200)
ircplom/client.py

index 7e2bdc3dc5a0e9bdf846e0e4d7ac97b467e5dcf1..9bd182972f4184ef0f5d802c64ee4f82537d086e 100644 (file)
@@ -84,6 +84,8 @@ _EXPECTATIONS: tuple[_MsgParseExpectation, ...] = (
                         params=(_MsgTok.NICKNAME_ME, _MsgTok.ANY)),
    _MsgParseExpectation(_MsgTok.USER_ADDRESS_ME, 'NICK',
                         params=(_MsgTok.NICKNAME,)),
+   _MsgParseExpectation(_MsgTok.USER_ADDRESS, 'NICK',
+                        params=(_MsgTok.NICKNAME,)),
    _MsgParseExpectation(_MsgTok.USER_ADDRESS, 'NOTICE', 2),
    _MsgParseExpectation(_MsgTok.SERVER, 'NOTICE', 2),
    _MsgParseExpectation(_MsgTok.USER_ADDRESS_ME, 'PART',
@@ -702,7 +704,16 @@ class Client(ABC, ClientQueueMixin):
         elif (ret := self._match_msg(msg, 'MODE')):
             self._db.user_modes = ret['any']
         elif (ret := self._match_msg(msg, 'NICK')):
-            self.set_nick(ret['nickname'], confirmed=True)
+            if 'sender_me' in ret:
+                self.set_nick(ret['nickname'], confirmed=True)
+            else:
+                for chan_name in self._db.chan_names:
+                    chan = self._db.chan(chan_name)
+                    if ret['sender'] in chan.users:
+                        chan.remove_completable('users', ret['sender'], True)
+                        chan.append_completable('users', ret['nickname'], True)
+                        self._log(f'{ret["sender"]} becomes {ret["nickname"]}',
+                                  scope=LogScope.CHAT, target=chan_name)
         elif (ret := self._match_msg(msg, 'NOTICE'))\
                 and (msg.params[0] != '*' or not self._db.nickname):
             kw = {'sender': ret['sender'], 'scope': LogScope.CHAT
@@ -720,16 +731,14 @@ class Client(ABC, ClientQueueMixin):
             if 'sender_me' in ret:
                 self._db.del_chan(ret['ch_name'])
             else:
-                ret['channel'].remove_completable('users', ret['sender'],
-                                                  stay_complete=True)
+                ret['channel'].remove_completable('users', ret['sender'], True)
         elif (ret := self._match_msg(msg, 'PING')):
             self.send(IrcMessage(verb='PONG', params=(ret['any'],)))
         elif (ret := self._match_msg(msg, 'QUIT')):
             for chan_name in self._db.chan_names:
                 chan = self._db.chan(chan_name)
                 if ret['sender'] in chan.users:
-                    chan.remove_completable('users', ret['sender'],
-                                            stay_complete=True)
+                    chan.remove_completable('users', ret['sender'], True)
                     self._log(f'{ret["sender"]} quits: {ret["any"]}',
                               scope=LogScope.CHAT, target=chan_name)
         else: