Skip to content

Commit

Permalink
refactor: move code to AutoSubmitMod namespace
Browse files Browse the repository at this point in the history
  • Loading branch information
NeKzor committed Nov 4, 2023
1 parent 0d18494 commit 00a7aba
Show file tree
Hide file tree
Showing 3 changed files with 72 additions and 54 deletions.
89 changes: 63 additions & 26 deletions src/Features/AutoSubmitMod.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,46 +25,50 @@ static std::string g_api_base;
static std::string g_api_key;
static bool g_key_valid;
static CURL *g_curl;
static CURL *g_curl_search;
static std::thread g_worker;
static std::thread g_worker_search;
static std::map<std::string, std::string> g_map_ids;
static bool g_is_querying;
static std::vector<json11::Json> g_times;

static bool ensureCurlReady() {
if (!g_curl) {
g_curl = curl_easy_init();
static bool ensureCurlReady(CURL **curl) {
if (!*curl) {
*curl = curl_easy_init();

if (!g_curl) {
if (!*curl) {
return false;
}
}

return true;
}

static std::optional<std::string> request(std::string url) {
curl_easy_setopt(g_curl, CURLOPT_URL, url.c_str());
curl_easy_setopt(g_curl, CURLOPT_NOPROGRESS, 1);
curl_easy_setopt(g_curl, CURLOPT_FOLLOWLOCATION, 1);
curl_easy_setopt(g_curl, CURLOPT_TIMEOUT, 30);
static std::optional<std::string> request(CURL *curl, std::string url) {
curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 1);
curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1);
curl_easy_setopt(curl, CURLOPT_TIMEOUT, 30);

#ifdef UNSAFELY_IGNORE_CERTIFICATE_ERROR
curl_easy_setopt(g_curl, CURLOPT_SSL_VERIFYPEER, 0);
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0);
#endif

curl_easy_setopt(
g_curl,
curl,
CURLOPT_WRITEFUNCTION,
+[](void *ptr, size_t sz, size_t nmemb, std::string *data) -> size_t {
data->append((char *)ptr, sz * nmemb);
return sz * nmemb;
});

std::string response;
curl_easy_setopt(g_curl, CURLOPT_WRITEDATA, &response);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &response);

CURLcode res = curl_easy_perform(g_curl);
CURLcode res = curl_easy_perform(curl);

long code;
curl_easy_getinfo(g_curl, CURLINFO_RESPONSE_CODE, &code);
curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &code);

if (res != CURLE_OK) {
THREAD_PRINT("ERROR IN AUTOSUBMIT REQUEST TO %s: %s\n", url.c_str(), curl_easy_strerror(res));
Expand All @@ -74,7 +78,7 @@ static std::optional<std::string> request(std::string url) {
}

static void testApiKey() {
if (!ensureCurlReady()) {
if (!ensureCurlReady(&g_curl)) {
THREAD_PRINT("Failed to test API key!\n");
return;
}
Expand All @@ -88,7 +92,7 @@ static void testApiKey() {

curl_easy_setopt(g_curl, CURLOPT_MIMEPOST, form);

auto response = request(g_api_base + "/validate-user");
auto response = request(g_curl, g_api_base + "/validate-user");

curl_mime_free(form);

Expand All @@ -100,7 +104,7 @@ static void testApiKey() {
g_key_valid = true;
THREAD_PRINT("API key valid!\n");

response = request(g_api_base + "/download-maps");
response = request(g_curl, g_api_base + "/download-maps");
if (!response) {
THREAD_PRINT("Failed to downloaded maps!\n");
return;
Expand Down Expand Up @@ -130,7 +134,7 @@ std::optional<std::string> AutoSubmitMod::GetMapId(std::string map_name) {
}

std::optional<int> getCurrentPbScore(std::string &map_id) {
if (!ensureCurlReady()) return {};
if (!ensureCurlReady(&g_curl)) return {};

curl_mime *form = curl_mime_init(g_curl);
curl_mimepart *field;
Expand All @@ -145,7 +149,7 @@ std::optional<int> getCurrentPbScore(std::string &map_id) {

curl_easy_setopt(g_curl, CURLOPT_MIMEPOST, form);

auto response = request(g_api_base + "/current-pb");
auto response = request(g_curl, g_api_base + "/current-pb");

curl_mime_free(form);

Expand All @@ -166,10 +170,34 @@ std::optional<int> getCurrentPbScore(std::string &map_id) {
return atoi(str.c_str());
}

static void startSearching(const char *mapName) {
auto map_id = AutoSubmitMod::GetMapId(std::string(mapName));
if (!map_id.has_value()) {
g_is_querying = false;
return;
}

auto json = AutoSubmitMod::GetTopScores(*map_id);

g_times.clear();
for (auto score : json) {
g_times.push_back(score);
}

g_is_querying = false;
}

void AutoSubmitMod::Search(const char *map) {
g_is_querying = true;

if (g_worker_search.joinable()) g_worker_search.join();
g_worker_search = std::thread(startSearching, map);
}

json11::Json::array AutoSubmitMod::GetTopScores(std::string &map_id) {
if (!ensureCurlReady()) return {};
if (!ensureCurlReady(&g_curl_search)) return {};

curl_mime *form = curl_mime_init(g_curl);
curl_mime *form = curl_mime_init(g_curl_search);
curl_mimepart *field;

field = curl_mime_addpart(form);
Expand All @@ -188,9 +216,9 @@ json11::Json::array AutoSubmitMod::GetTopScores(std::string &map_id) {
curl_mime_name(field, "after");
curl_mime_data(field, "2", CURL_ZERO_TERMINATED);

curl_easy_setopt(g_curl, CURLOPT_MIMEPOST, form);
curl_easy_setopt(g_curl_search, CURLOPT_MIMEPOST, form);

auto response = request(g_api_base + "/top-scores");
auto response = request(g_curl_search, g_api_base + "/top-scores");

curl_mime_free(form);

Expand All @@ -206,6 +234,14 @@ json11::Json::array AutoSubmitMod::GetTopScores(std::string &map_id) {
return json.array_items();
}

bool AutoSubmitMod::IsQuerying() {
return g_is_querying;
}

const std::vector<json11::Json>& AutoSubmitMod::GetTimes() {
return g_times;
}

static void submitTime(int score, std::string demopath, bool coop, std::string map_id, std::optional<std::string> rename_if_pb, std::optional<std::string> replay_append_if_pb) {
auto score_str = std::to_string(score);

Expand Down Expand Up @@ -247,7 +283,7 @@ static void submitTime(int score, std::string demopath, bool coop, std::string m
return;
}

if (!ensureCurlReady()) {
if (!ensureCurlReady(&g_curl)) {
toastHud.AddToast(AUTOSUBMIT_TOAST_TAG, "An error occurred submitting this time");
return;
}
Expand Down Expand Up @@ -283,7 +319,7 @@ static void submitTime(int score, std::string demopath, bool coop, std::string m

curl_easy_setopt(g_curl, CURLOPT_MIMEPOST, form);

auto resp = request(g_api_base + "/auto-submit");
auto resp = request(g_curl, g_api_base + "/auto-submit");

curl_mime_free(form);

Expand Down Expand Up @@ -361,5 +397,6 @@ void AutoSubmitMod::FinishRun(float final_time, const char *demopath, std::optio
}

ON_EVENT(SAR_UNLOAD) {
if (g_worker.joinable()) g_worker.detach();
if (g_worker.joinable()) g_worker.join();
if (g_worker_search.joinable()) g_worker_search.join();
}
3 changes: 3 additions & 0 deletions src/Features/AutoSubmitMod.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,8 @@ namespace AutoSubmitMod {
void LoadApiKey(bool output_nonexist);
void FinishRun(float final_time, const char *demopath, std::optional<std::string> rename_if_pb, std::optional<std::string> replay_append_if_pb);
std::optional<std::string> GetMapId(std::string map_name);
void Search(const char *map);
json11::Json::array GetTopScores(std::string &map_id);
bool IsQuerying();
const std::vector<json11::Json>& GetTimes();
}; // namespace AutoSubmitMod
34 changes: 6 additions & 28 deletions src/Modules/Client.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -519,33 +519,13 @@ DETOUR_T(void, Client::AddShadowToReceiver, unsigned short handle, void *pRender
}
Hook g_AddShadowToReceiverHook(&Client::AddShadowToReceiver_Hook);

static std::thread g_worker;
static bool g_is_querying;
static std::vector<json11::Json> g_times;

static void startSearching(const char *mapName) {
auto map_id = AutoSubmitMod::GetMapId(std::string(mapName));

auto json = AutoSubmitMod::GetTopScores(*map_id);

g_times.clear();
for (auto score : json) {
g_times.push_back(score);
}

g_is_querying = false;
}

extern Hook g_StartSearchingHook;
DETOUR(Client::StartSearching) {
struct CPortalLeaderboard {
char m_szMapName[128];
};

g_is_querying = true;

if (g_worker.joinable()) g_worker.join();
g_worker = std::thread(startSearching, ((CPortalLeaderboard *)thisptr)->m_szMapName);
AutoSubmitMod::Search(((CPortalLeaderboard *)thisptr)->m_szMapName);

return 0;
}
Expand Down Expand Up @@ -583,7 +563,7 @@ Hook g_PurgeAndDeleteElementsHook(&Client::PurgeAndDeleteElements_Hook);

extern Hook g_IsQueryingHook;
DETOUR(Client::IsQuerying) {
return g_is_querying;
return AutoSubmitMod::IsQuerying();
}
Hook g_IsQueryingHook(&Client::IsQuerying_Hook);

Expand All @@ -593,8 +573,10 @@ DETOUR(Client::SetPanelStats) {
void *m_pStatList = *(void **)((uintptr_t)thisptr + Offsets::m_pStatList);
int m_nStatHeight = *(int *)((uintptr_t)thisptr + Offsets::m_nStatHeight);

for (int i = 0; i < g_times.size(); ++i) {
const auto &time = g_times[i];
const auto &times = AutoSubmitMod::GetTimes();

for (size_t i = 0; i < times.size(); ++i) {
const auto &time = times[i];

PortalLeaderboardItem_t data;
data.m_xuid = atoll(time["userData"]["profileNumber"].string_value().c_str());
Expand All @@ -621,10 +603,6 @@ DETOUR(Client::OnCommand, const char *a2) {
}
Hook g_OnCommandHook(&Client::OnCommand_Hook);

ON_EVENT(SAR_UNLOAD) {
if (g_worker.joinable()) g_worker.detach();
}

bool Client::Init() {
bool readJmp = false;

Expand Down

0 comments on commit 00a7aba

Please sign in to comment.