diff --git a/client/commands.go b/client/commands.go index 0f58109..594cb5b 100644 --- a/client/commands.go +++ b/client/commands.go @@ -6,6 +6,28 @@ const ( INIT = "init" CONNECTED = "connected" DISCONNECTED = "disconnected" + ACTION = "ACTION" + AWAY = "AWAY" + CTCP = "CTCP" + CTCPREPLY = "CTCPREPLY" + INVITE = "INVITE" + JOIN = "JOIN" + KICK = "KICK" + MODE = "MODE" + NICK = "NICK" + NOTICE = "NOTICE" + OPER = "OPER" + PART = "PART" + PASS = "PASS" + PING = "PING" + PONG = "PONG" + PRIVMSG = "PRIVMSG" + QUIT = "QUIT" + TOPIC = "TOPIC" + USER = "USER" + VERSION = "VERSION" + WHO = "WHO" + WHOIS = "WHOIS" ) // this file contains the various commands you can @@ -20,18 +42,18 @@ const ( func (conn *Conn) Raw(rawline string) { conn.out <- rawline } // Pass() sends a PASS command to the server -func (conn *Conn) Pass(password string) { conn.out <- "PASS " + password } +func (conn *Conn) Pass(password string) { conn.out <- PASS + " " + password } // Nick() sends a NICK command to the server -func (conn *Conn) Nick(nick string) { conn.out <- "NICK " + nick } +func (conn *Conn) Nick(nick string) { conn.out <- NICK + " " + nick } // User() sends a USER command to the server func (conn *Conn) User(ident, name string) { - conn.out <- "USER " + ident + " 12 * :" + name + conn.out <- USER + " " + ident + " 12 * :" + name } // Join() sends a JOIN command to the server -func (conn *Conn) Join(channel string) { conn.out <- "JOIN " + channel } +func (conn *Conn) Join(channel string) { conn.out <- JOIN + " " + channel } // Part() sends a PART command to the server with an optional part message func (conn *Conn) Part(channel string, message ...string) { @@ -39,7 +61,7 @@ func (conn *Conn) Part(channel string, message ...string) { if msg != "" { msg = " :" + msg } - conn.out <- "PART " + channel + msg + conn.out <- PART + " " + channel + msg } // Kick() sends a KICK command to remove a nick from a channel @@ -48,7 +70,7 @@ func (conn *Conn) Kick(channel, nick string, message ...string) { if msg != "" { msg = " :" + msg } - conn.out <- "KICK " + channel + " " + nick + msg + conn.out <- KICK + " " + channel + " " + nick + msg } // Quit() sends a QUIT command to the server with an optional quit message @@ -57,20 +79,20 @@ func (conn *Conn) Quit(message ...string) { if msg == "" { msg = "GoBye!" } - conn.out <- "QUIT :" + msg + conn.out <- QUIT + " :" + msg } // Whois() sends a WHOIS command to the server -func (conn *Conn) Whois(nick string) { conn.out <- "WHOIS " + nick } +func (conn *Conn) Whois(nick string) { conn.out <- WHOIS + " " + nick } //Who() sends a WHO command to the server -func (conn *Conn) Who(nick string) { conn.out <- "WHO " + nick } +func (conn *Conn) Who(nick string) { conn.out <- WHO + " " + nick } // Privmsg() sends a PRIVMSG to the target t -func (conn *Conn) Privmsg(t, msg string) { conn.out <- "PRIVMSG " + t + " :" + msg } +func (conn *Conn) Privmsg(t, msg string) { conn.out <- PRIVMSG + " " + t + " :" + msg } // Notice() sends a NOTICE to the target t -func (conn *Conn) Notice(t, msg string) { conn.out <- "NOTICE " + t + " :" + msg } +func (conn *Conn) Notice(t, msg string) { conn.out <- NOTICE + " " + t + " :" + msg } // Ctcp() sends a (generic) CTCP message to the target t // with an optional argument @@ -93,10 +115,10 @@ func (conn *Conn) CtcpReply(t, ctcp string, arg ...string) { } // Version() sends a CTCP "VERSION" to the target t -func (conn *Conn) Version(t string) { conn.Ctcp(t, "VERSION") } +func (conn *Conn) Version(t string) { conn.Ctcp(t, VERSION) } // Action() sends a CTCP "ACTION" to the target t -func (conn *Conn) Action(t, msg string) { conn.Ctcp(t, "ACTION", msg) } +func (conn *Conn) Action(t, msg string) { conn.Ctcp(t, ACTION, msg) } // Topic() sends a TOPIC command to the channel // Topic(channel) retrieves the current channel topic (see "332" handler) @@ -106,7 +128,7 @@ func (conn *Conn) Topic(channel string, topic ...string) { if t != "" { t = " :" + t } - conn.out <- "TOPIC " + channel + t + conn.out <- TOPIC + " " + channel + t } // Mode() sends a MODE command to the server. This one can get complicated if @@ -121,7 +143,7 @@ func (conn *Conn) Mode(t string, modestring ...string) { if mode != "" { mode = " " + mode } - conn.out <- "MODE " + t + mode + conn.out <- MODE + " " + t + mode } // Away() sends an AWAY command to the server @@ -132,15 +154,18 @@ func (conn *Conn) Away(message ...string) { if msg != "" { msg = " :" + msg } - conn.out <- "AWAY" + msg + conn.out <- AWAY + msg } // Invite() sends an INVITE command to the server -func (conn *Conn) Invite(nick, channel string) { - conn.out <- "INVITE " + nick + " " + channel -} +func (conn *Conn) Invite(nick, channel string) { conn.out <- INVITE + " " + nick + " " + channel } // Oper() sends an OPER command to the server -func (conn *Conn) Oper(user, pass string) { - conn.out <- "OPER " + user + " " + pass -} +func (conn *Conn) Oper(user, pass string) { conn.out <- OPER + " " + user + " " + pass } + +// Ping() sends a PING command to the server +// A PONG response is to be expected afterwards +func (conn *Conn) Ping(message string) { conn.out <- PING + " :" + message } + +// Ping() sends a PONG command to the server +func (conn *Conn) Pong(message string) { conn.out <- PONG + " :" + message } diff --git a/client/commands_test.go b/client/commands_test.go index c3bb6ee..05650e3 100644 --- a/client/commands_test.go +++ b/client/commands_test.go @@ -75,4 +75,10 @@ func TestClientCommands(t *testing.T) { c.Oper("user", "pass") s.nc.Expect("OPER user pass") + + c.Ping("woot") + s.nc.Expect("PING :woot") + + c.Pong("pwoot") + s.nc.Expect("PONG :pwoot") } diff --git a/client/connection.go b/client/connection.go index f66f3c5..e1128a2 100644 --- a/client/connection.go +++ b/client/connection.go @@ -236,7 +236,7 @@ func (conn *Conn) ping() { for { select { case <-tick.C: - conn.Raw(fmt.Sprintf("PING :%d", time.Now().UnixNano())) + conn.Ping(fmt.Sprintf("%d", time.Now().UnixNano())) case <-conn.cPing: tick.Stop() return diff --git a/client/handlers.go b/client/handlers.go index 9e1c41b..5d017be 100644 --- a/client/handlers.go +++ b/client/handlers.go @@ -9,12 +9,12 @@ import ( // sets up the internal event handlers to do essential IRC protocol things var intHandlers = map[string]HandlerFunc{ - INIT: (*Conn).h_init, - "001": (*Conn).h_001, - "433": (*Conn).h_433, - "CTCP": (*Conn).h_CTCP, - "NICK": (*Conn).h_NICK, - "PING": (*Conn).h_PING, + INIT: (*Conn).h_init, + "001": (*Conn).h_001, + "433": (*Conn).h_433, + CTCP: (*Conn).h_CTCP, + NICK: (*Conn).h_NICK, + PING: (*Conn).h_PING, } func (conn *Conn) addIntHandlers() { @@ -36,7 +36,7 @@ func (conn *Conn) h_init(line *Line) { // Basic ping/pong handler func (conn *Conn) h_PING(line *Line) { - conn.Raw("PONG :" + line.Args[0]) + conn.Pong(line.Args[0]) } // Handler to trigger a "CONNECTED" event on receipt of numeric 001 @@ -80,10 +80,10 @@ func (conn *Conn) h_433(line *Line) { // Handle VERSION requests and CTCP PING func (conn *Conn) h_CTCP(line *Line) { - if line.Args[0] == "VERSION" { - conn.CtcpReply(line.Nick, "VERSION", "powered by goirc...") - } else if line.Args[0] == "PING" { - conn.CtcpReply(line.Nick, "PING", line.Args[2]) + if line.Args[0] == VERSION { + conn.CtcpReply(line.Nick, VERSION, "powered by goirc...") + } else if line.Args[0] == PING { + conn.CtcpReply(line.Nick, PING, line.Args[2]) } } diff --git a/client/line.go b/client/line.go index 706d373..b29a8fe 100644 --- a/client/line.go +++ b/client/line.go @@ -62,7 +62,7 @@ func parseLine(s string) *Line { // So, I think CTCP and (in particular) CTCP ACTION are better handled as // separate events as opposed to forcing people to have gargantuan // handlers to cope with the possibilities. - if (line.Cmd == "PRIVMSG" || line.Cmd == "NOTICE") && + if (line.Cmd == PRIVMSG || line.Cmd == NOTICE) && len(line.Args[1]) > 2 && strings.HasPrefix(line.Args[1], "\001") && strings.HasSuffix(line.Args[1], "\001") { @@ -72,16 +72,16 @@ func parseLine(s string) *Line { // Replace the line with the unwrapped CTCP line.Args[1] = t[1] } - if c := strings.ToUpper(t[0]); c == "ACTION" && line.Cmd == "PRIVMSG" { + if c := strings.ToUpper(t[0]); c == ACTION && line.Cmd == PRIVMSG { // make a CTCP ACTION it's own event a-la PRIVMSG line.Cmd = c } else { // otherwise, dispatch a generic CTCP/CTCPREPLY event that // contains the type of CTCP in line.Args[0] - if line.Cmd == "PRIVMSG" { - line.Cmd = "CTCP" + if line.Cmd == PRIVMSG { + line.Cmd = CTCP } else { - line.Cmd = "CTCPREPLY" + line.Cmd = CTCPREPLY } line.Args = append([]string{c}, line.Args...) } diff --git a/client/state_handlers.go b/client/state_handlers.go index ffc9211..380f760 100644 --- a/client/state_handlers.go +++ b/client/state_handlers.go @@ -9,19 +9,19 @@ import ( ) var stHandlers = map[string]HandlerFunc{ - "JOIN": (*Conn).h_JOIN, - "KICK": (*Conn).h_KICK, - "MODE": (*Conn).h_MODE, - "NICK": (*Conn).h_STNICK, - "PART": (*Conn).h_PART, - "QUIT": (*Conn).h_QUIT, - "TOPIC": (*Conn).h_TOPIC, - "311": (*Conn).h_311, - "324": (*Conn).h_324, - "332": (*Conn).h_332, - "352": (*Conn).h_352, - "353": (*Conn).h_353, - "671": (*Conn).h_671, + JOIN: (*Conn).h_JOIN, + KICK: (*Conn).h_KICK, + MODE: (*Conn).h_MODE, + NICK: (*Conn).h_STNICK, + PART: (*Conn).h_PART, + QUIT: (*Conn).h_QUIT, + TOPIC: (*Conn).h_TOPIC, + "311": (*Conn).h_311, + "324": (*Conn).h_324, + "332": (*Conn).h_332, + "352": (*Conn).h_352, + "353": (*Conn).h_353, + "671": (*Conn).h_671, } func (conn *Conn) addSTHandlers() {