def do_enable_autostart(self, line): if line == '': self.help_enable_autostart() return 0 try: int(line) except ValueError: console.error("Server ID must be a string") self.help_enable_autostart() return 0 try: server = MC_settings.get_by_id(line) except Exception as e: console.help("Unable to find a server with that ID: {}".format(e)) return 0 server = int(line) MC_settings.update({ MC_settings.auto_start_server: True }).where(MC_settings.id == server).execute() logger.info( "Enabled Autostart for Server {} via the console".format(server)) console.info("Enabled Autostart for Server {} ".format(server))
def setup_ftp(self, server_id=1): ftp_settings = None mc_settings = None try: ftp_settings = Ftp_Srv.get_by_id(1) mc_settings = MC_settings.get_by_id(server_id) except Exception as e: logging.exception("Error Loading FTP. Traceback:") self.last_error = e return False pemfile = os.path.join(helper.crafty_root, "app", 'web', 'certs', 'crafty.pem') if not helper.check_file_exists(pemfile): helper.create_ftp_pem() if ftp_settings is not None and mc_settings is not None: self.user = ftp_settings.user self.password = ftp_settings.password self.port = ftp_settings.port self.root_dir = mc_settings.server_path logger.info("FTP server is now setup - Port: {}, Dir: {}".format( self.port, self.root_dir))
def do_list_servers(self, line): servers = MC_settings.select() console.info("Servers Defined:") console.info('-' * 30) for s in servers: srv_obj = multi.get_server_obj(s.id) running = srv_obj.check_running() stats = multi.get_stats_for_server(s.id) # print(stats) console.info("Server ID: {}".format(s.id)) console.info("Name:{}".format(s.server_name)) console.info("Path: {}".format(s.server_path)) console.info("Memory: {}/{}:".format(s.memory_min, s.memory_max)) console.info("IP {} / Port: {}".format(s.server_ip, s.server_port)) console.info("AutoStart: {}".format(s.auto_start_server)) console.info("Currently Running: {}".format(running)) console.info("Started: {}".format(stats['server_start_time'])) console.info("CPU: {}".format(stats['cpu_usage'])) console.info("Memory: {}".format(stats['memory_usage'])) console.info("Players: {}/{}".format(stats['online_players'], stats['max_players'])) console.info("Server: {}".format(stats['server_version'])) console.info("MOTD: {}".format(stats['motd'])) console.info('-' * 30)
def do_restart(self, line): if line == '': self.help_start() return 0 try: int(line) except ValueError: console.error("Server ID must be a number") self.help_start() return 0 try: server = MC_settings.get_by_id(line) except Exception as e: console.help("Unable to find a server with that ID: {}".format(e)) return 0 server = int(line) Remote.insert({ Remote.command: 'restart_mc_server', Remote.server_id: server, Remote.command_source: "localhost" }).execute() console.info("Restarting Minecraft Server in background")
def ping_server(self): server_port = 25565 ip = "127.0.0.1" settings = MC_settings.get_by_id(self.server_id) server_port = settings.server_port ip = settings.server_ip logger.debug("Pinging %s on port %s", ip, server_port) mc_ping = ping(ip, int(server_port)) return mc_ping
def watch_for_commands(self): while True: command_instance = Remote.select().where(Remote.id == 1).exists() if command_instance: entry = Remote.get_by_id(1) command_data = model_to_dict(entry) command = command_data['command'] server_id = command_data['server_id'] source = command_data['command_source'] server_data = MC_settings.get_by_id(server_id) server_name = server_data.server_name logger.info( "Remote Command \"%s\" found for server \"%s\" from source %s. Executing!", command, server_name, source) self.handle_command(command, server_id) self.clear_all_commands() time.sleep(1)
def do_start(self, line): if line == '': self.help_start() return 0 try: int(line) except ValueError: console.error("Server ID must be a number") self.help_start() return 0 try: server = MC_settings.get_by_id(line) except Exception as e: console.help("Unable to find a server with that ID: {}".format(e)) return 0 server = int(line) if helper.is_setup_complete(): srv_obj = multi.get_server_obj(server) if srv_obj.check_running(): console.warning("Server already running") else: console.info("Starting Minecraft Server in background") Remote.insert({ Remote.command: 'start_mc_server', Remote.server_id: server, Remote.command_source: "localhost" }).execute() else: console.warning( "Unable to start server, please complete setup in the web GUI first" )
def do_stop(self, line): if line == '': self.help_stop() return 0 try: int(line) except ValueError: console.error("Server ID must be a number") self.help_stop() return 0 try: server = MC_settings.get_by_id(line) except Exception as e: console.help("Unable to find a server with that ID: {}".format(e)) return 0 server = int(line) if helper.is_setup_complete(): srv_obj = multi.get_server_obj(server) if not srv_obj.check_running(): console.warning("Server already stopped") else: console.info("Stopping Minecraft Server") multi.stop_server(server) ''' Remote.insert({ Remote.command: 'stop_mc_server' }).execute() ''' else: console.warning( "Unable to stop server, please complete setup in the web GUI first" )
def do_revert_server_jar(self, line): if line == '': self.help_update_server_jar() return 0 try: int(line) except ValueError: console.error("Server ID must be a number") self.help_update_server_jar() return 0 try: server = MC_settings.get_by_id(line) except Exception as e: console.help("Unable to find a server with that ID: {}".format(e)) return 0 server = int(line) if helper.is_setup_complete(): srv_obj = multi.get_server_obj(server) console.info("Reverting updated Server Jar in background") Remote.insert({ Remote.command: 'revert_server_jar_console', Remote.server_id: server, Remote.command_source: "localhost" }).execute() else: console.warning( "Unable to update server jar, please complete setup in the web GUI first" )
def handle_command(self, command, server_id): if command == "exit_crafty": logger.info("Sending Stop Command To Crafty") # stop the ftp server... if ftp_svr_object.check_running(): ftp_svr_object.stop_threaded_ftp_server() # kill all mc servers gracefully try: multi.stop_all_servers() except: pass logger.info("***** Crafty Stopped ***** \n") webhookmgr.run_command_webhooks( command, webhookmgr.payload_formatter( 200, {}, {"code": "CWEB_STOP"}, {"info": "Crafty is shutting down"})) os._exit(0) srv_obj = multi.get_server_obj(server_id) running = srv_obj.check_running() server_name = srv_obj.get_mc_server_name() if command == 'restart_web_server': self.tornado_obj.stop_web_server() time.sleep(1) self.tornado_obj.start_web_server(True) webhookmgr.run_command_webhooks( command, webhookmgr.payload_formatter( 200, {}, {"code": "WEBSRV_RESTART"}, {"info": "Crafty Web Interface action has completed"})) self.clear_all_commands() elif command == "reload_mc_settings": any_srv_obj = multi.get_first_server_object() any_srv_obj.reload_settings() elif command == 'restart_mc_server': if running: try: logger.info("Stopping MC Server") srv_obj.stop_threaded_server() except: logger.exception("Unable to stop server %s. Traceback: ", server_name) webhookmgr.run_command_webhooks( command, webhookmgr.payload_formatter(500, { "error": "TRACEBACK" }, { "server": { "id": server_id, "name": server_name, "running": running } }, { "info": "A Traceback occured while restarting the MC server" })) while True: server_up = srv_obj.is_server_pingable() if server_up: logger.info("%s still pingable, waiting...", server_name) time.sleep(.5) else: logger.info("Server %s has stopped", server_name) break srv_obj.run_threaded_server() else: logger.info("%s not running, starting it now", server_name) srv_obj.run_threaded_server() webhookmgr.run_command_webhooks( command, webhookmgr.payload_formatter( 200, {}, { "code": "SER_RESTART_DONE", "server": { "id": server_id, "name": server_name, "running": running } }, {"info": "Server restart action has completed"})) elif command == 'start_mc_server': srv_obj.run_threaded_server() time.sleep(2) multi.do_stats_for_servers() webhookmgr.run_command_webhooks( command, webhookmgr.payload_formatter( 200, {}, { "code": "SER_START_DONE", "server": { "id": server_id, "name": server_name, "running": running } }, {"info": "Server start action has completed"})) elif command == 'stop_mc_server': if running: logger.info("Stopping MC server %s", server_name) srv_obj.stop_threaded_server() time.sleep(2) multi.do_stats_for_servers() webhookmgr.run_command_webhooks( command, webhookmgr.payload_formatter( 200, {}, { "code": "SER_STOP_DONE", "server": { "id": server_id, "name": server_name, "running": running } }, {"info": "Server stop action has completed"})) else: logger.info("Stop halted! Server %s is not running!", server_name) webhookmgr.run_command_webhooks( command, webhookmgr.payload_formatter( 500, {"error": "SER_NOT_RUNNING"}, { "server": { "id": server_id, "name": server_name, "running": running } }, {"info": "Server is not running"})) elif command == 'update_server_jar': srv_obj.update_server_jar(False) elif command == 'revert_server_jar': srv_obj.revert_updated_server_jar(False) elif command == 'update_server_jar_console': srv_obj.update_server_jar(True) elif command == 'revert_server_jar_console': srv_obj.revert_updated_server_jar(True) elif command == "exit_crafty": logger.info("Sending Stop Command To Crafty") # stop the ftp server... if ftp_svr_object.check_running(): ftp_svr_object.stop_threaded_ftp_server() # kill all mc servers gracefully multi.stop_all_servers() logger.info("***** Crafty Stopped ***** \n") webhookmgr.run_command_webhooks( command, webhookmgr.payload_formatter( 200, {}, {"code": "CWEB_STOP"}, {"info": "Crafty is shutting down"})) os._exit(0) elif command == 'start_ftp': settings = MC_settings.get_by_id(server_id) if ftp_svr_object.check_running(): logger.warning( "The FTP server is already running - please stop it before starting again" ) webhookmgr.run_command_webhooks( command, webhookmgr.payload_formatter( 500, {"error": "FTP_RUNNING"}, {}, {"info": "FTP is already running"})) return False if helper.check_directory_exist(settings.server_path): logger.info("Setting FTP root path to {}".format( settings.server_path)) ftp_svr_object.set_root_dir(settings.server_path) else: logger.error("Path: {} not found!".format( settings.server_path)) webhookmgr.run_command_webhooks( command, webhookmgr.payload_formatter( 200, {"error": "PATH_NONEXISTANT"}, {"path": settings.server_path}, {"info": "Home path for FTP server not found"})) return False logger.info("Starting FTP Server") ftp_svr_object.run_threaded_ftp_server(server_id) webhookmgr.run_command_webhooks( command, webhookmgr.payload_formatter( 200, {}, {}, {"info": "FTP server successfully started"})) elif command == 'stop_ftp': ftp_svr_object.stop_threaded_ftp_server() webhookmgr.run_command_webhooks( command, webhookmgr.payload_formatter( 200, {}, {}, {"info": "FTP server successfully stopped"})) elif command == 'destroy_world': logger.info("Destroying World for Server: {} - {}".format( server_id, server_name)) srv_obj.destroy_world()
def get_mc_process_stats(self): world_data = self.get_world_info() server_settings = MC_settings.get(self.server_id) server_settings_dict = model_to_dict(server_settings) if self.check_running(): p = psutil.Process(self.PID) # call it first so we can be more accurate per the docs # https://giamptest.readthedocs.io/en/latest/#psutil.Process.cpu_percent dummy = p.cpu_percent() real_cpu = round( p.cpu_percent(interval=0.5) / psutil.cpu_count(), 2) # this is a faster way of getting data for a process with p.oneshot(): server_stats = { 'server_start_time': self.get_start_time(), 'server_running': self.check_running(), 'cpu_usage': real_cpu, 'memory_usage': helper.human_readable_file_size(p.memory_info()[0]), 'world_name': world_data['world_name'], 'world_size': world_data['world_size'], 'server_ip': server_settings_dict['server_ip'], 'server_port': server_settings_dict['server_port'] } else: server_stats = { 'server_start_time': "Not Started", 'server_running': False, 'cpu_usage': 0, 'memory_usage': "0 MB", 'world_name': world_data['world_name'], 'world_size': world_data['world_size'], 'server_ip': server_settings_dict['server_ip'], 'server_port': server_settings_dict['server_port'] } # are we pingable? try: server_ping = self.ping_server() except: server_ping = False pass if server_ping: online_stats = json.loads(server_ping.players) server_stats.update({'online': online_stats.get('online', 0)}) server_stats.update({'max': online_stats.get('max', 0)}) server_stats.update({'players': online_stats.get('players', 0)}) server_stats.update( {'server_description': server_ping.description}) server_stats.update({'server_version': server_ping.version}) else: server_stats.update({'online': 0}) server_stats.update({'max': 0}) server_stats.update({'players': []}) server_stats.update({'server_description': "Unable to connect"}) server_stats.update({'server_version': "Unable to connect"}) return server_stats
def get_mc_server_name(self, server_id=None): if server_id is None: server_id = self.server_id server_data = MC_settings.get_by_id(server_id) return server_data.server_name
def reload_settings(self): logger.info("Reloading MC Settings from the DB") self.settings = MC_settings.get_by_id(self.server_id) self.setup_server_run_command()