Mods tab bug fixes:
- mod_manager: fix wrong kwargs in set_enabled_mods, fix scan dir to use
mods/ subdir instead of server root, migrate old string-list format to
dict format on read
- service: replace dead server_mods SQL JOIN with get_enabled_mods()
call through the mod_manager capability; pass is_server_mod to
build_mod_args
- mods_router: accept list[EnabledModEntry] objects (name + is_server_mod)
instead of bare strings
Client/server mod split:
- Mods now stored as list[{"name": str, "is_server_mod": bool}]; old
string-list format auto-migrated on read
- is_server_mod=true routes to -serverMod= arg; false to -mod= arg
- ModList UI: amber Client/Server badge in selected pane; toggle button
in split-pane selector
Directory scaffold:
- process_config: adds "mods" to dir layout; provides get_dir_readme()
with per-directory README.txt content
- file_utils: ensure_server_dirs() gains readme_provider kwarg; writes
README.txt idempotently if absent
- service.create_server: passes readme_provider via hasattr probe
- main.py startup: backfills all existing servers with correct subdirs
and README files (idempotent)
Docs: API.md and FRONTEND.md updated for new mod schema and types
Test __init__.py files added for pytest discovery
76 lines
3.0 KiB
Python
76 lines
3.0 KiB
Python
"""Arma 3 process configuration: executables, ports, directory layout."""
|
|
|
|
|
|
class Arma3ProcessConfig:
|
|
|
|
def get_allowed_executables(self) -> list[str]:
|
|
return ["arma3server_x64.exe", "arma3server.exe"]
|
|
|
|
def get_port_conventions(self, game_port: int) -> dict[str, int]:
|
|
"""
|
|
Arma 3 derives 3 additional ports from the game port.
|
|
All 4 must be free when starting a server.
|
|
rcon_port is separate (user-configurable, not auto-derived here).
|
|
"""
|
|
return {
|
|
"game": game_port,
|
|
"steam_query": game_port + 1,
|
|
"von": game_port + 2,
|
|
"steam_auth": game_port + 3,
|
|
}
|
|
|
|
def get_default_game_port(self) -> int:
|
|
return 2302
|
|
|
|
def get_default_rcon_port(self, game_port: int) -> int | None:
|
|
return game_port + 4 # e.g. 2306 for default game port
|
|
|
|
def get_server_dir_layout(self) -> list[str]:
|
|
"""Subdirectories to create inside servers/{id}/."""
|
|
return ["server", "battleye", "mpmissions", "mods"]
|
|
|
|
_DIR_READMES: dict[str, str] = {
|
|
"server": (
|
|
"Arma 3 Server — Log Directory\n"
|
|
"==============================\n\n"
|
|
"Arma 3 writes RPT log files here (e.g. arma3server_2024-01-01_12-00-00.rpt).\n"
|
|
"These are viewable in Languard's Logs tab.\n\n"
|
|
"Do NOT place files here manually."
|
|
),
|
|
"battleye": (
|
|
"BattlEye Anti-Cheat\n"
|
|
"===================\n\n"
|
|
"BattlEye configuration and GUID ban list files live here.\n"
|
|
"Managed automatically by Arma 3 and Languard.\n\n"
|
|
"Do NOT modify these files manually unless you know what you are doing."
|
|
),
|
|
"mpmissions": (
|
|
"Mission Files\n"
|
|
"=============\n\n"
|
|
"Place Arma 3 mission files (.pbo) here to make them available for the server.\n"
|
|
"Once placed here they will appear in Languard's Missions tab.\n\n"
|
|
"Example: Wasteland_A3.Altis.pbo"
|
|
),
|
|
"mods": (
|
|
"Mods\n"
|
|
"====\n\n"
|
|
"Place Arma 3 mod folders here. Each mod folder must start with '@'.\n\n"
|
|
"Example layout:\n"
|
|
" mods/\n"
|
|
" @CBA_A3/\n"
|
|
" addons/\n"
|
|
" @ACE/\n"
|
|
" addons/\n\n"
|
|
"After placing mods here:\n"
|
|
" 1. Go to the Mods tab in Languard.\n"
|
|
" 2. Select the mods you want to enable.\n"
|
|
" 3. Toggle 'Server-only' for mods that should use -serverMod= (e.g. task force radio server plugin).\n"
|
|
" 4. Click 'Apply Selection'.\n"
|
|
" 5. Restart the server for changes to take effect.\n\n"
|
|
"Mods with a mod.cpp file will display their friendly name in the UI.\n"
|
|
"Workshop mods with meta.cpp will show their Workshop ID."
|
|
),
|
|
}
|
|
|
|
def get_dir_readme(self, dir_name: str) -> str | None:
|
|
return self._DIR_READMES.get(dir_name) |