fix: fix Arma 3 log discovery and improve config editor UX

- Fix logfiles_router and thread_registry to resolve .rpt log files
  from Path(server["exe_path"]).parent/server/ instead of the languard
  data dir, which never contained log files — log list and live tail
  both now work correctly
- Rewrite get_ui_schema() in config_generator to cover all ~80 fields
  across all 5 sections (server/basic/profile/launch/rcon) with proper
  toggle/select/number/password/tag-list/hidden widgets and labels;
  missions field is hidden (managed by Missions tab)
- Add formatSelectDisplay() to ConfigEditor so select fields show
  descriptive text (e.g. "0 - Never") instead of raw numbers in view mode
- Add ToggleDisplay for boolean fields (Enabled/Disabled with indicator dot)
- Add section tab labels and descriptions to ConfigEditor
- Add MissionList UX hints and dynamic Add/In Rotation button labels
- Add "hidden" to FieldSchema widget union type
- Update API.md, ARCHITECTURE.md, CLAUDE.md, FRONTEND.md, MODULES.md,
  THREADING.md to document log path fix and schema coverage
This commit is contained in:
Tran G. (Revernomad) Khoa
2026-04-18 15:56:04 +07:00
parent b7d670a91c
commit bf09a6ed1c
12 changed files with 253 additions and 56 deletions

View File

@@ -2,6 +2,7 @@
from __future__ import annotations
import logging
from pathlib import Path
from typing import Annotated
from fastapi import APIRouter, Depends, HTTPException
@@ -10,7 +11,6 @@ from sqlalchemy.engine import Connection
from adapters.registry import GameAdapterRegistry
from core.dal.server_repository import ServerRepository
from core.utils.file_utils import get_server_dir
from database import get_db
from dependencies import get_current_user, require_admin
@@ -30,7 +30,9 @@ def _get_rpt_parser(server_id: int, db: Connection):
adapter = GameAdapterRegistry.get(server["game_type"])
if not adapter.has_capability("log_parser"):
raise HTTPException(status_code=404, detail="Server does not support log files")
return adapter.get_log_parser(), get_server_dir(server_id)
# RPT files live next to the server exe (e.g. A3Master/server/*.rpt)
exe_dir = Path(server["exe_path"]).parent
return adapter.get_log_parser(), exe_dir
@router.get("")

View File

@@ -159,18 +159,16 @@ class ThreadRegistry:
game_type = server["game_type"]
adapter = self._adapter_registry.get(game_type)
# Log path: read from config if present, else use adapter default
# Log path: RPT files live next to the server exe, not in the languard data dir
log_path = None
if adapter.has_capability("log_parser"):
log_parser = adapter.get_log_parser()
# Try to resolve log path via the adapter's log file resolver
from core.utils.file_utils import get_server_dir
server_dir = get_server_dir(server_id)
if server_dir.exists():
resolver = log_parser.get_log_file_resolver(server_id)
resolved = resolver(server_dir)
if resolved is not None:
log_path = str(resolved)
from pathlib import Path
exe_dir = Path(server["exe_path"]).parent
resolver = log_parser.get_log_file_resolver(server_id)
resolved = resolver(exe_dir)
if resolved is not None:
log_path = str(resolved)
bundle: dict = {
"log_tail": None,