NOISSUE Split MultiMC app object into MultiMC and Env

This commit is contained in:
Petr Mrázek 2015-01-31 16:59:03 +01:00
parent e508728246
commit 6f3aa65bd6
44 changed files with 343 additions and 325 deletions

View File

@ -432,6 +432,8 @@ SET(MULTIMC_SOURCES
logic/DefaultVariable.h logic/DefaultVariable.h
# network stuffs # network stuffs
logic/Env.h
logic/Env.cpp
logic/net/NetAction.h logic/net/NetAction.h
logic/net/MD5EtagDownload.h logic/net/MD5EtagDownload.h
logic/net/MD5EtagDownload.cpp logic/net/MD5EtagDownload.cpp

View File

@ -23,6 +23,7 @@
#include "logic/net/HttpMetaCache.h" #include "logic/net/HttpMetaCache.h"
#include "logic/net/URLConstants.h" #include "logic/net/URLConstants.h"
#include "logic/Env.h"
#include "logic/java/JavaUtils.h" #include "logic/java/JavaUtils.h"
@ -108,8 +109,9 @@ MultiMC::MultiMC(int &argc, char **argv, bool test_mode) : QApplication(argc, ar
return; return;
} }
} }
origcwdPath = QDir::currentPath();
binPath = applicationDirPath(); QString origcwdPath = QDir::currentPath();
QString binPath = applicationDirPath();
QString adjustedBy; QString adjustedBy;
// change directory // change directory
QString dirParam = args["dir"].toString(); QString dirParam = args["dir"].toString();
@ -191,7 +193,7 @@ MultiMC::MultiMC(int &argc, char **argv, bool test_mode) : QApplication(argc, ar
initTranslations(); initTranslations();
// initialize the updater // initialize the updater
m_updateChecker.reset(new UpdateChecker()); m_updateChecker.reset(new UpdateChecker(BuildConfig.CHANLIST_URL, BuildConfig.VERSION_BUILD));
m_translationChecker.reset(new TranslationDownloader()); m_translationChecker.reset(new TranslationDownloader());
@ -219,15 +221,22 @@ MultiMC::MultiMC(int &argc, char **argv, bool test_mode) : QApplication(argc, ar
m_accounts->loadList(); m_accounts->loadList();
// init the http meta cache // init the http meta cache
initHttpMetaCache(); ENV.initHttpMetaCache(rootPath, staticDataPath);
// create the global network manager // create the global network manager
m_qnam.reset(new QNetworkAccessManager(this)); ENV.m_qnam.reset(new QNetworkAccessManager(this));
m_translationChecker->downloadTranslations();
// init proxy settings // 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? //FIXME: what to do with these?
m_profilers.insert("jprofiler", m_profilers.insert("jprofiler",
@ -285,7 +294,7 @@ void MultiMC::initTranslations()
} }
m_mmc_translator.reset(new QTranslator()); 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" QLOG_DEBUG() << "Loading MMC Language File for"
<< locale.bcp47Name().toLocal8Bit().constData() << "..."; << locale.bcp47Name().toLocal8Bit().constData() << "...";
@ -335,9 +344,6 @@ void MultiMC::initGlobalSettings(bool test_mode)
m_settings->registerSetting("AutoUpdate", true); m_settings->registerSetting("AutoUpdate", true);
m_settings->registerSetting("IconTheme", QString("multimc")); m_settings->registerSetting("IconTheme", QString("multimc"));
// Minecraft Sneaky Updates
m_settings->registerSetting("AutoUpdateMinecraftVersions", true);
// Notifications // Notifications
m_settings->registerSetting("ShownNotifications", QString()); m_settings->registerSetting("ShownNotifications", QString());
@ -530,99 +536,17 @@ void MultiMC::initGlobalSettings(bool test_mode)
m_settings->registerSetting("PagedGeometry", ""); 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() std::shared_ptr<IconList> MultiMC::icons()
{ {
if (!m_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; return m_icons;
} }
@ -690,13 +614,13 @@ void MultiMC::installUpdates(const QString updateFilesDir, UpdateFlags flags)
QLOG_INFO() << "Installing updates."; QLOG_INFO() << "Installing updates.";
#ifdef WINDOWS #ifdef WINDOWS
QString finishCmd = applicationFilePath(); QString finishCmd = applicationFilePath();
QString updaterBinary = PathCombine(bin(), "updater.exe"); QString updaterBinary = PathCombine(applicationDirPath(), "updater.exe");
#elif LINUX #elif LINUX
QString finishCmd = PathCombine(root(), "MultiMC"); QString finishCmd = PathCombine(root(), "MultiMC");
QString updaterBinary = PathCombine(bin(), "updater"); QString updaterBinary = PathCombine(applicationDirPath(), "updater");
#elif OSX #elif OSX
QString finishCmd = applicationFilePath(); QString finishCmd = applicationFilePath();
QString updaterBinary = PathCombine(bin(), "updater"); QString updaterBinary = PathCombine(applicationDirPath(), "updater");
#else #else
#error Unsupported operating system. #error Unsupported operating system.
#endif #endif
@ -713,7 +637,7 @@ void MultiMC::installUpdates(const QString updateFilesDir, UpdateFlags flags)
if (flags & RestartOnFinish) if (flags & RestartOnFinish)
{ {
args << "--finish-cmd" << finishCmd; args << "--finish-cmd" << finishCmd;
args << "--finish-dir" << data(); args << "--finish-dir" << dataPath;
} }
QLOG_INFO() << "Running updater with command" << updaterBinary << args.join(" "); QLOG_INFO() << "Running updater with command" << updaterBinary << args.join(" ");
QFile::setPermissions(updaterBinary, (QFileDevice::Permission)0x7755); QFile::setPermissions(updaterBinary, (QFileDevice::Permission)0x7755);
@ -724,6 +648,7 @@ void MultiMC::installUpdates(const QString updateFilesDir, UpdateFlags flags)
return; return;
} }
ENV.destroy();
// Now that we've started the updater, quit MultiMC. // Now that we've started the updater, quit MultiMC.
quit(); quit();
} }
@ -744,6 +669,7 @@ void MultiMC::onExit()
{ {
installUpdates(m_updateOnExitPath, m_updateOnExitFlags); installUpdates(m_updateOnExitPath, m_updateOnExitFlags);
} }
ENV.destroy();
} }
bool MultiMC::openJsonEditor(const QString &filename) bool MultiMC::openJsonEditor(const QString &filename)

View File

@ -40,6 +40,9 @@ Q_DECLARE_OPERATORS_FOR_FLAGS(UpdateFlags);
class MultiMC : public QApplication class MultiMC : public QApplication
{ {
// friends for the purpose of limiting access to deprecated stuff
friend class MultiMCPage;
friend class MainWindow;
Q_OBJECT Q_OBJECT
public: public:
enum Status enum Status
@ -53,106 +56,92 @@ public:
MultiMC(int &argc, char **argv, bool test_mode = false); MultiMC(int &argc, char **argv, bool test_mode = false);
virtual ~MultiMC(); virtual ~MultiMC();
// InstanceList, IconList, OneSixFTBInstance, LegacyUpdate, LegacyInstance, MCEditTool, JVisualVM, MinecraftInstance, JProfiler, BaseInstance
std::shared_ptr<SettingsObject> settings() std::shared_ptr<SettingsObject> settings()
{ {
return m_settings; return m_settings;
} }
// InstanceList, OneSixUpdate, MinecraftInstance, OneSixProfileStrategy
std::shared_ptr<MinecraftVersionList> minecraftlist();
std::shared_ptr<InstanceList> instances() // LegacyInstance, BaseInstance, OneSixInstance, InstanceList
{
return m_instances;
}
std::shared_ptr<MojangAccountList> accounts()
{
return m_accounts;
}
std::shared_ptr<IconList> icons(); std::shared_ptr<IconList> icons();
QIcon getThemedIcon(const QString& name); QIcon getThemedIcon(const QString& name);
void setIconTheme(const QString& name); void setIconTheme(const QString& name);
Status status() // DownloadUpdateTask
{
return m_status;
}
std::shared_ptr<QNetworkAccessManager> qnam()
{
return m_qnam;
}
std::shared_ptr<HttpMetaCache> metacache()
{
return m_metacache;
}
std::shared_ptr<UpdateChecker> updateChecker() std::shared_ptr<UpdateChecker> updateChecker()
{ {
return m_updateChecker; return m_updateChecker;
} }
// LegacyUpdate
std::shared_ptr<LWJGLVersionList> lwjgllist(); std::shared_ptr<LWJGLVersionList> lwjgllist();
// APPLICATION ONLY
std::shared_ptr<ForgeVersionList> forgelist(); std::shared_ptr<ForgeVersionList> forgelist();
// APPLICATION ONLY
std::shared_ptr<LiteLoaderVersionList> liteloaderlist(); std::shared_ptr<LiteLoaderVersionList> liteloaderlist();
std::shared_ptr<MinecraftVersionList> minecraftlist(); // APPLICATION ONLY
std::shared_ptr<JavaVersionList> javalist(); 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() QMap<QString, std::shared_ptr<BaseProfilerFactory>> profilers()
{ {
return m_profilers; return m_profilers;
} }
// APPLICATION ONLY
QMap<QString, std::shared_ptr<BaseDetachedToolFactory>> tools() QMap<QString, std::shared_ptr<BaseDetachedToolFactory>> tools()
{ {
return m_tools; return m_tools;
} }
// APPLICATION ONLY
void installUpdates(const QString updateFilesDir, UpdateFlags flags = None); 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 * Opens a json file using either a system default editor, or, if note empty, the editor
* specified in the settings * specified in the settings
*/ */
bool openJsonEditor(const QString &filename); 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. /// this is the static data. it stores things that don't move.
const QString &staticData() const QString &staticData()
{ {
return staticDataPath; return staticDataPath;
} }
// FIXME: remove. used by MainWindow to create application update tasks
/// this is the root of the 'installation'. Used for automatic updates /// this is the root of the 'installation'. Used for automatic updates
const QString &root() const QString &root()
{ {
return rootPath; 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: private slots:
/** /**
@ -165,8 +154,6 @@ private:
void initGlobalSettings(bool test_mode); void initGlobalSettings(bool test_mode);
void initHttpMetaCache();
void initTranslations(); void initTranslations();
private: private:
@ -180,8 +167,6 @@ private:
std::shared_ptr<UpdateChecker> m_updateChecker; std::shared_ptr<UpdateChecker> m_updateChecker;
std::shared_ptr<MojangAccountList> m_accounts; std::shared_ptr<MojangAccountList> m_accounts;
std::shared_ptr<IconList> m_icons; 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<LWJGLVersionList> m_lwjgllist;
std::shared_ptr<ForgeVersionList> m_forgelist; std::shared_ptr<ForgeVersionList> m_forgelist;
std::shared_ptr<LiteLoaderVersionList> m_liteloaderlist; std::shared_ptr<LiteLoaderVersionList> m_liteloaderlist;
@ -200,9 +185,7 @@ private:
QString rootPath; QString rootPath;
QString staticDataPath; QString staticDataPath;
QString binPath;
QString dataPath; QString dataPath;
QString origcwdPath;
Status m_status = MultiMC::Failed; Status m_status = MultiMC::Failed;
}; };

View File

@ -375,6 +375,7 @@ namespace Ui {
#include "logic/net/URLConstants.h" #include "logic/net/URLConstants.h"
#include "logic/net/NetJob.h" #include "logic/net/NetJob.h"
#include "logic/Env.h"
#include "logic/BaseInstance.h" #include "logic/BaseInstance.h"
#include "logic/OneSixInstance.h" #include "logic/OneSixInstance.h"
@ -572,7 +573,7 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWi
{ {
for (auto profile : account->profiles()) 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( auto action = CacheDownload::make(
QUrl("http://" + URLConstants::SKINS_BASE + profile.name + ".png"), meta); QUrl("http://" + URLConstants::SKINS_BASE + profile.name + ".png"), meta);
skin_dls.append(action); skin_dls.append(action);
@ -619,7 +620,7 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWi
if (MMC->settings()->get("AutoUpdate").toBool()) if (MMC->settings()->get("AutoUpdate").toBool())
{ {
auto updater = MMC->updateChecker(); auto updater = MMC->updateChecker();
updater->checkForUpdate(false); updater->checkForUpdate(MMC->settings()->get("UpdateChannel").toString(), false);
} }
m_notificationChecker.reset(new NotificationChecker()); m_notificationChecker.reset(new NotificationChecker());
connect(m_notificationChecker.get(), 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 // Doing so is a bit complicated, because we'd have to make sure it finished downloading
// before actually exiting MultiMC. // before actually exiting MultiMC.
ProgressDialog updateDlg(this); ProgressDialog updateDlg(this);
DownloadUpdateTask updateTask(repo, versionId, &updateDlg); DownloadUpdateTask updateTask(MMC->root(), repo, versionId, &updateDlg);
// If the task succeeds, install the updates. // If the task succeeds, install the updates.
if (updateDlg.exec(&updateTask)) if (updateDlg.exec(&updateTask))
{ {
@ -1070,7 +1071,7 @@ void MainWindow::instanceFromZipPack(QString instName, QString instGroup, QStrin
else else
{ {
const QString path = url.host() + '/' + url.path(); 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); CacheDownloadPtr dl = CacheDownload::make(url, entry);
NetJob job(tr("Modpack download")); NetJob job(tr("Modpack download"));
job.addNetAction(dl); job.addNetAction(dl);
@ -1357,7 +1358,7 @@ void MainWindow::on_actionConfig_Folder_triggered()
void MainWindow::on_actionCheckUpdate_triggered() void MainWindow::on_actionCheckUpdate_triggered()
{ {
auto updater = MMC->updateChecker(); auto updater = MMC->updateChecker();
updater->checkForUpdate(true); updater->checkForUpdate(MMC->settings()->get("UpdateChannel").toString(), true);
} }
template <typename T> template <typename T>

View File

@ -29,6 +29,7 @@
#include "logic/LegacyInstance.h" #include "logic/LegacyInstance.h"
#include "logic/forge/ForgeVersion.h" #include "logic/forge/ForgeVersion.h"
#include "logic/forge/ForgeVersionList.h" #include "logic/forge/ForgeVersionList.h"
#include "logic/Env.h"
#include "MultiMC.h" #include "MultiMC.h"
LegacyJarModPage::LegacyJarModPage(LegacyInstance *inst, QWidget *parent) LegacyJarModPage::LegacyJarModPage(LegacyInstance *inst, QWidget *parent)
@ -109,7 +110,7 @@ void LegacyJarModPage::on_addForgeBtn_clicked()
std::dynamic_pointer_cast<ForgeVersion>(vselect.selectedVersion()); std::dynamic_pointer_cast<ForgeVersion>(vselect.selectedVersion());
if (!forge) if (!forge)
return; return;
auto entry = MMC->metacache()->resolveEntry("minecraftforge", forge->filename()); auto entry = Env::getInstance().metacache()->resolveEntry("minecraftforge", forge->filename());
if (entry->stale) if (entry->stale)
{ {
NetJob *fjob = new NetJob("Forge download"); NetJob *fjob = new NetJob("Forge download");

View File

@ -22,6 +22,7 @@
#include "logic/net/NetJob.h" #include "logic/net/NetJob.h"
#include "logic/net/URLConstants.h" #include "logic/net/URLConstants.h"
#include "logic/Env.h"
#include "gui/dialogs/EditAccountDialog.h" #include "gui/dialogs/EditAccountDialog.h"
#include "gui/dialogs/ProgressDialog.h" #include "gui/dialogs/ProgressDialog.h"
@ -129,7 +130,7 @@ void AccountListPage::addAccount(const QString &errMsg)
for (AccountProfile profile : account->profiles()) 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( auto action = CacheDownload::make(
QUrl("http://" + URLConstants::SKINS_BASE + profile.name + ".png"), meta); QUrl("http://" + URLConstants::SKINS_BASE + profile.name + ".png"), meta);
job->addNetAction(action); job->addNetAction(action);

View File

@ -74,8 +74,6 @@ void MinecraftPage::on_maximizedCheckBox_clicked(bool checked)
void MinecraftPage::applySettings() void MinecraftPage::applySettings()
{ {
auto s = MMC->settings(); auto s = MMC->settings();
// Minecraft version updates
s->set("AutoUpdateMinecraftVersions", ui->autoupdateMinecraft->isChecked());
// Window Size // Window Size
s->set("LaunchMaximized", ui->maximizedCheckBox->isChecked()); s->set("LaunchMaximized", ui->maximizedCheckBox->isChecked());
@ -86,8 +84,6 @@ void MinecraftPage::applySettings()
void MinecraftPage::loadSettings() void MinecraftPage::loadSettings()
{ {
auto s = MMC->settings(); auto s = MMC->settings();
// Minecraft version updates
ui->autoupdateMinecraft->setChecked(s->get("AutoUpdateMinecraftVersions").toBool());
// Window Size // Window Size
ui->maximizedCheckBox->setChecked(s->get("LaunchMaximized").toBool()); ui->maximizedCheckBox->setChecked(s->get("LaunchMaximized").toBool());

View File

@ -7,7 +7,7 @@
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>545</width> <width>545</width>
<height>270</height> <height>195</height>
</rect> </rect>
</property> </property>
<property name="sizePolicy"> <property name="sizePolicy">
@ -49,22 +49,6 @@
<string>Minecraft</string> <string>Minecraft</string>
</attribute> </attribute>
<layout class="QVBoxLayout" name="verticalLayout_3"> <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> <item>
<widget class="QGroupBox" name="windowSizeGroupBox"> <widget class="QGroupBox" name="windowSizeGroupBox">
<property name="title"> <property name="title">
@ -155,7 +139,6 @@
</widget> </widget>
<tabstops> <tabstops>
<tabstop>tabWidget</tabstop> <tabstop>tabWidget</tabstop>
<tabstop>autoupdateMinecraft</tabstop>
<tabstop>maximizedCheckBox</tabstop> <tabstop>maximizedCheckBox</tabstop>
<tabstop>windowWidthSpinBox</tabstop> <tabstop>windowWidthSpinBox</tabstop>
<tabstop>windowHeightSpinBox</tabstop> <tabstop>windowHeightSpinBox</tabstop>

104
logic/Env.cpp Normal file
View File

@ -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;
}

44
logic/Env.h Normal file
View File

@ -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;
};

View File

@ -25,13 +25,13 @@
#include "logic/minecraft/MinecraftVersionList.h" #include "logic/minecraft/MinecraftVersionList.h"
#include "logic/BaseInstance.h" #include "logic/BaseInstance.h"
#include "logic/LegacyInstance.h" #include "logic/LegacyInstance.h"
#include "MultiMC.h" #include "logic/Env.h"
#include "logic/ModList.h" #include "logic/ModList.h"
#include "logger/QsLog.h" #include "logger/QsLog.h"
#include "logic/net/URLConstants.h" #include "logic/net/URLConstants.h"
#include "JarUtils.h" #include "JarUtils.h"
#include "MultiMC.h"
LegacyUpdate::LegacyUpdate(BaseInstance *inst, QObject *parent) : Task(parent), m_inst(inst) LegacyUpdate::LegacyUpdate(BaseInstance *inst, QObject *parent) : Task(parent), m_inst(inst)
{ {
@ -110,7 +110,7 @@ void LegacyUpdate::fmllibsStart()
// download missing libs to our place // download missing libs to our place
setStatus(tr("Dowloading FML libraries...")); setStatus(tr("Dowloading FML libraries..."));
auto dljob = new NetJob("FML libraries"); auto dljob = new NetJob("FML libraries");
auto metacache = MMC->metacache(); auto metacache = ENV.metacache();
for (auto &lib : fmlLibsToProcess) for (auto &lib : fmlLibsToProcess)
{ {
auto entry = metacache->resolveEntry("fmllibs", lib.filename); auto entry = metacache->resolveEntry("fmllibs", lib.filename);
@ -133,7 +133,7 @@ void LegacyUpdate::fmllibsFinished()
{ {
setStatus(tr("Copying FML libraries into the instance...")); setStatus(tr("Copying FML libraries into the instance..."));
LegacyInstance *inst = (LegacyInstance *)m_inst; LegacyInstance *inst = (LegacyInstance *)m_inst;
auto metacache = MMC->metacache(); auto metacache = ENV.metacache();
int index = 0; int index = 0;
for (auto &lib : fmlLibsToProcess) for (auto &lib : fmlLibsToProcess)
{ {
@ -197,7 +197,7 @@ void LegacyUpdate::lwjglStart()
QString url = version->url(); QString url = version->url();
QUrl realUrl(url); QUrl realUrl(url);
QString hostname = realUrl.host(); QString hostname = realUrl.host();
auto worker = MMC->qnam(); auto worker = ENV.qnam();
QNetworkRequest req(realUrl); QNetworkRequest req(realUrl);
req.setRawHeader("Host", hostname.toLatin1()); req.setRawHeader("Host", hostname.toLatin1());
req.setHeader(QNetworkRequest::UserAgentHeader, "MultiMC/5.0 (Cached)"); req.setHeader(QNetworkRequest::UserAgentHeader, "MultiMC/5.0 (Cached)");
@ -222,7 +222,7 @@ void LegacyUpdate::lwjglFinished(QNetworkReply *reply)
"a row. YMMV"); "a row. YMMV");
return; 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 // Here i check if there is a cookie for me in the reply and extract it
QList<QNetworkCookie> cookies = QList<QNetworkCookie> cookies =
qvariant_cast<QList<QNetworkCookie>>(reply->header(QNetworkRequest::SetCookieHeader)); 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 dljob = new NetJob("Minecraft.jar for version " + version_id);
auto metacache = MMC->metacache(); auto metacache = ENV.metacache();
auto entry = metacache->resolveEntry("versions", localPath); auto entry = metacache->resolveEntry("versions", localPath);
dljob->addNetAction(CacheDownload::make(QUrl(urlstr), entry)); dljob->addNetAction(CacheDownload::make(QUrl(urlstr), entry));
connect(dljob, SIGNAL(succeeded()), SLOT(jarFinished())); connect(dljob, SIGNAL(succeeded()), SLOT(jarFinished()));

View File

@ -14,7 +14,7 @@
*/ */
#include "LwjglVersionList.h" #include "LwjglVersionList.h"
#include "MultiMC.h" #include "logic/Env.h"
#include <QtNetwork> #include <QtNetwork>
#include <QtXml> #include <QtXml>
@ -82,7 +82,7 @@ void LWJGLVersionList::loadList()
Q_ASSERT_X(!m_loading, "loadList", "list is already loading (m_loading is true)"); Q_ASSERT_X(!m_loading, "loadList", "list is already loading (m_loading is true)");
setLoading(true); setLoading(true);
auto worker = MMC->qnam(); auto worker = ENV.qnam();
QNetworkRequest req(QUrl(RSS_URL)); QNetworkRequest req(QUrl(RSS_URL));
req.setRawHeader("Accept", "application/rss+xml, text/xml, */*"); req.setRawHeader("Accept", "application/rss+xml, text/xml, */*");
req.setRawHeader("User-Agent", "MultiMC/5.0 (Uncached)"); req.setRawHeader("User-Agent", "MultiMC/5.0 (Uncached)");

View File

@ -14,6 +14,7 @@
*/ */
#include "MultiMC.h" #include "MultiMC.h"
#include "logic/Env.h"
#include "OneSixUpdate.h" #include "OneSixUpdate.h"
#include <QtNetwork> #include <QtNetwork>
@ -94,7 +95,7 @@ void OneSixUpdate::assetIndexStart()
QString localPath = assetName + ".json"; QString localPath = assetName + ".json";
auto job = new NetJob(tr("Asset index for %1").arg(inst->name())); 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); auto entry = metacache->resolveEntry("asset_indexes", localPath);
job->addNetAction(CacheDownload::make(indexUrl, entry)); job->addNetAction(CacheDownload::make(indexUrl, entry));
jarlibDownloadJob.reset(job); jarlibDownloadJob.reset(job);
@ -118,7 +119,7 @@ void OneSixUpdate::assetIndexFinished()
QString asset_fname = "assets/indexes/" + assetName + ".json"; QString asset_fname = "assets/indexes/" + assetName + ".json";
if (!AssetsUtils::loadAssetsIndexJson(asset_fname, &index)) if (!AssetsUtils::loadAssetsIndexJson(asset_fname, &index))
{ {
auto metacache = MMC->metacache(); auto metacache = ENV.metacache();
auto entry = metacache->resolveEntry("asset_indexes", assetName + ".json"); auto entry = metacache->resolveEntry("asset_indexes", assetName + ".json");
metacache->evictEntry(entry); metacache->evictEntry(entry);
emitFailed(tr("Failed to read the assets index!")); 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 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); auto entry = metacache->resolveEntry("versions", localPath);
job->addNetAction(CacheDownload::make(QUrl(urlstr), entry)); job->addNetAction(CacheDownload::make(QUrl(urlstr), entry));
jarHashOnEntry = entry->md5sum; jarHashOnEntry = entry->md5sum;
@ -211,7 +212,7 @@ void OneSixUpdate::jarlibStart()
auto libs = version->getActiveNativeLibs(); auto libs = version->getActiveNativeLibs();
libs.append(version->getActiveNormalLibs()); libs.append(version->getActiveNormalLibs());
auto metacache = MMC->metacache(); auto metacache = ENV.metacache();
QList<ForgeXzDownloadPtr> ForgeLibs; QList<ForgeXzDownloadPtr> ForgeLibs;
QList<std::shared_ptr<OneSixLibrary>> brokenLocalLibs; QList<std::shared_ptr<OneSixLibrary>> brokenLocalLibs;
@ -317,7 +318,7 @@ void OneSixUpdate::jarlibFinished()
{ {
auto sourceJarPath = m_inst->versionsPath().absoluteFilePath(version->id + "/" + version->id + ".jar"); auto sourceJarPath = m_inst->versionsPath().absoluteFilePath(version->id + "/" + version->id + ".jar");
QString localPath = 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); auto entry = metacache->resolveEntry("versions", localPath);
QString fullJarPath = entry->getFullPath(); QString fullJarPath = entry->getFullPath();
if(!JarUtils::createModdedJar(sourceJarPath, finalJarPath, jarMods)) if(!JarUtils::createModdedJar(sourceJarPath, finalJarPath, jarMods))
@ -390,7 +391,7 @@ void OneSixUpdate::fmllibsStart()
// download missing libs to our place // download missing libs to our place
setStatus(tr("Dowloading FML libraries...")); setStatus(tr("Dowloading FML libraries..."));
auto dljob = new NetJob("FML libraries"); auto dljob = new NetJob("FML libraries");
auto metacache = MMC->metacache(); auto metacache = ENV.metacache();
for (auto &lib : fmlLibsToProcess) for (auto &lib : fmlLibsToProcess)
{ {
auto entry = metacache->resolveEntry("fmllibs", lib.filename); auto entry = metacache->resolveEntry("fmllibs", lib.filename);
@ -413,7 +414,7 @@ void OneSixUpdate::fmllibsFinished()
{ {
setStatus(tr("Copying FML libraries into the instance...")); setStatus(tr("Copying FML libraries into the instance..."));
OneSixInstance *inst = (OneSixInstance *)m_inst; OneSixInstance *inst = (OneSixInstance *)m_inst;
auto metacache = MMC->metacache(); auto metacache = ENV.metacache();
int index = 0; int index = 0;
for (auto &lib : fmlLibsToProcess) for (auto &lib : fmlLibsToProcess)
{ {

View File

@ -13,9 +13,9 @@
* limitations under the License. * limitations under the License.
*/ */
#include "MultiMC.h"
#include "logic/SkinUtils.h" #include "logic/SkinUtils.h"
#include "net/HttpMetaCache.h" #include "net/HttpMetaCache.h"
#include "logic/Env.h"
#include <QFile> #include <QFile>
#include <QJsonDocument> #include <QJsonDocument>
@ -29,7 +29,7 @@ namespace SkinUtils
*/ */
QPixmap getFaceFromCache(QString username, int height, int width) QPixmap getFaceFromCache(QString username, int height, int width)
{ {
QFile fskin(MMC->metacache() QFile fskin(ENV.metacache()
->resolveEntry("skins", username + ".png") ->resolveEntry("skins", username + ".png")
->getFullPath()); ->getFullPath());

View File

@ -19,9 +19,10 @@
#include <QJsonParseError> #include <QJsonParseError>
#include <QJsonDocument> #include <QJsonDocument>
#include <QJsonObject> #include <QJsonObject>
#include <QVariant>
#include <logger/QsLog.h>
#include "AssetsUtils.h" #include "AssetsUtils.h"
#include "MultiMC.h"
#include <pathutils.h> #include <pathutils.h>
namespace AssetsUtils namespace AssetsUtils

View File

@ -22,10 +22,12 @@
#include <QNetworkReply> #include <QNetworkReply>
#include <QByteArray> #include <QByteArray>
#include <MultiMC.h> #include <logic/Env.h>
#include <logic/auth/MojangAccount.h> #include <logic/auth/MojangAccount.h>
#include <logic/net/URLConstants.h> #include <logic/net/URLConstants.h>
#include "logger/QsLog.h"
YggdrasilTask::YggdrasilTask(MojangAccount *account, QObject *parent) YggdrasilTask::YggdrasilTask(MojangAccount *account, QObject *parent)
: Task(parent), m_account(account) : 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. // Get the content of the request we're going to send to the server.
QJsonDocument doc(getRequestContent()); QJsonDocument doc(getRequestContent());
auto worker = MMC->qnam(); auto worker = ENV.qnam();
QUrl reqUrl("https://" + URLConstants::AUTH_BASE + getEndpoint()); QUrl reqUrl("https://" + URLConstants::AUTH_BASE + getEndpoint());
QNetworkRequest netRequest(reqUrl); QNetworkRequest netRequest(reqUrl);
netRequest.setHeader(QNetworkRequest::ContentTypeHeader, "application/json"); netRequest.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");

View File

@ -21,6 +21,7 @@
#include "logic/OneSixInstance.h" #include "logic/OneSixInstance.h"
#include "logic/forge/ForgeVersionList.h" #include "logic/forge/ForgeVersionList.h"
#include "logic/minecraft/VersionFilterData.h" #include "logic/minecraft/VersionFilterData.h"
#include "logic/Env.h"
#include <quazip.h> #include <quazip.h>
#include <quazipfile.h> #include <quazipfile.h>
@ -28,7 +29,7 @@
#include <QStringList> #include <QStringList>
#include <QRegularExpression> #include <QRegularExpression>
#include <QRegularExpressionMatch> #include <QRegularExpressionMatch>
#include "MultiMC.h"
#include <QJsonDocument> #include <QJsonDocument>
#include <QJsonArray> #include <QJsonArray>
#include <QSaveFile> #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 // where do we put the library? decode the mojang path
OneSixLibrary lib(libraryName); OneSixLibrary lib(libraryName);
auto cacheentry = MMC->metacache()->resolveEntry("libraries", lib.storagePath()); auto cacheentry = ENV.metacache()->resolveEntry("libraries", lib.storagePath());
finalPath = "libraries/" + lib.storagePath(); finalPath = "libraries/" + lib.storagePath();
if (!ensureFilePathExists(finalPath)) if (!ensureFilePathExists(finalPath))
return; return;
@ -110,7 +111,7 @@ void ForgeInstaller::prepare(const QString &filename, const QString &universalUr
cacheentry->stale = false; cacheentry->stale = false;
cacheentry->md5sum = md5sum.result().toHex().constData(); cacheentry->md5sum = md5sum.result().toHex().constData();
MMC->metacache()->updateEntry(cacheentry); ENV.metacache()->updateEntry(cacheentry);
} }
file.close(); file.close();
@ -275,7 +276,7 @@ bool ForgeInstaller::addLegacy(OneSixInstance *to)
{ {
return false; 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()); finalPath = PathCombine(to->jarModsDir(), m_forge_version->filename());
if (!ensureFilePathExists(finalPath)) if (!ensureFilePathExists(finalPath))
{ {
@ -346,7 +347,7 @@ protected:
} }
void prepare(ForgeVersionPtr forgeVersion) 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]() auto installFunction = [this, entry, forgeVersion]()
{ {
if (!install(entry, forgeVersion)) if (!install(entry, forgeVersion))

View File

@ -1,4 +1,4 @@
#include "MultiMC.h" #include "logic/Env.h"
#include "ForgeMirrors.h" #include "ForgeMirrors.h"
#include "logger/QsLog.h" #include "logger/QsLog.h"
#include <algorithm> #include <algorithm>
@ -18,7 +18,7 @@ void ForgeMirrors::start()
QLOG_INFO() << "Downloading " << m_url.toString(); QLOG_INFO() << "Downloading " << m_url.toString();
QNetworkRequest request(m_url); QNetworkRequest request(m_url);
request.setHeader(QNetworkRequest::UserAgentHeader, "MultiMC/5.0 (Uncached)"); request.setHeader(QNetworkRequest::UserAgentHeader, "MultiMC/5.0 (Uncached)");
auto worker = MMC->qnam(); auto worker = ENV.qnam();
QNetworkReply *rep = worker->get(request); QNetworkReply *rep = worker->get(request);
m_reply = std::shared_ptr<QNetworkReply>(rep); m_reply = std::shared_ptr<QNetworkReply>(rep);

View File

@ -17,7 +17,7 @@
#include "logic/forge/ForgeVersion.h" #include "logic/forge/ForgeVersion.h"
#include "logic/net/NetJob.h" #include "logic/net/NetJob.h"
#include "logic/net/URLConstants.h" #include "logic/net/URLConstants.h"
#include "MultiMC.h" #include "logic/Env.h"
#include <QtNetwork> #include <QtNetwork>
#include <QtXml> #include <QtXml>
@ -162,8 +162,8 @@ void ForgeListLoadTask::executeTask()
setStatus(tr("Fetching Forge version lists...")); setStatus(tr("Fetching Forge version lists..."));
auto job = new NetJob("Version index"); auto job = new NetJob("Version index");
// we do not care if the version is stale or not. // we do not care if the version is stale or not.
auto forgeListEntry = MMC->metacache()->resolveEntry("minecraftforge", "list.json"); auto forgeListEntry = ENV.metacache()->resolveEntry("minecraftforge", "list.json");
auto gradleForgeListEntry = MMC->metacache()->resolveEntry("minecraftforge", "json"); auto gradleForgeListEntry = ENV.metacache()->resolveEntry("minecraftforge", "json");
// verify by poking the server. // verify by poking the server.
forgeListEntry->stale = true; forgeListEntry->stale = true;

View File

@ -13,7 +13,7 @@
* limitations under the License. * limitations under the License.
*/ */
#include "MultiMC.h" #include "logic/Env.h"
#include "ForgeXzDownload.h" #include "ForgeXzDownload.h"
#include <pathutils.h> #include <pathutils.h>
@ -67,7 +67,7 @@ void ForgeXzDownload::start()
request.setRawHeader(QString("If-None-Match").toLatin1(), m_entry->etag.toLatin1()); request.setRawHeader(QString("If-None-Match").toLatin1(), m_entry->etag.toLatin1());
request.setHeader(QNetworkRequest::UserAgentHeader, "MultiMC/5.0 (Cached)"); request.setHeader(QNetworkRequest::UserAgentHeader, "MultiMC/5.0 (Cached)");
auto worker = MMC->qnam(); auto worker = ENV.qnam();
QNetworkReply *rep = worker->get(request); QNetworkReply *rep = worker->get(request);
m_reply = std::shared_ptr<QNetworkReply>(rep); m_reply = std::shared_ptr<QNetworkReply>(rep);
@ -382,7 +382,7 @@ void ForgeXzDownload::decompressAndInstall()
m_entry->local_changed_timestamp = m_entry->local_changed_timestamp =
output_file_info.lastModified().toUTC().toMSecsSinceEpoch(); output_file_info.lastModified().toUTC().toMSecsSinceEpoch();
m_entry->stale = false; m_entry->stale = false;
MMC->metacache()->updateEntry(m_entry); ENV.metacache()->updateEntry(m_entry);
m_reply.reset(); m_reply.reset();
emit succeeded(m_index_within_job); emit succeeded(m_index_within_job);

View File

@ -15,18 +15,16 @@
#include "IconList.h" #include "IconList.h"
#include <pathutils.h> #include <pathutils.h>
#include "logic/settings/SettingsObject.h"
#include <QMap> #include <QMap>
#include <QEventLoop> #include <QEventLoop>
#include <QMimeData> #include <QMimeData>
#include <QUrl> #include <QUrl>
#include <QFileSystemWatcher> #include <QFileSystemWatcher>
#include <MultiMC.h> #include <MultiMC.h>
#include <logic/settings/Setting.h>
#define MAX_SIZE 1024 #define MAX_SIZE 1024
IconList::IconList(QObject *parent) : QAbstractListModel(parent) IconList::IconList(QString path, QObject *parent) : QAbstractListModel(parent)
{ {
// add builtin icons // add builtin icons
QDir instance_icons(":/icons/instances/"); QDir instance_icons(":/icons/instances/");
@ -43,10 +41,6 @@ IconList::IconList(QObject *parent) : QAbstractListModel(parent)
SLOT(directoryChanged(QString))); SLOT(directoryChanged(QString)));
connect(m_watcher.get(), SIGNAL(fileChanged(QString)), SLOT(fileChanged(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); directoryChanged(path);
} }

View File

@ -30,7 +30,7 @@ class IconList : public QAbstractListModel
{ {
Q_OBJECT Q_OBJECT
public: public:
explicit IconList(QObject *parent = 0); explicit IconList(QString path, QObject *parent = 0);
virtual ~IconList() {}; virtual ~IconList() {};
QIcon getIcon(QString key); QIcon getIcon(QString key);
@ -64,9 +64,10 @@ private:
IconList &operator=(const IconList &) = delete; IconList &operator=(const IconList &) = delete;
void reindex(); void reindex();
protected public slots:
slots:
void directoryChanged(const QString &path); void directoryChanged(const QString &path);
protected slots:
void fileChanged(const QString &path); void fileChanged(const QString &path);
void SettingChanged(const Setting & setting, QVariant value); void SettingChanged(const Setting & setting, QVariant value);
private: private:

View File

@ -12,7 +12,7 @@ JavaChecker::JavaChecker(QObject *parent) : QObject(parent)
void JavaChecker::performCheck() void JavaChecker::performCheck()
{ {
QString checkerJar = PathCombine(MMC->bin(), "jars", "JavaCheck.jar"); QString checkerJar = PathCombine(QCoreApplication::applicationDirPath(), "jars", "JavaCheck.jar");
QStringList args = {"-jar", checkerJar}; QStringList args = {"-jar", checkerJar};

View File

@ -14,7 +14,7 @@
*/ */
#include "LiteLoaderVersionList.h" #include "LiteLoaderVersionList.h"
#include "MultiMC.h" #include "logic/Env.h"
#include "logic/net/URLConstants.h" #include "logic/net/URLConstants.h"
#include <MMCError.h> #include <MMCError.h>
@ -104,7 +104,7 @@ void LLListLoadTask::executeTask()
setStatus(tr("Loading LiteLoader version list...")); setStatus(tr("Loading LiteLoader version list..."));
auto job = new NetJob("Version index"); auto job = new NetJob("Version index");
// we do not care if the version is stale or not. // 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. // verify by poking the server.
liteloaderEntry->stale = true; liteloaderEntry->stale = true;

View File

@ -151,7 +151,7 @@ QStringList MinecraftProcess::javaArguments() const
args << "-Duser.language=en"; args << "-Duser.language=en";
if (!m_nativeFolder.isEmpty()) if (!m_nativeFolder.isEmpty())
args << QString("-Djava.library.path=%1").arg(m_nativeFolder); 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; return args;
} }

View File

@ -152,9 +152,7 @@ QString MinecraftVersion::getPatchFilename()
bool MinecraftVersion::needsUpdate() bool MinecraftVersion::needsUpdate()
{ {
auto settings = MMC->settings(); return m_versionSource == Remote || hasUpdate();
bool result = m_versionSource == Remote || (hasUpdate() && settings->get("AutoUpdateMinecraftVersions").toBool());
return result;
} }
bool MinecraftVersion::hasUpdate() bool MinecraftVersion::hasUpdate()

View File

@ -18,7 +18,7 @@
#include <QtAlgorithms> #include <QtAlgorithms>
#include <QtNetwork> #include <QtNetwork>
#include "MultiMC.h" #include "logic/Env.h"
#include "MMCError.h" #include "MMCError.h"
#include "MinecraftVersionList.h" #include "MinecraftVersionList.h"
@ -399,7 +399,7 @@ MCVListLoadTask::MCVListLoadTask(MinecraftVersionList *vlist)
void MCVListLoadTask::executeTask() void MCVListLoadTask::executeTask()
{ {
setStatus(tr("Loading instance version list...")); setStatus(tr("Loading instance version list..."));
auto worker = MMC->qnam(); auto worker = ENV.qnam();
vlistReply = worker->get(QNetworkRequest( vlistReply = worker->get(QNetworkRequest(
QUrl("http://" + URLConstants::AWS_DOWNLOAD_VERSIONS + "versions.json"))); QUrl("http://" + URLConstants::AWS_DOWNLOAD_VERSIONS + "versions.json")));
connect(vlistReply, SIGNAL(finished()), this, SLOT(list_downloaded())); connect(vlistReply, SIGNAL(finished()), this, SLOT(list_downloaded()));

View File

@ -26,7 +26,6 @@
#include <modutils.h> #include <modutils.h>
#include <pathutils.h> #include <pathutils.h>
#include "MultiMC.h"
#include "logic/minecraft/VersionBuilder.h" #include "logic/minecraft/VersionBuilder.h"
#include "logic/minecraft/MinecraftProfile.h" #include "logic/minecraft/MinecraftProfile.h"
#include "logic/minecraft/OneSixRule.h" #include "logic/minecraft/OneSixRule.h"

View File

@ -14,7 +14,7 @@
*/ */
#include "ByteArrayDownload.h" #include "ByteArrayDownload.h"
#include "MultiMC.h" #include "logic/Env.h"
#include "logger/QsLog.h" #include "logger/QsLog.h"
ByteArrayDownload::ByteArrayDownload(QUrl url) : NetAction() ByteArrayDownload::ByteArrayDownload(QUrl url) : NetAction()
@ -28,7 +28,7 @@ void ByteArrayDownload::start()
QLOG_INFO() << "Downloading " << m_url.toString(); QLOG_INFO() << "Downloading " << m_url.toString();
QNetworkRequest request(m_url); QNetworkRequest request(m_url);
request.setHeader(QNetworkRequest::UserAgentHeader, "MultiMC/5.0 (Uncached)"); request.setHeader(QNetworkRequest::UserAgentHeader, "MultiMC/5.0 (Uncached)");
auto worker = MMC->qnam(); auto worker = ENV.qnam();
QNetworkReply *rep = worker->get(request); QNetworkReply *rep = worker->get(request);
m_reply = std::shared_ptr<QNetworkReply>(rep); m_reply = std::shared_ptr<QNetworkReply>(rep);

View File

@ -13,7 +13,6 @@
* limitations under the License. * limitations under the License.
*/ */
#include "MultiMC.h"
#include "CacheDownload.h" #include "CacheDownload.h"
#include <pathutils.h> #include <pathutils.h>
@ -21,6 +20,7 @@
#include <QFileInfo> #include <QFileInfo>
#include <QDateTime> #include <QDateTime>
#include "logger/QsLog.h" #include "logger/QsLog.h"
#include "logic/Env.h"
CacheDownload::CacheDownload(QUrl url, MetaEntryPtr entry) CacheDownload::CacheDownload(QUrl url, MetaEntryPtr entry)
: NetAction(), md5sum(QCryptographicHash::Md5) : NetAction(), md5sum(QCryptographicHash::Md5)
@ -74,7 +74,7 @@ void CacheDownload::start()
request.setHeader(QNetworkRequest::UserAgentHeader, "MultiMC/5.0 (Cached)"); request.setHeader(QNetworkRequest::UserAgentHeader, "MultiMC/5.0 (Cached)");
auto worker = MMC->qnam(); auto worker = ENV.qnam();
QNetworkReply *rep = worker->get(request); QNetworkReply *rep = worker->get(request);
m_reply = std::shared_ptr<QNetworkReply>(rep); m_reply = std::shared_ptr<QNetworkReply>(rep);
@ -168,7 +168,7 @@ void CacheDownload::downloadFinished()
m_entry->local_changed_timestamp = m_entry->local_changed_timestamp =
output_file_info.lastModified().toUTC().toMSecsSinceEpoch(); output_file_info.lastModified().toUTC().toMSecsSinceEpoch();
m_entry->stale = false; m_entry->stale = false;
MMC->metacache()->updateEntry(m_entry); ENV.metacache()->updateEntry(m_entry);
m_reply.reset(); m_reply.reset();
emit succeeded(m_index_within_job); emit succeeded(m_index_within_job);

View File

@ -13,7 +13,7 @@
* limitations under the License. * limitations under the License.
*/ */
#include "MultiMC.h" #include "logic/Env.h"
#include "HttpMetaCache.h" #include "HttpMetaCache.h"
#include <pathutils.h> #include <pathutils.h>
@ -32,7 +32,8 @@
QString MetaEntry::getFullPath() 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() HttpMetaCache::HttpMetaCache(QString path) : QObject()

View File

@ -17,6 +17,9 @@
#include <QString> #include <QString>
#include <QMap> #include <QMap>
#include <qtimer.h> #include <qtimer.h>
#include <memory>
class HttpMetaCache;
struct MetaEntry struct MetaEntry
{ {

View File

@ -13,7 +13,7 @@
* limitations under the License. * limitations under the License.
*/ */
#include "MultiMC.h" #include "logic/Env.h"
#include "MD5EtagDownload.h" #include "MD5EtagDownload.h"
#include <pathutils.h> #include <pathutils.h>
#include <QCryptographicHash> #include <QCryptographicHash>
@ -83,7 +83,7 @@ void MD5EtagDownload::start()
return; return;
} }
auto worker = MMC->qnam(); auto worker = ENV.qnam();
QNetworkReply *rep = worker->get(request); QNetworkReply *rep = worker->get(request);
m_reply = std::shared_ptr<QNetworkReply>(rep); m_reply = std::shared_ptr<QNetworkReply>(rep);

View File

@ -1,5 +1,5 @@
#include "PasteUpload.h" #include "PasteUpload.h"
#include "MultiMC.h" #include "logic/Env.h"
#include "logger/QsLog.h" #include "logger/QsLog.h"
#include <QJsonObject> #include <QJsonObject>
#include <QJsonDocument> #include <QJsonDocument>
@ -25,7 +25,7 @@ void PasteUpload::executeTask()
request.setRawHeader("Content-Type", "application/x-www-form-urlencoded"); request.setRawHeader("Content-Type", "application/x-www-form-urlencoded");
request.setRawHeader("Content-Length", QByteArray::number(content.size())); request.setRawHeader("Content-Length", QByteArray::number(content.size()));
auto worker = MMC->qnam(); auto worker = ENV.qnam();
QNetworkReply *rep = worker->post(request, content); QNetworkReply *rep = worker->post(request, content);
m_reply = std::shared_ptr<QNetworkReply>(rep); m_reply = std::shared_ptr<QNetworkReply>(rep);

View File

@ -7,7 +7,7 @@
#include <QStringList> #include <QStringList>
#include "logic/net/URLConstants.h" #include "logic/net/URLConstants.h"
#include "MultiMC.h" #include "logic/Env.h"
#include "logger/QsLog.h" #include "logger/QsLog.h"
ImgurAlbumCreation::ImgurAlbumCreation(QList<ScreenshotPtr> screenshots) : NetAction(), m_screenshots(screenshots) 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"; 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); QNetworkReply *rep = worker->post(request, data);
m_reply = std::shared_ptr<QNetworkReply>(rep); m_reply = std::shared_ptr<QNetworkReply>(rep);

View File

@ -9,7 +9,7 @@
#include <QUrl> #include <QUrl>
#include "logic/net/URLConstants.h" #include "logic/net/URLConstants.h"
#include "MultiMC.h" #include "logic/Env.h"
#include "logger/QsLog.h" #include "logger/QsLog.h"
ImgurUpload::ImgurUpload(ScreenshotPtr shot) : NetAction(), m_shot(shot) ImgurUpload::ImgurUpload(ScreenshotPtr shot) : NetAction(), m_shot(shot)
@ -48,7 +48,7 @@ void ImgurUpload::start()
namePart.setBody(m_shot->m_file.baseName().toUtf8()); namePart.setBody(m_shot->m_file.baseName().toUtf8());
multipart->append(namePart); multipart->append(namePart);
auto worker = MMC->qnam(); auto worker = ENV.qnam();
QNetworkReply *rep = worker->post(request, multipart); QNetworkReply *rep = worker->post(request, multipart);
m_reply = std::shared_ptr<QNetworkReply>(rep); m_reply = std::shared_ptr<QNetworkReply>(rep);

View File

@ -3,7 +3,8 @@
#include "logic/net/ByteArrayDownload.h" #include "logic/net/ByteArrayDownload.h"
#include "logic/net/CacheDownload.h" #include "logic/net/CacheDownload.h"
#include "logic/net/URLConstants.h" #include "logic/net/URLConstants.h"
#include "MultiMC.h" #include "logic/Env.h"
#include "logger/QsLog.h"
TranslationDownloader::TranslationDownloader() TranslationDownloader::TranslationDownloader()
{ {
@ -27,7 +28,7 @@ void TranslationDownloader::indexRecieved()
{ {
if (!line.isEmpty()) if (!line.isEmpty())
{ {
MetaEntryPtr entry = MMC->metacache()->resolveEntry("translations", "mmc_" + line); MetaEntryPtr entry = ENV.metacache()->resolveEntry("translations", "mmc_" + line);
entry->stale = true; entry->stale = true;
CacheDownloadPtr dl = CacheDownload::make( CacheDownloadPtr dl = CacheDownload::make(
QUrl(URLConstants::TRANSLATIONS_BASE_URL + line), QUrl(URLConstants::TRANSLATIONS_BASE_URL + line),

View File

@ -16,6 +16,7 @@
#include "DownloadUpdateTask.h" #include "DownloadUpdateTask.h"
#include "MultiMC.h" #include "MultiMC.h"
#include "logic/Env.h"
#include "BuildConfig.h" #include "BuildConfig.h"
#include "logic/updater/UpdateChecker.h" #include "logic/updater/UpdateChecker.h"
@ -28,10 +29,11 @@
#include <QDomDocument> #include <QDomDocument>
DownloadUpdateTask::DownloadUpdateTask(QString repoUrl, int versionId, QObject *parent) DownloadUpdateTask::DownloadUpdateTask(QString rootPath, QString repoUrl, int versionId, QObject *parent)
: Task(parent) : Task(parent)
{ {
m_cVersionId = BuildConfig.VERSION_BUILD; m_cVersionId = BuildConfig.VERSION_BUILD;
m_rootPath = rootPath;
m_nRepoUrl = repoUrl; m_nRepoUrl = repoUrl;
m_nVersionId = versionId; 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. // delete anything in the current one version's list that isn't in the new version's list.
for (VersionFileEntry entry : currentVersion) for (VersionFileEntry entry : currentVersion)
{ {
QFileInfo toDelete(PathCombine(MMC->root(), entry.path)); QFileInfo toDelete(PathCombine(m_rootPath, entry.path));
if (!toDelete.exists()) if (!toDelete.exists())
{ {
QLOG_ERROR() << "Expected file " << toDelete.absoluteFilePath() 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 // 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. // way to do this in the background.
QString fileMD5; QString fileMD5;
QString realEntryPath = PathCombine(MMC->root(), entry.path); QString realEntryPath = PathCombine(m_rootPath, entry.path);
QFile entryFile(realEntryPath); QFile entryFile(realEntryPath);
QFileInfo entryInfo(realEntryPath); QFileInfo entryInfo(realEntryPath);
@ -356,7 +358,6 @@ DownloadUpdateTask::processFileLists(NetJob *job,
} }
if (!pass) if (!pass)
{ {
QLOG_ERROR() << "ROOT: " << MMC->root();
ops.clear(); ops.clear();
return false; return false;
} }
@ -413,7 +414,7 @@ DownloadUpdateTask::processFileLists(NetJob *job,
} }
else 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(); QLOG_DEBUG() << "Updater will be in " << cache_entry->getFullPath();
// force check. // force check.
cache_entry->stale = true; cache_entry->stale = true;

View File

@ -27,13 +27,13 @@ class DownloadUpdateTask : public Task
Q_OBJECT Q_OBJECT
public: 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. * Gets the directory that contains the update files.
*/ */
QString updateFilesDir(); QString updateFilesDir();
public: public:
// TODO: We should probably put these data structures into a separate header... // 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. * 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. * 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. * 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, * 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. * 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 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. * 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 * 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. * current version's info file fails to download, as long as the new version's info file succeeded.
*/ */
virtual void parseDownloadedVersionInfo(); virtual void parseDownloadedVersionInfo();
@ -176,7 +176,7 @@ protected:
//! Network job for downloading version info files. //! Network job for downloading version info files.
NetJobPtr m_vinfoNetJob; NetJobPtr m_vinfoNetJob;
//! Network job for downloading update files. //! Network job for downloading update files.
NetJobPtr m_filesNetJob; NetJobPtr m_filesNetJob;
@ -188,6 +188,9 @@ protected:
int m_cVersionId; int m_cVersionId;
QString m_cRepoUrl; QString m_cRepoUrl;
// path to the root of the application
QString m_rootPath;
/*! /*!
* Temporary directory to store update files in. * Temporary directory to store update files in.
* This will be set to not auto delete. Task will fail if this fails to be created. * 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. * This fixes destination paths for OSX.
* The updater runs in MultiMC.app/Contents/MacOs by default * The updater runs in MultiMC.app/Contents/MacOs by default
* The destination paths are such as this: MultiMC.app/blah/blah * The destination paths are such as this: MultiMC.app/blah/blah
* *
* Therefore we chop off the 'MultiMC.app' prefix * Therefore we chop off the 'MultiMC.app' prefix
* *
* Returns false if the path couldn't be fixed (is invalid) * Returns false if the path couldn't be fixed (is invalid)
*/ */
static bool fixPathForOSX(QString &path); static bool fixPathForOSX(QString &path);

View File

@ -4,9 +4,10 @@
#include <QJsonObject> #include <QJsonObject>
#include <QJsonArray> #include <QJsonArray>
#include "MultiMC.h" #include "logic/Env.h"
#include "BuildConfig.h" #include "BuildConfig.h"
#include "logic/net/CacheDownload.h" #include "logic/net/CacheDownload.h"
#include "logger/QsLog.h"
NotificationChecker::NotificationChecker(QObject *parent) NotificationChecker::NotificationChecker(QObject *parent)
: QObject(parent), m_notificationsUrl(QUrl(BuildConfig.NOTIFICATION_URL)) : QObject(parent), m_notificationsUrl(QUrl(BuildConfig.NOTIFICATION_URL))
@ -43,7 +44,7 @@ void NotificationChecker::checkForNotifications()
return; return;
} }
m_checkJob.reset(new NetJob("Checking for notifications")); 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; entry->stale = true;
m_checkJob->addNetAction(m_download = CacheDownload::make(m_notificationsUrl, entry)); m_checkJob->addNetAction(m_download = CacheDownload::make(m_notificationsUrl, entry));
connect(m_download.get(), &CacheDownload::succeeded, this, connect(m_download.get(), &CacheDownload::succeeded, this,

View File

@ -15,23 +15,19 @@
#include "UpdateChecker.h" #include "UpdateChecker.h"
#include "MultiMC.h"
#include "BuildConfig.h"
#include "logger/QsLog.h" #include "logger/QsLog.h"
#include <QJsonObject> #include <QJsonObject>
#include <QJsonArray> #include <QJsonArray>
#include <QJsonValue> #include <QJsonValue>
#include "logic/settings/SettingsObject.h"
#define API_VERSION 0 #define API_VERSION 0
#define CHANLIST_FORMAT 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_updateChecking = false;
m_chanListLoading = false; m_chanListLoading = false;
m_checkUpdateWaiting = false; m_checkUpdateWaiting = false;
@ -48,7 +44,7 @@ bool UpdateChecker::hasChannels() const
return !m_channels.isEmpty(); return !m_channels.isEmpty();
} }
void UpdateChecker::checkForUpdate(bool notifyNoUpdate) void UpdateChecker::checkForUpdate(QString updateChannel, bool notifyNoUpdate)
{ {
QLOG_DEBUG() << "Checking for updates."; 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 " QLOG_DEBUG() << "Channel list isn't loaded yet. Loading channel list and deferring "
"update check."; "update check.";
m_checkUpdateWaiting = true; m_checkUpdateWaiting = true;
m_deferredUpdateChannel = updateChannel;
updateChanList(notifyNoUpdate); updateChanList(notifyNoUpdate);
return; return;
} }
@ -71,9 +68,6 @@ void UpdateChecker::checkForUpdate(bool notifyNoUpdate)
m_updateChecking = true; 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 // Find the desired channel within the channel list and get its repo URL. If if cannot be
// found, error. // found, error.
m_repoUrl = ""; 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 // We've got the version with the greatest ID number. Now compare it to our current build
// number and update if they're different. // number and update if they're different.
int newBuildNumber = newestVersion.value("Id").toVariant().toInt(); int newBuildNumber = newestVersion.value("Id").toVariant().toInt();
if (newBuildNumber != BuildConfig.VERSION_BUILD) if (newBuildNumber != m_currentBuild)
{ {
QLOG_DEBUG() << "Found newer version with ID" << newBuildNumber; QLOG_DEBUG() << "Found newer version with ID" << newBuildNumber;
// Update! // Update!
@ -251,7 +245,7 @@ void UpdateChecker::chanListDownloadFinished(bool notifyNoUpdate)
// If we're waiting to check for updates, do that now. // If we're waiting to check for updates, do that now.
if (m_checkUpdateWaiting) if (m_checkUpdateWaiting)
checkForUpdate(notifyNoUpdate); checkForUpdate(m_deferredUpdateChannel, notifyNoUpdate);
emit channelListLoaded(); emit channelListLoaded();
} }

View File

@ -24,10 +24,8 @@ class UpdateChecker : public QObject
Q_OBJECT Q_OBJECT
public: public:
UpdateChecker(); UpdateChecker(QString channelListUrl, int currentBuild);
void checkForUpdate(bool notifyNoUpdate); void checkForUpdate(QString updateChannel, bool notifyNoUpdate);
void setChannelListUrl(const QString &url) { m_channelListUrl = url; }
/*! /*!
* Causes the update checker to download the channel list from the URL specified in config.h (generated by CMake). * 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. * When the channel list finishes loading, if this is true, the update checker will check for updates.
*/ */
bool m_checkUpdateWaiting; bool m_checkUpdateWaiting;
/*!
* if m_checkUpdateWaiting, this is the last used update channel
*/
QString m_deferredUpdateChannel;
int m_currentBuild = -1;
}; };

View File

@ -91,7 +91,7 @@ slots:
void test_writeInstallScript() void test_writeInstallScript()
{ {
DownloadUpdateTask task( DownloadUpdateTask task(QCoreApplication::applicationDirPath(),
QUrl::fromLocalFile(QDir::current().absoluteFilePath("tests/data/")).toString(), 0); QUrl::fromLocalFile(QDir::current().absoluteFilePath("tests/data/")).toString(), 0);
DownloadUpdateTask::UpdateOperationList ops; DownloadUpdateTask::UpdateOperationList ops;
@ -105,7 +105,7 @@ slots:
QCOMPARE(TestsInternal::readFileUtf8(script).replace(QRegExp("[\r\n]+"), "\n"), QCOMPARE(TestsInternal::readFileUtf8(script).replace(QRegExp("[\r\n]+"), "\n"),
MULTIMC_GET_TEST_FILE_UTF8(testFile).replace(QRegExp("[\r\n]+"), "\n")); MULTIMC_GET_TEST_FILE_UTF8(testFile).replace(QRegExp("[\r\n]+"), "\n"));
} }
// DISABLED: fails. // DISABLED: fails.
/* /*
void test_parseVersionInfo_data() void test_parseVersionInfo_data()
@ -166,7 +166,7 @@ slots:
QTest::addColumn<DownloadUpdateTask::VersionFileList>("newVersion"); QTest::addColumn<DownloadUpdateTask::VersionFileList>("newVersion");
QTest::addColumn<DownloadUpdateTask::UpdateOperationList>("expectedOperations"); 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 // update fileOne, keep fileTwo, remove fileThree
QTest::newRow("test 1") QTest::newRow("test 1")

View File

@ -1,10 +1,6 @@
#include <QTest> #include <QTest>
#include <QSignalSpy> #include <QSignalSpy>
#include "logic/settings/SettingsObject.h"
#include "logic/settings/Setting.h"
#include "BuildConfig.h"
#include "TestUtil.h" #include "TestUtil.h"
#include "logic/updater/UpdateChecker.h" #include "logic/updater/UpdateChecker.h"
@ -24,19 +20,6 @@ QDebug operator<<(QDebug dbg, const UpdateChecker::ChannelListEntry &c)
return dbg.maybeSpace(); 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 class UpdateCheckerTest : public QObject
{ {
Q_OBJECT Q_OBJECT
@ -99,7 +82,6 @@ slots:
} }
void tst_ChannelListParsing() void tst_ChannelListParsing()
{ {
ResetSetting resetUpdateChannel(MMC->settings()->getSetting("UpdateChannel"));
QFETCH(QString, channel); QFETCH(QString, channel);
QFETCH(QString, channelUrl); QFETCH(QString, channelUrl);
@ -107,15 +89,11 @@ slots:
QFETCH(bool, valid); QFETCH(bool, valid);
QFETCH(QList<UpdateChecker::ChannelListEntry>, result); QFETCH(QList<UpdateChecker::ChannelListEntry>, result);
MMC->settings()->set("UpdateChannel", channel); UpdateChecker checker(channelUrl, 0);
UpdateChecker checker;
QSignalSpy channelListLoadedSpy(&checker, SIGNAL(channelListLoaded())); QSignalSpy channelListLoadedSpy(&checker, SIGNAL(channelListLoaded()));
QVERIFY(channelListLoadedSpy.isValid()); QVERIFY(channelListLoadedSpy.isValid());
checker.setChannelListUrl(channelUrl);
checker.updateChanList(false); checker.updateChanList(false);
if (valid) if (valid)
@ -147,18 +125,12 @@ slots:
} }
void tst_UpdateChecking() void tst_UpdateChecking()
{ {
ResetSetting resetUpdateChannel(MMC->settings()->getSetting("UpdateChannel"));
QFETCH(QString, channel); QFETCH(QString, channel);
QFETCH(QString, channelUrl); QFETCH(QString, channelUrl);
QFETCH(int, currentBuild); QFETCH(int, currentBuild);
QFETCH(QList<QVariant>, result); QFETCH(QList<QVariant>, result);
MMC->settings()->set("UpdateChannel", channel); UpdateChecker checker(channelUrl, currentBuild);
BuildConfig.VERSION_BUILD = currentBuild;
UpdateChecker checker;
checker.setChannelListUrl(channelUrl);
QSignalSpy updateAvailableSpy(&checker, SIGNAL(updateAvailable(QString,QString,int))); QSignalSpy updateAvailableSpy(&checker, SIGNAL(updateAvailable(QString,QString,int)));
QVERIFY(updateAvailableSpy.isValid()); QVERIFY(updateAvailableSpy.isValid());
@ -170,7 +142,7 @@ slots:
checker.m_channels[0].url = QUrl::fromLocalFile(QDir::current().absoluteFilePath("tests/data/")).toString(); checker.m_channels[0].url = QUrl::fromLocalFile(QDir::current().absoluteFilePath("tests/data/")).toString();
checker.checkForUpdate(false); checker.checkForUpdate(channel, false);
QVERIFY(updateAvailableSpy.wait()); QVERIFY(updateAvailableSpy.wait());
QList<QVariant> res = result; QList<QVariant> res = result;