Beispiel #1
0
// InvokeInit stops at the first error
// If plugins is nil, all plugins are inited.
// Otherwise, only the listed plugins are inited.
func InvokeInit(plugins []string, config map[string]map[string]interface{}) error {
	pluginState.Lock()
	defer pluginState.Unlock()
	if pluginState.State != StatePreInit {
		panic("InvokeInit called after init")
	}
	var pluginMap map[string]bool
	if plugins != nil {
		pluginMap = make(map[string]bool, len(plugins))
		pluginMap[""] = true // always load unnamed plugins, they're for support
		for _, name := range plugins {
			pluginMap[name] = true
		}
	}
	pluginState.State = StatePostInit
	registry = callback.NewRegistry(callback.DispatchSerial)
	for _, plugin := range pluginState.Plugins {
		if pluginMap != nil && !pluginMap[plugin.Name] {
			continue
		}
		callbacks := plugin.Callbacks
		if callbacks.Init != nil {
			if err := callbacks.Init(registry, config[plugin.Name]); err != nil {
				return err
			}
		}
		plugin.inited = true
	}
	return nil
}
Beispiel #2
0
// Connect initiates a connection to an IRC server identified by the Config.
// It returns once the connection has been established.
// If a connection could not be established, an error is returned.
func Connect(config Config) (SafeConn, error) {
	if config.Init == nil {
		return nil, errors.New("Config needs an Init function")
	}

	port := config.Port
	if port == 0 {
		if config.SSL {
			port = 6697
		} else {
			port = 6667
		}
	}
	addr := net.JoinHostPort(config.Host, strconv.FormatUint(uint64(port), 10))
	writer, reader := make(chan string), make(chan string)
	writeErr, readErr := make(chan error, 1), make(chan error, 1)
	invoker := make(chan func(*Conn))
	conn := &Conn{
		me: User{
			Nick: config.Nick,
			User: config.User,
		},
		stateRegistry: callback.NewRegistry(callback.DispatchSerial),
		nickInUse:     config.NickInUse,
		writer:        writer,
		reader:        reader,
		writeErr:      writeErr,
		readErr:       readErr,
		invoker:       invoker,
		safeConnState: &safeConnState{
			server:   addr,
			registry: callback.NewRegistry(callback.DispatchSerial),
		},
	}
	nc, err := dialServer(addr, config.Timeout, config.SSL, config.SSLConfig)
	if err != nil {
		return nil, err
	}
	conn.netconn = nc
	config.Init(conn)
	// set up the writer and reader before we call any callbacks
	go connWriter(nc, writer, writeErr, config.AllowFlood)
	go connReader(nc, reader, readErr)
	// also set up the invoker infinite queue
	queue := make(chan func(*Conn))
	go invokerQueue(invoker, queue)
	// set up the safeConnState
	conn.safeConnState.Lock()
	conn.safeConnState.writer = conn.writer
	conn.safeConnState.invoker = queue
	conn.safeConnState.Unlock()
	// set up the pinger
	if config.PingInterval >= 0 {
		delta := config.PingInterval
		if delta == 0 {
			delta = 3 * time.Minute
		}
		go pinger(conn.SafeConn(), delta)
	}
	// dispatch the INIT callback
	conn.safeConnState.registry.Dispatch(INIT, conn)
	// set up our state handlers
	conn.setupStateHandlers()
	// fire off the login lines
	conn.logIn(config.RealName, config.Password)
	// and finally, start the main loop in a new goroutine
	go conn.runLoop()
	return conn.SafeConn(), nil
}