static bool checkPNGFile(const char *filename)
{
	SmartBuf buffer;
	FILE *file = fopen(filename, "rb");
	if(file == NULL) return false;
	fseek(file, 0, SEEK_END);
	long fileSize = ftell(file);
	fseek(file, 0, SEEK_SET);
	if(fileSize > 0)
	{
		buffer = smartAnyAlloc(fileSize);
		if(!!buffer) fread(buffer.get(), 1, fileSize, file);
	}
	SAFE_CLOSE(file);
	return !buffer ? false : checkPNGBuf(buffer.get());
}
Example #2
0
void loadCheatFile(SmartBuf &buffer, u32 &size, const char *cheatPath, const char *gameId)
{
	FILE *fp = 0;
	u32 fileSize;
	SmartBuf fileBuf;

	buffer.release();
	size = 0;
	fp = fopen(fmt("%s/%s.gct", cheatPath, gameId), "rb");
		
	if (fp == 0)
		return;

	fseek(fp, 0, SEEK_END);
	fileSize = ftell(fp);
	fseek(fp, 0, SEEK_SET);
	fileBuf = smartCoverAlloc(fileSize);
	if (!fileBuf)
	{
		fclose(fp);
		return;
	}
	if (fread(fileBuf.get(), 1, fileSize, fp) != fileSize)
	{
		fclose(fp);
		return;
	}
	fclose(fp);
	buffer = fileBuf;
	size = fileSize;
}
s8 CMenu::_versionTxtDownloader() // code to download new version txt file
{
	u32 bufferSize = 0x001000;	// Maximum download size 4kb
	SmartBuf buffer = smartAnyAlloc(bufferSize);
	if(!buffer)
	{
		_setThrdMsg(L"Not enough memory", 1.f);
		m_thrdWorking = false;
		return 0;
	}

	_setThrdMsg(_t("dlmsg1", L"Initializing network..."), 0.f);

	if(_initNetwork() < 0)
		_setThrdMsg(_t("dlmsg2", L"Network initialization failed!"), 1.f);
	else
	{
		_setThrdMsg(_t("dlmsg11", L"Downloading..."), 0.2f);

		m_thrdStep = 0.2f;
		m_thrdStepLen = 0.9f - 0.2f;
		gprintf("TXT update URL: %s\n\n", m_cfg.getString("GENERAL", "updatetxturl", UPDATE_URL_VERSION).c_str());
		download = downloadfile(buffer.get(), bufferSize, m_cfg.getString("GENERAL", "updatetxturl", UPDATE_URL_VERSION).c_str(),CMenu::_downloadProgress, this);
		if(download.data == 0 || download.size < 19)
			_setThrdMsg(_t("dlmsg20", L"No version information found."), 1.f); // TODO: Check for 16
		else
		{
			_setThrdMsg(_t("dlmsg13", L"Saving..."), 0.9f);

			FILE *file = fopen(m_ver.c_str(), "wb");
			if(file != NULL)
			{
				fwrite(download.data, 1, download.size, file);
				SAFE_CLOSE(file);

// 				// version file valid, check for version with GIT_REV
// 				int svnrev = atoi(SVN_REV);
// 				gprintf("Installed Version: %d\n", svnrev);
// 				m_version.load(m_ver.c_str());
// 				int rev = m_version.getInt("GENERAL", "version");
// 				gprintf("Latest available Version: %d\n", rev);
// 				if(svnrev < rev)
// 					_setThrdMsg(_t("dlmsg19", L"New update available!"), 1.f);
// 				else
					_setThrdMsg(_t("dlmsg17", L"No new updates found."), 1.f);
			}
			else
				_setThrdMsg(_t("dlmsg15", L"Saving failed!"), 1.f);
		}
	}
	m_thrdWorking = false;
	return 0;
}
Example #4
0
static bool checkPNGFile(const char *filename)
{
	FILE *file = NULL;
	long fileSize = 0;
	SmartBuf ptrPng;

	file = fopen(filename, "rb");
	if (file == NULL)
		return false;
	fseek(file, 0, SEEK_END);
	fileSize = ftell(file);
	fseek(file, 0, SEEK_SET);
	if (fileSize > 0)
	{
		ptrPng = smartCoverAlloc(fileSize);
		if (!!ptrPng)
			fread(ptrPng.get(), 1, fileSize, file);
	}
	fclose(file);
	file = NULL;
	return !ptrPng ? false : checkPNGBuf(ptrPng.get());
}
int CMenu::_gametdbDownloaderAsync()
{
	string langCode;

	u32 bufferSize = 0x800000; // 8 MB
	SmartBuf buffer = smartAnyAlloc(bufferSize);
	if(!buffer)
	{
		_setThrdMsg(L"Not enough memory", 1.f);
		return 0;
	}
	langCode = m_loc.getString(m_curLanguage, "gametdb_code", "EN");
	_setThrdMsg(_t("dlmsg1", L"Initializing network..."), 0.f);
	if(_initNetwork() < 0)
		_setThrdMsg(_t("dlmsg2", L"Network initialization failed!"), 1.f);
	else
	{
		_setThrdMsg(_t("dlmsg11", L"Downloading..."), 0.0f);
		m_thrdStep = 0.0f;
		m_thrdStepLen = 1.0f;
		download = downloadfile(buffer.get(), bufferSize, sfmt(GAMETDB_URL, langCode.c_str()).c_str(), CMenu::_downloadProgress, this);
		if(download.data == 0)
			_setThrdMsg(_t("dlmsg12", L"Download failed!"), 1.f);
		else
		{
			string zippath = sfmt("%s/wiitdb.zip", m_settingsDir.c_str());

			gprintf("Downloading file to '%s'\n", zippath.c_str());

			remove(zippath.c_str());

			_setThrdMsg(wfmt(_fmt("dlmsg4", L"Saving %s"), "wiitdb.zip"), 1.f);
			FILE *file = fopen(zippath.c_str(), "wb");
			if(file == NULL)
			{
				gprintf("Can't save zip file\n");

				_setThrdMsg(_t("dlmsg15", L"Couldn't save ZIP file"), 1.f);
			}
			else
			{
				fwrite(download.data, download.size, 1, file);
				SAFE_CLOSE(file);

				gprintf("Extracting zip file: ");

				ZipFile zFile(zippath.c_str());
				bool zres = zFile.ExtractAll(m_settingsDir.c_str());

				gprintf(zres ? "success\n" : "failed\n");

				// We don't need the zipfile anymore
				remove(zippath.c_str());

				// Update cache
				m_gameList.SetLanguage(m_loc.getString(m_curLanguage, "gametdb_code", "EN").c_str());
				UpdateCache();

				_setThrdMsg(_t("dlmsg26", L"Updating cache..."), 0.f);

				_loadList();
				_initCF();
			}
		}
	}
	m_thrdWorking = false;
	return 0;
}
s8 CMenu::_versionDownloader() // code to download new version
{
	char dol_backup[33];
	strcpy(dol_backup, m_dol.c_str());
	strcat(dol_backup, ".backup");

	if(m_app_update_size == 0)	 m_app_update_size	= 0x400000;
	if(m_data_update_size == 0) m_data_update_size	= 0x400000;

	// check for existing dol
    ifstream filestr;
	gprintf("DOL Path: %s\n", m_dol.c_str());
    filestr.open(m_dol.c_str());
    if(filestr.fail())
	{
		filestr.close();
		rename(dol_backup, m_dol.c_str());
		filestr.open(m_dol.c_str());
		if(filestr.fail())
			_setThrdMsg(_t("dlmsg18", L"boot.dol not found at default path!"), 1.f);

		filestr.close();
		sleep(3);
		m_thrdWorking = false;
		return 0;
	}
    filestr.close();

	u32 bufferSize = max(m_app_update_size, m_data_update_size);	// Buffer for size of the biggest file.
	SmartBuf buffer = smartAnyAlloc(bufferSize);
	if(!buffer)
	{
		_setThrdMsg(L"Not enough memory!", 1.f);
		sleep(3);
		m_thrdWorking = false;
		return 0;
	}

	_setThrdMsg(_t("dlmsg1", L"Initializing network..."), 0.f);

	if(_initNetwork() < 0)
	{
		_setThrdMsg(_t("dlmsg2", L"Network initialization failed!"), 1.f);
		sleep(3);
		m_thrdWorking = false;
		return 0;
	}

	// Load actual file
	_setThrdMsg(_t("dlmsg22", L"Updating application directory..."), 0.2f);

	m_thrdStep = 0.2f;
	m_thrdStepLen = 0.9f - 0.2f;
	gprintf("App Update URL: %s\n", m_app_update_url);
	gprintf("Data Update URL: %s\n", m_app_update_url);

	download = downloadfile(buffer.get(), bufferSize, m_app_update_url, CMenu::_downloadProgress, this);
	if(download.data == 0 || download.size < m_app_update_size)
	{
		_setThrdMsg(_t("dlmsg12", L"Download failed!"), 1.f);
		sleep(3);
		m_thrdWorking = false;
		return 0;
	}

	// download finished, backup boot.dol and write new files.
	_setThrdMsg(_t("dlmsg13", L"Saving..."), 0.8f);

	remove(dol_backup);
	rename(m_dol.c_str(), dol_backup);

	remove(m_app_update_zip.c_str());

	FILE *file = fopen(m_app_update_zip.c_str(), "wb");
	if(file != NULL)
	{
		fwrite(download.data, 1, download.size, file);
		SAFE_CLOSE(file);

		_setThrdMsg(_t("dlmsg24", L"Extracting..."), 0.8f);

		ZipFile zFile(m_app_update_zip.c_str());
		bool result = zFile.ExtractAll(m_appDir.c_str());
		remove(m_app_update_zip.c_str());

		if(!result) goto fail;

		//Update apps dir succeeded, try to update the data dir.
		download.data = NULL;
		download.size = 0;

		//memset(&buffer, 0, bufferSize);  should we be clearing the buffer of any possible data before downloading?

		_setThrdMsg(_t("dlmsg23", L"Updating data directory..."), 0.2f);

		download = downloadfile(buffer.get(), bufferSize, m_data_update_url, CMenu::_downloadProgress, this);
		if(download.data == 0 || download.size < m_data_update_size)
		{
			_setThrdMsg(_t("dlmsg12", L"Download failed!"), 1.f);
			goto success;
		}

		// download finished, write new files.
		_setThrdMsg(_t("dlmsg13", L"Saving..."), 0.9f);

		remove(m_data_update_zip.c_str());

		file = fopen(m_data_update_zip.c_str(), "wb");
		if(file != NULL)
		{
			fwrite(download.data, 1, download.size, file);
			SAFE_CLOSE(file);

			_setThrdMsg(_t("dlmsg24", L"Extracting..."), 0.8f);

			ZipFile zDataFile(m_data_update_zip.c_str());
			result = zDataFile.ExtractAll(m_dataDir.c_str());
			remove(m_data_update_zip.c_str());

			if(!result)
				_setThrdMsg(_t("dlmsg15", L"Saving failed!"), 1.f);
		}

	}
	else
		goto fail;

success:
	_setThrdMsg(_t("dlmsg21", L"Wiiflow Advanced will now exit to allow the update to take effect."), 1.f);

    filestr.open(m_dol.c_str());
    if(filestr.fail())
	{
		_setThrdMsg(_t("dlmsg25", L"Extraction must have failed! Renaming the backup to boot.dol"), 1.f);
		rename(dol_backup, m_dol.c_str());
	}
    filestr.close();

	m_exit = true;
	goto out;

fail:
	rename(dol_backup, m_dol.c_str());
	_setThrdMsg(_t("dlmsg15", L"Saving failed!"), 1.f);
out:
	sleep(3);
	m_thrdWorking = false;
	return 0;
}
int CMenu::_coverDownloader(bool missingOnly)
{
	pair<string, string> coverPaths;
	vector<string> coverList;
	int count = 0, countFlat = 0;
	float listWeight = missingOnly ? 0.125f : 0.f;	// 1/8 of the progress bar for testing the PNGs we already have
	float dlWeight = 1.f - listWeight;

	u32 bufferSize = 0x280000;	// Maximum download size 2 MB
	SmartBuf buffer = smartAnyAlloc(bufferSize);
	if(!buffer)
	{
		_setThrdMsg(L"Not enough memory!", 1.f);
		m_thrdWorking = false;
		return 0;
	}
	bool savePNG = m_cfg.getBool("GENERAL", "keep_png", true);

	vector<string> fmtURLBox = stringToVector(m_cfg.getString("GENERAL", "url_full_covers", FMT_BPIC_URL), "|");
	vector<string> fmtURLFlat = stringToVector(m_cfg.getString("GENERAL", "url_flat_covers", FMT_PIC_URL), "|");

	u32 nbSteps = m_gameList.size();
	u32 step = 0;

	if(m_coverDLGameId.empty())
	{
		coverList.reserve(m_gameList.size());
		for(GameListIter list_iter = m_gameList.begin(); list_iter != m_gameList.end() && !m_thrdStop; list_iter++)
		{
			_setThrdMsg(_t("dlmsg7", L"Listing covers to download..."), listWeight *(float)step++ / (float)nbSteps);
			string id((*list_iter).id, sizeof(*list_iter).id);
			coverPaths = m_cf.getCoverPaths(id);
			if(!missingOnly || (!m_cf.fullCoverCached(id.c_str()) && !checkPNGFile(coverPaths.first.c_str())))
				coverList.push_back(id);
		}
	}
	else coverList.push_back(m_coverDLGameId);

	u32 n = coverList.size();
	if(!n || m_thrdStop)
	{
		if(!m_thrdStop)
			_setThrdMsg(L"Nothing in the list to download!", 1.f);
		m_thrdWorking = false;
		return 0;
	}

	step = 0;
	nbSteps = 1 + n * 2;

	if(!m_thrdStop)
		_setThrdMsg(_t("dlmsg1", L"Initializing network..."), listWeight + dlWeight *(float)step / (float)nbSteps);
	if(_initNetwork() < 0 || m_thrdStop)
	{
		if(!m_thrdStop)
			_setThrdMsg(_t("dlmsg2", L"Network initialization failed!"), 1.f);
		m_thrdWorking = false;
		return 0;
	}
	m_thrdStepLen = dlWeight / (float)nbSteps;

	Config m_newID;
	m_newID.load(sfmt("%s/newid.ini", m_settingsDir.c_str()).c_str());
	m_newID.setString("CHANNELS", "WFSF", "DWFA");

	for(vector<string>::iterator id_iter = coverList.begin(); id_iter != coverList.end() && !m_thrdStop; id_iter++)
	{
		// Try to get the full cover
		string url;
		const char *domain = _domainFromView();
		bool success = false;
		FILE *file = NULL;

		string newID = m_newID.getString(domain,(*id_iter),(*id_iter));
		if(!newID.empty() && strncasecmp(newID.c_str(), id_iter->c_str(), m_current_view != COVERFLOW_USB ? 4 : 6) == 0)
			m_newID.remove(domain,(*id_iter));
		else if(!newID.empty()) gprintf("old id = %s\nnew id = %s\n", id_iter->c_str(), newID.c_str());

		coverPaths = m_cf.getCoverPaths(*id_iter);
		for(vector<string>::iterator box_iter = fmtURLBox.begin(); box_iter != fmtURLBox.end() && !(m_thrdStop || success) && ++step; box_iter++)
		{
			url = makeURL(*box_iter, newID, countryCode(newID));
			m_thrdStep = listWeight + dlWeight *(float)step / (float)nbSteps;
			_setThrdMsg(wfmt(_fmt("dlmsg3", L"Downloading from %s"), url.c_str()), m_thrdStep);
			download = downloadfile(buffer.get(), bufferSize, url.c_str(), CMenu::_downloadProgress, this);
			if(download.data == NULL || download.size == 0 || !checkPNGBuf(download.data)) continue;

			if(savePNG)
			{
				_setThrdMsg(wfmt(_fmt("dlmsg4", L"Saving %s"), coverPaths.first.c_str()), m_thrdStep);
				file = fopen(coverPaths.first.c_str(), "wb");
				if(file == NULL) continue;
				fwrite(download.data, download.size, 1, file);
				SAFE_CLOSE(file);
			}

			_setThrdMsg(wfmt(_fmt("dlmsg10", L"Making %s"), sfmt("%s.wfc",id_iter->c_str()).c_str()), m_thrdStep);
			if(m_cf.preCacheCover(id_iter->c_str(), download.data, true))
			{
				count++;
				success = true;
			}
		}

		if(success || checkPNGFile(coverPaths.second.c_str())) continue;
		if(m_thrdStop) break;

		// Try to get the front cover
		for(vector<string>::iterator flat_iter = fmtURLFlat.begin(); flat_iter != fmtURLFlat.end() && !(m_thrdStop || success) && ++step; flat_iter++)
		{
			m_thrdStep = listWeight + dlWeight *(float)step / (float)nbSteps;
			url = makeURL(*flat_iter, newID, countryCode(newID));
			_setThrdMsg(wfmt(_fmt("dlmsg8", L"Full cover not found. Downloading from %s"), url.c_str()), m_thrdStep);
			download = downloadfile(buffer.get(), bufferSize, url.c_str(), CMenu::_downloadProgress, this);
			if(download.data == NULL || download.size == 0 || !checkPNGBuf(download.data)) continue;
			if(savePNG)
			{
				_setThrdMsg(wfmt(_fmt("dlmsg4", L"Saving %s"), coverPaths.second.c_str()), m_thrdStep);
				file = fopen(coverPaths.second.c_str(), "wb");
				if(file != NULL)
				{
					fwrite(download.data, download.size, 1, file);
					SAFE_CLOSE(file);
				}
			}

			_setThrdMsg(wfmt(_fmt("dlmsg10", L"Making %s"), sfmt("%s.wfc", id_iter->c_str()).c_str()), m_thrdStep);
			if(m_cf.preCacheCover(id_iter->c_str(), download.data, false))
			{
				countFlat++;
				success = true;
			}
		}
		newID.clear();
	}
	coverList.clear();
	m_newID.unload();

	if(countFlat == 0)
		_setThrdMsg(wfmt(_fmt("dlmsg5", L"%i/%i files downloaded."), count, n), 1.f);
	else
		_setThrdMsg(wfmt(_fmt("dlmsg9", L"%i/%i files downloaded. %i are front covers only."), count + countFlat, n, countFlat), 1.f);
	m_thrdWorking = false;
	return 0;
}
Example #8
0
void CMenu::_CheatSettings() {
	s32 padsState;
	WPADData *wd;
	u32 btn;
	WPAD_Rumble(WPAD_CHAN_0, 0);

	// try to load cheat file
	int txtavailable=0;
	m_cheatSettingsPage = 1; // init page
	
	txtavailable = m_cheatfile.openTxtfile(fmt("%s/%s.txt", m_txtCheatDir.c_str(), m_cf.getId().c_str())); 
	
	_showCheatSettings();
	_textCheatSettings();
	
	if (txtavailable)
		m_btnMgr.setText(m_cheatLblTitle,wfmt(L"%s",m_cheatfile.getGameName().c_str()));
	else 
		m_btnMgr.setText(m_cheatLblTitle,L"");
	
	while (true)
	{
		WPAD_ScanPads();
		padsState = WPAD_ButtonsDown(0);
		wd = WPAD_Data(0);
		btn = _btnRepeat(wd->btns_h);
		if ((padsState & (WPAD_BUTTON_HOME | WPAD_BUTTON_B)) != 0)
			break;
		if (wd->ir.valid)
			m_btnMgr.mouse(wd->ir.x - m_cur.width() / 2, wd->ir.y - m_cur.height() / 2);
		else if ((padsState & WPAD_BUTTON_UP) != 0)
			m_btnMgr.up();
		else if ((padsState & WPAD_BUTTON_DOWN) != 0)
			m_btnMgr.down();
		if ((padsState & WPAD_BUTTON_MINUS) != 0)
		{
			if (m_cheatSettingsPage > 1)
				--m_cheatSettingsPage;
			_hideCheatSettings();
			_showCheatSettings();
			m_btnMgr.click(m_cheatBtnPageM);
		}
		else if ((padsState & WPAD_BUTTON_PLUS) != 0)
		{
			_hideCheatSettings();
			if (m_cheatSettingsPage < (m_cheatfile.getCnt()+CHEATSPERPAGE-1)/CHEATSPERPAGE)
				++m_cheatSettingsPage;
			_showCheatSettings();
			m_btnMgr.click(m_cheatBtnPageP);
		}		
		if ((padsState & WPAD_BUTTON_A) != 0)
		{
			m_btnMgr.click();
			if (m_btnMgr.selected() == m_cheatBtnBack)
				break;
			else if (m_btnMgr.selected() == m_cheatBtnPageM)
			{
				_hideCheatSettings();
				if (m_cheatSettingsPage > 1)
					--m_cheatSettingsPage;
				_showCheatSettings();
			}
			else if (m_btnMgr.selected() == m_cheatBtnPageP)
			{
				_hideCheatSettings();
				if (m_cheatSettingsPage < (m_cheatfile.getCnt()+CHEATSPERPAGE-1)/CHEATSPERPAGE)
					++m_cheatSettingsPage;
				_showCheatSettings();
			}
				
			for (int i = 0; i < CHEATSPERPAGE; ++i)
				if (m_btnMgr.selected() == m_cheatBtnItem[i]) {
					// handling code for clicked cheat
					m_cheatfile.sCheatSelected[(m_cheatSettingsPage-1)*CHEATSPERPAGE + i] = !m_cheatfile.sCheatSelected[(m_cheatSettingsPage-1)*CHEATSPERPAGE + i];
					_showCheatSettings();
				}
			
			if (m_btnMgr.selected() == m_cheatBtnApply)
			{
				int operation_ok,check = 0;
				//checks if at least one cheat is selected
				for (unsigned int i=0; i < m_cheatfile.getCnt(); ++i) {
					if (m_cheatfile.sCheatSelected[i] == true) 
						{
						check = 1;
						break;
						}
					
					}
					
				if (check)
				{
					operation_ok = m_cheatfile.createGCT(fmt("%s/%s.gct", m_cheatDir.c_str(), m_cf.getId().c_str())); 
					operation_ok = m_cheatfile.createTXT(fmt("%s/%s.txt", m_txtCheatDir.c_str(), m_cf.getId().c_str())); 
					
				}
					
				m_cfg.setOptBool(m_cf.getId(), "cheat",1);
				if (operation_ok)
					break;
			}

			if (m_btnMgr.selected() == m_cheatBtnDownload)
			{
				// Download cheat code
				m_btnMgr.hide(m_cheatLblTitle);
				
				u32 bufferSize = 0x100000;	// Maximum download size 1 MB
				SmartBuf buffer;
				block cheatfile;
				FILE *file;
				char ip[16];
				
				if (!m_networkInit && _initNetwork(ip) < 0) {
					m_btnMgr.hide(m_cheatLblTitle);
					break;
				}
				m_networkInit = true;

				buffer = smartCoverAlloc(bufferSize);
				cheatfile = downloadfile(buffer.get(), bufferSize, sfmt(GECKOURL, m_cf.getId().c_str()).c_str(),CMenu::_downloadProgress, this);

				if (cheatfile.data != NULL && cheatfile.size > 65 && cheatfile.data[0] != '<') {
					// cheat file was downloaded and presumably no 404
					file = fopen(fmt("%s/%s.txt", m_txtCheatDir.c_str(), m_cf.getId().c_str()), "wb");
							
					if (file != NULL)
					{
						fwrite(cheatfile.data, 1, cheatfile.size, file);
						fclose(file);
						break;
					}
				}
				else
				{
					// cheat code not found, show result
					m_btnMgr.setText(m_cheatLblItem[0], _t("cheat4", L"Download not found."));
					m_btnMgr.setText(m_cheatLblItem[1], wfmt(L"http://www.geckocodes.org/codes/R/%s.txt",m_cf.getId().c_str()));
					m_btnMgr.show(m_cheatLblItem[1]);
				}
			}
		}
		_mainLoopCommon(wd);
	}
	_hideCheatSettings();
}
Example #9
0
int CMenu::_titleDownloader(bool missingOnly)
{
	block txt;
	Config titles;
	char ip[16];
	string langCode;
	wstringEx ws;
	bool ok = false;
	SmartBuf buffer;
	const char *p;
	const char *txtEnd;
	u32 len;
	u32 bufferSize = 1 * 0x100000;	// Maximum download size 1 MB

	buffer = smartCoverAlloc(bufferSize);
	if (!buffer)
	{
		_setThrdMsg(L"Not enough memory", 1.f);
		return 0;
	}
	titles.load(sfmt("%s/titles.ini", m_dataDir.c_str()).c_str());
	langCode = m_loc.getString(m_curLanguage, "wiitdb_code", "EN");
	_setThrdMsg(_t("dlmsg1", L"Initializing network..."), 0.f);
	if (!m_networkInit && _initNetwork(ip) < 0)
	{
		_setThrdMsg(_t("dlmsg2", L"Network initialization failed"), 1.f);
	}
	else
	{
		m_networkInit = true;
		_setThrdMsg(_t("dlmsg11", L"Downloading..."), 0.1f);
		m_thrdStep = 0.1f;
		m_thrdStepLen = 0.9f - 0.1f;
		txt = downloadfile(buffer.get(), bufferSize, sfmt(TITLES_URL, langCode.c_str()).c_str(), CMenu::_downloadProgress, this);
		if (txt.data == 0 || txt.size < 42)
		{
			_setThrdMsg(_t("dlmsg12", L"Download failed"), 1.f);
		}
		else
		{
			txt.data[min(txt.size, bufferSize - 1)] = 0;
			p = (const char *)txt.data;
			txtEnd = (const char *)txt.data + txt.size;
			while (p < txtEnd)
			{
				len = strcspn((char *)p, "\n");
				if (len > 7)
				{
					string l((char *)p, len);
					u32 i = l.find_first_of('=');
					u32 j = l.find_first_of(' ');
					u32 n = min(i, j);
					if (i != string::npos && n >= 4 && (n == 6 || n == 4))
					{
						u32 m = l.find_first_not_of(' ', i + 1);
						if (m != string::npos)
						{
							ok = true;
							wstringEx w;
							w.fromUTF8(l.substr(m, l[l.size() - 1] == '\r' ? l.size() - 1 - m : l.size() - m).c_str());
							if (missingOnly)
								titles.getWString("TITLES", l.substr(0, n), w);
							else
								titles.setWString("TITLES", l.substr(0, n), w);
						}
					}
				}
				p += len + 1;
			}
			if (!ok)
			{
				_setThrdMsg(_t("dlmsg16", L"Couldn't read file"), 1.f);
			}
		}
	}
	if (ok)
	{
		_setThrdMsg(_t("dlmsg13", L"Saving..."), 0.9f);
		titles.save();
		_setThrdMsg(_t("dlmsg14", L"Done."), 1.f);
	}
	m_thrdWorking = false;
	return 0;
}
Example #10
0
int CMenu::_coverDownloader(bool missingOnly)
{
	u32 n;
	u32 nbSteps;
	u32 step;
	float listWeight = missingOnly ? 0.125f : 0.f;	// 1/8 of the progress bar for testing the PNGs we already have
	float dlWeight = 1.f - listWeight;
	int count = 0;
	int countFlat = 0;
	FILE *file;
	char ip[16];
	string url;
	string path;
	block png;
	vector<string> coverList;
	bool savePNG;
	bool success;
	vector<string> fmtURLFlat;
	vector<string> fmtURLBox;
	u32 bufferSize = 0x400000;	// Maximum download size 4 MB
	SmartBuf buffer;

	// Use the cover space as a temporary buffer
	buffer = smartCoverAlloc(bufferSize);
	if (!buffer)
	{
		_setThrdMsg(L"Not enough memory", 1.f);
		m_thrdWorking = false;
		return 0;
	}
	savePNG = m_cfg.getBool(" GENERAL", "keep_png", true);
	fmtURLBox = stringToVector(m_cfg.getString(" GENERAL", "url_full_covers", FMT_BPIC_URL), '|');
	fmtURLFlat = stringToVector(m_cfg.getString(" GENERAL", "url_flat_covers", FMT_PIC_URL), '|');
	nbSteps = m_gameList.size();
	step = 0;
	if (m_coverDLGameId.empty())
	{
		coverList.reserve(m_gameList.size());
		for (u32 i = 0; i < m_gameList.size() && !m_thrdStop; ++i)
		{
			_setThrdMsg(_t("dlmsg7", L"Listing covers to download..."), listWeight * (float)step / (float)nbSteps);
			++step;
			string id((const char *)m_gameList[i].id, sizeof m_gameList[i].id);
			path = sfmt("%s/%s.png", m_boxPicDir.c_str(), id.c_str());
			if (!missingOnly || (!m_cf.fullCoverCached(id.c_str()) && !checkPNGFile(path.c_str())))
				coverList.push_back(id);
		}
	}
	else
		coverList.push_back(m_coverDLGameId);
	n = coverList.size();
	if (n > 0 && !m_thrdStop)
	{
		step = 0;
		nbSteps = 1 + n * 2;
		_setThrdMsg(_t("dlmsg1", L"Initializing network..."), listWeight + dlWeight * (float)step / (float)nbSteps);
		if (!m_networkInit && _initNetwork(ip) < 0)
		{
			_setThrdMsg(_t("dlmsg2", L"Network initialization failed"), 1.f);
			m_thrdWorking = false;
			return 0;
		}
		m_thrdStepLen = dlWeight / (float)nbSteps;
		m_networkInit = true;
		
		gprintf("Going to download %d covers\n", coverList.size());
		for (u32 i = 0; i < coverList.size() && !m_thrdStop; ++i)
		{
			// Try to get the full cover
			gprintf("Trying to get the full cover of %s\n", coverList[i].c_str());
			success = false;
			for (u32 j = 0; !success && j < fmtURLBox.size() && !m_thrdStop; ++j)
			{
				url = makeURL(fmtURLBox[j], coverList[i], countryCode(coverList[i]));
				if (j == 0)
					++step;
				m_thrdStep = listWeight + dlWeight * (float)step / (float)nbSteps;
				_setThrdMsg(wfmt(_fmt("dlmsg3", L"Downloading from %s"), url.c_str()), m_thrdStep);
				
				png = downloadfile(buffer.get(), bufferSize, url.c_str(), CMenu::_downloadProgress, this);
				if (png.data != NULL)
				{
					if (savePNG)
					{
						path = sfmt("%s/%s.png", m_boxPicDir.c_str(), coverList[i].c_str());
						_setThrdMsg(wfmt(_fmt("dlmsg4", L"Saving %s"), path.c_str()), listWeight + dlWeight * (float)(step + 1) / (float)nbSteps);
						file = fopen(path.c_str(), "wb");
						if (file != NULL)
						{
							fwrite(png.data, png.size, 1, file);
							fclose(file);
						}
					}
					
					_setThrdMsg(wfmt(_fmt("dlmsg10", L"Making %s"), sfmt("%s.wfc", coverList[i].c_str()).c_str()), listWeight + dlWeight * (float)(step + 1) / (float)nbSteps);
					if (m_cf.preCacheCover(coverList[i].c_str(), png.data, true))
					{
						++count;
						success = true;
					}
				}
			}
			if (!success && !m_thrdStop)
			{
				path = sfmt("%s/%s.png", m_picDir.c_str(), coverList[i].c_str());
				if (!checkPNGFile(path.c_str()))
				{
					// Try to get the front cover
					if (m_thrdStop)
						break;

					gprintf("Trying to get the front cover of %s\n", coverList[i].c_str());
					for (u32 j = 0; !success && j < fmtURLFlat.size() && !m_thrdStop; ++j)
					{
						url = makeURL(fmtURLFlat[j], coverList[i], countryCode(coverList[i]));
						_setThrdMsg(wfmt(_fmt("dlmsg8", L"Full cover not found. Downloading from %s"), url.c_str()), listWeight + dlWeight * (float)step / (float)nbSteps);

						png = downloadfile(buffer.get(), bufferSize, url.c_str(), CMenu::_downloadProgress, this);
						if (png.data != NULL)
						{
							if (savePNG)
							{
								_setThrdMsg(wfmt(_fmt("dlmsg4", L"Saving %s"), path.c_str()), listWeight + dlWeight * (float)(step + 1) / (float)nbSteps);
								file = fopen(path.c_str(), "wb");
								if (file != NULL)
								{
									fwrite(png.data, png.size, 1, file);
									fclose(file);
								}
							}

							_setThrdMsg(wfmt(_fmt("dlmsg10", L"Making %s"), sfmt("%s.wfc", coverList[i].c_str()).c_str()), listWeight + dlWeight * (float)(step + 1) / (float)nbSteps);
							if (m_cf.preCacheCover(coverList[i].c_str(), png.data, false))
							{
								++countFlat;
								success = true;
							}
						}
					}
				}
			}
			++step;
		}
		gprintf("Finished downloading covers\n");
	}
	if (countFlat == 0)
		_setThrdMsg(wfmt(_fmt("dlmsg5", L"%i/%i files downloaded."), count, n), 1.f);
	else
		_setThrdMsg(wfmt(_fmt("dlmsg9", L"%i/%i files downloaded. %i are front covers only."), count + countFlat, n, countFlat), 1.f);
	m_thrdWorking = false;
	return 0;
}