diff --git a/game/server/combat/models.py b/game/server/combat/models.py index f579743ce..c114e6ec7 100644 --- a/game/server/combat/models.py +++ b/game/server/combat/models.py @@ -33,15 +33,19 @@ def for_combat(combat: FrozenCombat, theater: ConflictTheater) -> FrozenCombatJs if isinstance(combat, AtIp): return FrozenCombatJs( id=combat.id, - flight_position=combat.flight.position().latlng(), - target_positions=[combat.flight.package.target.position.latlng()], + flight_position=LeafletPoint.from_pydcs(combat.flight.position()), + target_positions=[ + LeafletPoint.from_pydcs(combat.flight.package.target.position) + ], footprint=None, ) if isinstance(combat, DefendingSam): return FrozenCombatJs( id=combat.id, - flight_position=combat.flight.position().latlng(), - target_positions=[sam.position.latlng() for sam in combat.air_defenses], + flight_position=LeafletPoint.from_pydcs(combat.flight.position()), + target_positions=[ + LeafletPoint.from_pydcs(sam.position) for sam in combat.air_defenses + ], footprint=None, ) raise NotImplementedError(f"Unhandled FrozenCombat type: {combat.__class__}") diff --git a/game/server/controlpoints/models.py b/game/server/controlpoints/models.py index a0a22e766..6d197a8bf 100644 --- a/game/server/controlpoints/models.py +++ b/game/server/controlpoints/models.py @@ -33,7 +33,7 @@ def for_control_point(control_point: ControlPoint) -> ControlPointJs: id=control_point.id, name=control_point.name, blue=control_point.captured, - position=control_point.position.latlng(), + position=LeafletPoint.from_pydcs(control_point.position), mobile=control_point.moveable and control_point.captured, destination=destination, sidc=str(control_point.sidc()), diff --git a/game/server/eventstream/models.py b/game/server/eventstream/models.py index 1aa994da3..f8aeb8934 100644 --- a/game/server/eventstream/models.py +++ b/game/server/eventstream/models.py @@ -81,9 +81,13 @@ def from_events( for f in events.updated_front_lines ] + reset_on_map_center: LeafletPoint | None = None + if events.reset_on_map_center is not None: + reset_on_map_center = LeafletPoint.from_pydcs(events.reset_on_map_center) return GameUpdateEventsJs( updated_flight_positions={ - f[0].id: f[1].latlng() for f in events.updated_flight_positions + f[0].id: LeafletPoint.from_pydcs(f[1]) + for f in events.updated_flight_positions }, new_combats=new_combats, updated_combats=updated_combats, @@ -110,7 +114,7 @@ def from_events( ], updated_iads=updated_iads, deleted_iads=events.deleted_iads_connections, - reset_on_map_center=events.reset_on_map_center, + reset_on_map_center=reset_on_map_center, game_unloaded=events.game_unloaded, new_turn=events.new_turn, ) diff --git a/game/server/flights/models.py b/game/server/flights/models.py index bd965c519..f77b12551 100644 --- a/game/server/flights/models.py +++ b/game/server/flights/models.py @@ -37,7 +37,7 @@ def for_flight(flight: Flight, with_waypoints: bool) -> FlightJs: # lost. position = None if isinstance(flight.state, InFlight) or isinstance(flight.state, Killed): - position = flight.position().latlng() + position = LeafletPoint.from_pydcs(flight.position()) waypoints = None if with_waypoints: waypoints = waypoints_for_flight(flight) diff --git a/game/server/frontlines/models.py b/game/server/frontlines/models.py index be966a96d..aef282e1b 100644 --- a/game/server/frontlines/models.py +++ b/game/server/frontlines/models.py @@ -27,7 +27,10 @@ def for_front_line(theater: ConflictTheater, front_line: FrontLine) -> FrontLine bounds = FrontLineConflictDescription.frontline_bounds(front_line, theater) return FrontLineJs( id=front_line.id, - extents=[bounds.left_position.latlng(), bounds.right_position.latlng()], + extents=[ + LeafletPoint.from_pydcs(bounds.left_position), + LeafletPoint.from_pydcs(bounds.right_position), + ], ) @staticmethod diff --git a/game/server/game/models.py b/game/server/game/models.py index b5089d2ef..6ff76ebc2 100644 --- a/game/server/game/models.py +++ b/game/server/game/models.py @@ -7,12 +7,12 @@ from game.server.controlpoints.models import ControlPointJs from game.server.flights.models import FlightJs from game.server.frontlines.models import FrontLineJs +from game.server.iadsnetwork.models import IadsNetworkJs from game.server.leaflet import LeafletPoint from game.server.mapzones.models import ThreatZoneContainerJs, UnculledZoneJs from game.server.navmesh.models import NavMeshesJs from game.server.supplyroutes.models import SupplyRouteJs from game.server.tgos.models import TgoJs -from game.server.iadsnetwork.models import IadsConnectionJs, IadsNetworkJs if TYPE_CHECKING: from game import Game @@ -44,6 +44,8 @@ def from_game(game: Game) -> GameJs: iads_network=IadsNetworkJs.from_network(game.theater.iads_network), threat_zones=ThreatZoneContainerJs.for_game(game), navmeshes=NavMeshesJs.from_game(game), - map_center=game.theater.terrain.map_view_default.position.latlng(), + map_center=LeafletPoint.from_pydcs( + game.theater.terrain.map_view_default.position + ), unculled_zones=UnculledZoneJs.from_game(game), ) diff --git a/game/server/leaflet.py b/game/server/leaflet.py index 6e5ed8168..bd9a1f183 100644 --- a/game/server/leaflet.py +++ b/game/server/leaflet.py @@ -19,6 +19,11 @@ class Config: title = "LatLng" + @staticmethod + def from_pydcs(point: Point) -> LeafletPoint: + latlng = point.latlng() + return LeafletPoint(lat=latlng.lat, lng=latlng.lng) + LeafletLine = list[LeafletPoint] diff --git a/game/server/mapzones/models.py b/game/server/mapzones/models.py index f83f43e0f..335e3dd0d 100644 --- a/game/server/mapzones/models.py +++ b/game/server/mapzones/models.py @@ -36,7 +36,7 @@ class Config: def from_game(game: Game) -> list[UnculledZoneJs]: return [ UnculledZoneJs( - position=zone.latlng(), + position=LeafletPoint.from_pydcs(zone), radius=game.settings.perf_culling_distance * 1000, ) for zone in game.get_culling_zones() diff --git a/game/server/settings.py b/game/server/settings.py index 007591d00..f24ae182c 100644 --- a/game/server/settings.py +++ b/game/server/settings.py @@ -2,7 +2,7 @@ from functools import lru_cache -from pydantic import BaseSettings +from pydantic_settings import BaseSettings class ServerSettings(BaseSettings): diff --git a/game/server/supplyroutes/models.py b/game/server/supplyroutes/models.py index 8db6485ef..03ae7c27c 100644 --- a/game/server/supplyroutes/models.py +++ b/game/server/supplyroutes/models.py @@ -92,7 +92,7 @@ def for_link( # https://reactjs.org/docs/lists-and-keys.html#keys # https://github.com/dcs-liberation/dcs_liberation/issues/2167 id=uuid.uuid4(), - points=[p.latlng() for p in points], + points=[LeafletPoint.from_pydcs(p) for p in points], front_active=not sea and a.front_is_active(b), is_sea=sea, blue=a.captured, diff --git a/game/server/tgos/models.py b/game/server/tgos/models.py index 7124f0507..c28068dd7 100644 --- a/game/server/tgos/models.py +++ b/game/server/tgos/models.py @@ -38,7 +38,7 @@ def for_tgo(tgo: TheaterGroundObject) -> TgoJs: control_point_name=tgo.control_point.name, category=tgo.category, blue=tgo.control_point.captured, - position=tgo.position.latlng(), + position=LeafletPoint.from_pydcs(tgo.position), units=[unit.display_name for unit in tgo.units], threat_ranges=threat_ranges, detection_ranges=detection_ranges, diff --git a/game/server/waypoints/models.py b/game/server/waypoints/models.py index 1575ee797..8b9a1e4ce 100644 --- a/game/server/waypoints/models.py +++ b/game/server/waypoints/models.py @@ -82,7 +82,7 @@ def for_waypoint( return FlightWaypointJs( name=waypoint.name, - position=waypoint.position.latlng(), + position=LeafletPoint.from_pydcs(waypoint.position), altitude_ft=waypoint.alt.feet, altitude_reference=waypoint.alt_type, is_movable=is_movable, diff --git a/game/sim/gameupdateevents.py b/game/sim/gameupdateevents.py index cf7371eff..4721dc59b 100644 --- a/game/sim/gameupdateevents.py +++ b/game/sim/gameupdateevents.py @@ -5,7 +5,6 @@ from uuid import UUID from dcs import Point -from dcs.mapping import LatLng if TYPE_CHECKING: from game import Game @@ -38,7 +37,7 @@ class GameUpdateEvents: updated_control_points: set[ControlPoint] = field(default_factory=set) updated_iads: set[IadsNetworkNode] = field(default_factory=set) deleted_iads_connections: set[UUID] = field(default_factory=set) - reset_on_map_center: LatLng | None = None + reset_on_map_center: Point | None = None game_unloaded: bool = False new_turn: bool = False shutting_down: bool = False @@ -140,9 +139,7 @@ def game_loaded(self, game: Game | None) -> GameUpdateEvents: self.game_unloaded = True self.reset_on_map_center = None else: - self.reset_on_map_center = ( - game.theater.terrain.map_view_default.position.latlng() - ) + self.reset_on_map_center = game.theater.terrain.map_view_default.position self.game_unloaded = False return self diff --git a/requirements.txt b/requirements.txt index ff057bd6c..51852f7c0 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,54 +1,57 @@ -altgraph==0.17.3 -anyio==3.6.2 -asgiref==3.6.0 -attrs==22.2.0 +altgraph==0.17.4 +annotated-types==0.6.0 +anyio==3.7.1 +asgiref==3.7.2 +attrs==23.1.0 black==22.12.0 -certifi==2023.7.22 -cfgv==3.3.1 -click==8.1.3 +certifi==2023.11.17 +cfgv==3.4.0 +click==8.1.7 colorama==0.4.6 -coverage==7.0.5 -distlib==0.3.6 -exceptiongroup==1.1.0 -Faker==15.3.4 -fastapi==0.95.2 -filelock==3.9.0 +coverage==7.3.2 +distlib==0.3.7 +exceptiongroup==1.2.0 +Faker==20.1.0 +fastapi==0.104.1 +filelock==3.13.1 future==0.18.3 h11==0.14.0 -httptools==0.5.0 -identify==2.5.11 -idna==3.4 -iniconfig==1.1.1 +httptools==0.6.1 +identify==2.5.32 +idna==3.6 +iniconfig==2.0.0 Jinja2==3.1.2 -MarkupSafe==2.1.1 +MarkupSafe==2.1.3 mypy==1.2.0 mypy-extensions==1.0.0 -nodeenv==1.7.0 -numpy==1.25.1 -packaging==22.0 -pathspec==0.10.3 -pefile==2022.5.30 +nodeenv==1.8.0 +numpy==1.26.2 +packaging==23.2 +pathspec==0.11.2 +pefile==2023.2.7 Pillow==10.0.1 -platformdirs==2.6.2 -pluggy==1.0.0 -pre-commit==2.21.0 -pydantic==1.10.7 -git+https://github.com/pydcs/dcs@ca4cb436663416c8637ca17fdf1b090030696782#egg=pydcs -pyinstaller==5.13.0 -pyinstaller-hooks-contrib==2023.6 -pyproj==3.4.1 -PySide6==6.4.1 -PySide6-Addons==6.4.1 -PySide6-Essentials==6.4.1 -pytest==7.2.0 -pytest-cov==4.0.0 -pytest-mock==3.10.0 +platformdirs==4.0.0 +pluggy==1.3.0 +pre-commit==3.5.0 +pydantic==2.5.2 +pydantic-settings==2.1.0 +pydantic_core==2.14.5 +pydcs @ git+https://github.com/pydcs/dcs@05ebda06cbe77b09b2b0fae915993caaa30c81bd +pyinstaller==6.2.0 +pyinstaller-hooks-contrib==2023.10 +pyproj==3.6.1 +PySide6==6.6.0 +PySide6-Addons==6.6.0 +PySide6-Essentials==6.6.0 +pytest==7.4.3 +pytest-cov==4.1.0 +pytest-mock==3.12.0 python-dateutil==2.8.2 -python-dotenv==0.21.0 +python-dotenv==1.0.0 pywin32-ctypes==0.2.2 -PyYAML==6.0 -shapely==2.0.1 -shiboken6==6.4.1 +PyYAML==6.0.1 +shapely==2.0.2 +shiboken6==6.6.0 six==1.16.0 sniffio==1.3.0 starlette==0.27.0 @@ -57,10 +60,10 @@ tomli==2.0.1 types-Jinja2==2.11.9 types-MarkupSafe==1.1.10 types-Pillow==9.3.0.4 -types-PyYAML==6.0.12.2 -types-tabulate==0.9.0.0 -typing_extensions==4.4.0 -uvicorn==0.20.0 -virtualenv==20.17.1 -watchfiles==0.18.1 -websockets==10.4 +types-PyYAML==6.0.12.12 +types-tabulate==0.9.0.3 +typing_extensions==4.8.0 +uvicorn==0.24.0.post1 +virtualenv==20.24.7 +watchfiles==0.21.0 +websockets==12.0