func New(b bot.Bot, isupportPlugin *isupport.Plugin, modePlugin *mode.Plugin) *Plugin { plugin := &Plugin{ bot: b, tbmgr: map[string]*TemporaryBanManager{}, isupport: isupportPlugin, mode: modePlugin, OldHostmasks: []string{}, } modePlugin.HandleFunc("-b", func(e *mode.ModeChangeEvent) { if ok, _, _ := isupportPlugin.IsChannel(e.Target); !ok { return // not a channel } hostmask := e.Argument tbmgr := plugin.ensureTemporaryBanManager(e.Target) if ban, ok := tbmgr.Remove(hostmask); ok { logging.Debug("%v: %v removed the temporary ban for %v", e.Target, e.Nick, ban.Hostmask) plugin.syncBans(e.Target) } }) b.HandleFunc("join", func(conn *client.Conn, line *client.Line) { if line.Nick != conn.Me().Nick { return } plugin.loadBans(line.Args[0]) go plugin.dumpBans(line.Args[0]) }) return plugin }
func New(b bot.Bot, isupportPlugin *isupport.Plugin, modePlugin *mode.Plugin) *Plugin { plugin := &Plugin{ bot: b, tbmgr: map[string]*tempban.TemporaryBanManager{}, isupport: isupportPlugin, mode: modePlugin, } b.HandleFunc("join", func(conn *client.Conn, line *client.Line) { if line.Nick != conn.Me().Nick { return } plugin.loadBans(line.Args[0]) go plugin.dumpBans(line.Args[0]) }) return plugin }
// Creates a new plugin instance. func New(b bot.Bot, isupportPlugin *isupport.Plugin) *Plugin { plugin := &Plugin{ bot: b, isupport: isupportPlugin, } // ("."|"!"|"+"|"@")"bots" b.HandleFunc("privmsg", func(conn *client.Conn, line *client.Line) { // Check if this came from a channel named "bots" or "vpnbot" chanPrefixes, _ := plugin.isupport.Supports().ChanTypes() prefixes, channelName := isupport.SplitIrcPrefix(line.Args[0], chanPrefixes) if len(prefixes) <= 0 { return // target not a channel } if !strings.EqualFold(channelName, "bots") && !strings.EqualFold(channelName, "vpnbot") { return } // Check if this is the "bots" command (with either prefix below) words := strings.Split(line.Args[1], " ") prefixes, firstWord := isupport.SplitIrcPrefix(words[0], []rune(".!+@")) if len(prefixes) <= 0 { return // not a command } if !strings.EqualFold(firstWord, "bots") { return // not the bots command } // Report in! plugin.bot.Privmsg(line.Args[0], fmt.Sprintf( "Reporting in! [Go] See %v12%vhttps://github.com/icedream/vpnbot%v%v", "\x03", "\x1F", "\x1F", "\x03")) }) return plugin }
// Creates a new plugin instance. func New(b bot.Bot) *Plugin { plugin := &Plugin{ bot: b, supports: &Support{ Data: map[string]string{}, }, } // Handle 005/ISUPPORT b.HandleFunc(ircISupport, func(conn *client.Conn, line *client.Line) { if len(line.Args) < 2 || !strings.HasSuffix( line.Args[len(line.Args)-1], "are supported by this server") { return } // First arg is our name, last arg is "are supported by this server" for _, support := range line.Args[1 : len(line.Args)-1] { name := "" value := "" if strings.Contains(support, "=") { spl := strings.SplitN(support, "=", 2) name, value = strings.ToUpper(spl[0]), spl[1] } else { name = strings.ToUpper(support) } // Set in supports table plugin.supports.Data[name] = value } }) return plugin }
// Creates a new plugin instance. func New(b bot.Bot) *Plugin { plugin := &Plugin{ bot: b, } // Handle INVITE b.HandleFunc("invite", func(conn *client.Conn, line *client.Line) { if len(line.Args) < 2 { return } channel := line.Args[1] joinChan := make(chan interface{}) go func() { defer conn.HandleFunc("join", func(conn *client.Conn, line *client.Line) { // Is this us joining somewhere? if line.Nick != conn.Me().Nick { return } // JOIN message should always have a channel sent with it if len(line.Args) < 1 { return } // Is this the channel we got invited to? if line.Args[0] != channel { return } // Yup, we're done here joinChan <- struct{}{} }).Remove() select { case <-time.After(10 * time.Second): // Oops, we timed out logging.Warn("Timed out while waiting for us to join %v", channel) return case <-joinChan: } // We have joined successfully, let's send our hello message! b.Privmsg(channel, "Hi, I'm vpn, I automatically get rid of bad "+ "IP-changing ban evading bots! I need half-op (+h/%) to do "+ "this properly, thank you!") }() // Join and wait until joined b.Join(channel) }) return plugin }
// Creates a new plugin instance. func New(b bot.Bot, isupportPlugin *isupport.Plugin) *Plugin { plugin := &Plugin{ bot: b, isupport: isupportPlugin, intHandlers: handlerSet(), fgHandlers: handlerSet(), bgHandlers: handlerSet(), } // Handle MODE b.HandleFunc("mode", func(conn *client.Conn, line *client.Line) { if len(line.Args) < 2 { return } isChannel, _, _ := isupportPlugin.IsChannel(line.Args[0]) modes := line.Args[1] var action ModeChangeAction hasAction := false paramIndex := 2 getParam := func() (retval string, ok bool) { if len(line.Args) <= paramIndex { return } retval = line.Args[paramIndex] ok = true paramIndex++ return } knownModes, ok := isupportPlugin.Supports().ChanModes() if !ok { return // TODO use some decent defaults } for _, mode := range modes { switch mode { case '-': hasAction = true action = ModeChangeAction_Removed case '+': hasAction = true action = ModeChangeAction_Added default: if !hasAction { return // + or - must come first! } modeChange := ModeChange{ Mode: mode, Action: action, HasArgument: false, } if isChannel { // Find the mode in ISupports for _, knownMode := range knownModes { if knownMode.Mode != mode { continue } switch knownMode.Type { case isupport.ChanModeType_List, isupport.ChanModeType_Setting: // Always has a parameter arg, ok := getParam() if !ok { return // invalid syntax } modeChange.Argument = arg case isupport.ChanModeType_Setting_ParamWhenSet: // Only has parameter when set if action == ModeChangeAction_Added { arg, ok := getParam() if !ok { return // invalid syntax } modeChange.Argument = arg } case isupport.ChanModeType_Setting_NoParam: // No parameter } } } e := &ModeChangeEvent{ ModeChange: modeChange, Host: line.Host, Ident: line.Ident, Nick: line.Nick, Src: line.Src, Tags: line.Tags, Target: line.Target(), } // Pass event to handlers plugin.dispatch("*", e) switch action { case ModeChangeAction_Added: plugin.dispatch(string([]rune{rune('+'), mode}), e) case ModeChangeAction_Removed: plugin.dispatch(string([]rune{rune('-'), mode}), e) } } } }) return plugin }
func New(b bot.Bot, whoisPlugin *whois.Plugin, isupportPlugin *isupport.Plugin, tempbanPlugin *tempban.Plugin, nickservPlugin *nickserv.Plugin) *Plugin { if whoisPlugin == nil { panic("whoisPlugin must not be nil") } if isupportPlugin == nil { panic("isupportPlugin must not be nil") } if tempbanPlugin == nil { panic("tempbanPlugin must not be nil") } if nickservPlugin == nil { panic("nickservPlugin must not be nil") } plugin := &Plugin{ bot: b, whois: whoisPlugin, isupport: isupportPlugin, tempban: tempbanPlugin, nickserv: nickservPlugin, lastCheckNicks: map[string]time.Time{}, Admins: []string{}, } b.Conn().HandleFunc("join", plugin.OnJoin) b.Commands().Add("listbans", bot.Command{ Hidden: true, Pub: true, Help: "(only admins) Lists bans the bot set in a channel.", Handler: func(e *bot.Event) { if !plugin.isAdmin(e.Line.Src) { return } channel := e.Args if len(channel) < 1 { b.Privmsg(e.Target, "Need a channel to query.") return } bans := tempbanPlugin.Bans(channel) if len(bans) == 0 { b.Privmsg(e.Target, fmt.Sprintf("No bans set for \x02%v\x02.", channel)) } else { for i, ban := range bans { b.Privmsg(e.Target, fmt.Sprintf("%4v. \x02%-41v\x02 (\x02%v\x02, expires \x02%v\x02)", i+1, ban.Hostmask, ban.Reason, humanize.Time(ban.ExpirationTime))) } } }, }) b.Commands().Add("globalban", bot.Command{ Hidden: true, Pub: true, Help: "(only admins) Globally bans a specific nickname or hostmask with given duration and reason.", Handler: func(e *bot.Event) { if !plugin.isAdmin(e.Line.Src) { return } split := strings.SplitN(e.Args, " ", 3) if len(split) < 3 { b.Privmsg(e.Target, "Need a nickname or hostmask, duration and reason to ban, in this order.") return } nick, durationStr, reason := split[0], split[1], split[2] reason = fmt.Sprintf("Manual global ban: %v", reason) duration, err := time.ParseDuration(durationStr) var banmask string if !strings.Contains(nick, "@") && !strings.Contains(nick, "!") { if err != nil { b.Privmsg(e.Target, fmt.Sprintf("Failed to parse duration: %v", err)) return } // Generate the ban mask from WHOIS information info, err := whoisPlugin.WhoIs(nick) if err != nil { b.Privmsg(e.Target, fmt.Sprintf("Can't get information about this nick: %v", err)) return } banmask = fmt.Sprintf("%v!%v@%v", "*", "*", info.Host) } else { banmask = nick nick = "" } b.Privmsg(e.Target, fmt.Sprintf("Banning \x02%v\x02 until \x02%v\x02 with reason \x02%v\x02.", banmask, humanize.Time(time.Now().Add(duration)), reason)) plugin.banGlobal(plugin.generateBan(nick, banmask, reason, duration)) }, }) b.Commands().Add("globalunban", bot.Command{ Hidden: true, Pub: true, Help: "(only admins) Globally unbans a specific nickname or hostmask.", Handler: func(e *bot.Event) { if !plugin.isAdmin(e.Line.Src) { return } if len(e.Args) <= 0 { b.Privmsg(e.Target, "Need a nickname or hostmask.") return } nick := e.Args var banmask string if !strings.Contains(nick, "@") && !strings.Contains(nick, "!") { // Generate the ban mask from WHOIS information info, err := whoisPlugin.WhoIs(nick) if err != nil { b.Privmsg(e.Target, fmt.Sprintf("Can't get information about this nick: %v", err)) return } banmask = fmt.Sprintf("%v!%v@%v", "*", "*", info.Host) } else { banmask = nick } b.Privmsg(e.Target, fmt.Sprintf("Unbanning \x02%v\x02.", banmask)) plugin.unbanGlobal(banmask) }, }) return plugin }