From 59ad93302226f3e65aed1a62ea3c7b58315d0eb6 Mon Sep 17 00:00:00 2001 From: bunnei Date: Tue, 8 Aug 2017 20:06:25 -0400 Subject: citra_qt: Show one-time callout messages to user. --- src/citra_qt/configuration/config.cpp | 2 ++ src/citra_qt/main.cpp | 44 +++++++++++++++++++++++++++++++++++ src/citra_qt/main.h | 2 ++ src/citra_qt/ui_settings.h | 2 ++ 4 files changed, 50 insertions(+) (limited to 'src/citra_qt') diff --git a/src/citra_qt/configuration/config.cpp b/src/citra_qt/configuration/config.cpp index 6e42db007..7386814b3 100644 --- a/src/citra_qt/configuration/config.cpp +++ b/src/citra_qt/configuration/config.cpp @@ -194,6 +194,7 @@ void Config::ReadValues() { UISettings::values.show_status_bar = qt_config->value("showStatusBar", true).toBool(); UISettings::values.confirm_before_closing = qt_config->value("confirmClose", true).toBool(); UISettings::values.first_start = qt_config->value("firstStart", true).toBool(); + UISettings::values.callout_flags = qt_config->value("calloutFlags", 0).toUInt(); qt_config->endGroup(); } @@ -320,6 +321,7 @@ void Config::SaveValues() { qt_config->setValue("showStatusBar", UISettings::values.show_status_bar); qt_config->setValue("confirmClose", UISettings::values.confirm_before_closing); qt_config->setValue("firstStart", UISettings::values.first_start); + qt_config->setValue("calloutFlags", UISettings::values.callout_flags); qt_config->endGroup(); } diff --git a/src/citra_qt/main.cpp b/src/citra_qt/main.cpp index c1ae0ccc8..a8bf6201a 100644 --- a/src/citra_qt/main.cpp +++ b/src/citra_qt/main.cpp @@ -48,6 +48,47 @@ Q_IMPORT_PLUGIN(QWindowsIntegrationPlugin); #endif +/** + * "Callouts" are one-time instructional messages shown to the user. In the config settings, there + * is a bitfield "callout_flags" options, used to track if a message has already been shown to the + * user. This is 32-bits - if we have more than 32 callouts, we should retire and recyle old ones. + */ +enum class CalloutFlag : uint32_t { + Telemetry = 0x1, +}; + +static void ShowCalloutMessage(const QString& message, CalloutFlag flag) { + if (UISettings::values.callout_flags & static_cast(flag)) { + return; + } + + UISettings::values.callout_flags |= static_cast(flag); + + QMessageBox msg; + msg.setText(message); + msg.setStandardButtons(QMessageBox::Ok); + msg.setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); + msg.setStyleSheet("QLabel{min-width: 900px;}"); + msg.exec(); +} + +void GMainWindow::ShowCallouts() { + static const QString telemetry_message = + tr("To help improve Citra, the Citra Team collects anonymous usage data. No private or " + "personally identifying information is collected. This data helps us to understand how " + "people use Citra and prioritize our efforts. Furthermore, it helps us to more easily " + "identify emulation bugs and performance issues. This data includes:
  • Information" + " about the version of Citra you are using
  • Performance data about the games you " + "play
  • Your configuration settings
  • Information about your computer " + "hardware
  • Emulation errors and crash information
By default, this " + "feature is enabled. To disable this feature, click 'Emulation' from the menu and then " + "select 'Configure...'. Then, on the 'Web' tab, uncheck 'Share anonymous usage data with" + " the Citra team'.

By using this software, you agree to the above terms.
" + "
Learn " + "more"); + ShowCalloutMessage(telemetry_message, CalloutFlag::Telemetry); +} + GMainWindow::GMainWindow() : config(new Config()), emu_thread(nullptr) { Pica::g_debug_context = Pica::DebugContext::Construct(); setAcceptDrops(true); @@ -73,6 +114,9 @@ GMainWindow::GMainWindow() : config(new Config()), emu_thread(nullptr) { UpdateUITheme(); + // Show one-time "callout" messages to the user + ShowCallouts(); + QStringList args = QApplication::arguments(); if (args.length() >= 2) { BootGame(args[1]); diff --git a/src/citra_qt/main.h b/src/citra_qt/main.h index 360de2ced..d59a6d67d 100644 --- a/src/citra_qt/main.h +++ b/src/citra_qt/main.h @@ -80,6 +80,8 @@ private: void BootGame(const QString& filename); void ShutdownGame(); + void ShowCallouts(); + /** * Stores the filename in the recently loaded files list. * The new filename is stored at the beginning of the recently loaded files list. diff --git a/src/citra_qt/ui_settings.h b/src/citra_qt/ui_settings.h index 025c73f84..d85c92765 100644 --- a/src/citra_qt/ui_settings.h +++ b/src/citra_qt/ui_settings.h @@ -48,6 +48,8 @@ struct Values { // Shortcut name std::vector shortcuts; + + uint32_t callout_flags; }; extern Values values; -- cgit v1.2.3 From c781aea947e275a970a3431a36160b769865993d Mon Sep 17 00:00:00 2001 From: bunnei Date: Tue, 22 Aug 2017 22:37:03 -0400 Subject: settings: Add enable_telemetry, citra_username, and citra_token. --- src/citra/config.cpp | 4 ++++ src/citra/default_ini.h | 7 +++++++ src/citra_qt/configuration/config.cpp | 6 ++++++ src/core/settings.h | 3 +++ 4 files changed, 20 insertions(+) (limited to 'src/citra_qt') diff --git a/src/citra/config.cpp b/src/citra/config.cpp index 73846ed91..3869b6b5d 100644 --- a/src/citra/config.cpp +++ b/src/citra/config.cpp @@ -156,8 +156,12 @@ void Config::ReadValues() { static_cast(sdl2_config->GetInteger("Debugging", "gdbstub_port", 24689)); // Web Service + Settings::values.enable_telemetry = + sdl2_config->GetBoolean("WebService", "enable_telemetry", true); Settings::values.telemetry_endpoint_url = sdl2_config->Get( "WebService", "telemetry_endpoint_url", "https://services.citra-emu.org/api/telemetry"); + Settings::values.citra_username = sdl2_config->Get("WebService", "citra_username", ""); + Settings::values.citra_token = sdl2_config->Get("WebService", "citra_token", ""); } void Config::Reload() { diff --git a/src/citra/default_ini.h b/src/citra/default_ini.h index 9ea779dd8..666a2ad70 100644 --- a/src/citra/default_ini.h +++ b/src/citra/default_ini.h @@ -176,7 +176,14 @@ use_gdbstub=false gdbstub_port=24689 [WebService] +# Whether or not to enable telemetry +# 0: No, 1 (default): Yes +enable_telemetry = # Endpoint URL for submitting telemetry data telemetry_endpoint_url = +# Username and token for Citra Web Service +# See https://services.citra-emu.org/ for more info +citra_username = +citra_token = )"; } diff --git a/src/citra_qt/configuration/config.cpp b/src/citra_qt/configuration/config.cpp index 7386814b3..e2dceaa4c 100644 --- a/src/citra_qt/configuration/config.cpp +++ b/src/citra_qt/configuration/config.cpp @@ -139,10 +139,13 @@ void Config::ReadValues() { qt_config->endGroup(); qt_config->beginGroup("WebService"); + Settings::values.enable_telemetry = qt_config->value("enable_telemetry", true).toBool(); Settings::values.telemetry_endpoint_url = qt_config->value("telemetry_endpoint_url", "https://services.citra-emu.org/api/telemetry") .toString() .toStdString(); + Settings::values.citra_username = qt_config->value("citra_username").toString().toStdString(); + Settings::values.citra_token = qt_config->value("citra_token").toString().toStdString(); qt_config->endGroup(); qt_config->beginGroup("UI"); @@ -284,8 +287,11 @@ void Config::SaveValues() { qt_config->endGroup(); qt_config->beginGroup("WebService"); + qt_config->setValue("enable_telemetry", Settings::values.enable_telemetry); qt_config->setValue("telemetry_endpoint_url", QString::fromStdString(Settings::values.telemetry_endpoint_url)); + qt_config->setValue("citra_username", QString::fromStdString(Settings::values.citra_username)); + qt_config->setValue("citra_token", QString::fromStdString(Settings::values.citra_token)); qt_config->endGroup(); qt_config->beginGroup("UI"); diff --git a/src/core/settings.h b/src/core/settings.h index ca657719a..bf8014c5a 100644 --- a/src/core/settings.h +++ b/src/core/settings.h @@ -130,7 +130,10 @@ struct Values { u16 gdbstub_port; // WebService + bool enable_telemetry; std::string telemetry_endpoint_url; + std::string citra_username; + std::string citra_token; } extern values; // a special value for Values::region_value indicating that citra will automatically select a region -- cgit v1.2.3 From 40f417125b799fde86f00824633d1ef86be73c6a Mon Sep 17 00:00:00 2001 From: bunnei Date: Tue, 22 Aug 2017 22:47:56 -0400 Subject: telemetry: Log frontend type. --- src/citra/citra.cpp | 2 ++ src/citra_qt/main.cpp | 2 ++ 2 files changed, 4 insertions(+) (limited to 'src/citra_qt') diff --git a/src/citra/citra.cpp b/src/citra/citra.cpp index 14574e56c..e524c5535 100644 --- a/src/citra/citra.cpp +++ b/src/citra/citra.cpp @@ -165,6 +165,8 @@ int main(int argc, char** argv) { break; // Expected case } + Core::Telemetry().AddField(Telemetry::FieldType::App, "Frontend", "SDL"); + while (emu_window->IsOpen()) { system.RunLoop(); } diff --git a/src/citra_qt/main.cpp b/src/citra_qt/main.cpp index a8bf6201a..8adbcfe86 100644 --- a/src/citra_qt/main.cpp +++ b/src/citra_qt/main.cpp @@ -364,6 +364,8 @@ bool GMainWindow::LoadROM(const QString& filename) { const Core::System::ResultStatus result{system.Load(render_window, filename.toStdString())}; + Core::Telemetry().AddField(Telemetry::FieldType::App, "Frontend", "Qt"); + if (result != Core::System::ResultStatus::Success) { switch (result) { case Core::System::ResultStatus::ErrorGetLoader: -- cgit v1.2.3 From fb17e866aa58db05d4d16ba861b1150e6187592e Mon Sep 17 00:00:00 2001 From: bunnei Date: Tue, 22 Aug 2017 23:36:57 -0400 Subject: qt: Add web configuration tab. --- src/citra_qt/CMakeLists.txt | 3 + src/citra_qt/configuration/configure.ui | 15 ++- src/citra_qt/configuration/configure_dialog.cpp | 1 + src/citra_qt/configuration/configure_web.cpp | 44 +++++++++ src/citra_qt/configuration/configure_web.h | 30 ++++++ src/citra_qt/configuration/configure_web.ui | 126 ++++++++++++++++++++++++ 6 files changed, 217 insertions(+), 2 deletions(-) create mode 100644 src/citra_qt/configuration/configure_web.cpp create mode 100644 src/citra_qt/configuration/configure_web.h create mode 100644 src/citra_qt/configuration/configure_web.ui (limited to 'src/citra_qt') diff --git a/src/citra_qt/CMakeLists.txt b/src/citra_qt/CMakeLists.txt index f364b2284..e0a19fd9e 100644 --- a/src/citra_qt/CMakeLists.txt +++ b/src/citra_qt/CMakeLists.txt @@ -12,6 +12,7 @@ set(SRCS configuration/configure_graphics.cpp configuration/configure_input.cpp configuration/configure_system.cpp + configuration/configure_web.cpp debugger/graphics/graphics.cpp debugger/graphics/graphics_breakpoint_observer.cpp debugger/graphics/graphics_breakpoints.cpp @@ -42,6 +43,7 @@ set(HEADERS configuration/configure_graphics.h configuration/configure_input.h configuration/configure_system.h + configuration/configure_web.h debugger/graphics/graphics.h debugger/graphics/graphics_breakpoint_observer.h debugger/graphics/graphics_breakpoints.h @@ -71,6 +73,7 @@ set(UIS configuration/configure_graphics.ui configuration/configure_input.ui configuration/configure_system.ui + configuration/configure_web.ui debugger/registers.ui hotkeys.ui main.ui diff --git a/src/citra_qt/configuration/configure.ui b/src/citra_qt/configuration/configure.ui index 85e206e42..6abd1917e 100644 --- a/src/citra_qt/configuration/configure.ui +++ b/src/citra_qt/configuration/configure.ui @@ -6,8 +6,8 @@ 0 0 - 441 - 501 + 740 + 500 @@ -49,6 +49,11 @@ Debug + + + Web + + @@ -97,6 +102,12 @@
configuration/configure_graphics.h
1 + + ConfigureWeb + QWidget +
configuration/configure_web.h
+ 1 +
diff --git a/src/citra_qt/configuration/configure_dialog.cpp b/src/citra_qt/configuration/configure_dialog.cpp index dfc8c03a7..b87dc0e6c 100644 --- a/src/citra_qt/configuration/configure_dialog.cpp +++ b/src/citra_qt/configuration/configure_dialog.cpp @@ -23,5 +23,6 @@ void ConfigureDialog::applyConfiguration() { ui->graphicsTab->applyConfiguration(); ui->audioTab->applyConfiguration(); ui->debugTab->applyConfiguration(); + ui->webTab->applyConfiguration(); Settings::Apply(); } diff --git a/src/citra_qt/configuration/configure_web.cpp b/src/citra_qt/configuration/configure_web.cpp new file mode 100644 index 000000000..fff466aaa --- /dev/null +++ b/src/citra_qt/configuration/configure_web.cpp @@ -0,0 +1,44 @@ +// Copyright 2017 Citra Emulator Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#include "citra_qt/configuration/configure_web.h" +#include "core/settings.h" +#include "ui_configure_web.h" + +ConfigureWeb::ConfigureWeb(QWidget* parent) + : QWidget(parent), ui(std::make_unique()) { + ui->setupUi(this); + this->setConfiguration(); +} + +ConfigureWeb::~ConfigureWeb() {} + +void ConfigureWeb::setConfiguration() { + ui->web_credentials_disclaimer->setWordWrap(true); + ui->telemetry_learn_more->setOpenExternalLinks(true); + ui->telemetry_learn_more->setText("Learn more"); + + ui->web_signup_link->setOpenExternalLinks(true); + ui->web_signup_link->setText("Sign up"); + ui->web_token_info_link->setOpenExternalLinks(true); + ui->web_token_info_link->setText( + "What is my token?"); + + ui->toggle_telemetry->setChecked(Settings::values.enable_telemetry); + ui->edit_username->setText(QString::fromStdString(Settings::values.citra_username)); + ui->edit_token->setText(QString::fromStdString(Settings::values.citra_token)); + + updateWeb(); +} + +void ConfigureWeb::applyConfiguration() { + Settings::values.enable_telemetry = ui->toggle_telemetry->isChecked(); + Settings::values.citra_username = ui->edit_username->text().toStdString(); + Settings::values.citra_token = ui->edit_token->text().toStdString(); + Settings::Apply(); +} + +void ConfigureWeb::updateWeb() {} diff --git a/src/citra_qt/configuration/configure_web.h b/src/citra_qt/configuration/configure_web.h new file mode 100644 index 000000000..2c37b8f90 --- /dev/null +++ b/src/citra_qt/configuration/configure_web.h @@ -0,0 +1,30 @@ +// Copyright 2017 Citra Emulator Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#pragma once + +#include +#include + +namespace Ui { +class ConfigureWeb; +} + +class ConfigureWeb : public QWidget { + Q_OBJECT + +public: + explicit ConfigureWeb(QWidget* parent = nullptr); + ~ConfigureWeb(); + + void applyConfiguration(); + +public slots: + void updateWeb(); + +private: + void setConfiguration(); + + std::unique_ptr ui; +}; diff --git a/src/citra_qt/configuration/configure_web.ui b/src/citra_qt/configuration/configure_web.ui new file mode 100644 index 000000000..3bb8276fa --- /dev/null +++ b/src/citra_qt/configuration/configure_web.ui @@ -0,0 +1,126 @@ + + + ConfigureWeb + + + + 0 + 0 + 400 + 300 + + + + Form + + + + + + + + Citra Web Service + + + + + + By providing your username and token, you agree to allow Citra to collect additional usage data, which may include user identifying information. + + + + + + + + + Username: + + + + + + + 36 + + + + + + + Token: + + + + + + + 36 + + + QLineEdit::Password + + + + + + + Sign up + + + + + + + What is my token? + + + + + + + + + + + + Telemetry + + + + + + Share anonymous usage data with the Citra team + + + + + + + Learn more + + + + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + -- cgit v1.2.3 From 2e37201c63d5efb8eb39f993b77c11e73bd6a8e7 Mon Sep 17 00:00:00 2001 From: bunnei Date: Thu, 24 Aug 2017 19:31:17 -0400 Subject: # This is a combination of 2 commits. # This is the 1st commit message: qt: Add web configuration tab. # The commit message #2 will be skipped: # fixup! qt: Add web configuration tab. --- src/citra_qt/configuration/configure_web.ui | 33 ++++++++++++++++++++++++++--- 1 file changed, 30 insertions(+), 3 deletions(-) (limited to 'src/citra_qt') diff --git a/src/citra_qt/configuration/configure_web.ui b/src/citra_qt/configuration/configure_web.ui index 3bb8276fa..d8d283fad 100644 --- a/src/citra_qt/configuration/configure_web.ui +++ b/src/citra_qt/configuration/configure_web.ui @@ -17,11 +17,11 @@ - + Citra Web Service - + @@ -30,7 +30,7 @@ - + @@ -101,6 +101,33 @@ + + + + + + Telemetry ID: + + + + + + + + 0 + 0 + + + + Qt::RightToLeft + + + Regenerate + + + + + -- cgit v1.2.3 From 9f0da33c3349df47580d93fcd25346be4d2b94a7 Mon Sep 17 00:00:00 2001 From: bunnei Date: Wed, 23 Aug 2017 00:08:07 -0400 Subject: qt: Add an option to view/regenerate telemetry ID. --- src/citra_qt/configuration/configure_web.cpp | 14 +++++++++++--- src/citra_qt/configuration/configure_web.h | 2 +- src/core/telemetry_session.cpp | 19 ++++++++++++++++--- src/core/telemetry_session.h | 12 ++++++++++++ 4 files changed, 40 insertions(+), 7 deletions(-) (limited to 'src/citra_qt') diff --git a/src/citra_qt/configuration/configure_web.cpp b/src/citra_qt/configuration/configure_web.cpp index fff466aaa..8715fb018 100644 --- a/src/citra_qt/configuration/configure_web.cpp +++ b/src/citra_qt/configuration/configure_web.cpp @@ -4,11 +4,15 @@ #include "citra_qt/configuration/configure_web.h" #include "core/settings.h" +#include "core/telemetry_session.h" #include "ui_configure_web.h" ConfigureWeb::ConfigureWeb(QWidget* parent) : QWidget(parent), ui(std::make_unique()) { ui->setupUi(this); + connect(ui->button_regenerate_telemetry_id, &QPushButton::clicked, this, + &ConfigureWeb::refreshTelemetryID); + this->setConfiguration(); } @@ -30,8 +34,8 @@ void ConfigureWeb::setConfiguration() { ui->toggle_telemetry->setChecked(Settings::values.enable_telemetry); ui->edit_username->setText(QString::fromStdString(Settings::values.citra_username)); ui->edit_token->setText(QString::fromStdString(Settings::values.citra_token)); - - updateWeb(); + ui->label_telemetry_id->setText("Telemetry ID: 0x" + + QString::number(Core::GetTelemetryId(), 16).toUpper()); } void ConfigureWeb::applyConfiguration() { @@ -41,4 +45,8 @@ void ConfigureWeb::applyConfiguration() { Settings::Apply(); } -void ConfigureWeb::updateWeb() {} +void ConfigureWeb::refreshTelemetryID() { + const u64 new_telemetry_id{Core::RegenerateTelemetryId()}; + ui->label_telemetry_id->setText("Telemetry ID: 0x" + + QString::number(new_telemetry_id, 16).toUpper()); +} diff --git a/src/citra_qt/configuration/configure_web.h b/src/citra_qt/configuration/configure_web.h index 2c37b8f90..20bc254b9 100644 --- a/src/citra_qt/configuration/configure_web.h +++ b/src/citra_qt/configuration/configure_web.h @@ -21,7 +21,7 @@ public: void applyConfiguration(); public slots: - void updateWeb(); + void refreshTelemetryID(); private: void setConfiguration(); diff --git a/src/core/telemetry_session.cpp b/src/core/telemetry_session.cpp index 61ba78457..d0f257f58 100644 --- a/src/core/telemetry_session.cpp +++ b/src/core/telemetry_session.cpp @@ -38,21 +38,21 @@ static u64 GenerateTelemetryId() { return telemetry_id; } -static u64 GetTelemetryId() { +u64 GetTelemetryId() { u64 telemetry_id{}; static const std::string& filename{FileUtil::GetUserPath(D_CONFIG_IDX) + "telemetry_id"}; if (FileUtil::Exists(filename)) { FileUtil::IOFile file(filename, "rb"); if (!file.IsOpen()) { - LOG_ERROR(WebService, "failed to open telemetry_id: %s", filename.c_str()); + LOG_ERROR(Core, "failed to open telemetry_id: %s", filename.c_str()); return {}; } file.ReadBytes(&telemetry_id, sizeof(u64)); } else { FileUtil::IOFile file(filename, "wb"); if (!file.IsOpen()) { - LOG_ERROR(WebService, "failed to open telemetry_id: %s", filename.c_str()); + LOG_ERROR(Core, "failed to open telemetry_id: %s", filename.c_str()); return {}; } telemetry_id = GenerateTelemetryId(); @@ -62,6 +62,19 @@ static u64 GetTelemetryId() { return telemetry_id; } +u64 RegenerateTelemetryId() { + const u64 new_telemetry_id{GenerateTelemetryId()}; + static const std::string& filename{FileUtil::GetUserPath(D_CONFIG_IDX) + "telemetry_id"}; + + FileUtil::IOFile file(filename, "wb"); + if (!file.IsOpen()) { + LOG_ERROR(Core, "failed to open telemetry_id: %s", filename.c_str()); + return {}; + } + file.WriteBytes(&new_telemetry_id, sizeof(u64)); + return new_telemetry_id; +} + TelemetrySession::TelemetrySession() { #ifdef ENABLE_WEB_SERVICE backend = std::make_unique(); diff --git a/src/core/telemetry_session.h b/src/core/telemetry_session.h index cf53835c3..65613daae 100644 --- a/src/core/telemetry_session.h +++ b/src/core/telemetry_session.h @@ -35,4 +35,16 @@ private: std::unique_ptr backend; ///< Backend interface that logs fields }; +/** + * Gets TelemetryId, a unique identifier used for the user's telemetry sessions. + * @returns The current TelemetryId for the session. + */ +u64 GetTelemetryId(); + +/** + * Regenerates TelemetryId, a unique identifier used for the user's telemetry sessions. + * @returns The new TelemetryId that was generated. + */ +u64 RegenerateTelemetryId(); + } // namespace Core -- cgit v1.2.3