summaryrefslogtreecommitdiffstats
path: root/logic/notifications/NotificationChecker.cpp
blob: ab2570b702f759c5d5de9b3820b76ef72687eef3 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
#include "NotificationChecker.h"

#include <QJsonDocument>
#include <QJsonObject>
#include <QJsonArray>
#include <QDebug>

#include "Env.h"
#include "net/CacheDownload.h"


NotificationChecker::NotificationChecker(QObject *parent)
	: QObject(parent)
{
}

void NotificationChecker::setNotificationsUrl(const QUrl &notificationsUrl)
{
	m_notificationsUrl = notificationsUrl;
}

void NotificationChecker::setApplicationChannel(QString channel)
{
	m_appVersionChannel = channel;
}

void NotificationChecker::setApplicationFullVersion(QString version)
{
	m_appFullVersion = version;
}

void NotificationChecker::setApplicationPlatform(QString platform)
{
	m_appPlatform = platform;
}

QList<NotificationChecker::NotificationEntry> NotificationChecker::notificationEntries() const
{
	return m_entries;
}

void NotificationChecker::checkForNotifications()
{
	if (!m_notificationsUrl.isValid())
	{
		qCritical() << "Failed to check for notifications. No notifications URL set."
					 << "If you'd like to use MultiMC's notification system, please pass the "
						"URL to CMake at compile time.";
		return;
	}
	if (m_checkJob)
	{
		return;
	}
	m_checkJob.reset(new NetJob("Checking for notifications"));
	auto entry = ENV.metacache()->resolveEntry("root", "notifications.json");
	entry->setStale(true);
	m_checkJob->addNetAction(m_download = CacheDownload::make(m_notificationsUrl, entry));
	connect(m_download.get(), &CacheDownload::succeeded, this,
			&NotificationChecker::downloadSucceeded);
	m_checkJob->start();
}

void NotificationChecker::downloadSucceeded(int)
{
	m_entries.clear();

	QFile file(m_download->getTargetFilepath());
	if (file.open(QFile::ReadOnly))
	{
		QJsonArray root = QJsonDocument::fromJson(file.readAll()).array();
		for (auto it = root.begin(); it != root.end(); ++it)
		{
			QJsonObject obj = (*it).toObject();
			NotificationEntry entry;
			entry.id = obj.value("id").toDouble();
			entry.message = obj.value("message").toString();
			entry.channel = obj.value("channel").toString();
			entry.platform = obj.value("platform").toString();
			entry.from = obj.value("from").toString();
			entry.to = obj.value("to").toString();
			const QString type = obj.value("type").toString("critical");
			if (type == "critical")
			{
				entry.type = NotificationEntry::Critical;
			}
			else if (type == "warning")
			{
				entry.type = NotificationEntry::Warning;
			}
			else if (type == "information")
			{
				entry.type = NotificationEntry::Information;
			}
			if(entryApplies(entry))
				m_entries.append(entry);
		}
	}

	m_checkJob.reset();

	emit notificationCheckFinished();
}

bool versionLessThan(const QString &v1, const QString &v2)
{
	QStringList l1 = v1.split('.');
	QStringList l2 = v2.split('.');
	while (!l1.isEmpty() && !l2.isEmpty())
	{
		int one = l1.isEmpty() ? 0 : l1.takeFirst().toInt();
		int two = l2.isEmpty() ? 0 : l2.takeFirst().toInt();
		if (one != two)
		{
			return one < two;
		}
	}
	return false;
}

bool NotificationChecker::entryApplies(const NotificationChecker::NotificationEntry& entry) const
{
	bool channelApplies = entry.channel.isEmpty() || entry.channel == m_appVersionChannel;
	bool platformApplies = entry.platform.isEmpty() || entry.platform == m_appPlatform;
	bool fromApplies =
		entry.from.isEmpty() || entry.from == m_appFullVersion || !versionLessThan(m_appFullVersion, entry.from);
	bool toApplies =
		entry.to.isEmpty() || entry.to == m_appFullVersion || !versionLessThan(entry.to, m_appFullVersion);
	return channelApplies && platformApplies && fromApplies && toApplies;
}