@@ -248,12 +248,9 @@ private static string Truncate(string value) =>
248248 m . Groups [ "flags" ] . Success
249249 && m . Groups [ "flags" ] . Value . Contains ( "ShowInLog" , StringComparison . Ordinal ) ) ) ,
250250
251+ "CEntityComponentShipListProvider::SetVehicleSpawningInformations" or
251252 "CEntityComponentShipListProvider::SetVehicleSpawnedInformations" =>
252- Match ( VehicleSpawnRegex , line , m =>
253- new VehicleSpawnEvent (
254- line . Timestamp ,
255- m . Groups [ "entity" ] . Value ,
256- m . Groups [ "area" ] . Success ? m . Groups [ "area" ] . Value . Trim ( ) : null ) ) ,
253+ ParseVehicleSpawn ( line ) ,
257254
258255 "AttachmentReceived" => Match ( AttachmentRegex , line , m =>
259256 new AttachmentEvent (
@@ -565,6 +562,36 @@ internal static (string? Manufacturer, string Model) SplitVehicleId(string vehic
565562 return m . Success ? project ( m ) : null ;
566563 }
567564
565+ /// <summary>
566+ /// A ship being retrieved, from either spelling of the line.
567+ /// </summary>
568+ /// <remarks>
569+ /// Both spellings mark the same retrieval: "Spawning" when the request goes
570+ /// in, "Spawned" a few seconds later once the ship is on the pad. Build
571+ /// 12519617 stopped emitting "Spawned" at all, so reading only that one lost
572+ /// every retrieval on current builds - and silently, because the tag simply
573+ /// stopped appearing rather than failing to parse. The timestamp is
574+ /// therefore the request, not the arrival, which is all the current build
575+ /// offers. <see cref="SessionBuilder"/> collapses the pair by entity id, so
576+ /// reading both does not double-count a retrieval on older logs.
577+ ///
578+ /// The ASOP terminal also emits an [Error] twin of the request line when it
579+ /// cannot resolve the landing area name. It repeats an entity id already
580+ /// being retrieved on the line beside it, so it is not a second retrieval
581+ /// and must not count as a parse failure either.
582+ /// </remarks>
583+ private GameEvent ? ParseVehicleSpawn ( LogLine line )
584+ {
585+ if ( line . Body . Contains ( "Invalid landingAreaLocStr" , StringComparison . Ordinal ) )
586+ return null ;
587+
588+ return Match ( VehicleSpawnRegex , line , m =>
589+ new VehicleSpawnEvent (
590+ line . Timestamp ,
591+ m . Groups [ "entity" ] . Value ,
592+ m . Groups [ "area" ] . Success ? m . Groups [ "area" ] . Value . Trim ( ) : null ) ) ;
593+ }
594+
568595 /// <summary>
569596 /// Fleet queries log twice: an opening "Fetching vehicle list…" line with no
570597 /// counts, then a completion line carrying them. Only the latter is an event;
0 commit comments