summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordelthas <delthas@dille.cc>2022-09-02 13:44:31 +0200
committerdelthas <delthas@dille.cc>2022-09-02 13:44:31 +0200
commit1d85e0b51ff3921a5b1f7a9577149b86874eeea6 (patch)
treee97a32012a6b7185d21505f317d1df0f015fcf0f
parentAlways show the date of the top message (diff)
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.
-rw-r--r--irc/rpl.go1
-rw-r--r--irc/session.go29
2 files changed, 25 insertions, 5 deletions
diff --git a/irc/rpl.go b/irc/rpl.go
index 398b5b3..1e50938 100644
--- a/irc/rpl.go
+++ b/irc/rpl.go
@@ -43,6 +43,7 @@ const (
rplVersion = "351" // <version> <servername> :<comments>
rplWhoreply = "352" // <channel> <user> <host> <server> <nick> "H"/"G" ["*"] [("@"/"+")] :<hop count> <nick>
rplNamreply = "353" // <=/*/@> <channel> :1*(@/ /+user)
+ rplWhospecialreply = "354" // [token] [channel] [user] [ip] [host] [server] [nick] [flags] [hopcount] [idle] [account] [oplevel] [:realname]
rplEndofnames = "366" // <channel> :End of names list
rplBanlist = "367" // <channel> <ban mask>
rplEndofbanlist = "368" // <channel> :End of ban list
diff --git a/irc/session.go b/irc/session.go
index 0776436..3a6d4e1 100644
--- a/irc/session.go
+++ b/irc/session.go
@@ -134,6 +134,7 @@ type Session struct {
prefixSymbols string
prefixModes string
monitor bool
+ whox bool
users map[string]*User // known users.
channels map[string]Channel // joined channels.
@@ -359,6 +360,15 @@ func (s *Session) ChangeNick(nick string) {
s.out <- NewMessage("NICK", nick)
}
+func (s *Session) Who(target string) {
+ if s.whox {
+ // only request what we need, to optimize server who cache hits and reduce traffic
+ s.out <- NewMessage("WHO", target, "%uhnf")
+ } else {
+ s.out <- NewMessage("WHO", target)
+ }
+}
+
func (s *Session) ChangeMode(channel, flags string, args []string) {
if flags != "" {
args = append([]string{channel, flags}, args...)
@@ -693,7 +703,7 @@ func (s *Session) handleMessageRegistered(msg Message, playback bool) (Event, er
Name: s.nick, User: s.user, Host: s.host,
}}
if s.host == "" {
- s.out <- NewMessage("WHO", s.nick)
+ s.Who(s.nick)
}
case rplIsupport:
if len(msg.Params) < 3 {
@@ -701,14 +711,21 @@ func (s *Session) handleMessageRegistered(msg Message, playback bool) (Event, er
}
s.updateFeatures(msg.Params[1 : len(msg.Params)-1])
return RegisteredEvent{}, nil
- case rplWhoreply:
+ case rplWhoreply, rplWhospecialreply:
var nick, host, flags, username string
- if err := msg.ParseParams(nil, nil, &username, &host, nil, &nick, &flags, nil); err != nil {
+ var err error
+ if msg.Command == rplWhoreply {
+ err = msg.ParseParams(nil, nil, &username, &host, nil, &nick, &flags, nil)
+ } else {
+ // we always request WHOX with %uhnf
+ err = msg.ParseParams(nil, &username, &host, &nick, &flags)
+ }
+ if err != nil {
return nil, err
}
nickCf := s.Casemap(nick)
- away := flags[0] == 'G' // flags is not empty because it's not the trailing parameter
+ away := strings.ContainsRune(flags, 'G')
if s.nickCf == nickCf {
s.user = username
@@ -794,7 +811,7 @@ func (s *Session) handleMessageRegistered(msg Message, playback bool) (Event, er
// Only try to know who is away if the list is
// updated by the server via away-notify.
// Otherwise, it'll become outdated over time.
- s.out <- NewMessage("WHO", channel)
+ s.Who(channel)
}
} else if c, ok := s.channels[channelCf]; ok {
if _, ok := s.users[nickCf]; !ok {
@@ -1525,6 +1542,8 @@ func (s *Session) updateFeatures(features []string) {
numPrefixes := len(value)/2 - 1
s.prefixModes = value[1 : numPrefixes+1]
s.prefixSymbols = value[numPrefixes+2:]
+ case "WHOX":
+ s.whox = true
}
}
}