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)