Skip to content

Instantly share code, notes, and snippets.

@kostyay
Last active January 25, 2019 18:33
Show Gist options
  • Save kostyay/74ad9e6f95aa1436c6349c3f0d9595e4 to your computer and use it in GitHub Desktop.
Save kostyay/74ad9e6f95aa1436c6349c3f0d9595e4 to your computer and use it in GitHub Desktop.
Python script to download Zwift updates. Fixes the Z113 error/ Update failure "at line 594 in patcher.cpp"
#
# To use make sure to install the following packages:
# pip install requests pyOpenSSL ndg-httpsclient pyasn1
#
import sys
import xml.etree.ElementTree as ET
#import ipdb
import requests
import binascii
import os.path
import os
ZWIFT_CUR_VER_FILE = "Zwift_ver_cur.xml"
ZWIFT_BASE_URL = "https://cdn.zwift.com/gameassets/Zwift_Updates_Root/"
ZWIFT_CUR_VER_URL = "https://cdn.zwift.com/gameassets/Zwift_Updates_Root/{}".format(ZWIFT_CUR_VER_FILE)
def get_latest_zwift_manifest(output_dir):
cur_ver_file = requests.get(ZWIFT_CUR_VER_URL)
file(os.path.join(output_dir, ZWIFT_CUR_VER_FILE), "w+").write(cur_ver_file.content)
ver = ET.fromstring(cur_ver_file.content)
return ver.get('manifest')
def get_manifest_file(fname, output_dir):
r = requests.get("{}{}".format(ZWIFT_BASE_URL, fname))
file(os.path.join(output_dir, fname), "w+").write(r.content)
return r.content
def create_dir_if_missing(path):
path, fn = os.path.split(path)
if not os.path.isdir(path):
os.makedirs(path)
def format_asset_url(zwift_folder, path):
return "{}{}/{}".format(ZWIFT_BASE_URL, zwift_folder, path.replace("\\", "/"))
def download_file(url, dst, checksum):
print "Downloading file from {} to {} [expected crc={}]".format(url, dst, checksum)
if os.path.isfile(dst):
current_crc = binascii.crc32(file(dst, "rb").read())
if str(current_crc) == str(checksum):
print "File already downloaded.. skipping"
return
headers = {'Cache-Control': 'no-cache', 'Pragma': 'no-cache'}
r = requests.get(url, headers=headers)
with open(dst, "w+b") as code:
content = r.content
crc = binascii.crc32(content)
code.write(content)
if str(crc) != str(checksum) and checksum != '-1':
print "checksum mismatch"
ipdb.set_trace()
print "Total bytes: {} CRC: {}".format(len(content), crc)
print " Done"
def main():
try:
prog, outdir = sys.argv
except:
print "Error: download_zwift.py <outdir>"
sys.exit(0)
print "Downloading manifest.."
latest_manifest = get_latest_zwift_manifest(outdir)
manifest_file = get_manifest_file(latest_manifest, outdir)
print "Manifest version: {}".format(latest_manifest)
print "Reading manifest..."
root = ET.fromstring(manifest_file)
folder_name = root.get('folder')
print "Folder is {}".format(folder_name,)
files = root.getchildren()[0]
assert files.tag == 'files'
files = files.getchildren()
print "Total files to download {}".format(len(files),)
for f in files:
path = f.find('path').text
checksum = f.find('checksum').text
download_url = format_asset_url(folder_name, path)
output_file = os.path.join(outdir, path)
create_dir_if_missing(output_file)
print "Download url: {}".format(download_url)
download_file(download_url, output_file, checksum)
print "All done"
if __name__ == "__main__":
main()
@kostyay
Copy link
Author

kostyay commented May 13, 2018

Surprised Zwift havent fixed it yet.
Just reinstalled my PC and still having this problem.
Used the script to download the updates and everything is working again.

@grimfusion
Copy link

I'm kinda surprised this works. Usually, the Z113 error is caused when files pulled down from Zwift's update server don't match correct checksum values - basically when components in the update fail to completely download or end up corrupted. I take it your Python script works more reliably because it tries to download the files multiple times after a checksum mismatch whereas Zwift simply reports the update failed?

@nadodiganesh
Copy link

Can I get a Python 3+ compatible version of this code... tried now and started seeing quite some Print syntax errors, was about parantheses...tried my best to get that going. Now, I face ....

Downloading manifest..
Traceback (most recent call last):
File "D:\Zwift\download_zwift_updates.py", line 104, in
main()
File "D:\Zwift\download_zwift_updates.py", line 74, in main
latest_manifest = get_latest_zwift_manifest(outdir)
File "D:\Zwift\download_zwift_updates.py", line 22, in get_latest_zwift_manifest
file(os.path.join(output_dir, ZWIFT_CUR_VER_FILE), "w+").write(cur_ver_file.content)
NameError: name 'file' is not defined

... my little reading around it points to Python version compatibility, etc.

@Sivridis
Copy link

I had Z113 patcher.cpp problem while trying to install Zwift.
The method provided by Kostyay helped me and finally Zwift is working!!!
Dear @nadodiganesh yo should change "<path\to\zwift\install\dir>" to insall dir where Zwift was installed. I mean you should write this command to cmd

C:\Python27\python download_zwift_updates.py "C:\Program Files (x86)\Zwift"

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment