diff --git a/client/connection.go b/client/connection.go index cd2598e..fbbbf65 100644 --- a/client/connection.go +++ b/client/connection.go @@ -208,7 +208,9 @@ func (conn *Conn) runLoop() { for { select { case line := <-conn.in: - conn.dispatchEvent(line) + if line != nil { + conn.dispatchEvent(line) + } case <-conn.cLoop: // strobe on control channel, bail out return diff --git a/client/handlers.go b/client/handlers.go index 3359ce0..19af1fd 100644 --- a/client/handlers.go +++ b/client/handlers.go @@ -30,36 +30,6 @@ func (conn *Conn) AddHandler(name string, f func(*Conn, *Line)) { // loops through all event handlers for line.Cmd, running each in a goroutine func (conn *Conn) dispatchEvent(line *Line) { - // seems that we end up dispatching an event with a nil line when receiving - // EOF from the server. Until i've tracked down why.... - if line == nil { - conn.error("irc.dispatchEvent(): buh? line == nil :-(") - return - } - - // So, I think CTCP and (in particular) CTCP ACTION are better handled as - // separate events as opposed to forcing people to have gargantuan PRIVMSG - // handlers to cope with the possibilities. - if line.Cmd == "PRIVMSG" && - len(line.Args[1]) > 2 && - strings.HasPrefix(line.Args[1], "\001") && - strings.HasSuffix(line.Args[1], "\001") { - // WOO, it's a CTCP message - t := strings.Split(strings.Trim(line.Args[1], "\001"), " ", 2) - if len(t) > 1 { - // Replace the line with the unwrapped CTCP - line.Args[1] = t[1] - } - if c := strings.ToUpper(t[0]); c == "ACTION" { - // make a CTCP ACTION it's own event a-la PRIVMSG - line.Cmd = c - } else { - // otherwise, dispatch a generic CTCP event that - // contains the type of CTCP in line.Args[0] - line.Cmd = "CTCP" - line.Args = append([]string{c}, line.Args...) - } - } conn.Registry.Dispatch(line.Cmd, conn, line) } diff --git a/client/line.go b/client/line.go index eaf3484..313d542 100644 --- a/client/line.go +++ b/client/line.go @@ -51,6 +51,30 @@ func parseLine(s string) *Line { if len(args) > 1 { line.Args = args[1:] } + + // So, I think CTCP and (in particular) CTCP ACTION are better handled as + // separate events as opposed to forcing people to have gargantuan PRIVMSG + // handlers to cope with the possibilities. + if line.Cmd == "PRIVMSG" && + len(line.Args[1]) > 2 && + strings.HasPrefix(line.Args[1], "\001") && + strings.HasSuffix(line.Args[1], "\001") { + // WOO, it's a CTCP message + t := strings.Split(strings.Trim(line.Args[1], "\001"), " ", 2) + if len(t) > 1 { + // Replace the line with the unwrapped CTCP + line.Args[1] = t[1] + } + if c := strings.ToUpper(t[0]); c == "ACTION" { + // make a CTCP ACTION it's own event a-la PRIVMSG + line.Cmd = c + } else { + // otherwise, dispatch a generic CTCP event that + // contains the type of CTCP in line.Args[0] + line.Cmd = "CTCP" + line.Args = append([]string{c}, line.Args...) + } + } return line }