mirror of
https://git.uzuy-edge.org/Uzuy-X/Uzuy.git
synced 2024-11-27 07:50:24 +00:00
chore: remove telemetry and anonymize SCM (git) strings
This commit is contained in:
parent
984ad8d6d8
commit
b44f4cff93
@ -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
|
||||
|
@ -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 <fstream>
|
||||
#include <string>
|
||||
#include <fmt/format.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@"
|
||||
#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 <fstream>
|
||||
#include <string>
|
||||
#include <fmt/format.h>
|
||||
|
||||
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<unsigned char>(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
|
||||
|
@ -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[];
|
||||
|
@ -609,7 +609,8 @@ struct Values {
|
||||
Category::Network};
|
||||
|
||||
// WebService
|
||||
Setting<bool> enable_telemetry{linkage, false, "enable_telemetry", Category::WebService};
|
||||
|
||||
// Removed Telemtry API
|
||||
Setting<std::string> web_api_url{linkage, "http://localhost", "web_api_url",
|
||||
Category::WebService};
|
||||
Setting<std::string> uzuy_username{linkage, std::string(), "uzuy_username",
|
||||
|
@ -1,119 +0,0 @@
|
||||
// SPDX-FileCopyrightText: 2017 Citra Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#include <algorithm>
|
||||
#include <cstring>
|
||||
#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<FieldInterface> field) {
|
||||
fields[field->GetName()] = std::move(field);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
void Field<T>::Accept(VisitorInterface& visitor) const {
|
||||
visitor.Visit(*this);
|
||||
}
|
||||
|
||||
template class Field<bool>;
|
||||
template class Field<double>;
|
||||
template class Field<float>;
|
||||
template class Field<u8>;
|
||||
template class Field<u16>;
|
||||
template class Field<u32>;
|
||||
template class Field<u64>;
|
||||
template class Field<s8>;
|
||||
template class Field<s16>;
|
||||
template class Field<s32>;
|
||||
template class Field<s64>;
|
||||
template class Field<std::string>;
|
||||
template class Field<const char*>;
|
||||
template class Field<std::chrono::microseconds>;
|
||||
|
||||
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
|
@ -1,209 +0,0 @@
|
||||
// SPDX-FileCopyrightText: 2017 Citra Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <chrono>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#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 <typename T>
|
||||
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 <typename T>
|
||||
void AddField(FieldType type, std::string_view name, T value) {
|
||||
return AddField(std::make_unique<Field<T>>(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<FieldInterface> field);
|
||||
|
||||
private:
|
||||
std::map<std::string, std::unique_ptr<FieldInterface>> 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<bool>& field) = 0;
|
||||
virtual void Visit(const Field<double>& field) = 0;
|
||||
virtual void Visit(const Field<float>& field) = 0;
|
||||
virtual void Visit(const Field<u8>& field) = 0;
|
||||
virtual void Visit(const Field<u16>& field) = 0;
|
||||
virtual void Visit(const Field<u32>& field) = 0;
|
||||
virtual void Visit(const Field<u64>& field) = 0;
|
||||
virtual void Visit(const Field<s8>& field) = 0;
|
||||
virtual void Visit(const Field<s16>& field) = 0;
|
||||
virtual void Visit(const Field<s32>& field) = 0;
|
||||
virtual void Visit(const Field<s64>& field) = 0;
|
||||
virtual void Visit(const Field<std::string>& field) = 0;
|
||||
virtual void Visit(const Field<const char*>& field) = 0;
|
||||
virtual void Visit(const Field<std::chrono::microseconds>& 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<bool>& /*field*/) override {}
|
||||
void Visit(const Field<double>& /*field*/) override {}
|
||||
void Visit(const Field<float>& /*field*/) override {}
|
||||
void Visit(const Field<u8>& /*field*/) override {}
|
||||
void Visit(const Field<u16>& /*field*/) override {}
|
||||
void Visit(const Field<u32>& /*field*/) override {}
|
||||
void Visit(const Field<u64>& /*field*/) override {}
|
||||
void Visit(const Field<s8>& /*field*/) override {}
|
||||
void Visit(const Field<s16>& /*field*/) override {}
|
||||
void Visit(const Field<s32>& /*field*/) override {}
|
||||
void Visit(const Field<s64>& /*field*/) override {}
|
||||
void Visit(const Field<std::string>& /*field*/) override {}
|
||||
void Visit(const Field<const char*>& /*field*/) override {}
|
||||
void Visit(const Field<std::chrono::microseconds>& /*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
|
@ -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
|
||||
|
@ -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<Core::TelemetrySession>();
|
||||
|
||||
host1x_core = std::make_unique<Tegra::Host1x::Host1x>(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<Service::Services> services;
|
||||
|
||||
/// Telemetry session for this emulation session
|
||||
std::unique_ptr<Core::TelemetrySession> 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();
|
||||
}
|
||||
|
@ -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);
|
||||
|
||||
|
@ -1,294 +0,0 @@
|
||||
// SPDX-FileCopyrightText: 2017 Citra Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#include <array>
|
||||
|
||||
#include <mbedtls/ctr_drbg.h>
|
||||
#include <mbedtls/entropy.h>
|
||||
|
||||
#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<char, 18> personalization{{"uzuy Telemetry ID"}};
|
||||
|
||||
mbedtls_ctr_drbg_init(&ctr_drbg);
|
||||
ASSERT(mbedtls_ctr_drbg_seed(&ctr_drbg, mbedtls_entropy_func, &entropy,
|
||||
reinterpret_cast<const unsigned char*>(personalization.data()),
|
||||
personalization.size()) == 0);
|
||||
ASSERT(mbedtls_ctr_drbg_random(&ctr_drbg, reinterpret_cast<unsigned char*>(&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::milliseconds>(
|
||||
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<WebService::TelemetryJson>(
|
||||
Settings::values.web_api_url.GetValue(), Settings::values.uzuy_username.GetValue(),
|
||||
Settings::values.uzuy_token.GetValue());
|
||||
#else
|
||||
auto backend = std::make_unique<Telemetry::NullVisitor>();
|
||||
#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::milliseconds>(
|
||||
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<u8>(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<u32>(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<WebService::TelemetryJson>(
|
||||
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
|
@ -1,101 +0,0 @@
|
||||
// SPDX-FileCopyrightText: 2017 Citra Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#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 <typename T>
|
||||
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
|
Loading…
Reference in New Issue
Block a user