servii-backend/server_mc_manager.py

101 lines
3.6 KiB
Python
Raw Normal View History

2024-06-14 21:33:55 +00:00
import subprocess
import shlex
import time
import mcipc.query
import mcipc.query.client
2024-07-14 17:24:39 +00:00
from typing import Union
2024-06-14 21:33:55 +00:00
2024-06-20 16:57:04 +00:00
2024-06-14 21:33:55 +00:00
class MinecraftServerManager:
allowed_properties: list[str] = ["difficulty", "gamemode", "force-gamemode", "hardcore", "generate-structures",
"motd", "pvp", "online-mode", "max-players", "enable-command-block"]
2024-06-14 21:33:55 +00:00
def __init__(self):
self.servers: dict = {}
self.servers_count: int = 0
self.cooldowns = {}
2024-06-14 21:33:55 +00:00
def start_server(self, server_directory: str, port: int,
2024-07-14 17:24:39 +00:00
java_executable='java', jar_file='server.jar', memory_size='2048M') -> Union[int, None]:
if port in self.servers:
return None
2024-08-19 09:58:10 +00:00
reg_flags: str = ("-XX:+UseG1GC -XX:+ParallelRefProcEnabled -XX:MaxGCPauseMillis=200"
" -XX:+UnlockExperimentalVMOptions -XX:+DisableExplicitGC -XX:+AlwaysPreTouch"
" -XX:G1NewSizePercent=30 -XX:G1MaxNewSizePercent=40 -XX:G1HeapRegionSize=8M"
" -XX:G1ReservePercent=20 -XX:G1HeapWastePercent=5 -XX:G1MixedGCCountTarget=4"
" -XX:InitiatingHeapOccupancyPercent=15 -XX:G1MixedGCLiveThresholdPercent=90"
" -XX:G1RSetUpdatingPauseTimePercent=5 -XX:SurvivorRatio=32 -XX:+PerfDisableSharedMem"
" -XX:MaxTenuringThreshold=1 -Daikars.new.flags=true"
" -Dusing.aikars.flags=https://mcutils.com")
command = f"{java_executable} -Xmx{memory_size} {reg_flags} -jar {jar_file} --nogui"
2024-06-14 21:33:55 +00:00
process = subprocess.Popen(shlex.split(command), cwd=server_directory, stdin=subprocess.PIPE)
self.servers_count = len(self.servers) + 1
self.servers[port] = {
2024-06-14 21:33:55 +00:00
'process': process,
'directory': server_directory,
'port': port
2024-06-14 21:33:55 +00:00
}
return port
def execute_server_command(self, port, command) -> bool:
if port not in self.servers:
return False
process = self.servers[port]['process']
process.stdin.write(command.encode('utf-8') + b'\n')
process.stdin.flush()
return True
def stop_server(self, port: int) -> bool:
if port not in self.servers:
return False
process = self.servers[port]['process']
process.communicate(input=b"stop\n")
del self.servers[port]
return True
def stop_server_forcefully(self, port) -> bool:
if port not in self.servers:
return False
process = self.servers[port]['process']
process.terminate()
del self.servers[port]
return True
2024-06-14 21:33:55 +00:00
def get_servers(self):
return self.servers.values()
2024-06-20 16:57:04 +00:00
2024-06-14 21:33:55 +00:00
def get_server_id_by_port(self, port):
for server_id, server_info in self.servers.items():
if server_info['port'] == port:
return server_id
return None
2024-08-11 09:02:10 +00:00
def get_online_players(self, port) -> int:
with mcipc.query.Client('127.0.0.1', port) as client:
stats: mcipc.query.proto.FullStats = client.stats(full=True)
stats: int = stats.num_players
return stats
2024-06-14 21:33:55 +00:00
def set_cooldown(self, user_id):
expiry_timestamp = time.time() + 30
self.cooldowns[user_id] = expiry_timestamp
def has_cooldown(self, user_id):
expiry_timestamp = self.cooldowns.get(user_id)
if expiry_timestamp is None:
return False
current_time = time.time()
if current_time < expiry_timestamp:
return True
else:
del self.cooldowns[user_id]
return False
2024-08-11 09:02:10 +00:00
2024-06-14 21:33:55 +00:00
if __name__ == "__main__":
pass