Пример #1
0
func Connect(ctx *cli.Context) {
	fmt.Printf("Connecting to %s...\n", RC.Host)
	// create new IRC connection
	cfg := irc.NewConfig(RC.Nick, "rusty")
	cfg.SSL = RC.SSL

	if cfg.SSL {
		cfg.SSLConfig = &tls.Config{
			MinVersion:         0,
			MaxVersion:         0,
			InsecureSkipVerify: false,
			ServerName:         RC.Host,
			CipherSuites: []uint16{
				tls.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
				tls.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
				tls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
				tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
				tls.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,
				tls.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,
				tls.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,
				tls.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,
				tls.TLS_RSA_WITH_AES_256_CBC_SHA,
			},
		}
	}
	cfg.Server = fmt.Sprintf("%s:%d", RC.Host, RC.Port)
	cfg.NewNick = func(n string) string { return n + "_" }
	c := irc.Client(cfg)
	c.EnableStateTracking()
	c.HandleFunc(irc.CONNECTED,
		func(conn *irc.Conn, line *irc.Line) {
			fmt.Printf("Connected to %s\n", RC.Host)
			conn.Join(RC.Channel)
		})

	// Set up a handler to notify of disconnect events.
	quit := make(chan bool)
	c.HandleFunc(irc.DISCONNECTED,
		func(conn *irc.Conn, line *irc.Line) { quit <- true })

	c.HandleFunc(irc.JOIN, func(conn *irc.Conn, line *irc.Line) {
		if line.Nick == conn.Config().Me.String() && line.Args[0] == RC.Channel {
			fmt.Printf("Joined channel %s\n", RC.Channel)
		}
	})

	c.HandleFunc(irc.PRIVMSG, handle_privmsg)

	reallyquit := false
	for !reallyquit {
		// connect to server
		if err := c.ConnectTo(RC.Host); err != nil {
			fmt.Printf("Connection error: %s\n", err)
			return
		}
		// wait on quit channel
		<-quit
	}

}
Пример #2
0
func New(pc config.Config) plug.Plug {
	st := &state.Nick{
		Nick:  pc.Identity.Nick[0],
		Ident: pc.Identity.RealName,
		Name:  globals.Name(),
	}
	cf := &client.Config{
		Server:   pc.Connection.Addr,
		Pass:     pc.Identity.Password,
		Me:       st,
		NewNick:  nextNick(pc.Identity.Nick),
		Version:  globals.Version(),
		PingFreq: PING_FREQ,
		SplitLen: SPLIT_LEN,
		Timeout:  TIMEOUT,
		Recover:  logPanic,
		Flood:    true,
	}
	cl := client.Client(cf)
	p := &IRCPlug{
		config:  pc,
		client:  cl,
		endloop: make(chan bool),
		changes: make(chan plug.Change, CHANGE_CAPACITY),
	}
	cl.HandleFunc(client.CONNECTED, p.onConnected)
	cl.HandleFunc(client.DISCONNECTED, p.onDisconnected)
	cl.HandleFunc(client.PRIVMSG, p.onMessage)
	cl.HandleFunc(client.TOPIC, p.onTopic)
	return p
}
Пример #3
0
func main() {
	config := loadConfig()

	irclog.SetLogger(LogrusAdapter{*log})

	ircCfg := config.Network.GoIrcConfig()
	c := irc.Client(ircCfg)
	c.EnableStateTracking()

	module.InitModules(c, config)

	c.HandleFunc(irc.CONNECTED, func(conn *irc.Conn, line *irc.Line) {
		for _, cmd := range config.Network.OnConnectCmds {
			conn.Raw(cmd)
		}
		for channel, _ := range config.Network.Channels {
			conn.Join(channel)
		}
	})

	quit := make(chan bool)
	c.HandleFunc(irc.DISCONNECTED,
		func(conn *irc.Conn, line *irc.Line) { quit <- true })

	if err := c.ConnectTo(config.Network.Server); err != nil {
		panic(err)
	}

	// Wait for disconnect
	<-quit

}
Пример #4
0
func main() {

	ircConf := irc.NewConfig("doctwitchbot")
	ircConf.Server = "irc.freenode.net:6667"
	bot := irc.Client(ircConf)

	bot.HandleFunc(irc.CONNECTED, func(conn *irc.Conn, line *irc.Line) {
		fmt.Printf("Connected to IRC server\n")
		conn.Join("#mychannel")
		fmt.Printf("Joined channel.\n")
	})

	bot.HandleFunc(irc.PRIVMSG, func(conn *irc.Conn, line *irc.Line) {
		fmt.Printf("%+v %+v\n", line.Nick, line.Args)
	})

	// And a signal on disconnect
	quit := make(chan bool)

	bot.HandleFunc(irc.DISCONNECTED,
		func(conn *irc.Conn, line *irc.Line) {
			fmt.Printf("%+v\n", conn)
			fmt.Printf("%+v\n", line)
			fmt.Printf("Disconnected.\n")
			quit <- true
		})

	// Tell client to connect.
	if err := bot.Connect(); err != nil {
		fmt.Printf("Connection error: %s\n", err.Error())
	}

	// Wait for disconnect
	<-quit
}
Пример #5
0
func (i *irc) Start(server string, user string) {
	go func() {
		for {
			cfg := goirc.NewConfig(user)
			cfg.SSL = true
			cfg.Server = "irc.freenode.net:7000"
			cfg.NewNick = func(n string) string { return n + "^" }
			i.conn = goirc.Client(cfg)
			//i.conn = goirc.SimpleClient(user)
			//ircConn.SSL = true

			i.conn.HandleFunc("connected", func(conn *goirc.Conn, line *goirc.Line) {
				//conn.Join("#channel")
				i.connected = true
			})

			quit := make(chan bool)
			i.conn.HandleFunc("disconnected", func(conn *goirc.Conn, line *goirc.Line) {
				i.connected = false
				quit <- true
			})

			// Tell client to connect
			if err := i.conn.Connect(); err != nil {
				fmt.Printf("Connection error: %s\n", err)
			}

			i.SendMessage("willemvds", "STEVE!")

			// Wait for disconnect
			<-quit
		}
	}()
}
Пример #6
0
// Connect connects the bot to its serve
func (ib *IrcBot) Connect() {
	ib.connMu.Lock()
	defer ib.connMu.Unlock()

	//reconnect
	ib.reconnectAllowed = true

	settings := ib.dataService.LoadSettings()
	// create a config and fiddle with it first:
	cfg := irc.NewConfig(settings.Nick)
	cfg.Timeout = 10 * time.Second
	ib.conn = irc.Client(cfg)

	// Join channels
	ib.conn.HandleFunc("connected",
		func(conn *irc.Conn, line *irc.Line) {
			log.Printf("connected to " + ib.server.Name + ":" + strconv.Itoa(ib.server.Port))
			ib.logToConsole("connected to " + ib.server.Name + ":" + strconv.Itoa(ib.server.Port))

			for _, channel := range ib.server.Channels {
				ib.logToConsole("joining channel " + channel.Name)
				conn.Join(channel.Name)
			}
		})

	// Parse Messages
	ib.conn.HandleFunc("PRIVMSG", ib.parseMessage)

	ib.conn.HandleFunc("372", ib.log372)

	ib.conn.HandleFunc("DISCONNECTED", ib.handleDisconnect)

	ib.conn.HandleFunc("CTCP", ib.handleDCC)

	ib.conn.HandleFunc(irc.NOTICE, ib.handleNotice)

	// Tell client to connect.
	ips, err := net.LookupIP(ib.server.Name)
	if err != nil {
		log.Printf("Lookup error: %v\n", err)
		ib.logToConsole("Lookup error: " + err.Error())
	}

	for _, ip := range ips {
		server := ip.String() + ":" + strconv.Itoa(ib.server.Port)

		log.Printf("Connecting to '%v'", server)
		if err := ib.conn.ConnectTo(server); err != nil {
			log.Printf("Connection error: %v\n", err)
			ib.logToConsole("Connection error: " + err.Error())
		} else {
			break
		}
	}
}
Пример #7
0
func teddyBot(nick string, password string, config IRCNetworks) {

	cfg := irc.NewConfig(nick)
	cfg.SSL = config.Ssl
	cfg.SSLConfig = &tls.Config{ServerName: config.Host, InsecureSkipVerify: true}
	cfg.Server = config.Host
	cfg.NewNick = func(n string) string { return n + "^" }

	bot := irc.Client(cfg)
	bot.EnableStateTracking()

	bot.HandleFunc(irc.CONNECTED,
		func(conn *irc.Conn, line *irc.Line) {
			conn.Mode(conn.Me().Nick, "+B")
			bot.Privmsg("NickServ", fmt.Sprintf("identify %s", password))
			for key, channel := range config.Channels {
				fmt.Printf("Connecting to channel #%s\n", key)
				conn.Join(channel.Name + " " + channel.Key)
			}
		})

	bot.HandleFunc(irc.PRIVMSG,
		func(conn *irc.Conn, line *irc.Line) {
			if strings.HasPrefix(line.Text(), "http") {
				bot.Privmsg(line.Args[0], getTitle(line.Text()))
			} else if strings.HasPrefix(line.Text(), "!dance") {
				for _, moves := range dance() {
					bot.Privmsg(line.Args[0], moves)
				}
			} else if strings.HasPrefix(line.Text(), "!angrydance") {
				for _, moves := range angrydance() {
					bot.Privmsg(line.Args[0], moves)
				}
			}

		})

	quit := make(chan bool)

	bot.HandleFunc(irc.DISCONNECTED,
		func(conn *irc.Conn, line *irc.Line) { quit <- true })

	if err := bot.Connect(); err != nil {
		fmt.Printf("Connection error: %s\n", err.Error())
	}

	// go func(line *irc.Line) {
	// 	fmt.Println(line)
	// }

	<-quit

}
Пример #8
0
func main() {
	admhost := flag.String("admhost", "", "The operator hostname")
	flag.Parse()

	cfg := irc.NewConfig("ZeGoNoob", "tgn", "Ze Go Noob")
	cfg.SSL = true
	cfg.Server = "irc.freenode.net:7000"
	cfg.NewNick = func(n string) string { return n + "^" }
	c := irc.Client(cfg)

	// c.HandleFunc("connected",
	//	func(conn *irc.Conn, line *irc.Line) { conn.Join("#") })

	quit := make(chan bool)

	c.HandleFunc("connected",
		func(conn *irc.Conn, line *irc.Line) {
			log.Println("Connected to server!")
		})

	c.HandleFunc("disconnected",
		func(conn *irc.Conn, line *irc.Line) { quit <- true })

	c.HandleFunc(irc.PRIVMSG, func(conn *irc.Conn, line *irc.Line) {
		words := strings.Split(line.Args[1], " ")

		if line.Host == *admhost {
			if line.Args[1] == "quit" {
				quit <- true
			}
		}

		if words[0] == "reverse" {
			text := Reverse(strings.Join(words[1:], " "))
			conn.Privmsg(line.Nick, text)
		}

		log.Printf("%s!%s@%s: %s", line.Nick, line.Ident, line.Host, strings.Join(line.Args[1:], " "))
	})

	// Tell client to connect.
	if err := c.Connect(); err != nil {
		log.Printf("Connection error: %s\n", err.Error())
	}

	// Wait for disconnect
	<-quit

	log.Println("Bye!")
}
Пример #9
0
func IRCConnection(host, channel, nick string) {
	IRCConnQuit := make(chan bool)
	run := true
	cfg := irc.NewConfig(nick, nick)

	cfg.Server = host
	cfg.NewNick = func(n string) string { return n + "~" }

	cli := irc.Client(cfg)

	cli.EnableStateTracking()

	cli.HandleFunc(irc.DISCONNECTED, func(conn *irc.Conn, line *irc.Line) {
		fmt.Printf("[*] Connect Done\n")
		IRCConnQuit <- true
		run = false

	})
	cli.HandleFunc(irc.CONNECTED, func(conn *irc.Conn, line *irc.Line) {
		fmt.Printf("[*] Joining %s\n", channel)
		cli.Join(channel)
	})

	cli.HandleFunc(irc.PRIVMSG, func(conn *irc.Conn, line *irc.Line) {
		if line.Text()[0:1] == "^" {
			ParseCommand(conn, line.Nick, line.Text())
		}
	})

	cli.HandleFunc(irc.JOIN, func(conn *irc.Conn, line *irc.Line) {
		if val, ok := messages[line.Nick]; ok {
			message <- line.Nick + ", " + val
			delete(messages, line.Nick)
		}
	})

	fmt.Printf("[*] Connecting to %s\n", host)
	if err := cli.Connect(); err != nil {
		fmt.Printf("[*] Connection error: %s\n", err.Error())
	}

	// Run Worker
	for run {
		cli.Privmsg(channel, <-message)
	}

	<-IRCConnQuit
}
Пример #10
0
func newEndpointIRC(options *json.RawMessage) *EndpointIRC {
	e := &EndpointIRC{}
	json.Unmarshal(*options, &e.Config)
	c := irc.NewConfig(e.Config.Nick)
	c.Server = e.Config.Server
	e.conn = irc.Client(c)
	e.conn.EnableStateTracking()
	e.conn.HandleFunc(irc.CONNECTED, e.connect)
	e.conn.HandleFunc(irc.PRIVMSG, e.message)
	e.conn.HandleFunc(irc.DISCONNECTED,
		func(conn *irc.Conn, line *irc.Line) {
			time.AfterFunc(time.Second*30, func() {
				e.conn.Connect()
			})
		})
	return e
}
Пример #11
0
func New(server *Server) *ircClient.Conn {
	// irccon := irc.IRC(server.Nick, server.User)
	// irccon.VerboseCallbackHandler = false
	// irccon.Debug = false

	// //Set options
	// // ircobj.UseTLS = false //default is false
	// //ircobj.TLSOptions //set ssl options
	// // ircobj.Password = ""

	// server.Client = irccon

	// return irccon

	// other client
	cfg := ircClient.NewConfig(server.Nick, server.User, server.Version)

	cfg.SSL = server.SSL

	if len(server.Password) > 0 {
		cfg.Pass = server.Password
	}

	cfg.SSLConfig = &tls.Config{
		ServerName:         server.Address,
		InsecureSkipVerify: server.InsecureSkipVerify,
	}

	cfg.Server = fmt.Sprintf("%s:%s", server.Address, server.Port)
	cfg.NewNick = func(n string) string { return n + "^" }
	cfg.Version = server.Version
	cfg.QuitMessage = server.Version
	cfg.SplitLen = 2000

	c := ircClient.Client(cfg)

	// this will cause a lot of connection issues
	// c.EnableStateTracking()

	server.Client = c

	return c
}
Пример #12
0
// Create a new ModManager from a ServerInfo config
func NewManager(serverInfo *ServerInfo) (*ModManager, error) {
	ircCfg, err := serverInfo.configServer()
	if err != nil {
		return nil, err
	}
	con := irc.Client(ircCfg)

	// copy Chans and Accesss to allow serverInfo to be marked for GC
	chans := make([]string, len(serverInfo.Channels))
	copy(chans, serverInfo.Channels)

	access := access{
		list: make(map[string][]string, len(serverInfo.Access)),
	}

	for name, list := range serverInfo.Access {
		users := list.Users
		l := make([]string, len(users))
		copy(l, users)
		access.list[name] = l
	}

	m := &ModManager{
		core:    newCore(),
		modules: make([]*module.Module, 0, 5),
		cons:    console.New(os.Stdin),

		Conn: con,
		Config: &BotInfo{
			Chans:  chans,
			Access: access,
		},
		Quit: make(chan bool),
	}
	m.registerCoreCommands()
	m.registerCommands()

	return m, nil
}
Пример #13
0
func main() {
	if len(os.Args) != 3 {
		fmt.Printf("Usage: %s server:port nick\n", os.Args[0])
		os.Exit(1)
	}

	cfg := irc.NewConfig(os.Args[2])
	cfg.SSL = false
	cfg.Server = os.Args[1]
	cfg.NewNick = func(n string) string { return n + "_" }
	con := irc.Client(cfg)

	con.HandleFunc("connected", func(con *irc.Conn, line *irc.Line) { fmt.Println("Connected!") })

	// read commands from stdin
	in := make(chan string, 4)
	go ReadCmd(in)

	// do something about the stuff
	go ui(con, in)

	// make channel seeing the signal to quit
	quit := make(chan bool)
	con.HandleFunc("disconnected",
		func(conn *irc.Conn, line *irc.Line) { quit <- true })

	con.HandleFunc("PRIVMSG",
		func(conn *irc.Conn, line *irc.Line) {
			fmt.Printf("<%s> %s\n%s: ", line.Nick, line.Args[1], line.Args[0])
		})

	if err := con.Connect(); err != nil {
		fmt.Printf("Connection error: %s\n", err)
	}

	<-quit

}
Пример #14
0
func NewIRCGateway(cfg config.IRCGateway, botname string) *IRCGateway {

	//irc
	irccfg := irc.NewConfig(botname, botname, "Powered by botyard")
	if cfg.UseSSL == true {
		irccfg.SSL = true
		irccfg.SSLConfig = &tls.Config{
			InsecureSkipVerify: true,
		}
	}
	irccfg.Server = cfg.Server
	irccfg.NewNick = func(n string) string { return n + "^" } //TODO:

	c := irc.Client(irccfg)

	gw := &IRCGateway{
		id:      uuid.NewV4().String(),
		cfg:     cfg,
		ircConn: c,
		logger:  kitlog.NewContext(log.Logger).With("m", "Gateway-IRC"),
	}
	return gw
}
Пример #15
0
func main() {
	quit := make(chan bool, 1)

	var config Config
	if err := gcfg.ReadFileInto(&config, "config.gcfg"); err != nil {
		log.Fatal("Couldn't read configuration")
	}

	ircConf := irc.NewConfig(config.IRC.Nickname)
	ircConf.Server = config.IRC.Host
	bot := irc.Client(ircConf)

	bot.HandleFunc("connected", func(conn *irc.Conn, line *irc.Line) {
		log.Println("Connected to IRC server", config.IRC.Host)
		conn.Join(config.IRC.Channel)
	})

	bot.HandleFunc("privmsg", func(conn *irc.Conn, line *irc.Line) {
		log.Println("Received:", line.Nick, line.Text())
		if strings.HasPrefix(line.Text(), config.IRC.Nickname) {
			command := strings.Split(line.Text(), " ")[1]
			switch command {
			case "quit":
				log.Println("Received command to quit")
				quit <- true
			}
		}
	})

	log.Println("Connecting to IRC server", config.IRC.Host)
	if err := bot.Connect(); err != nil {
		log.Fatal("IRC connection failed:", err)
	}

	<-quit
}
Пример #16
0
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:
	cfg := irc.NewConfig(sys.ircnick, "ircflu", "ircflu")
	cfg.SSL = sys.ircssl
	cfg.Server = sys.irchost
	cfg.Pass = sys.ircpassword
	cfg.NewNick = func(n string) string { return n + "_" }
	sys.client = irc.Client(cfg)

	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.client.Config().Me.Nick {
			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)
			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)
		}
	}()
}
Пример #17
0
func main() {
	flag.Parse() // parses the logging flags. TODO

	logging.SetLogger(ircLogger{log.New(os.Stdout, "[irc]", log.LstdFlags)})

	cfg := irc.NewConfig(frankconf.BotNick, frankconf.BotNick, "Frank Böterrich der Zweite")
	cfg.SSL = true
	cfg.SSLConfig = &tls.Config{InsecureSkipVerify: true}
	cfg.Flood = true
	cfg.Server = frankconf.IrcServer
	cfg.NewNick = func(n string) string { return n + "_" }
	c := irc.Client(cfg)
	c.EnableStateTracking()

	// connect
	c.HandleFunc(irc.CONNECTED,
		func(conn *irc.Conn, line *irc.Line) {
			log.Printf("Connected as: %s\n", conn.Me().Nick)
			conn.Privmsg("nickserv", "identify "+frankconf.NickServPass)

			var instaJoin string
			if frankconf.Production {
				instaJoin = frankconf.InstaJoinProduction
			} else {
				instaJoin = frankconf.InstaJoinTesting
			}

			log.Printf("AutoJoining: %s\n", instaJoin)

			for _, cn := range strings.Split(instaJoin, " ") {
				if cn != "" {
					conn.Join(cn)
				}
			}

			// handle RSS
			frank.Rss(conn)

			// watch topics and maybe change them on midnight
			go frank.TopicChanger(conn)
		})

	// react
	c.HandleFunc("PRIVMSG",
		func(conn *irc.Conn, line *irc.Line) {
			// ignore eicar, the bot we love to hate.
			// Also ignore i3-bot.
			if line.Nick == "eicar" || line.Nick == "i3" {
				return
			}

			go frank.RaumBang(conn, line)
			go frank.UriFind(conn, line)
			go frank.Lmgtfy(conn, line)
			go frank.Karma(conn, line)
			go frank.Help(conn, line)
			go frank.ItsAlive(conn, line)
			go frank.Highlight(conn, line)
		})

	if frankconf.Verbose {
		c.HandleFunc("NOTICE",
			func(conn *irc.Conn, line *irc.Line) {
				tgt := line.Args[0]
				msg := line.Args[1]
				log.Printf("Debug NOTICE: tgt: %s, msg: %s\n", tgt, msg)
			})
	}

	c.HandleFunc("INVITE",
		func(conn *irc.Conn, line *irc.Line) {
			tgt := line.Args[0]
			cnnl := line.Args[1]

			// auto follow invites only in test mode or if asked by master
			if frankconf.Production && line.Nick != frankconf.Master {
				log.Printf("only following invites by %s in production\n", frankconf.Master)
				return
			}

			if conn.Me().Nick != tgt {
				log.Printf("WTF: received invite for %s but target was %s\n", conn.Me().Nick, tgt)
				return
			}

			log.Printf("Following invite for channel: %s\n", cnnl)
			conn.Join(cnnl)
		})

	// auto deop frank
	c.HandleFunc("MODE",
		func(conn *irc.Conn, line *irc.Line) {
			log.Printf("Mode change array length: %s", len(line.Args))
			log.Printf("Mode changes: %s", line.Args)

			if len(line.Args) < 3 {
				// mode statement cannot be not in a channel, so ignore
				return
			}

			var modeop bool // true => add mode, false => remove mode
			var nickIndex int = 2
			for i := 0; i < len(line.Args[1]); i++ {
				switch m := line.Args[1][i]; m {
				case '+':
					modeop = true
				case '-':
					modeop = false
				case 'o':
					if !modeop || line.Args[nickIndex] != conn.Me().Nick {
						nickIndex += 1
						break
					}
					channel := line.Args[0]

					if strings.Contains(" "+frankconf.OpOkIn+" ", " "+channel+" ") {
						if strings.ToLower(line.Nick) != "chanserv" {
							conn.Privmsg(channel, "Unbelievable "+line.Nick+", you… https://yrden.de/f1.ogg")
						}
					} else {
						conn.Mode(channel, "+v-o", conn.Me().Nick, conn.Me().Nick)
						conn.Privmsg(channel, line.Nick+": SKYNET® Protection activated")
					}
					return
				default:
					nickIndex += 1
				}
			}
		})

	// disconnect
	quit := make(chan bool)
	c.HandleFunc(irc.DISCONNECTED,
		func(conn *irc.Conn, line *irc.Line) { quit <- true })

	// go go GO!
	if err := c.Connect(); err != nil {
		log.Fatalf("Connection error: %s\n", err)
	}

	log.Printf("Frank has booted\n")

	// Wait for disconnect
	<-quit
}
Пример #18
0
func main() {
	fmt.Println("Allbotv2 loading...")

	// TODO persistent settings
	/*r, err := ioutil.ReadFile("settings.json")
	if err != nil {
		panic(err)
	}
	setting := IRCSetting{}*/

	// Do our connection settings
	cfg := irc.NewConfig(botName)
	cfg.SSL = false
	cfg.Server = ircServer
	cfg.NewNick = func(n string) string { return n + "^" }
	c := irc.Client(cfg)

	// Begin handlers
	c.HandleFunc("connected",
		func(conn *irc.Conn, line *irc.Line) {
			fmt.Printf("Connected to %s...\n", cfg.Server)

			if autoJoin {
				if len(channels) > 0 {
					for index, channel := range channels {
						fmt.Printf("Joining [%s] [%d/%d]\n", channel, index, len(channels)-1)
						conn.Join(channel)
					}
				}
			} else {
				fmt.Println("What's next?")
			}
		})

	c.HandleFunc("join",
		func(conn *irc.Conn, line *irc.Line) {
			if doOnJoin {
				//TODO send greeting
				eventJoin(conn, line)
			}
		})

	c.HandleFunc("privmsg",
		func(conn *irc.Conn, line *irc.Line) {
			fmt.Printf("[%s] %s : %s\n", line.Cmd, line.Nick, line.Args)

			// determine if channel message or addressing bot
			if line.Args[0] != botName {
				//fmt.Println("^---- Channel message -----^")
				if muzzle == false {
					eventPrivmsg(conn, line, true)
				}
			} else {
				//fmt.Println("^---- Priavte message -----^")
				eventPrivmsg(conn, line, false)
			}

		})

	c.HandleFunc("ctcp",
		func(conn *irc.Conn, line *irc.Line) {
			fmt.Printf("[%s] %s : %s\n", line.Cmd, line.Nick, line.Args)

			if debug {
				fmt.Printf("Line args: [%s]\n", line.Args[0])
			}

			if line.Args[0] == "VERSION" {
				fmt.Printf("CTCP Reply sent to: [%s]\n", line.Nick)
				conn.CtcpReply(line.Nick, "VERSION", "allbot")
			}
		})

	// And a signal on disconnect
	quit := make(chan bool)
	c.HandleFunc("disconnected",
		func(conn *irc.Conn, line *irc.Line) {
			// TODO reconnect upon disconnect signal
			quit <- true
		})

	// Tell client to connect.
	if err := c.Connect(); err != nil {
		fmt.Printf("Connection error: %s\n", err)
	}

	// Wait for disconnect
	<-quit
}
Пример #19
0
// Create
func (s *Server) Create() {
	verbf("Creating bot from server struct: %s", s)

	// Create connection
	s.Conn = irc.Client(&irc.Config{
		Me: &state.Nick{
			Nick:  s.Nick,
			Ident: s.Host,
			Host:  s.Host,
			Name:  s.RealName,
		},
		Server:      s.Network,
		Pass:        s.Password,
		SSL:         s.Ssl,
		PingFreq:    30 * time.Second,
		NewNick:     func(s string) string { return s + "_" },
		Version:     "Kittens IRC",
		QuitMessage: "bye!",
		SplitLen:    450,
		Recover:     (*irc.Conn).LogPanic,
	})

	// Enable state tracking
	s.Conn.EnableStateTracking()

	// Add connect handler
	s.Conn.HandleFunc(irc.CONNECTED,
		func(conn *irc.Conn, line *irc.Line) {
			s.Timestamp = time.Now().Unix()
			s.Connected = true
			infof("Connected to %s", s.Network)
			s.JoinChannels()
		})

	// Add disconnect handler
	s.Conn.HandleFunc(irc.DISCONNECTED,
		func(conn *irc.Conn, line *irc.Line) {
			s.Connected = false
			infof("Disconnected from %s", s.Network)
			infof("Reconnecting to %s", s.Network)
			s.Connect()
		})

	// Listen for messages
	s.Conn.HandleFunc(irc.PRIVMSG,
		func(conn *irc.Conn, line *irc.Line) {
			// Show output of line currently
			s.Logging(line)
		})

	// Listen for JOIN
	s.Conn.HandleFunc(irc.JOIN,
		func(conn *irc.Conn, line *irc.Line) {
			// Create new irc user if it doesn't exist
			db.Table("irc_users").Where("nickname = ? and host = ?", line.Nick, line.Host).Attrs(IrcUser{
				Nickname: line.Nick,
				Host:     line.Host,
				ServerId: s.Id,
			}).FirstOrCreate(&IrcUser{})

			// Get irc user
			var ircuser IrcUser
			db.Table("irc_users").Where("nickname = ? and host = ?", line.Nick, line.Host).First(&ircuser)

			// Create new channel related to irc user if it doesn't exist
			db.Table("irc_user_channels").Where("channel = ? and irc_user_id = ?", line.Args[0], ircuser.Id).Attrs(IrcUserChannel{
				Channel:      line.Args[0],
				IrcUserId:    ircuser.Id,
				Modes:        "",
				LastJoinedAt: time.Now(),
				LastPartedAt: time.Now(),
			}).FirstOrCreate(&IrcUserChannel{})

			// Get the irc user channel
			var iuc IrcUserChannel
			db.Table("irc_user_channels").Where("channel = ? and irc_user_id = ?", line.Args[0], ircuser.Id).First(&iuc)

			// Set the LastJoinedAt time
			iuc.LastJoinedAt = time.Now()
			db.Save(&iuc)
		})

	verbf("Finished creating bot for server %s", s.ServerName)

	// Connect server if enabled
	if s.Enabled {
		s.Connect()
	}
}
Пример #20
0
func main() {
	flag.Parse()
	log := logging.NewFromFlags()
	reg := event.NewRegistry()

	if *server == "" {
		//Don't call log.Fatal as we don't want a backtrace in this case
		log.Error("--server option required. \nOptions are:\n")
		flag.PrintDefaults()
		os.Exit(1)
	}

	// Connect to mongo
	db, err := db.Connect("localhost")
	if err != nil {
		log.Fatal("mongo dial failed: %v\n", err)
	}
	defer db.Session.Close()

	// Initialise the factoid driver (which currently acts as a plugin mgr too).
	fd := factdriver.FactoidDriver(db, log)

	// Configure IRC client
	irc := client.Client(*nick, "boing", "not really sp0rkle", reg, log)
	irc.SSL = *ssl

	// Initialise bot state
	bot := bot.Bot(irc, fd, log)
	bot.AddChannels(strings.Split(*channels, ","))

	// Add drivers
	bot.AddDriver(bot)
	bot.AddDriver(fd)
	bot.AddDriver(calcdriver.CalcDriver(log))
	bot.AddDriver(decisiondriver.DecisionDriver(log))
	bot.AddDriver(quotedriver.QuoteDriver(db, log))
	bot.AddDriver(netdriver.NetDriver(log))
	bot.AddDriver(seendriver.SeenDriver(db, log))
	bot.AddDriver(urldriver.UrlDriver(db, log))

	// Register everything (including http handlers)
	bot.RegisterAll()

	// Start up the HTTP server
	go http.ListenAndServe(*httpPort, nil)

	// Connect loop.
	quit := false
	for !quit {
		if err := irc.Connect(*server); err != nil {
			log.Fatal("Connection error: %s", err)
		}
		quit = <-bot.Quit
	}
	if bot.ReExec() {
		// Calling syscall.Exec probably means deferred functions won't get
		// called, so disconnect from mongodb first for politeness' sake.
		db.Session.Close()
		// If sp0rkle was run from PATH, we need to do that lookup manually.
		fq, _ := exec.LookPath(os.Args[0])
		log.Warn("Re-executing sp0rkle with args '%v'.", os.Args)
		err := syscall.Exec(fq, os.Args, os.Environ())
		if err != nil {
			// hmmmmmm
			log.Fatal("Couldn't re-exec sp0rkle: %v", err)
		}
	}
}
Пример #21
0
func (mod *IrcBee) Run(eventChan chan bees.Event) {
	if len(mod.server) == 0 {
		return
	}

	// channel signaling IRC connection status
	mod.connectedState = make(chan bool)

	// setup IRC client:
	cfg := irc.NewConfig(mod.nick, "beehive", "beehive")
	cfg.SSL = mod.ssl
	cfg.Server = mod.server
	cfg.Pass = mod.password
	cfg.NewNick = func(n string) string { return n + "_" }
	mod.client = irc.Client(cfg)

	mod.client.HandleFunc("connected", func(conn *irc.Conn, line *irc.Line) {
		mod.connectedState <- true
	})
	mod.client.HandleFunc("disconnected", func(conn *irc.Conn, line *irc.Line) {
		mod.connectedState <- false
	})
	mod.client.HandleFunc("PRIVMSG", func(conn *irc.Conn, line *irc.Line) {
		channel := line.Args[0]
		if channel == mod.client.Config().Me.Nick {
			channel = line.Src // replies go via PM too.
		}
		msg := ""
		if len(line.Args) > 1 {
			msg = line.Args[1]
		}
		user := line.Src[:strings.Index(line.Src, "!")]
		hostmask := line.Src[strings.Index(line.Src, "!")+2:]

		ev := bees.Event{
			Bee:  mod.Name(),
			Name: "message",
			Options: []bees.Placeholder{
				bees.Placeholder{
					Name:  "channel",
					Type:  "string",
					Value: channel,
				},
				bees.Placeholder{
					Name:  "user",
					Type:  "string",
					Value: user,
				},
				bees.Placeholder{
					Name:  "hostmask",
					Type:  "string",
					Value: hostmask,
				},
				bees.Placeholder{
					Name:  "text",
					Type:  "string",
					Value: msg,
				},
			},
		}
		eventChan <- ev
	})

	// loop on IRC dis/connected events
	for {
		log.Println("Connecting to IRC:", mod.server)
		err := mod.client.Connect()
		if err != nil {
			log.Println("Failed to connect to IRC:", mod.server)
			log.Println(err)
		} else {
			disconnected := false
			for {
				if disconnected {
					break
				}
				select {
				case <-mod.SigChan:
					mod.client.Quit()
					return

				case status := <-mod.connectedState:
					if status {
						log.Println("Connected to IRC:", mod.server)
						mod.Rejoin()
					} else {
						log.Println("Disconnected from IRC:", mod.server)
						disconnected = true
						break
					}

				default:
					time.Sleep(1 * time.Second)
				}
			}
		}
	}
}
Пример #22
0
func NewBridge(slackToken, slackChannel, ircServer, ircChannel, ircNick string, ircSSL, insecureSkipVerify bool) (bridge *Bridge) {
	sc := slack.NewSlackClient(slackToken)

	ircCfg := ircc.NewConfig(ircNick)
	ircCfg.Server = ircServer
	ircCfg.NewNick = func(n string) string { return n + "_" }
	if ircSSL {
		ircCfg.SSL = true
		if insecureSkipVerify {
			ircCfg.SSLConfig = &tls.Config{InsecureSkipVerify: true}
		}
	}
	c := ircc.Client(ircCfg)

	bridge = &Bridge{SlackChan: slackChannel, IRCChan: ircChannel, slack: sc, irc: c}

	// IRC Handlers
	c.HandleFunc(ircc.CONNECTED,
		func(conn *ircc.Conn, line *ircc.Line) {
			conn.Join(ircChannel)
			bridge.slack.Send(bridge.SlackChan, "Connected to IRC.")
			log.Println("Connected to IRC.")
		})

	c.HandleFunc(ircc.DISCONNECTED,
		func(conn *ircc.Conn, line *ircc.Line) {
			bridge.slack.Send(bridge.SlackChan, "Disconnected from IRC. Issuing reconnect...")
			log.Println("Disconnected from IRC. Issuing reconnect...")
			for {
				if err := conn.Connect(); err != nil {
					log.Println("IRC reconnect failed: ", err)
					log.Println("Trying again in 30 seconds...")
					time.Sleep(30 * time.Second)
					continue
				}
				// success
				break
			}
		})

	c.HandleFunc(ircc.PRIVMSG,
		func(conn *ircc.Conn, line *ircc.Line) {
			if line.Target() == bridge.IRCChan {
				msg := fmt.Sprintf("[%s]: %s", line.Nick, line.Text())
				bridge.slack.Send(bridge.SlackChan, msg)
			}
		})

	// Slack Handlers
	sc.HandleFunc("shutdown",
		func(sc *slack.SlackClient, e *slack.Event) {
			bridge.irc.Privmsg(bridge.IRCChan, "Disconnected from Slack.")
			log.Println("Disconnected from Slack.")

		})

	sc.HandleFunc("disconnected",
		func(sc *slack.SlackClient, e *slack.Event) {
			bridge.irc.Privmsg(bridge.IRCChan, "Issuing reconnect to Slack...")
			log.Println("Issuing reconnect to Slack...")
			sc.Connect()

		})

	sc.HandleFunc("connected",
		func(sc *slack.SlackClient, e *slack.Event) {
			bridge.irc.Privmsg(bridge.IRCChan, "Connected to Slack.")
			log.Println("Connected to Slack.")
		})

	sc.HandleFunc("message",
		func(sc *slack.SlackClient, e *slack.Event) {
			if e.Chan() == bridge.SlackChan && !sc.IsSelfMsg(e) && e.Text != "" {
				msg := fmt.Sprintf("[%s]: %s", e.Usernick(), e.Msg())
				// IRC has problems with newlines, therefore we split the message
				for _, line := range strings.SplitAfter(msg, "\n") {
					// we do not want to send empty lines...
					if strings.TrimSpace(line) != "" {
						bridge.irc.Privmsg(bridge.IRCChan, line)
					}
				}
			}

		})

	go func() {
		if err := c.Connect(); err != nil {
			log.Fatal("Could not connect to IRC: ", err)
		}
	}()
	go func() {
		if err := sc.Connect(); err != nil {
			log.Fatal("Could not connect to Slack: ", err)
		}
	}()
	return bridge
}
Пример #23
0
func main() {

	zax = ZAX{}
	zax_log, _ := os.OpenFile("zax.log", os.O_CREATE|os.O_APPEND, os.ModeAppend)
	irc_logging.SetLogger(IrcLogger{})

	log_file := logging.NewLogBackend(zax_log, "", 0)
	log_file_f := logging.NewBackendFormatter(log_file, format)

	log_stdout := logging.NewLogBackend(os.Stdout, "", 0)
	log_stdout_f := logging.NewBackendFormatter(log_stdout, format)
	log_stdout_levelled := logging.AddModuleLevel(log_stdout_f)
	log_stdout_levelled.SetLevel(logging.INFO, "")

	logging.SetBackend(log_stdout_levelled, log_file_f)

	last_url = ""

	m := []Message{}
	e := []Event{}
	u := []Url{}
	history = IrcHistory{}
	history.data = HistoryData{m, e, u}
	history.userdata = make(map[string]*HistoryData)
	log.Notice("Loading config...")

	file, _ := os.Open("conf.json")
	decoder := json.NewDecoder(file)
	config = Config{}
	err := decoder.Decode(&config)
	if err != nil {
		log.Errorf("Error loading config: %s", err.Error())
		os.Exit(-1)
	}

	log.Notice("Config loaded.")
	log.Notice("Opening history...")
	time_history := time.Now()
	file_history, err = os.OpenFile("history.log", os.O_CREATE, os.ModeAppend)
	if err != nil {
		log.Errorf("Unable to open history.log: %s", err.Error())
		os.Exit(-1)
	}
	log.Notice("Loading history...")
	reader := bufio.NewScanner(file_history)
	file_history_writer = bufio.NewWriter(file_history)
	for reader.Scan() {
		l := reader.Text()
		is_url := strings.HasPrefix(l, "url")
		is_msg := strings.HasPrefix(l, "msg")
		is_event := strings.HasPrefix(l, "event")
		parts := []string{}
		user := ""
		channel := ""
		timestamp := time.Time{}

		if is_url || is_msg || is_event {
			parts = strings.Split(l, ",")
			ts, _ := strconv.ParseInt(parts[1], 10, 64)
			timestamp = time.Unix(ts, 0)
			user = parts[2]
			channel = parts[3]
			if !history.IsUserInit(user) {
				history.InitUser(user)
			}
		}
		if strings.HasPrefix(l, "event") {
			evt_s := parts[4]
			data := ""
			if len(parts) == 6 {
				data = parts[5]
			}

			event := Event{evt_s, user, data, channel, timestamp}
			history.userdata[user].Events = append(history.userdata[user].Events, event)
			history.data.Events = append(history.data.Events, event)
		}

		if strings.HasPrefix(l, "msg") {
			text := ""
			for i := 4; i < len(parts); i++ {
				text = text + parts[i]
			}
			msg := Message{text, user, channel, timestamp}
			history.userdata[user].Messages = append(history.userdata[user].Messages, msg)
			history.data.Messages = append(history.data.Messages, msg)
		}

		if strings.HasPrefix(l, "url") {
			url := Url{parts[3], timestamp}
			history.userdata[user].Urls = append(history.userdata[user].Urls, url)
			history.data.Urls = append(history.data.Urls, url)
		}
	}
	elapsed := time.Since(time_history)
	log.Noticef("History loaded %d events, %d urls and %d messages in %f seconds.\n", len(history.data.Events), len(history.data.Urls), len(history.data.Messages), elapsed.Seconds())
	log.Notice("Initializing IRC connection.")

	// Init IRC connection
	log.Noticef("Creating IRC cfg. Server: %s, Use SSL: %t, Nickname %s", config.Server, config.SSL, config.Nickname)
	cfg := irc.NewConfig(config.Nickname)
	cfg.SSL = config.SSL
	cfg.SSLConfig = &tls.Config{}
	cfg.SSLConfig.InsecureSkipVerify = config.SSLIgnoreInsecure
	cfg.Me.Ident = "ZAX"
	cfg.Me.Name = "ZAX"
	cfg.Version = "ZAX"
	cfg.Server = config.Server
	cfg.NewNick = func(n string) string { return n + "^" }
	quit := make(chan bool)
	c := irc.Client(cfg)
	c.EnableStateTracking()
	c.Connect()
	zax.IrcClient = c
	zax.IrcConfig = cfg
	c.HandleFunc(irc.CONNECTED,
		func(conn *irc.Conn, line *irc.Line) {
			for i := 0; i < len(config.Channels); i++ {
				ch := config.Channels[i]
				c.Join(ch.Chan, ch.Password)
			}
		})
	c.HandleFunc(irc.DISCONNECTED,
		func(conn *irc.Conn, line *irc.Line) {
			log.Notice("Disconnected")
			quit <- true
		})
	c.HandleFunc(irc.JOIN,
		func(conn *irc.Conn, line *irc.Line) {
			log.Infof("[%s] %s (%s@%s) has joined.", line.Target(), line.Nick, line.Ident, line.Host)
			history.AddEvent(line.Nick, "join", "", line.Target())
		})

	c.HandleFunc(irc.QUIT,
		func(conn *irc.Conn, line *irc.Line) {
			log.Infof("[%s] %s (%s@%s) has quit.", line.Target(), line.Nick, line.Ident, line.Host)
			history.AddEvent(line.Nick, "quit", line.Text(), "")
		})

	c.HandleFunc(irc.PING,
		func(conn *irc.Conn, line *irc.Line) {
			log.Debug("PING.")
		})

	c.HandleFunc(irc.PRIVMSG,
		func(conn *irc.Conn, line *irc.Line) {
			sender_host := line.Host
			sender := line.Nick
			text := line.Text()
			channel := line.Target()
			target := line.Target()
			reply_to := line.Target()

			if line.Target() == config.Nickname {
				reply_to = sender
			}
			// Remove control characters
			text = strings.Replace(text, "", "", -1)
			text = strings.Replace(text, "", "", -1)

			log.Noticef("[%s] %s: %s", target, sender, text)

			history.AddMessage(sender, target, text)
			if len(config.ReportChan) > 0 {
				zax.Privmsg(config.ReportChan, fmt.Sprintf("[%s] %s: %s", target, sender, text))
			}

			args := strings.Split(text, " ")

			cmd_admin := []string{"%%", "<<"}

			// Check if admin
			if is_command(text, cmd_admin) {
				re_adm := regexp.MustCompile("(nick|host):(.+)")
				criteria := re_adm.FindStringSubmatch(config.Admin)
				//is_admin := false
				match_str := ""
				if criteria == nil {
					log.Debug("Unable to parse admin criteria.")
					return
				}
				re_adm_eval := regexp.MustCompile(criteria[2])
				if criteria[1] == "nick" {
					match_str = sender
				}
				if criteria[1] == "host" {
					match_str = sender_host
				}
				if !re_adm_eval.MatchString(match_str) {
					log.Debugf("Didn't pass the criteria: %s:%s", criteria[1], criteria[2])
					return
				}
				log.Debugf("Passed the criteria: %s:%s with %s", criteria[1], criteria[2], match_str)
				if text == "<<" {
					zax.Quit(get_quit_msg())
				}
				if strings.HasPrefix(text, "%%") {
					if len(args) == 4 {
						if args[1] == "opt" {
							if args[2] == "process_urls" {
								if args[3] == "on" {
									config.ProcessUrls = true
								}
								if args[3] == "off" {
									config.ProcessUrls = false
								}
							}
						}
					}

				}

			}

			cmd_rand := []string{".r", ".random"}
			cmd_steam := []string{".s", ".steam"}
			cmd_game := []string{".g", ".game"}
			cmd_url := []string{".u", ".url"}
			cmd_msg := []string{".m", ".msg"}
			cmd_seen := []string{"!"}
			cmd_help := []string{"?h"}

			if is_command(text, cmd_help) {
				reply_msg := ""
				if text == "?h" {
					reply_msg = "Cmds: [[.g(ame) .r(andom) .s(team) .u(rl) .m(sg) !]] -- Type ?h <cmd> for more info."
				}
				if len(args) > 1 {
					if args[1] == "!" {
						reply_msg = "Checks when user was last seen. Syntax: !<username>"
					}
					if is_command(args[1], cmd_rand) {
						reply_msg = "Generate random number. Syntax: .random <min> <max>"
					}
					if is_command(args[1], cmd_steam) {
						if len(args) == 3 {
							if args[2] == "symbols" {
								reply_msg = "MP=MultiPlayer, SP=SinglePlayer, CO=Co-op VAC=Valve Anti-Cheat, TC=Trading Card, Ach=Achievments, EA=Early Access, WS=Workshop support"
							}
						} else {
							reply_msg = "Search steam. For result symbols type '?h .s symbols' Syntax: .steam [ find | latest | random | trending | appid] <expression>"
						}
					}
					if is_command(args[1], cmd_game) {
						reply_msg = "Search for game info. Syntax: .game <query>"
					}
					if is_command(args[1], cmd_msg) {
						reply_msg = "Search message log. Syntax: .msg [ find | latest | random ] <expression>"
					}
					if is_command(args[1], cmd_url) {
						reply_msg = "Search URL log. Syntax: .url [ find | latest | random ] <expression>"
					}
				}
				zax.Privmsg(reply_to, reply_msg)
				return
			}
			if is_command(text, cmd_seen) {
				log.Debug("Executing seen command.")
				seen_user := strings.Replace(args[0], "!", "", -1)
				if seen_user == "" {
					log.Debug("No user was specified.")
					return
				}
				if seen_user == sender {
					log.Debug("Sender same as specified seen user, insult.")
					zax.Privmsg(reply_to, get_insult())
				}
				state := c.StateTracker().GetNick(seen_user)
				if state != nil {
					user_channels := state.Channels
					for i := 0; i < len(config.Channels); i++ {
						ch := config.Channels[i]
						_, exists := user_channels[ch.Chan]
						if exists {
							if ch.Chan == channel {
								zax.Privmsg(reply_to, get_insult())
								log.Notice("seen_user is here now.")
							} else {
								sender_state := c.StateTracker().GetNick(sender)
								_, exists := sender_state.Channels[ch.Chan]
								if exists {
									zax.Privmsg(reply_to, seen_user+" is on "+ch.Chan)
								} else {
									zax.Privmsg(reply_to, "Yeah, somewhere... can't tell you where though.")
								}
							}
						}
					}
				}
				time_seen := time.Time{}
				data, found := history.userdata[seen_user]
				if !found {
					zax.Privmsg(channel, get_user_not_exists())
					return
				}
				log.Debug("Finding latest event/msg...")
				action := ""
				evt := Event{}
				msg := Message{}

				if data.Events != nil && len(data.Events) > 0 {
					evt = data.Events[len(data.Events)-1]
				}
				if data.Messages != nil && len(data.Messages) > 0 {
					msg = data.Messages[len(data.Messages)-1]
				}
				is_event := false
				if evt.Event != "" {
					time_seen = evt.Timestamp
					is_event = true
				} else if msg.Msg != "" {
					time_seen = msg.Timestamp
					is_event = false
				} else {
					if evt.Timestamp.Unix() > msg.Timestamp.Unix() {
						time_seen = evt.Timestamp
						is_event = true
					} else {
						time_seen = msg.Timestamp
						is_event = false
					}
				}
				if is_event {
					if evt.Event == "quit" {
						action = "quitting"
					}
					if evt.Event == "join" {
						action = "joining"
					}
				} else {
					action = "writing: \"" + msg.Msg + "\""
				}
				log.Debugf("Found latest event %s at %d", action, time_seen.Unix())

				duration := time.Since(time_seen)
				days := 0
				hours := 0
				sec := 0
				min := 0

				log.Debugf("User %s seen hours: %.1f, minutes: %.1f, seconds %.1f ago.", seen_user, duration.Hours(), duration.Minutes(), duration.Seconds())

				if duration.Hours() > 24 {
					days = int(duration.Hours()) / 24
					hours = int(duration.Hours()) % 24
					min = 0
				} else if duration.Minutes() > 60 {
					hours = int(duration.Hours())
					min = int(duration.Minutes()) % 60
				} else if duration.Seconds() > 60 {
					min = int(duration.Minutes())
					sec = int(duration.Seconds()) % 60
				} else {
					sec = int(duration.Seconds())
				}

				if duration.Hours() > 24 {
					days = int(duration.Hours()) / 24
					hours = int(duration.Hours()) % 24
					min = 0
				}

				times := []string{}
				if days > 0 {
					times = append(times, strconv.Itoa(days)+" day(s)")
				}
				if hours > 0 {
					times = append(times, strconv.Itoa(hours)+" hour(s)")
				}
				if min > 0 {
					times = append(times, strconv.Itoa(min)+" minute(s)")
				}
				if sec > 0 {
					times = append(times, strconv.Itoa(sec)+" second(s)")
				}

				time_str := strings.Join(times, ", ")
				zax.Privmsg(reply_to, fmt.Sprintf("%s was last seen %s ago %s.", seen_user, time_str, action))
			}

			if is_command(text, cmd_game) {
				query := ""
				for i := 1; i < len(args); i++ {
					query += " " + args[i]
				}
				games, success := games.FindGames(query, config.UserAgent)
				if success {
					zax.Privmsg(reply_to, fmt.Sprintf("%s (%s) - %s\n", games[0].Name, games[0].Year, games[0].Url))
				}
			}

			if is_command(text, cmd_url) {
				var url Url
				var urls []Url
				urls = history.data.Urls

				is_cmd_last := args[1] == "last" || args[1] == "l"
				is_cmd_random := args[1] == "random" || args[1] == "r"
				is_cmd_find := args[1] == "find" || args[1] == "f"

				if is_cmd_last || is_cmd_random && len(args) == 3 {
					user_urls := history.userdata[args[2]].Urls
					if user_urls != nil {
						urls = user_urls
					}
				}
				if is_cmd_last {
					url = urls[len(urls)-1]
				}
				if is_cmd_random {
					url = urls[rand_int(0, len(urls)-1)]
				}
				if is_cmd_find {
					expr := ""
					for i := 2; i < len(args); i++ {
						expr += expr + args[i]
					}
					re := regexp.MustCompile(expr)
					for _, i_url := range urls {
						match := re.FindStringSubmatch(i_url.Url)
						if match != nil {
							url = i_url
						}
					}
				}
				if url.Url == "" {
					return
				}
				t := url.Timestamp
				zax.Privmsg(reply_to, fmt.Sprintf("[%d-%02d-%02d %02d:%02d:%02d] %v", t.Year(), t.Month(), t.Day(), t.Hour(), t.Minute(), t.Second(), url.Url))
				return
			}
			if is_command(text, cmd_msg) {
				var msg Message
				var msgs []Message

				msgs = history.data.Messages

				is_cmd_last := args[1] == "last" || args[1] == "l"
				is_cmd_random := args[1] == "random" || args[1] == "r"
				is_cmd_find := args[1] == "find" || args[1] == "f"

				if is_cmd_last || is_cmd_random && len(args) == 3 {
					user_msgs := history.userdata[args[2]].Messages
					if user_msgs != nil {
						msgs = user_msgs
					}
				}

				if is_cmd_last {
					msg = msgs[len(msgs)-1]
				}
				if is_cmd_random {
					msg = msgs[rand_int(0, len(msgs)-1)]
				}
				if is_cmd_find {
					expr := ""
					for i := 2; i < len(args); i++ {
						add := args[i]
						if i != 2 {
							add = " " + add
						}
						expr += add
					}
					re := regexp.MustCompile(expr)
					for _, i_msg := range msgs {
						match := re.FindStringSubmatch(i_msg.Msg)
						if match != nil {
							if !(strings.Contains(i_msg.Msg, fmt.Sprintf("%s %s", args[0], args[1]))) {
								msg = i_msg
							}
						}
					}
				}
				if msg.Msg == "" {
					return
				}
				t := msg.Timestamp
				zax.Privmsg(reply_to, fmt.Sprintf("[%d-%02d-%02d %02d:%02d:%02d] %v: %v", t.Year(), t.Month(), t.Day(), t.Hour(), t.Minute(), t.Second(), msg.User, msg.Msg))
			}
			if is_command(text, cmd_rand) {
				if len(args) < 3 {
					return
				}
				min, err := strconv.ParseInt(args[1], 10, 32)
				if err != nil {
					log.Debug("Failed to parse min.")
					return
				}
				max, err := strconv.ParseInt(args[2], 10, 32)
				if err != nil {
					log.Debug("Failed to parse max.")
					return
				}
				if min > max {
					return
				}
				zax.Privmsg(reply_to, "What about... "+strconv.Itoa(rand_int(int(min), int(max))))
			}
			if is_command(text, cmd_steam) {
				if len(args) < 2 {
					return
				}
				subcommand := args[1]
				success := false
				steam_appid := 0
				var err error

				steam_latest_url := "http://store.steampowered.com/search/?sort_by=Released_DESC&tags=-1&category1=998&page="

				if subcommand == "latest" || subcommand == "l" {
					steam_appid, success = steam.SearchSteampowered(steam_latest_url+"1", 0)
				}
				if subcommand == "random" || subcommand == "r" {
					page := strconv.Itoa(rand_int(1, 286))
					steam_appid, success = steam.SearchSteampowered(steam_latest_url+page, -2)
				}
				if subcommand == "trending" || subcommand == "t" {
					apps, suc := steam.GetTrending(config.UserAgent)
					if suc {
						app := apps[0]
						zax.Privmsg(reply_to, fmt.Sprintf("[Steamcharts] %s [%s increase in players last 24h] %d current players. Type '.s a %d' to get more info.", app.Name, app.Increase, app.Players, app.Id))
						return
					}
				}

				if subcommand == "appid" || subcommand == "a" {
					steam_appid, err = strconv.Atoi(args[2])
					success = (err == nil)
				}
				if subcommand == "find" || subcommand == "f" {
					re := regexp.MustCompile(fmt.Sprintf("%s %s ([[:alnum:]'*!_ ]+)", args[0], args[1]))
					match := re.FindStringSubmatch(text)
					if match == nil || len(match) == 0 {
						log.Debug("Doesn't match.")
						return
					}
					log.Debugf("matched term: %s", match[1])
					search_url := "http://store.steampowered.com/search/?snr=&term=" + match[1]
					log.Debugf("Search URL: %s", search_url)
					steam_appid, success = steam.SearchSteampowered(search_url, 0)
				}
				if success {
					log.Info("Found appid %d, retrieving info...", steam_appid)
					app, success2 := steam.GetAppInfo(steam_appid, config.UserAgent)
					if success2 {
						rating_str := ""
						if app.Reviews > 0 {
							rating_str = fmt.Sprintf("| %.1f%s rating (%d reviews)", app.Rating, "%", app.Reviews)
						}
						os_str := ""
						if app.OS("") != "" {
							os_str = fmt.Sprintf("%s - [%s]", app.OS("/"), app.Features("/"))
						}
						price := ""
						if app.PriceDiscount != "" {
							price = "| " + app.PriceDiscount
						} else {
							if app.Price != "" {
								price = "| " + app.Price
							}
						}
						base_str := ""
						if app.ReleaseYear != "" && app.Developer != "" {
							base_str = fmt.Sprintf("(%s by \"%s\")", app.ReleaseYear, app.Developer)
						}
						info := fmt.Sprintf("[http://steamspy.com/app/%d/] \"%s\" %s %s %s %s", app.Id, app.Name, base_str, os_str, rating_str, price)
						zax.Privmsg(reply_to, info)
					} else {
						log.Error("Failed to retrieve steamapp info.")
					}

				} else {
					log.Notice("Failed to retrieve appid from search.")
				}
			}
			// Handle URLs
			if !(sender == "Wipe" && (strings.Contains(text, "Steam") || strings.Contains(text, "YouTube"))) && config.ProcessUrls {
				log.Debug("Looking for URLs...")
				urls := xurls.Relaxed.FindAllString(text, -1)
				for i := 0; i < len(urls); i++ {
					url := urls[i]
					log.Debugf("Found reddit url: %s", url)
					history.AddUrl(sender, url)

					if url == last_url {
						log.Debugf("Matches same url (%s) as last time, ignore.", last_url)
						continue
					}
					reddit, success := reddit.Search(url)
					if success {
						zax.Privmsg(reply_to, reddit)
					} else {
						log.Debug("Failed to retrieve reddit URL for the link.")
					}
					last_url = url
				}
			}
			time.Sleep(10 * time.Millisecond)
		})

	<-quit
	log.Notice("Closing history.log")
	file_history.Close()
	time.Sleep(1000 * time.Millisecond)
}
Пример #24
0
func main() {
	flag.Parse()
	if *apiKey == "" {
		log.Fatalln("Missing API key, provide one using -api-key")
	}
	lfm = lastfm.New(*apiKey)
	loadNickMap()
	loadCache()

	if *cacheFile != "" {
		cacheTimer = time.NewTimer(120 * time.Second)
		go func() {
			for _ = range cacheTimer.C {
				saveCacheNow()
				cacheTimer.Reset(120 * time.Second)
			}
		}()
	}

	if *server == "" {
		log.Fatalln("No server to connect to")
	}
	if *channelList == "" {
		log.Fatalln("No channels to join")
	}

	config := client.NewConfig(*botNick)
	config.Version = "github.com/Kovensky/go-lastfm-bot"
	config.SSL = *useSSL
	config.Flood = false

	// TODO: CA management?
	config.SSLConfig = &tls.Config{InsecureSkipVerify: true}

	irc := client.Client(config)

	addNickHandlers(irc)
	addWhoHandlers(irc)

	irc.HandleFunc(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.HandleFunc("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.HandleFunc("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.HandleFunc("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.HandleFunc("332", func(irc *client.Conn, line *client.Line) {
		log.Println("Joined", line.Args[1])
	})
	irc.HandleFunc("INVITE", onInvite)
	irc.HandleFunc("PRIVMSG", onPrivmsg)

	quitting := false
	quit := make(chan bool)
	irc.HandleFunc(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)
			errorCount := 0
			for !irc.Connected() {
				log.Println("Reconnecting...")
				err := irc.ConnectTo(*server, *password)
				if err != nil {
					log.Println("Error reconnecting:", err)
					// limited exponential backoff (10, 12, 14, 18, 26, 42, 74)
					retryDuration := 10 + time.Duration(math.Pow(2, float64(errorCount)))*time.Second
					if errorCount < 6 {
						errorCount += 1
					}
					log.Println("Retrying in", retryDuration)
					time.Sleep(retryDuration)
				}
			}
		}()
	})
	if *useSSL {
		log.Println("Using SSL")
	}
	log.Println("Connecting to", *server)
	irc.ConnectTo(*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
}
Пример #25
0
func main() {
	if len(os.Args) < 2 {
		fmt.Println("Cannot read config file!")
		os.Exit(3)
	}
	irc.InitConf(os.Args[1])
	if len(irc.GetLogFile()) > 0 {
		f, err := os.OpenFile(irc.GetLogFile(), os.O_APPEND|os.O_CREATE|os.O_RDWR, 0666)
		if err != nil {
			fmt.Printf("Error opening log file: %v", err)
			os.Exit(3)
		}
		defer f.Close()
		log.SetOutput(f)
	} else {
		if runtime.GOOS == "windows" {
			var format = new(prefixed.TextFormatter)
			format.ForceColors = true
			log.SetFormatter(format)
		}
	}

	log.SetLevel(log.DebugLevel)
	log.Infof("<<<<<----- Application started %s ----->>>>>", time.Now())
	irc.InitImageAction()
	CheckAndCreate(irc.GetDataPath())
	CheckAndCreate(filepath.Join(irc.GetDataPath(), "thumb"))
	CheckAndCreate(filepath.Join(irc.GetDataPath(), "image"))
	CheckAndCreate(filepath.Join(irc.GetDataPath(), "gif"))
	CheckAndCreate(filepath.Join(irc.GetDataPath(), "webm"))

	cfg := client.NewConfig(irc.GetBotName())
	cfg.SSL = irc.GetUseSsl()
	cfg.Server = fmt.Sprintf("%s:%d", irc.GetServerAddress(), irc.GetServerPort())
	cfg.Pass = irc.GetServerPassword()

	c = client.Client(cfg)
	handler := irc.NewHandler(c, irc.GetChannel())

	var ssl crypt.Config
	ssl.InsecureSkipVerify = irc.GetAcceptInvalidCert()
	cfg.SSLConfig = &ssl

	quit = make(chan bool)
	lastReconnect = time.Now()

	c.HandleFunc("connected",
		func(conn *client.Conn, line *client.Line) {
			log.Infof("Connected to server %s, joining channel %s", irc.GetServerAddress(), irc.GetChannel())
			conn.Join(fmt.Sprintf("%s %s", irc.GetChannel(), irc.GetChannelPassword()))
		})

	c.HandleFunc("privmsg",
		func(conn *client.Conn, line *client.Line) {
			handler.Recv(line.Args[1], line.Nick)
		})

	c.HandleFunc("disconnected",
		func(conn *client.Conn, line *client.Line) {
			log.Infof("Disconnected from server %s", irc.GetServerAddress())
			handleDisconnect()
		})
	c.HandleFunc("KICK",
		func(conn *client.Conn, line *client.Line) {
			log.Infof("Kicked from channel %s", irc.GetChannel())
			if irc.GetAutoReJoin() {
				log.Infof("Joining channel %s", irc.GetChannel())
				conn.Join(fmt.Sprintf("%s %s", irc.GetChannel(), irc.GetChannelPassword()))
			}
		})
	err := connect()
	if err != nil {
		log.Errorf(err.Error())
		handleDisconnect()
	}
	go irc.ImageAction.StartupCheck()
	web.StartWeb()
	<-quit
}