Compare commits
10 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
963aa9f3e5 | ||
|
e4c0c569ec | ||
|
b6d0a9cdbd | ||
|
eff23a770a | ||
|
34ce3ac803 | ||
|
c59fd6df20 | ||
|
4824b20f28 | ||
|
4e53fa0392 | ||
|
d478ed5608 | ||
|
8db649ba5f |
60
README.md
60
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:
|
||||
@ -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:
|
||||
|
@ -31,6 +31,11 @@ public class DiscordController : MonoBehaviour
|
||||
clickCounter++;
|
||||
|
||||
presence.details = string.Format("Button clicked {0} times", clickCounter);
|
||||
presence.joinSecret = "aSecret";
|
||||
presence.partyId = "aPartyId";
|
||||
presence.partySize = 1;
|
||||
presence.partyMax = 3;
|
||||
presence.partyPrivacy = DiscordRpc.PartyPrivacy.Public;
|
||||
|
||||
DiscordRpc.UpdatePresence(presence);
|
||||
}
|
||||
|
@ -7,29 +7,31 @@ using AOT;
|
||||
public class DiscordRpc
|
||||
{
|
||||
[MonoPInvokeCallback(typeof(OnReadyInfo))]
|
||||
public static void ReadyCallback(ref DiscordUser connectedUser) { }
|
||||
public static void ReadyCallback(ref DiscordUser connectedUser) { Callbacks.readyCallback(ref connectedUser); }
|
||||
public delegate void OnReadyInfo(ref DiscordUser connectedUser);
|
||||
|
||||
[MonoPInvokeCallback(typeof(OnDisconnectedInfo))]
|
||||
public static void DisconnectedCallback(int errorCode, string message) { }
|
||||
public static void DisconnectedCallback(int errorCode, string message) { Callbacks.disconnectedCallback(errorCode, message); }
|
||||
public delegate void OnDisconnectedInfo(int errorCode, string message);
|
||||
|
||||
[MonoPInvokeCallback(typeof(OnErrorInfo))]
|
||||
public static void ErrorCallback(int errorCode, string message) { }
|
||||
public static void ErrorCallback(int errorCode, string message) { Callbacks.errorCallback(errorCode, message); }
|
||||
public delegate void OnErrorInfo(int errorCode, string message);
|
||||
|
||||
[MonoPInvokeCallback(typeof(OnJoinInfo))]
|
||||
public static void JoinCallback(string secret) { }
|
||||
public static void JoinCallback(string secret) { Callbacks.joinCallback(secret); }
|
||||
public delegate void OnJoinInfo(string secret);
|
||||
|
||||
[MonoPInvokeCallback(typeof(OnSpectateInfo))]
|
||||
public static void SpectateCallback(string secret) { }
|
||||
public static void SpectateCallback(string secret) { Callbacks.spectateCallback(secret); }
|
||||
public delegate void OnSpectateInfo(string secret);
|
||||
|
||||
[MonoPInvokeCallback(typeof(OnRequestInfo))]
|
||||
public static void RequestCallback(ref DiscordUser request) { }
|
||||
public static void RequestCallback(ref DiscordUser request) { Callbacks.requestCallback(ref request); }
|
||||
public delegate void OnRequestInfo(ref DiscordUser request);
|
||||
|
||||
static EventHandlers Callbacks { get; set; }
|
||||
|
||||
public struct EventHandlers
|
||||
{
|
||||
public OnReadyInfo readyCallback;
|
||||
@ -54,6 +56,7 @@ public class DiscordRpc
|
||||
public IntPtr partyId; /* max 128 bytes */
|
||||
public int partySize;
|
||||
public int partyMax;
|
||||
public int partyPrivacy;
|
||||
public IntPtr matchSecret; /* max 128 bytes */
|
||||
public IntPtr joinSecret; /* max 128 bytes */
|
||||
public IntPtr spectateSecret; /* max 128 bytes */
|
||||
@ -76,8 +79,29 @@ public class DiscordRpc
|
||||
Ignore = 2
|
||||
}
|
||||
|
||||
public enum PartyPrivacy
|
||||
{
|
||||
Private = 0,
|
||||
Public = 1
|
||||
}
|
||||
|
||||
public static void Initialize(string applicationId, ref EventHandlers handlers, bool autoRegister, string optionalSteamId)
|
||||
{
|
||||
Callbacks = handlers;
|
||||
|
||||
EventHandlers staticEventHandlers = new EventHandlers();
|
||||
staticEventHandlers.readyCallback += DiscordRpc.ReadyCallback;
|
||||
staticEventHandlers.disconnectedCallback += DiscordRpc.DisconnectedCallback;
|
||||
staticEventHandlers.errorCallback += DiscordRpc.ErrorCallback;
|
||||
staticEventHandlers.joinCallback += DiscordRpc.JoinCallback;
|
||||
staticEventHandlers.spectateCallback += DiscordRpc.SpectateCallback;
|
||||
staticEventHandlers.requestCallback += DiscordRpc.RequestCallback;
|
||||
|
||||
InitializeInternal(applicationId, ref staticEventHandlers, autoRegister, optionalSteamId);
|
||||
}
|
||||
|
||||
[DllImport("discord-rpc", EntryPoint = "Discord_Initialize", CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern void Initialize(string applicationId, ref EventHandlers handlers, bool autoRegister, string optionalSteamId);
|
||||
static extern void InitializeInternal(string applicationId, ref EventHandlers handlers, bool autoRegister, string optionalSteamId);
|
||||
|
||||
[DllImport("discord-rpc", EntryPoint = "Discord_Shutdown", CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern void Shutdown();
|
||||
@ -120,6 +144,7 @@ public class DiscordRpc
|
||||
public string partyId; /* max 128 bytes */
|
||||
public int partySize;
|
||||
public int partyMax;
|
||||
public PartyPrivacy partyPrivacy;
|
||||
public string matchSecret; /* max 128 bytes */
|
||||
public string joinSecret; /* max 128 bytes */
|
||||
public string spectateSecret; /* max 128 bytes */
|
||||
@ -147,6 +172,7 @@ public class DiscordRpc
|
||||
_presence.partyId = StrToPtr(partyId);
|
||||
_presence.partySize = partySize;
|
||||
_presence.partyMax = partyMax;
|
||||
_presence.partyPrivacy = (int)partyPrivacy;
|
||||
_presence.matchSecret = StrToPtr(matchSecret);
|
||||
_presence.joinSecret = StrToPtr(joinSecret);
|
||||
_presence.spectateSecret = StrToPtr(spectateSecret);
|
||||
|
@ -47,6 +47,7 @@ static void updateDiscordPresence()
|
||||
discordPresence.partyId = "party1234";
|
||||
discordPresence.partySize = 1;
|
||||
discordPresence.partyMax = 6;
|
||||
discordPresence.partyPrivacy = DISCORD_PARTY_PUBLIC;
|
||||
discordPresence.matchSecret = "xyzzy";
|
||||
discordPresence.joinSecret = "join";
|
||||
discordPresence.spectateSecret = "look";
|
||||
|
@ -153,6 +153,7 @@ void UDiscordRpc::UpdatePresence()
|
||||
rp.endTimestamp = RichPresence.endTimestamp;
|
||||
rp.partySize = RichPresence.partySize;
|
||||
rp.partyMax = RichPresence.partyMax;
|
||||
rp.partyPrivacy = (int)RichPresence.partyPrivacy;
|
||||
rp.instance = RichPresence.instance;
|
||||
|
||||
Discord_UpdatePresence(&rp);
|
||||
|
@ -35,6 +35,16 @@ enum class EDiscordJoinResponseCodes : uint8
|
||||
DISCORD_REPLY_IGNORE UMETA(DisplayName="Ignore")
|
||||
};
|
||||
|
||||
/**
|
||||
* Valid party privacy values
|
||||
*/
|
||||
UENUM(BlueprintType)
|
||||
enum class EDiscordPartyPrivacy: uint8
|
||||
{
|
||||
DISCORD_PARTY_PRIVATE UMETA(DisplayName="Private"),
|
||||
DISCORD_PARTY_PUBLIC UMETA(DisplayName="Public")
|
||||
};
|
||||
|
||||
DECLARE_LOG_CATEGORY_EXTERN(Discord, Log, All);
|
||||
|
||||
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FDiscordConnected, const FDiscordUserData&, joinRequest);
|
||||
@ -77,6 +87,8 @@ struct FDiscordRichPresence {
|
||||
UPROPERTY(BlueprintReadWrite)
|
||||
int partyMax;
|
||||
UPROPERTY(BlueprintReadWrite)
|
||||
EDiscordPartyPrivacy partyPrivacy;
|
||||
UPROPERTY(BlueprintReadWrite)
|
||||
FString matchSecret;
|
||||
UPROPERTY(BlueprintReadWrite)
|
||||
FString joinSecret;
|
||||
|
@ -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,
|
||||
|
@ -72,6 +72,11 @@ if(UNIX)
|
||||
|
||||
add_library(discord-rpc ${BASE_RPC_SRC})
|
||||
target_link_libraries(discord-rpc PUBLIC pthread)
|
||||
|
||||
if (APPLE)
|
||||
target_link_libraries(discord-rpc PRIVATE "-framework AppKit, -mmacosx-version-min=10.10")
|
||||
endif (APPLE)
|
||||
|
||||
target_compile_options(discord-rpc PRIVATE
|
||||
-g
|
||||
-Wall
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -7,7 +7,6 @@
|
||||
#define NOIME
|
||||
#include <windows.h>
|
||||
#include <psapi.h>
|
||||
#include <cwchar>
|
||||
#include <cstdio>
|
||||
|
||||
/**
|
||||
@ -20,6 +19,7 @@
|
||||
* The entire function is rewritten
|
||||
*/
|
||||
#ifdef __MINGW32__
|
||||
#include <wchar.h>
|
||||
/// 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 <cwchar>
|
||||
#include <strsafe.h>
|
||||
#endif // __MINGW32__
|
||||
|
||||
|
@ -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]) ||
|
||||
|
Loading…
x
Reference in New Issue
Block a user