| | |
| | |
| |
|
| | #include <chrono> |
| | #include <string> |
| |
|
| | #include <QEventLoop> |
| | #include <QNetworkAccessManager> |
| | #include <QNetworkReply> |
| |
|
| | #include <discord_rpc.h> |
| | #include <fmt/format.h> |
| |
|
| | #include "common/common_types.h" |
| | #include "common/string_util.h" |
| | #include "core/core.h" |
| | #include "core/loader/loader.h" |
| | #include "yuzu/discord_impl.h" |
| | #include "yuzu/uisettings.h" |
| |
|
| | namespace DiscordRPC { |
| |
|
| | DiscordImpl::DiscordImpl(Core::System& system_) : system{system_} { |
| | DiscordEventHandlers handlers{}; |
| | |
| | |
| | Discord_Initialize("712465656758665259", &handlers, 1, nullptr); |
| | } |
| |
|
| | DiscordImpl::~DiscordImpl() { |
| | Discord_ClearPresence(); |
| | Discord_Shutdown(); |
| | } |
| |
|
| | void DiscordImpl::Pause() { |
| | Discord_ClearPresence(); |
| | } |
| |
|
| | std::string DiscordImpl::GetGameString(const std::string& title) { |
| | |
| | std::string icon_name = Common::ToLower(title); |
| |
|
| | |
| | std::replace(icon_name.begin(), icon_name.end(), ' ', '-'); |
| |
|
| | |
| | std::erase_if(icon_name, [](char c) { return !std::isalnum(c) && c != '-'; }); |
| |
|
| | |
| | icon_name.erase(icon_name.begin(), std::find_if(icon_name.begin(), icon_name.end(), |
| | [](int ch) { return ch != '-'; })); |
| | icon_name.erase( |
| | std::find_if(icon_name.rbegin(), icon_name.rend(), [](int ch) { return ch != '-'; }).base(), |
| | icon_name.end()); |
| |
|
| | |
| | icon_name.erase(std::unique(icon_name.begin(), icon_name.end(), |
| | [](char a, char b) { return a == '-' && b == '-'; }), |
| | icon_name.end()); |
| |
|
| | return icon_name; |
| | } |
| |
|
| | void DiscordImpl::UpdateGameStatus(bool use_default) { |
| | const std::string default_text = "yuzu is an emulator for the Nintendo Switch"; |
| | const std::string default_image = "yuzu_logo"; |
| | const std::string url = use_default ? default_image : game_url; |
| | s64 start_time = std::chrono::duration_cast<std::chrono::seconds>( |
| | std::chrono::system_clock::now().time_since_epoch()) |
| | .count(); |
| | DiscordRichPresence presence{}; |
| |
|
| | presence.largeImageKey = url.c_str(); |
| | presence.largeImageText = game_title.c_str(); |
| | presence.smallImageKey = default_image.c_str(); |
| | presence.smallImageText = default_text.c_str(); |
| | presence.state = game_title.c_str(); |
| | presence.details = "Currently in game"; |
| | presence.startTimestamp = start_time; |
| | Discord_UpdatePresence(&presence); |
| | } |
| |
|
| | void DiscordImpl::Update() { |
| | const std::string default_text = "yuzu is an emulator for the Nintendo Switch"; |
| | const std::string default_image = "yuzu_logo"; |
| |
|
| | if (system.IsPoweredOn()) { |
| | system.GetAppLoader().ReadTitle(game_title); |
| |
|
| | |
| | std::string icon_name = GetGameString(game_title); |
| | game_url = fmt::format("https://yuzu-emu.org/images/game/boxart/{}.png", icon_name); |
| |
|
| | QNetworkAccessManager manager; |
| | QNetworkRequest request; |
| | request.setUrl(QUrl(QString::fromStdString(game_url))); |
| | request.setTransferTimeout(3000); |
| | QNetworkReply* reply = manager.head(request); |
| | QEventLoop request_event_loop; |
| | QObject::connect(reply, &QNetworkReply::finished, &request_event_loop, &QEventLoop::quit); |
| | request_event_loop.exec(); |
| | UpdateGameStatus(reply->error()); |
| | return; |
| | } |
| |
|
| | s64 start_time = std::chrono::duration_cast<std::chrono::seconds>( |
| | std::chrono::system_clock::now().time_since_epoch()) |
| | .count(); |
| |
|
| | DiscordRichPresence presence{}; |
| | presence.largeImageKey = default_image.c_str(); |
| | presence.largeImageText = default_text.c_str(); |
| | presence.details = "Currently not in game"; |
| | presence.startTimestamp = start_time; |
| | Discord_UpdatePresence(&presence); |
| | } |
| | } |
| |
|