While the host has no controller session, events between the instance
and the controller are dropped in both directions, and research_sync
only synced technologies on instance start. A technology finished during
the outage stayed unresearched on the controller and on every other
instance until the instance restarted.
On a new session the instance now runs the same technology sync as on
start, before taking the cluster queue. Contributions made while the
controller is unreachable are summed per technology and sent on connect
or resume, since progress from several instances can't be rebuilt from a
state sync that keeps the highest progress. A finish made while the
connection was dropped triggers the sync on resume too.
sync_technologies now runs while the game is running, so it skips
writing progress to a technology that finished after the dump.
Fixes#1123
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A QueueEvent arriving in the same socket read as a QueueSyncRequest reply is
applied before the reply, which then wrote the older queue over it. Skip the
reply when a QueueEvent was applied while it was in flight.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>