(Discord RPC) Update

This commit is contained in:
twinaphex 2020-05-22 04:56:53 +02:00
parent 3cd320fa83
commit a6030f89fe
9 changed files with 236 additions and 249 deletions

View File

@ -5,8 +5,7 @@
#include <stdint.h>
#include <time.h>
struct Backoff
{
struct Backoff {
int64_t minAmount;
int64_t maxAmount;
int64_t current;

View File

@ -6,10 +6,9 @@
#include <stdlib.h>
/* not really connectiony, but need per-platform */
int GetProcessId(void);
int GetProcessId();
struct BaseConnection
{
struct BaseConnection {
static BaseConnection* Create();
static void Destroy(BaseConnection*&);
bool isOpen{false};

View File

@ -1,3 +1,5 @@
#include "discord_rpc.h"
#include "discord_register.h"
#include <stdio.h>
#include <errno.h>
@ -11,11 +13,9 @@
#include <file/file_path.h>
#include <compat/strl.h>
#include <discord_rpc.h>
/* we want to register games so we can run them from
* Discord client as discord-<appid>:// */
void Discord_Register(const char *applicationId, const char *command)
void Discord_Register(const char* applicationId, const char* command)
{
FILE* fp;
int fileLen;
@ -82,7 +82,9 @@ void Discord_Register(const char *applicationId, const char *command)
fprintf(stderr, "Failed to register mime handler\n");
}
void Discord_RegisterSteamGame(const char *applicationId, const char *steamId)
void Discord_RegisterSteamGame(
const char* applicationId,
const char* steamId)
{
char command[256];
snprintf(command, sizeof(command), "xdg-open steam://rungameid/%s", steamId);

View File

@ -3,6 +3,8 @@
#import <AppKit/AppKit.h>
#include "../include/discord_register.h"
static void RegisterCommand(const char* applicationId, const char* command)
{
/* There does not appear to be a way to register arbitrary commands on OSX, so instead we'll save the command
@ -56,7 +58,9 @@ static void RegisterURL(const char* applicationId)
status = LSRegisterURL((__bridge CFURLRef)myURL, true);
if (status != noErr)
{
fprintf(stderr, "Error in LSRegisterURL: %d\n", (int)status);
}
}
void Discord_Register(const char* applicationId, const char* command)

View File

@ -1,4 +1,5 @@
#include "discord_rpc.h"
#include "discord_register.h"
#define WIN32_LEAN_AND_MEAN
#define NOMCX
@ -52,8 +53,8 @@ static LSTATUS regset(HKEY hkey,
const void* data,
DWORD len)
{
LSTATUS ret;
HKEY htkey = hkey, hsubkey = NULL;
LSTATUS ret;
if (subkey && subkey[0])
{
if ((ret = RegCreateKeyExW(hkey, subkey, 0, 0, 0, KEY_ALL_ACCESS, 0, &hsubkey, 0)) !=
@ -106,8 +107,9 @@ static void Discord_RegisterW(
len = (DWORD)lstrlenW(protocolDescription) + 1;
result =
RegSetKeyValueW(key, NULL, NULL, REG_SZ, protocolDescription, len * sizeof(wchar_t));
if (FAILED(result))
if (FAILED(result)) {
fprintf(stderr, "Error writing description\n");
}
len = (DWORD)lstrlenW(protocolDescription) + 1;
result = RegSetKeyValueW(key, NULL, L"URL Protocol", REG_SZ, &urlProtocol, sizeof(wchar_t));
@ -129,12 +131,11 @@ static void Discord_RegisterW(
void Discord_Register(const char* applicationId, const char* command)
{
wchar_t appId[32];
wchar_t openCommand[1024];
const wchar_t* wcommand = NULL;
wchar_t appId[32];
MultiByteToWideChar(CP_UTF8, 0, applicationId, -1, appId, 32);
if (command && command[0])
{
const int commandBufferLen =
@ -171,8 +172,7 @@ void Discord_RegisterSteamGame(
status = RegQueryValueExW(key,
L"SteamExe", NULL, NULL, (BYTE*)steamPath, &pathBytes);
RegCloseKey(key);
if (status != ERROR_SUCCESS || pathBytes < 1)
{
if (status != ERROR_SUCCESS || pathBytes < 1) {
fprintf(stderr, "Error reading SteamExe key\n");
return;
}

View File

@ -1,7 +1,7 @@
#include <retro_common_api.h>
#include "discord_rpc.h"
#include "backoff.h"
#include "discord_register.h"
#include "msg_queue.h"
#include "rpc_connection.h"
#include "serialization.h"
@ -15,23 +15,14 @@
#include <thread>
#endif
/* Forward declarations */
#if defined(__cplusplus) && !defined(CXX_BUILD)
extern "C" {
#endif
void Discord_Register(const char *a, const char *b);
void Discord_RegisterSteamGame(const char *a, const char *b);
#if defined(__cplusplus) && !defined(CXX_BUILD)
}
#endif
constexpr size_t MaxMessageSize{16 * 1024};
constexpr size_t MessageQueueSize{8};
constexpr size_t JoinQueueSize{8};
struct QueuedMessage
{
size_t length;
char buffer[16384];
char buffer[MaxMessageSize];
void Copy(const QueuedMessage& other)
{
@ -59,32 +50,25 @@ struct User
* from future changes in these sizes */
};
static int Pid{0};
static int Nonce{1};
static int LastErrorCode{0};
static int LastDisconnectErrorCode{0};
static char JoinGameSecret[256];
static char SpectateGameSecret[256];
static char LastErrorMessage[256];
static char LastDisconnectErrorMessage[256];
static RpcConnection* Connection{nullptr};
static DiscordEventHandlers QueuedHandlers{};
static DiscordEventHandlers Handlers{};
static std::atomic_bool WasJustConnected{false};
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 char JoinGameSecret[256];
static char SpectateGameSecret[256];
static int LastErrorCode{0};
static char LastErrorMessage[256];
static int LastDisconnectErrorCode{0};
static char LastDisconnectErrorMessage[256];
static std::mutex PresenceMutex;
static std::mutex HandlerMutex;
static QueuedMessage QueuedPresence{};
static MsgQueue<QueuedMessage, 8> SendQueue;
static MsgQueue<User, 8> JoinAskQueue;
static MsgQueue<QueuedMessage, MessageQueueSize> SendQueue;
static MsgQueue<User, JoinQueueSize> JoinAskQueue;
static User connectedUser;
/* We want to auto connect, and retry on failure,
@ -92,18 +76,19 @@ static User connectedUser;
* backoff from 0.5 seconds to 1 minute */
static Backoff ReconnectTimeMs(500, 60 * 1000);
static auto NextConnect = std::chrono::system_clock::now();
static int Pid{0};
static int Nonce{1};
#ifndef DISCORD_DISABLE_IO_THREAD
static void Discord_UpdateConnection(void);
class IoThreadHolder
{
private:
class IoThreadHolder {
private:
std::atomic_bool keepRunning{true};
std::mutex waitForIOMutex;
std::condition_variable waitForIOActivity;
std::thread ioThread;
public:
public:
void Start()
{
keepRunning.store(true);
@ -131,9 +116,8 @@ class IoThreadHolder
~IoThreadHolder() { Stop(); }
};
#else
class IoThreadHolder
{
public:
class IoThreadHolder {
public:
void Start() {}
void Stop() {}
void Notify() {}
@ -142,7 +126,7 @@ class IoThreadHolder
static IoThreadHolder* IoThread{nullptr};
static void UpdateReconnectTime(void)
static void UpdateReconnectTime()
{
NextConnect = std::chrono::system_clock::now() +
std::chrono::duration<int64_t, std::milli>{ReconnectTimeMs.nextDelay()};
@ -176,17 +160,17 @@ static void Discord_UpdateConnection(void)
if (!Connection->Read(message))
break;
const char *evtName = GetStrMember(&message, "evt");
const char *nonce = GetStrMember(&message, "nonce");
const char* evtName = GetStrMember(&message, "evt");
const char* nonce = GetStrMember(&message, "nonce");
if (nonce)
{
/* in responses only --
* should use to match up response when needed. */
if (evtName && !strcmp(evtName, "ERROR"))
if (evtName && strcmp(evtName, "ERROR") == 0)
{
JsonValue *data = GetObjMember(&message, "data");
auto data = GetObjMember(&message, "data");
LastErrorCode = GetIntMember(data, "code");
StringCopy(LastErrorMessage, GetStrMember(data, "message", ""));
GotErrorMessage.store(true);
@ -198,40 +182,39 @@ static void Discord_UpdateConnection(void)
if (!evtName)
continue;
JsonValue *data = GetObjMember(&message, "data");
auto data = GetObjMember(&message, "data");
if (!strcmp(evtName, "ACTIVITY_JOIN"))
if (strcmp(evtName, "ACTIVITY_JOIN") == 0)
{
const char *secret = GetStrMember(data, "secret");
auto secret = GetStrMember(data, "secret");
if (secret)
{
StringCopy(JoinGameSecret, secret);
WasJoinGame.store(true);
}
}
else if (!strcmp(evtName, "ACTIVITY_SPECTATE"))
else if (strcmp(evtName, "ACTIVITY_SPECTATE") == 0)
{
const char *secret = GetStrMember(data, "secret");
auto secret = GetStrMember(data, "secret");
if (secret)
{
StringCopy(SpectateGameSecret, secret);
WasSpectateGame.store(true);
}
}
else if (!strcmp(evtName, "ACTIVITY_JOIN_REQUEST"))
else if (strcmp(evtName, "ACTIVITY_JOIN_REQUEST") == 0)
{
JsonValue *user = GetObjMember(data, "user");
const char *userId = GetStrMember(user, "id");
const char *username = GetStrMember(user, "username");
const char *avatar = GetStrMember(user, "avatar");
auto user = GetObjMember(data, "user");
auto userId = GetStrMember(user, "id");
auto username = GetStrMember(user, "username");
auto avatar = GetStrMember(user, "avatar");
auto joinReq = JoinAskQueue.GetNextAddMessage();
if (userId && username && joinReq)
{
StringCopy(joinReq->userId, userId);
StringCopy(joinReq->username, username);
const char *discriminator = GetStrMember(user,
"discriminator");
auto discriminator = GetStrMember(user, "discriminator");
if (discriminator)
StringCopy(joinReq->discriminator, discriminator);
if (avatar)
@ -338,16 +321,16 @@ extern "C" DISCORD_EXPORT void Discord_Initialize(
Connection->onConnect = [](JsonDocument& readyMessage)
{
Discord_UpdateHandlers(&QueuedHandlers);
JsonValue *data = GetObjMember(&readyMessage, "data");
JsonValue *user = GetObjMember(data, "user");
const char *userId = GetStrMember(user, "id");
const char *username = GetStrMember(user, "username");
const char *avatar = GetStrMember(user, "avatar");
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);
const char *discriminator = GetStrMember(user, "discriminator");
auto discriminator = GetStrMember(user, "discriminator");
if (discriminator)
StringCopy(connectedUser.discriminator, discriminator);
if (avatar)

View File

@ -36,8 +36,8 @@ void RpcConnection::Open()
JsonDocument message;
if (Read(message))
{
const char *cmd = GetStrMember(&message, "cmd");
const char *evt = GetStrMember(&message, "evt");
auto cmd = GetStrMember(&message, "cmd");
auto evt = GetStrMember(&message, "evt");
if (cmd && evt
&& !strcmp(cmd, "DISPATCH")
&& !strcmp(evt, "READY"))

View File

@ -5,7 +5,7 @@
/* I took this from the buffer size libuv uses for named pipes;
* I suspect ours would usually be much smaller. */
#define MAX_RPC_FRAMESIZE 65536
constexpr size_t MaxRpcFrameSize = 64 * 1024;
struct RpcConnection
{
@ -33,7 +33,7 @@ struct RpcConnection
struct MessageFrame : public MessageFrameHeader
{
char message[MAX_RPC_FRAMESIZE - sizeof(MessageFrameHeader)];
char message[MaxRpcFrameSize - sizeof(MessageFrameHeader)];
};
enum class State : uint32_t