diff --git a/engine/common/protocol.h b/engine/common/protocol.h index ac501c5a2..816be4e57 100644 --- a/engine/common/protocol.h +++ b/engine/common/protocol.h @@ -110,6 +110,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #else #define SERVER_SUPPORTED_Z_EXTENSIONS (Z_EXT_PM_TYPE|Z_EXT_PM_TYPE_NEW|Z_EXT_PITCHLIMITS|Z_EXT_JOIN_OBSERVE|Z_EXT_PF_ONGROUND|Z_EXT_VWEP|Z_EXT_PF_SOLID) #endif +#define BUGGY_EZQUAKE_Z_EXTENSIONS (Z_EXT_PF_ONGROUND|Z_EXT_PF_SOLID) //ezquake bugs out on these when ANY fteextension is present. hack the serverinfo to hide these. #define CLIENT_SUPPORTED_Z_EXTENSIONS (SERVER_SUPPORTED_Z_EXTENSIONS|Z_EXT_PF_ONGROUND|Z_EXT_PF_SOLID) diff --git a/engine/server/sv_main.c b/engine/server/sv_main.c index a46805214..27a012f90 100644 --- a/engine/server/sv_main.c +++ b/engine/server/sv_main.c @@ -1970,11 +1970,60 @@ void SV_ClientProtocolExtensionsChanged(client_t *client) client->fteprotocolextensions &= Net_PextMask(PROTOCOL_VERSION_FTE1, ISNQCLIENT(client)); client->fteprotocolextensions2 &= Net_PextMask(PROTOCOL_VERSION_FTE2, ISNQCLIENT(client)); client->ezprotocolextensions1 &= Net_PextMask(PROTOCOL_VERSION_EZQUAKE1, ISNQCLIENT(client)) & EZPEXT1_SERVERADVERTISE; + client->zquake_extensions &= SERVER_SUPPORTED_Z_EXTENSIONS; //some gamecode can't cope with some extensions for some reasons... and I'm too lazy to fix the code to cope. if (svs.gametype == GT_HALFLIFE) client->fteprotocolextensions2 &= ~PEXT2_REPLACEMENTDELTAS; //baseline issues +#ifdef HAVE_LEGACY + if (ISQWCLIENT(client)) + { + //be prepared to recognise client versions, in order to block known-buggy extensions. + const char *s; + int ver; + extern cvar_t pext_ezquake_nochunks; + extern cvar_t pext_ezquake_verfortrans; + s = InfoBuf_ValueForKey(&client->userinfo, "*client"); + if (!strncmp(s, "ezQuake", 7) || !strncmp(s, "FortressOne", 11)) + { + COM_Parse(s); //skip name-of-fork + COM_Parse(s); //tokenize the version + ver = atoi(com_token); + + //this should actually have been resolved now, but for future use... + if ((client->fteprotocolextensions & PEXT_CHUNKEDDOWNLOADS) && pext_ezquake_nochunks.ival) + { + client->fteprotocolextensions &= ~PEXT_CHUNKEDDOWNLOADS; + SV_PrintToClient(client, PRINT_HIGH, "ezQuake's implementation of chunked downloads is blocked on this server.\n"); + } + + //client fails to read the extra byte when PF_EXTRA_PFS is set, instead checking for the 18th bit in a 16-bit (signed) variable. + if ((client->fteprotocolextensions & PEXT_TRANS) && ver < pext_ezquake_verfortrans.ival) + { + SV_PrintToClient(client, PRINT_HIGH, "ezQuake's implementation of PEXT_TRANS is buggy. Disabling.\n"); + client->fteprotocolextensions &= ~PEXT_TRANS; + } + //in order to simultaneously support PF_SOLID+Z_EXT_PF_SOLID and PF_HULLSIZE_Z+Z_EXT_PF_ONGROUND, I had to redefine the protocol when both were enabled. + //ezquake does not understand the change. + if ((client->zquake_extensions & (Z_EXT_PF_ONGROUND|Z_EXT_PF_SOLID)) && ver < pext_ezquake_verfortrans.ival) + { + if (client->fteprotocolextensions & PEXT_HULLSIZE) + SV_PrintToClient(host_client, PRINT_HIGH, "ezQuake's implementation of PEXT_HULLSIZE conflicts with zquake extensions.\n"); + if (client->fteprotocolextensions & PEXT_SCALE) + SV_PrintToClient(host_client, PRINT_HIGH, "ezQuake's implementation of PEXT_SCALE conflicts with zquake extensions.\n"); + if (client->fteprotocolextensions & PEXT_FATNESS) + SV_PrintToClient(host_client, PRINT_HIGH, "ezQuake's implementation of PEXT_FATNESS conflicts with zquake extensions.\n"); + if (client->fteprotocolextensions & PEXT_TRANS) + SV_PrintToClient(host_client, PRINT_HIGH, "ezQuake's implementation of PEXT_TRANS conflicts with zquake extensions.\n"); + client->fteprotocolextensions &= ~(PEXT_HULLSIZE|PEXT_TRANS|PEXT_SCALE|PEXT_FATNESS); + } + } + + //its not that I'm singling out ezquake or anything, but it has too many people using outdated versions that its hard to ignore. + } +#endif + // client->maxmodels = 256; if (client->fteprotocolextensions & PEXT_256PACKETENTITIES) diff --git a/engine/server/sv_user.c b/engine/server/sv_user.c index fe16434d3..7277c71d4 100644 --- a/engine/server/sv_user.c +++ b/engine/server/sv_user.c @@ -80,8 +80,8 @@ cvar_t sv_nqplayerphysics = CVARAFCD("sv_nqplayerphysics", "auto", "sv_nomsec", #ifdef HAVE_LEGACY static cvar_t sv_brokenmovetypes = CVARD("sv_brokenmovetypes", "0", "Emulate vanilla quakeworld by forcing MOVETYPE_WALK on all players. Shouldn't be used for any games other than QuakeWorld."); -static cvar_t pext_ezquake_nochunks = CVARD("pext_ezquake_nochunks", "0", "Prevents ezquake clients from being able to use the chunked download extension. This sidesteps numerous ezquake issues, and will make downloads slower but more robust."); -static cvar_t pext_ezquake_verfortrans = CVARD("pext_ezquake_verfortrans", "999999999", "ezQuake does not implement PEXT_TRANS properly. This is the version of ezquake required for PEXT_TRANS to be allowed. This was still broken when I wrote this description, hence the large value."); +cvar_t pext_ezquake_nochunks = CVARD("pext_ezquake_nochunks", "0", "Prevents ezquake clients from being able to use the chunked download extension. This sidesteps numerous ezquake issues, and will make downloads slower but more robust."); +cvar_t pext_ezquake_verfortrans = CVARD("pext_ezquake_verfortrans", "999999999", "ezQuake does not implement PEXT_TRANS properly. This is the version of ezquake required for PEXT_TRANS to be allowed. This was still broken when I wrote this description, hence the large value."); #endif cvar_t sv_chatfilter = CVAR("sv_chatfilter", "0"); @@ -320,42 +320,6 @@ void SV_New_f (void) return; } -#ifdef HAVE_LEGACY - { - //be prepared to recognise client versions, in order to block known-buggy extensions. - const char *s; - int ver; - s = InfoBuf_ValueForKey(&host_client->userinfo, "*client"); - if (!strncmp(s, "ezQuake", 7) || !strncmp(s, "FortressOne", 11)) - { - COM_Parse(s); //skip name-of-fork - COM_Parse(s); //tokenize the version - ver = atoi(com_token); - - //this should actually have been resolved now, but for future use... - if ((host_client->fteprotocolextensions & PEXT_CHUNKEDDOWNLOADS) && pext_ezquake_nochunks.ival) - { - host_client->fteprotocolextensions &= ~PEXT_CHUNKEDDOWNLOADS; - SV_PrintToClient(host_client, PRINT_HIGH, "ezQuake's implementation of chunked downloads is blocked on this server.\n"); - } - if ((host_client->zquake_extensions & (Z_EXT_PF_SOLID|Z_EXT_PF_ONGROUND)) && ver < pext_ezquake_verfortrans.ival) - { - if (host_client->fteprotocolextensions & PEXT_HULLSIZE) - SV_PrintToClient(host_client, PRINT_HIGH, "ezQuake's implementation of PEXT_HULLSIZE conflicts with zquake extensions.\n"); - if (host_client->fteprotocolextensions & PEXT_SCALE) - SV_PrintToClient(host_client, PRINT_HIGH, "ezQuake's implementation of PEXT_SCALE conflicts with zquake extensions.\n"); - if (host_client->fteprotocolextensions & PEXT_FATNESS) - SV_PrintToClient(host_client, PRINT_HIGH, "ezQuake's implementation of PEXT_FATNESS conflicts with zquake extensions.\n"); - if (host_client->fteprotocolextensions & PEXT_TRANS) - SV_PrintToClient(host_client, PRINT_HIGH, "ezQuake's implementation of PEXT_TRANS is buggy. Disabling.\n"); - host_client->fteprotocolextensions &= ~(PEXT_HULLSIZE|PEXT_TRANS|PEXT_SCALE|PEXT_FATNESS); - } - } - - //its not that I'm singling out ezquake or anything, but it has too many people using outdated versions that its hard to ignore. - } -#endif - ClientReliableCheckBlock(host_client, 800); //okay, so it might be longer, but I'm too lazy to work out the real size. // send the serverdata @@ -1094,6 +1058,7 @@ void SV_SendClientPrespawnInfo(client_t *client) if (!ISNQCLIENT(client) || (client->fteprotocolextensions2 & PEXT2_PREDINFO)) { //nq does not normally get serverinfo sent to it. i = InfoBuf_ToString(&svs.info, buffer, sizeof(buffer), NULL, NULL, NULL, &client->infosync, &svs.info); + Info_SetValueForStarKey(buffer, "*z_ext", va("%i", client->zquake_extensions), sizeof(buffer)); //should already be in there, so this should only ever make it shorter. ClientReliableWrite_Begin(client, svc_stufftext, 20 + i); ClientReliableWrite_String (client, va("fullserverinfo \"%s\"\n", buffer) ); }