commit 14522421484a391eaf2fc90489367968603956ca
parent d8835f83c84876fef279f8d7055e3f1ae8e93e37
Author: sin <sin@2f30.org>
Date: Wed, 17 Apr 2013 12:05:56 +0100
kunt: Update kunt to use the irc package
Diffstat:
M | src/kunt/kunt.go | | | 286 | ++++++++++++++++++++++++------------------------------------------------------- |
1 file changed, 87 insertions(+), 199 deletions(-)
diff --git a/src/kunt/kunt.go b/src/kunt/kunt.go
@@ -2,43 +2,22 @@ package main
import (
"bytes"
- "crypto/tls"
- "crypto/x509"
"flag"
"fmt"
"fsdb"
"io/ioutil"
+ "irc"
"log"
"math/rand"
- "net"
"os"
"os/exec"
"strings"
"time"
)
-/* Kunt context */
type kuntCtx struct {
- channel string
- nick string
- user string
- srv string
- port string
- ssl bool
stime time.Time
-}
-
-func newKunt(channel string, nick string,
- user string, srv string, port string, ssl bool) *kuntCtx {
- return &kuntCtx{channel, nick, user, srv, port, ssl, time.Now()}
-}
-
-/* Helper routines */
-func botWrite(conn net.Conn, buf []byte) {
- _, err := conn.Write(buf[0:])
- if err != nil {
- log.Fatal(err)
- }
+ ircCtx *irc.IrcContext
}
func resolveYoutubeTitle(link string) (title string, ret bool) {
@@ -58,8 +37,7 @@ func resolveYoutubeTitle(link string) (title string, ret bool) {
return
}
-/* Kunt command handling routines */
-func cmdKunt(conn net.Conn, s string) {
+func cmdKunt(msg irc.IrcMessage) {
actions := []string{
"die",
"die bitch",
@@ -71,11 +49,10 @@ func cmdKunt(conn net.Conn, s string) {
"no fucking way",
}
idx := rand.Intn(len(actions))
- r := fmt.Sprintf("PRIVMSG %s :%s\r\n", kunt.channel, actions[idx])
- botWrite(conn, []byte(r))
+ kunt.ircCtx.SendPrivmsg(msg.Params[0], string(actions[idx]))
}
-func cmdWisdom(conn net.Conn, s string) {
+func cmdWisdom(msg irc.IrcMessage) {
out, err := exec.Command("./fortune").Output()
if err != nil {
log.Fatal(err)
@@ -85,13 +62,12 @@ func cmdWisdom(conn net.Conn, s string) {
if i == "" {
continue
}
- r := fmt.Sprintf("PRIVMSG %s :%s\r\n", kunt.channel, i)
- botWrite(conn, []byte(r))
+ kunt.ircCtx.SendPrivmsg(msg.Params[0], i)
time.Sleep(512 * time.Millisecond)
}
}
-func cmdHelp(conn net.Conn, s string) {
+func cmdHelp(msg irc.IrcMessage) {
help := []string{
"!addquote <quote> -> Add a quote to the db",
"!randquote -> Print a random quote from the db",
@@ -106,49 +82,44 @@ func cmdHelp(conn net.Conn, s string) {
"!version -> Show version",
}
for _, i := range help {
- r := fmt.Sprintf("PRIVMSG %s :%s\r\n", kunt.channel, i)
- botWrite(conn, []byte(r))
+ kunt.ircCtx.SendPrivmsg(msg.Params[0], i)
time.Sleep(512 * time.Millisecond)
}
}
-func cmdVersion(conn net.Conn, s string) {
- ver := "v0.2.7"
- r := fmt.Sprintf("PRIVMSG %s :%s\r\n", kunt.channel, ver)
- botWrite(conn, []byte(r))
+func cmdVersion(msg irc.IrcMessage) {
+ ver := "v0.2.8"
+ kunt.ircCtx.SendPrivmsg(msg.Params[0], ver)
}
-func cmdRandQuote(conn net.Conn, s string) {
+func cmdRandQuote(msg irc.IrcMessage) {
if quoteDb.Empty() {
- r := fmt.Sprintf("PRIVMSG %s :Empty quote database\r\n",
- kunt.channel)
- botWrite(conn, []byte(r))
+ kunt.ircCtx.SendPrivmsg(msg.Params[0], "Empty quote database")
return
}
quote, idx := quoteDb.Rand()
- /* Print idx in red */
- r := fmt.Sprintf("PRIVMSG %s :%s%02d[%d]%s %s\r\n", kunt.channel,
+ // Print idx in red
+ text := fmt.Sprintf("%s%02d[%d]%s %s\r\n",
"\003", '5', idx, "\003", string(quote))
- botWrite(conn, []byte(r))
+ kunt.ircCtx.SendPrivmsg(msg.Params[0], text)
}
-func cmdAddQuote(conn net.Conn, s string) {
- idx := len("!addquote")
- if s[idx:idx+1] != " " {
- r := fmt.Sprintf("PRIVMSG %s :Missing parameter for !addquote\r\n",
- kunt.channel)
- botWrite(conn, []byte(r))
+func cmdAddQuote(msg irc.IrcMessage) {
+ if len(msg.Params) != 2 {
+ kunt.ircCtx.SendPrivmsg(msg.Params[0], "Missing parameter for !addquote\r\n")
return
}
- s = s[idx+1:]
- s = strings.TrimSpace(s)
- s += "\n"
+
+ s := ""
+ for i, v := range msg.Params {
+ if i > 1 {
+ s += v
+ }
+ }
buf := []byte(s)
quote, err := quoteDb.Put(-1, buf)
if err != nil {
- r := fmt.Sprintf("PRIVMSG %s :%s\r\n",
- kunt.channel, err.Error())
- botWrite(conn, []byte(r))
+ kunt.ircCtx.SendPrivmsg(msg.Params[0], err.Error())
return
}
err = quoteDb.FsWrite(quote, buf)
@@ -157,49 +128,40 @@ func cmdAddQuote(conn net.Conn, s string) {
}
}
-func cmdCountQuotes(conn net.Conn, s string) {
- r := fmt.Sprintf("PRIVMSG %s :The quote DB has %d quotes\r\n",
- kunt.channel, quoteDb.Len())
- botWrite(conn, []byte(r))
+func cmdCountQuotes(msg irc.IrcMessage) {
+ text := fmt.Sprintf("The quote DB has %d quotes", quoteDb.Len())
+ kunt.ircCtx.SendPrivmsg(msg.Params[0], text)
}
-func cmdRandUrl(conn net.Conn, s string) {
+func cmdRandUrl(msg irc.IrcMessage) {
if urlDb.Empty() {
- r := fmt.Sprintf("PRIVMSG %s :Empty url database\r\n",
- kunt.channel)
- botWrite(conn, []byte(r))
+ kunt.ircCtx.SendPrivmsg(msg.Params[0], "Empty url database")
return
}
url, idx := urlDb.Rand()
- /* Print idx in red */
- r := fmt.Sprintf("PRIVMSG %s :%s%02d[%d]%s %s\r\n", kunt.channel,
+ // Print idx in red
+ r := fmt.Sprintf("%s%02d[%d]%s %s",
"\003", '5', idx, "\003", string(url))
- botWrite(conn, []byte(r))
+ kunt.ircCtx.SendPrivmsg(msg.Params[0], r)
title, ok := resolveYoutubeTitle(string(url))
if ok {
- r = fmt.Sprintf("PRIVMSG %s :[YouTube] %s\r\n",
- kunt.channel, title)
- botWrite(conn, []byte(r))
+ r = fmt.Sprintf("[YouTube] %s", title)
+ kunt.ircCtx.SendPrivmsg(msg.Params[0], r)
}
}
-func cmdAddUrl(conn net.Conn, s string) {
- idx := len("!addurl")
- if s[idx:idx+1] != " " {
- r := fmt.Sprintf("PRIVMSG %s :Missing parameter for !addurl\r\n",
- kunt.channel)
- botWrite(conn, []byte(r))
+func cmdAddUrl(msg irc.IrcMessage) {
+ if len(msg.Params) != 2 {
+ kunt.ircCtx.SendPrivmsg(msg.Params[0], "Wrong formatting for !addurl")
return
}
- s = s[idx+1:]
- s = strings.TrimSpace(s)
+
+ s := strings.TrimSpace(msg.Params[1])
s += "\n"
buf := []byte(s)
url, err := urlDb.Put(-1, buf)
if err != nil {
- r := fmt.Sprintf("PRIVMSG %s :%s\r\n",
- kunt.channel, err.Error())
- botWrite(conn, []byte(r))
+ kunt.ircCtx.SendPrivmsg(msg.Params[0], err.Error())
return
}
err = urlDb.FsWrite(url, buf)
@@ -208,30 +170,26 @@ func cmdAddUrl(conn net.Conn, s string) {
}
}
-func cmdCountUrls(conn net.Conn, s string) {
- r := fmt.Sprintf("PRIVMSG %s :The url DB has %d urls\r\n",
- kunt.channel, urlDb.Len())
- botWrite(conn, []byte(r))
+func cmdCountUrls(msg irc.IrcMessage) {
+ r := fmt.Sprintf("The url DB has %d urls", urlDb.Len())
+ kunt.ircCtx.SendPrivmsg(msg.Params[0], r)
}
-func cmdUptime(conn net.Conn, s string) {
+func cmdUptime(msg irc.IrcMessage) {
etime := time.Now()
- r := fmt.Sprintf("PRIVMSG %s :%v\r\n", kunt.channel,
- etime.Sub(kunt.stime))
- botWrite(conn, []byte(r))
+ r := fmt.Sprintf("%v", etime.Sub(kunt.stime))
+ kunt.ircCtx.SendPrivmsg(msg.Params[0], r)
}
-func cmdSrc(conn net.Conn, s string) {
+func cmdSrc(msg irc.IrcMessage) {
src := "http://amnezia.2f30.org/tmp/kunt-latest.tgz"
- r := fmt.Sprintf("PRIVMSG %s :%s\r\n", kunt.channel, src)
- botWrite(conn, []byte(r))
+ kunt.ircCtx.SendPrivmsg(msg.Params[0], src)
}
-func cmdTodo(conn net.Conn, s string) {
+func cmdTodo(msg irc.IrcMessage) {
todo, err := ioutil.ReadFile("TODO")
if err != nil {
- r := fmt.Sprintf("PRIVMSG %s :No TODO list available\r\n", kunt.channel)
- botWrite(conn, []byte(r))
+ kunt.ircCtx.SendPrivmsg(msg.Params[0], "No TODO list available")
return
}
sf := strings.FieldsFunc(string(todo), func(r rune) bool {
@@ -241,10 +199,8 @@ func cmdTodo(conn net.Conn, s string) {
}
return false
})
- for _, i := range sf {
- r := fmt.Sprintf("PRIVMSG %s :%s\r\n", kunt.channel, i)
- botWrite(conn, []byte(r))
- time.Sleep(512 * time.Millisecond)
+ for _, v := range sf {
+ kunt.ircCtx.SendPrivmsg(msg.Params[0], v)
}
}
@@ -252,81 +208,32 @@ var sslon = flag.Bool("s", false, "SSL support")
var quoteDb *fsdb.Fsdb
var urlDb *fsdb.Fsdb
-var kunt *kuntCtx
+var kunt kuntCtx
+
+func handlePrivmsg(msg irc.IrcMessage) {
+}
func main() {
- flag.Parse()
+ log.SetPrefix("kunt: ")
+ flag.Parse()
if flag.NArg() < 1 {
fmt.Fprintf(os.Stderr, "usage: %s [-s] host:port\n",
os.Args[0])
os.Exit(1)
}
- service := flag.Arg(0)
-
- log.SetPrefix("kunt: ")
hostport := strings.Split(flag.Arg(0), ":")
- kunt = newKunt("#2f30", "kunt", "z0mg", hostport[0], hostport[1], *sslon)
-
- if *sslon {
- fmt.Println("SSL on")
- }
-
- tcpAddr, err := net.ResolveTCPAddr("tcp4", service)
- if err != nil {
- log.Fatal(err)
- }
- if *sslon {
- cert, err := tls.LoadX509KeyPair("certs/client.pem",
- "certs/client.key")
- if err != nil {
- log.Fatal(err)
- }
- conf := tls.Config{Certificates: []tls.Certificate{cert},
- InsecureSkipVerify: true}
-
- conn, err := tls.Dial("tcp", service, &conf)
- if err != nil {
- log.Fatal(err)
- }
- defer conn.Close()
-
- fmt.Println("Client: connected to: ", conn.RemoteAddr())
-
- state := conn.ConnectionState()
-
- for _, v := range state.PeerCertificates {
- fmt.Println(x509.MarshalPKIXPublicKey(v.PublicKey))
- fmt.Println(v.Subject)
- }
-
- fmt.Println("Client: handshake: ", state.HandshakeComplete)
- fmt.Println("Client: mutual: ", state.NegotiatedProtocolIsMutual)
- loop(conn)
- } else {
- conn, err := net.DialTCP("tcp", nil, tcpAddr)
- if err != nil {
- log.Fatal(err)
- }
- defer conn.Close()
- loop(conn)
- }
-}
-
-func loop(conn net.Conn) {
quoteDb = fsdb.NewFsdb("Quote DB", "db/quotes", "quote")
urlDb = fsdb.NewFsdb("Url DB", "db/urls", "url")
quoteDb.Load()
urlDb.Load()
- go InitiateConnection(conn)
-
rand.Seed(time.Now().UnixNano())
- dispatch := map[string]func(net.Conn, string){
+ dispatch := map[string]func(irc.IrcMessage){
"kunt": cmdKunt,
"!wisdom": cmdWisdom,
"!help": cmdHelp,
@@ -342,55 +249,36 @@ func loop(conn net.Conn) {
"!TODO": cmdTodo,
}
- for {
- var buf [512]byte
- n, err := conn.Read(buf[0:])
- if err != nil {
- log.Fatal(err)
- }
- fmt.Println(string(buf[0 : n-1]))
- s := string(buf[0:n])
- for i := range buf {
- buf[i] = 0
- }
+ cfg := irc.IrcConfig{
+ irc.Network: "grnet",
+ irc.Nick: "kunt",
+ irc.User: "z0mg",
+ irc.Serv: hostport[0],
+ irc.Port: hostport[1],
+ irc.Tls: *sslon,
+ }
- if strings.HasPrefix(s, "PING :") {
- r := strings.Replace(s, "PING :", "PONG :", 6)
- r = r + "\r\n"
- _, err := conn.Write([]byte(r))
- if err != nil {
- log.Fatal(err)
+ kunt.ircCtx = irc.NewIrcContext(cfg)
+ kunt.ircCtx.AddEventHandler(irc.IrcEvent{"PRIVMSG", func(msg irc.IrcMessage) {
+ cmd := msg.Params[1]
+ // Strip the leading ':'
+ cmd = cmd[1:]
+ for i, v := range dispatch {
+ if strings.HasPrefix(cmd, i) {
+ go v(msg)
}
- continue
}
+ }})
- q := fmt.Sprintf("PRIVMSG %s :", kunt.channel)
- msg := strings.Index(s, q)
- if msg == -1 {
- continue
- }
- msg += len(q)
- s = s[msg:]
- s = strings.TrimSpace(s)
- s += "\n"
+ kunt.ircCtx.Connect()
+ kunt.ircCtx.AddChannel("#2f30")
+ kunt.ircCtx.JoinChannels()
- for i, v := range dispatch {
- if strings.HasPrefix(s, i) {
- go v(conn, s)
- break
- }
+ donechan := make(chan bool)
+ select {
+ case stat := <-donechan:
+ if stat {
+ break
}
}
-
- os.Exit(0)
-}
-
-func InitiateConnection(conn net.Conn) {
- fmt.Println("initcon")
- query := fmt.Sprintf("NICK %s\r\n", kunt.nick)
- botWrite(conn, []byte(query))
- query = fmt.Sprintf("USER %s * 8 :%s\r\n", kunt.user, kunt.nick)
- botWrite(conn, []byte(query))
- query = fmt.Sprintf("JOIN %s\r\n", kunt.channel)
- botWrite(conn, []byte(query))
}