Last active
August 10, 2016 16:15
-
-
Save aquach/c825fde09d92fb8a6877 to your computer and use it in GitHub Desktop.
Downloads updates to Elite Dangerous by imitating the patcher.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import gzip | |
import hashlib | |
import os | |
import StringIO | |
import sys | |
import urllib | |
import getpass | |
from xml.etree import ElementTree | |
def generateDirectories(path): | |
dir = os.path.dirname(path) | |
if not os.path.isdir(dir): | |
os.makedirs(dir) | |
def getPatchManifest(manifestURL): | |
compressedManifest = StringIO.StringIO(urllib.urlopen(manifestURL).read()) | |
decompressedManifest = gzip.GzipFile(fileobj=compressedManifest) | |
parsedManifest = ElementTree.fromstring(decompressedManifest.read()) | |
return parsedManifest | |
def alreadyHaveAsset(downloadPath, assetHash): | |
if os.path.isfile(downloadPath): | |
# Asset exists on disk, but need to check version | |
sha1 = hashlib.sha1() | |
sha1.update(open(downloadPath, "rb").read()) | |
localHash = sha1.hexdigest() | |
return localHash == assetHash | |
else: | |
# Asset doesn't exist on disk | |
return False | |
def reportFileProgress(blockNumber, blockSize, fileSize): | |
blockSize /= 1048576.0 # Bytes -> Megabytes | |
fileSize /= 1048576.0 # Bytes -> Megabytes | |
currentSize = blockNumber * blockSize | |
percentComplete = min(100.0 * currentSize/fileSize, 100.00) | |
print "\r\t%.2f MB / %.2f MB (%.2f%%)" % (currentSize, fileSize, percentComplete), | |
def getAsset(assetNumber, assetCount, assetRelPath, assetURL, downloadPath): | |
print "Downloading file %d of %d: %s" % (assetNumber, assetCount, assetRelPath) | |
downloaded = False | |
currentTry = 1 | |
maxTries = 5 | |
while not downloaded and currentTry <= maxTries: | |
try: | |
urllib.urlretrieve(assetURL, downloadPath, reportFileProgress) | |
downloaded = True | |
except IOError: | |
print "Failed to download, retry %d of %d" % (currentTry, maxTries) | |
currentTry += 1 | |
def downloadAssets(manifest, downloadDir): | |
assetCount = len(manifest) | |
# Get assets | |
for assetNumber, asset in enumerate(manifest.getchildren()): | |
assetURL = asset.find("Download").text | |
assetSize = float(asset.find("Size").text) / 1048576.0 # Bytes -> Megabytes | |
assetHash = asset.find("Hash").text | |
assetRelPath = asset.find("Path").text | |
downloadPath = os.path.join(downloadDir, assetRelPath) | |
generateDirectories(downloadPath) | |
if alreadyHaveAsset(downloadPath, assetHash): | |
print "Skipping file %d of %d: %s" % (assetNumber+1, assetCount, assetRelPath) | |
else: | |
getAsset(assetNumber+1, assetCount, assetRelPath, assetURL, downloadPath) | |
if __name__ == "__main__": | |
# Found via Wireshark. | |
manifestURL = "http://cdn.zaonce.net/elitedangerous/win/manifests/RetailUpdate_1.1.02_Final+%282015.02.11.57320%29.xml.gz" | |
possibleDownloadDirs = [ | |
"C:\\Users\\%s\\AppData\\Local\\Frontier_Developments\\Products\\FORC-FDEV-D-1010" % getpass.getuser(), | |
"C:\\Program Files (x86)\Frontier\\EDLaunch\\Products\\FORC-FDEV-D-1010", | |
"C:\\Program Files\\Frontier\\EDLaunch\\Products\\FORC-FDEV-D-1010" | |
] | |
print "Looking for ED download directory in the following paths:\n" + "\n".join(possibleDownloadDirs) | |
downloadDirs = [ d for d in possibleDownloadDirs if os.path.isdir(downloadDir) ] | |
if len(downloadDirs) == 0: | |
print "Couldn't find ED download directory." | |
else | |
print "Downloading client files to %s..." % downloadDirs[0] | |
manifest = getPatchManifest(manifestURL) | |
downloadAssets(manifest, downloadDirs[0]) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment