diff --git a/examples/send-presence/send-presence.c b/examples/send-presence/send-presence.c index 17322ce..68082ea 100644 --- a/examples/send-presence/send-presence.c +++ b/examples/send-presence/send-presence.c @@ -95,8 +95,11 @@ static void gameLoop() } } -int main() +int main(int argc, char* argv[]) { + /* This would typically be in an installer and/or wrapped to only run once */ + Discord_Register(APPLICATION_ID); + DiscordEventHandlers handlers; memset(&handlers, 0, sizeof(handlers)); handlers.ready = handleDiscordReady; diff --git a/include/discord-rpc.h b/include/discord-rpc.h index 18c3014..33400ce 100644 --- a/include/discord-rpc.h +++ b/include/discord-rpc.h @@ -5,6 +5,12 @@ extern "C" { #endif +/* Registration */ + +void Discord_Register(const char* applicationId); + +/* RPC */ + typedef struct DiscordRichPresence { const char* state; const char* details; diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index e0dfb6a..a4bc465 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -6,7 +6,7 @@ if (${ENABLE_IO_THREAD} EQUAL OFF) add_definitions(-DDISCORD_DISABLE_IO_THREAD) endif (${ENABLE_IO_THREAD} EQUAL OFF) -set(BASE_RPC_SRC ${PROJECT_SOURCE_DIR}/include/discord-rpc.h discord-rpc.cpp rpc_connection.h rpc_connection.cpp serialization.h serialization.cpp connection.h backoff.h) +set(BASE_RPC_SRC ${PROJECT_SOURCE_DIR}/include/discord-rpc.h discord-rpc.cpp discord-register.cpp rpc_connection.h rpc_connection.cpp serialization.h serialization.cpp connection.h backoff.h) if(WIN32) add_library(discord-rpc STATIC ${BASE_RPC_SRC} connection_win.cpp) diff --git a/src/discord-register.cpp b/src/discord-register.cpp new file mode 100644 index 0000000..bd2fcc3 --- /dev/null +++ b/src/discord-register.cpp @@ -0,0 +1,76 @@ +#include "discord-rpc.h" +#include + +#ifdef _WIN32 +#define WIN32_LEAN_AND_MEAN +#define NOMCX +#define NOSERVICE +#define NOIME +#include +#include +#include +#pragma comment(lib, "Psapi.lib") +#endif + +void Discord_Register(const char* applicationId) +{ +#ifdef _WIN32 + // https://msdn.microsoft.com/en-us/library/aa767914(v=vs.85).aspx + // we want to register games so we can run them as discord-:// + // Update the HKEY_CURRENT_USER, because it doesn't seem to require special permissions. + + wchar_t appId[32]; + MultiByteToWideChar(CP_UTF8, 0, applicationId, -1, appId, 32); + + wchar_t exeFilePath[MAX_PATH]; + GetModuleFileNameExW(GetCurrentProcess(), nullptr, exeFilePath, MAX_PATH); + + wchar_t protocolName[64]; + StringCbPrintfW(protocolName, sizeof(protocolName), L"discord-%s", appId); + wchar_t protocolDescription[128]; + StringCbPrintfW( + protocolDescription, sizeof(protocolDescription), L"URL:Run game %s protocol", appId); + wchar_t urlProtocol = 0; + wchar_t openCommand[MAX_PATH + 8]; + StringCbPrintfW(openCommand, sizeof(openCommand), L"\"%s\" \"%%1\"", exeFilePath); + + wchar_t keyName[256]; + StringCbPrintfW(keyName, sizeof(keyName), L"Software\\Classes\\%s", protocolName); + HKEY key; + auto status = + RegCreateKeyExW(HKEY_CURRENT_USER, keyName, 0, nullptr, 0, KEY_WRITE, nullptr, &key, nullptr); + if (status != ERROR_SUCCESS) { + fprintf(stderr, "Error creating key\n"); + return; + } + DWORD len; + LSTATUS result; + len = lstrlenW(protocolDescription) + 1; + result = + RegSetKeyValueW(key, nullptr, nullptr, REG_SZ, protocolDescription, len * sizeof(wchar_t)); + if (FAILED(result)) { + fprintf(stderr, "Error writing description\n"); + } + + len = lstrlenW(protocolDescription) + 1; + result = RegSetKeyValueW(key, nullptr, L"URL Protocol", REG_SZ, &urlProtocol, sizeof(wchar_t)); + if (FAILED(result)) { + fprintf(stderr, "Error writing description\n"); + } + + len = lstrlenW(exeFilePath) + 1; + result = + RegSetKeyValueW(key, L"DefaultIcon", nullptr, REG_SZ, exeFilePath, len * sizeof(wchar_t)); + if (FAILED(result)) { + fprintf(stderr, "Error writing icon\n"); + } + + len = lstrlenW(openCommand) + 1; + result = RegSetKeyValueW( + key, L"shell\\open\\command", nullptr, REG_SZ, openCommand, len * sizeof(wchar_t)); + if (FAILED(result)) { + fprintf(stderr, "Error writing command\n"); + } + RegCloseKey(key); +#endif +}