names_channels_of_user: Callable,
remove_from_channels: Callable,
**kwargs) -> None:
+ self._modes: set[str] = set()
self.names_channels = lambda: names_channels_of_user(self)
self._remove_from_channels = lambda target, msg: remove_from_channels(
self, target, msg)
def id_(self, value: str) -> None:
self._id_ = value
+ @property
+ def modes(self) -> str:
+ 'User modes as collected by MODE messages on them.'
+ return ''.join(sorted(list(self._modes)))
+
+ @modes.setter
+ def modes(self, modeset: str) -> None:
+ operation, chars = modeset[:1], modeset[1:]
+ assert chars and operation in '+-'
+ for char in chars:
+ if operation == '+':
+ self._modes.add(char)
+ elif char in self._modes:
+ self._modes.remove(char)
+
class _UpdatingServerCapability(UpdatingAttrsMixin, ServerCapability):
pass
-insert ./lib/001-to-usermode
-# for: 001-to-usermode
+insert ./lib/001-setting-nick
insert ./lib/attempting-to-connected
insert ./lib/connect-to-connected
insert ./lib/cap-msg
insert ./lib/req-sasl
# for: get-sasl-plain, req-sasl
insert ./lib/servermsglogged
+insert ./lib/usermode
+insert ./lib/user-set-to
× disconnect-to-reconnect-0
-insert 001-to-usermode
+insert usermode
insert cmd-disconnect
× disconnect-to-reconnect-1
insert caps-neg-empty
> /window 2
+insert 001-setting-nick
insert disconnect-to-reconnect-0 :-1
insert disconnect-to-reconnect-1
log 1 $ caps:zba:data set to: []
log 1 > CAP :LIST
insert cap-msg : + CAPMSG :foo LIST * :foo rab oof
-log 1 $ users:me:nick set to: [?]
-log 1 $ users:me:nick set to: [foo]
+insert user-set-to :3 + USER_ID=me USERNICK :foo
insert cap-msg : + CAPMSG :foo LIST :zab rba
log 1 $ caps:foo:enabled set to: [True]
log 1 $ caps:oof:enabled set to: [True]
log 1 $ caps:zab:enabled set to: [True]
log 1 > CAP :END
-insert disconnect-to-reconnect 4:
+insert disconnect-to-reconnect
# check REQ for "sasl" (even if no PLAIN), denied
insert servermsglogged : + MSG ::*.?.net CAP * LS :foo bar sasl
insert req-sasl : + REPLY=NAK CAPLIST :
log 1 > CAP :END
-insert disconnect-to-reconnect 4:
+insert disconnect-to-reconnect
# check REQ for "sasl" with PLAIN successful (but for lack of password, negotiation still ending instantly)
insert get-sasl-plain
insert ./lib/retry-in
insert ./lib/servermsglogged
insert ./lib/user-set-to
+insert ./lib/usermode
× part-empty
insert part : + USERIDS_CLEAR :cleared
# check /join to, and part from, channel with one other user
insert join-channel-0 : + CHANNEL=#ch_test0 RESIDENT_NAMES :foo bar
-insert user-set-to :2 + USER_ID=1 USERNICK :bar
+insert user-set-to :3 + USER_ID=1 USERNICK :bar
insert join-channel-1 : + CHANNEL=#ch_test0 RESIDENT_IDS :[1], [me]
log 3 $ residents: bar, foo
insert part : + CHANNEL=#ch_test0 CHAN_WIN_ID=3 USERIDS_CLEAR :set to: [1]
# check /join into channel with many other users, with multi-line 353
insert join-channel-0 : + CHANNEL=#ch_test0 RESIDENT_NAMES :foo baz oof
-insert user-set-to :2 + USER_ID=2 USERNICK :baz
-insert user-set-to :2 + USER_ID=3 USERNICK :oof
+insert user-set-to :3 + USER_ID=2 USERNICK :baz
+insert user-set-to :3 + USER_ID=3 USERNICK :oof
insert servermsglogged : + MSG ::foo.bar.baz 353 foo = #ch_test0 :rab zab
-insert user-set-to :2 + USER_ID=4 USERNICK :rab
-insert user-set-to :2 + USER_ID=5 USERNICK :zab
+insert user-set-to :3 + USER_ID=4 USERNICK :rab
+insert user-set-to :3 + USER_ID=5 USERNICK :zab
insert join-channel-1 : + CHANNEL=#ch_test0 RESIDENT_IDS :[2], [3], [4], [5], [me]
log 3 $ residents: baz, oof, rab, zab, foo
# check _observed_ topic change _does_ affect users database, and …
insert servermsglogged : + MSG ::baz!~baz@baz.baz TOPIC #ch_test1 :foo bar baz
-insert user-set-to 2: + USER_ID=2 USERNAME=~baz USERHOST :baz.baz
+insert user-set-to 3: + USER_ID=2 USERNAME=~baz USERHOST :baz.baz
# … is echoed into channel window _if_ either content or setter change
insert topic-set-to : + CHANNEL=#ch_test1 NEWTOPIC :foo bar baz
insert servermsglogged : + MSG ::baz!~baz@baz.baz PRIVMSG #ch_test0 :msg_test3 msg_test4
log 3 < [baz] msg_test3 msg_test4
insert servermsglogged : + MSG ::oof!~oof@oof.oof NOTICE #ch_test0 :msg_test5 msg_test6
-insert user-set-to 2: + USER_ID=3 USERNAME=~oof USERHOST :oof.oof
+insert user-set-to 3: + USER_ID=3 USERNAME=~oof USERHOST :oof.oof
log 3 < (oof) msg_test5 msg_test6
# check effect of server NOTICE to channel
# check other-user part with exit message
insert servermsglogged : + MSG ::zab!~zab@zab.zab PART #ch_test0 :goodbye
-insert user-set-to 2: + USER_ID=5 USERNAME=~zab USERHOST :zab.zab
+insert user-set-to 3: + USER_ID=5 USERNAME=~zab USERHOST :zab.zab
insert parts-core : + CHAN_WIN_ID=3 CHANNEL=#ch_test0 USER_ID=5 NICK=zab exitPREFIX=:§ exitMSG=goodbye USERIDS_CLEAR=set§to:§[4],§[me] § :
log 1 $ users:5 cleared
# test effect of PREFIX
insert join-channel-0 : +0 CHANNEL=#ch_test6 RESIDENT_NAMES :foo @bar +baz =quux
-insert user-set-to :2 +1 USER_ID=1 USERNICK :bar
-insert user-set-to :2 +1 USER_ID=2 USERNICK :baz
-insert user-set-to :2 +1 USER_ID=3 USERNICK :=quux
+insert user-set-to :3 +1 USER_ID=1 USERNICK :bar
+insert user-set-to :3 +1 USER_ID=2 USERNICK :baz
+insert user-set-to :3 +1 USER_ID=3 USERNICK :=quux
insert join-channel-1 : +0 CHANNEL=#ch_test6 RESIDENT_IDS :[1], [2], [3], [me]
log 7 $ residents: bar, baz, =quux, foo
insert un-default : +0 KEY=PREFIX VALUE :(vE)+=
insert join-channel-0 : +0 CHANNEL=#ch_test7 RESIDENT_NAMES :foo @bar +baz =quux
-insert user-set-to :2 +1 USER_ID=4 USERNICK :@bar
-insert user-set-to :2 +1 USER_ID=5 USERNICK :quux
+insert user-set-to :3 +1 USER_ID=4 USERNICK :@bar
+insert user-set-to :3 +1 USER_ID=5 USERNICK :quux
insert join-channel-1 : +0 CHANNEL=#ch_test7 RESIDENT_IDS :[2], [4], [5], [me]
log 8 $ residents: baz, @bar, quux, foo
× 001-setting-nick
insert servermsglogged : +0 MSG ::foo.bar.baz 001 foo :Welcome to the foo.bar.baz network
-insert user-set-to :2 +1 USER_ID=me USERNICK :foo
+insert user-set-to :3 +1 USER_ID=me USERNICK :foo
insert ./lib/001-setting-nick
-insert ./lib/servermsglogged
-insert ./lib/user-set-to
-
-× usermode
-insert servermsglogged : +0 MSG ::foo!~baz@baz.bar.foo MODE foo ABC
-insert user-set-to 2: +1 USER_ID=me USERNAME=~baz USERHOST :baz.bar.foo
-log 1 $ users:me:modes set to: [ABC]
+insert ./lib/usermode
× 001-to-usermode
insert 001-setting-nick
log 1 > CAP REQ :sasl
log 1 > CAP :LIST
insert cap-msg : +0 CAPMSG :foo REPLY :sasl
-insert user-set-to :2 + USER_ID=me USERNICK :foo
+insert user-set-to :3 + USER_ID=me USERNICK :foo
insert cap-msg : +0 CAPMSG :foo LIST :CAPLIST
× get-sasl-plain
× user-set-to
log 1 $ users:USER_ID:nick set to: [?]
+log 1 $ users:USER_ID:modes set to: []
log 1 $ users:USER_ID:nick set to: [USERNICK]
log 1 $ users:USER_ID:user set to: [USERNAME]
log 1 $ users:USER_ID:host set to: [USERHOST]
--- /dev/null
+insert ./lib/servermsglogged
+insert ./lib/user-set-to
+
+× usermode
+insert servermsglogged : +0 MSG ::foo!~baz@baz.bar.foo MODE foo +ABC
+insert user-set-to 3: +1 USER_ID=me USERNAME=~baz USERHOST :baz.bar.foo
+log 1 $ users:me:modes set to: [ABC]
# collect user mode
insert servermsglogged : +0 MSG ::foo1 MODE foo1 :+Ziw
-log 1 $ users:me:modes set to: [+Ziw]
+log 1 $ users:me:modes set to: [Ziw]
# handle bot query NOTICE
insert servermsglogged : +0 MSG ::SaslServ!SaslServ@services.bar.baz NOTICE foo1 :Last login from ~baz@foo.bar.baz on Jan 1 22:00:00 2021 +0000.
log 3 < (SaslServ) Last login from ~baz@foo.bar.baz on Jan 1 22:00:00 2021 +0000.
# join channel with other user
insert join-channel-0 : +0 CHANNEL=#test RESIDENT_NAMES :foo @baz
-insert user-set-to :2 +1 USER_ID=1 USERNICK :baz
+insert user-set-to :3 +1 USER_ID=1 USERNICK :baz
insert join-channel-1 : +0 CHANNEL=#test RESIDENT_IDS :[1], [me]
log 4 $ residents: baz, foo
-insert ./lib/conn
-# for: attempting, connected
+insert ./lib/cap-msg
insert ./lib/cmd-disconnect
# for cmd-disconnect-0, cmd-disconnect-1
+insert ./lib/conn
+# for: attempting, connected
insert ./lib/disconnect
# for: disconnect1
-insert ./lib/servermsglogged
-insert ./lib/cap-msg
insert ./lib/req-sasl
# for: get-sasl-plain
+insert ./lib/servermsglogged
insert ./lib/user-set-to
× connecting-to-nick
insert cap-msg : +0 CAPMSG :* LS :
log 1 > CAP :LIST
insert cap-msg : +0 CAPMSG :foo LIST :
-insert user-set-to :2 + USER_ID=me USERNICK :foo
+insert user-set-to :3 + USER_ID=me USERNICK :foo
log 1 > CAP :END
#
insert cmd-disconnect-0 :-2 + ~baz@baz.bar.foo :~foo@foo.foo
-insert user-set-to 2: + USER_ID=me USERNAME=~foo USERHOST :foo.foo
+insert user-set-to 3: + USER_ID=me USERNAME=~foo USERHOST :foo.foo
insert cmd-disconnect-0 -2: + ~baz@baz.bar.foo :~foo@foo.foo
insert cmd-disconnect-1 :-1
insert disconnect1 1: + WIN_IDS :2
-# check successful SASL authentication
+# check failing SASL authentication
insert connecting-to-nick
insert cap-to-auth
-insert servermsglogged : + MSG ::foo.bar.baz 900 foo foo!foo@foo.foo foo :You are now logged in as foo
-insert user-set-to 2: + USER_ID=me USERNAME=foo USERHOST :foo.foo
-log 1 $ sasl_account set to: [foo]
-insert end-auth : + NUMERIC=903 SASL_STATE :successful
+insert end-auth : + NUMERIC=904 SASL_STATE :failed
#
insert cmd-disconnect-0 :-2 + ~baz@baz.bar.foo :~foo@foo.foo
-insert user-set-to 2:3 + USER_ID=me USERNAME :~foo
+insert user-set-to 3: + USER_ID=me USERNAME=~foo USERHOST :foo.foo
insert cmd-disconnect-0 -2: + ~baz@baz.bar.foo :~foo@foo.foo
insert cmd-disconnect-1
insert disconnect1 1:-1 + WIN_IDS :2
-log 1 $ sasl_account set to: []
log 1 $ sasl_auth_state set to: []
insert disconnect1 -1:
-# check failing SASL authentication
+# check successful SASL authentication
insert connecting-to-nick
insert cap-to-auth
-insert end-auth : + NUMERIC=904 SASL_STATE :failed
-#
-insert cmd-disconnect-0 :-2 + ~baz@baz.bar.foo :~foo@foo.foo
-insert user-set-to 2: + USER_ID=me USERNAME=~foo USERHOST :foo.foo
-insert cmd-disconnect-0 -2: + ~baz@baz.bar.foo :~foo@foo.foo
-insert cmd-disconnect-1
-insert disconnect1 1:-1 + WIN_IDS :2
-log 1 $ sasl_auth_state set to: []
-insert disconnect1 -1:
+insert servermsglogged : + MSG ::foo.bar.baz 900 foo foo!foo@foo.foo foo :You are now logged in as foo
+insert user-set-to 3: + USER_ID=me USERNAME=foo USERHOST :foo.foo
+log 1 $ sasl_account set to: [foo]
+insert end-auth : + NUMERIC=903 SASL_STATE :successful
+
+# check tilde addition and MODE setting
+insert servermsglogged : +0 MSG ::foo!~foo@foo.foo MODE foo +aBc
+log 1 $ users:me:user set to: [~foo]
+log 1 $ users:me:modes set to: [Bac]
+insert servermsglogged : +0 MSG ::foo!~foo@foo.foo MODE foo -cba
+log 1 $ users:me:modes set to: [B]