mirror of
https://github.com/zoffline/zwift-offline.git
synced 2026-08-03 01:15:46 -07:00
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:
+71
-70
@@ -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
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user