From c52cfa73b4f7e150733afcbf47e96cb5ef51efb4 Mon Sep 17 00:00:00 2001 From: m Date: Tue, 15 Mar 2022 18:59:03 -0500 Subject: [PATCH] discord rich presence joining TODO: - add a "session ID" randomly generated string - improve the Joining game on DW initalized > main thread? - join requests with avatars in game (ui scripting) --- src/client/component/discord.cpp | 52 +++++++++++++++++++++++++++++--- src/client/component/party.cpp | 10 ++++++ src/client/component/party.hpp | 2 ++ src/client/main.cpp | 11 +++++++ 4 files changed, 71 insertions(+), 4 deletions(-) diff --git a/src/client/component/discord.cpp b/src/client/component/discord.cpp index 5925a64a..455c510f 100644 --- a/src/client/component/discord.cpp +++ b/src/client/component/discord.cpp @@ -9,6 +9,7 @@ #include "party.hpp" #include +#include #include @@ -37,6 +38,12 @@ namespace discord discord_presence.partyMax = 0; discord_presence.startTimestamp = 0; discord_presence.largeImageKey = game::environment::is_sp() ? "menu_singleplayer" : "menu_multiplayer"; + + // set to blank when in lobby + discord_presence.matchSecret = ""; + discord_presence.joinSecret = ""; + discord_presence.partyId = ""; + discord_presence.state = ""; } else { @@ -59,6 +66,22 @@ namespace discord { strcpy_s(clean_hostname, "Private Match"); max_clients = game::Dvar_FindVar("sv_maxclients")->current.integer; + discord_presence.partyPrivacy = DISCORD_PARTY_PRIVATE; + } + else + { + discord_presence.partyPrivacy = DISCORD_PARTY_PUBLIC; + + // TODO: we need to make this a random string that represents the session ID + // const auto sessionId = party::get_state_challenge(); + discord_presence.partyId = "PLACEHOLDER"; + + const auto server_net_info = party::get_state_host(); + const auto server_ip_port = utils::string::va("%i.%i.%i.%i:%i", + server_net_info.ip[0], server_net_info.ip[1], server_net_info.ip[2], server_net_info.ip[3], + ntohs(server_net_info.port)); + + discord_presence.joinSecret = server_ip_port; } discord_presence.partySize = *reinterpret_cast(0x1429864C4); @@ -99,9 +122,9 @@ namespace discord handlers.ready = ready; handlers.errored = errored; handlers.disconnected = errored; - handlers.joinGame = nullptr; + handlers.joinGame = joinGame; handlers.spectateGame = nullptr; - handlers.joinRequest = nullptr; + handlers.joinRequest = joinRequest; Discord_Initialize("947125042930667530", &handlers, 1, nullptr); @@ -127,13 +150,13 @@ namespace discord private: bool initialized_ = false; - static void ready(const DiscordUser* /*request*/) + static void ready(const DiscordUser* request) { ZeroMemory(&discord_presence, sizeof(discord_presence)); discord_presence.instance = 1; - console::info("Discord: Ready\n"); + console::info("Discord: Ready on %s (%s)\n", request->username, request->userId); Discord_UpdatePresence(&discord_presence); } @@ -142,6 +165,27 @@ namespace discord { console::error("Discord: Error (%i): %s\n", error_code, message); } + + static void joinGame(const char* joinSecret) + { + console::info("Discord: Join game called with join secret: %s\n", joinSecret); + + scheduler::once([joinSecret]() + { + game::netadr_s target{}; + if (game::NET_StringToAdr(joinSecret, &target)) + { + console::info("Discord: Connecting to server: %s\n", joinSecret); + party::connect(target); + } + }, scheduler::pipeline::main); + } + + static void joinRequest(const DiscordUser* request) + { + console::info("Discord: joinRequest from %s (%s)\n", request->username, request->userId); + // Discord_Respond(request->userId, DISCORD_REPLY_YES); + } }; } diff --git a/src/client/component/party.cpp b/src/client/component/party.cpp index 38dd7277..5a88eb65 100644 --- a/src/client/component/party.cpp +++ b/src/client/component/party.cpp @@ -234,6 +234,16 @@ namespace party network::send(target, "getInfo", connect_state.challenge); } + game::netadr_s get_state_host() + { + return connect_state.host; + } + + std::string get_state_challenge() + { + return connect_state.challenge; + } + void start_map(const std::string& mapname) { if (game::Live_SyncOnlineDataFlags(0) > 32) diff --git a/src/client/component/party.hpp b/src/client/component/party.hpp index 0feb2e98..13990aea 100644 --- a/src/client/component/party.hpp +++ b/src/client/component/party.hpp @@ -9,6 +9,8 @@ namespace party void start_map(const std::string& mapname); void clear_sv_motd(); + game::netadr_s get_state_host(); + std::string get_state_challenge(); int server_client_count(); int get_client_num_by_name(const std::string& name); diff --git a/src/client/main.cpp b/src/client/main.cpp index 7329eb4c..500a09c4 100644 --- a/src/client/main.cpp +++ b/src/client/main.cpp @@ -146,6 +146,16 @@ void limit_parallel_dll_loading() RegCloseKey(key); } +// solution for other processes that may launch the mod +void apply_proper_directory() +{ + char module_path[MAX_PATH]; + GetModuleFileNameA(nullptr, module_path, MAX_PATH); + PathRemoveFileSpecA(module_path); + SetCurrentDirectoryA(module_path); + SetDllDirectoryA(module_path); +} + int main() { FARPROC entry_point; @@ -169,6 +179,7 @@ int main() try { + apply_proper_directory(); remove_crash_file(); if (!component_loader::post_start()) return 0;