diff --git a/Tadah.DLL/Discord.cpp b/Tadah.DLL/Discord.cpp new file mode 100644 index 0000000..4095b6d --- /dev/null +++ b/Tadah.DLL/Discord.cpp @@ -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 \ No newline at end of file diff --git a/Tadah.DLL/Helpers.cpp b/Tadah.DLL/Helpers.cpp index 59ef0e7..deb9861 100644 --- a/Tadah.DLL/Helpers.cpp +++ b/Tadah.DLL/Helpers.cpp @@ -104,4 +104,21 @@ std::string Helpers::joinQueryString(std::map 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; } \ No newline at end of file diff --git a/Tadah.DLL/Hooks/CRoblox.cpp b/Tadah.DLL/Hooks/CRoblox.cpp index e89e251..6e2f260 100644 --- a/Tadah.DLL/Hooks/CRoblox.cpp +++ b/Tadah.DLL/Hooks/CRoblox.cpp @@ -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 parameters = Helpers::parseQueryString(std::string(query)); + if (parameters.find("ticket") != parameters.end()) + { + ticket = parameters["ticket"]; + } + } + } + catch (...) + { + // + } + + if (ticket.empty()) + { + ExitProcess(EXIT_FAILURE); + } + return; } #endif diff --git a/Tadah.DLL/Hooks/Http.cpp b/Tadah.DLL/Hooks/Http.cpp index 9482f13..765cc85 100644 --- a/Tadah.DLL/Hooks/Http.cpp +++ b/Tadah.DLL/Hooks/Http.cpp @@ -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); diff --git a/Tadah.DLL/Include/Configuration.h b/Tadah.DLL/Include/Configuration.h index 6167038..676c56b 100644 --- a/Tadah.DLL/Include/Configuration.h +++ b/Tadah.DLL/Include/Configuration.h @@ -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 diff --git a/Tadah.DLL/Include/Discord.h b/Tadah.DLL/Include/Discord.h new file mode 100644 index 0000000..9500799 --- /dev/null +++ b/Tadah.DLL/Include/Discord.h @@ -0,0 +1,19 @@ +#pragma once + +#include +#include +#include +#include + +#include "Configuration.h" +#include "Hooks/CRoblox.h" + +#ifndef ARBITERBUILD + +std::thread updater; + +void InitializeDiscord(); +void UpdatePresence(); +void CleanupDiscord(); + +#endif \ No newline at end of file diff --git a/Tadah.DLL/Include/Helpers.h b/Tadah.DLL/Include/Helpers.h index 228f871..c4a52fa 100644 --- a/Tadah.DLL/Include/Helpers.h +++ b/Tadah.DLL/Include/Helpers.h @@ -15,4 +15,6 @@ public: static std::vector base64Decode(const std::string_view data); static std::map parseQueryString(std::string query); static std::string joinQueryString(std::map query); + static std::string ws2s(std::wstring widestring); + static size_t write(char* contents, size_t size, size_t memory, void* pointer); }; \ No newline at end of file diff --git a/Tadah.DLL/Include/Hooks/CRoblox.h b/Tadah.DLL/Include/Hooks/CRoblox.h index d361863..6b4eabf 100644 --- a/Tadah.DLL/Include/Hooks/CRoblox.h +++ b/Tadah.DLL/Include/Hooks/CRoblox.h @@ -1,6 +1,9 @@ #pragma once +#include + #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; \ No newline at end of file +extern CRobloxCommandLineInfo__ParseParam_t CRobloxCommandLineInfo__ParseParam; + +extern std::string ticket; \ No newline at end of file diff --git a/Tadah.DLL/Include/Hooks/Http.h b/Tadah.DLL/Include/Hooks/Http.h index fbe109b..b751161 100644 --- a/Tadah.DLL/Include/Hooks/Http.h +++ b/Tadah.DLL/Include/Hooks/Http.h @@ -4,6 +4,7 @@ #include #include "Configuration.h" +#include "Helpers.h" struct Http { diff --git a/Tadah.DLL/Include/pch.h b/Tadah.DLL/Include/pch.h index 7030668..d288abd 100644 --- a/Tadah.DLL/Include/pch.h +++ b/Tadah.DLL/Include/pch.h @@ -3,10 +3,14 @@ #include #include #include +#include #include #include #include #include #include #include -#include \ No newline at end of file +#include +#include + +namespace fs = std::filesystem; \ No newline at end of file diff --git a/Tadah.DLL/Tadah.DLL.vcxproj b/Tadah.DLL/Tadah.DLL.vcxproj index be54a62..c9eefe7 100644 --- a/Tadah.DLL/Tadah.DLL.vcxproj +++ b/Tadah.DLL/Tadah.DLL.vcxproj @@ -124,6 +124,7 @@ + @@ -136,6 +137,7 @@ + diff --git a/Tadah.DLL/Tadah.DLL.vcxproj.filters b/Tadah.DLL/Tadah.DLL.vcxproj.filters index 91357ba..664b20d 100644 --- a/Tadah.DLL/Tadah.DLL.vcxproj.filters +++ b/Tadah.DLL/Tadah.DLL.vcxproj.filters @@ -54,6 +54,9 @@ Header Files + + Header Files + @@ -86,6 +89,9 @@ Source Files\Hooks + + Source Files + diff --git a/Tadah.DLL/dllmain.cpp b/Tadah.DLL/dllmain.cpp index d23bef6..97a0d04 100644 --- a/Tadah.DLL/dllmain.cpp +++ b/Tadah.DLL/dllmain.cpp @@ -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; diff --git a/vcpkg.json b/vcpkg.json index 99580c1..22d7ac4 100644 --- a/vcpkg.json +++ b/vcpkg.json @@ -5,6 +5,7 @@ "dependencies": [ "curl", "detours", + "discord-rpc", "rapidjson" ] } \ No newline at end of file