diff options
-rw-r--r-- | assets/ui/download.menu | 167 | ||||
-rw-r--r-- | assets/ui/menus.txt | 1 | ||||
-rw-r--r-- | src/client/cl_main.c | 189 | ||||
-rw-r--r-- | src/qcommon/q_shared.h | 9 | ||||
-rw-r--r-- | src/ui/ui_gameinfo.c | 2 | ||||
-rw-r--r-- | src/ui/ui_main.c | 31 |
6 files changed, 348 insertions, 51 deletions
diff --git a/assets/ui/download.menu b/assets/ui/download.menu new file mode 100644 index 00000000..6bde3a67 --- /dev/null +++ b/assets/ui/download.menu @@ -0,0 +1,167 @@ +#include "ui/menudef.h" + +{ + \\ DOWNLOAD \\ + + menuDef + { + name "download_popmenu" + visible MENU_FALSE + fullscreen MENU_FALSE + rect 158 80 320 320 + focusColor 1 .75 0 1 + style WINDOW_STYLE_FILLED + border WINDOW_BORDER_FULL + popup + onClose { } + onOpen + { + uiScript loadServerInfo; + } + onESC + { + play "sound/misc/menu1.wav"; + close download_popmenu; + uiScript downloadIgnore; + } + + itemDef + { + name window + rect 10 15 300 320 + style WINDOW_STYLE_FILLED + backcolor 0 0 0 1 + visible MENU_TRUE + decoration + + border WINDOW_BORDER_FULL + borderSize 1.0 + borderColor 0.5 0.5 0.5 1 + } + + itemDef + { + name downloadinfo + rect 0 50 320 20 + text "Download" + textalign ALIGN_CENTER + textstyle ITEM_TEXTSTYLE_SHADOWEDMORE + textscale .333 + forecolor 1 1 1 1 + visible MENU_TRUE + decoration + } + + itemDef + { + name downloadinfo + rect 60 80 200 270 + type ITEM_TYPE_TEXT + style WINDOW_STYLE_FILLED + textstyle ITEM_TEXTSTYLE_SHADOWED + wrapped + cvar "com_downloadPromptText" + textalign ALIGN_CENTER + textvalign VALIGN_TOP + textscale .25 + forecolor 1 1 1 1 + visible MENU_TRUE + decoration + } + + + // BUTTON // + + + itemDef + { + name curl + text "Download from website" + textscale .25 + group grpControlbutton + type ITEM_TYPE_BUTTON + style WINDOW_STYLE_EMPTY + rect 60 250 200 15 + textalign ALIGN_CENTER + forecolor 1 1 1 1 + backcolor .37 .1 .1 1 + visible MENU_TRUE + cvarTest "ui_serverinfo_allowdl" + showCvar { 1 5 9 13 } + action + { + play "sound/misc/menu1.wav"; + close download_popmenu; + uiScript downloadCURL; + } + } + + itemDef + { + name udp + text "Download from server" + type ITEM_TYPE_BUTTON + textscale .25 + group grpControlbutton + style WINDOW_STYLE_EMPTY + rect 60 265 200 15 + textalign ALIGN_CENTER + forecolor 1 1 1 1 + backcolor .37 .1 .1 1 + visible MENU_TRUE + cvarTest "ui_serverinfo_allowdl" + showCvar { 1 3 9 11 } + action + { + play "sound/misc/menu1.wav"; + close download_popmenu; + uiScript downloadUDP; + } + } + + itemDef + { + name ignore + text "Ignore" + type ITEM_TYPE_BUTTON + textscale .25 + group grpControlbutton + style WINDOW_STYLE_EMPTY + rect 60 280 200 15 + textalign ALIGN_CENTER + forecolor 1 1 1 1 + backcolor .37 .1 .1 1 + visible MENU_TRUE + cvarTest "sv_pure" + hideCvar { 1 } + action + { + play "sound/misc/menu1.wav"; + close download_popmenu; + uiScript downloadIgnore; + } + } + + itemDef + { + name disconnect + text "Disconnect" + type ITEM_TYPE_BUTTON + textscale .25 + group grpControlbutton + type ITEM_TYPE_BUTTON + style WINDOW_STYLE_EMPTY + rect 60 295 200 15 + textalign ALIGN_CENTER + forecolor 1 1 1 1 + backcolor .37 .1 .1 1 + visible 1 + action + { + play "sound/misc/menu1.wav"; + close download_popmenu; + exec "disconnect"; + } + } + } +} diff --git a/assets/ui/menus.txt b/assets/ui/menus.txt index 25cc09bd..294d9953 100644 --- a/assets/ui/menus.txt +++ b/assets/ui/menus.txt @@ -12,6 +12,7 @@ loadMenu { "ui/quit.menu" } loadMenu { "ui/addfilter.menu" } loadMenu { "ui/error.menu" } + loadMenu { "ui/download.menu" } loadMenu { "ui/drop.menu" } loadMenu { "ui/serverinfo.menu" } loadMenu { "ui/findplayer.menu" } diff --git a/src/client/cl_main.c b/src/client/cl_main.c index 3551682f..9e2add18 100644 --- a/src/client/cl_main.c +++ b/src/client/cl_main.c @@ -87,6 +87,7 @@ cvar_t *cl_activeAction; cvar_t *cl_motdString; cvar_t *cl_allowDownload; +cvar_t *com_downloadPrompt; cvar_t *cl_conXOffset; cvar_t *cl_inGameVideo; @@ -1781,6 +1782,7 @@ Called when all downloading has been completed ================= */ void CL_DownloadsComplete( void ) { + Com_Printf("Downloads complete\n"); #ifdef USE_CURL // if we downloaded with cURL @@ -1873,8 +1875,8 @@ void CL_BeginDownload( const char *localName, const char *remoteName ) { clc.downloadBlock = 0; // Starting new file clc.downloadCount = 0; - // Stop any errant looping sounds that may be playing - S_ClearLoopingSounds( qtrue ); + // Stop any errant looping sounds that may be playing + S_ClearLoopingSounds( qtrue ); CL_AddReliableCommand( va("download %s", remoteName) ); } @@ -1890,9 +1892,95 @@ void CL_NextDownload(void) { char *s; char *remoteName, *localName; qboolean useCURL = qfalse; + int prompt; // We are looking to start a download here if (*clc.downloadList) { + + // Prompt if we do not allow automatic downloads + prompt = com_downloadPrompt->integer; + if( !( prompt & DLP_TYPE_MASK ) && + !( cl_allowDownload->integer & DLF_ENABLE ) ) { + char files[ MAX_INFO_STRING ], *name, *head, *pure_msg, + *url_msg = ""; + int i = 0, others = 0, swap = 0, max_list = 12; + + // Set the download URL message + if( ( clc.sv_allowDownload & DLF_ENABLE ) && + !( clc.sv_allowDownload & DLF_NO_REDIRECT ) ) { + url_msg = va("The server redirects to the following URL:\n%s", + clc.sv_dlURL); + max_list -= 6; + } + + // Make a pretty version of the download list + name = clc.downloadList; + if( *name == '@' ) + name++; + + do { + // Copy remote name + head = name; + while( *head && *head != '@' ) + head++; + + swap = *head; + *head = 0; + + if( i++ < max_list ) { + Com_sprintf( files, sizeof( files ), "%s%s%s", + files, i > 1 ? ", " : "", name ); + } else { + others++; + } + + *head = swap; + if( !swap ) + break; + + // Skip local name + head++; + while( *head && *head != '@' ) + head++; + + name = head + 1; + } while( *head ); + + if( others ) { + Com_sprintf( files, sizeof( files ), + "%s (%d other file%s)\n", files, others, + others > 1 ? "s" : "" ); + } + + // Set the pure message + if( cl_connectedToPureServer ) { + if( !( clc.sv_allowDownload & DLF_ENABLE ) || + ( ( clc.sv_allowDownload & DLF_NO_UDP ) && + ( clc.sv_allowDownload & DLF_NO_REDIRECT ) ) ) { + pure_msg = "You are missing files required by the server. " + "The server does not allow downloading. " + "You must install these files manually:"; + } else { + pure_msg = "You are missing files required by the server. " + "You must download these files or disconnect:"; + } + } else { + pure_msg = "You are missing optional files provided by the " + "server. You may not need them to play but can " + "choose to download them anyway:"; + } + + Cvar_Set( "com_downloadPromptText", + va("%s\n\n%s\n%s", pure_msg, files, url_msg ) ); + Cvar_Set( "com_downloadPrompt", va("%d", DLP_SHOW ) ); + return; + } + + if( !( prompt & DLP_PROMPTED ) ) + Cvar_Set( "com_downloadPrompt", va("%d", prompt | DLP_PROMPTED ) ); + + prompt &= DLP_TYPE_MASK; + s = clc.downloadList; // format is: @@ -1914,42 +2002,56 @@ void CL_NextDownload(void) { else s = localName + strlen(localName); // point at the nul byte #ifdef USE_CURL - if(!(cl_allowDownload->integer & DLF_NO_REDIRECT)) { + if( ( ( cl_allowDownload->integer & DLF_ENABLE ) && + !( cl_allowDownload->integer & DLF_NO_REDIRECT ) ) || + prompt == DLP_CURL ) { + Com_Printf("Trying CURL download: %s; %s\n", localName, remoteName); if(clc.sv_allowDownload & DLF_NO_REDIRECT) { Com_Printf("WARNING: server does not " - "allow download redirection " - "(sv_allowDownload is %d)\n", - clc.sv_allowDownload); + "allow download redirection " + "(sv_allowDownload is %d)\n", + clc.sv_allowDownload); } else if(!*clc.sv_dlURL) { Com_Printf("WARNING: server allows " - "download redirection, but does not " - "have sv_dlURL set\n"); + "download redirection, but does not " + "have sv_dlURL set\n"); } else if(!CL_cURL_Init()) { Com_Printf("WARNING: could not load " - "cURL library\n"); + "cURL library\n"); } else { CL_cURL_BeginDownload(localName, va("%s/%s", - clc.sv_dlURL, remoteName)); + clc.sv_dlURL, remoteName)); useCURL = qtrue; } } else if(!(clc.sv_allowDownload & DLF_NO_REDIRECT)) { - Com_Printf("WARNING: server allows download " - "redirection, but it disabled by client " - "configuration (cl_allowDownload is %d)\n", - cl_allowDownload->integer); + Com_Printf("WARNING: server allows download " + "redirection, but it disabled by client " + "configuration (cl_allowDownload is %d)\n", + cl_allowDownload->integer); } #endif /* USE_CURL */ if(!useCURL) { - if((cl_allowDownload->integer & DLF_NO_UDP)) { - Com_Error(ERR_DROP, "UDP Downloads are " - "disabled on your client. " - "(cl_allowDownload is %d)", - cl_allowDownload->integer); - return; + Com_Printf("Trying UDP download: %s; %s\n", localName, remoteName); + + if( ( !( cl_allowDownload->integer & DLF_ENABLE ) || + ( cl_allowDownload->integer & DLF_NO_UDP ) ) && + prompt != DLP_UDP ) { + if( cl_connectedToPureServer ) { + Com_Error(ERR_DROP, "Automatic downloads are " + "disabled on your client (cl_allowDownload is %d). " + "You can enable automatic downloads in the Options " + "menu.", + cl_allowDownload->integer); + return; + } + + Com_Printf("WARNING: UDP downloads are disabled.\n"); + CL_DownloadsComplete(); + return; } else { CL_BeginDownload( localName, remoteName ); @@ -1975,34 +2077,15 @@ and determine if we need to download them ================= */ void CL_InitDownloads(void) { - char missingfiles[1024]; - - if ( !(cl_allowDownload->integer & DLF_ENABLE) ) - { - // autodownload is disabled on the client - // but it's possible that some referenced files on the server are missing - if (FS_ComparePaks( missingfiles, sizeof( missingfiles ), qfalse ) ) - { - // NOTE TTimo I would rather have that printed as a modal message box - // but at this point while joining the game we don't know wether we will successfully join or not - Com_Printf( "\nWARNING: You are missing some files referenced by the server:\n%s" - "You might not be able to join the game\n" - "Go to the setting menu to turn on autodownload, or get the file elsewhere\n\n", missingfiles ); - } - } - else if ( FS_ComparePaks( clc.downloadList, sizeof( clc.downloadList ) , qtrue ) ) { - + if ( FS_ComparePaks( clc.downloadList, sizeof( clc.downloadList ) , qtrue ) ) { Com_Printf("Need paks: %s\n", clc.downloadList ); - + Cvar_Set( "com_downloadPrompt", "0" ); if ( *clc.downloadList ) { - // if autodownloading is not enabled on the server cls.state = CA_CONNECTED; CL_NextDownload(); return; } - } - CL_DownloadsComplete(); } @@ -2525,6 +2608,28 @@ void CL_Frame ( int msec ) { return; } + // We may have a download prompt ready + if( ( com_downloadPrompt->integer & DLP_TYPE_MASK ) && + !( com_downloadPrompt->integer & DLP_PROMPTED ) ) { + Com_Printf( "Download prompt returned %d\n", + com_downloadPrompt->integer ); + CL_NextDownload( ); + } + else if( com_downloadPrompt->integer & DLP_SHOW ) { + // If the UI VM does not support the download prompt, we need to catch + // the prompt here and replicate regular behavior. + // One frame will always run between requesting and showing the prompt. + + if( com_downloadPrompt->integer & DLP_STALE ) { + Com_Printf( "WARNING: UI VM does not support download prompt\n" ); + Cvar_Set( "com_downloadPrompt", va( "%d", DLP_IGNORE ) ); + CL_NextDownload( ); + } else { + Cvar_Set( "com_downloadPrompt", + va( "%d", com_downloadPrompt->integer | DLP_STALE ) ); + } + } + #ifdef USE_CURL if(clc.downloadCURLM) { CL_cURL_PerformDownload(); @@ -3029,6 +3134,8 @@ void CL_Init( void ) { #ifdef USE_CURL cl_cURLLib = Cvar_Get("cl_cURLLib", DEFAULT_CURL_LIB, CVAR_ARCHIVE); #endif + com_downloadPrompt = Cvar_Get ("com_downloadPrompt", "0", CVAR_TEMP); + Cvar_Get( "com_downloadPromptText", "", CVAR_TEMP ); cl_conXOffset = Cvar_Get ("cl_conXOffset", "0", 0); #ifdef MACOS_X diff --git a/src/qcommon/q_shared.h b/src/qcommon/q_shared.h index dc1d2058..622d71fe 100644 --- a/src/qcommon/q_shared.h +++ b/src/qcommon/q_shared.h @@ -1357,4 +1357,13 @@ typedef enum { #define MAX_EMOTICON_NAME_LEN 16 #define MAX_EMOTICONS 64 +// flags for com_downloadPrompt +#define DLP_TYPE_MASK 0x0f +#define DLP_IGNORE 0x01 // don't download anything +#define DLP_CURL 0x02 // download via HTTP redirect +#define DLP_UDP 0x04 // download from server +#define DLP_SHOW 0x10 // prompt needs to be shown +#define DLP_PROMPTED 0x20 // prompt has been processed by client +#define DLP_STALE 0x40 // prompt is not being shown by UI VM + #endif // __Q_SHARED_H diff --git a/src/ui/ui_gameinfo.c b/src/ui/ui_gameinfo.c index 4315ddfb..c11f7248 100644 --- a/src/ui/ui_gameinfo.c +++ b/src/ui/ui_gameinfo.c @@ -367,5 +367,7 @@ void UI_ServerInfo( void ) Info_ValueForKey( info, "g_unlagged" ) ); trap_Cvar_Set( "ui_serverinfo_ff", Info_ValueForKey( info, "ff" ) ); + trap_Cvar_Set( "ui_serverinfo_allowdl", + Info_ValueForKey( info, "sv_allowdownload" ) ); } } diff --git a/src/ui/ui_main.c b/src/ui/ui_main.c index ddc525e1..00cc23f2 100644 --- a/src/ui/ui_main.c +++ b/src/ui/ui_main.c @@ -2849,15 +2849,18 @@ static void UI_RunMenuScript( char **args ) Controls_SetConfig( qtrue ); else if( Q_stricmp( name, "loadControls" ) == 0 ) Controls_GetConfig(); - else if( Q_stricmp( name, "clearError" ) == 0 ) - trap_Cvar_Set( "com_errorMessage", "" ); - else if( Q_stricmp( name, "RefreshServers" ) == 0 ) - { - UI_StartServerRefresh( qtrue ); - UI_BuildServerDisplayList( qtrue ); - } - else if( Q_stricmp( name, "InitServerList" ) == 0 ) - { + else if (Q_stricmp(name, "clearError") == 0) { + trap_Cvar_Set("com_errorMessage", ""); + } else if (Q_stricmp(name, "downloadIgnore") == 0) { + trap_Cvar_Set("com_downloadPrompt", va("%d", DLP_IGNORE)); + } else if (Q_stricmp(name, "downloadCURL") == 0) { + trap_Cvar_Set("com_downloadPrompt", va("%d", DLP_CURL)); + } else if (Q_stricmp(name, "downloadUDP") == 0) { + trap_Cvar_Set("com_downloadPrompt", va("%d", DLP_UDP)); + } else if (Q_stricmp(name, "RefreshServers") == 0) { + UI_StartServerRefresh(qtrue); + UI_BuildServerDisplayList(qtrue); + } else if (Q_stricmp(name, "InitServerList") == 0) { int time = trap_RealTime( NULL ); int last; int sortColumn; @@ -4387,7 +4390,15 @@ void UI_DrawConnectScreen( qboolean overlay ) case CA_CONNECTED: { char downloadName[MAX_INFO_VALUE]; - + int prompt = trap_Cvar_VariableValue( "com_downloadPrompt" ); + + if( prompt & DLP_SHOW ) { + Com_Printf("Opening download prompt...\n"); + trap_Key_SetCatcher( KEYCATCH_UI ); + Menus_ActivateByName("download_popmenu"); + trap_Cvar_Set( "com_downloadPrompt", "0" ); + } + trap_Cvar_VariableStringBuffer( "cl_downloadName", downloadName, sizeof( downloadName ) ); if( *downloadName ) |