pythonhacktoberfeststeamauthenticationauthenticatorsteam-authenticatorsteam-clientsteam-guard-codessteam-websteamworksvalvewebapi
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
137 lines
3.8 KiB
137 lines
3.8 KiB
|
|
from collections import OrderedDict, deque
|
|
from six import itervalues
|
|
import vdf
|
|
from steam import webapi
|
|
from steam.enums import EServerType
|
|
from steam.util.web import make_requests_session
|
|
from steam.core.manifest import DepotManifest
|
|
|
|
|
|
def get_content_servers_from_cs(host, port, cell_id, num_servers=20, session=None):
|
|
proto = 'https' if port == 443 else 'http'
|
|
|
|
url = '%s://%s:%s/serverlist/%s/%s/' % (proto, host, port, cell_id, num_servers)
|
|
session = make_requests_session() if session is None else session
|
|
resp = session.get(url)
|
|
|
|
if resp.status_code != 200:
|
|
return []
|
|
|
|
kv = vdf.loads(resp.text, mapper=OrderedDict)
|
|
|
|
if kv.get('deferred') == '1':
|
|
return []
|
|
|
|
servers = []
|
|
|
|
for entry in itervalues(kv['serverlist']):
|
|
server = ContentServer()
|
|
server.type = entry['type']
|
|
server.https = True if entry['https_support'] == 'mandatory' else False
|
|
server.host = entry['Host']
|
|
server.vhost = entry['vhost']
|
|
server.port = 443 if server.https else 80
|
|
server.cell_id = entry['cell']
|
|
server.load = entry['load']
|
|
server.weighted_load = entry['weightedload']
|
|
servers.append(server)
|
|
|
|
return servers
|
|
|
|
|
|
def get_content_servers_from_webapi(cell_id, num_servers=20):
|
|
params = {'cellid': cell_id, 'max_servers': num_servers}
|
|
resp = webapi.get('IContentServerDirectoryService', 'GetServersForSteamPipe', params=params)
|
|
|
|
servers = []
|
|
|
|
for entry in resp['response']['servers']:
|
|
server = ContentServer()
|
|
server.type = entry['type']
|
|
server.https = True if entry['https_support'] == 'mandatory' else False
|
|
server.host = entry['host']
|
|
server.vhost = entry['vhost']
|
|
server.port = 443 if server.https else 80
|
|
server.cell_id = entry.get('cell_id', 0)
|
|
server.load = entry['load']
|
|
server.weighted_load = entry['weighted_load']
|
|
servers.append(server)
|
|
|
|
return servers
|
|
|
|
|
|
class CDNClient(object):
|
|
def __init__(self, client, app_id):
|
|
self.steam = client
|
|
self.app_id = app_id
|
|
self.web = make_requests_session()
|
|
self.servers = deque()
|
|
|
|
@property
|
|
def cell_id(self):
|
|
return self.steam.cell_id
|
|
|
|
def init_servers(self, num_servers=10):
|
|
self.servers.clear()
|
|
|
|
for ip, port in self.steam.servers[EServerType.CS]:
|
|
servers = get_content_servers_from_cs(ip, port, self.cell_id, num_servers, self.web)
|
|
|
|
if servers:
|
|
self.servers.extend(servers)
|
|
break
|
|
|
|
if not self.servers:
|
|
raise RuntimeError("No content servers on SteamClient instance. Is it logged in?")
|
|
|
|
def get_content_server(self):
|
|
server = self.servers[0]
|
|
self.servers.rotate(-1)
|
|
return server
|
|
|
|
def get(self, command, args, auth_token=''):
|
|
server = self.get_content_server()
|
|
|
|
url = "%s://%s:%s/%s/%s%s" % (
|
|
'https' if server.https else 'http',
|
|
server.host,
|
|
server.port,
|
|
command,
|
|
args,
|
|
auth_token,
|
|
)
|
|
|
|
return self.web.get(url)
|
|
|
|
def get_manifest(self, depot_id, manifest_id, auth_token):
|
|
resp = self.get('depot', '%s/manifest/%s/5' % (depot_id, manifest_id), auth_token)
|
|
|
|
resp.raise_for_status()
|
|
|
|
if resp.ok:
|
|
return DepotManifest(resp.content)
|
|
|
|
|
|
class ContentServer(object):
|
|
https = False
|
|
host = None
|
|
vhost = None
|
|
port = None
|
|
type = None
|
|
cell_id = 0
|
|
load = None
|
|
weighted_load = None
|
|
|
|
def __repr__(self):
|
|
return "<%s('%s://%s:%s', type=%s, cell_id=%s)>" % (
|
|
self.__class__.__name__,
|
|
'https' if self.https else 'http',
|
|
self.host,
|
|
self.port,
|
|
repr(self.type),
|
|
repr(self.cell_id),
|
|
)
|
|
|
|
|
|
|
|
|