From af22c0a64cc0138912d880abcd4145a9f97de263 Mon Sep 17 00:00:00 2001 From: Liam Stanley Date: Sun, 5 Feb 2017 07:09:48 -0500 Subject: [PATCH] remove unneeded c.IsConnected() checks; implement Whois(), Ping(), Pong(), Oper(), Kick(), Invite(), Away(), Back(), and List() --- client.go | 175 ++++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 129 insertions(+), 46 deletions(-) diff --git a/client.go b/client.go index 99c4cf4..8e49b8a 100644 --- a/client.go +++ b/client.go @@ -455,10 +455,6 @@ func (c *Client) GetNick() (nick string) { // Nick changes the client nickname. func (c *Client) Nick(name string) error { - if !c.IsConnected() { - return ErrNotConnected - } - if !IsValidNick(name) { return &ErrInvalidTarget{Target: name} } @@ -472,7 +468,7 @@ func (c *Client) Nick(name string) error { } // Channels returns the active list of channels that the client is in. -// Returns nil if tracking is disabled. +// Panics if tracking is disabled. func (c *Client) Channels() []string { if c.Config.DisableTracking { panic("Channels() used when tracking is disabled") @@ -491,8 +487,13 @@ func (c *Client) Channels() []string { return channels } -// IsInChannel returns true if the client is in channel. +// IsInChannel returns true if the client is in channel. Panics if tracking +// is disabled. func (c *Client) IsInChannel(channel string) bool { + if c.Config.DisableTracking { + panic("Channels() used when tracking is disabled") + } + c.state.mu.RLock() _, inChannel := c.state.channels[strings.ToLower(channel)] c.state.mu.RUnlock() @@ -500,12 +501,9 @@ func (c *Client) IsInChannel(channel string) bool { return inChannel } -// Join attempts to enter a list of IRC channels. Specify up to +// Join attempts to enter a list of IRC channels, at bulk if possible to +// prevent sending extensive JOIN commands. func (c *Client) Join(channels ...string) error { - if !c.IsConnected() { - return ErrNotConnected - } - // We can join multiple channels at once, however we need to ensure that // we are not exceeding the line length. (see maxLength) max := maxLength - len(JOIN) - 1 @@ -547,10 +545,6 @@ func (c *Client) JoinKey(channel, password string) error { return &ErrInvalidTarget{Target: channel} } - if !c.IsConnected() { - return ErrNotConnected - } - return c.Send(&Event{Command: JOIN, Params: []string{channel, password}}) } @@ -560,10 +554,6 @@ func (c *Client) Part(channel, message string) error { return &ErrInvalidTarget{Target: channel} } - if !c.IsConnected() { - return ErrNotConnected - } - return c.Send(&Event{Command: JOIN, Params: []string{channel}}) } @@ -573,10 +563,6 @@ func (c *Client) PartMessage(channel, message string) error { return &ErrInvalidTarget{Target: channel} } - if !c.IsConnected() { - return ErrNotConnected - } - return c.Send(&Event{Command: JOIN, Params: []string{channel}, Trailing: message}) } @@ -620,10 +606,6 @@ func (c *Client) Message(target, message string) error { return &ErrInvalidTarget{Target: target} } - if !c.IsConnected() { - return ErrNotConnected - } - return c.Send(&Event{Command: PRIVMSG, Params: []string{target}, Trailing: message}) } @@ -640,10 +622,6 @@ func (c *Client) Action(target, message string) error { return &ErrInvalidTarget{Target: target} } - if !c.IsConnected() { - return ErrNotConnected - } - return c.Send(&Event{ Command: PRIVMSG, Params: []string{target}, @@ -663,10 +641,6 @@ func (c *Client) Notice(target, message string) error { return &ErrInvalidTarget{Target: target} } - if !c.IsConnected() { - return ErrNotConnected - } - return c.Send(&Event{Command: NOTICE, Params: []string{target}, Trailing: message}) } @@ -684,10 +658,6 @@ func (c *Client) SendRaw(raw string) error { return errors.New("invalid event: " + raw) } - if !c.IsConnected() { - return ErrNotConnected - } - return c.Send(e) } @@ -712,11 +682,128 @@ func (c *Client) Who(target string) error { return &ErrInvalidTarget{Target: target} } - if !c.IsConnected() { - return ErrNotConnected + return c.Send(&Event{Command: WHO, Params: []string{target, "%tcuhnr,2"}}) +} + +// Whois sends a WHOIS query to the server, targetted at a specific user. +// as WHOIS is a bit slower, you may want to use WHO for brief user info. +func (c *Client) Whois(nick string) error { + if !IsValidNick(nick) { + return &ErrInvalidTarget{Target: nick} } - return c.Send(&Event{Command: WHO, Params: []string{target, "%tcuhnr,2"}}) + return c.Send(&Event{Command: WHOIS, Params: []string{nick}}) +} + +// Ping sends a PING query to the server, with a specific identifier that +// the server should respond with. +func (c *Client) Ping(id string) error { + return c.Send(&Event{Command: PING, Params: []string{id}}) +} + +// Pong sends a PONG query to the server, with an identifier which was +// received from a previous PING query received by the client. +func (c *Client) Pong(id string) error { + return c.Send(&Event{Command: PONG, Params: []string{id}}) +} + +// Oper sends a OPER authentication query to the server, with a username +// and password. +func (c *Client) Oper(user, pass string) error { + return c.Send(&Event{Command: OPER, Params: []string{user, pass}, Sensitive: true}) +} + +// Kick sends a KICK query to the server, attempting to kick nick from +// channel, with reason. If reason is blank, one will not be sent to the +// server. +func (c *Client) Kick(channel, nick, reason string) error { + if !IsValidChannel(channel) { + return &ErrInvalidTarget{Target: channel} + } + + if !IsValidNick(nick) { + return &ErrInvalidTarget{Target: nick} + } + + if reason != "" { + return c.Send(&Event{Command: KICK, Params: []string{channel, nick}, Trailing: reason}) + } + + return c.Send(&Event{Command: KICK, Params: []string{channel, nick}}) +} + +// Invite sends a INVITE query to the server, to invite nick to channel. +func (c *Client) Invite(channel, nick string) error { + if !IsValidChannel(channel) { + return &ErrInvalidTarget{Target: channel} + } + + if !IsValidNick(nick) { + return &ErrInvalidTarget{Target: nick} + } + + return c.Send(&Event{Command: INVITE, Params: []string{nick, channel}}) +} + +// Away sends a AWAY query to the server, suggesting that the client is no +// longer active. If reason is blank, Client.Back() is called. Also see +// Client.Back(). +func (c *Client) Away(reason string) error { + if reason == "" { + return c.Back() + } + + return c.Send(&Event{Command: AWAY, Params: []string{reason}}) +} + +// Back sends a AWAY query to the server, however the query is blank, +// suggesting that the client is active once again. Also see Client.Away(). +func (c *Client) Back() error { + return c.Send(&Event{Command: AWAY}) +} + +// LIST sends a LIST query to the server, which will list channels and topics. +// Supports multiple channels at once, in hopes it will reduce extensive +// LIST queries to the server. Supply no channels to run a list against the +// entire server (warning, that may mean LOTS of channels!) +func (c *Client) List(channels ...string) error { + if len(channels) == 0 { + return c.Send(&Event{Command: LIST}) + } + + // We can LIST multiple channels at once, however we need to ensure that + // we are not exceeding the line length. (see maxLength) + max := maxLength - len(JOIN) - 1 + + var buffer string + var err error + + for i := 0; i < len(channels); i++ { + if !IsValidChannel(channels[i]) { + return &ErrInvalidTarget{Target: channels[i]} + } + + if len(buffer+","+channels[i]) > max { + err = c.Send(&Event{Command: LIST, Params: []string{buffer}}) + if err != nil { + return err + } + buffer = "" + continue + } + + if len(buffer) == 0 { + buffer = channels[i] + } else { + buffer += "," + channels[i] + } + + if i == len(channels)-1 { + return c.Send(&Event{Command: LIST, Params: []string{buffer}}) + } + } + + return nil } // Whowas sends a WHOWAS query to the server. amount is the amount of results @@ -726,10 +813,6 @@ func (c *Client) Whowas(nick string, amount int) error { return &ErrInvalidTarget{Target: nick} } - if !c.IsConnected() { - return ErrNotConnected - } - return c.Send(&Event{Command: WHOWAS, Params: []string{nick, string(amount)}}) }