void Dlg_GameLibrary::RefreshList()
{
	std::map<std::string, std::string>::iterator iter = Results.begin();
	while (iter != Results.end())
	{
		const std::string& filepath = iter->first;
		const std::string& md5 = iter->second;

		if (VisibleResults.find(filepath) == VisibleResults.end())
		{
			//	Not yet added,
			if (m_GameHashLibrary.find(md5) != m_GameHashLibrary.end())
			{
				//	Found in our hash library!
				const GameID nGameID = m_GameHashLibrary[md5];
				RA_LOG("Found one! Game ID %d (%s)", nGameID, m_GameTitlesLibrary[nGameID].c_str());

				const std::string& sGameTitle = m_GameTitlesLibrary[nGameID];
				AddTitle(sGameTitle, filepath, nGameID);

				SetDlgItemText(m_hDialogBox, IDC_RA_SCANNERFOUNDINFO, NativeStr(sGameTitle).c_str());
				VisibleResults[filepath] = md5;	//	Copy to VisibleResults
			}
		}
		iter++;
	}
}
void Dlg_GameLibrary::KillThread()
{
	Dlg_GameLibrary::ThreadProcessingAllowed = false;
	while (Dlg_GameLibrary::ThreadProcessingActive)
	{
		RA_LOG("Waiting for background scanner...");
		Sleep(200);
	}
}
Beispiel #3
0
BOOL AchievementSet::Unlock( AchievementID nAchID )
{
	for( size_t i = 0; i < NumAchievements(); ++i )
	{
		if( m_Achievements[ i ].ID() == nAchID )
		{
			m_Achievements[ i ].SetActive( FALSE );
			return TRUE;	//	Update Dlg? //TBD
		}
	}

	RA_LOG( "Attempted to unlock achievement %d but failed!\n", nAchID );
	return FALSE;//??
}
Beispiel #4
0
HBITMAP LoadLocalPNG( const std::string& sPath, const RASize& sz )
{
	SetCurrentDirectory( Widen( g_sHomeDir ).c_str() );

	ASSERT( _FileExists( sPath ) );
	if( !_FileExists( sPath ) )
	{
		RA_LOG( "File could not be found: %s\n", sPath.c_str() );
		return nullptr;
	}

	HBITMAP hRetVal = nullptr;
	// Step 2: Decode the source image to IWICBitmapSource
	IWICBitmapDecoder* pDecoder = nullptr;
	HRESULT hr = g_UserImageFactoryInst.m_pIWICFactory->CreateDecoderFromFilename( Widen( sPath ).c_str(),			// Image to be decoded
																				   nullptr,							// Do not prefer a particular vendor
																				   GENERIC_READ,					// Desired read access to the file
																				   WICDecodeMetadataCacheOnDemand,	// Cache metadata when needed
																				   &pDecoder );						// Pointer to the decoder
	
	// Retrieve the first frame of the image from the decoder
	IWICBitmapFrameDecode* pFrame = nullptr;
	if( SUCCEEDED( hr ) )
		hr = pDecoder->GetFrame( 0, &pFrame );

	// Retrieve IWICBitmapSource from the frame
	if( SUCCEEDED( hr ) )
	{
		SAFE_RELEASE( g_UserImageFactoryInst.m_pOriginalBitmapSource );	//##SD ???
		pFrame->QueryInterface( IID_IWICBitmapSource, reinterpret_cast<void**>( &g_UserImageFactoryInst.m_pOriginalBitmapSource ) );
	}

	// Step 3: Scale the original IWICBitmapSource to the client rect size
	// and convert the pixel format
	IWICBitmapSource* pToRenderBitmapSource = nullptr;
	if( SUCCEEDED( hr ) )
		hr = ConvertBitmapSource( { 0, 0, sz.Width(), sz.Height() }, pToRenderBitmapSource );

	// Step 4: Create a DIB from the converted IWICBitmapSource
	if( SUCCEEDED( hr ) )
		hr = UserImageFactory_CreateDIBSectionFromBitmapSource( pToRenderBitmapSource, hRetVal );

	SAFE_RELEASE( pToRenderBitmapSource );
	SAFE_RELEASE( pDecoder );
	SAFE_RELEASE( pFrame );
	SAFE_RELEASE( g_UserImageFactoryInst.m_pOriginalBitmapSource );
	
	return hRetVal;
}
INT_PTR CALLBACK Dlg_GameLibrary::GameLibraryProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
	switch (uMsg)
	{
	case WM_INITDIALOG:
	{
		HWND hList = GetDlgItem(hDlg, IDC_RA_LBX_GAMELIST);
		SetupColumns(hList);

		ListView_SetExtendedListViewStyle(hList, LVS_EX_FULLROWSELECT | LVS_EX_HEADERDRAGDROP);

		SetDlgItemText(hDlg, IDC_RA_ROMDIR, NativeStr(g_sROMDirLocation).c_str());
		SetDlgItemText(hDlg, IDC_RA_GLIB_NAME, TEXT(""));

		m_GameHashLibrary.clear();
		m_GameTitlesLibrary.clear();
		m_ProgressLibrary.clear();
		ParseGameHashLibraryFromFile(m_GameHashLibrary);
		ParseGameTitlesFromFile(m_GameTitlesLibrary);
		ParseMyProgressFromFile(m_ProgressLibrary);

		//int msBetweenRefresh = 1000;	//	auto?
		//SetTimer( hDlg, 1, msBetweenRefresh, (TIMERPROC)g_GameLibrary.s_GameLibraryProc );
		RefreshList();

		return FALSE;
	}

	case WM_TIMER:
		if ((g_GameLibrary.GetHWND() != NULL) && (IsWindowVisible(g_GameLibrary.GetHWND())))
			RefreshList();
		//ReloadGameListData();
		return FALSE;

	case WM_NOTIFY:
		switch (LOWORD(wParam))
		{
		case IDC_RA_LBX_GAMELIST:
		{
			switch (((LPNMHDR)lParam)->code)
			{
			case LVN_ITEMCHANGED:
			{
				//RA_LOG( "Item Changed\n" );
				HWND hList = GetDlgItem(hDlg, IDC_RA_LBX_GAMELIST);
				const int nSel = ListView_GetSelectionMark(hList);
				if (nSel != -1)
				{
					TCHAR buffer[1024];
					ListView_GetItemText(hList, nSel, 1, buffer, 1024);
					SetWindowText(GetDlgItem(hDlg, IDC_RA_GLIB_NAME), buffer);
				}
			}
			break;

			case NM_CLICK:
				//RA_LOG( "Click\n" );
				break;

			case NM_DBLCLK:
				if (LaunchSelected())
				{
					EndDialog(hDlg, TRUE);
					return TRUE;
				}
				break;

			default:
				break;
			}
		}
		return FALSE;

		default:
			RA_LOG("%08x, %08x\n", wParam, lParam);
			return FALSE;
		}

	case WM_COMMAND:
		switch (LOWORD(wParam))
		{
		case IDOK:
			if (LaunchSelected())
			{
				EndDialog(hDlg, TRUE);
				return TRUE;
			}
			else
			{
				return FALSE;
			}

		case IDC_RA_RESCAN:
			ReloadGameListData();

			mtx.lock();	//?
			SetDlgItemText(m_hDialogBox, IDC_RA_SCANNERFOUNDINFO, TEXT("Scanning..."));
			mtx.unlock();
			return FALSE;

		case IDC_RA_PICKROMDIR:
			g_sROMDirLocation = GetFolderFromDialog();
			RA_LOG("Selected Folder: %s\n", g_sROMDirLocation.c_str());
			SetDlgItemText(hDlg, IDC_RA_ROMDIR, NativeStr(g_sROMDirLocation).c_str());
			return FALSE;

		case IDC_RA_LBX_GAMELIST:
		{
			HWND hList = GetDlgItem(hDlg, IDC_RA_LBX_GAMELIST);
			const int nSel = ListView_GetSelectionMark(hList);
			if (nSel != -1)
			{
				TCHAR sGameTitle[1024];
				ListView_GetItemText(hList, nSel, 1, sGameTitle, 1024);
				SetWindowText(GetDlgItem(hDlg, IDC_RA_GLIB_NAME), sGameTitle);
			}
		}
		return FALSE;

		case IDC_RA_REFRESH:
			RefreshList();
			return FALSE;

		default:
			return FALSE;
		}

	case WM_PAINT:
		if (nNumParsed != Results.size())
			nNumParsed = Results.size();
		return FALSE;

	case WM_CLOSE:
		EndDialog(hDlg, FALSE);
		return TRUE;

	case WM_USER:
		return FALSE;

	default:
		return FALSE;
	}
}
void Dlg_GameLibrary::ScanAndAddRomsRecursive(const std::string& sBaseDir)
{
	char sSearchDir[2048];
	sprintf_s(sSearchDir, 2048, "%s\\*.*", sBaseDir.c_str());

	WIN32_FIND_DATA ffd;
	HANDLE hFind = FindFirstFile(NativeStr(sSearchDir).c_str(), &ffd);
	if (hFind != INVALID_HANDLE_VALUE)
	{
		unsigned int ROM_MAX_SIZE = 6 * 1024 * 1024;
		unsigned char* sROMRawData = new unsigned char[ROM_MAX_SIZE];

		do
		{
			if (KEYDOWN(VK_ESCAPE))
				break;

			memset(sROMRawData, 0, ROM_MAX_SIZE);	//?!??

			const std::string sFilename = Narrow(ffd.cFileName);
			if (strcmp(sFilename.c_str(), ".") == 0 ||
				strcmp(sFilename.c_str(), "..") == 0)
			{
				//	Ignore 'this'
			}
			else if (ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
			{
				RA_LOG("Directory found: %s\n", ffd.cFileName);
				std::string sRecurseDir = sBaseDir + "\\" + sFilename.c_str();
				ScanAndAddRomsRecursive(sRecurseDir);
			}
			else
			{
				LARGE_INTEGER filesize;
				filesize.LowPart = ffd.nFileSizeLow;
				filesize.HighPart = ffd.nFileSizeHigh;
				if (filesize.QuadPart < 2048 || filesize.QuadPart > ROM_MAX_SIZE)
				{
					//	Ignore: wrong size
					RA_LOG("Ignoring %s, wrong size\n", sFilename.c_str());
				}
				else
				{
					//	Parse as ROM!
					RA_LOG("%s looks good: parsing!\n", sFilename.c_str());

					char sAbsFileDir[2048];
					sprintf_s(sAbsFileDir, 2048, "%s\\%s", sBaseDir.c_str(), sFilename.c_str());

					HANDLE hROMReader = CreateFile(NativeStr(sAbsFileDir).c_str(), GENERIC_READ, FILE_SHARE_READ,
						NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);

					if (hROMReader != INVALID_HANDLE_VALUE)
					{
						BY_HANDLE_FILE_INFORMATION File_Inf;
						int nSize = 0;
						if (GetFileInformationByHandle(hROMReader, &File_Inf))
							nSize = (File_Inf.nFileSizeHigh << 16) + File_Inf.nFileSizeLow;

						DWORD nBytes = 0;
						BOOL bResult = ReadFile(hROMReader, sROMRawData, nSize, &nBytes, NULL);
						const std::string sHashOut = RAGenerateMD5(sROMRawData, nSize);

						if (m_GameHashLibrary.find(sHashOut) != m_GameHashLibrary.end())
						{
							const unsigned int nGameID = m_GameHashLibrary[std::string(sHashOut)];
							RA_LOG("Found one! Game ID %d (%s)", nGameID, m_GameTitlesLibrary[nGameID].c_str());

							const std::string& sGameTitle = m_GameTitlesLibrary[nGameID];
							AddTitle(sGameTitle, sAbsFileDir, nGameID);
							SetDlgItemText(m_hDialogBox, IDC_RA_GLIB_NAME, NativeStr(sGameTitle).c_str());
							InvalidateRect(m_hDialogBox, nullptr, TRUE);
						}

						CloseHandle(hROMReader);
					}
				}
			}
		} while (FindNextFile(hFind, &ffd) != 0);

		delete[](sROMRawData);
		sROMRawData = NULL;

		FindClose(hFind);
	}

	SetDlgItemText(m_hDialogBox, IDC_RA_SCANNERFOUNDINFO, TEXT("Scanning complete"));
}
Beispiel #7
0
void RA_RichPresenceInterpretter::ParseRichPresenceFile( const char* sFilename )
{
	m_formats.clear();
	m_lookups.clear();
	m_sDisplay.clear();

	const char EndLine = '\n';

	const char* LookupStr = "Lookup:";
	const char* FormatStr = "Format:";
	const char* FormatTypeStr = "FormatType=";
	const char* DisplayableStr = "Display:";

	FILE* pFile = NULL;
	fopen_s( &pFile, sFilename, "r" );
	if( pFile != NULL )
	{
		DWORD nCharsRead = 0;
		char buffer[4096];

		_ReadTil( EndLine, buffer, 4096, &nCharsRead, pFile );
		while( nCharsRead != 0 )
		{
			if( strncmp( LookupStr, buffer, strlen( LookupStr ) ) == 0 )
			{
				//	Lookup type
				char* pBuf = buffer + ( strlen( LookupStr ) );
				RA_Lookup newLookup( _ReadStringTil( EndLine, pBuf, TRUE ) );
				while( nCharsRead != 0 && ( buffer[0] != EndLine ) )
				{
					_ReadTil( EndLine, buffer, 4096, &nCharsRead, pFile );
					if( nCharsRead > 2 )
					{
						char* pBuf = &buffer[0];
						const char* pValue = _ReadStringTil( '=', pBuf, TRUE );
						const char* pName = _ReadStringTil( EndLine, pBuf, TRUE );

						int nBase = 10;
						if( pValue[0] == '0' && pValue[1] == 'x' )
							nBase = 16;

						DataPos nVal = static_cast<DataPos>( strtol( pValue, NULL, nBase ) );

						newLookup.AddLookupData( nVal, pName );
					}
				}

				RA_LOG( "RP: Adding Lookup %s\n", newLookup.Description().c_str() );
				m_lookups.push_back( newLookup );

			}
			else if( strncmp( FormatStr, buffer, strlen( FormatStr ) ) == 0 )
			{
				//	
				char* pBuf = &buffer[0];
				const char* pUnused = _ReadStringTil( ':', pBuf, TRUE );
				std::string sDesc = _ReadStringTil( EndLine, pBuf, TRUE );

				_ReadTil( EndLine, buffer, 4096, &nCharsRead, pFile );
				if( nCharsRead > 0 && strncmp( FormatTypeStr, buffer, strlen( FormatTypeStr ) ) == 0 )
				{
					char* pBuf = &buffer[0];
					const char* pUnused = _ReadStringTil( '=', pBuf, TRUE );
					const char* pType = _ReadStringTil( EndLine, pBuf, TRUE );
					
					RA_Leaderboard::FormatType nType;

					if( strcmp( pType, "SCORE" ) == 0 || strcmp( pType, "POINTS" ) == 0 )
					{
						nType = RA_Leaderboard::Format_Score;
					}
					else if( strcmp( pType, "TIME" ) == 0 || strcmp( pType, "FRAMES" ) == 0 )
					{
						nType = RA_Leaderboard::Format_TimeFrames;
					}
					else if( strcmp( pType, "SECS" ) == 0 )
					{
						nType = RA_Leaderboard::Format_TimeSecs;
					}
					else if( strcmp( pType, "MILLISECS" ) == 0 )
					{
						nType = RA_Leaderboard::Format_TimeMillisecs;
					}
					else if( strcmp( pType, "VALUE" ) == 0 )
					{
						nType = RA_Leaderboard::Format_Value;
					}
					else
					{
						nType = RA_Leaderboard::Format_Other;
					}

					RA_LOG( "RP: Adding Formatter %s (%s)\n", sDesc.c_str(), pType );
					m_formats.push_back( RA_Formattable( sDesc, nType ) );
				}
			}
			else if( strncmp( DisplayableStr, buffer, strlen( DisplayableStr ) ) == 0 )
			{
				_ReadTil( EndLine, buffer, 4096, &nCharsRead, pFile );
				
				char* pBuf =  &buffer[0];
				m_sDisplay = _ReadStringTil( '\n', pBuf, TRUE );	//	Terminates \n instead
			}

			_ReadTil( EndLine, buffer, 4096, &nCharsRead, pFile );
		}

		fclose( pFile );
	}
}
Beispiel #8
0
void AchievementSet::LoadProgress( const char* sLoadStateFilename )
{
	char buffer[4096];
	long nFileSize = 0;
	unsigned int CondNumHits[50];	//	50 conditions per achievement
	unsigned int CondSourceVal[50];
	unsigned int CondSourceLastVal[50];
	unsigned int CondTargetVal[50];
	unsigned int CondTargetLastVal[50];
	unsigned int nID = 0;
	unsigned int nNumCond = 0;
	char cheevoProgressString[4096];
	unsigned int i = 0;
	unsigned int j = 0;
	char* pGivenProgressMD5 = NULL;
	char* pGivenCheevoMD5 = NULL;
	char cheevoMD5TestMangled[4096];
	int nMemStringLen = 0;

	if( !RAUsers::LocalUser().IsLoggedIn() )
		return;

	if( sLoadStateFilename == NULL )
		return;

	sprintf_s( buffer, 4096, "%s%s.rap", RA_DIR_DATA, sLoadStateFilename );

	char* pRawFile = _MallocAndBulkReadFileToBuffer( buffer, nFileSize );

	if( pRawFile != NULL )
	{
		unsigned int nOffs = 0;
		while( nOffs < (unsigned int)(nFileSize-2) && pRawFile[nOffs] != '\0' )
		{
			char* pIter = &pRawFile[nOffs];

			//	Parse achievement id and num conditions
			nID		 = strtol( pIter, &pIter, 10 ); pIter++;
			nNumCond = strtol( pIter, &pIter, 10 );	pIter++;

			//	Concurrently build the md5 checkstring
			sprintf_s( cheevoProgressString, 4096, "%d:%d:", nID, nNumCond );

			ZeroMemory( CondNumHits, 50*sizeof(unsigned int) );
			ZeroMemory( CondSourceVal, 50*sizeof(unsigned int) );
			ZeroMemory( CondSourceLastVal, 50*sizeof(unsigned int) );
			ZeroMemory( CondTargetVal, 50*sizeof(unsigned int) );
			ZeroMemory( CondTargetLastVal, 50*sizeof(unsigned int) );

			for( i = 0; i < nNumCond && i < 50; ++i )
			{
				//	Parse next condition state
				CondNumHits[i]		 = strtol( pIter, &pIter, 10 ); pIter++;
				CondSourceVal[i]	 = strtol( pIter, &pIter, 10 ); pIter++;
				CondSourceLastVal[i] = strtol( pIter, &pIter, 10 ); pIter++;
				CondTargetVal[i]	 = strtol( pIter, &pIter, 10 ); pIter++;
				CondTargetLastVal[i] = strtol( pIter, &pIter, 10 ); pIter++;
			
				//	Concurrently build the md5 checkstring
				sprintf_s( buffer, 4096, "%d:%d:%d:%d:%d:", 
					CondNumHits[i], 
					CondSourceVal[i],
					CondSourceLastVal[i],
					CondTargetVal[i],
					CondTargetLastVal[i] );

				strcat_s( cheevoProgressString, 4096, buffer );
			}

			//	Read the given md5:
			pGivenProgressMD5 = strtok_s( pIter, ":", &pIter );
			pGivenCheevoMD5 = strtok_s( pIter, ":", &pIter );
		
			//	Regenerate the md5 and see if it sticks:
			sprintf_s( cheevoMD5TestMangled, 4096, "%s%s%s%d", 
				RAUsers::LocalUser().Username().c_str(), cheevoProgressString, RAUsers::LocalUser().Username().c_str(), nID );

			std::string sRecalculatedProgressMD5 = RAGenerateMD5( cheevoMD5TestMangled );

			if( sRecalculatedProgressMD5.compare( pGivenProgressMD5 ) == 0 )
			{
				//	Embed in achievement:
				Achievement* pAch = Find( nID );
				if( pAch != NULL )
				{
					std::string sMemStr = pAch->CreateMemString();

					//	Recalculate the current achievement to see if it's compatible:
					std::string sMemMD5 = RAGenerateMD5( sMemStr );
					if( sMemMD5.compare( 0, 32, pGivenCheevoMD5 ) == 0 )
					{
						for( size_t nGrp = 0; nGrp < pAch->NumConditionGroups(); ++nGrp )
						{
							for( j = 0; j < pAch->NumConditions( nGrp ); ++j )
							{
								Condition& cond = pAch->GetCondition( nGrp, j );

								cond.OverrideCurrentHits( CondNumHits[ j ] );
								cond.CompSource().SetValues( CondSourceVal[ j ], CondSourceLastVal[ j ] );
								cond.CompTarget().SetValues( CondTargetVal[ j ], CondTargetLastVal[ j ] );

								pAch->SetDirtyFlag( Dirty_Conditions );
							}
						}
					}
					else
					{
						ASSERT( !"Achievement progress savestate incompatible (achievement has changed?)" );
						RA_LOG( "Achievement progress savestate incompatible (achievement has changed?)" );
					}
				}
				else
				{
					ASSERT( !"Achievement doesn't exist!" );
					RA_LOG( "Achievement doesn't exist!" );
				}
			}
			else
			{
				//assert(!"MD5 invalid... what to do... maybe they're trying to hack achievements?");
			}
		
			nOffs = (pIter - pRawFile);
		}
	
		free( pRawFile );
		pRawFile = NULL;
	}
}
Beispiel #9
0
//	static
BOOL AchievementSet::LoadFromFile( GameID nGameID )
{
	//	Is this safe?
	CoreAchievements->Clear();
	UnofficialAchievements->Clear();
	LocalAchievements->Clear();			//?!?!?

	if( nGameID == 0 )
		return TRUE;

	const std::string sFilename = GetAchievementSetFilename( nGameID );

	SetCurrentDirectory( Widen( g_sHomeDir ).c_str() );
	FILE* pFile = NULL;
	fopen_s( &pFile, sFilename.c_str(), "rb" );
	if( pFile != NULL )
	{
		//	Store this: we are now assuming this is the correct checksum if we have a file for it
		CoreAchievements->SetGameID( nGameID );
		UnofficialAchievements->SetGameID( nGameID );
		LocalAchievements->SetGameID( nGameID );

		Document doc;
		doc.ParseStream( FileStream( pFile ) );
		if( !doc.HasParseError() )
		{
			//ASSERT( doc["Success"].GetBool() );
			//const Value& PatchData = doc["PatchData"];
			const GameID nGameIDFetched = doc["ID"].GetUint();
			ASSERT( nGameIDFetched == nGameID );
			const std::string& sGameTitle = doc["Title"].GetString();
			const unsigned int nConsoleID = doc["ConsoleID"].GetUint();
			const std::string& sConsoleName = doc["ConsoleName"].GetString();
			const unsigned int nForumTopicID = doc["ForumTopicID"].GetUint();
			const unsigned int nGameFlags = doc["Flags"].GetUint();
			const std::string& sImageIcon = doc["ImageIcon"].GetString();
			const std::string& sImageTitle = doc["ImageTitle"].GetString();
			const std::string& sImageIngame = doc["ImageIngame"].GetString();
			const std::string& sImageBoxArt = doc["ImageBoxArt"].GetString();
			const std::string& sPublisher = doc["Publisher"].IsNull() ? "Unknown" : doc["Publisher"].GetString();
			const std::string& sDeveloper = doc["Developer"].IsNull() ? "Unknown" : doc["Developer"].GetString();
			const std::string& sGenre = doc["Genre"].IsNull() ? "Unknown" : doc["Genre"].GetString();
			const std::string& sReleased = doc["Released"].IsNull() ? "Unknown" : doc["Released"].GetString();
			const bool bIsFinal = doc["IsFinal"].GetBool();
			const std::string& sRichPresencePatch = doc["RichPresencePatch"].IsNull() ? "" : doc["RichPresencePatch"].GetString();
			
			//##SD store all this data somewhere? Do we want it?
			m_sPreferredGameTitle = sGameTitle;

			RA_RichPresenceInterpretter::PersistAndParseScript( nGameIDFetched, sRichPresencePatch );

			const Value& AchievementsData = doc["Achievements"];

			for( SizeType i = 0; i < AchievementsData.Size(); ++i )
			{
				//	Parse into correct boxes
				unsigned int nFlags = AchievementsData[i]["Flags"].GetUint();
				if( nFlags == 3 )
				{
					Achievement& newAch = CoreAchievements->AddAchievement();
					newAch.Parse( AchievementsData[i] );
				}
				else if( nFlags == 5 )
				{
					Achievement& newAch = UnofficialAchievements->AddAchievement();
					newAch.Parse( AchievementsData[i] );
				}
				else
				{
					RA_LOG( "Cannot deal with achievement with flags: %d\n", nFlags );
				}
			}
			
			const Value& LeaderboardsData = doc["Leaderboards"];
			
			for( SizeType i = 0; i < LeaderboardsData.Size(); ++i )
			{
				//"Leaderboards":[{"ID":"2","Mem":"STA:0xfe10=h0000_0xhf601=h0c_d0xhf601!=h0c_0xfff0=0_0xfffb=0::CAN:0xhfe13<d0xhfe13::SUB:0xf7cc!=0_d0xf7cc=0::VAL:0xhfe24*1_0xhfe25*60_0xhfe22*3600","Format":"TIME","Title":"Green Hill Act 1","Description":"Complete this act in the fastest time!"},
				
				RA_Leaderboard lb( LeaderboardsData[i]["ID"].GetUint() );
				lb.LoadFromJSON( LeaderboardsData[i] );

				g_LeaderboardManager.AddLeaderboard( lb );
			}
		}
		else
		{
			fclose( pFile );
			ASSERT( !"Could not parse file?!" );
			return FALSE;
		}

		fclose( pFile );
		
		unsigned int nTotalPoints = 0;
		for( size_t i = 0; i < CoreAchievements->NumAchievements(); ++i )
			nTotalPoints += CoreAchievements->GetAchievement( i ).Points();

		if( RAUsers::LocalUser().IsLoggedIn() )
		{	
			//	Loaded OK: post a request for unlocks
			PostArgs args;
			args['u'] = RAUsers::LocalUser().Username();
			args['t'] = RAUsers::LocalUser().Token();
			args['g'] = std::to_string( nGameID );
			args['h'] = g_bHardcoreModeActive ? "1" : "0";

			RAWeb::CreateThreadedHTTPRequest( RequestUnlocks, args );
			
			std::string sNumCoreAch = std::to_string( CoreAchievements->NumAchievements() );

			g_PopupWindows.AchievementPopups().AddMessage( 
				MessagePopup( "Loaded " + sNumCoreAch + " achievements, Total Score " + std::to_string( nTotalPoints ), "", PopupInfo ) );	//	TBD
		}

		return TRUE;
	}
	else
	{
		//	Cannot open file
		RA_LOG( "Cannot open file %s\n", sFilename.c_str() );
		return FALSE;
	}
}
Beispiel #10
0
BOOL AchievementSet::FetchFromWebBlocking( GameID nGameID )
{
	//	Can't open file: attempt to find it on SQL server!
	PostArgs args;
	args['u'] = RAUsers::LocalUser().Username();
	args['t'] = RAUsers::LocalUser().Token();
	args['g'] = std::to_string( nGameID );
	args['h'] = g_bHardcoreModeActive ? "1" : "0";

	Document doc;
	if( RAWeb::DoBlockingRequest( RequestPatch, args, doc ) && 
		doc.HasMember( "Success" ) && 
		doc[ "Success" ].GetBool() && 
		doc.HasMember( "PatchData" ) )
	{
		const Value& PatchData = doc[ "PatchData" ];

		//const std::string& sMinVer = PatchData["MinVer"].GetString();
		//const long nMinVerRequired = strtol( sMinVer.substr( 2 ).c_str(), NULL, 10 );
		
		//const long CURRENT_VER = strtol( std::string( g_sClientVersion ).substr( 2 ).c_str(), nullptr, 10 );
		//if( CURRENT_VER < nMinVerRequired )
		//{
		//	//	Client version too old!

		//	char buffer[4096];
		//	sprintf_s( buffer, 4096, 
		//		"Client version of 0.%03d is too old for the latest patch format.\r\n"
		//		"Version 0.%03d or greater required.\r\n"
		//		"Visit " RA_HOST " for a more recent version? ",
		//		CURRENT_VER,
		//		nMinVerRequired );

		//	if( MessageBox( nullptr, buffer, "Client out of date!", MB_YESNO ) == IDYES )
		//	{
		//		sprintf_s( buffer, 4096, "http://" RA_HOST "/download.php" );

		//		ShellExecute( NULL,
		//			"open",
		//			buffer,
		//			NULL,
		//			NULL,
		//			SW_SHOWNORMAL );
		//	}
		//	else
		//	{
		//		//MessageBox( nullptr, "Cannot load achievements for this game.", "Error", MB_OK );
		//	}

		//	return FALSE;
		//}
		//else
		{
			SetCurrentDirectory( Widen( g_sHomeDir ).c_str() );
			FILE* pf = nullptr;
			fopen_s( &pf, std::string( RA_DIR_DATA + std::to_string( nGameID ) + ".txt" ).c_str(), "wb" );
			if( pf != nullptr )
			{
				FileStream fs( pf );
				Writer<FileStream> writer( fs );
				PatchData.Accept( writer );
				fclose( pf );
				return TRUE;
			}
			else
			{
				ASSERT( !"Could not open patch file for writing?" );
				RA_LOG( "Could not open patch file for writing?" );
				return FALSE;
			}
		}
	}
	else
	{
		//	Could not connect...
		PopupWindows::AchievementPopups().AddMessage( 
			MessagePopup( "Could not connect to " RA_HOST_URL "...", "Working offline...", PopupInfo ) ); //?

		return FALSE;
	}
}