110 lines
3.2 KiB
Python
110 lines
3.2 KiB
Python
"""
|
|
Statistics router.
|
|
Auto-generated from main.py migration.
|
|
"""
|
|
from fastapi import APIRouter, HTTPException, Depends, status
|
|
from fastapi.security import HTTPAuthorizationCredentials
|
|
from typing import Optional, Dict, Any
|
|
from datetime import datetime
|
|
import random
|
|
import json
|
|
import logging
|
|
|
|
from ..core.security import get_current_user, security, verify_internal_key
|
|
from ..services.models import *
|
|
from ..services.helpers import calculate_distance, calculate_stamina_cost, calculate_player_capacity
|
|
from .. import database as db
|
|
from ..items import ItemsManager
|
|
from .. import game_logic
|
|
from ..core.websockets import manager
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
# These will be injected by main.py
|
|
LOCATIONS = None
|
|
ITEMS_MANAGER = None
|
|
WORLD = None
|
|
|
|
def init_router_dependencies(locations, items_manager, world):
|
|
"""Initialize router with game data dependencies"""
|
|
global LOCATIONS, ITEMS_MANAGER, WORLD
|
|
LOCATIONS = locations
|
|
ITEMS_MANAGER = items_manager
|
|
WORLD = world
|
|
|
|
router = APIRouter(tags=["statistics"])
|
|
|
|
|
|
|
|
# Endpoints
|
|
|
|
@router.get("/api/statistics/online-players")
|
|
async def get_online_players():
|
|
"""Get the current number of connected players"""
|
|
from ..redis_manager import redis_manager
|
|
|
|
if not redis_manager:
|
|
return {"count": 0}
|
|
|
|
count = await redis_manager.get_connected_player_count()
|
|
return {"count": count}
|
|
|
|
|
|
@router.get("/api/statistics/me")
|
|
async def get_my_stats(current_user: dict = Depends(get_current_user)):
|
|
"""Get current user's statistics"""
|
|
stats = await db.get_player_statistics(current_user['id'])
|
|
return {"statistics": stats}
|
|
|
|
|
|
@router.get("/api/statistics/{player_id}")
|
|
async def get_player_stats(player_id: int):
|
|
"""Get character statistics by character ID (public)"""
|
|
stats = await db.get_player_statistics(player_id)
|
|
if not stats:
|
|
raise HTTPException(status_code=404, detail="Character statistics not found")
|
|
|
|
player = await db.get_player_by_id(player_id)
|
|
if not player:
|
|
raise HTTPException(status_code=404, detail="Character not found")
|
|
|
|
return {
|
|
"player": {
|
|
"id": player['id'],
|
|
"name": player['name'],
|
|
"level": player['level']
|
|
},
|
|
"statistics": stats
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@router.get("/api/leaderboard/{stat_name}")
|
|
async def get_leaderboard_by_stat(stat_name: str, limit: int = 100):
|
|
"""
|
|
Get leaderboard for a specific statistic.
|
|
Available stats: distance_walked, enemies_killed, damage_dealt, damage_taken,
|
|
hp_restored, stamina_used, items_collected, deaths, etc.
|
|
"""
|
|
valid_stats = [
|
|
"distance_walked", "enemies_killed", "damage_dealt", "damage_taken",
|
|
"hp_restored", "stamina_used", "stamina_restored", "items_collected",
|
|
"items_dropped", "items_used", "deaths", "successful_flees", "failed_flees",
|
|
"combats_initiated", "total_playtime"
|
|
]
|
|
|
|
if stat_name not in valid_stats:
|
|
raise HTTPException(
|
|
status_code=400,
|
|
detail=f"Invalid stat name. Valid stats: {', '.join(valid_stats)}"
|
|
)
|
|
|
|
leaderboard = await db.get_leaderboard(stat_name, limit)
|
|
return {
|
|
"stat_name": stat_name,
|
|
"leaderboard": leaderboard
|
|
}
|
|
|