Discord Rich Presence + public key

This commit is contained in:
lightbulblighter 2022-08-05 17:51:34 -07:00
parent e20fb7ae51
commit 256f487e6e
No known key found for this signature in database
GPG Key ID: 58D6EDC2C38C9B3B
14 changed files with 248 additions and 13 deletions

138
Tadah.DLL/Discord.cpp Normal file
View File

@ -0,0 +1,138 @@
#include "pch.h"
#include "Discord.h"
#ifndef ARBITERBUILD
std::string username;
int placeId;
void InitializeDiscord()
{
// Check if Discord should be enabled by checking if the binary is the client as well as if the binary's containing folder contains a ".nodiscord" file
char buffer[MAX_PATH];
GetModuleFileNameA(NULL, buffer, MAX_PATH);
std::string path = std::string(buffer);
if (fs::path(path).stem() != "TadahPlayer")
{
return;
}
if (fs::exists(fs::path(path).parent_path() / ".nodiscord"))
{
return;
}
// Get the username and placeId
CURL* curl = curl_easy_init();
CURLcode result;
long response = 0;
std::string data;
if (!curl)
{
return;
}
curl_easy_setopt(curl, CURLOPT_URL, std::string(BASE_URL + std::string("/api/places/information?ticket=") + ticket));
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, Helpers::write);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &data);
result = curl_easy_perform(curl);
curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &response);
curl_easy_cleanup(curl);
if (result != CURLE_OK || response != 200)
{
return;
}
rapidjson::Document document;
document.Parse(data.c_str());
if (document.HasParseError() || !document.HasMember("username") || !document.HasMember("placeId"))
{
return;
}
username = document["username"].GetString();
placeId = document["placeId"].GetInt();
UpdatePresence();
// Run the updater
std::thread updater(UpdatePresence);
updater.join();
}
void UpdatePresence()
{
while (true)
{
std::this_thread::sleep_for(std::chrono::milliseconds(60 * 1000));
std::string title = "";
int size = 0;
int max = 0;
// Get title, size, and max
CURL* curl = curl_easy_init();
CURLcode result;
long response = 0;
std::string data;
if (!curl)
{
return;
}
curl_easy_setopt(curl, CURLOPT_URL, std::string(BASE_URL + std::string("/api/places/information?id=") + std::to_string(placeId)));
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, Helpers::write);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &data);
result = curl_easy_perform(curl);
curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &response);
curl_easy_cleanup(curl);
if (result != CURLE_OK || response != 200)
{
return;
}
rapidjson::Document document;
document.Parse(data.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 CleanupDiscord()
{
Discord_Shutdown();
}
#endif

View File

@ -104,4 +104,21 @@ std::string Helpers::joinQueryString(std::map<std::string, std::string> query)
result.pop_back(); // remove ending ampersand
return result;
}
// https://stackoverflow.com/a/12097772
std::string Helpers::ws2s(std::wstring widestring)
{
std::string string;
std::transform(widestring.begin(), widestring.end(), std::back_inserter(string), [](wchar_t c) {
return (char)c;
});
return string;
}
size_t Helpers::write(char* contents, size_t size, size_t memory, void* pointer)
{
((std::string*)pointer)->append((char*)contents, size * memory);
return size * memory;
}

View File

@ -2,6 +2,8 @@
#include "Hooks/CRoblox.h"
static std::string ticket;
static bool hasAuthUrlArg = false;
static bool hasAuthTicketArg = false;
static bool hasJoinArg = false;
@ -55,6 +57,36 @@ void __fastcall CRobloxCommandLineInfo__ParseParam_hook(CRobloxCommandLineInfo*
_this->m_bRunAutomated = TRUE;
CCommandLineInfo__ParseLast(_this, bLast);
// Parse the joinScriptUrl for it's placeId here
try
{
CURLU* curl = curl_url();
CURLUcode result = curl_url_set(curl, CURLUPART_URL, Helpers::ws2s(joinScriptUrl).c_str(), 0);
if (result == CURLE_OK)
{
char* query;
curl_url_get(curl, CURLUPART_QUERY, &query, 0);
curl_url_cleanup(curl);
std::map<std::string, std::string> parameters = Helpers::parseQueryString(std::string(query));
if (parameters.find("ticket") != parameters.end())
{
ticket = parameters["ticket"];
}
}
}
catch (...)
{
//
}
if (ticket.empty())
{
ExitProcess(EXIT_FAILURE);
}
return;
}
#endif

View File

@ -1,6 +1,5 @@
#include "pch.h"
#include "Helpers.h"
#include "Hooks/Http.h"
#define CHECK(condition, code) \
@ -13,12 +12,6 @@
Http__httpGetPostWinInet_t Http__httpGetPostWinInet = (Http__httpGetPostWinInet_t)ADDRESS_HTTP__HTTPGETPOSTWININET;
Http__trustCheck_t Http__trustCheck = (Http__trustCheck_t)ADDRESS_HTTP__TRUSTCHECK;
size_t write(char* contents, size_t size, size_t memory, void* pointer)
{
((std::string*)pointer)->append((char*)contents, size * memory);
return size * memory;
}
void __fastcall Http__httpGetPostWinInet_hook(Http* _this, void*, bool isPost, int a3, bool compressData, LPCSTR additionalHeaders, int a6)
{
CURLU* curl = curl_url();
@ -105,7 +98,7 @@ void __fastcall Http__httpGetPostWinInet_hook(Http* _this, void*, bool isPost, i
}
curl_easy_setopt(curl, CURLOPT_URL, api);
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write);
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, Helpers::write);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &data);
result = curl_easy_perform(curl);

View File

@ -1,14 +1,17 @@
#pragma once
#define BASE_URL "tadah.rocks"
#define DISCORD_APP_ID 923705431543668736
#define ALLOWED_WILDCARD_DOMAINS "tadah.rocks", "rbxcdn.com", "roblox.com"
#define ALLOWED_DOMAINS
#define ALLOWED_SCHEMES "http", "https"
#define ALLOWED_EMBEDDED_SCHEMES "javascript", "jscript", "res"
#ifdef _DEBUG
#define PUBLIC_KEY ""
#define PUBLIC_KEY "BgIAAACkAABSU0ExABAAAAEAAQAVZ+t4ywGMLfMmCbtQv8HNKsSGERgVq+giTsaTbovzYYsX4LRxqQWk81MDX3VlwdpHqcKlZJgsB9xQMt6jSy79f89UZybasguwuljUsFoUCkMinjnnJZuGKJouqq5+OL86q/PafC8xhDIU2GnP/ALcLsk9letXLUR/OFHnD32MkEzbMax89d263LO1T2sjGLQCVM438ATF2GNdqJIEWVLDGqv+4UkN+2otAfOToJ/y+e1L4fFi9xonV0vc8RhOQ8U6WzdKVK+0KpmAncFw/MUYAXtBO37CCVRX4cHQ+9XCFMO9XLBkC9F6GKe1RlhM/YsOqKVBvaiPpWlQFgQQk2VaPO37qjKiAHHAB9Dp3TJbF+5nUgsCHP1Z9f1nwdl1e/XrDSHjktF/r5dCOnwBGwZHsjxL526HdkH+z0OaBvpF+N72iJtIgimueMakpuAZLF5k++QRqsdJf6qgQPHSkXClA0arKM4OUsZt7lHnCnVxHdX/zWqGPhzZvo143OPLgpGvgVextlpJ3E3wFCItSSv85J6wyRd1bh68i9JOOHI08d/EQoa0/b2VqqKMv8XmULwRU7+h/INZbrFnNXT4k9UE3M4WmAfuKqm6/Aej8LAArZJycoCJSPfddUaFICIUlEw6qCayI/EcXxI+zu5ipJHL3FpsjTcnB873+DNWQHCD5g=="
#else
#define PUBLIC_KEY 0x0
#define PUBLIC_KEY 0x06, 0x02, 0x00, 0x00, 0x00, 0xa4, 0x00, 0x00, 0x52, 0x53, 0x41, 0x31, 0x00, 0x10, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x15, 0x67, 0xeb, 0x78, 0xcb, 0x01, 0x8c, 0x2d, 0xf3, 0x26, 0x09, 0xbb, 0x50, 0xbf, 0xc1, 0xcd, 0x2a, 0xc4, 0x86, 0x11, 0x18, 0x15, 0xab, 0xe8, 0x22, 0x4e, 0xc6, 0x93, 0x6e, 0x8b, 0xf3, 0x61, 0x8b, 0x17, 0xe0, 0xb4, 0x71, 0xa9, 0x05, 0xa4, 0xf3, 0x53, 0x03, 0x5f, 0x75, 0x65, 0xc1, 0xda, 0x47, 0xa9, 0xc2, 0xa5, 0x64, 0x98, 0x2c, 0x07, 0xdc, 0x50, 0x32, 0xde, 0xa3, 0x4b, 0x2e, 0xfd, 0x7f, 0xcf, 0x54, 0x67, 0x26, 0xda, 0xb2, 0x0b, 0xb0, 0xba, 0x58, 0xd4, 0xb0, 0x5a, 0x14, 0x0a, 0x43, 0x22, 0x9e, 0x39, 0xe7, 0x25, 0x9b, 0x86, 0x28, 0x9a, 0x2e, 0xaa, 0xae, 0x7e, 0x38, 0xbf, 0x3a, 0xab, 0xf3, 0xda, 0x7c, 0x2f, 0x31, 0x84, 0x32, 0x14, 0xd8, 0x69, 0xcf, 0xfc, 0x02, 0xdc, 0x2e, 0xc9, 0x3d, 0x95, 0xeb, 0x57, 0x2d, 0x44, 0x7f, 0x38, 0x51, 0xe7, 0x0f, 0x7d, 0x8c, 0x90, 0x4c, 0xdb, 0x31, 0xac, 0x7c, 0xf5, 0xdd, 0xba, 0xdc, 0xb3, 0xb5, 0x4f, 0x6b, 0x23, 0x18, 0xb4, 0x02, 0x54, 0xce, 0x37, 0xf0, 0x04, 0xc5, 0xd8, 0x63, 0x5d, 0xa8, 0x92, 0x04, 0x59, 0x52, 0xc3, 0x1a, 0xab, 0xfe, 0xe1, 0x49, 0x0d, 0xfb, 0x6a, 0x2d, 0x01, 0xf3, 0x93, 0xa0, 0x9f, 0xf2, 0xf9, 0xed, 0x4b, 0xe1, 0xf1, 0x62, 0xf7, 0x1a, 0x27, 0x57, 0x4b, 0xdc, 0xf1, 0x18, 0x4e, 0x43, 0xc5, 0x3a, 0x5b, 0x37, 0x4a, 0x54, 0xaf, 0xb4, 0x2a, 0x99, 0x80, 0x9d, 0xc1, 0x70, 0xfc, 0xc5, 0x18, 0x01, 0x7b, 0x41, 0x3b, 0x7e, 0xc2, 0x09, 0x54, 0x57, 0xe1, 0xc1, 0xd0, 0xfb, 0xd5, 0xc2, 0x14, 0xc3, 0xbd, 0x5c, 0xb0, 0x64, 0x0b, 0xd1, 0x7a, 0x18, 0xa7, 0xb5, 0x46, 0x58, 0x4c, 0xfd, 0x8b, 0x0e, 0xa8, 0xa5, 0x41, 0xbd, 0xa8, 0x8f, 0xa5, 0x69, 0x50, 0x16, 0x04, 0x10, 0x93, 0x65, 0x5a, 0x3c, 0xed, 0xfb, 0xaa, 0x32, 0xa2, 0x00, 0x71, 0xc0, 0x07, 0xd0, 0xe9, 0xdd, 0x32, 0x5b, 0x17, 0xee, 0x67, 0x52, 0x0b, 0x02, 0x1c, 0xfd, 0x59, 0xf5, 0xfd, 0x67, 0xc1, 0xd9, 0x75, 0x7b, 0xf5, 0xeb, 0x0d, 0x21, 0xe3, 0x92, 0xd1, 0x7f, 0xaf, 0x97, 0x42, 0x3a, 0x7c, 0x01, 0x1b, 0x06, 0x47, 0xb2, 0x3c, 0x4b, 0xe7, 0x6e, 0x87, 0x76, 0x41, 0xfe, 0xcf, 0x43, 0x9a, 0x06, 0xfa, 0x45, 0xf8, 0xde, 0xf6, 0x88, 0x9b, 0x48, 0x82, 0x29, 0xae, 0x78, 0xc6, 0xa4, 0xa6, 0xe0, 0x19, 0x2c, 0x5e, 0x64, 0xfb, 0xe4, 0x11, 0xaa, 0xc7, 0x49, 0x7f, 0xaa, 0xa0, 0x40, 0xf1, 0xd2, 0x91, 0x70, 0xa5, 0x03, 0x46, 0xab, 0x28, 0xce, 0x0e, 0x52, 0xc6, 0x6d, 0xee, 0x51, 0xe7, 0x0a, 0x75, 0x71, 0x1d, 0xd5, 0xff, 0xcd, 0x6a, 0x86, 0x3e, 0x1c, 0xd9, 0xbe, 0x8d, 0x78, 0xdc, 0xe3, 0xcb, 0x82, 0x91, 0xaf, 0x81, 0x57, 0xb1, 0xb6, 0x5a, 0x49, 0xdc, 0x4d, 0xf0, 0x14, 0x22, 0x2d, 0x49, 0x2b, 0xfc, 0xe4, 0x9e, 0xb0, 0xc9, 0x17, 0x75, 0x6e, 0x1e, 0xbc, 0x8b, 0xd2, 0x4e, 0x38, 0x72, 0x34, 0xf1, 0xdf, 0xc4, 0x42, 0x86, 0xb4, 0xfd, 0xbd, 0x95, 0xaa, 0xa2, 0x8c, 0xbf, 0xc5, 0xe6, 0x50, 0xbc, 0x11, 0x53, 0xbf, 0xa1, 0xfc, 0x83, 0x59, 0x6e, 0xb1, 0x67, 0x35, 0x74, 0xf8, 0x93, 0xd5, 0x04, 0xdc, 0xce, 0x16, 0x98, 0x07, 0xee, 0x2a, 0xa9, 0xba, 0xfc, 0x07, 0xa3, 0xf0, 0xb0, 0x00, 0xad, 0x92, 0x72, 0x72, 0x80, 0x89, 0x48, 0xf7, 0xdd, 0x75, 0x46, 0x85, 0x20, 0x22, 0x14, 0x94, 0x4c, 0x3a, 0xa8, 0x26, 0xb2, 0x23, 0xf1, 0x1c, 0x5f, 0x12, 0x3e, 0xce, 0xee, 0x62, 0xa4, 0x91, 0xcb, 0xdc, 0x5a, 0x6c, 0x8d, 0x37, 0x27, 0x07, 0xce, 0xf7, 0xf8, 0x33, 0x56, 0x40, 0x70, 0x83, 0xe6
#endif
#define PLAYERBUILD

View File

@ -0,0 +1,19 @@
#pragma once
#include <curl/curl.h>
#include <discord_rpc.h>
#include <discord_register.h>
#include <rapidjson/document.h>
#include "Configuration.h"
#include "Hooks/CRoblox.h"
#ifndef ARBITERBUILD
std::thread updater;
void InitializeDiscord();
void UpdatePresence();
void CleanupDiscord();
#endif

View File

@ -15,4 +15,6 @@ public:
static std::vector<BYTE> base64Decode(const std::string_view data);
static std::map<std::string, std::string> parseQueryString(std::string query);
static std::string joinQueryString(std::map<std::string, std::string> query);
static std::string ws2s(std::wstring widestring);
static size_t write(char* contents, size_t size, size_t memory, void* pointer);
};

View File

@ -1,6 +1,9 @@
#pragma once
#include <curl/curl.h>
#include "Configuration.h"
#include "Helpers.h"
class CWorkspace;
@ -37,4 +40,6 @@ BOOL __fastcall CRobloxApp__InitInstance_hook(CRobloxApp* _this);
void __fastcall CRobloxCommandLineInfo__ParseParam_hook(CRobloxCommandLineInfo* _this, void*, const char* pszParam, BOOL bFlag, BOOL bLast);
extern CRobloxApp__InitInstance_t CRobloxApp__InitInstance;
extern CRobloxCommandLineInfo__ParseParam_t CRobloxCommandLineInfo__ParseParam;
extern CRobloxCommandLineInfo__ParseParam_t CRobloxCommandLineInfo__ParseParam;
extern std::string ticket;

View File

@ -4,6 +4,7 @@
#include <rapidjson/document.h>
#include "Configuration.h"
#include "Helpers.h"
struct Http
{

View File

@ -3,10 +3,14 @@
#include <windows.h>
#include <iomanip>
#include <iostream>
#include <filesystem>
#include <fstream>
#include <sstream>
#include <string>
#include <vector>
#include <map>
#include <algorithm>
#include <stdexcept>
#include <stdexcept>
#include <thread>
namespace fs = std::filesystem;

View File

@ -124,6 +124,7 @@
</ItemDefinitionGroup>
<ItemGroup>
<ClInclude Include="Include\Configuration.h" />
<ClInclude Include="Include\Discord.h" />
<ClInclude Include="Include\Hooks\Context.h" />
<ClInclude Include="Include\Hooks\CRoblox.h" />
<ClInclude Include="Include\Hooks\StandardOut.h" />
@ -136,6 +137,7 @@
<ClInclude Include="Include\resource.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="Discord.cpp" />
<ClCompile Include="Hooks\Context.cpp" />
<ClCompile Include="dllmain.cpp" />
<ClCompile Include="Hooks\CRoblox.cpp" />

View File

@ -54,6 +54,9 @@
<ClInclude Include="Include\resource.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Include\Discord.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="dllmain.cpp">
@ -86,6 +89,9 @@
<ClCompile Include="Hooks\Context.cpp">
<Filter>Source Files\Hooks</Filter>
</ClCompile>
<ClCompile Include="Discord.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="Tadah.DLL.rc">

View File

@ -2,6 +2,10 @@
#include "Configuration.h"
#include "Patches.h"
#ifndef ARBITERBUILD
#include "Discord.h"
#endif
#include "Hooks/Http.h"
#include "Hooks/Crypt.h"
@ -9,7 +13,7 @@
#include "Hooks/Context.h"
#endif
#if defined(ARBITERBUILD)
#ifdef ARBITERBUILD
#include "Hooks/StandardOut.h"
#include "Hooks/ServerReplicator.h"
#endif
@ -78,11 +82,19 @@ BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserv
ExitProcess(EXIT_FAILURE);
}
#ifndef ARBITERBUILD
InitializeDiscord();
#endif
}
if (ul_reason_for_call == DLL_PROCESS_DETACH)
{
curl_global_cleanup();
#ifndef ARBITERBUILD
CleanupDiscord();
#endif
}
return TRUE;

View File

@ -5,6 +5,7 @@
"dependencies": [
"curl",
"detours",
"discord-rpc",
"rapidjson"
]
}