mirror of
https://notabug.org/litucks/torzu.git
synced 2024-11-30 05:41:14 +00:00
Removed telemetry and anonymized SCM (git) strings
This commit is contained in:
parent
d0ef57274a
commit
3857ff1aa8
@ -136,8 +136,6 @@ add_library(common STATIC
|
|||||||
string_util.cpp
|
string_util.cpp
|
||||||
string_util.h
|
string_util.h
|
||||||
swap.h
|
swap.h
|
||||||
telemetry.cpp
|
|
||||||
telemetry.h
|
|
||||||
thread.cpp
|
thread.cpp
|
||||||
thread.h
|
thread.h
|
||||||
thread_queue_list.h
|
thread_queue_list.h
|
||||||
|
@ -3,6 +3,10 @@
|
|||||||
|
|
||||||
#include "common/scm_rev.h"
|
#include "common/scm_rev.h"
|
||||||
|
|
||||||
|
#include <fstream>
|
||||||
|
#include <string>
|
||||||
|
#include <fmt/format.h>
|
||||||
|
|
||||||
#define GIT_REV "@GIT_REV@"
|
#define GIT_REV "@GIT_REV@"
|
||||||
#define GIT_BRANCH "@GIT_BRANCH@"
|
#define GIT_BRANCH "@GIT_BRANCH@"
|
||||||
#define GIT_DESC "@GIT_DESC@"
|
#define GIT_DESC "@GIT_DESC@"
|
||||||
@ -16,9 +20,9 @@
|
|||||||
|
|
||||||
namespace Common {
|
namespace Common {
|
||||||
|
|
||||||
const char g_scm_rev[] = GIT_REV;
|
const char* g_scm_rev;
|
||||||
const char g_scm_branch[] = GIT_BRANCH;
|
const char* g_scm_branch;
|
||||||
const char g_scm_desc[] = GIT_DESC;
|
const char* g_scm_desc;
|
||||||
const char g_build_name[] = BUILD_NAME;
|
const char g_build_name[] = BUILD_NAME;
|
||||||
const char g_build_date[] = BUILD_DATE;
|
const char g_build_date[] = BUILD_DATE;
|
||||||
const char g_build_fullname[] = BUILD_FULLNAME;
|
const char g_build_fullname[] = BUILD_FULLNAME;
|
||||||
@ -27,5 +31,49 @@ const char g_build_id[] = BUILD_ID;
|
|||||||
const char g_title_bar_format_idle[] = TITLE_BAR_FORMAT_IDLE;
|
const char g_title_bar_format_idle[] = TITLE_BAR_FORMAT_IDLE;
|
||||||
const char g_title_bar_format_running[] = TITLE_BAR_FORMAT_RUNNING;
|
const char g_title_bar_format_running[] = TITLE_BAR_FORMAT_RUNNING;
|
||||||
|
|
||||||
} // namespace
|
/// Anonymizes SCM data
|
||||||
|
/// This is quite weak. But better than nothing.
|
||||||
|
class scm_encrypt {
|
||||||
|
std::string m_scm_rev, m_scm_branch, m_scm_desc;
|
||||||
|
|
||||||
|
public:
|
||||||
|
scm_encrypt() {
|
||||||
|
// Get a key that is easy to obtain when asking the person directly but (usually) hard to
|
||||||
|
// guess
|
||||||
|
std::string key;
|
||||||
|
#ifdef __linux__
|
||||||
|
if (!std::getline(std::ifstream("/proc/sys/kernel/hostname"), key))
|
||||||
|
key = "linux_error_key";
|
||||||
|
#else
|
||||||
|
// Not a good fallback, but better than nothing I guess?
|
||||||
|
key = g_build_date;
|
||||||
|
#endif
|
||||||
|
// Copy strings in place
|
||||||
|
m_scm_rev = GIT_REV;
|
||||||
|
m_scm_branch = GIT_BRANCH;
|
||||||
|
m_scm_desc = GIT_DESC;
|
||||||
|
// XOR each string with key
|
||||||
|
auto key_it = key.begin();
|
||||||
|
for (auto& string : {&m_scm_rev, &m_scm_branch, &m_scm_desc}) {
|
||||||
|
for (auto& c : *string) {
|
||||||
|
c ^= *key_it;
|
||||||
|
if (++key_it == key.end())
|
||||||
|
key_it = key.begin();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Make each string human-readable
|
||||||
|
for (auto& string : {&m_scm_rev, &m_scm_branch, &m_scm_desc}) {
|
||||||
|
const std::string original = *string;
|
||||||
|
string->clear();
|
||||||
|
for (const auto c : original) {
|
||||||
|
string->append(std::format("{:x}", unsigned(c)));
|
||||||
|
}
|
||||||
|
string->pop_back();
|
||||||
|
}
|
||||||
|
// Set pointers
|
||||||
|
g_scm_rev = m_scm_rev.c_str();
|
||||||
|
g_scm_branch = m_scm_branch.c_str();
|
||||||
|
g_scm_desc = m_scm_desc.c_str();
|
||||||
|
}
|
||||||
|
} scm_encrypt_instance;
|
||||||
|
} // namespace Common
|
||||||
|
@ -5,9 +5,9 @@
|
|||||||
|
|
||||||
namespace Common {
|
namespace Common {
|
||||||
|
|
||||||
extern const char g_scm_rev[];
|
extern const char* g_scm_rev;
|
||||||
extern const char g_scm_branch[];
|
extern const char* g_scm_branch;
|
||||||
extern const char g_scm_desc[];
|
extern const char* g_scm_desc;
|
||||||
extern const char g_build_name[];
|
extern const char g_build_name[];
|
||||||
extern const char g_build_date[];
|
extern const char g_build_date[];
|
||||||
extern const char g_build_fullname[];
|
extern const char g_build_fullname[];
|
||||||
|
@ -609,7 +609,6 @@ struct Values {
|
|||||||
Category::Network};
|
Category::Network};
|
||||||
|
|
||||||
// WebService
|
// WebService
|
||||||
Setting<bool> enable_telemetry{linkage, true, "enable_telemetry", Category::WebService};
|
|
||||||
Setting<std::string> web_api_url{linkage, "https://api.ynet-fun.xyz", "web_api_url",
|
Setting<std::string> web_api_url{linkage, "https://api.ynet-fun.xyz", "web_api_url",
|
||||||
Category::WebService};
|
Category::WebService};
|
||||||
Setting<std::string> yuzu_username{linkage, std::string(), "yuzu_username",
|
Setting<std::string> yuzu_username{linkage, std::string(), "yuzu_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, ///< yuzu 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:
|
|
||||||
YUZU_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:
|
|
||||||
YUZU_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 {
|
|
||||||
YUZU_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
|
precompiled_headers.h
|
||||||
reporter.cpp
|
reporter.cpp
|
||||||
reporter.h
|
reporter.h
|
||||||
telemetry_session.cpp
|
|
||||||
telemetry_session.h
|
|
||||||
tools/freezer.cpp
|
tools/freezer.cpp
|
||||||
tools/freezer.h
|
tools/freezer.h
|
||||||
tools/renderdoc.cpp
|
tools/renderdoc.cpp
|
||||||
|
@ -55,7 +55,6 @@
|
|||||||
#include "core/memory/cheat_engine.h"
|
#include "core/memory/cheat_engine.h"
|
||||||
#include "core/perf_stats.h"
|
#include "core/perf_stats.h"
|
||||||
#include "core/reporter.h"
|
#include "core/reporter.h"
|
||||||
#include "core/telemetry_session.h"
|
|
||||||
#include "core/tools/freezer.h"
|
#include "core/tools/freezer.h"
|
||||||
#include "core/tools/renderdoc.h"
|
#include "core/tools/renderdoc.h"
|
||||||
#include "hid_core/hid_core.h"
|
#include "hid_core/hid_core.h"
|
||||||
@ -272,8 +271,6 @@ struct System::Impl {
|
|||||||
}
|
}
|
||||||
|
|
||||||
SystemResultStatus SetupForApplicationProcess(System& system, Frontend::EmuWindow& emu_window) {
|
SystemResultStatus SetupForApplicationProcess(System& system, Frontend::EmuWindow& emu_window) {
|
||||||
telemetry_session = std::make_unique<Core::TelemetrySession>();
|
|
||||||
|
|
||||||
host1x_core = std::make_unique<Tegra::Host1x::Host1x>(system);
|
host1x_core = std::make_unique<Tegra::Host1x::Host1x>(system);
|
||||||
gpu_core = VideoCore::CreateGPU(emu_window, system);
|
gpu_core = VideoCore::CreateGPU(emu_window, system);
|
||||||
if (!gpu_core) {
|
if (!gpu_core) {
|
||||||
@ -354,8 +351,6 @@ struct System::Impl {
|
|||||||
return init_result;
|
return init_result;
|
||||||
}
|
}
|
||||||
|
|
||||||
telemetry_session->AddInitialInfo(*app_loader, fs_controller, *content_provider);
|
|
||||||
|
|
||||||
// Initialize cheat engine
|
// Initialize cheat engine
|
||||||
if (cheat_engine) {
|
if (cheat_engine) {
|
||||||
cheat_engine->Initialize();
|
cheat_engine->Initialize();
|
||||||
@ -401,21 +396,6 @@ struct System::Impl {
|
|||||||
void ShutdownMainProcess() {
|
void ShutdownMainProcess() {
|
||||||
SetShuttingDown(true);
|
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;
|
is_powered_on = false;
|
||||||
exit_locked = false;
|
exit_locked = false;
|
||||||
exit_requested = false;
|
exit_requested = false;
|
||||||
@ -434,7 +414,6 @@ struct System::Impl {
|
|||||||
service_manager.reset();
|
service_manager.reset();
|
||||||
fs_controller.Reset();
|
fs_controller.Reset();
|
||||||
cheat_engine.reset();
|
cheat_engine.reset();
|
||||||
telemetry_session.reset();
|
|
||||||
core_timing.ClearPendingEvents();
|
core_timing.ClearPendingEvents();
|
||||||
app_loader.reset();
|
app_loader.reset();
|
||||||
audio_core.reset();
|
audio_core.reset();
|
||||||
@ -534,9 +513,6 @@ struct System::Impl {
|
|||||||
/// Services
|
/// Services
|
||||||
std::unique_ptr<Service::Services> services;
|
std::unique_ptr<Service::Services> services;
|
||||||
|
|
||||||
/// Telemetry session for this emulation session
|
|
||||||
std::unique_ptr<Core::TelemetrySession> telemetry_session;
|
|
||||||
|
|
||||||
/// Network instance
|
/// Network instance
|
||||||
Network::NetworkInstance network_instance;
|
Network::NetworkInstance network_instance;
|
||||||
|
|
||||||
@ -663,14 +639,6 @@ PerfStatsResults System::GetAndResetPerfStats() {
|
|||||||
return impl->GetAndResetPerfStats();
|
return impl->GetAndResetPerfStats();
|
||||||
}
|
}
|
||||||
|
|
||||||
TelemetrySession& System::TelemetrySession() {
|
|
||||||
return *impl->telemetry_session;
|
|
||||||
}
|
|
||||||
|
|
||||||
const TelemetrySession& System::TelemetrySession() const {
|
|
||||||
return *impl->telemetry_session;
|
|
||||||
}
|
|
||||||
|
|
||||||
Kernel::PhysicalCore& System::CurrentPhysicalCore() {
|
Kernel::PhysicalCore& System::CurrentPhysicalCore() {
|
||||||
return impl->kernel.CurrentPhysicalCore();
|
return impl->kernel.CurrentPhysicalCore();
|
||||||
}
|
}
|
||||||
|
@ -122,7 +122,6 @@ class GPUDirtyMemoryManager;
|
|||||||
class PerfStats;
|
class PerfStats;
|
||||||
class Reporter;
|
class Reporter;
|
||||||
class SpeedLimiter;
|
class SpeedLimiter;
|
||||||
class TelemetrySession;
|
|
||||||
|
|
||||||
struct PerfStatsResults;
|
struct PerfStatsResults;
|
||||||
|
|
||||||
@ -218,12 +217,6 @@ public:
|
|||||||
*/
|
*/
|
||||||
[[nodiscard]] bool IsPoweredOn() const;
|
[[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
|
/// Prepare the core emulation for a reschedule
|
||||||
void PrepareReschedule(u32 core_index);
|
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{{"yuzu 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::GetYuzuPath(Common::FS::YuzuPath::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::GetYuzuPath(Common::FS::YuzuPath::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.yuzu_username.GetValue(),
|
|
||||||
Settings::values.yuzu_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.yuzu_username.GetValue(),
|
|
||||||
Settings::values.yuzu_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 yuzu username to use for authentication.
|
|
||||||
* @param token yuzu 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
|
|
@ -12,10 +12,8 @@
|
|||||||
#include "common/logging/log.h"
|
#include "common/logging/log.h"
|
||||||
#include "common/microprofile.h"
|
#include "common/microprofile.h"
|
||||||
#include "common/settings.h"
|
#include "common/settings.h"
|
||||||
#include "common/telemetry.h"
|
|
||||||
#include "core/core_timing.h"
|
#include "core/core_timing.h"
|
||||||
#include "core/frontend/emu_window.h"
|
#include "core/frontend/emu_window.h"
|
||||||
#include "core/telemetry_session.h"
|
|
||||||
#include "video_core/capture.h"
|
#include "video_core/capture.h"
|
||||||
#include "video_core/present.h"
|
#include "video_core/present.h"
|
||||||
#include "video_core/renderer_opengl/gl_blit_screen.h"
|
#include "video_core/renderer_opengl/gl_blit_screen.h"
|
||||||
@ -90,13 +88,12 @@ void APIENTRY DebugHandler(GLenum source, GLenum type, GLuint id, GLenum severit
|
|||||||
}
|
}
|
||||||
} // Anonymous namespace
|
} // Anonymous namespace
|
||||||
|
|
||||||
RendererOpenGL::RendererOpenGL(Core::TelemetrySession& telemetry_session_,
|
RendererOpenGL::RendererOpenGL(Core::Frontend::EmuWindow& emu_window_,
|
||||||
Core::Frontend::EmuWindow& emu_window_,
|
|
||||||
Tegra::MaxwellDeviceMemoryManager& device_memory_, Tegra::GPU& gpu_,
|
Tegra::MaxwellDeviceMemoryManager& device_memory_, Tegra::GPU& gpu_,
|
||||||
std::unique_ptr<Core::Frontend::GraphicsContext> context_)
|
std::unique_ptr<Core::Frontend::GraphicsContext> context_)
|
||||||
: RendererBase{emu_window_, std::move(context_)}, telemetry_session{telemetry_session_},
|
: RendererBase{emu_window_, std::move(context_)}, emu_window{emu_window_},
|
||||||
emu_window{emu_window_}, device_memory{device_memory_}, gpu{gpu_}, device{emu_window_},
|
device_memory{device_memory_}, gpu{gpu_}, device{emu_window_}, state_tracker{},
|
||||||
state_tracker{}, program_manager{device},
|
program_manager{device},
|
||||||
rasterizer(emu_window, gpu, device_memory, device, program_manager, state_tracker) {
|
rasterizer(emu_window, gpu, device_memory, device, program_manager, state_tracker) {
|
||||||
if (Settings::values.renderer_debug && GLAD_GL_KHR_debug) {
|
if (Settings::values.renderer_debug && GLAD_GL_KHR_debug) {
|
||||||
glEnable(GL_DEBUG_OUTPUT);
|
glEnable(GL_DEBUG_OUTPUT);
|
||||||
@ -163,11 +160,6 @@ void RendererOpenGL::AddTelemetryFields() {
|
|||||||
LOG_INFO(Render_OpenGL, "GL_VERSION: {}", gl_version);
|
LOG_INFO(Render_OpenGL, "GL_VERSION: {}", gl_version);
|
||||||
LOG_INFO(Render_OpenGL, "GL_VENDOR: {}", gpu_vendor);
|
LOG_INFO(Render_OpenGL, "GL_VENDOR: {}", gpu_vendor);
|
||||||
LOG_INFO(Render_OpenGL, "GL_RENDERER: {}", gpu_model);
|
LOG_INFO(Render_OpenGL, "GL_RENDERER: {}", gpu_model);
|
||||||
|
|
||||||
constexpr auto user_system = Common::Telemetry::FieldType::UserSystem;
|
|
||||||
telemetry_session.AddField(user_system, "GPU_Vendor", std::string(gpu_vendor));
|
|
||||||
telemetry_session.AddField(user_system, "GPU_Model", std::string(gpu_model));
|
|
||||||
telemetry_session.AddField(user_system, "GPU_OpenGL_Version", std::string(gl_version));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void RendererOpenGL::RenderToBuffer(std::span<const Tegra::FramebufferConfig> framebuffers,
|
void RendererOpenGL::RenderToBuffer(std::span<const Tegra::FramebufferConfig> framebuffers,
|
||||||
|
@ -17,7 +17,6 @@
|
|||||||
|
|
||||||
namespace Core {
|
namespace Core {
|
||||||
class System;
|
class System;
|
||||||
class TelemetrySession;
|
|
||||||
} // namespace Core
|
} // namespace Core
|
||||||
|
|
||||||
namespace Core::Frontend {
|
namespace Core::Frontend {
|
||||||
@ -34,8 +33,7 @@ class BlitScreen;
|
|||||||
|
|
||||||
class RendererOpenGL final : public VideoCore::RendererBase {
|
class RendererOpenGL final : public VideoCore::RendererBase {
|
||||||
public:
|
public:
|
||||||
explicit RendererOpenGL(Core::TelemetrySession& telemetry_session_,
|
explicit RendererOpenGL(Core::Frontend::EmuWindow& emu_window_,
|
||||||
Core::Frontend::EmuWindow& emu_window_,
|
|
||||||
Tegra::MaxwellDeviceMemoryManager& device_memory_, Tegra::GPU& gpu_,
|
Tegra::MaxwellDeviceMemoryManager& device_memory_, Tegra::GPU& gpu_,
|
||||||
std::unique_ptr<Core::Frontend::GraphicsContext> context_);
|
std::unique_ptr<Core::Frontend::GraphicsContext> context_);
|
||||||
~RendererOpenGL() override;
|
~RendererOpenGL() override;
|
||||||
@ -60,7 +58,6 @@ private:
|
|||||||
void RenderScreenshot(std::span<const Tegra::FramebufferConfig> framebuffers);
|
void RenderScreenshot(std::span<const Tegra::FramebufferConfig> framebuffers);
|
||||||
void RenderAppletCaptureLayer(std::span<const Tegra::FramebufferConfig> framebuffers);
|
void RenderAppletCaptureLayer(std::span<const Tegra::FramebufferConfig> framebuffers);
|
||||||
|
|
||||||
Core::TelemetrySession& telemetry_session;
|
|
||||||
Core::Frontend::EmuWindow& emu_window;
|
Core::Frontend::EmuWindow& emu_window;
|
||||||
Tegra::MaxwellDeviceMemoryManager& device_memory;
|
Tegra::MaxwellDeviceMemoryManager& device_memory;
|
||||||
Tegra::GPU& gpu;
|
Tegra::GPU& gpu;
|
||||||
|
@ -15,10 +15,8 @@
|
|||||||
#include "common/polyfill_ranges.h"
|
#include "common/polyfill_ranges.h"
|
||||||
#include "common/scope_exit.h"
|
#include "common/scope_exit.h"
|
||||||
#include "common/settings.h"
|
#include "common/settings.h"
|
||||||
#include "common/telemetry.h"
|
|
||||||
#include "core/core_timing.h"
|
#include "core/core_timing.h"
|
||||||
#include "core/frontend/graphics_context.h"
|
#include "core/frontend/graphics_context.h"
|
||||||
#include "core/telemetry_session.h"
|
|
||||||
#include "video_core/capture.h"
|
#include "video_core/capture.h"
|
||||||
#include "video_core/gpu.h"
|
#include "video_core/gpu.h"
|
||||||
#include "video_core/present.h"
|
#include "video_core/present.h"
|
||||||
@ -98,12 +96,11 @@ Device CreateDevice(const vk::Instance& instance, const vk::InstanceDispatch& dl
|
|||||||
return Device(*instance, physical_device, surface, dld);
|
return Device(*instance, physical_device, surface, dld);
|
||||||
}
|
}
|
||||||
|
|
||||||
RendererVulkan::RendererVulkan(Core::TelemetrySession& telemetry_session_,
|
RendererVulkan::RendererVulkan(Core::Frontend::EmuWindow& emu_window,
|
||||||
Core::Frontend::EmuWindow& emu_window,
|
|
||||||
Tegra::MaxwellDeviceMemoryManager& device_memory_, Tegra::GPU& gpu_,
|
Tegra::MaxwellDeviceMemoryManager& device_memory_, Tegra::GPU& gpu_,
|
||||||
std::unique_ptr<Core::Frontend::GraphicsContext> context_) try
|
std::unique_ptr<Core::Frontend::GraphicsContext> context_) try
|
||||||
: RendererBase(emu_window, std::move(context_)), telemetry_session(telemetry_session_),
|
: RendererBase(emu_window, std::move(context_)), device_memory(device_memory_), gpu(gpu_),
|
||||||
device_memory(device_memory_), gpu(gpu_), library(OpenLibrary(context.get())),
|
library(OpenLibrary(context.get())),
|
||||||
instance(CreateInstance(*library, dld, VK_API_VERSION_1_1, render_window.GetWindowInfo().type,
|
instance(CreateInstance(*library, dld, VK_API_VERSION_1_1, render_window.GetWindowInfo().type,
|
||||||
Settings::values.renderer_debug.GetValue())),
|
Settings::values.renderer_debug.GetValue())),
|
||||||
debug_messenger(Settings::values.renderer_debug ? CreateDebugUtilsCallback(instance)
|
debug_messenger(Settings::values.renderer_debug ? CreateDebugUtilsCallback(instance)
|
||||||
@ -183,13 +180,6 @@ void RendererVulkan::Report() const {
|
|||||||
LOG_INFO(Render_Vulkan, "Device: {}", model_name);
|
LOG_INFO(Render_Vulkan, "Device: {}", model_name);
|
||||||
LOG_INFO(Render_Vulkan, "Vulkan: {}", api_version);
|
LOG_INFO(Render_Vulkan, "Vulkan: {}", api_version);
|
||||||
LOG_INFO(Render_Vulkan, "Available VRAM: {:.2f} GiB", available_vram);
|
LOG_INFO(Render_Vulkan, "Available VRAM: {:.2f} GiB", available_vram);
|
||||||
|
|
||||||
static constexpr auto field = Common::Telemetry::FieldType::UserSystem;
|
|
||||||
telemetry_session.AddField(field, "GPU_Vendor", vendor_name);
|
|
||||||
telemetry_session.AddField(field, "GPU_Model", model_name);
|
|
||||||
telemetry_session.AddField(field, "GPU_Vulkan_Driver", driver_name);
|
|
||||||
telemetry_session.AddField(field, "GPU_Vulkan_Version", api_version);
|
|
||||||
telemetry_session.AddField(field, "GPU_Vulkan_Extensions", extensions);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
vk::Buffer RendererVulkan::RenderToBuffer(std::span<const Tegra::FramebufferConfig> framebuffers,
|
vk::Buffer RendererVulkan::RenderToBuffer(std::span<const Tegra::FramebufferConfig> framebuffers,
|
||||||
|
@ -21,10 +21,6 @@
|
|||||||
#include "video_core/vulkan_common/vulkan_memory_allocator.h"
|
#include "video_core/vulkan_common/vulkan_memory_allocator.h"
|
||||||
#include "video_core/vulkan_common/vulkan_wrapper.h"
|
#include "video_core/vulkan_common/vulkan_wrapper.h"
|
||||||
|
|
||||||
namespace Core {
|
|
||||||
class TelemetrySession;
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace Core::Memory {
|
namespace Core::Memory {
|
||||||
class Memory;
|
class Memory;
|
||||||
}
|
}
|
||||||
@ -40,8 +36,7 @@ Device CreateDevice(const vk::Instance& instance, const vk::InstanceDispatch& dl
|
|||||||
|
|
||||||
class RendererVulkan final : public VideoCore::RendererBase {
|
class RendererVulkan final : public VideoCore::RendererBase {
|
||||||
public:
|
public:
|
||||||
explicit RendererVulkan(Core::TelemetrySession& telemtry_session,
|
explicit RendererVulkan(Core::Frontend::EmuWindow& emu_window,
|
||||||
Core::Frontend::EmuWindow& emu_window,
|
|
||||||
Tegra::MaxwellDeviceMemoryManager& device_memory_, Tegra::GPU& gpu_,
|
Tegra::MaxwellDeviceMemoryManager& device_memory_, Tegra::GPU& gpu_,
|
||||||
std::unique_ptr<Core::Frontend::GraphicsContext> context_);
|
std::unique_ptr<Core::Frontend::GraphicsContext> context_);
|
||||||
~RendererVulkan() override;
|
~RendererVulkan() override;
|
||||||
@ -67,7 +62,6 @@ private:
|
|||||||
void RenderScreenshot(std::span<const Tegra::FramebufferConfig> framebuffers);
|
void RenderScreenshot(std::span<const Tegra::FramebufferConfig> framebuffers);
|
||||||
void RenderAppletCaptureLayer(std::span<const Tegra::FramebufferConfig> framebuffers);
|
void RenderAppletCaptureLayer(std::span<const Tegra::FramebufferConfig> framebuffers);
|
||||||
|
|
||||||
Core::TelemetrySession& telemetry_session;
|
|
||||||
Tegra::MaxwellDeviceMemoryManager& device_memory;
|
Tegra::MaxwellDeviceMemoryManager& device_memory;
|
||||||
Tegra::GPU& gpu;
|
Tegra::GPU& gpu;
|
||||||
|
|
||||||
|
@ -19,16 +19,15 @@ namespace {
|
|||||||
std::unique_ptr<VideoCore::RendererBase> CreateRenderer(
|
std::unique_ptr<VideoCore::RendererBase> CreateRenderer(
|
||||||
Core::System& system, Core::Frontend::EmuWindow& emu_window, Tegra::GPU& gpu,
|
Core::System& system, Core::Frontend::EmuWindow& emu_window, Tegra::GPU& gpu,
|
||||||
std::unique_ptr<Core::Frontend::GraphicsContext> context) {
|
std::unique_ptr<Core::Frontend::GraphicsContext> context) {
|
||||||
auto& telemetry_session = system.TelemetrySession();
|
|
||||||
auto& device_memory = system.Host1x().MemoryManager();
|
auto& device_memory = system.Host1x().MemoryManager();
|
||||||
|
|
||||||
switch (Settings::values.renderer_backend.GetValue()) {
|
switch (Settings::values.renderer_backend.GetValue()) {
|
||||||
case Settings::RendererBackend::OpenGL:
|
case Settings::RendererBackend::OpenGL:
|
||||||
return std::make_unique<OpenGL::RendererOpenGL>(telemetry_session, emu_window,
|
return std::make_unique<OpenGL::RendererOpenGL>(emu_window, device_memory, gpu,
|
||||||
device_memory, gpu, std::move(context));
|
std::move(context));
|
||||||
case Settings::RendererBackend::Vulkan:
|
case Settings::RendererBackend::Vulkan:
|
||||||
return std::make_unique<Vulkan::RendererVulkan>(telemetry_session, emu_window,
|
return std::make_unique<Vulkan::RendererVulkan>(emu_window, device_memory, gpu,
|
||||||
device_memory, gpu, std::move(context));
|
std::move(context));
|
||||||
case Settings::RendererBackend::Null:
|
case Settings::RendererBackend::Null:
|
||||||
return std::make_unique<Null::RendererNull>(emu_window, gpu, std::move(context));
|
return std::make_unique<Null::RendererNull>(emu_window, gpu, std::move(context));
|
||||||
default:
|
default:
|
||||||
|
@ -5,8 +5,6 @@ add_library(web_service STATIC
|
|||||||
announce_room_json.cpp
|
announce_room_json.cpp
|
||||||
announce_room_json.h
|
announce_room_json.h
|
||||||
precompiled_headers.h
|
precompiled_headers.h
|
||||||
telemetry_json.cpp
|
|
||||||
telemetry_json.h
|
|
||||||
verify_login.cpp
|
verify_login.cpp
|
||||||
verify_login.h
|
verify_login.h
|
||||||
verify_user_jwt.cpp
|
verify_user_jwt.cpp
|
||||||
|
@ -1,130 +0,0 @@
|
|||||||
// SPDX-FileCopyrightText: 2017 Citra Emulator Project
|
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
|
||||||
|
|
||||||
#include <nlohmann/json.hpp>
|
|
||||||
#include "common/detached_tasks.h"
|
|
||||||
#include "web_service/telemetry_json.h"
|
|
||||||
#include "web_service/web_backend.h"
|
|
||||||
#include "web_service/web_result.h"
|
|
||||||
|
|
||||||
namespace WebService {
|
|
||||||
|
|
||||||
namespace Telemetry = Common::Telemetry;
|
|
||||||
|
|
||||||
struct TelemetryJson::Impl {
|
|
||||||
Impl(std::string host_, std::string username_, std::string token_)
|
|
||||||
: host{std::move(host_)}, username{std::move(username_)}, token{std::move(token_)} {}
|
|
||||||
|
|
||||||
nlohmann::json& TopSection() {
|
|
||||||
return sections[static_cast<u8>(Telemetry::FieldType::None)];
|
|
||||||
}
|
|
||||||
|
|
||||||
const nlohmann::json& TopSection() const {
|
|
||||||
return sections[static_cast<u8>(Telemetry::FieldType::None)];
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class T>
|
|
||||||
void Serialize(Telemetry::FieldType type, const std::string& name, T value) {
|
|
||||||
sections[static_cast<u8>(type)][name] = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SerializeSection(Telemetry::FieldType type, const std::string& name) {
|
|
||||||
TopSection()[name] = sections[static_cast<unsigned>(type)];
|
|
||||||
}
|
|
||||||
|
|
||||||
nlohmann::json output;
|
|
||||||
std::array<nlohmann::json, 7> sections;
|
|
||||||
std::string host;
|
|
||||||
std::string username;
|
|
||||||
std::string token;
|
|
||||||
};
|
|
||||||
|
|
||||||
TelemetryJson::TelemetryJson(std::string host, std::string username, std::string token)
|
|
||||||
: impl{std::make_unique<Impl>(std::move(host), std::move(username), std::move(token))} {}
|
|
||||||
TelemetryJson::~TelemetryJson() = default;
|
|
||||||
|
|
||||||
void TelemetryJson::Visit(const Telemetry::Field<bool>& field) {
|
|
||||||
impl->Serialize(field.GetType(), field.GetName(), field.GetValue());
|
|
||||||
}
|
|
||||||
|
|
||||||
void TelemetryJson::Visit(const Telemetry::Field<double>& field) {
|
|
||||||
impl->Serialize(field.GetType(), field.GetName(), field.GetValue());
|
|
||||||
}
|
|
||||||
|
|
||||||
void TelemetryJson::Visit(const Telemetry::Field<float>& field) {
|
|
||||||
impl->Serialize(field.GetType(), field.GetName(), field.GetValue());
|
|
||||||
}
|
|
||||||
|
|
||||||
void TelemetryJson::Visit(const Telemetry::Field<u8>& field) {
|
|
||||||
impl->Serialize(field.GetType(), field.GetName(), field.GetValue());
|
|
||||||
}
|
|
||||||
|
|
||||||
void TelemetryJson::Visit(const Telemetry::Field<u16>& field) {
|
|
||||||
impl->Serialize(field.GetType(), field.GetName(), field.GetValue());
|
|
||||||
}
|
|
||||||
|
|
||||||
void TelemetryJson::Visit(const Telemetry::Field<u32>& field) {
|
|
||||||
impl->Serialize(field.GetType(), field.GetName(), field.GetValue());
|
|
||||||
}
|
|
||||||
|
|
||||||
void TelemetryJson::Visit(const Telemetry::Field<u64>& field) {
|
|
||||||
impl->Serialize(field.GetType(), field.GetName(), field.GetValue());
|
|
||||||
}
|
|
||||||
|
|
||||||
void TelemetryJson::Visit(const Telemetry::Field<s8>& field) {
|
|
||||||
impl->Serialize(field.GetType(), field.GetName(), field.GetValue());
|
|
||||||
}
|
|
||||||
|
|
||||||
void TelemetryJson::Visit(const Telemetry::Field<s16>& field) {
|
|
||||||
impl->Serialize(field.GetType(), field.GetName(), field.GetValue());
|
|
||||||
}
|
|
||||||
|
|
||||||
void TelemetryJson::Visit(const Telemetry::Field<s32>& field) {
|
|
||||||
impl->Serialize(field.GetType(), field.GetName(), field.GetValue());
|
|
||||||
}
|
|
||||||
|
|
||||||
void TelemetryJson::Visit(const Telemetry::Field<s64>& field) {
|
|
||||||
impl->Serialize(field.GetType(), field.GetName(), field.GetValue());
|
|
||||||
}
|
|
||||||
|
|
||||||
void TelemetryJson::Visit(const Telemetry::Field<std::string>& field) {
|
|
||||||
impl->Serialize(field.GetType(), field.GetName(), field.GetValue());
|
|
||||||
}
|
|
||||||
|
|
||||||
void TelemetryJson::Visit(const Telemetry::Field<const char*>& field) {
|
|
||||||
impl->Serialize(field.GetType(), field.GetName(), std::string(field.GetValue()));
|
|
||||||
}
|
|
||||||
|
|
||||||
void TelemetryJson::Visit(const Telemetry::Field<std::chrono::microseconds>& field) {
|
|
||||||
impl->Serialize(field.GetType(), field.GetName(), field.GetValue().count());
|
|
||||||
}
|
|
||||||
|
|
||||||
void TelemetryJson::Complete() {
|
|
||||||
impl->SerializeSection(Telemetry::FieldType::App, "App");
|
|
||||||
impl->SerializeSection(Telemetry::FieldType::Session, "Session");
|
|
||||||
impl->SerializeSection(Telemetry::FieldType::Performance, "Performance");
|
|
||||||
impl->SerializeSection(Telemetry::FieldType::UserConfig, "UserConfig");
|
|
||||||
impl->SerializeSection(Telemetry::FieldType::UserSystem, "UserSystem");
|
|
||||||
|
|
||||||
auto content = impl->TopSection().dump();
|
|
||||||
// Send the telemetry async but don't handle the errors since they were written to the log
|
|
||||||
Common::DetachedTasks::AddTask([host{impl->host}, content]() {
|
|
||||||
Client{host, "", ""}.PostJson("/telemetry", content, true);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
bool TelemetryJson::SubmitTestcase() {
|
|
||||||
impl->SerializeSection(Telemetry::FieldType::App, "App");
|
|
||||||
impl->SerializeSection(Telemetry::FieldType::Session, "Session");
|
|
||||||
impl->SerializeSection(Telemetry::FieldType::UserFeedback, "UserFeedback");
|
|
||||||
impl->SerializeSection(Telemetry::FieldType::UserSystem, "UserSystem");
|
|
||||||
impl->SerializeSection(Telemetry::FieldType::UserConfig, "UserConfig");
|
|
||||||
|
|
||||||
auto content = impl->TopSection().dump();
|
|
||||||
Client client(impl->host, impl->username, impl->token);
|
|
||||||
auto value = client.PostJson("/gamedb/testcase", content, false);
|
|
||||||
|
|
||||||
return value.result_code == WebResult::Code::Success;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace WebService
|
|
@ -1,44 +0,0 @@
|
|||||||
// SPDX-FileCopyrightText: 2017 Citra Emulator Project
|
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <chrono>
|
|
||||||
#include <string>
|
|
||||||
#include "common/telemetry.h"
|
|
||||||
|
|
||||||
namespace WebService {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Implementation of VisitorInterface that serialized telemetry into JSON, and submits it to the
|
|
||||||
* yuzu web service
|
|
||||||
*/
|
|
||||||
class TelemetryJson : public Common::Telemetry::VisitorInterface {
|
|
||||||
public:
|
|
||||||
TelemetryJson(std::string host, std::string username, std::string token);
|
|
||||||
~TelemetryJson() override;
|
|
||||||
|
|
||||||
void Visit(const Common::Telemetry::Field<bool>& field) override;
|
|
||||||
void Visit(const Common::Telemetry::Field<double>& field) override;
|
|
||||||
void Visit(const Common::Telemetry::Field<float>& field) override;
|
|
||||||
void Visit(const Common::Telemetry::Field<u8>& field) override;
|
|
||||||
void Visit(const Common::Telemetry::Field<u16>& field) override;
|
|
||||||
void Visit(const Common::Telemetry::Field<u32>& field) override;
|
|
||||||
void Visit(const Common::Telemetry::Field<u64>& field) override;
|
|
||||||
void Visit(const Common::Telemetry::Field<s8>& field) override;
|
|
||||||
void Visit(const Common::Telemetry::Field<s16>& field) override;
|
|
||||||
void Visit(const Common::Telemetry::Field<s32>& field) override;
|
|
||||||
void Visit(const Common::Telemetry::Field<s64>& field) override;
|
|
||||||
void Visit(const Common::Telemetry::Field<std::string>& field) override;
|
|
||||||
void Visit(const Common::Telemetry::Field<const char*>& field) override;
|
|
||||||
void Visit(const Common::Telemetry::Field<std::chrono::microseconds>& field) override;
|
|
||||||
|
|
||||||
void Complete() override;
|
|
||||||
bool SubmitTestcase() override;
|
|
||||||
|
|
||||||
private:
|
|
||||||
struct Impl;
|
|
||||||
std::unique_ptr<Impl> impl;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace WebService
|
|
@ -6,14 +6,12 @@
|
|||||||
#include <QPushButton>
|
#include <QPushButton>
|
||||||
#include <QtConcurrent/qtconcurrentrun.h>
|
#include <QtConcurrent/qtconcurrentrun.h>
|
||||||
#include "common/logging/log.h"
|
#include "common/logging/log.h"
|
||||||
#include "common/telemetry.h"
|
|
||||||
#include "core/telemetry_session.h"
|
|
||||||
#include "ui_compatdb.h"
|
#include "ui_compatdb.h"
|
||||||
#include "yuzu/compatdb.h"
|
#include "yuzu/compatdb.h"
|
||||||
|
|
||||||
CompatDB::CompatDB(Core::TelemetrySession& telemetry_session_, QWidget* parent)
|
CompatDB::CompatDB(QWidget* parent)
|
||||||
: QWizard(parent, Qt::WindowTitleHint | Qt::WindowCloseButtonHint | Qt::WindowSystemMenuHint),
|
: QWizard(parent, Qt::WindowTitleHint | Qt::WindowCloseButtonHint | Qt::WindowSystemMenuHint),
|
||||||
ui{std::make_unique<Ui::CompatDB>()}, telemetry_session{telemetry_session_} {
|
ui{std::make_unique<Ui::CompatDB>()} {
|
||||||
ui->setupUi(this);
|
ui->setupUi(this);
|
||||||
|
|
||||||
connect(ui->radioButton_GameBoot_Yes, &QRadioButton::clicked, this, &CompatDB::EnableNext);
|
connect(ui->radioButton_GameBoot_Yes, &QRadioButton::clicked, this, &CompatDB::EnableNext);
|
||||||
@ -114,15 +112,10 @@ void CompatDB::Submit() {
|
|||||||
case CompatDBPage::Final:
|
case CompatDBPage::Final:
|
||||||
back();
|
back();
|
||||||
LOG_INFO(Frontend, "Compatibility Rating: {}", compatibility);
|
LOG_INFO(Frontend, "Compatibility Rating: {}", compatibility);
|
||||||
telemetry_session.AddField(Common::Telemetry::FieldType::UserFeedback, "Compatibility",
|
|
||||||
compatibility);
|
|
||||||
|
|
||||||
button(NextButton)->setEnabled(false);
|
button(NextButton)->setEnabled(false);
|
||||||
button(NextButton)->setText(tr("Submitting"));
|
button(NextButton)->setText(tr("Submitting"));
|
||||||
button(CancelButton)->setVisible(false);
|
button(CancelButton)->setVisible(false);
|
||||||
|
|
||||||
testcase_watcher.setFuture(
|
|
||||||
QtConcurrent::run([this] { return telemetry_session.SubmitTestcase(); }));
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
LOG_ERROR(Frontend, "Unexpected page: {}", currentId());
|
LOG_ERROR(Frontend, "Unexpected page: {}", currentId());
|
||||||
|
@ -6,7 +6,6 @@
|
|||||||
#include <memory>
|
#include <memory>
|
||||||
#include <QFutureWatcher>
|
#include <QFutureWatcher>
|
||||||
#include <QWizard>
|
#include <QWizard>
|
||||||
#include "core/telemetry_session.h"
|
|
||||||
|
|
||||||
namespace Ui {
|
namespace Ui {
|
||||||
class CompatDB;
|
class CompatDB;
|
||||||
@ -25,7 +24,7 @@ class CompatDB : public QWizard {
|
|||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit CompatDB(Core::TelemetrySession& telemetry_session_, QWidget* parent = nullptr);
|
explicit CompatDB(QWidget* parent = nullptr);
|
||||||
~CompatDB();
|
~CompatDB();
|
||||||
int nextId() const override;
|
int nextId() const override;
|
||||||
|
|
||||||
@ -38,6 +37,4 @@ private:
|
|||||||
CompatibilityStatus CalculateCompatibility() const;
|
CompatibilityStatus CalculateCompatibility() const;
|
||||||
void OnTestcaseSubmitted();
|
void OnTestcaseSubmitted();
|
||||||
void EnableNext();
|
void EnableNext();
|
||||||
|
|
||||||
Core::TelemetrySession& telemetry_session;
|
|
||||||
};
|
};
|
||||||
|
@ -5,7 +5,6 @@
|
|||||||
#include <QMessageBox>
|
#include <QMessageBox>
|
||||||
#include <QtConcurrent/QtConcurrentRun>
|
#include <QtConcurrent/QtConcurrentRun>
|
||||||
#include "common/settings.h"
|
#include "common/settings.h"
|
||||||
#include "core/telemetry_session.h"
|
|
||||||
#include "ui_configure_web.h"
|
#include "ui_configure_web.h"
|
||||||
#include "yuzu/configuration/configure_web.h"
|
#include "yuzu/configuration/configure_web.h"
|
||||||
#include "yuzu/uisettings.h"
|
#include "yuzu/uisettings.h"
|
||||||
@ -38,8 +37,6 @@ static std::string TokenFromDisplayToken(const std::string& display_token) {
|
|||||||
ConfigureWeb::ConfigureWeb(QWidget* parent)
|
ConfigureWeb::ConfigureWeb(QWidget* parent)
|
||||||
: QWidget(parent), ui(std::make_unique<Ui::ConfigureWeb>()) {
|
: QWidget(parent), ui(std::make_unique<Ui::ConfigureWeb>()) {
|
||||||
ui->setupUi(this);
|
ui->setupUi(this);
|
||||||
connect(ui->button_regenerate_telemetry_id, &QPushButton::clicked, this,
|
|
||||||
&ConfigureWeb::RefreshTelemetryID);
|
|
||||||
connect(ui->button_verify_login, &QPushButton::clicked, this, &ConfigureWeb::VerifyLogin);
|
connect(ui->button_verify_login, &QPushButton::clicked, this, &ConfigureWeb::VerifyLogin);
|
||||||
connect(&verify_watcher, &QFutureWatcher<bool>::finished, this, &ConfigureWeb::OnLoginVerified);
|
connect(&verify_watcher, &QFutureWatcher<bool>::finished, this, &ConfigureWeb::OnLoginVerified);
|
||||||
|
|
||||||
@ -64,10 +61,6 @@ void ConfigureWeb::changeEvent(QEvent* event) {
|
|||||||
void ConfigureWeb::RetranslateUI() {
|
void ConfigureWeb::RetranslateUI() {
|
||||||
ui->retranslateUi(this);
|
ui->retranslateUi(this);
|
||||||
|
|
||||||
ui->telemetry_learn_more->setText(
|
|
||||||
tr("<a href='https://yuzu-emu.org/help/feature/telemetry/'><span style=\"text-decoration: "
|
|
||||||
"underline; color:#039be5;\">Learn more</span></a>"));
|
|
||||||
|
|
||||||
ui->web_signup_link->setText(
|
ui->web_signup_link->setText(
|
||||||
tr("<a href='https://profile.yuzu-emu.org/'><span style=\"text-decoration: underline; "
|
tr("<a href='https://profile.yuzu-emu.org/'><span style=\"text-decoration: underline; "
|
||||||
"color:#039be5;\">Sign up</span></a>"));
|
"color:#039be5;\">Sign up</span></a>"));
|
||||||
@ -75,15 +68,11 @@ void ConfigureWeb::RetranslateUI() {
|
|||||||
ui->web_token_info_link->setText(
|
ui->web_token_info_link->setText(
|
||||||
tr("<a href='https://yuzu-emu.org/wiki/yuzu-web-service/'><span style=\"text-decoration: "
|
tr("<a href='https://yuzu-emu.org/wiki/yuzu-web-service/'><span style=\"text-decoration: "
|
||||||
"underline; color:#039be5;\">What is my token?</span></a>"));
|
"underline; color:#039be5;\">What is my token?</span></a>"));
|
||||||
|
|
||||||
ui->label_telemetry_id->setText(
|
|
||||||
tr("Telemetry ID: 0x%1").arg(QString::number(Core::GetTelemetryId(), 16).toUpper()));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConfigureWeb::SetConfiguration() {
|
void ConfigureWeb::SetConfiguration() {
|
||||||
ui->web_credentials_disclaimer->setWordWrap(true);
|
ui->web_credentials_disclaimer->setWordWrap(true);
|
||||||
|
|
||||||
ui->telemetry_learn_more->setOpenExternalLinks(true);
|
|
||||||
ui->web_signup_link->setOpenExternalLinks(true);
|
ui->web_signup_link->setOpenExternalLinks(true);
|
||||||
ui->web_token_info_link->setOpenExternalLinks(true);
|
ui->web_token_info_link->setOpenExternalLinks(true);
|
||||||
|
|
||||||
@ -93,7 +82,6 @@ void ConfigureWeb::SetConfiguration() {
|
|||||||
ui->username->setText(QString::fromStdString(Settings::values.yuzu_username.GetValue()));
|
ui->username->setText(QString::fromStdString(Settings::values.yuzu_username.GetValue()));
|
||||||
}
|
}
|
||||||
|
|
||||||
ui->toggle_telemetry->setChecked(Settings::values.enable_telemetry.GetValue());
|
|
||||||
ui->edit_token->setText(QString::fromStdString(GenerateDisplayToken(
|
ui->edit_token->setText(QString::fromStdString(GenerateDisplayToken(
|
||||||
Settings::values.yuzu_username.GetValue(), Settings::values.yuzu_token.GetValue())));
|
Settings::values.yuzu_username.GetValue(), Settings::values.yuzu_token.GetValue())));
|
||||||
|
|
||||||
@ -106,7 +94,6 @@ void ConfigureWeb::SetConfiguration() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void ConfigureWeb::ApplyConfiguration() {
|
void ConfigureWeb::ApplyConfiguration() {
|
||||||
Settings::values.enable_telemetry = ui->toggle_telemetry->isChecked();
|
|
||||||
UISettings::values.enable_discord_presence = ui->toggle_discordrpc->isChecked();
|
UISettings::values.enable_discord_presence = ui->toggle_discordrpc->isChecked();
|
||||||
if (user_verified) {
|
if (user_verified) {
|
||||||
Settings::values.yuzu_username =
|
Settings::values.yuzu_username =
|
||||||
@ -119,12 +106,6 @@ void ConfigureWeb::ApplyConfiguration() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConfigureWeb::RefreshTelemetryID() {
|
|
||||||
const u64 new_telemetry_id{Core::RegenerateTelemetryId()};
|
|
||||||
ui->label_telemetry_id->setText(
|
|
||||||
tr("Telemetry ID: 0x%1").arg(QString::number(new_telemetry_id, 16).toUpper()));
|
|
||||||
}
|
|
||||||
|
|
||||||
void ConfigureWeb::OnLoginChanged() {
|
void ConfigureWeb::OnLoginChanged() {
|
||||||
if (ui->edit_token->text().isEmpty()) {
|
if (ui->edit_token->text().isEmpty()) {
|
||||||
user_verified = true;
|
user_verified = true;
|
||||||
@ -147,11 +128,6 @@ void ConfigureWeb::VerifyLogin() {
|
|||||||
ui->button_verify_login->setText(tr("Verifying..."));
|
ui->button_verify_login->setText(tr("Verifying..."));
|
||||||
ui->label_token_verified->setPixmap(QIcon::fromTheme(QStringLiteral("sync")).pixmap(16));
|
ui->label_token_verified->setPixmap(QIcon::fromTheme(QStringLiteral("sync")).pixmap(16));
|
||||||
ui->label_token_verified->setToolTip(tr("Verifying..."));
|
ui->label_token_verified->setToolTip(tr("Verifying..."));
|
||||||
verify_watcher.setFuture(QtConcurrent::run(
|
|
||||||
[username = UsernameFromDisplayToken(ui->edit_token->text().toStdString()),
|
|
||||||
token = TokenFromDisplayToken(ui->edit_token->text().toStdString())] {
|
|
||||||
return Core::VerifyLogin(username, token);
|
|
||||||
}));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConfigureWeb::OnLoginVerified() {
|
void ConfigureWeb::OnLoginVerified() {
|
||||||
|
@ -25,7 +25,6 @@ private:
|
|||||||
void changeEvent(QEvent* event) override;
|
void changeEvent(QEvent* event) override;
|
||||||
void RetranslateUI();
|
void RetranslateUI();
|
||||||
|
|
||||||
void RefreshTelemetryID();
|
|
||||||
void OnLoginChanged();
|
void OnLoginChanged();
|
||||||
void VerifyLogin();
|
void VerifyLogin();
|
||||||
void OnLoginVerified();
|
void OnLoginVerified();
|
||||||
|
@ -122,56 +122,6 @@
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
|
||||||
<widget class="QGroupBox" name="groupBox">
|
|
||||||
<property name="title">
|
|
||||||
<string>Telemetry</string>
|
|
||||||
</property>
|
|
||||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
|
||||||
<item>
|
|
||||||
<widget class="QCheckBox" name="toggle_telemetry">
|
|
||||||
<property name="text">
|
|
||||||
<string>Share anonymous usage data with the yuzu team</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QLabel" name="telemetry_learn_more">
|
|
||||||
<property name="text">
|
|
||||||
<string>Learn more</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<layout class="QGridLayout" name="gridLayoutTelemetryId">
|
|
||||||
<item row="0" column="0">
|
|
||||||
<widget class="QLabel" name="label_telemetry_id">
|
|
||||||
<property name="text">
|
|
||||||
<string>Telemetry ID:</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="0" column="1">
|
|
||||||
<widget class="QPushButton" name="button_regenerate_telemetry_id">
|
|
||||||
<property name="sizePolicy">
|
|
||||||
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
|
||||||
<horstretch>0</horstretch>
|
|
||||||
<verstretch>0</verstretch>
|
|
||||||
</sizepolicy>
|
|
||||||
</property>
|
|
||||||
<property name="layoutDirection">
|
|
||||||
<enum>Qt::RightToLeft</enum>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string>Regenerate</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
</layout>
|
</layout>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
|
@ -110,7 +110,6 @@ static FileSys::VirtualFile VfsDirectoryCreateFileWrapper(const FileSys::Virtual
|
|||||||
#include "common/x64/cpu_detect.h"
|
#include "common/x64/cpu_detect.h"
|
||||||
#endif
|
#endif
|
||||||
#include "common/settings.h"
|
#include "common/settings.h"
|
||||||
#include "common/telemetry.h"
|
|
||||||
#include "core/core.h"
|
#include "core/core.h"
|
||||||
#include "core/core_timing.h"
|
#include "core/core_timing.h"
|
||||||
#include "core/crypto/key_manager.h"
|
#include "core/crypto/key_manager.h"
|
||||||
@ -129,7 +128,6 @@ static FileSys::VirtualFile VfsDirectoryCreateFileWrapper(const FileSys::Virtual
|
|||||||
#include "core/hle/service/sm/sm.h"
|
#include "core/hle/service/sm/sm.h"
|
||||||
#include "core/loader/loader.h"
|
#include "core/loader/loader.h"
|
||||||
#include "core/perf_stats.h"
|
#include "core/perf_stats.h"
|
||||||
#include "core/telemetry_session.h"
|
|
||||||
#include "frontend_common/config.h"
|
#include "frontend_common/config.h"
|
||||||
#include "input_common/drivers/tas_input.h"
|
#include "input_common/drivers/tas_input.h"
|
||||||
#include "input_common/drivers/virtual_amiibo.h"
|
#include "input_common/drivers/virtual_amiibo.h"
|
||||||
@ -198,28 +196,9 @@ constexpr size_t CopyBufferSize = 1_MiB;
|
|||||||
* user. This is 32-bits - if we have more than 32 callouts, we should retire and recycle old ones.
|
* user. This is 32-bits - if we have more than 32 callouts, we should retire and recycle old ones.
|
||||||
*/
|
*/
|
||||||
enum class CalloutFlag : uint32_t {
|
enum class CalloutFlag : uint32_t {
|
||||||
Telemetry = 0x1,
|
|
||||||
DRDDeprecation = 0x2,
|
DRDDeprecation = 0x2,
|
||||||
};
|
};
|
||||||
|
|
||||||
void GMainWindow::ShowTelemetryCallout() {
|
|
||||||
if (UISettings::values.callout_flags.GetValue() &
|
|
||||||
static_cast<uint32_t>(CalloutFlag::Telemetry)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
UISettings::values.callout_flags =
|
|
||||||
UISettings::values.callout_flags.GetValue() | static_cast<uint32_t>(CalloutFlag::Telemetry);
|
|
||||||
const QString telemetry_message =
|
|
||||||
tr("<a href='https://yuzu-emu.org/help/feature/telemetry/'>Anonymous "
|
|
||||||
"data is collected</a> to help improve yuzu. "
|
|
||||||
"<br/><br/>Would you like to share your usage data with us?");
|
|
||||||
if (!question(this, tr("Telemetry"), telemetry_message)) {
|
|
||||||
Settings::values.enable_telemetry = false;
|
|
||||||
system->ApplySettings();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const int GMainWindow::max_recent_files_item;
|
const int GMainWindow::max_recent_files_item;
|
||||||
|
|
||||||
static void RemoveCachedContents() {
|
static void RemoveCachedContents() {
|
||||||
@ -427,9 +406,6 @@ GMainWindow::GMainWindow(std::unique_ptr<QtConfig> config_, bool has_broken_vulk
|
|||||||
game_list->LoadCompatibilityList();
|
game_list->LoadCompatibilityList();
|
||||||
game_list->PopulateAsync(UISettings::values.game_dirs);
|
game_list->PopulateAsync(UISettings::values.game_dirs);
|
||||||
|
|
||||||
// Show one-time "callout" messages to the user
|
|
||||||
ShowTelemetryCallout();
|
|
||||||
|
|
||||||
// make sure menubar has the arrow cursor instead of inheriting from this
|
// make sure menubar has the arrow cursor instead of inheriting from this
|
||||||
ui->menubar->setCursor(QCursor());
|
ui->menubar->setCursor(QCursor());
|
||||||
statusBar()->setCursor(QCursor());
|
statusBar()->setCursor(QCursor());
|
||||||
@ -1870,7 +1846,6 @@ bool GMainWindow::LoadROM(const QString& filename, Service::AM::FrontendAppletPa
|
|||||||
}
|
}
|
||||||
current_game_path = filename;
|
current_game_path = filename;
|
||||||
|
|
||||||
system->TelemetrySession().AddField(Common::Telemetry::FieldType::App, "Frontend", "Qt");
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3556,8 +3531,6 @@ void GMainWindow::OnMenuReportCompatibility() {
|
|||||||
|
|
||||||
if (!Settings::values.yuzu_token.GetValue().empty() &&
|
if (!Settings::values.yuzu_token.GetValue().empty() &&
|
||||||
!Settings::values.yuzu_username.GetValue().empty()) {
|
!Settings::values.yuzu_username.GetValue().empty()) {
|
||||||
CompatDB compatdb{system->TelemetrySession(), this};
|
|
||||||
compatdb.exec();
|
|
||||||
} else {
|
} else {
|
||||||
QMessageBox::critical(
|
QMessageBox::critical(
|
||||||
this, tr("Missing yuzu Account"),
|
this, tr("Missing yuzu Account"),
|
||||||
@ -3786,8 +3759,6 @@ void GMainWindow::OnConfigure() {
|
|||||||
|
|
||||||
SetDefaultUIGeometry();
|
SetDefaultUIGeometry();
|
||||||
RestoreUIState();
|
RestoreUIState();
|
||||||
|
|
||||||
ShowTelemetryCallout();
|
|
||||||
}
|
}
|
||||||
InitializeHotkeys();
|
InitializeHotkeys();
|
||||||
|
|
||||||
|
@ -274,7 +274,6 @@ private:
|
|||||||
void BootGameFromList(const QString& filename, StartGameType with_config);
|
void BootGameFromList(const QString& filename, StartGameType with_config);
|
||||||
void ShutdownGame();
|
void ShutdownGame();
|
||||||
|
|
||||||
void ShowTelemetryCallout();
|
|
||||||
void SetDiscordEnabled(bool state);
|
void SetDiscordEnabled(bool state);
|
||||||
void LoadAmiibo(const QString& filename);
|
void LoadAmiibo(const QString& filename);
|
||||||
|
|
||||||
|
@ -143,7 +143,7 @@ struct Values {
|
|||||||
Setting<bool> disable_web_applet{linkage, true, "disable_web_applet", Category::Ui};
|
Setting<bool> disable_web_applet{linkage, true, "disable_web_applet", Category::Ui};
|
||||||
|
|
||||||
// Discord RPC
|
// Discord RPC
|
||||||
Setting<bool> enable_discord_presence{linkage, true, "enable_discord_presence", Category::Ui};
|
Setting<bool> enable_discord_presence{linkage, false, "enable_discord_presence", Category::Ui};
|
||||||
|
|
||||||
// logging
|
// logging
|
||||||
Setting<bool> show_console{linkage, false, "showConsole", Category::Ui};
|
Setting<bool> show_console{linkage, false, "showConsole", Category::Ui};
|
||||||
|
@ -19,7 +19,6 @@
|
|||||||
#include "common/scope_exit.h"
|
#include "common/scope_exit.h"
|
||||||
#include "common/settings.h"
|
#include "common/settings.h"
|
||||||
#include "common/string_util.h"
|
#include "common/string_util.h"
|
||||||
#include "common/telemetry.h"
|
|
||||||
#include "core/core.h"
|
#include "core/core.h"
|
||||||
#include "core/core_timing.h"
|
#include "core/core_timing.h"
|
||||||
#include "core/cpu_manager.h"
|
#include "core/cpu_manager.h"
|
||||||
@ -29,7 +28,6 @@
|
|||||||
#include "core/hle/service/am/applet_manager.h"
|
#include "core/hle/service/am/applet_manager.h"
|
||||||
#include "core/hle/service/filesystem/filesystem.h"
|
#include "core/hle/service/filesystem/filesystem.h"
|
||||||
#include "core/loader/loader.h"
|
#include "core/loader/loader.h"
|
||||||
#include "core/telemetry_session.h"
|
|
||||||
#include "frontend_common/config.h"
|
#include "frontend_common/config.h"
|
||||||
#include "input_common/main.h"
|
#include "input_common/main.h"
|
||||||
#include "network/network.h"
|
#include "network/network.h"
|
||||||
@ -403,8 +401,6 @@ int main(int argc, char** argv) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
system.TelemetrySession().AddField(Common::Telemetry::FieldType::App, "Frontend", "SDL");
|
|
||||||
|
|
||||||
if (use_multiplayer) {
|
if (use_multiplayer) {
|
||||||
if (auto member = system.GetRoomNetwork().GetRoomMember().lock()) {
|
if (auto member = system.GetRoomNetwork().GetRoomMember().lock()) {
|
||||||
member->BindOnChatMessageReceived(OnMessageReceived);
|
member->BindOnChatMessageReceived(OnMessageReceived);
|
||||||
|
3
tools/clang-format.sh
Executable file
3
tools/clang-format.sh
Executable file
@ -0,0 +1,3 @@
|
|||||||
|
#! /bin/sh
|
||||||
|
|
||||||
|
exec find src -iname *.h -o -iname *.cpp | xargs clang-format-15 -i -style=file:src/.clang-format
|
Loading…
Reference in New Issue
Block a user