From 94c9be05c99d89d55d0f892deac35be9e6b7f457 Mon Sep 17 00:00:00 2001 From: Tim Angus Date: Thu, 17 Jul 2025 20:43:05 +0100 Subject: [PATCH] Pull out non curl specific code from the curl backend --- code/client/cl_http.h | 4 +- code/client/cl_http_curl.c | 54 ++++-------------------- code/client/cl_main.c | 84 +++++++++++++++++++++++++++++++------- 3 files changed, 78 insertions(+), 64 deletions(-) diff --git a/code/client/cl_http.h b/code/client/cl_http.h index a8005784..2c86d5d8 100644 --- a/code/client/cl_http.h +++ b/code/client/cl_http.h @@ -28,7 +28,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA qboolean CL_HTTP_Init( void ); qboolean CL_HTTP_Available( void ); void CL_HTTP_Shutdown( void ); -void CL_HTTP_BeginDownload( const char *localName, const char *remoteURL ); -void CL_HTTP_PerformDownload( void ); +void CL_HTTP_BeginDownload( const char *remoteURL ); +qboolean CL_HTTP_PerformDownload( void ); #endif // __CL_HTTP_H__ diff --git a/code/client/cl_http_curl.c b/code/client/cl_http_curl.c index 3e513eea..f88bff26 100644 --- a/code/client/cl_http_curl.c +++ b/code/client/cl_http_curl.c @@ -264,30 +264,11 @@ CURLcode qcurl_easy_setopt_warn(CURL *curl, CURLoption option, ...) return result; } -void CL_HTTP_BeginDownload( const char *localName, const char *remoteURL ) +void CL_HTTP_BeginDownload( const char *remoteURL ) { CURLMcode result; - clc.httpUsed = qtrue; - Com_Printf("URL: %s\n", remoteURL); - Com_DPrintf("***** CL_HTTP_BeginDownload *****\n" - "Localname: %s\n" - "RemoteURL: %s\n" - "****************************\n", localName, remoteURL); CL_cURL_Cleanup(); - Q_strncpyz(clc.downloadURL, remoteURL, sizeof(clc.downloadURL)); - Q_strncpyz(clc.downloadName, localName, sizeof(clc.downloadName)); - Com_sprintf(clc.downloadTempName, sizeof(clc.downloadTempName), - "%s.tmp", localName); - - // Set so UI gets access to it - Cvar_Set("cl_downloadName", localName); - Cvar_Set("cl_downloadSize", "0"); - Cvar_Set("cl_downloadCount", "0"); - Cvar_SetValue("cl_downloadTime", cls.realtime); - - clc.downloadBlock = 0; // Starting new file - clc.downloadCount = 0; downloadCURL = qcurl_easy_init(); if(!downloadCURL) { @@ -295,16 +276,10 @@ void CL_HTTP_BeginDownload( const char *localName, const char *remoteURL ) "failed"); return; } - clc.download = FS_SV_FOpenFileWrite(clc.downloadTempName); - if(!clc.download) { - Com_Error(ERR_DROP, "CL_HTTP_BeginDownload: failed to open " - "%s for writing", clc.downloadTempName); - return; - } if(com_developer->integer) qcurl_easy_setopt_warn(downloadCURL, CURLOPT_VERBOSE, 1); - qcurl_easy_setopt_warn(downloadCURL, CURLOPT_URL, clc.downloadURL); + qcurl_easy_setopt_warn(downloadCURL, CURLOPT_URL, remoteURL); qcurl_easy_setopt_warn(downloadCURL, CURLOPT_TRANSFERTEXT, 0); qcurl_easy_setopt_warn(downloadCURL, CURLOPT_REFERER, va("ioQ3://%s", NET_AdrToString(clc.serverAddress))); @@ -337,19 +312,9 @@ void CL_HTTP_BeginDownload( const char *localName, const char *remoteURL ) Com_Error(ERR_DROP,"CL_HTTP_BeginDownload: qcurl_multi_add_handle() failed: %s", qcurl_multi_strerror(result)); return; } - - if(!(clc.sv_allowDownload & DLF_NO_DISCONNECT) && - !clc.disconnectedForHttpDownload) { - - CL_AddReliableCommand("disconnect", qtrue); - CL_WritePacket(); - CL_WritePacket(); - CL_WritePacket(); - clc.disconnectedForHttpDownload = qtrue; - } } -void CL_HTTP_PerformDownload(void) +qboolean CL_HTTP_PerformDownload(void) { CURLMcode res; CURLMsg *msg; @@ -362,17 +327,12 @@ void CL_HTTP_PerformDownload(void) i++; } if(res == CURLM_CALL_MULTI_PERFORM) - return; + return qfalse; msg = qcurl_multi_info_read(downloadCURLM, &c); if(msg == NULL) { - return; + return qfalse; } - FS_FCloseFile(clc.download); - if(msg->msg == CURLMSG_DONE && msg->data.result == CURLE_OK) { - FS_SV_Rename(clc.downloadTempName, clc.downloadName, qfalse); - clc.downloadRestart = qtrue; - } - else { + if(msg->msg != CURLMSG_DONE || msg->data.result != CURLE_OK) { long code; qcurl_easy_getinfo(msg->easy_handle, CURLINFO_RESPONSE_CODE, @@ -382,7 +342,7 @@ void CL_HTTP_PerformDownload(void) code, clc.downloadURL); } - CL_NextDownload(); + return qtrue; } #endif /* USE_HTTP */ diff --git a/code/client/cl_main.c b/code/client/cl_main.c index 3e36106c..0658fb5c 100644 --- a/code/client/cl_main.c +++ b/code/client/cl_main.c @@ -2154,34 +2154,73 @@ void CL_DownloadsComplete( void ) { /* ================= -CL_BeginDownload - -Requests a file to download from the server. Stores it in the current -game directory. +CL_InitDownload ================= */ -void CL_BeginDownload( const char *localName, const char *remoteName ) { - - Com_DPrintf("***** CL_BeginDownload *****\n" - "Localname: %s\n" - "Remotename: %s\n" - "****************************\n", localName, remoteName); - +static void CL_InitDownload( const char *localName ) { Q_strncpyz ( clc.downloadName, localName, sizeof(clc.downloadName) ); Com_sprintf( clc.downloadTempName, sizeof(clc.downloadTempName), "%s.tmp", localName ); // Set so UI gets access to it - Cvar_Set( "cl_downloadName", remoteName ); + Cvar_Set( "cl_downloadName", localName ); Cvar_Set( "cl_downloadSize", "0" ); Cvar_Set( "cl_downloadCount", "0" ); Cvar_SetValue( "cl_downloadTime", cls.realtime ); clc.downloadBlock = 0; // Starting new file clc.downloadCount = 0; +} +/* +================= +CL_BeginDownload + +Requests a file to download from the server. Stores it in the current +game directory. +================= +*/ +static void CL_BeginDownload( const char *remoteName ) { CL_AddReliableCommand(va("download %s", remoteName), qfalse); } +#ifdef USE_HTTP +/* +================= +CL_BeginHttpDownload +================= +*/ +static void CL_BeginHttpDownload( const char *remoteURL ) { + if(Q_strncmp(remoteURL, "http://", strlen("http://")) != 0 && + Q_strncmp(remoteURL, "https://", strlen("https://")) != 0) { + Com_Error(ERR_DROP, "Download Error: %s is a malformed/" + "unsupported URL", remoteURL); + } + + Com_Printf("URL: %s\n", remoteURL); + + CL_HTTP_BeginDownload(remoteURL); + Q_strncpyz(clc.downloadURL, remoteURL, sizeof(clc.downloadURL)); + + clc.download = FS_SV_FOpenFileWrite(clc.downloadTempName); + if(!clc.download) { + Com_Error(ERR_DROP, "CL_BeginHTTPDownload: failed to open " + "%s for writing", clc.downloadTempName); + } + + if(!(clc.sv_allowDownload & DLF_NO_DISCONNECT) && + !clc.disconnectedForHttpDownload) { + + CL_AddReliableCommand("disconnect", qtrue); + CL_WritePacket(); + CL_WritePacket(); + CL_WritePacket(); + clc.disconnectedForHttpDownload = qtrue; + } + + clc.httpUsed = qtrue; +} +#endif /* USE_HTTP */ + /* ================= CL_NextDownload @@ -2244,8 +2283,10 @@ void CL_NextDownload(void) "have sv_dlURL set\n"); } else if(CL_HTTP_Available()) { - CL_HTTP_BeginDownload(localName, va("%s/%s", + CL_InitDownload(localName); + CL_BeginHttpDownload(va("%s/%s", clc.sv_dlURL, remoteName)); + usedHTTP = qtrue; } } @@ -2265,7 +2306,8 @@ void CL_NextDownload(void) return; } else { - CL_BeginDownload( localName, remoteName ); + CL_InitDownload( localName ); + CL_BeginDownload( remoteName ); } } clc.downloadRestart = qtrue; @@ -2932,7 +2974,19 @@ void CL_Frame ( int msec ) { #ifdef USE_HTTP if(clc.httpUsed) { - CL_HTTP_PerformDownload(); + qboolean finished = CL_HTTP_PerformDownload(); + + if(finished) { + if(clc.download) { + FS_FCloseFile(clc.download); + clc.download = 0; + } + + FS_SV_Rename(clc.downloadTempName, clc.downloadName, qfalse); + clc.downloadRestart = qtrue; + CL_NextDownload(); + } + // we can't process frames normally when in disconnected // download mode since the ui vm expects clc.state to be // CA_CONNECTED