PostgreSQL + async refactoring, WebSocket server, Redis caching, minified assets
This commit is contained in:
+77
-19
@@ -29,30 +29,29 @@ from pathlib import Path
|
||||
import json
|
||||
from pathlib import Path
|
||||
|
||||
from database import get_db, SessionLocal, User, InventoryItem, CaseOpening, Contract, Upgrade, UpgradeRPU, PromoCode
|
||||
from database import get_db, get_db_executor, get_async_db, AsyncSessionLocal, SessionLocal, 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 (
|
||||
seed_achievements, check_achievement,
|
||||
check_open_cases_achievements, check_contracts_achievements,
|
||||
check_upgrade_achievements, check_upgrade_risk_achievements, check_upgrade_result_achievements,
|
||||
check_rare_item_achievement, check_knife_achievement,
|
||||
check_spent_achievements,
|
||||
check_balance_achievements,
|
||||
check_slot_match_achievements, check_slot_plays_achievements,
|
||||
check_slot_match_count_achievements,
|
||||
check_inventory_achievements,
|
||||
check_dildo_achievements, check_dildo_contract_achievement,
|
||||
check_crash_achievements, check_crash_cashout_achievements,
|
||||
check_items_unboxed_achievements, check_total_profit_achievements,
|
||||
check_achievements_count_achievements,
|
||||
check_upgrade_achievements, check_upgrade_risk_achievements,
|
||||
check_upgrade_result_achievements, check_rare_item_achievement,
|
||||
check_knife_achievement, check_spent_achievements,
|
||||
check_balance_achievements, check_slot_match_achievements,
|
||||
check_slot_plays_achievements, check_slot_match_count_achievements,
|
||||
check_inventory_achievements, check_dildo_achievements,
|
||||
check_dildo_contract_achievement, check_crash_achievements,
|
||||
check_crash_cashout_achievements, check_items_unboxed_achievements,
|
||||
check_total_profit_achievements, check_achievements_count_achievements,
|
||||
check_rare_item_count_achievements, check_knife_count_achievements,
|
||||
check_midnight_case_achievement, check_exact_cases_achievement,
|
||||
check_collection_achievements,
|
||||
get_user_achievements
|
||||
check_collection_achievements, get_user_achievements
|
||||
)
|
||||
from auth import (
|
||||
create_user, authenticate_user, create_access_token,
|
||||
get_current_user, get_current_user_optional, get_password_hash,
|
||||
get_current_user_sync, get_current_user_optional_sync,
|
||||
ACCESS_TOKEN_EXPIRE_MINUTES, is_item_craftable
|
||||
)
|
||||
|
||||
@@ -70,9 +69,10 @@ from backend import (
|
||||
from upgrade import (
|
||||
get_upgrade_rpu, calculate_upgrade_probability,
|
||||
get_adjusted_upgrade_probability, spin_upgrade_wheel,
|
||||
update_upgrade_stats
|
||||
update_upgrade_stats,
|
||||
get_upgrade_rpu_async, get_adjusted_upgrade_probability_async,
|
||||
update_upgrade_stats_async
|
||||
)
|
||||
|
||||
from rpu import get_adjusted_weights, get_user_rpu, update_rpu_stats, RARITY_TO_FIELD
|
||||
|
||||
from auth import get_password_hash
|
||||
@@ -100,6 +100,40 @@ from backend import app as api_app
|
||||
# Монтируем оригинальное API на /api/simulator чтобы избежать конфликтов
|
||||
app.mount("/api/simulator", api_app)
|
||||
|
||||
# ─── Pagination helper ─────────────────────────────────────────────────────
|
||||
DEFAULT_PAGE_SIZE = 50
|
||||
|
||||
def paginate(query, page: int = 1, page_size: int = DEFAULT_PAGE_SIZE):
|
||||
offset = (page - 1) * page_size
|
||||
return query.offset(offset).limit(page_size)
|
||||
|
||||
def paginated_response(items, total: int, page: int, page_size: int = DEFAULT_PAGE_SIZE):
|
||||
return {
|
||||
"items": items,
|
||||
"total": total,
|
||||
"page": page,
|
||||
"page_size": page_size,
|
||||
"pages": max(1, (total + page_size - 1) // page_size),
|
||||
}
|
||||
|
||||
# ─── Rate Limiting ──────────────────────────────────────────────────────────
|
||||
from collections import defaultdict
|
||||
import time
|
||||
_rate_limit_store: dict = defaultdict(list)
|
||||
|
||||
RATE_LIMIT_WINDOW = 60 # seconds
|
||||
RATE_LIMIT_MAX_CASES = 30 # max case opens per window
|
||||
RATE_LIMIT_MAX_GENERAL = 120 # max general requests per window
|
||||
|
||||
async def rate_limit_check(user_id: int, action: str, max_req: int, window: int = RATE_LIMIT_WINDOW):
|
||||
key = f"{user_id}:{action}"
|
||||
now = time.time()
|
||||
_rate_limit_store[key] = [t for t in _rate_limit_store.get(key, []) if now - t < window]
|
||||
if len(_rate_limit_store[key]) >= max_req:
|
||||
return False
|
||||
_rate_limit_store[key].append(now)
|
||||
return True
|
||||
|
||||
# ─── Вспомогательные функции ───────────────────────────────────────────────
|
||||
|
||||
# Кэш dildo-предметов (создаётся один раз)
|
||||
@@ -243,9 +277,33 @@ def record_activity_own_session(user_id: int, username: str, activity_type: str,
|
||||
}
|
||||
|
||||
# Сидируем достижения при старте
|
||||
db_seed = next(get_db())
|
||||
seed_achievements(db_seed)
|
||||
db_seed.close()
|
||||
try:
|
||||
from database import init_sync_db
|
||||
init_sync_db()
|
||||
db_seed = next(get_db())
|
||||
from achievements import ACHIEVEMENT_DEFS
|
||||
from database import Achievement
|
||||
existing = db_seed.query(Achievement).count()
|
||||
if existing == 0:
|
||||
for defn in ACHIEVEMENT_DEFS:
|
||||
db_seed.add(Achievement(**defn))
|
||||
db_seed.commit()
|
||||
print(f"[Seed] Добавлено {len(ACHIEVEMENT_DEFS)} достижений")
|
||||
else:
|
||||
existing_names = {a.name for a in db_seed.query(Achievement.name).all()}
|
||||
added = 0
|
||||
for defn in ACHIEVEMENT_DEFS:
|
||||
if defn["name"] not in existing_names:
|
||||
db_seed.add(Achievement(**defn))
|
||||
added += 1
|
||||
if added:
|
||||
db_seed.commit()
|
||||
print(f"[Seed] Добавлено {added} новых достижений")
|
||||
db_seed.close()
|
||||
except Exception as e:
|
||||
print(f"[Seed] {e}")
|
||||
import traceback
|
||||
traceback.print_exc()
|
||||
|
||||
async def broadcast_online_count():
|
||||
"""Рассылает всем количество игроков онлайн"""
|
||||
|
||||
Reference in New Issue
Block a user