Files
RRJClient/Core/UpdateController.cpp
2025-09-23 10:20:17 +03:00

171 lines
5.1 KiB
C++

#include "UpdateController.h"
#include <QElapsedTimer>
#include <QThread>
UpdateController::UpdateController(QObject *parent) :
QObject(parent),
versionContainer(nullptr)
{
applicationFolderPath = QDir::currentPath() + applicationFolderName;
hashCalculator = new FastHashCalculator;
}
void UpdateController::initialize(VersionContainer *versionContainer,DataParserOutput *dataParserOut, SendSystem *sendSystem)
{
this->versionContainer = versionContainer;
this->sendSystem = sendSystem;
this->dataParserOut = dataParserOut;
}
void UpdateController::calculateCommonHash()
{
appDataList.clear();
QElapsedTimer timer;
timer.start();
qDebug() << "Start calculate... ";
//appDataList = calculateHash(applicationFolderPath,"StreamingAssets");
hashCalculator->calculateHashes(applicationFolderPath,"StreamingAssets");
appDataList = *hashCalculator->getHashList();
calculateStreamingHash();
appDataList.append(streamingDataList);
qDebug() << "Hash count: " << appDataList.count() ;
dataParserOut->createFileDataList(appDataList,fullStaticDataFolderName + hashFilename);
qDebug() << "UpdateController threadID " << QThread::currentThreadId();
qDebug() <<"Calculate time " << timer.elapsed();
}
void UpdateController::calculateStreamingHash()
{
streamingDataList.clear();
//streamingDataList = calculateHash(QDir::currentPath() + streamingAssetsPath,"");
hashCalculator->calculateHashes(QDir::currentPath() + streamingAssetsPath,"");
streamingDataList = *hashCalculator->getHashList();
//std::sort(streamingDataList.begin(),streamingDataList.end());
dataParserOut->createFileDataList(streamingDataList,streamingHashFilename);
}
QList<FileData> UpdateController::calculateHash(const QString& path,const QString& ignoreName)
{
qDebug() << "Try calculate";
if(!QDir(path).exists())
{
QDir().mkdir(path);
}
QList<FileData> *hashes = new QList<FileData>;
quint64 currentSize = 0;
QStringList filter;
filter << "*";
QString hashString;
QDirIterator dirIterator(path,filter, QDir::AllEntries | QDir::NoDotAndDotDot, QDirIterator::Subdirectories);
while (dirIterator.hasNext())
{
QFileInfo fileInfo(dirIterator.next());
FileData currentFile;
QString fileName = fileInfo.fileName();
if(fileInfo.isDir() && !fileName.startsWith(".") && fileName != "RRJLoader")
{
currentFile.path = Tools::createLocalPath(fileInfo.absoluteFilePath());
currentFile.hash = "FOLDER";
if(!hashes->contains(currentFile))
{
hashes->push_back(currentFile);
}
}
}
QDirIterator fileIterator(path,filter,QDir::Files | QDir::NoDotAndDotDot,QDirIterator::Subdirectories);
while (fileIterator.hasNext())
{
fileIterator.next();
QFileInfo fileInfo = fileIterator.fileInfo();
FileData currentFile;
QFile file(fileInfo.absoluteFilePath());
currentSize += fileInfo.size();
quint64 fileSize = file.size(); //буффер для хэширования крупных файлов
const quint64 bufferSize = 1024;
if(fileInfo.isHidden()) continue;
if(ignoreName != "" && fileInfo.path().contains(ignoreName)) continue;
if(fileInfo.isFile() && file.open(QIODevice::ReadOnly))
{
char buffer[bufferSize];
int bytesRead;
int readSize = qMin(fileSize,bufferSize);
QCryptographicHash hash(QCryptographicHash::Md5);
while(readSize > 0 && (bytesRead = file.read(buffer,readSize)) > 0)
{
fileSize -= bytesRead;
hash.addData(buffer,bytesRead);
readSize = qMin(fileSize,bufferSize);
}
hashString = QString(hash.result().toHex());
currentFile.path = Tools::createLocalPath(fileInfo.absoluteFilePath());
currentFile.hash = hashString;
hashes->push_back(currentFile);
file.close();
}
}
return *hashes;
}
void UpdateController::updateFilesOnServer(QList<FileData> *fileSendList){
QListIterator<FileData> serverIterator(*fileSendList);
try {
while(serverIterator.hasNext())
{
FileData data = serverIterator.next();
if (data.hash == "FOLDER")
{
sendSystem->sendFolderBlock(data.path);
}
else
{
QString fullPath = Tools::createReceiveFullPath(data.path,versionContainer->getServerVersionData());
sendSystem->sendFileBlockWithVersion(fullPath,data.path);
}
}
calculateCommonHash();
sendSystem->sendFinish();
emit sigUpdateComplete(true);
}
catch (...)
{
emit sigUpdateComplete(false);
}
}
FastHashCalculator *UpdateController::getHashCalculator() const
{
return hashCalculator;
}
UpdateController::~UpdateController()
{
}