diff --git a/app/classes/models/servers.py b/app/classes/models/servers.py index 24ad7391..43501311 100644 --- a/app/classes/models/servers.py +++ b/app/classes/models/servers.py @@ -77,6 +77,7 @@ class Server_Stats(Model): version = CharField(default="") updating = BooleanField(default=False) waiting_start = BooleanField(default=False) + first_run = BooleanField(default=True) class Meta: @@ -182,6 +183,16 @@ class helper_servers: with database.atomic(): Server_Stats.update(updating=value).where(Server_Stats.server_id == server_id).execute() + @staticmethod + def set_first_run(server_id): + #Sets first run to false + try: + row = Server_Stats.select().where(Server_Stats.server_id == server_id) + except Exception as ex: + logger.error("Database entry not found. ".format(ex)) + with database.atomic(): + Server_Stats.update(first_run=False).where(Server_Stats.server_id == server_id).execute() + @staticmethod def get_TTL_without_player(server_id): last_stat = Server_Stats.select().where(Server_Stats.server_id == server_id).order_by(Server_Stats.created.desc()).first() diff --git a/app/classes/shared/server.py b/app/classes/shared/server.py index 3dfd28ce..a85004ae 100644 --- a/app/classes/shared/server.py +++ b/app/classes/shared/server.py @@ -16,7 +16,7 @@ import html from app.classes.shared.helpers import helper from app.classes.shared.console import console -from app.classes.models.servers import Servers, servers_helper +from app.classes.models.servers import Servers, helper_servers, servers_helper from app.classes.models.management import management_helper from app.classes.web.websocket_helper import websocket_helper from app.classes.shared.translation import translation @@ -196,6 +196,8 @@ class Server: logger.info("Launching Server {} with command {}".format(self.name, self.server_command)) console.info("Launching Server {} with command {}".format(self.name, self.server_command)) + #Checks for eula. Creates one if none detected. + #If EULA is detected and not set to one of these true vaiants we offer to set it true. if helper.check_file_exists(os.path.join(self.settings['path'], 'eula.txt')): f = open(os.path.join(self.settings['path'], 'eula.txt'), 'r') line = f.readline().lower() @@ -227,7 +229,6 @@ class Server: return False return False f.close() - if helper.is_os_windows(): logger.info("Windows Detected") creationflags=subprocess.CREATE_NEW_CONSOLE @@ -237,7 +238,9 @@ class Server: logger.info("Starting server in {p} with command: {c}".format(p=self.server_path, c=self.server_command)) + #Sets waiting start to false since server is now starting. servers_helper.set_waiting_start(self.server_id, False) + try: self.process = subprocess.Popen(self.server_command, cwd=self.server_path, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) except Exception as ex: @@ -257,7 +260,7 @@ class Server: 'error': translation.translate('error', 'start-error', user_lang).format(self.name, ex) }) return False - servers_helper.set_waiting_start(self.server_id, False) + out_buf = ServerOutBuf(self.process, self.server_id) logger.debug('Starting virtual terminal listener for server {}'.format(self.name)) @@ -272,10 +275,19 @@ class Server: console.info("Server {} running with PID {}".format(self.name, self.process.pid)) self.is_crashed = False self.stats.record_stats() - websocket_helper.broadcast_user(user_id, 'send_start_reload', { - }) - check_port_thread = threading.Thread(target=self.check_internet_thread, daemon=True, args=(user_id, user_lang, ), name=f"backup_{self.name}") - check_port_thread.start() + check_internet_thread = threading.Thread(target=self.check_internet_thread, daemon=True, args=(user_id, user_lang, ), name="{self.name}_Internet") + check_internet_thread.start() + #Checks if this is the servers first run. + if servers_helper.get_server_stats_by_id(self.server_id)['first_run']: + loc_server_port = servers_helper.get_server_stats_by_id(self.server_id)['server_port'] + #Sends port reminder message. + websocket_helper.broadcast_user(user_id, 'send_start_error', { + 'error': translation.translate('error', 'portReminder', user_lang).format(self.name, loc_server_port) + }) + servers_helper.set_first_run(self.server_id) + else: + websocket_helper.broadcast_user(user_id, 'send_start_reload', { + }) else: logger.warning("Server PID {} died right after starting - is this a server config issue?".format(self.process.pid)) console.warning("Server PID {} died right after starting - is this a server config issue?".format(self.process.pid)) @@ -285,28 +297,10 @@ class Server: console.info("Server {} has crash detection enabled - starting watcher task".format(self.name)) self.crash_watcher_schedule = schedule.every(30).seconds.do(self.detect_crash).tag(self.name) - + def check_internet_thread(self, user_id, user_lang): if user_id: - if helper.check_internet(): - loc_server_port = servers_helper.get_server_stats_by_id(self.server_id)['server_port'] - port_status = False - - checked = False - while not checked: - if helper.check_server_conn(loc_server_port): - checked = True - result_of_check = helper.check_port(loc_server_port) - - if result_of_check == True: - return - else: - websocket_helper.broadcast_user(user_id, 'send_start_error', { - 'error': translation.translate('error', 'closedPort', user_lang).format(loc_server_port) - }) - else: - time.sleep(5) - else: + if not helper.check_internet(): websocket_helper.broadcast_user(user_id, 'send_start_error', { 'error': translation.translate('error', 'internet', user_lang) }) diff --git a/app/classes/web/tornado.py b/app/classes/web/tornado.py index 4e4e5866..edf58172 100644 --- a/app/classes/web/tornado.py +++ b/app/classes/web/tornado.py @@ -175,9 +175,7 @@ class Webserver: self.HTTPS_Server = tornado.httpserver.HTTPServer(app, ssl_options=cert_objects) self.HTTPS_Server.listen(https_port) - logger.info("http://{}:{} is up and ready for connections.".format(helper.get_local_ip(), http_port)) logger.info("https://{}:{} is up and ready for connections.".format(helper.get_local_ip(), https_port)) - console.info("http://{}:{} is up and ready for connections.".format(helper.get_local_ip(), http_port)) console.info("https://{}:{} is up and ready for connections.".format(helper.get_local_ip(), https_port)) console.info("Server Init Complete: Listening For Connections:") diff --git a/app/migrations/20210915205501_first_run_.py b/app/migrations/20210915205501_first_run_.py new file mode 100644 index 00000000..73f29e69 --- /dev/null +++ b/app/migrations/20210915205501_first_run_.py @@ -0,0 +1,16 @@ +# Generated by database migrator +import peewee + +def migrate(migrator, database, **kwargs): + migrator.add_columns('server_stats', first_run=peewee.BooleanField(default=True)) + """ + Write your migrations here. + """ + + + +def rollback(migrator, database, **kwargs): + migrator.drop_columns('server_stats', ['first_run']) + """ + Write your rollback migrations here. + """ diff --git a/app/translations/en_EN.json b/app/translations/en_EN.json index 8a9d605c..acdafa45 100644 --- a/app/translations/en_EN.json +++ b/app/translations/en_EN.json @@ -12,7 +12,7 @@ "embarassing": "Oh my, well, this is embarrassing.", "error": "Error!", "start-error": "Server {} failed to start with error code: {}", - "closedPort": "We have detected port {} may not be open on the host network or a firewall is blocking it. Remote client connections to the server may be limited.", + "portReminder": "We have detected this is the first time {} has been run. Make sure to forward port {} through your router/firewall to make this remotely accessible from the internet.", "internet": "We have detected the machine running Crafty has no connection to the internet. Client connections to the server may be limited.", "eulaTitle": "Agree To EULA", "eulaMsg": "You must agree to the EULA. A copy of the Mojang EULA is linked under this message.", diff --git a/app/translations/lol_EN.json b/app/translations/lol_EN.json index f12a53de..373cd230 100644 --- a/app/translations/lol_EN.json +++ b/app/translations/lol_EN.json @@ -12,7 +12,7 @@ "embarassing": "OH MAH, WELL, DIS AR TEH EMBARRASIN.", "error": "BIG OOF!", "start-error": "CHAIR {} FAILD 2 START WIF OOF CODE: {}", - "closedPort": "WE HAS DETECTD CAT FLAP {} CUD NOT BE OPEN ON TEH WARM CHAIR'Z NETWORK OR FIREWAL IZ BLOCKIN IT. REMOTE HOOMAN CONNECSHUNS 2 TEH CHAIR CUD BE LIMITD.", + "portReminder": "WE HAS DETECTD DIS AR TEH FURST TIEM {} IZ BEAN RUN. IF U WANTS IT ACESIBLE TO NEIGHBORHOOD CATS PLZ UNLOCK CAT_FLAP, {}, THRU UR ROUTR IF U HAS NOT DUN SO.", "internet": "WE HAS DETECTD TEH BIG BOX RUNNIN CRAFTY HAS NO CONNECSHUN 2 TEH INTERNET. HOOMAN CONNECSHUNS 2 TEH SERVR CUD BE LIMITD.", "eulaTitle": "SAYZ YESH TWOO TEH LEGAL-WEEGALS", "eulaMsg": "U MUST SAY YESH. COPY OV TEH MOJANG EULA IZ LINKD UNDR DIS MESAGE.", diff --git a/main.py b/main.py index 68633e62..dcb20028 100644 --- a/main.py +++ b/main.py @@ -37,22 +37,6 @@ def do_intro(): console.magenta(intro) -def check_port_thread(): - port = helper.get_setting('https_port') - checked = False - while not checked: - if helper.check_server_conn(port): - checked = True - result_of_check = helper.check_port(port) - if result_of_check == True: - return - else: - console.warning("We have detected Crafty's port, {} may not be open on the host network or a firewall is blocking it. Remote client connections to Crafty may be limited.".format(helper.get_setting('https_port'))) - console.help("If you are not forwarding ports from your public IP or your router does not support hairpin NAT you can safely disregard the previous message.") - else: - time.sleep(5) - return - def setup_logging(debug=True): logging_config_file = os.path.join(os.path.curdir, @@ -128,6 +112,7 @@ if __name__ == '__main__': if fresh_install: console.debug("Fresh install detected") + console.warning("We have detected a fresh install. Please be sure to forward Crafty's port, {}, through your router/firewall if you would like to be able to access Crafty remotely.".format(helper.get_setting('https_port'))) installer.default_settings() else: console.debug("Existing install detected") @@ -160,8 +145,6 @@ if __name__ == '__main__': if not helper.check_internet(): console.warning("We have detected the machine running Crafty has no connection to the internet. Client connections to the server may be limited.") - check_port_thread = threading.Thread(target=check_port_thread, daemon=True, name="crafty_port_check") - check_port_thread.start() if not controller.check_system_user(): controller.add_system_user()