Files
popa_minecraft_launcher_api/app/services/coins.py

143 lines
6.1 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

from datetime import datetime
from app.db.database import users_collection, sessions_collection
from fastapi import HTTPException
class CoinsService:
async def update_player_coins(self, player_id: str, player_name: str, online_time: int, server_ip: str):
"""Обновляет монеты игрока на основе времени онлайн"""
# Находим пользователя
user = await self._find_user_by_uuid(player_id)
if not user:
return # Пользователь не найден
# Находим последнее обновление монет
last_update = await sessions_collection.find_one({
"player_id": player_id,
"server_ip": server_ip,
"update_type": "coins_update"
}, sort=[("timestamp", -1)])
now = datetime.now()
current_coins = user.get("coins", 0)
current_total_time = user.get("total_time_played", 0)
if last_update:
# Время с последнего начисления
last_timestamp = last_update["timestamp"]
seconds_since_update = int((now - last_timestamp).total_seconds())
# Начисляем монеты только за полные минуты
minutes_to_reward = seconds_since_update // 60
# Если прошло меньше минуты, пропускаем
if minutes_to_reward < 1:
return
else:
# Первое обновление (ограничиваем для безопасности)
minutes_to_reward = min(online_time // 60, 5)
if minutes_to_reward > 0:
# Обновляем монеты и время
new_coins = current_coins + minutes_to_reward
new_total_time = current_total_time + (minutes_to_reward * 60)
# Сохраняем в БД
await users_collection.update_one(
{"_id": user["_id"]},
{"$set": {
"coins": new_coins,
"total_time_played": new_total_time
}}
)
# Сохраняем запись о начислении
await sessions_collection.insert_one({
"player_id": player_id,
"player_name": player_name,
"server_ip": server_ip,
"update_type": "coins_update",
"timestamp": now,
"minutes_added": minutes_to_reward,
"coins_added": minutes_to_reward
})
print(f"[{now}] Игроку {user.get('username')} начислено {minutes_to_reward} монет. "
f"Всего монет: {new_coins}")
async def _find_user_by_uuid(self, player_id: str):
"""Находит пользователя по UUID с поддержкой разных форматов"""
# Пробуем найти как есть
user = await users_collection.find_one({"uuid": player_id})
if user:
return user
# Пробуем разные форматы UUID
if '-' in player_id:
user = await users_collection.find_one({"uuid": player_id.replace('-', '')})
else:
formatted_uuid = f"{player_id[:8]}-{player_id[8:12]}-{player_id[12:16]}-{player_id[16:20]}-{player_id[20:]}"
user = await users_collection.find_one({"uuid": formatted_uuid})
return user
async def get_player_coins(self, username: str):
"""Возвращает информацию о монетах и времени игрока"""
user = await users_collection.find_one({"username": username})
if not user:
return None
total_time = user.get("total_time_played", 0)
hours, remainder = divmod(total_time, 3600)
minutes, seconds = divmod(remainder, 60)
return {
"username": username,
"coins": user.get("coins", 0),
"total_time_played": {
"seconds": total_time,
"formatted": f"{hours}ч {minutes}м {seconds}с"
}
}
async def get_balance(self, username: str) -> int:
"""Получить текущий баланс пользователя"""
user = await users_collection.find_one({"username": username})
if not user:
raise HTTPException(status_code=404, detail=f"Пользователь {username} не найден")
return user.get("coins", 0)
async def increase_balance(self, username: str, amount: int) -> int:
"""Увеличить баланс пользователя"""
if amount <= 0:
raise ValueError("Сумма должна быть положительной")
result = await users_collection.update_one(
{"username": username},
{"$inc": {"coins": amount}}
)
if result.modified_count == 0:
raise HTTPException(status_code=404, detail=f"Пользователь {username} не найден")
user = await users_collection.find_one({"username": username})
return user.get("coins", 0)
async def decrease_balance(self, username: str, amount: int) -> int:
"""Уменьшить баланс пользователя"""
if amount <= 0:
raise ValueError("Сумма должна быть положительной")
result = await users_collection.update_one(
{"username": username},
{"$inc": {"coins": -amount}} # Уменьшаем на отрицательное значение
)
if result.modified_count == 0:
raise HTTPException(status_code=404, detail=f"Пользователь {username} не найден")
user = await users_collection.find_one({"username": username})
return user.get("coins", 0)