Exemple #1
0
    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)
Exemple #2
0
    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)