[+] Idle servers are now automatically stopped.

[~] Reverted testing id
[~] Tested classical python errors
[+] Added task scheduler
[+] Updated requirements.txt
This commit is contained in:
charleslemaux 2024-09-06 12:47:57 +02:00 committed by GitHub
commit a9512014e8
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 76 additions and 7 deletions

View File

@ -51,7 +51,7 @@ document.addEventListener('DOMContentLoaded', () => {
buttons.forEach(button => {
button.addEventListener('click', async event => {
const action = button.dataset.action;
const token = "kPbH7QbrOzTrNcpqTnZGDJfSj3E3";
const token = "MpkbDMOO8PQddQgB5VgBQdTMWF53";
const framework = document.getElementById('serverFramework').value;
const subdomain = document.getElementById('subdomain').value;
const email = document.getElementById('accountEmail').value;

4
app.py
View File

@ -1,6 +1,7 @@
import http
import inspect
from typing import Union
from apscheduler.schedulers.background import BackgroundScheduler
from flask import (Blueprint, Flask, Response, jsonify, request)
from flask_cors import CORS
@ -125,4 +126,7 @@ app.register_blueprint(apiBP)
if __name__ == '__main__':
atexit.register(exit_safety)
scheduler = BackgroundScheduler()
scheduler.add_job(generic_executor.scheduled_actions, 'interval', minutes=1)
scheduler.start()
app.run(host='0.0.0.0', port=3000, debug=False)

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

@ -9,4 +9,5 @@ Flask-Cors~=4.0.1
mcipc~=2.4.2
firebase-admin~=6.5.0
protobuf~=4.25.3
typing_extensions~=4.9.0
typing_extensions~=4.9.0
APScheduler~=3.10.4

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

View File

@ -1,3 +1,6 @@
import time
from os import remove
import file_manager
import firebase_manager
@ -14,4 +17,7 @@ if __name__ == '__main__':
#ban_user("MpkbDMOO8PQddQgB5VgBQdTMWF53")
#file_manager.log_action("gqZN3eCHF3V2er3Py3rlgk8u2t83", "test", "DeleteServer")
#firebase_manager.set_servers_not_running()
test: list[int] = [0, 987]
test.remove(85)
print(test)
pass