Source code for dayz_dev_tools.server_config

import dataclasses
import logging
import os
import platform
import typing

import pydantic
import tomli


if platform.system() == "Windows":
    DEFAULT_EXECUTABLE = os.path.join(".", "DayZServer_x64.exe")
    DEFAULT_WORKSHOP_DIRECTORY = "C:\\" + os.path.join(
        "Program Files (x86)", "Steam", "steamapps", "common", "DayZ", "!Workshop")
else:
    DEFAULT_EXECUTABLE = os.path.join(".", "DayZServer")
    DEFAULT_WORKSHOP_DIRECTORY = os.path.join(
        os.environ["HOME"], ".steam", "steamapps", "common", "DayZ", "!Workshop")


class _ServerConfig(pydantic.BaseModel):
    executable: str = DEFAULT_EXECUTABLE
    config: str = "serverDZ.cfg"
    directory: typing.Optional[str] = None
    profile_directory: typing.Optional[str] = None
    mission_directory: typing.Optional[str] = None
    parameters: typing.List[str] = pydantic.Field(default_factory=list)
    bundles: str = "bundles.py"


class _WorkshopConfig(pydantic.BaseModel):
    directory: str = DEFAULT_WORKSHOP_DIRECTORY


class _Bundle(pydantic.BaseModel):
    executable: typing.Optional[str] = None
    config: typing.Optional[str] = None
    directory: typing.Optional[str] = None
    profile_directory: typing.Optional[str] = None
    workshop_directory: typing.Optional[str] = None
    mission_directory: typing.Optional[str] = None
    mods: typing.Union[str, typing.List[str]] = pydantic.Field(default_factory=lambda: list())
    server_mods: typing.Union[str, typing.List[str]] = pydantic.Field(
        default_factory=lambda: list())
    parameters: typing.List[str] = pydantic.Field(default_factory=list)


class _Config(pydantic.BaseModel):
    server: _ServerConfig = pydantic.Field(default_factory=_ServerConfig)
    workshop: _WorkshopConfig = pydantic.Field(default_factory=_WorkshopConfig)
    bundle: typing.Dict[str, _Bundle] = pydantic.Field(default_factory=dict)


[docs] @dataclasses.dataclass class BundleConfig: """Configuration file bundle settings.""" #: DayZ Server executable filename override (optional) executable: typing.Optional[str] = None #: DayZ Server config filename override (optional) config: typing.Optional[str] = None #: Directory to switch to before running DayZ Server (optional) directory: typing.Optional[str] = None #: DayZ Server profile directory name override (optional) profile_directory: typing.Optional[str] = None #: DayZ workshop directory name override (optional) workshop_directory: typing.Optional[str] = None #: DayZ mod list to add mods: typing.List[str] = dataclasses.field(default_factory=list) #: DayZ server mod list to add server_mods: typing.List[str] = dataclasses.field(default_factory=list) #: DayZ Server mission directory name override (optional) mission_directory: typing.Optional[str] = None #: Extra server command line parameters to add parameters: typing.List[str] = dataclasses.field(default_factory=list)
[docs] @dataclasses.dataclass class ServerConfig: """Configuration file settings.""" #: DayZ Server executable filename executable: str #: DayZ Server config filename config: str #: Filename of the bundles Python module bundle_path: str #: DayZ workshop directory name workshop_directory: str #: Configuration file bundles, by name (see :class:`dayz_dev_tools.server_config.BundleConfig`) bundles: typing.Dict[str, BundleConfig] #: Directory to switch to before running DayZ Server (optional) directory: typing.Optional[str] = None #: DayZ Server profile directory name (optional) profile_directory: typing.Optional[str] = None #: DayZ Server mission directory name (optional) mission_directory: typing.Optional[str] = None #: Extra server command line parameters to add parameters: typing.List[str] = dataclasses.field(default_factory=list)
def _parse_mods(mods: typing.Union[str, typing.List[str]]) -> typing.List[str]: if isinstance(mods, str): return mods.split(";") return mods
[docs] def load(filename: str) -> ServerConfig: """Read a TOML-syntax DayZ Server configuration file. :Parameters: - `filename`: The name of the configuration file to read (e.g. ``server.toml``) :Returns: A :class:`~dayz_dev_tools.server_config.ServerConfig`. """ try: with open(filename, "rb") as toml_file: config = _Config.model_validate(tomli.load(toml_file)) except tomli.TOMLDecodeError as error: raise Exception(f"Configuration error in {filename}: {error}") from error except pydantic.ValidationError as error: loc = ".".join(str(ll) for ll in error.errors()[0]['loc']) inp = error.errors()[0]['input'] msg = error.errors()[0]['msg'] raise Exception(f"Configuration error at {loc}: {inp}: {msg}") from error except FileNotFoundError as error: logging.debug(f"Unable to read config file ({filename}): {error}") config = _Config() return ServerConfig( executable=config.server.executable, config=config.server.config, directory=config.server.directory, profile_directory=config.server.profile_directory, mission_directory=config.server.mission_directory, workshop_directory=config.workshop.directory, bundle_path=config.server.bundles, parameters=config.server.parameters, bundles={ name: BundleConfig( executable=bundle.executable, config=bundle.config, directory=bundle.directory, profile_directory=bundle.profile_directory, workshop_directory=bundle.workshop_directory, mods=_parse_mods(bundle.mods), server_mods=_parse_mods(bundle.server_mods), mission_directory=bundle.mission_directory, parameters=bundle.parameters) for name, bundle in config.bundle.items() })