Configurable back-end port

This commit is contained in:
Raffson 2024-02-10 17:58:44 +01:00
parent 63d05ea696
commit cb68ff0df3
No known key found for this signature in database
GPG Key ID: B0402B2C9B764D99
8 changed files with 62 additions and 13 deletions

View File

@ -36,6 +36,7 @@
* **[Mission Generator]** Set F-14's IP waypoint according to the flight-plan's ingress point * **[Mission Generator]** Set F-14's IP waypoint according to the flight-plan's ingress point
* **[Mission Generator]** Automatically de-spawn aircraft when arrival/divert is an off-map spawn * **[Mission Generator]** Automatically de-spawn aircraft when arrival/divert is an off-map spawn
* **[Options]** Option to de-spawn AI flights in the air if their start-type was manually set to In-Flight * **[Options]** Option to de-spawn AI flights in the air if their start-type was manually set to In-Flight
* **[Config]** Preference setting to configure the server-port on which Retribution's back-end will run
## Fixes ## Fixes
* **[Mission Generation]** Anti-ship strikes should use "group attack" in their attack-task * **[Mission Generation]** Anti-ship strikes should use "group attack" in their attack-task

View File

@ -17,6 +17,7 @@ if TYPE_CHECKING:
_dcs_saved_game_folder: Optional[str] = None _dcs_saved_game_folder: Optional[str] = None
_prefer_liberation_payloads: bool = False _prefer_liberation_payloads: bool = False
_server_port: int = 16880
# fmt: off # fmt: off
@ -75,11 +76,13 @@ class MigrationUnpickler(pickle.Unpickler):
# fmt: on # fmt: on
def setup(user_folder: str, prefer_liberation_payloads: bool) -> None: def setup(user_folder: str, prefer_liberation_payloads: bool, port: int) -> None:
global _dcs_saved_game_folder global _dcs_saved_game_folder
_dcs_saved_game_folder = user_folder
global _prefer_liberation_payloads global _prefer_liberation_payloads
global _server_port
_dcs_saved_game_folder = user_folder
_prefer_liberation_payloads = prefer_liberation_payloads _prefer_liberation_payloads = prefer_liberation_payloads
_server_port = port
if not save_dir().exists(): if not save_dir().exists():
save_dir().mkdir(parents=True) save_dir().mkdir(parents=True)
@ -126,6 +129,11 @@ def save_dir() -> Path:
return base_path() / "Retribution" / "Saves" return base_path() / "Retribution" / "Saves"
def server_port() -> int:
global _server_port
return _server_port
def _temporary_save_file() -> str: def _temporary_save_file() -> str:
return str(save_dir() / "tmpsave.retribution") return str(save_dir() / "tmpsave.retribution")

View File

@ -2,6 +2,7 @@ import time
from collections.abc import Iterator from collections.abc import Iterator
from contextlib import contextmanager from contextlib import contextmanager
from threading import Thread from threading import Thread
from typing import Optional
import uvicorn import uvicorn
from uvicorn import Config from uvicorn import Config
@ -13,12 +14,13 @@ from game.sim import GameUpdateEvents
class Server(uvicorn.Server): class Server(uvicorn.Server):
def __init__(self) -> None: def __init__(self, port: Optional[int]) -> None:
settings = ServerSettings.get(port)
super().__init__( super().__init__(
Config( Config(
app=app, app=app,
host=ServerSettings.get().server_bind_address, host=settings.server_bind_address,
port=ServerSettings.get().server_port, port=settings.server_port,
# Configured explicitly with default_logging.yaml or logging.yaml. # Configured explicitly with default_logging.yaml or logging.yaml.
log_config=None, log_config=None,
) )

View File

@ -1,6 +1,7 @@
from __future__ import annotations from __future__ import annotations
from functools import lru_cache from functools import lru_cache
from typing import Optional
from pydantic_settings import BaseSettings from pydantic_settings import BaseSettings
@ -30,5 +31,5 @@ class ServerSettings(BaseSettings):
@classmethod @classmethod
@lru_cache @lru_cache
def get(cls) -> ServerSettings: def get(cls, port: Optional[int] = server_port) -> ServerSettings:
return cls() return cls(server_port=port)

View File

@ -12,6 +12,7 @@ global __dcs_saved_game_directory
global __dcs_installation_directory global __dcs_installation_directory
global __last_save_file global __last_save_file
global __prefer_liberation_payloads global __prefer_liberation_payloads
global __server_port
USER_PATH = Path(os.environ["LOCALAPPDATA"]) / "DCSRetribution" USER_PATH = Path(os.environ["LOCALAPPDATA"]) / "DCSRetribution"
@ -25,6 +26,7 @@ def init():
global __last_save_file global __last_save_file
global __ignore_empty_install_directory global __ignore_empty_install_directory
global __prefer_liberation_payloads global __prefer_liberation_payloads
global __server_port
if PREFERENCES_PATH.exists(): if PREFERENCES_PATH.exists():
try: try:
@ -40,6 +42,7 @@ def init():
__prefer_liberation_payloads = pref_data.get( __prefer_liberation_payloads = pref_data.get(
"prefer_liberation_payloads", False "prefer_liberation_payloads", False
) )
__server_port = pref_data.get("server_port", 16880)
is_first_start = False is_first_start = False
except (KeyError, json.JSONDecodeError): except (KeyError, json.JSONDecodeError):
__dcs_saved_game_directory = "" __dcs_saved_game_directory = ""
@ -47,11 +50,13 @@ def init():
__last_save_file = "" __last_save_file = ""
__ignore_empty_install_directory = False __ignore_empty_install_directory = False
__prefer_liberation_payloads = False __prefer_liberation_payloads = False
__server_port = 16880
is_first_start = True is_first_start = True
else: else:
__last_save_file = "" __last_save_file = ""
__ignore_empty_install_directory = False __ignore_empty_install_directory = False
__prefer_liberation_payloads = False __prefer_liberation_payloads = False
__server_port = 16880
try: try:
__dcs_saved_game_directory = ( __dcs_saved_game_directory = (
dcs.installation.get_dcs_saved_games_directory() dcs.installation.get_dcs_saved_games_directory()
@ -68,18 +73,22 @@ def init():
__dcs_installation_directory = "" __dcs_installation_directory = ""
is_first_start = True is_first_start = True
persistency.setup(__dcs_saved_game_directory, __prefer_liberation_payloads) persistency.setup(
__dcs_saved_game_directory, __prefer_liberation_payloads, __server_port
)
return is_first_start return is_first_start
def setup(saved_game_dir, install_dir, prefer_liberation_payloads): def setup(saved_game_dir, install_dir, prefer_liberation_payloads, port):
global __dcs_saved_game_directory global __dcs_saved_game_directory
global __dcs_installation_directory global __dcs_installation_directory
global __prefer_liberation_payloads global __prefer_liberation_payloads
global __server_port
__dcs_saved_game_directory = saved_game_dir __dcs_saved_game_directory = saved_game_dir
__dcs_installation_directory = install_dir __dcs_installation_directory = install_dir
__prefer_liberation_payloads = prefer_liberation_payloads __prefer_liberation_payloads = prefer_liberation_payloads
persistency.setup(__dcs_saved_game_directory, __prefer_liberation_payloads) __server_port = port
persistency.setup(saved_game_dir, prefer_liberation_payloads, port)
def setup_last_save_file(last_save_file): def setup_last_save_file(last_save_file):
@ -92,12 +101,14 @@ def save_config():
global __dcs_installation_directory global __dcs_installation_directory
global __last_save_file global __last_save_file
global __ignore_empty_install_directory global __ignore_empty_install_directory
global __server_port
pref_data = { pref_data = {
"saved_game_dir": __dcs_saved_game_directory, "saved_game_dir": __dcs_saved_game_directory,
"dcs_install_dir": __dcs_installation_directory, "dcs_install_dir": __dcs_installation_directory,
"last_save_file": __last_save_file, "last_save_file": __last_save_file,
"ignore_empty_install_directory": __ignore_empty_install_directory, "ignore_empty_install_directory": __ignore_empty_install_directory,
"prefer_liberation_payloads": __prefer_liberation_payloads, "prefer_liberation_payloads": __prefer_liberation_payloads,
"server_port": __server_port,
} }
PREFERENCES_PATH.parent.mkdir(exist_ok=True, parents=True) PREFERENCES_PATH.parent.mkdir(exist_ok=True, parents=True)
with PREFERENCES_PATH.open("w") as prefs: with PREFERENCES_PATH.open("w") as prefs:
@ -119,6 +130,11 @@ def prefer_liberation_payloads():
return __prefer_liberation_payloads return __prefer_liberation_payloads
def server_port():
global __server_port
return __server_port
def ignore_empty_install_directory(): def ignore_empty_install_directory():
global __ignore_empty_install_directory global __ignore_empty_install_directory
return __ignore_empty_install_directory return __ignore_empty_install_directory

View File

@ -442,7 +442,8 @@ def main():
dump_task_priorities() dump_task_priorities()
return return
with Server().run_in_thread(): liberation_install.init()
with Server(liberation_install.server_port()).run_in_thread():
run_ui(game, UiFlags(args.dev, args.show_sim_speed_controls)) run_ui(game, UiFlags(args.dev, args.show_sim_speed_controls))

View File

@ -8,6 +8,7 @@ from PySide6.QtWebEngineCore import QWebEnginePage, QWebEngineSettings
from PySide6.QtWebEngineWidgets import QWebEngineView from PySide6.QtWebEngineWidgets import QWebEngineView
from game.server.settings import ServerSettings from game.server.settings import ServerSettings
from qt_ui.liberation_install import server_port
from qt_ui.models import GameModel from qt_ui.models import GameModel
@ -44,7 +45,7 @@ class QLiberationMap(QWebEngineView):
url = QUrl("http://localhost:3000") url = QUrl("http://localhost:3000")
else: else:
url = QUrl.fromLocalFile(str(Path("client/build/index.html").resolve())) url = QUrl.fromLocalFile(str(Path("client/build/index.html").resolve()))
server_settings = ServerSettings.get() server_settings = ServerSettings.get(server_port())
host = server_settings.server_bind_address host = server_settings.server_bind_address
if host.startswith("::"): if host.startswith("::"):
host = f"[{host}]" host = f"[{host}]"

View File

@ -12,6 +12,7 @@ from PySide6.QtWidgets import (
QPushButton, QPushButton,
QVBoxLayout, QVBoxLayout,
QCheckBox, QCheckBox,
QSpinBox,
) )
from qt_ui import liberation_install, liberation_theme from qt_ui import liberation_install, liberation_theme
@ -46,6 +47,9 @@ class QLiberationPreferences(QFrame):
self.payloads_cb = QCheckBox() self.payloads_cb = QCheckBox()
self.payloads_cb.setChecked(self.prefer_liberation_payloads) self.payloads_cb.setChecked(self.prefer_liberation_payloads)
self.port = liberation_install.server_port()
self.port_input = QSpinBox()
self.initUi() self.initUi()
def initUi(self): def initUi(self):
@ -87,6 +91,17 @@ class QLiberationPreferences(QFrame):
) )
layout.addWidget(self.payloads_cb, 5, 1, alignment=Qt.AlignmentFlag.AlignRight) layout.addWidget(self.payloads_cb, 5, 1, alignment=Qt.AlignmentFlag.AlignRight)
layout.addWidget(
QLabel("<strong>Server port (restart required):</strong>"),
6,
0,
alignment=Qt.AlignmentFlag.AlignLeft,
)
layout.addWidget(self.port_input, 6, 1, alignment=Qt.AlignmentFlag.AlignRight)
self.port_input.setRange(1, 2**16 - 1)
self.port_input.setValue(self.port)
self.port_input.setStyleSheet("QSpinBox{ width: 50 }")
main_layout.addLayout(layout) main_layout.addLayout(layout)
main_layout.addStretch() main_layout.addStretch()
@ -113,6 +128,7 @@ class QLiberationPreferences(QFrame):
self.saved_game_dir = self.edit_saved_game_dir.text() self.saved_game_dir = self.edit_saved_game_dir.text()
self.dcs_install_dir = self.edit_dcs_install_dir.text() self.dcs_install_dir = self.edit_dcs_install_dir.text()
self.prefer_liberation_payloads = self.payloads_cb.isChecked() self.prefer_liberation_payloads = self.payloads_cb.isChecked()
self.port = self.port_input.value()
set_theme_index(self.themeSelect.currentIndex()) set_theme_index(self.themeSelect.currentIndex())
if not os.path.isdir(self.saved_game_dir): if not os.path.isdir(self.saved_game_dir):
@ -169,7 +185,10 @@ class QLiberationPreferences(QFrame):
return False return False
liberation_install.setup( liberation_install.setup(
self.saved_game_dir, self.dcs_install_dir, self.prefer_liberation_payloads self.saved_game_dir,
self.dcs_install_dir,
self.prefer_liberation_payloads,
self.port,
) )
liberation_install.save_config() liberation_install.save_config()
liberation_theme.save_theme_config() liberation_theme.save_theme_config()