revert 97ababab11 - I done goofed up the sockets mane

revert Add WS support to matches (breaking change)

- Fixed issue where ELO rating could go in the negatives, read more [here](Mercury/dth-pingpong-mobileapp#3 (comment))
- Initial websocket support for multi-screen matchmaking, [#1](Mercury/dth-pingpong-mobileapp#1)
This commit is contained in:
Mercury. 2025-01-21 22:41:12 +01:00
parent 97ababab11
commit 9f1246ba1f

74
main.py
View file

@ -1,5 +1,4 @@
from fastapi import FastAPI, HTTPException, WebSocket from fastapi import FastAPI, HTTPException
from typing import Dict, List
from pydantic import BaseModel from pydantic import BaseModel
from fastapi.middleware.cors import CORSMiddleware from fastapi.middleware.cors import CORSMiddleware
from calls import * from calls import *
@ -16,9 +15,6 @@ app.add_middleware(
allow_headers=["*"], allow_headers=["*"],
) )
active_connections: Dict[int, List[WebSocket]] = {}
class RegisterRequest(BaseModel): class RegisterRequest(BaseModel):
email: str email: str
display_name: str display_name: str
@ -156,9 +152,6 @@ def create_match(request: CreateMatchRequest):
) )
match_id = cursor.fetchone()["match_id"] match_id = cursor.fetchone()["match_id"]
conn.commit() conn.commit()
active_connections[match_id] = []
return {"match_id": match_id} return {"match_id": match_id}
except Exception as e: except Exception as e:
conn.rollback() conn.rollback()
@ -167,6 +160,7 @@ def create_match(request: CreateMatchRequest):
cursor.close() cursor.close()
conn.close() conn.close()
@app.post("/joinmatch") @app.post("/joinmatch")
def join_match(request: JoinMatchRequest): def join_match(request: JoinMatchRequest):
conn = get_db_connection() conn = get_db_connection()
@ -200,7 +194,6 @@ def join_match(request: JoinMatchRequest):
(player2_uid, request.match_id) (player2_uid, request.match_id)
) )
conn.commit() conn.commit()
return {"message": "Joined match successfully", "match_id": request.match_id} return {"message": "Joined match successfully", "match_id": request.match_id}
except Exception as e: except Exception as e:
conn.rollback() conn.rollback()
@ -209,7 +202,6 @@ def join_match(request: JoinMatchRequest):
cursor.close() cursor.close()
conn.close() conn.close()
def calculate_elo(player1_elo, player2_elo, player1_score, player2_score): def calculate_elo(player1_elo, player2_elo, player1_score, player2_score):
k_factor = 32 k_factor = 32
expected1 = 1 / (1 + 10 ** ((player2_elo - player1_elo) / 400)) expected1 = 1 / (1 + 10 ** ((player2_elo - player1_elo) / 400))
@ -221,7 +213,7 @@ def calculate_elo(player1_elo, player2_elo, player1_score, player2_score):
return elo_change1, elo_change2 return elo_change1, elo_change2
@app.post("/endmatch") @app.post("/endmatch")
async def end_match(request: EndMatchRequest): def end_match(request: EndMatchRequest):
conn = get_db_connection() conn = get_db_connection()
cursor = conn.cursor() cursor = conn.cursor()
try: try:
@ -236,7 +228,7 @@ async def end_match(request: EndMatchRequest):
match = cursor.fetchone() match = cursor.fetchone()
if not match: if not match:
raise HTTPException(status_code=404, detail="Match not found") raise HTTPException(status_code=404, detail="Match not found")
player1_uid, player2_uid = match["player1_uid"], match["player2_uid"] player1_uid, player2_uid = match["player1_uid"], match["player2_uid"]
cursor.execute( cursor.execute(
@ -251,7 +243,9 @@ async def end_match(request: EndMatchRequest):
player1_elo = next(p["current_elo"] for p in players if p["uid"] == player1_uid) player1_elo = next(p["current_elo"] for p in players if p["uid"] == player1_uid)
player2_elo = next(p["current_elo"] for p in players if p["uid"] == player2_uid) player2_elo = next(p["current_elo"] for p in players if p["uid"] == player2_uid)
elo_change1, elo_change2 = calculate_elo(player1_elo, player2_elo, request.player1_score, request.player2_score) elo_change1, elo_change2 = calculate_elo(
player1_elo, player2_elo, request.player1_score, request.player2_score
)
cursor.execute( cursor.execute(
""" """
@ -262,28 +256,18 @@ async def end_match(request: EndMatchRequest):
""", """,
(request.player1_score, request.player2_score, elo_change1, elo_change2, request.match_id) (request.player1_score, request.player2_score, elo_change1, elo_change2, request.match_id)
) )
new_player1_elo = player1_elo + elo_change1
new_player1_elo = max(0, player1_elo + elo_change1) new_player2_elo = player2_elo + elo_change2
new_player2_elo = max(0, player2_elo + elo_change2)
cursor.execute( cursor.execute(
""" """
UPDATE users UPDATE users
SET current_elo = CASE SET current_elo = CASE WHEN uid = %s THEN %s WHEN uid = %s THEN %s END
WHEN uid = %s THEN %s
WHEN uid = %s THEN %s
END
WHERE uid IN (%s, %s); WHERE uid IN (%s, %s);
""", """,
(player1_uid, new_player1_elo, player2_uid, new_player2_elo, player1_uid, player2_uid) (player1_uid, new_player1_elo, player2_uid, new_player2_elo, player1_uid, player2_uid)
) )
conn.commit() conn.commit()
if request.match_id in active_connections:
connections = active_connections.pop(request.match_id, [])
for websocket in connections:
await websocket.close()
return {"message": "Match ended successfully"} return {"message": "Match ended successfully"}
except Exception as e: except Exception as e:
conn.rollback() conn.rollback()
@ -293,40 +277,6 @@ async def end_match(request: EndMatchRequest):
conn.close() conn.close()
@app.websocket("/ws/{match_id}")
async def websocket_endpoint(websocket: WebSocket, match_id: int):
await websocket.accept()
if match_id not in active_connections:
raise HTTPException(status_code=404, detail="Match not found")
active_connections[match_id].append(websocket)
try:
while True:
message = await websocket.receive_text()
data = json.loads(message)
if data["type"] == "score_update":
query = """
UPDATE matches
SET player1_score = :player1_score, player2_score = :player2_score
WHERE match_id = :match_id;
"""
await database.execute(query, {
"player1_score": data["player1_score"],
"player2_score": data["player2_score"],
"match_id": match_id
})
for connection in active_connections[match_id]:
if connection != websocket:
await connection.send_text(message)
except WebSocketDisconnect:
active_connections[match_id].remove(websocket)
if not active_connections[match_id]:
del active_connections[match_id]
@app.post("/getprofile") @app.post("/getprofile")
def get_profile(request: ProfileRequest): def get_profile(request: ProfileRequest):
conn = get_db_connection() conn = get_db_connection()
@ -462,4 +412,4 @@ def get_latest_commit_hashes():
return {"error": "Failed to fetch commit hashes from Forgejo"} return {"error": "Failed to fetch commit hashes from Forgejo"}
except Exception as e: except Exception as e:
return {"error": str(e)} return {"error": str(e)}