diff --git a/evennia/server/evennia_launcher.py b/evennia/server/evennia_launcher.py index 2f9206b4c1..c83d869336 100644 --- a/evennia/server/evennia_launcher.py +++ b/evennia/server/evennia_launcher.py @@ -467,9 +467,10 @@ ARG_OPTIONS = \ stop - shutdown server+portal reboot - shutdown server+portal, then start again reset - restart server in 'shutdown' mode - sstart - start only server (requires portal) + istart - start server in the foreground (until reload) + sstop - stop only server kill - send kill signal to portal+server (force) - skill = send kill signal only to server + skill - send kill signal only to server status - show server and portal run state info - show server and portal port info menu - show a menu of options @@ -955,14 +956,39 @@ def reboot_evennia(pprofiler=False, sprofiler=False): send_instruction(PSTATUS, None, _portal_running, _portal_not_running) -def stop_server_only(): +def start_server_interactive(): + """ + Start the Server under control of the launcher process (foreground) + + """ + def _iserver(): + _, server_twistd_cmd = _get_twistd_cmdline(False, False) + server_twistd_cmd.append("--nodaemon") + print("Starting Server in interactive mode (stop with Ctrl-C)...") + try: + Popen(server_twistd_cmd, env=getenv(), stderr=STDOUT).wait() + except KeyboardInterrupt: + print("... Stopped Server with Ctrl-C.") + else: + print("... Server stopped (leaving interactive mode).") + stop_server_only(when_stopped=_iserver) + + +def stop_server_only(when_stopped=None): """ Only stop the Server-component of Evennia (this is not useful except for debug) + Args: + when_stopped (callable): This will be called with no arguments when Server has stopped (or + if it had already stopped when this is called). + """ def _server_stopped(*args): - print("... Server stopped.") - _reactor_stop() + if when_stopped: + when_stopped() + else: + print("... Server stopped.") + _reactor_stop() def _portal_running(response): _, srun, _, _, _, _ = _parse_status(response) @@ -971,8 +997,11 @@ def stop_server_only(): wait_for_status_reply(_server_stopped) send_instruction(SSHUTD, {}) else: - print("Server is not running.") - _reactor_stop() + if when_stopped: + when_stopped() + else: + print("Server is not running.") + _reactor_stop() def _portal_not_running(fail): print("Evennia is not running.") @@ -1937,7 +1966,7 @@ def main(): # launch menu for operation init_game_directory(CURRENT_DIR, check_db=True) run_menu() - elif option in ('status', 'info', 'start', 'reload', 'reboot', + elif option in ('status', 'info', 'start', 'istart', 'reload', 'reboot', 'reset', 'stop', 'sstop', 'kill', 'skill'): # operate the server directly if not SERVER_LOGFILE: @@ -1948,6 +1977,8 @@ def main(): query_info() elif option == "start": start_evennia(args.profiler, args.profiler) + elif option == "istart": + start_server_interactive() elif option == 'reload': reload_evennia(args.profiler) elif option == 'reboot': diff --git a/evennia/server/server.py b/evennia/server/server.py index e42c85bae7..5a225704c2 100644 --- a/evennia/server/server.py +++ b/evennia/server/server.py @@ -507,10 +507,11 @@ ServerConfig.objects.conf("server_starting_mode", True) # what to execute from. application = service.Application('Evennia') -# custom logging -logfile = logger.WeeklyLogFile(os.path.basename(settings.SERVER_LOG_FILE), - os.path.dirname(settings.SERVER_LOG_FILE)) -application.setComponent(ILogObserver, logger.ServerLogObserver(logfile).emit) +if "--nodaemon" not in sys.argv: + # custom logging, but only if we are not running in interactive mode + logfile = logger.WeeklyLogFile(os.path.basename(settings.SERVER_LOG_FILE), + os.path.dirname(settings.SERVER_LOG_FILE)) + application.setComponent(ILogObserver, logger.ServerLogObserver(logfile).emit) # The main evennia server program. This sets up the database # and is where we store all the other services.