Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Issue 75: IMPLEMENT NAMES sendraw and 353 and 366 callbacks #76

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions irc.go
Original file line number Diff line number Diff line change
Expand Up @@ -307,6 +307,16 @@ func (irc *Connection) GetNick() string {
return irc.nickcurrent
}

// Query information about all nicks on a specific channel
// RFC 2812 details: https://tools.ietf.org/html/rfc2812#section-3.2.5
// Callback for 353 and 366 is what reads the info trigered by this into two
// gobal maps. NickChanMap which is a map of irc channnels to golang chan []string
// channels, and a NickChanState which is a map of irc channels to []string of
// the resulting nicks
func (irc *Connection) GetNicksOnChan(channel string) {
irc.SendRawf(fmt.Sprintf("NAMES %s", channel))
}

// Query information about a particular nickname.
// RFC 1459: https://tools.ietf.org/html/rfc1459#section-4.5.2
func (irc *Connection) Whois(nick string) {
Expand Down
58 changes: 58 additions & 0 deletions irc_callback.go
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
package irc

import (
"regexp"
"strconv"
"strings"
"time"
)

var NickChanMap = map[string]chan []string{}
var NickChanState = map[string][]string{}

// Register a callback to a connection and event code. A callback is a function
// which takes only an Event pointer as parameter. Valid event codes are all
// IRC/CTCP commands and error/response codes. This function returns the ID of
Expand Down Expand Up @@ -218,4 +222,58 @@ func (irc *Connection) setupCallbacks() {
irc.AddCallback("001", func(e *Event) {
irc.nickcurrent = e.Arguments[0]
})

// 353: RPL_NAMEREPLY per RFC1459
// will typically receive this on channel joins and when NAMES is
// called via GetNicksOnCHan
irc.AddCallback("353", func(e *Event) {
// get chan
re := regexp.MustCompile(`#\S+\s`)
channelName := re.FindString(e.Raw)
// check if chan exists in map
_, ok := NickChanMap[channelName]

// if not make one
if ok != true {
ch := make(chan []string, 1000)
NickChanMap[channelName] = ch
}
// split the datat into a slice
data := strings.Split(e.Message(), " ")

// then send
NickChanMap[channelName] <- data
})

// 363: RPL_ENDOFNAMES per RFC1459
// will receive this so we know that no more 353s are coming
irc.AddCallback("366", func(e *Event) {
go func(e *Event) {
// get chan
re := regexp.MustCompile(`#\S+\s`)
channelName := re.FindString(e.Raw)
// if channel doesn't exist return
c, ok := NickChanMap[channelName]
if ok != true {
return
}
// Note, callback 353 is not in a goroutine on purpose
// to prevent chance of channel being closed
// prematurely
close(c) // there's probably a more elegant way to do this
// append list of names
var theList []string
for r := range c {
theList = append(theList, r...)
}
// reset the channel with a new one since we closed the other
// one
ch := make(chan []string, 1000)
NickChanMap[channelName] = ch
// add theList of nicks to a global state var
NickChanState[channelName] = theList

}(e)
})

}