package main import ( "container/ring" "flag" "fmt" "log" "time" irc "github.com/fluffle/goirc/client" ) const maxLen = 500 var buffer = ring.New(10) func push(l *irc.Line) { buffer.Value = l buffer = buffer.Next() } func last(target string) { buffer.Do(func(v interface{}) { if v != nil { l := v.(*irc.Line) s := fmt.Sprintf("%v <%v> %v", l.Time.UTC().Format(time.Kitchen), l.Nick, l.Text()) conn.Notice(target, s) } }) } func notify(conn *irc.Conn, target string) chan string { c := make(chan string, 1) go func() { for msg := range c { log.Println("send", msg) if len(msg) > maxLen { msg = msg[:maxLen] + "..." } conn.Notice(target, msg) } }() return c } func kicker(conn *irc.Conn, channel string) chan string { c := make(chan string, 1) go func() { for nick := range c { if nick != conn.Me().Nick { log.Println("kick", nick) conn.Kick(channel, nick) } } }() return c } func join(room string) irc.HandlerFunc { return func(conn *irc.Conn, _ *irc.Line) { conn.Join(room) } } func discon(c chan struct{}) irc.HandlerFunc { return func(_ *irc.Conn, _ *irc.Line) { close(c) } } func privmsg(n, k chan string, room string) irc.HandlerFunc { l := links(n) return func(conn *irc.Conn, line *irc.Line) { if isFlood(line.Text()) { k <- line.Nick } if line.Text() == "last" { last(line.Nick) } else { push(line) } l <- line.Text() } } func main() { node := flag.String("node", "irc.freenode.org", "IRC Server") ssl := flag.Bool("ssl", false, "Use SSL") room := flag.String("room", "#lor", "IRC Channel") name := flag.String("name", "dim13", "Bots Name") flag.Parse() conf := irc.NewConfig(*name) conf.Server = *node conf.SSL = *ssl conn := irc.Client(conf) //conn.EnableStateTracking() // XXX done := make(chan struct{}) n := notify(conn, *room) k := kicker(conn, *room) go Watch(n, Feeds) // TODO shall it be there? // setup event handler handler := []struct { ev string f irc.HandlerFunc }{ {irc.DISCONNECTED, discon(done)}, {irc.CONNECTED, join(*room)}, {irc.KICK, join(*room)}, {irc.PRIVMSG, privmsg(n, k, *room)}, } for _, h := range handler { conn.HandleFunc(h.ev, h.f) } log.Println("Connect to", conf.Server) if err := conn.Connect(); err != nil { log.Fatal(err) } <-done log.Println("Disconnected") }