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)
This commit is contained in:
m 2022-03-15 18:59:03 -05:00
parent f5990e2acf
commit f8125af152
4 changed files with 71 additions and 4 deletions

View File

@ -9,6 +9,7 @@
#include "party.hpp" #include "party.hpp"
#include <utils/string.hpp> #include <utils/string.hpp>
#include <utils/cryptography.hpp>
#include <discord_rpc.h> #include <discord_rpc.h>
@ -37,6 +38,12 @@ namespace discord
discord_presence.partyMax = 0; discord_presence.partyMax = 0;
discord_presence.startTimestamp = 0; discord_presence.startTimestamp = 0;
discord_presence.largeImageKey = game::environment::is_sp() ? "menu_singleplayer" : "menu_multiplayer"; 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 else
{ {
@ -59,6 +66,22 @@ namespace discord
{ {
strcpy_s(clean_hostname, "Private Match"); strcpy_s(clean_hostname, "Private Match");
max_clients = game::Dvar_FindVar("sv_maxclients")->current.integer; 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<int*>(0x1429864C4); discord_presence.partySize = *reinterpret_cast<int*>(0x1429864C4);
@ -99,9 +122,9 @@ namespace discord
handlers.ready = ready; handlers.ready = ready;
handlers.errored = errored; handlers.errored = errored;
handlers.disconnected = errored; handlers.disconnected = errored;
handlers.joinGame = nullptr; handlers.joinGame = joinGame;
handlers.spectateGame = nullptr; handlers.spectateGame = nullptr;
handlers.joinRequest = nullptr; handlers.joinRequest = joinRequest;
Discord_Initialize("947125042930667530", &handlers, 1, nullptr); Discord_Initialize("947125042930667530", &handlers, 1, nullptr);
@ -127,13 +150,13 @@ namespace discord
private: private:
bool initialized_ = false; bool initialized_ = false;
static void ready(const DiscordUser* /*request*/) static void ready(const DiscordUser* request)
{ {
ZeroMemory(&discord_presence, sizeof(discord_presence)); ZeroMemory(&discord_presence, sizeof(discord_presence));
discord_presence.instance = 1; 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); Discord_UpdatePresence(&discord_presence);
} }
@ -142,6 +165,27 @@ namespace discord
{ {
console::error("Discord: Error (%i): %s\n", error_code, message); 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);
}
}; };
} }

View File

@ -234,6 +234,16 @@ namespace party
network::send(target, "getInfo", connect_state.challenge); 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) void start_map(const std::string& mapname)
{ {
if (game::Live_SyncOnlineDataFlags(0) > 32) if (game::Live_SyncOnlineDataFlags(0) > 32)

View File

@ -9,6 +9,8 @@ namespace party
void start_map(const std::string& mapname); void start_map(const std::string& mapname);
void clear_sv_motd(); void clear_sv_motd();
game::netadr_s get_state_host();
std::string get_state_challenge();
int server_client_count(); int server_client_count();
int get_client_num_by_name(const std::string& name); int get_client_num_by_name(const std::string& name);

View File

@ -146,6 +146,16 @@ void limit_parallel_dll_loading()
RegCloseKey(key); 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() int main()
{ {
FARPROC entry_point; FARPROC entry_point;
@ -169,6 +179,7 @@ int main()
try try
{ {
apply_proper_directory();
remove_crash_file(); remove_crash_file();
if (!component_loader::post_start()) return 0; if (!component_loader::post_start()) return 0;