From 661b5fa3b5e363d45ef687a533e060bd02b8d615 Mon Sep 17 00:00:00 2001 From: Chris Marsh Date: Fri, 23 Jun 2017 16:04:36 -0700 Subject: [PATCH] initial commit --- README.md | 8 ++++ src/discord-rpc.cpp | 0 src/discord-rpc.h | 99 +++++++++++++++++++++++++++++++++++++++++++++ src/full.cpp | 0 src/simple.cpp | 57 ++++++++++++++++++++++++++ 5 files changed, 164 insertions(+) create mode 100644 README.md create mode 100644 src/discord-rpc.cpp create mode 100644 src/discord-rpc.h create mode 100644 src/full.cpp create mode 100644 src/simple.cpp diff --git a/README.md b/README.md new file mode 100644 index 0000000..d696147 --- /dev/null +++ b/README.md @@ -0,0 +1,8 @@ +Discord RPC Sample +================== + +This is a lib and a couple of quick demos, one that implements the very minimal subset to show +current status, and one that is more complete. The idea here is to give you an lib that implements +the rpc connection and wraps sending events, and a basic example that uses it; you can use the lib +directly if you like, or use it as a guide to writing your own if it doesn't suit your game as is. + diff --git a/src/discord-rpc.cpp b/src/discord-rpc.cpp new file mode 100644 index 0000000..e69de29 diff --git a/src/discord-rpc.h b/src/discord-rpc.h new file mode 100644 index 0000000..b35f68d --- /dev/null +++ b/src/discord-rpc.h @@ -0,0 +1,99 @@ +#pragma once + +/* Requirements Overview +* + initialize the local IPC connection to Discord + + what we need for rich presence + - send rich presence data to the client + - start spectating a session + - join a game party + - request to send rich presence data ('on discord client connected') + + + general usage + - initialize the discord connection + - determine if the user is a guest account + - shutdown / support timing out +*/ + +struct DiscordRichPresence { + const char* name; // do we need this hear or can it be pulled from the app page? + uint64_t contextStartTimeUTC; + uint64_t contextEndTimeUTC; + const char* gameState; // eg. In Game + const char* gameMode; // e.g. Summoner's Rift + const char* gameModifier; // e.g. Ranked + const char* choice; // e.g. Aatrox + const char* flavorImageKey; // e.g. The map background + const char* choiceImageKey; // e.g. The character's portrait icon + const char* partyId; + uint16_t partySize; // e.g. 0 means ignored + uint16_t partyCapacity; // e.g. 0 means no limit + const char* contextSecret; // Required for the "notify me" feature + uint8_t isInstance; // Together with context_secret enables the "notify me" feature + const char* joinSecret; // Enables the "invite to join" feature + const char* spectateSecret; // Enables the "invite to spectate" feature +}; + +struct DiscordRichPresence { + uint64_t contextStartTimeUTC; // 0 means unspecified + uint64_t contextStopTimeUTC; // 0 means unspecified + const char* partyStatus[4]; // e.g. "In Game", "Summoner's Rift", "Ranked", "Aatrox" + const char* largeImageKey; // e.g. The map background + const char* smallImageKey; // e.g. The character's portrait icon + + const char* partyId; + uint16_t partySize; // e.g. 0 means ignored + uint16_t partyCapacity; // e.g. 0 means no limit + + // optional + const char* contextSecret; // Required for the "notify me" feature + uint8_t isInstance; // Together with context_secret enables the "notify me" feature + + const char* joinSecret; // Enables the "invite to join" feature + const char* spectateSecret; // Enables the "invite to spectate" feature +}; + +struct DiscordEventHandlers { + // required. + void (*ready)(); + void (*disconnected)(); + + // optional for rich presence + void (*wantsPresence)(); + void (*joinGame)(const char* joinSecret); + void (*spectateGame)(const char* spectateSecret); +}; + +struct DiscordChannelEventHandlers { + void (*messageCreate)(const DiscordMessage* message); + void (*messageUpdate)(const DiscordMessage* message); + void (*messageDelete)(const DiscordMessage* message); + void (*voiceStateCreate)(const DiscordVoiceState* state); + void (*voiceStateDelete)(const DiscordVoiceState* state); + void (*speakingStart)(const DiscordSpeakingState* state); + void (*speakingStop)(const DiscordSpeakingState* state); +} + +// Call this to start up the Discord SDK +void Discord_Initialize(const char* applicationId, DiscordEventHandlers* handlers); + +// Call this to subscribe to events in a specific voice or text channel +void Discord_Subscribe(const char* channelId, const DiscordChannelEventHandlers* handlers) + +// Call this when you're all done so we can cleanup without timing out. +void Discord_Shutdown(); + +// Call this whenever any of the data in the payload changes in a material way. +void Discord_UpdatePresence(const DiscordRichPresence* presence); + +// TBD RPC Requests +void Discord_Authenticate(); +void Discord_Authorize(); +void Discord_GetGuilds(); +void Discord_GetChannels(); +void Discord_GetChannel(); +void Discord_SelectVoiceChannel(); +void Discord_SelectTextChannel(); +void Discord_SendMessage(); diff --git a/src/full.cpp b/src/full.cpp new file mode 100644 index 0000000..e69de29 diff --git a/src/simple.cpp b/src/simple.cpp new file mode 100644 index 0000000..0b34cfb --- /dev/null +++ b/src/simple.cpp @@ -0,0 +1,57 @@ + +static const char* YOUR_APPLICATION_ID = "23984729347234"; + +void updateDiscordPresence() { + DiscordRichPresence myPresence = {0}; + myPresence.name = "League of Legends"; + myPresence.gameState = "In Game"; + myPresence.gameMode = "Summoner's Rift"; + myPresence.gameModifier = "Ranked"; + myPresence.choice = "Aatrox"; + myPresence.flavorImageKey = "FLAVOR_SUMMONERS_RIFT"; + myPresence.choiceImageKey = "PORTRAIT_AATROX"; + + myPresence.partyId = GameEngine_GetMultiplayerPartyId(); + myPresence.partySize = GameEngine_GetCurrentPartyCount(); + myPresence.partyCapacity = PARTY_CAPACITY; + + myPresence.context = GameEngine_GetPartyAndMatchSecret(); + myPresence.isInstance = true; + + myPresence.joinSecret = GameEngine_GetPartyAndMatchSecret(); + myPresence.spectateSecret = GameEngine_GetUserIdSecret(); + + Discord_UpdatePresence(&myPresence); +} + +void handleDiscordDisconnected() { + // oh noes +} + +void handleDiscordReady() { + updateDiscordPresence(); +} + +void handleDiscordWantsPresence() { + updateDiscordPresence(); +} + +void handleDiscordJoinGame(const char* joinSecret) { + GameEngine_JoinParty(joinSecret); +} + +void handleDiscordSpectateGame(const char* spectateSecret) { + GameEngine_SpectateGame(spectateSecret); +} + +int main() { + DiscordEventHandlers handlers = {0}; + handlers.ready = handleDiscordReady; + handlers.disconnected = handleDiscordDisconnected; + handlers.wantsPresence = handleDiscordWantsPresence; + handlers.joinGame = handleDiscordJoinGame; + handlers.spectateGame = handleDiscordSpectateGame; + + Discord_Initialize(YOUR_APPLICATION_ID, handlers); +} +