diff options
Diffstat (limited to 'logic')
-rw-r--r-- | logic/MinecraftProcess.cpp | 8 | ||||
-rw-r--r-- | logic/NagUtils.cpp | 18 | ||||
-rw-r--r-- | logic/net/CacheDownload.cpp | 100 | ||||
-rw-r--r-- | logic/net/CacheDownload.h | 8 | ||||
-rw-r--r-- | logic/net/URLConstants.h | 2 | ||||
-rw-r--r-- | logic/status/StatusChecker.cpp | 137 | ||||
-rw-r--r-- | logic/status/StatusChecker.h | 57 |
7 files changed, 271 insertions, 59 deletions
diff --git a/logic/MinecraftProcess.cpp b/logic/MinecraftProcess.cpp index 09d60771..18d63674 100644 --- a/logic/MinecraftProcess.cpp +++ b/logic/MinecraftProcess.cpp @@ -85,6 +85,14 @@ QString MinecraftProcess::censorPrivateInfo(QString in) in.replace(profileId, "<PROFILE ID>"); in.replace(profileName, "<PROFILE NAME>"); } + + auto i = m_account->user().properties.begin(); + while (i != m_account->user().properties.end()) + { + in.replace(i.value(), "<" + i.key().toUpper() + ">"); + ++i; + } + return in; } diff --git a/logic/NagUtils.cpp b/logic/NagUtils.cpp index 6f81b3c7..c963a98a 100644 --- a/logic/NagUtils.cpp +++ b/logic/NagUtils.cpp @@ -23,15 +23,15 @@ void checkJVMArgs(QString jvmargs, QWidget *parent) if (jvmargs.contains("-XX:PermSize=") || jvmargs.contains(QRegExp("-Xm[sx]"))) { CustomMessageBox::selectable( - parent, parent->tr("JVM arguments warning"), - parent->tr("You tried to manually set a JVM memory option (using " - " \"-XX:PermSize\", \"-Xmx\" or \"-Xms\") - there" - " are dedicated boxes for these in the settings (Java" - " tab, in the Memory group at the top).\n" - "Your manual settings will be overridden by the" - " dedicated options.\n" - "This message will be displayed until you remove them" - " from the JVM arguments."), + parent, QObject::tr("JVM arguments warning"), + QObject::tr("You tried to manually set a JVM memory option (using " + " \"-XX:PermSize\", \"-Xmx\" or \"-Xms\") - there" + " are dedicated boxes for these in the settings (Java" + " tab, in the Memory group at the top).\n" + "Your manual settings will be overridden by the" + " dedicated options.\n" + "This message will be displayed until you remove them" + " from the JVM arguments."), QMessageBox::Warning)->exec(); } } diff --git a/logic/net/CacheDownload.cpp b/logic/net/CacheDownload.cpp index 6eadae39..8a8d00f0 100644 --- a/logic/net/CacheDownload.cpp +++ b/logic/net/CacheDownload.cpp @@ -33,8 +33,10 @@ CacheDownload::CacheDownload(QUrl url, MetaEntryPtr entry) void CacheDownload::start() { + m_status = Job_InProgress; if (!m_entry->stale) { + m_status = Job_Finished; emit succeeded(m_index_within_job); return; } @@ -42,6 +44,15 @@ void CacheDownload::start() // if there already is a file and md5 checking is in effect and it can be opened if (!ensureFilePathExists(m_target_path)) { + QLOG_ERROR() << "Could not create folder for " + m_target_path; + m_status = Job_Failed; + emit failed(m_index_within_job); + return; + } + if (!m_output_file.open(QIODevice::WriteOnly)) + { + QLOG_ERROR() << "Could not open " + m_target_path + " for writing"; + m_status = Job_Failed; emit failed(m_index_within_job); return; } @@ -83,70 +94,65 @@ void CacheDownload::downloadError(QNetworkReply::NetworkError error) void CacheDownload::downloadFinished() { // if the download succeeded - if (m_status != Job_Failed) + if (m_status == Job_Failed) { + m_output_file.cancelWriting(); + m_reply.reset(); + m_status = Job_Failed; + emit failed(m_index_within_job); + return; + } + if (wroteAnyData) + { // nothing went wrong... - m_status = Job_Finished; - if (m_output_file.isOpen()) + if (m_output_file.commit()) { - // save the data to the downloadable if we aren't saving to file - m_output_file.close(); + m_status = Job_Finished; m_entry->md5sum = md5sum.result().toHex().constData(); } else { - if (m_output_file.open(QIODevice::ReadOnly)) - { - m_entry->md5sum = - QCryptographicHash::hash(m_output_file.readAll(), QCryptographicHash::Md5) - .toHex() - .constData(); - m_output_file.close(); - } - } - QFileInfo output_file_info(m_target_path); - - m_entry->etag = m_reply->rawHeader("ETag").constData(); - if (m_reply->hasRawHeader("Last-Modified")) - { - m_entry->remote_changed_timestamp = m_reply->rawHeader("Last-Modified").constData(); + QLOG_ERROR() << "Failed to commit changes to " << m_target_path; + m_output_file.cancelWriting(); + m_reply.reset(); + m_status = Job_Failed; + emit failed(m_index_within_job); + return; } - m_entry->local_changed_timestamp = - output_file_info.lastModified().toUTC().toMSecsSinceEpoch(); - m_entry->stale = false; - MMC->metacache()->updateEntry(m_entry); - - m_reply.reset(); - emit succeeded(m_index_within_job); - return; } - // else the download failed else { - m_output_file.close(); - m_output_file.remove(); - m_reply.reset(); - emit failed(m_index_within_job); - return; + m_status = Job_Finished; } + + QFileInfo output_file_info(m_target_path); + + m_entry->etag = m_reply->rawHeader("ETag").constData(); + if (m_reply->hasRawHeader("Last-Modified")) + { + m_entry->remote_changed_timestamp = m_reply->rawHeader("Last-Modified").constData(); + } + m_entry->local_changed_timestamp = + output_file_info.lastModified().toUTC().toMSecsSinceEpoch(); + m_entry->stale = false; + MMC->metacache()->updateEntry(m_entry); + + m_reply.reset(); + emit succeeded(m_index_within_job); + return; } void CacheDownload::downloadReadyRead() { - if (!m_output_file.isOpen()) - { - if (!m_output_file.open(QIODevice::WriteOnly)) - { - /* - * Can't open the file... the job failed - */ - m_reply->abort(); - emit failed(m_index_within_job); - return; - } - } QByteArray ba = m_reply->readAll(); md5sum.addData(ba); - m_output_file.write(ba); + if (m_output_file.write(ba) != ba.size()) + { + QLOG_ERROR() << "Failed writing into " + m_target_path; + m_status = Job_Failed; + m_reply->abort(); + emit failed(m_index_within_job); + } + wroteAnyData = true; } diff --git a/logic/net/CacheDownload.h b/logic/net/CacheDownload.h index e25aecd2..48be1dae 100644 --- a/logic/net/CacheDownload.h +++ b/logic/net/CacheDownload.h @@ -17,8 +17,8 @@ #include "NetAction.h" #include "HttpMetaCache.h" -#include <QFile> -#include <qcryptographichash.h> +#include <QCryptographicHash> +#include <QSaveFile> typedef std::shared_ptr<class CacheDownload> CacheDownloadPtr; class CacheDownload : public NetAction @@ -29,10 +29,12 @@ public: /// if saving to file, use the one specified in this string QString m_target_path; /// this is the output file, if any - QFile m_output_file; + QSaveFile m_output_file; /// the hash-as-you-download QCryptographicHash md5sum; + bool wroteAnyData = false; + public: explicit CacheDownload(QUrl url, MetaEntryPtr entry); static CacheDownloadPtr make(QUrl url, MetaEntryPtr entry) diff --git a/logic/net/URLConstants.h b/logic/net/URLConstants.h index 9579198d..8cb1f3fd 100644 --- a/logic/net/URLConstants.h +++ b/logic/net/URLConstants.h @@ -31,4 +31,6 @@ const QString SKINS_BASE("skins.minecraft.net/MinecraftSkins/"); const QString AUTH_BASE("authserver.mojang.com/"); const QString FORGE_LEGACY_URL("http://files.minecraftforge.net/minecraftforge/json"); const QString FORGE_GRADLE_URL("http://files.minecraftforge.net/maven/net/minecraftforge/forge/json"); +const QString MOJANG_STATUS_URL("http://status.mojang.com/check"); +const QString MOJANG_STATUS_NEWS_URL("http://status.mojang.com/news"); } diff --git a/logic/status/StatusChecker.cpp b/logic/status/StatusChecker.cpp new file mode 100644 index 00000000..7c856d3f --- /dev/null +++ b/logic/status/StatusChecker.cpp @@ -0,0 +1,137 @@ +/* Copyright 2013 MultiMC Contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "StatusChecker.h" + +#include <logic/net/URLConstants.h> + +#include <QByteArray> +#include <QDomDocument> + +#include <logger/QsLog.h> + +StatusChecker::StatusChecker() +{ + +} + +void StatusChecker::reloadStatus() +{ + if (isLoadingStatus()) + { + QLOG_INFO() << "Ignored request to reload status. Currently reloading already."; + return; + } + + QLOG_INFO() << "Reloading status."; + + NetJob* job = new NetJob("Status JSON"); + job->addNetAction(ByteArrayDownload::make(URLConstants::MOJANG_STATUS_URL)); + QObject::connect(job, &NetJob::succeeded, this, &StatusChecker::statusDownloadFinished); + QObject::connect(job, &NetJob::failed, this, &StatusChecker::statusDownloadFailed); + m_statusNetJob.reset(job); + job->start(); +} + +void StatusChecker::statusDownloadFinished() +{ + QLOG_DEBUG() << "Finished loading status JSON."; + + QByteArray data; + { + ByteArrayDownloadPtr dl = std::dynamic_pointer_cast<ByteArrayDownload>(m_statusNetJob->first()); + data = dl->m_data; + m_statusNetJob.reset(); + } + + QJsonParseError jsonError; + QJsonDocument jsonDoc = QJsonDocument::fromJson(data, &jsonError); + + if (jsonError.error != QJsonParseError::NoError) + { + fail("Error parsing status JSON:" + jsonError.errorString()); + return; + } + + if (!jsonDoc.isArray()) + { + fail("Error parsing status JSON: JSON root is not an array"); + return; + } + + QJsonArray root = jsonDoc.array(); + + for(auto status = root.begin(); status != root.end(); ++status) + { + QVariantMap map = (*status).toObject().toVariantMap(); + + for (QVariantMap::const_iterator iter = map.begin(); iter != map.end(); ++iter) + { + QString key = iter.key(); + QVariant value = iter.value(); + + if(value.type() == QVariant::Type::String) + { + m_statusEntries.insert(key, value.toString()); + QLOG_DEBUG() << "Status JSON object: " << key << m_statusEntries[key]; + } + else + { + fail("Malformed status JSON: expected status type to be a string."); + return; + } + } + } + + succeed(); +} + +void StatusChecker::statusDownloadFailed() +{ + fail("Failed to load status JSON."); +} + + +QMap<QString, QString> StatusChecker::getStatusEntries() const +{ + return m_statusEntries; +} + +bool StatusChecker::isLoadingStatus() const +{ + return m_statusNetJob.get() != nullptr; +} + +QString StatusChecker::getLastLoadErrorMsg() const +{ + return m_lastLoadError; +} + +void StatusChecker::succeed() +{ + m_lastLoadError = ""; + QLOG_DEBUG() << "Status loading succeeded."; + m_statusNetJob.reset(); + emit statusLoaded(); +} + +void StatusChecker::fail(const QString& errorMsg) +{ + m_lastLoadError = errorMsg; + QLOG_DEBUG() << "Failed to load status:" << errorMsg; + m_statusNetJob.reset(); + emit statusLoadingFailed(errorMsg); +} + diff --git a/logic/status/StatusChecker.h b/logic/status/StatusChecker.h new file mode 100644 index 00000000..1cb01836 --- /dev/null +++ b/logic/status/StatusChecker.h @@ -0,0 +1,57 @@ +/* Copyright 2013 MultiMC Contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include <QObject> +#include <QString> +#include <QList> + +#include <logic/net/NetJob.h> + +class StatusChecker : public QObject +{ + Q_OBJECT +public: + StatusChecker(); + + QString getLastLoadErrorMsg() const; + + bool isStatusLoaded() const; + + bool isLoadingStatus() const; + + QMap<QString, QString> getStatusEntries() const; + + void Q_SLOT reloadStatus(); + +signals: + void statusLoaded(); + void statusLoadingFailed(QString errorMsg); + +protected slots: + void statusDownloadFinished(); + void statusDownloadFailed(); + +protected: + QMap<QString, QString> m_statusEntries; + NetJobPtr m_statusNetJob; + bool m_loadedStatus; + QString m_lastLoadError; + + void Q_SLOT succeed(); + void Q_SLOT fail(const QString& errorMsg); +}; + |