diff --git a/frontend.py b/frontend.py index 4deeca9..715a06b 100644 --- a/frontend.py +++ b/frontend.py @@ -29,7 +29,7 @@ from pathlib import Path import json from pathlib import Path -from database import get_db, get_db_executor, get_async_db, AsyncSessionLocal, SessionLocal, User, InventoryItem, CaseOpening, Contract, Upgrade, UpgradeRPU, PromoCode +from database import get_db, get_db_executor, get_async_db, AsyncSessionLocal, SessionLocal, AsyncSession, User, InventoryItem, CaseOpening, Contract, Upgrade, UpgradeRPU, PromoCode from websocket_manager import manager, crash_game from sqlalchemy import select, func as sa_func, desc from achievements import ( @@ -890,7 +890,7 @@ def open_case_with_rpu(case_name: str, adjusted_weights: dict = None) -> dict: async def api_open_case( case_name: str = Form(...), count: int = Form(1), - db: Session = Depends(get_db), + db: AsyncSession = Depends(get_async_db), user: User = Depends(get_current_user) ): """Открытие кейса с проверкой баланса и учетом РПУ""" @@ -916,7 +916,7 @@ async def api_open_case( _rpu_mod._BATCH_MODE = True try: # Один раз считаем RPU на всю пачку (кэшируется внутри) - adjusted_weights = get_adjusted_weights(db, user.id) + adjusted_weights = await get_adjusted_weights(db, user.id) results = [] for _ in range(count): result = open_case_with_rpu(case_name, adjusted_weights) @@ -975,34 +975,35 @@ async def api_open_case( # Определяем был ли редкий дроп had_rare = any(r.get("rarity") in ("Covert", "Rare Special Item", "Extraordinary") for r in results) - update_rpu_stats(db, user.id, total_price, count, total_received, - rarity=results[0]["rarity"] if results else None, is_rare=had_rare) + await update_rpu_stats(db, user.id, total_price, count, total_received, + rarity=results[0]["rarity"] if results else None, is_rare=had_rare) # Проверка достижений unlocked_ach = [] - open_count = db.query(CaseOpening).filter(CaseOpening.user_id == user.id).count() - unlocked_ach += check_open_cases_achievements(db, user.id) - user_rpu = get_user_rpu(db, user.id) + open_count_result = await db.execute(select(sa_func.count(CaseOpening.id)).filter(CaseOpening.user_id == user.id)) + open_count = open_count_result.scalar() + unlocked_ach += await check_open_cases_achievements(db, user.id) + user_rpu = await get_user_rpu(db, user.id) total_spent = user_rpu.total_spent - unlocked_ach += check_spent_achievements(db, user.id, total_spent) + unlocked_ach += await check_spent_achievements(db, user.id, total_spent) for r in results: - unlocked_ach += check_rare_item_achievement(db, user.id, r.get("rarity", "")) + unlocked_ach += await check_rare_item_achievement(db, user.id, r.get("rarity", "")) item_data = get_item(r.get("id", 0)) if item_data: - unlocked_ach += check_knife_achievement(db, user.id, item_data) + unlocked_ach += await check_knife_achievement(db, user.id, item_data) - unlocked_ach += check_inventory_achievements(db, user.id) - unlocked_ach += check_dildo_achievements(db, user.id) - unlocked_ach += check_items_unboxed_achievements(db, user.id) - unlocked_ach += check_rare_item_count_achievements(db, user.id) - unlocked_ach += check_knife_count_achievements(db, user.id) - unlocked_ach += check_balance_achievements(db, user.id) - unlocked_ach += check_achievements_count_achievements(db, user.id) - unlocked_ach += check_midnight_case_achievement(db, user.id) - unlocked_ach += check_exact_cases_achievement(db, user.id, open_count) + unlocked_ach += await check_inventory_achievements(db, user.id) + unlocked_ach += await check_dildo_achievements(db, user.id) + unlocked_ach += await check_items_unboxed_achievements(db, user.id) + unlocked_ach += await check_rare_item_count_achievements(db, user.id) + unlocked_ach += await check_knife_count_achievements(db, user.id) + unlocked_ach += await check_balance_achievements(db, user.id) + unlocked_ach += await check_achievements_count_achievements(db, user.id) + unlocked_ach += await check_midnight_case_achievement(db, user.id) + unlocked_ach += await check_exact_cases_achievement(db, user.id, open_count) profit = user.balance + total_spent - unlocked_ach += check_total_profit_achievements(db, user.id, profit) + unlocked_ach += await check_total_profit_achievements(db, user.id, profit) # Запись активности — используем ту же db-сессию for r in results: @@ -1029,7 +1030,7 @@ async def api_open_case( _rpu_mod._batch_cache_clear() # Один большой commit вместо 40+ мелких - db.commit() + await db.commit() asyncio.ensure_future(manager.send_personal(user.id, {"type": "inventory_update"})) asyncio.ensure_future(manager.send_personal(user.id, {"type": "balance_update", "balance": user.balance})) @@ -1163,17 +1164,17 @@ async def api_promo_list( @app.get("/web/api/rpu-info") async def api_rpu_info( - db: Session = Depends(get_db), + db: AsyncSession = Depends(get_async_db), user: User = Depends(get_current_user) ): from rpu import get_rpu_v2_info - return get_rpu_v2_info(db, user.id) + return await get_rpu_v2_info(db, user.id) @app.post("/web/api/contracts/submit") async def api_submit_contract( inventory_ids: str = Form(...), - db: Session = Depends(get_db), + db: AsyncSession = Depends(get_async_db), user: User = Depends(get_current_user) ): try: @@ -1189,10 +1190,13 @@ async def api_submit_contract( all_knives = True for inv_id in ids: - inv_item = db.query(InventoryItem).filter( - InventoryItem.id == inv_id, - InventoryItem.user_id == user.id - ).first() + result = await db.execute( + select(InventoryItem).filter( + InventoryItem.id == inv_id, + InventoryItem.user_id == user.id + ) + ) + inv_item = result.scalar_one_or_none() if not inv_item: return JSONResponse(status_code=400, content={"error": f"Item {inv_id} not found"}) @@ -1221,8 +1225,8 @@ async def api_submit_contract( # Крафт дилдоков из ножей if all_knives and len(inventory_items) == 10: for inv_item in inventory_items: - db.delete(inv_item) - db.commit() + await db.delete(inv_item) + await db.commit() dildo_items = get_dildo_items() if not dildo_items: @@ -1285,7 +1289,7 @@ async def api_submit_contract( result.probability = 0.01 for inv_item in inventory_items: - db.delete(inv_item) + await db.delete(inv_item) received_item_data = get_item(result.received_item.id) @@ -1313,15 +1317,15 @@ async def api_submit_contract( ) db.add(contract) - db.commit() + await db.commit() - unlocked_ach = check_contracts_achievements(db, user.id) - unlocked_ach += check_inventory_achievements(db, user.id) - unlocked_ach += check_balance_achievements(db, user.id) - unlocked_ach += check_dildo_achievements(db, user.id) - unlocked_ach += check_dildo_contract_achievement(db, user.id) - unlocked_ach += check_collection_achievements(db, user.id) - unlocked_ach += check_achievements_count_achievements(db, user.id) + unlocked_ach = await check_contracts_achievements(db, user.id) + unlocked_ach += await check_inventory_achievements(db, user.id) + unlocked_ach += await check_balance_achievements(db, user.id) + unlocked_ach += await check_dildo_achievements(db, user.id) + unlocked_ach += await check_dildo_contract_achievement(db, user.id) + unlocked_ach += await check_collection_achievements(db, user.id) + unlocked_ach += await check_achievements_count_achievements(db, user.id) act = record_activity_own_session(user.id, user.username, "contract", f"🔄 выполнил(а) контракт и получил(а) {result.received_item.market_hash_name}", @@ -1352,14 +1356,17 @@ async def api_submit_contract( @app.get("/web/api/inventory/items") async def api_get_inventory( - db: Session = Depends(get_db), + db: AsyncSession = Depends(get_async_db), user: User = Depends(get_current_user) ): """Получение предметов инвентаря""" - items = db.query(InventoryItem).filter( - InventoryItem.user_id == user.id - ).order_by(desc(InventoryItem.obtained_at)).all() + result = await db.execute( + select(InventoryItem).filter( + InventoryItem.user_id == user.id + ).order_by(desc(InventoryItem.obtained_at)) + ) + items = result.scalars().all() result = [] for item in items: @@ -1409,19 +1416,25 @@ async def get_item_image( @app.get("/web/api/inventory/item-detail/{inventory_id}") async def api_item_detail( inventory_id: int, - db: Session = Depends(get_db), + db: AsyncSession = Depends(get_async_db), user: User = Depends(get_current_user) ): """Детальная информация о предмете с коллекцией""" - inv_item = db.query(InventoryItem).filter( - InventoryItem.id == inventory_id, - InventoryItem.user_id == user.id - ).first() + result = await db.execute( + select(InventoryItem).filter( + InventoryItem.id == inventory_id, + InventoryItem.user_id == user.id + ) + ) + inv_item = result.scalar_one_or_none() if not inv_item: # Also allow viewing if item exists (public profiles) - inv_item = db.query(InventoryItem).filter( - InventoryItem.id == inventory_id - ).first() + result = await db.execute( + select(InventoryItem).filter( + InventoryItem.id == inventory_id + ) + ) + inv_item = result.scalar_one_or_none() if not inv_item: return JSONResponse(status_code=404, content={"error": "Предмет не найден"}) @@ -1471,10 +1484,12 @@ async def api_item_detail( seen_base[base] = citem # Все предметы пользователя — для проверки владения - user_items = db.query(InventoryItem.item_id).filter( - InventoryItem.user_id == user.id - ).all() - user_item_ids = {iid for (iid,) in user_items} + user_items_result = await db.execute( + select(InventoryItem.item_id).filter( + InventoryItem.user_id == user.id + ) + ) + user_item_ids = {row[0] for row in user_items_result.all()} # Сортируем по редкости (низшая → высшая) sorted_bases = sorted(seen_base.values(), key=lambda x: RARITY_ORDER.get(x.get("rarity", "Unknown"), -1)) @@ -1707,7 +1722,7 @@ async def get_user_balance( @app.post("/web/api/cases/open/animated") async def api_open_case_animated( case_name: str = Form(...), - db: Session = Depends(get_db), + db: AsyncSession = Depends(get_async_db), user: User = Depends(get_current_user) ): """Открытие кейса с анимацией (возвращает результат)""" @@ -1720,7 +1735,7 @@ async def api_open_case_animated( "error": f"Недостаточно средств. Нужно {price_per_case:.2f} ₽, у вас {user.balance:.2f} ₽" }) - adjusted_weights = get_adjusted_weights(db, user.id) + adjusted_weights = await get_adjusted_weights(db, user.id) result = open_case_with_rpu(case_name, adjusted_weights) if not result: @@ -1761,29 +1776,29 @@ async def api_open_case_animated( user.balance -= price_per_case # Обновляем РПУ - from rpu import update_rpu_stats - update_rpu_stats(db, user.id, price_per_case, 1, - item_data.get("price_rub", 0), - rarity=item_data.get("rarity"), - is_rare=item_data.get("rarity") in ("Covert", "Rare Special Item", "Extraordinary")) + await update_rpu_stats(db, user.id, price_per_case, 1, + item_data.get("price_rub", 0), + rarity=item_data.get("rarity"), + is_rare=item_data.get("rarity") in ("Covert", "Rare Special Item", "Extraordinary")) - db.commit() + await db.commit() # Проверка достижений unlocked_ach = [] - unlocked_ach += check_open_cases_achievements(db, user.id) - unlocked_ach += check_spent_achievements(db, user.id, get_user_rpu(db, user.id).total_spent) - unlocked_ach += check_rare_item_achievement(db, user.id, item_data.get("rarity", "")) + unlocked_ach += await check_open_cases_achievements(db, user.id) + user_rpu = await get_user_rpu(db, user.id) + unlocked_ach += await check_spent_achievements(db, user.id, user_rpu.total_spent) + unlocked_ach += await check_rare_item_achievement(db, user.id, item_data.get("rarity", "")) item_full = get_item(result["id"]) if item_full: - unlocked_ach += check_knife_achievement(db, user.id, item_full) - unlocked_ach += check_inventory_achievements(db, user.id) - unlocked_ach += check_dildo_achievements(db, user.id) - unlocked_ach += check_items_unboxed_achievements(db, user.id) - unlocked_ach += check_rare_item_count_achievements(db, user.id) - unlocked_ach += check_knife_count_achievements(db, user.id) - unlocked_ach += check_balance_achievements(db, user.id) - unlocked_ach += check_achievements_count_achievements(db, user.id) + unlocked_ach += await check_knife_achievement(db, user.id, item_full) + unlocked_ach += await check_inventory_achievements(db, user.id) + unlocked_ach += await check_dildo_achievements(db, user.id) + unlocked_ach += await check_items_unboxed_achievements(db, user.id) + unlocked_ach += await check_rare_item_count_achievements(db, user.id) + unlocked_ach += await check_knife_count_achievements(db, user.id) + unlocked_ach += await check_balance_achievements(db, user.id) + unlocked_ach += await check_achievements_count_achievements(db, user.id) asyncio.ensure_future(manager.send_personal(user.id, {"type": "inventory_update"})) asyncio.ensure_future(manager.send_personal(user.id, {"type": "balance_update", "balance": user.balance})) @@ -2010,7 +2025,7 @@ def pick_slot_reel(grouped_items: list, adjusted_weights: dict, exclude_groups: async def api_open_slot_case( case_name: str = Form(...), free_spin: str = Form(""), - db: Session = Depends(get_db), + db: AsyncSession = Depends(get_async_db), user: User = Depends(get_current_user) ): """Слот-машина: 3 барабана, совпадение = приз""" @@ -2029,7 +2044,7 @@ async def api_open_slot_case( if not grouped_items or len(grouped_items) < 2: return JSONResponse(status_code=400, content={"error": "В кейсе недостаточно предметов"}) - adjusted_weights = get_adjusted_weights(db, user.id) + adjusted_weights = await get_adjusted_weights(db, user.id) # Буст для слотов: чаще выпадают активки SLOT_RARITY_BOOST = { @@ -2276,18 +2291,18 @@ async def api_open_slot_case( if not is_free: user.balance -= price_per_case - update_rpu_stats(db, user.id, price_per_case, 1) + await update_rpu_stats(db, user.id, price_per_case, 1) # Проверка достижений для слота unlocked_ach = [] if match: - unlocked_ach += check_slot_match_achievements(db, user.id) - unlocked_ach += check_slot_plays_achievements(db, user.id) - unlocked_ach += check_slot_match_count_achievements(db, user.id) - unlocked_ach += check_balance_achievements(db, user.id) - unlocked_ach += check_achievements_count_achievements(db, user.id) + unlocked_ach += await check_slot_match_achievements(db, user.id) + unlocked_ach += await check_slot_plays_achievements(db, user.id) + unlocked_ach += await check_slot_match_count_achievements(db, user.id) + unlocked_ach += await check_balance_achievements(db, user.id) + unlocked_ach += await check_achievements_count_achievements(db, user.id) - db.commit() + await db.commit() return JSONResponse({ "success": True, @@ -2309,7 +2324,7 @@ async def api_open_slot_case( async def api_open_multiple_cases( case_name: str = Form(...), count: int = Form(...), - db: Session = Depends(get_db), + db: AsyncSession = Depends(get_async_db), user: User = Depends(get_current_user) ): """Открытие нескольких кейсов с группировкой и РПУ""" @@ -2354,7 +2369,7 @@ async def api_open_multiple_cases( _rpu_mod._BATCH_MODE = True try: # Один раз считаем RPU на всю пачку (кэшируется внутри) - adjusted_weights = get_adjusted_weights(db, user.id) + adjusted_weights = await get_adjusted_weights(db, user.id) results = [] for _ in range(count): result = open_case_with_variants_rpu(case_name, adjusted_weights) @@ -2423,10 +2438,10 @@ async def api_open_multiple_cases( # Обновляем статистику РПУ total_received = sum(r.get("price", 0) for r in results) had_rare = any(r.get("rarity") in ("Covert", "Rare Special Item", "Extraordinary") for r in results) - update_rpu_stats(db, user.id, total_price, count, total_received, - rarity=results[0]["rarity"] if results else None, is_rare=had_rare) + await update_rpu_stats(db, user.id, total_price, count, total_received, + rarity=results[0]["rarity"] if results else None, is_rare=had_rare) - db.commit() + await db.commit() finally: _rpu_mod._BATCH_MODE = False _rpu_mod._batch_cache_clear() @@ -2454,21 +2469,22 @@ async def api_open_multiple_cases( # Проверка достижений unlocked_ach = [] - unlocked_ach += check_open_cases_achievements(db, user.id) - unlocked_ach += check_spent_achievements(db, user.id, get_user_rpu(db, user.id).total_spent) - unlocked_ach += check_inventory_achievements(db, user.id) - unlocked_ach += check_dildo_achievements(db, user.id) - unlocked_ach += check_items_unboxed_achievements(db, user.id) - unlocked_ach += check_rare_item_count_achievements(db, user.id) - unlocked_ach += check_knife_count_achievements(db, user.id) - unlocked_ach += check_balance_achievements(db, user.id) - unlocked_ach += check_achievements_count_achievements(db, user.id) + unlocked_ach += await check_open_cases_achievements(db, user.id) + user_rpu = await get_user_rpu(db, user.id) + unlocked_ach += await check_spent_achievements(db, user.id, user_rpu.total_spent) + unlocked_ach += await check_inventory_achievements(db, user.id) + unlocked_ach += await check_dildo_achievements(db, user.id) + unlocked_ach += await check_items_unboxed_achievements(db, user.id) + unlocked_ach += await check_rare_item_count_achievements(db, user.id) + unlocked_ach += await check_knife_count_achievements(db, user.id) + unlocked_ach += await check_balance_achievements(db, user.id) + unlocked_ach += await check_achievements_count_achievements(db, user.id) for r in results: - unlocked_ach += check_rare_item_achievement(db, user.id, r.get("rarity", "")) + unlocked_ach += await check_rare_item_achievement(db, user.id, r.get("rarity", "")) item_full = get_item(r.get("id", 0)) if item_full: - unlocked_ach += check_knife_achievement(db, user.id, item_full) + unlocked_ach += await check_knife_achievement(db, user.id, item_full) asyncio.ensure_future(manager.send_personal(user.id, {"type": "inventory_update"})) asyncio.ensure_future(manager.send_personal(user.id, {"type": "balance_update", "balance": user.balance})) @@ -2487,15 +2503,18 @@ async def api_open_multiple_cases( @app.post("/web/api/inventory/sell") async def api_sell_item( inventory_id: int = Form(...), - db: Session = Depends(get_db), + db: AsyncSession = Depends(get_async_db), user: User = Depends(get_current_user) ): """Продажа предмета из инвентаря""" - inv_item = db.query(InventoryItem).filter( - InventoryItem.id == inventory_id, - InventoryItem.user_id == user.id - ).first() + result = await db.execute( + select(InventoryItem).filter( + InventoryItem.id == inventory_id, + InventoryItem.user_id == user.id + ) + ) + inv_item = result.scalar_one_or_none() if not inv_item: return JSONResponse(status_code=400, content={"error": "Предмет не найден"}) @@ -2513,8 +2532,8 @@ async def api_sell_item( user.balance += price # Удаляем предмет - db.delete(inv_item) - db.commit() + await db.delete(inv_item) + await db.commit() asyncio.ensure_future(manager.send_personal(user.id, {"type": "inventory_update"})) asyncio.ensure_future(manager.send_personal(user.id, {"type": "balance_update", "balance": user.balance})) @@ -2531,7 +2550,7 @@ async def api_sell_item( @app.post("/web/api/inventory/sell/bulk") async def api_sell_bulk_items( inventory_ids: str = Form(...), - db: Session = Depends(get_db), + db: AsyncSession = Depends(get_async_db), user: User = Depends(get_current_user) ): """Массовая продажа предметов из инвентаря""" @@ -2545,10 +2564,13 @@ async def api_sell_bulk_items( return JSONResponse(status_code=400, content={"error": "Не выбрано ни одного предмета"}) # Получаем предметы - items_to_sell = db.query(InventoryItem).filter( - InventoryItem.id.in_(ids), - InventoryItem.user_id == user.id - ).all() + result = await db.execute( + select(InventoryItem).filter( + InventoryItem.id.in_(ids), + InventoryItem.user_id == user.id + ) + ) + items_to_sell = result.scalars().all() if not items_to_sell: return JSONResponse(status_code=400, content={"error": "Предметы не найдены"}) @@ -2569,11 +2591,11 @@ async def api_sell_bulk_items( sold_count += 1 # Удаляем предмет - db.delete(inv_item) + await db.delete(inv_item) # Начисляем деньги user.balance += total_received - db.commit() + await db.commit() asyncio.ensure_future(manager.send_personal(user.id, {"type": "inventory_update"})) asyncio.ensure_future(manager.send_personal(user.id, {"type": "balance_update", "balance": user.balance})) @@ -2764,13 +2786,16 @@ async def api_execute_upgrade( input_inventory_id: int = Form(...), target_item_id: int = Form(...), quick_mode: bool = Form(False), - db: Session = Depends(get_db), + db: AsyncSession = Depends(get_async_db), user: User = Depends(get_current_user) ): - input_item = db.query(InventoryItem).filter( - InventoryItem.id == input_inventory_id, - InventoryItem.user_id == user.id - ).first() + result = await db.execute( + select(InventoryItem).filter( + InventoryItem.id == input_inventory_id, + InventoryItem.user_id == user.id + ) + ) + input_item = result.scalar_one_or_none() if not input_item: return JSONResponse(status_code=400, content={"error": "Предмет не найден"}) @@ -2790,7 +2815,7 @@ async def api_execute_upgrade( }) base_probability = calculate_upgrade_probability(input_price, target_price) - adjusted_probability = get_adjusted_upgrade_probability(db, user.id, base_probability) + adjusted_probability = await get_adjusted_upgrade_probability_async(db, user.id, base_probability) # Бан: колесо падает аккурат на 1-15° после зелёной зоны (как будто был шанс) if user.is_banned: @@ -2808,7 +2833,7 @@ async def api_execute_upgrade( # Сохраняем поля до удаления saved_input_name = input_item.market_hash_name saved_input_item_id = input_item.item_id - db.delete(input_item) + await db.delete(input_item) if success: item_float = target_data.get("mid_float_used") or generate_item_float(target_data.get("rarity", "Unknown")) @@ -2845,16 +2870,16 @@ async def api_execute_upgrade( import rpu as _rpu_mod _rpu_mod._BATCH_MODE = True try: - update_upgrade_stats(db, user.id, success, input_price) + await update_upgrade_stats_async(db, user.id, success, input_price) - unlocked_ach = check_upgrade_achievements(db, user.id) - unlocked_ach += check_upgrade_risk_achievements(db, user.id, input_price) - unlocked_ach += check_upgrade_result_achievements(db, user.id, success, base_probability, input_price) - unlocked_ach += check_inventory_achievements(db, user.id) - unlocked_ach += check_dildo_achievements(db, user.id) - unlocked_ach += check_balance_achievements(db, user.id) - unlocked_ach += check_collection_achievements(db, user.id) - unlocked_ach += check_achievements_count_achievements(db, user.id) + unlocked_ach = await check_upgrade_achievements(db, user.id) + unlocked_ach += await check_upgrade_risk_achievements(db, user.id, input_price) + unlocked_ach += await check_upgrade_result_achievements(db, user.id, success, base_probability, input_price) + unlocked_ach += await check_inventory_achievements(db, user.id) + unlocked_ach += await check_dildo_achievements(db, user.id) + unlocked_ach += await check_balance_achievements(db, user.id) + unlocked_ach += await check_collection_achievements(db, user.id) + unlocked_ach += await check_achievements_count_achievements(db, user.id) if success: prob_pct = round(base_probability, 1) if base_probability > 0 else 0 @@ -2877,7 +2902,7 @@ async def api_execute_upgrade( finally: _rpu_mod._BATCH_MODE = False - db.commit() + await db.commit() asyncio.ensure_future(manager.send_personal(user.id, {"type": "inventory_update"})) asyncio.ensure_future(manager.send_personal(user.id, {"type": "balance_update", "balance": user.balance})) @@ -3087,7 +3112,7 @@ async def crash_page( @app.post("/web/api/crash/bet") async def api_crash_bet( amount: float = Form(...), - db: Session = Depends(get_db), + db: AsyncSession = Depends(get_async_db), user: User = Depends(get_current_user) ): g = crash_game @@ -3103,14 +3128,17 @@ async def api_crash_bet( # Проверка достижений from database import ActivityFeed as CrActivity - crash_count = db.query(CrActivity).filter( - CrActivity.user_id == user.id, - CrActivity.activity_type == "crash" - ).count() + 1 - unlocked_ach = check_crash_achievements(db, user.id, crash_count) - unlocked_ach += check_balance_achievements(db, user.id) - unlocked_ach += check_achievements_count_achievements(db, user.id) - db.commit() + crash_count_result = await db.execute( + select(sa_func.count(CrActivity.id)).filter( + CrActivity.user_id == user.id, + CrActivity.activity_type == "crash" + ) + ) + crash_count = crash_count_result.scalar() + 1 + unlocked_ach = await check_crash_achievements(db, user.id, crash_count) + unlocked_ach += await check_balance_achievements(db, user.id) + unlocked_ach += await check_achievements_count_achievements(db, user.id) + await db.commit() asyncio.ensure_future(manager.send_personal(user.id, {"type": "balance_update", "balance": user.balance})) @@ -3124,7 +3152,7 @@ async def api_crash_bet( @app.post("/web/api/crash/cashout") async def api_crash_cashout( - db: Session = Depends(get_db), + db: AsyncSession = Depends(get_async_db), user: User = Depends(get_current_user) ): g = crash_game @@ -3142,11 +3170,11 @@ async def api_crash_cashout( user.balance += payout # Проверка достижений - unlocked_ach = check_crash_cashout_achievements(db, user.id, g.current_multiplier) - unlocked_ach += check_balance_achievements(db, user.id) - unlocked_ach += check_achievements_count_achievements(db, user.id) + unlocked_ach = await check_crash_cashout_achievements(db, user.id, g.current_multiplier) + unlocked_ach += await check_balance_achievements(db, user.id) + unlocked_ach += await check_achievements_count_achievements(db, user.id) - db.commit() + await db.commit() asyncio.ensure_future(manager.send_personal(user.id, {"type": "balance_update", "balance": user.balance}))