Beispiel #1
0
func extractHosts(hbs []byte) ([]string, int, error) {
	var sl []string
	pos, total := 0, 0
	for i := 0; i < len(hbs); i++ {
		if len(sl) > 0 && sl[len(sl)-1] == "0.0.0.0:0" {
			logger.LogSteamInfo("0.0.0.0:0 detected. Got %d total hosts.", total-1)
			break
		}
		if pos+6 > len(hbs) {
			logger.LogSteamInfo("Got %d total hosts.", total)
			break
		}

		host, err := parseIP(hbs[pos : pos+6])
		if err != nil {
			logger.LogAppErrorf("Error parsing host: %s", err)
		} else {
			sl = append(sl, host)
			total++
		}
		// host:port = 6 bytes
		pos = pos + 6
	}
	return sl, total, nil
}
Beispiel #2
0
// NewMasterWebQuery initiates a new Steam "Master" server query using the Steam Web API for a
// given filter, returning a MasterQuery struct containing the hosts retrieved in the event of
// success or an empty struct and an error in the event of failure.
func NewMasterWebQuery(filter filters.Filter) (MasterQuery, error) {
	sl, err := getServersWeb(filter)
	if err != nil {
		return MasterQuery{}, err
	}
	logger.LogSteamInfo("*** Retrieved %d %s servers.", len(sl), filter.Game.Name)

	return MasterQuery{Servers: sl}, nil
}
Beispiel #3
0
func getServers(filter filters.Filter) ([]string, error) {
	maxHosts := config.Config.SteamConfig.MaximumHostsToReceive
	var serverlist []string
	var c net.Conn
	var err error
	retrieved := 0
	addr := "0.0.0.0:0"

	c, err = net.DialTimeout("udp", masterServerHost,
		time.Duration(QueryTimeout)*time.Second)
	if err != nil {
		logger.LogSteamError(ErrHostConnection(err.Error()))
		return nil, ErrHostConnection(err.Error())
	}

	defer c.Close()
	c.SetDeadline(time.Now().Add(time.Duration(QueryTimeout) * time.Second))

	for {
		s, err := queryMasterServer(c, addr, filter)
		if err != nil {
			// usually timeout - Valve throttles >30 UDP packets (>6930 servers) per min
			logger.WriteDebug("Master query error, likely due to Valve throttle/timeout :%s",
				err)
			break
		}
		// get hosts:ports beginning after header (0xFF, 0xFF, 0xFF, 0xFF, 0x66, 0x0A)
		ips, total, err := extractHosts(s[6:])
		if err != nil {
			return nil, logger.LogAppErrorf("Error when extracting addresses: %s",
				err)
		}
		retrieved = retrieved + total
		if retrieved >= maxHosts {
			logger.LogSteamInfo("Max host limit of %d reached!", maxHosts)
			logger.WriteDebug("Max host limit of %d reached!", maxHosts)
			break
		}
		logger.LogSteamInfo("%d hosts retrieved so far from master.", retrieved)
		logger.WriteDebug("%d hosts retrieved so far from master.", retrieved)
		for _, ip := range ips {
			serverlist = append(serverlist, ip)
		}

		if (serverlist[len(serverlist)-1]) != "0.0.0.0:0" {
			logger.LogSteamInfo("More hosts need to be retrieved. Last IP was: %s",
				serverlist[len(serverlist)-1])
			logger.WriteDebug("More hosts need to be retrieved. Last IP was: %s",
				serverlist[len(serverlist)-1])
			addr = serverlist[len(serverlist)-1]
		} else {
			logger.LogSteamInfo("IP retrieval complete!")
			logger.WriteDebug("IP retrieval complete!")
			break
		}
	}
	// remove 0.0.0.0:0
	if len(serverlist) != 0 {
		if serverlist[len(serverlist)-1] == "0.0.0.0:0" {
			serverlist = serverlist[:len(serverlist)-1]
		}
	}
	return serverlist, nil
}