diff --git a/src/connection.h b/src/connection.h index c59f0a1..6f57ddf 100644 --- a/src/connection.h +++ b/src/connection.h @@ -4,16 +4,24 @@ #include +enum class OPCODE : uint32_t { + HANDSHAKE = 0, + FRAME = 1, + CLOSE = 2, +}; + struct RpcMessageFrame { + OPCODE opcode; uint32_t length; - char message[64 * 1024 - sizeof(uint32_t)]; + char message[64 * 1024 - 8]; }; struct RpcConnection { void (*onConnect)() = nullptr; void (*onDisconnect)() = nullptr; + char appId[64]; - static RpcConnection* Create(); + static RpcConnection* Create(const char* applicationId); static void Destroy(RpcConnection*&); void Open(); void Close(); diff --git a/src/connection_win_sync.cpp b/src/connection_win_sync.cpp index 5c81bb6..866a6a2 100644 --- a/src/connection_win_sync.cpp +++ b/src/connection_win_sync.cpp @@ -8,16 +8,22 @@ #define NOIME #include +#include "yolojson.h" + +const int RpcVersion = 1; + struct WinRpcConnection : public RpcConnection { HANDLE pipe{INVALID_HANDLE_VALUE}; RpcMessageFrame frame; }; -static const wchar_t* PipeName = L"\\\\.\\pipe\\DiscordRpcServer"; +static const wchar_t* PipeName = L"\\\\?\\pipe\\discord-ipc"; -/*static*/ RpcConnection* RpcConnection::Create() +/*static*/ RpcConnection* RpcConnection::Create(const char* applicationId) { - return new WinRpcConnection; + auto connection = new WinRpcConnection; + StringCopy(connection->appId, applicationId, sizeof(connection->appId)); + return connection; } /*static*/ void RpcConnection::Destroy(RpcConnection*& c) @@ -49,6 +55,13 @@ void RpcConnection::Open() return; } } + + RpcMessageFrame* frame = GetNextFrame(); + frame->opcode = OPCODE::HANDSHAKE; + char* msg = frame->message; + JsonWriteHandshakeObj(msg, RpcVersion, appId); + frame->length = msg - frame->message; + WriteFrame(frame); } void RpcConnection::Close() @@ -86,5 +99,5 @@ RpcMessageFrame* RpcConnection::GetNextFrame() void RpcConnection::WriteFrame(RpcMessageFrame* frame) { auto self = reinterpret_cast(this); - self->Write(frame, frame->length); + self->Write(frame, 8 + frame->length); } diff --git a/src/discord-rpc.cpp b/src/discord-rpc.cpp index 97a12b0..498d6d6 100644 --- a/src/discord-rpc.cpp +++ b/src/discord-rpc.cpp @@ -11,7 +11,6 @@ static bool wasJustDisconnected = false; extern "C" void Discord_Initialize(const char* applicationId, DiscordEventHandlers* handlers) { - StringCopy(ApplicationId, applicationId, sizeof(ApplicationId)); if (handlers) { Handlers = *handlers; } @@ -19,7 +18,7 @@ extern "C" void Discord_Initialize(const char* applicationId, DiscordEventHandle Handlers = {}; } - MyConnection = RpcConnection::Create(); + MyConnection = RpcConnection::Create(applicationId); MyConnection->onConnect = []() { wasJustConnected = true; }; MyConnection->onDisconnect = []() { wasJustDisconnected = true; }; MyConnection->Open(); @@ -37,7 +36,7 @@ extern "C" void Discord_UpdatePresence(const DiscordRichPresence* presence) auto frame = MyConnection->GetNextFrame(); char* jsonWrite = frame->message; JsonWriteRichPresenceObj(jsonWrite, presence); - frame->length = sizeof(uint32_t) + (jsonWrite - frame->message); + frame->length = jsonWrite - frame->message; MyConnection->WriteFrame(frame); } diff --git a/src/yolojson.h b/src/yolojson.h index c045105..e8298fd 100644 --- a/src/yolojson.h +++ b/src/yolojson.h @@ -1,5 +1,8 @@ #pragma once +#include "connection.h" +#include "discord-rpc.h" + /* This is as simple of a json writing thing as possible; does not try to keep you from overflowing buffer, so make sure you have room. @@ -188,3 +191,16 @@ inline void JsonWriteRichPresenceObj(char*& dest, const DiscordRichPresence* pre dest -= 1; *(dest - 1) = '}'; } + +inline void JsonWriteHandshakeObj(char*& dest, int version, const char* applicationId) +{ + *dest++ = '{'; + + JsonWriteNumberProp(dest, "v", version); + JsonWriteStringProp(dest, "client_id", applicationId); + + dest -= 1; + *(dest - 1) = '}'; + *dest = 0; +} +