Merge pull request #9 from kiseki-lol/feature/discord-rich-presence
Discord Rich Presence
This commit is contained in:
commit
a9b488e7c5
|
|
@ -2,6 +2,10 @@ cmake_minimum_required(VERSION 3.4)
|
|||
|
||||
set(CMAKE_CXX_STANDARD 17)
|
||||
|
||||
# TODO: This shouldn't be necessary.
|
||||
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /MT")
|
||||
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /MTd")
|
||||
|
||||
project(Kiseki.Patcher VERSION 1.0.0)
|
||||
|
||||
option(COMPILE_PLAYER "Include player-specific code" OFF)
|
||||
|
|
|
|||
|
|
@ -26,6 +26,12 @@ if(COMPILE_PLAYER OR COMPILE_SERVER)
|
|||
list(APPEND SOURCE Source/Hooks/CRoblox.cpp)
|
||||
list(APPEND HEADER Header/Hooks/CRoblox.hpp)
|
||||
|
||||
if(COMPILE_PLAYER)
|
||||
# Discord Rich Presence integration
|
||||
list(APPEND SOURCE Source/Discord.cpp)
|
||||
list(APPEND HEADER Header/Discord.hpp)
|
||||
endif()
|
||||
|
||||
if(COMPILE_SERVER)
|
||||
# Hook ServerReplicator
|
||||
list(APPEND SOURCE Source/Hooks/ServerReplicator.cpp)
|
||||
|
|
@ -47,6 +53,11 @@ target_link_libraries(Kiseki.Patcher PRIVATE CURL::libcurl ${DETOURS_LIBRARY} ra
|
|||
|
||||
# Target-specific linking and compile options
|
||||
if(COMPILE_PLAYER)
|
||||
find_path(DISCORD_RPC_INCLUDE_DIRS "discord_rpc.h")
|
||||
find_library(DISCORD_RPC_LIBRARY discord-rpc REQUIRED)
|
||||
|
||||
target_include_directories(Kiseki.Patcher PRIVATE ${DISCORD_RPC_INCLUDE_DIRS})
|
||||
target_link_libraries(Kiseki.Patcher PRIVATE ${DISCORD_RPC_LIBRARY})
|
||||
target_compile_definitions(Kiseki.Patcher PRIVATE PLAYER)
|
||||
endif()
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,23 @@
|
|||
#ifdef PLAYER
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <thread>
|
||||
|
||||
#include <discord_rpc.h>
|
||||
#include <discord_register.h>
|
||||
#include <rapidjson/document.h>
|
||||
|
||||
#include "Hooks/CRoblox.hpp"
|
||||
|
||||
#include "Globals.hpp"
|
||||
|
||||
class Discord {
|
||||
public:
|
||||
static void Initialize(const std::string joinScriptUrl);
|
||||
static void Cleanup();
|
||||
private:
|
||||
static void Update();
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -8,6 +8,7 @@
|
|||
#include <map>
|
||||
|
||||
#include <curl/curl.h>
|
||||
#include <pugixml.hpp>
|
||||
|
||||
#include "Globals.hpp"
|
||||
|
||||
|
|
@ -31,4 +32,5 @@ public:
|
|||
static std::pair<bool, std::map<std::string, std::string>> parseURL(const std::string url);
|
||||
static std::string getRedirectURL(const std::string url);
|
||||
static std::pair<bool, std::string> httpGet(const std::string url);
|
||||
static std::string getBaseUrl();
|
||||
};
|
||||
|
|
@ -7,6 +7,10 @@
|
|||
#include "Globals.hpp"
|
||||
#include "Helpers.hpp"
|
||||
|
||||
#ifdef PLAYER
|
||||
#include "Discord.hpp"
|
||||
#endif
|
||||
|
||||
class CWorkspace;
|
||||
|
||||
const auto CWorkspace__ExecUrlScript = (HRESULT(__stdcall*)(CWorkspace * workspace, LPCWSTR, VARIANTARG, VARIANTARG, VARIANTARG, VARIANTARG, LPVOID))ADDRESS_CWORKSPACE__EXECURLSCRIPT;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,122 @@
|
|||
#ifdef PLAYER
|
||||
|
||||
#include "Discord.hpp"
|
||||
|
||||
bool isRunning = false;
|
||||
std::string username;
|
||||
int placeId;
|
||||
|
||||
void Discord::Initialize(const std::string joinScriptUrl)
|
||||
{
|
||||
std::pair<bool, std::map<std::string, std::string>> parsed = Helpers::parseURL(joinScriptUrl);
|
||||
|
||||
if (!parsed.first)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (parsed.second["query"].empty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
std::map<std::string, std::string> query = Helpers::parseQueryString(parsed.second["query"]);
|
||||
|
||||
if (query.find("ticket") == query.end())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (query.find("discord") == query.end())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (query["ticket"].empty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (query["discord"] == "0")
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Get the username and placeId
|
||||
std::pair<bool, std::string> response = Helpers::httpGet(Helpers::getBaseUrl() + std::string("/api/places/information?ticket=" + query["ticket"]));
|
||||
if (!response.first)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
rapidjson::Document document;
|
||||
document.Parse(response.second.c_str());
|
||||
|
||||
if (document.HasParseError() || !document.HasMember("username") || !document.HasMember("placeId"))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
username = document["username"].GetString();
|
||||
placeId = document["placeId"].GetInt();
|
||||
|
||||
Discord::Update();
|
||||
|
||||
// Run the updater
|
||||
std::thread updater(Discord::Update);
|
||||
updater.join();
|
||||
}
|
||||
|
||||
void Discord::Update()
|
||||
{
|
||||
isRunning = true;
|
||||
|
||||
while (isRunning)
|
||||
{
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(60 * 1000));
|
||||
|
||||
std::string title = "";
|
||||
int size = 0;
|
||||
int max = 0;
|
||||
|
||||
// Get title, size, and max
|
||||
std::pair<bool, std::string> response = Helpers::httpGet(Helpers::getBaseUrl() + std::string("/api/places/information?id=" + placeId));
|
||||
if (!response.first)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
rapidjson::Document document;
|
||||
document.Parse(response.second.c_str());
|
||||
|
||||
if (document.HasParseError() || !document.HasMember("title") || !document.HasMember("size") || !document.HasMember("max"))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
title = document["title"].GetString();
|
||||
size = document["size"].GetInt();
|
||||
max = document["max"].GetInt();
|
||||
|
||||
DiscordRichPresence presence;
|
||||
memset(&presence, 0, sizeof(presence));
|
||||
|
||||
presence.largeImageText = username.c_str();
|
||||
presence.largeImageKey = "logo";
|
||||
presence.smallImageText = "2011";
|
||||
presence.smallImageKey = "2011";
|
||||
|
||||
presence.details = title.c_str();
|
||||
presence.state = "In a game";
|
||||
presence.partySize = size;
|
||||
presence.partyMax = max;
|
||||
}
|
||||
}
|
||||
|
||||
void Discord::Cleanup()
|
||||
{
|
||||
isRunning = false;
|
||||
Discord_Shutdown();
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -250,3 +250,27 @@ std::pair<bool, std::string> Helpers::httpGet(const std::string url)
|
|||
|
||||
return std::make_pair(true, data);
|
||||
}
|
||||
|
||||
std::string Helpers::getBaseUrl()
|
||||
{
|
||||
std::string path = Helpers::getModulePath();
|
||||
path = path.substr(0, path.find_last_of("\\/"));
|
||||
|
||||
pugi::xml_document document;
|
||||
pugi::xml_parse_result result = document.load_file((path + "\\AppSettings.xml").c_str());
|
||||
|
||||
if (!result)
|
||||
{
|
||||
return "";
|
||||
}
|
||||
|
||||
pugi::xml_node settings = document.child("Settings");
|
||||
pugi::xml_node baseUrl = settings.child("BaseUrl");
|
||||
|
||||
if (!baseUrl)
|
||||
{
|
||||
return "";
|
||||
}
|
||||
|
||||
return baseUrl.child_value();
|
||||
}
|
||||
|
|
@ -79,6 +79,10 @@ void __fastcall CRobloxCommandLineInfo__ParseParam_hook(CRobloxCommandLineInfo*
|
|||
_this->m_bRunAutomated = TRUE;
|
||||
|
||||
CCommandLineInfo__ParseLast(_this, bLast);
|
||||
|
||||
#ifdef PLAYER
|
||||
Discord::Initialize(Helpers::ws2s(joinScriptUrl));
|
||||
#endif
|
||||
}
|
||||
|
||||
if (hasAuthenticationUrl && authenticationUrl.empty())
|
||||
|
|
|
|||
|
|
@ -3,6 +3,10 @@
|
|||
#include "Globals.hpp"
|
||||
#include "Patcher.hpp"
|
||||
|
||||
#ifdef PLAYER
|
||||
#include "Discord.hpp"
|
||||
#endif
|
||||
|
||||
#include "Hooks/Http.hpp"
|
||||
#include "Hooks/Crypt.hpp"
|
||||
#include "Hooks/CRoblox.hpp"
|
||||
|
|
@ -60,6 +64,10 @@ BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserv
|
|||
if (ul_reason_for_call == DLL_PROCESS_DETACH)
|
||||
{
|
||||
curl_global_cleanup();
|
||||
|
||||
#ifdef PLAYER
|
||||
Discord::Cleanup();
|
||||
#endif
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@
|
|||
"dependencies": [
|
||||
"curl",
|
||||
"detours",
|
||||
"discord-rpc",
|
||||
"rapidjson"
|
||||
]
|
||||
}
|
||||
Loading…
Reference in New Issue