mirror of
https://github.com/RYDE-WORK/ballistica.git
synced 2026-01-29 10:43:21 +08:00
server-wrapper hardening
This commit is contained in:
parent
a09232daa1
commit
3245507578
@ -420,7 +420,7 @@
|
||||
"assets/build/ba_data/audio/zoeOw.ogg": "https://files.ballistica.net/cache/ba1/a9/71/9286d55c45c37877f3267850f90b",
|
||||
"assets/build/ba_data/audio/zoePickup01.ogg": "https://files.ballistica.net/cache/ba1/2f/09/36e691de67eb8f155449a7170861",
|
||||
"assets/build/ba_data/audio/zoeScream01.ogg": "https://files.ballistica.net/cache/ba1/fd/a8/ad50785ce206e8dc3dcc7358b173",
|
||||
"assets/build/ba_data/data/langdata.json": "https://files.ballistica.net/cache/ba1/29/af/04afc95d95a712c79207291083ba",
|
||||
"assets/build/ba_data/data/langdata.json": "https://files.ballistica.net/cache/ba1/91/b8/a48083094a02608f5dff387d3469",
|
||||
"assets/build/ba_data/data/languages/arabic.json": "https://files.ballistica.net/cache/ba1/ac/3e/c50dc4e98df47f858c3a73ac4272",
|
||||
"assets/build/ba_data/data/languages/belarussian.json": "https://files.ballistica.net/cache/ba1/44/ed/5b972fa848cffb73723533c2ccb7",
|
||||
"assets/build/ba_data/data/languages/chinese.json": "https://files.ballistica.net/cache/ba1/9d/63/d360eeff63bc64e098427498880d",
|
||||
@ -444,7 +444,7 @@
|
||||
"assets/build/ba_data/data/languages/polish.json": "https://files.ballistica.net/cache/ba1/cd/c1/82bf70c3ee4894791506f4da1a15",
|
||||
"assets/build/ba_data/data/languages/portuguese.json": "https://files.ballistica.net/cache/ba1/98/45/ddeb7e797c02fb967e0c8b0dff7d",
|
||||
"assets/build/ba_data/data/languages/romanian.json": "https://files.ballistica.net/cache/ba1/44/3c/7cc06ca8d5475e1687d0ed05bdbf",
|
||||
"assets/build/ba_data/data/languages/russian.json": "https://files.ballistica.net/cache/ba1/ab/44/3d8b939f0c177cc46e8b0e4cae74",
|
||||
"assets/build/ba_data/data/languages/russian.json": "https://files.ballistica.net/cache/ba1/15/e2/08ce8831b3a6ee2a5324a4112b04",
|
||||
"assets/build/ba_data/data/languages/serbian.json": "https://files.ballistica.net/cache/ba1/e1/22/5471375791f8825a63e06371df29",
|
||||
"assets/build/ba_data/data/languages/slovak.json": "https://files.ballistica.net/cache/ba1/b7/0a/fab820b96e7aa587ee56427ecdc2",
|
||||
"assets/build/ba_data/data/languages/spanish.json": "https://files.ballistica.net/cache/ba1/72/6a/55e4f8ce819d0c39ee6d86e8c6a0",
|
||||
|
||||
@ -89,6 +89,7 @@ class ServerManagerApp:
|
||||
self._subprocess_sent_clean_exit = False
|
||||
self._subprocess_sent_unclean_exit = False
|
||||
self._subprocess_thread: Optional[Thread] = None
|
||||
self._subprocess_exited_cleanly: bool = False
|
||||
|
||||
# This may override the above defaults.
|
||||
self._parse_command_line_args()
|
||||
@ -584,23 +585,42 @@ class ServerManagerApp:
|
||||
if os.name == 'nt' else './ballisticacore_headless')
|
||||
assert self._ba_root_path is not None
|
||||
self._subprocess = None
|
||||
|
||||
# Launch!
|
||||
try:
|
||||
self._subprocess = subprocess.Popen(
|
||||
[binary_name, '-cfgdir', self._ba_root_path],
|
||||
stdin=subprocess.PIPE,
|
||||
cwd='dist')
|
||||
except Exception as exc:
|
||||
print(f'Error launching server subprocess: {exc}',
|
||||
print(
|
||||
f'{Clr.RED}Error launching server subprocess: {exc}{Clr.RST}',
|
||||
file=sys.stderr,
|
||||
flush=True)
|
||||
|
||||
# Do the thing.
|
||||
try:
|
||||
self._run_subprocess_until_exit()
|
||||
except Exception as exc:
|
||||
print(f'{Clr.RED}Error running server subprocess: {exc}{Clr.RST}',
|
||||
file=sys.stderr,
|
||||
flush=True)
|
||||
|
||||
# Do the thing.
|
||||
# No matter how this ends up, make sure the process is dead after.
|
||||
if self._subprocess is not None:
|
||||
try:
|
||||
self._run_subprocess_until_exit()
|
||||
finally:
|
||||
self._kill_subprocess()
|
||||
self._kill_subprocess()
|
||||
|
||||
# Avoid super fast death loops.
|
||||
if (not self._subprocess_exited_cleanly and self._auto_restart
|
||||
and not self._done):
|
||||
time.sleep(5.0)
|
||||
|
||||
# If they don't want auto-restart, we'll exit the whole wrapper.
|
||||
# (and with an error code if things ended badly).
|
||||
if not self._auto_restart:
|
||||
self._wrapper_shutdown_desired = True
|
||||
if not self._subprocess_exited_cleanly:
|
||||
self._should_report_subprocess_error = True
|
||||
|
||||
self._reset_subprocess_vars()
|
||||
|
||||
# If we want to die completely after this subprocess has ended,
|
||||
# tell the main thread to die.
|
||||
@ -662,8 +682,10 @@ class ServerManagerApp:
|
||||
self._subprocess.stdin.flush()
|
||||
|
||||
def _run_subprocess_until_exit(self) -> None:
|
||||
if self._subprocess is None:
|
||||
return
|
||||
|
||||
assert current_thread() is self._subprocess_thread
|
||||
assert self._subprocess is not None
|
||||
assert self._subprocess.stdin is not None
|
||||
|
||||
# Send the initial server config which should kick things off.
|
||||
@ -706,25 +728,13 @@ class ServerManagerApp:
|
||||
code: Optional[int] = self._subprocess.poll()
|
||||
if code is not None:
|
||||
|
||||
# If they don't want auto-restart, exit the whole wrapper.
|
||||
# (and make sure to exit with an error code if things ended
|
||||
# badly here).
|
||||
if not self._auto_restart:
|
||||
self._wrapper_shutdown_desired = True
|
||||
if code != 0:
|
||||
self._should_report_subprocess_error = True
|
||||
|
||||
clr = Clr.CYN if code == 0 else Clr.RED
|
||||
print(
|
||||
f'{clr}Server subprocess exited'
|
||||
f' with code {code}.{Clr.RST}',
|
||||
file=sys.stderr,
|
||||
flush=True)
|
||||
self._reset_subprocess_vars()
|
||||
|
||||
# Avoid super fast death loops.
|
||||
if code != 0 and self._auto_restart:
|
||||
time.sleep(5.0)
|
||||
self._subprocess_exited_cleanly = (code == 0)
|
||||
break
|
||||
|
||||
time.sleep(0.25)
|
||||
@ -809,6 +819,7 @@ class ServerManagerApp:
|
||||
self._subprocess_sent_clean_exit = False
|
||||
self._subprocess_sent_unclean_exit = False
|
||||
self._subprocess_force_kill_time = None
|
||||
self._subprocess_exited_cleanly = False
|
||||
|
||||
def _kill_subprocess(self) -> None:
|
||||
"""End the server subprocess if it still exists."""
|
||||
@ -827,7 +838,6 @@ class ServerManagerApp:
|
||||
self._subprocess.wait(timeout=10)
|
||||
except subprocess.TimeoutExpired:
|
||||
self._subprocess.kill()
|
||||
self._reset_subprocess_vars()
|
||||
print(f'{Clr.CYN}Subprocess stopped.{Clr.RST}',
|
||||
file=sys.stderr,
|
||||
flush=True)
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user