@@ -1733,10 +1733,28 @@ impl Client {
17331733 . iter ( )
17341734 . any ( |who_poll| who_poll. channel == target_channel)
17351735 {
1736- self . who_polls . push_back ( WhoPoll {
1736+ let mut who_poll = WhoPoll {
17371737 channel : target_channel. clone ( ) ,
17381738 status : WhoStatus :: Joined ,
1739- } ) ;
1739+ } ;
1740+
1741+ if self
1742+ . capabilities
1743+ . acknowledged ( Capability :: NoImplicitNames )
1744+ {
1745+ let message = prepare_who_polls (
1746+ & self . isupport ,
1747+ & self . capabilities ,
1748+ & mut who_poll,
1749+ ) ;
1750+ self . send (
1751+ None ,
1752+ message. into ( ) ,
1753+ TokenPriority :: High ,
1754+ ) ;
1755+ }
1756+
1757+ self . who_polls . push_back ( who_poll) ;
17401758 }
17411759
17421760 if !self . mode_requests . iter ( ) . any ( |mode_request| {
@@ -1810,6 +1828,10 @@ impl Client {
18101828 }
18111829 Command :: Numeric ( RPL_WHOREPLY , args) => {
18121830 let channel = ok ! ( args. get( 1 ) ) ;
1831+ let user = ok ! ( args. get( 2 ) ) ;
1832+ let host = ok ! ( args. get( 3 ) ) ;
1833+ let nick = ok ! ( args. get( 5 ) ) ;
1834+ let flags = ok ! ( args. get( 6 ) ) ;
18131835
18141836 let casemapping = self . casemapping ( ) ;
18151837
@@ -1825,8 +1847,8 @@ impl Client {
18251847 self . chanmap . get_mut ( & target_channel)
18261848 {
18271849 client_channel. update_user_away (
1828- ok ! ( args . get ( 5 ) ) ,
1829- ok ! ( args . get ( 6 ) ) ,
1850+ nick ,
1851+ flags ,
18301852 casemapping,
18311853 ) ;
18321854
@@ -1844,6 +1866,20 @@ impl Client {
18441866 self . server
18451867 ) ;
18461868 }
1869+
1870+ if let Ok ( mut user) = User :: parse_from_whoreply (
1871+ nick,
1872+ flags,
1873+ user,
1874+ host,
1875+ casemapping,
1876+ isupport:: get_prefix ( & self . isupport ) ,
1877+ ) {
1878+ if flags. starts_with ( 'G' ) {
1879+ user. update_away ( true ) ;
1880+ }
1881+ client_channel. users . insert ( user) ;
1882+ }
18471883 }
18481884
18491885 if !user_request {
@@ -1865,7 +1901,13 @@ impl Client {
18651901 }
18661902 }
18671903 Command :: Numeric ( RPL_WHOSPCRPL , args) => {
1904+ let token = ok ! ( args. get( 1 ) ) ;
18681905 let channel = ok ! ( args. get( 2 ) ) ;
1906+ let user = ok ! ( args. get( 3 ) ) ;
1907+ let host = ok ! ( args. get( 4 ) ) ;
1908+ let nick = ok ! ( args. get( 5 ) ) ;
1909+ let flags = ok ! ( args. get( 6 ) ) ;
1910+ let account = args. get ( 7 ) ;
18691911
18701912 let casemapping = self . casemapping ( ) ;
18711913
@@ -1890,8 +1932,7 @@ impl Client {
18901932 _,
18911933 Some ( request_token) ,
18921934 ) if matches ! ( source, WhoSource :: Poll ) => {
1893- if let Ok ( token) =
1894- ok ! ( args. get( 1 ) ) . parse :: < WhoToken > ( )
1935+ if let Ok ( token) = token. parse :: < WhoToken > ( )
18951936 && * request_token == token
18961937 {
18971938 who_poll. status = WhoStatus :: Receiving (
@@ -1926,36 +1967,49 @@ impl Client {
19261967 & who_poll. status
19271968 {
19281969 // Check token to ~ensure reply is to poll request
1929- if let Ok ( token) =
1930- ok ! ( args. get( 1 ) ) . parse :: < WhoToken > ( )
1931- {
1970+ if let Ok ( token) = token. parse :: < WhoToken > ( ) {
19321971 if token == WhoXPollParameters :: Default . token ( )
19331972 {
19341973 client_channel. update_user_away (
1935- ok ! ( args . get ( 3 ) ) ,
1936- ok ! ( args . get ( 4 ) ) ,
1974+ nick ,
1975+ flags ,
19371976 casemapping,
19381977 ) ;
19391978 } else if token
19401979 == WhoXPollParameters :: WithAccountName
19411980 . token ( )
19421981 {
1943- let user = ok ! ( args. get( 3 ) ) ;
1944-
19451982 client_channel. update_user_away (
1946- user ,
1947- ok ! ( args . get ( 4 ) ) ,
1983+ nick ,
1984+ flags ,
19481985 casemapping,
19491986 ) ;
19501987
19511988 client_channel. update_user_accountname (
1952- user ,
1953- ok ! ( args . get ( 5 ) ) ,
1989+ nick ,
1990+ ok ! ( account ) ,
19541991 casemapping,
19551992 ) ;
19561993 }
19571994 }
19581995 }
1996+
1997+ if let Ok ( mut user) = User :: parse_from_whoreply (
1998+ nick,
1999+ flags,
2000+ user,
2001+ host,
2002+ casemapping,
2003+ isupport:: get_prefix ( & self . isupport ) ,
2004+ ) {
2005+ if let Some ( account) = account {
2006+ user = user. with_accountname ( account) ;
2007+ }
2008+ if flags. starts_with ( 'G' ) {
2009+ user. update_away ( true ) ;
2010+ }
2011+ client_channel. users . insert ( user) ;
2012+ }
19592013 }
19602014
19612015 if !user_request {
@@ -2012,8 +2066,17 @@ impl Client {
20122066 matches ! ( who_poll. status, WhoStatus :: Received )
20132067 } ) )
20142068 {
2015- self . who_polls [ pos] . status =
2016- WhoStatus :: Waiting ( Instant :: now ( ) ) ;
2069+ if !self
2070+ . capabilities
2071+ . acknowledged ( Capability :: NoImplicitNames )
2072+ || matches ! (
2073+ self . who_polls[ pos] . status,
2074+ WhoStatus :: Received
2075+ )
2076+ {
2077+ self . who_polls [ pos] . status =
2078+ WhoStatus :: Waiting ( Instant :: now ( ) ) ;
2079+ }
20172080
20182081 if pos != 0
20192082 && let Some ( who_poll) =
@@ -3916,6 +3979,9 @@ impl Client {
39163979 let request = match & who_poll. status {
39173980 WhoStatus :: Joined => {
39183981 ( self . capabilities . acknowledged ( Capability :: AwayNotify )
3982+ || self
3983+ . capabilities
3984+ . acknowledged ( Capability :: NoImplicitNames )
39193985 || self . config . who_poll_enabled )
39203986 . then_some ( Request :: Poll )
39213987 }
@@ -3961,38 +4027,11 @@ impl Client {
39614027 }
39624028 ) ;
39634029
3964- let message =
3965- if self . isupport . contains_key ( & isupport:: Kind :: WHOX ) {
3966- let whox_params = if self
3967- . capabilities
3968- . acknowledged ( Capability :: AccountNotify )
3969- {
3970- WhoXPollParameters :: WithAccountName
3971- } else {
3972- WhoXPollParameters :: Default
3973- } ;
3974-
3975- who_poll. status = WhoStatus :: Requested (
3976- WhoSource :: Poll ,
3977- Instant :: now ( ) ,
3978- Some ( whox_params. token ( ) ) ,
3979- ) ;
3980-
3981- command ! (
3982- "WHO" ,
3983- who_poll. channel. to_string( ) ,
3984- whox_params. fields( ) . to_string( ) ,
3985- whox_params. token( ) . to_owned( )
3986- )
3987- } else {
3988- who_poll. status = WhoStatus :: Requested (
3989- WhoSource :: Poll ,
3990- Instant :: now ( ) ,
3991- None ,
3992- ) ;
3993-
3994- command ! ( "WHO" , who_poll. channel. to_string( ) )
3995- } ;
4030+ let message = prepare_who_polls (
4031+ & self . isupport ,
4032+ & self . capabilities ,
4033+ who_poll,
4034+ ) ;
39964035
39974036 self . send ( None , message. into ( ) , TokenPriority :: Low ) ;
39984037 }
@@ -4163,6 +4202,39 @@ fn compare_channels_default(chantypes: &[char], a: &str, b: &str) -> Ordering {
41634202 a. cmp ( b)
41644203}
41654204
4205+ fn prepare_who_polls (
4206+ isupport : & HashMap < isupport:: Kind , isupport:: Parameter > ,
4207+ capabilities : & Capabilities ,
4208+ who_poll : & mut WhoPoll ,
4209+ ) -> irc:: proto:: Message {
4210+ if isupport. contains_key ( & isupport:: Kind :: WHOX ) {
4211+ let whox_params =
4212+ if capabilities. acknowledged ( Capability :: AccountNotify ) {
4213+ WhoXPollParameters :: WithAccountName
4214+ } else {
4215+ WhoXPollParameters :: Default
4216+ } ;
4217+
4218+ who_poll. status = WhoStatus :: Requested (
4219+ WhoSource :: Poll ,
4220+ Instant :: now ( ) ,
4221+ Some ( whox_params. token ( ) ) ,
4222+ ) ;
4223+
4224+ command ! (
4225+ "WHO" ,
4226+ who_poll. channel. to_string( ) ,
4227+ whox_params. fields( ) . to_string( ) ,
4228+ whox_params. token( ) . to_owned( )
4229+ )
4230+ } else {
4231+ who_poll. status =
4232+ WhoStatus :: Requested ( WhoSource :: Poll , Instant :: now ( ) , None ) ;
4233+
4234+ command ! ( "WHO" , who_poll. channel. to_string( ) )
4235+ }
4236+ }
4237+
41664238fn compare_channels (
41674239 config : & config:: server:: Server ,
41684240 chantypes : & [ char ] ,
0 commit comments