2024-06-14 21:33:55 +00:00
|
|
|
import subprocess
|
|
|
|
import shlex
|
2024-07-11 15:02:21 +00:00
|
|
|
import time
|
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:
|
2024-07-08 20:05:07 +00:00
|
|
|
allowed_properties: list[str] = ["difficulty", "gamemode", "force-gamemode", "hardcore", "generate-structures",
|
2024-07-09 17:40:37 +00:00
|
|
|
"motd", "pvp", "online-mode", "max-players", "enable-command-block"]
|
2024-07-08 20:05:07 +00:00
|
|
|
|
2024-06-14 21:33:55 +00:00
|
|
|
def __init__(self):
|
2024-06-25 04:55:49 +00:00
|
|
|
self.servers: dict = {}
|
|
|
|
self.servers_count: int = 0
|
2024-07-11 15:02:21 +00:00
|
|
|
self.cooldowns = {}
|
2024-06-14 21:33:55 +00:00
|
|
|
|
2024-06-25 04:55:49 +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]:
|
2024-06-25 20:46:03 +00:00
|
|
|
|
|
|
|
if port in self.servers:
|
|
|
|
return None
|
|
|
|
|
2024-07-11 15:12:16 +00:00
|
|
|
command = f"{java_executable} -Xmx{memory_size} -Xms{memory_size} -jar {jar_file} --nogui > /dev/null"
|
2024-06-14 21:33:55 +00:00
|
|
|
process = subprocess.Popen(shlex.split(command), cwd=server_directory, stdin=subprocess.PIPE)
|
|
|
|
|
2024-06-25 04:55:49 +00:00
|
|
|
self.servers_count = len(self.servers) + 1
|
|
|
|
self.servers[port] = {
|
2024-06-14 21:33:55 +00:00
|
|
|
'process': process,
|
|
|
|
'directory': server_directory,
|
2024-06-25 04:55:49 +00:00
|
|
|
'port': port
|
2024-06-14 21:33:55 +00:00
|
|
|
}
|
2024-06-25 04:55:49 +00:00
|
|
|
return port
|
|
|
|
|
2024-06-25 20:46:03 +00:00
|
|
|
def execute_server_command(self, port, command) -> bool:
|
|
|
|
if port not in self.servers:
|
2024-06-25 04:55:49 +00:00
|
|
|
return False
|
2024-06-25 20:46:03 +00:00
|
|
|
process = self.servers[port]['process']
|
2024-06-25 04:55:49 +00:00
|
|
|
process.stdin.write(command.encode('utf-8') + b'\n')
|
|
|
|
process.stdin.flush()
|
|
|
|
return True
|
|
|
|
|
2024-06-25 20:46:03 +00:00
|
|
|
def stop_server(self, port: int) -> bool:
|
|
|
|
if port not in self.servers:
|
2024-06-25 04:55:49 +00:00
|
|
|
return False
|
2024-06-25 20:46:03 +00:00
|
|
|
process = self.servers[port]['process']
|
2024-06-25 04:55:49 +00:00
|
|
|
process.communicate(input=b"stop\n")
|
2024-06-25 20:46:03 +00:00
|
|
|
del self.servers[port]
|
2024-06-25 04:55:49 +00:00
|
|
|
return True
|
|
|
|
|
2024-07-11 15:12:16 +00:00
|
|
|
def stop_server_forcefully(self, port) -> bool:
|
|
|
|
if port not in self.servers:
|
2024-06-25 04:55:49 +00:00
|
|
|
return False
|
2024-07-11 15:12:16 +00:00
|
|
|
process = self.servers[port]['process']
|
2024-06-25 04:55:49 +00:00
|
|
|
process.terminate()
|
2024-07-11 15:12:16 +00:00
|
|
|
del self.servers[port]
|
2024-06-25 04:55:49 +00:00
|
|
|
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-07-11 15:02:21 +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-06-14 21:33:55 +00:00
|
|
|
|
|
|
|
if __name__ == "__main__":
|
|
|
|
pass
|