diff options
Diffstat (limited to 'irc/session.go')
-rw-r--r-- | irc/session.go | 48 |
1 files changed, 42 insertions, 6 deletions
diff --git a/irc/session.go b/irc/session.go index e0421a7..201f50c 100644 --- a/irc/session.go +++ b/irc/session.go @@ -57,7 +57,8 @@ var SupportedCapabilities = map[string]struct{}{ "sasl": {}, "setname": {}, - "draft/chathistory": {}, + "draft/chathistory": {}, + "soju.im/bouncer-networks": {}, } // Values taken by the "@+typing=" client tag. TypingUnspec means the value or @@ -91,8 +92,8 @@ type SessionParams struct { Nickname string Username string RealName string - - Auth SASLClient + NetID string + Auth SASLClient } type Session struct { @@ -108,6 +109,7 @@ type Session struct { real string acct string host string + netID string auth SASLClient availableCaps map[string]string @@ -138,6 +140,7 @@ func NewSession(out chan<- Message, params SessionParams) *Session { nickCf: CasemapASCII(params.Nickname), user: params.Username, real: params.RealName, + netID: params.NetID, auth: params.Auth, availableCaps: map[string]string{}, enabledCaps: map[string]struct{}{}, @@ -180,6 +183,10 @@ func (s *Session) Nick() string { return s.nick } +func (s *Session) NetID() string { + return s.netID +} + // NickCf is our casemapped nickname. func (s *Session) NickCf() string { return s.nickCf @@ -486,10 +493,10 @@ func (s *Session) handleUnregistered(msg Message) (Event, error) { return nil, err } - s.out <- NewMessage("CAP", "END") + s.endRegistration() s.host = ParsePrefix(userhost).Host case errNicklocked, errSaslfail, errSasltoolong, errSaslaborted, errSaslalready, rplSaslmechs: - s.out <- NewMessage("CAP", "END") + s.endRegistration() case "CAP": var subcommand string if err := msg.ParseParams(nil, &subcommand); err != nil { @@ -525,7 +532,7 @@ func (s *Session) handleUnregistered(msg Message) (Event, error) { _, ok := s.availableCaps["sasl"] if s.auth == nil || !ok { - s.out <- NewMessage("CAP", "END") + s.endRegistration() } } default: @@ -1024,6 +1031,19 @@ func (s *Session) handleRegistered(msg Message) (Event, error) { FormerNick: msg.Prefix.Name, }, nil } + case "BOUNCER": + if len(msg.Params) < 3 { + break + } + if msg.Params[0] != "NETWORK" || s.netID != "" { + break + } + id := msg.Params[1] + attrs := parseTags(msg.Params[2]) + return BouncerNetworkEvent{ + ID: id, + Name: attrs["name"], + }, nil case "PING": var payload string if err := msg.ParseParams(&payload); err != nil { @@ -1137,6 +1157,8 @@ func (s *Session) updateFeatures(features []string) { Switch: switch key { + case "BOUNCER_NETID": + s.netID = value case "CASEMAPPING": switch value { case "ascii": @@ -1175,3 +1197,17 @@ func (s *Session) updateFeatures(features []string) { } } } + +func (s *Session) endRegistration() { + if _, ok := s.enabledCaps["soju.im/bouncer-networks"]; !ok { + s.out <- NewMessage("CAP", "END") + return + } + if s.netID == "" { + s.out <- NewMessage("CAP", "END") + s.out <- NewMessage("BOUNCER", "LISTNETWORKS") + } else { + s.out <- NewMessage("BOUNCER", "BIND", s.netID) + s.out <- NewMessage("CAP", "END") + } +} |