From af79c1178b520b42eaa27629733cf0fe62fa1498 Mon Sep 17 00:00:00 2001 From: perast Date: Fri, 13 Nov 2020 09:16:38 +0100 Subject: [PATCH] Simplified ride with online players fetch Changed str to int in global_pace_partners Renamed variables, functions and classes consistently --- standalone.py | 141 ++++++++++++------------- zwift_offline.py | 262 ++++++++++++++++++++++------------------------- 2 files changed, 196 insertions(+), 207 deletions(-) diff --git a/standalone.py b/standalone.py index c39a059..6262c40 100755 --- a/standalone.py +++ b/standalone.py @@ -40,19 +40,19 @@ SERVER_IP_FILE = "%s/server-ip.txt" % STORAGE_DIR MAP_OVERRIDE = deque(maxlen=16) update_freq = 3 -globalGhosts = {} -ghostsEnabled = {} +global_ghosts = {} +ghosts_enabled = {} online = {} -playerUpdateQueue = {} -globalPacePartners = {} +player_update_queue = {} +global_pace_partners = {} -def roadID(state): +def road_id(state): return (state.f20 & 0xff00) >> 8 -def isForward(state): +def is_forward(state): return (state.f19 & 4) != 0 -def getCourse(state): +def get_course(state): return (state.f19 & 0xff0000) >> 16 def boolean(s): @@ -60,24 +60,24 @@ def boolean(s): if s.lower() in ['false', 'no', '0']: return False return None -def saveGhost(name, player_id): - global globalGhosts - if not player_id in globalGhosts.keys(): return - ghosts = globalGhosts[player_id] +def save_ghost(name, player_id): + global global_ghosts + if not player_id in global_ghosts.keys(): return + ghosts = global_ghosts[player_id] if len(ghosts.rec.states) > 0: - folder = '%s/%s/ghosts/%s/%s' % (STORAGE_DIR, player_id, getCourse(ghosts.rec.states[0]), roadID(ghosts.rec.states[0])) - if not isForward(ghosts.rec.states[0]): folder += '/reverse' + folder = '%s/%s/ghosts/%s/%s' % (STORAGE_DIR, player_id, get_course(ghosts.rec.states[0]), road_id(ghosts.rec.states[0])) + if not is_forward(ghosts.rec.states[0]): folder += '/reverse' try: if not os.path.isdir(folder): os.makedirs(folder) except: return - f = '%s/%s-%s.bin' % (folder, zwift_offline.getUTCDateTime().strftime("%Y-%m-%d-%H-%M-%S"), name) + f = '%s/%s-%s.bin' % (folder, zwift_offline.get_utc_date_time().strftime("%Y-%m-%d-%H-%M-%S"), name) with open(f, 'wb') as fd: fd.write(ghosts.rec.SerializeToString()) -def organizeGhosts(player_id): - # organize ghosts in course/roadID directory structure +def organize_ghosts(player_id): + # organize ghosts in course/road_id directory structure # previously they were saved directly in player_id/ghosts folder = '%s/%s/ghosts' % (STORAGE_DIR, player_id) if not os.path.isdir(folder): return @@ -87,8 +87,8 @@ def organizeGhosts(player_id): with open(file, 'rb') as fd: g = udp_node_msgs_pb2.Ghost() g.ParseFromString(fd.read()) - dest = '%s/%s/%s' % (folder, getCourse(g.states[0]), roadID(g.states[0])) - if not isForward(g.states[0]): dest += '/reverse' + dest = '%s/%s/%s' % (folder, get_course(g.states[0]), road_id(g.states[0])) + if not is_forward(g.states[0]): dest += '/reverse' try: if not os.path.isdir(dest): os.makedirs(dest) @@ -96,9 +96,9 @@ def organizeGhosts(player_id): return os.rename(file, os.path.join(dest, f)) -def loadGhosts(player_id, state, ghosts): - folder = '%s/%s/ghosts/%s/%s' % (STORAGE_DIR, player_id, getCourse(state), roadID(state)) - if not isForward(state): folder += '/reverse' +def load_ghosts(player_id, state, ghosts): + folder = '%s/%s/ghosts/%s/%s' % (STORAGE_DIR, player_id, get_course(state), road_id(state)) + if not is_forward(state): folder += '/reverse' if not os.path.isdir(folder): return s = list() for f in os.listdir(folder): @@ -107,24 +107,24 @@ def loadGhosts(player_id, state, ghosts): g = ghosts.play.ghosts.add() g.ParseFromString(fd.read()) s.append(g.states[0].roadTime) - ghosts.start_road = roadID(state) + ghosts.start_road = road_id(state) ghosts.start_rt = 0 if os.path.isfile(START_LINES_FILE): with open(START_LINES_FILE, 'r') as fd: sl = [tuple(line) for line in csv.reader(fd)] - rt = [t for t in sl if t[0] == str(getCourse(state)) and t[1] == str(roadID(state)) and (boolean(t[2]) == isForward(state) or not t[2])] + rt = [t for t in sl if t[0] == str(get_course(state)) and t[1] == str(road_id(state)) and (boolean(t[2]) == is_forward(state) or not t[2])] if rt: ghosts.start_road = int(rt[0][3]) ghosts.start_rt = int(rt[0][4]) if not ghosts.start_rt: s.append(state.roadTime) - if isForward(state): ghosts.start_rt = max(s) + if is_forward(state): ghosts.start_rt = max(s) else: ghosts.start_rt = min(s) for g in ghosts.play.ghosts: try: - while roadID(g.states[0]) != ghosts.start_road: + while road_id(g.states[0]) != ghosts.start_road: del g.states[0] - if isForward(g.states[0]): + if is_forward(g.states[0]): while not (g.states[0].roadTime <= ghosts.start_rt <= g.states[1].roadTime): del g.states[0] else: @@ -283,7 +283,7 @@ class TCPHandler(socketserver.BaseRequestHandler): msg.f11 = 1 payload = msg.SerializeToString() - lastAliveCheck = int(zwift_offline.getUTCTime()) + last_alive_check = int(zwift_offline.get_utc_time()) while True: #Check every 5 seconds for new updates tcpthreadevent.wait(timeout=5) @@ -294,9 +294,9 @@ class TCPHandler(socketserver.BaseRequestHandler): message.world_time = zwift_offline.world_time() #PlayerUpdate - if player_id in playerUpdateQueue and len(playerUpdateQueue[player_id]) > 0 and player_id in online: + if player_id in player_update_queue and len(player_update_queue[player_id]) > 0 and player_id in online: added_player_updates = list() - for player_update_proto in playerUpdateQueue[player_id]: + for player_update_proto in player_update_queue[player_id]: player_update = message.updates.add() player_update.ParseFromString(player_update_proto) @@ -313,18 +313,18 @@ class TCPHandler(socketserver.BaseRequestHandler): added_player_updates.append(player_update_proto) for player_update_proto in added_player_updates: - playerUpdateQueue[player_id].remove(player_update_proto) + player_update_queue[player_id].remove(player_update_proto) - t = int(zwift_offline.getUTCTime()) + t = int(zwift_offline.get_utc_time()) #Check if any updates are added and should be sent to client, otherwise just keep alive every 25 seconds if len(message.updates) > 0: - lastAliveCheck = t + last_alive_check = t message_payload = message.SerializeToString() self.request.sendall(struct.pack('!h', len(message_payload))) self.request.sendall(message_payload) - elif lastAliveCheck < t - 25: - lastAliveCheck = t + elif last_alive_check < t - 25: + last_alive_check = t self.request.sendall(struct.pack('!h', len(payload))) self.request.sendall(payload) except Exception as e: @@ -347,25 +347,26 @@ class PacePartnerVariables: route = None position = 0 -def loadPacePartners(): +def load_pace_partners(): folder = '%s/pace_partners' % STORAGE_DIR if not os.path.isdir(folder): return for (root, dirs, files) in os.walk(folder): for pp_id in dirs: + p_id = int(pp_id) route = '%s/%s/route.bin' % (folder, pp_id) if os.path.isfile(route): with open(route, 'rb') as fd: - globalPacePartners[pp_id] = PacePartnerVariables() - pp = globalPacePartners[pp_id] + global_pace_partners[p_id] = PacePartnerVariables() + pp = global_pace_partners[p_id] pp.route = udp_node_msgs_pb2.Ghost() pp.route.ParseFromString(fd.read()) pp.position = 0 -def playPacePartners(): +def play_pace_partners(): while True: - keys = globalPacePartners.keys() + keys = global_pace_partners.keys() for pp_id in keys: - pp = globalPacePartners[pp_id] + pp = global_pace_partners[pp_id] if pp.position < len(pp.route.states) - 1: pp.position += 1 else: pp.position = 0 ppthreadevent.wait(timeout=3) @@ -389,10 +390,10 @@ class UDPHandler(socketserver.BaseRequestHandler): state = recv.state #Add handling of ghosts for player if it's missing - if not player_id in globalGhosts.keys(): - globalGhosts[player_id] = GhostsVariables() + if not player_id in global_ghosts.keys(): + global_ghosts[player_id] = GhostsVariables() - ghosts = globalGhosts[player_id] + ghosts = global_ghosts[player_id] if recv.seqno == 1 or ghosts.rec == None: ghosts.rec = udp_node_msgs_pb2.Ghost() @@ -402,22 +403,22 @@ class UDPHandler(socketserver.BaseRequestHandler): ghosts.loaded = False ghosts.started = False ghosts.rec.player_id = player_id - organizeGhosts(player_id) + organize_ghosts(player_id) - t = int(zwift_offline.getUTCTime()) - ghosts.lastPackageTime = t + t = int(zwift_offline.get_utc_time()) + ghosts.last_package_time = t - if player_id in ghostsEnabled and ghostsEnabled[player_id]: - if not ghosts.loaded and getCourse(state): + if player_id in ghosts_enabled and ghosts_enabled[player_id]: + if not ghosts.loaded and get_course(state): ghosts.loaded = True - loadGhosts(player_id, state, ghosts) + load_ghosts(player_id, state, ghosts) if state.roadTime and ghosts.last_rt and state.roadTime != ghosts.last_rt: if t >= ghosts.last_rec + update_freq: s = ghosts.rec.states.add() s.CopyFrom(state) ghosts.last_rec = t - if not ghosts.started and ghosts.play.ghosts and roadID(state) == ghosts.start_road: - if isForward(state): + if not ghosts.started and ghosts.play.ghosts and road_id(state) == ghosts.start_road: + if is_forward(state): if state.roadTime >= ghosts.start_rt >= ghosts.last_rt: ghosts.started = True else: @@ -426,23 +427,23 @@ class UDPHandler(socketserver.BaseRequestHandler): ghosts.last_rt = state.roadTime keys = online.keys() - removePlayers = list() + remove_players = list() for p_id in keys: if zwift_offline.world_time() > online[p_id].worldTime + 10000: - removePlayers.insert(0, p_id) - for p_id in removePlayers: + remove_players.insert(0, p_id) + for p_id in remove_players: online.pop(p_id) if state.roadTime: online[player_id] = state #Remove ghosts entries for inactive players (disconnected?) - keys = globalGhosts.keys() - removePlayers = list() + keys = global_ghosts.keys() + remove_players = list() for p_id in keys: - if globalGhosts[p_id].lastPackageTime < t - 10: - removePlayers.insert(0, p_id) - for p_id in removePlayers: - globalGhosts.pop(p_id) + if global_ghosts[p_id].last_package_time < t - 10: + remove_players.insert(0, p_id) + for p_id in remove_players: + global_ghosts.pop(p_id) if ghosts.started and t >= ghosts.last_play + update_freq: message = udp_node_msgs_pb2.ServerToClient() @@ -496,13 +497,13 @@ class UDPHandler(socketserver.BaseRequestHandler): player = online[p_id] if player.id != player_id: #Check if players are close in world - if zwift_offline.isNearby(state, player): + if zwift_offline.is_nearby(state, player): nearby.append(p_id) - for p_id in globalPacePartners.keys(): - pace_partner_variables = globalPacePartners[p_id] + for p_id in global_pace_partners.keys(): + pace_partner_variables = global_pace_partners[p_id] pace_partner = pace_partner_variables.route.states[pace_partner_variables.position] #Check if pacepartner is close to player in world - if zwift_offline.isNearby(state, pace_partner): + if zwift_offline.is_nearby(state, pace_partner): nearby.append(p_id) players = len(nearby) message.num_msgs = players // 10 @@ -511,10 +512,10 @@ class UDPHandler(socketserver.BaseRequestHandler): player = None if p_id in online.keys(): player = online[p_id] - elif p_id in globalPacePartners.keys(): - pace_partner_variables = globalPacePartners[p_id] + elif p_id in global_pace_partners.keys(): + pace_partner_variables = global_pace_partners[p_id] player = pace_partner_variables.route.states[pace_partner_variables.position] - player.id = int(p_id) + player.id = p_id player.watchingRiderId = player.id player.worldTime = zwift_offline.world_time() if player != None: @@ -552,9 +553,9 @@ udpserver_thread = threading.Thread(target=udpserver.serve_forever) udpserver_thread.daemon = True udpserver_thread.start() -loadPacePartners() +load_pace_partners() ppthreadevent = threading.Event() -pp = threading.Thread(target=playPacePartners) +pp = threading.Thread(target=play_pace_partners) pp.start() -zwift_offline.run_standalone(online, globalPacePartners, ghostsEnabled, saveGhost, playerUpdateQueue) +zwift_offline.run_standalone(online, global_pace_partners, ghosts_enabled, save_ghost, player_update_queue) diff --git a/zwift_offline.py b/zwift_offline.py index 94a9792..db4230f 100644 --- a/zwift_offline.py +++ b/zwift_offline.py @@ -93,12 +93,12 @@ app.config['MAX_CONTENT_LENGTH'] = 1024 * 1024 db = SQLAlchemy(app) online = {} -globalPacePartners = {} -ghostsEnabled = {} -playerUpdateQueue = {} -playerIds = {} -playerPartialProfiles = {} -saveGhost = None +global_pace_partners = {} +ghosts_enabled = {} +player_update_queue = {} +player_ids = {} +player_partial_profiles = {} +save_ghost = None restarting = False restarting_in_minutes = 0 @@ -142,7 +142,7 @@ class Online: france = 0 paris = 0 -coursesLookup = { +courses_lookup = { 2: 'Richmond', 4: 'Unknown1', # event specific? 6: 'Watopia', @@ -156,44 +156,44 @@ coursesLookup = { 15: 'Paris' } -def getUTCDateTime(): +def get_utc_date_time(): return datetime.datetime.utcnow() -def getUTCSecondsFromDateTime(dt): +def get_utc_seconds_from_date_time(dt): return (time.mktime(dt.timetuple()) * 1000.0 + dt.microsecond / 1000.0) / 1000 -def getUTCTime(): - dt = getUTCDateTime() - return getUTCSecondsFromDateTime(dt) +def get_utc_time(): + dt = get_utc_date_time() + return get_utc_seconds_from_date_time(dt) -def getOnline(): - onlineInRegion = Online() +def get_online(): + online_in_region = Online() for p_id in online: player_state = online[p_id] - course = getCourse(player_state) - course_name = coursesLookup[course] + course = get_course(player_state) + course_name = courses_lookup[course] if course_name == 'Richmond': - onlineInRegion.richmond += 1 + online_in_region.richmond += 1 elif course_name == 'Watopia': - onlineInRegion.watopia += 1 + online_in_region.watopia += 1 elif course_name == 'London': - onlineInRegion.london += 1 + online_in_region.london += 1 elif course_name == 'New York': - onlineInRegion.newyork += 1 + online_in_region.newyork += 1 elif course_name == 'Innsbruck': - onlineInRegion.innsbruck += 1 + online_in_region.innsbruck += 1 elif course_name == 'Yorkshire': - onlineInRegion.yorkshire += 1 + online_in_region.yorkshire += 1 elif course_name == 'France': - onlineInRegion.france += 1 + online_in_region.france += 1 elif course_name == 'Paris': - onlineInRegion.paris += 1 - onlineInRegion.total += 1 - return onlineInRegion + online_in_region.paris += 1 + online_in_region.total += 1 + return online_in_region -def getPartialProfile(player_id): - if not player_id in playerPartialProfiles: +def get_partial_profile(player_id): + if not player_id in player_partial_profiles: #Read from disk profile_file = '%s/%s/profile.bin' % (STORAGE_DIR, player_id) if os.path.isfile(profile_file): @@ -201,23 +201,23 @@ def getPartialProfile(player_id): with open(profile_file, 'rb') as fd: profile = profile_pb2.Profile() profile.ParseFromString(fd.read()) - partialProfile = PartialProfile() - partialProfile.first_name = profile.first_name - partialProfile.last_name = profile.last_name - partialProfile.country_code = profile.country_code - playerPartialProfiles[player_id] = partialProfile + partial_profile = PartialProfile() + partial_profile.first_name = profile.first_name + partial_profile.last_name = profile.last_name + partial_profile.country_code = profile.country_code + player_partial_profiles[player_id] = partial_profile except: return None else: return None - return playerPartialProfiles[player_id] + return player_partial_profiles[player_id] -def getCourse(state): +def get_course(state): return (state.f19 & 0xff0000) >> 16 -def isNearby(player_state1, player_state2, range = 100000): +def is_nearby(player_state1, player_state2, range = 100000): try: - course1 = getCourse(player_state1) - course2 = getCourse(player_state2) + course1 = get_course(player_state1) + course2 = get_course(player_state2) if course1 == course2: x1 = int(player_state1.x) x2 = int(player_state2.x) @@ -299,7 +299,7 @@ def login(): if user and check_password_hash(user.pass_hash, password): login_user(user, remember=True) - return redirect(url_for("user_home", username=username, enable_ghosts=bool(user.enable_ghosts), online=getOnline())) + return redirect(url_for("user_home", username=username, enable_ghosts=bool(user.enable_ghosts), online=get_online())) else: flash("Invalid username or password.") @@ -310,7 +310,7 @@ def login(): @login_required def user_home(username): return render_template("user_home.html", username=current_user.username, enable_ghosts=bool(current_user.enable_ghosts), - online=getOnline(), is_admin=current_user.is_admin, restarting=restarting, restarting_in_minutes=restarting_in_minutes) + online=get_online(), is_admin=current_user.is_admin, restarting=restarting, restarting_in_minutes=restarting_in_minutes) def send_message_to_all_online(message): player_update = udp_node_msgs_pb2.PlayerUpdate() @@ -319,7 +319,7 @@ def send_message_to_all_online(message): player_update.world_time1 = world_time() player_update.world_time2 = world_time() + 60000 player_update.f12 = 1 - player_update.f14 = int(str(int(getUTCTime()*1000000))) + player_update.f14 = int(str(int(get_utc_time()*1000000))) chat_message = udp_node_msgs_pb2.ChatMessage() chat_message.rider_id = 0 @@ -333,9 +333,9 @@ def send_message_to_all_online(message): player_update.payload = chat_message.SerializeToString() for recieving_player_id in online.keys(): - if not recieving_player_id in playerUpdateQueue: - playerUpdateQueue[recieving_player_id] = list() - playerUpdateQueue[recieving_player_id].append(player_update.SerializeToString()) + if not recieving_player_id in player_update_queue: + player_update_queue[recieving_player_id] = list() + player_update_queue[recieving_player_id].append(player_update.SerializeToString()) def send_restarting_message(): global restarting @@ -488,7 +488,7 @@ def get_id(table_name): def world_time(): - return int((getUTCTime()-1414016075)*1000) + return int((get_utc_time()-1414016075)*1000) @app.route('/api/auth', methods=['GET']) @@ -504,7 +504,7 @@ def api_users_login(): response.info.relay_url = "https://us-or-rly101.zwift.com/relay" response.info.apis.todaysplan_url = "https://whats.todaysplan.com.au" response.info.apis.trainingpeaks_url = "https://api.trainingpeaks.com" - response.info.time = int(getUTCTime()) + response.info.time = int(get_utc_time()) udp_node = response.info.nodes.node.add() if os.path.exists(SERVER_IP_FILE): with open(SERVER_IP_FILE, 'r') as f: @@ -523,8 +523,8 @@ def api_users_logout(): player_id = current_user.player_id if player_id in online: online.pop(player_id) - if player_id in playerPartialProfiles: - playerPartialProfiles.pop(player_id) + if player_id in player_partial_profiles: + player_partial_profiles.pop(player_id) return '', 204 @@ -552,7 +552,7 @@ def api_zfiles(): zfile.id = int(random.getrandbits(31)) zfile.folder = "logfiles" zfile.filename = "yep_took_good_care_of_that_file.txt" - zfile.timestamp = int(getUTCTime()) + zfile.timestamp = int(get_utc_time()) return zfile.SerializeToString(), 200 @@ -632,7 +632,7 @@ def api_profiles_me(): elif current_user.player_id != profile.id: # Update AnonUser's player_id to match AnonUser.player_id = profile.id - ghostsEnabled[profile.id] = AnonUser.enable_ghosts + ghosts_enabled[profile.id] = AnonUser.enable_ghosts if not profile.email: profile.email = 'user@email.com' if profile.f60: @@ -747,7 +747,7 @@ def strava_upload(player_id, activity): logger.warn("Failed to read %s/strava_token.txt. Skipping Strava upload attempt." % profile_dir) return try: - if getUTCTime() > int(expires_at): + if get_utc_time() > int(expires_at): refresh_response = strava.refresh_access_token(client_id=client_id, client_secret=client_secret, refresh_token=refresh_token) with open('%s/strava_token.txt' % profile_dir, 'w') as f: @@ -815,7 +815,7 @@ def api_profiles_activities_id(player_id, activity_id): player_id = current_user.player_id if current_user.enable_ghosts: try: - saveGhost(activity.name, player_id) + save_ghost(activity.name, player_id) except: pass # Unconditionally *try* and upload to strava and garmin since profile may @@ -830,14 +830,14 @@ def api_profiles_activities_id(player_id, activity_id): @login_required def api_profiles_activities_rideon(recieving_player_id): sending_player_id = request.json['profileId'] - profile = getPartialProfile(sending_player_id) + profile = get_partial_profile(sending_player_id) if not profile == None: player_update = udp_node_msgs_pb2.PlayerUpdate() player_update.f2 = 1 player_update.type = 4 #ride on type player_update.world_time1 = world_time() player_update.world_time2 = player_update.world_time1 + 9890 - player_update.f14 = int(getUTCTime() * 1000000) + player_update.f14 = int(get_utc_time() * 1000000) ride_on = udp_node_msgs_pb2.RideOn() ride_on.rider_id = int(sending_player_id) @@ -848,9 +848,9 @@ def api_profiles_activities_rideon(recieving_player_id): player_update.payload = ride_on.SerializeToString() - if not recieving_player_id in playerUpdateQueue: - playerUpdateQueue[recieving_player_id] = list() - playerUpdateQueue[recieving_player_id].append(player_update.SerializeToString()) + if not recieving_player_id in player_update_queue: + player_update_queue[recieving_player_id] = list() + player_update_queue[recieving_player_id].append(player_update.SerializeToString()) return '{}', 200 @@ -873,11 +873,11 @@ def get_month_range(dt): def unix_time_millis(dt): - return int(getUTCSecondsFromDateTime(dt)*1000) + return int(get_utc_seconds_from_date_time(dt)*1000) def fill_in_goal_progress(goal, player_id): - now = getUTCDateTime() + now = get_utc_date_time() if goal.periodicity == 0: # weekly first_dt, last_dt = get_week_range(now) else: # monthly @@ -931,7 +931,7 @@ def api_profiles_goals(player_id): goal = goal_pb2.Goal() goal.ParseFromString(request.stream.read()) goal.id = get_id('goal') - now = getUTCDateTime() + now = get_utc_date_time() goal.created_on = unix_time_millis(now) set_goal_end_date(goal, now) fill_in_goal_progress(goal, player_id) @@ -946,7 +946,7 @@ def api_profiles_goals(player_id): goal = goals.goals.add() row_to_protobuf(row, goal) end_dt = datetime.datetime.fromtimestamp(goal.period_end_date / 1000) - now = getUTCDateTime() + now = get_utc_date_time() if end_dt < now: set_goal_end_date(goal, now) update_protobuf_in_db('goal', goal, goal.id) @@ -979,8 +979,36 @@ def api_tcp_config(): return infos.SerializeToString(), 200 +def add_player_to_world(player, course_world, is_pace_partner): + course_id = get_course(player) + if course_id in course_world.keys(): + partial_profile = get_partial_profile(player.id) + if not partial_profile == None: + online_player = None + if is_pace_partner: + online_player = course_world[course_id].pace_partner_states.add() + else: + online_player = course_world[course_id].player_states.add() + online_player.id = player.id + online_player.firstName = partial_profile.first_name + online_player.lastName = partial_profile.last_name + online_player.distance = player.distance + online_player.time = player.time + online_player.f6 = 840#0 + online_player.f8 = 0 + online_player.f9 = 0 + online_player.f10 = 0 + online_player.f11 = 0 + online_player.power = player.power + online_player.f13 = 2355 + online_player.x = player.x + online_player.altitude = player.altitude + online_player.y = player.y + course_world[course_id].f5 += 1 + + def relay_worlds_generic(world_id=None): - courses = coursesLookup.keys() + courses = courses_lookup.keys() # Android client also requests a JSON version if request.headers['Accept'] == 'application/json': if request.content_type == 'application/x-protobuf-lite': @@ -993,7 +1021,7 @@ def relay_worlds_generic(world_id=None): #serializedMessage = chat_message.SerializeToString() except: #Not able to decode as playerupdate, send dummy response - world = { 'currentDateTime': int(getUTCTime()), + world = { 'currentDateTime': int(get_utc_time()), 'currentWorldTime': world_time(), 'friendsInWorld': [], 'mapId': 1, @@ -1010,7 +1038,7 @@ def relay_worlds_generic(world_id=None): #PlayerUpdate player_update.world_time2 = world_time() + 60000 player_update.f12 = 1 - player_update.f14 = int(str(int(getUTCTime()*1000000))) + player_update.f14 = int(str(int(get_utc_time()*1000000))) for recieving_player_id in online.keys(): should_receive = False if player_update.type == 5 or player_update.type == 105: @@ -1023,7 +1051,7 @@ def relay_worlds_generic(world_id=None): if sending_player_id in online: sending_player = online[sending_player_id] #Check that players are on same course and close to each other - if isNearby(sending_player, recieving_player): + if is_nearby(sending_player, recieving_player): should_receive = True #Segment complete else: @@ -1033,19 +1061,20 @@ def relay_worlds_generic(world_id=None): if sending_player_id in online: sending_player = online[sending_player_id] #Check that players are on same course and close to each other - if getCourse(sending_player) == getCourse(recieving_player): + if get_course(sending_player) == get_course(recieving_player): should_receive = True #Other PlayerUpdate, send to all else: should_receive = True if should_receive: - if not recieving_player_id in playerUpdateQueue: - playerUpdateQueue[recieving_player_id] = list() - playerUpdateQueue[recieving_player_id].append(player_update.SerializeToString()) + if not recieving_player_id in player_update_queue: + player_update_queue[recieving_player_id] = list() + player_update_queue[recieving_player_id].append(player_update.SerializeToString()) return '{}', 200 else: # protobuf request worlds = world_pb2.Worlds() world = None + course_world = {} for course in courses: world = worlds.worlds.add() @@ -1053,57 +1082,16 @@ def relay_worlds_generic(world_id=None): world.name = 'Public Watopia' world.f3 = course world.world_time = world_time() - world.real_time = int(getUTCTime()) - playersInRegion = 0 - for p_id in online.keys(): - player = online[p_id] - courseId = getCourse(player) - if course == courseId: - partialProfile = getPartialProfile(player.id) - if not partialProfile == None: - onlinePlayer = world.player_states.add() - onlinePlayer.id = player.id - onlinePlayer.firstName = partialProfile.first_name - onlinePlayer.lastName = partialProfile.last_name - onlinePlayer.distance = player.distance - onlinePlayer.time = player.time - onlinePlayer.f6 = 840#0 - onlinePlayer.f8 = 0 - onlinePlayer.f9 = 0 - onlinePlayer.f10 = 0 - onlinePlayer.f11 = 0 - onlinePlayer.power = 250#player.power - onlinePlayer.f13 = 2355 - onlinePlayer.x = player.x - onlinePlayer.altitude = player.altitude - onlinePlayer.y = player.y - playersInRegion += 1 - for p_id in globalPacePartners.keys(): - pace_partner_variables = globalPacePartners[p_id] - pace_partner_id = int(p_id) - pace_partner = pace_partner_variables.route.states[pace_partner_variables.position] - courseId = getCourse(pace_partner) - if course == courseId: - partialProfile = getPartialProfile(pace_partner_id) - if not partialProfile == None: - online_pace_partner = world.pace_partner_states.add() - online_pace_partner.id = pace_partner_id - online_pace_partner.firstName = partialProfile.first_name - online_pace_partner.lastName = partialProfile.last_name - online_pace_partner.distance = pace_partner.distance - online_pace_partner.time = pace_partner.time - online_pace_partner.f6 = 840#0 - online_pace_partner.f8 = 0 - online_pace_partner.f9 = 0 - online_pace_partner.f10 = 0 - online_pace_partner.f11 = 0 - online_pace_partner.power = pace_partner.power - online_pace_partner.f13 = 2355 - online_pace_partner.x = pace_partner.x - online_pace_partner.altitude = pace_partner.altitude - online_pace_partner.y = pace_partner.y - playersInRegion += 1 - world.f5 = playersInRegion + world.real_time = int(get_utc_time()) + world.f5 = 0 + course_world[course] = world + for p_id in online.keys(): + player = online[p_id] + add_player_to_world(player, course_world, False) + for p_id in global_pace_partners.keys(): + pace_partner_variables = global_pace_partners[p_id] + pace_partner = pace_partner_variables.route.states[pace_partner_variables.position] + add_player_to_world(pace_partner, course_world, True) if world_id: world.id = world_id return world.SerializeToString() @@ -1132,8 +1120,8 @@ def relay_worlds_id_players_id(world_id, player_id): if player_id in online.keys(): player = online[player_id] return player.SerializeToString() - if str(player_id) in globalPacePartners.keys(): - pace_partner = globalPacePartners[str(player_id)] + if player_id in global_pace_partners.keys(): + pace_partner = global_pace_partners[player_id] return pace_partner.route.states[pace_partner.position].SerializeToString() return None @@ -1218,7 +1206,7 @@ def handle_segment_results(request): result.ParseFromString(request.stream.read()) result.id = get_id('segment_result') result.world_time = world_time() - result.finish_time_str = getUTCDateTime().strftime("%Y-%m-%dT%H:%M:%SZ") + result.finish_time_str = get_utc_date_time().strftime("%Y-%m-%dT%H:%M:%SZ") result.f20 = 0 insert_protobuf_into_db('segment_result', result) return '{"id": %ld}' % result.id, 200 @@ -1297,10 +1285,10 @@ def init_database(): return # Database needs to be upgraded, try to back it up first try: # Try writing to storage dir - copyfile(DATABASE_PATH, "%s.v%d.%d.bak" % (DATABASE_PATH, version, int(getUTCTime()))) + copyfile(DATABASE_PATH, "%s.v%d.%d.bak" % (DATABASE_PATH, version, int(get_utc_time()))) except: try: # Fall back to a temporary dir - copyfile(DATABASE_PATH, "%s/zwift-offline.db.v%s.%d.bak" % (tempfile.gettempdir(), version, int(getUTCTime()))) + copyfile(DATABASE_PATH, "%s/zwift-offline.db.v%s.%d.bak" % (tempfile.gettempdir(), version, int(get_utc_time()))) except: logging.warn("Failed to create a zoffline database backup prior to upgrading it.") @@ -1379,7 +1367,7 @@ def launch_zwift(): if MULTIPLAYER: return render_template("login_form.html") else: - return render_template("user_home.html", username="", enable_ghosts=False, online=getOnline(), + return render_template("user_home.html", username="", enable_ghosts=False, online=get_online(), is_admin=False, restarting=restarting, restarting_in_minutes=restarting_in_minutes) else: if MULTIPLAYER: @@ -1441,7 +1429,7 @@ def auth_realms_zwift_protocol_openid_connect_token(): def start_zwift(): if MULTIPLAYER: current_user.enable_ghosts = 'enableghosts' in request.form.keys() - ghostsEnabled[current_user.player_id] = current_user.enable_ghosts + ghosts_enabled[current_user.player_id] = current_user.enable_ghosts else: AnonUser.enable_ghosts = 'enableghosts' in request.form.keys() db.session.commit() @@ -1470,18 +1458,18 @@ def auth_realms_zwift_tokens_access_codes(): return FAKE_JWT, 200 -def run_standalone(passedOnline, passedGlobalPacePartners, passedGhostsEnabled, passedSaveGhost, passedPlayerUpdateQueue): +def run_standalone(passed_online, passed_global_pace_partners, passed_ghosts_enabled, passed_save_ghost, passed_player_update_queue): global online - global globalPacePartners - global ghostsEnabled - global saveGhost - global playerUpdateQueue + global global_pace_partners + global ghosts_enabled + global save_ghost + global player_update_queue global login_manager - online = passedOnline - globalPacePartners = passedGlobalPacePartners - ghostsEnabled = passedGhostsEnabled - saveGhost = passedSaveGhost - playerUpdateQueue = passedPlayerUpdateQueue + online = passed_online + global_pace_partners = passed_global_pace_partners + ghosts_enabled = passed_ghosts_enabled + save_ghost = passed_save_ghost + player_update_queue = passed_player_update_queue login_manager = LoginManager() login_manager.login_view = 'login' login_manager.session_protection = None