commit 1d85e0b
delthas
·
2022-09-02 11:44:31 +0000 UTC
parent 6ed5a57
Use WHOX rather than WHO when available This will reduce network usage and possibly increase WHO cache hit ratio on bouncers supporting a WHO cache.
2 files changed,
+25,
-5
+1,
-0
1@@ -43,6 +43,7 @@ const (
2 rplVersion = "351" // <version> <servername> :<comments>
3 rplWhoreply = "352" // <channel> <user> <host> <server> <nick> "H"/"G" ["*"] [("@"/"+")] :<hop count> <nick>
4 rplNamreply = "353" // <=/*/@> <channel> :1*(@/ /+user)
5+ rplWhospecialreply = "354" // [token] [channel] [user] [ip] [host] [server] [nick] [flags] [hopcount] [idle] [account] [oplevel] [:realname]
6 rplEndofnames = "366" // <channel> :End of names list
7 rplBanlist = "367" // <channel> <ban mask>
8 rplEndofbanlist = "368" // <channel> :End of ban list
+24,
-5
1@@ -134,6 +134,7 @@ type Session struct {
2 prefixSymbols string
3 prefixModes string
4 monitor bool
5+ whox bool
6
7 users map[string]*User // known users.
8 channels map[string]Channel // joined channels.
9@@ -359,6 +360,15 @@ func (s *Session) ChangeNick(nick string) {
10 s.out <- NewMessage("NICK", nick)
11 }
12
13+func (s *Session) Who(target string) {
14+ if s.whox {
15+ // only request what we need, to optimize server who cache hits and reduce traffic
16+ s.out <- NewMessage("WHO", target, "%uhnf")
17+ } else {
18+ s.out <- NewMessage("WHO", target)
19+ }
20+}
21+
22 func (s *Session) ChangeMode(channel, flags string, args []string) {
23 if flags != "" {
24 args = append([]string{channel, flags}, args...)
25@@ -693,7 +703,7 @@ func (s *Session) handleMessageRegistered(msg Message, playback bool) (Event, er
26 Name: s.nick, User: s.user, Host: s.host,
27 }}
28 if s.host == "" {
29- s.out <- NewMessage("WHO", s.nick)
30+ s.Who(s.nick)
31 }
32 case rplIsupport:
33 if len(msg.Params) < 3 {
34@@ -701,14 +711,21 @@ func (s *Session) handleMessageRegistered(msg Message, playback bool) (Event, er
35 }
36 s.updateFeatures(msg.Params[1 : len(msg.Params)-1])
37 return RegisteredEvent{}, nil
38- case rplWhoreply:
39+ case rplWhoreply, rplWhospecialreply:
40 var nick, host, flags, username string
41- if err := msg.ParseParams(nil, nil, &username, &host, nil, &nick, &flags, nil); err != nil {
42+ var err error
43+ if msg.Command == rplWhoreply {
44+ err = msg.ParseParams(nil, nil, &username, &host, nil, &nick, &flags, nil)
45+ } else {
46+ // we always request WHOX with %uhnf
47+ err = msg.ParseParams(nil, &username, &host, &nick, &flags)
48+ }
49+ if err != nil {
50 return nil, err
51 }
52
53 nickCf := s.Casemap(nick)
54- away := flags[0] == 'G' // flags is not empty because it's not the trailing parameter
55+ away := strings.ContainsRune(flags, 'G')
56
57 if s.nickCf == nickCf {
58 s.user = username
59@@ -794,7 +811,7 @@ func (s *Session) handleMessageRegistered(msg Message, playback bool) (Event, er
60 // Only try to know who is away if the list is
61 // updated by the server via away-notify.
62 // Otherwise, it'll become outdated over time.
63- s.out <- NewMessage("WHO", channel)
64+ s.Who(channel)
65 }
66 } else if c, ok := s.channels[channelCf]; ok {
67 if _, ok := s.users[nickCf]; !ok {
68@@ -1525,6 +1542,8 @@ func (s *Session) updateFeatures(features []string) {
69 numPrefixes := len(value)/2 - 1
70 s.prefixModes = value[1 : numPrefixes+1]
71 s.prefixSymbols = value[numPrefixes+2:]
72+ case "WHOX":
73+ s.whox = true
74 }
75 }
76 }