package main import ( "crypto/tls" "flag" "fmt" "io" "log" "sync" "dim13.org/bot/internal/feeds" "dim13.org/bot/internal/fix" "dim13.org/bot/internal/flood" "dim13.org/bot/internal/title" irc "github.com/fluffle/goirc/client" ) func limit(s string) string { const maxLen = 450 if len(s) > maxLen { return fmt.Sprintf("%.*s...", maxLen-3, s) } return s } type room struct { conn *irc.Conn target string } func roomWriter(conn *irc.Conn, target string) *room { return &room{conn: conn, target: target} } func (n *room) Write(p []byte) (int, error) { n.conn.Notice(n.target, limit(string(p))) return len(p), nil } func (n *room) Kick(nick string, message ...string) { n.conn.Kick(n.target, nick, message...) } func (n *room) Ban(nick string) { n.conn.Mode(n.target, "+b", nick+"!*@*") } func (n *room) HellBan(nick string) { n.conn.Mode(n.target, "+q", nick+"!*@*") } type message struct { title *title.Titles flood *flood.Check fix *fix.Fix } type kickWriter interface { io.Writer flood.Kicker } func msgHandler(w kickWriter) *message { return &message{ title: title.New(w), flood: flood.New(w), fix: fix.New(w), } } func (r *message) Handle(conn *irc.Conn, line *irc.Line) { text, nick := line.Text(), line.Nick // ignore self if nick == conn.Me().Nick { return } r.flood.Check(text, nick) r.title.Parse(text) r.fix.Fix(text, nick) } func main() { node := flag.String("node", "irc.freenode.org", "IRC server") notls := flag.Bool("notls", false, "disable TLS") room := flag.String("room", "#lor", "IRC channel") name := flag.String("name", "dim13", "bots name") flag.Parse() conf := irc.NewConfig(*name) conf.Server = *node if !*notls { conf.SSL = true conf.SSLConfig = &tls.Config{ServerName: *node} } conn := irc.Client(conf) var wg sync.WaitGroup wg.Add(1) conn.HandleFunc(irc.DISCONNECTED, func(_ *irc.Conn, _ *irc.Line) { wg.Done() }) w := roomWriter(conn, *room) conn.HandleFunc(irc.CONNECTED, func(conn *irc.Conn, _ *irc.Line) { conn.Join(*room) feeds.Watch(w, feeds.Feeds) }) conn.HandleFunc(irc.KICK, func(conn *irc.Conn, _ *irc.Line) { conn.Join(*room) }) conn.HandleBG(irc.PRIVMSG, msgHandler(w)) if err := conn.Connect(); err != nil { log.Fatal(err) } wg.Wait() }