Merge branch 'feature_mojang_status' into develop
This commit is contained in:
commit
f552366e03
@ -393,6 +393,10 @@ logic/news/NewsChecker.cpp
|
|||||||
logic/news/NewsEntry.h
|
logic/news/NewsEntry.h
|
||||||
logic/news/NewsEntry.cpp
|
logic/news/NewsEntry.cpp
|
||||||
|
|
||||||
|
# Status system
|
||||||
|
logic/status/StatusChecker.h
|
||||||
|
logic/status/StatusChecker.cpp
|
||||||
|
|
||||||
# legacy instances
|
# legacy instances
|
||||||
logic/LegacyInstance.h
|
logic/LegacyInstance.h
|
||||||
logic/LegacyInstance.cpp
|
logic/LegacyInstance.cpp
|
||||||
|
@ -20,8 +20,11 @@
|
|||||||
|
|
||||||
#include "logic/news/NewsChecker.h"
|
#include "logic/news/NewsChecker.h"
|
||||||
|
|
||||||
|
#include "logic/status/StatusChecker.h"
|
||||||
|
|
||||||
#include "logic/InstanceLauncher.h"
|
#include "logic/InstanceLauncher.h"
|
||||||
#include "logic/net/HttpMetaCache.h"
|
#include "logic/net/HttpMetaCache.h"
|
||||||
|
#include "logic/net/URLConstants.h"
|
||||||
|
|
||||||
#include "logic/JavaUtils.h"
|
#include "logic/JavaUtils.h"
|
||||||
|
|
||||||
@ -181,6 +184,9 @@ MultiMC::MultiMC(int &argc, char **argv, bool root_override)
|
|||||||
// initialize the news checker
|
// initialize the news checker
|
||||||
m_newsChecker.reset(new NewsChecker(NEWS_RSS_URL));
|
m_newsChecker.reset(new NewsChecker(NEWS_RSS_URL));
|
||||||
|
|
||||||
|
// initialize the status checker
|
||||||
|
m_statusChecker.reset(new StatusChecker());
|
||||||
|
|
||||||
// and instances
|
// and instances
|
||||||
auto InstDirSetting = m_settings->getSetting("InstanceDir");
|
auto InstDirSetting = m_settings->getSetting("InstanceDir");
|
||||||
m_instances.reset(new InstanceList(InstDirSetting->get().toString(), this));
|
m_instances.reset(new InstanceList(InstDirSetting->get().toString(), this));
|
||||||
|
@ -21,6 +21,7 @@ class JavaVersionList;
|
|||||||
class UpdateChecker;
|
class UpdateChecker;
|
||||||
class NotificationChecker;
|
class NotificationChecker;
|
||||||
class NewsChecker;
|
class NewsChecker;
|
||||||
|
class StatusChecker;
|
||||||
|
|
||||||
#if defined(MMC)
|
#if defined(MMC)
|
||||||
#undef MMC
|
#undef MMC
|
||||||
@ -113,6 +114,11 @@ public:
|
|||||||
return m_newsChecker;
|
return m_newsChecker;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::shared_ptr<StatusChecker> statusChecker()
|
||||||
|
{
|
||||||
|
return m_statusChecker;
|
||||||
|
}
|
||||||
|
|
||||||
std::shared_ptr<LWJGLVersionList> lwjgllist();
|
std::shared_ptr<LWJGLVersionList> lwjgllist();
|
||||||
|
|
||||||
std::shared_ptr<ForgeVersionList> forgelist();
|
std::shared_ptr<ForgeVersionList> forgelist();
|
||||||
@ -183,6 +189,7 @@ private:
|
|||||||
std::shared_ptr<UpdateChecker> m_updateChecker;
|
std::shared_ptr<UpdateChecker> m_updateChecker;
|
||||||
std::shared_ptr<NotificationChecker> m_notificationChecker;
|
std::shared_ptr<NotificationChecker> m_notificationChecker;
|
||||||
std::shared_ptr<NewsChecker> m_newsChecker;
|
std::shared_ptr<NewsChecker> m_newsChecker;
|
||||||
|
std::shared_ptr<StatusChecker> m_statusChecker;
|
||||||
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<QNetworkAccessManager> m_qnam;
|
||||||
|
@ -77,6 +77,8 @@
|
|||||||
|
|
||||||
#include "logic/news/NewsChecker.h"
|
#include "logic/news/NewsChecker.h"
|
||||||
|
|
||||||
|
#include "logic/status/StatusChecker.h"
|
||||||
|
|
||||||
#include "logic/net/URLConstants.h"
|
#include "logic/net/URLConstants.h"
|
||||||
|
|
||||||
#include "logic/BaseInstance.h"
|
#include "logic/BaseInstance.h"
|
||||||
@ -199,7 +201,27 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWi
|
|||||||
connect(MMC->instances().get(), SIGNAL(dataIsInvalid()), SLOT(selectionBad()));
|
connect(MMC->instances().get(), SIGNAL(dataIsInvalid()), SLOT(selectionBad()));
|
||||||
|
|
||||||
m_statusLeft = new QLabel(tr("No instance selected"), this);
|
m_statusLeft = new QLabel(tr("No instance selected"), this);
|
||||||
|
m_statusRight = new QLabel(tr("No status available"), this);
|
||||||
|
m_statusRefresh = new QToolButton(this);
|
||||||
|
m_statusRefresh->setToolButtonStyle(Qt::ToolButtonIconOnly);
|
||||||
|
m_statusRefresh->setIcon(
|
||||||
|
QPixmap(":/icons/toolbar/refresh").scaled(16, 16, Qt::KeepAspectRatio));
|
||||||
|
|
||||||
statusBar()->addPermanentWidget(m_statusLeft, 1);
|
statusBar()->addPermanentWidget(m_statusLeft, 1);
|
||||||
|
statusBar()->addPermanentWidget(m_statusRight, 0);
|
||||||
|
statusBar()->addPermanentWidget(m_statusRefresh, 0);
|
||||||
|
|
||||||
|
// Start status checker
|
||||||
|
{
|
||||||
|
connect(MMC->statusChecker().get(), &StatusChecker::statusLoaded, this, &MainWindow::updateStatusUI);
|
||||||
|
connect(MMC->statusChecker().get(), &StatusChecker::statusLoadingFailed, this, &MainWindow::updateStatusFailedUI);
|
||||||
|
|
||||||
|
connect(m_statusRefresh, &QAbstractButton::clicked, this, &MainWindow::reloadStatus);
|
||||||
|
connect(&statusTimer, &QTimer::timeout, this, &MainWindow::reloadStatus);
|
||||||
|
statusTimer.setSingleShot(true);
|
||||||
|
|
||||||
|
reloadStatus();
|
||||||
|
}
|
||||||
|
|
||||||
// Add "manage accounts" button, right align
|
// Add "manage accounts" button, right align
|
||||||
QWidget *spacer = new QWidget();
|
QWidget *spacer = new QWidget();
|
||||||
@ -498,6 +520,63 @@ void MainWindow::updateNewsLabel()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static QString convertStatus(const QString &status)
|
||||||
|
{
|
||||||
|
if(status == "green") return "↑";
|
||||||
|
else if(status == "yellow") return "-";
|
||||||
|
else if(status == "red") return "↓";
|
||||||
|
else return "?";
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::reloadStatus()
|
||||||
|
{
|
||||||
|
MMC->statusChecker()->reloadStatus();
|
||||||
|
updateStatusUI();
|
||||||
|
}
|
||||||
|
|
||||||
|
static QString makeStatusString(const QMap<QString, QString> statuses)
|
||||||
|
{
|
||||||
|
QString status = "";
|
||||||
|
status += "Web: " + convertStatus(statuses["minecraft.net"]);
|
||||||
|
status += " Account: " + convertStatus(statuses["account.mojang.com"]);
|
||||||
|
status += " Skins: " + convertStatus(statuses["skins.minecraft.net"]);
|
||||||
|
status += " Auth: " + convertStatus(statuses["authserver.mojang.com"]);
|
||||||
|
status += " Session: " + convertStatus(statuses["sessionserver.mojang.com"]);
|
||||||
|
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::updateStatusUI()
|
||||||
|
{
|
||||||
|
auto statusChecker = MMC->statusChecker();
|
||||||
|
auto statuses = statusChecker->getStatusEntries();
|
||||||
|
|
||||||
|
QString status = makeStatusString(statuses);
|
||||||
|
if(statusChecker->isLoadingStatus())
|
||||||
|
{
|
||||||
|
m_statusRefresh->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
|
||||||
|
m_statusRefresh->setText(tr("Loading..."));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_statusRefresh->setToolButtonStyle(Qt::ToolButtonIconOnly);
|
||||||
|
m_statusRefresh->setText(tr(""));
|
||||||
|
}
|
||||||
|
|
||||||
|
m_statusRight->setText(status);
|
||||||
|
|
||||||
|
statusTimer.start(60 * 1000);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::updateStatusFailedUI()
|
||||||
|
{
|
||||||
|
m_statusRight->setText(makeStatusString(QMap<QString, QString>()));
|
||||||
|
m_statusRefresh->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
|
||||||
|
m_statusRefresh->setText(tr("Failed."));
|
||||||
|
|
||||||
|
statusTimer.start(60 * 1000);
|
||||||
|
}
|
||||||
|
|
||||||
void MainWindow::updateAvailable(QString repo, QString versionName, int versionId)
|
void MainWindow::updateAvailable(QString repo, QString versionName, int versionId)
|
||||||
{
|
{
|
||||||
UpdateDialog dlg;
|
UpdateDialog dlg;
|
||||||
|
@ -17,6 +17,7 @@
|
|||||||
|
|
||||||
#include <QMainWindow>
|
#include <QMainWindow>
|
||||||
#include <QProcess>
|
#include <QProcess>
|
||||||
|
#include <QTimer>
|
||||||
|
|
||||||
#include "logic/lists/InstanceList.h"
|
#include "logic/lists/InstanceList.h"
|
||||||
#include "logic/BaseInstance.h"
|
#include "logic/BaseInstance.h"
|
||||||
@ -169,6 +170,12 @@ slots:
|
|||||||
|
|
||||||
void updateNewsLabel();
|
void updateNewsLabel();
|
||||||
|
|
||||||
|
void updateStatusUI();
|
||||||
|
|
||||||
|
void updateStatusFailedUI();
|
||||||
|
|
||||||
|
void reloadStatus();
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* Runs the DownloadUpdateTask and installs updates.
|
* Runs the DownloadUpdateTask and installs updates.
|
||||||
*/
|
*/
|
||||||
@ -198,8 +205,12 @@ private:
|
|||||||
Task *m_versionLoadTask;
|
Task *m_versionLoadTask;
|
||||||
|
|
||||||
QLabel *m_statusLeft;
|
QLabel *m_statusLeft;
|
||||||
|
QLabel *m_statusRight;
|
||||||
|
QToolButton *m_statusRefresh;
|
||||||
|
|
||||||
QMenu *accountMenu;
|
QMenu *accountMenu;
|
||||||
QToolButton *accountMenuButton;
|
QToolButton *accountMenuButton;
|
||||||
QAction *manageAccountsAction;
|
QAction *manageAccountsAction;
|
||||||
|
|
||||||
|
QTimer statusTimer;
|
||||||
};
|
};
|
||||||
|
@ -31,4 +31,6 @@ const QString SKINS_BASE("skins.minecraft.net/MinecraftSkins/");
|
|||||||
const QString AUTH_BASE("authserver.mojang.com/");
|
const QString AUTH_BASE("authserver.mojang.com/");
|
||||||
const QString FORGE_LEGACY_URL("http://files.minecraftforge.net/minecraftforge/json");
|
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 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");
|
||||||
}
|
}
|
||||||
|
137
logic/status/StatusChecker.cpp
Normal file
137
logic/status/StatusChecker.cpp
Normal file
@ -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);
|
||||||
|
}
|
||||||
|
|
57
logic/status/StatusChecker.h
Normal file
57
logic/status/StatusChecker.h
Normal file
@ -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);
|
||||||
|
};
|
||||||
|
|
Loading…
Reference in New Issue
Block a user