Example #1
0
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
}
Example #2
0
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
}
Example #3
0
// 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
}
Example #4
0
// 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
}
Example #5
0
// 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
}
Example #6
0
// 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
}
Example #7
0
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
}