(This is https://github.com/SpiritQuaddicted/reQuiem/issues/16 but I'll recap below.)
The short form of the situation is that it seems to be resolved by just removing a code snippet that jdhack had added. However I'd like to know why he might have added it. If you're bored and want to speculate, please do!
The function in question is PF_makestatic. In reQuiem it looks like this:
Code: Select all
void PF_makestatic (void)
{
edict_t *ent = G_EDICT(OFS_PARM0);
MSG_WriteSpawnstatic (&sv.signon, ent);
// JDH: if there's a local client running, send it a message
if (svs.clients[0].spawned && svs.clients[0].netconnection && !svs.clients[0].netconnection->socket)
MSG_WriteSpawnstatic (&svs.clients[0].message, ent);
// throw the entity away now
ED_Free (ent);
}
The code that writes to svs.clients[0] is jdhack's addition. Any guesses about what it is intended to do?
==========
Here's why it causes problems. The SV_SpawnServer flow during the triggered changelevel (when running in singleplayer) is:
- Unset the stored client and server protocol versions.
- Server protocol gets set again (to 10002 by default).
- Worldmodel is loaded.
- PR_LoadEdicts is called. This eventually ends up doing a lot of PF_makestatic calls.
- PF_makestatic shoves svc_spawnstatic messages both into sv.signon and also (because of jdhack's addition) into svs.clients[0].message.
- Because of the server protocol, all those svc_spawnstatic cmds use a short for modelindex instead of a byte.
- After all that, SV_SpawnServer calls SV_SendServerInfo. Among other things this generates an svc_serverinfo cmd (in svs.clients[0].message) that will tell the client which protocol version to use.
So at this point, in svs.clients[0].message we have svc_spawnstatic cmds followed later by svc_serverinfo (and a bit of other stuff).
At some point Host_PreSpawn_f is run, which copies the signon cmds to the end of svs.clients[0].message. So now it contains svc_spawnstatic cmds, then svc_serverinfo, then the same svc_spawnstatic cmds again.
When the client code tries to process this, it sees the initial set of svc_spawnstatic cmds before it sees the svc_serverinfo cmd. So it has a wrong (unset) protocol version when parsing the svc_spawnstatic cmds, it uses a byte rather than a short for modelindex, and things go downhill from there.
If I remove jdhack's change, then the message will contain svc_serverinfo before the svc_spawnstatics (from sv.signon) and things seem to work fine. But deleting someone else's code makes me nervous if I can't even guess what it is trying to do.
==========
Edit: thinking back, I'm not sure that I saw Host_PreSpawn_f copying to the same initial message, as opposed to some subsequent message. Shouldn't make a difference to the situation though.