1
0
mirror of https://github.com/vcmi/vcmi.git synced 2024-12-22 22:13:35 +02:00

code review

This commit is contained in:
Laserlicht 2024-12-02 20:29:17 +01:00
parent 0141522a60
commit 4fb1e9b056
4 changed files with 46 additions and 40 deletions

View File

@ -391,7 +391,7 @@ void FirstLaunchView::extractGogData()
QString hashError;
if(!errorText.isEmpty())
hashError = Innoextract::getHashError(tmpFileExe, tmpFileBin);
hashError = Innoextract::getHashError(tmpFileExe, tmpFileBin, fileExe, fileBin);
ui->progressBarGog->setVisible(false);
ui->pushButtonGogInstall->setVisible(true);

View File

@ -61,7 +61,7 @@ QString Innoextract::extract(QString installer, QString outDir, std::function<vo
return errorText;
}
QString Innoextract::getHashError(QString exeFile, QString binFile)
QString Innoextract::getHashError(QString exeFile, QString binFile, QString exeFileOriginal, QString binFileOriginal)
{
enum filetype
{
@ -77,6 +77,11 @@ QString Innoextract::getHashError(QString exeFile, QString binFile)
std::string bin;
};
struct fileinfo {
std::string hash;
int size = 0;
};
std::vector<data> knownHashes = {
{ H3_COMPLETE, "english", 822520, 1005040617, "66646a353b06417fa12c6384405688c84a315cc1", "c624e2071f4e35386765ab044ad5860ac245b7f4" }, // setup_heroes_of_might_and_magic_3_complete_4.0_(28740).exe
{ H3_COMPLETE, "french", 824960, 997305870, "072f1d4466ff16444d8c7949c6530448a9c53cfa", "9b6b451d2bd2f8b4be159e62fa6d32e87ee10455" }, // setup_heroes_of_might_and_magic_3_complete_4.0_(french)_(28740).exe
@ -96,63 +101,64 @@ QString Innoextract::getHashError(QString exeFile, QString binFile)
{ CHR, "english", 462976008, 0, "9039050e88b9dabcdb3ffa74b33e6aa86a20b7d9", "" }, // setup_heroes_chronicles_chapter8_2.1.0.42.exe
};
std::string exeHash;
std::string binHash;
int exeSize = 0;
int binSize = 0;
auto doHash = [](QFile f){
fileinfo tmp;
auto exe = QFile(exeFile);
if(exe.open(QFile::ReadOnly)) {
QCryptographicHash hash(QCryptographicHash::Algorithm::Sha1);
if(hash.addData(&exe))
exeHash = hash.result().toHex().toLower().toStdString();
else
return QString{}; // error with hashing
exeSize = exe.size();
}
else
return QString{}; // reading problem
if(!binFile.isEmpty())
{
auto bin = QFile(binFile);
if(bin.open(QFile::ReadOnly)) {
if(f.open(QFile::ReadOnly)) {
QCryptographicHash hash(QCryptographicHash::Algorithm::Sha1);
if(hash.addData(&bin))
binHash = hash.result().toHex().toLower().toStdString();
else
return QString{}; // error with hashing
binSize = bin.size();
if(hash.addData(&f))
tmp.hash = hash.result().toHex().toLower().toStdString();
tmp.size = f.size();
}
else
return QString{}; // reading problem
}
QString hashOutput = tr("SHA1 hash of provided files:\n") + tr("Exe") + " (" + QString::number(exeSize) + " " + tr("bytes") + ")" + ":\n" + QString::fromStdString(exeHash);
if(!binHash.empty())
hashOutput += "\n" + tr("Bin") + " (" + QString::number(binSize) + " " + tr("bytes") + ")" + ":\n" + QString::fromStdString(binHash);
return tmp;
};
fileinfo exeInfo;
fileinfo binInfo;
fileinfo exeInfoOriginal;
fileinfo binInfoOriginal;
exeInfo = doHash(QFile(exeFile));
if(!binFile.isEmpty())
binInfo = doHash(QFile(binFile));
exeInfoOriginal = doHash(QFile(exeFileOriginal));
if(!binFileOriginal.isEmpty())
binInfoOriginal = doHash(QFile(binFileOriginal));
if(exeInfo.hash.empty() || (!binFile.isEmpty() && binInfo.hash.empty()))
return QString{}; // hashing not possible -> previous error is enough
QString hashOutput = tr("SHA1 hash of provided files:\nExe (%1 bytes):\n%2").arg(QString::number(exeInfo.size), QString::fromStdString(exeInfo.hash));
if(!binInfo.hash.empty())
hashOutput += tr("\nBin (%1 bytes):\n%2").arg(QString::number(binInfo.size), QString::fromStdString(binInfo.hash));
if((!exeInfoOriginal.hash.empty() && exeInfo.hash != exeInfoOriginal.hash) || (!binInfoOriginal.hash.empty() && !binFile.isEmpty() && !binFileOriginal.isEmpty() && binInfo.hash != binInfoOriginal.hash))
return tr("Internal copy process failed. Enough space on device?\n\n%1").arg(hashOutput);
QString foundKnown;
QString exeLang;
QString binLang;
auto find = [exeHash, binHash](const data & d) { return (!d.exe.empty() && d.exe == exeHash) || (!d.bin.empty() && d.bin == binHash);};
auto find = [exeInfo, binInfo](const data & d) { return (!d.exe.empty() && d.exe == exeInfo.hash) || (!d.bin.empty() && d.bin == binInfo.hash);};
auto it = std::find_if(knownHashes.begin(), knownHashes.end(), find);
while(it != knownHashes.end()){
auto lang = QString::fromStdString((*it).language);
foundKnown += (exeHash == (*it).exe ? tr("Exe") : tr("Bin")) + " - " + lang + "\n";
if(exeHash == (*it).exe)
foundKnown += "\n" + (exeInfo.hash == (*it).exe ? tr("Exe") : tr("Bin")) + " - " + lang;
if(exeInfo.hash == (*it).exe)
exeLang = lang;
else
binLang = lang;
it = std::find_if(++it, knownHashes.end(), find);
}
if(!exeLang.isEmpty() && !binLang.isEmpty() && exeLang != binLang && !binFile.isEmpty())
return tr("Language mismatch!\n\n") + foundKnown + "\n\n" + hashOutput;
return tr("Language mismatch!\n%1\n\n%2").arg(foundKnown, hashOutput);
else if((!exeLang.isEmpty() || !binLang.isEmpty()) && !binFile.isEmpty())
return tr("Only one file known! Maybe files are corrupted? Please download again.\n\n") + foundKnown + "\n\n" + hashOutput;
return tr("Only one file known! Maybe files are corrupted? Please download again.\n%1\n\n%2").arg(foundKnown, hashOutput);
else if(!exeLang.isEmpty() && binFile.isEmpty())
return QString{};
else if(!exeLang.isEmpty() && !binFile.isEmpty() && exeLang == binLang)
return QString{};
return tr("Unknown files! Maybe files are corrupted? Please download again.\n\n") + hashOutput;
return tr("Unknown files! Maybe files are corrupted? Please download again.\n\n%1").arg(hashOutput);
}

View File

@ -13,5 +13,5 @@ class Innoextract : public QObject
{
public:
static QString extract(QString installer, QString outDir, std::function<void (float percent)> cb = nullptr);
static QString getHashError(QString exeFile, QString binFile);
static QString getHashError(QString exeFile, QString binFile, QString exeFileOriginal, QString binFileOriginal);
};

View File

@ -84,7 +84,7 @@ bool ChroniclesExtractor::extractGogInstaller(QString file)
if(!errorText.isEmpty())
{
QString hashError = Innoextract::getHashError(file, {});
QString hashError = Innoextract::getHashError(file, {}, {}, {});
QMessageBox::critical(parent, tr("Extracting error!"), errorText);
if(!hashError.isEmpty())
QMessageBox::critical(parent, tr("Hash error!"), hashError, QMessageBox::Ok, QMessageBox::Ok);