Add release channels for autoupdater (#2362)
Fetch releases from github and find corresponding installers on bintray
This commit is contained in:
parent
b9cd942308
commit
7373819c32
16 changed files with 507 additions and 237 deletions
|
@ -3,8 +3,10 @@ set(VERSION_STRING_H "${PROJECT_BINARY_DIR}/version_string.h")
|
|||
INCLUDE_DIRECTORIES(${PROJECT_BINARY_DIR})
|
||||
|
||||
set( hstring "extern const char *VERSION_STRING\;
|
||||
extern const char *VERSION_COMMIT\;
|
||||
extern const char *VERSION_DATE\;\n" )
|
||||
set( cppstring "const char *VERSION_STRING = \"${PROJECT_VERSION_FRIENDLY}\"\;
|
||||
const char *VERSION_COMMIT = \"${GIT_COMMIT_ID}\"\;
|
||||
const char *VERSION_DATE = \"${GIT_COMMIT_DATE_FRIENDLY}\"\;\n")
|
||||
|
||||
file(WRITE ${PROJECT_BINARY_DIR}/version_string.cpp.txt ${cppstring} )
|
||||
|
|
|
@ -112,9 +112,9 @@ SET(cockatrice_SOURCES
|
|||
src/settings/messagesettings.cpp
|
||||
src/settings/gamefilterssettings.cpp
|
||||
src/settings/layoutssettings.cpp
|
||||
src/update_checker.cpp
|
||||
src/update_downloader.cpp
|
||||
src/logger.cpp
|
||||
src/releasechannel.cpp
|
||||
${VERSION_STRING_CPP}
|
||||
)
|
||||
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
#include "settingscache.h"
|
||||
#include "thememanager.h"
|
||||
#include "priceupdater.h"
|
||||
#include "releasechannel.h"
|
||||
#include "soundengine.h"
|
||||
#include "sequenceEdit/shortcutstab.h"
|
||||
|
||||
|
@ -44,8 +45,18 @@ GeneralSettingsPage::GeneralSettingsPage()
|
|||
}
|
||||
|
||||
picDownloadCheckBox.setChecked(settingsCache->getPicDownload());
|
||||
|
||||
// updates
|
||||
QList<ReleaseChannel*> channels = settingsCache->getUpdateReleaseChannels();
|
||||
foreach(ReleaseChannel* chan, channels)
|
||||
{
|
||||
updateReleaseChannelBox.insertItem(chan->getIndex(), tr(chan->getName().toUtf8()));
|
||||
}
|
||||
updateReleaseChannelBox.setCurrentIndex(settingsCache->getUpdateReleaseChannel()->getIndex());
|
||||
|
||||
updateNotificationCheckBox.setChecked(settingsCache->getNotifyAboutUpdates());
|
||||
|
||||
// pixmap cache
|
||||
pixmapCacheEdit.setMinimum(PIXMAPCACHE_SIZE_MIN);
|
||||
// 2047 is the max value to avoid overflowing of QPixmapCache::setCacheLimit(int size)
|
||||
pixmapCacheEdit.setMaximum(PIXMAPCACHE_SIZE_MAX);
|
||||
|
@ -60,6 +71,7 @@ GeneralSettingsPage::GeneralSettingsPage()
|
|||
connect(&languageBox, SIGNAL(currentIndexChanged(int)), this, SLOT(languageBoxChanged(int)));
|
||||
connect(&picDownloadCheckBox, SIGNAL(stateChanged(int)), settingsCache, SLOT(setPicDownload(int)));
|
||||
connect(&pixmapCacheEdit, SIGNAL(valueChanged(int)), settingsCache, SLOT(setPixmapCacheSize(int)));
|
||||
connect(&updateReleaseChannelBox, SIGNAL(currentIndexChanged(int)), settingsCache, SLOT(setUpdateReleaseChannel(int)));
|
||||
connect(&updateNotificationCheckBox, SIGNAL(stateChanged(int)), settingsCache, SLOT(setNotifyAboutUpdate(int)));
|
||||
connect(&picDownloadCheckBox, SIGNAL(clicked(bool)), this, SLOT(setEnabledStatus(bool)));
|
||||
connect(defaultUrlEdit, SIGNAL(textChanged(QString)), settingsCache, SLOT(setPicUrl(QString)));
|
||||
|
@ -74,16 +86,18 @@ GeneralSettingsPage::GeneralSettingsPage()
|
|||
personalGrid->addWidget(&languageBox, 0, 1);
|
||||
personalGrid->addWidget(&pixmapCacheLabel, 1, 0);
|
||||
personalGrid->addWidget(&pixmapCacheEdit, 1, 1);
|
||||
personalGrid->addWidget(&updateNotificationCheckBox, 2, 0);
|
||||
personalGrid->addWidget(&picDownloadCheckBox, 3, 0, 1, 3);
|
||||
personalGrid->addWidget(&defaultUrlLabel, 4, 0, 1, 1);
|
||||
personalGrid->addWidget(defaultUrlEdit, 4, 1, 1, 1);
|
||||
personalGrid->addWidget(&defaultUrlRestoreButton, 4, 2, 1, 1);
|
||||
personalGrid->addWidget(&fallbackUrlLabel, 5, 0, 1, 1);
|
||||
personalGrid->addWidget(fallbackUrlEdit, 5, 1, 1, 1);
|
||||
personalGrid->addWidget(&fallbackUrlRestoreButton, 5, 2, 1, 1);
|
||||
personalGrid->addWidget(&urlLinkLabel, 6, 1, 1, 1);
|
||||
personalGrid->addWidget(&clearDownloadedPicsButton, 7, 0, 1, 3);
|
||||
personalGrid->addWidget(&updateReleaseChannelLabel, 2, 0);
|
||||
personalGrid->addWidget(&updateReleaseChannelBox, 2, 1);
|
||||
personalGrid->addWidget(&updateNotificationCheckBox, 3, 0);
|
||||
personalGrid->addWidget(&picDownloadCheckBox, 4, 0, 1, 3);
|
||||
personalGrid->addWidget(&defaultUrlLabel, 5, 0, 1, 1);
|
||||
personalGrid->addWidget(defaultUrlEdit, 5, 1, 1, 1);
|
||||
personalGrid->addWidget(&defaultUrlRestoreButton, 5, 2, 1, 1);
|
||||
personalGrid->addWidget(&fallbackUrlLabel, 6, 0, 1, 1);
|
||||
personalGrid->addWidget(fallbackUrlEdit, 6, 1, 1, 1);
|
||||
personalGrid->addWidget(&fallbackUrlRestoreButton, 6, 2, 1, 1);
|
||||
personalGrid->addWidget(&urlLinkLabel, 7, 1, 1, 1);
|
||||
personalGrid->addWidget(&clearDownloadedPicsButton, 8, 0, 1, 3);
|
||||
|
||||
urlLinkLabel.setTextInteractionFlags(Qt::LinksAccessibleByMouse);
|
||||
urlLinkLabel.setOpenExternalLinks(true);
|
||||
|
@ -269,8 +283,9 @@ void GeneralSettingsPage::retranslateUi()
|
|||
defaultUrlLabel.setText(tr("Primary download URL:"));
|
||||
fallbackUrlLabel.setText(tr("Fallback download URL:"));
|
||||
urlLinkLabel.setText(QString("<a href='%1'>%2</a>").arg(WIKI_CUSTOM_PIC_URL).arg(tr("How to set a custom picture url")));
|
||||
clearDownloadedPicsButton.setText(tr("Reset/Clear Downloaded Pictures"));
|
||||
updateNotificationCheckBox.setText(tr("Notify when new client features are available"));
|
||||
clearDownloadedPicsButton.setText(tr("Reset/clear downloaded pictures"));
|
||||
updateReleaseChannelLabel.setText(tr("Update channel"));
|
||||
updateNotificationCheckBox.setText(tr("Notify when a new version is available"));
|
||||
defaultUrlRestoreButton.setText(tr("Reset"));
|
||||
fallbackUrlRestoreButton.setText(tr("Reset"));
|
||||
}
|
||||
|
|
|
@ -63,6 +63,7 @@ private:
|
|||
QComboBox languageBox;
|
||||
QCheckBox picDownloadCheckBox;
|
||||
QCheckBox updateNotificationCheckBox;
|
||||
QComboBox updateReleaseChannelBox;
|
||||
QLabel languageLabel;
|
||||
QLabel pixmapCacheLabel;
|
||||
QLabel deckPathLabel;
|
||||
|
@ -73,6 +74,7 @@ private:
|
|||
QLabel defaultUrlLabel;
|
||||
QLabel fallbackUrlLabel;
|
||||
QLabel urlLinkLabel;
|
||||
QLabel updateReleaseChannelLabel;
|
||||
QPushButton clearDownloadedPicsButton;
|
||||
QPushButton defaultUrlRestoreButton;
|
||||
QPushButton fallbackUrlRestoreButton;
|
||||
|
|
|
@ -1,9 +1,3 @@
|
|||
#define HUMAN_DOWNLOAD_URL "https://bintray.com/cockatrice/Cockatrice/Cockatrice/_latestVersion"
|
||||
#define API_DOWNLOAD_BASE_URL "https://dl.bintray.com/cockatrice/Cockatrice/"
|
||||
#define DATE_LENGTH 10
|
||||
#define MAX_DATE_LENGTH 100
|
||||
#define SHORT_SHA1_HASH_LENGTH 7
|
||||
|
||||
#include <QtNetwork>
|
||||
#include <QProgressDialog>
|
||||
#include <QDesktopServices>
|
||||
|
@ -16,12 +10,15 @@
|
|||
#include <QApplication>
|
||||
|
||||
#include "dlg_update.h"
|
||||
#include "releasechannel.h"
|
||||
#include "settingscache.h"
|
||||
#include "window_main.h"
|
||||
|
||||
DlgUpdate::DlgUpdate(QWidget *parent) : QDialog(parent) {
|
||||
|
||||
//Handle layout
|
||||
text = new QLabel(this);
|
||||
statusLabel = new QLabel(this);
|
||||
descriptionLabel = new QLabel(tr("Current release channel:") + " " + tr(settingsCache->getUpdateReleaseChannel()->getName().toUtf8()), this);
|
||||
progress = new QProgressBar(this);
|
||||
|
||||
QDialogButtonBox *buttonBox = new QDialogButtonBox(this);
|
||||
|
@ -38,7 +35,8 @@ DlgUpdate::DlgUpdate(QWidget *parent) : QDialog(parent) {
|
|||
connect(ok, SIGNAL(clicked()), this, SLOT(closeDialog()));
|
||||
|
||||
QVBoxLayout *parentLayout = new QVBoxLayout(this);
|
||||
parentLayout->addWidget(text);
|
||||
parentLayout->addWidget(descriptionLabel);
|
||||
parentLayout->addWidget(statusLabel);
|
||||
parentLayout->addWidget(progress);
|
||||
parentLayout->addWidget(buttonBox);
|
||||
|
||||
|
@ -47,11 +45,9 @@ DlgUpdate::DlgUpdate(QWidget *parent) : QDialog(parent) {
|
|||
//Check for SSL (this probably isn't necessary)
|
||||
if (!QSslSocket::supportsSsl()) {
|
||||
enableUpdateButton(false);
|
||||
QMessageBox::critical(
|
||||
this,
|
||||
tr("Error"),
|
||||
tr("Cockatrice was not built with SSL support, so cannot download updates! "
|
||||
"Please visit the download page and update manually."));
|
||||
QMessageBox::critical(this, tr("Error"),
|
||||
tr("Cockatrice was not built with SSL support, so you cannot download updates automatically! "
|
||||
"Please visit the download page to update manually."));
|
||||
}
|
||||
|
||||
//Initialize the checker and downloader class
|
||||
|
@ -62,10 +58,10 @@ DlgUpdate::DlgUpdate(QWidget *parent) : QDialog(parent) {
|
|||
connect(uDownloader, SIGNAL(error(QString)),
|
||||
this, SLOT(downloadError(QString)));
|
||||
|
||||
uChecker = new UpdateChecker(this);
|
||||
connect(uChecker, SIGNAL(finishedCheck(bool, bool, QVariantMap * )),
|
||||
this, SLOT(finishedUpdateCheck(bool, bool, QVariantMap * )));
|
||||
connect(uChecker, SIGNAL(error(QString)),
|
||||
ReleaseChannel * channel = settingsCache->getUpdateReleaseChannel();
|
||||
connect(channel, SIGNAL(finishedCheck(bool, bool, Release * )),
|
||||
this, SLOT(finishedUpdateCheck(bool, bool, Release * )));
|
||||
connect(channel, SIGNAL(error(QString)),
|
||||
this, SLOT(updateCheckError(QString)));
|
||||
|
||||
//Check for updates
|
||||
|
@ -79,8 +75,7 @@ void DlgUpdate::closeDialog() {
|
|||
|
||||
|
||||
void DlgUpdate::gotoDownloadPage() {
|
||||
QUrl openUrl(HUMAN_DOWNLOAD_URL);
|
||||
QDesktopServices::openUrl(openUrl);
|
||||
QDesktopServices::openUrl(settingsCache->getUpdateReleaseChannel()->getManualDownloadUrl());
|
||||
}
|
||||
|
||||
void DlgUpdate::downloadUpdate() {
|
||||
|
@ -94,12 +89,12 @@ void DlgUpdate::beginUpdateCheck() {
|
|||
progress->setMinimum(0);
|
||||
progress->setMaximum(0);
|
||||
setLabel(tr("Checking for updates..."));
|
||||
uChecker->check();
|
||||
settingsCache->getUpdateReleaseChannel()->checkForUpdates();
|
||||
}
|
||||
|
||||
void DlgUpdate::finishedUpdateCheck(bool needToUpdate, bool isCompatible, QVariantMap *build) {
|
||||
void DlgUpdate::finishedUpdateCheck(bool needToUpdate, bool isCompatible, Release *release) {
|
||||
|
||||
QString commitHash, commitDate;
|
||||
QString publishDate, versionName;
|
||||
|
||||
//Update the UI to say we've finished
|
||||
progress->setMaximum(100);
|
||||
|
@ -108,40 +103,34 @@ void DlgUpdate::finishedUpdateCheck(bool needToUpdate, bool isCompatible, QVaria
|
|||
//If there are no available builds, then they can't auto update.
|
||||
enableUpdateButton(isCompatible);
|
||||
|
||||
//If there is an update, save its URL and work out its name
|
||||
if (isCompatible) {
|
||||
QString endUrl = (*build)["path"].toString();
|
||||
updateUrl = API_DOWNLOAD_BASE_URL + endUrl;
|
||||
commitHash = (*build)["sha1"].toString().left(SHORT_SHA1_HASH_LENGTH);
|
||||
commitDate = (*build)["created"].toString().remove(DATE_LENGTH, MAX_DATE_LENGTH);
|
||||
}
|
||||
|
||||
//Give the user the appropriate message
|
||||
if (needToUpdate) {
|
||||
if (isCompatible) {
|
||||
|
||||
QMessageBox::StandardButton reply;
|
||||
reply = QMessageBox::question(this, "Update Available",
|
||||
"A new build (commit " + commitHash + ") from " + commitDate +
|
||||
" is available. Download?",
|
||||
QMessageBox::Yes | QMessageBox::No);
|
||||
if (reply == QMessageBox::Yes)
|
||||
downloadUpdate();
|
||||
}
|
||||
else
|
||||
{
|
||||
QMessageBox::information(this, tr("Cockatrice Update"),
|
||||
tr("Your version of Cockatrice is out of date, but there are no packages"
|
||||
" available for your operating system. You may have to use a developer build or build from source"
|
||||
" yourself. Please visit the download page."));
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (!needToUpdate) {
|
||||
//If there's no need to update, tell them that. However we still allow them to run the
|
||||
//downloader themselves if there's a compatible build
|
||||
QMessageBox::information(this, tr("Cockatrice Update"), tr("Your version of Cockatrice is up to date."));
|
||||
}
|
||||
|
||||
if (isCompatible) {
|
||||
//If there is an update, save its URL and work out its name
|
||||
updateUrl = release->getDownloadUrl();
|
||||
publishDate = release->getPublishDate().toString(Qt::DefaultLocaleLongDate);
|
||||
|
||||
QMessageBox::StandardButton reply;
|
||||
reply = QMessageBox::question(this, "Update Available",
|
||||
tr("A new version is available:<br/>%1<br/>published on %2 ."
|
||||
"<br/>More informations are available on the <a href=\"%3\">release changelog</a>"
|
||||
"<br/>Do you want to update now?").arg(release->getName(), publishDate, release->getDescriptionUrl()),
|
||||
QMessageBox::Yes | QMessageBox::No);
|
||||
|
||||
if (reply == QMessageBox::Yes)
|
||||
downloadUpdate();
|
||||
} else {
|
||||
QMessageBox::information(this, tr("Cockatrice Update"),
|
||||
tr("A new version is available:<br/>%1<br/>published on %2 ."
|
||||
"<br/>More informations are available on the <a href=\"%3\">release changelog</a>"
|
||||
"<br/>Unfortunately there are no packages available for your operating system. "
|
||||
"You may have to use a developer build or build from source yourself. Please visit the download page.").arg(release->getName(), publishDate, release->getDescriptionUrl()));
|
||||
}
|
||||
}
|
||||
|
||||
void DlgUpdate::enableUpdateButton(bool enable) {
|
||||
|
@ -153,7 +142,7 @@ void DlgUpdate::enableOkButton(bool enable) {
|
|||
}
|
||||
|
||||
void DlgUpdate::setLabel(QString newText) {
|
||||
text->setText(newText);
|
||||
statusLabel->setText(newText);
|
||||
}
|
||||
|
||||
void DlgUpdate::updateCheckError(QString errorString) {
|
||||
|
@ -176,8 +165,8 @@ void DlgUpdate::downloadSuccessful(QUrl filepath) {
|
|||
close();
|
||||
} else {
|
||||
setLabel(tr("Error"));
|
||||
QMessageBox::critical(this, tr("Update Error"), "Unable to open the installer. You might be able to manually update"
|
||||
" by closing Cockatrice and running the installer at " + filepath.toLocalFile() + ".");
|
||||
QMessageBox::critical(this, tr("Update Error"),
|
||||
tr("Unable to open the installer. You might be able to manually update by closing Cockatrice and running the installer at %1.").arg(filepath.toLocalFile()));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -4,8 +4,8 @@
|
|||
#include <QtNetwork>
|
||||
#include <QProgressDialog>
|
||||
|
||||
#include "update_checker.h"
|
||||
#include "update_downloader.h"
|
||||
class Release;
|
||||
|
||||
class DlgUpdate : public QDialog {
|
||||
Q_OBJECT
|
||||
|
@ -13,7 +13,7 @@ public:
|
|||
DlgUpdate(QWidget *parent);
|
||||
|
||||
private slots:
|
||||
void finishedUpdateCheck(bool needToUpdate, bool isCompatible, QVariantMap *build);
|
||||
void finishedUpdateCheck(bool needToUpdate, bool isCompatible, Release *release);
|
||||
void gotoDownloadPage();
|
||||
void downloadUpdate();
|
||||
void updateCheckError(QString errorString);
|
||||
|
@ -27,11 +27,10 @@ private:
|
|||
void enableOkButton(bool enable);
|
||||
void beginUpdateCheck();
|
||||
void setLabel(QString text);
|
||||
QLabel *text;
|
||||
QLabel *statusLabel, *descriptionLabel;
|
||||
QProgressBar *progress;
|
||||
QPushButton *manualDownload, *gotoDownload, *ok;
|
||||
QPushButton *cancel;
|
||||
UpdateChecker *uChecker;
|
||||
UpdateDownloader *uDownloader;
|
||||
};
|
||||
|
||||
|
|
312
cockatrice/src/releasechannel.cpp
Normal file
312
cockatrice/src/releasechannel.cpp
Normal file
|
@ -0,0 +1,312 @@
|
|||
#include "releasechannel.h"
|
||||
#include "qt-json/json.h"
|
||||
#include "version_string.h"
|
||||
|
||||
#include <QNetworkReply>
|
||||
#include <QNetworkAccessManager>
|
||||
#include <QMessageBox>
|
||||
|
||||
#define STABLERELEASE_URL "https://api.github.com/repos/Cockatrice/Cockatrice/releases/latest"
|
||||
#define STABLETAG_URL "https://api.github.com/repos/Cockatrice/Cockatrice/git/refs/tags/"
|
||||
#define STABLEFILES_URL "https://api.bintray.com/packages/cockatrice/Cockatrice/Cockatrice/files"
|
||||
#define STABLEDOWNLOAD_URL "https://dl.bintray.com/cockatrice/Cockatrice/"
|
||||
#define STABLEMANUALDOWNLOAD_URL "https://bintray.com/cockatrice/Cockatrice/Cockatrice/_latestVersion#files"
|
||||
|
||||
#define DEVRELEASE_URL "https://api.github.com/repos/Cockatrice/Cockatrice/commits/master"
|
||||
#define DEVFILES_URL "https://api.bintray.com/packages/cockatrice/Cockatrice/Cockatrice-git/files"
|
||||
#define DEVDOWNLOAD_URL "https://dl.bintray.com/cockatrice/Cockatrice/"
|
||||
#define DEVMANUALDOWNLOAD_URL "https://bintray.com/cockatrice/Cockatrice/Cockatrice-git/_latestVersion#files"
|
||||
#define GIT_SHORT_HASH_LEN 7
|
||||
|
||||
int ReleaseChannel::sharedIndex = 0;
|
||||
|
||||
ReleaseChannel::ReleaseChannel()
|
||||
: response(nullptr), lastRelease(nullptr)
|
||||
{
|
||||
index = sharedIndex++;
|
||||
netMan = new QNetworkAccessManager(this);
|
||||
}
|
||||
|
||||
ReleaseChannel::~ReleaseChannel()
|
||||
{
|
||||
netMan->deleteLater();
|
||||
}
|
||||
|
||||
void ReleaseChannel::checkForUpdates()
|
||||
{
|
||||
QString releaseChannelUrl = getReleaseChannelUrl();
|
||||
qDebug() << "Searching for updates on the channel: " << releaseChannelUrl;
|
||||
response = netMan->get(QNetworkRequest(releaseChannelUrl));
|
||||
connect(response, SIGNAL(finished()), this, SLOT(releaseListFinished()));
|
||||
}
|
||||
|
||||
#if defined(Q_OS_OSX)
|
||||
bool ReleaseChannel::downloadMatchesCurrentOS(QVariantMap build)
|
||||
{
|
||||
return build["name"].toString().endsWith(".dmg");
|
||||
}
|
||||
|
||||
#elif defined(Q_OS_WIN)
|
||||
|
||||
#include <QSysInfo>
|
||||
|
||||
bool ReleaseChannel::downloadMatchesCurrentOS(QVariantMap build)
|
||||
{
|
||||
QString wordSize = QSysInfo::buildAbi().split('-')[2];
|
||||
QString arch;
|
||||
if (wordSize == "llp64") {
|
||||
arch = "win64";
|
||||
} else if (wordSize == "ilp32") {
|
||||
arch = "win32";
|
||||
} else {
|
||||
qWarning() << "Error checking for upgrade version: wordSize is" << wordSize;
|
||||
return false;
|
||||
}
|
||||
|
||||
auto fileName = build["name"].toString();
|
||||
// Checking for .zip is a workaround for the May 6th 2016 release
|
||||
auto zipName = arch + ".zip";
|
||||
auto exeName = arch + ".exe";
|
||||
return fileName.endsWith(exeName) || fileName.endsWith(zipName);
|
||||
}
|
||||
#else
|
||||
|
||||
bool ReleaseChannel::downloadMatchesCurrentOS(QVariantMap)
|
||||
{
|
||||
//If the OS doesn't fit one of the above #defines, then it will never match
|
||||
return false;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
QString StableReleaseChannel::getManualDownloadUrl() const
|
||||
{
|
||||
return QString(STABLEMANUALDOWNLOAD_URL);
|
||||
}
|
||||
|
||||
QString StableReleaseChannel::getName() const
|
||||
{
|
||||
return tr("Stable releases");
|
||||
}
|
||||
|
||||
QString StableReleaseChannel::getReleaseChannelUrl() const
|
||||
{
|
||||
return QString(STABLERELEASE_URL);
|
||||
}
|
||||
|
||||
void StableReleaseChannel::releaseListFinished()
|
||||
{
|
||||
QNetworkReply *reply = static_cast<QNetworkReply *>(sender());
|
||||
bool ok;
|
||||
QString tmp = QString(reply->readAll());
|
||||
reply->deleteLater();
|
||||
|
||||
QVariantMap resultMap = QtJson::Json::parse(tmp, ok).toMap();
|
||||
if (!ok) {
|
||||
qWarning() << "No reply received from the release update server:" << tmp;
|
||||
emit error(tr("No reply received from the release update server."));
|
||||
return;
|
||||
}
|
||||
|
||||
if(!(resultMap.contains("name") &&
|
||||
resultMap.contains("html_url") &&
|
||||
resultMap.contains("tag_name") &&
|
||||
resultMap.contains("published_at"))) {
|
||||
qWarning() << "Invalid received from the release update server:" << tmp;
|
||||
emit error(tr("Invalid reply received from the release update server."));
|
||||
return;
|
||||
}
|
||||
|
||||
if(!lastRelease)
|
||||
lastRelease = new Release;
|
||||
|
||||
lastRelease->setName(resultMap["name"].toString());
|
||||
lastRelease->setDescriptionUrl(resultMap["html_url"].toString());
|
||||
lastRelease->setPublishDate(resultMap["published_at"].toDate());
|
||||
|
||||
qDebug() << "Got reply from release server, size=" << tmp.size()
|
||||
<< "name=" << lastRelease->getName()
|
||||
<< "desc=" << lastRelease->getDescriptionUrl()
|
||||
<< "date=" << lastRelease->getPublishDate();
|
||||
|
||||
QString url = QString(STABLETAG_URL) + resultMap["tag_name"].toString();
|
||||
qDebug() << "Searching for a corresponding tag on the stable channel: " << url;
|
||||
response = netMan->get(QNetworkRequest(url));
|
||||
connect(response, SIGNAL(finished()), this, SLOT(tagListFinished()));
|
||||
}
|
||||
|
||||
void StableReleaseChannel::tagListFinished()
|
||||
{
|
||||
QNetworkReply *reply = static_cast<QNetworkReply *>(sender());
|
||||
bool ok;
|
||||
QString tmp = QString(reply->readAll());
|
||||
reply->deleteLater();
|
||||
|
||||
QVariantMap resultMap = QtJson::Json::parse(tmp, ok).toMap();
|
||||
if (!ok) {
|
||||
qWarning() << "No reply received from the tag update server:" << tmp;
|
||||
emit error(tr("No reply received from the tag update server."));
|
||||
return;
|
||||
}
|
||||
|
||||
if(!(resultMap.contains("object") &&
|
||||
resultMap["object"].toMap().contains("sha"))) {
|
||||
qWarning() << "Invalid received from the tag update server:" << tmp;
|
||||
emit error(tr("Invalid reply received from the tag update server."));
|
||||
return;
|
||||
}
|
||||
|
||||
lastRelease->setCommitHash(resultMap["object"].toMap()["sha"].toString());
|
||||
qDebug() << "Got reply from tag server, size=" << tmp.size()
|
||||
<< "commit=" << lastRelease->getCommitHash();
|
||||
|
||||
qDebug() << "Searching for a corresponding file on the stable channel: " << QString(STABLEFILES_URL);
|
||||
response = netMan->get(QNetworkRequest(QString(STABLEFILES_URL)));
|
||||
connect(response, SIGNAL(finished()), this, SLOT(fileListFinished()));
|
||||
}
|
||||
|
||||
void StableReleaseChannel::fileListFinished()
|
||||
{
|
||||
QNetworkReply *reply = static_cast<QNetworkReply *>(sender());
|
||||
bool ok;
|
||||
QString tmp = QString(reply->readAll());
|
||||
reply->deleteLater();
|
||||
|
||||
QVariantList resultList = QtJson::Json::parse(tmp, ok).toList();
|
||||
if (!ok) {
|
||||
qWarning() << "No reply received from the file update server:" << tmp;
|
||||
emit error(tr("No reply received from the file update server."));
|
||||
return;
|
||||
}
|
||||
|
||||
QString shortHash = lastRelease->getCommitHash().left(GIT_SHORT_HASH_LEN);
|
||||
QString myHash = QString(VERSION_COMMIT);
|
||||
qDebug() << "Current hash=" << myHash << "update hash=" << shortHash;
|
||||
|
||||
bool needToUpdate = (QString::compare(shortHash, myHash, Qt::CaseInsensitive) != 0);
|
||||
bool compatibleVersion = false;
|
||||
|
||||
foreach(QVariant file, resultList)
|
||||
{
|
||||
QVariantMap map = file.toMap();
|
||||
// TODO: map github version to bintray version
|
||||
/*
|
||||
if(!map.contains("version"))
|
||||
continue;
|
||||
if(!map["version"].toString().endsWith(shortHash))
|
||||
continue;
|
||||
*/
|
||||
|
||||
if(!downloadMatchesCurrentOS(map))
|
||||
continue;
|
||||
|
||||
compatibleVersion = true;
|
||||
|
||||
QString url = QString(STABLEDOWNLOAD_URL) + map["path"].toString();
|
||||
lastRelease->setDownloadUrl(url);
|
||||
qDebug() << "Found compatible version url=" << url;
|
||||
break;
|
||||
}
|
||||
|
||||
emit finishedCheck(needToUpdate, compatibleVersion, lastRelease);
|
||||
}
|
||||
|
||||
QString DevReleaseChannel::getManualDownloadUrl() const
|
||||
{
|
||||
return QString(DEVMANUALDOWNLOAD_URL);
|
||||
}
|
||||
|
||||
QString DevReleaseChannel::getName() const
|
||||
{
|
||||
return tr("Development snapshots");
|
||||
}
|
||||
|
||||
QString DevReleaseChannel::getReleaseChannelUrl() const
|
||||
{
|
||||
return QString(DEVRELEASE_URL);
|
||||
}
|
||||
|
||||
void DevReleaseChannel::releaseListFinished()
|
||||
{
|
||||
QNetworkReply *reply = static_cast<QNetworkReply *>(sender());
|
||||
bool ok;
|
||||
QString tmp = QString(reply->readAll());
|
||||
reply->deleteLater();
|
||||
|
||||
QVariantMap resultMap = QtJson::Json::parse(tmp, ok).toMap();
|
||||
if (!ok) {
|
||||
qWarning() << "No reply received from the release update server:" << tmp;
|
||||
emit error(tr("No reply received from the release update server."));
|
||||
return;
|
||||
}
|
||||
|
||||
if(!(resultMap.contains("commit") &&
|
||||
resultMap.contains("html_url") &&
|
||||
resultMap.contains("sha") &&
|
||||
resultMap["commit"].toMap().contains("author") &&
|
||||
resultMap["commit"].toMap()["author"].toMap().contains("date"))) {
|
||||
qWarning() << "Invalid received from the release update server:" << tmp;
|
||||
emit error(tr("Invalid reply received from the release update server."));
|
||||
return;
|
||||
}
|
||||
|
||||
if(!lastRelease)
|
||||
lastRelease = new Release;
|
||||
|
||||
lastRelease->setName("Commit " + resultMap["sha"].toString());
|
||||
lastRelease->setDescriptionUrl(resultMap["html_url"].toString());
|
||||
lastRelease->setCommitHash(resultMap["sha"].toString());
|
||||
lastRelease->setPublishDate(resultMap["commit"].toMap()["author"].toMap()["date"].toDate());
|
||||
|
||||
qDebug() << "Got reply from release server, size=" << tmp.size()
|
||||
<< "name=" << lastRelease->getName()
|
||||
<< "desc=" << lastRelease->getDescriptionUrl()
|
||||
<< "commit=" << lastRelease->getCommitHash()
|
||||
<< "date=" << lastRelease->getPublishDate();
|
||||
|
||||
qDebug() << "Searching for a corresponding file on the dev channel: " << QString(DEVFILES_URL);
|
||||
response = netMan->get(QNetworkRequest(QString(DEVFILES_URL)));
|
||||
connect(response, SIGNAL(finished()), this, SLOT(fileListFinished()));
|
||||
}
|
||||
|
||||
void DevReleaseChannel::fileListFinished()
|
||||
{
|
||||
QNetworkReply *reply = static_cast<QNetworkReply *>(sender());
|
||||
bool ok;
|
||||
QString tmp = QString(reply->readAll());
|
||||
reply->deleteLater();
|
||||
|
||||
QVariantList resultList = QtJson::Json::parse(tmp, ok).toList();
|
||||
if (!ok) {
|
||||
qWarning() << "No reply received from the file update server:" << tmp;
|
||||
emit error(tr("No reply received from the file update server."));
|
||||
return;
|
||||
}
|
||||
|
||||
QString shortHash = lastRelease->getCommitHash().left(GIT_SHORT_HASH_LEN);
|
||||
QString myHash = QString(VERSION_COMMIT);
|
||||
qDebug() << "Current hash=" << myHash << "update hash=" << shortHash;
|
||||
|
||||
bool needToUpdate = (QString::compare(shortHash, myHash, Qt::CaseInsensitive) != 0);
|
||||
bool compatibleVersion = false;
|
||||
|
||||
foreach(QVariant file, resultList)
|
||||
{
|
||||
QVariantMap map = file.toMap();
|
||||
if(!map.contains("version"))
|
||||
continue;
|
||||
if(!map["version"].toString().endsWith(shortHash))
|
||||
continue;
|
||||
|
||||
if(!downloadMatchesCurrentOS(map))
|
||||
continue;
|
||||
|
||||
compatibleVersion = true;
|
||||
QString url = QString(DEVDOWNLOAD_URL) + map["path"].toString();
|
||||
lastRelease->setDownloadUrl(url);
|
||||
qDebug() << "Found compatible version url=" << url;
|
||||
break;
|
||||
}
|
||||
|
||||
emit finishedCheck(needToUpdate, compatibleVersion, lastRelease);
|
||||
}
|
93
cockatrice/src/releasechannel.h
Normal file
93
cockatrice/src/releasechannel.h
Normal file
|
@ -0,0 +1,93 @@
|
|||
#ifndef RELEASECHANNEL_H
|
||||
#define RELEASECHANNEL_H
|
||||
|
||||
#include <QString>
|
||||
#include <QDate>
|
||||
#include <QObject>
|
||||
#include <QVariantMap>
|
||||
|
||||
class QNetworkReply;
|
||||
class QNetworkAccessManager;
|
||||
|
||||
class Release {
|
||||
friend class StableReleaseChannel;
|
||||
friend class DevReleaseChannel;
|
||||
public:
|
||||
Release() {};
|
||||
~Release() {};
|
||||
private:
|
||||
QString name, descriptionUrl, downloadUrl, commitHash;
|
||||
QDate publishDate;
|
||||
protected:
|
||||
void setName(QString _name) { name = _name; }
|
||||
void setDescriptionUrl(QString _descriptionUrl) { descriptionUrl = _descriptionUrl; }
|
||||
void setDownloadUrl(QString _downloadUrl) { downloadUrl = _downloadUrl; }
|
||||
void setCommitHash(QString _commitHash) { commitHash = _commitHash; }
|
||||
void setPublishDate(QDate _publishDate) { publishDate = _publishDate; }
|
||||
public:
|
||||
QString getName() const { return name; }
|
||||
QString getDescriptionUrl() const { return descriptionUrl; }
|
||||
QString getDownloadUrl() const { return downloadUrl; }
|
||||
QString getCommitHash() const { return commitHash; }
|
||||
QDate getPublishDate() const { return publishDate; }
|
||||
};
|
||||
|
||||
class ReleaseChannel: public QObject {
|
||||
Q_OBJECT
|
||||
public:
|
||||
ReleaseChannel();
|
||||
~ReleaseChannel();
|
||||
protected:
|
||||
// shared by all instances
|
||||
static int sharedIndex;
|
||||
int index;
|
||||
QNetworkAccessManager *netMan;
|
||||
QNetworkReply *response;
|
||||
Release * lastRelease;
|
||||
protected:
|
||||
static bool downloadMatchesCurrentOS(QVariantMap build);
|
||||
virtual QString getReleaseChannelUrl() const = 0;
|
||||
public:
|
||||
int getIndex() const { return index; }
|
||||
Release * getLastRelease() { return lastRelease; }
|
||||
virtual QString getManualDownloadUrl() const = 0;
|
||||
virtual QString getName() const = 0;
|
||||
void checkForUpdates();
|
||||
signals:
|
||||
void finishedCheck(bool needToUpdate, bool isCompatible, Release *release);
|
||||
void error(QString errorString);
|
||||
protected slots:
|
||||
virtual void releaseListFinished() = 0;
|
||||
virtual void fileListFinished() = 0;
|
||||
};
|
||||
|
||||
class StableReleaseChannel: public ReleaseChannel {
|
||||
Q_OBJECT
|
||||
public:
|
||||
StableReleaseChannel() {};
|
||||
~StableReleaseChannel() {};
|
||||
virtual QString getManualDownloadUrl() const;
|
||||
virtual QString getName() const;
|
||||
protected:
|
||||
virtual QString getReleaseChannelUrl() const;
|
||||
protected slots:
|
||||
virtual void releaseListFinished();
|
||||
void tagListFinished();
|
||||
virtual void fileListFinished();
|
||||
};
|
||||
|
||||
class DevReleaseChannel: public ReleaseChannel {
|
||||
Q_OBJECT
|
||||
public:
|
||||
DevReleaseChannel() {};
|
||||
~DevReleaseChannel() {};
|
||||
virtual QString getManualDownloadUrl() const;
|
||||
virtual QString getName() const;
|
||||
protected:
|
||||
virtual QString getReleaseChannelUrl() const;
|
||||
protected slots:
|
||||
virtual void releaseListFinished();
|
||||
virtual void fileListFinished();
|
||||
};
|
||||
|
||||
#endif
|
|
@ -1,4 +1,6 @@
|
|||
#include "settingscache.h"
|
||||
#include "releasechannel.h"
|
||||
|
||||
#include <QSettings>
|
||||
#include <QFile>
|
||||
#include <QDir>
|
||||
|
@ -162,7 +164,13 @@ SettingsCache::SettingsCache()
|
|||
if(!QFile(settingsPath+"global.ini").exists())
|
||||
translateLegacySettings();
|
||||
|
||||
// updates - don't reorder them or their index in the settings won't match
|
||||
releaseChannels << new StableReleaseChannel()
|
||||
<< new DevReleaseChannel();
|
||||
|
||||
notifyAboutUpdates = settings->value("personal/updatenotification", true).toBool();
|
||||
updateReleaseChannel = settings->value("personal/updatereleasechannel", 0).toInt();
|
||||
|
||||
lang = settings->value("personal/lang").toString();
|
||||
keepalive = settings->value("personal/keepalive", 5).toInt();
|
||||
|
||||
|
@ -642,4 +650,10 @@ void SettingsCache::setNotifyAboutUpdate(int _notifyaboutupdate)
|
|||
{
|
||||
notifyAboutUpdates = _notifyaboutupdate;
|
||||
settings->setValue("personal/updatenotification", notifyAboutUpdates);
|
||||
}
|
||||
}
|
||||
|
||||
void SettingsCache::setUpdateReleaseChannel(int _updateReleaseChannel)
|
||||
{
|
||||
updateReleaseChannel = _updateReleaseChannel;
|
||||
settings->setValue("personal/updatereleasechannel", updateReleaseChannel);
|
||||
}
|
||||
|
|
|
@ -11,6 +11,8 @@
|
|||
#include "settings/gamefilterssettings.h"
|
||||
#include "settings/layoutssettings.h"
|
||||
|
||||
class ReleaseChannel;
|
||||
|
||||
// the falbacks are used for cards without a muid
|
||||
#define PIC_URL_DEFAULT "http://gatherer.wizards.com/Handlers/Image.ashx?multiverseid=!cardid!&type=card"
|
||||
#define PIC_URL_FALLBACK "http://gatherer.wizards.com/Handlers/Image.ashx?name=!name!&type=card"
|
||||
|
@ -58,6 +60,7 @@ private:
|
|||
QString lang;
|
||||
QString deckPath, replaysPath, picsPath, customPicsPath, cardDatabasePath, customCardDatabasePath, tokenDatabasePath, themeName;
|
||||
bool notifyAboutUpdates;
|
||||
int updateReleaseChannel;
|
||||
bool picDownload;
|
||||
bool notificationsEnabled;
|
||||
bool spectatorNotificationsEnabled;
|
||||
|
@ -110,6 +113,7 @@ private:
|
|||
QString getSafeConfigPath(QString configEntry, QString defaultPath) const;
|
||||
QString getSafeConfigFilePath(QString configEntry, QString defaultPath) const;
|
||||
bool rememberGameSettings;
|
||||
QList<ReleaseChannel*> releaseChannels;
|
||||
|
||||
public:
|
||||
SettingsCache();
|
||||
|
@ -131,6 +135,8 @@ public:
|
|||
bool getNotificationsEnabled() const { return notificationsEnabled; }
|
||||
bool getSpectatorNotificationsEnabled() const { return spectatorNotificationsEnabled; }
|
||||
bool getNotifyAboutUpdates() const { return notifyAboutUpdates; }
|
||||
ReleaseChannel * getUpdateReleaseChannel() const { return releaseChannels.at(updateReleaseChannel); }
|
||||
QList<ReleaseChannel*> getUpdateReleaseChannels() const { return releaseChannels; }
|
||||
|
||||
bool getDoubleClickToPlay() const { return doubleClickToPlay; }
|
||||
bool getPlayToStack() const { return playToStack; }
|
||||
|
@ -249,6 +255,7 @@ public slots:
|
|||
void setSpectatorsCanSeeEverything(const bool _spectatorsCanSeeEverything);
|
||||
void setRememberGameSettings(const bool _rememberGameSettings);
|
||||
void setNotifyAboutUpdate(int _notifyaboutupdate);
|
||||
void setUpdateReleaseChannel(int _updateReleaseChannel);
|
||||
};
|
||||
|
||||
extern SettingsCache *settingsCache;
|
||||
|
|
|
@ -1,124 +0,0 @@
|
|||
#include <algorithm>
|
||||
#include <QMessageBox>
|
||||
|
||||
#include "update_checker.h"
|
||||
#include "version_string.h"
|
||||
#include "qt-json/json.h"
|
||||
|
||||
#define LATEST_FILES_URL "https://api.bintray.com/packages/cockatrice/Cockatrice/Cockatrice/files"
|
||||
|
||||
UpdateChecker::UpdateChecker(QObject *parent) : QObject(parent)
|
||||
{
|
||||
//Parse the commit date. We'll use this to check for new versions
|
||||
//We know the format because it's based on `git log` which is documented here:
|
||||
// https://git-scm.com/docs/git-log#_commit_formatting
|
||||
buildDate = QDate::fromString(VERSION_DATE, "yyyy-MM-dd");
|
||||
latestFilesUrl = QUrl(LATEST_FILES_URL);
|
||||
response = NULL;
|
||||
netMan = new QNetworkAccessManager(this);
|
||||
build = NULL;
|
||||
}
|
||||
|
||||
UpdateChecker::~UpdateChecker()
|
||||
{
|
||||
delete build;
|
||||
}
|
||||
|
||||
void UpdateChecker::check()
|
||||
{
|
||||
response = netMan->get(QNetworkRequest(latestFilesUrl));
|
||||
connect(response, SIGNAL(finished()),
|
||||
this, SLOT(fileListFinished()));
|
||||
}
|
||||
|
||||
#if defined(Q_OS_OSX)
|
||||
bool UpdateChecker::downloadMatchesCurrentOS(QVariant build)
|
||||
{
|
||||
return build
|
||||
.toMap()["name"]
|
||||
.toString()
|
||||
.endsWith(".dmg");
|
||||
}
|
||||
|
||||
#elif defined(Q_OS_WIN)
|
||||
bool UpdateChecker::downloadMatchesCurrentOS(QVariant build)
|
||||
{
|
||||
QString wordSize = QSysInfo::buildAbi().split('-')[2];
|
||||
QString arch;
|
||||
if (wordSize == "llp64") {
|
||||
arch = "win64";
|
||||
} else if (wordSize == "ilp32") {
|
||||
arch = "win32";
|
||||
} else {
|
||||
qWarning() << "Error checking for upgrade version: wordSize is" << wordSize;
|
||||
return false;
|
||||
}
|
||||
|
||||
auto fileName = build
|
||||
.toMap()["name"]
|
||||
.toString();
|
||||
// Checking for .zip is a workaround for the May 6th 2016 release
|
||||
auto zipName = arch + ".zip";
|
||||
auto exeName = arch + ".exe";
|
||||
return fileName.endsWith(exeName) || fileName.endsWith(zipName);
|
||||
}
|
||||
#else
|
||||
|
||||
bool UpdateChecker::downloadMatchesCurrentOS(QVariant)
|
||||
{
|
||||
//If the OS doesn't fit one of the above #defines, then it will never match
|
||||
return false;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
QDate UpdateChecker::dateFromBuild(QVariant build)
|
||||
{
|
||||
QString formatString = "yyyy-MM-dd";
|
||||
QString dateString = build.toMap()["created"].toString();
|
||||
dateString = dateString.remove(formatString.length(), dateString.length());
|
||||
|
||||
return QDate::fromString(dateString, formatString);
|
||||
}
|
||||
|
||||
QDate UpdateChecker::findOldestBuild(QVariantList allBuilds)
|
||||
{
|
||||
//Map the build array into an array of dates
|
||||
std::vector<QDate> dateArray(allBuilds.size());
|
||||
std::transform(allBuilds.begin(), allBuilds.end(), dateArray.begin(), dateFromBuild);
|
||||
|
||||
//Return the first date
|
||||
return *std::min_element(dateArray.begin(), dateArray.end());
|
||||
}
|
||||
|
||||
QVariantMap *UpdateChecker::findCompatibleBuild(QVariantList allBuilds)
|
||||
{
|
||||
|
||||
QVariantList::iterator result = std::find_if(allBuilds.begin(), allBuilds.end(), downloadMatchesCurrentOS);
|
||||
|
||||
//If there is no compatible version, return NULL
|
||||
if (result == allBuilds.end())
|
||||
return NULL;
|
||||
else {
|
||||
QVariantMap *ret = new QVariantMap;
|
||||
*ret = (*result).toMap();
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateChecker::fileListFinished()
|
||||
{
|
||||
try {
|
||||
QVariantList builds = QtJson::Json::parse(response->readAll()).toList();
|
||||
build = findCompatibleBuild(builds);
|
||||
QDate bintrayBuildDate = findOldestBuild(builds);
|
||||
|
||||
bool needToUpdate = bintrayBuildDate > buildDate;
|
||||
bool compatibleVersion = build != NULL;
|
||||
|
||||
emit finishedCheck(needToUpdate, compatibleVersion, build);
|
||||
}
|
||||
catch (const std::exception &exc) {
|
||||
emit error(exc.what());
|
||||
}
|
||||
}
|
|
@ -1,38 +0,0 @@
|
|||
//
|
||||
// Created by miguel on 28/12/15.
|
||||
//
|
||||
|
||||
#ifndef COCKATRICE_UPDATECHECKER_H
|
||||
#define COCKATRICE_UPDATECHECKER_H
|
||||
|
||||
#include <QObject>
|
||||
#include <QUrl>
|
||||
#include <QDate>
|
||||
#include <QtNetwork>
|
||||
|
||||
class UpdateChecker : public QObject {
|
||||
Q_OBJECT
|
||||
public:
|
||||
UpdateChecker(QObject *parent);
|
||||
~UpdateChecker();
|
||||
void check();
|
||||
signals:
|
||||
void finishedCheck(bool needToUpdate, bool isCompatible, QVariantMap *build);
|
||||
void error(QString errorString);
|
||||
private:
|
||||
static QVariantMap *findCompatibleBuild();
|
||||
static QDate findOldestBuild(QVariantList allBuilds);
|
||||
static QDate dateFromBuild(QVariant build);
|
||||
static QVariantMap *findCompatibleBuild(QVariantList allBuilds);
|
||||
static bool downloadMatchesCurrentOS(QVariant build);
|
||||
QVariantMap *build;
|
||||
QUrl latestFilesUrl;
|
||||
QDate buildDate;
|
||||
QNetworkAccessManager *netMan;
|
||||
QNetworkReply *response;
|
||||
private slots:
|
||||
void fileListFinished();
|
||||
};
|
||||
|
||||
|
||||
#endif //COCKATRICE_UPDATECHECKER_H
|
|
@ -13,7 +13,6 @@ void UpdateDownloader::beginDownload(QUrl downloadUrl) {
|
|||
|
||||
response = netMan->get(QNetworkRequest(downloadUrl));
|
||||
connect(response, SIGNAL(finished()), this, SLOT(fileFinished()));
|
||||
connect(response, SIGNAL(readyRead()), this, SLOT(fileReadyRead()));
|
||||
connect(response, SIGNAL(downloadProgress(qint64, qint64)), this, SLOT(downloadProgress(qint64, qint64)));
|
||||
connect(response, SIGNAL(error(QNetworkReply::NetworkError)), this, SLOT(downloadError(QNetworkReply::NetworkError)));
|
||||
}
|
||||
|
|
|
@ -51,7 +51,6 @@
|
|||
#include "settingscache.h"
|
||||
#include "tab_game.h"
|
||||
#include "version_string.h"
|
||||
#include "update_checker.h"
|
||||
#include "carddatabase.h"
|
||||
#include "window_sets.h"
|
||||
#include "dlg_edit_tokens.h"
|
||||
|
|
|
@ -29,7 +29,6 @@
|
|||
|
||||
#include "abstractclient.h"
|
||||
#include "pb/response.pb.h"
|
||||
#include "update_checker.h"
|
||||
|
||||
class TabSupervisor;
|
||||
class RemoteClient;
|
||||
|
|
|
@ -23,7 +23,9 @@ SET(oracle_SOURCES
|
|||
../cockatrice/src/settings/layoutssettings.cpp
|
||||
../cockatrice/src/thememanager.cpp
|
||||
../cockatrice/src/qt-json/json.cpp
|
||||
)
|
||||
../cockatrice/src/releasechannel.cpp
|
||||
${VERSION_STRING_CPP}
|
||||
)
|
||||
|
||||
set(oracle_RESOURCES oracle.qrc)
|
||||
|
||||
|
|
Loading…
Reference in a new issue