Netplay state demotions, i.e. changes from playing to spectating or
disconnected states, could cause chain disconnections of all other
clients. This was due to a bug in when MODE change messages were sent.
Clients rely on the server sending all messages in its own order, and as
a consequence, the server typically holds messages for retransmission
until they can be retransmitted at the correct time. MODE messages were
not held, so could be sent early. When they were sent early, this caused
other clients to panic and disconnect.
A smaller but much stupider secondary bug was also fixed, in which the
first connection could be dropped due simply to writing connections[0]
instead of connections[i] somewhere.
This commit adds support for temporary desync in netplay. When frontend
features that can't be truly synced, in particular rewind, are used,
netplay is momentarily disabled. As soon as the feature finished, e.g. a
rewind ending, netplay resumes with a state load. For rewind, netplay
peers won't actually experience the effect of rewind, but they will load
the rewound state.
This used to be a configuration option because spectator mode and "net"
mode were incompatible. When the ability to switch between player and
spectator was added, the configuration option was removed, since it was
no longer a mode toggle. This re-adds it, mainly so that I can use it to
implement regression tests.
This patch transfers core_reset across netplay. Resets effectively
worked before thanks to check_frames, but this makes resets work even
without check_frames, and in particular should allow resets to force
sync in savestateless cores, bringing them one step closer to actually
being usable by non-experts.