diff --git a/irc/client.go b/irc/client.go index 8ba36979..d3be21db 100644 --- a/irc/client.go +++ b/irc/client.go @@ -494,6 +494,14 @@ func (client *Client) LoggedIntoAccount() bool { return client.account != nil && client.account != &NoAccount } +// RplISupport outputs our ISUPPORT lines to the client. This is used on connection and in VERSION responses. +func (client *Client) RplISupport() { + for _, tokenline := range client.server.getISupport().CachedReply { + // ugly trickery ahead + client.Send(nil, client.server.name, RPL_ISUPPORT, append([]string{client.nick}, tokenline...)...) + } +} + // Quit sends the given quit message to the client (but does not destroy them). func (client *Client) Quit(message string) { client.quitMutex.Lock() diff --git a/irc/getters.go b/irc/getters.go index 3002471e..254a7119 100644 --- a/irc/getters.go +++ b/irc/getters.go @@ -3,7 +3,9 @@ package irc -func (server *Server) getISupport() *ISupportList { +import "github.com/oragono/oragono/irc/isupport" + +func (server *Server) getISupport() *isupport.List { server.configurableStateMutex.RLock() defer server.configurableStateMutex.RUnlock() return server.isupport diff --git a/irc/isupport.go b/irc/isupport/list.go similarity index 73% rename from irc/isupport.go rename to irc/isupport/list.go index 3e7b8edc..82f11f64 100644 --- a/irc/isupport.go +++ b/irc/isupport/list.go @@ -1,34 +1,37 @@ // Copyright (c) 2016 Daniel Oaks // released under the MIT license -package irc +package isupport import "fmt" import "sort" -const isupportSupportedString = "are supported by this server" +const ( + maxLastArgLength = 400 + supportedString = "are supported by this server" +) -// ISupportList holds a list of ISUPPORT tokens -type ISupportList struct { +// List holds a list of ISUPPORT tokens +type List struct { Tokens map[string]*string CachedReply [][]string } -// NewISupportList returns a new ISupportList -func NewISupportList() *ISupportList { - var il ISupportList +// NewList returns a new List +func NewList() *List { + var il List il.Tokens = make(map[string]*string) il.CachedReply = make([][]string, 0) return &il } // Add adds an RPL_ISUPPORT token to our internal list -func (il *ISupportList) Add(name string, value string) { +func (il *List) Add(name string, value string) { il.Tokens[name] = &value } // AddNoValue adds an RPL_ISUPPORT token that does not have a value -func (il *ISupportList) AddNoValue(name string) { +func (il *List) AddNoValue(name string) { il.Tokens[name] = nil } @@ -41,7 +44,7 @@ func getTokenString(name string, value *string) string { } // GetDifference returns the difference between two token lists. -func (il *ISupportList) GetDifference(newil *ISupportList) [][]string { +func (il *List) GetDifference(newil *List) [][]string { var outTokens sort.StringSlice // append removed tokens @@ -86,7 +89,7 @@ func (il *ISupportList) GetDifference(newil *ISupportList) [][]string { } if len(cache) == 13 || len(token)+length >= maxLastArgLength { - cache = append(cache, isupportSupportedString) + cache = append(cache, supportedString) replies = append(replies, cache) cache = make([]string, 0) length = 0 @@ -94,7 +97,7 @@ func (il *ISupportList) GetDifference(newil *ISupportList) [][]string { } if len(cache) > 0 { - cache = append(cache, isupportSupportedString) + cache = append(cache, supportedString) replies = append(replies, cache) } @@ -102,7 +105,7 @@ func (il *ISupportList) GetDifference(newil *ISupportList) [][]string { } // RegenerateCachedReply regenerates the cached RPL_ISUPPORT reply -func (il *ISupportList) RegenerateCachedReply() { +func (il *List) RegenerateCachedReply() { il.CachedReply = make([][]string, 0) var length int // Length of the current cache var cache []string // Token list cache @@ -127,7 +130,7 @@ func (il *ISupportList) RegenerateCachedReply() { } if len(cache) == 13 || len(token)+length >= maxLastArgLength { - cache = append(cache, isupportSupportedString) + cache = append(cache, supportedString) il.CachedReply = append(il.CachedReply, cache) cache = make([]string, 0) length = 0 @@ -135,15 +138,7 @@ func (il *ISupportList) RegenerateCachedReply() { } if len(cache) > 0 { - cache = append(cache, isupportSupportedString) + cache = append(cache, supportedString) il.CachedReply = append(il.CachedReply, cache) } } - -// RplISupport outputs our ISUPPORT lines to the client. This is used on connection and in VERSION responses. -func (client *Client) RplISupport() { - for _, tokenline := range client.server.getISupport().CachedReply { - // ugly trickery ahead - client.Send(nil, client.server.name, RPL_ISUPPORT, append([]string{client.nick}, tokenline...)...) - } -} diff --git a/irc/isupport_test.go b/irc/isupport/list_test.go similarity index 95% rename from irc/isupport_test.go rename to irc/isupport/list_test.go index 70c831f6..4c92313e 100644 --- a/irc/isupport_test.go +++ b/irc/isupport/list_test.go @@ -1,7 +1,7 @@ // Copyright (c) 2016 Daniel Oaks // released under the MIT license -package irc +package isupport import ( "reflect" @@ -10,7 +10,7 @@ import ( func TestISUPPORT(t *testing.T) { // create first list - tList1 := NewISupportList() + tList1 := NewList() tList1.Add("SASL", "yes") tList1.Add("CASEMAPPING", "rfc1459-strict") tList1.Add("INVEX", "i") @@ -24,7 +24,7 @@ func TestISUPPORT(t *testing.T) { } // create second list - tList2 := NewISupportList() + tList2 := NewList() tList2.Add("SASL", "yes") tList2.Add("CASEMAPPING", "ascii") tList2.AddNoValue("INVEX") diff --git a/irc/server.go b/irc/server.go index 17d5c871..f3273400 100644 --- a/irc/server.go +++ b/irc/server.go @@ -24,6 +24,7 @@ import ( "github.com/goshuirc/irc-go/ircfmt" "github.com/goshuirc/irc-go/ircmsg" "github.com/oragono/oragono/irc/caps" + "github.com/oragono/oragono/irc/isupport" "github.com/oragono/oragono/irc/logger" "github.com/oragono/oragono/irc/sno" "github.com/tidwall/buntdb" @@ -91,7 +92,7 @@ type Server struct { defaultChannelModes Modes dlines *DLineManager loggingRawIO bool - isupport *ISupportList + isupport *isupport.List klines *KLineManager limits Limits listeners map[string]*ListenerWrapper @@ -175,7 +176,7 @@ func (server *Server) setISupport() { server.configurableStateMutex.RLock() // add RPL_ISUPPORT tokens - isupport := NewISupportList() + isupport := isupport.NewList() isupport.Add("AWAYLEN", strconv.Itoa(server.limits.AwayLen)) isupport.Add("CASEMAPPING", casemappingName) isupport.Add("CHANMODES", strings.Join([]string{Modes{BanMask, ExceptMask, InviteMask}.String(), "", Modes{UserLimit, Key}.String(), Modes{InviteOnly, Moderated, NoOutside, OpOnlyTopic, ChanRoleplaying, Secret}.String()}, ","))