mirror of
https://gitea.msk.dinamika-avia.ru/Constanta-Design/RRJClient.git
synced 2026-03-28 05:25:39 +03:00
feat: fast hash checker
This commit is contained in:
@@ -1,6 +1,7 @@
|
|||||||
#include "UpdateController.h"
|
#include "UpdateController.h"
|
||||||
|
|
||||||
|
|
||||||
|
#include <QElapsedTimer>
|
||||||
#include <QThread>
|
#include <QThread>
|
||||||
|
|
||||||
UpdateController::UpdateController(QObject *parent) :
|
UpdateController::UpdateController(QObject *parent) :
|
||||||
@@ -15,23 +16,33 @@ void UpdateController::initialize(VersionContainer *versionContainer,DataParserO
|
|||||||
this->versionContainer = versionContainer;
|
this->versionContainer = versionContainer;
|
||||||
this->sendSystem = sendSystem;
|
this->sendSystem = sendSystem;
|
||||||
this->dataParserOut = dataParserOut;
|
this->dataParserOut = dataParserOut;
|
||||||
|
hashCalculator = new FastHashCalculator;
|
||||||
}
|
}
|
||||||
|
|
||||||
void UpdateController::calculateCommonHash()
|
void UpdateController::calculateCommonHash()
|
||||||
{
|
{
|
||||||
appDataList.clear();
|
appDataList.clear();
|
||||||
appDataList = calculateHash(applicationFolderPath,"StreamingAssets");
|
QElapsedTimer timer;
|
||||||
|
timer.start();
|
||||||
|
qDebug() << "Start calculate... ";
|
||||||
|
//appDataList = calculateHash(applicationFolderPath,"StreamingAssets");
|
||||||
|
hashCalculator->calculateHashes(applicationFolderPath,"StreamingAssets");
|
||||||
|
appDataList = *hashCalculator->getHashList();
|
||||||
calculateStreamingHash();
|
calculateStreamingHash();
|
||||||
appDataList.append(streamingDataList);
|
appDataList.append(streamingDataList);
|
||||||
|
qDebug() << "Hash count: " << appDataList.count() ;
|
||||||
dataParserOut->createFileDataList(appDataList,fullStaticDataFolderName + hashFilename);
|
dataParserOut->createFileDataList(appDataList,fullStaticDataFolderName + hashFilename);
|
||||||
qDebug() << "UpdateController threadID " << QThread::currentThreadId();
|
qDebug() << "UpdateController threadID " << QThread::currentThreadId();
|
||||||
|
qDebug() <<"Calculate time " << timer.elapsed();
|
||||||
}
|
}
|
||||||
|
|
||||||
void UpdateController::calculateStreamingHash()
|
void UpdateController::calculateStreamingHash()
|
||||||
{
|
{
|
||||||
streamingDataList.clear();
|
streamingDataList.clear();
|
||||||
streamingDataList = calculateHash(QDir::currentPath() + streamingAssetsPath,"");
|
//streamingDataList = calculateHash(QDir::currentPath() + streamingAssetsPath,"");
|
||||||
std::sort(streamingDataList.begin(),streamingDataList.end());
|
hashCalculator->calculateHashes(QDir::currentPath() + streamingAssetsPath,"");
|
||||||
|
streamingDataList = *hashCalculator->getHashList();
|
||||||
|
//std::sort(streamingDataList.begin(),streamingDataList.end());
|
||||||
dataParserOut->createFileDataList(streamingDataList,streamingHashFilename);
|
dataParserOut->createFileDataList(streamingDataList,streamingHashFilename);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -84,7 +95,7 @@ QList<FileData> UpdateController::calculateHash(const QString& path,const QStrin
|
|||||||
|
|
||||||
emit sigSendHashInfo(fullSize,Tools::convertFileSize(currentSize,false));
|
emit sigSendHashInfo(fullSize,Tools::convertFileSize(currentSize,false));
|
||||||
quint64 fileSize = file.size(); //буффер для хэширования крупных файлов
|
quint64 fileSize = file.size(); //буффер для хэширования крупных файлов
|
||||||
const quint64 bufferSize = 10240;
|
const quint64 bufferSize = 1024;
|
||||||
|
|
||||||
if(fileInfo.isHidden()) continue;
|
if(fileInfo.isHidden()) continue;
|
||||||
if(ignoreName != "" && fileInfo.path().contains(ignoreName)) continue;
|
if(ignoreName != "" && fileInfo.path().contains(ignoreName)) continue;
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
|
|
||||||
#include "Core/sendsystem.h"
|
#include "Core/sendsystem.h"
|
||||||
#include "Core/versioncontainer.h"
|
#include "Core/versioncontainer.h"
|
||||||
|
#include "fasthashcalculator.h"
|
||||||
#include <QXmlStreamWriter>
|
#include <QXmlStreamWriter>
|
||||||
#include <QXmlStreamReader>
|
#include <QXmlStreamReader>
|
||||||
#include <QXmlStreamAttribute>
|
#include <QXmlStreamAttribute>
|
||||||
@@ -40,6 +41,7 @@ signals:
|
|||||||
private:
|
private:
|
||||||
SendSystem *sendSystem;
|
SendSystem *sendSystem;
|
||||||
DataParserOutput * dataParserOut;
|
DataParserOutput * dataParserOut;
|
||||||
|
FastHashCalculator* hashCalculator;
|
||||||
QString applicationFolderPath;
|
QString applicationFolderPath;
|
||||||
VersionContainer *versionContainer;
|
VersionContainer *versionContainer;
|
||||||
QList<FileData> appDataList;
|
QList<FileData> appDataList;
|
||||||
|
|||||||
98
Core/fasthashcalculator.cpp
Normal file
98
Core/fasthashcalculator.cpp
Normal file
@@ -0,0 +1,98 @@
|
|||||||
|
#include "fasthashcalculator.h"
|
||||||
|
#include <QtConcurrent>
|
||||||
|
|
||||||
|
|
||||||
|
FastHashCalculator::FastHashCalculator(QObject *parent) : QObject(parent)
|
||||||
|
{
|
||||||
|
hashList = new QList<FileData>();
|
||||||
|
}
|
||||||
|
void FastHashCalculator::calculateHashes(const QString& path, const QString& ignoreName)
|
||||||
|
{
|
||||||
|
hashList->clear();
|
||||||
|
|
||||||
|
if(!QDir(path).exists()){
|
||||||
|
QDir().mkdir(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
QString hashString;
|
||||||
|
QStringList filter;
|
||||||
|
filter << "*";
|
||||||
|
QList<FileData> *folders = new QList<FileData>;
|
||||||
|
//QString fullSize = Tools::convertFileSize(getDirectorySize(path),false);
|
||||||
|
|
||||||
|
QDirIterator dirIterator(path,filter, QDir::AllEntries, QDirIterator::Subdirectories);
|
||||||
|
|
||||||
|
while (dirIterator.hasNext())
|
||||||
|
{
|
||||||
|
QFileInfo fileInfo(dirIterator.next());
|
||||||
|
FileData currentFolder;
|
||||||
|
if(fileInfo.isDir() && !fileInfo.fileName().startsWith(".") && fileInfo.fileName() != "RRJLoader")
|
||||||
|
{
|
||||||
|
currentFolder.path = Tools::createLocalPath(fileInfo.absoluteFilePath());
|
||||||
|
currentFolder.hash = "FOLDER";
|
||||||
|
|
||||||
|
if(!folders->contains(currentFolder))
|
||||||
|
{
|
||||||
|
folders->push_back(currentFolder);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
QDirIterator fileIterator(path,filter,QDir::Files | QDir::NoDotAndDotDot,QDirIterator::Subdirectories);
|
||||||
|
|
||||||
|
QList<QString> files;
|
||||||
|
files.clear();
|
||||||
|
|
||||||
|
while(fileIterator.hasNext())
|
||||||
|
{
|
||||||
|
fileIterator.next();
|
||||||
|
QFileInfo fileInfo = fileIterator.fileInfo();
|
||||||
|
QString path = fileInfo.absoluteFilePath();
|
||||||
|
|
||||||
|
if (fileInfo.isHidden()) continue;
|
||||||
|
if (!fileInfo.isFile()) continue;
|
||||||
|
if (fileInfo.fileName().contains(".meta")) continue;
|
||||||
|
if (ignoreName != "" && fileInfo.path().contains(ignoreName)) continue;
|
||||||
|
|
||||||
|
files.append(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
QtConcurrent::map(files, [this](const QString &filePath)
|
||||||
|
{
|
||||||
|
QByteArray hash = calculateFileHashOptimized(filePath);
|
||||||
|
QMutexLocker locker(&_mutex);
|
||||||
|
FileData currentFile;
|
||||||
|
QString hashName;
|
||||||
|
|
||||||
|
currentFile.path = Tools::createLocalPath(filePath);
|
||||||
|
currentFile.hash = hash.toHex();
|
||||||
|
hashList->append(currentFile);
|
||||||
|
}).waitForFinished();
|
||||||
|
|
||||||
|
hashList->append(*folders);
|
||||||
|
emit finished();
|
||||||
|
}
|
||||||
|
|
||||||
|
QByteArray FastHashCalculator::calculateFileHashOptimized(const QString &filePath)
|
||||||
|
{
|
||||||
|
QFile file(filePath);
|
||||||
|
if (!file.open(QIODevice::ReadOnly)) return QByteArray();
|
||||||
|
|
||||||
|
QCryptographicHash hash(QCryptographicHash::Md5);
|
||||||
|
const qint64 bufferSize = 2 * 1024; // 2MB
|
||||||
|
QByteArray buffer;
|
||||||
|
buffer.resize(bufferSize);
|
||||||
|
|
||||||
|
while (!file.atEnd()) {
|
||||||
|
qint64 bytesRead = file.read(buffer.data(), bufferSize);
|
||||||
|
hash.addData(buffer.constData(), bytesRead);
|
||||||
|
}
|
||||||
|
|
||||||
|
return hash.result();
|
||||||
|
}
|
||||||
|
|
||||||
|
QList<FileData> *FastHashCalculator::getHashList() const
|
||||||
|
{
|
||||||
|
return hashList;
|
||||||
|
}
|
||||||
34
Core/fasthashcalculator.h
Normal file
34
Core/fasthashcalculator.h
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
#ifndef FASTHASHCALCULATOR_H
|
||||||
|
#define FASTHASHCALCULATOR_H
|
||||||
|
|
||||||
|
#include <QHash>
|
||||||
|
#include <QMutex>
|
||||||
|
#include <QObject>
|
||||||
|
#include <QFile>
|
||||||
|
#include <QDirIterator>
|
||||||
|
#include <Data/FileData.h>
|
||||||
|
#include "tools.h"
|
||||||
|
|
||||||
|
|
||||||
|
class FastHashCalculator : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
explicit FastHashCalculator(QObject *parent = nullptr);
|
||||||
|
void calculateHashes(const QString& path, const QString& ignoreName);
|
||||||
|
QList<FileData> *getHashList() const;
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void finished();
|
||||||
|
|
||||||
|
private:
|
||||||
|
QByteArray calculateFileHashOptimized(const QString &filePath);
|
||||||
|
void calculateSingleHash(const QString &filePath);
|
||||||
|
|
||||||
|
QList<FileData>* hashList;
|
||||||
|
QMutex _mutex;
|
||||||
|
quint64 currentSize;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // FASTHASHCALCULATOR_H
|
||||||
@@ -47,7 +47,6 @@ void TCPClient::setConnect(ServerSettings *serverSettings)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void TCPClient::setDisconnect()
|
void TCPClient::setDisconnect()
|
||||||
{
|
{
|
||||||
socket->disconnect();
|
socket->disconnect();
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ public:
|
|||||||
void initialize(RecognizeSystem *recognize,SendSystem *sendSystem);
|
void initialize(RecognizeSystem *recognize,SendSystem *sendSystem);
|
||||||
void setConnect(ServerSettings *serverSettings);
|
void setConnect(ServerSettings *serverSettings);
|
||||||
~TCPClient(){};
|
~TCPClient(){};
|
||||||
|
void setDisconnect();
|
||||||
bool getIsConnected() const;
|
bool getIsConnected() const;
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
@@ -43,8 +43,6 @@ private:
|
|||||||
QTcpSocket *socket;
|
QTcpSocket *socket;
|
||||||
RecognizeSystem *recognizeSystem;
|
RecognizeSystem *recognizeSystem;
|
||||||
bool isConnected;
|
bool isConnected;
|
||||||
|
|
||||||
void setDisconnect();
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // TCPCLIENT_H
|
#endif // TCPCLIENT_H
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
QT += core gui
|
QT += core gui
|
||||||
QT += network
|
QT += network
|
||||||
QT += xml
|
QT += xml
|
||||||
QT += testlib
|
QT += concurrent
|
||||||
|
|
||||||
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
|
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
|
||||||
CONFIG += c++11
|
CONFIG += c++11
|
||||||
@@ -18,6 +18,7 @@ DEFINES += QT_DEPRECATED_WARNINGS
|
|||||||
|
|
||||||
SOURCES += \
|
SOURCES += \
|
||||||
Core/dataparseroutput.cpp \
|
Core/dataparseroutput.cpp \
|
||||||
|
Core/fasthashcalculator.cpp \
|
||||||
Core/notifycontroller.cpp \
|
Core/notifycontroller.cpp \
|
||||||
Core/postprocessorsystem.cpp \
|
Core/postprocessorsystem.cpp \
|
||||||
Core/sendsystem.cpp \
|
Core/sendsystem.cpp \
|
||||||
@@ -45,6 +46,7 @@ SOURCES += \
|
|||||||
|
|
||||||
HEADERS += \
|
HEADERS += \
|
||||||
Core/dataparseroutput.h \
|
Core/dataparseroutput.h \
|
||||||
|
Core/fasthashcalculator.h \
|
||||||
Core/notifycontroller.h \
|
Core/notifycontroller.h \
|
||||||
Core/postprocessorsystem.h \
|
Core/postprocessorsystem.h \
|
||||||
Core/versioncontainer.h \
|
Core/versioncontainer.h \
|
||||||
|
|||||||
@@ -1,2 +1,2 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<AuthData Login="O1" Password="1111" InstructorName="" ClientName="Коровин А.В." AccessType="trainee"/>
|
<AuthData Login="O5" Password="5555" InstructorName="" ClientName="Синицин И.И." AccessType="trainee"/>
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -1,5 +1,5 @@
|
|||||||
<?xml version='1.0' encoding='UTF-8'?>
|
<?xml version='1.0' encoding='UTF-8'?>
|
||||||
<ServerSettingsContainer>
|
<ServerSettingsContainer>
|
||||||
<ServerSettings Port="6000" LocalPortMath="18004" AutoStart="0" Language="RUS" DestPortMath="18003" UseMathModel="1" Address="192.168.100.134"/>
|
<ServerSettings Address="192.168.100.83" Port="6000" UseMathModel="1" AutoStart="0" DestPortMath="18003" Language="RUS" LocalPortMath="18004"/>
|
||||||
<VersionData Created="Вт авг 19 11:09:28 2025" isChangable="0" Version="base"/>
|
<VersionData Version="base" Created="Ср авг 20 17:12:35 2025" isChangable="0"/>
|
||||||
</ServerSettingsContainer>
|
</ServerSettingsContainer>
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -1,2 +1,2 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<ClientNotify Code="DISABLE"/>
|
<ClientAutorization Login="O5" Password="5555"/>
|
||||||
|
|||||||
@@ -351,15 +351,14 @@ void CoreManager::saveServerSettingsWithConnect()
|
|||||||
|
|
||||||
if(client->getIsConnected())
|
if(client->getIsConnected())
|
||||||
{
|
{
|
||||||
|
client->setDisconnect();
|
||||||
entryWidget->showLoginWidget(true);
|
entryWidget->showLoginWidget(true);
|
||||||
widgetManager->getMainWindow()->showOfflineButton(true);
|
widgetManager->getMainWindow()->showOfflineButton(true);
|
||||||
widgetManager->activateLoadingAnimation(false);
|
widgetManager->activateLoadingAnimation(false);
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
emit sigSetConnect(settings);
|
emit sigSetConnect(settings);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
void CoreManager::checkAppAvailable()
|
void CoreManager::checkAppAvailable()
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user