Added server/client feature set communication

This commit is contained in:
woogerboy21 2015-08-27 00:10:41 -04:00
parent baa61d0571
commit 044c2356ff
26 changed files with 225 additions and 22 deletions

View file

@ -19,6 +19,7 @@
#include "get_pb_extension.h"
#include <google/protobuf/descriptor.h>
#include "client_metatypes.h"
#include "featureset.h"
AbstractClient::AbstractClient(QObject *parent)
: QObject(parent), nextCmdId(0), status(StatusDisconnected)
@ -45,6 +46,10 @@ AbstractClient::AbstractClient(QObject *parent)
qRegisterMetaType<ServerInfo_User>("ServerInfo_User");
qRegisterMetaType<QList<ServerInfo_User> >("QList<ServerInfo_User>");
qRegisterMetaType<Event_ReplayAdded>("Event_ReplayAdded");
qRegisterMetaType<QList<QString> >("missingFeatures");
FeatureSet features;
features.initalizeFeatureList(clientFeatures);
connect(this, SIGNAL(sigQueuePendingCommand(PendingCommand *)), this, SLOT(queuePendingCommand(PendingCommand *)));
}

View file

@ -25,6 +25,7 @@ class Event_NotifyUser;
class Event_ConnectionClosed;
class Event_ServerShutdown;
class Event_ReplayAdded;
class FeatureSet;
enum ClientStatus {
StatusDisconnected,
@ -96,6 +97,8 @@ public:
static PendingCommand *prepareRoomCommand(const ::google::protobuf::Message &cmd, int roomId);
static PendingCommand *prepareModeratorCommand(const ::google::protobuf::Message &cmd);
static PendingCommand *prepareAdminCommand(const ::google::protobuf::Message &cmd);
QMap<QString, bool> clientFeatures;
};
#endif

View file

@ -24,6 +24,6 @@ Q_DECLARE_METATYPE(Event_UserMessage)
Q_DECLARE_METATYPE(ServerInfo_User)
Q_DECLARE_METATYPE(QList<ServerInfo_User>)
Q_DECLARE_METATYPE(Event_ReplayAdded)
Q_DECLARE_METATYPE(QList<QString>)
#endif

View file

@ -45,6 +45,7 @@ GeneralSettingsPage::GeneralSettingsPage()
picDownloadCheckBox.setChecked(settingsCache->getPicDownload());
picDownloadHqCheckBox.setChecked(settingsCache->getPicDownloadHq());
updateNotificationCheckBox.setChecked(settingsCache->getNotifyAboutUpdates());
pixmapCacheEdit.setMinimum(PIXMAPCACHE_SIZE_MIN);
// 2047 is the max value to avoid overflowing of QPixmapCache::setCacheLimit(int size)
@ -64,19 +65,21 @@ GeneralSettingsPage::GeneralSettingsPage()
connect(&picDownloadHqCheckBox, SIGNAL(stateChanged(int)), settingsCache, SLOT(setPicDownloadHq(int)));
connect(&pixmapCacheEdit, SIGNAL(valueChanged(int)), settingsCache, SLOT(setPixmapCacheSize(int)));
connect(&picDownloadHqCheckBox, SIGNAL(clicked(bool)), this, SLOT(setEnabledStatus(bool)));
connect(&updateNotificationCheckBox, SIGNAL(stateChanged(int)), settingsCache, SLOT(setNotifyAboutUpdate(int)));
connect(highQualityURLEdit, SIGNAL(textChanged(QString)), settingsCache, SLOT(setPicUrlHq(QString)));
QGridLayout *personalGrid = new QGridLayout;
personalGrid->addWidget(&languageLabel, 0, 0);
personalGrid->addWidget(&languageBox, 0, 1);
personalGrid->addWidget(&pixmapCacheLabel, 1, 0, 1, 1);
personalGrid->addWidget(&pixmapCacheEdit, 1, 1, 1, 1);
personalGrid->addWidget(&picDownloadCheckBox, 2, 0, 1, 2);
personalGrid->addWidget(&picDownloadHqCheckBox, 3, 0, 1, 2);
personalGrid->addWidget(&clearDownloadedPicsButton, 4, 0, 1, 1);
personalGrid->addWidget(&highQualityURLLabel, 5, 0, 1, 1);
personalGrid->addWidget(highQualityURLEdit, 5, 1, 1, 1);
personalGrid->addWidget(&highQualityURLLinkLabel, 6, 1, 1, 1);
personalGrid->addWidget(&pixmapCacheLabel, 1, 0);
personalGrid->addWidget(&pixmapCacheEdit, 1, 1);
personalGrid->addWidget(&updateNotificationCheckBox, 2, 0);
personalGrid->addWidget(&picDownloadCheckBox, 3, 0);
personalGrid->addWidget(&picDownloadHqCheckBox, 4, 0);
personalGrid->addWidget(&highQualityURLLabel, 5, 0);
personalGrid->addWidget(highQualityURLEdit, 5, 1);
personalGrid->addWidget(&highQualityURLLinkLabel, 6, 1);
personalGrid->addWidget(&clearDownloadedPicsButton, 6, 0);
highQualityURLLinkLabel.setTextInteractionFlags(Qt::LinksAccessibleByMouse);
highQualityURLLinkLabel.setOpenExternalLinks(true);
@ -246,6 +249,7 @@ void GeneralSettingsPage::retranslateUi()
highQualityURLLabel.setText(tr("Custom Card Download URL:"));
highQualityURLLinkLabel.setText(QString("<a href='%1'>%2</a>").arg(LINKING_FAQ_URL).arg(tr("Linking FAQ")));
clearDownloadedPicsButton.setText(tr("Reset/Clear Downloaded Pictures"));
updateNotificationCheckBox.setText(tr("Notify when new client features are available"));
}
void GeneralSettingsPage::setEnabledStatus(bool status)
@ -914,3 +918,4 @@ void DlgSettings::retranslateUi()
for (int i = 0; i < pagesWidget->count(); i++)
dynamic_cast<AbstractSettingsPage *>(pagesWidget->widget(i))->retranslateUi();
}

View file

@ -60,6 +60,7 @@ private:
QComboBox languageBox;
QCheckBox picDownloadCheckBox;
QCheckBox picDownloadHqCheckBox;
QCheckBox updateNotificationCheckBox;
QLabel languageLabel;
QLabel pixmapCacheLabel;
QLabel deckPathLabel;

View file

@ -33,7 +33,6 @@
#include <QSystemTrayIcon>
#include "QtNetwork/QNetworkInterface"
#include <QCryptographicHash>
#include "main.h"
#include "window_main.h"
#include "dlg_settings.h"
@ -43,6 +42,7 @@
#include "pixmapgenerator.h"
#include "rng_sfmt.h"
#include "soundengine.h"
#include "featureset.h"
//Q_IMPORT_PLUGIN(qjpeg)

View file

@ -1,3 +1,4 @@
#include <QList>
#include <QTimer>
#include <QThread>
#include "remoteclient.h"
@ -81,7 +82,6 @@ void RemoteClient::processServerIdentificationEvent(const Event_ServerIdentifica
cmdRegister.set_country(country.toStdString());
cmdRegister.set_real_name(realName.toStdString());
cmdRegister.set_clientid(settingsCache->getClientID().toStdString());
PendingCommand *pend = prepareSessionCommand(cmdRegister);
connect(pend, SIGNAL(finished(Response, CommandContainer, QVariant)), this, SLOT(registerResponse(Response)));
sendCommand(pend);
@ -105,8 +105,7 @@ void RemoteClient::processServerIdentificationEvent(const Event_ServerIdentifica
doLogin();
}
void RemoteClient::doLogin()
{
void RemoteClient::doLogin() {
setStatus(StatusLoggingIn);
Command_Login cmdLogin;
@ -114,6 +113,13 @@ void RemoteClient::doLogin()
cmdLogin.set_password(password.toStdString());
cmdLogin.set_clientid(settingsCache->getClientID().toStdString());
cmdLogin.set_clientver(VERSION_STRING);
if (!clientFeatures.isEmpty()) {
QMap<QString, bool>::iterator i;
for (i = clientFeatures.begin(); i != clientFeatures.end(); ++i)
cmdLogin.add_clientfeatures(i.key().toStdString().c_str());
}
PendingCommand *pend = prepareSessionCommand(cmdLogin);
connect(pend, SIGNAL(finished(Response, CommandContainer, QVariant)), this, SLOT(loginResponse(Response)));
sendCommand(pend);
@ -140,8 +146,17 @@ void RemoteClient::loginResponse(const Response &response)
for (int i = resp.ignore_list_size() - 1; i >= 0; --i)
ignoreList.append(resp.ignore_list(i));
emit ignoreListReceived(ignoreList);
if (resp.missing_features_size() > 0 && settingsCache->getNotifyAboutUpdates())
emit notifyUserAboutUpdate();
} else {
emit loginError(response.response_code(), QString::fromStdString(resp.denied_reason_str()), resp.denied_end_time());
QList<QString> missingFeatures;
if (resp.missing_features_size() > 0) {
for (int i = 0; i < resp.missing_features_size(); ++i)
missingFeatures << QString::fromStdString(resp.missing_features(i));
}
emit loginError(response.response_code(), QString::fromStdString(resp.denied_reason_str()), resp.denied_end_time(), missingFeatures);
setStatus(StatusDisconnecting);
}
}

View file

@ -11,7 +11,7 @@ class RemoteClient : public AbstractClient {
signals:
void maxPingTime(int seconds, int maxSeconds);
void serverTimeout();
void loginError(Response::ResponseCode resp, QString reasonStr, quint32 endTime);
void loginError(Response::ResponseCode resp, QString reasonStr, quint32 endTime, QList<QString> missingFeatures);
void registerError(Response::ResponseCode resp, QString reasonStr, quint32 endTime);
void activateError();
void socketError(const QString &errorString);
@ -21,6 +21,7 @@ signals:
void sigRegisterToServer(const QString &hostname, unsigned int port, const QString &_userName, const QString &_password, const QString &_email, const int _gender, const QString &_country, const QString &_realname);
void sigActivateToServer(const QString &_token);
void sigDisconnectFromServer();
void notifyUserAboutUpdate();
private slots:
void slotConnected();
void readData();

View file

@ -130,6 +130,7 @@ SettingsCache::SettingsCache()
if(!QFile(settingsPath+"global.ini").exists())
translateLegacySettings();
notifyAboutUpdates = settings->value("personal/updatenotification", true).toBool();
lang = settings->value("personal/lang").toString();
keepalive = settings->value("personal/keepalive", 5).toInt();
deckPath = settings->value("paths/decks").toString();
@ -620,4 +621,10 @@ void SettingsCache::setRememberGameSettings(const bool _rememberGameSettings)
{
rememberGameSettings = _rememberGameSettings;
settings->setValue("game/remembergamesettings", rememberGameSettings);
}
void SettingsCache::setNotifyAboutUpdate(int _notifyaboutupdate)
{
notifyAboutUpdates = _notifyaboutupdate;
settings->setValue("personal/updatenotification", notifyAboutUpdates);
}

View file

@ -58,6 +58,7 @@ private:
QByteArray mainWindowGeometry;
QString lang;
QString deckPath, replaysPath, picsPath, cardDatabasePath, tokenDatabasePath, themeName;
bool notifyAboutUpdates;
bool picDownload;
bool picDownloadHq;
bool notificationsEnabled;
@ -129,6 +130,7 @@ public:
bool getPicDownloadHq() const { return picDownloadHq; }
bool getNotificationsEnabled() const { return notificationsEnabled; }
bool getSpectatorNotificationsEnabled() const { return spectatorNotificationsEnabled; }
bool getNotifyAboutUpdates() const { return notifyAboutUpdates; }
bool getDoubleClickToPlay() const { return doubleClickToPlay; }
bool getPlayToStack() const { return playToStack; }
@ -251,6 +253,7 @@ public slots:
void setSpectatorsCanTalk(const bool _spectatorsCanTalk);
void setSpectatorsCanSeeEverything(const bool _spectatorsCanSeeEverything);
void setRememberGameSettings(const bool _rememberGameSettings);
void setNotifyAboutUpdate(int _notifyaboutupdate);
};
extern SettingsCache *settingsCache;

View file

@ -30,6 +30,7 @@
#include <QDateTime>
#include <QSystemTrayIcon>
#include <QApplication>
#if QT_VERSION < 0x050000
#include <QtGui/qtextdocument.h> // for Qt::escape()
#endif
@ -293,9 +294,23 @@ void MainWindow::serverTimeout()
actConnect();
}
void MainWindow::loginError(Response::ResponseCode r, QString reasonStr, quint32 endTime)
void MainWindow::loginError(Response::ResponseCode r, QString reasonStr, quint32 endTime, QList<QString> missingFeatures)
{
switch (r) {
case Response::RespClientUpdateRequired: {
QString formatedMissingFeatures;
formatedMissingFeatures = "Missing Features: ";
for (int i = 0; i < missingFeatures.size(); ++i)
formatedMissingFeatures.append(QString("\n %1").arg(QChar(0x2022)) + " " + missingFeatures.value(i) );
QMessageBox msgBox;
msgBox.setIcon(QMessageBox::Critical);
msgBox.setWindowTitle(tr("Failed Login"));
msgBox.setText(tr("Your client does not support features that the server requires, please update your client and try again."));
msgBox.setDetailedText(formatedMissingFeatures);
msgBox.exec();
break;
}
case Response::RespWrongPassword:
QMessageBox::critical(this, tr("Error"), tr("Incorrect username or password. Please check your authentication information and try again."));
break;
@ -561,13 +576,13 @@ MainWindow::MainWindow(QWidget *parent)
client = new RemoteClient;
connect(client, SIGNAL(connectionClosedEventReceived(const Event_ConnectionClosed &)), this, SLOT(processConnectionClosedEvent(const Event_ConnectionClosed &)));
connect(client, SIGNAL(serverShutdownEventReceived(const Event_ServerShutdown &)), this, SLOT(processServerShutdownEvent(const Event_ServerShutdown &)));
connect(client, SIGNAL(loginError(Response::ResponseCode, QString, quint32)), this, SLOT(loginError(Response::ResponseCode, QString, quint32)));
connect(client, SIGNAL(loginError(Response::ResponseCode, QString, quint32, QList<QString>)), this, SLOT(loginError(Response::ResponseCode, QString, quint32, QList<QString>)));
connect(client, SIGNAL(socketError(const QString &)), this, SLOT(socketError(const QString &)));
connect(client, SIGNAL(serverTimeout()), this, SLOT(serverTimeout()));
connect(client, SIGNAL(statusChanged(ClientStatus)), this, SLOT(statusChanged(ClientStatus)));
connect(client, SIGNAL(protocolVersionMismatch(int, int)), this, SLOT(protocolVersionMismatch(int, int)));
connect(client, SIGNAL(userInfoChanged(const ServerInfo_User &)), this, SLOT(userInfoReceived(const ServerInfo_User &)), Qt::BlockingQueuedConnection);
connect(client, SIGNAL(notifyUserAboutUpdate()), this, SLOT(notifyUserAboutUpdate()));
connect(client, SIGNAL(registerAccepted()), this, SLOT(registerAccepted()));
connect(client, SIGNAL(registerAcceptedNeedsActivate()), this, SLOT(registerAcceptedNeedsActivate()));
connect(client, SIGNAL(registerError(Response::ResponseCode, QString, quint32)), this, SLOT(registerError(Response::ResponseCode, QString, quint32)));
@ -795,3 +810,8 @@ void MainWindow::refreshShortcuts()
aExit->setShortcuts(settingsCache->shortcuts().getShortcut("MainWindow/aExit"));
aCheckCardUpdates->setShortcuts(settingsCache->shortcuts().getShortcut("MainWindow/aCheckCardUpdates"));
}
void MainWindow::notifyUserAboutUpdate()
{
QMessageBox::information(this, tr("Information"), tr("Your client appears to be missing features that the server supports.\nThis usually means that your client version is out of date,pleae check to see if there is a new client available for download."));
}

View file

@ -20,6 +20,7 @@
#ifndef WINDOW_H
#define WINDOW_H
#include <QList>
#include <QMainWindow>
#include <QSystemTrayIcon>
#include <QProcess>
@ -42,7 +43,7 @@ private slots:
void processConnectionClosedEvent(const Event_ConnectionClosed &event);
void processServerShutdownEvent(const Event_ServerShutdown &event);
void serverTimeout();
void loginError(Response::ResponseCode r, QString reasonStr, quint32 endTime);
void loginError(Response::ResponseCode r, QString reasonStr, quint32 endTime, QList<QString> missingFeatures);
void registerError(Response::ResponseCode r, QString reasonStr, quint32 endTime);
void activateError();
void socketError(const QString &errorStr);
@ -53,7 +54,7 @@ private slots:
void activateAccepted();
void localGameEnded();
void pixmapCacheSizeChanged(int newSizeInMBs);
void notifyUserAboutUpdate();
void actConnect();
void actDisconnect();
void actSinglePlayer();