Compare commits

...

10 Commits

Author SHA1 Message Date
Mason Sciotti
963aa9f3e5
[Maintenance PR for Legacy Gamedevs] Add party privacy enum (#306)
* Add party privacy enum

* Add party privacy enum

* Possible unreal working

* Cast to int
2020-09-21 14:51:48 -07:00
msciotti
e4c0c569ec
Clarify deprecation 2019-11-27 11:26:13 -08:00
IceNinjaman
b6d0a9cdbd wchar.h instead cwchar when compiler is MinGW to prevent weird behavior with vsnwprintf (#277) 2019-11-27 11:24:32 -08:00
msciotti
eff23a770a
add deprecation note to readme 2019-07-10 14:39:38 -07:00
Kenny McCormick
34ce3ac803 fix "destopFileFormat" typo (#283)
resolution for #282
2019-04-30 11:39:14 -07:00
msciotti
c59fd6df20
Revert "Choose pipe number on initialize (#250)"
This reverts commit 4824b20f28b1ebffb2a57881684ef87f76659a6c.
2019-01-24 13:23:35 -08:00
Mason Sciotti
4824b20f28
Choose pipe number on initialize (#250)
* Choose pipe number on initialize

* Get pipe from base connection instance

* UE4 support

* Warnings as errors yelling

* Fix windows connection

* Oops all variables

* maybe this fixes it

* This one actually works!!!!

* Fix double function declaration
2019-01-14 00:16:22 -08:00
Mason Sciotti
4e53fa0392
Fix code signing for macOS 10.10 (#260)
* Fix code signing for macOS 10.10
- Fixes #259

* Maybe this works
2018-12-19 08:40:51 -08:00
Joshua Harrington
d478ed5608 Moved UE setup to be with unity setup (#254) 2018-12-14 16:04:31 -08:00
Jan Bubenik
8db649ba5f Static EventHandler for IL2CPP support (#258)
* Added staticEventHandler which forward the invoke to the actual eventHandler set though Initialize

* Code Formatting - Replaced abs with 4 white spaces
2018-12-14 16:00:47 -08:00
11 changed files with 103 additions and 38 deletions

View File

@ -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:

View File

@ -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);
}

View File

@ -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);

View File

@ -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";

View File

@ -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);

View File

@ -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;

View File

@ -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,

View File

@ -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

View File

@ -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;
}

View File

@ -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__

View File

@ -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]) ||