Skip to content

Commit b8d25e1

Browse files
committed
feat: sar_download_file
This could potentially be unsafe, but it could also automate srconfigs updates, challenge_maplist, fast taunts, containerridesave, vaultsave, tram save, etc. Just be careful with usage, it overwrites! Smartly reads through game directories for existing file to overwrite (even p2common), falls back to main game directory i.e. portal2 / portalreloaded / whatever if file doesn't exist. also fixed a bug with createTempPath -- instead of creating tmp_0_1_2 now it creates tmp_2
1 parent 1e57b61 commit b8d25e1

3 files changed

Lines changed: 66 additions & 2 deletions

File tree

src/Features/ConfigPlus.cpp

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
#include "Event.hpp"
22
#include "Features/Session.hpp"
3+
#include "Features/Updater.hpp"
34
#include "Modules/Client.hpp"
45
#include "Modules/Engine.hpp"
6+
#include "Modules/FileSystem.hpp"
57

68
#include <cstdlib>
79
#include <cstring>
@@ -11,6 +13,8 @@
1113
#include <vector>
1214
#include <unordered_set>
1315
#include <fstream>
16+
#include <curl/curl.h>
17+
#include <regex>
1418

1519
// Fuck you Windows
1620
#ifdef _WIN32
@@ -52,6 +56,64 @@ static void SavePersistentSvars() {
5256
}
5357
}
5458

59+
CON_COMMAND_F(sar_download_file, "sar_download_file <url> <filepath> [directory] - Downloads a file from a URL and saves it to a path relative to game directory (e.g. portal2)\nIf directory isn't specified or invalid, looks for and overwrites existing file or uses base game directory\n", FCVAR_DONTRECORD) {
60+
if (args.ArgC() < 3 || args.ArgC() > 4 || !args[1][0] || !args[2][0]) {
61+
return console->Print(sar_download_file.ThisPtr()->m_pszHelpString);
62+
}
63+
64+
if (!Utils::StartsWith(args[1], "https://s.portal2.sr/") && !Utils::StartsWith(args[1], "https://raw.githubusercontent.com/p2sr/")) {
65+
return console->Print("URL domain is not portal2.sr.\n");
66+
}
67+
68+
std::string filepath = args[2];
69+
std::string gamedir = args.ArgC() > 3 ? args[3] : "";
70+
71+
auto result = fileSystem->FindFileSomewhere(filepath, gamedir);
72+
if (result.has_value()) {
73+
filepath = result.value();
74+
} else {
75+
filepath = std::string(engine->GetGameDirectory()) + "/" + filepath;
76+
if (gamedir != "") for (auto path : fileSystem->GetSearchPaths()) {
77+
if (path.find(gamedir) != std::string::npos) {
78+
filepath = path + filepath;
79+
break;
80+
}
81+
}
82+
}
83+
84+
CURL *curl = curl_easy_init();
85+
FILE *fp;
86+
CURLcode res;
87+
auto temp = createTempPath("sar_download_file.tmp");
88+
if (curl) {
89+
fp = fopen(temp.c_str(), "wb");
90+
curl_easy_setopt(curl, CURLOPT_URL, args[1]);
91+
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, &fwrite);
92+
curl_easy_setopt(curl, CURLOPT_WRITEDATA, fp);
93+
res = curl_easy_perform(curl);
94+
curl_easy_cleanup(curl);
95+
fclose(fp);
96+
}
97+
98+
if (res == CURLE_OK) {
99+
100+
// Create any intermediate directories
101+
std::string dirpath = filepath;
102+
std::replace(dirpath.begin(), dirpath.end(), '\\', '/');
103+
dirpath = dirpath.substr(0, dirpath.rfind('/'));
104+
std::filesystem::create_directories(dirpath);
105+
106+
std::filesystem::remove(filepath);
107+
std::filesystem::copy(temp, filepath); // for some reason moving the file doesn't work
108+
109+
} else {
110+
console->Print("An error occurred\n");
111+
}
112+
113+
std::filesystem::remove(temp);
114+
115+
}
116+
55117
static void SetSvar(std::string name, std::string val) {
56118
g_svars[name] = val;
57119
if (g_persistentSvars.count(name) != 0) SavePersistentSvars();

src/Features/Updater.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -199,7 +199,7 @@ static bool getLatestVersion(std::string *name, std::string *dlUrl, std::string
199199
return true;
200200
}
201201

202-
static std::string createTempPath(const char *filename) {
202+
std::string createTempPath(const char *filename) {
203203
auto base = std::filesystem::temp_directory_path().append(filename);
204204
if (!std::filesystem::exists(base)) {
205205
return base.string();
@@ -209,7 +209,7 @@ static std::string createTempPath(const char *filename) {
209209
std::filesystem::path p;
210210

211211
do {
212-
p = base.concat(Utils::ssprintf("_%d", n++));
212+
p = base.string() + Utils::ssprintf("_%d", n++);
213213
} while (std::filesystem::exists(p));
214214

215215
return p.string();

src/Features/Updater.hpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,3 @@
11
#pragma once
2+
3+
extern std::string createTempPath(const char *filename);

0 commit comments

Comments
 (0)