mirror of
https://gitlab.com/crafty-controller/crafty-4.git
synced 2024-08-30 18:23:09 +00:00
2a512d7273
Mostly just breaking up strings and comments into new lines Some strings dont require 'f' but keeping in for readability with the rest of the concatinated string
848 lines
30 KiB
Python
848 lines
30 KiB
Python
import os
|
|
import pathlib
|
|
from pathlib import Path
|
|
import shutil
|
|
import time
|
|
import logging
|
|
import tempfile
|
|
from typing import Union
|
|
|
|
from app.classes.controllers.crafty_perms_controller import Crafty_Perms_Controller
|
|
from app.classes.controllers.management_controller import Management_Controller
|
|
from app.classes.controllers.users_controller import Users_Controller
|
|
from app.classes.controllers.roles_controller import Roles_Controller
|
|
from app.classes.controllers.server_perms_controller import Server_Perms_Controller
|
|
from app.classes.controllers.servers_controller import Servers_Controller
|
|
from app.classes.models.server_permissions import Enum_Permissions_Server
|
|
from app.classes.models.users import helper_users
|
|
from app.classes.models.management import helpers_management
|
|
from app.classes.models.servers import servers_helper
|
|
from app.classes.shared.console import console
|
|
from app.classes.shared.helpers import helper
|
|
from app.classes.shared.server import Server
|
|
from app.classes.shared.file_helpers import file_helper
|
|
from app.classes.minecraft.server_props import ServerProps
|
|
from app.classes.minecraft.serverjars import server_jar_obj
|
|
from app.classes.minecraft.stats import Stats
|
|
from app.classes.web.websocket_helper import websocket_helper
|
|
|
|
try:
|
|
from peewee import DoesNotExist
|
|
|
|
# TZLocal is set as a hidden import on win pipeline
|
|
from tzlocal import get_localzone
|
|
from apscheduler.schedulers.background import BackgroundScheduler
|
|
|
|
except ModuleNotFoundError as err:
|
|
helper.auto_installer_fix(err)
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
|
class Controller:
|
|
def __init__(self):
|
|
self.servers_list = []
|
|
self.stats = Stats(self)
|
|
self.crafty_perms = Crafty_Perms_Controller()
|
|
self.management = Management_Controller()
|
|
self.roles = Roles_Controller()
|
|
self.server_perms = Server_Perms_Controller()
|
|
self.servers = Servers_Controller()
|
|
self.users = Users_Controller()
|
|
tz = get_localzone()
|
|
self.support_scheduler = BackgroundScheduler(timezone=str(tz))
|
|
self.support_scheduler.start()
|
|
|
|
def check_server_loaded(self, server_id_to_check: int):
|
|
|
|
logger.info(f"Checking to see if we already registered {server_id_to_check}")
|
|
|
|
for s in self.servers_list:
|
|
known_server = s.get("server_id")
|
|
if known_server is None:
|
|
return False
|
|
|
|
if known_server == server_id_to_check:
|
|
logger.info(
|
|
f"skipping initialization of server {server_id_to_check} "
|
|
f"because it is already loaded"
|
|
)
|
|
return True
|
|
|
|
return False
|
|
|
|
def init_all_servers(self):
|
|
|
|
servers = self.servers.get_all_defined_servers()
|
|
|
|
for s in servers:
|
|
server_id = s.get("server_id")
|
|
|
|
# if we have already initialized this server, let's skip it.
|
|
if self.check_server_loaded(server_id):
|
|
continue
|
|
|
|
# if this server path no longer exists - let's warn and bomb out
|
|
if not helper.check_path_exists(
|
|
helper.get_os_understandable_path(s["path"])
|
|
):
|
|
logger.warning(
|
|
f"Unable to find server {s['server_name']} at path {s['path']}. "
|
|
f"Skipping this server"
|
|
)
|
|
|
|
console.warning(
|
|
f"Unable to find server {s['server_name']} at path {s['path']}. "
|
|
f"Skipping this server"
|
|
)
|
|
continue
|
|
|
|
settings_file = os.path.join(
|
|
helper.get_os_understandable_path(s["path"]), "server.properties"
|
|
)
|
|
|
|
# if the properties file isn't there, let's warn
|
|
if not helper.check_file_exists(settings_file):
|
|
logger.error(f"Unable to find {settings_file}. Skipping this server.")
|
|
console.error(f"Unable to find {settings_file}. Skipping this server.")
|
|
continue
|
|
|
|
settings = ServerProps(settings_file)
|
|
|
|
temp_server_dict = {
|
|
"server_id": s.get("server_id"),
|
|
"server_data_obj": s,
|
|
"server_obj": Server(self.stats),
|
|
"server_settings": settings.props,
|
|
}
|
|
|
|
# setup the server, do the auto start and all that jazz
|
|
temp_server_dict["server_obj"].do_server_setup(s)
|
|
|
|
# add this temp object to the list of init servers
|
|
self.servers_list.append(temp_server_dict)
|
|
|
|
if s["auto_start"]:
|
|
self.servers.set_waiting_start(s["server_id"], True)
|
|
|
|
self.refresh_server_settings(s["server_id"])
|
|
|
|
console.info(
|
|
f"Loaded Server: ID {s['server_id']}"
|
|
+ f" | Name: {s['server_name']}"
|
|
+ f" | Autostart: {s['auto_start']}"
|
|
+ f" | Delay: {s['auto_start_delay']} "
|
|
)
|
|
|
|
def refresh_server_settings(self, server_id: int):
|
|
server_obj = self.get_server_obj(server_id)
|
|
server_obj.reload_server_settings()
|
|
|
|
@staticmethod
|
|
def check_system_user():
|
|
if helper_users.get_user_id_by_name("system") is not None:
|
|
return True
|
|
else:
|
|
return False
|
|
|
|
def set_project_root(self, root_dir):
|
|
self.project_root = root_dir
|
|
|
|
def package_support_logs(self, exec_user):
|
|
if exec_user["preparing"]:
|
|
return
|
|
self.users.set_prepare(exec_user["user_id"])
|
|
# pausing so on screen notifications can run for user
|
|
time.sleep(7)
|
|
websocket_helper.broadcast_user(
|
|
exec_user["user_id"], "notification", "Preparing your support logs"
|
|
)
|
|
tempDir = tempfile.mkdtemp()
|
|
tempZipStorage = tempfile.mkdtemp()
|
|
full_temp = os.path.join(tempDir, "support_logs")
|
|
os.mkdir(full_temp)
|
|
tempZipStorage = os.path.join(tempZipStorage, "support_logs")
|
|
crafty_path = os.path.join(full_temp, "crafty")
|
|
os.mkdir(crafty_path)
|
|
server_path = os.path.join(full_temp, "server")
|
|
os.mkdir(server_path)
|
|
if exec_user["superuser"]:
|
|
auth_servers = self.servers.get_all_defined_servers()
|
|
else:
|
|
user_servers = self.servers.get_authorized_servers(
|
|
int(exec_user["user_id"])
|
|
)
|
|
auth_servers = []
|
|
for server in user_servers:
|
|
if (
|
|
Enum_Permissions_Server.Logs
|
|
in self.server_perms.get_user_id_permissions_list(
|
|
exec_user["user_id"], server["server_id"]
|
|
)
|
|
):
|
|
auth_servers.append(server)
|
|
else:
|
|
logger.info(
|
|
f"Logs permission not available for server "
|
|
f"{server['server_name']}. Skipping."
|
|
)
|
|
# we'll iterate through our list of log paths from auth servers.
|
|
for server in auth_servers:
|
|
final_path = os.path.join(server_path, str(server["server_name"]))
|
|
try:
|
|
os.mkdir(final_path)
|
|
except FileExistsError:
|
|
final_path += "_" + server["server_uuid"]
|
|
os.mkdir(final_path)
|
|
try:
|
|
file_helper.copy_file(server["log_path"], final_path)
|
|
except Exception as e:
|
|
logger.warning(f"Failed to copy file with error: {e}")
|
|
# Copy crafty logs to archive dir
|
|
full_log_name = os.path.join(crafty_path, "logs")
|
|
file_helper.copy_dir(os.path.join(self.project_root, "logs"), full_log_name)
|
|
self.support_scheduler.add_job(
|
|
self.log_status,
|
|
"interval",
|
|
seconds=1,
|
|
id="logs_" + str(exec_user["user_id"]),
|
|
args=[full_temp, tempZipStorage + ".zip", exec_user],
|
|
)
|
|
file_helper.make_archive(tempZipStorage, tempDir)
|
|
|
|
if len(websocket_helper.clients) > 0:
|
|
websocket_helper.broadcast_user(
|
|
exec_user["user_id"],
|
|
"support_status_update",
|
|
helper.calc_percent(full_temp, tempZipStorage + ".zip"),
|
|
)
|
|
|
|
tempZipStorage += ".zip"
|
|
websocket_helper.broadcast_user(exec_user["user_id"], "send_logs_bootbox", {})
|
|
|
|
self.users.set_support_path(exec_user["user_id"], tempZipStorage)
|
|
|
|
self.users.stop_prepare(exec_user["user_id"])
|
|
self.support_scheduler.remove_job("logs_" + str(exec_user["user_id"]))
|
|
|
|
@staticmethod
|
|
def add_system_user():
|
|
helper_users.add_user(
|
|
"system",
|
|
helper.random_string_generator(64),
|
|
"default@example.com",
|
|
False,
|
|
False,
|
|
)
|
|
|
|
def get_server_settings(self, server_id):
|
|
for s in self.servers_list:
|
|
if int(s["server_id"]) == int(server_id):
|
|
return s["server_settings"]
|
|
|
|
logger.warning(f"Unable to find server object for server id {server_id}")
|
|
return False
|
|
|
|
def crash_detection(self, server_obj):
|
|
svr = self.get_server_obj(server_obj.server_id)
|
|
# start or stop crash detection depending upon user preference
|
|
# The below functions check to see if the server is running.
|
|
# They only execute if it's running.
|
|
if server_obj.crash_detection == 1:
|
|
svr.start_crash_detection()
|
|
else:
|
|
svr.stop_crash_detection()
|
|
|
|
def log_status(self, source_path, dest_path, exec_user):
|
|
results = helper.calc_percent(source_path, dest_path)
|
|
self.log_stats = results
|
|
|
|
if len(websocket_helper.clients) > 0:
|
|
websocket_helper.broadcast_user(
|
|
exec_user["user_id"], "support_status_update", results
|
|
)
|
|
|
|
def send_log_status(self):
|
|
try:
|
|
return self.log_stats
|
|
except:
|
|
return {"percent": 0, "total_files": 0}
|
|
|
|
def get_server_obj(self, server_id: Union[str, int]) -> Union[bool, Server]:
|
|
for s in self.servers_list:
|
|
if str(s["server_id"]) == str(server_id):
|
|
return s["server_obj"]
|
|
|
|
logger.warning(f"Unable to find server object for server id {server_id}")
|
|
return False # TODO: Change to None
|
|
|
|
def get_server_data(self, server_id: str):
|
|
for s in self.servers_list:
|
|
if str(s["server_id"]) == str(server_id):
|
|
return s["server_data_obj"]
|
|
|
|
logger.warning(f"Unable to find server object for server id {server_id}")
|
|
return False
|
|
|
|
@staticmethod
|
|
def list_defined_servers():
|
|
servers = servers_helper.get_all_defined_servers()
|
|
return servers
|
|
|
|
def list_running_servers(self):
|
|
running_servers = []
|
|
|
|
# for each server
|
|
for s in self.servers_list:
|
|
|
|
# is the server running?
|
|
srv_obj = s["server_obj"]
|
|
running = srv_obj.check_running()
|
|
# if so, let's add a dictionary to the list of running servers
|
|
if running:
|
|
running_servers.append({"id": srv_obj.server_id, "name": srv_obj.name})
|
|
|
|
return running_servers
|
|
|
|
def stop_all_servers(self):
|
|
servers = self.list_running_servers()
|
|
logger.info(f"Found {len(servers)} running server(s)")
|
|
console.info(f"Found {len(servers)} running server(s)")
|
|
|
|
logger.info("Stopping All Servers")
|
|
console.info("Stopping All Servers")
|
|
|
|
for s in servers:
|
|
logger.info(f"Stopping Server ID {s['id']} - {s['name']}")
|
|
console.info(f"Stopping Server ID {s['id']} - {s['name']}")
|
|
|
|
self.stop_server(s["id"])
|
|
|
|
# let's wait 2 seconds to let everything flush out
|
|
time.sleep(2)
|
|
|
|
logger.info("All Servers Stopped")
|
|
console.info("All Servers Stopped")
|
|
|
|
def stop_server(self, server_id):
|
|
# issue the stop command
|
|
svr_obj = self.get_server_obj(server_id)
|
|
svr_obj.stop_threaded_server()
|
|
|
|
def create_jar_server(
|
|
self,
|
|
server: str,
|
|
version: str,
|
|
name: str,
|
|
min_mem: int,
|
|
max_mem: int,
|
|
port: int,
|
|
):
|
|
server_id = helper.create_uuid()
|
|
server_dir = os.path.join(helper.servers_dir, server_id)
|
|
backup_path = os.path.join(helper.backup_path, server_id)
|
|
if helper.is_os_windows():
|
|
server_dir = helper.wtol_path(server_dir)
|
|
backup_path = helper.wtol_path(backup_path)
|
|
server_dir.replace(" ", "^ ")
|
|
backup_path.replace(" ", "^ ")
|
|
|
|
server_file = f"{server}-{version}.jar"
|
|
full_jar_path = os.path.join(server_dir, server_file)
|
|
|
|
# make the dir - perhaps a UUID?
|
|
helper.ensure_dir_exists(server_dir)
|
|
helper.ensure_dir_exists(backup_path)
|
|
|
|
try:
|
|
# do a eula.txt
|
|
with open(os.path.join(server_dir, "eula.txt"), "w", encoding="utf-8") as f:
|
|
f.write("eula=false")
|
|
f.close()
|
|
|
|
# setup server.properties with the port
|
|
with open(
|
|
os.path.join(server_dir, "server.properties"), "w", encoding="utf-8"
|
|
) as f:
|
|
f.write(f"server-port={port}")
|
|
f.close()
|
|
|
|
except Exception as e:
|
|
logger.error(f"Unable to create required server files due to :{e}")
|
|
return False
|
|
|
|
if helper.is_os_windows():
|
|
server_command = (
|
|
f"java -Xms{helper.float_to_string(min_mem)}M "
|
|
f"-Xmx{helper.float_to_string(max_mem)}M "
|
|
f'-jar "{full_jar_path}" nogui'
|
|
)
|
|
else:
|
|
server_command = (
|
|
f"java -Xms{helper.float_to_string(min_mem)}M "
|
|
f"-Xmx{helper.float_to_string(max_mem)}M "
|
|
f"-jar {full_jar_path} nogui"
|
|
)
|
|
server_log_file = f"{server_dir}/logs/latest.log"
|
|
server_stop = "stop"
|
|
|
|
new_id = self.register_server(
|
|
name,
|
|
server_id,
|
|
server_dir,
|
|
backup_path,
|
|
server_command,
|
|
server_file,
|
|
server_log_file,
|
|
server_stop,
|
|
port,
|
|
server_type="minecraft-java",
|
|
)
|
|
|
|
# download the jar
|
|
server_jar_obj.download_jar(server, version, full_jar_path, new_id)
|
|
|
|
return new_id
|
|
|
|
@staticmethod
|
|
def verify_jar_server(server_path: str, server_jar: str):
|
|
server_path = helper.get_os_understandable_path(server_path)
|
|
path_check = helper.check_path_exists(server_path)
|
|
jar_check = helper.check_file_exists(os.path.join(server_path, server_jar))
|
|
if not path_check or not jar_check:
|
|
return False
|
|
return True
|
|
|
|
@staticmethod
|
|
def verify_zip_server(zip_path: str):
|
|
zip_path = helper.get_os_understandable_path(zip_path)
|
|
zip_check = helper.check_file_exists(zip_path)
|
|
if not zip_check:
|
|
return False
|
|
return True
|
|
|
|
def import_jar_server(
|
|
self,
|
|
server_name: str,
|
|
server_path: str,
|
|
server_jar: str,
|
|
min_mem: int,
|
|
max_mem: int,
|
|
port: int,
|
|
):
|
|
server_id = helper.create_uuid()
|
|
new_server_dir = os.path.join(helper.servers_dir, server_id)
|
|
backup_path = os.path.join(helper.backup_path, server_id)
|
|
if helper.is_os_windows():
|
|
new_server_dir = helper.wtol_path(new_server_dir)
|
|
backup_path = helper.wtol_path(backup_path)
|
|
new_server_dir.replace(" ", "^ ")
|
|
backup_path.replace(" ", "^ ")
|
|
|
|
helper.ensure_dir_exists(new_server_dir)
|
|
helper.ensure_dir_exists(backup_path)
|
|
server_path = helper.get_os_understandable_path(server_path)
|
|
try:
|
|
file_helper.copy_dir(server_path, new_server_dir, True)
|
|
except shutil.Error as ex:
|
|
logger.error(f"Server import failed with error: {ex}")
|
|
|
|
has_properties = False
|
|
for item in os.listdir(new_server_dir):
|
|
if str(item) == "server.properties":
|
|
has_properties = True
|
|
if not has_properties:
|
|
logger.info(
|
|
f"No server.properties found on zip file import. "
|
|
f"Creating one with port selection of {str(port)}"
|
|
)
|
|
with open(
|
|
os.path.join(new_server_dir, "server.properties"), "w", encoding="utf-8"
|
|
) as f:
|
|
f.write(f"server-port={port}")
|
|
f.close()
|
|
|
|
full_jar_path = os.path.join(new_server_dir, server_jar)
|
|
|
|
if helper.is_os_windows():
|
|
server_command = (
|
|
f"java -Xms{helper.float_to_string(min_mem)}M "
|
|
f"-Xmx{helper.float_to_string(max_mem)}M "
|
|
f'-jar "{full_jar_path}" nogui'
|
|
)
|
|
else:
|
|
server_command = (
|
|
f"java -Xms{helper.float_to_string(min_mem)}M "
|
|
f"-Xmx{helper.float_to_string(max_mem)}M "
|
|
f"-jar {full_jar_path} nogui"
|
|
)
|
|
server_log_file = f"{new_server_dir}/logs/latest.log"
|
|
server_stop = "stop"
|
|
|
|
new_id = self.register_server(
|
|
server_name,
|
|
server_id,
|
|
new_server_dir,
|
|
backup_path,
|
|
server_command,
|
|
server_jar,
|
|
server_log_file,
|
|
server_stop,
|
|
port,
|
|
server_type="minecraft-java",
|
|
)
|
|
return new_id
|
|
|
|
def import_zip_server(
|
|
self,
|
|
server_name: str,
|
|
zip_path: str,
|
|
server_jar: str,
|
|
min_mem: int,
|
|
max_mem: int,
|
|
port: int,
|
|
):
|
|
server_id = helper.create_uuid()
|
|
new_server_dir = os.path.join(helper.servers_dir, server_id)
|
|
backup_path = os.path.join(helper.backup_path, server_id)
|
|
if helper.is_os_windows():
|
|
new_server_dir = helper.wtol_path(new_server_dir)
|
|
backup_path = helper.wtol_path(backup_path)
|
|
new_server_dir.replace(" ", "^ ")
|
|
backup_path.replace(" ", "^ ")
|
|
|
|
tempDir = helper.get_os_understandable_path(zip_path)
|
|
helper.ensure_dir_exists(new_server_dir)
|
|
helper.ensure_dir_exists(backup_path)
|
|
has_properties = False
|
|
# extracts archive to temp directory
|
|
for item in os.listdir(tempDir):
|
|
if str(item) == "server.properties":
|
|
has_properties = True
|
|
try:
|
|
if not os.path.isdir(os.path.join(tempDir, item)):
|
|
file_helper.move_file(
|
|
os.path.join(tempDir, item), os.path.join(new_server_dir, item)
|
|
)
|
|
else:
|
|
file_helper.move_dir(
|
|
os.path.join(tempDir, item), os.path.join(new_server_dir, item)
|
|
)
|
|
except Exception as ex:
|
|
logger.error(f"ERROR IN ZIP IMPORT: {ex}")
|
|
if not has_properties:
|
|
logger.info(
|
|
f"No server.properties found on zip file import. "
|
|
f"Creating one with port selection of {str(port)}"
|
|
)
|
|
with open(
|
|
os.path.join(new_server_dir, "server.properties"), "w", encoding="utf-8"
|
|
) as f:
|
|
f.write(f"server-port={port}")
|
|
f.close()
|
|
|
|
full_jar_path = os.path.join(new_server_dir, server_jar)
|
|
|
|
if helper.is_os_windows():
|
|
server_command = (
|
|
f"java -Xms{helper.float_to_string(min_mem)}M "
|
|
f"-Xmx{helper.float_to_string(max_mem)}M "
|
|
f'-jar "{full_jar_path}" nogui'
|
|
)
|
|
else:
|
|
server_command = (
|
|
f"java -Xms{helper.float_to_string(min_mem)}M "
|
|
f"-Xmx{helper.float_to_string(max_mem)}M "
|
|
f"-jar {full_jar_path} nogui"
|
|
)
|
|
logger.debug("command: " + server_command)
|
|
server_log_file = f"{new_server_dir}/logs/latest.log"
|
|
server_stop = "stop"
|
|
|
|
new_id = self.register_server(
|
|
server_name,
|
|
server_id,
|
|
new_server_dir,
|
|
backup_path,
|
|
server_command,
|
|
server_jar,
|
|
server_log_file,
|
|
server_stop,
|
|
port,
|
|
server_type="minecraft-java",
|
|
)
|
|
return new_id
|
|
|
|
# **********************************************************************************
|
|
# BEDROCK IMPORTS
|
|
# **********************************************************************************
|
|
|
|
def import_bedrock_server(
|
|
self, server_name: str, server_path: str, server_exe: str, port: int
|
|
):
|
|
server_id = helper.create_uuid()
|
|
new_server_dir = os.path.join(helper.servers_dir, server_id)
|
|
backup_path = os.path.join(helper.backup_path, server_id)
|
|
if helper.is_os_windows():
|
|
new_server_dir = helper.wtol_path(new_server_dir)
|
|
backup_path = helper.wtol_path(backup_path)
|
|
new_server_dir.replace(" ", "^ ")
|
|
backup_path.replace(" ", "^ ")
|
|
|
|
helper.ensure_dir_exists(new_server_dir)
|
|
helper.ensure_dir_exists(backup_path)
|
|
server_path = helper.get_os_understandable_path(server_path)
|
|
try:
|
|
file_helper.copy_dir(server_path, new_server_dir, True)
|
|
except shutil.Error as ex:
|
|
logger.error(f"Server import failed with error: {ex}")
|
|
|
|
has_properties = False
|
|
for item in os.listdir(new_server_dir):
|
|
if str(item) == "server.properties":
|
|
has_properties = True
|
|
if not has_properties:
|
|
logger.info(
|
|
f"No server.properties found on zip file import. "
|
|
f"Creating one with port selection of {str(port)}"
|
|
)
|
|
with open(
|
|
os.path.join(new_server_dir, "server.properties"), "w", encoding="utf-8"
|
|
) as f:
|
|
f.write(f"server-port={port}")
|
|
f.close()
|
|
|
|
full_jar_path = os.path.join(new_server_dir, server_exe)
|
|
|
|
if helper.is_os_windows():
|
|
server_command = f'"{full_jar_path}"'
|
|
else:
|
|
server_command = f"./{server_exe}"
|
|
logger.debug("command: " + server_command)
|
|
server_log_file = "N/A"
|
|
server_stop = "stop"
|
|
|
|
new_id = self.register_server(
|
|
server_name,
|
|
server_id,
|
|
new_server_dir,
|
|
backup_path,
|
|
server_command,
|
|
server_exe,
|
|
server_log_file,
|
|
server_stop,
|
|
port,
|
|
server_type="minecraft-bedrock",
|
|
)
|
|
if os.name != "nt":
|
|
if helper.check_file_exists(full_jar_path):
|
|
os.chmod(full_jar_path, 0o2775)
|
|
return new_id
|
|
|
|
def import_bedrock_zip_server(
|
|
self, server_name: str, zip_path: str, server_exe: str, port: int
|
|
):
|
|
server_id = helper.create_uuid()
|
|
new_server_dir = os.path.join(helper.servers_dir, server_id)
|
|
backup_path = os.path.join(helper.backup_path, server_id)
|
|
if helper.is_os_windows():
|
|
new_server_dir = helper.wtol_path(new_server_dir)
|
|
backup_path = helper.wtol_path(backup_path)
|
|
new_server_dir.replace(" ", "^ ")
|
|
backup_path.replace(" ", "^ ")
|
|
|
|
tempDir = helper.get_os_understandable_path(zip_path)
|
|
helper.ensure_dir_exists(new_server_dir)
|
|
helper.ensure_dir_exists(backup_path)
|
|
has_properties = False
|
|
# extracts archive to temp directory
|
|
for item in os.listdir(tempDir):
|
|
if str(item) == "server.properties":
|
|
has_properties = True
|
|
try:
|
|
if not os.path.isdir(os.path.join(tempDir, item)):
|
|
file_helper.move_file(
|
|
os.path.join(tempDir, item), os.path.join(new_server_dir, item)
|
|
)
|
|
else:
|
|
file_helper.move_dir(
|
|
os.path.join(tempDir, item), os.path.join(new_server_dir, item)
|
|
)
|
|
except Exception as ex:
|
|
logger.error(f"ERROR IN ZIP IMPORT: {ex}")
|
|
if not has_properties:
|
|
logger.info(
|
|
f"No server.properties found on zip file import. "
|
|
f"Creating one with port selection of {str(port)}"
|
|
)
|
|
with open(
|
|
os.path.join(new_server_dir, "server.properties"), "w", encoding="utf-8"
|
|
) as f:
|
|
f.write(f"server-port={port}")
|
|
f.close()
|
|
|
|
full_jar_path = os.path.join(new_server_dir, server_exe)
|
|
|
|
if helper.is_os_windows():
|
|
server_command = f'"{full_jar_path}"'
|
|
else:
|
|
server_command = f"./{server_exe}"
|
|
logger.debug("command: " + server_command)
|
|
server_log_file = "N/A"
|
|
server_stop = "stop"
|
|
|
|
new_id = self.register_server(
|
|
server_name,
|
|
server_id,
|
|
new_server_dir,
|
|
backup_path,
|
|
server_command,
|
|
server_exe,
|
|
server_log_file,
|
|
server_stop,
|
|
port,
|
|
server_type="minecraft-bedrock",
|
|
)
|
|
if os.name != "nt":
|
|
if helper.check_file_exists(full_jar_path):
|
|
os.chmod(full_jar_path, 0o2775)
|
|
|
|
return new_id
|
|
|
|
# **********************************************************************************
|
|
# BEDROCK IMPORTS END
|
|
# **********************************************************************************
|
|
|
|
def rename_backup_dir(self, old_server_id, new_server_id, new_uuid):
|
|
server_data = self.servers.get_server_data_by_id(old_server_id)
|
|
old_bu_path = server_data["backup_path"]
|
|
Server_Perms_Controller.backup_role_swap(old_server_id, new_server_id)
|
|
if not helper.is_os_windows():
|
|
backup_path = helper.validate_traversal(helper.backup_path, old_bu_path)
|
|
if helper.is_os_windows():
|
|
backup_path = helper.validate_traversal(
|
|
helper.wtol_path(helper.backup_path), helper.wtol_path(old_bu_path)
|
|
)
|
|
backup_path = helper.wtol_path(str(backup_path))
|
|
backup_path.replace(" ", "^ ")
|
|
backup_path = Path(backup_path)
|
|
backup_path_components = list(backup_path.parts)
|
|
backup_path_components[-1] = new_uuid
|
|
new_bu_path = pathlib.PurePath(os.path.join(*backup_path_components))
|
|
if os.path.isdir(new_bu_path):
|
|
if helper.validate_traversal(helper.backup_path, new_bu_path):
|
|
os.rmdir(new_bu_path)
|
|
backup_path.rename(new_bu_path)
|
|
|
|
def register_server(
|
|
self,
|
|
name: str,
|
|
server_uuid: str,
|
|
server_dir: str,
|
|
backup_path: str,
|
|
server_command: str,
|
|
server_file: str,
|
|
server_log_file: str,
|
|
server_stop: str,
|
|
server_port: int,
|
|
server_type: str,
|
|
):
|
|
# put data in the db
|
|
|
|
new_id = self.servers.create_server(
|
|
name,
|
|
server_uuid,
|
|
server_dir,
|
|
backup_path,
|
|
server_command,
|
|
server_file,
|
|
server_log_file,
|
|
server_stop,
|
|
server_type,
|
|
server_port,
|
|
)
|
|
|
|
if not helper.check_file_exists(os.path.join(server_dir, "crafty_managed.txt")):
|
|
try:
|
|
# place a file in the dir saying it's owned by crafty
|
|
with open(
|
|
os.path.join(server_dir, "crafty_managed.txt"),
|
|
"w",
|
|
encoding="utf-8",
|
|
) as f:
|
|
f.write(
|
|
"The server is managed by Crafty Controller.\n "
|
|
"Leave this directory/files alone please"
|
|
)
|
|
f.close()
|
|
|
|
except Exception as e:
|
|
logger.error(f"Unable to create required server files due to :{e}")
|
|
return False
|
|
|
|
# let's re-init all servers
|
|
self.init_all_servers()
|
|
|
|
return new_id
|
|
|
|
def remove_server(self, server_id, files):
|
|
counter = 0
|
|
for s in self.servers_list:
|
|
|
|
# if this is the droid... im mean server we are looking for...
|
|
if str(s["server_id"]) == str(server_id):
|
|
server_data = self.get_server_data(server_id)
|
|
server_name = server_data["server_name"]
|
|
|
|
logger.info(f"Deleting Server: ID {server_id} | Name: {server_name} ")
|
|
console.info(f"Deleting Server: ID {server_id} | Name: {server_name} ")
|
|
|
|
srv_obj = s["server_obj"]
|
|
running = srv_obj.check_running()
|
|
|
|
if running:
|
|
self.stop_server(server_id)
|
|
if files:
|
|
try:
|
|
file_helper.del_dirs(
|
|
helper.get_os_understandable_path(
|
|
self.servers.get_server_data_by_id(server_id)["path"]
|
|
)
|
|
)
|
|
except Exception as e:
|
|
logger.error(
|
|
f"Unable to delete server files for server with ID: "
|
|
f"{server_id} with error logged: {e}"
|
|
)
|
|
if helper.check_path_exists(
|
|
self.servers.get_server_data_by_id(server_id)["backup_path"]
|
|
):
|
|
file_helper.del_dirs(
|
|
helper.get_os_understandable_path(
|
|
self.servers.get_server_data_by_id(server_id)[
|
|
"backup_path"
|
|
]
|
|
)
|
|
)
|
|
|
|
# Cleanup scheduled tasks
|
|
try:
|
|
helpers_management.delete_scheduled_task_by_server(server_id)
|
|
except DoesNotExist:
|
|
logger.info("No scheduled jobs exist. Continuing.")
|
|
# remove the server from the DB
|
|
self.servers.remove_server(server_id)
|
|
|
|
# remove the server from servers list
|
|
self.servers_list.pop(counter)
|
|
|
|
counter += 1
|
|
|
|
@staticmethod
|
|
def clear_unexecuted_commands():
|
|
helpers_management.clear_unexecuted_commands()
|
|
|
|
@staticmethod
|
|
def clear_support_status():
|
|
helper_users.clear_support_status()
|