usbloadergx/source/network/update.cpp
2012-05-09 19:33:27 +00:00

385 lines
9.3 KiB
C++

/***************************************************************************
* Copyright (C) 2009
* by Dimok
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any
* damages arising from the use of this software.
*
* Permission is granted to anyone to use this software for any
* purpose, including commercial applications, and to alter it and
* redistribute it freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you
* must not claim that you wrote the original software. If you use
* this software in a product, an acknowledgment in the product
* documentation would be appreciated but is not required.
*
* 2. Altered source versions must be plainly marked as such, and
* must not be misrepresented as being the original software.
*
* 3. This notice may not be removed or altered from any source
* distribution.
*
* update.cpp
*
* Update operations
* for Wii-Xplorer 2009
***************************************************************************/
#include <stdio.h>
#include <string.h>
#include <ogcsys.h>
#include <string>
#include "gecko.h"
#include "ZipFile.h"
#include "http.h"
#include "networkops.h"
#include "HTML_Stream.h"
#include "FileDownloader.h"
#include "settings/CSettings.h"
#include "settings/GameTitles.h"
#include "language/gettext.h"
#include "language/UpdateLanguage.h"
#include "homebrewboot/BootHomebrew.h"
#include "utils/StringTools.h"
#include "utils/ShowError.h"
#include "prompts/PromptWindows.h"
#include "FileOperations/fileops.h"
#include "xml/GameTDB.hpp"
#include "wad/nandtitle.h"
#include "wad/wad.h"
#include "sys.h"
#include "svnrev.h"
static const char * GameTDB_URL = "http://www.gametdb.com/wiitdb.zip";
/****************************************************************************
* Checking if an Update is available
***************************************************************************/
int CheckForBetaUpdate()
{
int revnumber = 0;
HTML_Stream HTML("http://code.google.com/p/usbloader-gui/downloads/list");
const char * HTML_Pos = NULL;
do
{
HTML_Pos = HTML.FindStringEnd("href='");
char * tmpLink = HTML.CopyString("'\"");
if (tmpLink)
{
char *fileext = strrchr(tmpLink, '.');
if (fileext)
{
if (strcasecmp(fileext, ".dol") == 0)
{
char revtxt[80];
char *filename = strrchr(tmpLink, '/') + 2;
u8 n = 0;
for (n = 0; n < strlen(filename) - 2; n++)
revtxt[n] = filename[n];
revtxt[n] = 0;
int fileRev = atoi(revtxt);
if (fileRev > revnumber)
{
revnumber = fileRev;
}
}
}
free(tmpLink);
}
} while (HTML_Pos != NULL);
return revnumber;
}
static bool CheckNewGameTDBVersion(const char *url)
{
u64 Version = 0;
char * HEAD_Responde = HEAD_Request(url);
if(!HEAD_Responde)
return false;
char * version_ptr = strstr(HEAD_Responde, "X-GameTDB-Timestamp: ");
if(version_ptr)
{
version_ptr += strlen("X-GameTDB-Timestamp: ");
Version = strtoull(version_ptr, NULL, 10);
}
free(HEAD_Responde);
std::string Title;
std::string Filepath = Settings.titlestxt_path;
if(Settings.titlestxt_path[Filepath.size()-1] != '/')
Filepath += '/';
Filepath += "wiitdb.xml";
GameTDB XML_DB;
if(!XML_DB.OpenFile((Filepath.c_str())))
return true; //! If no file exists we need the file
u64 ExistingVersion = XML_DB.GetGameTDBVersion();
gprintf("Existing GameTDB Version: %llu Online GameTDB Version: %llu\n", ExistingVersion, Version);
return (ExistingVersion != Version);
}
int UpdateGameTDB()
{
if(CheckNewGameTDBVersion(GameTDB_URL) == false)
{
gprintf("Not updating GameTDB: Version is the same\n");
return -1;
}
gprintf("Updating GameTDB...\n");
string ZipPath = Settings.titlestxt_path;
if(Settings.titlestxt_path[ZipPath.size()-1] != '/')
ZipPath += '/';
ZipPath += "wiitdb.zip";
int filesize = DownloadFileToPath(GameTDB_URL, ZipPath.c_str(), false);
if(filesize <= 0)
return -1;
ZipFile zFile(ZipPath.c_str());
bool result = zFile.ExtractAll(Settings.titlestxt_path);
//! The zip file is not needed anymore so we can remove it
remove(ZipPath.c_str());
//! Reload all titles and reload cached titles because the file changed now.
GameTitles.SetDefault();
GameTitles.LoadTitlesFromGameTDB(Settings.titlestxt_path);
return (result ? filesize : -1);
}
static void UpdateIconPng()
{
char iconpath[200];
struct block file = downloadfile("http://usbloader-gui.googlecode.com/svn/branches/updates/icon.png");
if (file.data != NULL)
{
snprintf(iconpath, sizeof(iconpath), "%sicon.png", Settings.update_path);
FILE * pfile = fopen(iconpath, "wb");
if(pfile)
{
fwrite(file.data, 1, file.size, pfile);
fclose(pfile);
}
free(file.data);
}
}
static void UpdateMetaXml()
{
char xmlpath[200];
struct block file = downloadfile("http://usbloader-gui.googlecode.com/svn/branches/updates/meta.xml");
if (file.data != NULL)
{
snprintf(xmlpath, sizeof(xmlpath), "%smeta.xml", Settings.update_path);
FILE *pfile = fopen(xmlpath, "wb");
if(pfile)
{
fwrite(file.data, 1, file.size, pfile);
fclose(pfile);
}
free(file.data);
}
}
int CheckUpdate()
{
if (!IsNetworkInit())
return -1;
int revnumber = 0;
int currentrev = atoi(GetRev());
#ifdef FULLCHANNEL
struct block file = downloadfile( "http://usbloader-gui.googlecode.com/svn/branches/updates/update_wad.txt" );
#else
struct block file = downloadfile("http://usbloader-gui.googlecode.com/svn/branches/updates/update_dol.txt");
#endif
if (file.data != NULL)
{
revnumber = atoi((char *) file.data);
free(file.data);
}
if (revnumber > currentrev)
return revnumber;
return -1;
}
static int ApplicationDownload(void)
{
std::string DownloadURL;
int newrev = 0;
int currentrev = atoi(GetRev());
#ifdef FULLCHANNEL
struct block file = downloadfile( "http://usbloader-gui.googlecode.com/svn/branches/updates/update_wad.txt" );
#else
struct block file = downloadfile("http://usbloader-gui.googlecode.com/svn/branches/updates/update_dol.txt");
#endif
if (file.data != NULL)
{
// first line of the text file is the revisionc
newrev = atoi((char *) file.data);
// 2nd line of the text file is the url
char *ptr = strchr((char *)file.data, '\n');
while(ptr && (*ptr == '\r' || *ptr == '\n' || *ptr == ' '))
ptr++;
while(ptr && *ptr != '\0' && *ptr != '\r' && *ptr != '\n')
{
DownloadURL.push_back(*ptr);
ptr++;
}
free(file.data);
}
if (newrev <= currentrev)
{
WindowPrompt(tr( "No new updates." ), 0, tr( "OK" ));
return 0;
}
bool update_error = false;
char tmppath[250];
#ifdef FULLCHANNEL
snprintf(tmppath, sizeof(tmppath), "%s/ULNR.wad", Settings.BootDevice);
#else
char realpath[250];
snprintf(realpath, sizeof(realpath), "%sboot.dol", Settings.update_path);
snprintf(tmppath, sizeof(tmppath), "%sboot.tmp", Settings.update_path);
#endif
int update_choice = WindowPrompt(fmt("Rev%i %s.", newrev, tr( "available" )), tr( "How do you want to update?" ), tr( "Update DOL" ), tr( "Update All" ), tr( "Cancel" ));
if (update_choice == 0)
return 0;
int ret = DownloadFileToPath(DownloadURL.c_str(), tmppath, false);
if(ret < 1024*1024)
{
remove(tmppath);
WindowPrompt(tr("Failed updating"), tr("Error while downloding file"), tr( "OK" ));
if(update_choice == 1)
return -1;
update_error = true;
}
else
{
#ifdef FULLCHANNEL
FILE * wadFile = fopen(tmppath, "rb");
if(!wadFile)
{
update_error = true;
WindowPrompt(tr("Failed updating"), tr("Error opening downloaded file"), tr( "OK" ));
return -1;
}
int error = Wad_Install( wadFile );
if(error)
{
update_error = true;
ShowError(tr( "The wad installation failed with error %i" ), error);
}
else
WindowPrompt(tr( "Success" ), tr( "The wad file was installed" ), tr( "OK" ));
RemoveFile(tmppath);
#else
gprintf("%s\n%s\n", realpath, tmppath);
RemoveFile(realpath);
if(!RenameFile(tmppath, realpath))
update_error = true;
#endif
}
if (update_choice == 2)
{
UpdateIconPng();
UpdateMetaXml();
UpdateGameTDB();
DownloadAllLanguageFiles();
}
if(update_error)
{
ShowError(tr( "Error while updating USB Loader GX." ));
return -1;
}
if (update_choice > 0)
{
WindowPrompt(tr( "Successfully updated." ), tr( "Restarting..." ), 0, 0, 0, 0, 150);
RebootApp();
}
return 0;
}
int UpdateApp()
{
if (!IsNetworkInit() && !NetworkInitPrompt())
{
WindowPrompt(tr("Error !"), tr("Could not initialize network!"), tr("OK"));
return -1;
}
if (!CreateSubfolder(Settings.update_path))
{
WindowPrompt(tr("Error !"), tr("Can't create directory"), tr("OK"));
return -1;
}
int choice = WindowPrompt(tr( "What do you want to update?" ), 0, "USB Loader GX", tr( "WiiTDB.xml" ), tr( "Language Files" ), tr( "Cancel" ));
if(choice == 0)
return 0;
if(choice == 1)
{
return ApplicationDownload();
}
else if (choice == 2)
{
if(UpdateGameTDB() < 0)
{
WindowPrompt(fmt("%s", tr( "WiiTDB.xml is up to date." )), 0, tr("OK"));
return 1;
}
else
{
WindowPrompt(tr( "Successfully Updated" ), 0, tr( "OK" ));
return 1;
}
}
else if (choice == 3)
{
if(UpdateLanguageFiles() > 0)
WindowPrompt(tr( "Successfully Updated" ), 0, tr( "OK" ));
}
return 1;
}