from fastapi import HTTPException from datetime import datetime import json from app.services.coins import CoinsService from app.models.server.event import PlayerEvent, OnlinePlayersUpdate import uuid class EventService: def __init__(self): self.coins_service = CoinsService() async def process_event(self, event_data): """Обработка событий от сервера Minecraft""" try: # Проверяем формат ваших событий (event_type вместо type) event_type = event_data.get("event_type") if not event_type: # Для совместимости со старым форматом event_type = event_data.get("type") if not event_type: raise HTTPException(status_code=400, detail="Missing event type") server_ip = event_data.get("server_ip") if not server_ip: raise HTTPException(status_code=400, detail="Missing server IP") # Преобразуем ваши типы событий в нужные форматы if event_type == "online_players_update": # Регистрируем сервер, если его нет await self._register_server(server_ip, event_data) # Обновляем данные об онлайн игроках players = event_data.get("players", []) await self._update_online_players(server_ip, players) return {"status": "success"} elif event_type == "player_join": player_id = event_data.get("player_id") player_name = event_data.get("player_name") if not player_id or not player_name: raise HTTPException(status_code=400, detail="Missing player data") # Регистрируем вход игрока await self._register_player_login(server_ip, player_id, player_name) return {"status": "success"} elif event_type == "player_quit": player_id = event_data.get("player_id") player_name = event_data.get("player_name") if not player_id or not player_name: raise HTTPException(status_code=400, detail="Missing player data") # Регистрируем выход игрока await self._register_player_logout(server_ip, player_id, player_name) return {"status": "success"} elif event_type == "player_session": player_id = event_data.get("player_id") player_name = event_data.get("player_name") duration = event_data.get("duration", 0) if not player_id or not player_name: raise HTTPException(status_code=400, detail="Missing player data") # Обрабатываем информацию о сессии await self._process_player_session(server_ip, player_id, player_name, duration) return {"status": "success"} # Если тип события не распознан print(f"[{datetime.now()}] Неизвестное событие: {event_data}") raise HTTPException(status_code=400, detail="Invalid event type") except HTTPException as e: print(f"[{datetime.now()}] Ошибка обработки события: {e.status_code}: {e.detail}") print(f"Полученные данные: {event_data}") raise except Exception as e: print(f"[{datetime.now()}] Необработанная ошибка: {str(e)}") print(f"Полученные данные: {event_data}") raise HTTPException(status_code=500, detail=f"Server error: {str(e)}") async def _register_server(self, server_ip, event_data): """Регистрирует сервер, если его нет в базе""" from app.db.database import db import uuid game_servers_collection = db.game_servers # Проверяем, есть ли уже такой сервер existing_server = await game_servers_collection.find_one({"ip": server_ip}) if not existing_server: # Создаем новую запись сервера server_data = { "id": str(uuid.uuid4()), "name": f"Server {server_ip}", # Можно улучшить название "ip": server_ip, "port": 25565, # Стандартный порт Minecraft "description": f"Minecraft server {server_ip}", "max_players": 100, "registered_at": datetime.utcnow(), "last_activity": datetime.utcnow() # Добавляем поле last_activity } await game_servers_collection.insert_one(server_data) print(f"[{datetime.utcnow()}] Зарегистрирован новый сервер: {server_ip}") else: # Обновляем активность существующего сервера await game_servers_collection.update_one( {"ip": server_ip}, {"$set": {"last_activity": datetime.utcnow()}} ) return existing_server or await game_servers_collection.find_one({"ip": server_ip}) async def _update_online_players(self, server_ip, players_data): """Обновляет информацию об онлайн игроках""" from app.db.database import db online_players_collection = db.online_players game_servers_collection = db.game_servers # Получаем ID сервера server = await self._register_server(server_ip, {}) server_id = server["id"] # Обновляем время активности сервера await game_servers_collection.update_one( {"id": server_id}, {"$set": {"last_activity": datetime.utcnow()}} ) # Помечаем всех игроков как оффлайн на этом сервере await online_players_collection.update_many( {"server_id": server_id}, {"$set": {"is_online": False}} ) # Обновляем данные для каждого онлайн игрока now = datetime.utcnow() for player in players_data: player_id = player.get("player_id") player_name = player.get("player_name") online_time = player.get("online_time", 0) if not player_id or not player_name: continue # Проверяем, существует ли уже запись existing_player = await online_players_collection.find_one({ "uuid": player_id, "server_id": server_id }) if existing_player: # Обновляем существующую запись await online_players_collection.update_one( {"_id": existing_player["_id"]}, {"$set": { "username": player_name, "is_online": True, "last_seen": now, "online_duration": online_time }} ) else: # Создаем новую запись await online_players_collection.insert_one({ "uuid": player_id, "username": player_name, "server_id": server_id, "is_online": True, "login_time": now, "last_seen": now, "online_duration": online_time }) online_count = len(players_data) print(f"[{now}] Обновлена информация о {online_count} игроках на сервере {server_ip}") # Также обновляем информацию о коинах для каждого игрока if players_data: from app.services.coins import CoinsService coins_service = CoinsService() for player in players_data: player_id = player.get("player_id") player_name = player.get("player_name") online_time = player.get("online_time", 0) if player_id and player_name: await coins_service.update_player_coins(player_id, player_name, online_time, server_ip) async def _register_player_login(self, server_ip, player_id, player_name): """Регистрирует вход игрока на сервер""" from app.db.database import db online_players_collection = db.online_players server = await self._register_server(server_ip, {}) server_id = server["id"] now = datetime.utcnow() # Проверяем, есть ли уже запись для этого игрока existing_player = await online_players_collection.find_one({ "uuid": player_id, "server_id": server_id }) if existing_player: # Обновляем запись await online_players_collection.update_one( {"_id": existing_player["_id"]}, {"$set": { "username": player_name, "is_online": True, "login_time": now, "last_seen": now }} ) else: # Создаем новую запись await online_players_collection.insert_one({ "uuid": player_id, "username": player_name, "server_id": server_id, "is_online": True, "login_time": now, "last_seen": now, "online_duration": 0 }) print(f"[{now}] Игрок {player_name} зашел на сервер {server_ip}") async def _register_player_logout(self, server_ip, player_id, player_name): """Регистрирует выход игрока с сервера""" from app.db.database import db online_players_collection = db.online_players server = await self._register_server(server_ip, {}) server_id = server["id"] now = datetime.utcnow() # Ищем запись игрока player = await online_players_collection.find_one({ "uuid": player_id, "server_id": server_id }) if player: # Обновляем запись await online_players_collection.update_one( {"_id": player["_id"]}, {"$set": { "is_online": False, "last_seen": now }} ) print(f"[{now}] Игрок {player_name} вышел с сервера {server_ip}") async def _process_player_session(self, server_ip, player_id, player_name, duration): """Обрабатывает информацию о завершенной сессии игрока""" from app.db.database import db from app.services.coins import CoinsService server = await self._register_server(server_ip, {}) server_id = server["id"] # Обновляем статистику времени игры await db.player_sessions.insert_one({ "uuid": player_id, "username": player_name, "server_id": server_id, "server_ip": server_ip, "duration": duration, "session_end": datetime.utcnow() }) # Начисляем коины за время игры coins_service = CoinsService() await coins_service.update_player_coins(player_id, player_name, duration, server_ip) print(f"[{datetime.now()}] Сессия игрока {player_name} завершена, длительность: {duration} сек.")