From 29641da939f971e817b712b2995ad90fb3c5ef58 Mon Sep 17 00:00:00 2001 From: Chris Marsh Date: Tue, 18 Jul 2017 14:29:54 -0700 Subject: [PATCH] clean out simplest version --- CMakeLists.txt | 5 - examples/simplest/CMakeLists.txt | 3 - examples/simplest/simplest.c | 73 ------- src/CMakeLists.txt | 4 +- src/connection_win.cpp | 2 - src/connection_win_sync.cpp | 141 ------------- src/discord-rpc-simple.cpp | 326 ------------------------------- src/discord-rpc.cpp | 1 - src/rpc_connection.cpp | 4 +- src/rpc_connection.h | 2 +- 10 files changed, 5 insertions(+), 556 deletions(-) delete mode 100644 examples/simplest/CMakeLists.txt delete mode 100644 examples/simplest/simplest.c delete mode 100644 src/connection_win_sync.cpp delete mode 100644 src/discord-rpc-simple.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index f66e701..29ee58f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -23,8 +23,3 @@ add_library(rapidjson STATIC IMPORTED ${RAPIDJSON}) add_subdirectory(src) add_subdirectory(examples/simple) - -if(WIN32) - add_subdirectory(examples/simplest) -endif(WIN32) - diff --git a/examples/simplest/CMakeLists.txt b/examples/simplest/CMakeLists.txt deleted file mode 100644 index 97ba34f..0000000 --- a/examples/simplest/CMakeLists.txt +++ /dev/null @@ -1,3 +0,0 @@ -include_directories(${PROJECT_SOURCE_DIR}/include) -add_executable(simplest-client simplest.c) -target_link_libraries(simplest-client discord-rpc-simple) diff --git a/examples/simplest/simplest.c b/examples/simplest/simplest.c deleted file mode 100644 index 00748a5..0000000 --- a/examples/simplest/simplest.c +++ /dev/null @@ -1,73 +0,0 @@ -/* - This is a simple example in C of using the rich presence API syncronously, just sending presence. -*/ - -#define _CRT_SECURE_NO_WARNINGS /* thanks Microsoft */ - -#include -#include -#include -#include - -#include "discord-rpc.h" - -static const char* APPLICATION_ID = "12345678910"; -static int FrustrationLevel = 0; - -static void updateDiscordPresence() { - char buffer[256]; - DiscordRichPresence discordPresence; - memset(&discordPresence, 0, sizeof(discordPresence)); - discordPresence.state = "West of House"; - sprintf(buffer, "Frustration level: %d", FrustrationLevel); - discordPresence.details = buffer; - Discord_UpdatePresence(&discordPresence); -} - -static int prompt(char* line, size_t size) { - int res; - char* nl; - printf("\n> "); - fflush(stdout); - res = fgets(line, size, stdin) ? 1 : 0; - line[size - 1] = 0; - nl = strchr(line, '\n'); - if (nl) { - *nl = 0; - } - return res; -} - -static void gameLoop() { - char line[512]; - char* space; - - printf("You are standing in an open field west of a white house.\n"); - while (prompt(line, sizeof(line))) { - if (time(NULL) & 1) { - printf("I don't understand that.\n"); - } else { - space = strchr(line, ' '); - if (space) { - *space = 0; - } - printf("I don't know the word \"%s\".\n", line); - } - - ++FrustrationLevel; - - updateDiscordPresence(); - } -} - -int main() { - DiscordEventHandlers handlers; - memset(&handlers, 0, sizeof(handlers)); - Discord_Initialize(APPLICATION_ID, &handlers); - - gameLoop(); - - Discord_Shutdown(); - return 0; -} - diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 54aadba..f485074 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -3,8 +3,6 @@ include_directories(${PROJECT_SOURCE_DIR}/include) set(BASE_RPC_SRC ${PROJECT_SOURCE_DIR}/include/discord-rpc.h discord-rpc.cpp rpc_connection.h rpc_connection.cpp yolojson.h connection.h backoff.h) if(WIN32) - add_library(discord-rpc-simple STATIC ${PROJECT_SOURCE_DIR}/include/discord-rpc.h discord-rpc-simple.cpp) - add_library(discord-rpc STATIC ${BASE_RPC_SRC} connection_win.cpp) endif(WIN32) @@ -12,4 +10,4 @@ if(UNIX) add_library(discord-rpc STATIC ${BASE_RPC_SRC} connection_unix.cpp) endif(UNIX) -target_include_directories(discord-rpc PRIVATE ${RAPIDJSON}/include) \ No newline at end of file +target_include_directories(discord-rpc PRIVATE ${RAPIDJSON}/include) diff --git a/src/connection_win.cpp b/src/connection_win.cpp index 007f53a..1a5a445 100644 --- a/src/connection_win.cpp +++ b/src/connection_win.cpp @@ -1,7 +1,5 @@ #include "connection.h" -#include - #define WIN32_LEAN_AND_MEAN #define NOMCX #define NOSERVICE diff --git a/src/connection_win_sync.cpp b/src/connection_win_sync.cpp deleted file mode 100644 index 13235fc..0000000 --- a/src/connection_win_sync.cpp +++ /dev/null @@ -1,141 +0,0 @@ -#include "connection.h" - -#include - -#define WIN32_LEAN_AND_MEAN -#define NOMCX -#define NOSERVICE -#define NOIME -#include - -#include "yolojson.h" - -const int RpcVersion = 1; -const int NumFrames = 4; - -struct WinRpcConnection : public RpcConnection { - HANDLE pipe{INVALID_HANDLE_VALUE}; - RpcMessageFrame readFrame; - RpcMessageFrame frames[NumFrames]; - int nextFrame{0}; -}; - -static const wchar_t* PipeName = L"\\\\?\\pipe\\discord-ipc"; - -/*static*/ RpcConnection* RpcConnection::Create(const char* applicationId) -{ - auto connection = new WinRpcConnection; - StringCopy(connection->appId, applicationId, sizeof(connection->appId)); - return connection; -} - -/*static*/ void RpcConnection::Destroy(RpcConnection*& c) -{ - auto self = reinterpret_cast(c); - delete self; - c = nullptr; -} - -void RpcConnection::Open() -{ - auto self = reinterpret_cast(this); - for (;;) { - self->pipe = ::CreateFileW(PipeName, GENERIC_READ | GENERIC_WRITE, 0, nullptr, OPEN_EXISTING, 0, nullptr); - if (self->pipe != INVALID_HANDLE_VALUE) { - break; - } - - if (GetLastError() != ERROR_PIPE_BUSY) { - printf("Could not open pipe. Error: %d\n", GetLastError()); - return; - } - - if (!WaitNamedPipeW(PipeName, 10000)) { - printf("Could not open pipe: 10 second wait timed out.\n"); - return; - } - } - - RpcMessageFrame* frame = GetNextFrame(); - frame->opcode = OPCODE::HANDSHAKE; - char* msg = frame->message; - JsonWriteHandshakeObj(msg, RpcVersion, appId); - frame->length = msg - frame->message; - WriteFrame(frame); - - if (self->onConnect) { - self->onConnect(); - } -} - -void RpcConnection::Close() -{ - auto self = reinterpret_cast(this); - ::CloseHandle(self->pipe); - self->pipe = INVALID_HANDLE_VALUE; - if (self->onDisconnect) { - self->onDisconnect(); - } -} - -void RpcConnection::Write(const void* data, size_t length) -{ - auto self = reinterpret_cast(this); - const int retries = 3; - for (int i = 0; i < retries; ++i) { - if (self->pipe == INVALID_HANDLE_VALUE) { - self->Open(); - if (self->pipe == INVALID_HANDLE_VALUE) { - break; - } - } - BOOL success = ::WriteFile(self->pipe, data, length, nullptr, nullptr); - if (success) { - break; - } - - /* hmm - RpcMessageFrame* frame = self->Read(); - if (frame) { - self->HandleError(frame); - } - */ - - self->Close(); - } -} - -RpcMessageFrame* RpcConnection::Read() -{ - auto self = reinterpret_cast(this); - DWORD bytesAvailable = 0; - if (::PeekNamedPipe(self->pipe, nullptr, 0, nullptr, &bytesAvailable, nullptr) && bytesAvailable > 8) { - if (::ReadFile(self->pipe, &self->readFrame, 8, nullptr, nullptr) != TRUE) { - return nullptr; - } - - if (self->readFrame.length > 0) { - if (::ReadFile(self->pipe, &self->readFrame.message, self->readFrame.length, nullptr, nullptr) != TRUE) { - return nullptr; - } - self->readFrame.message[self->readFrame.length] = 0; - } - - return &self->readFrame; - } - return nullptr; -} - -RpcMessageFrame* RpcConnection::GetNextFrame() -{ - auto self = reinterpret_cast(this); - auto result = &(self->frames[self->nextFrame]); - self->nextFrame = (self->nextFrame + 1) % NumFrames; - return result; -} - -void RpcConnection::WriteFrame(RpcMessageFrame* frame) -{ - auto self = reinterpret_cast(this); - self->Write(frame, 8 + frame->length); -} diff --git a/src/discord-rpc-simple.cpp b/src/discord-rpc-simple.cpp deleted file mode 100644 index a6a0f69..0000000 --- a/src/discord-rpc-simple.cpp +++ /dev/null @@ -1,326 +0,0 @@ -#include "discord-rpc.h" - -#include - -// I just want the basics -#define WIN32_LEAN_AND_MEAN -#define NOMCX -#define NOSERVICE -#define NOIME -#include - -namespace { - -const int RpcVersion = 1; - -enum class OPCODE : uint32_t { - HANDSHAKE = 0, - FRAME = 1, - CLOSE = 2, -}; - -struct RpcMessageFrame { - OPCODE opcode; - uint32_t length; - char message[64 * 1024 - 8]; -}; - -static const wchar_t* PipeName = L"\\\\?\\pipe\\discord-ipc"; -static HANDLE PipeHandle{ INVALID_HANDLE_VALUE }; - -static char ApplicationId[64]{}; -static DiscordEventHandlers Handlers{}; -static RpcMessageFrame Frame; - -// if only there was a standard library function for this -size_t StringCopy(char* dest, const char* src, size_t maxBytes = UINT32_MAX) { - if (!dest || !src || !maxBytes) { - return 0; - } - size_t copied; - for (copied = 1; *src && copied < maxBytes; ++copied) { - *dest++ = *src++; - } - *dest = 0; - return copied - 1; -} - -void JsonWriteEscapedString(char*& dest, const char* src) -{ - for (char c = *src++; c; c = *src++) { - switch (c) { - case '\"': - case '\\': - *dest++ = '\\'; - *dest++ = c; - break; - case '\b': - *dest++ = '\\'; - *dest++ = 'b'; - break; - case '\f': - *dest++ = '\\'; - *dest++ = 'f'; - break; - case '\n': - *dest++ = '\\'; - *dest++ = 'n'; - break; - case '\r': - *dest++ = '\\'; - *dest++ = 'r'; - break; - case '\t': - *dest++ = '\\'; - *dest++ = 't'; - break; - default: - *dest++ = c; - break; - } - } -} - -template void JsonWriteNumber(char*& dest, T number) -{ - if (!number) { - *dest++ = '0'; - return; - } - if (number < 0) { - *dest++ = '-'; - number = -number; - } - char temp[32]; - int place = 0; - while (number) { - auto digit = number % 10; - number = number / 10; - temp[place++] = '0' + (char)digit; - } - for (--place; place >= 0; --place) { - *dest++ = temp[place]; - } - *dest = 0; -} - -void JsonWritePropName(char*& dest, const char* name) -{ - *dest++ = '"'; - dest += StringCopy(dest, name); - *dest++ = '"'; - *dest++ = ':'; - *dest++ = ' '; -} - -void JsonWritePropSep(char*& dest) -{ - *dest++ = ','; - *dest++ = ' '; -} - -void JsonWriteStringProp(char*& dest, const char* name, const char* value) -{ - JsonWritePropName(dest, name); - *dest++ = '"'; - JsonWriteEscapedString(dest, value); - *dest++ = '"'; - JsonWritePropSep(dest); -} - -template -void JsonWriteNumberAsStringProp(char*& dest, const char* name, T value) -{ - JsonWritePropName(dest, name); - *dest++ = '"'; - JsonWriteNumber(dest, value); - *dest++ = '"'; - JsonWritePropSep(dest); -} - -template -void JsonWriteNumberProp(char*& dest, const char* name, T value) -{ - JsonWritePropName(dest, name); - JsonWriteNumber(dest, value); - JsonWritePropSep(dest); -} - -void JsonWriteBoolProp(char*& dest, const char* name, bool value) -{ - JsonWritePropName(dest, name); - dest += StringCopy(dest, value ? "true" : "false"); - JsonWritePropSep(dest); -} - -void JsonWriteRichPresenceObj(char*& dest, const DiscordRichPresence* presence) -{ - *dest++ = '{'; - - if (presence->state) { - JsonWriteStringProp(dest, "state", presence->state); - } - - if (presence->details) { - JsonWriteStringProp(dest, "details", presence->details); - } - - if (presence->startTimestamp) { - JsonWriteNumberAsStringProp(dest, "start_timestamp", presence->startTimestamp); - } - - if (presence->endTimestamp) { - JsonWriteNumberAsStringProp(dest, "end_timestamp", presence->endTimestamp); - } - - if (presence->largeImageKey) { - JsonWriteStringProp(dest, "large_image_key", presence->largeImageKey); - } - - if (presence->largeImageText) { - JsonWriteStringProp(dest, "large_image_text", presence->largeImageText); - } - - if (presence->smallImageKey) { - JsonWriteStringProp(dest, "small_image_key", presence->smallImageKey); - } - - if (presence->smallImageText) { - JsonWriteStringProp(dest, "small_image_text", presence->smallImageText); - } - - if (presence->partyId) { - JsonWriteStringProp(dest, "party_id", presence->partyId); - } - - if (presence->partyMax) { - JsonWriteNumberProp(dest, "party_size", presence->partySize); - JsonWriteNumberProp(dest, "party_max", presence->partyMax); - } - - if (presence->matchSecret) { - JsonWriteStringProp(dest, "match_secret", presence->matchSecret); - } - - if (presence->joinSecret) { - JsonWriteStringProp(dest, "join_secret", presence->joinSecret); - } - - if (presence->spectateSecret) { - JsonWriteStringProp(dest, "spectate_secret", presence->spectateSecret); - } - - JsonWriteBoolProp(dest, "instance", presence->instance != 0); - - dest -= 1; - *(dest - 1) = '}'; - *dest = 0; -} - -void JsonWriteHandshakeObj(char*& dest, const char* applicationId) -{ - *dest++ = '{'; - - JsonWriteNumberProp(dest, "v", RpcVersion); - JsonWriteStringProp(dest, "client_id", applicationId); - - dest -= 1; - *(dest - 1) = '}'; - *dest = 0; -} - -void ConnectionWrite(const RpcMessageFrame* frame); - -void ConnectionOpen() -{ - for (;;) { - PipeHandle = CreateFileW(PipeName, GENERIC_READ | GENERIC_WRITE, 0, nullptr, OPEN_EXISTING, 0, nullptr); - if (PipeHandle != INVALID_HANDLE_VALUE) { - if (Handlers.ready) { - Handlers.ready(); - } - break; - } - - DWORD err = GetLastError(); - - if (err == ERROR_FILE_NOT_FOUND) { - printf("No server running\n"); - return; - } - - if (err != ERROR_PIPE_BUSY) { - printf("Could not open pipe. Error: %d\n", GetLastError()); - return; - } - - if (!WaitNamedPipeW(PipeName, 10000)) { - printf("Could not open pipe: 10 second wait timed out.\n"); - return; - } - } - - RpcMessageFrame frame; - frame.opcode = OPCODE::HANDSHAKE; - char* msg = frame.message; - JsonWriteHandshakeObj(msg, ApplicationId); - frame.length = msg - frame.message; - ConnectionWrite(&frame); -} - -void ConnectionClose() -{ - CloseHandle(PipeHandle); - PipeHandle = INVALID_HANDLE_VALUE; - if (Handlers.disconnected) { - Handlers.disconnected(0, ""); - } -} - -void ConnectionWrite(const RpcMessageFrame* frame) -{ - if (PipeHandle == INVALID_HANDLE_VALUE) { - ConnectionOpen(); - if (PipeHandle == INVALID_HANDLE_VALUE) { - return; - } - } - BOOL success = WriteFile(PipeHandle, frame, 8 + frame->length, nullptr, nullptr); - if (!success) { - ConnectionClose(); - } -} - -} // anonymous namespace - -extern "C" void Discord_Initialize(const char* applicationId, DiscordEventHandlers* handlers) -{ - StringCopy(ApplicationId, applicationId, sizeof(ApplicationId)); - if (handlers) { - Handlers = *handlers; - } - else { - Handlers = {}; - } - - ConnectionOpen(); -} - -extern "C" void Discord_Shutdown() -{ - Handlers = {}; - ConnectionClose(); -} - -extern "C" void Discord_UpdatePresence(const DiscordRichPresence* presence) -{ - Frame.opcode = OPCODE::FRAME; - char* jsonWrite = Frame.message; - JsonWriteRichPresenceObj(jsonWrite, presence); - Frame.length = jsonWrite - Frame.message; - ConnectionWrite(&Frame); -} - -extern "C" void Discord_Update() -{ -} diff --git a/src/discord-rpc.cpp b/src/discord-rpc.cpp index 0240580..d45854a 100644 --- a/src/discord-rpc.cpp +++ b/src/discord-rpc.cpp @@ -6,7 +6,6 @@ #include "rapidjson/document.h" -#include #include #include diff --git a/src/rpc_connection.cpp b/src/rpc_connection.cpp index 09ad0fb..6942003 100644 --- a/src/rpc_connection.cpp +++ b/src/rpc_connection.cpp @@ -56,14 +56,16 @@ void RpcConnection::Close() state = State::Disconnected; } -void RpcConnection::Write(const void* data, size_t length) +bool RpcConnection::Write(const void* data, size_t length) { sendFrame.opcode = Opcode::Frame; memcpy(sendFrame.message, data, length); sendFrame.length = length; if (!connection->Write(&sendFrame, sizeof(MessageFrameHeader) + length)) { Close(); + return false; } + return true; } bool RpcConnection::Read(rapidjson::Document& message) diff --git a/src/rpc_connection.h b/src/rpc_connection.h index d31f1c4..4e1a8e6 100644 --- a/src/rpc_connection.h +++ b/src/rpc_connection.h @@ -48,6 +48,6 @@ struct RpcConnection { void Open(); void Close(); - void Write(const void* data, size_t length); + bool Write(const void* data, size_t length); bool Read(rapidjson::Document& message); };