package irc // this file contains the basic set of event handlers // to manage tracking an irc connection etc. import ( "fmt"; "strings"; ) // Add an event handler for a specific IRC command func (conn *IRCConn) AddHandler(name string, f func (*IRCConn, *IRCLine)) { n := strings.ToUpper(name); if e, ok := conn.events[n]; ok { if len(e) == cap(e) { // crap, we're full. expand e by another 10 handler slots ne := make([]func (*IRCConn, *IRCLine), len(e), len(e)+10); for i := 0; i 2 && line.Text[0] == '\001' && line.Text[len(line.Text)-1] == '\001' { // WOO, it's a CTCP message t := strings.Split(line.Text[1:len(line.Text)-1], " ", 2); 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"; a := make([]string, len(line.Args)+1); a[0] = c; for i:=0; i 1 { // for some CTCP messages this could make more sense // in line.Args[], but meh. MEH, I say. line.Text = t[1]; } } if funcs, ok := conn.events[line.Cmd]; ok { for _, f := range funcs { go f(conn, line) } } } // sets up the internal event handlers to do useful things with lines // XXX: is there a better way of doing this? func (conn *IRCConn) setupEvents() { // Basic ping/pong handler conn.AddHandler("PING", func(conn *IRCConn, line *IRCLine) { conn.send(fmt.Sprintf("PONG :%s", line.Text)); }); // Handler to trigger a "CONNECTED" event on receipt of numeric 001 conn.AddHandler("001", func(conn *IRCConn, line *IRCLine) { l := new(IRCLine); l.Cmd = "CONNECTED"; conn.dispatchEvent(l); }); // Handler to deal with "433 :Nickname already in use" on connection conn.AddHandler("433", func(conn *IRCConn, line *IRCLine) { conn.Nick(conn.Me + "_"); }); }