예제 #1
0
파일: bot.go 프로젝트: raindevteam/rain
// moduleExited is called when a module process has exited. If an error was returned when exiting
// it will be logged. The output (Stdout and Stderr) is also logged. If the module exists in the
// handler it will be removed. The module is also unregistered from the bot.
func (b *Bot) moduleExited(name string, result *Result) {
	b.Mu.Lock()
	defer b.Mu.Unlock()

	if result.Err != nil {
		rlog.Error("Bot", name+" [Module Process] has exited with: "+result.Err.Error())
	} else {
		rlog.Info("Bot", "Module "+name+" [Module Process] has exited")
	}

	if result.Output != "" {
		rlog.Info(name, "Process output:"+"\n ----\n"+result.Output+"\n ----\n")
	}

	if b.Handler.ModuleExists(name) {
		// If the module process is dead we can rest assured signalling it to clean up will fail
		// so we won't even try. It's the sanest thing to do!
		b.Handler.RemoveModule(ModuleName(name))
	}

	if !b.Modules[name].Registered {
		rlog.Error("Bot", name+" [Module Client] did not manage to register")
	} else {
		b.Modules[name].Registered = false
		rlog.Info("Bot", name+" [Module Client] has been unregistered from the bot")
	}
}
예제 #2
0
파일: bot.go 프로젝트: raindevteam/rain
// DefaultConnectWithMsg is similar to DefaultConnect, except a user may pass a pre-connect and
// post-connect message.
func (b *Bot) DefaultConnectWithMsg(pre string, post string) {
	if pre != "" {
		rlog.Info("Bot", pre)
	}

	b.Connect()

	if post != "" {
		rlog.Info("Bot", post)
	}

	b.Listen()
}
예제 #3
0
파일: bot.go 프로젝트: raindevteam/rain
// LoadModules starts the bot's rpc master server and then calls moduleRun() on all modules.
func (b *Bot) loadModules() {
	b.startRPCServer()
	for name, module := range b.Modules {
		if _, ok := module.Options["noload"]; ok {
			rlog.Info("Bot", "Module "+name+" has option noload, not loading")
			continue
		}

		go func(name string, pm *ProcessManager) {
			result := pm.Start(b.ListenPort)
			b.moduleExited(name, result)
		}(name, module.PM)

		rlog.Info("Bot", "Module "+name+" loaded")
	}
}
예제 #4
0
파일: bot.go 프로젝트: raindevteam/rain
// EnableModules goes through every module list found in the config and sets them up appropriately.
func (b *Bot) EnableModules() {
	rlog.Info("Bot", "Enabling Modules...")

	b.Handler.AddRemoveCallback(func(name ModuleName) {
		b.Modules[strings.ToLower(string(name))].Registered = false
	})

	for modtype, modules := range b.Config.Module.Modules {
		for name, value := range modules {
			route, optionsArray := b.Parser.ParseModuleValue(value)

			optionsMap := make(map[string]bool)
			for _, opt := range optionsArray {
				optionsMap[opt] = true
			}

			if route == "." {
				route = DefaultModulesRoute + modtype
			}

			b.Modules[strings.ToLower(name)] = NewModule(name, route, optionsMap, modtype)
			rlog.Debug("Bot", "Module "+name+" Created")
		}
	}
	b.loadModules()
}
예제 #5
0
파일: bapi.go 프로젝트: raindevteam/rain
// JoinChannel takes a JoinRequest. It will add the channel to join to the ToJoinChs map so that
// when the bot receives a JOIN reply from the IRC server, it can verify whether it joined a
// channel.
func (b BotAPI) JoinChannel(jr JoinRequest, result *string) error {
	b.bot.ToJoinChs[strings.ToLower(jr.Channel)] = jr.Caller

	if jr.Password != "" {
		b.bot.Send(irc.JOIN, jr.Channel, jr.Password)
	} else {
		rlog.Info("BAPI", "Joining "+jr.Channel)
		b.bot.Send(irc.JOIN, jr.Channel)
	}

	return nil
}
예제 #6
0
파일: bot.go 프로젝트: raindevteam/rain
// startRPCServer registers the master consumer for plugins. The master consumer allows plugins to
// communicate with the bot, allowing access to connected channels, users and registered modules.
// Conventionally, it uses a json codec to serve.
func (b *Bot) startRPCServer() {
	rpc.RegisterName("Master", BotAPI{b})
	master, err := net.Listen("tcp", ":0")
	b.ListenPort = strconv.Itoa(master.Addr().(*net.TCPAddr).Port)
	rlog.Info("Bot", "Listening on port: "+b.ListenPort)

	if err != nil {
		rlog.Error("Bot", err.Error())
	}

	// Start accepting connections
	go func() {
		for {
			conn, _ := master.Accept()
			go rpc.ServeCodec(RpcCodecServer(conn))
		}
	}()
}
예제 #7
0
// Join will create a new channel if the bot is the one joining. Otherwise it updates a channel's
// user list
func (l *Listeners) Join(msg *irc.Message) {
	l.bot.Mu.Lock()
	defer l.bot.Mu.Unlock()

	who := msg.Prefix.Name
	where := msg.Trailing

	if who == l.bot.GetNick() {
		rlog.Info("Bot", "Joined: "+where)

		caller, ok := l.bot.ToJoinChs[strings.ToLower(where)]
		if ok {
			l.bot.Say(caller, "Joined "+where)
		}

		channel := rbot.NewChannel(where)
		l.bot.Channels[strings.ToLower(where)] = channel
		return
	}

	channel := l.bot.Channels[strings.ToLower(where)]
	channel.Users[who] = ""
}