This commit is contained in:
2026-03-19 22:34:02 +01:00
parent d1a39620a7
commit fa05447895
18 changed files with 796 additions and 369 deletions

View File

@@ -149,7 +149,7 @@ async def open_pack(request: Request, user: UserModel = Depends(get_current_user
cards = (
db.query(CardModel)
.filter(CardModel.user_id == None)
.filter(CardModel.user_id == None, CardModel.ai_used == False)
.limit(5)
.all()
)
@@ -191,6 +191,7 @@ def get_decks(user: UserModel = Depends(get_current_user), db: Session = Depends
"id": str(deck.id),
"name": deck.name,
"card_count": len(cards),
"total_cost": sum(card.cost for card in cards),
"times_played": deck.times_played,
"wins": deck.wins,
"losses": deck.losses,
@@ -215,7 +216,7 @@ def update_deck(deck_id: str, body: dict, user: UserModel = Depends(get_current_
deck.name = body["name"]
if "card_ids" in body:
db.query(DeckCardModel).filter(DeckCardModel.deck_id == deck.id).delete()
for card_id in body["card_ids"][:20]:
for card_id in body["card_ids"]:
db.add(DeckCardModel(deck_id=deck.id, card_id=uuid.UUID(card_id)))
if deck.times_played > 0:
deck.wins = 0
@@ -265,9 +266,10 @@ async def queue_endpoint(websocket: WebSocket, deck_id: str, db: Session = Depen
await websocket.close(code=1008)
return
card_count = db.query(DeckCardModel).filter(DeckCardModel.deck_id == deck.id).count()
if card_count < 20:
await websocket.send_json({"type": "error", "message": "Deck must have 20 cards"})
card_ids = [dc.card_id for dc in db.query(DeckCardModel).filter(DeckCardModel.deck_id == deck.id).all()]
total_cost = db.query(func.sum(CardModel.cost)).filter(CardModel.id.in_(card_ids)).scalar() or 0
if total_cost == 0 or total_cost > 50:
await websocket.send_json({"type": "error", "message": "Deck total cost must be between 1 and 50"})
await websocket.close(code=1008)
return
@@ -318,7 +320,7 @@ async def game_endpoint(websocket: WebSocket, game_id: str, db: Session = Depend
except WebSocketDisconnect:
if game_id in connections:
connections[game_id].pop(user_id, None)
asyncio.create_task(handle_disconnect(game_id, user_id, db))
asyncio.create_task(handle_disconnect(game_id, user_id))
@app.get("/profile")
def get_profile(user: UserModel = Depends(get_current_user), db: Session = Depends(get_db)):
@@ -441,28 +443,27 @@ async def start_solo_game(deck_id: str, difficulty: int = 5, user: UserModel = D
if not deck:
raise HTTPException(status_code=404, detail="Deck not found")
card_count = db.query(DeckCardModel).filter(DeckCardModel.deck_id == deck.id).count()
if card_count < 20:
raise HTTPException(status_code=400, detail="Deck must have 20 cards")
card_ids = [dc.card_id for dc in db.query(DeckCardModel).filter(DeckCardModel.deck_id == deck.id).all()]
total_cost = db.query(func.sum(CardModel.cost)).filter(CardModel.id.in_(card_ids)).scalar() or 0
if total_cost == 0 or total_cost > 50:
raise HTTPException(status_code=400, detail="Deck total cost must be between 1 and 50")
player_cards = load_deck_cards(deck_id, str(user.id), db)
if player_cards is None:
raise HTTPException(status_code=503, detail="Couldn't load deck")
ai_cards = db.query(CardModel).filter(
CardModel.user_id == None
).order_by(func.random()).limit(100).all()
CardModel.user_id == None,
).order_by(func.random()).limit(500).all()
if len(ai_cards) < 20:
if len(ai_cards) == 0:
raise HTTPException(status_code=503, detail="Not enough cards in pool for AI deck")
for card in ai_cards:
db.delete(card)
card.ai_used = True
db.commit()
game_id = create_solo_game(str(user.id), user.username, player_cards, ai_cards, deck_id, difficulty)
asyncio.create_task(fill_card_pool())
return {"game_id": game_id}
@@ -488,7 +489,7 @@ def reset_password(req: ResetPasswordRequest, user: UserModel = Depends(get_curr
@app.post("/auth/forgot-password")
def forgot_password(req: ForgotPasswordRequest, db: Session = Depends(get_db)):
user = db.query(UserModel).filter(UserModel.email == req.email).first()
# Always return success even if email not found — prevents user enumeration
# Always return success even if email not found. Prevents user enumeration
if user:
token = secrets.token_urlsafe(32)
user.reset_token = token