Init
This commit is contained in:
commit
508a04cf4c
30 changed files with 1545 additions and 0 deletions
207
irc.go
Normal file
207
irc.go
Normal file
|
@ -0,0 +1,207 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"crypto/tls"
|
||||
"fmt"
|
||||
"net"
|
||||
"strings"
|
||||
)
|
||||
|
||||
const (
|
||||
PING = "PING"
|
||||
JOIN = "JOIN"
|
||||
PART = "PART"
|
||||
MODE = "MODE"
|
||||
PRIVMSG = "PRIVMSG"
|
||||
NOTICE = "NOTICE"
|
||||
TOPIC = "TOPIC"
|
||||
QUIT = "QUIT"
|
||||
|
||||
RPL_WELCOME = "001"
|
||||
RPL_YOURHOST = "002"
|
||||
RPL_CREATED = "003"
|
||||
RPL_LUSERCLIENT = "251"
|
||||
RPL_LUSEROP = "252"
|
||||
RPL_LUSERUNKNOWN = "253"
|
||||
RPL_LUSERCHANNELS = "254"
|
||||
RPL_LUSERME = "255"
|
||||
|
||||
RPL_WHOISUSER = "311"
|
||||
RPL_WHOISSERVER = "312"
|
||||
RPL_WHOISOPERATOR = "313"
|
||||
RPL_WHOISIDLE = "317"
|
||||
RPL_ENDOFWHOIS = "318"
|
||||
RPL_WHOISCHANNELS = "319"
|
||||
|
||||
RPL_TOPIC = "332"
|
||||
|
||||
RPL_NAMREPLY = "353"
|
||||
RPL_ENDOFNAMES = "366"
|
||||
|
||||
RPL_MOTD = "372"
|
||||
RPL_MOTDSTART = "375"
|
||||
RPL_ENDOFMOTD = "376"
|
||||
)
|
||||
|
||||
type Message struct {
|
||||
Prefix string
|
||||
Command string
|
||||
Params []string
|
||||
Trailing string
|
||||
}
|
||||
|
||||
type IRC struct {
|
||||
conn net.Conn
|
||||
reader *bufio.Reader
|
||||
|
||||
Messages chan *Message
|
||||
Server string
|
||||
Host string
|
||||
TLS bool
|
||||
TLSConfig *tls.Config
|
||||
nick string
|
||||
Username string
|
||||
Realname string
|
||||
}
|
||||
|
||||
func NewIRC(nick, username string) *IRC {
|
||||
return &IRC{
|
||||
nick: nick,
|
||||
Username: username,
|
||||
Realname: nick,
|
||||
Messages: make(chan *Message, 32),
|
||||
}
|
||||
}
|
||||
|
||||
func (i *IRC) Connect(address string) {
|
||||
if idx := strings.Index(address, ":"); idx < 0 {
|
||||
i.Host = address
|
||||
|
||||
if i.TLS {
|
||||
address += ":6697"
|
||||
} else {
|
||||
address += ":6667"
|
||||
}
|
||||
} else {
|
||||
i.Host = address[:idx]
|
||||
}
|
||||
i.Server = address
|
||||
|
||||
if i.TLS {
|
||||
if i.TLSConfig == nil {
|
||||
i.TLSConfig = &tls.Config{InsecureSkipVerify: true}
|
||||
}
|
||||
i.conn, _ = tls.Dial("tcp", address, i.TLSConfig)
|
||||
} else {
|
||||
i.conn, _ = net.Dial("tcp", address)
|
||||
}
|
||||
|
||||
i.reader = bufio.NewReader(i.conn)
|
||||
|
||||
i.Nick(i.nick)
|
||||
i.User(i.Username, i.Realname)
|
||||
|
||||
go i.recv()
|
||||
}
|
||||
|
||||
func (i *IRC) Pass(password string) {
|
||||
i.Write("PASS " + password)
|
||||
}
|
||||
|
||||
func (i *IRC) Nick(nick string) {
|
||||
i.Write("NICK " + nick)
|
||||
}
|
||||
|
||||
func (i *IRC) User(username, realname string) {
|
||||
i.Writef("USER %s 0 * :%s", username, realname)
|
||||
}
|
||||
|
||||
func (i *IRC) Join(channels ...string) {
|
||||
i.Write("JOIN " + strings.Join(channels, ","))
|
||||
}
|
||||
|
||||
func (i *IRC) Part(channels ...string) {
|
||||
i.Write("PART " + strings.Join(channels, ","))
|
||||
}
|
||||
|
||||
func (i *IRC) Privmsg(target, msg string) {
|
||||
i.Writef("PRIVMSG %s :%s", target, msg)
|
||||
}
|
||||
|
||||
func (i *IRC) Notice(target, msg string) {
|
||||
i.Writef("NOTICE %s :%s", target, msg)
|
||||
}
|
||||
|
||||
func (i *IRC) Topic(channel string) {
|
||||
i.Write("TOPIC " + channel)
|
||||
}
|
||||
|
||||
func (i *IRC) Whois(nick string) {
|
||||
i.Write("WHOIS " + nick)
|
||||
}
|
||||
|
||||
func (i *IRC) Quit() {
|
||||
i.Write("QUIT")
|
||||
i.conn.Close()
|
||||
}
|
||||
|
||||
func (i *IRC) Write(data string) {
|
||||
fmt.Fprint(i.conn, data+"\r\n")
|
||||
}
|
||||
|
||||
func (i *IRC) Writef(format string, a ...interface{}) {
|
||||
fmt.Fprintf(i.conn, format+"\r\n", a...)
|
||||
}
|
||||
|
||||
func (i *IRC) recv() {
|
||||
defer i.conn.Close()
|
||||
for {
|
||||
line, err := i.reader.ReadString('\n')
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
msg := parseMessage(line)
|
||||
msg.Prefix = parseUser(msg.Prefix)
|
||||
|
||||
switch msg.Command {
|
||||
case PING:
|
||||
i.Write("PONG :" + msg.Trailing)
|
||||
}
|
||||
|
||||
i.Messages <- msg
|
||||
}
|
||||
}
|
||||
|
||||
func parseMessage(line string) *Message {
|
||||
line = strings.Trim(line, "\r\n")
|
||||
msg := Message{}
|
||||
cmdStart := 0
|
||||
cmdEnd := len(line)
|
||||
|
||||
if strings.HasPrefix(line, ":") {
|
||||
cmdStart = strings.Index(line, " ") + 1
|
||||
msg.Prefix = line[1 : cmdStart-1]
|
||||
}
|
||||
|
||||
if i := strings.LastIndex(line, " :"); i > 0 {
|
||||
cmdEnd = i
|
||||
msg.Trailing = line[i+2:]
|
||||
}
|
||||
|
||||
cmd := strings.Split(line[cmdStart:cmdEnd], " ")
|
||||
msg.Command = cmd[0]
|
||||
if len(cmd) > 1 {
|
||||
msg.Params = cmd[1:]
|
||||
}
|
||||
|
||||
return &msg
|
||||
}
|
||||
|
||||
func parseUser(user string) string {
|
||||
if i := strings.Index(user, "!"); i > 0 {
|
||||
return user[:i]
|
||||
}
|
||||
return user
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue