Merge branch 'develop' of https://github.com/robotbrain/MultiMC5 into develop

This commit is contained in:
Petr Mrázek 2013-12-25 01:19:38 +01:00
commit 5a2df0d41a
4 changed files with 53 additions and 31 deletions

View File

@ -681,7 +681,10 @@ 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(); connect(updater.get(), &UpdateChecker::noUpdateFound, [this](){
CustomMessageBox::selectable(this, "No update found.", "No MultiMC update was found!\nYou are using the latest version.")->exec();
});
updater->checkForUpdate(true);
} }
void MainWindow::on_actionSettings_triggered() void MainWindow::on_actionSettings_triggered()

View File

@ -47,14 +47,16 @@ bool UpdateChecker::hasChannels() const
return !m_channels.isEmpty(); return !m_channels.isEmpty();
} }
void UpdateChecker::checkForUpdate() void UpdateChecker::checkForUpdate(bool notifyNoUpdate)
{ {
QLOG_DEBUG() << "Checking for updates."; QLOG_DEBUG() << "Checking for updates.";
// If the channel list hasn't loaded yet, load it and defer checking for updates until later. // If the channel list hasn't loaded yet, load it and defer checking for updates until
// later.
if (!m_chanListLoaded) if (!m_chanListLoaded)
{ {
QLOG_DEBUG() << "Channel list isn't loaded yet. Loading channel list and deferring update check."; QLOG_DEBUG() << "Channel list isn't loaded yet. Loading channel list and deferring "
"update check.";
m_checkUpdateWaiting = true; m_checkUpdateWaiting = true;
updateChanList(); updateChanList();
return; return;
@ -72,7 +74,8 @@ void UpdateChecker::checkForUpdate()
// TODO: Allow user to select channels. For now, we'll just use the current channel. // TODO: Allow user to select channels. For now, we'll just use the current channel.
QString updateChannel = m_currentChannel; QString updateChannel = m_currentChannel;
// Find the desired channel within the channel list and get its repo URL. If if cannot be found, error. // Find the desired channel within the channel list and get its repo URL. If if cannot be
// found, error.
m_repoUrl = ""; m_repoUrl = "";
for (ChannelListEntry entry : m_channels) for (ChannelListEntry entry : m_channels)
{ {
@ -91,20 +94,22 @@ void UpdateChecker::checkForUpdate()
auto job = new NetJob("GoUpdate Repository Index"); auto job = new NetJob("GoUpdate Repository Index");
job->addNetAction(ByteArrayDownload::make(indexUrl)); job->addNetAction(ByteArrayDownload::make(indexUrl));
connect(job, SIGNAL(succeeded()), SLOT(updateCheckFinished())); connect(job, &NetJob::succeeded, [this, notifyNoUpdate]()
{ updateCheckFinished(notifyNoUpdate); });
connect(job, SIGNAL(failed()), SLOT(updateCheckFailed())); connect(job, SIGNAL(failed()), SLOT(updateCheckFailed()));
indexJob.reset(job); indexJob.reset(job);
job->start(); job->start();
} }
void UpdateChecker::updateCheckFinished() void UpdateChecker::updateCheckFinished(bool notifyNoUpdate)
{ {
QLOG_DEBUG() << "Finished downloading repo index. Checking for new versions."; QLOG_DEBUG() << "Finished downloading repo index. Checking for new versions.";
QJsonParseError jsonError; QJsonParseError jsonError;
QByteArray data; QByteArray data;
{ {
ByteArrayDownloadPtr dl = std::dynamic_pointer_cast<ByteArrayDownload>(indexJob->first()); ByteArrayDownloadPtr dl =
std::dynamic_pointer_cast<ByteArrayDownload>(indexJob->first());
data = dl->m_data; data = dl->m_data;
indexJob.reset(); indexJob.reset();
} }
@ -112,7 +117,8 @@ void UpdateChecker::updateCheckFinished()
QJsonDocument jsonDoc = QJsonDocument::fromJson(data, &jsonError); QJsonDocument jsonDoc = QJsonDocument::fromJson(data, &jsonError);
if (jsonError.error != QJsonParseError::NoError || !jsonDoc.isObject()) if (jsonError.error != QJsonParseError::NoError || !jsonDoc.isObject())
{ {
QLOG_ERROR() << "Failed to parse GoUpdate repository index. JSON error" << jsonError.errorString() << "at offset" << jsonError.offset; QLOG_ERROR() << "Failed to parse GoUpdate repository index. JSON error"
<< jsonError.errorString() << "at offset" << jsonError.offset;
return; return;
} }
@ -122,7 +128,8 @@ void UpdateChecker::updateCheckFinished()
int apiVersion = object.value("ApiVersion").toVariant().toInt(&success); int apiVersion = object.value("ApiVersion").toVariant().toInt(&success);
if (apiVersion != API_VERSION || !success) if (apiVersion != API_VERSION || !success)
{ {
QLOG_ERROR() << "Failed to check for updates. API version mismatch. We're using" << API_VERSION << "server has" << apiVersion; QLOG_ERROR() << "Failed to check for updates. API version mismatch. We're using"
<< API_VERSION << "server has" << apiVersion;
return; return;
} }
@ -132,19 +139,27 @@ void UpdateChecker::updateCheckFinished()
for (QJsonValue versionVal : versions) for (QJsonValue versionVal : versions)
{ {
QJsonObject version = versionVal.toObject(); QJsonObject version = versionVal.toObject();
if (newestVersion.value("Id").toVariant().toInt() < version.value("Id").toVariant().toInt()) if (newestVersion.value("Id").toVariant().toInt() <
version.value("Id").toVariant().toInt())
{ {
QLOG_DEBUG() << "Found newer version with ID" << version.value("Id").toVariant().toInt(); QLOG_DEBUG() << "Found newer version with ID"
<< version.value("Id").toVariant().toInt();
newestVersion = version; newestVersion = version;
} }
} }
// We've got the version with the greatest ID number. Now compare it to our current build number and update if they're different. // 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(); int newBuildNumber = newestVersion.value("Id").toVariant().toInt();
if (newBuildNumber != MMC->version().build) if (newBuildNumber != MMC->version().build)
{ {
// Update! // Update!
emit updateAvailable(m_repoUrl, newestVersion.value("Name").toVariant().toString(), newBuildNumber); emit updateAvailable(m_repoUrl, newestVersion.value("Name").toVariant().toString(),
newBuildNumber);
}
else if (notifyNoUpdate)
{
emit noUpdateFound();
} }
m_updateChecking = false; m_updateChecking = false;
@ -163,12 +178,13 @@ void UpdateChecker::updateChanList()
if (m_channelListUrl.isEmpty()) if (m_channelListUrl.isEmpty())
{ {
QLOG_ERROR() << "Failed to update channel list. No channel list URL set." QLOG_ERROR() << "Failed to update channel list. No channel list URL set."
<< "If you'd like to use MultiMC's update system, please pass the channel list URL to CMake at compile time."; << "If you'd like to use MultiMC's update system, please pass the channel "
"list URL to CMake at compile time.";
return; return;
} }
m_chanListLoading = true; m_chanListLoading = true;
NetJob* job = new NetJob("Update System Channel List"); NetJob *job = new NetJob("Update System Channel List");
job->addNetAction(ByteArrayDownload::make(QUrl(m_channelListUrl))); job->addNetAction(ByteArrayDownload::make(QUrl(m_channelListUrl)));
QObject::connect(job, &NetJob::succeeded, this, &UpdateChecker::chanListDownloadFinished); QObject::connect(job, &NetJob::succeeded, this, &UpdateChecker::chanListDownloadFinished);
QObject::connect(job, &NetJob::failed, this, &UpdateChecker::chanListDownloadFailed); QObject::connect(job, &NetJob::failed, this, &UpdateChecker::chanListDownloadFailed);
@ -180,7 +196,8 @@ void UpdateChecker::chanListDownloadFinished()
{ {
QByteArray data; QByteArray data;
{ {
ByteArrayDownloadPtr dl = std::dynamic_pointer_cast<ByteArrayDownload>(chanListJob->first()); ByteArrayDownloadPtr dl =
std::dynamic_pointer_cast<ByteArrayDownload>(chanListJob->first());
data = dl->m_data; data = dl->m_data;
chanListJob.reset(); chanListJob.reset();
} }
@ -190,7 +207,8 @@ void UpdateChecker::chanListDownloadFinished()
if (jsonError.error != QJsonParseError::NoError) if (jsonError.error != QJsonParseError::NoError)
{ {
// TODO: Report errors to the user. // TODO: Report errors to the user.
QLOG_ERROR() << "Failed to parse channel list JSON:" << jsonError.errorString() << "at" << jsonError.offset; QLOG_ERROR() << "Failed to parse channel list JSON:" << jsonError.errorString() << "at"
<< jsonError.offset;
return; return;
} }
@ -200,7 +218,9 @@ void UpdateChecker::chanListDownloadFinished()
int formatVersion = object.value("format_version").toVariant().toInt(&success); int formatVersion = object.value("format_version").toVariant().toInt(&success);
if (formatVersion != CHANLIST_FORMAT || !success) if (formatVersion != CHANLIST_FORMAT || !success)
{ {
QLOG_ERROR() << "Failed to check for updates. Channel list format version mismatch. We're using" << CHANLIST_FORMAT << "server has" << formatVersion; QLOG_ERROR()
<< "Failed to check for updates. Channel list format version mismatch. We're using"
<< CHANLIST_FORMAT << "server has" << formatVersion;
return; return;
} }
@ -210,12 +230,10 @@ void UpdateChecker::chanListDownloadFinished()
for (QJsonValue chanVal : channelArray) for (QJsonValue chanVal : channelArray)
{ {
QJsonObject channelObj = chanVal.toObject(); QJsonObject channelObj = chanVal.toObject();
ChannelListEntry entry{ ChannelListEntry entry{channelObj.value("id").toVariant().toString(),
channelObj.value("id").toVariant().toString(), channelObj.value("name").toVariant().toString(),
channelObj.value("name").toVariant().toString(), channelObj.value("description").toVariant().toString(),
channelObj.value("description").toVariant().toString(), channelObj.value("url").toVariant().toString()};
channelObj.value("url").toVariant().toString()
};
if (entry.id.isEmpty() || entry.name.isEmpty() || entry.url.isEmpty()) if (entry.id.isEmpty() || entry.name.isEmpty() || entry.url.isEmpty())
{ {
QLOG_ERROR() << "Channel list entry with empty ID, name, or URL. Skipping."; QLOG_ERROR() << "Channel list entry with empty ID, name, or URL. Skipping.";
@ -233,7 +251,7 @@ void UpdateChecker::chanListDownloadFinished()
// 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(); checkForUpdate(false);
emit channelListLoaded(); emit channelListLoaded();
} }
@ -244,4 +262,3 @@ void UpdateChecker::chanListDownloadFailed()
QLOG_ERROR() << "Failed to download channel list."; QLOG_ERROR() << "Failed to download channel list.";
emit channelListLoaded(); emit channelListLoaded();
} }

View File

@ -25,7 +25,7 @@ class UpdateChecker : public QObject
public: public:
UpdateChecker(); UpdateChecker();
void checkForUpdate(); void checkForUpdate(bool notifyNoUpdate);
void setCurrentChannel(const QString &channel) { m_currentChannel = channel; } void setCurrentChannel(const QString &channel) { m_currentChannel = channel; }
void setChannelListUrl(const QString &url) { m_channelListUrl = url; } void setChannelListUrl(const QString &url) { m_channelListUrl = url; }
@ -65,8 +65,10 @@ signals:
//! Signal emitted when the channel list finishes loading or fails to load. //! Signal emitted when the channel list finishes loading or fails to load.
void channelListLoaded(); void channelListLoaded();
void noUpdateFound();
private slots: private slots:
void updateCheckFinished(); void updateCheckFinished(bool notifyNoUpdate);
void updateCheckFailed(); void updateCheckFailed();
void chanListDownloadFinished(); void chanListDownloadFinished();

View File

@ -149,7 +149,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(); checker.checkForUpdate(false);
QVERIFY(updateAvailableSpy.wait()); QVERIFY(updateAvailableSpy.wait());
QList<QVariant> res = result; QList<QVariant> res = result;