Update server url + motd/updater cleanup
This commit is contained in:
parent
a3df8a3e22
commit
9a9bb2e196
@ -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()));
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -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())
|
||||
{
|
||||
|
@ -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);
|
||||
|
@ -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()
|
||||
|
Loading…
Reference in New Issue
Block a user