2012-08-05 19:07:47 +02:00
/****************************************************************************
* Copyright ( C ) 2011 Dimok
* Copyright ( C ) 2012 Cyan
*
* This program is free software : you can redistribute it and / or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation , either version 3 of the License , or
* ( at your option ) any later version .
*
* This program is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
* GNU General Public License for more details .
*
* You should have received a copy of the GNU General Public License
* along with this program . If not , see < http : //www.gnu.org/licenses/>.
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2011-02-03 22:46:54 +01:00
# include <gccore.h>
# include <string.h>
# include "ImageDownloader.h"
# include "network/networkops.h"
# include "prompts/PromptWindows.h"
# include "prompts/ProgressWindow.h"
# include "prompts/CheckboxPrompt.hpp"
# include "FileOperations/fileops.h"
# include "settings/CSettings.h"
# include "settings/GameTitles.h"
# include "language/gettext.h"
# include "usbloader/GetMissingGameFiles.hpp"
# include "utils/StringTools.h"
# include "gecko.h"
# define VALID_IMAGE(x) (!(x.size == 36864 || x.size <= 1024 || x.size == 7386 || x.size <= 1174 || x.size == 4446 || x.data == NULL))
2011-10-21 20:48:10 +02:00
static const char * serverURL3D = " http://art.gametdb.com/wii/cover3D/ " ;
static const char * serverURL2D = " http://art.gametdb.com/wii/cover/ " ;
static const char * serverURLFullHQ = " http://art.gametdb.com/wii/coverfullHQ/ " ;
static const char * serverURLFull = " http://art.gametdb.com/wii/coverfull/ " ;
static const char * serverURLOrigDiscs = " http://art.gametdb.com/wii/disc/ " ;
static const char * serverURLCustomDiscs = " http://art.gametdb.com/wii/disccustom/ " ;
2012-08-05 19:07:47 +02:00
static const char * serverURLCustomBannersGC = Settings . CustomBannersURL ;
2011-02-03 22:46:54 +01:00
void ImageDownloader : : DownloadImages ( )
{
2012-08-05 19:07:47 +02:00
bool ValidBannerURL = false ;
if ( strncasecmp ( serverURLCustomBannersGC , " http:// " , strlen ( " http:// " ) ) = = 0 )
{
char * path = strchr ( serverURLCustomBannersGC + strlen ( " http:// " ) , ' / ' ) ;
if ( path )
ValidBannerURL = true ;
}
bool showBanner = ( ValidBannerURL & & Settings . LoaderMode & MODE_GCGAMES ) ;
int choice = CheckboxWindow ( tr ( " Cover Download " ) , 0 , tr ( " 3D Covers " ) , tr ( " Flat Covers " ) , tr ( " Full Covers " ) , tr ( " Discarts " ) , showBanner ? tr ( " Custom Banners " ) : 0 , 0 , showBanner ? 0x1F : 0xF ) ; // ask for download choice
2011-12-22 23:44:48 +01:00
if ( choice = = 0 | | choice = = CheckedNone )
2011-07-26 00:28:22 +02:00
return ;
2011-02-03 22:46:54 +01:00
2011-07-26 00:28:22 +02:00
ImageDownloader Downloader ;
Downloader . SetChoices ( choice ) ;
Downloader . Start ( ) ;
2011-02-03 22:46:54 +01:00
}
void ImageDownloader : : Start ( )
{
2011-07-26 00:28:22 +02:00
gprintf ( " CoverDownload start - choices: %04X \n " , choices ) ;
2011-02-03 22:46:54 +01:00
2011-07-26 00:28:22 +02:00
MissingImagesCount = 0 ;
FindMissingImages ( ) ;
2011-02-03 22:46:54 +01:00
2011-07-26 00:28:22 +02:00
if ( MissingImagesCount = = 0 )
{
WindowPrompt ( tr ( " No file missing! " ) , 0 , tr ( " OK " ) ) ;
return ;
}
2011-02-03 22:46:54 +01:00
2011-07-26 00:28:22 +02:00
u32 TotalDownloadCount = MissingImagesCount ;
2011-02-03 22:46:54 +01:00
2011-07-26 00:28:22 +02:00
if ( WindowPrompt ( tr ( " Found missing images. " ) , fmt ( tr ( " %i missing files " ) , TotalDownloadCount ) , tr ( " Yes " ) , tr ( " No " ) ) = = 0 )
return ;
2011-02-03 22:46:54 +01:00
2011-07-26 00:28:22 +02:00
if ( ! IsNetworkInit ( ) & & ! NetworkInitPrompt ( ) )
{
gprintf ( " No network \n " ) ;
return ;
}
2011-02-03 22:46:54 +01:00
2011-10-01 12:41:00 +02:00
ProgressCancelEnable ( true ) ;
2011-02-03 22:46:54 +01:00
2011-07-26 00:28:22 +02:00
DownloadProcess ( TotalDownloadCount ) ;
2011-02-03 22:46:54 +01:00
2011-10-01 12:41:00 +02:00
ProgressCancelEnable ( false ) ;
2011-07-26 00:28:22 +02:00
ProgressStop ( ) ;
2011-02-03 22:46:54 +01:00
2011-07-26 00:28:22 +02:00
if ( MissingImagesCount = = 0 )
WindowPrompt ( tr ( " Download finished " ) , tr ( " All images downloaded successfully. " ) , tr ( " OK " ) ) ;
else
{
int res = WindowPrompt ( tr ( " Download finished " ) , fmt ( tr ( " %i files not found on the server! " ) , MissingImagesCount ) , tr ( " Save List " ) , tr ( " OK " ) ) ;
if ( res )
CreateCSVLog ( ) ;
}
2011-02-03 22:46:54 +01:00
}
void ImageDownloader : : FindMissingImages ( )
{
2011-07-26 00:28:22 +02:00
if ( choices & CheckedBox1 )
2012-08-05 19:07:47 +02:00
FindMissing ( Settings . covers_path , serverURL3D , NULL , tr ( " Downloading 3D Covers " ) , NULL , " .png " ) ;
2011-07-26 00:28:22 +02:00
if ( choices & CheckedBox2 )
2012-08-05 19:07:47 +02:00
FindMissing ( Settings . covers2d_path , serverURL2D , NULL , tr ( " Downloading Flat Covers " ) , NULL , " .png " ) ;
2011-07-26 00:28:22 +02:00
if ( choices & CheckedBox3 )
2012-08-05 19:07:47 +02:00
{
const char * downloadURL = ( Settings . coversfull = = COVERSFULL_HQ | | Settings . coversfull = = COVERSFULL_HQ_LQ ) ? serverURLFullHQ : serverURLFull ;
const char * progressTitle = ( Settings . coversfull = = COVERSFULL_HQ | | Settings . coversfull = = COVERSFULL_HQ_LQ ) ? tr ( " Downloading Full HQ Covers " ) : tr ( " Downloading Full LQ Covers " ) ;
const char * backupURL = ( Settings . coversfull = = COVERSFULL_HQ_LQ | | Settings . coversfull = = COVERSFULL_LQ_HQ ) ? ( ( Settings . coversfull = = COVERSFULL_HQ_LQ ) ? serverURLFull : serverURLFullHQ ) : NULL ;
const char * backupProgressTitle = ( Settings . coversfull = = COVERSFULL_HQ_LQ | | Settings . coversfull = = COVERSFULL_LQ_HQ ) ? ( ( Settings . coversfull = = COVERSFULL_HQ_LQ ) ? tr ( " Downloading Full LQ Covers " ) : tr ( " Downloading Full HQ Covers " ) ) : NULL ;
FindMissing ( Settings . coversFull_path , downloadURL , backupURL , progressTitle , backupProgressTitle , " .png " ) ;
}
2011-07-26 00:28:22 +02:00
if ( choices & CheckedBox4 )
{
2012-08-05 19:07:47 +02:00
const char * downloadURL = ( Settings . discart = = DISCARTS_ORIGINALS | | Settings . discart = = DISCARTS_ORIGINALS_CUSTOMS ) ? serverURLOrigDiscs : serverURLCustomDiscs ;
const char * progressTitle = ( Settings . discart = = DISCARTS_ORIGINALS | | Settings . discart = = DISCARTS_ORIGINALS_CUSTOMS ) ? tr ( " Downloading original Discarts " ) : tr ( " Downloading custom Discarts " ) ;
const char * backupURL = ( Settings . discart = = DISCARTS_ORIGINALS_CUSTOMS | | Settings . discart = = DISCARTS_CUSTOMS_ORIGINALS ) ? ( ( Settings . discart = = DISCARTS_ORIGINALS_CUSTOMS ) ? serverURLCustomDiscs : serverURLOrigDiscs ) : NULL ;
const char * backupProgressTitle = ( Settings . discart = = DISCARTS_ORIGINALS_CUSTOMS | | Settings . discart = = DISCARTS_CUSTOMS_ORIGINALS ) ? ( ( Settings . discart = = DISCARTS_ORIGINALS_CUSTOMS ) ? tr ( " Downloading custom Discarts " ) : tr ( " Downloading original Discarts " ) ) : NULL ;
FindMissing ( Settings . disc_path , downloadURL , backupURL , progressTitle , backupProgressTitle , " .png " ) ;
2011-07-26 00:28:22 +02:00
}
2012-08-05 19:07:47 +02:00
if ( choices & CheckedBox5 )
2011-07-26 00:28:22 +02:00
{
2012-08-05 19:07:47 +02:00
FindMissing ( Settings . BNRCachePath , serverURLCustomBannersGC , NULL , tr ( " Downloading Custom Banners " ) , NULL , " .bnr " ) ;
2011-07-26 00:28:22 +02:00
}
2011-02-03 22:46:54 +01:00
}
2012-08-05 19:07:47 +02:00
void ImageDownloader : : FindMissing ( const char * writepath , const char * downloadURL , const char * backupURL , const char * progressTitle , const char * backupProgressTitle , const char * fileExt )
2011-02-03 22:46:54 +01:00
{
2011-07-26 00:28:22 +02:00
if ( ! CreateSubfolder ( writepath ) )
{
WindowPrompt ( tr ( " Error ! " ) , fmt ( " %s %s " , tr ( " Can't create directory " ) , writepath ) , tr ( " OK " ) ) ;
return ;
}
std : : vector < std : : string > MissingFilesList ;
2016-01-02 17:23:01 +01:00
if ( ( Settings . LoaderMode & MODE_GCGAMES ) & & strcmp ( fileExt , " .bnr " ) = = 0 )
2012-08-05 19:07:47 +02:00
{
short LoaderModeBackup = Settings . LoaderMode ;
Settings . LoaderMode = MODE_GCGAMES ; // Limit banner download for GameCube Only.
GetMissingGameFiles ( writepath , fileExt , MissingFilesList ) ;
Settings . LoaderMode = LoaderModeBackup ;
}
else
{
GetMissingGameFiles ( writepath , fileExt , MissingFilesList ) ;
}
2011-07-26 00:28:22 +02:00
int size = MissingImages . size ( ) ;
MissingImages . resize ( size + MissingFilesList . size ( ) ) ;
for ( u32 i = 0 , n = size ; i < MissingFilesList . size ( ) ; + + i , + + n )
{
MissingImages [ n ] . gameID = MissingFilesList [ i ] ;
MissingImages [ n ] . downloadURL = downloadURL ;
MissingImages [ n ] . backupURL = backupURL ;
MissingImages [ n ] . writepath = writepath ;
MissingImages [ n ] . progressTitle = progressTitle ;
2012-08-05 19:07:47 +02:00
MissingImages [ n ] . backupProgressTitle = backupProgressTitle ;
MissingImages [ n ] . fileExt = fileExt ;
2011-07-26 00:28:22 +02:00
}
MissingImagesCount + = MissingFilesList . size ( ) ;
2011-02-03 22:46:54 +01:00
}
int ImageDownloader : : DownloadProcess ( int TotalDownloadCount )
{
2011-07-26 00:28:22 +02:00
char progressMsg [ 255 ] ;
2012-08-05 19:07:47 +02:00
char * path = strchr ( serverURLCustomBannersGC + strlen ( " http:// " ) , ' / ' ) ;
int domainlength = path - serverURLCustomBannersGC ;
char domain [ domainlength + 1 ] ;
strncpy ( domain , serverURLCustomBannersGC , domainlength ) ;
domain [ domainlength ] = ' \0 ' ;
2011-07-26 00:28:22 +02:00
for ( u32 i = 0 , pos = 0 ; i < MissingImages . size ( ) ; + + i , + + pos )
{
2011-10-01 12:41:00 +02:00
if ( ProgressCanceled ( ) )
2011-07-26 00:28:22 +02:00
break ;
2012-08-05 19:07:47 +02:00
if ( strcmp ( MissingImages [ i ] . fileExt , " .bnr " ) = = 0 )
snprintf ( progressMsg , sizeof ( progressMsg ) , " %s : %s.bnr " , domain , MissingImages [ i ] . gameID . c_str ( ) ) ;
else
snprintf ( progressMsg , sizeof ( progressMsg ) , " http://gametdb.com : %s.png " , MissingImages [ i ] . gameID . c_str ( ) ) ;
2011-07-26 00:28:22 +02:00
ShowProgress ( MissingImages [ i ] . progressTitle , fmt ( " %i %s " , TotalDownloadCount - pos , tr ( " files left " ) ) , progressMsg , pos , TotalDownloadCount ) ;
2012-08-05 19:07:47 +02:00
if ( MissingImages [ i ] . gameID . size ( ) < 3 )
2011-07-26 00:28:22 +02:00
continue ;
2012-08-05 19:07:47 +02:00
struct block file = DownloadImage ( MissingImages [ i ] . downloadURL , MissingImages [ i ] . gameID . c_str ( ) , MissingImages [ i ] . fileExt ) ;
2011-07-26 00:28:22 +02:00
if ( ! file . data )
{
if ( MissingImages [ i ] . backupURL )
{
2012-08-05 19:07:47 +02:00
gprintf ( " Trying backup URL. \n " ) ;
MissingImages [ i ] . downloadURL = MissingImages [ i ] . backupURL ;
MissingImages [ i ] . backupURL = NULL ;
MissingImages [ i ] . progressTitle = MissingImages [ i ] . backupProgressTitle ;
2011-07-26 00:28:22 +02:00
- - i ;
- - pos ;
}
continue ;
}
2012-08-05 19:07:47 +02:00
gprintf ( " - OK \n " ) ;
2011-07-26 00:28:22 +02:00
char imgPath [ 200 ] ;
2012-08-05 19:07:47 +02:00
snprintf ( imgPath , sizeof ( imgPath ) , " %s/%s%s " , MissingImages [ i ] . writepath , MissingImages [ i ] . gameID . c_str ( ) , MissingImages [ i ] . fileExt ) ;
2011-07-26 00:28:22 +02:00
FILE * pfile = fopen ( imgPath , " wb " ) ;
if ( pfile ! = NULL )
{
fwrite ( file . data , 1 , file . size , pfile ) ;
fclose ( pfile ) ;
MissingImagesCount - - ;
}
free ( file . data ) ;
//! Remove the image from the vector since it's done
MissingImages . erase ( MissingImages . begin ( ) + i ) ;
- - i ;
}
return MissingImages . size ( ) ;
2011-02-03 22:46:54 +01:00
}
2012-08-05 19:07:47 +02:00
struct block ImageDownloader : : DownloadImage ( const char * url , const char * gameID , const char * fileExt )
2011-02-03 22:46:54 +01:00
{
2011-07-26 00:28:22 +02:00
char CheckedRegion [ 10 ] ;
char downloadURL [ 512 ] ;
bool PAL = false ;
2012-08-05 19:07:47 +02:00
if ( strcmp ( fileExt , " .bnr " ) = = 0 )
{
snprintf ( downloadURL , sizeof ( downloadURL ) , " %s%s.bnr " , url , gameID ) ;
gprintf ( " %s " , downloadURL ) ;
struct block file = downloadfile ( downloadURL ) ;
2016-01-02 17:23:01 +01:00
if ( file . size > 132 & & IsValidBanner ( file . data ) ) // 132 = IMET magic location in the banner with u8 header
2012-08-05 19:07:47 +02:00
return file ;
free ( file . data ) ;
snprintf ( downloadURL , sizeof ( downloadURL ) , " %s%.3s.bnr " , url , gameID ) ;
gprintf ( " - Not found. trying ID3: \n %s " , downloadURL ) ;
file = downloadfile ( downloadURL ) ;
2016-01-02 17:23:01 +01:00
if ( file . size > 132 & & IsValidBanner ( file . data ) )
2012-08-05 19:07:47 +02:00
return file ;
gprintf ( " - Not found. \n " ) ;
free ( file . data ) ;
memset ( & file , 0 , sizeof ( struct block ) ) ;
return file ;
}
2011-07-26 00:28:22 +02:00
//Creates URL depending from which Country the game is
switch ( gameID [ 3 ] )
{
case ' J ' :
sprintf ( downloadURL , " %sJA/%s.png " , url , gameID ) ;
sprintf ( CheckedRegion , " JA " ) ;
break ;
case ' W ' :
sprintf ( downloadURL , " %sZH/%s.png " , url , gameID ) ;
sprintf ( CheckedRegion , " ZH " ) ;
break ;
case ' K ' :
sprintf ( downloadURL , " %sKO/%s.png " , url , gameID ) ;
sprintf ( CheckedRegion , " KO " ) ;
break ;
case ' P ' :
case ' D ' :
case ' F ' :
case ' I ' :
case ' S ' :
case ' H ' :
case ' U ' :
case ' X ' :
case ' Y ' :
case ' Z ' :
sprintf ( downloadURL , " %s%s/%s.png " , url , Settings . db_language , gameID ) ;
sprintf ( CheckedRegion , " %s " , Settings . db_language ) ;
PAL = true ;
break ;
case ' E ' :
sprintf ( downloadURL , " %sUS/%s.png " , url , gameID ) ;
sprintf ( CheckedRegion , " US " ) ;
break ;
default :
strcpy ( downloadURL , " " ) ;
strcpy ( CheckedRegion , " " ) ;
break ;
}
2012-08-05 19:07:47 +02:00
gprintf ( " %s " , downloadURL ) ;
2011-07-26 00:28:22 +02:00
struct block file = downloadfile ( downloadURL ) ;
if ( VALID_IMAGE ( file ) )
return file ;
free ( file . data ) ;
file . data = NULL ;
if ( PAL & & strcmp ( CheckedRegion , " EN " ) ! = 0 )
{
snprintf ( downloadURL , sizeof ( downloadURL ) , " %sEN/%s.png " , url , gameID ) ;
2012-08-05 19:07:47 +02:00
gprintf ( " - Not found. \n %s " , downloadURL ) ;
2011-07-26 00:28:22 +02:00
file = downloadfile ( downloadURL ) ;
if ( VALID_IMAGE ( file ) )
return file ;
}
else if ( strcmp ( CheckedRegion , " " ) = = 0 )
{
const char * lang = Settings . db_language ;
if ( strcmp ( lang , " EN " ) = = 0 & & CONF_GetRegion ( ) = = CONF_REGION_US )
lang = " US " ;
snprintf ( downloadURL , sizeof ( downloadURL ) , " %s%s/%s.png " , url , lang , gameID ) ;
2012-08-05 19:07:47 +02:00
gprintf ( " - Not found. \n %s " , downloadURL ) ;
2011-07-26 00:28:22 +02:00
file = downloadfile ( downloadURL ) ;
if ( VALID_IMAGE ( file ) )
return file ;
free ( file . data ) ;
snprintf ( downloadURL , sizeof ( downloadURL ) , " %sOTHER/%s.png " , url , gameID ) ;
2012-08-05 19:07:47 +02:00
gprintf ( " - Not found. \n %s " , downloadURL ) ;
2011-07-26 00:28:22 +02:00
file = downloadfile ( downloadURL ) ;
if ( VALID_IMAGE ( file ) )
return file ;
2015-11-17 15:41:27 +01:00
if ( gameID [ 3 ] = = ' R ' ) // no english cover found, try russian
{
lang = " RU " ;
free ( file . data ) ;
snprintf ( downloadURL , sizeof ( downloadURL ) , " %s%s/%s.png " , url , lang , gameID ) ;
gprintf ( " - Not found. \n %s " , downloadURL ) ;
file = downloadfile ( downloadURL ) ;
if ( VALID_IMAGE ( file ) )
return file ;
}
if ( gameID [ 3 ] = = ' V ' ) // no English cover found, try Finnish and Swedish
{
lang = " FI " ;
free ( file . data ) ;
snprintf ( downloadURL , sizeof ( downloadURL ) , " %s%s/%s.png " , url , lang , gameID ) ;
gprintf ( " - Not found. \n %s " , downloadURL ) ;
file = downloadfile ( downloadURL ) ;
if ( VALID_IMAGE ( file ) )
return file ;
lang = " SE " ;
free ( file . data ) ;
snprintf ( downloadURL , sizeof ( downloadURL ) , " %s%s/%s.png " , url , lang , gameID ) ;
gprintf ( " - Not found. \n %s " , downloadURL ) ;
file = downloadfile ( downloadURL ) ;
if ( VALID_IMAGE ( file ) )
return file ;
}
2011-07-26 00:28:22 +02:00
}
2012-08-05 19:07:47 +02:00
gprintf ( " - Not found. \n " ) ;
2011-07-26 00:28:22 +02:00
free ( file . data ) ;
memset ( & file , 0 , sizeof ( struct block ) ) ;
return file ;
2011-02-03 22:46:54 +01:00
}
void ImageDownloader : : CreateCSVLog ( )
{
2011-07-26 00:28:22 +02:00
char path [ 200 ] ;
snprintf ( path , sizeof ( path ) , " %s/MissingImages.csv " , Settings . update_path ) ;
FILE * f = fopen ( path , " wb " ) ;
if ( ! f ) return ;
const char * ImageType = " 3D Cover " ;
fprintf ( f , " \" ID \" , \" Name \" , \" ImageType \" \n " ) ;
for ( u32 i = 0 ; i < MissingImages . size ( ) ; + + i )
{
if ( MissingImages [ i ] . downloadURL = = serverURL3D )
{
ImageType = " 3D Cover " ;
}
else if ( MissingImages [ i ] . downloadURL = = serverURL2D )
{
ImageType = " 2D Cover " ;
}
else if ( MissingImages [ i ] . downloadURL = = serverURLFullHQ )
{
ImageType = " Full HQ Cover " ;
}
else if ( MissingImages [ i ] . downloadURL = = serverURLFull )
{
ImageType = " Full LQ Cover " ;
}
else if ( MissingImages [ i ] . downloadURL = = serverURLOrigDiscs )
{
ImageType = " Original Discart " ;
}
else if ( MissingImages [ i ] . downloadURL = = serverURLCustomDiscs )
{
ImageType = " Custom Discart " ;
}
2012-08-05 19:07:47 +02:00
else if ( MissingImages [ i ] . downloadURL = = serverURLCustomBannersGC )
{
ImageType = " Custom Banner " ;
}
2011-07-26 00:28:22 +02:00
fprintf ( f , " \" %s \" , \" %s \" , \" %s \" \n " , MissingImages [ i ] . gameID . c_str ( ) , GameTitles . GetTitle ( MissingImages [ i ] . gameID . c_str ( ) ) , ImageType ) ;
2012-08-05 19:07:47 +02:00
gprintf ( " \" %s \" , \" %s \" , \" %s \" \n " , MissingImages [ i ] . gameID . c_str ( ) , GameTitles . GetTitle ( MissingImages [ i ] . gameID . c_str ( ) ) , ImageType ) ;
2011-07-26 00:28:22 +02:00
}
fclose ( f ) ;
2011-02-03 22:46:54 +01:00
}
2012-08-05 19:07:47 +02:00
bool ImageDownloader : : IsValidBanner ( unsigned char * banner )
{
if ( ! ( ( * ( u32 * ) ( banner + 64 ) ) = = ' IMET ' ) )
{
if ( ! ( ( * ( u32 * ) ( banner + 128 ) ) = = ' IMET ' ) ) // with U8Archive header
return false ;
}
return true ;
}