dispatch/irc/client.go

175 lines
3.3 KiB
Go
Raw Normal View History

2015-06-05 22:34:13 +00:00
package irc
import (
"bufio"
"crypto/tls"
"net"
"strings"
"sync"
2016-03-01 00:51:26 +00:00
"github.com/jpillora/backoff"
"github.com/matryer/resync"
2015-06-05 22:34:13 +00:00
)
type Client struct {
2016-01-13 17:53:54 +00:00
Server string
Host string
TLS bool
TLSConfig *tls.Config
Password string
Username string
Realname string
Messages chan *Message
ConnectionChanged chan bool
HandleNickInUse func(string) string
2015-06-05 22:34:13 +00:00
2016-02-03 20:12:32 +00:00
nick string
channels []string
2015-06-05 22:34:13 +00:00
conn net.Conn
connected bool
dialer *net.Dialer
reader *bufio.Reader
2016-01-13 00:00:57 +00:00
backoff *backoff.Backoff
2015-06-05 22:34:13 +00:00
out chan string
quit chan struct{}
reconnect chan struct{}
ready sync.WaitGroup
2016-01-12 23:12:51 +00:00
sendRecv sync.WaitGroup
once resync.Once
2015-06-05 22:34:13 +00:00
lock sync.Mutex
}
func NewClient(nick, username string) *Client {
return &Client{
2016-01-13 17:53:54 +00:00
nick: nick,
Username: username,
Realname: nick,
Messages: make(chan *Message, 32),
ConnectionChanged: make(chan bool, 16),
out: make(chan string, 32),
quit: make(chan struct{}),
reconnect: make(chan struct{}),
2016-01-13 00:00:57 +00:00
backoff: &backoff.Backoff{
Jitter: true,
},
2015-06-05 22:34:13 +00:00
}
}
func (c *Client) GetNick() string {
c.lock.Lock()
defer c.lock.Unlock()
return c.nick
}
2017-04-11 04:04:59 +00:00
func (c *Client) setNick(nick string) {
c.lock.Lock()
c.nick = nick
c.lock.Unlock()
}
2015-06-05 22:34:13 +00:00
func (c *Client) Connected() bool {
c.lock.Lock()
defer c.lock.Unlock()
return c.connected
}
func (c *Client) Nick(nick string) {
c.Write("NICK " + nick)
}
func (c *Client) Oper(name, password string) {
c.Write("OPER " + name + " " + password)
}
func (c *Client) Mode(target, modes, params string) {
c.Write(strings.TrimRight("MODE "+target+" "+modes+" "+params, " "))
}
func (c *Client) Quit() {
go func() {
if c.Connected() {
c.write("QUIT")
}
close(c.quit)
}()
}
func (c *Client) Join(channels ...string) {
c.Write("JOIN " + strings.Join(channels, ","))
}
func (c *Client) Part(channels ...string) {
c.Write("PART " + strings.Join(channels, ","))
}
func (c *Client) Topic(channel string, topic ...string) {
msg := "TOPIC " + channel
if len(topic) > 0 {
msg += " :" + topic[0]
}
c.Write(msg)
2015-06-05 22:34:13 +00:00
}
func (c *Client) Invite(nick, channel string) {
c.Write("INVITE " + nick + " " + channel)
}
func (c *Client) Kick(channel string, users ...string) {
c.Write("KICK " + channel + " " + strings.Join(users, ","))
}
func (c *Client) Privmsg(target, msg string) {
c.Writef("PRIVMSG %s :%s", target, msg)
}
func (c *Client) Notice(target, msg string) {
c.Writef("NOTICE %s :%s", target, msg)
}
func (c *Client) Whois(nick string) {
c.Write("WHOIS " + nick)
}
func (c *Client) Away(message string) {
c.Write("AWAY :" + message)
}
2015-06-11 02:57:52 +00:00
func (c *Client) writePass(password string) {
c.write("PASS " + password)
}
func (c *Client) writeNick(nick string) {
c.write("NICK " + nick)
}
func (c *Client) writeUser(username, realname string) {
c.writef("USER %s 0 * :%s", username, realname)
}
func (c *Client) register() {
if c.Password != "" {
c.writePass(c.Password)
}
c.writeNick(c.nick)
c.writeUser(c.Username, c.Realname)
}
2016-02-03 20:12:32 +00:00
func (c *Client) addChannel(channel string) {
c.lock.Lock()
c.channels = append(c.channels, channel)
c.lock.Unlock()
}
func (c *Client) flushChannels() {
c.lock.Lock()
if len(c.channels) > 0 {
c.Join(c.channels...)
c.channels = []string{}
}
c.lock.Unlock()
}