mirror of
https://github.com/dcs-retribution/dcs-retribution.git
synced 2025-11-10 15:41:24 +00:00
Move waypoints and commit boundaries to FastAPI.
This commit is contained in:
@@ -1,8 +1,10 @@
|
||||
from fastapi import Depends, FastAPI
|
||||
|
||||
from . import debuggeometries, eventstream
|
||||
from . import debuggeometries, eventstream, flights, waypoints
|
||||
from .security import ApiKeyManager
|
||||
|
||||
app = FastAPI(dependencies=[Depends(ApiKeyManager.verify)])
|
||||
app.include_router(debuggeometries.router)
|
||||
app.include_router(eventstream.router)
|
||||
app.include_router(flights.router)
|
||||
app.include_router(waypoints.router)
|
||||
|
||||
@@ -1,15 +1,20 @@
|
||||
from game import Game
|
||||
from qt_ui.models import GameModel
|
||||
|
||||
|
||||
class GameContext:
|
||||
_game: Game | None
|
||||
_game_model: GameModel
|
||||
|
||||
@classmethod
|
||||
def set(cls, game: Game | None) -> None:
|
||||
cls._game = game
|
||||
def set_model(cls, game_model: GameModel) -> None:
|
||||
cls._game_model = game_model
|
||||
|
||||
@classmethod
|
||||
def get(cls) -> Game:
|
||||
if cls._game is None:
|
||||
if cls._game_model.game is None:
|
||||
raise RuntimeError("GameContext has no Game set")
|
||||
return cls._game
|
||||
return cls._game_model.game
|
||||
|
||||
@classmethod
|
||||
def get_model(cls) -> GameModel:
|
||||
return cls._game_model
|
||||
|
||||
1
game/server/flights/__init__.py
Normal file
1
game/server/flights/__init__.py
Normal file
@@ -0,0 +1 @@
|
||||
from .routes import router
|
||||
34
game/server/flights/routes.py
Normal file
34
game/server/flights/routes.py
Normal file
@@ -0,0 +1,34 @@
|
||||
from uuid import UUID
|
||||
|
||||
from fastapi import APIRouter, Depends
|
||||
from shapely.geometry import LineString, Point as ShapelyPoint
|
||||
|
||||
from game import Game
|
||||
from game.server import GameContext
|
||||
from game.server.leaflet import LeafletPoly, ShapelyUtil
|
||||
from gen.flights.flightplan import CasFlightPlan, PatrollingFlightPlan
|
||||
|
||||
router: APIRouter = APIRouter(prefix="/flights")
|
||||
|
||||
|
||||
@router.get("/{flight_id}/commit-boundary")
|
||||
def commit_boundary(
|
||||
flight_id: UUID, game: Game = Depends(GameContext.get)
|
||||
) -> LeafletPoly:
|
||||
flight = game.db.flights.get(flight_id)
|
||||
if not isinstance(flight.flight_plan, PatrollingFlightPlan):
|
||||
return []
|
||||
start = flight.flight_plan.patrol_start
|
||||
end = flight.flight_plan.patrol_end
|
||||
if isinstance(flight.flight_plan, CasFlightPlan):
|
||||
center = flight.flight_plan.target.position
|
||||
commit_center = ShapelyPoint(center.x, center.y)
|
||||
else:
|
||||
commit_center = LineString(
|
||||
[
|
||||
ShapelyPoint(start.x, start.y),
|
||||
ShapelyPoint(end.x, end.y),
|
||||
]
|
||||
)
|
||||
bubble = commit_center.buffer(flight.flight_plan.engagement_distance.meters)
|
||||
return ShapelyUtil.poly_to_leaflet(bubble, game.theater)
|
||||
1
game/server/waypoints/__init__.py
Normal file
1
game/server/waypoints/__init__.py
Normal file
@@ -0,0 +1 @@
|
||||
from .routes import router
|
||||
81
game/server/waypoints/routes.py
Normal file
81
game/server/waypoints/routes.py
Normal file
@@ -0,0 +1,81 @@
|
||||
from datetime import timedelta
|
||||
from uuid import UUID
|
||||
|
||||
from fastapi import APIRouter, Depends, HTTPException, status
|
||||
|
||||
from game import Game
|
||||
from game.ato.flightwaypoint import BaseFlightWaypoint, FlightWaypoint
|
||||
from game.ato.flightwaypointtype import FlightWaypointType
|
||||
from game.server import GameContext
|
||||
from game.theater import LatLon
|
||||
from game.utils import meters
|
||||
|
||||
router: APIRouter = APIRouter(prefix="/waypoints")
|
||||
|
||||
|
||||
@router.get("/{flight_id}", response_model=list[BaseFlightWaypoint])
|
||||
def all_waypoints_for_flight(
|
||||
flight_id: UUID, game: Game = Depends(GameContext.get)
|
||||
) -> list[FlightWaypoint]:
|
||||
flight = game.db.flights.get(flight_id)
|
||||
departure = FlightWaypoint(
|
||||
FlightWaypointType.TAKEOFF,
|
||||
flight.departure.position.x,
|
||||
flight.departure.position.y,
|
||||
meters(0),
|
||||
)
|
||||
departure.alt_type = "RADIO"
|
||||
points = [departure] + flight.flight_plan.waypoints
|
||||
for point in points:
|
||||
point.update_latlng(game.theater)
|
||||
return points
|
||||
|
||||
|
||||
@router.post("/{flight_id}/{waypoint_idx}/position")
|
||||
def set_position(
|
||||
flight_id: UUID,
|
||||
waypoint_idx: int,
|
||||
position: LatLon,
|
||||
game: Game = Depends(GameContext.get),
|
||||
) -> None:
|
||||
flight = game.db.flights.get(flight_id)
|
||||
if waypoint_idx == 0:
|
||||
raise HTTPException(status_code=status.HTTP_403_FORBIDDEN)
|
||||
|
||||
waypoint = flight.flight_plan.waypoints[waypoint_idx - 1]
|
||||
if not waypoint.is_movable:
|
||||
raise HTTPException(status_code=status.HTTP_403_FORBIDDEN)
|
||||
|
||||
point = game.theater.ll_to_point(position)
|
||||
waypoint.x = point.x
|
||||
waypoint.y = point.y
|
||||
package_model = (
|
||||
GameContext.get_model()
|
||||
.ato_model_for(flight.blue)
|
||||
.find_matching_package_model(flight.package)
|
||||
)
|
||||
if package_model is None:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_404_NOT_FOUND,
|
||||
detail=f"Could not find PackageModel owning {flight}",
|
||||
)
|
||||
package_model.update_tot()
|
||||
|
||||
|
||||
@router.get("/{flight_id}/{waypoint_idx}/timing")
|
||||
def waypoint_timing(
|
||||
flight_id: UUID, waypoint_idx: int, game: Game = Depends(GameContext.get)
|
||||
) -> str | None:
|
||||
flight = game.db.flights.get(flight_id)
|
||||
if waypoint_idx == 0:
|
||||
return f"Depart T+{flight.flight_plan.takeoff_time()}"
|
||||
|
||||
waypoint = flight.flight_plan.waypoints[waypoint_idx - 1]
|
||||
prefix = "TOT"
|
||||
time = flight.flight_plan.tot_for_waypoint(waypoint)
|
||||
if time is None:
|
||||
prefix = "Depart"
|
||||
time = flight.flight_plan.depart_time_for_waypoint(waypoint)
|
||||
if time is None:
|
||||
return ""
|
||||
return f"{prefix} T+{timedelta(seconds=int(time.total_seconds()))}"
|
||||
Reference in New Issue
Block a user