2005-04-16 16:22:17 +00:00
# include "quakedef.h"
2005-12-22 02:29:11 +00:00
2005-11-03 23:49:49 +00:00
# ifdef WEBCLIENT
2006-01-21 00:06:49 +00:00
# define DOWNLOADMENU
2005-12-22 02:29:11 +00:00
# endif
# ifdef DOWNLOADMENU
2005-04-16 16:22:17 +00:00
2008-02-13 07:57:42 +00:00
# define ROOTDOWNLOADABLESSOURCE "http: //fteqw.com/downloadables.txt"
2005-04-16 16:22:17 +00:00
# define INSTALLEDFILES "installed.lst" //the file that resides in the quakedir (saying what's installed).
# define DPF_HAVEAVERSION 1 //any old version
# define DPF_WANTTOINSTALL 2 //user selected it
# define DPF_DISPLAYVERSION 4 //some sort of conflict, the package is listed twice, so show versions so the user knows what's old.
# define DPF_DELETEONUNINSTALL 8 //for previously installed packages, remove them from the list
2005-10-16 12:53:42 +00:00
# define DPF_DOWNLOADING 16
2006-01-28 06:41:20 +00:00
# define DPF_ENQUED 32
2005-10-16 12:53:42 +00:00
2013-03-12 23:03:04 +00:00
void CL_StartCinematicOrMenu ( void ) ;
2005-10-16 12:53:42 +00:00
int dlcount = 1 ;
2005-04-16 16:22:17 +00:00
2005-10-16 12:53:42 +00:00
//note: these are allocated for the life of the exe
2005-04-16 16:22:17 +00:00
char * downloadablelist [ 256 ] = {
2005-08-26 22:56:51 +00:00
ROOTDOWNLOADABLESSOURCE
2005-10-16 12:53:42 +00:00
} ;
char * downloadablelistnameprefix [ 256 ] = {
" "
} ;
2006-01-28 06:41:20 +00:00
char downloadablelistreceived [ 256 ] ; //well
2005-04-16 16:22:17 +00:00
int numdownloadablelists = 1 ;
typedef struct package_s {
char fullname [ 256 ] ;
char * name ;
char src [ 256 ] ;
char dest [ 64 ] ;
2005-10-14 18:28:44 +00:00
char gamedir [ 16 ] ;
2005-04-16 16:22:17 +00:00
unsigned int version ; //integral.
2005-10-16 12:53:42 +00:00
int dlnum ;
2005-04-16 16:22:17 +00:00
int flags ;
struct package_s * next ;
} package_t ;
typedef struct {
menucustom_t * list ;
2005-04-18 03:21:16 +00:00
char intermediatefilename [ MAX_QPATH ] ;
2006-01-28 06:41:20 +00:00
char pathprefix [ MAX_QPATH ] ;
2005-04-16 16:22:17 +00:00
int parsedsourcenum ;
2006-01-28 06:41:20 +00:00
qboolean populated ;
2005-04-16 16:22:17 +00:00
} dlmenu_t ;
package_t * availablepackages ;
int numpackages ;
2005-12-22 02:29:11 +00:00
static package_t * BuildPackageList ( vfsfile_t * f , int flags , char * prefix )
2005-04-16 16:22:17 +00:00
{
char line [ 1024 ] ;
package_t * p ;
package_t * first = NULL ;
char * sl ;
2005-10-14 18:28:44 +00:00
int version ;
2005-04-16 16:22:17 +00:00
do
{
2005-12-22 02:29:11 +00:00
if ( ! VFS_GETS ( f , line , sizeof ( line ) - 1 ) )
break ;
2005-04-16 16:22:17 +00:00
while ( ( sl = strchr ( line , ' \n ' ) ) )
* sl = ' \0 ' ;
while ( ( sl = strchr ( line , ' \r ' ) ) )
* sl = ' \0 ' ;
Cmd_TokenizeString ( line , false , false ) ;
2005-12-22 02:29:11 +00:00
} while ( ! Cmd_Argc ( ) ) ;
2005-04-16 16:22:17 +00:00
if ( strcmp ( Cmd_Argv ( 0 ) , " version " ) )
return NULL ; //it's not the right format.
2005-10-14 18:28:44 +00:00
version = atoi ( Cmd_Argv ( 1 ) ) ;
2005-10-16 12:53:42 +00:00
if ( version ! = 0 & & version ! = 1 )
2005-10-14 18:28:44 +00:00
{
2007-10-05 18:08:47 +00:00
Con_Printf ( " Packagelist is of a future or incompatible version \n " ) ;
2005-04-16 16:22:17 +00:00
return NULL ; //it's not the right version.
2005-10-14 18:28:44 +00:00
}
2005-04-16 16:22:17 +00:00
2005-12-22 02:29:11 +00:00
while ( 1 )
2005-04-16 16:22:17 +00:00
{
2005-12-22 02:29:11 +00:00
if ( ! VFS_GETS ( f , line , sizeof ( line ) - 1 ) )
2005-04-16 16:22:17 +00:00
break ;
while ( ( sl = strchr ( line , ' \n ' ) ) )
* sl = ' \0 ' ;
while ( ( sl = strchr ( line , ' \r ' ) ) )
* sl = ' \0 ' ;
Cmd_TokenizeString ( line , false , false ) ;
if ( Cmd_Argc ( ) )
{
2005-10-14 18:28:44 +00:00
if ( ! strcmp ( Cmd_Argv ( 0 ) , " sublist " ) )
2005-04-16 16:22:17 +00:00
{
2005-10-14 18:28:44 +00:00
int i ;
sl = Cmd_Argv ( 1 ) ;
2006-01-28 06:41:20 +00:00
for ( i = 0 ; i < numdownloadablelists ; i + + )
2005-04-16 16:22:17 +00:00
{
2005-10-14 18:28:44 +00:00
if ( ! strcmp ( downloadablelist [ i ] , sl ) )
break ;
}
2006-01-28 06:41:20 +00:00
if ( i = = numdownloadablelists & & i ! = 256 )
2005-10-14 18:28:44 +00:00
{
downloadablelist [ i ] = BZ_Malloc ( strlen ( sl ) + 1 ) ;
strcpy ( downloadablelist [ i ] , sl ) ;
2005-10-16 12:53:42 +00:00
if ( * prefix )
sl = va ( " %s/%s " , prefix , Cmd_Argv ( 2 ) ) ;
else
sl = Cmd_Argv ( 2 ) ;
downloadablelistnameprefix [ i ] = BZ_Malloc ( strlen ( sl ) + 1 ) ;
strcpy ( downloadablelistnameprefix [ i ] , sl ) ;
2006-01-28 06:41:20 +00:00
numdownloadablelists + + ;
2005-10-14 18:28:44 +00:00
i + + ;
2005-04-16 16:22:17 +00:00
}
2005-10-14 18:28:44 +00:00
continue ;
}
2005-04-16 16:22:17 +00:00
2005-10-14 18:28:44 +00:00
if ( Cmd_Argc ( ) > 5 | | Cmd_Argc ( ) < 3 )
{
2005-04-16 16:22:17 +00:00
Con_Printf ( " Package list is bad - %s \n " , line ) ;
continue ; //but try the next line away
}
p = BZ_Malloc ( sizeof ( * p ) ) ;
2005-10-16 12:53:42 +00:00
if ( * prefix )
Q_strncpyz ( p - > fullname , va ( " %s/%s " , prefix , Cmd_Argv ( 0 ) ) , sizeof ( p - > fullname ) ) ;
else
Q_strncpyz ( p - > fullname , Cmd_Argv ( 0 ) , sizeof ( p - > fullname ) ) ;
2005-04-16 16:22:17 +00:00
p - > name = p - > fullname ;
while ( ( sl = strchr ( p - > name , ' / ' ) ) )
p - > name = sl + 1 ;
Q_strncpyz ( p - > src , Cmd_Argv ( 1 ) , sizeof ( p - > src ) ) ;
Q_strncpyz ( p - > dest , Cmd_Argv ( 2 ) , sizeof ( p - > dest ) ) ;
p - > version = atoi ( Cmd_Argv ( 3 ) ) ;
2005-10-14 18:28:44 +00:00
Q_strncpyz ( p - > gamedir , Cmd_Argv ( 4 ) , sizeof ( p - > gamedir ) ) ;
2005-10-16 12:53:42 +00:00
if ( ! * p - > gamedir )
strcpy ( p - > gamedir , " id1 " ) ;
2005-10-14 18:28:44 +00:00
2005-04-16 16:22:17 +00:00
p - > flags = flags ;
p - > next = first ;
first = p ;
}
}
return first ;
}
2005-10-16 12:53:42 +00:00
static void WriteInstalledPackages ( void )
{
2005-12-22 02:29:11 +00:00
char * s ;
2005-10-16 12:53:42 +00:00
package_t * p ;
2008-12-23 02:55:20 +00:00
vfsfile_t * f = FS_OpenVFS ( INSTALLEDFILES , " wb " , FS_ROOT ) ;
2005-10-16 12:53:42 +00:00
if ( ! f )
{
Con_Printf ( " menu_download: Can't update installed list \n " ) ;
return ;
}
2005-12-22 02:29:11 +00:00
s = " version 1 \n " ;
VFS_WRITE ( f , s , strlen ( s ) ) ;
2005-10-16 12:53:42 +00:00
for ( p = availablepackages ; p ; p = p - > next )
{
if ( p - > flags & DPF_HAVEAVERSION )
2005-12-22 02:29:11 +00:00
{
2006-02-17 19:54:47 +00:00
s = va ( " \" %s \" \" %s \" \" %s \" %i \" %s \" \n " , p - > fullname , p - > src , p - > dest , p - > version , p - > gamedir ) ;
2005-12-22 02:29:11 +00:00
VFS_WRITE ( f , s , strlen ( s ) ) ;
}
2005-10-16 12:53:42 +00:00
}
2005-12-22 02:29:11 +00:00
VFS_CLOSE ( f ) ;
2005-10-16 12:53:42 +00:00
}
static qboolean ComparePackages ( package_t * * l , package_t * p )
2005-04-16 16:22:17 +00:00
{
int v = strcmp ( ( * l ) - > fullname , p - > fullname ) ;
if ( v < 0 )
{
p - > next = ( * l ) ;
( * l ) = p ;
return true ;
}
else if ( v = = 0 )
{
if ( p - > version = = ( * l ) - > version )
if ( ! strcmp ( ( * l ) - > dest , p - > dest ) )
{ /*package matches, free, don't add*/
strcpy ( ( * l ) - > src , p - > src ) ; //use the source of the new package (existing packages are read FIRST)
( * l ) - > flags | = p - > flags ;
2005-10-16 12:53:42 +00:00
( * l ) - > flags & = ~ DPF_DELETEONUNINSTALL ;
2005-04-16 16:22:17 +00:00
BZ_Free ( p ) ;
return true ;
}
p - > flags | = DPF_DISPLAYVERSION ;
( * l ) - > flags | = DPF_DISPLAYVERSION ;
}
return false ;
}
2005-10-16 12:53:42 +00:00
static void InsertPackage ( package_t * * l , package_t * p )
2005-04-16 16:22:17 +00:00
{
package_t * lp ;
if ( ! * l ) //there IS no list.
{
* l = p ;
p - > next = NULL ;
return ;
}
if ( ComparePackages ( l , p ) )
return ;
for ( lp = * l ; lp - > next ; lp = lp - > next )
{
if ( ComparePackages ( & lp - > next , p ) )
return ;
}
lp - > next = p ;
p - > next = NULL ;
}
2005-10-16 12:53:42 +00:00
static void ConcatPackageLists ( package_t * l2 )
2005-04-16 16:22:17 +00:00
{
package_t * n ;
while ( l2 )
{
n = l2 - > next ;
InsertPackage ( & availablepackages , l2 ) ;
l2 = n ;
numpackages + + ;
}
}
2010-03-14 14:35:56 +00:00
static void dlnotification ( struct dl_download * dl )
2005-08-26 22:56:51 +00:00
{
2005-10-16 12:53:42 +00:00
int i ;
2005-12-22 02:29:11 +00:00
vfsfile_t * f ;
2010-03-14 14:35:56 +00:00
f = dl - > file ;
dl - > file = NULL ;
2006-01-28 06:41:20 +00:00
2010-03-14 14:35:56 +00:00
i = dl - > user_num ;
2006-01-28 06:41:20 +00:00
2005-08-26 22:56:51 +00:00
if ( f )
{
2006-01-28 06:41:20 +00:00
downloadablelistreceived [ i ] = 1 ;
2005-10-16 12:53:42 +00:00
ConcatPackageLists ( BuildPackageList ( f , 0 , downloadablelistnameprefix [ i ] ) ) ;
2005-12-22 02:29:11 +00:00
VFS_CLOSE ( f ) ;
2005-08-26 22:56:51 +00:00
}
2006-01-28 06:41:20 +00:00
else
downloadablelistreceived [ i ] = - 1 ;
2005-08-26 22:56:51 +00:00
}
2006-01-28 06:41:20 +00:00
static void MD_Draw ( int x , int y , struct menucustom_s * c , struct menu_s * m )
2005-04-16 16:22:17 +00:00
{
2006-01-28 06:41:20 +00:00
package_t * p ;
2012-10-08 04:36:10 +00:00
int fl ;
2013-03-12 22:47:42 +00:00
p = c - > dptr ;
2006-01-28 06:41:20 +00:00
if ( p )
{
2009-11-04 21:16:50 +00:00
Draw_FunString ( x + 4 , y , " ^Ue080^Ue082 " ) ;
2005-04-16 16:22:17 +00:00
2012-10-08 04:36:10 +00:00
fl = p - > flags & ( DPF_HAVEAVERSION | DPF_WANTTOINSTALL ) ;
if ( ( p - > flags & ( DPF_DOWNLOADING | DPF_ENQUED ) ) & & ( ( int ) ( realtime * 4 ) & 1 ) )
fl | = DPF_HAVEAVERSION ; //flicker have if we're downloading it.
switch ( fl )
{
case 0 :
2009-11-04 21:16:50 +00:00
Draw_FunString ( x + 8 , y , " ^Ue081 " ) ;
2012-10-08 04:36:10 +00:00
break ;
case DPF_HAVEAVERSION :
Draw_FunString ( x , y , " REM " ) ;
break ;
case DPF_WANTTOINSTALL :
Draw_FunString ( x , y , " GET " ) ;
break ;
case DPF_HAVEAVERSION | DPF_WANTTOINSTALL :
Draw_FunString ( x + 8 , y , " ^Ue083 " ) ;
break ;
}
2006-01-28 06:41:20 +00:00
if ( & m - > selecteditem - > common = = & c - > common )
2009-11-04 21:16:50 +00:00
Draw_AltFunString ( x + 48 , y , p - > name ) ;
2006-01-28 06:41:20 +00:00
else
2009-11-04 21:16:50 +00:00
Draw_FunString ( x + 48 , y , p - > name ) ;
2006-01-28 06:41:20 +00:00
if ( p - > flags & DPF_DISPLAYVERSION )
{
2009-11-04 21:16:50 +00:00
Draw_FunString ( x + 48 + strlen ( p - > name ) * 8 , y , va ( " (%i.%i) " , p - > version / 1000 , p - > version % 1000 ) ) ;
2006-01-28 06:41:20 +00:00
}
}
}
static qboolean MD_Key ( struct menucustom_s * c , struct menu_s * m , int key )
{
package_t * p , * p2 ;
2013-03-12 22:47:42 +00:00
p = c - > dptr ;
2006-01-28 06:41:20 +00:00
if ( key = = K_ENTER | | key = = K_MOUSE1 )
{
p - > flags ^ = DPF_WANTTOINSTALL ;
if ( p - > flags & DPF_WANTTOINSTALL )
{
for ( p2 = availablepackages ; p2 ; p2 = p2 - > next )
{
if ( p = = p2 )
continue ;
if ( ! strcmp ( p - > dest , p2 - > dest ) )
p2 - > flags & = ~ DPF_WANTTOINSTALL ;
}
}
else
p - > flags & = ~ DPF_ENQUED ;
return true ;
}
2005-04-16 16:22:17 +00:00
2006-01-28 06:41:20 +00:00
return false ;
}
qboolean MD_PopMenu ( union menuoption_s * mo , struct menu_s * m , int key )
{
if ( key = = K_ENTER | | key = = K_MOUSE1 )
{
M_RemoveMenu ( m ) ;
return true ;
}
return false ;
}
2010-03-14 14:35:56 +00:00
static void Menu_Download_Got ( struct dl_download * dl ) ;
2006-01-28 06:41:20 +00:00
qboolean MD_ApplyDownloads ( union menuoption_s * mo , struct menu_s * m , int key )
{
if ( key = = K_ENTER | | key = = K_MOUSE1 )
{
char * temp ;
package_t * last = NULL , * p ;
for ( p = availablepackages ; p ; p = p - > next )
{
if ( ! ( p - > flags & DPF_WANTTOINSTALL ) & & ( p - > flags & DPF_HAVEAVERSION ) )
{ //if we don't want it but we have it anyway:
if ( * p - > gamedir )
{
2008-05-25 01:14:17 +00:00
char * fname = va ( " %s/%s " , p - > gamedir , p - > dest ) ;
2008-12-23 02:55:20 +00:00
FS_Remove ( fname , FS_ROOT ) ;
2006-01-28 06:41:20 +00:00
}
else
FS_Remove ( p - > dest , FS_GAME ) ;
p - > flags & = ~ DPF_HAVEAVERSION ; //FIXME: This is error prone.
WriteInstalledPackages ( ) ;
if ( p - > flags & DPF_DELETEONUNINSTALL )
{
if ( last )
last - > next = p - > next ;
else
availablepackages = p - > next ;
// BZ_Free(p);
return true ;
}
}
last = p ;
}
for ( p = availablepackages ; p ; p = p - > next )
{
if ( ( p - > flags & DPF_WANTTOINSTALL ) & & ! ( p - > flags & ( DPF_HAVEAVERSION | DPF_DOWNLOADING ) ) )
{ //if we want it and don't have it:
p - > dlnum = dlcount + + ;
temp = va ( " dl_%i.tmp " , p - > dlnum ) ;
Con_Printf ( " Downloading %s (to %s) \n " , p - > fullname , temp ) ;
p - > flags | = DPF_DOWNLOADING ;
if ( ! HTTP_CL_Get ( p - > src , temp , Menu_Download_Got ) )
p - > flags & = ~ DPF_DOWNLOADING ;
}
}
return true ;
}
return false ;
}
void M_AddItemsToDownloadMenu ( menu_t * m )
{
char path [ MAX_QPATH ] ;
int y ;
2005-04-16 16:22:17 +00:00
package_t * p ;
2006-01-28 06:41:20 +00:00
menucustom_t * c ;
char * slash ;
menuoption_t * mo ;
2005-04-16 16:22:17 +00:00
dlmenu_t * info = m - > data ;
2006-01-28 06:41:20 +00:00
int prefixlen ;
p = availablepackages ;
2005-04-16 16:22:17 +00:00
2012-10-08 04:36:10 +00:00
// MC_AddRedText(m, 0, 40, "WntHav", false);
2006-01-28 06:41:20 +00:00
prefixlen = strlen ( info - > pathprefix ) ;
2006-02-01 22:36:12 +00:00
y = 48 + 4 ;
2006-01-28 06:41:20 +00:00
for ( p = availablepackages ; p ; p = p - > next )
{
if ( strncmp ( p - > fullname , info - > pathprefix , prefixlen ) )
continue ;
slash = strchr ( p - > fullname + prefixlen , ' / ' ) ;
if ( slash )
{
Q_strncpyz ( path , p - > fullname , MAX_QPATH ) ;
slash = strchr ( path + prefixlen , ' / ' ) ;
if ( slash )
* slash = ' \0 ' ;
2008-02-13 07:57:42 +00:00
2006-01-28 06:41:20 +00:00
for ( mo = m - > options ; mo ; mo = mo - > common . next )
if ( mo - > common . type = = mt_button )
if ( ! strcmp ( mo - > button . text , path + prefixlen ) )
break ;
if ( ! mo )
{
2006-02-01 22:36:12 +00:00
MC_AddConsoleCommand ( m , 6 * 8 , y , path + prefixlen , va ( " menu_download \" %s/ \" " , path ) ) ;
2006-01-28 06:41:20 +00:00
y + = 8 ;
}
}
else
{
2013-03-12 22:47:42 +00:00
c = MC_AddCustom ( m , 0 , y , p , 0 ) ;
2006-01-28 06:41:20 +00:00
c - > draw = MD_Draw ;
c - > key = MD_Key ;
c - > common . width = 320 ;
c - > common . height = 8 ;
y + = 8 ;
}
}
y + = 4 ;
MC_AddCommand ( m , 0 , y , " Back " , MD_PopMenu ) ;
y + = 8 ;
MC_AddCommand ( m , 0 , y , " Apply " , MD_ApplyDownloads ) ;
/*
for ( pn = 1 , p = availablepackages ; p & & pn < info - > firstpackagenum ; p = p - > next , pn + + )
m - >
if ( lastpathlen ! = p - > name - p - > fullname | | strncmp ( p - > fullname , lastpath , lastpathlen ) )
{
lastpathlen = p - > name - p - > fullname ;
lastpath = p - > fullname ;
if ( ! lastpathlen )
Draw_FunStringLen ( x + 40 , y , " / " , 1 ) ;
else
Draw_FunStringLen ( x + 40 , y , p - > fullname , lastpathlen ) ;
y + = 8 ;
}
Draw_Character ( x , y , 128 ) ;
Draw_Character ( x + 8 , y , 130 ) ;
Draw_Character ( x + 16 , y , 128 ) ;
Draw_Character ( x + 24 , y , 130 ) ;
//if you want it
if ( p - > flags & DPF_WANTTOINSTALL )
Draw_Character ( x + 4 , y , 131 ) ;
else
Draw_Character ( x + 4 , y , 129 ) ;
//if you have it already
if ( p - > flags & ( DPF_HAVEAVERSION | ( ( ( ( int ) ( realtime * 4 ) ) & 1 ) ? DPF_DOWNLOADING : 0 ) ) )
Draw_Character ( x + 20 , y , 131 ) ;
else
Draw_Character ( x + 20 , y , 129 ) ;
if ( pn = = info - > highlightednum )
Draw_Alt_String ( x + 48 , y , p - > name ) ;
else
Draw_String ( x + 48 , y , p - > name ) ;
if ( p - > flags & DPF_DISPLAYVERSION )
{
Draw_String ( x + 48 + strlen ( p - > name ) * 8 , y , va ( " (%i.%i) " , p - > version / 1000 , p - > version % 1000 ) ) ;
}
*/
}
void M_Download_UpdateStatus ( struct menu_s * m )
{
2010-03-14 14:35:56 +00:00
struct dl_download * dl ;
2006-01-28 06:41:20 +00:00
dlmenu_t * info = m - > data ;
int i ;
while ( ! cls . downloadmethod & & ( info - > parsedsourcenum = = - 1 | | info - > parsedsourcenum < numdownloadablelists ) )
2005-04-16 16:22:17 +00:00
{ //done downloading
char basename [ 64 ] ;
info - > parsedsourcenum + + ;
2006-01-28 06:41:20 +00:00
if ( info - > parsedsourcenum < numdownloadablelists )
{
if ( ! downloadablelistreceived [ info - > parsedsourcenum ] )
{
sprintf ( basename , " dlinfo_%i.inf " , info - > parsedsourcenum ) ;
2010-03-14 14:35:56 +00:00
dl = HTTP_CL_Get ( downloadablelist [ info - > parsedsourcenum ] , basename , dlnotification ) ;
if ( dl )
dl - > user_num = info - > parsedsourcenum ;
else
2006-01-28 06:41:20 +00:00
Con_Printf ( " Could not contact server \n " ) ;
return ;
}
}
}
for ( i = 0 ; i < numdownloadablelists ; i + + )
{
if ( ! downloadablelistreceived [ i ] )
2005-04-16 16:22:17 +00:00
{
2006-01-28 06:41:20 +00:00
// Draw_String(x+8, y+8, "Waiting for package list");
return ;
2005-04-16 16:22:17 +00:00
}
}
2006-01-28 06:41:20 +00:00
2005-04-16 16:22:17 +00:00
if ( ! availablepackages )
{
2006-01-28 06:41:20 +00:00
// Draw_String(x+8, y+8, "Could not obtain a package list");
2005-04-16 16:22:17 +00:00
return ;
}
2006-01-28 06:41:20 +00:00
if ( ! info - > populated )
{
info - > populated = true ;
M_AddItemsToDownloadMenu ( m ) ;
}
}
/*
static void M_Download_Draw ( int x , int y , struct menucustom_s * c , struct menu_s * m )
{
int pn ;
int lastpathlen = 0 ;
char * lastpath = " " ;
package_t * p ;
dlmenu_t * info = m - > data ;
int i ;
2005-04-16 16:22:17 +00:00
y + = 8 ;
Draw_Alt_String ( x + 4 , y , " I H " ) ;
( info - > highlightednum = = 0 ? Draw_Alt_String : Draw_String ) ( x + 40 , y , " Apply changes " ) ;
y + = 8 ;
for ( pn = 1 , p = availablepackages ; p & & pn < info - > firstpackagenum ; p = p - > next , pn + + )
;
for ( ; p ; p = p - > next , y + = 8 , pn + + )
{
if ( lastpathlen ! = p - > name - p - > fullname | | strncmp ( p - > fullname , lastpath , lastpathlen ) )
{
lastpathlen = p - > name - p - > fullname ;
lastpath = p - > fullname ;
2005-10-14 18:28:44 +00:00
2005-04-16 16:22:17 +00:00
if ( ! lastpathlen )
Draw_FunStringLen ( x + 40 , y , " / " , 1 ) ;
else
Draw_FunStringLen ( x + 40 , y , p - > fullname , lastpathlen ) ;
y + = 8 ;
}
Draw_Character ( x , y , 128 ) ;
Draw_Character ( x + 8 , y , 130 ) ;
Draw_Character ( x + 16 , y , 128 ) ;
Draw_Character ( x + 24 , y , 130 ) ;
//if you want it
if ( p - > flags & DPF_WANTTOINSTALL )
Draw_Character ( x + 4 , y , 131 ) ;
else
Draw_Character ( x + 4 , y , 129 ) ;
//if you have it already
2005-10-16 12:53:42 +00:00
if ( p - > flags & ( DPF_HAVEAVERSION | ( ( ( ( int ) ( realtime * 4 ) ) & 1 ) ? DPF_DOWNLOADING : 0 ) ) )
2005-04-16 16:22:17 +00:00
Draw_Character ( x + 20 , y , 131 ) ;
else
Draw_Character ( x + 20 , y , 129 ) ;
if ( pn = = info - > highlightednum )
2005-10-20 00:07:14 +00:00
Draw_Alt_String ( x + 48 , y , p - > name ) ;
2005-04-16 16:22:17 +00:00
else
2005-10-20 00:07:14 +00:00
Draw_String ( x + 48 , y , p - > name ) ;
2005-04-16 16:22:17 +00:00
if ( p - > flags & DPF_DISPLAYVERSION )
{
2005-10-20 00:07:14 +00:00
Draw_String ( x + 48 + strlen ( p - > name ) * 8 , y , va ( " (%i.%i) " , p - > version / 1000 , p - > version % 1000 ) ) ;
2005-04-16 16:22:17 +00:00
}
}
}
2006-01-28 06:41:20 +00:00
*/
2010-03-14 14:35:56 +00:00
static void Menu_Download_Got ( struct dl_download * dl )
2005-04-16 16:22:17 +00:00
{
2010-03-14 14:35:56 +00:00
char * fname = dl - > localname ;
qboolean successful = dl - > status = = DL_FINISHED ;
2006-01-28 06:41:20 +00:00
char * ext ;
2005-10-16 12:53:42 +00:00
package_t * p ;
int dlnum = atoi ( fname + 3 ) ;
for ( p = availablepackages ; p ; p = p - > next )
{
if ( p - > dlnum = = dlnum )
{
char * destname ;
2006-01-28 06:41:20 +00:00
char * diskname = fname ;
2005-10-16 12:53:42 +00:00
if ( ! successful )
{
p - > flags & = ~ DPF_DOWNLOADING ;
Con_Printf ( " Couldn't download %s (from %s to %s) \n " , p - > name , p - > src , p - > dest ) ;
return ;
}
if ( ! ( p - > flags & DPF_DOWNLOADING ) )
{
Con_Printf ( " menu_download: We're not downloading %s, apparently \n " , p - > dest ) ;
return ;
}
p - > flags & = ~ DPF_DOWNLOADING ;
2006-01-28 06:41:20 +00:00
ext = COM_FileExtension ( p - > dest ) ;
if ( ! stricmp ( ext , " pak " ) | | ! stricmp ( ext , " pk3 " ) )
FS_UnloadPackFiles ( ) ; //we reload them after
2005-10-16 12:53:42 +00:00
2006-01-28 06:41:20 +00:00
if ( * p - > gamedir )
destname = va ( " %s/%s " , p - > gamedir , p - > dest ) ;
else
destname = va ( " %s " , p - > dest ) ;
2012-04-24 07:59:11 +00:00
if ( FS_Remove ( destname , * p - > gamedir ? FS_ROOT : FS_GAME ) )
2006-01-28 06:41:20 +00:00
Con_Printf ( " Deleted old %s \n " , destname ) ;
2012-04-24 07:59:11 +00:00
if ( ! FS_Rename2 ( diskname , destname , FS_GAME , * p - > gamedir ? FS_ROOT : FS_GAME ) )
2005-10-16 12:53:42 +00:00
{
2006-01-28 06:41:20 +00:00
Con_Printf ( " Couldn't rename %s to %s. Removed instead. \n " , diskname , destname ) ;
FS_Remove ( diskname , FS_GAME ) ;
2005-10-16 12:53:42 +00:00
return ;
}
Con_Printf ( " Downloaded %s (to %s) \n " , p - > name , destname ) ;
p - > flags | = DPF_HAVEAVERSION ;
WriteInstalledPackages ( ) ;
2006-01-28 06:41:20 +00:00
ext = COM_FileExtension ( p - > dest ) ;
if ( ! stricmp ( ext , " pak " ) | | ! stricmp ( ext , " pk3 " ) )
FS_ReloadPackFiles ( ) ;
2005-10-16 12:53:42 +00:00
return ;
}
}
Con_Printf ( " menu_download: Can't figure out where %s came from \n " , fname ) ;
}
2006-01-28 06:41:20 +00:00
/*
2005-10-16 12:53:42 +00:00
static qboolean M_Download_Key ( struct menucustom_s * c , struct menu_s * m , int key )
{
char * temp ;
2005-04-16 16:22:17 +00:00
int pn ;
package_t * p , * p2 ;
dlmenu_t * info = m - > data ;
switch ( key )
{
case K_UPARROW :
if ( info - > highlightednum > 0 )
info - > highlightednum - - ;
return true ;
case K_DOWNARROW : //cap range when drawing
if ( info - > highlightednum < numpackages )
info - > highlightednum + + ;
return true ;
case K_ENTER :
if ( ! info - > highlightednum )
{ //do it
//uninstall packages first
package_t * last = NULL ;
for ( p = availablepackages ; p ; p = p - > next )
{
if ( ! ( p - > flags & DPF_WANTTOINSTALL ) & & ( p - > flags & DPF_HAVEAVERSION ) )
{ //if we don't want it but we have it anyway:
2006-01-21 00:06:49 +00:00
if ( * p - > gamedir )
{
char * fname = va ( " %s " , p - > gamedir , p - > dest ) ;
FS_Remove ( fname , FS_BASE ) ;
}
else
FS_Remove ( p - > dest , FS_GAME ) ;
2005-04-16 16:22:17 +00:00
p - > flags & = ~ DPF_HAVEAVERSION ; //FIXME: This is error prone.
2005-10-16 12:53:42 +00:00
WriteInstalledPackages ( ) ;
2005-04-16 16:22:17 +00:00
if ( p - > flags & DPF_DELETEONUNINSTALL )
{
2005-10-16 12:53:42 +00:00
if ( last )
last - > next = p - > next ;
else
availablepackages = p - > next ;
2005-04-16 16:22:17 +00:00
BZ_Free ( p ) ;
return M_Download_Key ( c , m , key ) ; //I'm lazy.
}
}
last = p ;
}
for ( p = availablepackages ; p ; p = p - > next )
{
2005-10-16 12:53:42 +00:00
if ( ( p - > flags & DPF_WANTTOINSTALL ) & & ! ( p - > flags & ( DPF_HAVEAVERSION | DPF_DOWNLOADING ) ) )
2005-04-16 16:22:17 +00:00
{ //if we want it and don't have it:
2005-10-16 12:53:42 +00:00
p - > dlnum = dlcount + + ;
temp = va ( " dl_%i.tmp " , p - > dlnum ) ;
Con_Printf ( " Downloading %s (to %s) \n " , p - > fullname , temp ) ;
p - > flags | = DPF_DOWNLOADING ;
if ( ! HTTP_CL_Get ( p - > src , temp , Menu_Download_Got ) )
p - > flags & = ~ DPF_DOWNLOADING ;
2005-04-16 16:22:17 +00:00
}
}
}
else
{
for ( pn = 1 , p = availablepackages ; p & & pn < info - > highlightednum ; p = p - > next , pn + + )
;
if ( p )
{
p - > flags = ( p - > flags & ~ DPF_WANTTOINSTALL ) | DPF_WANTTOINSTALL - ( p - > flags & DPF_WANTTOINSTALL ) ;
if ( p - > flags & DPF_WANTTOINSTALL )
{
for ( p2 = availablepackages ; p2 ; p2 = p2 - > next )
{
if ( p = = p2 )
continue ;
if ( ! strcmp ( p - > dest , p2 - > dest ) )
p2 - > flags & = ~ DPF_WANTTOINSTALL ;
}
}
}
}
return true ;
}
return false ;
}
2006-01-28 06:41:20 +00:00
*/
2005-04-16 16:22:17 +00:00
void Menu_DownloadStuff_f ( void )
{
2006-01-28 06:41:20 +00:00
int i ;
2005-04-16 16:22:17 +00:00
menu_t * menu ;
dlmenu_t * info ;
key_dest = key_menu ;
m_state = m_complex ;
menu = M_CreateMenu ( sizeof ( dlmenu_t ) ) ;
info = menu - > data ;
2006-01-28 06:41:20 +00:00
menu - > event = M_Download_UpdateStatus ;
/*
2005-04-16 16:22:17 +00:00
menu - > selecteditem = ( menuoption_t * ) ( info - > list = MC_AddCustom ( menu , 0 , 32 , NULL ) ) ;
info - > list - > draw = M_Download_Draw ;
info - > list - > key = M_Download_Key ;
2006-01-28 06:41:20 +00:00
*/
2005-04-16 16:22:17 +00:00
info - > parsedsourcenum = - 1 ;
2006-01-28 06:41:20 +00:00
Q_strncpyz ( info - > pathprefix , Cmd_Argv ( 1 ) , sizeof ( info - > pathprefix ) ) ;
if ( ! * info - > pathprefix )
{
for ( i = 0 ; i < numdownloadablelists ; i + + )
downloadablelistreceived [ i ] = 0 ;
}
2005-04-16 16:22:17 +00:00
MC_AddWhiteText ( menu , 24 , 8 , " Downloads " , false ) ;
MC_AddWhiteText ( menu , 16 , 24 , " \35 \36 \36 \36 \36 \36 \36 \36 \36 \36 \36 \36 \36 \36 \36 \36 \36 \36 \36 \36 \36 \36 \36 \36 \36 \36 \36 \36 \36 \36 \36 \36 \36 \36 \36 \36 \37 " , false ) ;
{
static qboolean loadedinstalled ;
2008-12-23 02:55:20 +00:00
vfsfile_t * f = loadedinstalled ? NULL : FS_OpenVFS ( INSTALLEDFILES , " rb " , FS_ROOT ) ;
2005-04-16 16:22:17 +00:00
loadedinstalled = true ;
if ( f )
{
2005-10-16 12:53:42 +00:00
ConcatPackageLists ( BuildPackageList ( f , DPF_DELETEONUNINSTALL | DPF_HAVEAVERSION | DPF_WANTTOINSTALL , " " ) ) ;
2005-12-22 02:29:11 +00:00
VFS_CLOSE ( f ) ;
2005-04-16 16:22:17 +00:00
}
}
}
2005-12-22 02:29:11 +00:00
# elif defined(WEBCLIENT)
void Menu_DownloadStuff_f ( void )
{
Con_Printf ( " Not yet reimplemented \n " ) ;
}
2005-04-16 16:22:17 +00:00
# endif
2005-12-22 02:29:11 +00:00
2013-03-12 23:09:25 +00:00
# if defined(WEBCLIENT)
2012-11-27 03:23:19 +00:00
static int numbootdownloads ;
# include "fs.h"
2013-03-12 23:09:25 +00:00
# ifdef AVAIL_ZLIB
2012-11-27 03:23:19 +00:00
extern searchpathfuncs_t zipfilefuncs ;
2013-03-31 04:21:08 +00:00
static int CL_BootDownload_Extract ( const char * fname , int fsize , void * ptr , void * spath )
2012-11-27 03:23:19 +00:00
{
char buffer [ 512 * 1024 ] ;
int read ;
void * zip = ptr ;
flocation_t loc ;
int slashes ;
const char * s ;
vfsfile_t * compressedpak ;
vfsfile_t * decompressedpak ;
if ( zipfilefuncs . FindFile ( zip , & loc , fname , NULL ) )
{
compressedpak = zipfilefuncs . OpenVFS ( zip , & loc , " rb " ) ;
if ( compressedpak )
{
//this extra logic is so we can handle things like nexuiz/data/blah.pk3
//as well as just data/blah.pk3
slashes = 0 ;
for ( s = strchr ( fname , ' / ' ) ; s ; s = strchr ( s + 1 , ' / ' ) )
slashes + + ;
for ( ; slashes > 1 ; slashes - - )
fname = strchr ( fname , ' / ' ) + 1 ;
if ( ! slashes )
{
FS_CreatePath ( fname , FS_GAMEONLY ) ;
decompressedpak = FS_OpenVFS ( fname , " wb " , FS_GAMEONLY ) ;
}
else
{
FS_CreatePath ( fname , FS_ROOT ) ;
decompressedpak = FS_OpenVFS ( fname , " wb " , FS_ROOT ) ;
}
if ( decompressedpak )
{
for ( ; ; )
{
read = VFS_READ ( compressedpak , buffer , sizeof ( buffer ) ) ;
if ( read < = 0 )
break ;
if ( VFS_WRITE ( decompressedpak , buffer , read ) ! = read )
{
Con_Printf ( " write failed writing %s. disk full? \n " , fname ) ;
break ;
}
}
VFS_CLOSE ( decompressedpak ) ;
}
VFS_CLOSE ( compressedpak ) ;
}
}
return true ;
}
2013-03-12 23:09:25 +00:00
# endif
2013-03-12 23:01:08 +00:00
qboolean FS_LoadPackageFromFile ( vfsfile_t * vfs , char * pname , char * localname , int * crc , qboolean copyprotect , qboolean istemporary , qboolean isexplicit ) ;
void FS_GenCachedPakName ( char * pname , char * crc , char * local , int llen ) ;
2012-11-27 03:23:19 +00:00
static void CL_BootDownload_Complete ( struct dl_download * dl )
{
void * zip ;
2013-03-12 23:09:25 +00:00
char * q = strchr ( dl - > url , ' ? ' ) ;
char * ext ;
if ( dl - > file & & dl - > status = = DL_FINISHED )
2012-11-27 03:23:19 +00:00
{
2013-03-12 23:09:25 +00:00
if ( q ) * q = ' 0 ' ;
ext = COM_FileExtension ( dl - > url ) ;
if ( q ) * q = ' ? ' ;
if ( ! stricmp ( ext , " zip " ) )
2013-03-12 23:01:08 +00:00
{
2013-03-12 23:09:25 +00:00
# ifdef AVAIL_ZLIB
if ( dl - > status = = DL_FINISHED )
zip = zipfilefuncs . OpenNew ( dl - > file , dl - > url ) ;
else
zip = NULL ;
if ( zip )
2013-03-12 23:01:08 +00:00
{
2013-03-12 23:09:25 +00:00
dl - > file = NULL ; //file is now owned by the zip context.
if ( dl - > user_ctx )
2013-03-12 23:01:08 +00:00
{
2013-03-12 23:09:25 +00:00
vfsfile_t * in , * out ;
flocation_t loc ;
qboolean found = false ;
int crc ;
found = zipfilefuncs . FindFile ( zip , & loc , dl - > user_ctx , NULL ) ;
if ( ! found )
{
char * s = COM_SkipPath ( dl - > user_ctx ) ;
if ( s ! = dl - > user_ctx )
found = zipfilefuncs . FindFile ( zip , & loc , s , NULL ) ;
}
if ( found )
2013-03-12 23:01:08 +00:00
{
2013-03-12 23:09:25 +00:00
in = zipfilefuncs . OpenVFS ( zip , & loc , " rb " ) ;
if ( in )
2013-03-12 23:01:08 +00:00
{
2013-03-12 23:09:25 +00:00
char local [ MAX_OSPATH ] ;
FS_GenCachedPakName ( dl - > user_ctx , va ( " %i " , dl - > user_num ) , local , sizeof ( local ) ) ;
FS_CreatePath ( local , FS_ROOT ) ;
out = FS_OpenVFS ( local , " wb " , FS_ROOT ) ;
if ( out )
2013-03-12 23:01:08 +00:00
{
2013-03-12 23:09:25 +00:00
char buffer [ 8192 ] ;
int read ;
for ( ; ; )
{
read = VFS_READ ( in , buffer , sizeof ( buffer ) ) ;
if ( read < = 0 )
break ;
if ( VFS_WRITE ( out , buffer , read ) ! = read )
{
Con_Printf ( " write failed writing %s. disk full? \n " , local ) ;
break ;
}
}
VFS_CLOSE ( out ) ;
out = FS_OpenVFS ( local , " rb " , FS_ROOT ) ;
crc = dl - > user_num ;
if ( ! FS_LoadPackageFromFile ( out , dl - > user_ctx , local , & crc , true , false , true ) )
{
if ( crc = = dl - > user_num )
Con_Printf ( CON_WARNING " Manifest package \" %s \" is unusable. \n " , ( char * ) dl - > user_ctx ) ;
else
Con_Printf ( CON_WARNING " Manifest package \" %s \" is unusable or has invalid crc. Stated crc %#x is not calculated crc %#x \n " , ( char * ) dl - > user_ctx , dl - > user_num , crc ) ;
FS_Remove ( local , FS_ROOT ) ;
}
2013-03-12 23:01:08 +00:00
}
}
2013-03-12 23:09:25 +00:00
VFS_CLOSE ( in ) ;
2013-03-12 23:01:08 +00:00
}
2013-03-12 23:09:25 +00:00
free ( dl - > user_ctx ) ;
}
else
{
/*scan it to extract its contents*/
zipfilefuncs . EnumerateFiles ( zip , " */*.pk3 " , CL_BootDownload_Extract , zip ) ;
zipfilefuncs . EnumerateFiles ( zip , " */*.pak " , CL_BootDownload_Extract , zip ) ;
zipfilefuncs . EnumerateFiles ( zip , " */*/*.pk3 " , CL_BootDownload_Extract , zip ) ;
zipfilefuncs . EnumerateFiles ( zip , " */*/*.pak " , CL_BootDownload_Extract , zip ) ;
2013-03-12 23:01:08 +00:00
}
2013-03-12 23:09:25 +00:00
/*close it, delete the temp file from disk, etc*/
zipfilefuncs . ClosePath ( zip ) ;
/*restart the filesystem so those new files can be found*/
Cmd_ExecuteString ( " fs_restart \n " , RESTRICT_LOCAL ) ;
}
# endif
2013-03-12 23:01:08 +00:00
}
else
{
2013-03-12 23:09:25 +00:00
//okay, its named directly, write it out as it is
vfsfile_t * out ;
int crc , * crcptr = & crc ;
char local [ MAX_OSPATH ] ;
qboolean ispackage = ( ! stricmp ( ext , " pak " ) | | ! stricmp ( ext , " pk3 " ) ) ;
# ifndef NACL
if ( ispackage )
{
FS_GenCachedPakName ( dl - > user_ctx , va ( " %i " , dl - > user_num ) , local , sizeof ( local ) ) ;
# else
//nacl permits any files to be listed in the manifest file, as there's no prior files to override/conflict, so don't mess about with crcs etc
crcptr = NULL ;
Q_strncpyz ( local , dl - > user_ctx , sizeof ( local ) ) ;
if ( 1 )
{
# endif
FS_CreatePath ( local , FS_ROOT ) ;
2012-11-27 03:23:19 +00:00
2013-03-12 23:09:25 +00:00
//write it out
out = FS_OpenVFS ( local , " wb " , FS_ROOT ) ;
if ( ! out )
Con_Printf ( " Unable to open %s for writing \n " , local ) ;
else
{
char buffer [ 65535 ] ;
int read ;
for ( ; ; )
{
read = VFS_READ ( dl - > file , buffer , sizeof ( buffer ) ) ;
if ( read < = 0 )
break ;
if ( VFS_WRITE ( out , buffer , read ) ! = read )
{
Con_Printf ( " write failed writing %s. disk full? \n " , local ) ;
break ;
}
}
VFS_CLOSE ( out ) ;
2012-11-27 03:23:19 +00:00
2013-03-12 23:09:25 +00:00
if ( ispackage )
{
if ( crcptr )
{
//load it as a package
out = FS_OpenVFS ( local , " rb " , FS_ROOT ) ;
if ( out )
{
crc = dl - > user_num ;
if ( ! FS_LoadPackageFromFile ( out , dl - > user_ctx , local , crcptr , true , false , true ) )
{
if ( crc = = dl - > user_num )
Con_Printf ( CON_WARNING " Manifest package \" %s \" is unusable. \n " , ( char * ) dl - > user_ctx ) ;
else
Con_Printf ( CON_WARNING " Manifest package \" %s \" is unusable or has invalid crc. Stated crc %#x is not calculated crc %#x \n " , ( char * ) dl - > user_ctx , dl - > user_num , crc ) ;
FS_Remove ( local , FS_ROOT ) ;
}
Cmd_ExecuteString ( " fs_restart \n " , RESTRICT_LOCAL ) ;
}
}
else
Cmd_ExecuteString ( " fs_restart \n " , RESTRICT_LOCAL ) ;
}
}
}
else
Con_Printf ( " File %s isn't a recognised package! \n " , ( char * ) dl - > user_ctx ) ;
}
2012-11-27 03:23:19 +00:00
}
if ( ! - - numbootdownloads )
{
CL_ExecInitialConfigs ( ) ;
Cmd_StuffCmds ( ) ;
Cbuf_Execute ( ) ;
Cmd_ExecuteString ( " vid_restart \n " , RESTRICT_LOCAL ) ;
2013-03-12 23:03:04 +00:00
CL_StartCinematicOrMenu ( ) ;
2012-11-27 03:23:19 +00:00
}
}
2013-03-12 23:01:08 +00:00
static void CL_Manifest_Complete ( struct dl_download * dl )
{
2013-03-12 23:09:25 +00:00
if ( ! dl - > file )
Con_Printf ( " Unable to load manifest from %s \n " , dl - > url ) ;
else
2013-03-12 23:01:08 +00:00
{
vfsfile_t * f ;
char buffer [ 1024 ] ;
char * fname ;
int crc ;
char local [ MAX_OSPATH ] ;
while ( VFS_GETS ( dl - > file , buffer , sizeof ( buffer ) ) )
{
Cmd_TokenizeString ( buffer , false , false ) ;
if ( ! Cmd_Argc ( ) )
continue ;
fname = Cmd_Argv ( 0 ) ;
crc = strtoul ( Cmd_Argv ( 1 ) , NULL , 0 ) ;
f = FS_OpenVFS ( fname , " rb " , FS_ROOT ) ;
if ( f )
{
//should be loaded as needed
VFS_CLOSE ( f ) ;
}
else
{
FS_GenCachedPakName ( fname , va ( " %i " , crc ) , local , sizeof ( local ) ) ;
f = FS_OpenVFS ( local , " rb " , FS_ROOT ) ;
if ( f )
{
int truecrc = crc ;
if ( ! FS_LoadPackageFromFile ( f , fname , local , & truecrc , true , false , true ) )
{
if ( crc = = truecrc )
Con_Printf ( CON_WARNING " Manifest package \" %s \" is unusable. \n " , fname ) ;
else
Con_Printf ( CON_WARNING " Manifest package \" %s \" is unusable or has invalid crc. Stated crc %#x is not calculated crc %#x \n " , fname , crc , truecrc ) ;
FS_Remove ( local , FS_ROOT ) ;
}
}
else
{
2013-03-12 23:09:25 +00:00
int args = Cmd_Argc ( ) - 2 ;
if ( ! args )
Con_Printf ( " No mirrors for \" %s \" \n " , fname ) ;
else
2013-03-12 23:01:08 +00:00
{
2013-03-12 23:09:25 +00:00
struct dl_download * ndl ;
# ifdef NACL
args = 0 ; //nacl currently depends upon the browser's download cache for all file persistance, which means we want the same file every time.
//there's only one way to do that, sadly.
# else
args = rand ( ) % args ;
# endif
Con_Printf ( " Downloading \" %s \" from \" %s \" \n " , fname , Cmd_Argv ( 2 + args ) ) ;
ndl = HTTP_CL_Get ( Cmd_Argv ( 2 ) , " " , CL_BootDownload_Complete ) ;
if ( ndl )
{
ndl - > user_ctx = strdup ( fname ) ;
ndl - > user_num = crc ;
# ifdef MULTITHREAD
DL_CreateThread ( ndl , FS_OpenTemp ( ) , CL_BootDownload_Complete ) ;
# endif
numbootdownloads + + ;
}
2013-03-12 23:01:08 +00:00
}
}
}
}
}
if ( ! - - numbootdownloads )
{
CL_ExecInitialConfigs ( ) ;
Cmd_StuffCmds ( ) ;
Cbuf_Execute ( ) ;
Cmd_ExecuteString ( " vid_restart \n " , RESTRICT_LOCAL ) ;
2013-03-12 23:03:04 +00:00
CL_StartCinematicOrMenu ( ) ;
2013-03-12 23:01:08 +00:00
}
}
2012-11-27 03:23:19 +00:00
qboolean CL_CheckBootDownloads ( void )
{
char * downloads = fs_gamedownload . string ;
char token [ 2048 ] ;
char * c , * s ;
vfsfile_t * f ;
struct dl_download * dl ;
int mirrors ;
2013-03-12 23:01:08 +00:00
int man = COM_CheckParm ( " -manifest " ) ;
if ( man )
{
const char * fname = com_argv [ man + 1 ] ;
2013-03-12 23:09:25 +00:00
if ( * fname )
2013-03-12 23:01:08 +00:00
{
2013-03-12 23:09:25 +00:00
Con_Printf ( " Checking manifest from \" %s \" \n " , fname ) ;
dl = HTTP_CL_Get ( fname , " " , CL_Manifest_Complete ) ;
if ( dl )
{
# ifdef MULTITHREAD
DL_CreateThread ( dl , FS_OpenTemp ( ) , CL_Manifest_Complete ) ;
# endif
numbootdownloads + + ;
}
2013-03-12 23:01:08 +00:00
}
}
2012-11-27 03:23:19 +00:00
while ( ( downloads = COM_ParseOut ( downloads , token , sizeof ( token ) ) ) )
{
//FIXME: do we want to add some sort of file size indicator?
c = token ;
while ( * c & & * c ! = ' : ' & & * c ! = ' | ' )
c + + ;
if ( ! * c ) //erp?
continue ;
* c + + = 0 ;
f = FS_OpenVFS ( token , " rb " , FS_ROOT ) ;
if ( f )
{
Con_DPrintf ( " Already have %s \n " , token ) ;
VFS_CLOSE ( f ) ;
continue ;
}
mirrors = 1 ;
for ( s = c ; * s ; s + + )
{
if ( * s = = ' | ' )
mirrors + + ;
}
mirrors = rand ( ) % mirrors ;
while ( mirrors )
{
mirrors - - ;
while ( * c ! = ' | ' )
c + + ;
c + + ;
}
for ( s = c ; * s ; s + + )
{
if ( * s = = ' | ' )
* s = 0 ;
}
Con_Printf ( " Attempting to download %s \n " , c ) ;
2013-03-12 23:09:25 +00:00
dl = HTTP_CL_Get ( c , " " , CL_BootDownload_Complete ) ;
2012-11-27 03:23:19 +00:00
if ( dl )
{
# ifdef MULTITHREAD
DL_CreateThread ( dl , FS_OpenTemp ( ) , CL_BootDownload_Complete ) ;
# endif
numbootdownloads + + ;
}
}
return ! numbootdownloads ;
}
# else
qboolean CL_CheckBootDownloads ( void )
{
2013-03-12 23:09:25 +00:00
if ( COM_CheckParm ( " -manifest " ) )
Con_Printf ( " download manifests not supported in this build \n " ) ;
2012-11-27 03:23:19 +00:00
return true ;
}
# endif