diff --git a/standalone.py b/standalone.py index 6eb8efe..1449534 100644 --- a/standalone.py +++ b/standalone.py @@ -14,8 +14,6 @@ import itertools import socketserver from urllib3 import PoolManager from http.server import SimpleHTTPRequestHandler -from http.cookies import SimpleCookie -from collections import deque from datetime import datetime, timedelta, timezone from Crypto.Cipher import AES @@ -76,9 +74,6 @@ else: pass discord = DummyDiscord() -MAP_OVERRIDE = deque(maxlen=16) -CLIMB_OVERRIDE = deque(maxlen=16) - bot_update_freq = 3 pacer_update_freq = 1 simulated_latency = 300 #makes bots animation smoother than using current time @@ -93,6 +88,8 @@ global_bots = {} global_news = {} #player id to dictionary of peer_player_id->worldTime global_relay = {} global_clients = {} +map_override = {} +climb_override = {} def sigint_handler(num, frame): httpd.shutdown() @@ -113,45 +110,26 @@ class CDNHandler(SimpleHTTPRequestHandler): return fullpath def do_GET(self): - path_end = self.path.split('/')[-1] - if path_end == 'map_override': - cookies_string = self.headers.get('Cookie') - cookies = SimpleCookie() - cookies.load(cookies_string) - # We have no identifying information when Zwift makes MapSchedule request except for the client's IP. - if 'selected_map' in cookies: - MAP_OVERRIDE.append((self.client_address[0], cookies['selected_map'].value)) - if 'selected_climb' in cookies: - CLIMB_OVERRIDE.append((self.client_address[0], cookies['selected_climb'].value)) - self.send_response(302) - self.send_header('Cookie', cookies_string) - self.send_header('Location', 'https://secure.zwift.com/ride') + # Check if client requested the map be overridden + if self.path == '/gameassets/MapSchedule_v2.xml' and self.client_address[0] in map_override: + self.send_response(200) + self.send_header('Content-type', 'text/xml') self.end_headers() + start = datetime.today() - timedelta(days=1) + output = '1' % (map_override[self.client_address[0]], start.strftime("%Y-%m-%dT00:01-04")) + self.wfile.write(output.encode()) + del map_override[self.client_address[0]] return - if self.path == '/gameassets/MapSchedule_v2.xml': - # Check if client requested the map be overridden - for override in MAP_OVERRIDE: - if override[0] == self.client_address[0]: - self.send_response(200) - self.send_header('Content-type', 'text/xml') - self.end_headers() - start = datetime.today() - timedelta(days=1) - output = '1' % (override[1], start.strftime("%Y-%m-%dT00:01-04")) - self.wfile.write(output.encode()) - MAP_OVERRIDE.remove(override) - return - if self.path == '/gameassets/PortalRoadSchedule_v1.xml': - for override in CLIMB_OVERRIDE: - if override[0] == self.client_address[0]: - self.send_response(200) - self.send_header('Content-type', 'text/xml') - self.end_headers() - start = datetime.today() - timedelta(days=1) - output = '1' % (override[1], start.strftime("%Y-%m-%dT00:01-04")) - self.wfile.write(output.encode()) - CLIMB_OVERRIDE.remove(override) - return - if CDN_PROXY and self.path.startswith('/gameassets/') and not path_end.endswith('_ver_cur.xml') and not ('User-Agent' in self.headers and 'python-urllib3' in self.headers['User-Agent']): + if self.path == '/gameassets/PortalRoadSchedule_v1.xml' and self.client_address[0] in climb_override: + self.send_response(200) + self.send_header('Content-type', 'text/xml') + self.end_headers() + start = datetime.today() - timedelta(days=1) + output = '1' % (climb_override[self.client_address[0]], start.strftime("%Y-%m-%dT00:01-04")) + self.wfile.write(output.encode()) + del climb_override[self.client_address[0]] + return + if CDN_PROXY and self.path.startswith('/gameassets/') and not self.path.endswith('_ver_cur.xml') and not ('User-Agent' in self.headers and 'python-urllib3' in self.headers['User-Agent']): try: self.send_response(200) self.end_headers() @@ -865,4 +843,4 @@ if os.path.exists(FAKE_DNS_FILE) and os.path.exists(SERVER_IP_FILE): dns = threading.Thread(target=fake_dns, args=(server_ip,)) dns.start() -zo.run_standalone(online, global_relay, global_pace_partners, global_bots, global_ghosts, ghosts_enabled, save_ghost, regroup_ghosts, player_update_queue, discord) +zo.run_standalone(online, global_relay, global_pace_partners, global_bots, global_ghosts, ghosts_enabled, save_ghost, regroup_ghosts, player_update_queue, map_override, climb_override, discord) diff --git a/zwift_offline.py b/zwift_offline.py index 7e520a1..2f86b73 100644 --- a/zwift_offline.py +++ b/zwift_offline.py @@ -139,12 +139,6 @@ app.config['MAX_CONTENT_LENGTH'] = 1024 * 1024 db = SQLAlchemy() db.init_app(app) -online = {} -global_pace_partners = {} -global_bots = {} -global_ghosts = {} -ghosts_enabled = {} -player_update_queue = {} zc_connect_queue = {} player_partial_profiles = {} restarting = False @@ -3781,21 +3775,16 @@ def start_zwift(): AnonUser.enable_ghosts = 'enableghosts' in request.form.keys() save_option(AnonUser.enable_ghosts, ENABLEGHOSTS_FILE) selected_map = request.form['map'] + if selected_map != 'CALENDAR': + # We have no identifying information when Zwift makes MapSchedule request except for the client's IP. + map_override[request.remote_addr] = selected_map selected_climb = request.form['climb'] - if selected_map == 'CALENDAR' and selected_climb == 'CALENDAR': - return redirect("/ride", 302) - else: - response = make_response(redirect("http://cdn.zwift.com/map_override", 302)) - if selected_map != 'CALENDAR': - response.set_cookie('selected_map', selected_map, domain=".zwift.com") - if selected_climb != 'CALENDAR': - response.set_cookie('selected_climb', selected_climb, domain=".zwift.com") - if MULTIPLAYER: - response.set_cookie('remember_token', request.cookies['remember_token'], domain=".zwift.com") - return response + if selected_climb != 'CALENDAR': + climb_override[request.remote_addr] = selected_climb + return redirect("/ride", 302) -def run_standalone(passed_online, passed_global_relay, passed_global_pace_partners, passed_global_bots, passed_global_ghosts, passed_ghosts_enabled, passed_save_ghost, passed_regroup_ghosts, passed_player_update_queue, passed_discord): +def run_standalone(passed_online, passed_global_relay, passed_global_pace_partners, passed_global_bots, passed_global_ghosts, passed_ghosts_enabled, passed_save_ghost, passed_regroup_ghosts, passed_player_update_queue, passed_map_override, passed_climb_override, passed_discord): global online global global_relay global global_pace_partners @@ -3805,6 +3794,8 @@ def run_standalone(passed_online, passed_global_relay, passed_global_pace_partne global save_ghost global regroup_ghosts global player_update_queue + global map_override + global climb_override global discord global login_manager online = passed_online @@ -3816,6 +3807,8 @@ def run_standalone(passed_online, passed_global_relay, passed_global_pace_partne save_ghost = passed_save_ghost regroup_ghosts = passed_regroup_ghosts player_update_queue = passed_player_update_queue + map_override = passed_map_override + climb_override = passed_climb_override discord = passed_discord login_manager = LoginManager() login_manager.login_view = 'login'