early-access version 1795
This commit is contained in:
parent
b57607168a
commit
635de11af2
16 changed files with 144 additions and 78 deletions
|
@ -1,7 +1,7 @@
|
||||||
yuzu emulator early access
|
yuzu emulator early access
|
||||||
=============
|
=============
|
||||||
|
|
||||||
This is the source code for early-access 1794.
|
This is the source code for early-access 1795.
|
||||||
|
|
||||||
## Legal Notice
|
## Legal Notice
|
||||||
|
|
||||||
|
|
2
externals/discord-rpc/.travis.yml
vendored
2
externals/discord-rpc/.travis.yml
vendored
|
@ -43,5 +43,5 @@ before_install:
|
||||||
script:
|
script:
|
||||||
- mkdir build
|
- mkdir build
|
||||||
- cd build
|
- cd build
|
||||||
- cmake -DCLANG_FORMAT_SUFFIX=$CLANG_FORMAT_SUFFIX --config Release ..
|
- cmake -DCLANG_FORMAT_SUFFIX=$CLANG_FORMAT_SUFFIX -DWARNINGS_AS_ERRORS=On --config Release ..
|
||||||
- cmake --build . -- -j2
|
- cmake --build . -- -j2
|
||||||
|
|
66
externals/discord-rpc/README.md
vendored
66
externals/discord-rpc/README.md
vendored
|
@ -1,5 +1,11 @@
|
||||||
# Discord RPC
|
# 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.
|
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
|
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.
|
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
|
### 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:
|
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/`
|
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/`
|
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
|
7. Click on both DLLs and make sure they are targetting the correct architectures in the Unity editor properties pane
|
||||||
8. Done!
|
8. Done!
|
||||||
|
|
||||||
#### MacOS
|
#### MacOS
|
||||||
|
|
||||||
4. Copy `discord-rpc-osx/osx-dynamic/lib/libdiscord-rpc.dylib` to `Assets/Plugins/`
|
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!
|
6. Done!
|
||||||
|
|
||||||
#### Linux
|
#### 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.
|
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
|
## 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:
|
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:
|
||||||
|
@ -141,7 +147,7 @@ Below is a table of unofficial, community-developed wrappers for and implementat
|
||||||
| Name | Language |
|
| Name | Language |
|
||||||
| ------------------------------------------------------------------------- | --------------------------------- |
|
| ------------------------------------------------------------------------- | --------------------------------- |
|
||||||
| [Discord RPC C#](https://github.com/Lachee/discord-rpc-csharp) | C# |
|
| [Discord RPC C#](https://github.com/Lachee/discord-rpc-csharp) | C# |
|
||||||
| [DerelictDiscordRPC](https://github.com/voidblaster/DerelictDiscordRPC) | [D](https://dlang.org/) |
|
| [Discord RPC D](https://github.com/voidblaster/discord-rpc-d) | [D](https://dlang.org/) |
|
||||||
| [discord-rpc.jar](https://github.com/Vatuu/discord-rpc 'Discord-RPC.jar') | Java |
|
| [discord-rpc.jar](https://github.com/Vatuu/discord-rpc 'Discord-RPC.jar') | Java |
|
||||||
| [java-discord-rpc](https://github.com/MinnDevelopment/java-discord-rpc) | Java |
|
| [java-discord-rpc](https://github.com/MinnDevelopment/java-discord-rpc) | Java |
|
||||||
| [Discord-IPC](https://github.com/jagrosh/DiscordIPC) | Java |
|
| [Discord-IPC](https://github.com/jagrosh/DiscordIPC) | Java |
|
||||||
|
|
|
@ -14,7 +14,6 @@ public class DiscordController : MonoBehaviour
|
||||||
public DiscordRpc.RichPresence presence = new DiscordRpc.RichPresence();
|
public DiscordRpc.RichPresence presence = new DiscordRpc.RichPresence();
|
||||||
public string applicationId;
|
public string applicationId;
|
||||||
public string optionalSteamId;
|
public string optionalSteamId;
|
||||||
public int callbackCalls;
|
|
||||||
public int clickCounter;
|
public int clickCounter;
|
||||||
public DiscordRpc.DiscordUser joinRequest;
|
public DiscordRpc.DiscordUser joinRequest;
|
||||||
public UnityEngine.Events.UnityEvent onConnect;
|
public UnityEngine.Events.UnityEvent onConnect;
|
||||||
|
@ -32,6 +31,11 @@ public class DiscordController : MonoBehaviour
|
||||||
clickCounter++;
|
clickCounter++;
|
||||||
|
|
||||||
presence.details = string.Format("Button clicked {0} times", 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);
|
DiscordRpc.UpdatePresence(presence);
|
||||||
}
|
}
|
||||||
|
@ -52,41 +56,35 @@ public class DiscordController : MonoBehaviour
|
||||||
|
|
||||||
public void ReadyCallback(ref DiscordRpc.DiscordUser connectedUser)
|
public void ReadyCallback(ref DiscordRpc.DiscordUser connectedUser)
|
||||||
{
|
{
|
||||||
++callbackCalls;
|
|
||||||
Debug.Log(string.Format("Discord: connected to {0}#{1}: {2}", connectedUser.username, connectedUser.discriminator, connectedUser.userId));
|
Debug.Log(string.Format("Discord: connected to {0}#{1}: {2}", connectedUser.username, connectedUser.discriminator, connectedUser.userId));
|
||||||
onConnect.Invoke();
|
onConnect.Invoke();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void DisconnectedCallback(int errorCode, string message)
|
public void DisconnectedCallback(int errorCode, string message)
|
||||||
{
|
{
|
||||||
++callbackCalls;
|
|
||||||
Debug.Log(string.Format("Discord: disconnect {0}: {1}", errorCode, message));
|
Debug.Log(string.Format("Discord: disconnect {0}: {1}", errorCode, message));
|
||||||
onDisconnect.Invoke();
|
onDisconnect.Invoke();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ErrorCallback(int errorCode, string message)
|
public void ErrorCallback(int errorCode, string message)
|
||||||
{
|
{
|
||||||
++callbackCalls;
|
|
||||||
Debug.Log(string.Format("Discord: error {0}: {1}", errorCode, message));
|
Debug.Log(string.Format("Discord: error {0}: {1}", errorCode, message));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void JoinCallback(string secret)
|
public void JoinCallback(string secret)
|
||||||
{
|
{
|
||||||
++callbackCalls;
|
|
||||||
Debug.Log(string.Format("Discord: join ({0})", secret));
|
Debug.Log(string.Format("Discord: join ({0})", secret));
|
||||||
onJoin.Invoke(secret);
|
onJoin.Invoke(secret);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SpectateCallback(string secret)
|
public void SpectateCallback(string secret)
|
||||||
{
|
{
|
||||||
++callbackCalls;
|
|
||||||
Debug.Log(string.Format("Discord: spectate ({0})", secret));
|
Debug.Log(string.Format("Discord: spectate ({0})", secret));
|
||||||
onSpectate.Invoke(secret);
|
onSpectate.Invoke(secret);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void RequestCallback(ref DiscordRpc.DiscordUser request)
|
public void RequestCallback(ref DiscordRpc.DiscordUser request)
|
||||||
{
|
{
|
||||||
++callbackCalls;
|
|
||||||
Debug.Log(string.Format("Discord: join request {0}#{1}: {2}", request.username, request.discriminator, request.userId));
|
Debug.Log(string.Format("Discord: join request {0}#{1}: {2}", request.username, request.discriminator, request.userId));
|
||||||
joinRequest = request;
|
joinRequest = request;
|
||||||
onJoinRequest.Invoke(request);
|
onJoinRequest.Invoke(request);
|
||||||
|
@ -104,10 +102,8 @@ public class DiscordController : MonoBehaviour
|
||||||
void OnEnable()
|
void OnEnable()
|
||||||
{
|
{
|
||||||
Debug.Log("Discord: init");
|
Debug.Log("Discord: init");
|
||||||
callbackCalls = 0;
|
|
||||||
|
|
||||||
handlers = new DiscordRpc.EventHandlers();
|
handlers = new DiscordRpc.EventHandlers();
|
||||||
handlers.readyCallback = ReadyCallback;
|
handlers.readyCallback += ReadyCallback;
|
||||||
handlers.disconnectedCallback += DisconnectedCallback;
|
handlers.disconnectedCallback += DisconnectedCallback;
|
||||||
handlers.errorCallback += ErrorCallback;
|
handlers.errorCallback += ErrorCallback;
|
||||||
handlers.joinCallback += JoinCallback;
|
handlers.joinCallback += JoinCallback;
|
||||||
|
|
|
@ -2,35 +2,44 @@
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
using AOT;
|
||||||
|
|
||||||
public class DiscordRpc
|
public class DiscordRpc
|
||||||
{
|
{
|
||||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
[MonoPInvokeCallback(typeof(OnReadyInfo))]
|
||||||
public delegate void ReadyCallback(ref DiscordUser connectedUser);
|
public static void ReadyCallback(ref DiscordUser connectedUser) { Callbacks.readyCallback(ref connectedUser); }
|
||||||
|
public delegate void OnReadyInfo(ref DiscordUser connectedUser);
|
||||||
|
|
||||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
[MonoPInvokeCallback(typeof(OnDisconnectedInfo))]
|
||||||
public delegate 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);
|
||||||
|
|
||||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
[MonoPInvokeCallback(typeof(OnErrorInfo))]
|
||||||
public delegate 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);
|
||||||
|
|
||||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
[MonoPInvokeCallback(typeof(OnJoinInfo))]
|
||||||
public delegate void JoinCallback(string secret);
|
public static void JoinCallback(string secret) { Callbacks.joinCallback(secret); }
|
||||||
|
public delegate void OnJoinInfo(string secret);
|
||||||
|
|
||||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
[MonoPInvokeCallback(typeof(OnSpectateInfo))]
|
||||||
public delegate void SpectateCallback(string secret);
|
public static void SpectateCallback(string secret) { Callbacks.spectateCallback(secret); }
|
||||||
|
public delegate void OnSpectateInfo(string secret);
|
||||||
|
|
||||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
[MonoPInvokeCallback(typeof(OnRequestInfo))]
|
||||||
public delegate 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 struct EventHandlers
|
||||||
{
|
{
|
||||||
public ReadyCallback readyCallback;
|
public OnReadyInfo readyCallback;
|
||||||
public DisconnectedCallback disconnectedCallback;
|
public OnDisconnectedInfo disconnectedCallback;
|
||||||
public ErrorCallback errorCallback;
|
public OnErrorInfo errorCallback;
|
||||||
public JoinCallback joinCallback;
|
public OnJoinInfo joinCallback;
|
||||||
public SpectateCallback spectateCallback;
|
public OnSpectateInfo spectateCallback;
|
||||||
public RequestCallback requestCallback;
|
public OnRequestInfo requestCallback;
|
||||||
}
|
}
|
||||||
|
|
||||||
[Serializable, StructLayout(LayoutKind.Sequential)]
|
[Serializable, StructLayout(LayoutKind.Sequential)]
|
||||||
|
@ -47,6 +56,7 @@ public class DiscordRpc
|
||||||
public IntPtr partyId; /* max 128 bytes */
|
public IntPtr partyId; /* max 128 bytes */
|
||||||
public int partySize;
|
public int partySize;
|
||||||
public int partyMax;
|
public int partyMax;
|
||||||
|
public int partyPrivacy;
|
||||||
public IntPtr matchSecret; /* max 128 bytes */
|
public IntPtr matchSecret; /* max 128 bytes */
|
||||||
public IntPtr joinSecret; /* max 128 bytes */
|
public IntPtr joinSecret; /* max 128 bytes */
|
||||||
public IntPtr spectateSecret; /* max 128 bytes */
|
public IntPtr spectateSecret; /* max 128 bytes */
|
||||||
|
@ -69,8 +79,29 @@ public class DiscordRpc
|
||||||
Ignore = 2
|
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)]
|
[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)]
|
[DllImport("discord-rpc", EntryPoint = "Discord_Shutdown", CallingConvention = CallingConvention.Cdecl)]
|
||||||
public static extern void Shutdown();
|
public static extern void Shutdown();
|
||||||
|
@ -113,6 +144,7 @@ public class DiscordRpc
|
||||||
public string partyId; /* max 128 bytes */
|
public string partyId; /* max 128 bytes */
|
||||||
public int partySize;
|
public int partySize;
|
||||||
public int partyMax;
|
public int partyMax;
|
||||||
|
public PartyPrivacy partyPrivacy;
|
||||||
public string matchSecret; /* max 128 bytes */
|
public string matchSecret; /* max 128 bytes */
|
||||||
public string joinSecret; /* max 128 bytes */
|
public string joinSecret; /* max 128 bytes */
|
||||||
public string spectateSecret; /* max 128 bytes */
|
public string spectateSecret; /* max 128 bytes */
|
||||||
|
@ -140,6 +172,7 @@ public class DiscordRpc
|
||||||
_presence.partyId = StrToPtr(partyId);
|
_presence.partyId = StrToPtr(partyId);
|
||||||
_presence.partySize = partySize;
|
_presence.partySize = partySize;
|
||||||
_presence.partyMax = partyMax;
|
_presence.partyMax = partyMax;
|
||||||
|
_presence.partyPrivacy = (int)partyPrivacy;
|
||||||
_presence.matchSecret = StrToPtr(matchSecret);
|
_presence.matchSecret = StrToPtr(matchSecret);
|
||||||
_presence.joinSecret = StrToPtr(joinSecret);
|
_presence.joinSecret = StrToPtr(joinSecret);
|
||||||
_presence.spectateSecret = StrToPtr(spectateSecret);
|
_presence.spectateSecret = StrToPtr(spectateSecret);
|
||||||
|
@ -160,7 +193,7 @@ public class DiscordRpc
|
||||||
var buffer = Marshal.AllocHGlobal(convbytecnt + 1);
|
var buffer = Marshal.AllocHGlobal(convbytecnt + 1);
|
||||||
for (int i = 0; i < convbytecnt + 1; i++)
|
for (int i = 0; i < convbytecnt + 1; i++)
|
||||||
{
|
{
|
||||||
Marshal.WriteByte(buffer, i , 0);
|
Marshal.WriteByte(buffer, i, 0);
|
||||||
}
|
}
|
||||||
_buffers.Add(buffer);
|
_buffers.Add(buffer);
|
||||||
Marshal.Copy(Encoding.UTF8.GetBytes(input), 0, buffer, convbytecnt);
|
Marshal.Copy(Encoding.UTF8.GetBytes(input), 0, buffer, convbytecnt);
|
||||||
|
|
|
@ -47,6 +47,7 @@ static void updateDiscordPresence()
|
||||||
discordPresence.partyId = "party1234";
|
discordPresence.partyId = "party1234";
|
||||||
discordPresence.partySize = 1;
|
discordPresence.partySize = 1;
|
||||||
discordPresence.partyMax = 6;
|
discordPresence.partyMax = 6;
|
||||||
|
discordPresence.partyPrivacy = DISCORD_PARTY_PUBLIC;
|
||||||
discordPresence.matchSecret = "xyzzy";
|
discordPresence.matchSecret = "xyzzy";
|
||||||
discordPresence.joinSecret = "join";
|
discordPresence.joinSecret = "join";
|
||||||
discordPresence.spectateSecret = "look";
|
discordPresence.spectateSecret = "look";
|
||||||
|
|
|
@ -153,6 +153,7 @@ void UDiscordRpc::UpdatePresence()
|
||||||
rp.endTimestamp = RichPresence.endTimestamp;
|
rp.endTimestamp = RichPresence.endTimestamp;
|
||||||
rp.partySize = RichPresence.partySize;
|
rp.partySize = RichPresence.partySize;
|
||||||
rp.partyMax = RichPresence.partyMax;
|
rp.partyMax = RichPresence.partyMax;
|
||||||
|
rp.partyPrivacy = (int)RichPresence.partyPrivacy;
|
||||||
rp.instance = RichPresence.instance;
|
rp.instance = RichPresence.instance;
|
||||||
|
|
||||||
Discord_UpdatePresence(&rp);
|
Discord_UpdatePresence(&rp);
|
||||||
|
|
|
@ -35,6 +35,16 @@ enum class EDiscordJoinResponseCodes : uint8
|
||||||
DISCORD_REPLY_IGNORE UMETA(DisplayName="Ignore")
|
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_LOG_CATEGORY_EXTERN(Discord, Log, All);
|
||||||
|
|
||||||
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FDiscordConnected, const FDiscordUserData&, joinRequest);
|
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FDiscordConnected, const FDiscordUserData&, joinRequest);
|
||||||
|
@ -77,6 +87,8 @@ struct FDiscordRichPresence {
|
||||||
UPROPERTY(BlueprintReadWrite)
|
UPROPERTY(BlueprintReadWrite)
|
||||||
int partyMax;
|
int partyMax;
|
||||||
UPROPERTY(BlueprintReadWrite)
|
UPROPERTY(BlueprintReadWrite)
|
||||||
|
EDiscordPartyPrivacy partyPrivacy;
|
||||||
|
UPROPERTY(BlueprintReadWrite)
|
||||||
FString matchSecret;
|
FString matchSecret;
|
||||||
UPROPERTY(BlueprintReadWrite)
|
UPROPERTY(BlueprintReadWrite)
|
||||||
FString joinSecret;
|
FString joinSecret;
|
||||||
|
|
3
externals/discord-rpc/include/discord_rpc.h
vendored
3
externals/discord-rpc/include/discord_rpc.h
vendored
|
@ -35,6 +35,7 @@ typedef struct DiscordRichPresence {
|
||||||
const char* partyId; /* max 128 bytes */
|
const char* partyId; /* max 128 bytes */
|
||||||
int partySize;
|
int partySize;
|
||||||
int partyMax;
|
int partyMax;
|
||||||
|
int partyPrivacy;
|
||||||
const char* matchSecret; /* max 128 bytes */
|
const char* matchSecret; /* max 128 bytes */
|
||||||
const char* joinSecret; /* max 128 bytes */
|
const char* joinSecret; /* max 128 bytes */
|
||||||
const char* spectateSecret; /* max 128 bytes */
|
const char* spectateSecret; /* max 128 bytes */
|
||||||
|
@ -60,6 +61,8 @@ typedef struct DiscordEventHandlers {
|
||||||
#define DISCORD_REPLY_NO 0
|
#define DISCORD_REPLY_NO 0
|
||||||
#define DISCORD_REPLY_YES 1
|
#define DISCORD_REPLY_YES 1
|
||||||
#define DISCORD_REPLY_IGNORE 2
|
#define DISCORD_REPLY_IGNORE 2
|
||||||
|
#define DISCORD_PARTY_PRIVATE 0
|
||||||
|
#define DISCORD_PARTY_PUBLIC 1
|
||||||
|
|
||||||
DISCORD_EXPORT void Discord_Initialize(const char* applicationId,
|
DISCORD_EXPORT void Discord_Initialize(const char* applicationId,
|
||||||
DiscordEventHandlers* handlers,
|
DiscordEventHandlers* handlers,
|
||||||
|
|
5
externals/discord-rpc/src/CMakeLists.txt
vendored
5
externals/discord-rpc/src/CMakeLists.txt
vendored
|
@ -72,6 +72,11 @@ if(UNIX)
|
||||||
|
|
||||||
add_library(discord-rpc ${BASE_RPC_SRC})
|
add_library(discord-rpc ${BASE_RPC_SRC})
|
||||||
target_link_libraries(discord-rpc PUBLIC pthread)
|
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
|
target_compile_options(discord-rpc PRIVATE
|
||||||
-g
|
-g
|
||||||
-Wall
|
-Wall
|
||||||
|
|
|
@ -118,5 +118,8 @@ bool BaseConnection::Read(void* data, size_t length)
|
||||||
}
|
}
|
||||||
Close();
|
Close();
|
||||||
}
|
}
|
||||||
|
else if (res == 0) {
|
||||||
|
Close();
|
||||||
|
}
|
||||||
return res == (int)length;
|
return res == (int)length;
|
||||||
}
|
}
|
||||||
|
|
|
@ -41,7 +41,7 @@ extern "C" DISCORD_EXPORT void Discord_Register(const char* applicationId, const
|
||||||
command = exePath;
|
command = exePath;
|
||||||
}
|
}
|
||||||
|
|
||||||
const char* destopFileFormat = "[Desktop Entry]\n"
|
const char* desktopFileFormat = "[Desktop Entry]\n"
|
||||||
"Name=Game %s\n"
|
"Name=Game %s\n"
|
||||||
"Exec=%s %%u\n" // note: it really wants that %u in there
|
"Exec=%s %%u\n" // note: it really wants that %u in there
|
||||||
"Type=Application\n"
|
"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";
|
"MimeType=x-scheme-handler/discord-%s;\n";
|
||||||
char desktopFile[2048];
|
char desktopFile[2048];
|
||||||
int fileLen = snprintf(
|
int fileLen = snprintf(
|
||||||
desktopFile, sizeof(desktopFile), destopFileFormat, applicationId, command, applicationId);
|
desktopFile, sizeof(desktopFile), desktopFileFormat, applicationId, command, applicationId);
|
||||||
if (fileLen <= 0) {
|
if (fileLen <= 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,7 +7,6 @@
|
||||||
#define NOIME
|
#define NOIME
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
#include <psapi.h>
|
#include <psapi.h>
|
||||||
#include <cwchar>
|
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -20,6 +19,7 @@
|
||||||
* The entire function is rewritten
|
* The entire function is rewritten
|
||||||
*/
|
*/
|
||||||
#ifdef __MINGW32__
|
#ifdef __MINGW32__
|
||||||
|
#include <wchar.h>
|
||||||
/// strsafe.h fixes
|
/// strsafe.h fixes
|
||||||
static HRESULT StringCbPrintfW(LPWSTR pszDest, size_t cbDest, LPCWSTR pszFormat, ...)
|
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;
|
return ret;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
|
#include <cwchar>
|
||||||
#include <strsafe.h>
|
#include <strsafe.h>
|
||||||
#endif // __MINGW32__
|
#endif // __MINGW32__
|
||||||
|
|
||||||
|
|
16
externals/discord-rpc/src/discord_rpc.cpp
vendored
16
externals/discord-rpc/src/discord_rpc.cpp
vendored
|
@ -54,6 +54,7 @@ static std::atomic_bool WasJustDisconnected{false};
|
||||||
static std::atomic_bool GotErrorMessage{false};
|
static std::atomic_bool GotErrorMessage{false};
|
||||||
static std::atomic_bool WasJoinGame{false};
|
static std::atomic_bool WasJoinGame{false};
|
||||||
static std::atomic_bool WasSpectateGame{false};
|
static std::atomic_bool WasSpectateGame{false};
|
||||||
|
static std::atomic_bool UpdatePresence{false};
|
||||||
static char JoinGameSecret[256];
|
static char JoinGameSecret[256];
|
||||||
static char SpectateGameSecret[256];
|
static char SpectateGameSecret[256];
|
||||||
static int LastErrorCode{0};
|
static int LastErrorCode{0};
|
||||||
|
@ -214,17 +215,17 @@ static void Discord_UpdateConnection(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
// writes
|
// writes
|
||||||
if (QueuedPresence.length) {
|
if (UpdatePresence.exchange(false) && QueuedPresence.length) {
|
||||||
QueuedMessage local;
|
QueuedMessage local;
|
||||||
{
|
{
|
||||||
std::lock_guard<std::mutex> guard(PresenceMutex);
|
std::lock_guard<std::mutex> guard(PresenceMutex);
|
||||||
local.Copy(QueuedPresence);
|
local.Copy(QueuedPresence);
|
||||||
QueuedPresence.length = 0;
|
|
||||||
}
|
}
|
||||||
if (!Connection->Write(local.buffer, local.length)) {
|
if (!Connection->Write(local.buffer, local.length)) {
|
||||||
// if we fail to send, requeue
|
// if we fail to send, requeue
|
||||||
std::lock_guard<std::mutex> guard(PresenceMutex);
|
std::lock_guard<std::mutex> guard(PresenceMutex);
|
||||||
QueuedPresence.Copy(local);
|
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 = RpcConnection::Create(applicationId);
|
||||||
Connection->onConnect = [](JsonDocument& readyMessage) {
|
Connection->onConnect = [](JsonDocument& readyMessage) {
|
||||||
Discord_UpdateHandlers(&QueuedHandlers);
|
Discord_UpdateHandlers(&QueuedHandlers);
|
||||||
|
if (QueuedPresence.length > 0) {
|
||||||
|
UpdatePresence.exchange(true);
|
||||||
|
SignalIOActivity();
|
||||||
|
}
|
||||||
auto data = GetObjMember(&readyMessage, "data");
|
auto data = GetObjMember(&readyMessage, "data");
|
||||||
auto user = GetObjMember(data, "user");
|
auto user = GetObjMember(data, "user");
|
||||||
auto userId = GetStrMember(user, "id");
|
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) {
|
Connection->onDisconnect = [](int err, const char* message) {
|
||||||
LastDisconnectErrorCode = err;
|
LastDisconnectErrorCode = err;
|
||||||
StringCopy(LastDisconnectErrorMessage, message);
|
StringCopy(LastDisconnectErrorMessage, message);
|
||||||
{
|
|
||||||
std::lock_guard<std::mutex> guard(HandlerMutex);
|
|
||||||
Handlers = {};
|
|
||||||
}
|
|
||||||
WasJustDisconnected.exchange(true);
|
WasJustDisconnected.exchange(true);
|
||||||
UpdateReconnectTime();
|
UpdateReconnectTime();
|
||||||
};
|
};
|
||||||
|
@ -354,6 +355,8 @@ extern "C" DISCORD_EXPORT void Discord_Shutdown(void)
|
||||||
Connection->onConnect = nullptr;
|
Connection->onConnect = nullptr;
|
||||||
Connection->onDisconnect = nullptr;
|
Connection->onDisconnect = nullptr;
|
||||||
Handlers = {};
|
Handlers = {};
|
||||||
|
QueuedPresence.length = 0;
|
||||||
|
UpdatePresence.exchange(false);
|
||||||
if (IoThread != nullptr) {
|
if (IoThread != nullptr) {
|
||||||
IoThread->Stop();
|
IoThread->Stop();
|
||||||
delete IoThread;
|
delete IoThread;
|
||||||
|
@ -369,6 +372,7 @@ extern "C" DISCORD_EXPORT void Discord_UpdatePresence(const DiscordRichPresence*
|
||||||
std::lock_guard<std::mutex> guard(PresenceMutex);
|
std::lock_guard<std::mutex> guard(PresenceMutex);
|
||||||
QueuedPresence.length = JsonWriteRichPresenceObj(
|
QueuedPresence.length = JsonWriteRichPresenceObj(
|
||||||
QueuedPresence.buffer, sizeof(QueuedPresence.buffer), Nonce++, Pid, presence);
|
QueuedPresence.buffer, sizeof(QueuedPresence.buffer), Nonce++, Pid, presence);
|
||||||
|
UpdatePresence.exchange(true);
|
||||||
}
|
}
|
||||||
SignalIOActivity();
|
SignalIOActivity();
|
||||||
}
|
}
|
||||||
|
|
8
externals/discord-rpc/src/rpc_connection.cpp
vendored
8
externals/discord-rpc/src/rpc_connection.cpp
vendored
|
@ -26,12 +26,8 @@ void RpcConnection::Open()
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (state == State::Disconnected) {
|
if (state == State::Disconnected && !connection->Open()) {
|
||||||
if (connection->Open()) {
|
return;
|
||||||
}
|
|
||||||
else {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (state == State::SentHandshake) {
|
if (state == State::SentHandshake) {
|
||||||
|
|
7
externals/discord-rpc/src/serialization.cpp
vendored
7
externals/discord-rpc/src/serialization.cpp
vendored
|
@ -134,7 +134,7 @@ size_t JsonWriteRichPresenceObj(char* dest,
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((presence->partyId && presence->partyId[0]) || presence->partySize ||
|
if ((presence->partyId && presence->partyId[0]) || presence->partySize ||
|
||||||
presence->partyMax) {
|
presence->partyMax || presence->partyPrivacy) {
|
||||||
WriteObject party(writer, "party");
|
WriteObject party(writer, "party");
|
||||||
WriteOptionalString(writer, "id", presence->partyId);
|
WriteOptionalString(writer, "id", presence->partyId);
|
||||||
if (presence->partySize && presence->partyMax) {
|
if (presence->partySize && presence->partyMax) {
|
||||||
|
@ -142,6 +142,11 @@ size_t JsonWriteRichPresenceObj(char* dest,
|
||||||
writer.Int(presence->partySize);
|
writer.Int(presence->partySize);
|
||||||
writer.Int(presence->partyMax);
|
writer.Int(presence->partyMax);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (presence->partyPrivacy) {
|
||||||
|
WriteKey(writer, "privacy");
|
||||||
|
writer.Int(presence->partyPrivacy);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((presence->matchSecret && presence->matchSecret[0]) ||
|
if ((presence->matchSecret && presence->matchSecret[0]) ||
|
||||||
|
|
Loading…
Reference in a new issue