diff --git a/src/client/component/download.cpp b/src/client/component/download.cpp index 18e152ee..78c19acf 100644 --- a/src/client/component/download.cpp +++ b/src/client/component/download.cpp @@ -88,7 +88,7 @@ namespace download }, scheduler::pipeline::lui); } - console::debug("Download progress: %lli/%lli\n", progress, total); + //console::debug("Download progress: %lli/%lli\n", progress, total); if (download_aborted()) { return -1; diff --git a/src/client/component/motd.cpp b/src/client/component/motd.cpp index 0b8400c1..70e7828d 100644 --- a/src/client/component/motd.cpp +++ b/src/client/component/motd.cpp @@ -1,37 +1,125 @@ #include #include "loader/component_loader.hpp" +#include "console.hpp" #include "materials.hpp" +#include "motd.hpp" +#include "scheduler.hpp" #include "game/game.hpp" -#include +#include + +#define WEBSITE_DATA_URL "https://raw.githubusercontent.com/h1-mod/website/publish/data" namespace motd { + namespace + { + bool waiting = true; + int index = 0; + + featured_content_t featured_content; + + //std::optional motd_image_data; + + void get_featured_content(const std::string& content_name, const int content_index) + { + const auto name = utils::string::va(content_name.data(), content_index); + const auto url = utils::string::va(WEBSITE_DATA_URL "/%s", name); + const auto result = utils::http::get_data(url, {}, {}, {}); + if (result.has_value()) + { + featured_content.insert_or_assign(name, result.value()); + } + }; + + bool handle_featured_content() + { + if (index > 3) + { + return scheduler::cond_end; + } + + scheduler::once([&]() + { + if (index > 3) + { + return; + } + + const auto name = (index == 0 ? "motd.json" : "featured%d.json"); + get_featured_content(name, index); + + ++index; + }, scheduler::async); + + return scheduler::cond_continue; + } + + /* + void download_motd_image() + { + motd_image_data = utils::http::get_data(WEBSITE_DATA_URL "/motd.png", {}, {}, {}); + waiting = false; + } + + bool setup_motd_image() + { + if (waiting) + { + return scheduler::cond_continue; + } + + if (!motd_image_data.has_value()) + { + printf("motd image doesn't have a value\n"); + return scheduler::cond_end; + } + + printf("motd image loading..."); + + const auto material = materials::create_material("motd_image"); + try + { + if (!materials::setup_material_image(material, motd_image_data.value().buffer)) + { + materials::free_material(material); + } + + printf("motd image loaded"); + } + catch (const std::exception& e) + { + materials::free_material(material); + console::error("Failed to load MOTD image: %s\n", e.what()); + } + + return scheduler::cond_end; + } + */ + } + + featured_content_t& get_featured_content() + { + return featured_content; + } + class component final : public component_interface { public: void post_load() override { - std::thread([] - { - //auto data = utils::http::get_data("https://h1.gg/data/motd.png"); - //if (data.has_value()) - //{ - // materials::add("motd_image", data.value().buffer); - //} - }).detach(); - } - - void post_unpack() override - { - if (game::environment::is_sp()) + if (!game::environment::is_mp()) { return; } + + //scheduler::once(download_motd_image, scheduler::async); + //scheduler::schedule(setup_motd_image, scheduler::main); + scheduler::schedule(handle_featured_content, scheduler::async); } }; } -REGISTER_COMPONENT(motd::component) \ No newline at end of file +REGISTER_COMPONENT(motd::component) diff --git a/src/client/component/motd.hpp b/src/client/component/motd.hpp new file mode 100644 index 00000000..31afa12f --- /dev/null +++ b/src/client/component/motd.hpp @@ -0,0 +1,10 @@ +#pragma once + +#include + +namespace motd +{ + using featured_content_t = std::unordered_map; + + featured_content_t& get_featured_content(); +} diff --git a/src/client/component/party.cpp b/src/client/component/party.cpp index 91a4f073..62823891 100644 --- a/src/client/component/party.cpp +++ b/src/client/component/party.cpp @@ -249,7 +249,7 @@ namespace party if (mapname.contains('.') || mapname.contains("::")) { - throw std::runtime_error(utils::string::va("Invalid server mapname value %s\n", mapname.data())); + throw std::runtime_error(utils::string::va("Invalid server mapname value '%s'", mapname.data())); } const auto check_file = [&](const usermap_file& file) @@ -261,10 +261,10 @@ namespace party { if (!file.optional) { - std::string missing_value = "Server %s is empty"; + std::string missing_value = "Server '%s' is empty"; if (file.name == "usermap_hash"s) { - missing_value += " (or you are missing content for map '%s')\n"; + missing_value += " (or you are missing content for map '%s')"; } throw std::runtime_error(utils::string::va(missing_value.data(), file.name.data(), mapname.data())); } @@ -306,7 +306,7 @@ namespace party if (!server_fs_game.starts_with("mods/") || server_fs_game.contains('.') || server_fs_game.contains("::")) { - throw std::runtime_error(utils::string::va("Invalid server fs_game value %s\n", server_fs_game.data())); + throw std::runtime_error(utils::string::va("Invalid server fs_game value '%s'", server_fs_game.data())); } auto needs_restart = false; @@ -321,7 +321,7 @@ namespace party } throw std::runtime_error( - utils::string::va("Connection failed: Server %s is empty.", file.name.data())); + utils::string::va("Server '%s' is empty", file.name.data())); } const auto file_path = server_fs_game + "/mod" + file.extension; diff --git a/src/client/game/demonware/services/bdMarketingComms.cpp b/src/client/game/demonware/services/bdMarketingComms.cpp index aa6ac61c..0de1d9d8 100644 --- a/src/client/game/demonware/services/bdMarketingComms.cpp +++ b/src/client/game/demonware/services/bdMarketingComms.cpp @@ -1,5 +1,8 @@ #include +#include "component/motd.hpp" +#include "component/scheduler.hpp" + #include #include "../services.hpp" @@ -14,67 +17,21 @@ namespace demonware void bdMarketingComms::getMessages(service_server* server, byte_buffer* /*buffer*/) const { - /*auto reply = server->create_reply(this->task_id()); - - const int timeout = 7; // seconds - - std::optional motd_content; - std::optional featured_content; - std::optional featured2_content; - - auto get_motd = [&motd_content]() - { - motd_content = utils::http::get_data("https://h1.gg/data/motd.json", {}, {}, {}, timeout); - }; - auto get_featured = [&featured_content]() - { - featured_content = utils::http::get_data("https://h1.gg/data/featured.json", {}, {}, {}, timeout); - }; - auto get_featured2 = [&featured2_content]() - { - featured2_content = utils::http::get_data("https://h1.gg/data/featured2.json", {}, {}, {}, timeout); - }; - - std::thread get_motd_thread(get_motd); - std::thread get_featured_thread(get_featured); - std::thread get_featured2_thread(get_featured2); - - get_motd_thread.join(); - get_featured_thread.join(); - get_featured2_thread.join(); - - if (motd_content.has_value()) - { - const auto motd = new bdMarketingMessage; - motd->m_messageID = 1; - motd->m_languageCode = "en-US"; - motd->m_content = motd_content.value().buffer.data(); - motd->m_metadata = "{}"; - reply->add(motd); - } - - if (featured_content.has_value()) - { - const auto featured = new bdMarketingMessage; - featured->m_messageID = 2; - featured->m_languageCode = "en-US"; - featured->m_content = featured_content.value().buffer.data(); - featured->m_metadata = "{}"; - reply->add(featured); - } - - if (featured2_content.has_value()) - { - const auto featured2 = new bdMarketingMessage; - featured2->m_messageID = 3; - featured2->m_languageCode = "en-US"; - featured2->m_content = featured2_content.value().buffer.data(); - featured2->m_metadata = "{}"; - reply->add(featured2); - } - - reply->send();*/ auto reply = server->create_reply(this->task_id()); + + int message_id = 1; + const auto featured_content = motd::get_featured_content(); + for (const auto& [key, value] : featured_content) + { + const auto marketing_message = new bdMarketingMessage; + marketing_message->m_messageID = message_id; + marketing_message->m_languageCode = "en-US"; + marketing_message->m_content = value.buffer; + marketing_message->m_metadata = "{}"; + reply->add(marketing_message); + ++message_id; + } + reply->send(); }