From e806485b5fe76f354c103072def4c5ca2e054130 Mon Sep 17 00:00:00 2001 From: blackbeard420 Date: Sun, 5 Jan 2020 12:39:58 -0500 Subject: [PATCH] initial commit --- go.mod | 3 ++ irc.go | 156 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 159 insertions(+) create mode 100644 go.mod create mode 100644 irc.go diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..5e5cdb0 --- /dev/null +++ b/go.mod @@ -0,0 +1,3 @@ +module thc420.xyz/gitea/blackbeard420/irc + +go 1.13 diff --git a/irc.go b/irc.go new file mode 100644 index 0000000..2f4f88f --- /dev/null +++ b/irc.go @@ -0,0 +1,156 @@ +package irc + +import ( + "bufio" + "fmt" + "log" + "net" + "strconv" + "strings" + "time" +) + +type IrcConnection struct { + Sock net.Conn + privmsgCallback func(string, string, string) + joinCallback func(string, string) + quitCallback func(string, string) + partCallback func(string, string, string) + numericCallback func(string, int, string) + joined bool + channels []string +} + +func (c *IrcConnection) SendPong(ping string) { + pong := strings.Replace(ping, "PING", "PONG", 1) + c.Sock.Write([]byte(fmt.Sprintf("%s\n", pong))) + log.Println("pong sent") +} + +func (c *IrcConnection) SendPrivmsg(channel, msg string) { + _, err := c.Sock.Write([]byte(fmt.Sprintf("PRIVMSG %s :%s\n", channel, msg))) + if err != nil { + log.Printf("Error sending private message: %s\n", err.Error()) + } +} + +func (c *IrcConnection) SendNotice(channel, msg string) { + _, err := c.Sock.Write([]byte(fmt.Sprintf("NOTICE %s :%s\n", channel, msg))) + if err != nil { + log.Printf("Error sending NOTICE message: %s\n", err.Error()) + } +} + +func (c *IrcConnection) SendNick(nick string) { + c.Sock.Write([]byte(fmt.Sprintf("NICK %s\n", nick))) +} + +func (c *IrcConnection) SendJoin(channel string) { + c.Sock.Write([]byte(fmt.Sprintf("JOIN %s\n", channel))) +} + +func (c *IrcConnection) SendPart(channel, msg string) { + c.Sock.Write([]byte(fmt.Sprintf("PART %s :%s\n", channel, msg))) +} + +func (c *IrcConnection) SendQuit(msg string) { + c.Sock.Write([]byte(fmt.Sprintf("QUIT :%s\n", msg))) +} + +func (c *IrcConnection) DelayedSend(sock net.Conn, dur time.Duration, channel, msg string) { + time.Sleep(dur) + c.SendPrivmsg(channel, msg) +} + +func (c *IrcConnection) Names(channel string) { + c.Sock.Write([]byte(fmt.Sprintf("NAMES %s\n", channel))) +} + +//NewIrcConnection creates and connects an IrcConnection +func NewIrcConnection(server, nick, user, pass string) *IrcConnection { + irc := &IrcConnection{} + + sock, err := net.Dial("tcp", server) + if err != nil { + log.Fatalln(err.Error()) + } + irc.Sock = sock + irc.Sock.Write([]byte(fmt.Sprintf("USER %s * * :%s\n", user, user))) + irc.SendNick(nick) + irc.Sock.Write([]byte(fmt.Sprintf("PASS %s\n", pass))) + return irc +} + +func getNick(name string) string { + return strings.Split(name, "!")[0] +} + +func (c *IrcConnection) parseMessage(line string) { + if line[0] == ':' { + buf := line[1:] + params := strings.SplitN(buf, " ", 3) + from := params[0] + cmd := params[1] + args := params[2] + + if _, e := strconv.Atoi(cmd); e == nil { + //numeric message + if !c.joined { + if cmd == "376" { + for _, v := range c.channels { + c.SendJoin(v) + } + c.joined = true + } + } + if c.numericCallback != nil { + code, _ := strconv.Atoi(cmd) + c.numericCallback(from, code, args) + } + } else { + t := strings.SplitN(args, ":", 2) + target := strings.TrimSpace(t[0]) + msg := "" + if len(t) > 1 { + msg = t[1] + } + + switch strings.ToLower(cmd) { + case "privmsg": + if c.privmsgCallback != nil { + c.privmsgCallback(target, from, msg) + } + case "join": + if c.joinCallback != nil { + c.joinCallback(from, target) + } + case "quit": + if c.quitCallback != nil { + c.quitCallback(from, msg) + } + case "part": + if c.partCallback != nil { + c.partCallback(from, target, msg) + } + } + } + } +} + +//Run runs the irc event loop +func (c *IrcConnection) Run() { + rdr := bufio.NewScanner(c.Sock) + + c.joined = false + + for rdr.Scan() { + line := rdr.Text() + + if strings.HasPrefix(line, "PING") { + c.SendPong(line) + continue + } + + c.parseMessage(line) + } +}