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 "images.hpp"
#include "command.hpp"
#include "updater.hpp"
#include <utils/string.hpp>
#include <utils/http.hpp>
@ -13,15 +14,14 @@
#include <utils/io.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
{
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<nlohmann::json, std::recursive_mutex> marketing;
@ -31,6 +31,12 @@ namespace motd
time_t date_created;
};
struct parsed_cache_file
{
cached_file_header header{};
std::string data;
};
std::filesystem::path get_cache_folder()
{
return utils::properties::get_appdata_path() / "cache";
@ -45,10 +51,10 @@ namespace motd
void cache_file(const std::string& name, const std::string& data)
{
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{};
header.signature = CACHE_FILE_SIGNATURE;
header.signature = cache_file_signature;
header.date_created = now;
buffer.append(reinterpret_cast<char*>(&header), sizeof(header));
@ -58,6 +64,42 @@ namespace motd
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)
{
const auto path = get_cached_file_name(name);
@ -66,29 +108,41 @@ namespace motd
return {};
}
auto now = std::chrono::system_clock::now();
auto data = utils::io::read_file(path);
if (data.size() < sizeof(cached_file_header))
const auto parsed = parse_cached_file(path);
if (!parsed.has_value())
{
return {};
}
auto buffer = data.data();
const auto header = reinterpret_cast<cached_file_header*>(buffer);
if (header->signature != CACHE_FILE_SIGNATURE)
{
return {};
return {parsed->data};
}
void delete_old_files()
{
const auto path = get_cache_folder().generic_string();
if (!utils::io::directory_exists(path))
{
return;
}
const auto now = std::chrono::system_clock::now();
const auto files = utils::io::list_files(path);
for (const auto& file : files)
{
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)
if (now - date >= cache_max_age)
{
utils::io::remove_file(path);
return {};
utils::io::remove_file(file);
}
}
const auto file_data = buffer + sizeof(cached_file_header);
return std::string{file_data, data.size() - sizeof(cached_file_header)};
}
std::optional<std::string> download_image(const std::string& url)
@ -99,6 +153,8 @@ namespace motd
return {cached.value()};
}
console::debug("[HTTP] GET File \"%s\"\n", url.data());
const auto res = utils::http::get_data(url);
if (res.has_value())
{
@ -120,7 +176,6 @@ namespace motd
if (image_data.has_value())
{
const auto& image = image_data.value();
console::debug("Downloaded motd image\n");
images::override_texture("motd_image", image);
}
}
@ -136,7 +191,7 @@ namespace motd
for (const auto& [key, tab] : data["featured"].items())
{
index++;
if (index >= MAX_FEATURED_TABS + 1)
if (index >= max_featured_tabs + 1)
{
return;
}
@ -153,7 +208,6 @@ namespace motd
if (image_data.has_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);
}
};
@ -216,6 +270,8 @@ namespace motd
void init(bool load_images = true)
{
delete_old_files();
links.access([](links_map_t& map)
{
init_links(map);
@ -225,7 +281,7 @@ namespace motd
{
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())
{
try
@ -266,7 +322,7 @@ namespace motd
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{};
};
// remove this at some point
std::vector<std::string> old_data_files =
{
{"./cdata"},
};
utils::concurrency::container<update_data_t> update_data;
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)));
}
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;
for (const auto& file : old_data_files)
{
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);
}
const auto file = std::format("{}?{}", select(FILES_PATH, FILES_PATH_DEV), get_time_str());
return updater::get_server_file(file);
}
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()
{
utils::nt::relaunch_self("-singleplayer");
@ -342,7 +349,7 @@ namespace updater
{
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([]()
{
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())
{
@ -484,8 +491,6 @@ namespace updater
return;
}
delete_old_data_files();
const auto garbage_files = update_data.access<std::vector<std::string>>([](update_data_t& data_)
{
return data_.garbage_files;
@ -531,7 +536,7 @@ namespace updater
console::info("[Updater] downloading file %s\n", file.name.data());
#endif
const auto data = download_file(file.name);
const auto data = download_data_file(file.name);
if (is_update_cancelled())
{

View File

@ -4,6 +4,8 @@
namespace updater
{
std::optional<std::string> get_server_file(const std::string& endpoint);
void relaunch();
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);
#endif
}
void remove_crash_file()
{
utils::io::remove_file("__h2Exe");
utils::io::remove_file("h2_sp_patched.exe"); // remove this at some point
}
void verify_version()