(1) All mode change code unified, so server mode changes and client mode
changes and announcements go through the same functions
(2) New messages which are translateable and work with multiple input
devices
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 makes spectator mode and slave mode in netplay always stay
ahead of the input, thereby avoiding rewinds, which is sort of the
point. This also changes catch-up detection to be a bit less eager, so
that they hopefully don't flap between stalling for server input and
catching up with that input.
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.
Previously, if two clients were connected to the same server and one of
them was ahead of the server, the only way to rectify that situation was
for the client to get so far ahead that it stalled, as the server could
only catch up with an ahead client if all clients were ahead. That's
unrealistic. This gives the server the alternate option of demanding
that a client stall. This keeps things nicely in line even with >2
players.
Previously, we could be stalled by one player but still reading data
from another, which would wedge the client because we would never act
upon the newly-read data. Now we act upon data even if we're stalled.
Fixes bugs in initial connection with high latency.
Making the netplay handshake protocol send the core and content as an
explicit command, so that the other side can (notionally) choose to load
it. That isn't implemented, of course.