From 9823f7b96fa6c68cc685e8a7b0d6250d104ada1d Mon Sep 17 00:00:00 2001 From: Raffson Date: Wed, 6 Jul 2022 22:27:06 +0200 Subject: [PATCH] Push full navmesh/threatzone info in the event stream. https://github.com/dcs-liberation/dcs_liberation/issues/2253 https://github.com/dcs-liberation/dcs_liberation/issues/2263 --- client/src/api/eventstream.tsx | 27 ++++++++------------------- client/src/api/navMeshSlice.ts | 17 ++++++++++------- client/src/api/threatZonesSlice.ts | 18 +++++++++++++++--- game/coalition.py | 4 ++-- game/server/eventstream/models.py | 20 ++++++++++++++++---- game/sim/gameupdateevents.py | 14 ++++++++------ 6 files changed, 59 insertions(+), 41 deletions(-) diff --git a/client/src/api/eventstream.tsx b/client/src/api/eventstream.tsx index 2b32858a..4dfb1a5e 100644 --- a/client/src/api/eventstream.tsx +++ b/client/src/api/eventstream.tsx @@ -17,12 +17,13 @@ import { } from "./frontLinesSlice"; import reloadGameState from "./gamestate"; import { - liberationApi, ControlPoint, Flight, FrontLine, IadsConnection, + NavMesh, Tgo, + ThreatZones, UnculledZone, } from "./liberationApi"; import { navMeshUpdated } from "./navMeshSlice"; @@ -37,9 +38,9 @@ interface GameUpdateEvents { new_combats: Combat[]; updated_combats: Combat[]; ended_combats: string[]; - navmesh_updates: boolean[]; + navmesh_updates: {blue: boolean, mesh: NavMesh}[]; updated_unculled_zones: UnculledZone[]; - threat_zones_updated: boolean; + threat_zones_updated: {blue: boolean, zones: ThreatZones}[]; new_flights: Flight[]; updated_flights: Flight[]; deleted_flights: string[]; @@ -78,28 +79,16 @@ export const handleStreamedEvents = ( dispatch(endCombat(id)); } - for (const blue of events.navmesh_updates) { - dispatch( - liberationApi.endpoints.getNavmesh.initiate({ forPlayer: blue }) - ).then((result) => { - if (result.data) { - dispatch(navMeshUpdated({ blue: blue, mesh: result.data })); - } - }); + if (Object.keys(events.navmesh_updates).length > 0) { + dispatch(navMeshUpdated(events.navmesh_updates)); } if (events.updated_unculled_zones.length > 0) { dispatch(unculledZonesUpdated(events.updated_unculled_zones)); } - if (events.threat_zones_updated) { - dispatch(liberationApi.endpoints.getThreatZones.initiate()).then( - (result) => { - if (result.data) { - dispatch(threatZonesUpdated(result.data)); - } - } - ); + if (Object.keys(events.threat_zones_updated).length > 0) { + dispatch(threatZonesUpdated(events.threat_zones_updated)); } if (events.new_flights.length > 0) { diff --git a/client/src/api/navMeshSlice.ts b/client/src/api/navMeshSlice.ts index ea1f0ed0..3aa5cf67 100644 --- a/client/src/api/navMeshSlice.ts +++ b/client/src/api/navMeshSlice.ts @@ -13,7 +13,7 @@ const initialState: NavMeshState = { red: [], }; -interface INavMeshUpdate { +export interface INavMeshUpdate { blue: boolean; mesh: NavMesh; } @@ -22,12 +22,15 @@ const navMeshSlice = createSlice({ name: "navmesh", initialState: initialState, reducers: { - updated: (state, action: PayloadAction) => { - const polys = action.payload.mesh.polys; - if (action.payload.blue) { - state.blue = polys; - } else { - state.red = polys; + updated: (state, action: PayloadAction) => { + for (const [blue, navmesh] of Object.entries(action.payload)) { + const data = {blue: (blue === "true"), mesh: navmesh} as unknown as INavMeshUpdate + const polys = data.mesh.polys; + if (data.blue) { + state.blue = polys; + } else { + state.red = polys; + } } }, }, diff --git a/client/src/api/threatZonesSlice.ts b/client/src/api/threatZonesSlice.ts index 902fef1d..c0d35d4c 100644 --- a/client/src/api/threatZonesSlice.ts +++ b/client/src/api/threatZonesSlice.ts @@ -1,6 +1,6 @@ import { RootState } from "../app/store"; import { gameLoaded, gameUnloaded } from "./actions"; -import { ThreatZoneContainer } from "./liberationApi"; +import { ThreatZoneContainer, ThreatZones } from "./liberationApi"; import { PayloadAction, createSlice } from "@reduxjs/toolkit"; interface ThreatZonesState { @@ -24,12 +24,24 @@ const initialState: ThreatZonesState = { }, }; +export interface IThreatZoneUpdate { + blue: boolean; + zones: ThreatZones; +} + export const threatZonesSlice = createSlice({ name: "threatZonesState", initialState, reducers: { - updated: (state, action: PayloadAction) => { - state.zones = action.payload; + updated: (state, action: PayloadAction) => { + for (const [blue, zones] of Object.entries(action.payload)) { + const data = {blue: (blue === "true"), zones: zones} as unknown as IThreatZoneUpdate + if (data.blue) { + state.zones.blue = data.zones; + } else { + state.zones.red = data.zones; + } + } }, }, extraReducers: (builder) => { diff --git a/game/coalition.py b/game/coalition.py index 4f3a8051..1f20b3de 100644 --- a/game/coalition.py +++ b/game/coalition.py @@ -121,13 +121,13 @@ class Coalition: def compute_threat_zones(self, events: GameUpdateEvents) -> None: self._threat_zone = ThreatZones.for_faction(self.game, self.player) - events.update_threat_zones() + events.update_threat_zones(self.player, self._threat_zone) def compute_nav_meshes(self, events: GameUpdateEvents) -> None: self._navmesh = NavMesh.from_threat_zones( self.opponent.threat_zone, self.game.theater ) - events.update_navmesh(self.player) + events.update_navmesh(self.player, self._navmesh) def update_transit_network(self) -> None: self.transit_network = TransitNetworkBuilder( diff --git a/game/server/eventstream/models.py b/game/server/eventstream/models.py index 582928b2..cfe4a063 100644 --- a/game/server/eventstream/models.py +++ b/game/server/eventstream/models.py @@ -11,6 +11,8 @@ from game.server.flights.models import FlightJs from game.server.frontlines.models import FrontLineJs from game.server.iadsnetwork.models import IadsConnectionJs from game.server.leaflet import LeafletPoint +from game.server.mapzones.models import ThreatZonesJs +from game.server.navmesh.models import NavMeshJs from game.server.tgos.models import TgoJs from game.server.mapzones.models import UnculledZoneJs @@ -24,9 +26,9 @@ class GameUpdateEventsJs(BaseModel): new_combats: list[FrozenCombatJs] updated_combats: list[FrozenCombatJs] ended_combats: list[UUID] - navmesh_updates: set[bool] + navmesh_updates: dict[bool, NavMeshJs] updated_unculled_zones: list[UnculledZoneJs] - threat_zones_updated: bool + threat_zones_updated: dict[bool, ThreatZonesJs] new_flights: list[FlightJs] updated_flights: list[FlightJs] deleted_flights: set[UUID] @@ -51,6 +53,8 @@ class GameUpdateEventsJs(BaseModel): # because we need to send the unload event. new_combats = [] updated_combats = [] + updated_navmeshes = {} + updated_threat_zones = {} updated_unculled_zones = [] updated_iads = [] if game is not None: @@ -61,6 +65,14 @@ class GameUpdateEventsJs(BaseModel): FrozenCombatJs.for_combat(c, game.theater) for c in events.updated_combats ] + updated_navmeshes = { + player: NavMeshJs.from_navmesh(mesh, game) + for player, mesh in events.navmesh_updates.items() + } + updated_threat_zones = { + player: ThreatZonesJs.from_zones(zones, game.theater) + for player, zones in events.threat_zones_updated.items() + } updated_unculled_zones = UnculledZoneJs.from_game(game) for node in events.updated_iads: updated_iads.extend(IadsConnectionJs.connections_for_node(node)) @@ -72,9 +84,9 @@ class GameUpdateEventsJs(BaseModel): new_combats=new_combats, updated_combats=updated_combats, ended_combats=[c.id for c in events.ended_combats], - navmesh_updates=events.navmesh_updates, + navmesh_updates=updated_navmeshes, updated_unculled_zones=updated_unculled_zones, - threat_zones_updated=events.threat_zones_updated, + threat_zones_updated=updated_threat_zones, new_flights=[ FlightJs.for_flight(f, with_waypoints=True) for f in events.new_flights ], diff --git a/game/sim/gameupdateevents.py b/game/sim/gameupdateevents.py index b25b362b..cf7371ef 100644 --- a/game/sim/gameupdateevents.py +++ b/game/sim/gameupdateevents.py @@ -10,8 +10,10 @@ from dcs.mapping import LatLng if TYPE_CHECKING: from game import Game from game.ato import Flight, Package + from game.navmesh import NavMesh from game.sim.combat import FrozenCombat from game.theater import ControlPoint, FrontLine, TheaterGroundObject + from game.threatzones import ThreatZones from game.theater.iadsnetwork.iadsnetwork import IadsNetworkNode @@ -22,9 +24,9 @@ class GameUpdateEvents: updated_combats: list[FrozenCombat] = field(default_factory=list) ended_combats: list[FrozenCombat] = field(default_factory=list) updated_flight_positions: list[tuple[Flight, Point]] = field(default_factory=list) - navmesh_updates: set[bool] = field(default_factory=set) + navmesh_updates: dict[bool, NavMesh] = field(default_factory=dict) unculled_zones_updated: list[Point] = field(default_factory=list) - threat_zones_updated: bool = False + threat_zones_updated: dict[bool, ThreatZones] = field(default_factory=dict) new_flights: set[Flight] = field(default_factory=set) updated_flights: set[Flight] = field(default_factory=set) deleted_flights: set[UUID] = field(default_factory=set) @@ -67,16 +69,16 @@ class GameUpdateEvents: self.updated_flight_positions.append((flight, new_position)) return self - def update_navmesh(self, player: bool) -> GameUpdateEvents: - self.navmesh_updates.add(player) + def update_navmesh(self, player: bool, navmesh: NavMesh) -> GameUpdateEvents: + self.navmesh_updates[player] = navmesh return self def update_unculled_zones(self, zones: list[Point]) -> GameUpdateEvents: self.unculled_zones_updated = zones return self - def update_threat_zones(self) -> GameUpdateEvents: - self.threat_zones_updated = True + def update_threat_zones(self, player: bool, zones: ThreatZones) -> GameUpdateEvents: + self.threat_zones_updated[player] = zones return self def new_flight(self, flight: Flight) -> GameUpdateEvents: