diff --git a/.gitmodules b/.gitmodules index a3ad53c3..11377e21 100644 --- a/.gitmodules +++ b/.gitmodules @@ -10,3 +10,9 @@ [submodule "deps/GSL"] path = deps/GSL url = https://github.com/Microsoft/GSL.git +[submodule "deps/rapidjson"] + path = deps/rapidjson + url = https://github.com/Tencent/rapidjson.git +[submodule "deps/discord-rpc"] + path = deps/discord-rpc + url = https://github.com/discord/discord-rpc.git diff --git a/deps/discord-rpc b/deps/discord-rpc new file mode 160000 index 00000000..963aa9f3 --- /dev/null +++ b/deps/discord-rpc @@ -0,0 +1 @@ +Subproject commit 963aa9f3e5ce81a4682c6ca3d136cddda614db33 diff --git a/deps/premake/discord-rpc.lua b/deps/premake/discord-rpc.lua new file mode 100644 index 00000000..ef28bcb3 --- /dev/null +++ b/deps/premake/discord-rpc.lua @@ -0,0 +1,39 @@ +discordrpc = { + source = path.join(dependencies.basePath, "discord-rpc"), +} + +function discordrpc.import() + links { "discord-rpc" } + discordrpc.includes() +end + +function discordrpc.includes() + includedirs { + path.join(discordrpc.source, "include"), + } +end + +function discordrpc.project() + project "discord-rpc" + language "C++" + + discordrpc.includes() + rapidjson.import(); + + files { + path.join(discordrpc.source, "src/*.h"), + path.join(discordrpc.source, "src/*.cpp"), + } + + removefiles { + path.join(discordrpc.source, "src/dllmain.cpp"), + path.join(discordrpc.source, "src/*_linux.cpp"), + path.join(discordrpc.source, "src/*_unix.cpp"), + path.join(discordrpc.source, "src/*_osx.cpp"), + } + + warnings "Off" + kind "StaticLib" +end + +table.insert(dependencies, discordrpc) diff --git a/deps/premake/rapidjson.lua b/deps/premake/rapidjson.lua new file mode 100644 index 00000000..d1085120 --- /dev/null +++ b/deps/premake/rapidjson.lua @@ -0,0 +1,19 @@ +rapidjson = { + source = path.join(dependencies.basePath, "rapidjson"), +} + +function rapidjson.import() + rapidjson.includes() +end + +function rapidjson.includes() + includedirs { + path.join(rapidjson.source, "include"), + } +end + +function rapidjson.project() + +end + +table.insert(dependencies, rapidjson) diff --git a/deps/rapidjson b/deps/rapidjson new file mode 160000 index 00000000..e0f68a43 --- /dev/null +++ b/deps/rapidjson @@ -0,0 +1 @@ +Subproject commit e0f68a435610e70ab5af44fc6a90523d69b210b3 diff --git a/src/component/discord.cpp b/src/component/discord.cpp new file mode 100644 index 00000000..db770c37 --- /dev/null +++ b/src/component/discord.cpp @@ -0,0 +1,88 @@ +#include +#include "loader/component_loader.hpp" +#include "scheduler.hpp" +#include "game/game.hpp" + +#include + +#include + +namespace discord +{ + namespace + { + DiscordRichPresence discord_presence; + + void update_discord() + { + Discord_RunCallbacks(); + + if (!game::CL_IsCgameInitialized()) + { + discord_presence.details = "Main Menu"; + discord_presence.state = ""; + + discord_presence.startTimestamp = 0; + + discord_presence.largeImageKey = "h2"; + } + else + { + const auto map = game::Dvar_FindVar("mapname")->current.string; + const auto mapname = game::UI_SafeTranslateString(utils::string::va("PRESENCE_SP_%s", map)); + + discord_presence.details = mapname; + discord_presence.state = ""; + + if (!discord_presence.startTimestamp) + { + discord_presence.startTimestamp = std::chrono::duration_cast( + std::chrono::system_clock::now().time_since_epoch()).count(); + } + } + + Discord_UpdatePresence(&discord_presence); + } + } + + class component final : public component_interface + { + public: + void post_unpack() override + { + DiscordEventHandlers handlers; + ZeroMemory(&handlers, sizeof(handlers)); + handlers.ready = ready; + handlers.errored = errored; + handlers.disconnected = errored; + handlers.joinGame = nullptr; + handlers.spectateGame = nullptr; + handlers.joinRequest = nullptr; + + Discord_Initialize("835690302583996416", &handlers, 1, nullptr); + + scheduler::loop(update_discord, scheduler::pipeline::async, 5s); + + initialized_ = true; + } + + private: + bool initialized_ = false; + + static void ready(const DiscordUser* /*request*/) + { + ZeroMemory(&discord_presence, sizeof(discord_presence)); + + discord_presence.instance = 1; + + Discord_UpdatePresence(&discord_presence); + } + + static void errored(const int error_code, const char* message) + { + printf("Discord: (%i) %s", error_code, message); + } + }; +} + +REGISTER_COMPONENT(discord::component) \ No newline at end of file diff --git a/src/game/symbols.hpp b/src/game/symbols.hpp index d5cde839..8953fc60 100644 --- a/src/game/symbols.hpp +++ b/src/game/symbols.hpp @@ -33,6 +33,8 @@ namespace game WEAK symbol generateHashValue{0x343D20}; + WEAK symbol CL_IsCgameInitialized{0x3CA0C0}; + WEAK symbol FindEntityId{0x5C1C50}; WEAK symbol GetEntityFieldValue{0x5C6100}; @@ -62,6 +64,8 @@ namespace game WEAK symbol Sys_ShowConsole{0x633080}; + WEAK symbol UI_SafeTranslateString{0x5A2930}; + WEAK symbol longjmp{0x89EED0}; WEAK symbol _setjmp{0x8EC2E0};