void ScreenArcadePatch::Update( float fDeltaTime ) { /* start the thread once the opening transition has finished. */ if( !m_Thread.IsCreated() && !this->IsTransitioning() ) m_Thread.Create( PatchThread_Start, this ); Screen::Update( fDeltaTime ); m_StateText.SetText( g_StateText ); m_PatchText.SetText( g_PatchText ); // nothing to do. if( m_State == m_LastUpdatedState ) return; m_LastUpdatedState = m_State; // update the HelpText switch( m_State ) { case PATCH_NONE: STATE_TEXT( "Please insert a USB card containing an update." ); PATCH_TEXT( THEME->GetMetric("ScreenArcadePatch","IntroText") ); case PATCH_CHECKING: m_textHelp->SetText( WAITING_HELP_TEXT ); break; case PATCH_ERROR: m_textHelp->SetText( ERROR_HELP_TEXT ); break; case PATCH_INSTALLED: m_textHelp->SetText( FINISHED_HELP_TEXT ); break; } }
static void UpdateProgress( unsigned long iCurrent, unsigned long iTotal ) { float fPercent = iCurrent / (iTotal/100); CString sProgress = ssprintf( "Copying patch (%.0f%%)\n\n" "Please do not remove the USB Card.", fPercent ); PATCH_TEXT( sProgress ); }
bool UpdateProgress( uint64_t iCurrent, uint64_t iTotal ) { float fPercent = iCurrent / (iTotal/100); CString sProgress = ssprintf( "Copying patch (%.0f%%)\n\n" "Please do not remove the USB Card.", fPercent ); PATCH_TEXT( sProgress ); return true; }
void ScreenArcadePatch::PatchMain() { m_State = PATCH_CHECKING; /* NOTE: we used to look for OpenITG prefixed updates also, but the * original ITG binary does not, so if we want people to be able to * upgrade directly from ITG to OITG, we have to continue to use the * "ITG 2 " prefix. Sad times. */ /* set up patterns to match */ CStringArray vsPatterns; vsPatterns.push_back( "ITG 2 *.itg" ); /* check to see if either player has patches */ PlayerNumber pn = PLAYER_INVALID; /* HasPatch() will early abort for us, due to the size() check, * if P1 and P2 both have patches. We just want the first one. */ FOREACH_PlayerNumber( p ) if( this->HasPatch(p, vsPatterns) ) pn = p; /* no matches on either card. */ if( pn == PLAYER_INVALID ) { m_State = PATCH_NONE; return; } /* set the help text to the patch name, blank the patch text */ m_textHelp->SetText( m_vsPatches[0] ); PATCH_TEXT( "" ); /* set up the key paths we want to verify against */ CStringArray vsRSAPaths; vsRSAPaths.push_back( "Data/Patch-OpenITG.rsa" ); vsRSAPaths.push_back( "Data/Patch.rsa" ); /* create the path for the patch file */ CString sPatchFile = m_sProfileDir + m_vsPatches[0]; // copy the patch file into memory // TODO: see if we can FILEMAN->GetFileDriver( "/@mem/" ). m_MemDriver = new RageFileDriverMem; int iError = 0; m_PatchFile = m_MemDriver->Open( ITG_TEMP_FILE, RageFile::WRITE, iError ); if( iError != 0 ) { STATE_TEXT( ssprintf("Failed to open temporary file:\n%s", strerror(iError)) ); m_State = PATCH_ERROR; } /* give up to an hour for the data to copy */ MEMCARDMAN->MountCard( pn, 3600 ); RageFile patch; if( !patch.Open(sPatchFile) ) { STATE_TEXT( ssprintf("Failed to open patch file (%s):\n%s", sPatchFile.c_str(), patch.GetError().c_str()) ); m_State = PATCH_ERROR; } if( m_State == PATCH_ERROR ) { MEMCARDMAN->UnmountCard(pn); return; } CString sError; if( FileCopy( patch, *m_PatchFile, sError, &UpdateProgress) ) { STATE_TEXT( "Patch copied! Checking..." ); PATCH_TEXT( "" ); } else { STATE_TEXT( ssprintf("Patch copying failed:\n" "%s", sError.c_str()) ); m_State = PATCH_ERROR; } MEMCARDMAN->UnmountCard( pn ); if( m_State == PATCH_ERROR ) return; /* re-open the patch file read-open. this should not fail. */ m_PatchFile = m_MemDriver->Open( ITG_TEMP_FILE, RageFile::READ, iError ); if( !this->VerifyPatch(m_PatchFile, vsRSAPaths) ) { PATCH_TEXT( "" ); m_State = PATCH_ERROR; return; } /* reset the error checker */ iError = 0; /* check the XML data */ CString sGame, sSuccessMessage; int iPatchRevision; /* open our new copy and read from it */ RageFileDriverZip *fZip = new RageFileDriverZip( m_PatchFile ); // we'll catch this in a bit, after we've freed our memory if( !this->GetXMLData(fZip, sGame, sSuccessMessage, iPatchRevision) ) m_State = PATCH_ERROR; SAFE_DELETE( fZip ); // if the XML get earlier failed, return now. if( m_State == PATCH_ERROR ) return; // accept patches for oITG or ITG2 if( sGame != "OpenITG" && sGame != "In The Groove 2" ) { sError = ssprintf( "revision is for another game\n" "(\"%s\")", sGame.c_str() ); STATE_TEXT( ssprintf("Cannot proceed: %s", sError.c_str()) ); m_State = PATCH_ERROR; return; } int iCurrentRevision = DiagnosticsUtil::GetRevision(); // HACK: allow any patch at all if it's revision 1. if( iCurrentRevision != 1 && iCurrentRevision == iPatchRevision ) { sError = ssprintf( "patch revision (%d) matches the machine revision.", iPatchRevision ); STATE_TEXT( ssprintf("Cannot proceed: %s", sError.c_str()) ); m_State = PATCH_ERROR; return; } /* wipe any unsucessful or unused patch data */ DeleteRecursive( TEMP_PATCH_DIR ); DeleteRecursive( FINAL_PATCH_DIR ); FILEMAN->CreateDir( TEMP_PATCH_DIR ); /* re-open the ZIP file now */ fZip = new RageFileDriverZip; if( !fZip->Load(m_PatchFile) ) { PATCH_TEXT( "Failed to re-open ZIP file!" ); m_State = PATCH_ERROR; return; } CStringArray vsDirs, vsFiles; vsDirs.push_back( "/" ); /* find all the files we're going to write with a recursive check */ while( vsDirs.size() ) { CString sDir = vsDirs.back(); vsDirs.pop_back(); fZip->GetDirListing( sDir + "/*", vsFiles, false, true ); fZip->GetDirListing( sDir + "/*", vsDirs, true, true ); } PATCH_TEXT( "Extracting files..." ); /* write them now */ for( unsigned i = 0; i < vsFiles.size(); i++ ) { const CString &sPath = vsFiles[i]; CString sCleanPath = sPath; TrimLeft( sCleanPath, "/" ); if( fZip->GetFileType(sPath) != RageFileManager::TYPE_FILE ) continue; LOG->Trace( "ScreenArcadePatch: copying file \"%s\"", sCleanPath.c_str() ); PATCH_TEXT( ssprintf("Extracting files...\n" "%s", sCleanPath.c_str()) ); RageFileBasic *fCopyFrom = fZip->Open( sPath, RageFile::READ, iError ); RageFile fCopyTo; fCopyTo.Open( TEMP_PATCH_DIR + sCleanPath, RageFile::WRITE ); if( !FileCopy(*fCopyFrom, fCopyTo) ) { PATCH_TEXT( ssprintf("Could not copy \"%s\":\n" "%s", sCleanPath.c_str(),sError.c_str()) ); m_State = PATCH_ERROR; SAFE_DELETE( fCopyFrom ); SAFE_DELETE( fZip ); return; } SAFE_DELETE( fCopyFrom ); fCopyTo.Close(); /* set CHMOD info */ #ifdef LINUX /* get the actual path to the files */ CString sRealPath = ResolveTempFilePath( sCleanPath ); const RageFileDriverZip::FileInfo *fi = fZip->GetFileInfo( sPath ); int ret = chmod( sRealPath.c_str(), fi->m_iFilePermissions ); LOG->Trace( "chmod( %s, %#o ) returned %i", sRealPath.c_str(), fi->m_iFilePermissions, ret ); #endif // LINUX } SAFE_DELETE( fZip ); /* clear the previous copying text */ STATE_TEXT( "Finalizing patch data..." ); PATCH_TEXT( "" ); #ifdef LINUX sync(); sleep(5); #endif /* we've successfully copied everything. now, move the directory and we're done. */ if( FILEMAN->Move(TEMP_PATCH_DIR, FINAL_PATCH_DIR) ) { STATE_TEXT( sSuccessMessage ); m_State = PATCH_INSTALLED; } else { STATE_TEXT( "Failed to finalize patch data!\nCheck your system permissions" ); m_State = PATCH_ERROR; } }