Changeset 350 in code


Ignore:
Timestamp:
Jul 6, 2020, 9:06:20 AM (5 years ago)
Author:
contact
Message:

Sort and split JOIN messages

Sort channels so that channels with a key appear first. Split JOIN
messages so that we don't reach the message size limit.

Location:
trunk
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/irc.go

    r346 r350  
    33import (
    44        "fmt"
     5        "sort"
    56        "strings"
    67
     
    1819
    1920const maxMessageLength = 512
     21
     22// The server-time layout, as defined in the IRCv3 spec.
     23const serverTimeLayout = "2006-01-02T15:04:05.000Z"
    2024
    2125type userModes string
     
    294298}
    295299
    296 // The server-time layout, as defined in the IRCv3 spec.
    297 const serverTimeLayout = "2006-01-02T15:04:05.000Z"
     300func join(channels, keys []string) []*irc.Message {
     301        // Put channels with a key first
     302        js := joinSorter{channels, keys}
     303        sort.Sort(&js)
     304
     305        // Two spaces because there are three words (JOIN, channels and keys)
     306        maxLength := maxMessageLength - (len("JOIN") + 2)
     307
     308        var msgs []*irc.Message
     309        var channelsBuf, keysBuf strings.Builder
     310        for i, channel := range channels {
     311                key := keys[i]
     312
     313                n := channelsBuf.Len() + keysBuf.Len() + 1 + len(channel)
     314                if key != "" {
     315                        n += 1 + len(key)
     316                }
     317
     318                if channelsBuf.Len() > 0 && n > maxLength {
     319                        // No room for the new channel in this message
     320                        params := []string{channelsBuf.String()}
     321                        if keysBuf.Len() > 0 {
     322                                params = append(params, keysBuf.String())
     323                        }
     324                        msgs = append(msgs, &irc.Message{Command: "JOIN", Params: params})
     325                        channelsBuf.Reset()
     326                        keysBuf.Reset()
     327                }
     328
     329                if channelsBuf.Len() > 0 {
     330                        channelsBuf.WriteByte(',')
     331                }
     332                channelsBuf.WriteString(channel)
     333                if key != "" {
     334                        if keysBuf.Len() > 0 {
     335                                keysBuf.WriteByte(',')
     336                        }
     337                        keysBuf.WriteString(key)
     338                }
     339        }
     340        if channelsBuf.Len() > 0 {
     341                params := []string{channelsBuf.String()}
     342                if keysBuf.Len() > 0 {
     343                        params = append(params, keysBuf.String())
     344                }
     345                msgs = append(msgs, &irc.Message{Command: "JOIN", Params: params})
     346        }
     347
     348        return msgs
     349}
     350
     351type joinSorter struct {
     352        channels []string
     353        keys     []string
     354}
     355
     356func (js *joinSorter) Len() int {
     357        return len(js.channels)
     358}
     359
     360func (js *joinSorter) Less(i, j int) bool {
     361        if (js.keys[i] != "") != (js.keys[j] != "") {
     362                // Only one of the channels has a key
     363                return js.keys[i] != ""
     364        }
     365        return js.channels[i] < js.channels[j]
     366}
     367
     368func (js *joinSorter) Swap(i, j int) {
     369        js.channels[i], js.channels[j] = js.channels[j], js.channels[i]
     370        js.keys[i], js.keys[j] = js.keys[j], js.keys[i]
     371}
  • trunk/upstream.go

    r343 r350  
    554554
    555555                if len(uc.network.channels) > 0 {
    556                         // TODO: split this into multiple messages if need be
    557                         var names, keys []string
     556                        var channels, keys []string
    558557                        for _, ch := range uc.network.channels {
    559                                 names = append(names, ch.Name)
     558                                channels = append(channels, ch.Name)
    560559                                keys = append(keys, ch.Key)
    561560                        }
    562                         uc.SendMessage(&irc.Message{
    563                                 Command: "JOIN",
    564                                 Params: []string{
    565                                         strings.Join(names, ","),
    566                                         strings.Join(keys, ","),
    567                                 },
    568                         })
     561
     562                        for _, msg := range join(channels, keys) {
     563                                uc.SendMessage(msg)
     564                        }
    569565                }
    570566        case irc.RPL_MYINFO:
Note: See TracChangeset for help on using the changeset viewer.