mirror of
https://github.com/TwilitRealm/dusklight
synced 2026-05-24 15:00:55 -04:00
977ad16806
* Basic PAL ISO & language support Probably still needs much more work * Add language selector to pre-launch * Store DVDDiskID in a global Can use this later for things * More version system API improvements * d_name mostly region switching fully JPN doesn't work yet cuz it'll be a nightmare, probably. * More version switching support * Mark GCN PAL as supported ROM * Fix remaining REL assets to have PAL offsets * d_a_mg_fish PAL * d_a_mg_fshop PAL * isRegionUsa helper * d_menu_fishing PAL * d_msg_class PAL * m_Do_MemCardRWmng PAL * Update CARDInit call & remove DUSK_TP_VERSION * Fix Ganon cape Missed this one. * Remove tp_version from Sentry --------- Co-authored-by: Luke Street <luke@street.dev>
188 lines
4.7 KiB
C++
188 lines
4.7 KiB
C++
#include "dusk/crash_reporting.h"
|
|
|
|
#include "dusk/app_info.hpp"
|
|
#include "dusk/dusk.h"
|
|
#include "dusk/logging.h"
|
|
#include "dusk/main.h"
|
|
#include "dusk/settings.h"
|
|
#include "version.h"
|
|
|
|
#include <cstdlib>
|
|
#include <filesystem>
|
|
#include <string>
|
|
#include <string_view>
|
|
#include <system_error>
|
|
|
|
#include "SDL3/SDL_filesystem.h"
|
|
|
|
#if DUSK_ENABLE_SENTRY_NATIVE
|
|
#include <sentry.h>
|
|
#endif
|
|
|
|
namespace dusk {
|
|
|
|
namespace {
|
|
|
|
#if DUSK_ENABLE_SENTRY_NATIVE
|
|
bool g_sentryInitialized = false;
|
|
|
|
bool IsTruthy(std::string_view value) {
|
|
return value == "1" || value == "true" || value == "TRUE" || value == "yes"
|
|
|| value == "YES" || value == "on" || value == "ON";
|
|
}
|
|
|
|
std::string GetEnvOrEmpty(const char* name) {
|
|
if (const char* value = std::getenv(name)) {
|
|
return value;
|
|
}
|
|
return {};
|
|
}
|
|
|
|
bool GetEffectiveEnabled() {
|
|
const std::string env = GetEnvOrEmpty("DUSK_SENTRY_ENABLED");
|
|
if (!env.empty()) {
|
|
return IsTruthy(env);
|
|
}
|
|
return getSettings().backend.enableCrashReporting;
|
|
}
|
|
|
|
std::string GetEffectiveDsn() {
|
|
const std::string env = GetEnvOrEmpty("DUSK_SENTRY_DSN");
|
|
if (!env.empty()) {
|
|
return env;
|
|
}
|
|
return DUSK_SENTRY_DSN;
|
|
}
|
|
|
|
bool GetEffectiveDebug() {
|
|
const std::string env = GetEnvOrEmpty("DUSK_SENTRY_DEBUG");
|
|
if (!env.empty()) {
|
|
return IsTruthy(env);
|
|
}
|
|
return false;
|
|
}
|
|
|
|
std::string GetReleaseName() {
|
|
return std::string(AppName) + "@" DUSK_WC_DESCRIBE;
|
|
}
|
|
|
|
std::filesystem::path GetSentryDatabasePath() {
|
|
return dusk::ConfigPath / "sentry";
|
|
}
|
|
|
|
std::filesystem::path GetLogAttachmentPath() {
|
|
if (const char* logPath = GetLogFilePath()) {
|
|
return logPath;
|
|
}
|
|
return {};
|
|
}
|
|
|
|
std::filesystem::path GetCrashpadHandlerPath() {
|
|
const char* basePath = SDL_GetBasePath();
|
|
if (!basePath) {
|
|
return {};
|
|
}
|
|
|
|
const std::filesystem::path handlerDir(basePath);
|
|
#if _WIN32
|
|
return handlerDir / "crashpad_handler.exe";
|
|
#else
|
|
return handlerDir / "crashpad_handler";
|
|
#endif
|
|
}
|
|
|
|
void ConfigurePathOptions(sentry_options_t* options) {
|
|
const auto databasePath = GetSentryDatabasePath();
|
|
std::error_code ec;
|
|
std::filesystem::create_directories(databasePath, ec);
|
|
if (ec) {
|
|
DuskLog.warn("Unable to create Sentry database path '{}': {}",
|
|
databasePath.string(), ec.message());
|
|
}
|
|
|
|
#if _WIN32
|
|
const std::wstring databasePathWide = databasePath.wstring();
|
|
sentry_options_set_database_pathw(options, databasePathWide.c_str());
|
|
|
|
const auto handlerPath = GetCrashpadHandlerPath();
|
|
if (!handlerPath.empty()) {
|
|
const std::wstring handlerPathWide = handlerPath.wstring();
|
|
sentry_options_set_handler_pathw(options, handlerPathWide.c_str());
|
|
}
|
|
#else
|
|
const std::string databasePathUtf8 = databasePath.string();
|
|
sentry_options_set_database_path(options, databasePathUtf8.c_str());
|
|
|
|
const auto handlerPath = GetCrashpadHandlerPath();
|
|
if (!handlerPath.empty()) {
|
|
const std::string handlerPathUtf8 = handlerPath.string();
|
|
sentry_options_set_handler_path(options, handlerPathUtf8.c_str());
|
|
}
|
|
#endif
|
|
|
|
const auto logPath = GetLogAttachmentPath();
|
|
if (!logPath.empty()) {
|
|
#if _WIN32
|
|
sentry_options_add_attachmentw(options, logPath.wstring().c_str());
|
|
#else
|
|
sentry_options_add_attachment(options, logPath.string().c_str());
|
|
#endif
|
|
}
|
|
}
|
|
#endif
|
|
|
|
} // namespace
|
|
|
|
void InitializeCrashReporting() {
|
|
#if DUSK_ENABLE_SENTRY_NATIVE
|
|
if (g_sentryInitialized) {
|
|
return;
|
|
}
|
|
|
|
if (!GetEffectiveEnabled()) {
|
|
return;
|
|
}
|
|
|
|
const std::string dsn = GetEffectiveDsn();
|
|
if (dsn.empty()) {
|
|
DuskLog.warn("Crash reporting is enabled but no Sentry DSN is configured");
|
|
return;
|
|
}
|
|
|
|
const std::string release = GetReleaseName();
|
|
|
|
sentry_options_t* options = sentry_options_new();
|
|
sentry_options_set_dsn(options, dsn.c_str());
|
|
sentry_options_set_release(options, release.c_str());
|
|
sentry_options_set_environment(options, DUSK_SENTRY_ENVIRONMENT);
|
|
sentry_options_set_debug(options, GetEffectiveDebug() ? 1 : 0);
|
|
sentry_options_set_cache_keep(options, 1);
|
|
sentry_options_set_max_breadcrumbs(options, 100);
|
|
ConfigurePathOptions(options);
|
|
|
|
if (sentry_init(options) != 0) {
|
|
DuskLog.warn("Failed to initialize Sentry crash reporting");
|
|
return;
|
|
}
|
|
|
|
sentry_set_tag("git_branch", DUSK_WC_BRANCH);
|
|
sentry_set_tag("build_type", DUSK_BUILD_TYPE);
|
|
g_sentryInitialized = true;
|
|
|
|
DuskLog.info("Initialized Sentry crash reporting");
|
|
#endif
|
|
}
|
|
|
|
void ShutdownCrashReporting() {
|
|
#if DUSK_ENABLE_SENTRY_NATIVE
|
|
if (!g_sentryInitialized) {
|
|
return;
|
|
}
|
|
|
|
sentry_close();
|
|
g_sentryInitialized = false;
|
|
#endif
|
|
}
|
|
|
|
} // namespace dusk
|