add: store pranks
This commit is contained in:
@ -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} сек.")
|
||||
|
Reference in New Issue
Block a user