103 lines
4.3 KiB
Python
103 lines
4.3 KiB
Python
from datetime import datetime
|
||
from app.db.database import users_collection, sessions_collection
|
||
|
||
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}с"
|
||
}
|
||
}
|