From 6ad99a860c9b7d2729d4106ebbd69d284164dc12 Mon Sep 17 00:00:00 2001 From: dreamsyntax Date: Tue, 26 Aug 2025 01:12:43 -0700 Subject: [PATCH] Externals: Update discord-rpc Upgrade to 963aa9f3e5ce81a4682c6ca3d136cddda614db33 --- Externals/discord-rpc/README.md | 64 ++++++++++--------- Externals/discord-rpc/include/discord_rpc.h | 3 + Externals/discord-rpc/src/connection_unix.cpp | 3 + .../src/discord_register_linux.cpp | 4 +- .../discord-rpc/src/discord_register_win.cpp | 3 +- Externals/discord-rpc/src/discord_rpc.cpp | 16 +++-- Externals/discord-rpc/src/rpc_connection.cpp | 8 +-- Externals/discord-rpc/src/serialization.cpp | 7 +- 8 files changed, 63 insertions(+), 45 deletions(-) diff --git a/Externals/discord-rpc/README.md b/Externals/discord-rpc/README.md index c2251ff506..1285fb844d 100644 --- a/Externals/discord-rpc/README.md +++ b/Externals/discord-rpc/README.md @@ -1,5 +1,11 @@ # Discord RPC +## Deprecation Notice + +This library has been deprecated in favor of Discord's GameSDK. [Learn more here](https://discordapp.com/developers/docs/game-sdk/sdk-starter-guide) + +--- + This is a library for interfacing your game with a locally running Discord desktop client. It's known to work on Windows, macOS, and Linux. You can use the lib directly if you like, or use it as a guide to writing your own if it doesn't suit your game as is. PRs/feedback welcome if you have an improvement everyone might want, or can describe how this doesn't meet your needs. Included here are some quick demos that implement the very minimal subset to show current status, and @@ -15,6 +21,33 @@ Zeroith, you should be set up to build things because you are a game developer, First, head on over to the [Discord developers site](https://discordapp.com/developers/applications/me) and make yourself an app. Keep track of `Client ID` -- you'll need it here to pass to the init function. +### Unreal Engine 4 Setup + +To use the Rich Presense plugin with Unreal Engine Projects: + +1. Download the latest [release](https://github.com/discordapp/discord-rpc/releases) for each operating system you are targeting and the zipped source code +2. In the source code zip, copy the UE plugin—`examples/unrealstatus/Plugins/discordrpc`—to your project's plugin directory +3. At `[YOUR_UE_PROJECT]/Plugins/discordrpc/source/ThirdParty/DiscordRpcLibrary/`, create an `Include` folder and copy `discord_rpc.h` and `discord_register.h` to it from the zip +4. Follow the steps below for each OS +5. Build your UE4 project +6. Launch the editor, and enable the Discord plugin. + +#### Windows + +- At `[YOUR_UE_PROJECT]/Plugins/discordrpc/source/ThirdParty/DiscordRpcLibrary/`, create a `Win64` folder +- Copy `lib/discord-rpc.lib` and `bin/discord-rpc.dll` from `[RELEASE_ZIP]/win64-dynamic` to the `Win64` folder + +#### Mac + +- At `[YOUR_UE_PROJECT]/Plugins/discordrpc/source/ThirdParty/DiscordRpcLibrary/`, create a `Mac` folder +- Copy `libdiscord-rpc.dylib` from `[RELEASE_ZIP]/osx-dynamic/lib` to the `Mac` folder + +#### Linux + +- At `[YOUR_UE_PROJECT]/Plugins/discordrpc/source/ThirdParty/DiscordRpcLibrary/`, create a `Linux` folder +- Inside, create another folder `x86_64-unknown-linux-gnu` +- Copy `libdiscord-rpc.so` from `[RELEASE_ZIP]/linux-dynamic/lib` to `Linux/x86_64-unknown-linux-gnu` + ### Unity Setup If you're a Unity developer looking to integrate Rich Presence into your game, follow this simple guide to get started towards success: @@ -29,14 +62,14 @@ We've got our `Plugins` folder ready, so let's get platform-specific! 4. Create `x86` and `x86_64` folders inside `Assets/Plugins/` 5. Copy `discord-rpc-win/win64-dynamic/bin/discord-rpc.dll` to `Assets/Plugins/x86_64/` -6. Copy `discord-rpc-win/win32-dynamic/bin/discord-rpc.dll` to `Assets/Plguins/x86/` +6. Copy `discord-rpc-win/win32-dynamic/bin/discord-rpc.dll` to `Assets/Plugins/x86/` 7. Click on both DLLs and make sure they are targetting the correct architectures in the Unity editor properties pane 8. Done! #### MacOS 4. Copy `discord-rpc-osx/osx-dynamic/lib/libdiscord-rpc.dylib` to `Assets/Plugins/` -5. Rename `libdiscord-rpc.dylib` to `libdiscord-rpc.bundle` +5. Rename `libdiscord-rpc.dylib` to `discord-rpc.bundle` 6. Done! #### Linux @@ -101,33 +134,6 @@ This is a sample [Unity](https://unity3d.com/) project that wraps a DLL version This is a sample [Unreal](https://www.unrealengine.com) project that wraps the DLL version of the library with an Unreal plugin, exposes a blueprint class for interacting with it, and uses that to make a very simple UI. Run `python build.py unreal` in the root directory to build the correct library files and place them in their respective folders. -### Using the Unreal Engine plugin with your own project - -To use the Rich Presense plugin with Unreal Engine Projects: - -1. Download the latest [release](https://github.com/discordapp/discord-rpc/releases) for each operating system you are targeting and the zipped source code -2. In the source code zip, copy the UE plugin—`examples/unrealstatus/Plugins/discordrpc`—to your project's plugin directory -3. At `[YOUR_UE_PROJECT]/Plugins/discordrpc/source/ThirdParty/DiscordRpcLibrary/`, create an `Include` folder and copy `discord_rpc.h` and `discord_register.h` to it from the zip -4. Follow the steps below for each OS -5. Build your UE4 project -6. Launch the editor, and enable the Discord plugin. - -#### Windows - -- At `[YOUR_UE_PROJECT]/Plugins/discordrpc/source/ThirdParty/DiscordRpcLibrary/`, create a `Win64` folder -- Copy `lib/discord-rpc.lib` and `bin/discord-rpc.dll` from `[RELEASE_ZIP]/win64-dynamic` to the `Win64` folder - -#### Mac - -- At `[YOUR_UE_PROJECT]/Plugins/discordrpc/source/ThirdParty/DiscordRpcLibrary/`, create a `Mac` folder -- Copy `libdiscord-rpc.dylib` from `[RELEASE_ZIP]/osx-dynamic/lib` to the `Mac` folder - -#### Linux - -- At `[YOUR_UE_PROJECT]/Plugins/discordrpc/source/ThirdParty/DiscordRpcLibrary/`, create a `Linux` folder -- Inside, create another folder `x86_64-unknown-linux-gnu` -- Copy `libdiscord-rpc.so` from `[RELEASE_ZIP]/linux-dynamic/lib` to `Linux/x86_64-unknown-linux-gnu` - ## Wrappers and Implementations Below is a table of unofficial, community-developed wrappers for and implementations of Rich Presence in various languages. If you would like to have yours added, please make a pull request adding your repository to the table. The repository should include: diff --git a/Externals/discord-rpc/include/discord_rpc.h b/Externals/discord-rpc/include/discord_rpc.h index 3e1441e058..9470434a84 100644 --- a/Externals/discord-rpc/include/discord_rpc.h +++ b/Externals/discord-rpc/include/discord_rpc.h @@ -35,6 +35,7 @@ typedef struct DiscordRichPresence { const char* partyId; /* max 128 bytes */ int partySize; int partyMax; + int partyPrivacy; const char* matchSecret; /* max 128 bytes */ const char* joinSecret; /* max 128 bytes */ const char* spectateSecret; /* max 128 bytes */ @@ -60,6 +61,8 @@ typedef struct DiscordEventHandlers { #define DISCORD_REPLY_NO 0 #define DISCORD_REPLY_YES 1 #define DISCORD_REPLY_IGNORE 2 +#define DISCORD_PARTY_PRIVATE 0 +#define DISCORD_PARTY_PUBLIC 1 DISCORD_EXPORT void Discord_Initialize(const char* applicationId, DiscordEventHandlers* handlers, diff --git a/Externals/discord-rpc/src/connection_unix.cpp b/Externals/discord-rpc/src/connection_unix.cpp index 6fe359ea4f..85dace3ccc 100644 --- a/Externals/discord-rpc/src/connection_unix.cpp +++ b/Externals/discord-rpc/src/connection_unix.cpp @@ -118,5 +118,8 @@ bool BaseConnection::Read(void* data, size_t length) } Close(); } + else if (res == 0) { + Close(); + } return res == (int)length; } diff --git a/Externals/discord-rpc/src/discord_register_linux.cpp b/Externals/discord-rpc/src/discord_register_linux.cpp index 09911dcc6c..dd92eea0d4 100644 --- a/Externals/discord-rpc/src/discord_register_linux.cpp +++ b/Externals/discord-rpc/src/discord_register_linux.cpp @@ -41,7 +41,7 @@ extern "C" DISCORD_EXPORT void Discord_Register(const char* applicationId, const command = exePath; } - const char* destopFileFormat = "[Desktop Entry]\n" + const char* desktopFileFormat = "[Desktop Entry]\n" "Name=Game %s\n" "Exec=%s %%u\n" // note: it really wants that %u in there "Type=Application\n" @@ -50,7 +50,7 @@ extern "C" DISCORD_EXPORT void Discord_Register(const char* applicationId, const "MimeType=x-scheme-handler/discord-%s;\n"; char desktopFile[2048]; int fileLen = snprintf( - desktopFile, sizeof(desktopFile), destopFileFormat, applicationId, command, applicationId); + desktopFile, sizeof(desktopFile), desktopFileFormat, applicationId, command, applicationId); if (fileLen <= 0) { return; } diff --git a/Externals/discord-rpc/src/discord_register_win.cpp b/Externals/discord-rpc/src/discord_register_win.cpp index e441318dd5..0b1c4a13da 100644 --- a/Externals/discord-rpc/src/discord_register_win.cpp +++ b/Externals/discord-rpc/src/discord_register_win.cpp @@ -7,7 +7,6 @@ #define NOIME #include #include -#include #include /** @@ -20,6 +19,7 @@ * The entire function is rewritten */ #ifdef __MINGW32__ +#include /// strsafe.h fixes static HRESULT StringCbPrintfW(LPWSTR pszDest, size_t cbDest, LPCWSTR pszFormat, ...) { @@ -34,6 +34,7 @@ static HRESULT StringCbPrintfW(LPWSTR pszDest, size_t cbDest, LPCWSTR pszFormat, return ret; } #else +#include #include #endif // __MINGW32__ diff --git a/Externals/discord-rpc/src/discord_rpc.cpp b/Externals/discord-rpc/src/discord_rpc.cpp index 2e44c939ce..03924538c3 100644 --- a/Externals/discord-rpc/src/discord_rpc.cpp +++ b/Externals/discord-rpc/src/discord_rpc.cpp @@ -54,6 +54,7 @@ static std::atomic_bool WasJustDisconnected{false}; static std::atomic_bool GotErrorMessage{false}; static std::atomic_bool WasJoinGame{false}; static std::atomic_bool WasSpectateGame{false}; +static std::atomic_bool UpdatePresence{false}; static char JoinGameSecret[256]; static char SpectateGameSecret[256]; static int LastErrorCode{0}; @@ -214,17 +215,17 @@ static void Discord_UpdateConnection(void) } // writes - if (QueuedPresence.length) { + if (UpdatePresence.exchange(false) && QueuedPresence.length) { QueuedMessage local; { std::lock_guard guard(PresenceMutex); local.Copy(QueuedPresence); - QueuedPresence.length = 0; } if (!Connection->Write(local.buffer, local.length)) { // if we fail to send, requeue std::lock_guard guard(PresenceMutex); QueuedPresence.Copy(local); + UpdatePresence.exchange(true); } } @@ -310,6 +311,10 @@ extern "C" DISCORD_EXPORT void Discord_Initialize(const char* applicationId, Connection = RpcConnection::Create(applicationId); Connection->onConnect = [](JsonDocument& readyMessage) { Discord_UpdateHandlers(&QueuedHandlers); + if (QueuedPresence.length > 0) { + UpdatePresence.exchange(true); + SignalIOActivity(); + } auto data = GetObjMember(&readyMessage, "data"); auto user = GetObjMember(data, "user"); auto userId = GetStrMember(user, "id"); @@ -335,10 +340,6 @@ extern "C" DISCORD_EXPORT void Discord_Initialize(const char* applicationId, Connection->onDisconnect = [](int err, const char* message) { LastDisconnectErrorCode = err; StringCopy(LastDisconnectErrorMessage, message); - { - std::lock_guard guard(HandlerMutex); - Handlers = {}; - } WasJustDisconnected.exchange(true); UpdateReconnectTime(); }; @@ -354,6 +355,8 @@ extern "C" DISCORD_EXPORT void Discord_Shutdown(void) Connection->onConnect = nullptr; Connection->onDisconnect = nullptr; Handlers = {}; + QueuedPresence.length = 0; + UpdatePresence.exchange(false); if (IoThread != nullptr) { IoThread->Stop(); delete IoThread; @@ -369,6 +372,7 @@ extern "C" DISCORD_EXPORT void Discord_UpdatePresence(const DiscordRichPresence* std::lock_guard guard(PresenceMutex); QueuedPresence.length = JsonWriteRichPresenceObj( QueuedPresence.buffer, sizeof(QueuedPresence.buffer), Nonce++, Pid, presence); + UpdatePresence.exchange(true); } SignalIOActivity(); } diff --git a/Externals/discord-rpc/src/rpc_connection.cpp b/Externals/discord-rpc/src/rpc_connection.cpp index bf9e4cc7a4..0933162169 100644 --- a/Externals/discord-rpc/src/rpc_connection.cpp +++ b/Externals/discord-rpc/src/rpc_connection.cpp @@ -26,12 +26,8 @@ void RpcConnection::Open() return; } - if (state == State::Disconnected) { - if (connection->Open()) { - } - else { - return; - } + if (state == State::Disconnected && !connection->Open()) { + return; } if (state == State::SentHandshake) { diff --git a/Externals/discord-rpc/src/serialization.cpp b/Externals/discord-rpc/src/serialization.cpp index 6cc1e9013d..70efa637f3 100644 --- a/Externals/discord-rpc/src/serialization.cpp +++ b/Externals/discord-rpc/src/serialization.cpp @@ -134,7 +134,7 @@ size_t JsonWriteRichPresenceObj(char* dest, } if ((presence->partyId && presence->partyId[0]) || presence->partySize || - presence->partyMax) { + presence->partyMax || presence->partyPrivacy) { WriteObject party(writer, "party"); WriteOptionalString(writer, "id", presence->partyId); if (presence->partySize && presence->partyMax) { @@ -142,6 +142,11 @@ size_t JsonWriteRichPresenceObj(char* dest, writer.Int(presence->partySize); writer.Int(presence->partyMax); } + + if (presence->partyPrivacy) { + WriteKey(writer, "privacy"); + writer.Int(presence->partyPrivacy); + } } if ((presence->matchSecret && presence->matchSecret[0]) ||