"""Player endpoints — list current players for a running server.""" from __future__ import annotations import logging from typing import Annotated from fastapi import APIRouter, Depends from pydantic import BaseModel from sqlalchemy.engine import Connection from core.dal.player_repository import PlayerRepository from core.servers.service import ServerService from database import get_db from dependencies import get_current_user, require_admin logger = logging.getLogger(__name__) router = APIRouter(prefix="/servers/{server_id}/players", tags=["players"]) class KickRequest(BaseModel): reason: str = "Kicked by admin" class BanFromPlayerRequest(BaseModel): reason: str = "Banned by admin" duration_minutes: int | None = None def _ok(data): return {"success": True, "data": data, "error": None} @router.get("") def list_players( server_id: int, db: Annotated[Connection, Depends(get_db)], _user: Annotated[dict, Depends(get_current_user)], ) -> dict: """List current players (cached from RemoteAdminPollerThread).""" ServerService(db).get_server(server_id) # raises 404 if not found player_repo = PlayerRepository(db) players = player_repo.get_all(server_id=server_id) count = player_repo.count(server_id=server_id) return _ok({ "server_id": server_id, "player_count": count, "players": players, }) @router.get("/history") def player_history( server_id: int, db: Annotated[Connection, Depends(get_db)], _user: Annotated[dict, Depends(get_current_user)], limit: int = 100, offset: int = 0, search: str | None = None, ) -> dict: """Get historical player sessions.""" ServerService(db).get_server(server_id) # raises 404 if not found player_repo = PlayerRepository(db) total, rows = player_repo.get_history( server_id=server_id, limit=limit, offset=offset, search=search, ) return _ok({"total": total, "items": rows}) @router.post("/{slot_id}/kick") def kick_player( server_id: int, slot_id: int, body: KickRequest, db: Annotated[Connection, Depends(get_db)], _admin: Annotated[dict, Depends(require_admin)], ) -> dict: ServerService(db).kick_player(server_id, slot_id, body.reason) return _ok({"message": f"Player {slot_id} kicked"}) @router.post("/{slot_id}/ban") def ban_player_from_list( server_id: int, slot_id: int, body: BanFromPlayerRequest, db: Annotated[Connection, Depends(get_db)], admin: Annotated[dict, Depends(require_admin)], ) -> dict: ban = ServerService(db).ban_from_player( server_id, slot_id, body.reason, body.duration_minutes, banned_by=admin["username"], ) return _ok(ban)