// Create a new Gobot from the given gesture config func CreateGobot(config *Config) *Gobot { bot := &Gobot{config.BotName, config, nil, make(chan bool), nil} flag.Parse() bot.client = irc.SimpleClient(config.BotName) bot.client.SSL = config.SSL bot.client.Flood = config.DisableFloodProtection bot.client.EnableStateTracking() bot.client.AddHandler(irc.CONNECTED, func(conn *irc.Conn, line *irc.Line) { log.Println("Connected to", config.Hostname, "!") for _, channel := range config.Channels { conn.Join(channel) } }) bot.client.AddHandler("JOIN", func(conn *irc.Conn, line *irc.Line) { if line.Nick == bot.Name { log.Printf("Joined %+v\n", line.Args) } }) bot.client.AddHandler(irc.DISCONNECTED, func(conn *irc.Conn, line *irc.Line) { bot.quitter <- true }) bot.client.AddHandler("PRIVMSG", func(conn *irc.Conn, line *irc.Line) { bot.messageReceived(conn, line) }) return bot }
func Init() { lock.Lock() defer lock.Unlock() if irc != nil { return } if *server == "" { // Don't call logging.Fatal as we don't want a backtrace in this case logging.Error("--server option required. \nOptions are:\n") flag.PrintDefaults() os.Exit(1) } // Configure IRC client irc = client.SimpleClient(*nick, "boing", "not really sp0rkle") irc.SSL = *ssl irc.Flood = true HandleFunc(bot_connected, "connected") HandleFunc(bot_disconnected, "disconnected") // This is a special handler that dispatches commands from the command set HandleFunc(bot_command, "privmsg") // This is a special handler that triggers a rebuild and re-exec HandleFunc(bot_rebuild, "notice") // This is a special handler that triggers a shutdown and disconnect HandleFunc(bot_shutdown, "notice") CommandFunc(bot_help, "help", "If you need to ask, you're beyond help.") }
func main() { flag.Parse() last_message = make(map[string]string) c := irc.SimpleClient(*nick) // Add handlers to do things here! // e.g. join a channel on connect. c.HandleFunc("connected", func(conn *irc.Conn, line *irc.Line) { log.Printf("Connected to %s as %s", c.Config().Server, c.Config().Me.Nick) conn.Join(*channel) }) // And a signal on disconnect quit := make(chan bool) c.HandleFunc("disconnected", func(conn *irc.Conn, line *irc.Line) { log.Print("Disconnected") quit <- true }) // Watch for messages c.HandleFunc("PRIVMSG", privmsg) // Tell client to connect. if err := c.ConnectTo(*server); err != nil { fmt.Printf("Connection error: %s\n", err) return } // Wait for disconnect <-quit }
func main() { if len(os.Args) != 4 { log.Fatalf("Usage: %v nickname server channel", os.Args[0]) } var nickname = os.Args[1] var server = os.Args[2] var channel = os.Args[3] log.Printf("Running Pipo") ns, err := nonsentence.New("nonsentence.db") if err != nil { log.Fatal(err) } defer ns.Close() quit := make(chan bool) client := irc.SimpleClient(nickname) client.HandleFunc(irc.CONNECTED, func(conn *irc.Conn, line *irc.Line) { conn.Join(channel) }) client.HandleFunc(irc.DISCONNECTED, func(conn *irc.Conn, line *irc.Line) { quit <- true }) client.HandleFunc(irc.PRIVMSG, func(conn *irc.Conn, line *irc.Line) { log.Printf("Message to %v: %v", line.Target(), line.Text()) // If a channel message is received, store it if line.Target() == channel { // If the message mentioned my name, reply if strings.Contains(line.Text(), nickname) { saySomething(client, channel, ns) } // Ignore first word if it ends with a ':' var words = strings.Fields(line.Text()) if (len(words) > 0) && strings.HasSuffix(words[0], ":") { words = words[1:] } if err := ns.Add(strings.Join(words, " ")); err != nil { log.Printf("Error while adding sentence: %v", err) } } else if !strings.HasPrefix(line.Target(), "#") { // If a private message is received, say something saySomething(client, channel, ns) } }) log.Printf("Connecting...") if err := client.ConnectTo(server); err != nil { log.Fatal(err) } defer client.Quit("Terminating") log.Printf("Connected!") <-quit }
func main() { var p toml.Parser d := p.ParseFile("config/app.conf") twitch := Twitch{ host: d.GetString("twitch.host"), user: d.GetString("twitch.user"), token: d.GetString("twitch.token"), channel: "#" + d.GetString("twitch.channel"), } in := make(chan Input) go inputHandler(in) // make sure emulator window is open h := win32.FindWindow("DeSmuME", "DeSmuME 0.9.10 x64") if h == nil { panic("Couldn't find emulator window.") } fmt.Printf("Emulator Window: %v\n", h) // connect to TwitchTV chat c := irc.SimpleClient(twitch.user) c.AddHandler("connected", func(conn *irc.Conn, line *irc.Line) { c.Join(twitch.channel) }) quit := make(chan bool) c.AddHandler("disconnected", func(conn *irc.Conn, line *irc.Line) { quit <- true }) c.AddHandler("privmsg", func(conn *irc.Conn, line *irc.Line) { if line.Args[0] != twitch.channel { return } user, message := line.Nick, line.Args[1] key, ok := validKeys[message] if !ok { return } in <- Input{ user: user, message: message, key: key, } }) if err := c.Connect(twitch.host, twitch.token); err != nil { panic("Couldn't connect to TwitchTV.") } // keep the connection alive <-quit }
func Connect() { conn = irc.SimpleClient("gmb0t", "gmb0t", "Game Master") conn.EnableStateTracking() conn.AddHandler("connected", postConnect) conn.AddHandler("disconnected", func(c *irc.Conn, l *irc.Line) { Quit <- true }) conn.AddHandler("NOTICE", parseNotice) go parseCommands() conn.Connect(server) }
func main() { quit = make(chan bool) c = irc.SimpleClient("cognito") setupIRCHandlers() if err := c.Connect(server); err != nil { fmt.Printf("Connection error: %s\n", err.Error()) } <-quit }
// Open opens the service and returns a channel which all messages will be sent on. func (i *IRC) Open() (<-chan Message, error) { i.Conn = client.SimpleClient(i.nick, i.nick, i.nick) i.Conn.Config().Version = i.nick i.Conn.Config().QuitMessage = "" i.Conn.HandleFunc("connected", i.onConnect) i.Conn.HandleFunc("disconnected", i.onDisconnect) i.Conn.HandleFunc(client.PRIVMSG, i.onMessage) go i.Conn.ConnectTo(i.host, i.password) return i.messageChan, nil }
func (i *IRC) Connect() { c := irc.SimpleClient(i.Nick) c.SSL = i.SSL connected := make(chan bool) c.AddHandler(irc.CONNECTED, func(conn *irc.Conn, line *irc.Line) { conn.Join(i.Channel) connected <- true }) c.Connect(i.Server) <-connected i.ClientStarted = true i.Client = c }
func main() { flag.Parse() readConfig(flag.Arg(0)) // config.go client := irc.SimpleClient(config.Nick) client.SSL = true client.AddHandler("connected", connected) client.AddHandler("privmsg", message) client.AddHandler("disconnected", disconnected) quit := make(chan bool) err := client.Connect(config.Server) if err != nil { fmt.Printf("Connection Error: %s\n", err) } <-quit }
func NewMettbot(nick string, args ...string) *Mettbot { bot := &Mettbot{ irc.SimpleClient(nick, args...), // *irc.Conn make(chan bool), // Quitted make(chan string), // QuotesPrnt make(chan string), // MettsPrnt make(chan int), // QuotesLinesPrnt make(chan int), // MettsLinesPrnt make(chan string, 4), // Input make(chan bool), // IsMett false, // ReallyQuit make(map[string]string), // Topics 0, // MsgSinceMett } bot.EnableStateTracking() return bot }
func main() { // prepare our zmq sockets context, _ := zmq.NewContext() reqsocket, _ := context.NewSocket(zmq.REQ) subsocket, _ := context.NewSocket(zmq.SUB) defer context.Close() defer reqsocket.Close() defer subsocket.Close() reqsocket.Connect(REQ_SOCKET) subsocket.SetSockOptString(zmq.SUBSCRIBE, SUB_KEY) subsocket.Connect(SUB_SOCKET) // configure our IRC client c := irc.SimpleClient(NICK) // most of the functionality is arranged by adding handlers c.AddHandler("connected", func(conn *irc.Conn, line *irc.Line) { conn.Join(CHANNEL) sendMessage(reqsocket, statusMessage("joined "+CHANNEL)) // spawn a goroutine that will do the ZMQ -> IRC bridge go zmqToIrcLoop(conn, subsocket) }) quit := make(chan bool) c.AddHandler("disconnected", func(conn *irc.Conn, line *irc.Line) { sendMessage(reqsocket, statusMessage("disconnected")) quit <- true }) // this is the handler that gets triggered whenever someone posts // in the channel c.AddHandler("PRIVMSG", func(conn *irc.Conn, line *irc.Line) { // forward messages from IRC -> zmq PUB socket if line.Nick != NICK { sendMessage(reqsocket, Message{"message", line.Nick, line.Args[1]}) } }) // Now we can connect if err := c.Connect("irc.freenode.net"); err != nil { sendMessage(reqsocket, statusMessage("error connecting: "+err.Error())) fmt.Printf("Connection error: %s\n", err.Error()) } // Wait for disconnect <-quit }
// init must be called first on a non-initialized irc // client. It will connect with SSL to a given irc server using a given // username, join a channel and wait for messages func init() { var err error config, err = common.ReadConfigFrom(configurationFilename) if err != nil { panic(err) } // IRC INIT Log("Create irc client") ircClient = irc.SimpleClient(config.Get("ajaxchat", "user")) ircClient.EnableStateTracking() ircClient.SSL = true ircClient.AddHandler(irc.CONNECTED, func(conn *irc.Conn, line *irc.Line) { conn.Join(ircChannel) }) ircClient.AddHandler(irc.DISCONNECTED, func(conn *irc.Conn, line *irc.Line) { Connect() }) ircClient.AddHandler("privmsg", func(conn *irc.Conn, line *irc.Line) { FromIrcMessage <- createMessageFromIrc(line) }) }
func initServerConnection(server Server, quit chan bool) { c := irc.SimpleClient(server.Nick) c.SSL = server.SSL c.SSLConfig = &tls.Config{InsecureSkipVerify: true} c.AddHandler("connected", func(conn *irc.Conn, line *irc.Line) { for _, channel := range server.Channels { conn.Join(channel) } }) c.AddHandler("disconnected", func(conn *irc.Conn, line *irc.Line) { quit <- true }) c.AddHandler("privmsg", func(conn *irc.Conn, line *irc.Line) { matches := urlRegex.FindAllString(line.Args[1], -1) for _, match := range matches { if len(match) >= server.MinLength { blacklist := false for _, item := range server.Blacklist { if strings.Contains(match, item) { blacklist = true continue } } if blacklist { continue } uri, err := goisgd.Shorten(match) if err != nil { continue } conn.Privmsg(line.Args[0], uri) } } }) // Tell client to connect if err := c.Connect(fmt.Sprintf("%s:%d", server.Server, server.Port), server.Password); err != nil { fmt.Printf("Connection error: %v\n", err) } }
func NewWeierBot(server, nick, password string, channels []string) *WeierBot { w := &WeierBot{ server: server, client: irc.SimpleClient(nick), log: make(chan Message, 512), disconnect: make(chan bool), } w.client.Me.Name = nick w.client.Me.Ident = nick w.client.AddHandler("connected", func(conn *irc.Conn, line *irc.Line) { if password != "" { conn.Privmsg("NickServ", "identify "+password) } for _, ch := range channels { log.Printf("Joining %s\n", ch) conn.Join(ch) } }) w.client.AddHandler("disconnected", func(conn *irc.Conn, line *irc.Line) { w.disconnect <- true }) w.client.AddHandler("join", func(conn *irc.Conn, line *irc.Line) { if len(line.Args) >= 1 && strings.HasPrefix(line.Args[0], "#") { conn.Privmsg(line.Nick, fmt.Sprintf("Hallo %s, willkommen auf %s. "+ "Dieser Channel wird unter http://weierbot.tux21b.org/ mitgespeichert.", line.Nick, line.Args[0])) } }) w.client.AddHandler("privmsg", func(conn *irc.Conn, line *irc.Line) { if len(line.Args) < 2 { return } w.handleMessage(line.Args[0], Message{ Nick: line.Nick, Time: line.Time, Message: line.Args[1], }) }) go w.writeLog() return w }
func main() { flag.Parse() // Compile regular expressions which match the greeting words if they // appear as a standalone word. for _, greetword := range strings.SplitN(*greetings, ",", -1) { re := regexp.MustCompile(`\b` + greetword + `\b`) greetings_re = append(greetings_re, re) } my_histogram = histogram.Load(*histogram_path) quit := make(chan bool) c := irc.SimpleClient("Eyo", "i3", "http://i3wm.org/") c.AddHandler("connected", func(conn *irc.Conn, line *irc.Line) { log.Printf("Connected, joining channel %s\n", *irc_channel) conn.Join(*irc_channel) }) c.AddHandler("disconnected", func(conn *irc.Conn, line *irc.Line) { quit <- true }) c.AddHandler("PRIVMSG", handleMessage) log.Printf("Connecting...\n") if err := c.Connect("chat.freenode.net"); err != nil { log.Printf("Connection error: %s\n", err.Error()) } // program main loop for { select { case <-quit: log.Println("Disconnected. Reconnecting...") if err := c.Connect("chat.freenode.net"); err != nil { log.Printf("Connection error: %s\n", err.Error()) } } } log.Fatalln("Fell out of the main loop?!") }
func main() { var err error db, err = sql.Open("sqlite3", "./plusplus.db") if err != nil { fmt.Println(err) return } defer db.Close() c := irc.SimpleClient("plusplusbot", "plusplusbot") c.EnableStateTracking() c.HandleFunc("connected", func(conn *irc.Conn, line *irc.Line) { for _, room := range os.Args[1:] { c.Join("#" + room) } }) quit := make(chan bool) c.HandleFunc("disconnected", func(conn *irc.Conn, line *irc.Line) { quit <- true }) c.HandleFunc("privmsg", func(conn *irc.Conn, line *irc.Line) { println(line.Src, line.Args[0], line.Args[1]) if line.Args[1] == "!++" { go ranking(c, line) } else { parse(line.Args[1], func(nick string, plus int) { go plusplus(c, line, nick, plus) }) } }) for { if err := c.ConnectTo("irc.freenode.net:6667"); err != nil { fmt.Printf("Connection error: %s\n", err) return } <-quit } }
func main() { flag.Parse() // parses the logging flags. c := irc.SimpleClient("slugbot", "slugbot", "slugbot :: GoIRC guts") // Optionally, enable SSL c.SSL = true // Add handlers to do things here! // e.g. join a channel on connect. c.AddHandler("connected", func(conn *irc.Conn, line *irc.Line) { conn.Join("#candlepin") }) // And a signal on disconnect quit := make(chan bool) c.AddHandler("disconnected", func(conn *irc.Conn, line *irc.Line) { quit <- true }) // Tell client to connect if err := c.Connect("irc.freenode.net"); err != nil { fmt.Printf("Connection error: %s\n", err) } // Wait for disconnect <-quit }
func main() { flag.Parse() // create new IRC connection c := irc.SimpleClient(*nick, "etherbot", "the etherpad robot") // c.EnableStateTracking() c.AddHandler("connected", func(conn *irc.Conn, line *irc.Line) { conn.Join(*channel) }) // Set up a handler to notify of disconnect events. quit := make(chan bool) c.AddHandler("disconnected", func(conn *irc.Conn, line *irc.Line) { quit <- true }) // Set up handlers for incoming messages c.AddHandler("PRIVMSG", func(conn *irc.Conn, line *irc.Line) { if match, err := regexp.MatchString(`https?://id\.etherpad\.mozilla\.org/.`, line.Args[1]); match && err == nil { re := regexp.MustCompile(`https?://id\.etherpad\.mozilla\.org/\S+`) pad := re.FindString(line.Args[1]) if len(pad) > 0 { go func() { if isPrivate(pad) { c.Privmsg(line.Args[0], line.Nick+": Please make sure that etherpad is public. Thanks!") } }() } } }) if err := c.Connect(*host); err != nil { fmt.Printf("Connection error: %s\n", err) return } <-quit }
func main() { c := irc.SimpleClient(config.Nick, config.Ident, config.FullName) c.SSL = true c.AddHandler(irc.CONNECTED, func(conn *irc.Conn, line *irc.Line) { conn.Join(config.Channel) log.Println("Connected!") }) quit := make(chan bool) c.AddHandler(irc.DISCONNECTED, func(conn *irc.Conn, line *irc.Line) { quit <- true }) c.AddHandler("PRIVMSG", handleMessage) if err := c.Connect("irc.freenode.net", config.Nick+":"+config.IRCPass); err != nil { log.Fatalln("Connection error: %s\n", err) } <-quit }
func main() { levelTwoUsername = "******" levelTwoServer = "level2-bonus.danopia.net" flagServ = "FlagServ" flag.Parse() c := irc.SimpleClient("lukegbbot") c.SSL = true var myUrl string myUrl = "" var myCommand *exec.Cmd var myStdoutPipe io.ReadCloser var myStdinPipe io.WriteCloser c.AddHandler("connected", func(conn *irc.Conn, line *irc.Line) { log.Println("Connected - joining channels") conn.Join("#level8-bonus") }) quit := make(chan bool) c.AddHandler("disconnected", func(conn *irc.Conn, line *irc.Line) { quit <- true }) c.AddHandler("PRIVMSG", func(conn *irc.Conn, line *irc.Line) { // try matching the regexp lineData := strings.Join(line.Args[1:], " ") sentTo := line.Args[0] //replyTo := line.Args[0] if sentTo[0] != ([]uint8("#"))[0] { sentTo = "__ME__" //replyTo = line.Nick } if sentTo != "__ME__" && line.Nick == flagServ && strings.Contains(lineData, "Go!") && myUrl != "" { // go! myStdinPipe.Write([]byte("\n")) go doTheBreak(conn, myCommand, myStdoutPipe, myUrl) myUrl = "" } else if sentTo != "__ME__" && lineData == "!start" { conn.Privmsg(sentTo, "!join") } if line.Nick == "lukegb" { // extra commands if strings.HasPrefix(lineData, "FB") { conn.Privmsg(sentTo, strings.Replace(lineData, "FB", "!", 1)) } } }) c.AddHandler("NOTICE", func(conn *irc.Conn, line *irc.Line) { // try matching the regexp lineData := strings.Join(line.Args[1:], " ") log.Println(line.Args) sentTo := line.Args[0] //replyTo := line.Args[0] if sentTo[0] != ([]uint8("#"))[0] { sentTo = "__ME__" } if sentTo == "__ME__" && line.Nick == flagServ { // ooh, it's a URL myUrl = strings.Replace(strings.Replace(lineData, "Your CTF endpoint will be <", "", 1), ">", "", 1)[1:67] myCommand = exec.Command("./pingit_recvit", "-servermode", myUrl, levelTwoServer) myStdoutPipe, _ = myCommand.StdoutPipe() myStdinPipe, _ = myCommand.StdinPipe() myCommand.Start() } }) if err := c.Connect("irc.stripe.com:6697"); err != nil { fmt.Printf("Connection error: %s\n", err.Error()) os.Exit(1) } <-quit }
func RunForever(b *cobe.Cobe2Brain, o *Options) { stop := make(chan bool) conn := irc.SimpleClient(o.Nick) conn.Config().Server = o.Server conn.Me().Ident = o.Nick conn.Me().Name = o.Nick conn.HandleFunc("connected", func(conn *irc.Conn, line *irc.Line) { log.Printf("Connected to %s. Joining %s.", o.Server, strings.Join(o.Channels, ", ")) for _, channel := range o.Channels { conn.Join(channel) } }) conn.HandleFunc("disconnected", func(conn *irc.Conn, line *irc.Line) { log.Printf("Disconnected from %s.", o.Server) backoffConnect(conn, o) }) conn.HandleFunc("kick", func(conn *irc.Conn, line *irc.Line) { if line.Args[1] == o.Nick { var channel = line.Args[0] log.Printf("Kicked from %s. Rejoining.", channel) conn.Join(channel) } }) // The space after comma/colon is needed so we won't treat // urls as messages spoken to http. userMsg := regexp.MustCompile(`^(\S+)[,:]\s(.*?)$`) conn.HandleFunc("privmsg", func(conn *irc.Conn, line *irc.Line) { user := line.Nick if in(o.Ignore, user) { log.Printf("Ignoring privmsg from %s", user) return } target := line.Args[0] if !in(o.Channels, target) { log.Printf("Ignoring privmsg on %s", target) return } var to, msg string groups := userMsg.FindStringSubmatch(line.Args[1]) if len(groups) > 0 { to = groups[1] msg = groups[2] } else { msg = line.Args[1] } msg = strings.TrimSpace(msg) log.Printf("Learn: %s", msg) b.Learn(msg) if to == o.Nick { reply := b.Reply(msg) log.Printf("Reply: %s", reply) conn.Privmsg(target, fmt.Sprintf("%s: %s", user, reply)) } }) backoffConnect(conn, o) <-stop }
func main() { serverEightRegexp := regexp.MustCompile(`https://level08-([0-9]).stripe-ctf.com/user-([a-z]{10})/`) serverEightBonusRegexp := regexp.MustCompile(`https://level8-bonus.danopia.net/([a-z0-9]{32})/`) flagNumberRegex := regexp.MustCompile(`[0-9]{12}`) levelTwoUsername = "******" levelTwoServer = "level02-4.stripe-ctf.com" usedMeMap = make(map[string]time.Time) currentUrls = make(map[string]bool) // deserialize from disk knownFlags = make(map[string]*Flag) deserializeFromDisk(&knownFlags) serializeToDisk = make(chan bool) go serializeToDiskLoop() flag.Parse() c := irc.SimpleClient("FlagBot|lukegb") c.SSL = true c.AddHandler("connected", func(conn *irc.Conn, line *irc.Line) { log.Println("Connected - joining channels") conn.Join("#level8") conn.Join("#level8-bottest") conn.Join("#level8-bonus") }) quit := make(chan bool) c.AddHandler("disconnected", func(conn *irc.Conn, line *irc.Line) { quit <- true }) c.AddHandler("PRIVMSG", func(conn *irc.Conn, line *irc.Line) { // try matching the regexp lineData := strings.Join(line.Args[1:], " ") sentTo := line.Args[0] replyTo := line.Args[0] if sentTo[0] != ([]uint8("#"))[0] { sentTo = "__ME__" replyTo = line.Nick } //log.Printf("%s <%s> %s\n", line.Args[0], line.Nick, lineData) matches := serverEightRegexp.FindStringSubmatch(lineData) if matches != nil { meineUrl := fmt.Sprintf("https://level08-%s.stripe-ctf.com/user-%s/", matches[1], matches[2]) log.Printf(" ---> FOUND URL: %s - using %s\n", matches[0], meineUrl) // am I running it already? canRun := lockUrl(meineUrl) if !canRun { log.Printf(" ---> Already running.\n") // ignore it return } // can they use me? canUse := lockUsedMe(line.Host) if line.Nick == "lukegb" || line.Nick == "lukegb_" { canUse = true } if !canUse { unlockUrl(meineUrl) log.Printf(" ---> Denied.\n") conn.Notice(line.Nick, "You've already pasted a URL - I'm not doing another one so fast.") return } // now check to see if this is one I've already done flag, ok := knownFlags[meineUrl] if ok && !(strings.Contains(lineData, "FORCEGRAB") && (line.Nick == "lukegb" || line.Nick == "lukegb_")) { unlockUrl(meineUrl) // oh if flag.Result == 0 || flag.Result == -1 { log.Printf("Hmm, flag.Result was %d\n", flag.Result) // just keep going } else { conn.Privmsg(replyTo, fmt.Sprintf("%s: I've already done that flag. I did it in %ds, %s ago.", line.Nick, int64(flag.Duration.Seconds()), time.Since(flag.BeganAt.Add(flag.Duration)).String())) return } } // wooo conn.Privmsg(replyTo, fmt.Sprintf("%s: I'm off to break %s :)", line.Nick, meineUrl)) go doTheBreak(conn, meineUrl, line.Nick, replyTo, matches[1], matches[2], true) return } // now try matching a l8-bonus round matches = serverEightBonusRegexp.FindStringSubmatch(lineData) if matches != nil { return } // try matching a flag response match := flagNumberRegex.FindString(lineData) if match != "" { mNum, err := strconv.ParseInt(match, 10, 64) if err != nil { conn.Privmsg("lukegb_", "Error parsing string "+match+" to int64 "+err.Error()) return } for _, v := range knownFlags { if v.Result == mNum { if v.Who == line.Nick { if !v.WhoUserFoundIt { conn.Privmsg(replyTo, fmt.Sprintf("%s: Congrats on the capture :)", line.Nick)) v.WhoUserFoundIt = true serializeToDisk <- true } } else { conn.Privmsg(replyTo, fmt.Sprintf("%s: ...was that flag actually yours? ._.", line.Nick)) } break } } return } }) if err := c.Connect("irc.stripe.com:6697"); err != nil { fmt.Printf("Connection error: %s\n", err.Error()) os.Exit(1) } <-quit }
func main() { var irchost = flag.String( "irchost", "localhost", "Hostname of IRC server, eg: irc.example.org:6667") var ircnick = flag.String( "ircnick", "gocat", "Nickname to use for IRC") var ircssl = flag.Bool( "ircssl", false, "Use SSL for IRC connection") var catbind = flag.String( "catbind", ":12345", "net.Listen spec, to listen for IRCCat msgs") var catfam = flag.String( "catfamily", "tcp4", "net.Listen address family for IRCCat msgs") flag.Parse() fmt.Println("Go irccat") // to block main: control := make(chan string) // msgs from tcp catport to this chan: catmsgs := make(chan CatMsg) // channel signaling irc connection status chConnected := make(chan bool) // setup IRC client: c := irc.SimpleClient(*ircnick) c.SSL = *ircssl // Listen on catport: go CatportServer(catmsgs, *catfam, *catbind) go CatMsgSender(catmsgs, c) // loop on IRC dis/connected events setupClient(c, chConnected) for { log.Println("Connecting to IRC...") err := c.Connect(*irchost) if err != nil { log.Println("Failed to connect to IRCd") log.Println(err) continue } for { status := <-chConnected if status { log.Println("Connected to IRC") c.Join("#rjtest") } else { log.Println("Disconnected from IRC") break } } time.Sleep(5 * time.Second) } <-control }
func main() { flag.Parse() go getDocFilenames() // Channel on which the HTTP handler sends lines to IRC. to_irc = make(chan string) quit := make(chan bool) http.HandleFunc("/push_buildbot", func(w http.ResponseWriter, r *http.Request) { // Buildbot sends the packets URL-encoded. if err := r.ParseForm(); err != nil { log.Printf("Could not ParseForm: %s", err.Error()) } // Decode the JSON into BuildbotEvents and send them to IRC if // appropriate. var packets []BuildbotEvent err := json.Unmarshal([]byte(r.Form.Get("packets")), &packets) if err != nil { log.Printf("Could not parse JSON: %s\n", err.Error()) } for _, event := range packets { if event.Ev != nil { to_irc <- event.Ev.AsChatLine() } } }) http.HandleFunc("/push_commit", func(w http.ResponseWriter, r *http.Request) { body, err := ioutil.ReadAll(r.Body) if err != nil { log.Printf("Could not read body: %s\n", err.Error()) return } lines := strings.Split(string(body), "\n") for _, line := range lines { to_irc <- line } }) // Handle HTTP requests in a different Goroutine. go func() { if err := http.ListenAndServe(*listen, nil); err != nil { log.Fatal("ListenAndServer: ", err.Error()) } }() c := irc.SimpleClient(*irc_nick, "i3", "http://build.i3wm.org/") c.HandleFunc("connected", func(conn *irc.Conn, line *irc.Line) { log.Printf("Connected, joining channel %s\n", *irc_channel) conn.Join(*irc_channel) }) c.HandleFunc("disconnected", func(conn *irc.Conn, line *irc.Line) { quit <- true }) c.HandleFunc("PRIVMSG", handleLine) log.Printf("Connecting...\n") if err := c.ConnectTo("chat.freenode.net", *irc_password); err != nil { log.Printf("Connection error: %s\n", err.Error()) } everyDay := make(chan bool) go func() { for { time.Sleep(24 * time.Hour) everyDay <- true } }() // program main loop for { select { case line, _ := <-to_irc: c.Privmsg(*irc_channel, line) case <-everyDay: go getDocFilenames() case <-quit: log.Println("Disconnected. Reconnecting...") if err := c.ConnectTo("chat.freenode.net", *irc_password); err != nil { log.Printf("Connection error: %s\n", err.Error()) } } } log.Fatalln("Fell out of the main loop?!") }
func ircClientRoutine(netConf irclogsme.NetworkConfig, messageChan chan irclogsme.LogMessage, cmdChan chan irclogsme.CommandMessage) { // this is a go routine ircCli := irc.SimpleClient(netConf.Nick, netConf.User, "http://irclogs.me") ircCli.EnableStateTracking() quit := make(chan bool) ircCli.AddHandler("disconnected", func(conn *irc.Conn, line *irc.Line) { LogInfo("(%s) Disconnected?!?", netConf.Name) quit <- true }) var actualChannels []string ircCli.AddHandler("connected", func(conn *irc.Conn, line *irc.Line) { LogInfo("(%s) Connected!") LogInfo("(%s) Executing connection commands.") for _, cmd := range netConf.AuthCommands { LogDebug("(%s) - executing: %s", netConf.Name, cmd) conn.Raw(cmd) } LogInfo("(%s) Joining channels.", netConf.Name) actualChannels := make([]string, 0) for channelName, _ := range netConf.Channels { LogDebug("(%s) - joining %s", netConf.Name, channelName) conn.Join(channelName) actualChannels = append(actualChannels, channelName) time.Sleep(1 * time.Second) } }) ircCli.AddHandler("PRIVMSG", func(conn *irc.Conn, line *irc.Line) { LogDebug("(%s) [%s] <%s> {%s} %s", netConf.Name, line.Time.String(), line.Src, line.Args[0], line.Args[1]) // make a log message! messageChan <- irclogsme.LogMessage{ Type: irclogsme.LMT_PRIVMSG, NetworkId: netConf.Id, Channel: line.Args[0], Payload: line.Args[1], Time: line.Time, Nick: line.Nick, Ident: line.Ident, Host: line.Host, } }) ircCli.AddHandler("NOTICE", func(conn *irc.Conn, line *irc.Line) { LogDebug("(%s) [%s] <%s> {%s} %s", netConf.Name, line.Time.String(), line.Src, line.Args[0], line.Args[1]) if line.Args[0][0] != '#' { return } // make a log message! messageChan <- irclogsme.LogMessage{ Type: irclogsme.LMT_NOTICE, NetworkId: netConf.Id, Channel: line.Args[0], Payload: line.Args[1], Time: line.Time, Nick: line.Nick, Ident: line.Ident, Host: line.Host, } }) ircCli.AddHandler("TOPIC", func(conn *irc.Conn, line *irc.Line) { LogDebug("(%s) [%s] <%s> {%s} %s", netConf.Name, line.Time.String(), line.Src, line.Args[0], line.Args[1]) // make a log message! messageChan <- irclogsme.LogMessage{ Type: irclogsme.LMT_TOPIC, NetworkId: netConf.Id, Channel: line.Args[0], Payload: line.Args[1], Time: line.Time, Nick: line.Nick, Ident: line.Ident, Host: line.Host, } }) ircCli.AddHandler("JOIN", func(conn *irc.Conn, line *irc.Line) { LogDebug("(%s) [%s] <%s> joined %s", netConf.Name, line.Time.String(), line.Src, line.Args[0]) // make a log message! messageChan <- irclogsme.LogMessage{ Type: irclogsme.LMT_JOIN, NetworkId: netConf.Id, Channel: line.Args[0], Time: line.Time, Nick: line.Nick, Ident: line.Ident, Host: line.Host, } }) ircCli.AddHandler("PART", func(conn *irc.Conn, line *irc.Line) { var message string if len(line.Args) > 1 { message = line.Args[1] } LogDebug("(%s) [%s] <%s> parted %s: %s", netConf.Name, line.Time.String(), line.Src, line.Args[0], message) // make a log message! messageChan <- irclogsme.LogMessage{ Type: irclogsme.LMT_PART, NetworkId: netConf.Id, Channel: line.Args[0], Payload: message, Time: line.Time, Nick: line.Nick, Ident: line.Ident, Host: line.Host, } }) ircCli.AddHandler("KICK", func(conn *irc.Conn, line *irc.Line) { var message string if len(line.Args) > 2 { message = line.Args[2] } channel := line.Args[0] who := line.Args[1] LogDebug("(%s) [%s] <%s> kicked %s from %s: %s", netConf.Name, line.Time.String(), line.Src, who, channel, message) // make a log message! messageChan <- irclogsme.LogMessage{ Type: irclogsme.LMT_PART, NetworkId: netConf.Id, Channel: channel, Payload: message, Target: who, Time: line.Time, Nick: line.Nick, Ident: line.Ident, Host: line.Host, } }) ircCli.AddHandler("QUIT", func(conn *irc.Conn, line *irc.Line) { var message string if len(line.Args) > 0 { message = line.Args[0] } LogDebug("(%s) [%s] <%s> quit: %s", netConf.Name, line.Time.String(), line.Src, message) theirNick := conn.ST.GetNick(line.Nick) outChannels := make([]string, 0) for _, channel := range actualChannels { if _, ok := theirNick.IsOnStr(channel); ok { outChannels = append(outChannels, channel) } } // make a log message! for _, outChannel := range outChannels { messageChan <- irclogsme.LogMessage{ Type: irclogsme.LMT_QUIT, NetworkId: netConf.Id, Payload: message, Channel: outChannel, Time: line.Time, Nick: line.Nick, Ident: line.Ident, Host: line.Host, } } }) ircCli.AddHandler("ACTION", func(conn *irc.Conn, line *irc.Line) { var message string if len(line.Args) > 1 { message = line.Args[1] } LogDebug("(%s) [%s] * %s %s", netConf.Name, line.Time.String(), line.Src, message) messageChan <- irclogsme.LogMessage{ Type: irclogsme.LMT_ACTION, NetworkId: netConf.Id, Channel: line.Args[0], Payload: message, Time: line.Time, Nick: line.Nick, Ident: line.Ident, Host: line.Host, } }) currentServer := 0 LogInfo("(%s) starting loop", netConf.Name) for { LogInfo("(%s) CONNECTING", netConf.Name) ircCli.Connect(netConf.IrcServers[currentServer]) superloop := true for superloop { select { case <-quit: break case cmdmsg := <-cmdChan: LogDebug("(%s) Got Command: %x", netConf.Name, cmdmsg) switch cmdmsg.Type { case irclogsme.CMT_CONNECT: LogDebug("(%s) connect unimplemented!", netConf.Name) case irclogsme.CMT_DISCONNECT: LogDebug("(%s) disconnecting...") ircCli.Quit("disconnecting...") // waiting for next command for { cmdmsg := <-cmdChan LogDebug("(%s) Got Command while d/ced: %x", netConf.Name, cmdmsg) if cmdmsg.Type == irclogsme.CMT_CONNECT { LogInfo("(%s) Reconnecting...", netConf.Name) superloop = false break } else { LogInfo("(%s) Command dropped!") } } case irclogsme.CMT_START_LOGGING: LogDebug("(%s) joining channel %s", netConf.Name, cmdmsg.Channel) ircCli.Join(cmdmsg.Channel) actualChannels = append(actualChannels, cmdmsg.Channel) case irclogsme.CMT_STOP_LOGGING: LogDebug("(%s) parting channel %s", netConf.Name, cmdmsg.Channel) ircCli.Part(cmdmsg.Channel, "told to part") nuker := -1 for k, v := range actualChannels { if v == cmdmsg.Channel { nuker = k } } if nuker != -1 { actualChannels = append(actualChannels[:nuker], actualChannels[nuker+1:]...) } case irclogsme.CMT_TELL: LogDebug("(%s) telling <%s> %s", netConf.Name, cmdmsg.Target, cmdmsg.Message) ircCli.Privmsg(cmdmsg.Target, cmdmsg.Message) } } } time.Sleep(1 * time.Second) currentServer = (currentServer + 1) % len(netConf.IrcServers) } }
func (sys *IrcSubSystem) Run(channelIn, channelOut chan msgsystem.Message) { if len(sys.irchost) == 0 { return } // channel signaling irc connection status sys.ConnectedState = make(chan bool) // setup IRC client: sys.client = irc.SimpleClient(sys.ircnick, "ircflu", "ircflu") sys.client.Config().SSL = sys.ircssl sys.client.HandleFunc("connected", func(conn *irc.Conn, line *irc.Line) { sys.ConnectedState <- true }) sys.client.HandleFunc("disconnected", func(conn *irc.Conn, line *irc.Line) { sys.ConnectedState <- false }) sys.client.HandleFunc("PRIVMSG", func(conn *irc.Conn, line *irc.Line) { channel := line.Args[0] text := "" if len(line.Args) > 1 { text = line.Args[1] } if channel == sys.ircnick { log.Println("PM from " + line.Src) channel = line.Src // replies go via PM too. } else { log.Println("Message in channel " + line.Args[0] + " from " + line.Src) } msg := msgsystem.Message{ To: []string{channel}, Msg: text, Source: line.Src, Authed: auth.IsAuthed(line.Src), } channelIn <- msg }) // loop on IRC dis/connected events go func() { for { log.Println("Connecting to IRC:", sys.irchost) sys.client.Config().Server = sys.irchost sys.client.Config().Pass = sys.ircpassword err := sys.client.Connect() if err != nil { log.Println("Failed to connect to IRC:", sys.irchost) log.Println(err) continue } for { status := <-sys.ConnectedState if status { log.Println("Connected to IRC:", sys.irchost) if len(sys.channels) == 0 { // join default channel sys.Join(sys.ircchannel) } else { // we must have been disconnected, rejoin channels sys.Rejoin() } } else { log.Println("Disconnected from IRC:", sys.irchost) break } } time.Sleep(5 * time.Second) } }() }
func main() { // Parse flags from command line flag.Parse() log := logging.InitFromFlags() // setup logging log.SetLogLevel(2) if _, err := os.Stat(*config_file); err != nil { generate_config_file(*config_file) log.Error("You must edit the " + *config_file + " file before continuing") os.Exit(0) } //generate a config file if it isn't found if *generate_config { generate_config_file(*config_file) log.Error("You must edit the " + *config_file + " file before continuing") os.Exit(0) } // handle configuration log.Info("Read configuration file: " + *config_file) settings := yaml.New() settings.Read(*config_file) if *channel == "" { *channel = settings.Get("connection/channel").(string) log.Debug("Read channel from config file: " + *channel) } else { log.Debug("Read channel from flag: " + *channel) } if *nick == "" { *nick = settings.Get("connection/nick").(string) log.Debug("Read nick from config file: " + *nick) } else { log.Debug("Read nick from flag: " + *nick) } if *realname == "" { *realname = settings.Get("connection/realname").(string) log.Debug("Read realname from config file: " + *realname) } else { log.Debug("Read realname from flag: " + *realname) } if *irc_server == "" { *irc_server = settings.Get("connection/irc_server").(string) log.Debug("Read irc_server from config file: " + *irc_server) } else { log.Debug("Read irc_server from flag: " + *irc_server) } if *rejoin_on_kick == true { *rejoin_on_kick = settings.Get("bot_config/rejoin_on_kick").(bool) log.Debug("Read rejoin_on_kick from config file: %t ", *rejoin_on_kick) } else { log.Debug("Read rejoin_on_kick from flag: %t ", *rejoin_on_kick) } // bitly shorturl_enabled := settings.Get("bitly/shorturls_enabled").(bool) bitly_username := settings.Get("bitly/username").(string) bitly_api_key := settings.Get("bitly/api_key").(string) if shorturl_enabled { bitly.SetUser(bitly_username) bitly.SetKey(bitly_api_key) } owner_nick := to.String(settings.Get("bot_config/owner")) friends := to.List(settings.Get("bot_config/friends")) trusted_identities := make([]string, 0) trusted_identities = append(trusted_identities, owner_nick) for _, value := range friends { trusted_identities = append(trusted_identities, value.(string)) } // set up bot command event registry bot_command_registry := event.NewRegistry() reallyquit := false // Bot command handlers // addfriend addfriend_state := make(chan string) bot_command_registry.AddHandler(NewHandler(func(conn *irc.Conn, line *irc.Line, commands []string) { if line.Src == owner_nick { channel := line.Args[0] if len(commands) > 1 { target := commands[1] log.Debug("adding friend: %q", target) conn.Whois(target) log.Debug("triggering channel: %q", target) addfriend_state <- target } else { conn.Privmsg(channel, line.Nick+": use !addfriend <friend nick>") } } }), "addfriend") //save bot_command_registry.AddHandler(NewHandler(func(conn *irc.Conn, line *irc.Line, commands []string) { if line.Src == owner_nick { channel := line.Args[0] conn.Privmsg(channel, line.Nick+": saving settings") settings.Set("bot_config/friends", friends) settings.Write(*config_file) log.Info("%q", to.List(settings.Get("bot_config/friends"))) } }), "save") //reload bot_command_registry.AddHandler(NewHandler(func(conn *irc.Conn, line *irc.Line, commands []string) { if line.Src == owner_nick { channel := line.Args[0] conn.Privmsg(channel, line.Nick+": reloading settings") friends := to.List(settings.Get("bot_config/friends")) trusted_identities = make([]string, 0) trusted_identities = append(trusted_identities, owner_nick) for _, value := range friends { trusted_identities = append(trusted_identities, value.(string)) } log.Info("%q", to.List(settings.Get("bot_config/friends"))) } }), "reload") // op bot_command_registry.AddHandler(NewHandler(func(conn *irc.Conn, line *irc.Line, commands []string) { if Trust(line.Src, trusted_identities) { channel := line.Args[0] if len(commands) > 1 { target := commands[1] log.Info("Oping user: "******"+o "+target) } else { log.Info("Oping user: "******"+o "+line.Nick) } } }), "op") //deop bot_command_registry.AddHandler(NewHandler(func(conn *irc.Conn, line *irc.Line, commands []string) { if Trust(line.Src, trusted_identities) { channel := line.Args[0] if len(commands) > 1 { target := commands[1] conn.Mode(channel, "-o "+target) } else { conn.Mode(channel, "-o "+line.Nick) } } }), "deop") // kick bot_command_registry.AddHandler(NewHandler(func(conn *irc.Conn, line *irc.Line, commands []string) { if Trust(line.Src, trusted_identities) { channel := line.Args[0] if len(commands) > 1 { target := commands[1] kick_message := "get out" if len(commands) > 2 { //this doesn't work. Need to fix. kick_message = commands[2] } //do'nt kick if owner if target != strings.Split(owner_nick, "!")[0] { //don't kick if self if *nick != target { conn.Kick(channel, target, kick_message) } else { conn.Privmsg(channel, line.Nick+": why would i kick myself?") } } else { conn.Privmsg(channel, line.Nick+": why would i kick my lovely friend "+target+"?") } } else { conn.Privmsg(channel, line.Nick+": invalid command") } } }), "kick") //quit bot_command_registry.AddHandler(NewHandler(func(conn *irc.Conn, line *irc.Line, commands []string) { if line.Src == owner_nick { quit_message := "i died" reallyquit = true if len(commands) > 1 { quit_message = commands[1] } conn.Quit(quit_message) } }), "quit") //urlshortener bot_command_registry.AddHandler(NewHandler(func(conn *irc.Conn, line *irc.Line, commands []string) { log.Info("URLS event") channel := line.Args[0] for _, long_url := range commands { work_url := long_url work_urlr := regexp.MustCompile(`^[\w-]+://([^/?]+)(/(?:[^/?]+/)*)?([^./?][^/?]+?)?(\.[^.?]*)?(\?.*)?$`) url_parts := work_urlr.FindAllStringSubmatch(work_url, -1) domain := url_parts[0][1] ext := url_parts[0][4] forbidden_extensions := "png|gif|jpg|mp3|avi|md|zip" extension_regex := regexp.MustCompile(`(` + forbidden_extensions + `)`) extension_test := extension_regex.FindAllStringSubmatch(ext, -1) title := "" url_util_channel := make(chan string) if extension_test == nil { go grab_title(work_url, url_util_channel) title = <-url_util_channel } go shorten_url(work_url, url_util_channel, bitly_username, bitly_api_key) short_url := <-url_util_channel output := "" if short_url != long_url { output = output + "<" + short_url + "> (at " + domain + ") " } if title != "" { output = output + " " + title } conn.Privmsg(channel, output) } }), "urlshortener") // create new IRC connection log.Info("create new IRC connection") irc_client := irc.SimpleClient(*nick, *realname) // IRC HANDLERS! irc_client.EnableStateTracking() irc_client.AddHandler("connected", func(conn *irc.Conn, line *irc.Line) { log.Info("connected as " + *nick) conn.Join(*channel) }) // Set up a handler to notify of disconnect events. quit := make(chan bool) irc_client.AddHandler("disconnected", func(conn *irc.Conn, line *irc.Line) { log.Info("disconnected") quit <- true }) //Handle Private messages irc_client.AddHandler("PRIVMSG", func(conn *irc.Conn, line *irc.Line) { log.Info("privmsg") irc_input := strings.ToLower(line.Args[1]) if strings.HasPrefix(irc_input, *command_char) { irc_command := strings.Split(irc_input[1:], " ") bot_command_registry.Dispatch(irc_command[0], conn, line, irc_command) } url_regex := regexp.MustCompile(`\b(([\w-]+://?|www[.])[^\s()<>]+(?:\([\w\d]+\)|([^[:punct:]\s]|/)))`) urls := url_regex.FindAllString(irc_input, -1) if len(urls) > 0 { bot_command_registry.Dispatch("urlshortener", conn, line, urls) } }) //handle kick by rejoining kicked channel irc_client.AddHandler("KICK", func(conn *irc.Conn, line *irc.Line) { log.Info("Kicked from " + line.Args[0]) if *rejoin_on_kick { log.Info("rejoining " + line.Args[0]) conn.Join(line.Args[0]) } }) //notify on 332 - topic reply on join to channel irc_client.AddHandler("332", func(conn *irc.Conn, line *irc.Line) { log.Debug("Topic is %q, on %q ", line.Args[2], line.Args[1]) }) //notify on MODE irc_client.AddHandler("MODE", func(conn *irc.Conn, line *irc.Line) { for _, v := range line.Args { log.Info("mode: %q ", v) } }) //notify on WHOIS irc_client.AddHandler("311", func(conn *irc.Conn, line *irc.Line) { addedfriend := <-addfriend_state log.Info("addfriend channel: %q", addedfriend) if addedfriend == line.Args[1] { friend := line.Args[1] + "!" + line.Args[2] + "@" + line.Args[3] log.Debug("added friend " + friend) trusted_identities = append(trusted_identities, friend) friends = append(friends, friend) log.Debug("friends: %q", friends) conn.Privmsg(strings.Split(owner_nick, "!")[0], line.Nick+": added "+line.Args[1]+" as friend") //addfriend_state <- "" } else { log.Info("addfriend channel is empty: %q", addedfriend) } }) //notify on join irc_client.AddHandler("JOIN", func(conn *irc.Conn, line *irc.Line) { log.Info("Joined " + line.Args[0]) }) //handle topic changes irc_client.AddHandler("TOPIC", func(conn *irc.Conn, line *irc.Line) { log.Info("Topic on " + line.Args[0] + " changed to: " + line.Args[1]) }) // set up a goroutine to read commands from stdin if *generate_config == false { for !reallyquit { // connect to server if err := irc_client.Connect(*irc_server); err != nil { fmt.Printf("Connection error: %s\n", err) return } // wait on quit channel <-quit } } }
func main() { flag.Parse() // create new IRC connection c := irc.SimpleClient("GoTest", "gotest") c.EnableStateTracking() c.AddHandler("connected", func(conn *irc.Conn, line *irc.Line) { conn.Join(*channel) }) // Set up a handler to notify of disconnect events. quit := make(chan bool) c.AddHandler("disconnected", func(conn *irc.Conn, line *irc.Line) { quit <- true }) // set up a goroutine to read commands from stdin in := make(chan string, 4) reallyquit := false go func() { con := bufio.NewReader(os.Stdin) for { s, err := con.ReadString('\n') if err != nil { // wha?, maybe ctrl-D... close(in) break } // no point in sending empty lines down the channel if len(s) > 2 { in <- s[0 : len(s)-1] } } }() // set up a goroutine to do parsey things with the stuff from stdin go func() { for cmd := range in { if cmd[0] == ':' { switch idx := strings.Index(cmd, " "); { case cmd[1] == 'd': fmt.Printf(c.String()) case cmd[1] == 'f': if len(cmd) > 2 && cmd[2] == 'e' { // enable flooding c.Flood = true } else if len(cmd) > 2 && cmd[2] == 'd' { // disable flooding c.Flood = false } for i := 0; i < 20; i++ { c.Privmsg("#", "flood test!") } case idx == -1: continue case cmd[1] == 'q': reallyquit = true c.Quit(cmd[idx+1 : len(cmd)]) case cmd[1] == 'j': c.Join(cmd[idx+1 : len(cmd)]) case cmd[1] == 'p': c.Part(cmd[idx+1 : len(cmd)]) } } else { c.Raw(cmd) } } }() for !reallyquit { // connect to server if err := c.Connect(*host); err != nil { fmt.Printf("Connection error: %s\n", err) return } // wait on quit channel <-quit } }
func main() { flag.Parse() if *apiKey == "" { log.Fatalln("Missing API key, provide one using -api-key") } lfm = lastfm.New(*apiKey) loadNickMap() loadCache() cacheCleaner := time.Tick(time.Hour) go func() { for _ = range cacheCleaner { cleanCache() } }() if *cacheFile != "" { cleanCache() cacheTimer = time.NewTimer(time.Hour) cacheTimer.Stop() go func() { for _ = range cacheTimer.C { saveCacheNow() } }() } if *server == "" { log.Fatalln("No server to connect to") } if *channelList == "" { log.Fatalln("No channels to join") } irc := client.SimpleClient(*botNick) irc.SSL = *useSSL irc.Flood = false // TODO: CA management? irc.SSLConfig = &tls.Config{InsecureSkipVerify: true} addNickHandlers(irc) addWhoHandlers(irc) irc.AddHandler(client.CONNECTED, func(irc *client.Conn, line *client.Line) { if *nickPass != "" { if irc.Me.Nick != *botNick { log.Println("Nick", *botNick, "was not available; trying to retake it") irc.Privmsg("NickServ", fmt.Sprintf("GHOST %s %s", *botNick, *nickPass)) } else { log.Println("Identifying with NickServ") irc.Privmsg("NickServ", fmt.Sprintf("IDENTIFY %s", *nickPass)) } } log.Println("Connected; joining", *channelList) irc.Join(*channelList) }) irc.AddHandler("NOTICE", func(irc *client.Conn, line *client.Line) { if strings.ToLower(line.Nick) == "nickserv" { log.Println("NickServ:", line.Args[1]) switch { case strings.Contains(strings.ToLower(line.Args[1]), "ghost"): log.Println("Ghost command successful") log.Println("Changing nick to", *botNick) irc.Nick(*botNick) case strings.Contains(line.Args[1], "identified"), strings.Contains(line.Args[1], "recognized"): log.Println("Successfully identified with NickServ; joining", *channelList) irc.Join(*channelList) } } }) irc.AddHandler("QUIT", func(irc *client.Conn, line *client.Line) { if line.Nick == *botNick { log.Println("Nick", *botNick, "now available, changing to it") irc.Nick(*botNick) } }) irc.AddHandler("NICK", func(irc *client.Conn, line *client.Line) { if line.Args[len(line.Args)-1] == irc.Me.Nick { log.Println("Nick successfully changed to", irc.Me.Nick) if *nickPass != "" { log.Println("Identifying with NickServ") irc.Privmsg("NickServ", fmt.Sprintf("IDENTIFY %s", *nickPass)) } } }) irc.AddHandler("332", func(irc *client.Conn, line *client.Line) { log.Println("Joined", line.Args[1]) }) irc.AddHandler("INVITE", onInvite) irc.AddHandler("PRIVMSG", onPrivmsg) quitting := false quit := make(chan bool) irc.AddHandler(client.DISCONNECTED, func(irc *client.Conn, line *client.Line) { if quitting { quit <- true return } resetIdentifiedCache() log.Println("Disconnected; waiting 10 seconds then reconnecting...") saveCacheNow() go func() { time.Sleep(10 * time.Second) log.Println("Reconnecting...") irc.Connect(*server, *password) }() }) if *useSSL { log.Println("Using SSL") } log.Println("Connecting to", *server) irc.Connect(*server, *password) sig = make(chan os.Signal, 1) signal.Notify(sig, os.Interrupt, os.Kill, syscall.SIGTERM) <-sig quitting = true log.Println("Disconnecting") irc.Quit("Exiting") saveCacheNow() <-quit // wait until the QUIT is sent to server }