func CreateServer(config *Config) *Server { var err error srv := &Server{Config: config} // We have global alias and minions files available to everyone. The // alias module and irc io adapter use aliases and everything uses minions. srv.Aliases, err = alias.Open(config.AliasFilePath) if err != nil { log.Fatal("alias file error: ", err.Error()) } srv.Minions, err = OpenMinionsFile(config.MinionsFilePath) if err != nil { log.Fatal("minions file error: ", err.Error()) } srv.RegisteredCommands = make(map[string]Command) srv.InputQueue = make(chan *Message, 128) srv.OutputQueue = make(chan *OutputMessage, 128) srv.ClientRegistry = make(map[string]*Client) srv.Salt = make([]byte, 32) _, err = io.ReadFull(rand.Reader, srv.Salt) if err != nil { log.Fatal("failed to generate startup salt") } return srv }
func main() { ParseCommandLine() err := ParseConfigFile() if err != nil { log.Fatal("config error: ", err.Error()) } // We have global alias and minions files available to everyone. The // alias module and irc io adapter use aliases and everything uses minions. Aliases, err = alias.Open(cfg.AliasFilePath) if err != nil { log.Fatal("alias file error: ", err.Error()) } Minions, err = OpenMinionsFile(cfg.MinionsFilePath) if err != nil { log.Fatal("minions file error: ", err.Error()) } log.Printf("registering modules") RegisterModule(&AliasModule{}) RegisterModule(&CommandsModule{}) RegisterModule(&ImageModule{}) RegisterModule(&VideoModule{}) RegisterModule(&RebootModule{}) RegisterModule(&MinionsModule{}) RegisterModule(&NopModule{}) RegisterModule(&PingModule{}) RegisterModule(&PlayModule{}) RegisterModule(&SayModule{}) RegisterModule(&SkipModule{}) RegisterModule(&ShutUpModule{}) RegisterModule(&TurretModule{}) RegisterModule(&VolumeModule{}) RegisterModule(&XombreroModule{}) log.Printf("starting i/o adapters") ircerrch, minionerrch, err := StartAdapters() if err != nil { log.Fatal("failed to start adapters: ", err.Error()) } go waitForTraceRequest() log.Printf("ready") for { select { case err := <-ircerrch: log.Printf("irc handler error: %s", err.Error()) case err := <-minionerrch: log.Printf("minion handler error: %s", err.Error()) case msg := <-InputQueue: switch msg.Type { case MsgTypeIRCChannel: go IRCMessageHandler(msg) case MsgTypeIRCPrivate: go IRCMessageHandler(msg) case MsgTypeMinion: go MinionMessageHandler(msg) case MsgTypeExit: log.Printf("terminating: %s", msg.Body) os.Exit(0) case MsgTypeFatal: log.Fatal("fatal error: " + msg.Body) default: log.Printf("msg handler error: un-handled type"+ " '%d'", msg.Type) } // This delay allows each scheduled routine to start. // This is not particularly pretty but in case a user // sends multiple commands in the same request (e.g. // say 1; say 2; say 3), it should give enough time for // the output messages to be processed in the same // order they were received. time.Sleep(50 * time.Millisecond) } } }