diff --git a/irc.go b/irc.go new file mode 100644 index 0000000..769d701 --- /dev/null +++ b/irc.go @@ -0,0 +1,137 @@ +// vi:ts=4:sts=4:sw=4:noet:tw=72 +// +// flokatirc +// +// Copyright (c) 2015,2016 Andreas Neue + +package main + +import ( + "crypto/tls" + "flag" + "fmt" + "strings" + "time" + + "git.dnix.de/an/flokatilib/modules" + "git.dnix.de/an/xlog" + + irc "github.com/fluffle/goirc/client" +) + +var ( + usetls = flag.Bool("tls", true, "Use TLS") + port = flag.String("port", "6697", "Server port") + nsname = flag.String("nsname", "NickServ", "NickServ name") + nspass = flag.String("nspass", "", "NickServ password") + automsgTo = flag.String("automsg_to", "", "Autosend IRC msg recipient") + automsgText = flag.String("automsg_text", "", "Autosend IRC msg text") +) + +func Irc(say chan string) { + //bot := ircx.Classic(*server, *name) + cfg := irc.NewConfig(*name) + cfg.SSL = *usetls + cfg.SSLConfig = &tls.Config{ServerName: *server} + cfg.Server = *server + ":" + *port + cfg.NewNick = func(n string) string { return n + "^" } + cfg.Me.Ident = *name + cfg.Me.Name = *name + bot := irc.Client(cfg) + SetupHandlers(bot, say) + + go CheckConnection(bot) + go Ping(bot) + + modules.Init(say, *mods) + modules.BotNick = strings.ToLower(*name) + + for { + var targets string + for { + if bot.Connected() { + break + } + time.Sleep(1 * time.Second) + } + line := strings.Split(<-say, "\n") + xlog.Debug("Say: \"%s\"", line) + if len(line) < 2 { + continue + } + if line[0] != "*" { + targets = line[0] + } else { + targets = *channels + } + for _, tar := range strings.Split(targets, ",") { + bot.Privmsg(tar, line[1]) + time.Sleep(1 * time.Second) + } + } + time.Sleep(1 * time.Millisecond) +} + +func SetupHandlers(bot *irc.Conn, say chan string) { + xlog.Info("Registering handlers") + bot.HandleFunc("001", func(c *irc.Conn, l *irc.Line) { + go func(c *irc.Conn, l *irc.Line) { + if *nspass != "" { + xlog.Info("Authenticating with NickServ: %v, %v", *name, "xxxxxx") + bot.Privmsg(*nsname, "IDENTIFY "+*name+" "+*nspass) + } + if *automsgTo != "" && *automsgText != "" { + xlog.Info("Sending automsg ...") + bot.Privmsg(*automsgTo, *automsgText) + } + xlog.Info("Joining channels: %v", *channels) + for _, ch := range strings.Split(*channels, ",") { + bot.Join(ch) + } + time.Sleep(2 * time.Second) + msg := fmt.Sprintf("running on %s", SoftwareInfo()) + say <- fmt.Sprintf("%s\n\001ACTION %s\001", "*", msg) + }(c, l) + }) + bot.HandleFunc("PRIVMSG", func(c *irc.Conn, l *irc.Line) { + go func(c *irc.Conn, l *irc.Line) { + //TODO: implement message handler table + HandleMessage(l) + modules.HandleMessage(&modules.Message{From: l.Nick, Channel: l.Args[0], Text: l.Text()}) + }(c, l) + }) +} + +func CheckConnection(bot *irc.Conn) { + for { + if !bot.Connected() { + xlog.Info("Not connected, connecting ...") + if err := bot.Connect(); err != nil { + xlog.Error("Unable to dial IRC Server: %v", err) + } + time.Sleep(10 * time.Second) + } + time.Sleep(1 * time.Millisecond) + } +} + +func HandleMessage(l *irc.Line) { + tok := strings.Split(l.Text(), " ") + if len(tok) < 1 { + return + } + switch tok[0] { + case "!version": + //msg := ctcp.Action(fmt.Sprintf("running on %s", SoftwareInfo())) + //sayCh <- fmt.Sprintf("%s\n%s", "*", msg) + //sayCh <- fmt.Sprintf("%s\n%s", "*", SoftwareInfo()) + default: + } +} + +func Ping(bot *irc.Conn) { + for { + time.Sleep(1 * time.Minute) + bot.Raw("PING") + } +} diff --git a/main.go b/main.go index 8f373a5..310b2b5 100644 --- a/main.go +++ b/main.go @@ -37,8 +37,8 @@ func main() { modules.Init(say, *mods) modules.BotNick = strings.ToLower(*nick) switch *protocol { - //case "irc": - // Irc() + case "irc": + Irc(say) case "matrix": Matrix(say) default: