#include #include #include "Application.h" #include "BlockedModsDialog.h" #include "ui_BlockedModsDialog.h" #include #include #include #include #include BlockedModsDialog::BlockedModsDialog(QWidget *parent, const QString &title, const QString &text, QList &mods) : QDialog(parent), ui(new Ui::BlockedModsDialog), mods(mods) { ui->setupUi(this); auto openAllButton = ui->buttonBox->addButton(tr("Open All"), QDialogButtonBox::ActionRole); connect(openAllButton, &QPushButton::clicked, this, &BlockedModsDialog::openAll); connect(&watcher, &QFileSystemWatcher::directoryChanged, this, &BlockedModsDialog::directoryChanged); hashing_task = shared_qobject_ptr(new ConcurrentTask(this, "MakeHashesTask", 10)); qDebug() << "Mods List: " << mods; setupWatch(); scanPaths(true); this->setWindowTitle(title); ui->label->setText(text); update(); } BlockedModsDialog::~BlockedModsDialog() { delete ui; } void BlockedModsDialog::openAll() { for(auto &mod : mods) { QDesktopServices::openUrl(mod.websiteUrl); } } void BlockedModsDialog::update() { QString text; QString span; for (auto &mod : mods) { if (mod.matched) { // ✔ -> html for HEAVY CHECK MARK : ✔ span = QString(" ✔ Found at %1 ").arg(mod.localPath); } else { // ✘ -> html for HEAVY BALLOT X : ✘ span = QString(" ✘ Not Found "); } text += QString("%1: %2

Hash: %3 %4


").arg(mod.name, mod.websiteUrl, mod.hash, span); } ui->textBrowser->setText(text); } void BlockedModsDialog::directoryChanged(QString path) { qDebug() << "Directory changed: " << path; scanPath(path, false); } void BlockedModsDialog::setupWatch() { const QString downloadsFolder = QStandardPaths::writableLocation(QStandardPaths::DownloadLocation); const QString modsFolder = APPLICATION->settings()->get("CentralModsDir").toString(); watcher.addPath(downloadsFolder); watcher.addPath(modsFolder); } void BlockedModsDialog::scanPaths(bool init) { for (auto &dir : watcher.directories()) { scanPath(dir, init); } } void BlockedModsDialog::scanPath(QString path, bool init) { QDir scan_dir(path); QDirIterator scan_it(path, QDir::Filter::Files | QDir::Filter::Hidden, QDirIterator::NoIteratorFlags); while (scan_it.hasNext()) { QString file = scan_it.next(); if (checked_paths.contains(file)){ continue; } if (!checkValidPath(file)) { continue; } auto hash_task = Hashing::createBlockedModHasher(file, ModPlatform::Provider::FLAME, "sha1"); qDebug() << "Creating Hash task for path: " << file; connect(hash_task.get(), &Task::succeeded, [this, hash_task, file] { checkMatchHash(hash_task->getResult(), file); }); connect(hash_task.get(), &Task::failed, [this, hash_task, file] { qDebug() << "Failed to hash path: " << file; }); if (init) { checked_paths.insert(file); } hashing_task->addTask(hash_task); } hashing_task->start(); } void BlockedModsDialog::checkMatchHash(QString hash, QString path) { bool match = false; qDebug() << "Checking for match on hash: " << hash << " | From path:" << path; for (auto &mod : mods) { if (mod.matched) { continue; } if (mod.hash.compare(hash, Qt::CaseInsensitive) == 0) { mod.matched = true; mod.localPath = path; match = true; qDebug() << "Hash match found: " << mod.name << " " << hash << " | From path:" << path; break; } } if (match) { update(); } } bool BlockedModsDialog::checkValidPath(QString path) { QFileInfo file = QFileInfo(path); QString filename = file.fileName(); for (auto &mod : mods) { if (mod.name.compare(filename, Qt::CaseInsensitive) == 0) { qDebug() << "Name match found: " << mod.name << " | From path:" << path; return true; } } return false; } bool BlockedModsDialog::allModsMatched() { for (auto &mod : mods) { if (!mod.matched) return false; } return true; } QDebug operator<<(QDebug debug, const BlockedMod &m) { QDebugStateSaver saver(debug); debug.nospace() << "{ name: " << m.name << ", websiteUrl: " << m.websiteUrl << ", hash: " << m.hash << ", matched: " << m.matched << ", localPath: " << m.localPath <<"}"; return debug; }