Adding user object to READY event (#159)
* Pass the READY event data down in onConnect * Changes made for UE4 and Unity wrappers * Changing object name from joinRequest to DiscordUser
This commit is contained in:
parent
2ce9fe068b
commit
64027b336f
10 changed files with 97 additions and 56 deletions
|
@ -7,7 +7,7 @@ public class DiscordJoinEvent : UnityEngine.Events.UnityEvent<string> { }
|
||||||
public class DiscordSpectateEvent : UnityEngine.Events.UnityEvent<string> { }
|
public class DiscordSpectateEvent : UnityEngine.Events.UnityEvent<string> { }
|
||||||
|
|
||||||
[System.Serializable]
|
[System.Serializable]
|
||||||
public class DiscordJoinRequestEvent : UnityEngine.Events.UnityEvent<DiscordRpc.JoinRequest> { }
|
public class DiscordJoinRequestEvent : UnityEngine.Events.UnityEvent<DiscordRpc.DiscordUser> { }
|
||||||
|
|
||||||
public class DiscordController : MonoBehaviour
|
public class DiscordController : MonoBehaviour
|
||||||
{
|
{
|
||||||
|
@ -16,7 +16,7 @@ public class DiscordController : MonoBehaviour
|
||||||
public string optionalSteamId;
|
public string optionalSteamId;
|
||||||
public int callbackCalls;
|
public int callbackCalls;
|
||||||
public int clickCounter;
|
public int clickCounter;
|
||||||
public DiscordRpc.JoinRequest joinRequest;
|
public DiscordRpc.DiscordUser joinRequest;
|
||||||
public UnityEngine.Events.UnityEvent onConnect;
|
public UnityEngine.Events.UnityEvent onConnect;
|
||||||
public UnityEngine.Events.UnityEvent onDisconnect;
|
public UnityEngine.Events.UnityEvent onDisconnect;
|
||||||
public UnityEngine.Events.UnityEvent hasResponded;
|
public UnityEngine.Events.UnityEvent hasResponded;
|
||||||
|
@ -50,10 +50,10 @@ public class DiscordController : MonoBehaviour
|
||||||
hasResponded.Invoke();
|
hasResponded.Invoke();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ReadyCallback()
|
public void ReadyCallback(ref DiscordRpc.DiscordUser connectedUser)
|
||||||
{
|
{
|
||||||
++callbackCalls;
|
++callbackCalls;
|
||||||
Debug.Log("Discord: ready");
|
Debug.Log(string.Format("Discord: connected to {0}#{1}: {2}", connectedUser.username, connectedUser.discriminator, connectedUser.userId));
|
||||||
onConnect.Invoke();
|
onConnect.Invoke();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -84,7 +84,7 @@ public class DiscordController : MonoBehaviour
|
||||||
onSpectate.Invoke(secret);
|
onSpectate.Invoke(secret);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void RequestCallback(ref DiscordRpc.JoinRequest request)
|
public void RequestCallback(ref DiscordRpc.DiscordUser request)
|
||||||
{
|
{
|
||||||
++callbackCalls;
|
++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));
|
||||||
|
|
|
@ -6,7 +6,7 @@ using System.Text;
|
||||||
public class DiscordRpc
|
public class DiscordRpc
|
||||||
{
|
{
|
||||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
||||||
public delegate void ReadyCallback();
|
public delegate void ReadyCallback(ref DiscordUser connectedUser);
|
||||||
|
|
||||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
||||||
public delegate void DisconnectedCallback(int errorCode, string message);
|
public delegate void DisconnectedCallback(int errorCode, string message);
|
||||||
|
@ -21,7 +21,7 @@ public class DiscordRpc
|
||||||
public delegate void SpectateCallback(string secret);
|
public delegate void SpectateCallback(string secret);
|
||||||
|
|
||||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
||||||
public delegate void RequestCallback(ref JoinRequest request);
|
public delegate void RequestCallback(ref DiscordUser request);
|
||||||
|
|
||||||
public struct EventHandlers
|
public struct EventHandlers
|
||||||
{
|
{
|
||||||
|
@ -54,7 +54,7 @@ public class DiscordRpc
|
||||||
}
|
}
|
||||||
|
|
||||||
[Serializable]
|
[Serializable]
|
||||||
public struct JoinRequest
|
public struct DiscordUser
|
||||||
{
|
{
|
||||||
public string userId;
|
public string userId;
|
||||||
public string username;
|
public string username;
|
||||||
|
|
|
@ -52,14 +52,18 @@ static void updateDiscordPresence()
|
||||||
discordPresence.spectateSecret = "look";
|
discordPresence.spectateSecret = "look";
|
||||||
discordPresence.instance = 0;
|
discordPresence.instance = 0;
|
||||||
Discord_UpdatePresence(&discordPresence);
|
Discord_UpdatePresence(&discordPresence);
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
Discord_ClearPresence();
|
Discord_ClearPresence();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void handleDiscordReady(void)
|
static void handleDiscordReady(const DiscordUser* connectedUser)
|
||||||
{
|
{
|
||||||
printf("\nDiscord: ready\n");
|
printf("\nDiscord: connected to user %s#%s - %s\n",
|
||||||
|
connectedUser->username,
|
||||||
|
connectedUser->discriminator,
|
||||||
|
connectedUser->userId);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void handleDiscordDisconnected(int errcode, const char* message)
|
static void handleDiscordDisconnected(int errcode, const char* message)
|
||||||
|
@ -82,13 +86,13 @@ static void handleDiscordSpectate(const char* secret)
|
||||||
printf("\nDiscord: spectate (%s)\n", secret);
|
printf("\nDiscord: spectate (%s)\n", secret);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void handleDiscordJoinRequest(const DiscordJoinRequest* request)
|
static void handleDiscordJoinRequest(const DiscordUser* request)
|
||||||
{
|
{
|
||||||
int response = -1;
|
int response = -1;
|
||||||
char yn[4];
|
char yn[4];
|
||||||
printf("\nDiscord: join request from %s - %s - %s\n",
|
printf("\nDiscord: join request from %s#%s - %s\n",
|
||||||
request->username,
|
request->username,
|
||||||
request->avatar,
|
request->discriminator,
|
||||||
request->userId);
|
request->userId);
|
||||||
do {
|
do {
|
||||||
printf("Accept? (y/n)");
|
printf("Accept? (y/n)");
|
||||||
|
@ -152,7 +156,8 @@ static void gameLoop()
|
||||||
if (SendPresence) {
|
if (SendPresence) {
|
||||||
printf("Clearing presence information.\n");
|
printf("Clearing presence information.\n");
|
||||||
SendPresence = 0;
|
SendPresence = 0;
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
printf("Restoring presence information.\n");
|
printf("Restoring presence information.\n");
|
||||||
SendPresence = 1;
|
SendPresence = 1;
|
||||||
}
|
}
|
||||||
|
|
Binary file not shown.
|
@ -6,12 +6,22 @@ DEFINE_LOG_CATEGORY(Discord)
|
||||||
|
|
||||||
static UDiscordRpc* self = nullptr;
|
static UDiscordRpc* self = nullptr;
|
||||||
|
|
||||||
static void ReadyHandler()
|
static void ReadyHandler(const DiscordUser* connectedUser)
|
||||||
{
|
{
|
||||||
UE_LOG(Discord, Log, TEXT("Discord connected"));
|
FDiscordUserData ud;
|
||||||
|
ud.userId = ANSI_TO_TCHAR(connectedUser->userId);
|
||||||
|
ud.username = ANSI_TO_TCHAR(connectedUser->username);
|
||||||
|
ud.discriminator = ANSI_TO_TCHAR(connectedUser->discriminator);
|
||||||
|
ud.avatar = ANSI_TO_TCHAR(connectedUser->avatar);
|
||||||
|
UE_LOG(Discord,
|
||||||
|
Log,
|
||||||
|
TEXT("Discord connected to %s - %s#%s"),
|
||||||
|
*ud.userId,
|
||||||
|
*ud.username,
|
||||||
|
*ud.discriminator);
|
||||||
if (self) {
|
if (self) {
|
||||||
self->IsConnected = true;
|
self->IsConnected = true;
|
||||||
self->OnConnected.Broadcast();
|
self->OnConnected.Broadcast(ud);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -52,16 +62,21 @@ static void SpectateGameHandler(const char* spectateSecret)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void JoinRequestHandler(const DiscordJoinRequest* request)
|
static void JoinRequestHandler(const DiscordUser* request)
|
||||||
{
|
{
|
||||||
FDiscordJoinRequestData jr;
|
FDiscordUserData ud;
|
||||||
jr.userId = ANSI_TO_TCHAR(request->userId);
|
ud.userId = ANSI_TO_TCHAR(request->userId);
|
||||||
jr.username = ANSI_TO_TCHAR(request->username);
|
ud.username = ANSI_TO_TCHAR(request->username);
|
||||||
jr.discriminator = ANSI_TO_TCHAR(request->discriminator);
|
ud.discriminator = ANSI_TO_TCHAR(request->discriminator);
|
||||||
jr.avatar = ANSI_TO_TCHAR(request->avatar);
|
ud.avatar = ANSI_TO_TCHAR(request->avatar);
|
||||||
UE_LOG(Discord, Log, TEXT("Discord join request from %s - %s#%s"), *jr.userId, *jr.username, *jr.discriminator);
|
UE_LOG(Discord,
|
||||||
|
Log,
|
||||||
|
TEXT("Discord join request from %s - %s#%s"),
|
||||||
|
*ud.userId,
|
||||||
|
*ud.username,
|
||||||
|
*ud.discriminator);
|
||||||
if (self) {
|
if (self) {
|
||||||
self->OnJoinRequest.Broadcast(jr);
|
self->OnJoinRequest.Broadcast(ud);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -11,7 +11,7 @@
|
||||||
* Ask to join callback data
|
* Ask to join callback data
|
||||||
*/
|
*/
|
||||||
USTRUCT(BlueprintType)
|
USTRUCT(BlueprintType)
|
||||||
struct FDiscordJoinRequestData {
|
struct FDiscordUserData {
|
||||||
GENERATED_USTRUCT_BODY()
|
GENERATED_USTRUCT_BODY()
|
||||||
|
|
||||||
UPROPERTY(BlueprintReadOnly)
|
UPROPERTY(BlueprintReadOnly)
|
||||||
|
@ -27,12 +27,12 @@ struct FDiscordJoinRequestData {
|
||||||
|
|
||||||
DECLARE_LOG_CATEGORY_EXTERN(Discord, Log, All);
|
DECLARE_LOG_CATEGORY_EXTERN(Discord, Log, All);
|
||||||
|
|
||||||
DECLARE_DYNAMIC_MULTICAST_DELEGATE(FDiscordConnected);
|
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FDiscordConnected, const FDiscordUserData&, joinRequest);
|
||||||
DECLARE_DYNAMIC_MULTICAST_DELEGATE_TwoParams(FDiscordDisconnected, int, errorCode, const FString&, errorMessage);
|
DECLARE_DYNAMIC_MULTICAST_DELEGATE_TwoParams(FDiscordDisconnected, int, errorCode, const FString&, errorMessage);
|
||||||
DECLARE_DYNAMIC_MULTICAST_DELEGATE_TwoParams(FDiscordErrored, int, errorCode, const FString&, errorMessage);
|
DECLARE_DYNAMIC_MULTICAST_DELEGATE_TwoParams(FDiscordErrored, int, errorCode, const FString&, errorMessage);
|
||||||
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FDiscordJoin, const FString&, joinSecret);
|
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FDiscordJoin, const FString&, joinSecret);
|
||||||
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FDiscordSpectate, const FString&, spectateSecret);
|
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FDiscordSpectate, const FString&, spectateSecret);
|
||||||
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FDiscordJoinRequest, const FDiscordJoinRequestData&, joinRequest);
|
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FDiscordJoinRequest, const FDiscordUserData&, joinRequest);
|
||||||
|
|
||||||
// clang-format on
|
// clang-format on
|
||||||
|
|
||||||
|
|
|
@ -41,20 +41,20 @@ typedef struct DiscordRichPresence {
|
||||||
int8_t instance;
|
int8_t instance;
|
||||||
} DiscordRichPresence;
|
} DiscordRichPresence;
|
||||||
|
|
||||||
typedef struct DiscordJoinRequest {
|
typedef struct DiscordUser {
|
||||||
const char* userId;
|
const char* userId;
|
||||||
const char* username;
|
const char* username;
|
||||||
const char* discriminator;
|
const char* discriminator;
|
||||||
const char* avatar;
|
const char* avatar;
|
||||||
} DiscordJoinRequest;
|
} DiscordUser;
|
||||||
|
|
||||||
typedef struct DiscordEventHandlers {
|
typedef struct DiscordEventHandlers {
|
||||||
void (*ready)(void);
|
void (*ready)(const DiscordUser* request);
|
||||||
void (*disconnected)(int errorCode, const char* message);
|
void (*disconnected)(int errorCode, const char* message);
|
||||||
void (*errored)(int errorCode, const char* message);
|
void (*errored)(int errorCode, const char* message);
|
||||||
void (*joinGame)(const char* joinSecret);
|
void (*joinGame)(const char* joinSecret);
|
||||||
void (*spectateGame)(const char* spectateSecret);
|
void (*spectateGame)(const char* spectateSecret);
|
||||||
void (*joinRequest)(const DiscordJoinRequest* request);
|
void (*joinRequest)(const DiscordUser* request);
|
||||||
} DiscordEventHandlers;
|
} DiscordEventHandlers;
|
||||||
|
|
||||||
#define DISCORD_REPLY_NO 0
|
#define DISCORD_REPLY_NO 0
|
||||||
|
|
|
@ -32,7 +32,7 @@ struct QueuedMessage {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct JoinRequest {
|
struct User {
|
||||||
// snowflake (64bit int), turned into a ascii decimal string, at most 20 chars +1 null
|
// snowflake (64bit int), turned into a ascii decimal string, at most 20 chars +1 null
|
||||||
// terminator = 21
|
// terminator = 21
|
||||||
char userId[32];
|
char userId[32];
|
||||||
|
@ -64,7 +64,8 @@ static std::mutex PresenceMutex;
|
||||||
static std::mutex HandlerMutex;
|
static std::mutex HandlerMutex;
|
||||||
static QueuedMessage QueuedPresence{};
|
static QueuedMessage QueuedPresence{};
|
||||||
static MsgQueue<QueuedMessage, MessageQueueSize> SendQueue;
|
static MsgQueue<QueuedMessage, MessageQueueSize> SendQueue;
|
||||||
static MsgQueue<JoinRequest, JoinQueueSize> JoinAskQueue;
|
static MsgQueue<User, JoinQueueSize> JoinAskQueue;
|
||||||
|
static User connectedUser;
|
||||||
|
|
||||||
// We want to auto connect, and retry on failure, but not as fast as possible. This does expoential
|
// We want to auto connect, and retry on failure, but not as fast as possible. This does expoential
|
||||||
// backoff from 0.5 seconds to 1 minute
|
// backoff from 0.5 seconds to 1 minute
|
||||||
|
@ -292,7 +293,6 @@ extern "C" DISCORD_EXPORT void Discord_Initialize(const char* applicationId,
|
||||||
}
|
}
|
||||||
|
|
||||||
Handlers = {};
|
Handlers = {};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Connection) {
|
if (Connection) {
|
||||||
|
@ -300,8 +300,27 @@ extern "C" DISCORD_EXPORT void Discord_Initialize(const char* applicationId,
|
||||||
}
|
}
|
||||||
|
|
||||||
Connection = RpcConnection::Create(applicationId);
|
Connection = RpcConnection::Create(applicationId);
|
||||||
Connection->onConnect = []() {
|
Connection->onConnect = [](JsonDocument& readyMessage) {
|
||||||
Discord_UpdateHandlers(&QueuedHandlers);
|
Discord_UpdateHandlers(&QueuedHandlers);
|
||||||
|
auto data = GetObjMember(&readyMessage, "data");
|
||||||
|
auto user = GetObjMember(data, "user");
|
||||||
|
auto userId = GetStrMember(user, "id");
|
||||||
|
auto username = GetStrMember(user, "username");
|
||||||
|
auto avatar = GetStrMember(user, "avatar");
|
||||||
|
if (userId && username) {
|
||||||
|
StringCopy(connectedUser.userId, userId);
|
||||||
|
StringCopy(connectedUser.username, username);
|
||||||
|
auto discriminator = GetStrMember(user, "discriminator");
|
||||||
|
if (discriminator) {
|
||||||
|
StringCopy(connectedUser.discriminator, discriminator);
|
||||||
|
}
|
||||||
|
if (avatar) {
|
||||||
|
StringCopy(connectedUser.avatar, avatar);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
connectedUser.avatar[0] = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
WasJustConnected.exchange(true);
|
WasJustConnected.exchange(true);
|
||||||
ReconnectTimeMs.reset();
|
ReconnectTimeMs.reset();
|
||||||
};
|
};
|
||||||
|
@ -385,7 +404,11 @@ extern "C" DISCORD_EXPORT void Discord_RunCallbacks(void)
|
||||||
if (WasJustConnected.exchange(false)) {
|
if (WasJustConnected.exchange(false)) {
|
||||||
std::lock_guard<std::mutex> guard(HandlerMutex);
|
std::lock_guard<std::mutex> guard(HandlerMutex);
|
||||||
if (Handlers.ready) {
|
if (Handlers.ready) {
|
||||||
Handlers.ready();
|
DiscordUser du{connectedUser.userId,
|
||||||
|
connectedUser.username,
|
||||||
|
connectedUser.discriminator,
|
||||||
|
connectedUser.avatar};
|
||||||
|
Handlers.ready(&du);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -420,8 +443,8 @@ extern "C" DISCORD_EXPORT void Discord_RunCallbacks(void)
|
||||||
{
|
{
|
||||||
std::lock_guard<std::mutex> guard(HandlerMutex);
|
std::lock_guard<std::mutex> guard(HandlerMutex);
|
||||||
if (Handlers.joinRequest) {
|
if (Handlers.joinRequest) {
|
||||||
DiscordJoinRequest djr{req->userId, req->username, req->discriminator, req->avatar};
|
DiscordUser du{req->userId, req->username, req->discriminator, req->avatar};
|
||||||
Handlers.joinRequest(&djr);
|
Handlers.joinRequest(&du);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
JoinAskQueue.CommitSend();
|
JoinAskQueue.CommitSend();
|
||||||
|
@ -439,7 +462,6 @@ extern "C" DISCORD_EXPORT void Discord_RunCallbacks(void)
|
||||||
extern "C" DISCORD_EXPORT void Discord_UpdateHandlers(DiscordEventHandlers* newHandlers)
|
extern "C" DISCORD_EXPORT void Discord_UpdateHandlers(DiscordEventHandlers* newHandlers)
|
||||||
{
|
{
|
||||||
if (newHandlers) {
|
if (newHandlers) {
|
||||||
|
|
||||||
#define HANDLE_EVENT_REGISTRATION(handler_name, event) \
|
#define HANDLE_EVENT_REGISTRATION(handler_name, event) \
|
||||||
if (!Handlers.handler_name && newHandlers->handler_name) { \
|
if (!Handlers.handler_name && newHandlers->handler_name) { \
|
||||||
RegisterForEvent(event); \
|
RegisterForEvent(event); \
|
||||||
|
@ -457,8 +479,7 @@ extern "C" DISCORD_EXPORT void Discord_UpdateHandlers(DiscordEventHandlers* newH
|
||||||
|
|
||||||
Handlers = *newHandlers;
|
Handlers = *newHandlers;
|
||||||
}
|
}
|
||||||
else
|
else {
|
||||||
{
|
|
||||||
std::lock_guard<std::mutex> guard(HandlerMutex);
|
std::lock_guard<std::mutex> guard(HandlerMutex);
|
||||||
Handlers = {};
|
Handlers = {};
|
||||||
}
|
}
|
||||||
|
|
|
@ -42,7 +42,7 @@ void RpcConnection::Open()
|
||||||
if (cmd && evt && !strcmp(cmd, "DISPATCH") && !strcmp(evt, "READY")) {
|
if (cmd && evt && !strcmp(cmd, "DISPATCH") && !strcmp(evt, "READY")) {
|
||||||
state = State::Connected;
|
state = State::Connected;
|
||||||
if (onConnect) {
|
if (onConnect) {
|
||||||
onConnect();
|
onConnect(message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,7 +40,7 @@ struct RpcConnection {
|
||||||
|
|
||||||
BaseConnection* connection{nullptr};
|
BaseConnection* connection{nullptr};
|
||||||
State state{State::Disconnected};
|
State state{State::Disconnected};
|
||||||
void (*onConnect)(){nullptr};
|
void (*onConnect)(JsonDocument& message){nullptr};
|
||||||
void (*onDisconnect)(int errorCode, const char* message){nullptr};
|
void (*onDisconnect)(int errorCode, const char* message){nullptr};
|
||||||
char appId[64]{};
|
char appId[64]{};
|
||||||
int lastErrorCode{0};
|
int lastErrorCode{0};
|
||||||
|
|
Loading…
Reference in a new issue