[App] Send diagnostics on server connection

Took 32 seconds

Took 22 seconds
This commit is contained in:
Lukas Brübach 2026-01-02 18:25:47 +01:00
parent bbd8671e6e
commit b9198d99e9
13 changed files with 258 additions and 9 deletions

View file

@ -42,6 +42,7 @@ set(cockatrice_SOURCES
src/interface/widgets/dialogs/dlg_manage_sets.cpp src/interface/widgets/dialogs/dlg_manage_sets.cpp
src/interface/widgets/dialogs/dlg_register.cpp src/interface/widgets/dialogs/dlg_register.cpp
src/interface/widgets/dialogs/dlg_select_set_for_cards.cpp src/interface/widgets/dialogs/dlg_select_set_for_cards.cpp
src/interface/widgets/dialogs/dlg_prompt_send_diagnostics.cpp
src/interface/widgets/dialogs/dlg_settings.cpp src/interface/widgets/dialogs/dlg_settings.cpp
src/interface/widgets/dialogs/dlg_startup_card_check.cpp src/interface/widgets/dialogs/dlg_startup_card_check.cpp
src/interface/widgets/dialogs/dlg_tip_of_the_day.cpp src/interface/widgets/dialogs/dlg_tip_of_the_day.cpp

View file

@ -212,6 +212,7 @@ SettingsCache::SettingsCache()
cardUpdateCheckInterval = settings->value("personal/cardUpdateCheckInterval", 7).toInt(); cardUpdateCheckInterval = settings->value("personal/cardUpdateCheckInterval", 7).toInt();
lastCardUpdateCheck = settings->value("personal/lastCardUpdateCheck", QDateTime::currentDateTime().date()).toDate(); lastCardUpdateCheck = settings->value("personal/lastCardUpdateCheck", QDateTime::currentDateTime().date()).toDate();
notifyAboutUpdates = settings->value("personal/updatenotification", true).toBool(); notifyAboutUpdates = settings->value("personal/updatenotification", true).toBool();
sendDiagnostics = settings->value("personal/senddiagnostics", 0).toInt();
notifyAboutNewVersion = settings->value("personal/newversionnotification", true).toBool(); notifyAboutNewVersion = settings->value("personal/newversionnotification", true).toBool();
if (settings->contains("personal/updatereleasechannel")) { if (settings->contains("personal/updatereleasechannel")) {
@ -1496,6 +1497,12 @@ void SettingsCache::setNotifyAboutUpdate(QT_STATE_CHANGED_T _notifyaboutupdate)
settings->setValue("personal/updatenotification", notifyAboutUpdates); settings->setValue("personal/updatenotification", notifyAboutUpdates);
} }
void SettingsCache::setSendDiagnostics(int _sendDiagnostics)
{
sendDiagnostics = _sendDiagnostics;
settings->setValue("personal/senddiagnostics", sendDiagnostics);
}
void SettingsCache::setNotifyAboutNewVersion(QT_STATE_CHANGED_T _notifyaboutnewversion) void SettingsCache::setNotifyAboutNewVersion(QT_STATE_CHANGED_T _notifyaboutnewversion)
{ {
notifyAboutNewVersion = static_cast<bool>(_notifyaboutnewversion); notifyAboutNewVersion = static_cast<bool>(_notifyaboutnewversion);

View file

@ -218,6 +218,7 @@ private:
int cardUpdateCheckInterval; int cardUpdateCheckInterval;
QDate lastCardUpdateCheck; QDate lastCardUpdateCheck;
bool notifyAboutUpdates; bool notifyAboutUpdates;
int sendDiagnostics;
bool notifyAboutNewVersion; bool notifyAboutNewVersion;
bool showTipsOnStartup; bool showTipsOnStartup;
QList<int> seenTips; QList<int> seenTips;
@ -498,6 +499,10 @@ public:
{ {
return notifyAboutUpdates; return notifyAboutUpdates;
} }
[[nodiscard]] int getSendDiagnostics() const override
{
return sendDiagnostics;
}
[[nodiscard]] bool getNotifyAboutNewVersion() const [[nodiscard]] bool getNotifyAboutNewVersion() const
{ {
return notifyAboutNewVersion; return notifyAboutNewVersion;
@ -1105,6 +1110,7 @@ public slots:
void setCardUpdateCheckInterval(int value); void setCardUpdateCheckInterval(int value);
void setLastCardUpdateCheck(QDate value); void setLastCardUpdateCheck(QDate value);
void setNotifyAboutUpdate(QT_STATE_CHANGED_T _notifyaboutupdate); void setNotifyAboutUpdate(QT_STATE_CHANGED_T _notifyaboutupdate);
void setSendDiagnostics(int _sendDiagnostics);
void setNotifyAboutNewVersion(QT_STATE_CHANGED_T _notifyaboutnewversion); void setNotifyAboutNewVersion(QT_STATE_CHANGED_T _notifyaboutnewversion);
void setUpdateReleaseChannelIndex(int value); void setUpdateReleaseChannelIndex(int value);
void setMaxFontSize(int _max); void setMaxFontSize(int _max);

View file

@ -0,0 +1,55 @@
#include "dlg_prompt_send_diagnostics.h"
#include <QHBoxLayout>
#include <QPushButton>
#include <QVBoxLayout>
DlgPromptSendDiagnostics::DlgPromptSendDiagnostics(QWidget *parent) : QDialog(parent), choice(SendDiagnosticsDisabled)
{
auto *layout = new QVBoxLayout(this);
messageLabel = new QLabel(this);
messageLabel->setWordWrap(true);
layout->addWidget(messageLabel);
auto *buttonLayout = new QHBoxLayout;
noButton = new QPushButton(this);
minimalButton = new QPushButton(this);
fullButton = new QPushButton(this);
buttonLayout->addWidget(noButton);
buttonLayout->addWidget(minimalButton);
buttonLayout->addWidget(fullButton);
layout->addLayout(buttonLayout);
// Connect buttons
connect(noButton, &QPushButton::clicked, this, [this]() {
choice = SendDiagnosticsDisabled;
accept();
});
connect(minimalButton, &QPushButton::clicked, this, [this]() {
choice = SendDiagnosticsBasic;
accept();
});
connect(fullButton, &QPushButton::clicked, this, [this]() {
choice = SendDiagnosticsFull;
accept();
});
retranslateUi();
}
void DlgPromptSendDiagnostics::retranslateUi()
{
setWindowTitle(tr("Help us improve Cockatrice"));
messageLabel->setText(tr("Hi there! Cockatrice is made by a small team, and we want to make it better for you.\n\n"
"Wed love to collect a tiny bit of anonymous technical data about how you use the app — "
"nothing personal, just usage info so we know what works and what needs improvement."));
noButton->setText(tr("No, thank you"));
minimalButton->setText(tr("Minimal"));
fullButton->setText(tr("Full"));
}

View file

@ -0,0 +1,34 @@
#ifndef COCKATRICE_DLG_PROMPT_SEND_DIAGNOSTICS_H
#define COCKATRICE_DLG_PROMPT_SEND_DIAGNOSTICS_H
#include "dlg_settings.h"
#include <QDialog>
#include <QLabel>
#include <libcockatrice/interfaces/interface_network_settings_provider.h>
class QPushButton;
class DlgPromptSendDiagnostics : public QDialog
{
Q_OBJECT
public:
explicit DlgPromptSendDiagnostics(QWidget *parent = nullptr);
SendDiagnosticsMode selectedChoice() const
{
return choice;
}
void retranslateUi();
private:
SendDiagnosticsMode choice;
QLabel *messageLabel;
QPushButton *noButton;
QPushButton *minimalButton;
QPushButton *fullButton;
};
#endif // COCKATRICE_DLG_PROMPT_SEND_DIAGNOSTICS_H

View file

@ -13,6 +13,7 @@
#include "../interface/widgets/utility/get_text_with_max.h" #include "../interface/widgets/utility/get_text_with_max.h"
#include "../interface/widgets/utility/sequence_edit.h" #include "../interface/widgets/utility/sequence_edit.h"
#include "../main.h" #include "../main.h"
#include "dlg_prompt_send_diagnostics.h"
#include <../../client/settings/card_counter_settings.h> #include <../../client/settings/card_counter_settings.h>
#include <QAbstractButton> #include <QAbstractButton>
@ -101,6 +102,27 @@ GeneralSettingsPage::GeneralSettingsPage()
advertiseTranslationPageLabel.setTextInteractionFlags(Qt::LinksAccessibleByMouse); advertiseTranslationPageLabel.setTextInteractionFlags(Qt::LinksAccessibleByMouse);
advertiseTranslationPageLabel.setOpenExternalLinks(true); advertiseTranslationPageLabel.setOpenExternalLinks(true);
// Add items with the enum as userData
populateSendDiagnosticsCombo(SettingsCache::instance().getSendDiagnostics());
connect(&sendDiagnosticsSelector, QOverload<int>::of(&QComboBox::currentIndexChanged), this, [this](int index) {
int mode = sendDiagnosticsSelector.itemData(index).toInt();
if (mode == SendDiagnosticsUnprompted) {
DlgPromptSendDiagnostics dlg(this);
if (dlg.exec() == QDialog::Accepted) {
mode = dlg.selectedChoice();
} else {
mode = SendDiagnosticsDisabled;
}
}
SettingsCache::instance().setSendDiagnostics(mode);
// Rebuild combo if we transitioned out of Unprompted
populateSendDiagnosticsCombo(mode);
});
connect(&languageBox, qOverload<int>(&QComboBox::currentIndexChanged), this, connect(&languageBox, qOverload<int>(&QComboBox::currentIndexChanged), this,
&GeneralSettingsPage::languageBoxChanged); &GeneralSettingsPage::languageBoxChanged);
connect(&startupUpdateCheckCheckBox, &QCheckBox::QT_STATE_CHANGED, &settings, connect(&startupUpdateCheckCheckBox, &QCheckBox::QT_STATE_CHANGED, &settings,
@ -125,15 +147,17 @@ GeneralSettingsPage::GeneralSettingsPage()
personalGrid->addWidget(&advertiseTranslationPageLabel, 1, 1, Qt::AlignRight); personalGrid->addWidget(&advertiseTranslationPageLabel, 1, 1, Qt::AlignRight);
personalGrid->addWidget(&updateReleaseChannelLabel, 2, 0); personalGrid->addWidget(&updateReleaseChannelLabel, 2, 0);
personalGrid->addWidget(&updateReleaseChannelBox, 2, 1); personalGrid->addWidget(&updateReleaseChannelBox, 2, 1);
personalGrid->addWidget(&startupUpdateCheckCheckBox, 4, 0, 1, 2); personalGrid->addWidget(&sendDiagnosticsLabel, 3, 0);
personalGrid->addWidget(&startupCardUpdateCheckBehaviorLabel, 5, 0); personalGrid->addWidget(&sendDiagnosticsSelector, 3, 1);
personalGrid->addWidget(&startupCardUpdateCheckBehaviorSelector, 5, 1); personalGrid->addWidget(&startupUpdateCheckCheckBox, 5, 0, 1, 2);
personalGrid->addWidget(&cardUpdateCheckIntervalLabel, 6, 0); personalGrid->addWidget(&startupCardUpdateCheckBehaviorLabel, 6, 0);
personalGrid->addWidget(&cardUpdateCheckIntervalSpinBox, 6, 1); personalGrid->addWidget(&startupCardUpdateCheckBehaviorSelector, 6, 1);
personalGrid->addWidget(&lastCardUpdateCheckDateLabel, 7, 1); personalGrid->addWidget(&cardUpdateCheckIntervalLabel, 7, 0);
personalGrid->addWidget(&updateNotificationCheckBox, 8, 0, 1, 2); personalGrid->addWidget(&cardUpdateCheckIntervalSpinBox, 7, 1);
personalGrid->addWidget(&newVersionOracleCheckBox, 9, 0, 1, 2); personalGrid->addWidget(&lastCardUpdateCheckDateLabel, 8, 1);
personalGrid->addWidget(&showTipsOnStartup, 10, 0, 1, 2); personalGrid->addWidget(&updateNotificationCheckBox, 9, 0, 1, 2);
personalGrid->addWidget(&newVersionOracleCheckBox, 10, 0, 1, 2);
personalGrid->addWidget(&showTipsOnStartup, 11, 0, 1, 2);
personalGroupBox = new QGroupBox; personalGroupBox = new QGroupBox;
personalGroupBox->setLayout(personalGrid); personalGroupBox->setLayout(personalGrid);
@ -268,6 +292,32 @@ QString GeneralSettingsPage::languageName(const QString &lang)
return qTranslator.translate("i18n", DEFAULT_LANG_NAME); return qTranslator.translate("i18n", DEFAULT_LANG_NAME);
} }
void GeneralSettingsPage::populateSendDiagnosticsCombo(int mode)
{
QSignalBlocker blocker(sendDiagnosticsSelector);
sendDiagnosticsSelector.clear();
if (mode == SendDiagnosticsUnprompted) {
sendDiagnosticsSelector.addItem(QString(), SendDiagnosticsUnprompted);
}
sendDiagnosticsSelector.addItem(tr("Disabled"), SendDiagnosticsDisabled);
sendDiagnosticsSelector.addItem(tr("Minimal"), SendDiagnosticsBasic);
sendDiagnosticsSelector.addItem(tr("Full"), SendDiagnosticsFull);
// Restore selection
for (int i = 0; i < sendDiagnosticsSelector.count(); ++i) {
if (sendDiagnosticsSelector.itemData(i).toInt() == mode) {
sendDiagnosticsSelector.setCurrentIndex(i);
return;
}
}
// Fallback: if unprompted was removed, default to Disabled
sendDiagnosticsSelector.setCurrentIndex(0);
}
void GeneralSettingsPage::deckPathButtonClicked() void GeneralSettingsPage::deckPathButtonClicked()
{ {
QString path = QFileDialog::getExistingDirectory(this, tr("Choose path"), deckPathEdit->text()); QString path = QFileDialog::getExistingDirectory(this, tr("Choose path"), deckPathEdit->text());
@ -376,6 +426,7 @@ void GeneralSettingsPage::retranslateUi()
customCardDatabasePathLabel.setText(tr("Custom database directory:")); customCardDatabasePathLabel.setText(tr("Custom database directory:"));
tokenDatabasePathLabel.setText(tr("Token database:")); tokenDatabasePathLabel.setText(tr("Token database:"));
updateReleaseChannelLabel.setText(tr("Update channel")); updateReleaseChannelLabel.setText(tr("Update channel"));
sendDiagnosticsLabel.setText(tr("Send usage statistics:"));
startupUpdateCheckCheckBox.setText(tr("Check for client updates on startup")); startupUpdateCheckCheckBox.setText(tr("Check for client updates on startup"));
startupCardUpdateCheckBehaviorLabel.setText(tr("Check for card database updates on startup")); startupCardUpdateCheckBehaviorLabel.setText(tr("Check for card database updates on startup"));
startupCardUpdateCheckBehaviorSelector.setItemText(startupCardUpdateCheckBehaviorIndexNone, tr("Don't check")); startupCardUpdateCheckBehaviorSelector.setItemText(startupCardUpdateCheckBehaviorIndexNone, tr("Don't check"));

View file

@ -63,6 +63,7 @@ private slots:
private: private:
QStringList findQmFiles(); QStringList findQmFiles();
QString languageName(const QString &lang); QString languageName(const QString &lang);
void populateSendDiagnosticsCombo(int mode);
QLineEdit *deckPathEdit; QLineEdit *deckPathEdit;
QLineEdit *filtersPathEdit; QLineEdit *filtersPathEdit;
QLineEdit *replaysPathEdit; QLineEdit *replaysPathEdit;
@ -84,6 +85,7 @@ private:
QCheckBox updateNotificationCheckBox; QCheckBox updateNotificationCheckBox;
QCheckBox newVersionOracleCheckBox; QCheckBox newVersionOracleCheckBox;
QComboBox updateReleaseChannelBox; QComboBox updateReleaseChannelBox;
QComboBox sendDiagnosticsSelector;
QLabel languageLabel; QLabel languageLabel;
QLabel deckPathLabel; QLabel deckPathLabel;
QLabel filtersPathLabel; QLabel filtersPathLabel;
@ -93,6 +95,7 @@ private:
QLabel customCardDatabasePathLabel; QLabel customCardDatabasePathLabel;
QLabel tokenDatabasePathLabel; QLabel tokenDatabasePathLabel;
QLabel updateReleaseChannelLabel; QLabel updateReleaseChannelLabel;
QLabel sendDiagnosticsLabel;
QLabel advertiseTranslationPageLabel; QLabel advertiseTranslationPageLabel;
QCheckBox showTipsOnStartup; QCheckBox showTipsOnStartup;
}; };

View file

@ -28,6 +28,7 @@
#include "../interface/widgets/dialogs/dlg_forgot_password_request.h" #include "../interface/widgets/dialogs/dlg_forgot_password_request.h"
#include "../interface/widgets/dialogs/dlg_forgot_password_reset.h" #include "../interface/widgets/dialogs/dlg_forgot_password_reset.h"
#include "../interface/widgets/dialogs/dlg_manage_sets.h" #include "../interface/widgets/dialogs/dlg_manage_sets.h"
#include "../interface/widgets/dialogs/dlg_prompt_send_diagnostics.h"
#include "../interface/widgets/dialogs/dlg_register.h" #include "../interface/widgets/dialogs/dlg_register.h"
#include "../interface/widgets/dialogs/dlg_settings.h" #include "../interface/widgets/dialogs/dlg_settings.h"
#include "../interface/widgets/dialogs/dlg_startup_card_check.h" #include "../interface/widgets/dialogs/dlg_startup_card_check.h"
@ -851,6 +852,7 @@ MainWindow::MainWindow(QWidget *parent)
connect(client, &RemoteClient::protocolVersionMismatch, this, &MainWindow::protocolVersionMismatch); connect(client, &RemoteClient::protocolVersionMismatch, this, &MainWindow::protocolVersionMismatch);
connect(client, &RemoteClient::userInfoChanged, this, &MainWindow::userInfoReceived, Qt::BlockingQueuedConnection); connect(client, &RemoteClient::userInfoChanged, this, &MainWindow::userInfoReceived, Qt::BlockingQueuedConnection);
connect(client, &RemoteClient::notifyUserAboutUpdate, this, &MainWindow::notifyUserAboutUpdate); connect(client, &RemoteClient::notifyUserAboutUpdate, this, &MainWindow::notifyUserAboutUpdate);
connect(client, &RemoteClient::notifyUserAboutDiagnostics, this, &MainWindow::notifyUserAboutDiagnostics);
connect(client, &RemoteClient::registerAccepted, this, &MainWindow::registerAccepted); connect(client, &RemoteClient::registerAccepted, this, &MainWindow::registerAccepted);
connect(client, &RemoteClient::registerAcceptedNeedsActivate, this, &MainWindow::registerAcceptedNeedsActivate); connect(client, &RemoteClient::registerAcceptedNeedsActivate, this, &MainWindow::registerAcceptedNeedsActivate);
connect(client, &RemoteClient::registerError, this, &MainWindow::registerError); connect(client, &RemoteClient::registerError, this, &MainWindow::registerError);
@ -1385,6 +1387,21 @@ void MainWindow::notifyUserAboutUpdate()
"running a custom or pre-release version.\n\nTo update your client, go to Help -> Check for Updates.")); "running a custom or pre-release version.\n\nTo update your client, go to Help -> Check for Updates."));
} }
void MainWindow::notifyUserAboutDiagnostics()
{
int mode = SendDiagnosticsDisabled;
DlgPromptSendDiagnostics dlg(this);
if (dlg.exec() == QDialog::Accepted) {
mode = dlg.selectedChoice();
}
SettingsCache::instance().setSendDiagnostics(mode);
if (mode == SendDiagnosticsBasic || mode == SendDiagnosticsFull) {
client->sendDiagnostics();
}
}
void MainWindow::actOpenCustomFolder() void MainWindow::actOpenCustomFolder()
{ {
QString dir = SettingsCache::instance().getCustomPicsPath(); QString dir = SettingsCache::instance().getCustomPicsPath();

View file

@ -81,6 +81,7 @@ private slots:
void localGameEnded(); void localGameEnded();
void pixmapCacheSizeChanged(int newSizeInMBs); void pixmapCacheSizeChanged(int newSizeInMBs);
void notifyUserAboutUpdate(); void notifyUserAboutUpdate();
void notifyUserAboutDiagnostics();
void actDisconnect(); void actDisconnect();
void actSinglePlayer(); void actSinglePlayer();
void actWatchReplay(); void actWatchReplay();

View file

@ -2,6 +2,13 @@
#define COCKATRICE_INETWORKSETTINGSPROVIDER_H #define COCKATRICE_INETWORKSETTINGSPROVIDER_H
#include <QString> #include <QString>
enum SendDiagnosticsMode {
SendDiagnosticsUnprompted = 0, // never asked
SendDiagnosticsDisabled = 1,
SendDiagnosticsBasic = 2,
SendDiagnosticsFull = 3,
};
class INetworkSettingsProvider class INetworkSettingsProvider
{ {
public: public:
@ -12,6 +19,7 @@ public:
[[nodiscard]] virtual int getTimeOut() const = 0; [[nodiscard]] virtual int getTimeOut() const = 0;
[[nodiscard]] virtual int getKeepAlive() const = 0; [[nodiscard]] virtual int getKeepAlive() const = 0;
[[nodiscard]] virtual bool getNotifyAboutUpdates() const = 0; [[nodiscard]] virtual bool getNotifyAboutUpdates() const = 0;
[[nodiscard]] virtual int getSendDiagnostics() const = 0;
virtual void setKnownMissingFeatures(const QString &_knownMissingFeatures) = 0; virtual void setKnownMissingFeatures(const QString &_knownMissingFeatures) = 0;
virtual QString getKnownMissingFeatures() = 0; virtual QString getKnownMissingFeatures() = 0;

View file

@ -278,6 +278,34 @@ void RemoteClient::passwordSaltResponse(const Response &response)
} }
} }
Command_ClientDiagnostics RemoteClient::generateClientDiagnostics()
{
Command_ClientDiagnostics diag;
diag.set_clientver(VERSION_STRING);
#if defined(Q_OS_WIN)
diag.set_os("windows");
#elif defined(Q_OS_MAC)
diag.set_os("macos");
#elif defined(Q_OS_LINUX)
diag.set_os("linux");
#else
diag.set_os("unknown");
#endif
diag.set_arch(QSysInfo::currentCpuArchitecture().toStdString());
return diag;
}
void RemoteClient::addDiagnosticsFeature(Command_ClientDiagnostics *diag, const QString &name, const QString &value)
{
FeatureFlag *flag = diag->add_feature_flags();
flag->set_name(name.toStdString());
flag->set_value(value.toStdString());
}
void RemoteClient::loginResponse(const Response &response) void RemoteClient::loginResponse(const Response &response)
{ {
const Response_Login &resp = response.GetExtension(Response_Login::ext); const Response_Login &resp = response.GetExtension(Response_Login::ext);
@ -302,6 +330,15 @@ void RemoteClient::loginResponse(const Response &response)
ignoreList.append(resp.ignore_list(i)); ignoreList.append(resp.ignore_list(i));
emit ignoreListReceived(ignoreList); emit ignoreListReceived(ignoreList);
// send diagnostics if enabled
SendDiagnosticsMode mode = SendDiagnosticsMode(networkSettingsProvider->getSendDiagnostics());
if (mode == SendDiagnosticsUnprompted) {
emit notifyUserAboutDiagnostics();
} else if (mode == SendDiagnosticsBasic || mode == SendDiagnosticsFull) {
sendDiagnostics();
}
if (newMissingFeatureFound(possibleMissingFeatures) && resp.missing_features_size() > 0 && if (newMissingFeatureFound(possibleMissingFeatures) && resp.missing_features_size() > 0 &&
networkSettingsProvider->getNotifyAboutUpdates()) { networkSettingsProvider->getNotifyAboutUpdates()) {
networkSettingsProvider->setKnownMissingFeatures(possibleMissingFeatures); networkSettingsProvider->setKnownMissingFeatures(possibleMissingFeatures);
@ -320,6 +357,13 @@ void RemoteClient::loginResponse(const Response &response)
} }
} }
void RemoteClient::sendDiagnostics()
{
Command_ClientDiagnostics diag = generateClientDiagnostics();
PendingCommand *pend = prepareSessionCommand(diag);
sendCommand(pend);
}
void RemoteClient::registerResponse(const Response &response) void RemoteClient::registerResponse(const Response &response)
{ {
const Response_Register &resp = response.GetExtension(Response_Register::ext); const Response_Register &resp = response.GetExtension(Response_Register::ext);

View file

@ -39,6 +39,7 @@ signals:
const QString &_realname); const QString &_realname);
void sigActivateToServer(const QString &_token); void sigActivateToServer(const QString &_token);
void sigDisconnectFromServer(); void sigDisconnectFromServer();
void notifyUserAboutDiagnostics();
void notifyUserAboutUpdate(); void notifyUserAboutUpdate();
void sigRequestForgotPasswordToServer(const QString &hostname, unsigned int port, const QString &_userName); void sigRequestForgotPasswordToServer(const QString &hostname, unsigned int port, const QString &_userName);
void sigForgotPasswordSuccess(); void sigForgotPasswordSuccess();
@ -80,6 +81,8 @@ private slots:
void doLogin(); void doLogin();
void doHashedLogin(); void doHashedLogin();
Command_Login generateCommandLogin(); Command_Login generateCommandLogin();
Command_ClientDiagnostics generateClientDiagnostics();
void addDiagnosticsFeature(Command_ClientDiagnostics *diag, const QString &name, const QString &value);
void doDisconnectFromServer(); void doDisconnectFromServer();
void doActivateToServer(const QString &_token); void doActivateToServer(const QString &_token);
void doRequestForgotPasswordToServer(const QString &hostname, unsigned int port, const QString &_userName); void doRequestForgotPasswordToServer(const QString &hostname, unsigned int port, const QString &_userName);
@ -120,6 +123,9 @@ private:
protected slots: protected slots:
void sendCommandContainer(const CommandContainer &cont) override; void sendCommandContainer(const CommandContainer &cont) override;
public slots:
void sendDiagnostics();
public: public:
explicit RemoteClient(QObject *parent = nullptr, INetworkSettingsProvider *networkSettingsProvider = nullptr); explicit RemoteClient(QObject *parent = nullptr, INetworkSettingsProvider *networkSettingsProvider = nullptr);
~RemoteClient() override; ~RemoteClient() override;

View file

@ -55,6 +55,22 @@ message Command_Login {
optional string hashed_password = 6; optional string hashed_password = 6;
} }
message FeatureFlag {
optional string name = 1;
optional string value = 2;
}
message Command_ClientDiagnostics {
extend SessionCommand {
optional Command_ClientDiagnostics ext = 1051;
}
optional string clientver = 1;
repeated FeatureFlag feature_flags = 2;
optional string os = 3;
optional string arch = 4;
}
message Command_Message { message Command_Message {
extend SessionCommand { extend SessionCommand {
optional Command_Message ext = 1002; optional Command_Message ext = 1002;