Changed: Allow to use a readable and writable data path for IG patch (usefull when data are read only)

This commit is contained in:
kervala 2015-01-11 15:06:02 +01:00
parent c90a3049c4
commit 9891de01ce
2 changed files with 82 additions and 30 deletions

View file

@ -207,9 +207,23 @@ CPatchManager::CPatchManager() : State("t_state"), DataScanState("t_data_scan_st
// ****************************************************************************
void CPatchManager::setClientRootPath(const std::string& clientRootPath)
{
ClientRootPath = clientRootPath;
ClientPatchPath = ClientRootPath + "unpack/";
ClientDataPath = ClientRootPath + "data/";
ClientRootPath = CPath::standardizePath(clientRootPath);
ClientPatchPath = CPath::standardizePath(ClientRootPath + "unpack");
ReadableClientDataPath = CPath::standardizePath(ClientRootPath + "data");
std::string writableTest = ReadableClientDataPath + "writableTest";
// if succeeded to create a delete a temporary file in data directory
if (CFile::createEmptyFile(writableTest) && CFile::deleteFile(writableTest))
{
// use it to patch data files
WritableClientDataPath = ReadableClientDataPath;
}
else
{
// use system user profile to patch data files
WritableClientDataPath = CPath::standardizePath(CPath::getApplicationDirectory("Ryzom") + "data");
}
}
// ****************************************************************************
@ -253,7 +267,7 @@ void CPatchManager::init(const std::vector<std::string>& patchURIs, const std::s
DisplayedServerPath = ServerPath;
NLMISC::CFile::createDirectory(ClientPatchPath);
NLMISC::CFile::createDirectory(ClientDataPath);
NLMISC::CFile::createDirectory(WritableClientDataPath);
// try to read the version file from the server (that will replace the version number)
@ -787,7 +801,7 @@ void CPatchManager::createBatchFile(CProductDescriptionForClient &descFile, bool
if (!result)
{
//:TODO: handle exception?
// TODO: handle exception?
string err = toString("Error unpacking %s", rFilename.c_str());
if (useBatchFile)
@ -913,7 +927,6 @@ void CPatchManager::createBatchFile(CProductDescriptionForClient &descFile, bool
throw NLMISC::EWriteError(UpdateBatchFilename.c_str());
}
}
}
// ****************************************************************************
@ -1616,9 +1629,25 @@ void CPatchManager::getPatchFromDesc(SFileToPatch &ftpOut, const CBNPFile &fIn,
// Only look in data path if the file should not be unpack (otherwise it should only remains in the "unpack" directory)
if (!needUnpack)
{
if (sFilePath.empty() && NLMISC::CFile::fileExists(ClientDataPath + rFilename)) sFilePath = ClientDataPath + rFilename;
if (sFilePath.empty())
{
if (NLMISC::CFile::fileExists(WritableClientDataPath + rFilename))
{
// if file exists in writable directory, use it
sFilePath = WritableClientDataPath + rFilename;
}
else if (NLMISC::CFile::fileExists(ReadableClientDataPath + rFilename))
{
// if file exists in readable directory, use it
sFilePath = ReadableClientDataPath + rFilename;
}
}
}
if (sFilePath.empty() && NLMISC::CFile::fileExists(ClientPatchPath + rFilename))
{
sFilePath = ClientPatchPath + rFilename;
}
if (sFilePath.empty() && NLMISC::CFile::fileExists(ClientPatchPath + rFilename)) sFilePath = ClientPatchPath + rFilename;
// following lines removed by Sadge to ensure that the correct file is patched
// string sFilePath = CPath::lookup(rFilename, false, false);
@ -2039,7 +2068,8 @@ uint CPatchManager::applyScanDataResult()
if(ScanDataThread)
return 0;
uint numError= 0;
uint numError= 0;
{
TSyncDataScanState::CAccessor ac(&DataScanState);
CDataScanState &val= ac.value();
@ -2057,7 +2087,8 @@ uint CPatchManager::applyScanDataResult()
// get file path
// following lines added by Sadge to ensure that the correct file gets patched
string sFilePath;
if (NLMISC::CFile::fileExists(ClientDataPath + ftp.FileName)) sFilePath = ClientDataPath + ftp.FileName;
if (NLMISC::CFile::fileExists(WritableClientDataPath + ftp.FileName)) sFilePath = WritableClientDataPath + ftp.FileName;
if (sFilePath.empty() && NLMISC::CFile::fileExists(ReadableClientDataPath + ftp.FileName)) sFilePath = ReadableClientDataPath + ftp.FileName;
if (sFilePath.empty() && NLMISC::CFile::fileExists(ClientPatchPath + ftp.FileName)) sFilePath = ClientPatchPath + ftp.FileName;
// following lines removed by Sadge to ensure that the correct file gets patched
@ -2768,15 +2799,31 @@ public:
void CPatchThread::processFile (CPatchManager::SFileToPatch &rFTP)
{
CPatchManager *pPM = CPatchManager::getInstance();
// Source File Name
// Source File Name (in writable or readable directory)
string SourceName;
// Destination File Name (in writable directory)
string DestinationName;
if (rFTP.ExtractPath.empty())
{
DestinationName = pPM->WritableClientDataPath + rFTP.FileName;
if (rFTP.LocalFileExists)
{
// following lines added by Sadge to ensure that the correct file gets patched
SourceName.clear();
if (NLMISC::CFile::fileExists(pPM->ClientDataPath + rFTP.FileName)) SourceName = pPM->ClientDataPath + rFTP.FileName;
if (NLMISC::CFile::fileExists(pPM->WritableClientDataPath + rFTP.FileName))
{
SourceName = pPM->WritableClientDataPath + rFTP.FileName;
}
else if (NLMISC::CFile::fileExists(pPM->ReadableClientDataPath + rFTP.FileName))
{
SourceName = pPM->ReadableClientDataPath + rFTP.FileName;
}
// version from previous download
if (SourceName.empty()) throw Exception (std::string("ERROR: Failed to find file: ")+rFTP.FileName);
@ -2788,12 +2835,13 @@ void CPatchThread::processFile (CPatchManager::SFileToPatch &rFTP)
// note : if file was background downloaded, we have :
// rFTP.LocalFileExists = false
// rFTP.SrcFileName = "unpack/filename.bnp.tmp"
SourceName = pPM->ClientDataPath + rFTP.FileName;
SourceName = DestinationName;
}
}
else
{
SourceName = pPM->ClientPatchPath + rFTP.FileName;
DestinationName = SourceName;
}
if (rFTP.LocalFileToDelete)
@ -2838,7 +2886,7 @@ void CPatchThread::processFile (CPatchManager::SFileToPatch &rFTP)
for (uint i=0; i<rFTP.PatcheSizes.size(); ++i)
totalPatchSize += rFTP.PatcheSizes[i];
}
else
else if (!rFTP.PatcheSizes.empty())
{
totalPatchSize = rFTP.PatcheSizes.back();
}
@ -2930,11 +2978,11 @@ void CPatchThread::processFile (CPatchManager::SFileToPatch &rFTP)
pPM->deleteFile(SourceName, false, false); // File can exists if bad BNP loading
if (_CommitPatch)
{
pPM->renameFile(OutFilename+".tmp", SourceName);
pPM->renameFile(OutFilename+".tmp", DestinationName);
}
}
}
if (usePatchFile && !rFTP.Patches.empty())
if (usePatchFile)
{
uint32 currentPatchedSize = 0;
for (uint32 j = 0; j < rFTP.Patches.size(); ++j)
@ -2987,21 +3035,14 @@ void CPatchThread::processFile (CPatchManager::SFileToPatch &rFTP)
SourceNameXD = SourceNameXD.substr(0, SourceNameXD.rfind('.'));
SourceNameXD += "_.ref";
std::string refPath;
if (_CommitPatch)
{
refPath = pPM->ClientDataPath;
}
else
if (!_CommitPatch)
{
// works
refPath = pPM->ClientPatchPath;
std::string tmpRefFile = SourceNameXD + ".tmp";
if (!NLMISC::CFile::fileExists(pPM->ClientPatchPath + tmpRefFile))
{
// Not found in the patch directory -> version in data directory should be good, or would have been
// detected by the check thread else.
refPath = pPM->ClientDataPath;
}
else
{
@ -3018,7 +3059,14 @@ void CPatchThread::processFile (CPatchManager::SFileToPatch &rFTP)
// if (SourceNameXDFull.empty())
// SourceNameXDFull = pPM->ClientDataPath + SourceNameXD;
// SourceNameXD = SourceNameXDFull;
SourceNameXD = pPM->ClientDataPath + SourceNameXD;
if (CFile::fileExists(pPM->WritableClientDataPath + SourceNameXD))
{
SourceNameXD = pPM->WritableClientDataPath + SourceNameXD;
}
else if (CFile::fileExists(pPM->ReadableClientDataPath + SourceNameXD))
{
SourceNameXD = pPM->ReadableClientDataPath + SourceNameXD;
}
}
PatchName = pPM->ClientPatchPath + PatchName;
@ -3042,7 +3090,8 @@ void CPatchThread::processFile (CPatchManager::SFileToPatch &rFTP)
PatchSizeProgress += rFTP.PatcheSizes[j];
currentPatchedSize += rFTP.PatcheSizes[j];
}
if (tmpSourceName != SourceName)
if (tmpSourceName != DestinationName)
{
pPM->deleteFile(SourceName, false, false); // File can exists if bad BNP loading
if (!_CommitPatch)
@ -3052,7 +3101,7 @@ void CPatchThread::processFile (CPatchManager::SFileToPatch &rFTP)
}
else
{
pPM->renameFile(tmpSourceName, SourceName);
pPM->renameFile(tmpSourceName, DestinationName);
}
}
}
@ -3060,9 +3109,10 @@ void CPatchThread::processFile (CPatchManager::SFileToPatch &rFTP)
{
PatchSizeProgress += totalPatchSize;
}
// If all patches applied with success so file size should be ok
// We just have to change file date to match the last patch applied
pPM->applyDate(SourceName, rFTP.LastFileDate);
pPM->applyDate(DestinationName, rFTP.LastFileDate);
//progress.progress(1.f);
}
@ -3413,6 +3463,7 @@ bool CPatchManager::extract(const std::string& patchPath,
string err = toString("Can't open file '%s' for writing: code=%d %s (error code 29)", updateBatchFilename.c_str(), errno, strerror(errno));
throw Exception (err);
}
fprintf(fp, "@echo off\n");
fprintf(fp, "ping 127.0.0.1 -n 7 -w 1000 > nul\n"); // wait

View file

@ -447,8 +447,9 @@ private:
std::string UpdateBatchFilename;
// Where the client get all delta and desc file
std::string ClientPatchPath;
std::string ClientDataPath;
std::string ClientPatchPath; // Temporary path
std::string ReadableClientDataPath; // Where original data can be found
std::string WritableClientDataPath; // Where data can be written
/// Output useful information for debugging in the log file
bool VerboseLog;