diff --git a/src/pr2_cmds.c b/src/pr2_cmds.c index 7a705a6a..abcc029b 100644 --- a/src/pr2_cmds.c +++ b/src/pr2_cmds.c @@ -1572,6 +1572,10 @@ void PF2_infokey(int e1, char *key, char *valbuff, int sizebuff) snprintf(ov, sizeof(ov), "%d", cl->file_percent ? cl->file_percent : -1); //bliP: file percent else if (!strcmp(key, "ping")) snprintf(ov, sizeof(ov), "%d", (int)SV_CalcPing(cl)); +#ifdef FTE_PEXT_CSQC + else if (!strcmp(key, "csqcactive") || !strcmp(key, "*csqcactive")) + snprintf(ov, sizeof(ov), "%d", (int)cl->csqcactive); +#endif else if (!strcmp(key, "*userid")) snprintf(ov, sizeof(ov), "%d", cl->userid); else if (!strncmp(key, "login", 6)) diff --git a/src/server.h b/src/server.h index 70c8cd8f..190a201e 100644 --- a/src/server.h +++ b/src/server.h @@ -128,6 +128,9 @@ typedef struct entity_state_t static_entities[512]; int static_entity_count; +#ifdef FTE_PEXT_CSQC + unsigned int csqcchecksum; +#endif } server_t; #define NUM_SPAWN_PARMS 16 @@ -345,6 +348,10 @@ typedef struct client_s } voice_target; #endif +#ifdef FTE_PEXT_CSQC + qbool csqcactive; +#endif + //===== NETWORK ============ qbool process_pext; // true if we wait for reply from client on "cmd pext" command. int chokecount; diff --git a/src/sv_init.c b/src/sv_init.c index 806b11c6..d18f47f8 100644 --- a/src/sv_init.c +++ b/src/sv_init.c @@ -196,6 +196,33 @@ static unsigned SV_CheckModel(char *mdl) return crc; } +#ifdef FTE_PEXT_CSQC +static void SV_LoadCSQC(void) +{ + extern cvar_t sv_csqc_progname; + int size; + + byte *file = FS_LoadTempFile(sv_csqc_progname.string, &size); + if (file) + { + char text[64]; + sv.csqcchecksum = Com_BlockChecksum(file, size); + sprintf(text, "0x%x", sv.csqcchecksum); + Info_SetValueForStarKey(svs.info, "*csprogs", text, MAX_SERVERINFO_STRING); + sprintf(text, "0x%x", (unsigned int)size); + Info_SetValueForStarKey(svs.info, "*csprogssize", text, MAX_SERVERINFO_STRING); + Info_SetValueForStarKey(svs.info, "*csprogsname", sv_csqc_progname.string, MAX_SERVERINFO_STRING); + } + else + { + sv.csqcchecksum = 0; + Info_SetValueForStarKey(svs.info, "*csprogs", "", MAX_SERVERINFO_STRING); + Info_SetValueForStarKey(svs.info, "*csprogssize", "", MAX_SERVERINFO_STRING); + Info_SetValueForStarKey(svs.info, "*csprogsname", "", MAX_SERVERINFO_STRING); + } +} +#endif + /* ================ SV_SpawnServer @@ -339,6 +366,10 @@ void SV_SpawnServer(char *mapname, qbool devmap, char* entityfile, qbool loading sv.time = 1.0; +#ifdef FTE_PEXT_CSQC + SV_LoadCSQC(); +#endif + // load progs to get entity field count // which determines how big each edict is // and allocate edicts diff --git a/src/sv_main.c b/src/sv_main.c index 97935baf..a759112e 100644 --- a/src/sv_main.c +++ b/src/sv_main.c @@ -194,6 +194,10 @@ cvar_t sv_pext_mvdsv_serversideweapon = { "sv_pext_mvdsv_serversideweapon", "1" cvar_t sv_extlimits = { "sv_extlimits", "2" }; +#ifdef FTE_PEXT_CSQC +cvar_t sv_csqc_progname = { "sv_csqc_progname", "csprogs.dat" }; +#endif + qbool sv_error = false; client_t *WatcherId = NULL; // QW262 @@ -3529,6 +3533,10 @@ void SV_InitLocal (void) Cvar_Register(&sv_mod_extensions); +#ifdef FTE_PEXT_CSQC + Cvar_Register (&sv_csqc_progname); +#endif + // QW262 --> Cmd_AddCommand ("svadmin", SV_Admin_f); // <-- QW262 @@ -3570,6 +3578,9 @@ void SV_InitLocal (void) #ifdef FTE_PEXT_SPAWNSTATIC2 svs.fteprotocolextensions |= FTE_PEXT_SPAWNSTATIC2; #endif +#ifdef FTE_PEXT_CSQC + svs.fteprotocolextensions |= FTE_PEXT_CSQC; +#endif #ifdef FTE_PEXT2_VOICECHAT svs.fteprotocolextensions2 |= FTE_PEXT2_VOICECHAT; diff --git a/src/sv_user.c b/src/sv_user.c index 71f6d70d..9623aac4 100644 --- a/src/sv_user.c +++ b/src/sv_user.c @@ -318,6 +318,17 @@ static void Cmd_New_f (void) if (!gamedir[0]) gamedir = "qw"; +#ifdef FTE_PEXT_CSQC + if (sv.csqcchecksum && !(sv_client->fteprotocolextensions & FTE_PEXT_CSQC)) + { + SV_ClientPrintf(sv_client, PRINT_HIGH, "\n\n\n\n" + "This server is using CSQC - you are missing out due to your choice of outdated client / protocol!\n" + "Please upgrade to one of the following:\n" + "> ezQuake (https://www.ezquake.com) (hardcoded KTX support)\n" + "> FTEQW (http://fte.triptohell.info/)\n"); + } +#endif + #ifdef FTE_PEXT_FLOATCOORDS if (msg_coordsize > 2 && !(sv_client->fteprotocolextensions & FTE_PEXT_FLOATCOORDS)) { @@ -1416,10 +1427,14 @@ static void Cmd_Download_f(void) if (sv_client->special) allow_dl = true; // NOTE: user used techlogin, allow dl anything in quake dir in such case! - else if (!strstr(name, "/")) - allow_dl = false; // should be in subdir else if (!(int)allow_download.value) allow_dl = false; // global allow check +#ifdef FTE_PEXT_CSQC + else if (!strncmp(name, "csprogs.dat", 11)) + allow_dl = true; // we always allow csprogs.dat to be downloaded (if downloads are permitted). +#endif + else if (!strstr(name, "/")) + allow_dl = false; // should be in subdir else if (!strncmp(name, "skins/", 6)) allow_dl = allow_download_skins.value; // skins else if (!strncmp(name, "progs/", 6)) @@ -3042,6 +3057,18 @@ void SV_Voice_UnmuteAll_f(void) #endif // FTE_PEXT2_VOICECHAT +#ifdef FTE_PEXT_CSQC +void SV_EnableClientsCSQC(void) +{ + sv_client->csqcactive = true; +} + +void SV_DisableClientsCSQC(void) +{ + sv_client->csqcactive = false; +} +#endif + /* * Parse protocol extensions which supported by client. * This is workaround for the proxy case, like: qwfwd. We can't use it in case of qizmo thought. @@ -3293,6 +3320,11 @@ static ucmd_t ucmds[] = {"unmuteall", SV_Voice_UnmuteAll_f, false}, /*reenables*/ #endif +#ifdef FTE_PEXT_CSQC + {"enablecsqc", SV_EnableClientsCSQC, false}, + {"disablecsqc", SV_DisableClientsCSQC, false}, +#endif + {"pext", Cmd_PEXT_f, false}, // user reply with supported protocol extensions. #if defined(SERVERONLY) && defined(WWW_INTEGRATION)