Files
fairhopper/hopper/watchdog.py
2023-03-30 21:13:54 +02:00

71 lines
2.1 KiB
Python

import asyncio
import datetime
import logging
import time
from threading import Thread
from typing import Optional
from hopper.interfaces import SendGameDumpInterface
from hopper.models.player import PlayerList
from settings import settings
class InactivityWatchdog(Thread):
def __init__(
self, players: PlayerList, ws_server: Optional[SendGameDumpInterface] = None
) -> None:
self.players = players
self.ws_server = ws_server
self.stopped = False
super().__init__(daemon=True)
def run(self) -> None:
logging.info("Starting inactivity watchdog")
while not self.stopped:
self.cleanup_players()
time.sleep(settings.inacivity_watchdog.TICK_INTERVAL)
def cleanup_players(self) -> None:
now = datetime.datetime.now()
inactivity_threshold = now - datetime.timedelta(
seconds=settings.inacivity_watchdog.INACIVITY_TIMEOUT
)
kick_threshold = now - datetime.timedelta(
seconds=settings.inacivity_watchdog.KICK_TIMEOUT
)
send_game_dump = False
for player in self.players:
if (
player.can_be_deactivated
and player.active
and player.last_seen < inactivity_threshold
):
player.active = False
logging.info(f"Player {player} set as inactive")
send_game_dump = True
# safe remove from list
n = 0
while n < len(self.players):
player = self.players[n]
if player.can_be_deactivated and player.last_seen < kick_threshold:
self.players.pop(n)
logging.info(f"Player {player} kicked out")
send_game_dump = True
else:
n += 1
if send_game_dump:
self.send_game_dump()
def send_game_dump(self):
if not self.ws_server:
return
logging.info("Sending WS game dump")
asyncio.run(self.ws_server.send_game_dump())
def stop(self) -> None:
self.stopped = True