Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Discord Game SDK support #1217

Open
wants to merge 26 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 8 commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
eb21260
Add Discord Network support.
Buggem Dec 10, 2024
0a1244b
Dynamically load Discord Game SDK with `SDL_LoadObject()` to avoid CM…
Buggem Dec 12, 2024
7975b27
Patch potential crash scenarios and remove warnings.
Buggem Dec 12, 2024
76d5738
Replace `strncpy` with `SDL_strncpy`
Buggem Dec 12, 2024
76d4368
Remove unneeded headerfiles, .vscode folder, and move comment
Buggem Dec 12, 2024
ce111cf
Make Discord not required to exist - thanks @Daaaav
Buggem Dec 12, 2024
7d3e7db
Avoid segfault if Discord is not detected, remove useless headerfiles
Buggem Dec 13, 2024
17fea40
Remove localisation features from the RPC, as people on English Disco…
Buggem Dec 14, 2024
459437c
Remove placeholder
Buggem Dec 15, 2024
7fcba85
Add @Daaaav's changes (full changelog below)
Buggem Dec 15, 2024
5cbf03d
Fix bad implementation of inversion of discordDetected
Buggem Dec 15, 2024
132c504
finish off naming convention = type*
Buggem Dec 17, 2024
29708db
Finish @Daaaav's requests :D
Buggem Dec 19, 2024
3b5108e
More requests (see full changelog below)
Buggem Dec 21, 2024
bef03b6
consistancy
Buggem Dec 21, 2024
d35fb29
maybe remove console spam (seperate commit to consider reverts)
Buggem Dec 21, 2024
9c05ffe
Finish formatting
Buggem Dec 22, 2024
731f2ce
Merge branch 'TerryCavanagh:master' into discordrpc
Buggem Dec 31, 2024
6e5fed0
Add more names for different areas of the game IG
Buggem Jan 1, 2025
bf9dd78
Make the RPC less invasive, only change when we NEED to.
Buggem Jan 25, 2025
fba8f7d
Strip unused stdio.h headerfile [redo]
Buggem Jan 25, 2025
28a38bd
Commit flibit's changes **needs polish**
Buggem Jan 26, 2025
ec132ac
Polish Flibit's changes to work. (PLS FIX POINTERS D:)
Buggem Jan 26, 2025
62ecc83
Patch out pointer control (new method sucks but ok I guess)
Buggem Jan 26, 2025
4a12fae
small commit: `type* varname` convention
Buggem Jan 26, 2025
6bc5649
Merge branch 'TerryCavanagh:master' into discordrpc
Buggem Feb 19, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions desktop_version/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ option(BUNDLE_DEPENDENCIES "Use bundled TinyXML-2, PhysicsFS, and FAudio (if dis

option(STEAM "Use the Steam API" OFF)
option(GOG "Use the GOG API" OFF)
option(DISCORD "Use the Discord API" OFF)

option(OFFICIAL_BUILD "Compile an official build of the game" OFF)

Expand All @@ -19,6 +20,7 @@ option(MAKEANDPLAY "Compile a version of the game without the main campaign (pro
if(OFFICIAL_BUILD AND NOT MAKEANDPLAY)
set(STEAM ON)
set(GOG ON)
set(DISCORD ON)
endif()

option(REMOVE_ABSOLUTE_PATHS "If supported by the compiler, replace all absolute paths to source directories compiled into the binary (if any) with relative paths" ON)
Expand Down Expand Up @@ -133,6 +135,9 @@ endif()
if(GOG)
list(APPEND VVV_C_SRC src/GOGNetwork.c)
endif()
if(DISCORD)
list(APPEND VVV_C_SRC src/DiscordNetwork.c)
endif()
if(CMAKE_SYSTEM_NAME STREQUAL "iOS")
list(APPEND VVV_C_SRC src/SDL_uikit_main.c)
endif()
Expand Down Expand Up @@ -210,6 +215,9 @@ endif()
if(GOG)
target_compile_definitions(VVVVVV PRIVATE -DGOG_NETWORK)
endif()
if(DISCORD)
target_compile_definitions(VVVVVV PRIVATE -DDISCORD_NETWORK)
endif()

set(XML2_SRC
../third_party/tinyxml2/tinyxml2.cpp
Expand Down
165 changes: 165 additions & 0 deletions desktop_version/src/DiscordNetwork.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,165 @@
#include "MakeAndPlay.h"

#ifndef MAKEANDPLAY

#include <stdint.h>
#include <stdio.h>
#include <stdbool.h>
#include <SDL.h>

#include "Vlogging.h"

// Library includes
#include "discord_game_sdk.h"

#if defined(_WIN32)
#define DISCORD_LIBRARY "discord_game_sdk.dll"
#elif defined(__APPLE__)
#define DISCORD_LIBRARY "libdiscord_game_sdk.dylib"
#elif defined(__linux__) || defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__HAIKU__) || defined(__DragonFly__)
#define DISCORD_LIBRARY "libdiscord_game_sdk.so"
#else
#error DISCORD_LIBRARY: Unrecognized platform!
#endif


#define DISCORD_CRASH_LIMIT 10
#define DISCORD_CLIENT_ID 1315544357532729447 // TO TERRY/FLIBIT: You can create your own Discord instance at the Discord Developer Portal. This ID belongs to me, so just be aware that if my account was to get hacked, VVVVVV RPC would too. Use your own!


struct DISCORD_application {
struct IDiscordCore* core;
struct IDiscordActivityManager* activityMan;
} app;

struct DiscordActivity activity;

bool discordNotDetected = false;
int discordCrashes = 0; // This is here to ensure we do not get stuck in a theoratical softlock of opening and crashing Discord instances.

static void* libHandle = NULL;


#define FUNC_LIST \
FOREACH_FUNC(enum EDiscordResult, DiscordCreate, (DiscordVersion, struct DiscordCreateParams*, struct IDiscordCore**))



#define FOREACH_FUNC(rettype, name, params) static rettype (*name) params = NULL;
FUNC_LIST
#undef FOREACH_FUNC

static void ClearPointers(void)
{
SDL_UnloadObject(libHandle);
libHandle = NULL;
#define FOREACH_FUNC(rettype, name, params) name = NULL;
FUNC_LIST
#undef FOREACH_FUNC
}

void DISCORD_shutdown(void)
{
if (libHandle)
{
ClearPointers();
}
}

int32_t DISCORD_init(void)
{
#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__HAIKU__) || defined(__DragonFly__)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should probably be rewritten to check for OSes that Discord does support, rather than ones it doesn't.

return 0;
#endif
libHandle = SDL_LoadObject(DISCORD_LIBRARY);
if (!libHandle)
{
vlog_info(DISCORD_LIBRARY " not found!");
printf("Can't load object %s : %s\n", DISCORD_LIBRARY, SDL_GetError());
return 0;
}

#define FOREACH_FUNC(rettype, name, params) \
name = (rettype (*) params) (intptr_t) SDL_LoadFunction(libHandle, #name); \
if (!name) \
{ \
vlog_error(DISCORD_LIBRARY " symbol " #name " not found!"); \
ClearPointers(); \
return 0; \
}
FUNC_LIST
#undef FOREACH_FUNC
memset(&app, 0, sizeof(app));

struct DiscordCreateParams params;
params.client_id = DISCORD_CLIENT_ID;
params.flags = DiscordCreateFlags_NoRequireDiscord;

if(!DiscordCreate(DISCORD_VERSION, &params, &app.core))
{
return 1;
}

if(app.core == NULL)
{
discordNotDetected = true;
return 0;
}


SDL_strlcpy(activity.assets.large_image, "vvvvvv", sizeof(activity.assets.large_image));
SDL_strlcpy(activity.assets.large_text, "Outside Dimension VVVVVV", sizeof(activity.assets.large_text));

app.activityMan = app.core->get_activity_manager(app.core);
app.activityMan->update_activity(app.activityMan, &activity, NULL, NULL);



return 0;
}

void DISCORD_REQUIRE(int x) {
if(discordNotDetected)
{
return;
}
if(discordCrashes > DISCORD_CRASH_LIMIT)
{
DISCORD_shutdown();
return;
}
if(x != DiscordResult_Ok)
{
++discordCrashes;
DISCORD_shutdown();
DISCORD_init();
return;
}
discordCrashes = 0;
}

void DISCORD_update(const char *level, const char *name)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd probably rename level and name to something like area and roomname, to make them clearer. Also, code style thing: we put the * with the type, not the variable name. (I see it's that way in the existing Steam code but we've been consistent in all new code)

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Daaaav GOGNetwork does not have the type* naming convention for functions I didn't implement, so I added that too. Should I just keep to my Discord implementation? Or would this fix be acceptable as part of this PR?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd say it'd be acceptable to move spaces in the GOG/Steam code so that you don't have to add new code that either introduces type * convention or is inconsistent with the existing code. For more unrelated parts (functions you didn't implement for Discord but which were in the same GOG/Steam files you were already making consistency fixes in... Eh. Might as well.

{
if(discordCrashes > DISCORD_CRASH_LIMIT) {
return;
}
if(app.activityMan == NULL)
{
app.activityMan = app.core->get_activity_manager(app.core);
}
SDL_strlcpy(activity.state, name, sizeof(activity.state));
SDL_strlcpy(activity.assets.large_image, "vvvvvv", sizeof(activity.assets.large_image));
SDL_strlcpy(activity.assets.large_text, level, sizeof(activity.assets.large_text));

app.activityMan->update_activity(app.activityMan, &activity, NULL, NULL);

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Newlines in this file seem generally inconsistent. This should probably be cleaned up.

DISCORD_REQUIRE(app.core->run_callbacks(app.core));
}
void DISCORD_unlockAchievement(const char *name)
{
// No "achievements" in Discord
}



#endif // MakeAndPlay
2 changes: 1 addition & 1 deletion desktop_version/src/GOGNetwork.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ void GOG_shutdown(void)
{
}

void GOG_update(void)
void GOG_update(const char *level, const char *name)
{
}

Expand Down
25 changes: 20 additions & 5 deletions desktop_version/src/Network.c
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#include <stdint.h>
#include <stdio.h>

#include "MakeAndPlay.h"
#include "Unused.h"
Expand All @@ -10,6 +11,9 @@
#ifdef GOG_NETWORK
#undef GOG_NETWORK
#endif
#ifdef DISCORD_NETWORK
#undef DISCORD_NETWORK
#endif
#endif

#ifdef STEAM_NETWORK
Expand All @@ -22,27 +26,35 @@
#else
#define GOG_NUM 0
#endif
#ifdef DISCORD_NETWORK
#define DISCORD_NUM 1
#else
#define DISCORD_NUM 0
#endif

#define NUM_BACKENDS (STEAM_NUM+GOG_NUM)
#define NUM_BACKENDS (STEAM_NUM+GOG_NUM+DISCORD_NUM)
#define DECLARE_BACKEND(name) \
int32_t name##_init(void); \
void name##_shutdown(void); \
void name##_update(void); \
void name##_update(const char *level, const char *name); \
void name##_unlockAchievement(const char *name);
#ifdef STEAM_NETWORK
DECLARE_BACKEND(STEAM)
#endif
#ifdef GOG_NETWORK
DECLARE_BACKEND(GOG)
#endif
#ifdef DISCORD_NETWORK
DECLARE_BACKEND(DISCORD)
#endif
#undef DECLARE_BACKEND

typedef struct NetworkBackend
{
int32_t IsInit;
int32_t (*Init)(void);
void (*Shutdown)(void);
void (*Update)(void);
void (*Update)(const char*, const char*);
void (*UnlockAchievement)(const char*);
} NetworkBackend;

Expand All @@ -64,6 +76,9 @@ int NETWORK_init(void)
#ifdef GOG_NETWORK
ASSIGN_BACKEND(GOG, STEAM_NUM)
#endif
#ifdef DISCORD_NETWORK
ASSIGN_BACKEND(DISCORD, STEAM_NUM+GOG_NUM)
#endif
#undef ASSIGN_BACKEND
#if NUM_BACKENDS > 0
for (i = 0; i < NUM_BACKENDS; i += 1)
Expand All @@ -89,14 +104,14 @@ void NETWORK_shutdown(void)
#endif
}

void NETWORK_update(void)
void NETWORK_update(const char *level, const char *name)
{
#if NUM_BACKENDS > 0
int32_t i;
for (i = 0; i < NUM_BACKENDS; i += 1)
if (backends[i].IsInit)
{
backends[i].Update();
backends[i].Update(level, name);
}
#endif
}
Expand Down
2 changes: 1 addition & 1 deletion desktop_version/src/Network.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ int32_t NETWORK_init(void);

void NETWORK_shutdown(void);

void NETWORK_update(void);
void NETWORK_update(const char *level, const char *name);

void NETWORK_unlockAchievement(const char *name);

Expand Down
2 changes: 1 addition & 1 deletion desktop_version/src/SteamNetwork.c
Original file line number Diff line number Diff line change
Expand Up @@ -234,7 +234,7 @@ void STEAM_shutdown(void)
}
}

void STEAM_update(void)
void STEAM_update(const char *level, const char *name)
{
if (!libHandle)
{
Expand Down
Loading