Update server url + motd/updater cleanup

This commit is contained in:
fed 2023-10-21 14:42:07 +02:00
parent a3df8a3e22
commit 9a9bb2e196
No known key found for this signature in database
GPG Key ID: 1D2C630F04722996
4 changed files with 123 additions and 60 deletions

View File

@ -5,6 +5,7 @@
#include "console.hpp" #include "console.hpp"
#include "images.hpp" #include "images.hpp"
#include "command.hpp" #include "command.hpp"
#include "updater.hpp"
#include <utils/string.hpp> #include <utils/string.hpp>
#include <utils/http.hpp> #include <utils/http.hpp>
@ -13,15 +14,14 @@
#include <utils/io.hpp> #include <utils/io.hpp>
#include <utils/cryptography.hpp> #include <utils/cryptography.hpp>
#define MAX_FEATURED_TABS 8
#define CACHE_MAX_AGE 24h * 5
#define CACHE_FILE_SIGNATURE 'CM2H' // H2MC (H2-MOD Cache)
namespace motd namespace motd
{ {
namespace namespace
{ {
constexpr auto max_featured_tabs = 8;
constexpr auto cache_max_age = 24h * 5; // 5 days
constexpr auto cache_file_signature = 'CM2H'; // H2MC (H2-MOD Cache);
utils::concurrency::container<links_map_t> links; utils::concurrency::container<links_map_t> links;
utils::concurrency::container<nlohmann::json, std::recursive_mutex> marketing; utils::concurrency::container<nlohmann::json, std::recursive_mutex> marketing;
@ -31,6 +31,12 @@ namespace motd
time_t date_created; time_t date_created;
}; };
struct parsed_cache_file
{
cached_file_header header{};
std::string data;
};
std::filesystem::path get_cache_folder() std::filesystem::path get_cache_folder()
{ {
return utils::properties::get_appdata_path() / "cache"; return utils::properties::get_appdata_path() / "cache";
@ -45,10 +51,10 @@ namespace motd
void cache_file(const std::string& name, const std::string& data) void cache_file(const std::string& name, const std::string& data)
{ {
std::string buffer; std::string buffer;
auto now = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now()); const auto now = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now());
cached_file_header header{}; cached_file_header header{};
header.signature = CACHE_FILE_SIGNATURE; header.signature = cache_file_signature;
header.date_created = now; header.date_created = now;
buffer.append(reinterpret_cast<char*>(&header), sizeof(header)); buffer.append(reinterpret_cast<char*>(&header), sizeof(header));
@ -58,6 +64,42 @@ namespace motd
utils::io::write_file(path, buffer, false); utils::io::write_file(path, buffer, false);
} }
std::optional<cached_file_header> parse_cached_file_header(std::string& data)
{
if (data.size() < sizeof(cached_file_header))
{
return {};
}
auto buffer = data.data();
const auto header = reinterpret_cast<cached_file_header*>(buffer);
return {*header};
}
std::optional<parsed_cache_file> parse_cached_file(const std::string& path)
{
parsed_cache_file parsed{};
auto data = utils::io::read_file(path);
const auto header = parse_cached_file_header(data);
if (!header.has_value())
{
return {};
}
if (header->signature != cache_file_signature)
{
return {};
}
const auto file_data = data.data() + sizeof(cached_file_header);
parsed.header = *header;
parsed.data = std::string{file_data, data.size() - sizeof(cached_file_header)};
return {parsed};
}
std::optional<std::string> read_cached_file(const std::string& name) std::optional<std::string> read_cached_file(const std::string& name)
{ {
const auto path = get_cached_file_name(name); const auto path = get_cached_file_name(name);
@ -66,29 +108,41 @@ namespace motd
return {}; return {};
} }
auto now = std::chrono::system_clock::now(); const auto parsed = parse_cached_file(path);
auto data = utils::io::read_file(path); if (!parsed.has_value())
if (data.size() < sizeof(cached_file_header))
{ {
return {}; return {};
} }
auto buffer = data.data(); return {parsed->data};
const auto header = reinterpret_cast<cached_file_header*>(buffer); }
if (header->signature != CACHE_FILE_SIGNATURE)
void delete_old_files()
{
const auto path = get_cache_folder().generic_string();
if (!utils::io::directory_exists(path))
{ {
return {}; return;
} }
const auto date = std::chrono::system_clock::from_time_t(header->date_created); const auto now = std::chrono::system_clock::now();
if (now - date >= CACHE_MAX_AGE) const auto files = utils::io::list_files(path);
{
utils::io::remove_file(path);
return {};
}
const auto file_data = buffer + sizeof(cached_file_header); for (const auto& file : files)
return std::string{file_data, data.size() - sizeof(cached_file_header)}; {
std::string data{};
if (!utils::io::read_file(file, &data))
{
continue;
}
const auto header = parse_cached_file_header(data);
const auto date = std::chrono::system_clock::from_time_t(header->date_created);
if (now - date >= cache_max_age)
{
utils::io::remove_file(file);
}
}
} }
std::optional<std::string> download_image(const std::string& url) std::optional<std::string> download_image(const std::string& url)
@ -99,6 +153,8 @@ namespace motd
return {cached.value()}; return {cached.value()};
} }
console::debug("[HTTP] GET File \"%s\"\n", url.data());
const auto res = utils::http::get_data(url); const auto res = utils::http::get_data(url);
if (res.has_value()) if (res.has_value())
{ {
@ -120,7 +176,6 @@ namespace motd
if (image_data.has_value()) if (image_data.has_value())
{ {
const auto& image = image_data.value(); const auto& image = image_data.value();
console::debug("Downloaded motd image\n");
images::override_texture("motd_image", image); images::override_texture("motd_image", image);
} }
} }
@ -136,7 +191,7 @@ namespace motd
for (const auto& [key, tab] : data["featured"].items()) for (const auto& [key, tab] : data["featured"].items())
{ {
index++; index++;
if (index >= MAX_FEATURED_TABS + 1) if (index >= max_featured_tabs + 1)
{ {
return; return;
} }
@ -153,7 +208,6 @@ namespace motd
if (image_data.has_value()) if (image_data.has_value())
{ {
const auto& image = image_data.value(); const auto& image = image_data.value();
console::debug("Downloaded featured tab image %i\n", index);
images::override_texture(std::format("{}_{}", image_name, index), image); images::override_texture(std::format("{}_{}", image_name, index), image);
} }
}; };
@ -216,6 +270,8 @@ namespace motd
void init(bool load_images = true) void init(bool load_images = true)
{ {
delete_old_files();
links.access([](links_map_t& map) links.access([](links_map_t& map)
{ {
init_links(map); init_links(map);
@ -225,7 +281,7 @@ namespace motd
{ {
data.clear(); data.clear();
const auto marketing_data = utils::http::get_data("https://master.fed0001.xyz/h2-mod/marketing.json"); const auto marketing_data = updater::get_server_file("h2-mod/marketing.json");
if (marketing_data.has_value()) if (marketing_data.has_value())
{ {
try try
@ -266,7 +322,7 @@ namespace motd
return 0; return 0;
} }
return std::min(MAX_FEATURED_TABS, static_cast<int>(data["featured"].size())); return std::min(max_featured_tabs, static_cast<int>(data["featured"].size()));
}); });
} }

View File

@ -70,12 +70,6 @@ namespace updater
std::vector<std::string> garbage_files{}; std::vector<std::string> garbage_files{};
}; };
// remove this at some point
std::vector<std::string> old_data_files =
{
{"./cdata"},
};
utils::concurrency::container<update_data_t> update_data; utils::concurrency::container<update_data_t> update_data;
std::string select(const std::string& main, const std::string& develop) std::string select(const std::string& main, const std::string& develop)
@ -165,31 +159,16 @@ namespace updater
return utils::string::va("%i", uint32_t(time(nullptr))); return utils::string::va("%i", uint32_t(time(nullptr)));
} }
std::optional<std::string> download_file(const std::string& name) std::optional<std::string> download_data_file(const std::string& name)
{ {
return utils::http::get_data(MASTER + select(DATA_PATH, DATA_PATH_DEV) + name + "?" + get_time_str()); const auto file = std::format("{}{}?{}", select(DATA_PATH, DATA_PATH_DEV), name, get_time_str());
return updater::get_server_file(file);
} }
bool has_old_data_files() std::optional<std::string> download_file_list()
{ {
bool has = false; const auto file = std::format("{}?{}", select(FILES_PATH, FILES_PATH_DEV), get_time_str());
for (const auto& file : old_data_files) return updater::get_server_file(file);
{
if (utils::io::directory_exists(file))
{
has = true;
}
}
return has;
}
void delete_old_data_files()
{
for (const auto& file : old_data_files)
{
std::filesystem::remove_all(file);
}
} }
bool is_update_cancelled() bool is_update_cancelled()
@ -285,6 +264,34 @@ namespace updater
} }
} }
std::optional<std::string> get_server_file(const std::string& endpoint)
{
static std::vector<std::string> server_urls =
{
{"https://h2-mod.fed.cat/"},
{"https://master.fed0001.xyz/"}, // remove this at some point
};
const auto try_url = [&](const std::string& base_url)
{
const auto url = base_url + endpoint;
console::debug("[HTTP] GET file \"%s\"\n", url.data());
const auto result = utils::http::get_data(url);
return result;
};
for (const auto& url : server_urls)
{
const auto result = try_url(url);
if (result.has_value())
{
return result;
}
}
return {};
}
void relaunch() void relaunch()
{ {
utils::nt::relaunch_self("-singleplayer"); utils::nt::relaunch_self("-singleplayer");
@ -342,7 +349,7 @@ namespace updater
{ {
return update_data.access<bool>([](update_data_t& data_) return update_data.access<bool>([](update_data_t& data_)
{ {
return data_.required_files.size() > 0 || data_.garbage_files.size() > 0 || has_old_data_files(); return data_.required_files.size() > 0 || data_.garbage_files.size() > 0;
}); });
} }
@ -393,7 +400,7 @@ namespace updater
scheduler::once([]() scheduler::once([]()
{ {
const auto files_data = utils::http::get_data(MASTER + select(FILES_PATH, FILES_PATH_DEV) + "?" + get_time_str()); const auto files_data = download_file_list();
if (is_update_cancelled()) if (is_update_cancelled())
{ {
@ -484,8 +491,6 @@ namespace updater
return; return;
} }
delete_old_data_files();
const auto garbage_files = update_data.access<std::vector<std::string>>([](update_data_t& data_) const auto garbage_files = update_data.access<std::vector<std::string>>([](update_data_t& data_)
{ {
return data_.garbage_files; return data_.garbage_files;
@ -531,7 +536,7 @@ namespace updater
console::info("[Updater] downloading file %s\n", file.name.data()); console::info("[Updater] downloading file %s\n", file.name.data());
#endif #endif
const auto data = download_file(file.name); const auto data = download_data_file(file.name);
if (is_update_cancelled()) if (is_update_cancelled())
{ {

View File

@ -4,6 +4,8 @@
namespace updater namespace updater
{ {
std::optional<std::string> get_server_file(const std::string& endpoint);
void relaunch(); void relaunch();
void set_has_tried_update(bool tried); void set_has_tried_update(bool tried);

View File

@ -125,10 +125,10 @@ FARPROC load_binary(const launcher::mode mode)
return loader.load(self, data); return loader.load(self, data);
#endif #endif
} }
void remove_crash_file() void remove_crash_file()
{ {
utils::io::remove_file("__h2Exe"); utils::io::remove_file("__h2Exe");
utils::io::remove_file("h2_sp_patched.exe"); // remove this at some point
} }
void verify_version() void verify_version()