From b44f4cff931be30b9b31503f072f2f9423fafa40 Mon Sep 17 00:00:00 2001 From: Phoenix Date: Sat, 14 Sep 2024 15:19:23 +1000 Subject: [PATCH] chore: remove telemetry and anonymize SCM (git) strings --- src/common/CMakeLists.txt | 2 - src/common/scm_rev.cpp.in | 101 +++++++++-- src/common/scm_rev.h | 6 +- src/common/settings.h | 3 +- src/common/telemetry.cpp | 119 ------------- src/common/telemetry.h | 209 ----------------------- src/core/CMakeLists.txt | 2 - src/core/core.cpp | 32 ---- src/core/core.h | 7 - src/core/telemetry_session.cpp | 294 --------------------------------- src/core/telemetry_session.h | 101 ----------- 11 files changed, 94 insertions(+), 782 deletions(-) delete mode 100644 src/common/telemetry.cpp delete mode 100644 src/common/telemetry.h delete mode 100644 src/core/telemetry_session.cpp delete mode 100644 src/core/telemetry_session.h diff --git a/src/common/CMakeLists.txt b/src/common/CMakeLists.txt index 31c5c9824..017146a1e 100644 --- a/src/common/CMakeLists.txt +++ b/src/common/CMakeLists.txt @@ -136,8 +136,6 @@ add_library(common STATIC string_util.cpp string_util.h swap.h - telemetry.cpp - telemetry.h thread.cpp thread.h thread_queue_list.h diff --git a/src/common/scm_rev.cpp.in b/src/common/scm_rev.cpp.in index f0c124d69..8265c0a7b 100644 --- a/src/common/scm_rev.cpp.in +++ b/src/common/scm_rev.cpp.in @@ -3,11 +3,15 @@ #include "common/scm_rev.h" -#define GIT_REV "@GIT_REV@" -#define GIT_BRANCH "@GIT_BRANCH@" -#define GIT_DESC "@GIT_DESC@" -#define BUILD_NAME "@REPO_NAME@" -#define BUILD_DATE "@BUILD_DATE@" +#include +#include +#include + +#define GIT_REV "@GIT_REV@" +#define GIT_BRANCH "@GIT_BRANCH@" +#define GIT_DESC "@GIT_DESC@" +#define BUILD_NAME "@REPO_NAME@" +#define BUILD_DATE "@BUILD_DATE@" #define BUILD_FULLNAME "@BUILD_FULLNAME@" #define BUILD_VERSION "@BUILD_VERSION@" #define BUILD_ID "@BUILD_ID@" @@ -16,16 +20,89 @@ namespace Common { -const char g_scm_rev[] = GIT_REV; -const char g_scm_branch[] = GIT_BRANCH; -const char g_scm_desc[] = GIT_DESC; -const char g_build_name[] = BUILD_NAME; -const char g_build_date[] = BUILD_DATE; +const char* g_scm_rev; +const char* g_scm_branch; +const char* g_scm_desc; +const char g_build_name[] = BUILD_NAME; +const char g_build_date[] = BUILD_DATE; const char g_build_fullname[] = BUILD_FULLNAME; -const char g_build_version[] = BUILD_VERSION; +const char g_build_version[] = BUILD_VERSION; const char g_build_id[] = BUILD_ID; const char g_title_bar_format_idle[] = TITLE_BAR_FORMAT_IDLE; const char g_title_bar_format_running[] = TITLE_BAR_FORMAT_RUNNING; -} // namespace +#include +#include +#include +namespace Common { + +constexpr const char* DEFAULT_LINUX_KEY = "linux_error_key"; +constexpr const char* DEFAULT_FALLBACK_KEY = "default_key"; + +class SCMEncrypt { + std::string m_scm_rev, m_scm_branch, m_scm_desc; + + std::string GetKey() { +#ifdef __linux__ + std::ifstream file("/proc/sys/kernel/hostname"); + std::string key; + if (!std::getline(file, key)) { + return DEFAULT_LINUX_KEY; + } + return key; +#else + // Fallback key for non-Linux systems + return BUILD_DATE; // Using BUILD_DATE as the fallback key +#endif + } + + void XORWithKey(std::string& str, const std::string& key) { + auto key_it = key.begin(); + for (auto& c : str) { + c ^= *key_it; + if (++key_it == key.end()) { + key_it = key.begin(); // Wrap around if key length is smaller than string + } + } + } + + std::string ToHexString(const std::string& str) { + std::string result; + for (const auto& c : str) { + result.append(fmt::format("{:02x}", static_cast(c))); // Convert to hex + } + return result; + } + +public: + SCMEncrypt() { + // Fetch the key + const std::string key = GetKey(); + + // Assign values from the defines + m_scm_rev = GIT_REV; + m_scm_branch = GIT_BRANCH; + m_scm_desc = GIT_DESC; + + // XOR the strings with the key + XORWithKey(m_scm_rev, key); + XORWithKey(m_scm_branch, key); + XORWithKey(m_scm_desc, key); + + // Convert the XOR-ed strings to human-readable hex format + m_scm_rev = ToHexString(m_scm_rev); + m_scm_branch = ToHexString(m_scm_branch); + m_scm_desc = ToHexString(m_scm_desc); + + // Set global pointers to the encrypted values + g_scm_rev = m_scm_rev.c_str(); + g_scm_branch = m_scm_branch.c_str(); + g_scm_desc = m_scm_desc.c_str(); + } +}; + +// Create an instance of SCMEncrypt +SCMEncrypt scm_encrypt_instance; + +} // namespace Common diff --git a/src/common/scm_rev.h b/src/common/scm_rev.h index 88404316a..59d0cfcfb 100644 --- a/src/common/scm_rev.h +++ b/src/common/scm_rev.h @@ -5,9 +5,9 @@ namespace Common { -extern const char g_scm_rev[]; -extern const char g_scm_branch[]; -extern const char g_scm_desc[]; +extern const char* g_scm_rev; +extern const char* g_scm_branch; +extern const char* g_scm_desc; extern const char g_build_name[]; extern const char g_build_date[]; extern const char g_build_fullname[]; diff --git a/src/common/settings.h b/src/common/settings.h index 9fd6de528..2887e16dd 100644 --- a/src/common/settings.h +++ b/src/common/settings.h @@ -609,7 +609,8 @@ struct Values { Category::Network}; // WebService - Setting enable_telemetry{linkage, false, "enable_telemetry", Category::WebService}; + + // Removed Telemtry API Setting web_api_url{linkage, "http://localhost", "web_api_url", Category::WebService}; Setting uzuy_username{linkage, std::string(), "uzuy_username", diff --git a/src/common/telemetry.cpp b/src/common/telemetry.cpp deleted file mode 100644 index 929ed67e4..000000000 --- a/src/common/telemetry.cpp +++ /dev/null @@ -1,119 +0,0 @@ -// SPDX-FileCopyrightText: 2017 Citra Emulator Project -// SPDX-License-Identifier: GPL-2.0-or-later - -#include -#include -#include "common/scm_rev.h" -#include "common/telemetry.h" - -#ifdef ARCHITECTURE_x86_64 -#include "common/x64/cpu_detect.h" -#endif - -namespace Common::Telemetry { - -void FieldCollection::Accept(VisitorInterface& visitor) const { - for (const auto& field : fields) { - field.second->Accept(visitor); - } -} - -void FieldCollection::AddField(std::unique_ptr field) { - fields[field->GetName()] = std::move(field); -} - -template -void Field::Accept(VisitorInterface& visitor) const { - visitor.Visit(*this); -} - -template class Field; -template class Field; -template class Field; -template class Field; -template class Field; -template class Field; -template class Field; -template class Field; -template class Field; -template class Field; -template class Field; -template class Field; -template class Field; -template class Field; - -void AppendBuildInfo(FieldCollection& fc) { - const bool is_git_dirty{std::strstr(Common::g_scm_desc, "dirty") != nullptr}; - fc.AddField(FieldType::App, "Git_IsDirty", is_git_dirty); - fc.AddField(FieldType::App, "Git_Branch", Common::g_scm_branch); - fc.AddField(FieldType::App, "Git_Revision", Common::g_scm_rev); - fc.AddField(FieldType::App, "BuildDate", Common::g_build_date); - fc.AddField(FieldType::App, "BuildName", Common::g_build_name); -} - -void AppendCPUInfo(FieldCollection& fc) { -#ifdef ARCHITECTURE_x86_64 - - const auto& caps = Common::GetCPUCaps(); - const auto add_field = [&fc](std::string_view field_name, const auto& field_value) { - fc.AddField(FieldType::UserSystem, field_name, field_value); - }; - add_field("CPU_Model", caps.cpu_string); - add_field("CPU_BrandString", caps.brand_string); - - add_field("CPU_Extension_x64_SSE", caps.sse); - add_field("CPU_Extension_x64_SSE2", caps.sse2); - add_field("CPU_Extension_x64_SSE3", caps.sse3); - add_field("CPU_Extension_x64_SSSE3", caps.ssse3); - add_field("CPU_Extension_x64_SSE41", caps.sse4_1); - add_field("CPU_Extension_x64_SSE42", caps.sse4_2); - - add_field("CPU_Extension_x64_AVX", caps.avx); - add_field("CPU_Extension_x64_AVX_VNNI", caps.avx_vnni); - add_field("CPU_Extension_x64_AVX2", caps.avx2); - - // Skylake-X/SP level AVX512, for compatibility with the previous telemetry field - add_field("CPU_Extension_x64_AVX512", - caps.avx512f && caps.avx512cd && caps.avx512vl && caps.avx512dq && caps.avx512bw); - - add_field("CPU_Extension_x64_AVX512F", caps.avx512f); - add_field("CPU_Extension_x64_AVX512CD", caps.avx512cd); - add_field("CPU_Extension_x64_AVX512VL", caps.avx512vl); - add_field("CPU_Extension_x64_AVX512DQ", caps.avx512dq); - add_field("CPU_Extension_x64_AVX512BW", caps.avx512bw); - add_field("CPU_Extension_x64_AVX512BITALG", caps.avx512bitalg); - add_field("CPU_Extension_x64_AVX512VBMI", caps.avx512vbmi); - - add_field("CPU_Extension_x64_AES", caps.aes); - add_field("CPU_Extension_x64_BMI1", caps.bmi1); - add_field("CPU_Extension_x64_BMI2", caps.bmi2); - add_field("CPU_Extension_x64_F16C", caps.f16c); - add_field("CPU_Extension_x64_FMA", caps.fma); - add_field("CPU_Extension_x64_FMA4", caps.fma4); - add_field("CPU_Extension_x64_GFNI", caps.gfni); - add_field("CPU_Extension_x64_INVARIANT_TSC", caps.invariant_tsc); - add_field("CPU_Extension_x64_LZCNT", caps.lzcnt); - add_field("CPU_Extension_x64_MONITORX", caps.monitorx); - add_field("CPU_Extension_x64_MOVBE", caps.movbe); - add_field("CPU_Extension_x64_PCLMULQDQ", caps.pclmulqdq); - add_field("CPU_Extension_x64_POPCNT", caps.popcnt); - add_field("CPU_Extension_x64_SHA", caps.sha); - add_field("CPU_Extension_x64_WAITPKG", caps.waitpkg); -#else - fc.AddField(FieldType::UserSystem, "CPU_Model", "Other"); -#endif -} - -void AppendOSInfo(FieldCollection& fc) { -#ifdef __APPLE__ - fc.AddField(FieldType::UserSystem, "OsPlatform", "Apple"); -#elif defined(_WIN32) - fc.AddField(FieldType::UserSystem, "OsPlatform", "Windows"); -#elif defined(__linux__) || defined(linux) || defined(__linux) - fc.AddField(FieldType::UserSystem, "OsPlatform", "Linux"); -#else - fc.AddField(FieldType::UserSystem, "OsPlatform", "Unknown"); -#endif -} - -} // namespace Common::Telemetry diff --git a/src/common/telemetry.h b/src/common/telemetry.h deleted file mode 100644 index b202b938c..000000000 --- a/src/common/telemetry.h +++ /dev/null @@ -1,209 +0,0 @@ -// SPDX-FileCopyrightText: 2017 Citra Emulator Project -// SPDX-License-Identifier: GPL-2.0-or-later - -#pragma once - -#include -#include -#include -#include -#include "common/common_funcs.h" -#include "common/common_types.h" - -namespace Common::Telemetry { - -/// Field type, used for grouping fields together in the final submitted telemetry log -enum class FieldType : u8 { - None = 0, ///< No specified field group - App, ///< uzuy application fields (e.g. version, branch, etc.) - Session, ///< Emulated session fields (e.g. title ID, log, etc.) - Performance, ///< Emulated performance (e.g. fps, emulated CPU speed, etc.) - UserFeedback, ///< User submitted feedback (e.g. star rating, user notes, etc.) - UserConfig, ///< User configuration fields (e.g. emulated CPU core, renderer, etc.) - UserSystem, ///< User system information (e.g. host CPU type, RAM, etc.) -}; - -struct VisitorInterface; - -/** - * Interface class for telemetry data fields. - */ -class FieldInterface { -public: - virtual ~FieldInterface() = default; - - /** - * Accept method for the visitor pattern. - * @param visitor Reference to the visitor that will visit this field. - */ - virtual void Accept(VisitorInterface& visitor) const = 0; - - /** - * Gets the name of this field. - * @returns Name of this field as a string. - */ - virtual const std::string& GetName() const = 0; -}; - -/** - * Represents a telemetry data field, i.e. a unit of data that gets logged and submitted to our - * telemetry web service. - */ -template -class Field : public FieldInterface { -public: - UZUY_NON_COPYABLE(Field); - - Field(FieldType type_, std::string_view name_, T value_) - : name(name_), type(type_), value(std::move(value_)) {} - - ~Field() override = default; - - Field(Field&&) noexcept = default; - Field& operator=(Field&& other) noexcept = default; - - void Accept(VisitorInterface& visitor) const override; - - [[nodiscard]] const std::string& GetName() const override { - return name; - } - - /** - * Returns the type of the field. - */ - [[nodiscard]] FieldType GetType() const { - return type; - } - - /** - * Returns the value of the field. - */ - [[nodiscard]] const T& GetValue() const { - return value; - } - - [[nodiscard]] bool operator==(const Field& other) const { - return (type == other.type) && (name == other.name) && (value == other.value); - } - - [[nodiscard]] bool operator!=(const Field& other) const { - return !operator==(other); - } - -private: - std::string name; ///< Field name, must be unique - FieldType type{}; ///< Field type, used for grouping fields together - T value; ///< Field value -}; - -/** - * Collection of data fields that have been logged. - */ -class FieldCollection final { -public: - UZUY_NON_COPYABLE(FieldCollection); - - FieldCollection() = default; - ~FieldCollection() = default; - - FieldCollection(FieldCollection&&) noexcept = default; - FieldCollection& operator=(FieldCollection&&) noexcept = default; - - /** - * Accept method for the visitor pattern, visits each field in the collection. - * @param visitor Reference to the visitor that will visit each field. - */ - void Accept(VisitorInterface& visitor) const; - - /** - * Creates a new field and adds it to the field collection. - * @param type Type of the field to add. - * @param name Name of the field to add. - * @param value Value for the field to add. - */ - template - void AddField(FieldType type, std::string_view name, T value) { - return AddField(std::make_unique>(type, name, std::move(value))); - } - - /** - * Adds a new field to the field collection. - * @param field Field to add to the field collection. - */ - void AddField(std::unique_ptr field); - -private: - std::map> fields; -}; - -/** - * Telemetry fields visitor interface class. A backend to log to a web service should implement - * this interface. - */ -struct VisitorInterface { - virtual ~VisitorInterface() = default; - - virtual void Visit(const Field& field) = 0; - virtual void Visit(const Field& field) = 0; - virtual void Visit(const Field& field) = 0; - virtual void Visit(const Field& field) = 0; - virtual void Visit(const Field& field) = 0; - virtual void Visit(const Field& field) = 0; - virtual void Visit(const Field& field) = 0; - virtual void Visit(const Field& field) = 0; - virtual void Visit(const Field& field) = 0; - virtual void Visit(const Field& field) = 0; - virtual void Visit(const Field& field) = 0; - virtual void Visit(const Field& field) = 0; - virtual void Visit(const Field& field) = 0; - virtual void Visit(const Field& field) = 0; - - /// Completion method, called once all fields have been visited - virtual void Complete() = 0; - virtual bool SubmitTestcase() = 0; -}; - -/** - * Empty implementation of VisitorInterface that drops all fields. Used when a functional - * backend implementation is not available. - */ -struct NullVisitor final : public VisitorInterface { - UZUY_NON_COPYABLE(NullVisitor); - - NullVisitor() = default; - ~NullVisitor() override = default; - - void Visit(const Field& /*field*/) override {} - void Visit(const Field& /*field*/) override {} - void Visit(const Field& /*field*/) override {} - void Visit(const Field& /*field*/) override {} - void Visit(const Field& /*field*/) override {} - void Visit(const Field& /*field*/) override {} - void Visit(const Field& /*field*/) override {} - void Visit(const Field& /*field*/) override {} - void Visit(const Field& /*field*/) override {} - void Visit(const Field& /*field*/) override {} - void Visit(const Field& /*field*/) override {} - void Visit(const Field& /*field*/) override {} - void Visit(const Field& /*field*/) override {} - void Visit(const Field& /*field*/) override {} - - void Complete() override {} - bool SubmitTestcase() override { - return false; - } -}; - -/// Appends build-specific information to the given FieldCollection, -/// such as branch name, revision hash, etc. -void AppendBuildInfo(FieldCollection& fc); - -/// Appends CPU-specific information to the given FieldCollection, -/// such as instruction set extensions, etc. -void AppendCPUInfo(FieldCollection& fc); - -/// Appends OS-specific information to the given FieldCollection, -/// such as platform name, etc. -void AppendOSInfo(FieldCollection& fc); - -} // namespace Common::Telemetry diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index 7c658ca2f..e8defffef 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -1136,8 +1136,6 @@ add_library(core STATIC precompiled_headers.h reporter.cpp reporter.h - telemetry_session.cpp - telemetry_session.h tools/freezer.cpp tools/freezer.h tools/renderdoc.cpp diff --git a/src/core/core.cpp b/src/core/core.cpp index e1c8b41ee..0cb81d6d8 100644 --- a/src/core/core.cpp +++ b/src/core/core.cpp @@ -55,7 +55,6 @@ #include "core/memory/cheat_engine.h" #include "core/perf_stats.h" #include "core/reporter.h" -#include "core/telemetry_session.h" #include "core/tools/freezer.h" #include "core/tools/renderdoc.h" #include "hid_core/hid_core.h" @@ -272,8 +271,6 @@ struct System::Impl { } SystemResultStatus SetupForApplicationProcess(System& system, Frontend::EmuWindow& emu_window) { - telemetry_session = std::make_unique(); - host1x_core = std::make_unique(system); gpu_core = VideoCore::CreateGPU(emu_window, system); if (!gpu_core) { @@ -354,8 +351,6 @@ struct System::Impl { return init_result; } - telemetry_session->AddInitialInfo(*app_loader, fs_controller, *content_provider); - // Initialize cheat engine if (cheat_engine) { cheat_engine->Initialize(); @@ -401,21 +396,6 @@ struct System::Impl { void ShutdownMainProcess() { SetShuttingDown(true); - // Log last frame performance stats if game was loaded - if (perf_stats) { - const auto perf_results = GetAndResetPerfStats(); - constexpr auto performance = Common::Telemetry::FieldType::Performance; - - telemetry_session->AddField(performance, "Shutdown_EmulationSpeed", - perf_results.emulation_speed * 100.0); - telemetry_session->AddField(performance, "Shutdown_Framerate", - perf_results.average_game_fps); - telemetry_session->AddField(performance, "Shutdown_Frametime", - perf_results.frametime * 1000.0); - telemetry_session->AddField(performance, "Mean_Frametime_MS", - perf_stats->GetMeanFrametime()); - } - is_powered_on = false; exit_locked = false; exit_requested = false; @@ -434,7 +414,6 @@ struct System::Impl { service_manager.reset(); fs_controller.Reset(); cheat_engine.reset(); - telemetry_session.reset(); core_timing.ClearPendingEvents(); app_loader.reset(); audio_core.reset(); @@ -534,9 +513,6 @@ struct System::Impl { /// Services std::unique_ptr services; - /// Telemetry session for this emulation session - std::unique_ptr telemetry_session; - /// Network instance Network::NetworkInstance network_instance; @@ -663,14 +639,6 @@ PerfStatsResults System::GetAndResetPerfStats() { return impl->GetAndResetPerfStats(); } -TelemetrySession& System::TelemetrySession() { - return *impl->telemetry_session; -} - -const TelemetrySession& System::TelemetrySession() const { - return *impl->telemetry_session; -} - Kernel::PhysicalCore& System::CurrentPhysicalCore() { return impl->kernel.CurrentPhysicalCore(); } diff --git a/src/core/core.h b/src/core/core.h index 90826bd3a..0cc1108b8 100644 --- a/src/core/core.h +++ b/src/core/core.h @@ -122,7 +122,6 @@ class GPUDirtyMemoryManager; class PerfStats; class Reporter; class SpeedLimiter; -class TelemetrySession; struct PerfStatsResults; @@ -218,12 +217,6 @@ public: */ [[nodiscard]] bool IsPoweredOn() const; - /// Gets a reference to the telemetry session for this emulation session. - [[nodiscard]] Core::TelemetrySession& TelemetrySession(); - - /// Gets a reference to the telemetry session for this emulation session. - [[nodiscard]] const Core::TelemetrySession& TelemetrySession() const; - /// Prepare the core emulation for a reschedule void PrepareReschedule(u32 core_index); diff --git a/src/core/telemetry_session.cpp b/src/core/telemetry_session.cpp deleted file mode 100644 index 4247aa0db..000000000 --- a/src/core/telemetry_session.cpp +++ /dev/null @@ -1,294 +0,0 @@ -// SPDX-FileCopyrightText: 2017 Citra Emulator Project -// SPDX-License-Identifier: GPL-2.0-or-later - -#include - -#include -#include - -#include "common/assert.h" -#include "common/common_types.h" -#include "common/fs/file.h" -#include "common/fs/fs.h" -#include "common/fs/path_util.h" -#include "common/logging/log.h" - -#include "common/settings.h" -#include "common/settings_enums.h" -#include "core/file_sys/control_metadata.h" -#include "core/file_sys/patch_manager.h" -#include "core/loader/loader.h" -#include "core/telemetry_session.h" - -#ifdef ENABLE_WEB_SERVICE -#include "web_service/telemetry_json.h" -#include "web_service/verify_login.h" -#endif - -namespace Core { - -namespace Telemetry = Common::Telemetry; - -static u64 GenerateTelemetryId() { - u64 telemetry_id{}; - - mbedtls_entropy_context entropy; - mbedtls_entropy_init(&entropy); - mbedtls_ctr_drbg_context ctr_drbg; - static constexpr std::array personalization{{"uzuy Telemetry ID"}}; - - mbedtls_ctr_drbg_init(&ctr_drbg); - ASSERT(mbedtls_ctr_drbg_seed(&ctr_drbg, mbedtls_entropy_func, &entropy, - reinterpret_cast(personalization.data()), - personalization.size()) == 0); - ASSERT(mbedtls_ctr_drbg_random(&ctr_drbg, reinterpret_cast(&telemetry_id), - sizeof(u64)) == 0); - - mbedtls_ctr_drbg_free(&ctr_drbg); - mbedtls_entropy_free(&entropy); - - return telemetry_id; -} - -static const char* TranslateRenderer(Settings::RendererBackend backend) { - switch (backend) { - case Settings::RendererBackend::OpenGL: - return "OpenGL"; - case Settings::RendererBackend::Vulkan: - return "Vulkan"; - case Settings::RendererBackend::Null: - return "Null"; - } - return "Unknown"; -} - -static const char* TranslateGPUAccuracyLevel(Settings::GpuAccuracy backend) { - switch (backend) { - case Settings::GpuAccuracy::Normal: - return "Normal"; - case Settings::GpuAccuracy::High: - return "High"; - case Settings::GpuAccuracy::Extreme: - return "Extreme"; - } - return "Unknown"; -} - -static const char* TranslateNvdecEmulation(Settings::NvdecEmulation backend) { - switch (backend) { - case Settings::NvdecEmulation::Off: - return "Off"; - case Settings::NvdecEmulation::Cpu: - return "CPU"; - case Settings::NvdecEmulation::Gpu: - return "GPU"; - } - return "Unknown"; -} - -static constexpr const char* TranslateVSyncMode(Settings::VSyncMode mode) { - switch (mode) { - case Settings::VSyncMode::Immediate: - return "Immediate"; - case Settings::VSyncMode::Mailbox: - return "Mailbox"; - case Settings::VSyncMode::Fifo: - return "FIFO"; - case Settings::VSyncMode::FifoRelaxed: - return "FIFO Relaxed"; - } - return "Unknown"; -} - -static constexpr const char* TranslateASTCDecodeMode(Settings::AstcDecodeMode mode) { - switch (mode) { - case Settings::AstcDecodeMode::Cpu: - return "CPU"; - case Settings::AstcDecodeMode::Gpu: - return "GPU"; - case Settings::AstcDecodeMode::CpuAsynchronous: - return "CPU Asynchronous"; - } - return "Unknown"; -} - -u64 GetTelemetryId() { - u64 telemetry_id{}; - const auto filename = Common::FS::GetUzuyPath(Common::FS::UzuyPath::ConfigDir) / "telemetry_id"; - - bool generate_new_id = !Common::FS::Exists(filename); - - if (!generate_new_id) { - Common::FS::IOFile file{filename, Common::FS::FileAccessMode::Read, - Common::FS::FileType::BinaryFile}; - - if (!file.IsOpen()) { - LOG_ERROR(Core, "failed to open telemetry_id: {}", - Common::FS::PathToUTF8String(filename)); - return {}; - } - - if (!file.ReadObject(telemetry_id) || telemetry_id == 0) { - LOG_ERROR(Frontend, "telemetry_id is 0. Generating a new one.", telemetry_id); - generate_new_id = true; - } - } - - if (generate_new_id) { - Common::FS::IOFile file{filename, Common::FS::FileAccessMode::Write, - Common::FS::FileType::BinaryFile}; - - if (!file.IsOpen()) { - LOG_ERROR(Core, "failed to open telemetry_id: {}", - Common::FS::PathToUTF8String(filename)); - return {}; - } - - telemetry_id = GenerateTelemetryId(); - - if (!file.WriteObject(telemetry_id)) { - LOG_ERROR(Core, "Failed to write telemetry_id to file."); - } - } - - return telemetry_id; -} - -u64 RegenerateTelemetryId() { - const u64 new_telemetry_id{GenerateTelemetryId()}; - const auto filename = Common::FS::GetUzuyPath(Common::FS::UzuyPath::ConfigDir) / "telemetry_id"; - - Common::FS::IOFile file{filename, Common::FS::FileAccessMode::Write, - Common::FS::FileType::BinaryFile}; - - if (!file.IsOpen()) { - LOG_ERROR(Core, "failed to open telemetry_id: {}", Common::FS::PathToUTF8String(filename)); - return {}; - } - - if (!file.WriteObject(new_telemetry_id)) { - LOG_ERROR(Core, "Failed to write telemetry_id to file."); - } - - return new_telemetry_id; -} - -bool VerifyLogin(const std::string& username, const std::string& token) { -#ifdef ENABLE_WEB_SERVICE - return WebService::VerifyLogin(Settings::values.web_api_url.GetValue(), username, token); -#else - return false; -#endif -} - -TelemetrySession::TelemetrySession() = default; - -TelemetrySession::~TelemetrySession() { - // Log one-time session end information - const s64 shutdown_time{std::chrono::duration_cast( - std::chrono::system_clock::now().time_since_epoch()) - .count()}; - AddField(Telemetry::FieldType::Session, "Shutdown_Time", shutdown_time); - -#ifdef ENABLE_WEB_SERVICE - auto backend = std::make_unique( - Settings::values.web_api_url.GetValue(), Settings::values.uzuy_username.GetValue(), - Settings::values.uzuy_token.GetValue()); -#else - auto backend = std::make_unique(); -#endif - - // Complete the session, submitting to the web service backend if necessary - field_collection.Accept(*backend); - if (Settings::values.enable_telemetry) { - backend->Complete(); - } -} - -void TelemetrySession::AddInitialInfo(Loader::AppLoader& app_loader, - const Service::FileSystem::FileSystemController& fsc, - const FileSys::ContentProvider& content_provider) { - // Log one-time top-level information - AddField(Telemetry::FieldType::None, "TelemetryId", GetTelemetryId()); - - // Log one-time session start information - const s64 init_time{std::chrono::duration_cast( - std::chrono::system_clock::now().time_since_epoch()) - .count()}; - AddField(Telemetry::FieldType::Session, "Init_Time", init_time); - - u64 program_id{}; - const Loader::ResultStatus res{app_loader.ReadProgramId(program_id)}; - if (res == Loader::ResultStatus::Success) { - const std::string formatted_program_id{fmt::format("{:016X}", program_id)}; - AddField(Telemetry::FieldType::Session, "ProgramId", formatted_program_id); - - std::string name; - app_loader.ReadTitle(name); - - if (name.empty()) { - const auto metadata = [&content_provider, &fsc, program_id] { - const FileSys::PatchManager pm{program_id, fsc, content_provider}; - return pm.GetControlMetadata(); - }(); - if (metadata.first != nullptr) { - name = metadata.first->GetApplicationName(); - } - } - - if (!name.empty()) { - AddField(Telemetry::FieldType::Session, "ProgramName", name); - } - } - - AddField(Telemetry::FieldType::Session, "ProgramFormat", - static_cast(app_loader.GetFileType())); - - // Log application information - Telemetry::AppendBuildInfo(field_collection); - - // Log user system information - Telemetry::AppendCPUInfo(field_collection); - Telemetry::AppendOSInfo(field_collection); - - // Log user configuration information - constexpr auto field_type = Telemetry::FieldType::UserConfig; - AddField(field_type, "Audio_SinkId", - Settings::CanonicalizeEnum(Settings::values.sink_id.GetValue())); - AddField(field_type, "Core_UseMultiCore", Settings::values.use_multi_core.GetValue()); - AddField(field_type, "Renderer_Backend", - TranslateRenderer(Settings::values.renderer_backend.GetValue())); - AddField(field_type, "Renderer_UseSpeedLimit", Settings::values.use_speed_limit.GetValue()); - AddField(field_type, "Renderer_SpeedLimit", Settings::values.speed_limit.GetValue()); - AddField(field_type, "Renderer_UseDiskShaderCache", - Settings::values.use_disk_shader_cache.GetValue()); - AddField(field_type, "Renderer_GPUAccuracyLevel", - TranslateGPUAccuracyLevel(Settings::values.gpu_accuracy.GetValue())); - AddField(field_type, "Renderer_UseAsynchronousGpuEmulation", - Settings::values.use_asynchronous_gpu_emulation.GetValue()); - AddField(field_type, "Renderer_NvdecEmulation", - TranslateNvdecEmulation(Settings::values.nvdec_emulation.GetValue())); - AddField(field_type, "Renderer_AccelerateASTC", - TranslateASTCDecodeMode(Settings::values.accelerate_astc.GetValue())); - AddField(field_type, "Renderer_UseVsync", - TranslateVSyncMode(Settings::values.vsync_mode.GetValue())); - AddField(field_type, "Renderer_ShaderBackend", - static_cast(Settings::values.shader_backend.GetValue())); - AddField(field_type, "Renderer_UseAsynchronousShaders", - Settings::values.use_asynchronous_shaders.GetValue()); - AddField(field_type, "System_UseDockedMode", Settings::IsDockedMode()); -} - -bool TelemetrySession::SubmitTestcase() { -#ifdef ENABLE_WEB_SERVICE - auto backend = std::make_unique( - Settings::values.web_api_url.GetValue(), Settings::values.uzuy_username.GetValue(), - Settings::values.uzuy_token.GetValue()); - field_collection.Accept(*backend); - return backend->SubmitTestcase(); -#else - return false; -#endif -} - -} // namespace Core diff --git a/src/core/telemetry_session.h b/src/core/telemetry_session.h deleted file mode 100644 index 3d77527d2..000000000 --- a/src/core/telemetry_session.h +++ /dev/null @@ -1,101 +0,0 @@ -// SPDX-FileCopyrightText: 2017 Citra Emulator Project -// SPDX-License-Identifier: GPL-2.0-or-later - -#pragma once - -#include -#include "common/telemetry.h" - -namespace FileSys { -class ContentProvider; -} - -namespace Loader { -class AppLoader; -} - -namespace Service::FileSystem { -class FileSystemController; -} - -namespace Core { - -/** - * Instruments telemetry for this emulation session. Creates a new set of telemetry fields on each - * session, logging any one-time fields. Interfaces with the telemetry backend used for submitting - * data to the web service. Submits session data on close. - */ -class TelemetrySession { -public: - explicit TelemetrySession(); - ~TelemetrySession(); - - TelemetrySession(const TelemetrySession&) = delete; - TelemetrySession& operator=(const TelemetrySession&) = delete; - - TelemetrySession(TelemetrySession&&) = delete; - TelemetrySession& operator=(TelemetrySession&&) = delete; - - /** - * Adds the initial telemetry info necessary when starting up a title. - * - * This includes information such as: - * - Telemetry ID - * - Initialization time - * - Title ID - * - Title name - * - Title file format - * - Miscellaneous settings values. - * - * @param app_loader The application loader to use to retrieve - * title-specific information. - * @param fsc Filesystem controller to use to retrieve info. - * @param content_provider Content provider to use to retrieve info. - */ - void AddInitialInfo(Loader::AppLoader& app_loader, - const Service::FileSystem::FileSystemController& fsc, - const FileSys::ContentProvider& content_provider); - - /** - * Wrapper around the Telemetry::FieldCollection::AddField method. - * @param type Type of the field to add. - * @param name Name of the field to add. - * @param value Value for the field to add. - */ - template - void AddField(Common::Telemetry::FieldType type, const char* name, T value) { - field_collection.AddField(type, name, std::move(value)); - } - - /** - * Submits a Testcase. - * @returns A bool indicating whether the submission succeeded - */ - bool SubmitTestcase(); - -private: - /// Tracks all added fields for the session - Common::Telemetry::FieldCollection field_collection; -}; - -/** - * 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(); - -/** - * Verifies the username and token. - * @param username uzuy username to use for authentication. - * @param token uzuy token to use for authentication. - * @returns Future with bool indicating whether the verification succeeded - */ -bool VerifyLogin(const std::string& username, const std::string& token); - -} // namespace Core