def crash_detected(self, name): # let's make sure the settings are setup right self.reload_settings() # the server crashed, or isn't found - so let's reset things. logger.warning( "The server %s seems to have vanished unexpectedly, did it crash?", name) if self.settings.crash_detection: logger.info( "The server %s has crashed and will be restarted. Restarting server", name) webhookmgr.run_event_webhooks( "mc_crashed", webhookmgr.payload_formatter( 200, {}, { "server": { "name": self.get_mc_server_name(), "id": self.server_id, "running": not self.PID is None, "PID": self.PID, "restart_count": self.restart_count } }, {"info": "Minecraft Server has crashed"})) self.run_threaded_server() return True else: webhookmgr.run_event_webhooks( "mc_crashed_no_restart", webhookmgr.payload_formatter(200, {}, { "server": { "name": self.get_mc_server_name(), "id": self.server_id, "running": not self.PID is None, "PID": self.PID, "restart_count": self.restart_count } }, { "info": "Minecraft Server has crashed too much, auto restart disabled" })) logger.info( "The server %s has crashed, crash detection is disabled and it will not be restarted", name) return False
def stop_server(self): # remove any scheduled tasks for this server schedule.clear(self.name) if self.detect_bungee_waterfall(): logger.info( 'Waterfall/Bungee Detected: Sending shutdown command "end" to server ID:{} - {}' .format(self.server_id, self.name)) self.send_command("end") else: logger.info( 'Sending shutdown command "stop" to server ID:{} - {}'.format( self.server_id, self.name)) self.send_command("stop") for x in range(6): self.PID = None if self.check_running(True): logger.debug("Polling says Minecraft server %s is running", self.name) time.sleep(10) # now the server is dead, we set process to none else: logger.debug("Minecraft server %s has stopped", self.name) self.cleanup_server_object() # return true as the server is down webhookmgr.run_event_webhooks( "mc_stop", webhookmgr.payload_formatter( 200, {}, { "server": { "name": self.get_mc_server_name(), "id": self.server_id, "running": not self.PID is None, "PID": self.PID, "restart_count": self.restart_count } }, {"info": "Minecraft Server has stopped"})) return True # if we got this far, the server isn't responding, and needs to be forced down logger.critical( "Unable to stop the server %s. Terminating it via SIGKILL > %s", self.name, self.PID) webhookmgr.run_event_webhooks( "mc_stop", webhookmgr.payload_formatter(500, {"error": "SER_STOP_FAIL"}, { "server": { "name": self.get_mc_server_name(), "id": self.server_id, "running": not self.PID is None, "PID": self.PID, "restart_count": self.restart_count } }, { "info": "Minecraft Server has not gracefully stopped. Terminating." })) self.killpid(self.PID)
def start_server(self): # fail safe in case we try to start something already running if self.check_running(): logger.error("Server is already running - Cancelling Startup") return False if not self.jar_exists: console.warning("Minecraft server JAR does not exist...") logger.critical("Minecraft server JAR does not exists...") return False if not self.java_path_exists: console.warning("Minecraft server Java path does not exist...") logger.critical("Minecraft server Java path does not exist...") return False if not helper.check_writeable(self.server_path): console.warning("Unable to write/access {}".format( self.server_path)) logger.critical("Unable to write/access {}".format( self.server_path)) return False logger.info("Launching Minecraft server %s with command %s", self.name, self.server_command) if os.name == "nt": logger.info("Windows Detected - launching cmd") self.server_command = self.server_command.replace('\\', '/') logging.info("Opening CMD prompt") self.process = pexpect.popen_spawn.PopenSpawn('cmd \r\n', timeout=None, encoding=None) drive_letter = self.server_path[:1] if drive_letter.lower() != "c": logger.info( "Server is not on the C drive, changing drive letter to {}:" .format(drive_letter)) self.process.send("{}:\r\n".format(drive_letter)) logging.info("changing directories to {}".format( self.server_path.replace('\\', '/'))) self.process.send('cd {} \r\n'.format( self.server_path.replace('\\', '/'))) logging.info("Sending command {} to CMD".format( self.server_command)) self.process.send(self.server_command + "\r\n") self.is_crashed = False else: logger.info("Linux Detected - launching Bash") self.process = pexpect.popen_spawn.PopenSpawn('/bin/bash \n', timeout=None, encoding=None) logger.info("Changing directory to %s", self.server_path) self.process.send('cd {} \n'.format(self.server_path)) logger.info("Sending server start command: {} to shell".format( self.server_command)) self.process.send(self.server_command + '\n') self.is_crashed = False ts = time.time() self.start_time = str( datetime.datetime.fromtimestamp(ts).strftime('%Y-%m-%d %H:%M:%S')) if psutil.pid_exists(self.process.pid): parent = psutil.Process(self.process.pid) time.sleep(.5) children = parent.children(recursive=True) for c in children: self.PID = c.pid logger.info("Minecraft server %s running with PID %s", self.name, self.PID) webhookmgr.run_event_webhooks( "mc_start", webhookmgr.payload_formatter( 200, {}, { "server": { "name": self.get_mc_server_name(), "id": self.server_id, "running": not self.PID is None, "PID": self.PID, "restart_count": self.restart_count } }, {"info": "Minecraft Server has started"})) self.is_crashed = False else: webhookmgr.run_event_webhooks( "mc_start", webhookmgr.payload_formatter(500, {"error": "SER_DIED"}, { "server": { "name": self.get_mc_server_name(), "id": self.server_id, "running": not self.PID is None, "PID": self.PID, "restart_count": self.restart_count } }, { "info": "Minecraft Server died right after startup! Config issue?" })) logger.warning( "Server PID %s died right after starting - is this a server config issue?", self.PID) if self.settings.crash_detection: logger.info( "Server %s has crash detection enabled - starting watcher task", self.name) schedule.every(30).seconds.do(self.check_running).tag(self.name)