123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146 |
- // Copyright (c) 2016 Daniel Oaks <daniel@danieloaks.net>
- // released under the MIT license
-
- package irc
-
- import "fmt"
-
- const isupportSupportedString = "are supported by this server"
-
- // ISupportList holds a list of ISUPPORT tokens
- type ISupportList struct {
- Tokens map[string]*string
- CachedReply [][]string
- }
-
- // NewISupportList returns a new ISupportList
- func NewISupportList() *ISupportList {
- var il ISupportList
- 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) {
- il.Tokens[name] = &value
- }
-
- // AddNoValue adds an RPL_ISUPPORT token that does not have a value
- func (il *ISupportList) AddNoValue(name string) {
- il.Tokens[name] = nil
- }
-
- // getTokenString gets the appropriate string for a token+value.
- func getTokenString(name string, value *string) string {
- if value == nil {
- return name
- }
- return fmt.Sprintf("%s=%s", name, *value)
- }
-
- // GetDifference returns the difference between two token lists.
- func (il *ISupportList) GetDifference(newil *ISupportList) [][]string {
- replies := make([][]string, 0)
- var length int // Length of the current cache
- var cache []string // Token list cache
-
- // append removed tokens
- for name := range il.Tokens {
- _, exists := newil.Tokens[name]
- if exists {
- continue
- }
-
- token := fmt.Sprintf("-%s", name)
-
- if len(token)+length <= maxLastArgLength {
- // account for the space separating tokens
- if len(cache) > 0 {
- length++
- }
- cache = append(cache, token)
- length += len(token)
- }
-
- if len(cache) == 13 || len(token)+length >= maxLastArgLength {
- cache = append(cache, isupportSupportedString)
- replies = append(replies, cache)
- cache = make([]string, 0)
- length = 0
- }
- }
-
- // append added tokens
- for name, value := range newil.Tokens {
- newval, exists := il.Tokens[name]
- if exists && *value == *newval {
- continue
- }
-
- token := getTokenString(name, value)
-
- if len(token)+length <= maxLastArgLength {
- // account for the space separating tokens
- if len(cache) > 0 {
- length++
- }
- cache = append(cache, token)
- length += len(token)
- }
-
- if len(cache) == 13 || len(token)+length >= maxLastArgLength {
- cache = append(cache, isupportSupportedString)
- replies = append(replies, cache)
- cache = make([]string, 0)
- length = 0
- }
- }
-
- if len(cache) > 0 {
- cache = append(cache, isupportSupportedString)
- replies = append(replies, cache)
- }
-
- return replies
- }
-
- // RegenerateCachedReply regenerates the cached RPL_ISUPPORT reply
- func (il *ISupportList) RegenerateCachedReply() {
- il.CachedReply = make([][]string, 0)
- var length int // Length of the current cache
- var cache []string // Token list cache
-
- for name, value := range il.Tokens {
- token := getTokenString(name, value)
-
- if len(token)+length <= maxLastArgLength {
- // account for the space separating tokens
- if len(cache) > 0 {
- length++
- }
- cache = append(cache, token)
- length += len(token)
- }
-
- if len(cache) == 13 || len(token)+length >= maxLastArgLength {
- cache = append(cache, isupportSupportedString)
- il.CachedReply = append(il.CachedReply, cache)
- cache = make([]string, 0)
- length = 0
- }
- }
-
- if len(cache) > 0 {
- cache = append(cache, isupportSupportedString)
- 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.isupport.CachedReply {
- // ugly trickery ahead
- client.Send(nil, client.server.name, RPL_ISUPPORT, append([]string{client.nick}, tokenline...)...)
- }
- }
|