Server config can now be toml OR json.

This commit is contained in:
Eric 2024-04-26 11:45:41 -07:00
parent ac28d632d9
commit ba6b01e31f
No known key found for this signature in database
GPG Key ID: 89C93F0F8D6D5A98
6 changed files with 109 additions and 63 deletions

56
.efrocachemap generated
View File

@ -4038,26 +4038,26 @@
"build/assets/windows/Win32/ucrtbased.dll": "2def5335207d41b21b9823f6805997f1", "build/assets/windows/Win32/ucrtbased.dll": "2def5335207d41b21b9823f6805997f1",
"build/assets/windows/Win32/vc_redist.x86.exe": "b08a55e2e77623fe657bea24f223a3ae", "build/assets/windows/Win32/vc_redist.x86.exe": "b08a55e2e77623fe657bea24f223a3ae",
"build/assets/windows/Win32/vcruntime140d.dll": "865b2af4d1e26a1a8073c89acb06e599", "build/assets/windows/Win32/vcruntime140d.dll": "865b2af4d1e26a1a8073c89acb06e599",
"build/prefab/full/linux_arm64_gui/debug/ballisticakit": "e553487272cc8d9ea777a5b7d16ba62e", "build/prefab/full/linux_arm64_gui/debug/ballisticakit": "ca2e5467c9fd0d6011fd437570cd91db",
"build/prefab/full/linux_arm64_gui/release/ballisticakit": "b979f63bcc3f53841d7b89ae1be26504", "build/prefab/full/linux_arm64_gui/release/ballisticakit": "cd78f8c891f2a479e80ff887b44f68a6",
"build/prefab/full/linux_arm64_server/debug/dist/ballisticakit_headless": "a282c22c281c3234665f1e7421fd80c6", "build/prefab/full/linux_arm64_server/debug/dist/ballisticakit_headless": "d438465da7e25c63a8258de633825def",
"build/prefab/full/linux_arm64_server/release/dist/ballisticakit_headless": "eb02b5727311db707a4372c4733eeb49", "build/prefab/full/linux_arm64_server/release/dist/ballisticakit_headless": "b61895c9e4d1a24223f7920b3f6de4f1",
"build/prefab/full/linux_x86_64_gui/debug/ballisticakit": "b7824de9695fe9219d07fcf96e039a16", "build/prefab/full/linux_x86_64_gui/debug/ballisticakit": "ab522dc854d311423280342ce73dc043",
"build/prefab/full/linux_x86_64_gui/release/ballisticakit": "5fe54ba7d7250a4e88203ddc7d122d72", "build/prefab/full/linux_x86_64_gui/release/ballisticakit": "21d99edd90998395c233d8c584d71037",
"build/prefab/full/linux_x86_64_server/debug/dist/ballisticakit_headless": "d36e3dfb83b4d4a4eeb3c5221a230d31", "build/prefab/full/linux_x86_64_server/debug/dist/ballisticakit_headless": "9c27b58189514fe65164956c8e12aa70",
"build/prefab/full/linux_x86_64_server/release/dist/ballisticakit_headless": "676a86a2235dc5feeb5b2ac50faef8c3", "build/prefab/full/linux_x86_64_server/release/dist/ballisticakit_headless": "044aff1f8c7bcb723fa924c06ca0f35c",
"build/prefab/full/mac_arm64_gui/debug/ballisticakit": "b094a46a8d4376f0de49e51b979b8833", "build/prefab/full/mac_arm64_gui/debug/ballisticakit": "ec8479f0c4b2e0931cfbbb32adb4e7b3",
"build/prefab/full/mac_arm64_gui/release/ballisticakit": "a54c48845d6a222083e27a8eeacfcf4f", "build/prefab/full/mac_arm64_gui/release/ballisticakit": "fe1689f1f9265566f1cce654e8fb799c",
"build/prefab/full/mac_arm64_server/debug/dist/ballisticakit_headless": "fbe8abc5d637fd945a0c9cee358e32ae", "build/prefab/full/mac_arm64_server/debug/dist/ballisticakit_headless": "371a5f6316096fab814421c8ec1fd715",
"build/prefab/full/mac_arm64_server/release/dist/ballisticakit_headless": "e85ad52a005548cdffec2d3f68c76c6c", "build/prefab/full/mac_arm64_server/release/dist/ballisticakit_headless": "67fded9b0202808732cb229bd5a3a7ad",
"build/prefab/full/mac_x86_64_gui/debug/ballisticakit": "31d588a5bde8b2028129001b5b3be192", "build/prefab/full/mac_x86_64_gui/debug/ballisticakit": "77b1f6783cc04529c81f9f0235298b9d",
"build/prefab/full/mac_x86_64_gui/release/ballisticakit": "a9df28724e77a4f241561a8da401c6a4", "build/prefab/full/mac_x86_64_gui/release/ballisticakit": "95ad8571c5f2eade0d02860d047718d6",
"build/prefab/full/mac_x86_64_server/debug/dist/ballisticakit_headless": "0d56f8b4c531f6e7f2d33bc0a5fd4ef2", "build/prefab/full/mac_x86_64_server/debug/dist/ballisticakit_headless": "82b1dfb87c807c9feb68df7d2af7801f",
"build/prefab/full/mac_x86_64_server/release/dist/ballisticakit_headless": "931e8d780ca39a9b4f6878c15cf34283", "build/prefab/full/mac_x86_64_server/release/dist/ballisticakit_headless": "fa7020b5487fc1112a4dea7a771e353e",
"build/prefab/full/windows_x86_gui/debug/BallisticaKit.exe": "120259c59b3584db3b6e16711cc01c10", "build/prefab/full/windows_x86_gui/debug/BallisticaKit.exe": "51674afa0617784af56456f7c3b64978",
"build/prefab/full/windows_x86_gui/release/BallisticaKit.exe": "e6e8c688fd2540ba3f0402236d91fa2d", "build/prefab/full/windows_x86_gui/release/BallisticaKit.exe": "1fe133e0da2c0d803ae27b3d2cc249b5",
"build/prefab/full/windows_x86_server/debug/dist/BallisticaKitHeadless.exe": "47eaa7e4c28292f47ab50aa90120325a", "build/prefab/full/windows_x86_server/debug/dist/BallisticaKitHeadless.exe": "9aea6af15fcccf541b499e3da18a4351",
"build/prefab/full/windows_x86_server/release/dist/BallisticaKitHeadless.exe": "2858480f76f850ace31a37bc7ff5aeab", "build/prefab/full/windows_x86_server/release/dist/BallisticaKitHeadless.exe": "79e87c8b51a7989783f4b6c3ea2a256f",
"build/prefab/lib/linux_arm64_gui/debug/libballisticaplus.a": "e40234644df79316d71808a731ba14f0", "build/prefab/lib/linux_arm64_gui/debug/libballisticaplus.a": "e40234644df79316d71808a731ba14f0",
"build/prefab/lib/linux_arm64_gui/release/libballisticaplus.a": "8563857336ffcf40abfeac81fc3955eb", "build/prefab/lib/linux_arm64_gui/release/libballisticaplus.a": "8563857336ffcf40abfeac81fc3955eb",
"build/prefab/lib/linux_arm64_server/debug/libballisticaplus.a": "e40234644df79316d71808a731ba14f0", "build/prefab/lib/linux_arm64_server/debug/libballisticaplus.a": "e40234644df79316d71808a731ba14f0",
@ -4074,14 +4074,14 @@
"build/prefab/lib/mac_x86_64_gui/release/libballisticaplus.a": "9768548c6dfdff65fb25661540025ffe", "build/prefab/lib/mac_x86_64_gui/release/libballisticaplus.a": "9768548c6dfdff65fb25661540025ffe",
"build/prefab/lib/mac_x86_64_server/debug/libballisticaplus.a": "1a0cc7e78dc66dec6ee85a8a0d68aefd", "build/prefab/lib/mac_x86_64_server/debug/libballisticaplus.a": "1a0cc7e78dc66dec6ee85a8a0d68aefd",
"build/prefab/lib/mac_x86_64_server/release/libballisticaplus.a": "9768548c6dfdff65fb25661540025ffe", "build/prefab/lib/mac_x86_64_server/release/libballisticaplus.a": "9768548c6dfdff65fb25661540025ffe",
"build/prefab/lib/windows/Debug_Win32/BallisticaKitGenericPlus.lib": "d0ebeba4c65ae9d39e831e30ee526022", "build/prefab/lib/windows/Debug_Win32/BallisticaKitGenericPlus.lib": "56462426bd911948c0e88fa6c5f94cc0",
"build/prefab/lib/windows/Debug_Win32/BallisticaKitGenericPlus.pdb": "85d436353222ca21a15d71602753a5e6", "build/prefab/lib/windows/Debug_Win32/BallisticaKitGenericPlus.pdb": "b1e15a8626bae1eccf7ebac12969e629",
"build/prefab/lib/windows/Debug_Win32/BallisticaKitHeadlessPlus.lib": "73d6b99a4e8ada86a0328e62d33b3683", "build/prefab/lib/windows/Debug_Win32/BallisticaKitHeadlessPlus.lib": "ee487ee3624f5818c4231b4f2d2bcc0f",
"build/prefab/lib/windows/Debug_Win32/BallisticaKitHeadlessPlus.pdb": "f6203b004d00432c08c2f47f170111b8", "build/prefab/lib/windows/Debug_Win32/BallisticaKitHeadlessPlus.pdb": "af95530e8c5919789393a991065740d6",
"build/prefab/lib/windows/Release_Win32/BallisticaKitGenericPlus.lib": "f1f41e53e35805a071f86c252adcb517", "build/prefab/lib/windows/Release_Win32/BallisticaKitGenericPlus.lib": "4e61cced1e4adb4c68195738e90d216a",
"build/prefab/lib/windows/Release_Win32/BallisticaKitGenericPlus.pdb": "4addbf2b7b2bc99e13d91f5b14660239", "build/prefab/lib/windows/Release_Win32/BallisticaKitGenericPlus.pdb": "c84f1f4036f79da07cc7f902c514932c",
"build/prefab/lib/windows/Release_Win32/BallisticaKitHeadlessPlus.lib": "585587b1488674c182f67b77fe7bcf4e", "build/prefab/lib/windows/Release_Win32/BallisticaKitHeadlessPlus.lib": "158b3c50b56657b3dddd3955d29c2c68",
"build/prefab/lib/windows/Release_Win32/BallisticaKitHeadlessPlus.pdb": "a8a272cd5146456f654d7b154e512404", "build/prefab/lib/windows/Release_Win32/BallisticaKitHeadlessPlus.pdb": "b8040d0ced3e1678f40aaee32d73f6ca",
"src/assets/ba_data/python/babase/_mgen/__init__.py": "f885fed7f2ed98ff2ba271f9dbe3391c", "src/assets/ba_data/python/babase/_mgen/__init__.py": "f885fed7f2ed98ff2ba271f9dbe3391c",
"src/assets/ba_data/python/babase/_mgen/enums.py": "b611c090513a21e2fe90e56582724e9d", "src/assets/ba_data/python/babase/_mgen/enums.py": "b611c090513a21e2fe90e56582724e9d",
"src/ballistica/base/mgen/pyembed/binding_base.inc": "72bfed2cce8ff19741989dec28302f3f", "src/ballistica/base/mgen/pyembed/binding_base.inc": "72bfed2cce8ff19741989dec28302f3f",

View File

@ -1,4 +1,4 @@
### 1.7.34 (build 21821, api 8, 2024-04-25) ### 1.7.34 (build 21823, api 8, 2024-04-26)
- Bumped Python version from 3.11 to 3.12 for all builds and project tools. One - Bumped Python version from 3.11 to 3.12 for all builds and project tools. One
of the things this means is that we can use `typing.override` instead of the of the things this means is that we can use `typing.override` instead of the
`typing_extensions` version so the annoying requirement of installing `typing_extensions` version so the annoying requirement of installing
@ -44,6 +44,15 @@
- (build 21810) Fixed an issue where AppSubsystems could get inited multiple - (build 21810) Fixed an issue where AppSubsystems could get inited multiple
times (due to functools.cached_property no longer being thread-safe in Python times (due to functools.cached_property no longer being thread-safe in Python
3.12). 3.12).
- The server config file is now in `toml` format instead of `yaml`. Python has
built in support for reading `toml` as of 3.11 which means we don't have to
bundle extra packages, and `toml` has more of a clean minimal design that
works well for config files. Also I plan to use it for AssetPackage
configuration stuff so this keeps things consistent.
- The server config can now be set to a `.json` file as an alternative to the
default `.toml`. This can be handy when procedurally generating server
configs. If no `--config` path is explicitly passed, it will look for
`config.json` and `config.toml` in the same dir as the script in that order.
### 1.7.33 (build 21795, api 8, 2024-03-24) ### 1.7.33 (build 21795, api 8, 2024-03-24)
- Stress test input-devices are now a bit smarter; they won't press any buttons - Stress test input-devices are now a bit smarter; they won't press any buttons
@ -601,11 +610,6 @@
can be useful for core engine code to directly and clearly point out problems can be useful for core engine code to directly and clearly point out problems
that cannot be recovered from (Exceptions in such cases can tend to be that cannot be recovered from (Exceptions in such cases can tend to be
'handled' which leads to a broken or crashing app). 'handled' which leads to a broken or crashing app).
- The server config file is now in `toml` format instead of `yaml`. Python has
built in support for reading `toml` as of 3.11 which means we don't have to
bundle extra packages, and `toml` has more of a clean minimal design that
works well for config files. Also I plan to use it for AssetPackage
configuration stuff so this keeps things consistent.
### 1.7.23 (build 21178, api 8, 2023-07-19) ### 1.7.23 (build 21178, api 8, 2023-07-19)

View File

@ -1275,7 +1275,7 @@ VENV_PYTHON ?= python3.12
# Increment this to force all downstream venvs to fully rebuild. Useful after # Increment this to force all downstream venvs to fully rebuild. Useful after
# removing requirements since upgrading in place will never uninstall stuff. # removing requirements since upgrading in place will never uninstall stuff.
VENV_STATE = 0 VENV_STATE = 1
# Rebuild our virtual environment whenever reqs, Python version, or explicit # Rebuild our virtual environment whenever reqs, Python version, or explicit
# state number changes. This is a dependency of env so it should not itself # state number changes. This is a dependency of env so it should not itself

View File

@ -52,7 +52,7 @@ if TYPE_CHECKING:
# Build number and version of the ballistica binary we expect to be # Build number and version of the ballistica binary we expect to be
# using. # using.
TARGET_BALLISTICA_BUILD = 21821 TARGET_BALLISTICA_BUILD = 21823
TARGET_BALLISTICA_VERSION = '1.7.34' TARGET_BALLISTICA_VERSION = '1.7.34'

View File

@ -1,15 +1,17 @@
#!/usr/bin/env python3.12 #!/usr/bin/env python3.12
# Released under the MIT License. See LICENSE for details. # Released under the MIT License. See LICENSE for details.
# #
# pylint: disable=too-many-lines
"""BallisticaKit server manager.""" """BallisticaKit server manager."""
from __future__ import annotations from __future__ import annotations
import json
import os import os
import signal
import subprocess
import sys import sys
import time import time
import json
import signal
import tomllib
import subprocess
from pathlib import Path from pathlib import Path
from threading import Lock, Thread, current_thread from threading import Lock, Thread, current_thread
from typing import TYPE_CHECKING from typing import TYPE_CHECKING
@ -41,6 +43,10 @@ VERSION_STR = '1.3.2'
# #
# - Server config file is now in toml format instead of yaml. # - Server config file is now in toml format instead of yaml.
# #
# - Server config can now be set to a .json file OR a .toml file.
# By default it will look for 'config.json' and then 'config.toml'
# in the same dir as this script.
#
# 1.3.1 # 1.3.1
# #
# - Windows binary is now named 'BallisticaKitHeadless.exe'. # - Windows binary is now named 'BallisticaKitHeadless.exe'.
@ -103,8 +109,7 @@ class ServerManagerApp:
IMMEDIATE_SHUTDOWN_TIME_LIMIT = 5.0 IMMEDIATE_SHUTDOWN_TIME_LIMIT = 5.0
def __init__(self) -> None: def __init__(self) -> None:
self._config_path = 'config.toml' self._user_provided_config_path: str | None = None
self._user_provided_config_path = False
self._config = ServerConfig() self._config = ServerConfig()
self._ba_root_path = os.path.abspath('dist/ba_root') self._ba_root_path = os.path.abspath('dist/ba_root')
self._interactive = sys.stdin.isatty() self._interactive = sys.stdin.isatty()
@ -127,13 +132,14 @@ class ServerManagerApp:
self._subprocess_sent_unclean_exit = False self._subprocess_sent_unclean_exit = False
self._subprocess_thread: Thread | None = None self._subprocess_thread: Thread | None = None
self._subprocess_exited_cleanly: bool | None = None self._subprocess_exited_cleanly: bool | None = None
self._did_multi_config_warning = False
# This may override the above defaults. # This may override the above defaults.
self._parse_command_line_args() self._parse_command_line_args()
# Do an initial config-load. If the config is invalid at this # Do an initial config-load. If the config is invalid at this
# point we can cleanly die (we're more lenient later on # point we can cleanly die; we're more resilient later on reload
# reloads). # attempts.
self.load_config(strict=True, print_confirmation=False) self.load_config(strict=True, print_confirmation=False)
@property @property
@ -409,8 +415,7 @@ class ServerManagerApp:
raise CleanError(f"Supplied path does not exist: '{path}'.") raise CleanError(f"Supplied path does not exist: '{path}'.")
# We need an abs path because we may be in a different # We need an abs path because we may be in a different
# cwd currently than we will be during the run. # cwd currently than we will be during the run.
self._config_path = os.path.abspath(path) self._user_provided_config_path = os.path.abspath(path)
self._user_provided_config_path = True
i += 2 i += 2
elif arg == '--root': elif arg == '--root':
if i + 1 >= argc: if i + 1 >= argc:
@ -478,9 +483,9 @@ class ServerManagerApp:
+ cls._par( + cls._par(
'Set the config file read by the server script. The config' 'Set the config file read by the server script. The config'
' file contains most options for what kind of game to host.' ' file contains most options for what kind of game to host.'
' It should be in toml format. If not specified, the script' ' It should be in toml or json format. If not specified,'
' will look for a file named \'config.toml\' in the same' ' the script will look for a file named \'config.toml\' or'
' directory as the script.' ' \'config.json\' in the same directory as the script.'
) )
+ '\n' + '\n'
f'{Clr.BLD}--root [path]{Clr.RST}\n' f'{Clr.BLD}--root [path]{Clr.RST}\n'
@ -570,21 +575,51 @@ class ServerManagerApp:
return return
time.sleep(1) time.sleep(1)
def _get_config_path(self) -> str:
if self._user_provided_config_path is not None:
return self._user_provided_config_path
# Otherwise look for config.toml or config.json in the same dir
# as our script. Need to work in abs paths since we may chdir when
# we start running.
toml_path = os.path.abspath(
os.path.join(os.path.dirname(__file__), 'config.toml')
)
toml_exists = os.path.exists(toml_path)
json_path = os.path.abspath(
os.path.join(os.path.dirname(__file__), 'config.json')
)
json_exists = os.path.exists(json_path)
# Warn if both configs are present.
if toml_exists and json_exists and not self._did_multi_config_warning:
self._did_multi_config_warning = True
print(
f'{Clr.YLW}Both config.toml and config.json'
f' found; will use json.{Clr.RST}',
flush=True,
)
if json_exists:
return json_path
return toml_path
def _load_config_from_file(self, print_confirmation: bool) -> ServerConfig: def _load_config_from_file(self, print_confirmation: bool) -> ServerConfig:
out: ServerConfig | None = None out: ServerConfig | None = None
if not os.path.exists(self._config_path): config_path = self._get_config_path()
if not os.path.exists(config_path):
# Special case: # Special case:
# #
# If the user didn't specify a particular config file, allow # If the user didn't provide a config path AND the default
# gracefully falling back to defaults if the default one is # config path does not exist, fall back to defaults.
# missing.
if not self._user_provided_config_path: if not self._user_provided_config_path:
if print_confirmation: if print_confirmation:
print( print(
f'{Clr.YLW}Default config file not found' f'{Clr.YLW}Default config file not found'
f' (\'{self._config_path}\'); using default' f' (\'{config_path}\'); using default'
f' settings.{Clr.RST}', f' config.{Clr.RST}',
flush=True, flush=True,
) )
self._config_mtime = None self._config_mtime = None
@ -592,17 +627,23 @@ class ServerManagerApp:
return ServerConfig() return ServerConfig()
# Don't be so lenient if the user pointed us at one though. # Don't be so lenient if the user pointed us at one though.
raise RuntimeError(f"Config file not found: '{self._config_path}'.") raise RuntimeError(f"Config file not found: '{config_path}'.")
import tomllib with open(config_path, encoding='utf-8') as infile:
if config_path.endswith('.toml'):
with open(self._config_path, encoding='utf-8') as infile: user_config_raw = tomllib.loads(infile.read())
user_config_raw = tomllib.loads(infile.read()) elif config_path.endswith('.json'):
user_config_raw = json.loads(infile.read())
else:
raise CleanError(
f"Invalid config file path '{config_path}';"
f" path must end with '.toml' or '.json'."
)
out = dataclass_from_dict(ServerConfig, user_config_raw) out = dataclass_from_dict(ServerConfig, user_config_raw)
# Update our known mod-time since we know it exists. # Update our known mod-time since we know it exists.
self._config_mtime = Path(self._config_path).stat().st_mtime self._config_mtime = Path(config_path).stat().st_mtime
self._last_config_mtime_check_time = time.time() self._last_config_mtime_check_time = time.time()
if print_confirmation: if print_confirmation:
@ -879,8 +920,9 @@ class ServerManagerApp:
): ):
self._last_config_mtime_check_time = now self._last_config_mtime_check_time = now
mtime: float | None mtime: float | None
if os.path.isfile(self._config_path): config_path = self._get_config_path()
mtime = Path(self._config_path).stat().st_mtime if os.path.isfile(config_path):
mtime = Path(config_path).stat().st_mtime
else: else:
mtime = None mtime = None
if mtime != self._config_mtime: if mtime != self._config_mtime:

View File

@ -39,7 +39,7 @@ auto main(int argc, char** argv) -> int {
namespace ballistica { namespace ballistica {
// These are set automatically via script; don't modify them here. // These are set automatically via script; don't modify them here.
const int kEngineBuildNumber = 21821; const int kEngineBuildNumber = 21823;
const char* kEngineVersion = "1.7.34"; const char* kEngineVersion = "1.7.34";
const int kEngineApiVersion = 8; const int kEngineApiVersion = 8;