from time import sleep from typing import Callable from classes import ProcessStatus from config import Config from controllers import Controllers from fastapi import HTTPException from logs import logger def stop_server( action: str, countdown: int, reason: str, timeout: int, then: Callable | None = None, *args, **kwargs, ): """Warns the players, stops the Server, and kills its process if its taking too long. Parameters: action (str): Action to write in the warning ("SERVER IS {action}..."). countdown (int): Seconds to wait after the warning. reason: (str): The reason for the Server shutdown. timeout (int): Seconds to wait before killing the process. then (Callable | None) (default: None): Function to be called after the Server is stopped. """ logger.debug( 'stop_server(action="%s", countdown=%s, reason="%s", timeout=%s, then=%s, args=%s, kwargs=%s', action, countdown, reason, timeout, then, args, kwargs, ) if countdown: logger.debug("stop_server(...) - Starting countdown") Controllers.server.command(f"say SERVER IS {action} IN {countdown} SECONDS!!!") Controllers.server.command(f"say REASON: '{reason}'") while countdown > 0 and Controllers.server.status().get("players", {}).get( "online", 0 ): sleep(1) countdown -= 1 logger.info("stop_server(...) - Stopping server") Controllers.server.command("stop") while timeout > 0 and Controllers.process.status() == ProcessStatus.RUNNING: sleep(1) timeout -= 1 if Controllers.process.status() == ProcessStatus.RUNNING: logger.warning("stop_server(...) - Killing server") Controllers.process.kill() if then: logger.debug("stop_server(...) - Running callback") then(*args, **kwargs) def check_password(password: str): if password != Config.MINECRAFTD_PASSWORD: logger.debug('check_password("%s") - Password is invalid', password) raise HTTPException(401, "Password is invalid")