mirror of
https://github.com/Mauler125/r5sdk.git
synced 2025-02-09 19:15:03 +01:00
The game will now not be installed if the download fails (this should've never happened in the first place). The CPU usage fix should also fix download speed throttling.
181 lines
5.0 KiB
C++
181 lines
5.0 KiB
C++
//===========================================================================//
|
|
//
|
|
// Purpose: A set of utilities to perform requests
|
|
//
|
|
//===========================================================================//
|
|
#include "tier1/cvar.h"
|
|
#include "tier2/curlutils.h"
|
|
|
|
size_t CURLWriteStringCallback(char* data, const size_t size, const size_t nmemb, string* userp)
|
|
{
|
|
userp->append(data, size * nmemb);
|
|
return size * nmemb;
|
|
}
|
|
|
|
size_t CURLWriteFileCallback(void* data, const size_t size, const size_t nmemb, FILE* userp)
|
|
{
|
|
const size_t numBytesWritten = fwrite(data, size, nmemb, userp);
|
|
return numBytesWritten;
|
|
}
|
|
|
|
void CURLInitCommonOptions(CURL* curl, const char* remote,
|
|
const void* writeData, const CURLParams& params)
|
|
{
|
|
curl_easy_setopt(curl, CURLOPT_TIMEOUT, params.timeout);
|
|
curl_easy_setopt(curl, CURLOPT_VERBOSE, params.verbose);
|
|
curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, params.followRedirect);
|
|
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, params.verifyPeer);
|
|
curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1L);
|
|
curl_easy_setopt(curl, CURLOPT_USE_SSL, CURLUSESSL_ALL);
|
|
curl_easy_setopt(curl, CURLOPT_URL, remote);
|
|
curl_easy_setopt(curl, CURLOPT_WRITEDATA, writeData);
|
|
curl_easy_setopt(curl, CURLOPT_USERAGENT, "R5R HTTPS/1.0");
|
|
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, params.writeFunction);
|
|
}
|
|
|
|
bool CURLDownloadFile(const char* remote, const char* savePath, const char* fileName,
|
|
const char* options, curl_off_t dataSize, void* customPointer, CURLParams& params)
|
|
{
|
|
CURL* curl = curl_easy_init();
|
|
if (!curl)
|
|
{
|
|
V_snprintf(params.errorBuffer, sizeof(params.errorBuffer), "CURL: %s", "Easy init failed");
|
|
|
|
if (params.printError)
|
|
Error(eDLL_T::COMMON, NO_ERROR, "%s\n", params.errorBuffer);
|
|
|
|
return false;
|
|
}
|
|
|
|
string filePath = savePath;
|
|
|
|
AppendSlash(filePath);
|
|
filePath.append(fileName);
|
|
|
|
FILE* file = fopen(filePath.c_str(), options);
|
|
if (!file)
|
|
{
|
|
V_snprintf(params.errorBuffer, sizeof(params.errorBuffer), "CURL: %s", "Open file failed");
|
|
|
|
if (params.printError)
|
|
Error(eDLL_T::COMMON, NO_ERROR, "%s\n", params.errorBuffer);
|
|
|
|
curl_easy_cleanup(curl);
|
|
return false;
|
|
}
|
|
|
|
CURLProgress progressData;
|
|
|
|
progressData.curl = curl;
|
|
progressData.name = fileName;
|
|
progressData.user = customPointer;
|
|
progressData.size = dataSize;
|
|
|
|
CURLInitCommonOptions(curl, remote, file, params);
|
|
|
|
if (params.statusFunction)
|
|
{
|
|
curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 0l);
|
|
curl_easy_setopt(curl, CURLOPT_XFERINFODATA, &progressData);
|
|
curl_easy_setopt(curl, CURLOPT_XFERINFOFUNCTION, params.statusFunction);
|
|
}
|
|
|
|
CURLcode res = curl_easy_perform(curl);
|
|
|
|
if (res != CURLE_OK)
|
|
{
|
|
V_snprintf(params.errorBuffer, sizeof(params.errorBuffer),
|
|
"CURL: Download of file '%s' failed; %s", fileName, curl_easy_strerror(res));
|
|
|
|
if (params.printError)
|
|
Error(eDLL_T::COMMON, NO_ERROR, "%s\n", params.errorBuffer);
|
|
|
|
curl_easy_cleanup(curl);
|
|
fclose(file);
|
|
|
|
return false;
|
|
}
|
|
|
|
curl_easy_cleanup(curl);
|
|
fclose(file);
|
|
|
|
return true;
|
|
}
|
|
|
|
CURL* CURLInitRequest(const char* remote, const char* request,
|
|
string& outResponse, curl_slist*& slist, CURLParams& params)
|
|
{
|
|
std::function<void(const char*)> fnError = [&](const char* errorMsg)
|
|
{
|
|
V_snprintf(params.errorBuffer, sizeof(params.errorBuffer), "CURL: %s", errorMsg);
|
|
|
|
if (params.printError)
|
|
Error(eDLL_T::COMMON, NO_ERROR, "%s\n", params.errorBuffer);
|
|
|
|
curl_slist_free_all(slist);
|
|
};
|
|
|
|
slist = curl_slist_append(slist, "Content-Type: application/json");
|
|
if (!slist)
|
|
{
|
|
fnError("Slist init failed");
|
|
return nullptr;
|
|
}
|
|
|
|
CURL* curl = curl_easy_init();
|
|
if (!curl)
|
|
{
|
|
fnError("Easy init failed");
|
|
return nullptr;
|
|
}
|
|
|
|
CURLInitCommonOptions(curl, remote, &outResponse, params);
|
|
|
|
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, slist);
|
|
if (request)
|
|
{
|
|
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, request);
|
|
curl_easy_setopt(curl, CURLOPT_POST, 1L);
|
|
}
|
|
|
|
return curl;
|
|
}
|
|
|
|
CURLcode CURLSubmitRequest(CURL* curl, curl_slist*& slist)
|
|
{
|
|
CURLcode res = curl_easy_perform(curl);
|
|
curl_slist_free_all(slist);
|
|
|
|
return res;
|
|
}
|
|
|
|
CURLINFO CURLRetrieveInfo(CURL* curl)
|
|
{
|
|
CURLINFO status;
|
|
curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &status);
|
|
curl_easy_cleanup(curl);
|
|
|
|
return status;
|
|
}
|
|
|
|
bool CURLHandleError(CURL* curl, const CURLcode res, string& outMessage, const bool logError)
|
|
{
|
|
if (res == CURLE_OK)
|
|
return true;
|
|
|
|
const char* curlError = curl_easy_strerror(res);
|
|
|
|
if (logError)
|
|
Error(eDLL_T::COMMON, NO_ERROR, "CURL: %s\n", curlError);
|
|
|
|
outMessage = curlError;
|
|
curl_easy_cleanup(curl);
|
|
|
|
return false;
|
|
}
|
|
|
|
void CURLFormatUrl(string& outUrl, const char* host, const char* api)
|
|
{
|
|
outUrl = Format("%s%s%s", "https://", host, api);
|
|
}
|