Merge pull request #10940 from InvoxiPlayGames/ipc-discord
Add Discord presence ioctlv to /dev/dolphin
This commit is contained in:
commit
4c2d707538
|
@ -131,6 +131,21 @@ void Host_UpdateTitle(const std::string& title)
|
||||||
__android_log_write(ANDROID_LOG_INFO, DOLPHIN_TAG, title.c_str());
|
__android_log_write(ANDROID_LOG_INFO, DOLPHIN_TAG, title.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Host_UpdateDiscordClientID(const std::string& client_id)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Host_UpdateDiscordPresenceRaw(const std::string& details, const std::string& state,
|
||||||
|
const std::string& large_image_key,
|
||||||
|
const std::string& large_image_text,
|
||||||
|
const std::string& small_image_key,
|
||||||
|
const std::string& small_image_text,
|
||||||
|
const int64_t start_timestamp, const int64_t end_timestamp,
|
||||||
|
const int party_size, const int party_max)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
void Host_UpdateDisasmDialog()
|
void Host_UpdateDisasmDialog()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
|
@ -64,4 +64,14 @@ void Host_UpdateTitle(const std::string& title);
|
||||||
void Host_YieldToUI();
|
void Host_YieldToUI();
|
||||||
void Host_TitleChanged();
|
void Host_TitleChanged();
|
||||||
|
|
||||||
|
void Host_UpdateDiscordClientID(const std::string& client_id = {});
|
||||||
|
bool Host_UpdateDiscordPresenceRaw(const std::string& details = {}, const std::string& state = {},
|
||||||
|
const std::string& large_image_key = {},
|
||||||
|
const std::string& large_image_text = {},
|
||||||
|
const std::string& small_image_key = {},
|
||||||
|
const std::string& small_image_text = {},
|
||||||
|
const int64_t start_timestamp = 0,
|
||||||
|
const int64_t end_timestamp = 0, const int party_size = 0,
|
||||||
|
const int party_max = 0);
|
||||||
|
|
||||||
std::unique_ptr<GBAHostInterface> Host_CreateGBAHost(std::weak_ptr<HW::GBA::Core> core);
|
std::unique_ptr<GBAHostInterface> Host_CreateGBAHost(std::weak_ptr<HW::GBA::Core> core);
|
||||||
|
|
|
@ -15,8 +15,10 @@
|
||||||
#include "Common/Timer.h"
|
#include "Common/Timer.h"
|
||||||
#include "Common/Version.h"
|
#include "Common/Version.h"
|
||||||
#include "Core/Config/MainSettings.h"
|
#include "Core/Config/MainSettings.h"
|
||||||
|
#include "Core/Config/UISettings.h"
|
||||||
#include "Core/Core.h"
|
#include "Core/Core.h"
|
||||||
#include "Core/HW/Memmap.h"
|
#include "Core/HW/Memmap.h"
|
||||||
|
#include "Core/Host.h"
|
||||||
|
|
||||||
namespace IOS::HLE
|
namespace IOS::HLE
|
||||||
{
|
{
|
||||||
|
@ -30,6 +32,9 @@ enum
|
||||||
IOCTL_DOLPHIN_SET_SPEED_LIMIT = 0x04,
|
IOCTL_DOLPHIN_SET_SPEED_LIMIT = 0x04,
|
||||||
IOCTL_DOLPHIN_GET_CPU_SPEED = 0x05,
|
IOCTL_DOLPHIN_GET_CPU_SPEED = 0x05,
|
||||||
IOCTL_DOLPHIN_GET_REAL_PRODUCTCODE = 0x06,
|
IOCTL_DOLPHIN_GET_REAL_PRODUCTCODE = 0x06,
|
||||||
|
IOCTL_DOLPHIN_DISCORD_SET_CLIENT = 0x07,
|
||||||
|
IOCTL_DOLPHIN_DISCORD_SET_PRESENCE = 0x08,
|
||||||
|
IOCTL_DOLPHIN_DISCORD_RESET = 0x09
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -139,6 +144,67 @@ IPCReply GetRealProductCode(const IOCtlVRequest& request)
|
||||||
return IPCReply(IPC_SUCCESS);
|
return IPCReply(IPC_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
IPCReply SetDiscordClient(const IOCtlVRequest& request)
|
||||||
|
{
|
||||||
|
if (!Config::Get(Config::MAIN_USE_DISCORD_PRESENCE))
|
||||||
|
return IPCReply(IPC_EACCES);
|
||||||
|
|
||||||
|
if (!request.HasNumberOfValidVectors(1, 0))
|
||||||
|
return IPCReply(IPC_EINVAL);
|
||||||
|
|
||||||
|
std::string new_client_id =
|
||||||
|
Memory::GetString(request.in_vectors[0].address, request.in_vectors[0].size);
|
||||||
|
|
||||||
|
Host_UpdateDiscordClientID(new_client_id);
|
||||||
|
|
||||||
|
return IPCReply(IPC_SUCCESS);
|
||||||
|
}
|
||||||
|
|
||||||
|
IPCReply SetDiscordPresence(const IOCtlVRequest& request)
|
||||||
|
{
|
||||||
|
if (!Config::Get(Config::MAIN_USE_DISCORD_PRESENCE))
|
||||||
|
return IPCReply(IPC_EACCES);
|
||||||
|
|
||||||
|
if (!request.HasNumberOfValidVectors(10, 0))
|
||||||
|
return IPCReply(IPC_EINVAL);
|
||||||
|
|
||||||
|
std::string details =
|
||||||
|
Memory::GetString(request.in_vectors[0].address, request.in_vectors[0].size);
|
||||||
|
std::string state = Memory::GetString(request.in_vectors[1].address, request.in_vectors[1].size);
|
||||||
|
std::string large_image_key =
|
||||||
|
Memory::GetString(request.in_vectors[2].address, request.in_vectors[2].size);
|
||||||
|
std::string large_image_text =
|
||||||
|
Memory::GetString(request.in_vectors[3].address, request.in_vectors[3].size);
|
||||||
|
std::string small_image_key =
|
||||||
|
Memory::GetString(request.in_vectors[4].address, request.in_vectors[4].size);
|
||||||
|
std::string small_image_text =
|
||||||
|
Memory::GetString(request.in_vectors[5].address, request.in_vectors[5].size);
|
||||||
|
|
||||||
|
int64_t start_timestamp = Memory::Read_U64(request.in_vectors[6].address);
|
||||||
|
int64_t end_timestamp = Memory::Read_U64(request.in_vectors[7].address);
|
||||||
|
int party_size = Memory::Read_U32(request.in_vectors[8].address);
|
||||||
|
int party_max = Memory::Read_U32(request.in_vectors[9].address);
|
||||||
|
|
||||||
|
bool ret = Host_UpdateDiscordPresenceRaw(details, state, large_image_key, large_image_text,
|
||||||
|
small_image_key, small_image_text, start_timestamp,
|
||||||
|
end_timestamp, party_size, party_max);
|
||||||
|
|
||||||
|
if (!ret)
|
||||||
|
return IPCReply(IPC_EACCES);
|
||||||
|
|
||||||
|
return IPCReply(IPC_SUCCESS);
|
||||||
|
}
|
||||||
|
|
||||||
|
IPCReply ResetDiscord(const IOCtlVRequest& request)
|
||||||
|
{
|
||||||
|
if (!Config::Get(Config::MAIN_USE_DISCORD_PRESENCE))
|
||||||
|
return IPCReply(IPC_EACCES);
|
||||||
|
|
||||||
|
Host_UpdateDiscordClientID();
|
||||||
|
|
||||||
|
return IPCReply(IPC_SUCCESS);
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
IPCReply DolphinDevice::GetSystemTime(const IOCtlVRequest& request) const
|
IPCReply DolphinDevice::GetSystemTime(const IOCtlVRequest& request) const
|
||||||
|
@ -186,6 +252,13 @@ std::optional<IPCReply> DolphinDevice::IOCtlV(const IOCtlVRequest& request)
|
||||||
return GetCPUSpeed(request);
|
return GetCPUSpeed(request);
|
||||||
case IOCTL_DOLPHIN_GET_REAL_PRODUCTCODE:
|
case IOCTL_DOLPHIN_GET_REAL_PRODUCTCODE:
|
||||||
return GetRealProductCode(request);
|
return GetRealProductCode(request);
|
||||||
|
case IOCTL_DOLPHIN_DISCORD_SET_CLIENT:
|
||||||
|
return SetDiscordClient(request);
|
||||||
|
case IOCTL_DOLPHIN_DISCORD_SET_PRESENCE:
|
||||||
|
return SetDiscordPresence(request);
|
||||||
|
case IOCTL_DOLPHIN_DISCORD_RESET:
|
||||||
|
return ResetDiscord(request);
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return IPCReply(IPC_EINVAL);
|
return IPCReply(IPC_EINVAL);
|
||||||
}
|
}
|
||||||
|
|
|
@ -122,6 +122,30 @@ void Host_TitleChanged()
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Host_UpdateDiscordClientID(const std::string& client_id)
|
||||||
|
{
|
||||||
|
#ifdef USE_DISCORD_PRESENCE
|
||||||
|
Discord::UpdateClientID(client_id);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Host_UpdateDiscordPresenceRaw(const std::string& details, const std::string& state,
|
||||||
|
const std::string& large_image_key,
|
||||||
|
const std::string& large_image_text,
|
||||||
|
const std::string& small_image_key,
|
||||||
|
const std::string& small_image_text,
|
||||||
|
const int64_t start_timestamp, const int64_t end_timestamp,
|
||||||
|
const int party_size, const int party_max)
|
||||||
|
{
|
||||||
|
#ifdef USE_DISCORD_PRESENCE
|
||||||
|
return Discord::UpdateDiscordPresenceRaw(details, state, large_image_key, large_image_text,
|
||||||
|
small_image_key, small_image_text, start_timestamp,
|
||||||
|
end_timestamp, party_size, party_max);
|
||||||
|
#else
|
||||||
|
return false;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
std::unique_ptr<GBAHostInterface> Host_CreateGBAHost(std::weak_ptr<HW::GBA::Core> core)
|
std::unique_ptr<GBAHostInterface> Host_CreateGBAHost(std::weak_ptr<HW::GBA::Core> core)
|
||||||
{
|
{
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
|
@ -287,6 +287,30 @@ void Host_TitleChanged()
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Host_UpdateDiscordClientID(const std::string& client_id)
|
||||||
|
{
|
||||||
|
#ifdef USE_DISCORD_PRESENCE
|
||||||
|
Discord::UpdateClientID(client_id);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Host_UpdateDiscordPresenceRaw(const std::string& details, const std::string& state,
|
||||||
|
const std::string& large_image_key,
|
||||||
|
const std::string& large_image_text,
|
||||||
|
const std::string& small_image_key,
|
||||||
|
const std::string& small_image_text,
|
||||||
|
const int64_t start_timestamp, const int64_t end_timestamp,
|
||||||
|
const int party_size, const int party_max)
|
||||||
|
{
|
||||||
|
#ifdef USE_DISCORD_PRESENCE
|
||||||
|
return Discord::UpdateDiscordPresenceRaw(details, state, large_image_key, large_image_text,
|
||||||
|
small_image_key, small_image_text, start_timestamp,
|
||||||
|
end_timestamp, party_size, party_max);
|
||||||
|
#else
|
||||||
|
return false;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
#ifndef HAS_LIBMGBA
|
#ifndef HAS_LIBMGBA
|
||||||
std::unique_ptr<GBAHostInterface> Host_CreateGBAHost(std::weak_ptr<HW::GBA::Core> core)
|
std::unique_ptr<GBAHostInterface> Host_CreateGBAHost(std::weak_ptr<HW::GBA::Core> core)
|
||||||
{
|
{
|
||||||
|
|
|
@ -43,6 +43,21 @@ void Host_UpdateTitle(const std::string& title)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Host_UpdateDiscordClientID(const std::string& client_id)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Host_UpdateDiscordPresenceRaw(const std::string& details, const std::string& state,
|
||||||
|
const std::string& large_image_key,
|
||||||
|
const std::string& large_image_text,
|
||||||
|
const std::string& small_image_key,
|
||||||
|
const std::string& small_image_text,
|
||||||
|
const int64_t start_timestamp, const int64_t end_timestamp,
|
||||||
|
const int party_size, const int party_max)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
void Host_UpdateDisasmDialog()
|
void Host_UpdateDisasmDialog()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
|
@ -189,12 +189,27 @@ void Init()
|
||||||
handlers.ready = HandleDiscordReady;
|
handlers.ready = HandleDiscordReady;
|
||||||
handlers.joinRequest = HandleDiscordJoinRequest;
|
handlers.joinRequest = HandleDiscordJoinRequest;
|
||||||
handlers.joinGame = HandleDiscordJoin;
|
handlers.joinGame = HandleDiscordJoin;
|
||||||
// The number is the client ID for Dolphin, it's used for images and the application name
|
Discord_Initialize(DEFAULT_CLIENT_ID.c_str(), &handlers, 1, nullptr);
|
||||||
Discord_Initialize("455712169795780630", &handlers, 1, nullptr);
|
|
||||||
UpdateDiscordPresence();
|
UpdateDiscordPresence();
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void UpdateClientID(const std::string& new_client)
|
||||||
|
{
|
||||||
|
#ifdef USE_DISCORD_PRESENCE
|
||||||
|
if (!Config::Get(Config::MAIN_USE_DISCORD_PRESENCE))
|
||||||
|
return;
|
||||||
|
|
||||||
|
s_using_custom_client = new_client.empty() || new_client.compare(DEFAULT_CLIENT_ID) != 0;
|
||||||
|
|
||||||
|
Shutdown();
|
||||||
|
if (s_using_custom_client)
|
||||||
|
Discord_Initialize(new_client.c_str(), nullptr, 0, nullptr);
|
||||||
|
else // if initialising dolphin's client ID, make sure to restore event handlers
|
||||||
|
Init();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
void CallPendingCallbacks()
|
void CallPendingCallbacks()
|
||||||
{
|
{
|
||||||
#ifdef USE_DISCORD_PRESENCE
|
#ifdef USE_DISCORD_PRESENCE
|
||||||
|
@ -213,6 +228,39 @@ void InitNetPlayFunctionality(Handler& handler)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool UpdateDiscordPresenceRaw(const std::string& details, const std::string& state,
|
||||||
|
const std::string& large_image_key,
|
||||||
|
const std::string& large_image_text,
|
||||||
|
const std::string& small_image_key,
|
||||||
|
const std::string& small_image_text, const int64_t start_timestamp,
|
||||||
|
const int64_t end_timestamp, const int party_size,
|
||||||
|
const int party_max)
|
||||||
|
{
|
||||||
|
#ifdef USE_DISCORD_PRESENCE
|
||||||
|
if (!Config::Get(Config::MAIN_USE_DISCORD_PRESENCE))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// only /dev/dolphin sets this, don't let homebrew change official client ID raw presence
|
||||||
|
if (!s_using_custom_client)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
DiscordRichPresence discord_presence = {};
|
||||||
|
discord_presence.details = details.c_str();
|
||||||
|
discord_presence.state = state.c_str();
|
||||||
|
discord_presence.largeImageKey = large_image_key.c_str();
|
||||||
|
discord_presence.largeImageText = large_image_text.c_str();
|
||||||
|
discord_presence.smallImageKey = small_image_key.c_str();
|
||||||
|
discord_presence.smallImageText = small_image_text.c_str();
|
||||||
|
discord_presence.startTimestamp = start_timestamp;
|
||||||
|
discord_presence.endTimestamp = end_timestamp;
|
||||||
|
discord_presence.partySize = party_size;
|
||||||
|
discord_presence.partyMax = party_max;
|
||||||
|
Discord_UpdatePresence(&discord_presence);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
void UpdateDiscordPresence(int party_size, SecretType type, const std::string& secret,
|
void UpdateDiscordPresence(int party_size, SecretType type, const std::string& secret,
|
||||||
const std::string& current_game)
|
const std::string& current_game)
|
||||||
{
|
{
|
||||||
|
@ -220,6 +268,10 @@ void UpdateDiscordPresence(int party_size, SecretType type, const std::string& s
|
||||||
if (!Config::Get(Config::MAIN_USE_DISCORD_PRESENCE))
|
if (!Config::Get(Config::MAIN_USE_DISCORD_PRESENCE))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
// reset the client ID if running homebrew has changed it
|
||||||
|
if (s_using_custom_client)
|
||||||
|
UpdateClientID(DEFAULT_CLIENT_ID);
|
||||||
|
|
||||||
const std::string& title =
|
const std::string& title =
|
||||||
current_game.empty() ? SConfig::GetInstance().GetTitleDescription() : current_game;
|
current_game.empty() ? SConfig::GetInstance().GetTitleDescription() : current_game;
|
||||||
std::string game_artwork = ArtworkForGameId(SConfig::GetInstance().GetGameID());
|
std::string game_artwork = ArtworkForGameId(SConfig::GetInstance().GetGameID());
|
||||||
|
|
|
@ -8,6 +8,9 @@
|
||||||
|
|
||||||
namespace Discord
|
namespace Discord
|
||||||
{
|
{
|
||||||
|
// The number is the client ID for Dolphin, it's used for images and the application name
|
||||||
|
const std::string DEFAULT_CLIENT_ID = "455712169795780630";
|
||||||
|
|
||||||
class Handler
|
class Handler
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -24,9 +27,19 @@ enum class SecretType
|
||||||
RoomID,
|
RoomID,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static bool s_using_custom_client = false;
|
||||||
|
|
||||||
void Init();
|
void Init();
|
||||||
void InitNetPlayFunctionality(Handler& handler);
|
void InitNetPlayFunctionality(Handler& handler);
|
||||||
void CallPendingCallbacks();
|
void CallPendingCallbacks();
|
||||||
|
void UpdateClientID(const std::string& new_client = {});
|
||||||
|
bool UpdateDiscordPresenceRaw(const std::string& details = {}, const std::string& state = {},
|
||||||
|
const std::string& large_image_key = {},
|
||||||
|
const std::string& large_image_text = {},
|
||||||
|
const std::string& small_image_key = {},
|
||||||
|
const std::string& small_image_text = {},
|
||||||
|
const int64_t start_timestamp = 0, const int64_t end_timestamp = 0,
|
||||||
|
const int party_size = 0, const int party_max = 0);
|
||||||
void UpdateDiscordPresence(int party_size = 0, SecretType type = SecretType::Empty,
|
void UpdateDiscordPresence(int party_size = 0, SecretType type = SecretType::Empty,
|
||||||
const std::string& secret = {}, const std::string& current_game = {});
|
const std::string& secret = {}, const std::string& current_game = {});
|
||||||
std::string CreateSecretFromIPAddress(const std::string& ip_address, int port);
|
std::string CreateSecretFromIPAddress(const std::string& ip_address, int port);
|
||||||
|
|
|
@ -25,6 +25,19 @@ void Host_Message(HostMessageID)
|
||||||
void Host_UpdateTitle(const std::string&)
|
void Host_UpdateTitle(const std::string&)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
void Host_UpdateDiscordClientID(const std::string& client_id)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
bool Host_UpdateDiscordPresenceRaw(const std::string& details, const std::string& state,
|
||||||
|
const std::string& large_image_key,
|
||||||
|
const std::string& large_image_text,
|
||||||
|
const std::string& small_image_key,
|
||||||
|
const std::string& small_image_text,
|
||||||
|
const int64_t start_timestamp, const int64_t end_timestamp,
|
||||||
|
const int party_size, const int party_max)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
void Host_UpdateDisasmDialog()
|
void Host_UpdateDisasmDialog()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,6 +25,19 @@ void Host_Message(HostMessageID)
|
||||||
void Host_UpdateTitle(const std::string&)
|
void Host_UpdateTitle(const std::string&)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
void Host_UpdateDiscordClientID(const std::string& client_id)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
bool Host_UpdateDiscordPresenceRaw(const std::string& details, const std::string& state,
|
||||||
|
const std::string& large_image_key,
|
||||||
|
const std::string& large_image_text,
|
||||||
|
const std::string& small_image_key,
|
||||||
|
const std::string& small_image_text,
|
||||||
|
const int64_t start_timestamp, const int64_t end_timestamp,
|
||||||
|
const int party_size, const int party_max)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
void Host_UpdateDisasmDialog()
|
void Host_UpdateDisasmDialog()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue