Steps to reproduce:
1) Player A builds a CB sensor.
2) Player B attacks the CB sensor with a mortar borg.
3) Player B runs away with the mortar borg where player A can't see.
4) Player A builds artillery.
5) Player B slowly kills off all the artillery with an MG viper wheels tank, while the artillery just sits there
pointing at the mortar borg without firing.
To trigger, the artillery must be built after the last CB sensor in range of where the mortar borg attacks. Any
type of mobile artillery can trigger the bug, such as archangel leopard tracks, or MRA dragon wheels.
Workaround: Player A can build an uplink, so that the mortar borg becomes visible, and the artillery fires. If
there's still anything left of the artillery by the time the uplink is built, that is.
Fixes ticket:3529.
Desynch was due to host-spoofed GAME_PLAYER_LEFT message being processed by clients at random times.
Instead of putting the GAME_PLAYER_LEFT in a NET_SHARE_GAME_QUEUE, put the GAME_PLAYER_LEFT in a NET_SHARE_GAME_QUEUE
in a NET_SEND_TO_PLAYER, such that the clients' NETrecvNet() will process the GAME_PLAYER_LEFT in the same iteration
of the for (current = 0; current < MAX_CONNECTED_PLAYERS; ++current) loop as the real GAME_* messages from that
player, and therefore not mix up the messages.
To reproduce before this commit, start 8-or-so clients, set all to debug mode, change game speed of some clients
slightly, start kicking players. Keep trying again, until desynch is reproduced. Changing game speed of some clients
might or might not be required.
See 93f0e61d92.
Although it no longer crashed when trying to join a game with some closed slots (see previous commits), it is also
desirable to actually be able to join it.
NET_CreatePlayer() should not be able to fail here, though. See following commit.
Crash was due to treating ERROR_FULL == 2 as an uint8_t pointer, and trying to dereference it.
Spurious assertions are possible in the case that the research tree is excessively interconnected, such as
researches 31-40 all depending on all of researches 21-30, and researches 21-30 all depending on all researches
11-20, and so on. Although it probably shouldn't assert on excessively interconnected research trees, the loop as
written could take a ridiculously long time, anyway.
For some weird reason, select() sometimes returns that a socket write would not block, but the socket write does
block, anyway.
On display in the bottom of a locked manpage for select(), stuck in a disused lavatory with a sign on the door
saying "Beware of the Leopard":
BUGS
Under Linux, select() may report a socket file descriptor as "ready for reading", while nevertheless a
subsequent read blocks. This could for example happen when data has arrived but upon examination has wrong
checksum and is discarded. There may be other circumstances in which a file descriptor is spuriously
reported as ready. Thus it may be safer to use O_NONBLOCK on sockets that should not block.
This would explain a socket read unexpectedly blocking, although the issue is actually a socket write unexpectedly
blocking.
Fixes ticket:3410, or else.
Previous unconventional behaviour was to consider the set of previously-unselected droids becoming selected, and
report the size of the set plus the size of the set of types of droids in the set.
Iff there was exactly one droid of each type previously selected, and there was at least one unselected droid of
each selected type, then the reported unit count would coincidentally be correct.
Fixes ticket:3479.
Nexus was building units with an unresearched sensor (equivalent to the default sensor). Since
6365f2dbec, Nexus can no longer build unresearched units.
In the tutorial, the designed MG viper wheels would also use the same unresearched sensor.
Replaced unresearched DefaultSensor1Mk1 with ZNULLSENSOR. Removed special case for tutorial in
7079ad2951, which is no longer required.
Problem persisted until the frozen client drops completely, or unfreezes (net connection is restored).
To reproduce, test with host and 2 other clients, and freeze one client with kill -STOP or by pausing the net
connection somehow.
Cause was lack of flushing, due to an inverted condition exposed in b9cc7702b7 and
introduced in c1ca4d2d34. Would probably trigger before
b9cc7702b7, for any remaining clients that freeze for any reason (for example, because
of <2.5 FPS or momentary hard drive swapping) for more than 400ms.