[+] Idle servers are now automatically stopped.

This commit is contained in:
Charles Le Maux 2024-09-06 12:44:05 +02:00
parent afdb356220
commit bd568f6356
3 changed files with 63 additions and 5 deletions

View File

@ -1,3 +1,4 @@
import time
from datetime import datetime
from typing import Union
@ -7,6 +8,7 @@ from firebase_admin import auth, credentials, firestore
from google.api_core.exceptions import Aborted, DataLoss, NotFound, OutOfRange, PermissionDenied, ResourceExhausted
import file_manager
from generic_executor import mc_manager
cred = credentials.Certificate('secrets/servii.json')
app = firebase_admin.initialize_app(cred)
@ -185,5 +187,22 @@ def log_exception_to_firestore(exception: Exception = None, user_id: str = None,
print(f"Failed to add log entry: {e}")
def close_idle_server(user_id: Union[str, None], name: Union[str, None], port: int,
server_stamp: Union[float, None]) -> None:
if any(var is None for var in (user_id, name, server_stamp)):
return
try:
mc_manager.stop_server(port)
update_server_running_state(user_id, name, False)
now: float = time.time()
elapsed_seconds = now - server_stamp
hours = int(elapsed_seconds // 3600)
minutes = int((elapsed_seconds % 3600) // 60)
seconds = round(elapsed_seconds % 60, 2)
file_manager.log_action(user_id, name, "ServerStop (idle)",
f"Suspended inactive server activities. Uptime : {hours}h {minutes}m {seconds}s")
except Exception as e:
print(e, user_id, name, server_stamp)
if __name__ == "__main__":
pass

View File

@ -1,7 +1,6 @@
import json
import os
from http import HTTPStatus
from typing import Union, Tuple, Dict
from typing import Union
from cloudflare.types.dns import SRVRecord
from firebase_admin.auth import UserRecord
@ -218,7 +217,7 @@ def server_run(user: UserRecord, name: str) -> tuple[HTTPStatus, Union[str, None
mc_manager.set_cooldown(user_id=user_id)
try:
port: int = firebase_manager.get_server_port(user_id)
server_id = mc_manager.start_server(f"users/{user_id}/{name}", port)
server_id = mc_manager.start_server(f"users/{user_id}/{name}", port, user_id, name)
if server_id is None:
return HTTPStatus.OK, f"You cannot run multiples instances at this time."
mc_manager.servers[server_id]['port'] = int(port)
@ -302,5 +301,8 @@ def run_command(user: UserRecord, command: str, name: str) -> tuple[HTTPStatus,
return HTTPStatus.INTERNAL_SERVER_ERROR, f"Error executing command: {command} || {str(e)}"
def scheduled_actions() -> None:
mc_manager.check_servers_idle()
if __name__ == "__main__":
pass

View File

@ -5,6 +5,9 @@ import mcipc.query
import mcipc.query.client
from typing import Union
import firebase_manager
import generic_executor
class MinecraftServerManager:
allowed_properties: list[str] = ["difficulty", "gamemode", "force-gamemode", "hardcore", "generate-structures",
@ -14,8 +17,9 @@ class MinecraftServerManager:
self.servers: dict = {}
self.servers_count: int = 0
self.cooldowns = {}
self.offline_ports: list[int] = []
def start_server(self, server_directory: str, port: int,
def start_server(self, server_directory: str, port: int, user_id: str, server_name: str,
java_executable='java', jar_file='server.jar', memory_size='2048M') -> Union[int, None]:
if port in self.servers:
@ -38,7 +42,10 @@ class MinecraftServerManager:
self.servers[port] = {
'process': process,
'directory': server_directory,
'port': port
'port': port,
'user_id': user_id,
'name': server_name,
'time': time.time(),
}
return port
@ -56,6 +63,8 @@ class MinecraftServerManager:
process = self.servers[port]['process']
process.communicate(input=b"stop\n")
del self.servers[port]
if port in self.offline_ports:
self.offline_ports.remove(port)
return True
def stop_server_forcefully(self, port) -> bool:
@ -98,6 +107,34 @@ class MinecraftServerManager:
del self.cooldowns[user_id]
return False
def check_servers_idle(self) -> None:
servers: dict = self.servers.copy()
for port, server_info in servers.items():
online_players = self.get_online_players(port)
if online_players == 0:
if port not in self.offline_ports:
self.offline_ports.append(port)
else:
print(f"Closing {port} server.")
user_id = server_info.get("user_id", None)
name = server_info.get("name", None)
server_stamp = server_info.get("time", None)
print(f"{user_id}, {name}, {server_stamp}")
firebase_manager.close_idle_server(
user_id=user_id,
name=name,
server_stamp=server_stamp,
port=port,
)
else:
if port in self.offline_ports:
self.offline_ports.remove(port)
print(f"Offline_servers : {self.offline_ports}")
return
if __name__ == "__main__":
pass