add: store pranks

This commit is contained in:
2025-07-18 18:05:45 +05:00
parent d52d4dbf75
commit 7e4e2c0bad
7 changed files with 623 additions and 51 deletions

View File

@ -3,68 +3,274 @@ 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: dict):
async def process_event(self, event_data):
"""Обработка событий от сервера Minecraft"""
try:
# Проверяем формат ваших событий (event_type вместо type)
event_type = event_data.get("event_type")
server_ip = event_data.get("server_ip", "unknown")
if not event_type:
# Для совместимости со старым форматом
event_type = event_data.get("type")
if not event_type:
raise HTTPException(status_code=400, detail="Missing event type")
if event_type == "player_join":
player_name = event_data["player_name"]
player_id = event_data["player_id"]
print(f"[{datetime.now()}] Игрок вошел: {player_name} (ID: {player_id}) "
f"IP сервера: {server_ip}")
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_name = event_data["player_name"]
player_id = event_data["player_id"]
print(f"[{datetime.now()}] Игрок вышел: {player_name} (ID: {player_id}) "
f"IP сервера: {server_ip}")
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_name = event_data["player_name"]
player_id = event_data["player_id"]
duration = event_data["duration"]
player_id = event_data.get("player_id")
player_name = event_data.get("player_name")
duration = event_data.get("duration", 0)
# Обновляем монеты через выделенный сервис
await self.coins_service.update_player_coins(player_id, player_name, duration, server_ip)
print(f"[{datetime.now()}] Игрок {player_name} провел на сервере: {duration} секунд "
f"IP сервера: {server_ip}")
elif event_type == "online_players_update":
players = event_data["players"]
print(f"\n[{datetime.now()}] Текущие онлайн-игроки ({len(players)}): "
f"IP сервера: {server_ip}")
# Обрабатываем каждого игрока
for player in players:
player_id = player["player_id"]
player_name = player["player_name"]
online_time = player["online_time"]
if not player_id or not player_name:
raise HTTPException(status_code=400, detail="Missing player data")
# Обновляем монеты через выделенный сервис
await self.coins_service.update_player_coins(
player_id, player_name, online_time, server_ip
)
hours, remainder = divmod(online_time, 3600)
minutes, seconds = divmod(remainder, 60)
print(f" - {player_name} (ID: {player_id}) "
f"Онлайн: {hours}ч {minutes}м {seconds}с")
print()
else:
print(f"[{datetime.now()}] Неизвестное событие: {json.dumps(event_data, indent=2)}")
raise HTTPException(status_code=400, detail="Invalid event type")
return {"status": "success", "message": "Event processed"}
# Обрабатываем информацию о сессии
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"Полученные данные: {json.dumps(event_data, indent=2)}")
raise HTTPException(status_code=400, detail=str(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()
}
await game_servers_collection.insert_one(server_data)
print(f"[{datetime.utcnow()}] Зарегистрирован новый сервер: {server_ip}")
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
# Получаем ID сервера
server = await self._register_server(server_ip, {})
server_id = server["id"]
# Помечаем всех игроков как оффлайн на этом сервере
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} сек.")