// vi:ts=4:sts=4:sw=4:noet:tw=72 // // flokatirc // // Copyright (c) 2015,2016 Andreas Neue package main import ( "flag" "fmt" "runtime" "strings" "time" "code.dnix.de/an/xlog" "github.com/nickvanw/ircx" "github.com/sorcix/irc" "github.com/sorcix/irc/ctcp" "flokatirc/modules" "flokatirc/version" ) 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") mods = flag.String("mods", "", "Modules to load") params = flag.String("params", "", "Module params") autocmd = flag.String("autocmd", "", "Autosend IRC command") ) func init() { flag.Parse() } var ( sayCh chan string ) func main() { sayCh = make(chan string, 1024) xlog.Init(xlog.INFO) //bot := ircx.Classic(*server, *name) cfg := ircx.Config{User: *name, MaxRetries: 1000} bot := ircx.New(*server, *name, cfg) xlog.Info("%s started", SoftwareInfo()) xlog.Info("Logging in") if err := bot.Connect(); err != nil { xlog.Fatal("Unable to dial IRC Server: %v", err) } //mods := strings.Split(*modules, ",") //TODO: implement more robust list parsing modules.Init(sayCh, *mods, *params) 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) } } }() go Ping(bot) if *autocmd != "" { println(*autocmd) bot.Sender.Send(&irc.Message{Command: *autocmd}) } RegisterHandlers(bot) bot.HandleLoop() xlog.Info("Exiting") } func RegisterHandlers(bot *ircx.Bot) { xlog.Info("Registering handlers") bot.HandleFunc(irc.RPL_WELCOME, ConnectHandler) bot.HandleFunc(irc.PING, PingHandler) bot.HandleFunc(irc.PRIVMSG, PrivmsgHandler) } func Ping(bot *ircx.Bot) { for { time.Sleep(1 * time.Minute) bot.Sender.Send(&irc.Message{Command: irc.PING}) } } func ConnectHandler(s ircx.Sender, m *irc.Message) { if *nspass != "" { xlog.Info("Authenticating with NickServ: %v, %v", *name, *nspass) s.Send(&irc.Message{ Command: irc.PRIVMSG, Params: []string{*nsname}, Trailing: "IDENTIFY " + *name + " " + *nspass, }) } xlog.Info("Joining channels: %v", *channels) for _, ch := range strings.Split(*channels, ",") { s.Send(&irc.Message{ Command: irc.JOIN, Params: []string{ch}, }) } time.Sleep(2 * time.Second) msg := ctcp.Action(fmt.Sprintf("running on %s", SoftwareInfo())) sayCh <- fmt.Sprintf("%s\n%s", "*", msg) } func PingHandler(s ircx.Sender, m *irc.Message) { xlog.Info("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) modules.HandleMessage(m) } func HandleMessage(m *irc.Message) { tok := strings.Split(m.Trailing, " ") 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 SoftwareInfo() string { return fmt.Sprintf("flokatirc %s-%s (built %s [%s])", version.FlokatiVersion, version.FlokatiBuild, version.FlokatiBuilddate, runtime.Version()) }