diff options
44 files changed, 343 insertions, 325 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index e4cd6387..3807d04f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -432,6 +432,8 @@ SET(MULTIMC_SOURCES logic/DefaultVariable.h # network stuffs + logic/Env.h + logic/Env.cpp logic/net/NetAction.h logic/net/MD5EtagDownload.h logic/net/MD5EtagDownload.cpp diff --git a/MultiMC.cpp b/MultiMC.cpp index 3644a6ad..b1b03ed9 100644 --- a/MultiMC.cpp +++ b/MultiMC.cpp @@ -23,6 +23,7 @@ #include "logic/net/HttpMetaCache.h" #include "logic/net/URLConstants.h" +#include "logic/Env.h" #include "logic/java/JavaUtils.h" @@ -108,8 +109,9 @@ MultiMC::MultiMC(int &argc, char **argv, bool test_mode) : QApplication(argc, ar return; } } - origcwdPath = QDir::currentPath(); - binPath = applicationDirPath(); + + QString origcwdPath = QDir::currentPath(); + QString binPath = applicationDirPath(); QString adjustedBy; // change directory QString dirParam = args["dir"].toString(); @@ -191,7 +193,7 @@ MultiMC::MultiMC(int &argc, char **argv, bool test_mode) : QApplication(argc, ar initTranslations(); // initialize the updater - m_updateChecker.reset(new UpdateChecker()); + m_updateChecker.reset(new UpdateChecker(BuildConfig.CHANLIST_URL, BuildConfig.VERSION_BUILD)); m_translationChecker.reset(new TranslationDownloader()); @@ -219,15 +221,22 @@ MultiMC::MultiMC(int &argc, char **argv, bool test_mode) : QApplication(argc, ar m_accounts->loadList(); // init the http meta cache - initHttpMetaCache(); + ENV.initHttpMetaCache(rootPath, staticDataPath); // create the global network manager - m_qnam.reset(new QNetworkAccessManager(this)); - - m_translationChecker->downloadTranslations(); + ENV.m_qnam.reset(new QNetworkAccessManager(this)); // init proxy settings - updateProxySettings(); + { + QString proxyTypeStr = settings()->get("ProxyType").toString(); + QString addr = settings()->get("ProxyAddr").toString(); + int port = settings()->get("ProxyPort").value<qint16>(); + QString user = settings()->get("ProxyUser").toString(); + QString pass = settings()->get("ProxyPass").toString(); + ENV.updateProxySettings(proxyTypeStr, addr, port, user, pass); + } + + m_translationChecker->downloadTranslations(); //FIXME: what to do with these? m_profilers.insert("jprofiler", @@ -285,7 +294,7 @@ void MultiMC::initTranslations() } m_mmc_translator.reset(new QTranslator()); - if (m_mmc_translator->load("mmc_" + locale.bcp47Name(), staticData() + "/translations")) + if (m_mmc_translator->load("mmc_" + locale.bcp47Name(), staticDataPath + "/translations")) { QLOG_DEBUG() << "Loading MMC Language File for" << locale.bcp47Name().toLocal8Bit().constData() << "..."; @@ -335,9 +344,6 @@ void MultiMC::initGlobalSettings(bool test_mode) m_settings->registerSetting("AutoUpdate", true); m_settings->registerSetting("IconTheme", QString("multimc")); - // Minecraft Sneaky Updates - m_settings->registerSetting("AutoUpdateMinecraftVersions", true); - // Notifications m_settings->registerSetting("ShownNotifications", QString()); @@ -530,99 +536,17 @@ void MultiMC::initGlobalSettings(bool test_mode) m_settings->registerSetting("PagedGeometry", ""); } -void MultiMC::initHttpMetaCache() -{ - m_metacache.reset(new HttpMetaCache("metacache")); - m_metacache->addBase("asset_indexes", QDir("assets/indexes").absolutePath()); - m_metacache->addBase("asset_objects", QDir("assets/objects").absolutePath()); - m_metacache->addBase("versions", QDir("versions").absolutePath()); - m_metacache->addBase("libraries", QDir("libraries").absolutePath()); - m_metacache->addBase("minecraftforge", QDir("mods/minecraftforge").absolutePath()); - m_metacache->addBase("fmllibs", QDir("mods/minecraftforge/libs").absolutePath()); - m_metacache->addBase("liteloader", QDir("mods/liteloader").absolutePath()); - m_metacache->addBase("general", QDir("cache").absolutePath()); - m_metacache->addBase("skins", QDir("accounts/skins").absolutePath()); - m_metacache->addBase("root", QDir(root()).absolutePath()); - m_metacache->addBase("translations", QDir(staticData() + "/translations").absolutePath()); - m_metacache->Load(); -} - -void MultiMC::updateProxySettings() -{ - QString proxyTypeStr = settings()->get("ProxyType").toString(); - - // Get the proxy settings from the settings object. - QString addr = settings()->get("ProxyAddr").toString(); - int port = settings()->get("ProxyPort").value<qint16>(); - QString user = settings()->get("ProxyUser").toString(); - QString pass = settings()->get("ProxyPass").toString(); - - // Set the application proxy settings. - if (proxyTypeStr == "SOCKS5") - { - QNetworkProxy::setApplicationProxy( - QNetworkProxy(QNetworkProxy::Socks5Proxy, addr, port, user, pass)); - } - else if (proxyTypeStr == "HTTP") - { - QNetworkProxy::setApplicationProxy( - QNetworkProxy(QNetworkProxy::HttpProxy, addr, port, user, pass)); - } - else if (proxyTypeStr == "None") - { - // If we have no proxy set, set no proxy and return. - QNetworkProxy::setApplicationProxy(QNetworkProxy(QNetworkProxy::NoProxy)); - } - else - { - // If we have "Default" selected, set Qt to use the system proxy settings. - QNetworkProxyFactory::setUseSystemConfiguration(true); - } - - QLOG_INFO() << "Detecting proxy settings..."; - QNetworkProxy proxy = QNetworkProxy::applicationProxy(); - if (m_qnam.get()) - m_qnam->setProxy(proxy); - QString proxyDesc; - if (proxy.type() == QNetworkProxy::NoProxy) - { - QLOG_INFO() << "Using no proxy is an option!"; - return; - } - switch (proxy.type()) - { - case QNetworkProxy::DefaultProxy: - proxyDesc = "Default proxy: "; - break; - case QNetworkProxy::Socks5Proxy: - proxyDesc = "Socks5 proxy: "; - break; - case QNetworkProxy::HttpProxy: - proxyDesc = "HTTP proxy: "; - break; - case QNetworkProxy::HttpCachingProxy: - proxyDesc = "HTTP caching: "; - break; - case QNetworkProxy::FtpCachingProxy: - proxyDesc = "FTP caching: "; - break; - default: - proxyDesc = "DERP proxy: "; - break; - } - proxyDesc += QString("%3@%1:%2 pass %4") - .arg(proxy.hostName()) - .arg(proxy.port()) - .arg(proxy.user()) - .arg(proxy.password()); - QLOG_INFO() << proxyDesc; -} - std::shared_ptr<IconList> MultiMC::icons() { if (!m_icons) { - m_icons.reset(new IconList); + + auto setting = MMC->settings()->getSetting("IconsDir"); + m_icons.reset(new IconList(setting->get().toString())); + connect(setting.get(), &Setting::SettingChanged,[&](const Setting &, QVariant value) + { + m_icons->directoryChanged(value.toString()); + }); } return m_icons; } @@ -690,13 +614,13 @@ void MultiMC::installUpdates(const QString updateFilesDir, UpdateFlags flags) QLOG_INFO() << "Installing updates."; #ifdef WINDOWS QString finishCmd = applicationFilePath(); - QString updaterBinary = PathCombine(bin(), "updater.exe"); + QString updaterBinary = PathCombine(applicationDirPath(), "updater.exe"); #elif LINUX QString finishCmd = PathCombine(root(), "MultiMC"); - QString updaterBinary = PathCombine(bin(), "updater"); + QString updaterBinary = PathCombine(applicationDirPath(), "updater"); #elif OSX QString finishCmd = applicationFilePath(); - QString updaterBinary = PathCombine(bin(), "updater"); + QString updaterBinary = PathCombine(applicationDirPath(), "updater"); #else #error Unsupported operating system. #endif @@ -713,7 +637,7 @@ void MultiMC::installUpdates(const QString updateFilesDir, UpdateFlags flags) if (flags & RestartOnFinish) { args << "--finish-cmd" << finishCmd; - args << "--finish-dir" << data(); + args << "--finish-dir" << dataPath; } QLOG_INFO() << "Running updater with command" << updaterBinary << args.join(" "); QFile::setPermissions(updaterBinary, (QFileDevice::Permission)0x7755); @@ -724,6 +648,7 @@ void MultiMC::installUpdates(const QString updateFilesDir, UpdateFlags flags) return; } + ENV.destroy(); // Now that we've started the updater, quit MultiMC. quit(); } @@ -744,6 +669,7 @@ void MultiMC::onExit() { installUpdates(m_updateOnExitPath, m_updateOnExitFlags); } + ENV.destroy(); } bool MultiMC::openJsonEditor(const QString &filename) @@ -40,6 +40,9 @@ Q_DECLARE_OPERATORS_FOR_FLAGS(UpdateFlags); class MultiMC : public QApplication { + // friends for the purpose of limiting access to deprecated stuff + friend class MultiMCPage; + friend class MainWindow; Q_OBJECT public: enum Status @@ -53,106 +56,92 @@ public: MultiMC(int &argc, char **argv, bool test_mode = false); virtual ~MultiMC(); + // InstanceList, IconList, OneSixFTBInstance, LegacyUpdate, LegacyInstance, MCEditTool, JVisualVM, MinecraftInstance, JProfiler, BaseInstance std::shared_ptr<SettingsObject> settings() { return m_settings; } + // InstanceList, OneSixUpdate, MinecraftInstance, OneSixProfileStrategy + std::shared_ptr<MinecraftVersionList> minecraftlist(); - std::shared_ptr<InstanceList> instances() - { - return m_instances; - } - - std::shared_ptr<MojangAccountList> accounts() - { - return m_accounts; - } - + // LegacyInstance, BaseInstance, OneSixInstance, InstanceList std::shared_ptr<IconList> icons(); QIcon getThemedIcon(const QString& name); void setIconTheme(const QString& name); - Status status() - { - return m_status; - } - - std::shared_ptr<QNetworkAccessManager> qnam() - { - return m_qnam; - } - - std::shared_ptr<HttpMetaCache> metacache() - { - return m_metacache; - } - + // DownloadUpdateTask std::shared_ptr<UpdateChecker> updateChecker() { return m_updateChecker; } + // LegacyUpdate std::shared_ptr<LWJGLVersionList> lwjgllist(); + // APPLICATION ONLY std::shared_ptr<ForgeVersionList> forgelist(); + // APPLICATION ONLY std::shared_ptr<LiteLoaderVersionList> liteloaderlist(); - std::shared_ptr<MinecraftVersionList> minecraftlist(); - + // APPLICATION ONLY std::shared_ptr<JavaVersionList> javalist(); + // APPLICATION ONLY + std::shared_ptr<InstanceList> instances() + { + return m_instances; + } + + // APPLICATION ONLY + std::shared_ptr<MojangAccountList> accounts() + { + return m_accounts; + } + + // APPLICATION ONLY + Status status() + { + return m_status; + } + + // APPLICATION ONLY QMap<QString, std::shared_ptr<BaseProfilerFactory>> profilers() { return m_profilers; } + + // APPLICATION ONLY QMap<QString, std::shared_ptr<BaseDetachedToolFactory>> tools() { return m_tools; } + // APPLICATION ONLY void installUpdates(const QString updateFilesDir, UpdateFlags flags = None); /*! - * Updates the application proxy settings from the settings object. - */ - void updateProxySettings(); - - /*! * Opens a json file using either a system default editor, or, if note empty, the editor * specified in the settings */ bool openJsonEditor(const QString &filename); +protected: /* to be removed! */ + // FIXME: remove. used by MultiMCPage to enumerate translations. /// this is the static data. it stores things that don't move. const QString &staticData() { return staticDataPath; } + + // FIXME: remove. used by MainWindow to create application update tasks /// this is the root of the 'installation'. Used for automatic updates const QString &root() { return rootPath; } - /// this is the where the binary files reside - const QString &bin() - { - return binPath; - } - /// this is the work/data path. All user data is here. - const QString &data() - { - return dataPath; - } - /** - * this is the original work path before it was changed by the adjustment mechanism - */ - const QString &origcwd() - { - return origcwdPath; - } private slots: /** @@ -165,8 +154,6 @@ private: void initGlobalSettings(bool test_mode); - void initHttpMetaCache(); - void initTranslations(); private: @@ -180,8 +167,6 @@ private: std::shared_ptr<UpdateChecker> m_updateChecker; std::shared_ptr<MojangAccountList> m_accounts; std::shared_ptr<IconList> m_icons; - std::shared_ptr<QNetworkAccessManager> m_qnam; - std::shared_ptr<HttpMetaCache> m_metacache; std::shared_ptr<LWJGLVersionList> m_lwjgllist; std::shared_ptr<ForgeVersionList> m_forgelist; std::shared_ptr<LiteLoaderVersionList> m_liteloaderlist; @@ -200,9 +185,7 @@ private: QString rootPath; QString staticDataPath; - QString binPath; QString dataPath; - QString origcwdPath; Status m_status = MultiMC::Failed; }; diff --git a/gui/MainWindow.cpp b/gui/MainWindow.cpp index f12ccf24..721a6833 100644 --- a/gui/MainWindow.cpp +++ b/gui/MainWindow.cpp @@ -375,6 +375,7 @@ namespace Ui { #include "logic/net/URLConstants.h" #include "logic/net/NetJob.h" +#include "logic/Env.h" #include "logic/BaseInstance.h" #include "logic/OneSixInstance.h" @@ -572,7 +573,7 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWi { for (auto profile : account->profiles()) { - auto meta = MMC->metacache()->resolveEntry("skins", profile.name + ".png"); + auto meta = Env::getInstance().metacache()->resolveEntry("skins", profile.name + ".png"); auto action = CacheDownload::make( QUrl("http://" + URLConstants::SKINS_BASE + profile.name + ".png"), meta); skin_dls.append(action); @@ -619,7 +620,7 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWi if (MMC->settings()->get("AutoUpdate").toBool()) { auto updater = MMC->updateChecker(); - updater->checkForUpdate(false); + updater->checkForUpdate(MMC->settings()->get("UpdateChannel").toString(), false); } m_notificationChecker.reset(new NotificationChecker()); connect(m_notificationChecker.get(), @@ -981,7 +982,7 @@ void MainWindow::downloadUpdates(QString repo, int versionId, bool installOnExit // Doing so is a bit complicated, because we'd have to make sure it finished downloading // before actually exiting MultiMC. ProgressDialog updateDlg(this); - DownloadUpdateTask updateTask(repo, versionId, &updateDlg); + DownloadUpdateTask updateTask(MMC->root(), repo, versionId, &updateDlg); // If the task succeeds, install the updates. if (updateDlg.exec(&updateTask)) { @@ -1070,7 +1071,7 @@ void MainWindow::instanceFromZipPack(QString instName, QString instGroup, QStrin else { const QString path = url.host() + '/' + url.path(); - auto entry = MMC->metacache()->resolveEntry("general", path); + auto entry = ENV.metacache()->resolveEntry("general", path); CacheDownloadPtr dl = CacheDownload::make(url, entry); NetJob job(tr("Modpack download")); job.addNetAction(dl); @@ -1357,7 +1358,7 @@ void MainWindow::on_actionConfig_Folder_triggered() void MainWindow::on_actionCheckUpdate_triggered() { auto updater = MMC->updateChecker(); - updater->checkForUpdate(true); + updater->checkForUpdate(MMC->settings()->get("UpdateChannel").toString(), true); } template <typename T> diff --git a/gui/pages/LegacyJarModPage.cpp b/gui/pages/LegacyJarModPage.cpp index 8eddf625..219e92ef 100644 --- a/gui/pages/LegacyJarModPage.cpp +++ b/gui/pages/LegacyJarModPage.cpp @@ -29,6 +29,7 @@ #include "logic/LegacyInstance.h" #include "logic/forge/ForgeVersion.h" #include "logic/forge/ForgeVersionList.h" +#include "logic/Env.h" #include "MultiMC.h" LegacyJarModPage::LegacyJarModPage(LegacyInstance *inst, QWidget *parent) @@ -109,7 +110,7 @@ void LegacyJarModPage::on_addForgeBtn_clicked() std::dynamic_pointer_cast<ForgeVersion>(vselect.selectedVersion()); if (!forge) return; - auto entry = MMC->metacache()->resolveEntry("minecraftforge", forge->filename()); + auto entry = Env::getInstance().metacache()->resolveEntry("minecraftforge", forge->filename()); if (entry->stale) { NetJob *fjob = new NetJob("Forge download"); diff --git a/gui/pages/global/AccountListPage.cpp b/gui/pages/global/AccountListPage.cpp index dec7c6e0..2de77115 100644 --- a/gui/pages/global/AccountListPage.cpp +++ b/gui/pages/global/AccountListPage.cpp @@ -22,6 +22,7 @@ #include "logic/net/NetJob.h" #include "logic/net/URLConstants.h" +#include "logic/Env.h" #include "gui/dialogs/EditAccountDialog.h" #include "gui/dialogs/ProgressDialog.h" @@ -129,7 +130,7 @@ void AccountListPage::addAccount(const QString &errMsg) for (AccountProfile profile : account->profiles()) { - auto meta = MMC->metacache()->resolveEntry("skins", profile.name + ".png"); + auto meta = Env::getInstance().metacache()->resolveEntry("skins", profile.name + ".png"); auto action = CacheDownload::make( QUrl("http://" + URLConstants::SKINS_BASE + profile.name + ".png"), meta); job->addNetAction(action); diff --git a/gui/pages/global/MinecraftPage.cpp b/gui/pages/global/MinecraftPage.cpp index c2a015ad..5566542c 100644 --- a/gui/pages/global/MinecraftPage.cpp +++ b/gui/pages/global/MinecraftPage.cpp @@ -74,8 +74,6 @@ void MinecraftPage::on_maximizedCheckBox_clicked(bool checked) void MinecraftPage::applySettings() { auto s = MMC->settings(); - // Minecraft version updates - s->set("AutoUpdateMinecraftVersions", ui->autoupdateMinecraft->isChecked()); // Window Size s->set("LaunchMaximized", ui->maximizedCheckBox->isChecked()); @@ -86,8 +84,6 @@ void MinecraftPage::applySettings() void MinecraftPage::loadSettings() { auto s = MMC->settings(); - // Minecraft version updates - ui->autoupdateMinecraft->setChecked(s->get("AutoUpdateMinecraftVersions").toBool()); // Window Size ui->maximizedCheckBox->setChecked(s->get("LaunchMaximized").toBool()); diff --git a/gui/pages/global/MinecraftPage.ui b/gui/pages/global/MinecraftPage.ui index 9e7df224..825f6a56 100644 --- a/gui/pages/global/MinecraftPage.ui +++ b/gui/pages/global/MinecraftPage.ui @@ -7,7 +7,7 @@ <x>0</x> <y>0</y> <width>545</width> - <height>270</height> + <height>195</height> </rect> </property> <property name="sizePolicy"> @@ -50,22 +50,6 @@ </attribute> <layout class="QVBoxLayout" name="verticalLayout_3"> <item> - <widget class="QGroupBox" name="groupBox_5"> - <property name="title"> - <string>Minecraft Version Updates</string> - </property> - <layout class="QVBoxLayout" name="verticalLayout_14"> - <item> - <widget class="QCheckBox" name="autoupdateMinecraft"> - <property name="text"> - <string>Automatically update to latest version revision</string> - </property> - </widget> - </item> - </layout> - </widget> - </item> - <item> <widget class="QGroupBox" name="windowSizeGroupBox"> <property name="title"> <string>Window Size</string> @@ -155,7 +139,6 @@ </widget> <tabstops> <tabstop>tabWidget</tabstop> - <tabstop>autoupdateMinecraft</tabstop> <tabstop>maximizedCheckBox</tabstop> <tabstop>windowWidthSpinBox</tabstop> <tabstop>windowHeightSpinBox</tabstop> diff --git a/logic/Env.cpp b/logic/Env.cpp new file mode 100644 index 00000000..de93ded3 --- /dev/null +++ b/logic/Env.cpp @@ -0,0 +1,104 @@ +#include "Env.h" +#include "logic/net/HttpMetaCache.h" +#include <QDir> +#include <QNetworkProxy> +#include <QNetworkAccessManager> +#include "logger/QsLog.h" +#include "MultiMC.h" + +Env::Env() +{ + // null +} + +void Env::destroy() +{ + m_metacache.reset(); + m_qnam.reset(); +} + +Env& Env::Env::getInstance() +{ + static Env instance; + return instance; +} + +void Env::initHttpMetaCache(QString rootPath, QString staticDataPath) +{ + m_metacache.reset(new HttpMetaCache("metacache")); + m_metacache->addBase("asset_indexes", QDir("assets/indexes").absolutePath()); + m_metacache->addBase("asset_objects", QDir("assets/objects").absolutePath()); + m_metacache->addBase("versions", QDir("versions").absolutePath()); + m_metacache->addBase("libraries", QDir("libraries").absolutePath()); + m_metacache->addBase("minecraftforge", QDir("mods/minecraftforge").absolutePath()); + m_metacache->addBase("fmllibs", QDir("mods/minecraftforge/libs").absolutePath()); + m_metacache->addBase("liteloader", QDir("mods/liteloader").absolutePath()); + m_metacache->addBase("general", QDir("cache").absolutePath()); + m_metacache->addBase("skins", QDir("accounts/skins").absolutePath()); + m_metacache->addBase("root", QDir(rootPath).absolutePath()); + m_metacache->addBase("translations", QDir(staticDataPath + "/translations").absolutePath()); + m_metacache->Load(); +} + +void Env::updateProxySettings(QString proxyTypeStr, QString addr, int port, QString user, QString password) +{ + // Set the application proxy settings. + if (proxyTypeStr == "SOCKS5") + { + QNetworkProxy::setApplicationProxy( + QNetworkProxy(QNetworkProxy::Socks5Proxy, addr, port, user, password)); + } + else if (proxyTypeStr == "HTTP") + { + QNetworkProxy::setApplicationProxy( + QNetworkProxy(QNetworkProxy::HttpProxy, addr, port, user, password)); + } + else if (proxyTypeStr == "None") + { + // If we have no proxy set, set no proxy and return. + QNetworkProxy::setApplicationProxy(QNetworkProxy(QNetworkProxy::NoProxy)); + } + else + { + // If we have "Default" selected, set Qt to use the system proxy settings. + QNetworkProxyFactory::setUseSystemConfiguration(true); + } + + QLOG_INFO() << "Detecting proxy settings..."; + QNetworkProxy proxy = QNetworkProxy::applicationProxy(); + if (m_qnam.get()) + m_qnam->setProxy(proxy); + QString proxyDesc; + if (proxy.type() == QNetworkProxy::NoProxy) + { + QLOG_INFO() << "Using no proxy is an option!"; + return; + } + switch (proxy.type()) + { + case QNetworkProxy::DefaultProxy: + proxyDesc = "Default proxy: "; + break; + case QNetworkProxy::Socks5Proxy: + proxyDesc = "Socks5 proxy: "; + break; + case QNetworkProxy::HttpProxy: + proxyDesc = "HTTP proxy: "; + break; + case QNetworkProxy::HttpCachingProxy: + proxyDesc = "HTTP caching: "; + break; + case QNetworkProxy::FtpCachingProxy: + proxyDesc = "FTP caching: "; + break; + default: + proxyDesc = "DERP proxy: "; + break; + } + proxyDesc += QString("%3@%1:%2 pass %4") + .arg(proxy.hostName()) + .arg(proxy.port()) + .arg(proxy.user()) + .arg(proxy.password()); + QLOG_INFO() << proxyDesc; +} diff --git a/logic/Env.h b/logic/Env.h new file mode 100644 index 00000000..523c51f0 --- /dev/null +++ b/logic/Env.h @@ -0,0 +1,44 @@ +#pragma once + +#include <memory> +#include <QString> + +class QNetworkAccessManager; +class HttpMetaCache; + +#if defined(ENV) + #undef ENV +#endif +#define ENV (Env::getInstance()) + +class Env +{ + friend class MultiMC; +private: + Env(); +public: + static Env& getInstance(); + + // call when Qt stuff is being torn down + void destroy(); + + std::shared_ptr<QNetworkAccessManager> qnam() + { + return m_qnam; + } + + std::shared_ptr<HttpMetaCache> metacache() + { + return m_metacache; + } + + /// init the cache. FIXME: possible future hook point + void initHttpMetaCache(QString rootPath, QString staticDataPath); + + /// Updates the application proxy settings from the settings object. + void updateProxySettings(QString proxyTypeStr, QString addr, int port, QString user, QString password); + +protected: + std::shared_ptr<QNetworkAccessManager> m_qnam; + std::shared_ptr<HttpMetaCache> m_metacache; +}; diff --git a/logic/LegacyUpdate.cpp b/logic/LegacyUpdate.cpp index 30f781ab..d955d456 100644 --- a/logic/LegacyUpdate.cpp +++ b/logic/LegacyUpdate.cpp @@ -25,13 +25,13 @@ #include "logic/minecraft/MinecraftVersionList.h" #include "logic/BaseInstance.h" #include "logic/LegacyInstance.h" -#include "MultiMC.h" +#include "logic/Env.h" #include "logic/ModList.h" #include "logger/QsLog.h" #include "logic/net/URLConstants.h" #include "JarUtils.h" - +#include "MultiMC.h" LegacyUpdate::LegacyUpdate(BaseInstance *inst, QObject *parent) : Task(parent), m_inst(inst) { @@ -110,7 +110,7 @@ void LegacyUpdate::fmllibsStart() // download missing libs to our place setStatus(tr("Dowloading FML libraries...")); auto dljob = new NetJob("FML libraries"); - auto metacache = MMC->metacache(); + auto metacache = ENV.metacache(); for (auto &lib : fmlLibsToProcess) { auto entry = metacache->resolveEntry("fmllibs", lib.filename); @@ -133,7 +133,7 @@ void LegacyUpdate::fmllibsFinished() { setStatus(tr("Copying FML libraries into the instance...")); LegacyInstance *inst = (LegacyInstance *)m_inst; - auto metacache = MMC->metacache(); + auto metacache = ENV.metacache(); int index = 0; for (auto &lib : fmlLibsToProcess) { @@ -197,7 +197,7 @@ void LegacyUpdate::lwjglStart() QString url = version->url(); QUrl realUrl(url); QString hostname = realUrl.host(); - auto worker = MMC->qnam(); + auto worker = ENV.qnam(); QNetworkRequest req(realUrl); req.setRawHeader("Host", hostname.toLatin1()); req.setHeader(QNetworkRequest::UserAgentHeader, "MultiMC/5.0 (Cached)"); @@ -222,7 +222,7 @@ void LegacyUpdate::lwjglFinished(QNetworkReply *reply) "a row. YMMV"); return; } - auto worker = MMC->qnam(); + auto worker = ENV.qnam(); // Here i check if there is a cookie for me in the reply and extract it QList<QNetworkCookie> cookies = qvariant_cast<QList<QNetworkCookie>>(reply->header(QNetworkRequest::SetCookieHeader)); @@ -376,7 +376,7 @@ void LegacyUpdate::jarStart() auto dljob = new NetJob("Minecraft.jar for version " + version_id); - auto metacache = MMC->metacache(); + auto metacache = ENV.metacache(); auto entry = metacache->resolveEntry("versions", localPath); dljob->addNetAction(CacheDownload::make(QUrl(urlstr), entry)); connect(dljob, SIGNAL(succeeded()), SLOT(jarFinished())); diff --git a/logic/LwjglVersionList.cpp b/logic/LwjglVersionList.cpp index 41c951e4..77b7a05e 100644 --- a/logic/LwjglVersionList.cpp +++ b/logic/LwjglVersionList.cpp @@ -14,7 +14,7 @@ */ #include "LwjglVersionList.h" -#include "MultiMC.h" +#include "logic/Env.h" #include <QtNetwork> #include <QtXml> @@ -82,7 +82,7 @@ void LWJGLVersionList::loadList() Q_ASSERT_X(!m_loading, "loadList", "list is already loading (m_loading is true)"); setLoading(true); - auto worker = MMC->qnam(); + auto worker = ENV.qnam(); QNetworkRequest req(QUrl(RSS_URL)); req.setRawHeader("Accept", "application/rss+xml, text/xml, */*"); req.setRawHeader("User-Agent", "MultiMC/5.0 (Uncached)"); diff --git a/logic/OneSixUpdate.cpp b/logic/OneSixUpdate.cpp index 692e4ce3..26a55cc9 100644 --- a/logic/OneSixUpdate.cpp +++ b/logic/OneSixUpdate.cpp @@ -14,6 +14,7 @@ */ #include "MultiMC.h" +#include "logic/Env.h" #include "OneSixUpdate.h" #include <QtNetwork> @@ -94,7 +95,7 @@ void OneSixUpdate::assetIndexStart() QString localPath = assetName + ".json"; auto job = new NetJob(tr("Asset index for %1").arg(inst->name())); - auto metacache = MMC->metacache(); + auto metacache = ENV.metacache(); auto entry = metacache->resolveEntry("asset_indexes", localPath); job->addNetAction(CacheDownload::make(indexUrl, entry)); jarlibDownloadJob.reset(job); @@ -118,7 +119,7 @@ void OneSixUpdate::assetIndexFinished() QString asset_fname = "assets/indexes/" + assetName + ".json"; if (!AssetsUtils::loadAssetsIndexJson(asset_fname, &index)) { - auto metacache = MMC->metacache(); + auto metacache = ENV.metacache(); auto entry = metacache->resolveEntry("asset_indexes", assetName + ".json"); metacache->evictEntry(entry); emitFailed(tr("Failed to read the assets index!")); @@ -200,7 +201,7 @@ void OneSixUpdate::jarlibStart() auto job = new NetJob(tr("Libraries for instance %1").arg(inst->name())); - auto metacache = MMC->metacache(); + auto metacache = ENV.metacache(); auto entry = metacache->resolveEntry("versions", localPath); job->addNetAction(CacheDownload::make(QUrl(urlstr), entry)); jarHashOnEntry = entry->md5sum; @@ -211,7 +212,7 @@ void OneSixUpdate::jarlibStart() auto libs = version->getActiveNativeLibs(); libs.append(version->getActiveNormalLibs()); - auto metacache = MMC->metacache(); + auto metacache = ENV.metacache(); QList<ForgeXzDownloadPtr> ForgeLibs; QList<std::shared_ptr<OneSixLibrary>> brokenLocalLibs; @@ -317,7 +318,7 @@ void OneSixUpdate::jarlibFinished() { auto sourceJarPath = m_inst->versionsPath().absoluteFilePath(version->id + "/" + version->id + ".jar"); QString localPath = version_id + "/" + version_id + ".jar"; - auto metacache = MMC->metacache(); + auto metacache = ENV.metacache(); auto entry = metacache->resolveEntry("versions", localPath); QString fullJarPath = entry->getFullPath(); if(!JarUtils::createModdedJar(sourceJarPath, finalJarPath, jarMods)) @@ -390,7 +391,7 @@ void OneSixUpdate::fmllibsStart() // download missing libs to our place setStatus(tr("Dowloading FML libraries...")); auto dljob = new NetJob("FML libraries"); - auto metacache = MMC->metacache(); + auto metacache = ENV.metacache(); for (auto &lib : fmlLibsToProcess) { auto entry = metacache->resolveEntry("fmllibs", lib.filename); @@ -413,7 +414,7 @@ void OneSixUpdate::fmllibsFinished() { setStatus(tr("Copying FML libraries into the instance...")); OneSixInstance *inst = (OneSixInstance *)m_inst; - auto metacache = MMC->metacache(); + auto metacache = ENV.metacache(); int index = 0; for (auto &lib : fmlLibsToProcess) { diff --git a/logic/SkinUtils.cpp b/logic/SkinUtils.cpp index 33fc5b1b..68d94117 100644 --- a/logic/SkinUtils.cpp +++ b/logic/SkinUtils.cpp @@ -13,9 +13,9 @@ * limitations under the License. */ -#include "MultiMC.h" #include "logic/SkinUtils.h" #include "net/HttpMetaCache.h" +#include "logic/Env.h" #include <QFile> #include <QJsonDocument> @@ -29,7 +29,7 @@ namespace SkinUtils */ QPixmap getFaceFromCache(QString username, int height, int width) { - QFile fskin(MMC->metacache() + QFile fskin(ENV.metacache() ->resolveEntry("skins", username + ".png") ->getFullPath()); diff --git a/logic/assets/AssetsUtils.cpp b/logic/assets/AssetsUtils.cpp index 472b9589..82a0da95 100644 --- a/logic/assets/AssetsUtils.cpp +++ b/logic/assets/AssetsUtils.cpp @@ -19,9 +19,10 @@ #include <QJsonParseError> #include <QJsonDocument> #include <QJsonObject> +#include <QVariant> +#include <logger/QsLog.h> #include "AssetsUtils.h" -#include "MultiMC.h" #include <pathutils.h> namespace AssetsUtils diff --git a/logic/auth/YggdrasilTask.cpp b/logic/auth/YggdrasilTask.cpp index a2a021af..6b5ed256 100644 --- a/logic/auth/YggdrasilTask.cpp +++ b/logic/auth/YggdrasilTask.cpp @@ -22,10 +22,12 @@ #include <QNetworkReply> #include <QByteArray> -#include <MultiMC.h> +#include <logic/Env.h> #include <logic/auth/MojangAccount.h> #include <logic/net/URLConstants.h> +#include "logger/QsLog.h" + YggdrasilTask::YggdrasilTask(MojangAccount *account, QObject *parent) : Task(parent), m_account(account) { @@ -39,7 +41,7 @@ void YggdrasilTask::executeTask() // Get the content of the request we're going to send to the server. QJsonDocument doc(getRequestContent()); - auto worker = MMC->qnam(); + auto worker = ENV.qnam(); QUrl reqUrl("https://" + URLConstants::AUTH_BASE + getEndpoint()); QNetworkRequest netRequest(reqUrl); netRequest.setHeader(QNetworkRequest::ContentTypeHeader, "application/json"); diff --git a/logic/forge/ForgeInstaller.cpp b/logic/forge/ForgeInstaller.cpp index 01671306..19cecaeb 100644 --- a/logic/forge/ForgeInstaller.cpp +++ b/logic/forge/ForgeInstaller.cpp @@ -21,6 +21,7 @@ #include "logic/OneSixInstance.h" #include "logic/forge/ForgeVersionList.h" #include "logic/minecraft/VersionFilterData.h" +#include "logic/Env.h" #include <quazip.h> #include <quazipfile.h> @@ -28,7 +29,7 @@ #include <QStringList> #include <QRegularExpression> #include <QRegularExpressionMatch> -#include "MultiMC.h" + #include <QJsonDocument> #include <QJsonArray> #include <QSaveFile> @@ -86,7 +87,7 @@ void ForgeInstaller::prepare(const QString &filename, const QString &universalUr // where do we put the library? decode the mojang path OneSixLibrary lib(libraryName); - auto cacheentry = MMC->metacache()->resolveEntry("libraries", lib.storagePath()); + auto cacheentry = ENV.metacache()->resolveEntry("libraries", lib.storagePath()); finalPath = "libraries/" + lib.storagePath(); if (!ensureFilePathExists(finalPath)) return; @@ -110,7 +111,7 @@ void ForgeInstaller::prepare(const QString &filename, const QString &universalUr cacheentry->stale = false; cacheentry->md5sum = md5sum.result().toHex().constData(); - MMC->metacache()->updateEntry(cacheentry); + ENV.metacache()->updateEntry(cacheentry); } file.close(); @@ -275,7 +276,7 @@ bool ForgeInstaller::addLegacy(OneSixInstance *to) { return false; } - auto entry = MMC->metacache()->resolveEntry("minecraftforge", m_forge_version->filename()); + auto entry = ENV.metacache()->resolveEntry("minecraftforge", m_forge_version->filename()); finalPath = PathCombine(to->jarModsDir(), m_forge_version->filename()); if (!ensureFilePathExists(finalPath)) { @@ -346,7 +347,7 @@ protected: } void prepare(ForgeVersionPtr forgeVersion) { - auto entry = MMC->metacache()->resolveEntry("minecraftforge", forgeVersion->filename()); + auto entry = ENV.metacache()->resolveEntry("minecraftforge", forgeVersion->filename()); auto installFunction = [this, entry, forgeVersion]() { if (!install(entry, forgeVersion)) diff --git a/logic/forge/ForgeMirrors.cpp b/logic/forge/ForgeMirrors.cpp index b224306f..bb50d0b7 100644 --- a/logic/forge/ForgeMirrors.cpp +++ b/logic/forge/ForgeMirrors.cpp @@ -1,4 +1,4 @@ -#include "MultiMC.h" +#include "logic/Env.h" #include "ForgeMirrors.h" #include "logger/QsLog.h" #include <algorithm> @@ -18,7 +18,7 @@ void ForgeMirrors::start() QLOG_INFO() << "Downloading " << m_url.toString(); QNetworkRequest request(m_url); request.setHeader(QNetworkRequest::UserAgentHeader, "MultiMC/5.0 (Uncached)"); - auto worker = MMC->qnam(); + auto worker = ENV.qnam(); QNetworkReply *rep = worker->get(request); m_reply = std::shared_ptr<QNetworkReply>(rep); diff --git a/logic/forge/ForgeVersionList.cpp b/logic/forge/ForgeVersionList.cpp index 3e736b78..d7bb8af2 100644 --- a/logic/forge/ForgeVersionList.cpp +++ b/logic/forge/ForgeVersionList.cpp @@ -17,7 +17,7 @@ #include "logic/forge/ForgeVersion.h" #include "logic/net/NetJob.h" #include "logic/net/URLConstants.h" -#include "MultiMC.h" +#include "logic/Env.h" #include <QtNetwork> #include <QtXml> @@ -162,8 +162,8 @@ void ForgeListLoadTask::executeTask() setStatus(tr("Fetching Forge version lists...")); auto job = new NetJob("Version index"); // we do not care if the version is stale or not. - auto forgeListEntry = MMC->metacache()->resolveEntry("minecraftforge", "list.json"); - auto gradleForgeListEntry = MMC->metacache()->resolveEntry("minecraftforge", "json"); + auto forgeListEntry = ENV.metacache()->resolveEntry("minecraftforge", "list.json"); + auto gradleForgeListEntry = ENV.metacache()->resolveEntry("minecraftforge", "json"); // verify by poking the server. forgeListEntry->stale = true; diff --git a/logic/forge/ForgeXzDownload.cpp b/logic/forge/ForgeXzDownload.cpp index 781fa385..c2e5f76e 100644 --- a/logic/forge/ForgeXzDownload.cpp +++ b/logic/forge/ForgeXzDownload.cpp @@ -13,7 +13,7 @@ * limitations under the License. */ -#include "MultiMC.h" +#include "logic/Env.h" #include "ForgeXzDownload.h" #include <pathutils.h> @@ -67,7 +67,7 @@ void ForgeXzDownload::start() request.setRawHeader(QString("If-None-Match").toLatin1(), m_entry->etag.toLatin1()); request.setHeader(QNetworkRequest::UserAgentHeader, "MultiMC/5.0 (Cached)"); - auto worker = MMC->qnam(); + auto worker = ENV.qnam(); QNetworkReply *rep = worker->get(request); m_reply = std::shared_ptr<QNetworkReply>(rep); @@ -382,7 +382,7 @@ void ForgeXzDownload::decompressAndInstall() m_entry->local_changed_timestamp = output_file_info.lastModified().toUTC().toMSecsSinceEpoch(); m_entry->stale = false; - MMC->metacache()->updateEntry(m_entry); + ENV.metacache()->updateEntry(m_entry); m_reply.reset(); emit succeeded(m_index_within_job); diff --git a/logic/icons/IconList.cpp b/logic/icons/IconList.cpp index 217255a1..6db8b035 100644 --- a/logic/icons/IconList.cpp +++ b/logic/icons/IconList.cpp @@ -15,18 +15,16 @@ #include "IconList.h" #include <pathutils.h> -#include "logic/settings/SettingsObject.h" #include <QMap> #include <QEventLoop> #include <QMimeData> #include <QUrl> #include <QFileSystemWatcher> #include <MultiMC.h> -#include <logic/settings/Setting.h> #define MAX_SIZE 1024 -IconList::IconList(QObject *parent) : QAbstractListModel(parent) +IconList::IconList(QString path, QObject *parent) : QAbstractListModel(parent) { // add builtin icons QDir instance_icons(":/icons/instances/"); @@ -43,10 +41,6 @@ IconList::IconList(QObject *parent) : QAbstractListModel(parent) SLOT(directoryChanged(QString))); connect(m_watcher.get(), SIGNAL(fileChanged(QString)), SLOT(fileChanged(QString))); - auto setting = MMC->settings()->getSetting("IconsDir"); - QString path = setting->get().toString(); - connect(setting.get(), SIGNAL(SettingChanged(const Setting &, QVariant)), - SLOT(SettingChanged(const Setting &, QVariant))); directoryChanged(path); } diff --git a/logic/icons/IconList.h b/logic/icons/IconList.h index 1952eba4..8687eba6 100644 --- a/logic/icons/IconList.h +++ b/logic/icons/IconList.h @@ -30,7 +30,7 @@ class IconList : public QAbstractListModel { Q_OBJECT public: - explicit IconList(QObject *parent = 0); + explicit IconList(QString path, QObject *parent = 0); virtual ~IconList() {}; QIcon getIcon(QString key); @@ -64,9 +64,10 @@ private: IconList &operator=(const IconList &) = delete; void reindex(); -protected -slots: +public slots: void directoryChanged(const QString &path); + +protected slots: void fileChanged(const QString &path); void SettingChanged(const Setting & setting, QVariant value); private: diff --git a/logic/java/JavaChecker.cpp b/logic/java/JavaChecker.cpp index a08f476d..dc0370e7 100644 --- a/logic/java/JavaChecker.cpp +++ b/logic/java/JavaChecker.cpp @@ -12,7 +12,7 @@ JavaChecker::JavaChecker(QObject *parent) : QObject(parent) void JavaChecker::performCheck() { - QString checkerJar = PathCombine(MMC->bin(), "jars", "JavaCheck.jar"); + QString checkerJar = PathCombine(QCoreApplication::applicationDirPath(), "jars", "JavaCheck.jar"); QStringList args = {"-jar", checkerJar}; diff --git a/logic/liteloader/LiteLoaderVersionList.cpp b/logic/liteloader/LiteLoaderVersionList.cpp index 92d51c6e..48f098d0 100644 --- a/logic/liteloader/LiteLoaderVersionList.cpp +++ b/logic/liteloader/LiteLoaderVersionList.cpp @@ -14,7 +14,7 @@ */ #include "LiteLoaderVersionList.h" -#include "MultiMC.h" +#include "logic/Env.h" #include "logic/net/URLConstants.h" #include <MMCError.h> @@ -104,7 +104,7 @@ void LLListLoadTask::executeTask() setStatus(tr("Loading LiteLoader version list...")); auto job = new NetJob("Version index"); // we do not care if the version is stale or not. - auto liteloaderEntry = MMC->metacache()->resolveEntry("liteloader", "versions.json"); + auto liteloaderEntry = ENV.metacache()->resolveEntry("liteloader", "versions.json"); // verify by poking the server. liteloaderEntry->stale = true; diff --git a/logic/minecraft/MinecraftProcess.cpp b/logic/minecraft/MinecraftProcess.cpp index 0fc3f067..97eb8ee8 100644 --- a/logic/minecraft/MinecraftProcess.cpp +++ b/logic/minecraft/MinecraftProcess.cpp @@ -151,7 +151,7 @@ QStringList MinecraftProcess::javaArguments() const args << "-Duser.language=en"; if (!m_nativeFolder.isEmpty()) args << QString("-Djava.library.path=%1").arg(m_nativeFolder); - args << "-jar" << PathCombine(MMC->bin(), "jars", "NewLaunch.jar"); + args << "-jar" << PathCombine(QCoreApplication::applicationDirPath(), "jars", "NewLaunch.jar"); return args; } diff --git a/logic/minecraft/MinecraftVersion.cpp b/logic/minecraft/MinecraftVersion.cpp index 32682bfb..28afb5e7 100644 --- a/logic/minecraft/MinecraftVersion.cpp +++ b/logic/minecraft/MinecraftVersion.cpp @@ -152,9 +152,7 @@ QString MinecraftVersion::getPatchFilename() bool MinecraftVersion::needsUpdate() { - auto settings = MMC->settings(); - bool result = m_versionSource == Remote || (hasUpdate() && settings->get("AutoUpdateMinecraftVersions").toBool()); - return result; + return m_versionSource == Remote || hasUpdate(); } bool MinecraftVersion::hasUpdate() diff --git a/logic/minecraft/MinecraftVersionList.cpp b/logic/minecraft/MinecraftVersionList.cpp index 68e93d54..26b51731 100644 --- a/logic/minecraft/MinecraftVersionList.cpp +++ b/logic/minecraft/MinecraftVersionList.cpp @@ -18,7 +18,7 @@ #include <QtAlgorithms> #include <QtNetwork> -#include "MultiMC.h" +#include "logic/Env.h" #include "MMCError.h" #include "MinecraftVersionList.h" @@ -399,7 +399,7 @@ MCVListLoadTask::MCVListLoadTask(MinecraftVersionList *vlist) void MCVListLoadTask::executeTask() { setStatus(tr("Loading instance version list...")); - auto worker = MMC->qnam(); + auto worker = ENV.qnam(); vlistReply = worker->get(QNetworkRequest( QUrl("http://" + URLConstants::AWS_DOWNLOAD_VERSIONS + "versions.json"))); connect(vlistReply, SIGNAL(finished()), this, SLOT(list_downloaded())); diff --git a/logic/minecraft/VersionBuilder.cpp b/logic/minecraft/VersionBuilder.cpp index 7f77b493..2a7096e8 100644 --- a/logic/minecraft/VersionBuilder.cpp +++ b/logic/minecraft/VersionBuilder.cpp @@ -26,7 +26,6 @@ #include <modutils.h> #include <pathutils.h> -#include "MultiMC.h" #include "logic/minecraft/VersionBuilder.h" #include "logic/minecraft/MinecraftProfile.h" #include "logic/minecraft/OneSixRule.h" diff --git a/logic/net/ByteArrayDownload.cpp b/logic/net/ByteArrayDownload.cpp index 00254caa..e56ac9b6 100644 --- a/logic/net/ByteArrayDownload.cpp +++ b/logic/net/ByteArrayDownload.cpp @@ -14,7 +14,7 @@ */ #include "ByteArrayDownload.h" -#include "MultiMC.h" +#include "logic/Env.h" #include "logger/QsLog.h" ByteArrayDownload::ByteArrayDownload(QUrl url) : NetAction() @@ -28,7 +28,7 @@ void ByteArrayDownload::start() QLOG_INFO() << "Downloading " << m_url.toString(); QNetworkRequest request(m_url); request.setHeader(QNetworkRequest::UserAgentHeader, "MultiMC/5.0 (Uncached)"); - auto worker = MMC->qnam(); + auto worker = ENV.qnam(); QNetworkReply *rep = worker->get(request); m_reply = std::shared_ptr<QNetworkReply>(rep); diff --git a/logic/net/CacheDownload.cpp b/logic/net/CacheDownload.cpp index 95278b0d..1bf59c60 100644 --- a/logic/net/CacheDownload.cpp +++ b/logic/net/CacheDownload.cpp @@ -13,7 +13,6 @@ * limitations under the License. */ -#include "MultiMC.h" #include "CacheDownload.h" #include <pathutils.h> @@ -21,6 +20,7 @@ #include <QFileInfo> #include <QDateTime> #include "logger/QsLog.h" +#include "logic/Env.h" CacheDownload::CacheDownload(QUrl url, MetaEntryPtr entry) : NetAction(), md5sum(QCryptographicHash::Md5) @@ -74,7 +74,7 @@ void CacheDownload::start() request.setHeader(QNetworkRequest::UserAgentHeader, "MultiMC/5.0 (Cached)"); - auto worker = MMC->qnam(); + auto worker = ENV.qnam(); QNetworkReply *rep = worker->get(request); m_reply = std::shared_ptr<QNetworkReply>(rep); @@ -168,7 +168,7 @@ void CacheDownload::downloadFinished() m_entry->local_changed_timestamp = output_file_info.lastModified().toUTC().toMSecsSinceEpoch(); m_entry->stale = false; - MMC->metacache()->updateEntry(m_entry); + ENV.metacache()->updateEntry(m_entry); m_reply.reset(); emit succeeded(m_index_within_job); diff --git a/logic/net/HttpMetaCache.cpp b/logic/net/HttpMetaCache.cpp index 4533a736..eb931b8a 100644 --- a/logic/net/HttpMetaCache.cpp +++ b/logic/net/HttpMetaCache.cpp @@ -13,7 +13,7 @@ * limitations under the License. */ -#include "MultiMC.h" +#include "logic/Env.h" #include "HttpMetaCache.h" #include <pathutils.h> @@ -32,7 +32,8 @@ QString MetaEntry::getFullPath() { - return PathCombine(MMC->metacache()->getBasePath(base), path); + // FIXME: make local? + return PathCombine(ENV.metacache()->getBasePath(base), path); } HttpMetaCache::HttpMetaCache(QString path) : QObject() diff --git a/logic/net/HttpMetaCache.h b/logic/net/HttpMetaCache.h index dd44623c..042f66bf 100644 --- a/logic/net/HttpMetaCache.h +++ b/logic/net/HttpMetaCache.h @@ -17,6 +17,9 @@ #include <QString> #include <QMap> #include <qtimer.h> +#include <memory> + +class HttpMetaCache; struct MetaEntry { diff --git a/logic/net/MD5EtagDownload.cpp b/logic/net/MD5EtagDownload.cpp index c1d7f7a8..79038f36 100644 --- a/logic/net/MD5EtagDownload.cpp +++ b/logic/net/MD5EtagDownload.cpp @@ -13,7 +13,7 @@ * limitations under the License. */ -#include "MultiMC.h" +#include "logic/Env.h" #include "MD5EtagDownload.h" #include <pathutils.h> #include <QCryptographicHash> @@ -83,7 +83,7 @@ void MD5EtagDownload::start() return; } - auto worker = MMC->qnam(); + auto worker = ENV.qnam(); QNetworkReply *rep = worker->get(request); m_reply = std::shared_ptr<QNetworkReply>(rep); diff --git a/logic/net/PasteUpload.cpp b/logic/net/PasteUpload.cpp index c7bde06e..f68595c9 100644 --- a/logic/net/PasteUpload.cpp +++ b/logic/net/PasteUpload.cpp @@ -1,5 +1,5 @@ #include "PasteUpload.h" -#include "MultiMC.h" +#include "logic/Env.h" #include "logger/QsLog.h" #include <QJsonObject> #include <QJsonDocument> @@ -25,7 +25,7 @@ void PasteUpload::executeTask() request.setRawHeader("Content-Type", "application/x-www-form-urlencoded"); request.setRawHeader("Content-Length", QByteArray::number(content.size())); - auto worker = MMC->qnam(); + auto worker = ENV.qnam(); QNetworkReply *rep = worker->post(request, content); m_reply = std::shared_ptr<QNetworkReply>(rep); diff --git a/logic/screenshots/ImgurAlbumCreation.cpp b/logic/screenshots/ImgurAlbumCreation.cpp index 91cf4bb1..86edd5a5 100644 --- a/logic/screenshots/ImgurAlbumCreation.cpp +++ b/logic/screenshots/ImgurAlbumCreation.cpp @@ -7,7 +7,7 @@ #include <QStringList> #include "logic/net/URLConstants.h" -#include "MultiMC.h" +#include "logic/Env.h" #include "logger/QsLog.h" ImgurAlbumCreation::ImgurAlbumCreation(QList<ScreenshotPtr> screenshots) : NetAction(), m_screenshots(screenshots) @@ -33,7 +33,7 @@ void ImgurAlbumCreation::start() const QByteArray data = "ids=" + ids.join(',').toUtf8() + "&title=Minecraft%20Screenshots&privacy=hidden"; - auto worker = MMC->qnam(); + auto worker = ENV.qnam(); QNetworkReply *rep = worker->post(request, data); m_reply = std::shared_ptr<QNetworkReply>(rep); diff --git a/logic/screenshots/ImgurUpload.cpp b/logic/screenshots/ImgurUpload.cpp index f305aec0..91643e68 100644 --- a/logic/screenshots/ImgurUpload.cpp +++ b/logic/screenshots/ImgurUpload.cpp @@ -9,7 +9,7 @@ #include <QUrl> #include "logic/net/URLConstants.h" -#include "MultiMC.h" +#include "logic/Env.h" #include "logger/QsLog.h" ImgurUpload::ImgurUpload(ScreenshotPtr shot) : NetAction(), m_shot(shot) @@ -48,7 +48,7 @@ void ImgurUpload::start() namePart.setBody(m_shot->m_file.baseName().toUtf8()); multipart->append(namePart); - auto worker = MMC->qnam(); + auto worker = ENV.qnam(); QNetworkReply *rep = worker->post(request, multipart); m_reply = std::shared_ptr<QNetworkReply>(rep); diff --git a/logic/trans/TranslationDownloader.cpp b/logic/trans/TranslationDownloader.cpp index d2b96a01..77f1b9f7 100644 --- a/logic/trans/TranslationDownloader.cpp +++ b/logic/trans/TranslationDownloader.cpp @@ -3,7 +3,8 @@ #include "logic/net/ByteArrayDownload.h" #include "logic/net/CacheDownload.h" #include "logic/net/URLConstants.h" -#include "MultiMC.h" +#include "logic/Env.h" +#include "logger/QsLog.h" TranslationDownloader::TranslationDownloader() { @@ -27,7 +28,7 @@ void TranslationDownloader::indexRecieved() { if (!line.isEmpty()) { - MetaEntryPtr entry = MMC->metacache()->resolveEntry("translations", "mmc_" + line); + MetaEntryPtr entry = ENV.metacache()->resolveEntry("translations", "mmc_" + line); entry->stale = true; CacheDownloadPtr dl = CacheDownload::make( QUrl(URLConstants::TRANSLATIONS_BASE_URL + line), diff --git a/logic/updater/DownloadUpdateTask.cpp b/logic/updater/DownloadUpdateTask.cpp index 9d4c5bd8..af0cf0a8 100644 --- a/logic/updater/DownloadUpdateTask.cpp +++ b/logic/updater/DownloadUpdateTask.cpp @@ -16,6 +16,7 @@ #include "DownloadUpdateTask.h" #include "MultiMC.h" +#include "logic/Env.h" #include "BuildConfig.h" #include "logic/updater/UpdateChecker.h" @@ -28,10 +29,11 @@ #include <QDomDocument> -DownloadUpdateTask::DownloadUpdateTask(QString repoUrl, int versionId, QObject *parent) +DownloadUpdateTask::DownloadUpdateTask(QString rootPath, QString repoUrl, int versionId, QObject *parent) : Task(parent) { m_cVersionId = BuildConfig.VERSION_BUILD; + m_rootPath = rootPath; m_nRepoUrl = repoUrl; m_nVersionId = versionId; @@ -293,7 +295,7 @@ DownloadUpdateTask::processFileLists(NetJob *job, // delete anything in the current one version's list that isn't in the new version's list. for (VersionFileEntry entry : currentVersion) { - QFileInfo toDelete(PathCombine(MMC->root(), entry.path)); + QFileInfo toDelete(PathCombine(m_rootPath, entry.path)); if (!toDelete.exists()) { QLOG_ERROR() << "Expected file " << toDelete.absoluteFilePath() @@ -327,7 +329,7 @@ DownloadUpdateTask::processFileLists(NetJob *job, // TODO: Let's not MD5sum a ton of files on the GUI thread. We should probably find a // way to do this in the background. QString fileMD5; - QString realEntryPath = PathCombine(MMC->root(), entry.path); + QString realEntryPath = PathCombine(m_rootPath, entry.path); QFile entryFile(realEntryPath); QFileInfo entryInfo(realEntryPath); @@ -356,7 +358,6 @@ DownloadUpdateTask::processFileLists(NetJob *job, } if (!pass) { - QLOG_ERROR() << "ROOT: " << MMC->root(); ops.clear(); return false; } @@ -413,7 +414,7 @@ DownloadUpdateTask::processFileLists(NetJob *job, } else { - auto cache_entry = MMC->metacache()->resolveEntry("root", entry.path); + auto cache_entry = ENV.metacache()->resolveEntry("root", entry.path); QLOG_DEBUG() << "Updater will be in " << cache_entry->getFullPath(); // force check. cache_entry->stale = true; diff --git a/logic/updater/DownloadUpdateTask.h b/logic/updater/DownloadUpdateTask.h index ecfa349b..9a994687 100644 --- a/logic/updater/DownloadUpdateTask.h +++ b/logic/updater/DownloadUpdateTask.h @@ -27,13 +27,13 @@ class DownloadUpdateTask : public Task Q_OBJECT public: - explicit DownloadUpdateTask(QString repoUrl, int versionId, QObject* parent=0); + explicit DownloadUpdateTask(QString rootPath, QString repoUrl, int versionId, QObject* parent=0); /*! * Gets the directory that contains the update files. */ QString updateFilesDir(); - + public: // TODO: We should probably put these data structures into a separate header... @@ -130,7 +130,7 @@ protected: /*! * Downloads the version info files from the repository. * The files for both the current build, and the build that we're updating to need to be downloaded. - * If the current version's info file can't be found, MultiMC will not delete files that + * If the current version's info file can't be found, MultiMC will not delete files that * were removed between versions. It will still replace files that have changed, however. * Note that although the repository URL for the current version is not given to the update task, * the task will attempt to look it up in the UpdateChecker's channel list. @@ -142,7 +142,7 @@ protected: * This function is called when version information is finished downloading. * This handles parsing the JSON downloaded by the version info network job and then calls processFileLists. * Note that this function will sometimes be called even if the version info download emits failed. If - * we couldn't download the current version's info file, we can still update. This will be called even if the + * we couldn't download the current version's info file, we can still update. This will be called even if the * current version's info file fails to download, as long as the new version's info file succeeded. */ virtual void parseDownloadedVersionInfo(); @@ -176,7 +176,7 @@ protected: //! Network job for downloading version info files. NetJobPtr m_vinfoNetJob; - + //! Network job for downloading update files. NetJobPtr m_filesNetJob; @@ -188,6 +188,9 @@ protected: int m_cVersionId; QString m_cRepoUrl; + // path to the root of the application + QString m_rootPath; + /*! * Temporary directory to store update files in. * This will be set to not auto delete. Task will fail if this fails to be created. @@ -199,9 +202,9 @@ protected: * This fixes destination paths for OSX. * The updater runs in MultiMC.app/Contents/MacOs by default * The destination paths are such as this: MultiMC.app/blah/blah - * + * * Therefore we chop off the 'MultiMC.app' prefix - * + * * Returns false if the path couldn't be fixed (is invalid) */ static bool fixPathForOSX(QString &path); diff --git a/logic/updater/NotificationChecker.cpp b/logic/updater/NotificationChecker.cpp index 5b458ddd..7a3f314b 100644 --- a/logic/updater/NotificationChecker.cpp +++ b/logic/updater/NotificationChecker.cpp @@ -4,9 +4,10 @@ #include <QJsonObject> #include <QJsonArray> -#include "MultiMC.h" +#include "logic/Env.h" #include "BuildConfig.h" #include "logic/net/CacheDownload.h" +#include "logger/QsLog.h" NotificationChecker::NotificationChecker(QObject *parent) : QObject(parent), m_notificationsUrl(QUrl(BuildConfig.NOTIFICATION_URL)) @@ -43,7 +44,7 @@ void NotificationChecker::checkForNotifications() return; } m_checkJob.reset(new NetJob("Checking for notifications")); - auto entry = MMC->metacache()->resolveEntry("root", "notifications.json"); + auto entry = ENV.metacache()->resolveEntry("root", "notifications.json"); entry->stale = true; m_checkJob->addNetAction(m_download = CacheDownload::make(m_notificationsUrl, entry)); connect(m_download.get(), &CacheDownload::succeeded, this, diff --git a/logic/updater/UpdateChecker.cpp b/logic/updater/UpdateChecker.cpp index c5cd2c2f..cd0b3c72 100644 --- a/logic/updater/UpdateChecker.cpp +++ b/logic/updater/UpdateChecker.cpp @@ -15,23 +15,19 @@ #include "UpdateChecker.h" -#include "MultiMC.h" -#include "BuildConfig.h" - #include "logger/QsLog.h" #include <QJsonObject> #include <QJsonArray> #include <QJsonValue> -#include "logic/settings/SettingsObject.h" - #define API_VERSION 0 #define CHANLIST_FORMAT 0 -UpdateChecker::UpdateChecker() +UpdateChecker::UpdateChecker(QString channelListUrl, int currentBuild) { - m_channelListUrl = BuildConfig.CHANLIST_URL; + m_channelListUrl = channelListUrl; + m_currentBuild = currentBuild; m_updateChecking = false; m_chanListLoading = false; m_checkUpdateWaiting = false; @@ -48,7 +44,7 @@ bool UpdateChecker::hasChannels() const return !m_channels.isEmpty(); } -void UpdateChecker::checkForUpdate(bool notifyNoUpdate) +void UpdateChecker::checkForUpdate(QString updateChannel, bool notifyNoUpdate) { QLOG_DEBUG() << "Checking for updates."; @@ -59,6 +55,7 @@ void UpdateChecker::checkForUpdate(bool notifyNoUpdate) QLOG_DEBUG() << "Channel list isn't loaded yet. Loading channel list and deferring " "update check."; m_checkUpdateWaiting = true; + m_deferredUpdateChannel = updateChannel; updateChanList(notifyNoUpdate); return; } @@ -71,9 +68,6 @@ void UpdateChecker::checkForUpdate(bool notifyNoUpdate) m_updateChecking = true; - // Get the channel we're checking. - QString updateChannel = MMC->settings()->get("UpdateChannel").toString(); - // Find the desired channel within the channel list and get its repo URL. If if cannot be // found, error. m_repoUrl = ""; @@ -149,7 +143,7 @@ void UpdateChecker::updateCheckFinished(bool notifyNoUpdate) // We've got the version with the greatest ID number. Now compare it to our current build // number and update if they're different. int newBuildNumber = newestVersion.value("Id").toVariant().toInt(); - if (newBuildNumber != BuildConfig.VERSION_BUILD) + if (newBuildNumber != m_currentBuild) { QLOG_DEBUG() << "Found newer version with ID" << newBuildNumber; // Update! @@ -251,7 +245,7 @@ void UpdateChecker::chanListDownloadFinished(bool notifyNoUpdate) // If we're waiting to check for updates, do that now. if (m_checkUpdateWaiting) - checkForUpdate(notifyNoUpdate); + checkForUpdate(m_deferredUpdateChannel, notifyNoUpdate); emit channelListLoaded(); } diff --git a/logic/updater/UpdateChecker.h b/logic/updater/UpdateChecker.h index 7c49b6e0..2b08680a 100644 --- a/logic/updater/UpdateChecker.h +++ b/logic/updater/UpdateChecker.h @@ -24,10 +24,8 @@ class UpdateChecker : public QObject Q_OBJECT public: - UpdateChecker(); - void checkForUpdate(bool notifyNoUpdate); - - void setChannelListUrl(const QString &url) { m_channelListUrl = url; } + UpdateChecker(QString channelListUrl, int currentBuild); + void checkForUpdate(QString updateChannel, bool notifyNoUpdate); /*! * Causes the update checker to download the channel list from the URL specified in config.h (generated by CMake). @@ -107,5 +105,11 @@ private: * When the channel list finishes loading, if this is true, the update checker will check for updates. */ bool m_checkUpdateWaiting; + + /*! + * if m_checkUpdateWaiting, this is the last used update channel + */ + QString m_deferredUpdateChannel; + int m_currentBuild = -1; }; diff --git a/tests/tst_DownloadUpdateTask.cpp b/tests/tst_DownloadUpdateTask.cpp index e6784402..8d8905b5 100644 --- a/tests/tst_DownloadUpdateTask.cpp +++ b/tests/tst_DownloadUpdateTask.cpp @@ -91,7 +91,7 @@ slots: void test_writeInstallScript() { - DownloadUpdateTask task( + DownloadUpdateTask task(QCoreApplication::applicationDirPath(), QUrl::fromLocalFile(QDir::current().absoluteFilePath("tests/data/")).toString(), 0); DownloadUpdateTask::UpdateOperationList ops; @@ -105,7 +105,7 @@ slots: QCOMPARE(TestsInternal::readFileUtf8(script).replace(QRegExp("[\r\n]+"), "\n"), MULTIMC_GET_TEST_FILE_UTF8(testFile).replace(QRegExp("[\r\n]+"), "\n")); } - + // DISABLED: fails. /* void test_parseVersionInfo_data() @@ -166,7 +166,7 @@ slots: QTest::addColumn<DownloadUpdateTask::VersionFileList>("newVersion"); QTest::addColumn<DownloadUpdateTask::UpdateOperationList>("expectedOperations"); - DownloadUpdateTask *downloader = new DownloadUpdateTask(QString(), -1); + DownloadUpdateTask *downloader = new DownloadUpdateTask(QCoreApplication::applicationDirPath(), QString(), -1); // update fileOne, keep fileTwo, remove fileThree QTest::newRow("test 1") diff --git a/tests/tst_UpdateChecker.cpp b/tests/tst_UpdateChecker.cpp index 8ed82faf..49a4a6a3 100644 --- a/tests/tst_UpdateChecker.cpp +++ b/tests/tst_UpdateChecker.cpp @@ -1,10 +1,6 @@ #include <QTest> #include <QSignalSpy> -#include "logic/settings/SettingsObject.h" -#include "logic/settings/Setting.h" - -#include "BuildConfig.h" #include "TestUtil.h" #include "logic/updater/UpdateChecker.h" @@ -24,19 +20,6 @@ QDebug operator<<(QDebug dbg, const UpdateChecker::ChannelListEntry &c) return dbg.maybeSpace(); } -class ResetSetting -{ -public: - ResetSetting(std::shared_ptr<Setting> setting) : setting(setting), oldValue(setting->get()) {} - ~ResetSetting() - { - setting->set(oldValue); - } - - std::shared_ptr<Setting> setting; - QVariant oldValue; -}; - class UpdateCheckerTest : public QObject { Q_OBJECT @@ -99,7 +82,6 @@ slots: } void tst_ChannelListParsing() { - ResetSetting resetUpdateChannel(MMC->settings()->getSetting("UpdateChannel")); QFETCH(QString, channel); QFETCH(QString, channelUrl); @@ -107,15 +89,11 @@ slots: QFETCH(bool, valid); QFETCH(QList<UpdateChecker::ChannelListEntry>, result); - MMC->settings()->set("UpdateChannel", channel); - - UpdateChecker checker; + UpdateChecker checker(channelUrl, 0); QSignalSpy channelListLoadedSpy(&checker, SIGNAL(channelListLoaded())); QVERIFY(channelListLoadedSpy.isValid()); - checker.setChannelListUrl(channelUrl); - checker.updateChanList(false); if (valid) @@ -147,18 +125,12 @@ slots: } void tst_UpdateChecking() { - ResetSetting resetUpdateChannel(MMC->settings()->getSetting("UpdateChannel")); - QFETCH(QString, channel); QFETCH(QString, channelUrl); QFETCH(int, currentBuild); QFETCH(QList<QVariant>, result); - MMC->settings()->set("UpdateChannel", channel); - BuildConfig.VERSION_BUILD = currentBuild; - - UpdateChecker checker; - checker.setChannelListUrl(channelUrl); + UpdateChecker checker(channelUrl, currentBuild); QSignalSpy updateAvailableSpy(&checker, SIGNAL(updateAvailable(QString,QString,int))); QVERIFY(updateAvailableSpy.isValid()); @@ -170,7 +142,7 @@ slots: checker.m_channels[0].url = QUrl::fromLocalFile(QDir::current().absoluteFilePath("tests/data/")).toString(); - checker.checkForUpdate(false); + checker.checkForUpdate(channel, false); QVERIFY(updateAvailableSpy.wait()); QList<QVariant> res = result; |