def run_scheduled_server(self): # delay the startup as long as the console.info("Starting Minecraft server {}".format(self.name)) self.run_threaded_server() # remove the scheduled job since it's ran return schedule.CancelJob
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 stop_all_servers(self): servers = self.list_running_servers() logger.info("Found %s running server(s)", len(servers)) logger.info("Stopping All Servers") for s in servers: logger.info("Stopping Server ID %s (%s)", s['id'], s['name']) console.info("Stopping Server ID {} ({})".format( s['id'], s['name'])) # get object svr_obj = self.get_server_obj(s['id']) running = svr_obj.check_running() # issue the stop command self.stop_server(s['id']) # while it's running, we wait while running: logger.info( "Server %s is still running - waiting 2s to see if it stops", s['name']) console.info( "Server {} is still running - waiting 2s to see if it stops" .format(s['name'])) running = svr_obj.check_running() time.sleep(2) # let's wait 2 seconds so the remote commands get cleared and then we can do another loop time.sleep(2) logger.info("All Servers Stopped")
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 do_reload_webserver(self, line): Remote.insert({ Remote.command: 'restart_web_server', Remote.server_id: 1, Remote.command_source: 'localhost' }).execute() console.info( "Reloading Tornado Webserver, Please wait 5 seconds to reconnect")
def do_change_web_port(self, line): if int(line) > 65535: console.error("Invalid Port") return False if int(line) < 1: console.error("Invalid Port") return False Webserver.update({Webserver.port_number: int(line)}).execute() console.info("Tornado Webserver Port set to port: {}".format(line))
def do_check_update(self, line): console.info("Getting Latest Version Info:") master = helper.check_version('master') beta = helper.check_version('beta') snaps = helper.check_version('snapshot') current = helper.get_version() console.info("Master Branch has: {}.{}.{}".format( master['major'], master['minor'], master['sub'])) console.info("Beta Branch has: {}.{}.{}".format( beta['major'], beta['minor'], beta['sub'])) console.info("Snaps Branch has: {}.{}.{}".format( snaps['major'], snaps['minor'], snaps['sub'])) console.info("You are on Version: {}.{}.{}".format( current['major'], current['minor'], current['sub']))
def do_init_setup(self, server_id): if helper.is_setup_complete(): self.server_id = server_id self.name = self.get_mc_server_name(self.server_id) self.reload_settings() logger.debug("Loading Minecraft server object for server %s-%s", server_id, self.name) console.info("Loading Minecraft server object for server {}-{}".format( server_id, self.name)) # if setup is complete, we do an auto start if helper.is_setup_complete(): self.do_auto_start()
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_set_passwd(self, line): try: user = Users.get(Users.username == line).username except: console.error("User: {} Not Found".format(line)) return False new_pass = input("NEW password for: {} > ".format(user)) if len(new_pass) > 512: console.warning("Password Too Long") return False if len(new_pass) < 6: console.warning("Password Too Short") return False Users.update({ Users.password: helper.encode_pass(new_pass) }).where(Users.username == user).execute() console.info("Password for {} is now set to {}".format(user, new_pass))
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_auto_start(self): # do we want to auto launch the minecraft server? if self.settings.auto_start_server: delay = int(self.settings.auto_start_delay) logger.info( "Auto Start is Enabled - Scheduling start for %s seconds from now", delay) console.info( "Auto Start is Enabled - Scheduling start for {} seconds from now" .format(delay)) schedule.every(int(delay)).seconds.do(self.run_scheduled_server) # TODO : remove this old code after 3.0 Beta # time.sleep(int(delay)) # here we need to schedule the delay, as a function that auto kills it's schedule # delay the startup as long as the # console.info("Starting Minecraft Server {}".format(self.name)) # self.run_threaded_server() else: logger.info("Auto Start is Disabled") console.info("Auto Start is Disabled")
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 run_tornado(self, silent=False): # First, patch asyncio if needed self._asyncio_patch() # let's verify we have an SSL cert helper.create_self_signed_cert() websettings = Webserver.get() crafty_settings = Crafty_settings.get() lang = crafty_settings.language port_number = websettings.port_number web_root = helper.get_web_root_path() logger.info( "Starting Tornado HTTPS Server on port {}".format(port_number)) if not silent: console.info( "Starting Tornado HTTPS Server on port {}".format(port_number)) console.info( "https://{}:{} is up and ready for connection:".format( helper.get_local_ip(), port_number)) asyncio.set_event_loop(asyncio.new_event_loop()) tornado.template.Loader('.') tornado.locale.set_default_locale(lang) ip = helper.get_public_ip() if not silent: if ip: console.info("Your public IP is: {}".format(ip)) else: console.warning( "Unable to find your public IP\nThe service might be down, or your internet is down." ) handlers = [ (r'/', PublicHandler), (r'/([a-zA-Z]+)', PublicHandler), (r'/admin/downloadbackup', DownloadHandler), (r'/admin/(.*)', AdminHandler, dict(mcserver=self.mc_server)), (r'/ajax/(.*)', AjaxHandler, dict(mcserver=self.mc_server)), (r'/setup/(.*)', SetupHandler, dict(mcserver=self.mc_server)), (r'/static(.*)', tornado.web.StaticFileHandler, { "path": '/' }), (r'/images(.*)', tornado.web.StaticFileHandler, { "path": "/images" }), # API routes (r'/api/v1/host_stats', api_routes.GetHostStats, dict(mcserver=self.mc_server)), (r'/api/v1/server_stats', api_routes.GetServerStats, dict(mcserver=self.mc_server)), # Server related (r'/api/v1/server/send_command', api_routes.SendCommand, dict(mcserver=self.mc_server)), (r'/api/v1/server/get_logs', api_routes.GetMCLogs, dict(mcserver=self.mc_server)), (r'/api/v1/server/search_logs', api_routes.SearchMCLogs, dict(mcserver=self.mc_server)), (r'/api/v1/server/force_backup', api_routes.ForceServerBackup, dict(mcserver=self.mc_server)), (r'/api/v1/server/start', api_routes.StartServer, dict(mcserver=self.mc_server)), (r'/api/v1/server/stop', api_routes.StopServer, dict(mcserver=self.mc_server)), (r'/api/v1/server/restart', api_routes.RestartServer, dict(mcserver=self.mc_server)), (r'/api/v1/list_servers', api_routes.ListServers, dict(mcserver=self.mc_server)), # Crafty related (r'/api/v1/crafty/add_user', api_routes.CreateUser), (r'/api/v1/crafty/del_user', api_routes.DeleteUser), (r'/api/v1/crafty/get_logs', api_routes.GetCraftyLogs), (r'/api/v1/crafty/search_logs', api_routes.SearchCraftyLogs) ] cert_objects = { 'certfile': os.path.join(web_root, 'certs', 'crafty.crt'), 'keyfile': os.path.join(web_root, 'certs', 'crafty.key') } app = tornado.web.Application( handlers, template_path=os.path.join(web_root, 'templates'), static_path=os.path.join(web_root, 'static'), debug=True, cookie_secret=helper.random_string_generator(20), xsrf_cookies=True, autoreload=False, log_function=self.log_function, login_url="/", default_handler_class=My404Handler) self.http_server = tornado.httpserver.HTTPServer( app, ssl_options=cert_objects) self.http_server.listen(port_number) tornado.locale.load_translations(os.path.join(web_root, 'translations')) self.ioloop = tornado.ioloop.IOLoop.instance() self.ioloop.start()
def stop_all_children(self): console.info("Stopping any server daemons") multi.stop_all_servers() self.print_crafty_end()
else: peewee.do_database_migrations() # only import / new database tables are created do we load the rest of the things! from app.classes.ftp import ftp_svr_object # from app.classes.minecraft_server import mc_server from app.classes.http import tornado_srv from app.classes.craftycmd import MainPrompt from app.classes.minecraft_server import mc_server from app.classes.remote_coms import remote_commands from app.classes.multiserv import multi logger.info("Starting Scheduler Daemon") console.info("Starting Scheduler Daemon") scheduler = threading.Thread(name='Scheduler', target=start_scheduler, daemon=True) scheduler.start() # startup Tornado if we aren't killing all craftys tornado_srv.start_web_server(True) websettings = Webserver.get() port_number = websettings.port_number console.info("Starting Tornado HTTPS Server https://{}:{}".format(helper.get_local_ip(), port_number)) if fresh_install: console.info("Please connect to https://{}:{} to continue the install:".format( helper.get_local_ip(), port_number)) console.info("Your Username is: Admin") console.info("Your Password is: {}".format(admin_pass))
def revert_updated_server_jar(self, with_console=True): self.reload_settings() self.updating = True logger.info("Starting Jar Revert Process") if with_console: console.info("Starting Jar Revert Process") backup_dir = os.path.join(self.settings.server_path, 'crafty_jar_backups') backup_jar_name = os.path.join(backup_dir, 'old_server.jar') current_jar = os.path.join(self.settings.server_path, self.settings.server_jar) was_running = False # verify we have a backup if not helper.check_file_exists(backup_jar_name): logger.critical("Can't find server.jar backup! - can't continue") console.critical("Can't find server.jar backup! - can't continue") self.updating = False return False if self.check_running(): was_running = True logger.info("Server was running, stopping server for jar revert") if with_console: console.info( "Server was running, stopping server for jar revert") self.stop_threaded_server() # make sure the backup directory exists helper.ensure_dir_exists(backup_dir) # remove the current_server.jar if helper.check_file_exists(backup_jar_name): logger.info("Removing current server jar %s", backup_jar_name) if with_console: console.info( "Removing current server jar: {}".format(backup_jar_name)) os.remove(current_jar) logger.info("Copying old jar back") if with_console: console.info("Copying old jar back") helper.copy_file(backup_jar_name, current_jar) if was_running: logger.info( "Server was running, starting server backup after update") if with_console: console.info( "Server was running, starting server backup after update") self.run_threaded_server() self.updating = False console.info( "Server Jar Revert Completed - press enter to get the prompt back")
def do_list_users(self, line): console.info("Users defined:") all_users = Users.select().execute() for user in all_users: console.info("User: {} - Role:{}".format(user.username, user.role))
def update_server_jar(self, with_console=True): self.reload_settings() self.updating = True logger.info("Starting Jar Update Process") if with_console: console.info("Starting Jar Update Process") backup_dir = os.path.join(self.settings.server_path, 'crafty_jar_backups') backup_jar_name = os.path.join(backup_dir, 'old_server.jar') current_jar = os.path.join(self.settings.server_path, self.settings.server_jar) was_running = False if self.check_running(): was_running = True logger.info("Server was running, stopping server for jar update") if with_console: console.info( "Server was running, stopping server for jar update") self.stop_threaded_server() # make sure the backup directory exists helper.ensure_dir_exists(backup_dir) # remove the old_server.jar if helper.check_file_exists(backup_jar_name): logger.info("Removing old backup jar %s", backup_jar_name) if with_console: console.info( "Removing old backup jar {}".format(backup_jar_name)) os.remove(backup_jar_name) logger.info("Starting Server Jar Download") if with_console: console.info("Starting Server Jar Download") # backup the server jar file logger.info("Backing up Current Jar") helper.copy_file(current_jar, backup_jar_name) # download the new server jar file download_complete = helper.download_file(self.settings.jar_url, current_jar) if download_complete: logger.info("Server Jar Download Complete") if with_console: console.info("Server Jar Download Complete") else: if with_console: console.info("Server Jar Had An Error") if was_running: logger.info( "Server was running, starting server backup after update") if with_console: console.info( "Server was running, starting server backup after update") self.run_threaded_server() self.updating = False console.info( "Server Jar Update Completed - press enter to get the prompt back")
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_show_stats(self, line): multi.do_host_status() host_stats = multi.get_host_status() server_stats = multi.get_stats_for_servers() websettings = Webserver.get() port_number = websettings.port_number console.info("/" * 75) console.info("#\t\t Crafty Controller Server Stats \t\t\t#") console.info("/" * 75) console.info("Boot Time:\t {}".format(host_stats['boot_time'])) console.info("Webconsole at:\t https://{}:{}".format( helper.get_local_ip(), port_number)) console.info("-" * 75) console.info("CPU Usage:\t {}".format(host_stats['cpu_usage'])) console.info("CPU Cores:\t {}".format(host_stats['cpu_cores'])) console.info("Mem Percent:\t {}".format(host_stats['mem_percent'])) console.info("Mem Usage: \t {} / {}".format(host_stats['mem_usage'], host_stats['mem_total'])) console.info("Disk Percent:\t {}".format(host_stats['disk_percent'])) console.info("Disk Usage: \t {} / {}".format(host_stats['disk_usage'], host_stats['disk_total'])) console.info("-" * 75) console.info(" --- Minecraft Servers --- ") console.info("-" * 75) s = 1 while s <= len(server_stats): data = server_stats[s] console.info("Server ID {}".format(data['server_id'])) console.info("Running {}".format(data['server_running'])) console.info("Players: {}/{}".format(data['online_players'], data['max_players'])) s += 1 console.help("Use the list_servers command to get more detailed data")