Simplified ride with online players fetch

Changed str to int in global_pace_partners
Renamed variables, functions and classes consistently
This commit is contained in:
perast
2020-11-13 09:16:38 +01:00
parent 03466c4565
commit af79c1178b
2 changed files with 196 additions and 207 deletions
+71 -70
View File
@@ -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)
+125 -137
View File
@@ -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