Beispiel #1
0
func Load(path string) *Config {
	cfg := new(Config)

	if _, err := toml.DecodeFile(path, &cfg); err != nil {
		logger.Fatalf("Cannot read config file; %s", err)
	}

	return cfg
}
Beispiel #2
0
func (a *NPServer) Start() error {
	// You can't use property, err := sth, because golang will qq
	// This thing binds a classic TCP listener to the server
	var err error
	a.listener, err = net.Listen("tcp", environment.Env.Config.NP.BindingAddress)
	if err != nil {
		logger.Fatalf("Error listening; %s", err)
	}

	defer a.listener.Close()

	logger.Infof("Serving NP server on %s", environment.Env.Config.NP.BindingAddress)

	var tempDelay time.Duration

	for {
		conn, e := a.listener.Accept()

		if e != nil {
			if ne, ok := e.(net.Error); ok && ne.Temporary() {
				if tempDelay == 0 {
					tempDelay = 5 * time.Millisecond
				} else {
					tempDelay *= 2
				}

				if max := 1 * time.Second; tempDelay > max {
					tempDelay = max
				}

				logger.Errorf("http: Accept error: %v; retrying in %v", e, tempDelay)
				time.Sleep(tempDelay)
				continue
			}

			return e
		}

		// Seperated it from the listener code to make it clean
		go a.HandleConnection(conn)
	}

	return nil
}
Beispiel #3
0
func main() {
	// Add the Stdout logger
	logger.AddOutput(logger.Stdout{
		MinLevel: logger.ERROR, //logger.DEBUG,
		Colored:  true,
	})

	// Load settings from config.toml in working directory
	settings := config.Load("./config.toml")

	/*logger.AddOutput(&logger.File{
		MinLevel: logger.WARNING,
		Path:     "./server.log",
	})*/

	// Load the aCI3 key
	err := aci.LoadKey(settings.NP.AnticheatKeyPath)
	if err != nil {
		logger.Fatalf("Cannot load aCI3 key; %s", err)
	} else {
		logger.Infof("Loaded aCI3 key")
	}

	// Start the NewRelic client if it's enabled in the config file
	if settings.NewRelic.Enabled {
		agent := gorelic.NewAgent()
		agent.Verbose = settings.NewRelic.Verbose
		agent.NewrelicName = settings.NewRelic.Name
		agent.NewrelicLicense = settings.NewRelic.License
		agent.Run()
	}

	// Generate a Jet database connector.
	// Here, err shows if the connection string syntax is valid.
	// The actual creds are checked during the first query.
	database, err := jet.Open(
		settings.Database.Driver,
		settings.Database.ConnectionString,
	)
	defer database.Close()

	if err != nil {
		logger.Fatalf("Cannot connect to database; %s", err)
	}

	// But Redis connects here! As far as I know, autoreconnect is implemented
	cache := redis.NewTCPClient(&redis.Options{
		Addr:     settings.Redis.Address,
		Password: settings.Redis.Password,
		DB:       int64(settings.Redis.Database),
	})
	defer cache.Close()

	// Set up a new environment object
	environment.SetEnvironment(&environment.Environment{
		Config:   settings,
		Database: database,
		Redis:    cache,
	})

	// This thing is massive
	// The main network platform server that game connects to
	if settings.NP.Enabled {
		np_server := np.New()
		go np_server.Start()
	}

	// HTTP-based remote authentication form and a simple API
	// Is supposed to replace half of 3k
	if settings.HTTP.Enabled {
		http_server := http.New()
		go http_server.Start()
	}

	/*if settings.PlayerLog.Enabled {
		playerlog_server := playerlog.Init(settings.PlayerLog)
		go playerlog_server.Start()
	}

	if settings.Misc.Enabled {
		misc_server := misc.Init(settings.Misc)
		go misc_server.Start()
	}*/

	// select{} stops execution of the program until all goroutines close
	// TODO: add panic recovery!
	if settings.NP.Enabled ||
		settings.PlayerLog.Enabled ||
		settings.Misc.Enabled ||
		settings.HTTP.Enabled {
		select {}
	}
}