mirror of
https://github.com/libretro/RetroArch
synced 2025-02-07 03:40:24 +00:00
(Discord RPC) Update
This commit is contained in:
parent
3cd320fa83
commit
a6030f89fe
6
deps/discord-rpc/include/discord_rpc.h
vendored
6
deps/discord-rpc/include/discord_rpc.h
vendored
@ -53,9 +53,9 @@ typedef struct DiscordEventHandlers
|
||||
#define DISCORD_REPLY_IGNORE 2
|
||||
|
||||
DISCORD_EXPORT void Discord_Initialize(const char* applicationId,
|
||||
DiscordEventHandlers* handlers,
|
||||
int autoRegister,
|
||||
const char* optionalSteamId);
|
||||
DiscordEventHandlers* handlers,
|
||||
int autoRegister,
|
||||
const char* optionalSteamId);
|
||||
DISCORD_EXPORT void Discord_Shutdown(void);
|
||||
|
||||
/* checks for incoming messages, dispatches callbacks */
|
||||
|
55
deps/discord-rpc/src/backoff.h
vendored
55
deps/discord-rpc/src/backoff.h
vendored
@ -5,37 +5,36 @@
|
||||
#include <stdint.h>
|
||||
#include <time.h>
|
||||
|
||||
struct Backoff
|
||||
{
|
||||
int64_t minAmount;
|
||||
int64_t maxAmount;
|
||||
int64_t current;
|
||||
int fails;
|
||||
std::mt19937_64 randGenerator;
|
||||
std::uniform_real_distribution<> randDistribution;
|
||||
struct Backoff {
|
||||
int64_t minAmount;
|
||||
int64_t maxAmount;
|
||||
int64_t current;
|
||||
int fails;
|
||||
std::mt19937_64 randGenerator;
|
||||
std::uniform_real_distribution<> randDistribution;
|
||||
|
||||
double rand01() { return randDistribution(randGenerator); }
|
||||
double rand01() { return randDistribution(randGenerator); }
|
||||
|
||||
Backoff(int64_t min, int64_t max)
|
||||
Backoff(int64_t min, int64_t max)
|
||||
: minAmount(min)
|
||||
, maxAmount(max)
|
||||
, current(min)
|
||||
, fails(0)
|
||||
, randGenerator((uint64_t)time(0))
|
||||
{
|
||||
}
|
||||
, maxAmount(max)
|
||||
, current(min)
|
||||
, fails(0)
|
||||
, randGenerator((uint64_t)time(0))
|
||||
{
|
||||
}
|
||||
|
||||
void reset()
|
||||
{
|
||||
fails = 0;
|
||||
current = minAmount;
|
||||
}
|
||||
void reset()
|
||||
{
|
||||
fails = 0;
|
||||
current = minAmount;
|
||||
}
|
||||
|
||||
int64_t nextDelay()
|
||||
{
|
||||
++fails;
|
||||
int64_t delay = (int64_t)((double)current * 2.0 * rand01());
|
||||
current = std::min(current + delay, maxAmount);
|
||||
return current;
|
||||
}
|
||||
int64_t nextDelay()
|
||||
{
|
||||
++fails;
|
||||
int64_t delay = (int64_t)((double)current * 2.0 * rand01());
|
||||
current = std::min(current + delay, maxAmount);
|
||||
return current;
|
||||
}
|
||||
};
|
||||
|
19
deps/discord-rpc/src/connection.h
vendored
19
deps/discord-rpc/src/connection.h
vendored
@ -6,15 +6,14 @@
|
||||
#include <stdlib.h>
|
||||
|
||||
/* not really connectiony, but need per-platform */
|
||||
int GetProcessId(void);
|
||||
int GetProcessId();
|
||||
|
||||
struct BaseConnection
|
||||
{
|
||||
static BaseConnection* Create();
|
||||
static void Destroy(BaseConnection*&);
|
||||
bool isOpen{false};
|
||||
bool Open();
|
||||
bool Close();
|
||||
bool Write(const void* data, size_t length);
|
||||
bool Read(void* data, size_t length);
|
||||
struct BaseConnection {
|
||||
static BaseConnection* Create();
|
||||
static void Destroy(BaseConnection*&);
|
||||
bool isOpen{false};
|
||||
bool Open();
|
||||
bool Close();
|
||||
bool Write(const void* data, size_t length);
|
||||
bool Read(void* data, size_t length);
|
||||
};
|
||||
|
10
deps/discord-rpc/src/discord_register_linux.c
vendored
10
deps/discord-rpc/src/discord_register_linux.c
vendored
@ -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);
|
||||
|
76
deps/discord-rpc/src/discord_register_osx.m
vendored
76
deps/discord-rpc/src/discord_register_osx.m
vendored
@ -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
|
||||
@ -29,52 +31,54 @@ static void RegisterCommand(const char* applicationId, const char* command)
|
||||
|
||||
static void RegisterURL(const char* applicationId)
|
||||
{
|
||||
char url[256];
|
||||
snprintf(url, sizeof(url), "discord-%s", applicationId);
|
||||
CFStringRef cfURL = CFStringCreateWithCString(NULL, url, kCFStringEncodingUTF8);
|
||||
NSString* myBundleId = [[NSBundle mainBundle] bundleIdentifier];
|
||||
char url[256];
|
||||
snprintf(url, sizeof(url), "discord-%s", applicationId);
|
||||
CFStringRef cfURL = CFStringCreateWithCString(NULL, url, kCFStringEncodingUTF8);
|
||||
NSString* myBundleId = [[NSBundle mainBundle] bundleIdentifier];
|
||||
|
||||
if (!myBundleId)
|
||||
{
|
||||
fprintf(stderr, "No bundle id found\n");
|
||||
return;
|
||||
}
|
||||
if (!myBundleId)
|
||||
{
|
||||
fprintf(stderr, "No bundle id found\n");
|
||||
return;
|
||||
}
|
||||
|
||||
NSURL* myURL = [[NSBundle mainBundle] bundleURL];
|
||||
if (!myURL)
|
||||
{
|
||||
fprintf(stderr, "No bundle url found\n");
|
||||
return;
|
||||
}
|
||||
NSURL* myURL = [[NSBundle mainBundle] bundleURL];
|
||||
if (!myURL)
|
||||
{
|
||||
fprintf(stderr, "No bundle url found\n");
|
||||
return;
|
||||
}
|
||||
|
||||
OSStatus status = LSSetDefaultHandlerForURLScheme(cfURL, (__bridge CFStringRef)myBundleId);
|
||||
if (status != noErr)
|
||||
{
|
||||
fprintf(stderr, "Error in LSSetDefaultHandlerForURLScheme: %d\n", (int)status);
|
||||
return;
|
||||
}
|
||||
OSStatus status = LSSetDefaultHandlerForURLScheme(cfURL, (__bridge CFStringRef)myBundleId);
|
||||
if (status != noErr)
|
||||
{
|
||||
fprintf(stderr, "Error in LSSetDefaultHandlerForURLScheme: %d\n", (int)status);
|
||||
return;
|
||||
}
|
||||
|
||||
status = LSRegisterURL((__bridge CFURLRef)myURL, true);
|
||||
if (status != noErr)
|
||||
fprintf(stderr, "Error in LSRegisterURL: %d\n", (int)status);
|
||||
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)
|
||||
{
|
||||
if (command)
|
||||
RegisterCommand(applicationId, command);
|
||||
else
|
||||
{
|
||||
/* RAII Lite */
|
||||
@autoreleasepool {
|
||||
RegisterURL(applicationId);
|
||||
}
|
||||
}
|
||||
if (command)
|
||||
RegisterCommand(applicationId, command);
|
||||
else
|
||||
{
|
||||
/* RAII Lite */
|
||||
@autoreleasepool {
|
||||
RegisterURL(applicationId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Discord_RegisterSteamGame(const char* applicationId, const char* steamId)
|
||||
{
|
||||
char command[256];
|
||||
snprintf(command, sizeof(command), "steam://rungameid/%s", steamId);
|
||||
Discord_Register(applicationId, command);
|
||||
char command[256];
|
||||
snprintf(command, sizeof(command), "steam://rungameid/%s", steamId);
|
||||
Discord_Register(applicationId, command);
|
||||
}
|
||||
|
150
deps/discord-rpc/src/discord_register_win.c
vendored
150
deps/discord-rpc/src/discord_register_win.c
vendored
@ -1,4 +1,5 @@
|
||||
#include "discord_rpc.h"
|
||||
#include "discord_register.h"
|
||||
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#define NOMCX
|
||||
@ -52,99 +53,99 @@ static LSTATUS regset(HKEY hkey,
|
||||
const void* data,
|
||||
DWORD len)
|
||||
{
|
||||
LSTATUS ret;
|
||||
HKEY htkey = hkey, hsubkey = NULL;
|
||||
if (subkey && subkey[0])
|
||||
{
|
||||
if ((ret = RegCreateKeyExW(hkey, subkey, 0, 0, 0, KEY_ALL_ACCESS, 0, &hsubkey, 0)) !=
|
||||
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)) !=
|
||||
ERROR_SUCCESS)
|
||||
return ret;
|
||||
htkey = hsubkey;
|
||||
}
|
||||
ret = RegSetValueExW(htkey, name, 0, type, (const BYTE*)data, len);
|
||||
if (hsubkey && hsubkey != hkey)
|
||||
RegCloseKey(hsubkey);
|
||||
return ret;
|
||||
return ret;
|
||||
htkey = hsubkey;
|
||||
}
|
||||
ret = RegSetValueExW(htkey, name, 0, type, (const BYTE*)data, len);
|
||||
if (hsubkey && hsubkey != hkey)
|
||||
RegCloseKey(hsubkey);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void Discord_RegisterW(
|
||||
const wchar_t* applicationId, const wchar_t* command)
|
||||
{
|
||||
/* https://msdn.microsoft.com/en-us/library/aa767914(v=vs.85).aspx
|
||||
* we want to register games so we can run them as discord-<appid>://
|
||||
* Update the HKEY_CURRENT_USER, because it doesn't seem to require special permissions. */
|
||||
/* https://msdn.microsoft.com/en-us/library/aa767914(v=vs.85).aspx
|
||||
* we want to register games so we can run them as discord-<appid>://
|
||||
* Update the HKEY_CURRENT_USER, because it doesn't seem to require special permissions. */
|
||||
|
||||
DWORD len;
|
||||
LSTATUS result;
|
||||
wchar_t urlProtocol = 0;
|
||||
wchar_t keyName[256];
|
||||
wchar_t protocolName[64];
|
||||
wchar_t protocolDescription[128];
|
||||
wchar_t exeFilePath[MAX_PATH];
|
||||
DWORD exeLen = GetModuleFileNameW(NULL, exeFilePath, MAX_PATH);
|
||||
wchar_t openCommand[1024];
|
||||
DWORD len;
|
||||
LSTATUS result;
|
||||
wchar_t urlProtocol = 0;
|
||||
wchar_t keyName[256];
|
||||
wchar_t protocolName[64];
|
||||
wchar_t protocolDescription[128];
|
||||
wchar_t exeFilePath[MAX_PATH];
|
||||
DWORD exeLen = GetModuleFileNameW(NULL, exeFilePath, MAX_PATH);
|
||||
wchar_t openCommand[1024];
|
||||
|
||||
if (command && command[0])
|
||||
StringCbPrintfW(openCommand, sizeof(openCommand), L"%S", command);
|
||||
else
|
||||
StringCbPrintfW(openCommand, sizeof(openCommand), L"%S", exeFilePath);
|
||||
if (command && command[0])
|
||||
StringCbPrintfW(openCommand, sizeof(openCommand), L"%S", command);
|
||||
else
|
||||
StringCbPrintfW(openCommand, sizeof(openCommand), L"%S", exeFilePath);
|
||||
|
||||
StringCbPrintfW(protocolName, sizeof(protocolName),
|
||||
L"discord-%S", applicationId);
|
||||
StringCbPrintfW(
|
||||
protocolDescription, sizeof(protocolDescription),
|
||||
L"URL:Run game %S protocol", applicationId);
|
||||
StringCbPrintfW(keyName, sizeof(keyName), L"Software\\Classes\\%S", protocolName);
|
||||
HKEY key;
|
||||
LSTATUS status =
|
||||
StringCbPrintfW(protocolName, sizeof(protocolName),
|
||||
L"discord-%S", applicationId);
|
||||
StringCbPrintfW(
|
||||
protocolDescription, sizeof(protocolDescription),
|
||||
L"URL:Run game %S protocol", applicationId);
|
||||
StringCbPrintfW(keyName, sizeof(keyName), L"Software\\Classes\\%S", protocolName);
|
||||
HKEY key;
|
||||
LSTATUS status =
|
||||
RegCreateKeyExW(HKEY_CURRENT_USER, keyName, 0, NULL, 0, KEY_WRITE, NULL, &key, NULL);
|
||||
if (status != ERROR_SUCCESS)
|
||||
{
|
||||
fprintf(stderr, "Error creating key\n");
|
||||
return;
|
||||
}
|
||||
len = (DWORD)lstrlenW(protocolDescription) + 1;
|
||||
result =
|
||||
if (status != ERROR_SUCCESS)
|
||||
{
|
||||
fprintf(stderr, "Error creating key\n");
|
||||
return;
|
||||
}
|
||||
len = (DWORD)lstrlenW(protocolDescription) + 1;
|
||||
result =
|
||||
RegSetKeyValueW(key, NULL, NULL, REG_SZ, protocolDescription, len * sizeof(wchar_t));
|
||||
if (FAILED(result))
|
||||
fprintf(stderr, "Error writing description\n");
|
||||
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));
|
||||
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));
|
||||
if (FAILED(result))
|
||||
fprintf(stderr, "Error writing description\n");
|
||||
|
||||
result = RegSetKeyValueW(
|
||||
key, L"DefaultIcon", NULL, REG_SZ, exeFilePath, (exeLen + 1) * sizeof(wchar_t));
|
||||
if (FAILED(result))
|
||||
fprintf(stderr, "Error writing icon\n");
|
||||
result = RegSetKeyValueW(
|
||||
key, L"DefaultIcon", NULL, REG_SZ, exeFilePath, (exeLen + 1) * sizeof(wchar_t));
|
||||
if (FAILED(result))
|
||||
fprintf(stderr, "Error writing icon\n");
|
||||
|
||||
len = (DWORD)lstrlenW(openCommand) + 1;
|
||||
result = RegSetKeyValueW(
|
||||
key, L"shell\\open\\command", NULL, REG_SZ, openCommand, len * sizeof(wchar_t));
|
||||
if (FAILED(result))
|
||||
fprintf(stderr, "Error writing command\n");
|
||||
RegCloseKey(key);
|
||||
len = (DWORD)lstrlenW(openCommand) + 1;
|
||||
result = RegSetKeyValueW(
|
||||
key, L"shell\\open\\command", NULL, REG_SZ, openCommand, len * sizeof(wchar_t));
|
||||
if (FAILED(result))
|
||||
fprintf(stderr, "Error writing command\n");
|
||||
RegCloseKey(key);
|
||||
}
|
||||
|
||||
void Discord_Register(const char* applicationId, const char* command)
|
||||
{
|
||||
wchar_t appId[32];
|
||||
wchar_t openCommand[1024];
|
||||
const wchar_t* wcommand = NULL;
|
||||
wchar_t openCommand[1024];
|
||||
const wchar_t* wcommand = NULL;
|
||||
wchar_t appId[32];
|
||||
|
||||
MultiByteToWideChar(CP_UTF8, 0, applicationId, -1, appId, 32);
|
||||
MultiByteToWideChar(CP_UTF8, 0, applicationId, -1, appId, 32);
|
||||
if (command && command[0])
|
||||
{
|
||||
const int commandBufferLen =
|
||||
sizeof(openCommand) / sizeof(*openCommand);
|
||||
MultiByteToWideChar(CP_UTF8, 0, command, -1,
|
||||
openCommand, commandBufferLen);
|
||||
wcommand = openCommand;
|
||||
}
|
||||
|
||||
if (command && command[0])
|
||||
{
|
||||
const int commandBufferLen =
|
||||
sizeof(openCommand) / sizeof(*openCommand);
|
||||
MultiByteToWideChar(CP_UTF8, 0, command, -1,
|
||||
openCommand, commandBufferLen);
|
||||
wcommand = openCommand;
|
||||
}
|
||||
|
||||
Discord_RegisterW(appId, wcommand);
|
||||
Discord_RegisterW(appId, wcommand);
|
||||
}
|
||||
|
||||
void Discord_RegisterSteamGame(
|
||||
@ -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;
|
||||
}
|
||||
|
161
deps/discord-rpc/src/discord_rpc.cpp
vendored
161
deps/discord-rpc/src/discord_rpc.cpp
vendored
@ -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,57 +76,57 @@ 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:
|
||||
std::atomic_bool keepRunning{true};
|
||||
std::mutex waitForIOMutex;
|
||||
std::condition_variable waitForIOActivity;
|
||||
std::thread ioThread;
|
||||
class IoThreadHolder {
|
||||
private:
|
||||
std::atomic_bool keepRunning{true};
|
||||
std::mutex waitForIOMutex;
|
||||
std::condition_variable waitForIOActivity;
|
||||
std::thread ioThread;
|
||||
|
||||
public:
|
||||
void Start()
|
||||
{
|
||||
keepRunning.store(true);
|
||||
ioThread = std::thread([&]() {
|
||||
const std::chrono::duration<int64_t, std::milli> maxWait{500LL};
|
||||
Discord_UpdateConnection();
|
||||
while (keepRunning.load()) {
|
||||
std::unique_lock<std::mutex> lock(waitForIOMutex);
|
||||
waitForIOActivity.wait_for(lock, maxWait);
|
||||
Discord_UpdateConnection();
|
||||
}
|
||||
});
|
||||
}
|
||||
public:
|
||||
void Start()
|
||||
{
|
||||
keepRunning.store(true);
|
||||
ioThread = std::thread([&]() {
|
||||
const std::chrono::duration<int64_t, std::milli> maxWait{500LL};
|
||||
Discord_UpdateConnection();
|
||||
while (keepRunning.load()) {
|
||||
std::unique_lock<std::mutex> lock(waitForIOMutex);
|
||||
waitForIOActivity.wait_for(lock, maxWait);
|
||||
Discord_UpdateConnection();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void Notify() { waitForIOActivity.notify_all(); }
|
||||
void Notify() { waitForIOActivity.notify_all(); }
|
||||
|
||||
void Stop()
|
||||
{
|
||||
keepRunning.exchange(false);
|
||||
Notify();
|
||||
if (ioThread.joinable())
|
||||
void Stop()
|
||||
{
|
||||
keepRunning.exchange(false);
|
||||
Notify();
|
||||
if (ioThread.joinable())
|
||||
ioThread.join();
|
||||
}
|
||||
}
|
||||
|
||||
~IoThreadHolder() { Stop(); }
|
||||
~IoThreadHolder() { Stop(); }
|
||||
};
|
||||
#else
|
||||
class IoThreadHolder
|
||||
{
|
||||
public:
|
||||
void Start() {}
|
||||
void Stop() {}
|
||||
void Notify() {}
|
||||
class IoThreadHolder {
|
||||
public:
|
||||
void Start() {}
|
||||
void Stop() {}
|
||||
void Notify() {}
|
||||
};
|
||||
#endif /* DISCORD_DISABLE_IO_THREAD */
|
||||
|
||||
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,18 +160,18 @@ 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");
|
||||
LastErrorCode = GetIntMember(data, "code");
|
||||
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 joinReq = JoinAskQueue.GetNextAddMessage();
|
||||
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)
|
||||
|
4
deps/discord-rpc/src/rpc_connection.cpp
vendored
4
deps/discord-rpc/src/rpc_connection.cpp
vendored
@ -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"))
|
||||
|
4
deps/discord-rpc/src/rpc_connection.h
vendored
4
deps/discord-rpc/src/rpc_connection.h
vendored
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user