diff options
Diffstat (limited to 'api/logic/status/StatusChecker.cpp')
-rw-r--r-- | api/logic/status/StatusChecker.cpp | 153 |
1 files changed, 153 insertions, 0 deletions
diff --git a/api/logic/status/StatusChecker.cpp b/api/logic/status/StatusChecker.cpp new file mode 100644 index 00000000..13cac037 --- /dev/null +++ b/api/logic/status/StatusChecker.cpp @@ -0,0 +1,153 @@ +/* Copyright 2013-2015 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 <net/URLConstants.h> + +#include <QByteArray> + +#include <QDebug> + +StatusChecker::StatusChecker() +{ + +} + +void StatusChecker::timerEvent(QTimerEvent *e) +{ + QObject::timerEvent(e); + reloadStatus(); +} + +void StatusChecker::reloadStatus() +{ + if (isLoadingStatus()) + { + // qDebug() << "Ignored request to reload status. Currently reloading already."; + return; + } + + // qDebug() << "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); + emit statusLoading(true); + job->start(); +} + +void StatusChecker::statusDownloadFinished() +{ + qDebug() << "Finished loading status JSON."; + m_statusEntries.clear(); + 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()); + //qDebug() << "Status JSON object: " << key << m_statusEntries[key]; + } + else + { + fail("Malformed status JSON: expected status type to be a string."); + return; + } + } + } + + succeed(); +} + +void StatusChecker::statusDownloadFailed(QString reason) +{ + fail(tr("Failed to load status JSON:\n%1").arg(reason)); +} + + +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() +{ + if(m_prevEntries != m_statusEntries) + { + emit statusChanged(m_statusEntries); + m_prevEntries = m_statusEntries; + } + m_lastLoadError = ""; + qDebug() << "Status loading succeeded."; + m_statusNetJob.reset(); + emit statusLoading(false); +} + +void StatusChecker::fail(const QString& errorMsg) +{ + if(m_prevEntries != m_statusEntries) + { + emit statusChanged(m_statusEntries); + m_prevEntries = m_statusEntries; + } + m_lastLoadError = errorMsg; + qDebug() << "Failed to load status:" << errorMsg; + m_statusNetJob.reset(); + emit statusLoading(false); +} + |