From 540584990eee411f1c3c12c295c04010b1771fa2 Mon Sep 17 00:00:00 2001 From: Andrew Date: Thu, 10 Feb 2022 18:20:36 -0500 Subject: [PATCH 1/2] Inital bedrock support --- app/classes/minecraft/mc_ping.py | 66 +- app/classes/minecraft/stats.py | 17 +- app/classes/models/servers.py | 9 +- app/classes/shared/main_controller.py | 10 +- app/classes/web/server_handler.py | 6 +- .../panel/parts/server_controls_list.html | 3 +- .../templates/server/bedrock_wizard.html | 2 +- app/frontend/templates/server/wizard.html | 650 ++++++++++++++++++ 8 files changed, 743 insertions(+), 20 deletions(-) diff --git a/app/classes/minecraft/mc_ping.py b/app/classes/minecraft/mc_ping.py index 3f1d34db..52e8fe83 100644 --- a/app/classes/minecraft/mc_ping.py +++ b/app/classes/minecraft/mc_ping.py @@ -133,13 +133,7 @@ def ping(ip, port): sock.connect((ip, port)) except socket.error: - #We'll try gathering this data on a UDP port next - try: - sock =socket.socket(socket.AF_INET, socket.SOCK_DGRAM) - sock.connect((ip, port)) - #If the udp port fails as well we're toast. :sadcat: - except socket.error: - return False + return False try: host = ip.encode('utf-8') @@ -171,3 +165,61 @@ def ping(ip, port): return Server(json.loads(data)) finally: sock.close() + +# For the rest of requests see wiki.vg/Protocol +def ping_bedrock(ip, port): + def read_var_int(): + i = 0 + j = 0 + while True: + k = sock.recv(1) + if not k: + return 0 + k = k[0] + i |= (k & 0x7f) << (j * 7) + j += 1 + if j > 5: + raise ValueError('var_int too big') + if not k & 0x80: + return i + + sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) + try: + sock.connect((ip, port)) + + except: + print("in except") + return False + + try: + host = ip.encode('utf-8') + data = b'' # wiki.vg/Server_List_Ping + data += b'\x00' # packet ID + data += b'\x04' # protocol variant + data += struct.pack('>b', len(host)) + host + data += struct.pack('>H', port) + data += b'\x01' # next state + data = struct.pack('>b', len(data)) + data + sock.sendall(data + b'\x01\x00') # handshake + status ping + try: + length = read_var_int() # full packet length + except: + return False + if length < 10: + if length < 0: + return False + else: + return False + sock.recv(1) # packet type, 0 for pings + length = read_var_int() # string length + data = b'' + while len(data) != length: + chunk = sock.recv(length - len(data)) + if not chunk: + return False + + data += chunk + logger.debug(f"Server reports this data on ping: {data}") + return Server(json.loads(data)) + finally: + sock.close() diff --git a/app/classes/minecraft/stats.py b/app/classes/minecraft/stats.py index 3a231b76..d117699a 100644 --- a/app/classes/minecraft/stats.py +++ b/app/classes/minecraft/stats.py @@ -9,7 +9,7 @@ from app.classes.models.management import Host_Stats from app.classes.models.servers import Server_Stats, servers_helper from app.classes.shared.helpers import helper -from app.classes.minecraft.mc_ping import ping +from app.classes.minecraft.mc_ping import ping, ping_bedrock logger = logging.getLogger(__name__) @@ -177,7 +177,10 @@ class Stats: server_port = server['server_port'] logger.debug("Pinging {internal_ip} on port {server_port}") - int_mc_ping = ping(internal_ip, int(server_port)) + if servers_helper.get_server_type_by_id(server_id) == 'minecraft-bedrock': + int_mc_ping = ping_bedrock(internal_ip, int(server_port)) + else: + int_mc_ping = ping(internal_ip, int(server_port)) ping_data = {} @@ -223,7 +226,10 @@ class Stats: server = s.get('server_name', f"ID#{server_id}") logger.debug("Pinging server '{server}' on {internal_ip}:{server_port}") - int_mc_ping = ping(internal_ip, int(server_port)) + if servers_helper.get_server_type_by_id(server_id) == 'minecraft-bedrock': + int_mc_ping = ping_bedrock(internal_ip, int(server_port)) + else: + int_mc_ping = ping(internal_ip, int(server_port)) int_data = False ping_data = {} @@ -286,7 +292,10 @@ class Stats: logger.debug(f"Pinging server '{server.name}' on {internal_ip}:{server_port}") - int_mc_ping = ping(internal_ip, int(server_port)) + if servers_helper.get_server_type_by_id(server_id) == 'minecraft-bedrock': + int_mc_ping = ping_bedrock(internal_ip, int(server_port)) + else: + int_mc_ping = ping(internal_ip, int(server_port)) int_data = False ping_data = {} diff --git a/app/classes/models/servers.py b/app/classes/models/servers.py index 8679e2a3..c99aff1f 100644 --- a/app/classes/models/servers.py +++ b/app/classes/models/servers.py @@ -100,6 +100,7 @@ class helper_servers: server_file: str, server_log_file: str, server_stop: str, + server_type: str, server_port=25565): return Servers.insert({ Servers.server_name: name, @@ -113,7 +114,8 @@ class helper_servers: Servers.log_path: server_log_file, Servers.server_port: server_port, Servers.stop_command: server_stop, - Servers.backup_path: backup_path + Servers.backup_path: backup_path, + Servers.type: server_type }).execute() @@ -121,6 +123,11 @@ class helper_servers: def get_server_obj(server_id): return Servers.get_by_id(server_id) + @staticmethod + def get_server_type_by_id(server_id): + server_type = Servers.select().where(Servers.server_id == server_id).get() + return server_type.type + @staticmethod def update_server(server_obj): return server_obj.save() diff --git a/app/classes/shared/main_controller.py b/app/classes/shared/main_controller.py index cd7904e5..cff534d8 100644 --- a/app/classes/shared/main_controller.py +++ b/app/classes/shared/main_controller.py @@ -297,7 +297,7 @@ class Controller: # download the jar server_jar_obj.download_jar(server, version, full_jar_path) - new_id = self.register_server(name, server_id, server_dir, backup_path, server_command, server_file, server_log_file, server_stop, port, type='minecraft-java') + 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') return new_id @staticmethod @@ -399,7 +399,9 @@ class Controller: server_log_file, server_stop, port, type='minecraft-java') return new_id -#---------------------------------------------------BEDROCK IMPORTS--------------------------------------------------- + #************************************************************************************************ + # BEDROCK IMPORTS + #************************************************************************************************ def import_bedrock_server(self, server_name: str, server_path: str, server_exe: str, port: int): server_id = helper.create_uuid() @@ -484,7 +486,9 @@ class Controller: server_log_file, server_stop, port, server_type='minecraft-bedrock') return new_id -#---------------------------------------------------END BEDROCK IMPORTS--------------------------------------------------- + #************************************************************************************************ + # 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) diff --git a/app/classes/web/server_handler.py b/app/classes/web/server_handler.py index c7eddf1a..7a3b47a4 100644 --- a/app/classes/web/server_handler.py +++ b/app/classes/web/server_handler.py @@ -292,7 +292,7 @@ class ServerHandler(BaseHandler): port = bleach.clean(self.get_argument('port', '')) import_type = bleach.clean(self.get_argument('create_type', '')) import_server_path = bleach.clean(self.get_argument('server_path', '')) - import_server_jar = bleach.clean(self.get_argument('server_jar', '')) + import_server_exe = bleach.clean(self.get_argument('server_jar', '')) server_parts = server.split("|") captured_roles = [] for role in user_roles: @@ -310,7 +310,7 @@ class ServerHandler(BaseHandler): self.redirect("/panel/error?error=Server path or Server Jar not found!") return - new_server_id = self.controller.import_jar_server(server_name, import_server_path,import_server_jar, min_mem, max_mem, port) + new_server_id = self.controller.import_bedrock_server(server_name, import_server_path,import_server_exe, port) self.controller.management.add_to_audit_log(exec_user['user_id'], f"imported a jar server named \"{server_name}\"", # Example: Admin imported a server named "old creative" new_server_id, @@ -323,7 +323,7 @@ class ServerHandler(BaseHandler): self.redirect("/panel/error?error=Temp path not found!") return - new_server_id = self.controller.import_zip_server(server_name, zip_path, import_server_jar, min_mem, max_mem, port) + new_server_id = self.controller.import_bedrock_zip_server(server_name, zip_path, import_server_exe, port) if new_server_id == "false": self.redirect("/panel/error?error=Zip file not accessible! You can fix this permissions issue with" + f"sudo chown -R crafty:crafty {import_server_path} And sudo chmod 2775 -R {import_server_path}") diff --git a/app/frontend/templates/panel/parts/server_controls_list.html b/app/frontend/templates/panel/parts/server_controls_list.html index 6cbad0d2..90728be4 100644 --- a/app/frontend/templates/panel/parts/server_controls_list.html +++ b/app/frontend/templates/panel/parts/server_controls_list.html @@ -5,7 +5,8 @@ {{ translate('serverDetails', 'terminal', data['lang']) }} {% end %} - {% if data['permissions']['Logs'] in data['user_permissions'] %} + + {% if data['permissions']['Logs'] in data['user_permissions'] and data['server_data']['type'] != 'minecraft-bedrock'%}