START_LINES_FILE = '%s/start_lines.csv' % STORAGE_DIR if not os.path.isfile(START_LINES_FILE): copyfile('%s/start_lines.csv' % sys._MEIPASS, START_LINES_FILE) else: SCRIPT_DIR = os.path.dirname(os.path.realpath(__file__)) CDN_DIR = "%s/cdn" % SCRIPT_DIR STORAGE_DIR = "%s/storage" % SCRIPT_DIR START_LINES_FILE = '%s/start_lines.csv' % SCRIPT_DIR PROXYPASS_FILE = "%s/cdn-proxy.txt" % STORAGE_DIR SERVER_IP_FILE = "%s/server-ip.txt" % STORAGE_DIR MAP_OVERRIDE = None ENABLEGHOSTS_FILE = "%s/enable_ghosts.txt" % STORAGE_DIR rec = udp_node_msgs_pb2.Ghost() play = udp_node_msgs_pb2.Ghosts() seqno = 1 last_rec = 0 last_play = 0 play_count = 0 last_rt = 0 ghosts_enabled = False ghosts_loaded = False ghosts_started = False start_road = 0 start_rt = 0 update_freq = 3 def roadID(state): return (state.f20 & 0xff00) >> 8
def handle(self): data = self.request[0] socket = self.request[1] recv = udp_node_msgs_pb2.ClientToServer() try: recv.ParseFromString(data[:-4]) except: try: #If no sensors connected, first byte must be skipped recv.ParseFromString(data[1:-4]) except: return client_address = self.client_address player_id = recv.player_id state = recv.state #Add last updates for player if missing if not player_id in last_updates.keys(): last_updates[player_id] = 0 if not player_id in last_online_updates.keys(): last_online_updates[player_id] = 0 if not player_id in last_pp_updates.keys(): last_pp_updates[player_id] = 0 if not player_id in last_bot_updates.keys(): last_bot_updates[player_id] = 0 t = int(zwift_offline.get_utc_time()) #Update player online state if state.roadTime and t >= last_updates[player_id] + online_update_freq: last_updates[player_id] = t if not player_id in online.keys(): discord.send_message('%s riders online' % (len(online) + 1)) online[player_id] = state #Add handling of ghosts for player if it's missing if not player_id in global_ghosts.keys(): global_ghosts[player_id] = GhostsVariables() ghosts = global_ghosts[player_id] ghosts.last_package_time = t if recv.seqno == 1: ghosts.rec = None organize_ghosts(player_id) #Changed course if get_course(state) and ghosts.course != get_course(state): ghosts.rec = None ghosts.course = get_course(state) if ghosts.rec == None: ghosts.rec = udp_node_msgs_pb2.Ghost() ghosts.play = udp_node_msgs_pb2.Ghosts() ghosts.last_rt = 0 ghosts.play_count = 0 ghosts.loaded = False ghosts.started = False ghosts.rec.player_id = player_id if player_id in ghosts_enabled and ghosts_enabled[player_id]: #Load ghosts for current course if not ghosts.loaded and get_course(state): ghosts.loaded = True load_ghosts(player_id, state, ghosts) #Save player state as ghost if moving if state.roadTime and ghosts.last_rt and state.roadTime != ghosts.last_rt: if t >= ghosts.last_rec + ghost_update_freq: s = ghosts.rec.states.add() s.CopyFrom(state) ghosts.last_rec = t #Start loaded ghosts 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 and abs( state.roadTime - ghosts.start_rt) < 500000: ghosts.started = True else: if state.roadTime < ghosts.start_rt and abs( state.roadTime - ghosts.start_rt) < 500000: ghosts.started = True #Uncomment to print player state when stopped (to find new start lines) #else: print('course', get_course(state), 'road', road_id(state), 'isForward', is_forward(state), 'roadTime', state.roadTime) ghosts.last_rt = state.roadTime #Set state of player being watched watching_state = None if state.watchingRiderId == player_id: watching_state = state elif state.watchingRiderId in online.keys(): watching_state = online[state.watchingRiderId] elif state.watchingRiderId in global_pace_partners.keys(): pp = global_pace_partners[state.watchingRiderId] watching_state = pp.route.states[pp.position] elif state.watchingRiderId in global_bots.keys(): bot = global_bots[state.watchingRiderId] watching_state = bot.route.states[bot.position] elif state.watchingRiderId > 10000000: ghost = ghosts.play.ghosts[math.floor(state.watchingRiderId / 10000000) - 1] if len(ghost.states) > ghosts.play_count: watching_state = ghost.states[ghosts.play_count] #Check if online players, pace partners, bots and ghosts are nearby nearby = list() if t >= last_online_updates[player_id] + online_update_freq: last_online_updates[player_id] = t for p_id in online.keys(): player = online[p_id] if player.id != player_id and zwift_offline.is_nearby( watching_state, player): nearby.append(p_id) if t >= last_pp_updates[player_id] + pacer_update_freq: last_pp_updates[player_id] = t 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] if zwift_offline.is_nearby(watching_state, pace_partner): nearby.append(p_id) if t >= last_bot_updates[player_id] + bot_update_freq: last_bot_updates[player_id] = t for p_id in global_bots.keys(): bot_variables = global_bots[p_id] bot = bot_variables.route.states[bot_variables.position] if zwift_offline.is_nearby(watching_state, bot): nearby.append(p_id) if ghosts.started and t >= ghosts.last_play + ghost_update_freq: ghosts.last_play = t ghost_id = 1 for g in ghosts.play.ghosts: if len(g.states ) > ghosts.play_count and zwift_offline.is_nearby( watching_state, g.states[ghosts.play_count]): nearby.append(player_id + ghost_id * 10000000) ghost_id += 1 ghosts.play_count += 1 #Send nearby riders states or empty message message = get_empty_message(player_id) if nearby: message.num_msgs = math.ceil(len(nearby) / 10) for p_id in nearby: player = None if p_id in online.keys(): player = online[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] elif p_id in global_bots.keys(): bot_variables = global_bots[p_id] player = bot_variables.route.states[bot_variables.position] elif p_id > 10000000: player = ghosts.play.ghosts[math.floor(p_id / 10000000) - 1].states[ghosts.play_count - 1] player.id = p_id player.worldTime = zwift_offline.world_time() if player != None: if len(message.states) > 9: message.world_time = zwift_offline.world_time() socket.sendto(message.SerializeToString(), client_address) message.msgnum += 1 del message.states[:] s = message.states.add() s.CopyFrom(player) else: message.num_msgs = 1 message.world_time = zwift_offline.world_time() socket.sendto(message.SerializeToString(), client_address)
def handle(self): data = self.request[0] socket = self.request[1] recv = udp_node_msgs_pb2.ClientToServer() try: recv.ParseFromString(data[:-4]) except: try: recv.ParseFromString(data[3:-4]) except: return client_address = self.client_address player_id = recv.player_id state = recv.state nearby_state = state if state.watchingRiderId in online.keys(): nearby_state = online[state.watchingRiderId] elif state.watchingRiderId in global_pace_partners.keys(): pp = global_pace_partners[state.watchingRiderId] nearby_state = pp.route.states[pp.position] #Add handling of ghosts for player if it's missing if not player_id in global_ghosts.keys(): global_ghosts[player_id] = GhostsVariables() ghosts = global_ghosts[player_id] #Add pace partner last update for player if it's missing if not player_id in last_pp_updates.keys(): last_pp_updates[player_id] = 0 last_pp_update = last_pp_updates[player_id] #Add bot last update for player if it's missing if not player_id in last_bot_updates.keys(): last_bot_updates[player_id] = 0 last_bot_update = last_bot_updates[player_id] if recv.seqno == 1 or ghosts.rec == None: ghosts.rec = udp_node_msgs_pb2.Ghost() ghosts.play = udp_node_msgs_pb2.Ghosts() ghosts.last_rt = 0 ghosts.play_count = 0 ghosts.loaded = False ghosts.started = False ghosts.rec.player_id = player_id organize_ghosts(player_id) t = int(zwift_offline.get_utc_time()) ghosts.last_package_time = t if player_id in ghosts_enabled and ghosts_enabled[player_id]: if not ghosts.loaded and get_course(state): ghosts.loaded = True load_ghosts(player_id, state, ghosts) if state.roadTime and ghosts.last_rt and state.roadTime != ghosts.last_rt: if t >= ghosts.last_rec + ghost_update_freq: s = ghosts.rec.states.add() s.CopyFrom(state) ghosts.last_rec = t 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: if state.roadTime <= ghosts.start_rt <= ghosts.last_rt: ghosts.started = True # else: print('course', get_course(state), 'road', road_id(state), 'isForward', is_forward(state), 'roadTime', state.roadTime) ghosts.last_rt = state.roadTime keys = online.keys() remove_players = list() for p_id in keys: if zwift_offline.world_time() > online[p_id].worldTime + 10000: 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 = global_ghosts.keys() remove_players = list() for p_id in keys: 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 + ghost_update_freq: message = get_empty_message(player_id) active_ghosts = 0 for g in ghosts.play.ghosts: if len(g.states) > ghosts.play_count: active_ghosts += 1 if active_ghosts: message.num_msgs = active_ghosts // 10 if active_ghosts % 10: message.num_msgs += 1 ghost_id = 1 for g in ghosts.play.ghosts: if len(g.states) > ghosts.play_count: if len(message.states) < 10: state = message.states.add() state.CopyFrom(g.states[ghosts.play_count]) state.id = player_id + ghost_id * 10000000 state.worldTime = zwift_offline.world_time() else: message.world_time = zwift_offline.world_time() socket.sendto(message.SerializeToString(), client_address) message.msgnum += 1 del message.states[:] state = message.states.add() state.CopyFrom(g.states[ghosts.play_count]) state.id = player_id + ghost_id * 10000000 state.worldTime = zwift_offline.world_time() ghost_id += 1 else: message.num_msgs = 1 message.world_time = zwift_offline.world_time() socket.sendto(message.SerializeToString(), client_address) ghosts.play_count += 1 ghosts.last_play = t message = get_empty_message(player_id) nearby = list() for p_id in online.keys(): player = online[p_id] if player.id != player_id: #Check if players are close in world if zwift_offline.is_nearby(nearby_state, player): nearby.append(p_id) if t >= last_pp_update + pacer_update_freq: last_pp_updates[player_id] = t 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.is_nearby(nearby_state, pace_partner): nearby.append(p_id) if t >= last_bot_update + bot_update_freq: last_bot_updates[player_id] = t for p_id in global_bots.keys(): bot_variables = global_bots[p_id] bot = bot_variables.route.states[bot_variables.position] #Check if bot is close to player in world if zwift_offline.is_nearby(nearby_state, bot): nearby.append(p_id) players = len(nearby) message.num_msgs = players // 10 if players % 10: message.num_msgs += 1 for p_id in nearby: player = None if p_id in online.keys(): player = online[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] elif p_id in global_bots.keys(): bot_variables = global_bots[p_id] player = bot_variables.route.states[bot_variables.position] if player != None: if len(message.states) < 10: state = message.states.add() state.CopyFrom(player) else: message.world_time = zwift_offline.world_time() socket.sendto(message.SerializeToString(), client_address) message.msgnum += 1 del message.states[:] state = message.states.add() state.CopyFrom(player) message.world_time = zwift_offline.world_time() socket.sendto(message.SerializeToString(), client_address)