finish /Thumbs/ fixes

This commit is contained in:
lightbulblighter 2022-06-06 02:47:27 -07:00
parent d04cbd5ca8
commit 9ec7686a6f
No known key found for this signature in database
GPG Key ID: 0B2452F9DE0E2D01
4 changed files with 77 additions and 12 deletions

View File

@ -50,7 +50,7 @@ bool Crypt::verifySignatureBase64(std::string message, std::string signatureBase
if (!CryptCreateHash(context, algorithm, NULL, 0, &hash))
{
return false;
throw std::runtime_error("");
}
try
@ -88,6 +88,8 @@ bool Crypt::verifySignatureBase64(std::string message, std::string signatureBase
}
::CryptDestroyHash(hash);
return true;
}
Crypt__verifySignatureBase64_t Crypt__verifySignatureBase64 = (Crypt__verifySignatureBase64_t)ADDRESS_CRYPT__VERIFYSIGNATUREBASE64;

View File

@ -51,20 +51,45 @@ void __fastcall Http__httpGetPostWinInet_hook(Http* _this, void*, bool isPost, i
}
else if (_path == "/thumbs/asset.ashx" || _path == "/thumbs/avatar.ashx")
{
// https://www.roblox.com/asset/request-thumbnail-fix?assetId=1818&assetVersionId=0&width=420&height=420&imageFormat=Png&thumbnailFormatId=296&overrideModeration=false
// https://www.roblox.com/avatar/request-thumbnail-fix?userId=86890093&width=100&height=100&imageFormat=Png&thumbnailFormatId=41&dummy=false
// https://www.roblox.com/asset/request-thumbnail-fix for asset.ashx ; needs assetId
// https://www.roblox.com/avatar/request-thumbnail-fix for avatar.ashx ; needs userId
/*
Both Roblox endpoints require thumbnailFormatId to be set. We will make the default value for it as 0.
std::string replaceWith = _path == "/thumbs/asset.ashx" ? "assetId" : "userId";
std::string apiUrl = "https://www.roblox.com/" + std::string(_path == "/thumbs/asset.ashx" ? "asset" : "avatar") + "/request-thumbnail-fix?";
Asset.ashx -> requires overrideModeration (default false) -> /asset/request-thumbnail-fix
Avatar.ashx -> requires dummy (default false) -> /avatar/request-thumbnail-fix
// parse query stuff here
std::string query = "";
apiUrl += query;
1. Parse query
2. Construct a brand new blank query with thumbnailFormatId as 0 and dummy/overrideModeration as false (if Avatar.ashx or Asset.ashx)
3. Merge the old query with priority over the old query so that if they declared any of the special variables, ours gets overwritten
4. Rename id (if found) to assetId or userId (specific to the endpoint)
5. Append to the Roblox url (specific to the endpoint)
6. Fetch Roblox API
7. Parse JSON
8. Set the URL as the given url
*/
printf("\napiUrl: %s\n", apiUrl.c_str());
std::string api = "https://www.roblox.com/" + std::string(_path == "/thumbs/asset.ashx" ? "asset" : "avatar") + "/request-thumbnail-fix";
std::map<std::string, std::string> source = Util::parseQueryString(query);
std::map<std::string, std::string> fixed = {
{ _path == "/thumbs/asset.ashx" ? "overrideModeration" : "dummy", "false" },
{ "thumbnailFormatId", "0" }
};
for (auto& pair : source)
{
fixed[pair.first] = pair.second;
}
if (fixed.find("id") != fixed.end())
{
auto handler = fixed.extract("id");
handler.key() = _path == "/thumbs/asset.ashx" ? "assetId" : "userId";
fixed.insert(std::move(handler));
}
api += Util::joinQueryString(fixed);
// get the api response
CURL* curl = curl_easy_init();
CURLcode result;
@ -76,7 +101,7 @@ void __fastcall Http__httpGetPostWinInet_hook(Http* _this, void*, bool isPost, i
throw std::runtime_error("Failed to initialize cURL");
}
curl_easy_setopt(curl, CURLOPT_URL, apiUrl);
curl_easy_setopt(curl, CURLOPT_URL, api);
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &data);

View File

@ -130,4 +130,40 @@ std::vector<BYTE> Util::base64Decode(const std::string_view data)
}
return out;
}
// https://stackoverflow.com/a/28269049
std::map<std::string, std::string> Util::parseQueryString(std::string query)
{
std::istringstream stream(query);
std::map<std::string, std::string> parsed;
std::string pair, key, value;
while (std::getline(stream, pair, '&')) // split each term
{
std::istringstream term(pair);
if (std::getline(std::getline(term, key, '='), value))
{
parsed[key] = value;
}
}
return parsed;
}
std::string Util::joinQueryString(std::map<std::string, std::string> query)
{
std::stringstream stream;
stream << "?";
for (auto const& pair : query)
{
stream << pair.first << "=" << pair.second << "&";
}
std::string result = stream.str();
result.pop_back(); // remove ending ampersand
return result;
}

View File

@ -14,4 +14,6 @@ public:
static bool isASCII(const std::string& s);
static std::string toLower(std::string s);
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);
};