Skip to content

Instantly share code, notes, and snippets.

@aquach
Last active August 10, 2016 16:15
Show Gist options
  • Save aquach/c825fde09d92fb8a6877 to your computer and use it in GitHub Desktop.
Save aquach/c825fde09d92fb8a6877 to your computer and use it in GitHub Desktop.
Downloads updates to Elite Dangerous by imitating the patcher.
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
print "Failed to download, retry %d of %d" % (currentTry, maxTries)
currentTry += 1
print
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