Example #1
0
def loadGhosts(player_id, state):
    global play
    global spawn
    if not player_id: return
    folder = '%s/%s/ghosts/load' % (STORAGE_DIR, player_id)
    if not os.path.isdir(folder): return
    s = list()
    for (root, dirs, files) in os.walk(folder):
        for f in files:
            if f.endswith('.bin'):
                with open(os.path.join(root, f), 'rb') as fd:
                    g = udp_node_msgs_pb2.Ghost()
                    g.ParseFromString(fd.read())
                    if course(g.states[0]) == course(state) and roadID(
                            g.states[0]) == roadID(state) and isForward(
                                g.states[0]) == isForward(state):
                        h = play.ghosts.add()
                        h.CopyFrom(g)
                        s.append(g.states[0].roadTime)
    s.append(state.roadTime)
    if isForward(state): spawn = max(s)
    else: spawn = min(s)
    for g in play.ghosts:
        if isForward(g.states[0]):
            while g.states[0].roadTime < spawn:
                del g.states[0]
        else:
            while g.states[0].roadTime > spawn:
                del g.states[0]
Example #2
0
def load_bots():
    if not os.path.isdir(BOTS_DIR): return
    for (root, dirs, files) in os.walk(BOTS_DIR):
        for bot_id in dirs:
            p_id = int(bot_id)
            route = '%s/%s/route.bin' % (BOTS_DIR, bot_id)
            if os.path.isfile(route):
                with open(route, 'rb') as fd:
                    global_bots[p_id] = BotVariables()
                    bot = global_bots[p_id]
                    bot.route = udp_node_msgs_pb2.Ghost()
                    bot.route.ParseFromString(fd.read())
                    bot.position = 0
Example #3
0
def load_pace_partners():
    if not os.path.isdir(PACE_PARTNERS_DIR): return
    for (root, dirs, files) in os.walk(PACE_PARTNERS_DIR):
        for pp_id in dirs:
            p_id = int(pp_id)
            route = '%s/%s/route.bin' % (PACE_PARTNERS_DIR, pp_id)
            if os.path.isfile(route):
                with open(route, 'rb') as fd:
                    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
Example #4
0
def loadGhosts(player_id, state):
    global play
    global start_road
    global start_rt
    if not player_id: return
    folder = '%s/%s/ghosts/load' % (STORAGE_DIR, player_id)
    if not os.path.isdir(folder): return
    s = list()
    for (root, dirs, files) in os.walk(folder):
        for f in files:
            if f.endswith('.bin'):
                with open(os.path.join(root, f), 'rb') as fd:
                    g = udp_node_msgs_pb2.Ghost()
                    g.ParseFromString(fd.read())
                    if course(g.states[0]) == course(state) and roadID(g.states[0]) == roadID(state) and isForward(
                            g.states[0]) == isForward(state):
                        h = play.ghosts.add()
                        h.CopyFrom(g)
                        s.append(g.states[0].roadTime)
    start_road = roadID(state)
    start_rt = 0
    sl_file = '%s/start_lines.csv' % STORAGE_DIR
    if os.path.isfile(sl_file):
        with open(sl_file, 'r') as fd:
            sl = [tuple(line) for line in csv.reader(fd)]
            rt = [t for t in sl if t[0] == str(course(state)) and t[1] == str(roadID(state)) and (
                    t[2] == str(isForward(state)) or not t[2])]
            if rt:
                start_road = int(rt[0][3])
                start_rt = int(rt[0][4])
    if not start_rt:
        s.append(state.roadTime)
        if isForward(state):
            start_rt = max(s)
        else:
            start_rt = min(s)
    for g in play.ghosts:
        while roadID(g.states[0]) != start_road:
            del g.states[0]
        if isForward(g.states[0]):
            while not (g.states[0].roadTime <= start_rt <= g.states[1].roadTime):
                del g.states[0]
        else:
            while not (g.states[0].roadTime >= start_rt >= g.states[1].roadTime):
                del g.states[0]
Example #5
0
def organizeGhosts(player_id):
    # organize ghosts in course/roadID 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
    for f in os.listdir(folder):
        if f.endswith('.bin'):
            file = os.path.join(folder, f)
            with open(file, 'rb') as fd:
                g = udp_node_msgs_pb2.Ghost()
                g.ParseFromString(fd.read())
                dest = '%s/%s/%s' % (folder, course(g.states[0]), roadID(g.states[0]))
                if not isForward(g.states[0]): dest += '/reverse'
                try:
                    if not os.path.isdir(dest):
                        os.makedirs(dest)
                except:
                    return
            os.rename(file, os.path.join(dest, f))
Example #6
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)
Example #7
0
    STORAGE_DIR = "%s/storage" % os.path.dirname(sys.executable)
    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
Example #8
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)