func Register(b *bot.Bot) { if len(*chans) == 0 { log.Printf("skipping paste init: no channels to notify") return } b.OnConnect(addServer) b.OnDisconnect(delServer) go pasteloop() }
func Register(b *bot.Bot) { if len(*chans) == 0 { log.Printf("skipping paste init: no channels to notify") } b.OnConnect(addServer) b.OnDisconnect(delServer) url, err := url.Parse(*psrvurl) if err != nil { log.Fatalf("paste: bad url %q: %s", *psrvurl, err) } psrv := proto.NewGoPasteWebClient(webrpc.ProtoBuf, url) go waitloop(psrv) }
// Run creates the proper bindings on the bot and listens for commands on its // servers. This function does not exit, and so it should be called in its own // goroutine if further work needs to be done. func Run(b *bot.Bot, startchar byte, cmds []*Command) { // Handy local type for bundling data type event struct { name string srv *bot.Server msg *bot.Message } // Make the event handler events := make(chan event, 10) handle := func(evname string, srv *bot.Server, msg *bot.Message) { events <- event{evname, srv, msg} } // Listen for the events we want for _, evname := range []string{ bot.ON_CHANMSG, bot.ON_PRIVMSG, bot.ON_NOTICE, } { b.OnEvent(evname, handle) } // Sort the commands for help sort.Sort(commandSorter(cmds)) // Map the commands for easy access cmdmap := make(map[string][]*Command, len(cmds)) cmdlen := 0 for _, cmd := range cmds { cmd.name = strings.ToUpper(cmd.name) cmdmap[cmd.name] = append(cmdmap[cmd.name], cmd) if l := len(cmd.name); l > cmdlen { cmdlen = l } } log.Printf("Command length: %d", cmdlen) // Add ping if _, ok := cmdmap["PING"]; !ok { c := &Command{ name: "PING", help: "Built-in CTCP PING handler", priv: true, hook: func(s *Source, r *Response, cmd string, args []string) { r.Private() r.Printf("PING %s", strings.Join(args, " ")) }, } cmdmap["PING"] = append(cmdmap["PING"], c) cmds = append(cmds, c) } // Add the help command if _, ok := cmdmap["HELP"]; !ok { c := &Command{ name: "HELP", help: "Online help", priv: false, } cmdmap["HELP"] = append(cmdmap["HELP"], c) cmds = append(cmds, c) c.hook = genhelp(cmds, cmdlen) } // Wait for events and handle them for e := range events { // Ignore malformatted messages if len(e.msg.Args) < 2 || len(e.msg.Args[1]) == 0 { continue } // Determine if it is a command (CTCP or with the leader char) text, ctcp := e.msg.Args[1], false switch text[0] { case 0x01: text, ctcp = DecodeCTCP(text), true case startchar: text = text[1:] default: if e.name == bot.ON_CHANMSG { continue } } if text == "" { continue } // Parse the command into arguments command, args := "", strings.Fields(text) command, args = args[0], args[1:] // Look up the command cmd, ok := cmdmap[strings.ToUpper(command)] if !ok { continue } // Build the reply replies := make(chan *bot.Message, 10) go func() { if ctcp { for m := range replies { switch m.Command { case bot.CMD_PRIVMSG: fallthrough case bot.CMD_NOTICE: if len(m.Args) > 1 { m.Args[1] = EncodeCTCP(m.Args[1]) } } e.srv.WriteMessage(m) } return } for m := range replies { e.srv.WriteMessage(m) } }() resp := &Response{ out: replies, } src := &Source{ server: e.srv, message: e.msg, } // Set the public/private responses nick := e.msg.ID().Nick switch e.name { case bot.ON_CHANMSG: resp.public = e.msg.Args[0] resp.private = nick case bot.ON_PRIVMSG: resp.public = nick resp.private = nick case bot.ON_NOTICE: resp.public = "" resp.private = "" } // Call the hook for _, cmd := range cmd { cmd.hook.call(src, resp, command, args) } } }