oldnapalm 82f5a9d2f6 Update schedule | 1 day ago | |
---|---|---|
.github | 10 months ago | |
apache | 6 years ago | |
cdn | 1 day ago | |
data | 2 days ago | |
protobuf | 3 weeks ago | |
scripts | 1 day ago | |
ssl | 2 years ago | |
storage | 7 years ago | |
.dockerignore | 7 years ago | |
.gitignore | 4 years ago | |
CHANGELOG | 2 years ago | |
Dockerfile | 4 months ago | |
LICENSE | 4 years ago | |
README.md | 2 days ago | |
discord_bot.py | 1 month ago | |
docker-compose.yml | 2 years ago | |
fake_dns.py | 5 months ago | |
online_sync.py | 4 months ago | |
requirements.txt | 1 month ago | |
standalone.py | 1 week ago | |
standalone.spec | 10 months ago | |
tokens.py | 6 years ago | |
zwift-offline.wsgi | 6 years ago | |
zwift_offline.py | 5 days ago |
zoffline enables the use of Zwift offline by acting as a partial implementation of a Zwift server. By default zoffline is only for a single player. See Step 6: Enable Multiplayer for how to enable support for multiple users/profiles.
zoffline also offers riding against ghosts (your previous rides). Enable this feature by checking "Enable ghosts" in zoffline's launcher. See Extra features for more details.
Additionally, zoffline's launcher allows selecting a specific map to ride on without mucking about with config files.
Setting up zoffline requires two primary steps. First, zoffline must be installed and run on a system before running Zwift (either on the system running Zwift or on another locally networked system). Second, Zwift must be configured to use zoffline instead of the official Zwift server.
There are three ways with which to install and run zoffline depending on your platform:
Simplest (Windows only)
To install zoffline on Windows:
server-ip.txt
file in the storage
directory containing the IP address of the PC running zoffline.storage
directory in the same folder it's in to store your Zwift progress.Linux, Windows, or macOS (from source)
To install zoffline on Linux, Windows, or macOS:
pip3 install -r requirements.txt
pip install -r requirements.txt
C:\Users\<username>\AppData\Local\Programs\Python\Python<version>\Scripts\pip.exe
instead of just pip
server-ip.txt
file in the storage
directory containing the IP address of the PC running zoffline.sudo ./standalone.py
sudo python3 standalone.py
python standalone.py
C:\Users\<username>\AppData\Local\Programs\Python\Python<version>\python.exe
instead of just python
storage
directory. It contains your Zwift progress state.zoffline can be installed on the same machine as Zwift or another local machine.
Using Docker
docker create --name zwift-offline -p 443:443 -p 80:80 -p 3024:3024/udp -p 3025:3025 -p 53:53/udp -v </path/to/host/storage>:/usr/src/app/zwift-offline/storage -e TZ=<timezone> zoffline/zoffline
-v </path/to/host/storage>:/usr/src/app/zwift-offline/storage
if you don't care if your Zwift progress state is retained across zoffline updates (unlikely).-v
will likely need to be world readable and writable.<timezone>
values (e.g. America/New_York) can be found here.--restart unless-stopped
will make zoffline start on boot if you have Docker v1.9.0 or greater.server-ip.txt
file in the </path/to/host/storage>
directory containing the IP address of the PC running zoffline.docker start zwift-offline
Using Docker Compose
docker-compose.yml
file in this repo which will build from the Dockerfile, or use this example compose file:
version: "3.3"
services:
zoffline:
image: zoffline/zoffline:latest
container_name: zoffline
environment:
- TZ=Europe/London
volumes:
- ./storage/:/usr/src/app/zwift-offline/storage
ports:
- 80:80
- 443:443
- 3024:3024/udp
- 3025:3025
restart: unless-stopped
volumes
tag replace ./storage/
before the :
with the directory path you want to use as your local zoffline data store.server-ip.txt
file in the storage
directory containing the IP address of the PC running zoffline.docker-compose up -d
Windows Instructions
certutil.exe -importpfx Root cert-zwift-com.p12
C:\Program Files (x86)\Zwift\data\cacert.pem
ssl/cert-zwift-com.pem
to cacert.pemC:\Windows\System32\Drivers\etc\hosts
<zoffline ip> us-or-rly101.zwift.com secure.zwift.com cdn.zwift.com launcher.zwift.com
<zoffline ip>
is the ip address of the machine running zoffline. If
it's running on the same machine as Zwift, use 127.0.0.1
as the ip.)hosts
file unchanged except for when specifically using zoffline, you may optionally use the launch.bat script within the scripts
directory to launch zoffline instead of using the normal Zwift Launcher. See #121 for details.Why: We need to redirect Zwift to use zoffline and convince Windows and Zwift to accept zoffline's self signed certificates for Zwift's domain names. Feel free to generate your own certificates and do the same.
macOS Instructions
sed -n '29,53p' cert-zwift-com.pem >> ~/Library/Application\ Support/Zwift/data/cacert.pem
/etc/hosts
<zoffline ip> us-or-rly101.zwift.com secure.zwift.com cdn.zwift.com launcher.zwift.com
<zoffline ip>
is the ip address of the machine running zoffline. If
it's running on the same machine as Zwift, use 127.0.0.1
as the ip.)Why: We need to redirect Zwift to use zoffline and convince macOS and Zwift to accept zoffline's self signed certificates for Zwift's domain names. Feel free to generate your own certificates and do the same.
Android (non-rooted device)
ZofflineObb.apk
from hereapp-Github-release.apk
from herehosts.txt
file to use with the app (you could use a text editor app or create it online with an online tool such as this). The file must look like this (replace <zoffline ip>
with the IP address of the machine running zoffline):
<zoffline ip> us-or-rly101.zwift.com
<zoffline ip> secure.zwift.com
<zoffline ip> cdn.zwift.com
hosts.txt
filefake-dns.txt
file in the storage
directory and set the "DNS 1" of your phone Wi-Fi connection to the IP address of the PC running zofflineAndroid Settings > Applications > Zwift
and clear data or uninstall and reinstall the app.ZofflineObb
app and run it (allow access to storage)Why: We need to redirect Zwift to use zoffline (this is done by the Virtual Hosts app) and convince Zwift to accept zoffline's self signed certificates for Zwift's domain names (this is done by the patch tool ZofflineObb).
Android (rooted device)
ssl/cert-zwift-com.pem
to /data/data/com.zwift.zwiftgame/dataES/cacert.pem
on the device
adb push ssl/cert-zwift-com.pem /data/data/com.zwift.zwiftgame/dataES/
adb shell
: cd /data/data/com.zwift.zwiftgame/dataES/
adb shell
: cat cert-zwift-com.pem >> cacert.pem
/etc/hosts
file
<zoffline ip> us-or-rly101.zwift.com secure.zwift.com cdn.zwift.com
<zoffline ip>
is the IP address of the machine running zoffline.)adb pull /etc/hosts
adb push hosts /etc/hosts
hosts
file.Why: We need to redirect Zwift to use zoffline and convince Zwift to accept zoffline's self signed certificates for Zwift's domain names. Feel free to generate your own certificates and do the same.
To use Zwift online like normal, comment out or remove the line added to the hosts
file before starting Zwift. Then ensure Zwift is fully closed (right click
the Zwift system tray icon and exit) and restart Zwift.
Expand
If you don't obtain your current Zwift profile before first starting Zwift with zoffline enabled, you will be prompted to create a new profile (height, weight, gender). Your profile can be further customized and changed via the in game menu (e.g. name, nationality, weight change, etc).
To obtain your current profile:
https://<zoffline_ip>/profile/zoffline/
).scripts/get_profile.py -u <your_zwift_username>
get_profile.exe
obtained from https://github.com/oldnapalm/zoffline-helper/releases/latest in place of scripts/get_profile.py
profile.bin
, achievements.bin
and economy_config.txt
(saved in whatever directory you ran get_profile.py in) into the storage/1
directory.
storage/1
directory within the same folder as zoffline.exe if it does not already exist.1
should be in the path you passed to -v
Strava
launcher.zwift.com
and use the "Settings - Strava" button in the launcher window (Windows and macOS only).scripts/strava_auth.py --client-id CLIENT_ID --client-secret CLIENT_SECRET
strava_auth.exe
obtained from https://github.com/oldnapalm/zoffline-helper/releases/latest in place of scripts/strava_auth.py
strava_token.txt
(saved in whatever directory you ran strava_auth.py
in) into the storage/1
directory.Garmin Connect
pip install garth
garmin_domain.txt
in the storage
directory containing the domain
garmin.cn
https://<zoffline_ip>/garmin/zoffline/
).garmin_auth.py
and move the resulting garth
folder (saved in whatever directory you ran garmin_auth.py
in) into the storage/1
directory.
garmin_auth.exe
obtained from https://github.com/oldnapalm/zoffline-helper/releases/latest instead.Intervals.icu
https://<zoffline_ip>/intervals/zoffline/
).Android (non-rooted device)
apk-mitm/dist/tools/apktool.js
(run npm root -g
to find its location) and edit it like this:
js
decode(inputPath, outputPath) {
return this.run([
'decode',
'-resm', // add this
'dummy', // add this
inputPath,
'--output',
outputPath,
'--frame-path',
this.options.frameworkPath,
], 'decoding');
}
zca.apk
) to a known locationapk-mitm --certificate cert-zwift-com.pem zca.apk
zca-patched.apk
to your phone and install itapp-Github-release.apk
from herehosts.txt
file to use with the app (you could use a text editor app or create it online with an online tool such as this). The file must look like this (replace <zoffline ip>
with the IP address of the machine running zoffline):
<zoffline ip> us-or-rly101.zwift.com
<zoffline ip> secure.zwift.com
cdn.zwift.com
to hosts.txt
, Companion needs to download images from the official serverhosts.txt
filefake-dns.txt
file in the storage
directory and set the "DNS 1" of your phone Wi-Fi connection to the IP address of the PC running zofflineExpand
To enable support for multiple users perform the steps below:
multiplayer.txt
file in the storage
directory.server-ip.txt
file in the storage
directory containing the IP address of the PC running zoffline.
gmail_credentials.txt
file in the storage
directory containing the login credentials of a Gmail account. You need to access https://security.google.com/settings/security/apppasswords and create an app password to allow the login from the server.Ghosts
https://<zoffline_ip>/user/zoffline/
, check "Enable ghosts" and click "Start Zwift" to save the option).storage/<player_id>/ghosts/<world>/<route>
. Next time you ride the same route, the ghost will be loaded..regroup
in chat to regroup the ghosts.ghost_profile.txt
inside the storage
folder. The script find_equip.py
can be used to populate this file.
Bots
enable_bots.txt
inside the storage
folder to load ghosts as bots, they will keep riding around regardless of the route you are riding.enable_bots.txt
can contain a multiplier value (be careful, if the resulting number of bots is too high, it may cause performance issues or not work at all).bot.txt
inside the storage
folder. The script get_pro_names.py
can be used to populate this file.RoboPacers
bot_editor.py
can be used to modify profile.bin
(set name, player ID and route ID) and route.bin
(cut the exceeding points to make a perfect loop).Bookmarks
.bookmark <name>
in the chat.All-time leaderboards
all_time_leaderboards.txt
in the storage
directory.Entitlements
unlock_entitlements.txt
in the storage
directory.unlock_all_equipment.txt
instead.
CDN proxy
cdn-proxy.txt
file in the storage
directory. This can only work if you are running zoffline on a different machine than the Zwift client.disable_proxy.txt
file in the storage
directory.get_gameassets.py
to download the game files.
Discord bridge
pip3 install discord.py
discord.cfg
file in the storage
directory containing
[discord]
token =
webhook =
channel =
welcome_message =
help_message =
Please join the community supported Discord server and Strava club.
Docker
-or-
Future Zwift updates may break zoffline until it's updated. While zoffline is
enabled Zwift updates will not be installed. If a zoffline update broke
something, check the CHANGELOG
for possible changes that need to be made.
Don't expose zoffline to the internet, it was not designed with that in mind.
If zoffline is out of date from Zwift's official client
If zoffline is behind in support of the latest Zwift client it can be updated to run using the latest Zwift version.
C:\Program Files (x86)\Zwift\Zwift_ver_cur.xml
to zoffline's cdn/gameassets/Zwift_Updates_Root/
overwriting the existing file.~/Library/Application Support/Zwift/ZwiftMac_ver_cur.xml
to zoffline's cdn/gameassets/Zwift_Updates_Root/
overwriting the existing file.Note: there is no guarantee that an untested Zwift update will work with zoffline. However, historically, Zwift updates rarely break zoffline.
Alternatively, this script can be used to downgrade Zwift to the version supported by zoffline.
Zwift is a trademark of Zwift, Inc., which is not affiliated with the maker of this project and does not endorse this project.
All product and company names are trademarks of their respective holders. Use of them does not imply any affiliation with or endorsement by them.