Example #1
0
// StartMasterRetrieval starts a timed retrieval of servers specified by a given
// filter from the Steam Master server after an initial delay of initialDelay
// seconds. It retrieves the list every timeBetweenQueries seconds thereafter.
// A bool can be sent to the stop channel to cancel all timed retrievals.
func StartMasterRetrieval(stop chan bool, filter filters.Filter,
	initialDelay int, timeBetweenQueries int) {
	retrticker := time.NewTicker(time.Duration(timeBetweenQueries) * time.Second)

	logger.WriteDebug(
		"Waiting %d seconds before grabbing %s servers. Will retrieve servers every %d secs afterwards.", initialDelay, filter.Game.Name, timeBetweenQueries)

	logger.LogAppInfo(
		"Waiting %d seconds before grabbing %s servers from master. Will retrieve every %d secs afterwards.", initialDelay, filter.Game.Name, timeBetweenQueries)

	firstretrieval := time.NewTimer(time.Duration(initialDelay) * time.Second)
	<-firstretrieval.C
	logger.WriteDebug("Starting first retrieval of %s servers from master.",
		filter.Game.Name)
	sl, err := retrieve(filter)
	if err != nil {
		logger.LogAppErrorf("Error when performing timed master retrieval: %s", err)
	}
	models.MasterList = sl

	for {
		select {
		case <-retrticker.C:
			go func(filters.Filter) {
				logger.WriteDebug("%s: Starting %s master server query", time.Now().Format(
					"Mon Jan 2 15:04:05 2006 EST"), filter.Game.Name)
				logger.LogAppInfo("%s: Starting %s master server query", time.Now().Format(
					"Mon Jan 2 15:04:05 2006 EST"), filter.Game.Name)
				sl, err := retrieve(filter)
				if err != nil {
					logger.LogAppErrorf("Error when performing timed master retrieval: %s",
						err)
				}
				models.MasterList = sl
			}(filter)
		case <-stop:
			retrticker.Stop()
			return
		}
	}
}
Example #2
0
// Start listening for and responding to HTTP requests via the web server. Panics
// if unable to start.
func Start(runSilent bool) {
	r := newRouter()

	if !runSilent {
		printStartInfo()
	}

	logger.LogAppInfo("Starting HTTP server on port %d",
		config.Config.WebConfig.APIWebPort)

	srv := http.Server{
		Addr:           fmt.Sprintf(":%d", config.Config.WebConfig.APIWebPort),
		Handler:        r,
		ReadTimeout:    30 * time.Second,
		WriteTimeout:   30 * time.Second,
		MaxHeaderBytes: 1 << 20}

	err := srv.ListenAndServe()
	if err != nil {
		logger.LogAppError(err)
		panic(fmt.Sprintf("Unable to start HTTP server, error: %s\n", err))
	}
}
Example #3
0
func buildServerList(data a2sData, addtoServerDB bool) (*models.APIServerList,
	error) {
	// Cannot ignore all three requests
	for _, g := range data.HostsGames {
		if g.IgnoreInfo && g.IgnorePlayers && g.IgnoreRules {
			return nil, logger.LogAppErrorf("Cannot ignore all three A2S_ requests!")
		}
	}
	successcount := 0
	var success bool
	srvDBhosts := make(map[string]string, len(data.HostsGames))
	sl := &models.APIServerList{
		Servers:       make([]models.APIServer, 0),
		FailedServers: make([]string, 0),
	}

	for host, game := range data.HostsGames {
		info, iok := data.Info[host]
		players, pok := data.Players[host]
		if players == nil {
			// return empty array instead of nil pointers (null) in json
			players = make([]models.SteamPlayerInfo, 0)
		}
		rules, rok := data.Rules[host]
		success = iok && rok && pok

		if game.IgnoreInfo {
			success = pok && rok
		}
		if game.IgnorePlayers {
			success = iok && rok
		}
		if game.IgnoreRules {
			rules = make(map[string]string, 0)
			success = iok && pok
		}
		if game.IgnoreInfo && game.IgnorePlayers {
			success = rok
		}
		if game.IgnoreInfo && game.IgnoreRules {
			success = pok
		}
		if game.IgnorePlayers && game.IgnoreRules {
			success = iok
		}

		if success {
			srv := models.APIServer{
				Game:            game.Name,
				Players:         players,
				FilteredPlayers: removeBuggedPlayers(players),
				Rules:           rules,
				Info:            info,
			}
			// Gametype support: gametype can be found in rules, info, or not
			// at all depending on the game (currently just for QuakeLive & Reflex)
			srv.Info.GameTypeShort, srv.Info.GameTypeFull = getGameType(game, srv)

			ip, port, serr := net.SplitHostPort(host)
			if serr == nil {
				srv.IP = ip
				srv.Host = host
				p, perr := strconv.Atoi(port)
				if perr == nil {
					srv.Port = p
				}
				if !strings.EqualFold(game.Name, filters.GameUnspecified.String()) {
					srvDBhosts[host] = game.Name
				}
				loc := make(chan models.DbCountry, 1)
				go db.CountryDB.GetCountryInfo(loc, ip)
				srv.CountryInfo = <-loc
			}
			sl.Servers = append(sl.Servers, srv)
			successcount++
		} else {
			sl.FailedServers = append(sl.FailedServers, host)
		}
	}

	sl.RetrievedAt = time.Now().Format("Mon Jan 2 15:04:05 2006 EST")
	sl.RetrievedTimeStamp = time.Now().Unix()
	sl.ServerCount = len(sl.Servers)
	sl.FailedCount = len(sl.FailedServers)

	if len(srvDBhosts) != 0 {
		go db.ServerDB.AddServersToDB(srvDBhosts)
		sl.Servers = setServerIDsForList(sl.Servers)
	}

	logger.LogAppInfo(
		"Successfully queried (%d/%d) servers. %d timed out or otherwise failed.",
		successcount, len(data.HostsGames), sl.FailedCount)
	logger.WriteDebug("Server Queries: Successful: (%d/%d) servers\tFailed: %d servers",
		successcount, len(data.HostsGames), sl.FailedCount)
	return sl, nil
}