Check if players are nearby

Save and use partialprofile instead of loading from .bin
Checkbox for ghosts should reflect db
Moved pop to /logout
This commit is contained in:
perast
2020-11-05 11:16:07 +01:00
parent 4d9878ee35
commit e7e8a49a01
3 changed files with 104 additions and 56 deletions
+1 -1
View File
@@ -36,7 +36,7 @@
</div>
<div class="col-md-4 top-buffer">
<div class="form-check">
<input class="form-check-input" type="checkbox" checked="true" id="enableghosts" name="enableghosts">
<input class="form-check-input" type="checkbox" {{'checked' if enable_ghosts else ''}} id="enableghosts" name="enableghosts">
<label class="form-check-label" for="enableghosts">
Enable ghosts
</label>
+11 -7
View File
@@ -436,16 +436,19 @@ class UDPHandler(socketserver.BaseRequestHandler):
message.f5 = 1
message.f11 = 1
msgnum = 1
players = len(online)
for p_id in online.keys():
player = online[p_id]
if player.id == player_id:
players -= 1
message.num_msgs = players // 10
if players % 10: message.num_msgs += 1
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.isNearby(recv.state, player):
nearby.append(p_id)
players = len(nearby)
message.num_msgs = players // 10
if players % 10: message.num_msgs += 1
for p_id in nearby:
if p_id in online.keys():
player = online[p_id]
if len(message.states) < 10:
state = message.states.add()
state.CopyFrom(player)
@@ -457,6 +460,7 @@ class UDPHandler(socketserver.BaseRequestHandler):
del message.states[:]
state = message.states.add()
state.CopyFrom(player)
else: message.num_msgs -= 1
message.world_time = zwift_offline.world_time()
message.msgnum = msgnum
socket.sendto(message.SerializeToString(), client_address)
+92 -48
View File
@@ -88,6 +88,7 @@ ghostsEnabled = {}
rideOnQueue = {}
messageQueue = {}
playerIds = {}
playerPartialProfiles = {}
temporaryLoginValues = {}
saveGhost = None
@@ -103,6 +104,11 @@ class User(db.Model):
def __repr__(self):
return '' % self.username
class PartialProfile:
first_name: str
last_name: str
country_code: int
def setMachineIdAndGhostsEnabled(request, player_id, ghosts_enabled):
machine_id = request.headers.get('X_MACHINE_ID')
#Remove machine id for other users
@@ -129,6 +135,49 @@ def getPlayerId(request):
ghostsEnabled[player_id] = ghosts_enabled
return player_id
def getPartialProfile(player_id):
player_id_str = str(player_id)
if not player_id_str in playerPartialProfiles:
#Read from disk
profile_file = '%s/%s/profile.bin' % (STORAGE_DIR, player_id_str)
if os.path.isfile(profile_file):
try:
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_str] = partialProfile
except:
return None
else: return None
return playerPartialProfiles[player_id_str]
def getCourse(state):
return (state.f19 & 0xff0000) >> 16
def isNearby(player_state1, player_state2, range = 1000):
try:
course1 = getCourse(player_state1)
course2 = getCourse(player_state2)
if course1 == course2:
x1 = int(player_state1.x)
x2 = int(player_state2.x)
if x1 - range <= x2 or x1 + range >= x2:
y1 = int(player_state1.y)
y2 = int(player_state2.y)
if y1 - range <= y2 or y1 + range >= y2:
a1 = int(player_state1.altitude)
a2 = int(player_state2.altitude)
if a1 - range <= a2 or a1 + range >= a2:
return True
except:
pass
return False
@app.route("/signup/", methods=["GET", "POST"])
def signup():
if request.method == "POST":
@@ -173,7 +222,7 @@ def login():
if user and check_password_hash(user.pass_hash, password):
session[username] = True
temporaryLoginValues[request.remote_addr + ":player_id"] = user.uid + 1000
return redirect(url_for("user_home", username=username))
return redirect(url_for("user_home", username=username, enable_ghosts=bool(user.enable_ghosts)))
else:
flash("Invalid username or password.")
@@ -185,7 +234,8 @@ def user_home(username):
if not session.get(username):
abort(401)
return render_template("user_home.html", username=username)
user = User.query.filter_by(username=username).first()
return render_template("user_home.html", username=username, enable_ghosts=bool(user.enable_ghosts))
@app.route("/upload/<username>/", methods=["GET", "POST"])
@@ -331,6 +381,12 @@ def api_users_login():
@app.route('/api/users/logout', methods=['POST'])
def api_users_logout():
#Remove player from online when leaving game/world
player_id = getPlayerId(request)
if player_id in online:
online.pop(player_id)
if player_id in playerPartialProfiles:
playerPartialProfiles.pop(player_id)
return '', 204
@@ -576,21 +632,18 @@ def api_profiles_activities_id(player_id, activity_id):
def api_profiles_activities_rideon(recieving_player_id):
sending_player_id = request.json['profileId']
ride_on = udp_node_msgs_pb2.RideOn()
profile_file = '%s/%s/profile.bin' % (STORAGE_DIR, sending_player_id)
if os.path.isfile(profile_file):
with open(profile_file, 'rb') as fd:
profile = profile_pb2.Profile()
profile.ParseFromString(fd.read())
ride_on.rider_id = int(sending_player_id)
ride_on.to_rider_id = int(recieving_player_id)
ride_on.firstName = profile.first_name
ride_on.lastName = profile.last_name
ride_on.countryCode = profile.country_code
recieving_player_id_str = str(recieving_player_id)
sending_player_id_str = str(sending_player_id)
if not recieving_player_id_str in rideOnQueue:
rideOnQueue[recieving_player_id_str] = {}
rideOnQueue[recieving_player_id_str][sending_player_id_str] = ride_on
profile = getPartialProfile(sending_player_id)
if not profile == None:
ride_on.rider_id = int(sending_player_id)
ride_on.to_rider_id = int(recieving_player_id)
ride_on.firstName = profile.first_name
ride_on.lastName = profile.last_name
ride_on.countryCode = profile.country_code
recieving_player_id_str = str(recieving_player_id)
sending_player_id_str = str(sending_player_id)
if not recieving_player_id_str in rideOnQueue:
rideOnQueue[recieving_player_id_str] = {}
rideOnQueue[recieving_player_id_str][sending_player_id_str] = ride_on
return '{}', 200
@@ -752,12 +805,10 @@ def relay_worlds_generic(world_id=None):
sending_player_id_str = str(chat_message.rider_id)
if sending_player_id_str in online:
sending_player = online[sending_player_id_str]
sending_player_course = (sending_player.f19 & 0xff0000) >> 16
for p_id in online.keys():
player = online[p_id]
receiving_player_course = (player.f19 & 0xff0000) >> 16
#TODO: Check distance between players
if sending_player_course == receiving_player_course:
#Check that players are on same course and close to each other
if isNearby(sending_player, player):
recieving_player_id_str = p_id
if not recieving_player_id_str in messageQueue:
messageQueue[recieving_player_id_str] = {}
@@ -777,30 +828,27 @@ def relay_worlds_generic(world_id=None):
playersInRegion = 0
for p_id in online.keys():
player = online[p_id]
courseId = (player.f19 & 0xff0000) >> 16
courseId = getCourse(player)
if course == courseId:
profile_file = '%s/%s/profile.bin' % (STORAGE_DIR, player.id)
if os.path.isfile(profile_file):
with open(profile_file, 'rb') as fd:
profile = profile_pb2.Profile()
profile.ParseFromString(fd.read())
onlinePlayer = world.player_states.add()
onlinePlayer.id = player.id
onlinePlayer.firstName = profile.first_name
onlinePlayer.lastName = profile.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 = playersInRegion + 1
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
world.f5 = playersInRegion
if world_id:
world.id = world_id
@@ -942,10 +990,6 @@ def api_segment_results():
@app.route('/relay/worlds/<int:world_id>/leave', methods=['POST'])
def relay_worlds_leave(world_id):
#Remove player from online when leaving game/world
player_id = getPlayerId(request)
if player_id in online:
online.pop(player_id)
return '{"worldtime":%ld}' % world_time()