Implementing Discord RPC: Difference between revisions
GamerDude27 (talk | contribs) m (Grammar corrections, a styling edit and corrections to the last change made) |
GamerDude27 (talk | contribs) m (Code readability and a few grammar corrections) |
||
Line 3: | Line 3: | ||
Implementing [https://github.com/discordapp/discord-rpc Discord RPC] into the Source engine is | Implementing [https://github.com/discordapp/discord-rpc Discord RPC] into the Source engine is simple, and it makes your mod stand out more, as your in-game "presence" can be seen through Discord. | ||
== What is Discord RPC? == | == What is Discord RPC? == | ||
Line 16: | Line 16: | ||
== The Installation == | == The Installation == | ||
First off you'll need to download the latest version Discord RPC. You can do so by going to Discord's GitHub repository [https://github.com/discordapp/discord-rpc/releases here]. And download the latest '''discord-rpc-win.zip''' file, as of writing we'll be using v3.3.0. Once downloaded, open the archive and go to '''win32-dynamic/lib/''' and extract | First off you'll need to download the latest version Discord RPC. You can do so by going to Discord's GitHub repository [https://github.com/discordapp/discord-rpc/releases here]. And download the latest '''discord-rpc-win.zip''' file, as of writing we'll be using v3.3.0. Once downloaded, open the archive and go to '''win32-dynamic/lib/''' and extract '''discord-rpc.lib''' to your mod's '''<src code directory>/src/lib/public/''' once that's done we'll do the same for the include files, in your archive take a step back and go into the include folder, now extract '''discord_rpc.h''' and '''discord_register.h''' to '''<src code directory>/src/public/'''. Now for the final step, once again in your archive take a step back and go into the bin folder, now extract '''discord-rpc.dll''' to your mod's /bin folder ex. '''<Steam directory>/steamapps/sourcemods/YourMod/bin/'''. | ||
== The Setup == | == The Setup == | ||
Now that the installation is done, it's time to set up our system. There's not a whole lot to do here, but this is a necessary step you'll have to take | Now that the installation is done, it's time to set up our system. There's not a whole lot to do here, but this is a necessary step you'll have to take to make the implementation work. | ||
To start, go | To start off, go into '''<src code directory>/src/vpc_scripts/''' and open '''source_dll_win32_base.vpc''' with your favorite text editor (I personally use Notepad++). Once you've opened the file, scroll all the way down to <code>$Folder "Link Libraries"</code> and under <code>$Implib "$LIBPUBLIC\vstdlib"</code> add <code>$Lib "$LIBPUBLIC\discord-rpc"</code>. After you've modified the VPC scripts, make sure to rerun '''createallprojects.bat''' and/or '''creategameprojects.bat''' before continuing, otherwise you might experience errors while building. | ||
All that needs to be done now is to start the Discord RPC system when the modification launches. To do this, open up | All that needs to be done now is to start the Discord RPC system when the modification launches. To do this, open up '''cdll_client_int.cpp''', and at the bottom add <code>#include "discord_rpc.h"</code> and <code>#include <time.h></code> to the list of includes, then under | ||
< | <source lang="cpp"> | ||
static ConVar s_cl_class("cl_class", "default", FCVAR_USERINFO|FCVAR_ARCHIVE, "Default class when joining a game"); | static ConVar s_cl_class("cl_class", "default", FCVAR_USERINFO|FCVAR_ARCHIVE, "Default class when joining a game"); | ||
</ | </source> | ||
add | add | ||
< | <source lang="cpp"> | ||
// Discord RPC | // Discord RPC | ||
static ConVar cl_discord_appid("cl_discord_appid", "123456789123456789", FCVAR_DEVELOPMENTONLY | FCVAR_CHEAT); | static ConVar cl_discord_appid("cl_discord_appid", "123456789123456789", FCVAR_DEVELOPMENTONLY | FCVAR_CHEAT); | ||
static int64_t startTimestamp = time(0); | static int64_t startTimestamp = time(0); | ||
</ | </source> | ||
where the numbers after | where the numbers after <code>cl_discord_appid</code> are your applications RPC appid, to set up a RPC client go [https://discordapp.com/developers/applications/ here], once your application is set up the number you'll want to place after <code>cl_discord_appid</code> is the "Client ID" seen in "General Information". | ||
When that's done add the following above | When that's done add the following above <code>CHLClient::CHLClient()</code> | ||
< | <source lang="cpp"> | ||
//----------------------------------------------------------------------------- | //----------------------------------------------------------------------------- | ||
// Discord RPC | // Discord RPC | ||
Line 77: | Line 77: | ||
// Not implemented | // Not implemented | ||
} | } | ||
</ | </source> | ||
Now scroll down to | Now scroll down to <code>CHLClient::Init( ... )</code> and add the following above <code>return true;</code> at the bottom of the function. | ||
< | <source lang="cpp"> | ||
// Discord RPC | // Discord RPC | ||
DiscordEventHandlers handlers; | DiscordEventHandlers handlers; | ||
Line 108: | Line 108: | ||
Discord_UpdatePresence(&discordPresence); | Discord_UpdatePresence(&discordPresence); | ||
} | } | ||
</ | </source> | ||
"ModImageHere" is an image key, remember that Discord developer page you were on earlier, where you set up your application? Go back there and to your application page, now go down to "Rich Presence" and click on "Art Assets" and click "Add Image(s)". Add an image you want for your mod and whatever you name that image is the name you replace "ModImageHere" with. | <code>"ModImageHere"</code> is an image key, remember that Discord developer page you were on earlier, where you set up your application? Go back there and to your application page, now go down to "Rich Presence" and click on "Art Assets" and click "Add Image(s)". Add an image you want for your mod and whatever you name that image is the name you replace <code>"ModImageHere"</code> with. | ||
Now that that's done, let's go further down to the | Now that that's done, let's go further down to the <code>CHLClient::Shutdown( void )</code> function, here we'll add the Shutdown method, add the following below the </code>#endif</code> for <code>WORKSHOP_IMPORT_ENABLED</code> | ||
< | <source lang="cpp"> | ||
// Discord RPC | // Discord RPC | ||
Discord_Shutdown(); | Discord_Shutdown(); | ||
</ | </source> | ||
Now go further down to | Now go further down to <code>CHLClient::LevelInitPreEntity( ... )</code> and above the comment for <code>g_RagdollLVManager.SetLowViolence( pMapName );</code> add | ||
< | <source lang="cpp"> | ||
// Discord RPC | // Discord RPC | ||
if (!g_bTextMode) | if (!g_bTextMode) | ||
Line 133: | Line 133: | ||
Discord_UpdatePresence(&discordPresence); | Discord_UpdatePresence(&discordPresence); | ||
} | } | ||
</ | </source> | ||
Now we'll add the last piece of code into | Now we'll add the last piece of code into <code>CHLClient::LevelShutdown( void )</code>. Below | ||
< | <source lang="cpp"> | ||
gHUD.LevelShutdown(); | gHUD.LevelShutdown(); | ||
</ | </source> | ||
add | add | ||
< | <source lang="cpp"> | ||
// Discord RPC | // Discord RPC | ||
if (!g_bTextMode) | if (!g_bTextMode) | ||
Line 153: | Line 153: | ||
Discord_UpdatePresence(&discordPresence); | Discord_UpdatePresence(&discordPresence); | ||
} | } | ||
</ | </source> | ||
== Conclusion == | == Conclusion == | ||
The installation and setup are both complete! | The installation and setup are both complete! Try launching your mod and check your Discord status, now load up a map and check again! | ||
This system works for both the SP and MP branch of Source SDK 2013. Source SDK 2007 has not been tested yet | This system works for both the SP and MP branch of Source SDK 2013. Source SDK 2007 has not been tested yet but should work just as well. | ||
[[Category:Programming]] | [[Category:Programming]] | ||
[[Category:Free source code]] | [[Category:Free source code]] |
Revision as of 12:48, 21 February 2020
Implementing Discord RPC into the Source engine is simple, and it makes your mod stand out more, as your in-game "presence" can be seen through Discord.
What is Discord RPC?
Discord RPC is a library for interfacing your game with a locally running Discord desktop client. It's known to work on Windows, macOS, and Linux. 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.
Below is an example using this article as a base, with obvious modifications:
The Installation
First off you'll need to download the latest version Discord RPC. You can do so by going to Discord's GitHub repository here. And download the latest discord-rpc-win.zip file, as of writing we'll be using v3.3.0. Once downloaded, open the archive and go to win32-dynamic/lib/ and extract discord-rpc.lib to your mod's <src code directory>/src/lib/public/ once that's done we'll do the same for the include files, in your archive take a step back and go into the include folder, now extract discord_rpc.h and discord_register.h to <src code directory>/src/public/. Now for the final step, once again in your archive take a step back and go into the bin folder, now extract discord-rpc.dll to your mod's /bin folder ex. <Steam directory>/steamapps/sourcemods/YourMod/bin/.
The Setup
Now that the installation is done, it's time to set up our system. There's not a whole lot to do here, but this is a necessary step you'll have to take to make the implementation work.
To start off, go into <src code directory>/src/vpc_scripts/ and open source_dll_win32_base.vpc with your favorite text editor (I personally use Notepad++). Once you've opened the file, scroll all the way down to $Folder "Link Libraries"
and under $Implib "$LIBPUBLIC\vstdlib"
add $Lib "$LIBPUBLIC\discord-rpc"
. After you've modified the VPC scripts, make sure to rerun createallprojects.bat and/or creategameprojects.bat before continuing, otherwise you might experience errors while building.
All that needs to be done now is to start the Discord RPC system when the modification launches. To do this, open up cdll_client_int.cpp, and at the bottom add #include "discord_rpc.h"
and #include <time.h>
to the list of includes, then under
static ConVar s_cl_class("cl_class", "default", FCVAR_USERINFO|FCVAR_ARCHIVE, "Default class when joining a game");
add
// Discord RPC
static ConVar cl_discord_appid("cl_discord_appid", "123456789123456789", FCVAR_DEVELOPMENTONLY | FCVAR_CHEAT);
static int64_t startTimestamp = time(0);
where the numbers after cl_discord_appid
are your applications RPC appid, to set up a RPC client go here, once your application is set up the number you'll want to place after cl_discord_appid
is the "Client ID" seen in "General Information".
When that's done add the following above CHLClient::CHLClient()
//-----------------------------------------------------------------------------
// Discord RPC
//-----------------------------------------------------------------------------
static void HandleDiscordReady(const DiscordUser* connectedUser)
{
DevMsg("Discord: Connected to user %s#%s - %s\n",
connectedUser->username,
connectedUser->discriminator,
connectedUser->userId);
}
static void HandleDiscordDisconnected(int errcode, const char* message)
{
DevMsg("Discord: Disconnected (%d: %s)\n", errcode, message);
}
static void HandleDiscordError(int errcode, const char* message)
{
DevMsg("Discord: Error (%d: %s)\n", errcode, message);
}
static void HandleDiscordJoin(const char* secret)
{
// Not implemented
}
static void HandleDiscordSpectate(const char* secret)
{
// Not implemented
}
static void HandleDiscordJoinRequest(const DiscordUser* request)
{
// Not implemented
}
Now scroll down to CHLClient::Init( ... )
and add the following above return true;
at the bottom of the function.
// Discord RPC
DiscordEventHandlers handlers;
memset(&handlers, 0, sizeof(handlers));
handlers.ready = HandleDiscordReady;
handlers.disconnected = HandleDiscordDisconnected;
handlers.errored = HandleDiscordError;
handlers.joinGame = HandleDiscordJoin;
handlers.spectateGame = HandleDiscordSpectate;
handlers.joinRequest = HandleDiscordJoinRequest;
char appid[255];
sprintf(appid, "%d", engine->GetAppID());
Discord_Initialize(cl_discord_appid.GetString(), &handlers, 1, appid);
if (!g_bTextMode)
{
DiscordRichPresence discordPresence;
memset(&discordPresence, 0, sizeof(discordPresence));
discordPresence.state = "In-Game";
discordPresence.details = "Main Menu";
discordPresence.startTimestamp = startTimestamp;
discordPresence.largeImageKey = "ModImageHere";
Discord_UpdatePresence(&discordPresence);
}
"ModImageHere"
is an image key, remember that Discord developer page you were on earlier, where you set up your application? Go back there and to your application page, now go down to "Rich Presence" and click on "Art Assets" and click "Add Image(s)". Add an image you want for your mod and whatever you name that image is the name you replace "ModImageHere"
with.
Now that that's done, let's go further down to the CHLClient::Shutdown( void )
function, here we'll add the Shutdown method, add the following below the #endif for WORKSHOP_IMPORT_ENABLED
// Discord RPC
Discord_Shutdown();
Now go further down to CHLClient::LevelInitPreEntity( ... )
and above the comment for g_RagdollLVManager.SetLowViolence( pMapName );
add
// Discord RPC
if (!g_bTextMode)
{
DiscordRichPresence discordPresence;
memset(&discordPresence, 0, sizeof(discordPresence));
char buffer[256];
discordPresence.state = "In-Game";
sprintf(buffer, "Map: %s", pMapName);
discordPresence.details = buffer;
discordPresence.largeImageKey = "ModImageHere";
Discord_UpdatePresence(&discordPresence);
}
Now we'll add the last piece of code into CHLClient::LevelShutdown( void )
. Below
gHUD.LevelShutdown();
add
// Discord RPC
if (!g_bTextMode)
{
DiscordRichPresence discordPresence;
memset(&discordPresence, 0, sizeof(discordPresence));
discordPresence.state = "In-Game";
discordPresence.details = "Main Menu";
discordPresence.startTimestamp = startTimestamp;
discordPresence.largeImageKey = "ModImageHere";
Discord_UpdatePresence(&discordPresence);
}
Conclusion
The installation and setup are both complete! Try launching your mod and check your Discord status, now load up a map and check again!
This system works for both the SP and MP branch of Source SDK 2013. Source SDK 2007 has not been tested yet but should work just as well.