aboutsummaryrefslogtreecommitdiff
path: root/launcher
diff options
context:
space:
mode:
authorRachel Powers <508861+Ryex@users.noreply.github.com>2022-10-25 01:19:19 -0700
committerRachel Powers <508861+Ryex@users.noreply.github.com>2022-11-01 04:24:11 -0700
commit1598d6582473f1bb6aa02fd9b4dabc8210771e56 (patch)
tree42dcb5df3a1629af1c1a7a0205545a835234e7d8 /launcher
parent028e086960402f685e07163def36d6b5eee1b796 (diff)
downloadPrismLauncher-1598d6582473f1bb6aa02fd9b4dabc8210771e56.tar.gz
PrismLauncher-1598d6582473f1bb6aa02fd9b4dabc8210771e56.tar.bz2
PrismLauncher-1598d6582473f1bb6aa02fd9b4dabc8210771e56.zip
watch filesystem, compute and match hashes
Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com>
Diffstat (limited to 'launcher')
-rw-r--r--launcher/modplatform/helpers/HashUtils.cpp58
-rw-r--r--launcher/modplatform/helpers/HashUtils.h15
-rw-r--r--launcher/ui/dialogs/BlockedModsDialog.cpp120
-rw-r--r--launcher/ui/dialogs/BlockedModsDialog.h23
4 files changed, 212 insertions, 4 deletions
diff --git a/launcher/modplatform/helpers/HashUtils.cpp b/launcher/modplatform/helpers/HashUtils.cpp
index a7bbaba5..bf53aa0e 100644
--- a/launcher/modplatform/helpers/HashUtils.cpp
+++ b/launcher/modplatform/helpers/HashUtils.cpp
@@ -35,6 +35,18 @@ Hasher::Ptr createFlameHasher(QString file_path)
return new FlameHasher(file_path);
}
+Hasher::Ptr createBlockedModHasher(QString file_path, ModPlatform::Provider provider)
+{
+ return new BlockedModHasher(file_path, provider);
+}
+
+Hasher::Ptr createBlockedModHasher(QString file_path, ModPlatform::Provider provider, QString type)
+{
+ auto hasher = new BlockedModHasher(file_path, provider);
+ hasher->useHashType(type);
+ return hasher;
+}
+
void ModrinthHasher::executeTask()
{
QFile file(m_path);
@@ -78,4 +90,50 @@ void FlameHasher::executeTask()
}
}
+
+BlockedModHasher::BlockedModHasher(QString file_path, ModPlatform::Provider provider)
+ : Hasher(file_path), provider(provider) {
+ setObjectName(QString("BlockedModHasher: %1").arg(file_path));
+ hash_type = ProviderCaps.hashType(provider).first();
+}
+
+void BlockedModHasher::executeTask()
+{
+ QFile file(m_path);
+
+ try {
+ file.open(QFile::ReadOnly);
+ } catch (FS::FileSystemException& e) {
+ qCritical() << QString("Failed to open JAR file in %1").arg(m_path);
+ qCritical() << QString("Reason: ") << e.cause();
+
+ emitFailed("Failed to open file for hashing.");
+ return;
+ }
+
+ m_hash = ProviderCaps.hash(provider, &file, hash_type);
+
+ file.close();
+
+ if (m_hash.isEmpty()) {
+ emitFailed("Empty hash!");
+ } else {
+ emitSucceeded();
+ }
+}
+
+QStringList BlockedModHasher::getHashTypes() {
+ return ProviderCaps.hashType(provider);
+}
+
+bool BlockedModHasher::useHashType(QString type) {
+ auto types = ProviderCaps.hashType(provider);
+ if (types.contains(type)) {
+ hash_type = type;
+ return true;
+ }
+ qDebug() << "Bad hash type " << type << " for provider";
+ return false;
+}
+
} // namespace Hashing
diff --git a/launcher/modplatform/helpers/HashUtils.h b/launcher/modplatform/helpers/HashUtils.h
index 38fddf03..fa3244f6 100644
--- a/launcher/modplatform/helpers/HashUtils.h
+++ b/launcher/modplatform/helpers/HashUtils.h
@@ -40,8 +40,23 @@ class ModrinthHasher : public Hasher {
void executeTask() override;
};
+class BlockedModHasher : public Hasher {
+ public:
+ BlockedModHasher(QString file_path, ModPlatform::Provider provider);
+
+ void executeTask() override;
+
+ QStringList getHashTypes();
+ bool useHashType(QString type);
+ private:
+ ModPlatform::Provider provider;
+ QString hash_type;
+};
+
Hasher::Ptr createHasher(QString file_path, ModPlatform::Provider provider);
Hasher::Ptr createFlameHasher(QString file_path);
Hasher::Ptr createModrinthHasher(QString file_path);
+Hasher::Ptr createBlockedModHasher(QString file_path, ModPlatform::Provider provider);
+Hasher::Ptr createBlockedModHasher(QString file_path, ModPlatform::Provider provider, QString type);
} // namespace Hashing
diff --git a/launcher/ui/dialogs/BlockedModsDialog.cpp b/launcher/ui/dialogs/BlockedModsDialog.cpp
index e29f8eb3..9ba033d7 100644
--- a/launcher/ui/dialogs/BlockedModsDialog.cpp
+++ b/launcher/ui/dialogs/BlockedModsDialog.cpp
@@ -1,3 +1,6 @@
+#include <qfileinfo.h>
+#include <qnamespace.h>
+#include "Application.h"
#include "BlockedModsDialog.h"
#include "ui_BlockedModsDialog.h"
#include <QPushButton>
@@ -5,20 +8,29 @@
#include <QDesktopServices>
#include <QDebug>
+#include <QStandardPaths>
-BlockedModsDialog::BlockedModsDialog(QWidget *parent, const QString &title, const QString &text, const QList<BlockedMod> &mods) :
+
+
+BlockedModsDialog::BlockedModsDialog(QWidget *parent, const QString &title, const QString &text, QList<BlockedMod> &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<ConcurrentTask>(new ConcurrentTask(this, "MakeHashesTask", 10));
+
qDebug() << "Mods List: " << mods;
+ setupWatch();
+ scanPaths(true);
+
this->setWindowTitle(title);
ui->label->setText(text);
- ui->textBrowser->setText(body);
update();
}
@@ -50,6 +62,110 @@ void BlockedModsDialog::update() {
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);
diff --git a/launcher/ui/dialogs/BlockedModsDialog.h b/launcher/ui/dialogs/BlockedModsDialog.h
index 4be020ec..f1ea99ca 100644
--- a/launcher/ui/dialogs/BlockedModsDialog.h
+++ b/launcher/ui/dialogs/BlockedModsDialog.h
@@ -1,7 +1,14 @@
#pragma once
#include <QDialog>
+#include <QString>
+#include <QList>
+#include <QFileSystemWatcher>
+
+#include "modplatform/helpers/HashUtils.h"
+
+#include "tasks/ConcurrentTask.h"
struct BlockedMod {
QString name;
@@ -20,15 +27,27 @@ class BlockedModsDialog : public QDialog {
Q_OBJECT
public:
- BlockedModsDialog(QWidget *parent, const QString &title, const QString &text, const QList<BlockedMod> &mods);
+ BlockedModsDialog(QWidget *parent, const QString &title, const QString &text, QList<BlockedMod> &mods);
~BlockedModsDialog() override;
private:
Ui::BlockedModsDialog *ui;
- const QList<BlockedMod> &mods;
+ QList<BlockedMod> &mods;
+ QFileSystemWatcher watcher;
+ shared_qobject_ptr<ConcurrentTask> hashing_task;
+ QSet<QString> checked_paths;
+
void openAll();
void update();
+ void directoryChanged(QString path);
+ void setupWatch();
+ void scanPaths(bool init);
+ void scanPath(QString path, bool init);
+ void checkMatchHash(QString hash, QString path);
+
+ bool checkValidPath(QString path);
+ bool allModsMatched();
};