From 5cbe9f7317899cd815b38d9f083bc99738fc1dd3 Mon Sep 17 00:00:00 2001 From: GeckoEidechse Date: Sun, 17 Sep 2023 01:45:16 +0200 Subject: test ci format check --- NorthstarDLL/scripts/client/clientchathooks.cpp | 2 +- NorthstarDLL/scripts/client/cursorposition.cpp | 8 +- NorthstarDLL/scripts/client/scriptmodmenu.cpp | 2 +- .../scripts/client/scriptserverbrowser.cpp | 42 +- .../client/scriptservertoclientstringcommand.cpp | 8 +- NorthstarDLL/scripts/scriptdatatables.cpp | 178 ++++---- NorthstarDLL/scripts/scripthttprequesthandler.cpp | 466 ++++++++++----------- NorthstarDLL/scripts/scriptjson.cpp | 44 +- NorthstarDLL/scripts/scriptjson.h | 6 +- NorthstarDLL/scripts/scriptutility.cpp | 12 +- NorthstarDLL/scripts/server/miscserverscript.cpp | 10 +- 11 files changed, 389 insertions(+), 389 deletions(-) (limited to 'NorthstarDLL/scripts') diff --git a/NorthstarDLL/scripts/client/clientchathooks.cpp b/NorthstarDLL/scripts/client/clientchathooks.cpp index df9497ef..6aff1fc3 100644 --- a/NorthstarDLL/scripts/client/clientchathooks.cpp +++ b/NorthstarDLL/scripts/client/clientchathooks.cpp @@ -33,7 +33,7 @@ void, __fastcall, (void* self, const char* message, int inboxId, bool isTeam, bo NS::Utils::RemoveAsciiControlSequences(const_cast(message), true); SQRESULT result = g_pSquirrel->Call( - "CHudChat_ProcessMessageStartThread", static_cast(senderId) - 1, payload, isTeam, isDead, type); + "CHudChat_ProcessMessageStartThread", static_cast(senderId) - 1, payload, isTeam, isDead, type); if (result == SQRESULT_ERROR) for (CHudChat* hud = *CHudChat::allHuds; hud != NULL; hud = hud->next) CHudChat__AddGameLine(hud, message, inboxId, isTeam, isDead); diff --git a/NorthstarDLL/scripts/client/cursorposition.cpp b/NorthstarDLL/scripts/client/cursorposition.cpp index c0e8623c..c1f0c4c2 100644 --- a/NorthstarDLL/scripts/client/cursorposition.cpp +++ b/NorthstarDLL/scripts/client/cursorposition.cpp @@ -11,10 +11,10 @@ ADD_SQFUNC("vector ornull", NSGetCursorPosition, "", "", ScriptContext::UI) return SQRESULT_NULL; g_pSquirrel->pushvector( - sqvm, - {p.x > 0 ? p.x > rcClient.right ? rcClient.right : (float)p.x : 0, - p.y > 0 ? p.y > rcClient.bottom ? rcClient.bottom : (float)p.y : 0, - 0}); + sqvm, + {p.x > 0 ? p.x > rcClient.right ? rcClient.right : (float)p.x : 0, + p.y > 0 ? p.y > rcClient.bottom ? rcClient.bottom : (float)p.y : 0, + 0}); return SQRESULT_NOTNULL; } g_pSquirrel->raiseerror(sqvm, "Failed retrieving cursor position of game window"); diff --git a/NorthstarDLL/scripts/client/scriptmodmenu.cpp b/NorthstarDLL/scripts/client/scriptmodmenu.cpp index a88478fb..da75c64f 100644 --- a/NorthstarDLL/scripts/client/scriptmodmenu.cpp +++ b/NorthstarDLL/scripts/client/scriptmodmenu.cpp @@ -135,7 +135,7 @@ ADD_SQFUNC("bool", NSIsModRequiredOnClient, "string modName", "", ScriptContext: } ADD_SQFUNC( - "array", NSGetModConvarsByModName, "string modName", "", ScriptContext::SERVER | ScriptContext::CLIENT | ScriptContext::UI) + "array", NSGetModConvarsByModName, "string modName", "", ScriptContext::SERVER | ScriptContext::CLIENT | ScriptContext::UI) { const SQChar* modName = g_pSquirrel->getstring(sqvm, 1); g_pSquirrel->newarray(sqvm, 0); diff --git a/NorthstarDLL/scripts/client/scriptserverbrowser.cpp b/NorthstarDLL/scripts/client/scriptserverbrowser.cpp index ff6da6e2..94d964ed 100644 --- a/NorthstarDLL/scripts/client/scriptserverbrowser.cpp +++ b/NorthstarDLL/scripts/client/scriptserverbrowser.cpp @@ -52,12 +52,12 @@ ADD_SQFUNC("void", NSTryAuthWithServer, "int serverIndex, string password = ''", if (serverIndex >= g_pMasterServerManager->m_vRemoteServers.size()) { g_pSquirrel->raiseerror( - sqvm, - fmt::format( - "Tried to auth with server index {} when only {} servers are available", - serverIndex, - g_pMasterServerManager->m_vRemoteServers.size()) - .c_str()); + sqvm, + fmt::format( + "Tried to auth with server index {} when only {} servers are available", + serverIndex, + g_pMasterServerManager->m_vRemoteServers.size()) + .c_str()); return SQRESULT_ERROR; } @@ -68,10 +68,10 @@ ADD_SQFUNC("void", NSTryAuthWithServer, "int serverIndex, string password = ''", // do auth g_pMasterServerManager->AuthenticateWithServer( - R2::g_pLocalPlayerUserID, - g_pMasterServerManager->m_sOwnClientAuthToken, - g_pMasterServerManager->m_vRemoteServers[serverIndex], - (char*)password); + R2::g_pLocalPlayerUserID, + g_pMasterServerManager->m_sOwnClientAuthToken, + g_pMasterServerManager->m_vRemoteServers[serverIndex], + (char*)password); return SQRESULT_NULL; } @@ -93,7 +93,7 @@ ADD_SQFUNC("void", NSConnectToAuthedServer, "", "", ScriptContext::UI) if (!g_pMasterServerManager->m_bHasPendingConnectionInfo) { g_pSquirrel->raiseerror( - sqvm, fmt::format("Tried to connect to authed server before any pending connection info was available").c_str()); + sqvm, fmt::format("Tried to connect to authed server before any pending connection info was available").c_str()); return SQRESULT_ERROR; } @@ -103,16 +103,16 @@ ADD_SQFUNC("void", NSConnectToAuthedServer, "", "", ScriptContext::UI) // i'm honestly not entirely sure how silentconnect works regarding ports and encryption so using connect for now R2::g_pCVar->FindVar("serverfilter")->SetValue(info.authToken); R2::Cbuf_AddText( - R2::Cbuf_GetCurrentPlayer(), - fmt::format( - "connect {}.{}.{}.{}:{}", - info.ip.S_un.S_un_b.s_b1, - info.ip.S_un.S_un_b.s_b2, - info.ip.S_un.S_un_b.s_b3, - info.ip.S_un.S_un_b.s_b4, - info.port) - .c_str(), - R2::cmd_source_t::kCommandSrcCode); + R2::Cbuf_GetCurrentPlayer(), + fmt::format( + "connect {}.{}.{}.{}:{}", + info.ip.S_un.S_un_b.s_b1, + info.ip.S_un.S_un_b.s_b2, + info.ip.S_un.S_un_b.s_b3, + info.ip.S_un.S_un_b.s_b4, + info.port) + .c_str(), + R2::cmd_source_t::kCommandSrcCode); g_pMasterServerManager->m_bHasPendingConnectionInfo = false; return SQRESULT_NULL; diff --git a/NorthstarDLL/scripts/client/scriptservertoclientstringcommand.cpp b/NorthstarDLL/scripts/client/scriptservertoclientstringcommand.cpp index a3a81c8a..47e189a4 100644 --- a/NorthstarDLL/scripts/client/scriptservertoclientstringcommand.cpp +++ b/NorthstarDLL/scripts/client/scriptservertoclientstringcommand.cpp @@ -11,8 +11,8 @@ void ConCommand_ns_script_servertoclientstringcommand(const CCommand& arg) ON_DLL_LOAD_CLIENT_RELIESON("client.dll", ScriptServerToClientStringCommand, ClientSquirrel, (CModule module)) { RegisterConCommand( - "ns_script_servertoclientstringcommand", - ConCommand_ns_script_servertoclientstringcommand, - "", - FCVAR_CLIENTDLL | FCVAR_SERVER_CAN_EXECUTE); + "ns_script_servertoclientstringcommand", + ConCommand_ns_script_servertoclientstringcommand, + "", + FCVAR_CLIENTDLL | FCVAR_SERVER_CAN_EXECUTE); } diff --git a/NorthstarDLL/scripts/scriptdatatables.cpp b/NorthstarDLL/scripts/scriptdatatables.cpp index 532624f3..478cacc2 100644 --- a/NorthstarDLL/scripts/scriptdatatables.cpp +++ b/NorthstarDLL/scripts/scriptdatatables.cpp @@ -328,10 +328,10 @@ REPLACE_SQFUNC(GetDataTableString, (ScriptContext::UI | ScriptContext::CLIENT | if (nRow >= csv->dataPointers.size() || nCol >= csv->dataPointers[nRow].size()) { g_pSquirrel->raiseerror( - sqvm, - fmt::format( - "row {} and col {} are outside of range row {} and col {}", nRow, nCol, csv->dataPointers.size(), csv->columns.size()) - .c_str()); + sqvm, + fmt::format( + "row {} and col {} are outside of range row {} and col {}", nRow, nCol, csv->dataPointers.size(), csv->columns.size()) + .c_str()); return SQRESULT_ERROR; } @@ -355,10 +355,10 @@ REPLACE_SQFUNC(GetDataTableAsset, (ScriptContext::UI | ScriptContext::CLIENT | S if (nRow >= csv->dataPointers.size() || nCol >= csv->dataPointers[nRow].size()) { g_pSquirrel->raiseerror( - sqvm, - fmt::format( - "row {} and col {} are outside of range row {} and col {}", nRow, nCol, csv->dataPointers.size(), csv->columns.size()) - .c_str()); + sqvm, + fmt::format( + "row {} and col {} are outside of range row {} and col {}", nRow, nCol, csv->dataPointers.size(), csv->columns.size()) + .c_str()); return SQRESULT_ERROR; } @@ -382,10 +382,10 @@ REPLACE_SQFUNC(GetDataTableInt, (ScriptContext::UI | ScriptContext::CLIENT | Scr if (nRow >= csv->dataPointers.size() || nCol >= csv->dataPointers[nRow].size()) { g_pSquirrel->raiseerror( - sqvm, - fmt::format( - "row {} and col {} are outside of range row {} and col {}", nRow, nCol, csv->dataPointers.size(), csv->columns.size()) - .c_str()); + sqvm, + fmt::format( + "row {} and col {} are outside of range row {} and col {}", nRow, nCol, csv->dataPointers.size(), csv->columns.size()) + .c_str()); return SQRESULT_ERROR; } @@ -409,10 +409,10 @@ REPLACE_SQFUNC(GetDataTableFloat, (ScriptContext::UI | ScriptContext::CLIENT | S if (nRow >= csv->dataPointers.size() || nCol >= csv->dataPointers[nRow].size()) { g_pSquirrel->raiseerror( - sqvm, - fmt::format( - "row {} and col {} are outside of range row {} and col {}", nRow, nCol, csv->dataPointers.size(), csv->columns.size()) - .c_str()); + sqvm, + fmt::format( + "row {} and col {} are outside of range row {} and col {}", nRow, nCol, csv->dataPointers.size(), csv->columns.size()) + .c_str()); return SQRESULT_ERROR; } @@ -436,10 +436,10 @@ REPLACE_SQFUNC(GetDataTableBool, (ScriptContext::UI | ScriptContext::CLIENT | Sc if (nRow >= csv->dataPointers.size() || nCol >= csv->dataPointers[nRow].size()) { g_pSquirrel->raiseerror( - sqvm, - fmt::format( - "row {} and col {} are outside of range row {} and col {}", nRow, nCol, csv->dataPointers.size(), csv->columns.size()) - .c_str()); + sqvm, + fmt::format( + "row {} and col {} are outside of range row {} and col {}", nRow, nCol, csv->dataPointers.size(), csv->columns.size()) + .c_str()); return SQRESULT_ERROR; } @@ -463,10 +463,10 @@ REPLACE_SQFUNC(GetDataTableVector, (ScriptContext::UI | ScriptContext::CLIENT | if (nRow >= csv->dataPointers.size() || nCol >= csv->dataPointers[nRow].size()) { g_pSquirrel->raiseerror( - sqvm, - fmt::format( - "row {} and col {} are outside of range row {} and col {}", nRow, nCol, csv->dataPointers.size(), csv->columns.size()) - .c_str()); + sqvm, + fmt::format( + "row {} and col {} are outside of range row {} and col {}", nRow, nCol, csv->dataPointers.size(), csv->columns.size()) + .c_str()); return SQRESULT_ERROR; } @@ -819,67 +819,67 @@ void ConCommand_dump_datatables(const CCommand& args) { // likely not a comprehensive list, might be missing a couple? static const std::vector VANILLA_DATATABLE_PATHS = { - "datatable/burn_meter_rewards.rpak", - "datatable/burn_meter_store.rpak", - "datatable/calling_cards.rpak", - "datatable/callsign_icons.rpak", - "datatable/camo_skins.rpak", - "datatable/default_pilot_loadouts.rpak", - "datatable/default_titan_loadouts.rpak", - "datatable/faction_leaders.rpak", - "datatable/fd_awards.rpak", - "datatable/features_mp.rpak", - "datatable/non_loadout_weapons.rpak", - "datatable/pilot_abilities.rpak", - "datatable/pilot_executions.rpak", - "datatable/pilot_passives.rpak", - "datatable/pilot_properties.rpak", - "datatable/pilot_weapons.rpak", - "datatable/pilot_weapon_features.rpak", - "datatable/pilot_weapon_mods.rpak", - "datatable/pilot_weapon_mods_common.rpak", - "datatable/playlist_items.rpak", - "datatable/titans_mp.rpak", - "datatable/titan_abilities.rpak", - "datatable/titan_executions.rpak", - "datatable/titan_fd_upgrades.rpak", - "datatable/titan_nose_art.rpak", - "datatable/titan_passives.rpak", - "datatable/titan_primary_mods.rpak", - "datatable/titan_primary_mods_common.rpak", - "datatable/titan_primary_weapons.rpak", - "datatable/titan_properties.rpak", - "datatable/titan_skins.rpak", - "datatable/titan_voices.rpak", - "datatable/unlocks_faction_level.rpak", - "datatable/unlocks_fd_titan_level.rpak", - "datatable/unlocks_player_level.rpak", - "datatable/unlocks_random.rpak", - "datatable/unlocks_titan_level.rpak", - "datatable/unlocks_weapon_level_pilot.rpak", - "datatable/weapon_skins.rpak", - "datatable/xp_per_faction_level.rpak", - "datatable/xp_per_fd_titan_level.rpak", - "datatable/xp_per_player_level.rpak", - "datatable/xp_per_titan_level.rpak", - "datatable/xp_per_weapon_level.rpak", - "datatable/faction_leaders_dropship_anims.rpak", - "datatable/score_events.rpak", - "datatable/startpoints.rpak", - "datatable/sp_levels.rpak", - "datatable/community_entries.rpak", - "datatable/spotlight_images.rpak", - "datatable/death_hints_mp.rpak", - "datatable/flightpath_assets.rpak", - "datatable/earn_meter_mp.rpak", - "datatable/battle_chatter_voices.rpak", - "datatable/battle_chatter.rpak", - "datatable/titan_os_conversations.rpak", - "datatable/faction_dialogue.rpak", - "datatable/grunt_chatter_mp.rpak", - "datatable/spectre_chatter_mp.rpak", - "datatable/pain_death_sounds.rpak", - "datatable/caller_ids_mp.rpak"}; + "datatable/burn_meter_rewards.rpak", + "datatable/burn_meter_store.rpak", + "datatable/calling_cards.rpak", + "datatable/callsign_icons.rpak", + "datatable/camo_skins.rpak", + "datatable/default_pilot_loadouts.rpak", + "datatable/default_titan_loadouts.rpak", + "datatable/faction_leaders.rpak", + "datatable/fd_awards.rpak", + "datatable/features_mp.rpak", + "datatable/non_loadout_weapons.rpak", + "datatable/pilot_abilities.rpak", + "datatable/pilot_executions.rpak", + "datatable/pilot_passives.rpak", + "datatable/pilot_properties.rpak", + "datatable/pilot_weapons.rpak", + "datatable/pilot_weapon_features.rpak", + "datatable/pilot_weapon_mods.rpak", + "datatable/pilot_weapon_mods_common.rpak", + "datatable/playlist_items.rpak", + "datatable/titans_mp.rpak", + "datatable/titan_abilities.rpak", + "datatable/titan_executions.rpak", + "datatable/titan_fd_upgrades.rpak", + "datatable/titan_nose_art.rpak", + "datatable/titan_passives.rpak", + "datatable/titan_primary_mods.rpak", + "datatable/titan_primary_mods_common.rpak", + "datatable/titan_primary_weapons.rpak", + "datatable/titan_properties.rpak", + "datatable/titan_skins.rpak", + "datatable/titan_voices.rpak", + "datatable/unlocks_faction_level.rpak", + "datatable/unlocks_fd_titan_level.rpak", + "datatable/unlocks_player_level.rpak", + "datatable/unlocks_random.rpak", + "datatable/unlocks_titan_level.rpak", + "datatable/unlocks_weapon_level_pilot.rpak", + "datatable/weapon_skins.rpak", + "datatable/xp_per_faction_level.rpak", + "datatable/xp_per_fd_titan_level.rpak", + "datatable/xp_per_player_level.rpak", + "datatable/xp_per_titan_level.rpak", + "datatable/xp_per_weapon_level.rpak", + "datatable/faction_leaders_dropship_anims.rpak", + "datatable/score_events.rpak", + "datatable/startpoints.rpak", + "datatable/sp_levels.rpak", + "datatable/community_entries.rpak", + "datatable/spotlight_images.rpak", + "datatable/death_hints_mp.rpak", + "datatable/flightpath_assets.rpak", + "datatable/earn_meter_mp.rpak", + "datatable/battle_chatter_voices.rpak", + "datatable/battle_chatter.rpak", + "datatable/titan_os_conversations.rpak", + "datatable/faction_dialogue.rpak", + "datatable/grunt_chatter_mp.rpak", + "datatable/spectre_chatter_mp.rpak", + "datatable/pain_death_sounds.rpak", + "datatable/caller_ids_mp.rpak"}; for (const char* datatable : VANILLA_DATATABLE_PATHS) DumpDatatable(datatable); @@ -899,10 +899,10 @@ ON_DLL_LOAD_RELIESON("client.dll", ClientScriptDatatables, ClientSquirrel, (CMod ON_DLL_LOAD_RELIESON("engine.dll", SharedScriptDataTables, ConVar, (CModule module)) { Cvar_ns_prefer_datatable_from_disk = new ConVar( - "ns_prefer_datatable_from_disk", - IsDedicatedServer() && Tier0::CommandLine()->CheckParm("-nopakdedi") ? "1" : "0", - FCVAR_NONE, - "whether to prefer loading datatables from disk, rather than rpak"); + "ns_prefer_datatable_from_disk", + IsDedicatedServer() && Tier0::CommandLine()->CheckParm("-nopakdedi") ? "1" : "0", + FCVAR_NONE, + "whether to prefer loading datatables from disk, rather than rpak"); RegisterConCommand("dump_datatables", ConCommand_dump_datatables, "dumps all datatables from a hardcoded list", FCVAR_NONE); RegisterConCommand("dump_datatable", ConCommand_dump_datatable, "dump a datatable", FCVAR_NONE); diff --git a/NorthstarDLL/scripts/scripthttprequesthandler.cpp b/NorthstarDLL/scripts/scripthttprequesthandler.cpp index 813bd50e..8fddaeff 100644 --- a/NorthstarDLL/scripts/scripthttprequesthandler.cpp +++ b/NorthstarDLL/scripts/scripthttprequesthandler.cpp @@ -220,7 +220,7 @@ template int HttpRequestHandler::MakeHttpRequest(const H if (IsHttpDisabled()) { spdlog::warn("NS_InternalMakeHttpRequest called while the game is running with -disablehttprequests." - " Please check if requests are allowed using NSIsHttpEnabled() first."); + " Please check if requests are allowed using NSIsHttpEnabled() first."); return -1; } @@ -230,219 +230,219 @@ template int HttpRequestHandler::MakeHttpRequest(const H int handle = ++m_iLastRequestHandle; std::thread requestThread( - [this, handle, requestParameters, bAllowLocalHttp]() - { - std::string hostname, resolvedAddress, resolvedPort; - - if (!bAllowLocalHttp) - { - if (!IsHttpDestinationHostAllowed(requestParameters.baseUrl, hostname, resolvedAddress, resolvedPort)) - { - spdlog::warn( - "HttpRequestHandler::MakeHttpRequest attempted to make a request to a private network. This is only allowed when " - "running the game with -allowlocalhttp."); - g_pSquirrel->AsyncCall( - "NSHandleFailedHttpRequest", - handle, - (int)0, - "Cannot make HTTP requests to private network hosts without -allowlocalhttp. Check your console for more " - "information."); - return; - } - } - - CURL* curl = curl_easy_init(); - if (!curl) - { - spdlog::error("HttpRequestHandler::MakeHttpRequest failed to init libcurl for request."); - g_pSquirrel->AsyncCall( - "NSHandleFailedHttpRequest", handle, static_cast(CURLE_FAILED_INIT), curl_easy_strerror(CURLE_FAILED_INIT)); - return; - } - - // HEAD has no body. - if (requestParameters.method == HttpRequestMethod::HRM_HEAD) - { - curl_easy_setopt(curl, CURLOPT_NOBODY, 1L); - } - - curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, HttpRequestMethod::ToString(requestParameters.method).c_str()); - - // Only resolve to IPv4 if we don't allow private network requests. - curl_slist* host = nullptr; - if (!bAllowLocalHttp) - { - curl_easy_setopt(curl, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4); - host = curl_slist_append(host, fmt::format("{}:{}:{}", hostname, resolvedPort, resolvedAddress).c_str()); - curl_easy_setopt(curl, CURLOPT_RESOLVE, host); - } - - // Ensure we only allow HTTP or HTTPS. - curl_easy_setopt(curl, CURLOPT_PROTOCOLS, CURLPROTO_HTTP | CURLPROTO_HTTPS); - - // Allow redirects - curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L); - curl_easy_setopt(curl, CURLOPT_MAXREDIRS, 3L); - - // Check if the url already contains a query. - // If so, we'll know to append with & instead of start with ? - std::string queryUrl = requestParameters.baseUrl; - bool bUrlContainsQuery = false; - - // If this fails, just ignore the parsing and trust what the user wants to query. - // Probably will fail but handling it here would be annoying. - CURLU* curlUrl = curl_url(); - if (curlUrl) - { - if (curl_url_set(curlUrl, CURLUPART_URL, queryUrl.c_str(), CURLU_DEFAULT_SCHEME) == CURLUE_OK) - { - char* currentQuery; - if (curl_url_get(curlUrl, CURLUPART_QUERY, ¤tQuery, 0) == CURLUE_OK) - { - if (currentQuery && std::strlen(currentQuery) != 0) - { - bUrlContainsQuery = true; - } - } - - curl_free(currentQuery); - } - - curl_url_cleanup(curlUrl); - } - - // GET requests, or POST-like requests with an empty body, can have query parameters. - // Append them to the base url. - if (HttpRequestMethod::CanHaveQueryParameters(requestParameters.method) && - !HttpRequestMethod::UsesCurlPostOptions(requestParameters.method) || - requestParameters.body.empty()) - { - bool isFirstValue = true; - for (const auto& kv : requestParameters.queryParameters) - { - char* key = curl_easy_escape(curl, kv.first.c_str(), kv.first.length()); - - for (const std::string& queryValue : kv.second) - { - char* value = curl_easy_escape(curl, queryValue.c_str(), queryValue.length()); - - if (isFirstValue && !bUrlContainsQuery) - { - queryUrl.append(fmt::format("?{}={}", key, value)); - isFirstValue = false; - } - else - { - queryUrl.append(fmt::format("&{}={}", key, value)); - } - - curl_free(value); - } - - curl_free(key); - } - } - - // If this method uses POST-like curl options, set those and set the body. - // The body won't be sent if it's empty anyway, meaning the query parameters above, if any, would be. - if (HttpRequestMethod::UsesCurlPostOptions(requestParameters.method)) - { - // Grab the body and set it as a POST field - curl_easy_setopt(curl, CURLOPT_POST, 1L); - - curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, requestParameters.body.length()); - curl_easy_setopt(curl, CURLOPT_COPYPOSTFIELDS, requestParameters.body.c_str()); - } - - // Set the full URL for this http request. - curl_easy_setopt(curl, CURLOPT_URL, queryUrl.c_str()); - - std::string bodyBuffer; - std::string headerBuffer; - - // Set up buffers to write the response headers and body. - curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, HttpCurlWriteToStringBufferCallback); - curl_easy_setopt(curl, CURLOPT_WRITEDATA, &bodyBuffer); - curl_easy_setopt(curl, CURLOPT_HEADERFUNCTION, HttpCurlWriteToStringBufferCallback); - curl_easy_setopt(curl, CURLOPT_HEADERDATA, &headerBuffer); - - // Add all the headers for the request. - curl_slist* headers = nullptr; - - // Content-Type header for POST-like requests. - if (HttpRequestMethod::UsesCurlPostOptions(requestParameters.method) && !requestParameters.body.empty()) - { - headers = curl_slist_append(headers, fmt::format("Content-Type: {}", requestParameters.contentType).c_str()); - } - - for (const auto& kv : requestParameters.headers) - { - for (const std::string& headerValue : kv.second) - { - headers = curl_slist_append(headers, fmt::format("{}: {}", kv.first, headerValue).c_str()); - } - } - - if (headers != nullptr) - { - curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers); - } - - // Disable SSL checks if requested by the user. - if (DisableHttpSsl()) - { - curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L); - curl_easy_setopt(curl, CURLOPT_SSL_VERIFYSTATUS, 0L); - } - - // Enforce the Northstar user agent, unless an override was specified. - if (requestParameters.userAgent.empty()) - { - curl_easy_setopt(curl, CURLOPT_USERAGENT, &NSUserAgent); - } - else - { - curl_easy_setopt(curl, CURLOPT_USERAGENT, requestParameters.userAgent.c_str()); - } - - // Set the timeout for this request. Max 60 seconds so mods can't just spin up native threads all the time. - curl_easy_setopt(curl, CURLOPT_TIMEOUT, std::clamp(requestParameters.timeout, 1, 60)); - - CURLcode result = curl_easy_perform(curl); - if (IsRunning()) - { - if (result == CURLE_OK) - { - // While the curl request is OK, it could return a non success code. - // Squirrel side will handle firing the correct callback. - long httpCode = 0; - curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &httpCode); - g_pSquirrel->AsyncCall( - "NSHandleSuccessfulHttpRequest", handle, static_cast(httpCode), bodyBuffer, headerBuffer); - } - else - { - // Pass CURL result code & error. - spdlog::error( - "curl_easy_perform() failed with code {}, error: {}", static_cast(result), curl_easy_strerror(result)); - - // If it's an SSL issue, tell the user they may disable SSL checks using -disablehttpssl. - if (result == CURLE_PEER_FAILED_VERIFICATION || result == CURLE_SSL_CERTPROBLEM || - result == CURLE_SSL_INVALIDCERTSTATUS) - { - spdlog::error("You can try disabling SSL verifications for this issue using the -disablehttpssl launch argument. " - "Keep in mind this is potentially dangerous!"); - } - - g_pSquirrel->AsyncCall( - "NSHandleFailedHttpRequest", handle, static_cast(result), curl_easy_strerror(result)); - } - } - - curl_easy_cleanup(curl); - curl_slist_free_all(headers); - curl_slist_free_all(host); - }); + [this, handle, requestParameters, bAllowLocalHttp]() + { + std::string hostname, resolvedAddress, resolvedPort; + + if (!bAllowLocalHttp) + { + if (!IsHttpDestinationHostAllowed(requestParameters.baseUrl, hostname, resolvedAddress, resolvedPort)) + { + spdlog::warn( + "HttpRequestHandler::MakeHttpRequest attempted to make a request to a private network. This is only allowed when " + "running the game with -allowlocalhttp."); + g_pSquirrel->AsyncCall( + "NSHandleFailedHttpRequest", + handle, + (int)0, + "Cannot make HTTP requests to private network hosts without -allowlocalhttp. Check your console for more " + "information."); + return; + } + } + + CURL* curl = curl_easy_init(); + if (!curl) + { + spdlog::error("HttpRequestHandler::MakeHttpRequest failed to init libcurl for request."); + g_pSquirrel->AsyncCall( + "NSHandleFailedHttpRequest", handle, static_cast(CURLE_FAILED_INIT), curl_easy_strerror(CURLE_FAILED_INIT)); + return; + } + + // HEAD has no body. + if (requestParameters.method == HttpRequestMethod::HRM_HEAD) + { + curl_easy_setopt(curl, CURLOPT_NOBODY, 1L); + } + + curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, HttpRequestMethod::ToString(requestParameters.method).c_str()); + + // Only resolve to IPv4 if we don't allow private network requests. + curl_slist* host = nullptr; + if (!bAllowLocalHttp) + { + curl_easy_setopt(curl, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4); + host = curl_slist_append(host, fmt::format("{}:{}:{}", hostname, resolvedPort, resolvedAddress).c_str()); + curl_easy_setopt(curl, CURLOPT_RESOLVE, host); + } + + // Ensure we only allow HTTP or HTTPS. + curl_easy_setopt(curl, CURLOPT_PROTOCOLS, CURLPROTO_HTTP | CURLPROTO_HTTPS); + + // Allow redirects + curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L); + curl_easy_setopt(curl, CURLOPT_MAXREDIRS, 3L); + + // Check if the url already contains a query. + // If so, we'll know to append with & instead of start with ? + std::string queryUrl = requestParameters.baseUrl; + bool bUrlContainsQuery = false; + + // If this fails, just ignore the parsing and trust what the user wants to query. + // Probably will fail but handling it here would be annoying. + CURLU* curlUrl = curl_url(); + if (curlUrl) + { + if (curl_url_set(curlUrl, CURLUPART_URL, queryUrl.c_str(), CURLU_DEFAULT_SCHEME) == CURLUE_OK) + { + char* currentQuery; + if (curl_url_get(curlUrl, CURLUPART_QUERY, ¤tQuery, 0) == CURLUE_OK) + { + if (currentQuery && std::strlen(currentQuery) != 0) + { + bUrlContainsQuery = true; + } + } + + curl_free(currentQuery); + } + + curl_url_cleanup(curlUrl); + } + + // GET requests, or POST-like requests with an empty body, can have query parameters. + // Append them to the base url. + if (HttpRequestMethod::CanHaveQueryParameters(requestParameters.method) && + !HttpRequestMethod::UsesCurlPostOptions(requestParameters.method) || + requestParameters.body.empty()) + { + bool isFirstValue = true; + for (const auto& kv : requestParameters.queryParameters) + { + char* key = curl_easy_escape(curl, kv.first.c_str(), kv.first.length()); + + for (const std::string& queryValue : kv.second) + { + char* value = curl_easy_escape(curl, queryValue.c_str(), queryValue.length()); + + if (isFirstValue && !bUrlContainsQuery) + { + queryUrl.append(fmt::format("?{}={}", key, value)); + isFirstValue = false; + } + else + { + queryUrl.append(fmt::format("&{}={}", key, value)); + } + + curl_free(value); + } + + curl_free(key); + } + } + + // If this method uses POST-like curl options, set those and set the body. + // The body won't be sent if it's empty anyway, meaning the query parameters above, if any, would be. + if (HttpRequestMethod::UsesCurlPostOptions(requestParameters.method)) + { + // Grab the body and set it as a POST field + curl_easy_setopt(curl, CURLOPT_POST, 1L); + + curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, requestParameters.body.length()); + curl_easy_setopt(curl, CURLOPT_COPYPOSTFIELDS, requestParameters.body.c_str()); + } + + // Set the full URL for this http request. + curl_easy_setopt(curl, CURLOPT_URL, queryUrl.c_str()); + + std::string bodyBuffer; + std::string headerBuffer; + + // Set up buffers to write the response headers and body. + curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, HttpCurlWriteToStringBufferCallback); + curl_easy_setopt(curl, CURLOPT_WRITEDATA, &bodyBuffer); + curl_easy_setopt(curl, CURLOPT_HEADERFUNCTION, HttpCurlWriteToStringBufferCallback); + curl_easy_setopt(curl, CURLOPT_HEADERDATA, &headerBuffer); + + // Add all the headers for the request. + curl_slist* headers = nullptr; + + // Content-Type header for POST-like requests. + if (HttpRequestMethod::UsesCurlPostOptions(requestParameters.method) && !requestParameters.body.empty()) + { + headers = curl_slist_append(headers, fmt::format("Content-Type: {}", requestParameters.contentType).c_str()); + } + + for (const auto& kv : requestParameters.headers) + { + for (const std::string& headerValue : kv.second) + { + headers = curl_slist_append(headers, fmt::format("{}: {}", kv.first, headerValue).c_str()); + } + } + + if (headers != nullptr) + { + curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers); + } + + // Disable SSL checks if requested by the user. + if (DisableHttpSsl()) + { + curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L); + curl_easy_setopt(curl, CURLOPT_SSL_VERIFYSTATUS, 0L); + } + + // Enforce the Northstar user agent, unless an override was specified. + if (requestParameters.userAgent.empty()) + { + curl_easy_setopt(curl, CURLOPT_USERAGENT, &NSUserAgent); + } + else + { + curl_easy_setopt(curl, CURLOPT_USERAGENT, requestParameters.userAgent.c_str()); + } + + // Set the timeout for this request. Max 60 seconds so mods can't just spin up native threads all the time. + curl_easy_setopt(curl, CURLOPT_TIMEOUT, std::clamp(requestParameters.timeout, 1, 60)); + + CURLcode result = curl_easy_perform(curl); + if (IsRunning()) + { + if (result == CURLE_OK) + { + // While the curl request is OK, it could return a non success code. + // Squirrel side will handle firing the correct callback. + long httpCode = 0; + curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &httpCode); + g_pSquirrel->AsyncCall( + "NSHandleSuccessfulHttpRequest", handle, static_cast(httpCode), bodyBuffer, headerBuffer); + } + else + { + // Pass CURL result code & error. + spdlog::error( + "curl_easy_perform() failed with code {}, error: {}", static_cast(result), curl_easy_strerror(result)); + + // If it's an SSL issue, tell the user they may disable SSL checks using -disablehttpssl. + if (result == CURLE_PEER_FAILED_VERIFICATION || result == CURLE_SSL_CERTPROBLEM || + result == CURLE_SSL_INVALIDCERTSTATUS) + { + spdlog::error("You can try disabling SSL verifications for this issue using the -disablehttpssl launch argument. " + "Keep in mind this is potentially dangerous!"); + } + + g_pSquirrel->AsyncCall( + "NSHandleFailedHttpRequest", handle, static_cast(result), curl_easy_strerror(result)); + } + } + + curl_easy_cleanup(curl); + curl_slist_free_all(headers); + curl_slist_free_all(host); + }); requestThread.detach(); return handle; @@ -462,7 +462,7 @@ template SQRESULT SQ_InternalMakeHttpRequest(HSquirrelVM if (IsHttpDisabled()) { spdlog::warn("NS_InternalMakeHttpRequest called while the game is running with -disablehttprequests." - " Please check if requests are allowed using NSIsHttpEnabled() first."); + " Please check if requests are allowed using NSIsHttpEnabled() first."); g_pSquirrel->pushinteger(sqvm, -1); return SQRESULT_NOTNULL; } @@ -543,28 +543,28 @@ template SQRESULT SQ_IsLocalHttpAllowed(HSquirrelVM* sqv template void HttpRequestHandler::RegisterSQFuncs() { g_pSquirrel->AddFuncRegistration( - "int", - "NS_InternalMakeHttpRequest", - "int method, string baseUrl, table > headers, table > queryParams, string contentType, " - "string body, " - "int timeout, string userAgent", - "[Internal use only] Passes the HttpRequest struct fields to be reconstructed in native and used for an http request", - SQ_InternalMakeHttpRequest); + "int", + "NS_InternalMakeHttpRequest", + "int method, string baseUrl, table > headers, table > queryParams, string contentType, " + "string body, " + "int timeout, string userAgent", + "[Internal use only] Passes the HttpRequest struct fields to be reconstructed in native and used for an http request", + SQ_InternalMakeHttpRequest); g_pSquirrel->AddFuncRegistration( - "bool", - "NSIsHttpEnabled", - "", - "Whether or not HTTP requests are enabled. You can opt-out by starting the game with -disablehttprequests.", - SQ_IsHttpEnabled); + "bool", + "NSIsHttpEnabled", + "", + "Whether or not HTTP requests are enabled. You can opt-out by starting the game with -disablehttprequests.", + SQ_IsHttpEnabled); g_pSquirrel->AddFuncRegistration( - "bool", - "NSIsLocalHttpAllowed", - "", - "Whether or not HTTP requests can be made to a private network address. You can enable this by starting the game with " - "-allowlocalhttp.", - SQ_IsLocalHttpAllowed); + "bool", + "NSIsLocalHttpAllowed", + "", + "Whether or not HTTP requests can be made to a private network address. You can enable this by starting the game with " + "-allowlocalhttp.", + SQ_IsLocalHttpAllowed); } ON_DLL_LOAD_RELIESON("client.dll", HttpRequestHandler_ClientInit, ClientSquirrel, (CModule module)) diff --git a/NorthstarDLL/scripts/scriptjson.cpp b/NorthstarDLL/scripts/scriptjson.cpp index 06bda6f4..4e13e994 100644 --- a/NorthstarDLL/scripts/scriptjson.cpp +++ b/NorthstarDLL/scripts/scriptjson.cpp @@ -58,13 +58,13 @@ DecodeJsonTable(HSquirrelVM* sqvm, rapidjson::GenericValue case rapidjson::kObjectType: g_pSquirrel->pushstring(sqvm, itr->name.GetString(), -1); DecodeJsonTable( - sqvm, (rapidjson::GenericValue, rapidjson::MemoryPoolAllocator>*)&itr->value); + sqvm, (rapidjson::GenericValue, rapidjson::MemoryPoolAllocator>*)&itr->value); g_pSquirrel->newslot(sqvm, -3, false); break; case rapidjson::kArrayType: g_pSquirrel->pushstring(sqvm, itr->name.GetString(), -1); DecodeJsonArray( - sqvm, (rapidjson::GenericValue, rapidjson::MemoryPoolAllocator>*)&itr->value); + sqvm, (rapidjson::GenericValue, rapidjson::MemoryPoolAllocator>*)&itr->value); g_pSquirrel->newslot(sqvm, -3, false); break; case rapidjson::kStringType: @@ -97,9 +97,9 @@ DecodeJsonTable(HSquirrelVM* sqvm, rapidjson::GenericValue } template void EncodeJSONTable( - SQTable* table, - rapidjson::GenericValue, rapidjson::MemoryPoolAllocator>* obj, - rapidjson::MemoryPoolAllocator& allocator) + SQTable* table, + rapidjson::GenericValue, rapidjson::MemoryPoolAllocator>* obj, + rapidjson::MemoryPoolAllocator& allocator) { for (int i = 0; i < table->_numOfNodes; i++) { @@ -113,7 +113,7 @@ template void EncodeJSONTable( { case OT_STRING: obj->AddMember( - rapidjson::StringRef(node->key._VAL.asString->_val), rapidjson::StringRef(node->val._VAL.asString->_val), allocator); + rapidjson::StringRef(node->key._VAL.asString->_val), rapidjson::StringRef(node->val._VAL.asString->_val), allocator); break; case OT_INTEGER: obj->AddMember(rapidjson::StringRef(node->key._VAL.asString->_val), node->val._VAL.asInteger, allocator); @@ -148,9 +148,9 @@ template void EncodeJSONTable( } template void EncodeJSONArray( - SQArray* arr, - rapidjson::GenericValue, rapidjson::MemoryPoolAllocator>* obj, - rapidjson::MemoryPoolAllocator& allocator) + SQArray* arr, + rapidjson::GenericValue, rapidjson::MemoryPoolAllocator>* obj, + rapidjson::MemoryPoolAllocator& allocator) { for (int i = 0; i < arr->_usedSlots; i++) { @@ -191,11 +191,11 @@ template void EncodeJSONArray( } ADD_SQFUNC( - "table", - DecodeJSON, - "string json, bool fatalParseErrors = false", - "converts a json string to a squirrel table", - ScriptContext::UI | ScriptContext::CLIENT | ScriptContext::SERVER) + "table", + DecodeJSON, + "string json, bool fatalParseErrors = false", + "converts a json string to a squirrel table", + ScriptContext::UI | ScriptContext::CLIENT | ScriptContext::SERVER) { const char* pJson = g_pSquirrel->getstring(sqvm, 1); const bool bFatalParseErrors = g_pSquirrel->getbool(sqvm, 2); @@ -207,9 +207,9 @@ ADD_SQFUNC( g_pSquirrel->newtable(sqvm); std::string sErrorString = fmt::format( - "Failed parsing json file: encountered parse error \"{}\" at offset {}", - GetParseError_En(doc.GetParseError()), - doc.GetErrorOffset()); + "Failed parsing json file: encountered parse error \"{}\" at offset {}", + GetParseError_En(doc.GetParseError()), + doc.GetErrorOffset()); if (bFatalParseErrors) { @@ -226,11 +226,11 @@ ADD_SQFUNC( } ADD_SQFUNC( - "string", - EncodeJSON, - "table data", - "converts a squirrel table to a json string", - ScriptContext::UI | ScriptContext::CLIENT | ScriptContext::SERVER) + "string", + EncodeJSON, + "table data", + "converts a squirrel table to a json string", + ScriptContext::UI | ScriptContext::CLIENT | ScriptContext::SERVER) { rapidjson_document doc; doc.SetObject(); diff --git a/NorthstarDLL/scripts/scriptjson.h b/NorthstarDLL/scripts/scriptjson.h index b747106b..ed53236d 100644 --- a/NorthstarDLL/scripts/scriptjson.h +++ b/NorthstarDLL/scripts/scriptjson.h @@ -5,9 +5,9 @@ #include "rapidjson/stringbuffer.h" template void EncodeJSONTable( - SQTable* table, - rapidjson::GenericValue, rapidjson::MemoryPoolAllocator>* obj, - rapidjson::MemoryPoolAllocator& allocator); + SQTable* table, + rapidjson::GenericValue, rapidjson::MemoryPoolAllocator>* obj, + rapidjson::MemoryPoolAllocator& allocator); template void DecodeJsonTable(HSquirrelVM* sqvm, rapidjson::GenericValue, rapidjson::MemoryPoolAllocator>* obj); diff --git a/NorthstarDLL/scripts/scriptutility.cpp b/NorthstarDLL/scripts/scriptutility.cpp index 054836ca..0b22d315 100644 --- a/NorthstarDLL/scripts/scriptutility.cpp +++ b/NorthstarDLL/scripts/scriptutility.cpp @@ -4,11 +4,11 @@ // asset function StringToAsset( string assetName ) ADD_SQFUNC( - "asset", - StringToAsset, - "string assetName", - "converts a given string to an asset", - ScriptContext::UI | ScriptContext::CLIENT | ScriptContext::SERVER) + "asset", + StringToAsset, + "string assetName", + "converts a given string to an asset", + ScriptContext::UI | ScriptContext::CLIENT | ScriptContext::SERVER) { g_pSquirrel->pushasset(sqvm, g_pSquirrel->getstring(sqvm, 1), -1); return SQRESULT_NOTNULL; @@ -16,7 +16,7 @@ ADD_SQFUNC( // string function NSGetLocalPlayerUID() ADD_SQFUNC( - "string", NSGetLocalPlayerUID, "", "Returns the local player's uid.", ScriptContext::UI | ScriptContext::CLIENT | ScriptContext::SERVER) + "string", NSGetLocalPlayerUID, "", "Returns the local player's uid.", ScriptContext::UI | ScriptContext::CLIENT | ScriptContext::SERVER) { if (R2::g_pLocalPlayerUserID) { diff --git a/NorthstarDLL/scripts/server/miscserverscript.cpp b/NorthstarDLL/scripts/server/miscserverscript.cpp index 3ea44ceb..090bdc4c 100644 --- a/NorthstarDLL/scripts/server/miscserverscript.cpp +++ b/NorthstarDLL/scripts/server/miscserverscript.cpp @@ -59,11 +59,11 @@ ADD_SQFUNC("bool", NSIsDedicated, "", "", ScriptContext::SERVER) } ADD_SQFUNC( - "bool", - NSDisconnectPlayer, - "entity player, string reason", - "Disconnects the player from the server with the given reason", - ScriptContext::SERVER) + "bool", + NSDisconnectPlayer, + "entity player, string reason", + "Disconnects the player from the server with the given reason", + ScriptContext::SERVER) { const R2::CBasePlayer* pPlayer = g_pSquirrel->template getentity(sqvm, 1); const char* reason = g_pSquirrel->getstring(sqvm, 2); -- cgit v1.2.3