// vi:ts=4:sts=4:sw=4:noet:tw=72 // // flokatirc // // Copyright (c) 2015,2016 Andreas Neue package main import ( "flag" "fmt" "log" "strings" "time" "github.com/nickvanw/ircx" "github.com/sorcix/irc" "flokatirc/version" modfortune "flokatirc/modules/fortune" modrss "flokatirc/modules/rss" modsaytime "flokatirc/modules/saytime" modsc "flokatirc/modules/sc" modstoll "flokatirc/modules/stoll" modtwitch "flokatirc/modules/twitch" modweather "flokatirc/modules/weather" ) var ( name = flag.String("name", "Flokati", "Nickname to use") server = flag.String("server", "chat.freenode.org:6667", "Host:Port to connect to") channels = flag.String("chan", "#test", "Channels to join") nsname = flag.String("nsname", "NickServ", "NickServ name") nspass = flag.String("nspass", "", "NickServ password") modules = flag.String("modules", "rss,starcitizen,fortune,saytime", "Module list, comma separated") ) func init() { flag.Parse() } var ( sayCh chan string ) func main() { sayCh = make(chan string, 1024) //bot := ircx.Classic(*server, *name) cfg := ircx.Config{User: *name, MaxRetries: 1000} bot := ircx.New(*server, *name, cfg) log.Printf("%s started", SoftwareInfo()) log.Println("Logging in") if err := bot.Connect(); err != nil { log.Panicln("Unable to dial IRC Server:", err) } //mods := strings.Split(*modules, ",") //TODO: implement more robust list parsing //XXX: this sucks if strings.Contains(*modules, "rss") { go modrss.Init(sayCh, "newsfeeds.conf") } if strings.Contains(*modules, "starcitizen") { go modsc.Init(sayCh) } if strings.Contains(*modules, "fortune") { go modfortune.Init(sayCh) } if strings.Contains(*modules, "stoll") { go modstoll.Init(sayCh) } if strings.Contains(*modules, "saytime") { go modsaytime.Init(sayCh) } if strings.Contains(*modules, "twitch") { go modtwitch.Init(sayCh) } if strings.Contains(*modules, "weather") { go modweather.Init(sayCh) } go func() { for { var targets string line := strings.Split(<-sayCh, "\n") if len(line) < 2 { continue } if line[0] != "*" { targets = line[0] } else { targets = *channels } for _, tar := range strings.Split(targets, ",") { bot.Sender.Send(&irc.Message{ Command: irc.PRIVMSG, Params: []string{tar}, Trailing: line[1], }) time.Sleep(1 * time.Second) } } }() RegisterHandlers(bot) bot.HandleLoop() log.Println("Exiting") } func RegisterHandlers(bot *ircx.Bot) { log.Println("Registering handlers") bot.HandleFunc(irc.RPL_WELCOME, ConnectHandler) bot.HandleFunc(irc.PING, PingHandler) bot.HandleFunc(irc.PRIVMSG, PrivmsgHandler) } func ConnectHandler(s ircx.Sender, m *irc.Message) { if *nspass != "" { log.Printf("Authenticating with NickServ: %v, %v", *name, *nspass) s.Send(&irc.Message{ Command: irc.PRIVMSG, Params: []string{*nsname}, Trailing: "IDENTIFY " + *name + " " + *nspass, }) } log.Printf("Joining channels: %v", *channels) for _, ch := range strings.Split(*channels, ",") { s.Send(&irc.Message{ Command: irc.JOIN, Params: []string{ch}, }) } time.Sleep(5 * time.Second) //sayCh <- fmt.Sprintf("%s\n\001ACTION running on %s", "*", SoftwareInfo()) sayCh <- fmt.Sprintf("%s\n%s", "*", SoftwareInfo()) } func PingHandler(s ircx.Sender, m *irc.Message) { log.Println("PingPong") s.Send(&irc.Message{ Command: irc.PONG, Params: m.Params, Trailing: m.Trailing, }) } func PrivmsgHandler(s ircx.Sender, m *irc.Message) { //TODO: implement message handler table HandleMessage(m) modsc.HandleMessage(m) modfortune.HandleMessage(m) modstoll.HandleMessage(m) modsaytime.HandleMessage(m) modtwitch.HandleMessage(m) modweather.HandleMessage(m) } func HandleMessage(m *irc.Message) { tok := strings.Split(m.Trailing, " ") if len(tok) < 1 { return } switch tok[0] { case "!version": //sayCh <- fmt.Sprintf("%s\n\001ACTION running on %s", "*", SoftwareInfo()) sayCh <- fmt.Sprintf("%s\n%s", "*", SoftwareInfo()) default: } } func SoftwareInfo() string { return fmt.Sprintf("flokatirc %s-%s (built %s)", version.FlokatiVersion, version.FlokatiBuild, version.FlokatiBuilddate) }