diff --git a/src/citymania/cm_community_link.cpp b/src/citymania/cm_community_link.cpp new file mode 100644 index 0000000000..d845d6710b --- /dev/null +++ b/src/citymania/cm_community_link.cpp @@ -0,0 +1,87 @@ +#include "cm_community_link.hpp" +#include "../fileio_func.h" + +#include +#include + +using namespace citymania; +using namespace std::literals; + +constexpr std::array ALL_COMMUNITIES = { Community::CITYMANIA, Community::NICE, Community::BTPRO }; +static_assert(ALL_COMMUNITIES.size() == Community::NONE); + +const std::array COMMUNITIES_FILENAMES = { + "citymania.json"s, + "nice.json"s, + "btpro.json"s +}; +static_assert(COMMUNITIES_FILENAMES.size() == static_cast(Community::NONE)); + +const std::array COMMUNITIES_ADDRESSES = { + "citymania.json"s, + "https://home.miguelhorta.name/nice.json"s, + "btpro.json"s +}; +static_assert(COMMUNITIES_ADDRESSES.size() == static_cast(Community::NONE)); + +CommunityLink::CommunityLink() +{ + for (const auto com : ALL_COMMUNITIES) { + communities[com].SetPaths(COMMUNITIES_FILENAMES[com], COMMUNITIES_ADDRESSES[com]); + communities[com].LoadFromFile(); + } + + communities[ActiveCommunity()].Refresh(); +} + +/*static*/ Community::List CommunityLink::ActiveCommunity() +{ + if (_settings_client.gui.cm_active_community <= Community::NONE) + return _settings_client.gui.cm_active_community; + + _settings_client.gui.cm_active_community = Community::NONE; + return Community::NONE; +} + +Community::Community() +{ + +} + +void Community::SetPaths(const std::string &filename, const std::string &address) +{ + this->filename = filename; + this->address = address; +} + +bool Community::Refresh() +{ + if (request_in_progress.test_and_set()) + return false; + + if (this->address.empty()) + return false; + + NetworkHTTPSocketHandler::Connect(this->address, this); +} + +void Community::OnReceiveData(std::unique_ptr data, size_t length) +{ + assert(data.get() == nullptr || length != 0); + + + if (data != nullptr) { + /* Append the rest of the response. */ + std::copy(data.get(), data.get() + length, std::back_inserter(this->http_response)); + return; + } else { + /* Make sure the response is properly terminated. */ + this->http_response.push_back('\0'); + } +} + +void Community::OnFailure() +{ + request_in_progress.clear(); + http_response.clear(); +} diff --git a/src/citymania/cm_community_link.hpp b/src/citymania/cm_community_link.hpp new file mode 100644 index 0000000000..33f5e0b578 --- /dev/null +++ b/src/citymania/cm_community_link.hpp @@ -0,0 +1,60 @@ +#pragma once + +#include "../network/network.h" //networking +#include "../network/core/http.h" //networking + +#include +#include +#include + +namespace citymania { + + + class Community : public HTTPCallback { + void Reset(); + public: + enum List { + CITYMANIA = 0, + NICE, + BTPRO, + NONE, // < This has to be the last entry + }; + + Community(); + void SetPaths(const std::string&, const std::string&); + ~Community() = default; + void LoadFromFile(); + + bool Refresh(); + void OnReceiveData(std::unique_ptr data, size_t length) override; + void OnFailure() override; + bool IsCancelled() const override { return false; } + private: + std::string filename; + std::string address; + std::vector http_response; + std::atomic_flag request_in_progress = ATOMIC_FLAG_INIT; + }; + + class CommunityLink { + CommunityLink *instance = nullptr; + std::size_t active_community = Community::NONE; + std::array communities; + CommunityLink(); + public: + CommunityLink &inst() + { + if (!instance) { + instance = new CommunityLink(); + } + return *instance; + } + void OnSeverJoin(); + void Refresh(); + + static Community::List ActiveCommunity(); + }; + +} + +// TODO block multiple requests diff --git a/src/citymania/cm_intro_gui.cpp b/src/citymania/cm_intro_gui.cpp new file mode 100644 index 0000000000..e69de29bb2 diff --git a/src/lang/english.txt b/src/lang/english.txt index ae88fdc084..5c426fa880 100644 --- a/src/lang/english.txt +++ b/src/lang/english.txt @@ -6261,6 +6261,12 @@ CM_STR_CONFIG_SETTING_GRAPH_BACKGROUND_HELPTEXT :Main background CM_STR_CONFIG_SETTING_GRAPH_BACKGROUND_BLACK :Black CM_STR_CONFIG_SETTING_GRAPH_BACKGROUND_GREY :Light grey +# Communities +CM_STR_COMMUNITY_CITYMANIA :{BLACK}CityMania +CM_STR_COMMUNITY_NICE :{BLACK}N-ice +CM_STR_COMMUNITY_BTPRO :{BLACK}BTPro +CM_STR_COMMUNITY_NONE :{BLACK}None + # Community login window CM_STR_LOGIN_WINDOW_CAPTION :{WHITE}Login Window CM_STR_LOGIN_WINDOW_CITYMANIA :{BLACK}CityMania diff --git a/src/table/settings/cmclient_settings.ini b/src/table/settings/cmclient_settings.ini index 53b1d085e9..47e633a3ff 100644 --- a/src/table/settings/cmclient_settings.ini +++ b/src/table/settings/cmclient_settings.ini @@ -298,3 +298,15 @@ def = true str = CM_STR_CONFIG_SETTING_TOOLBAR_DROPDOWN_CLOSE strhelp = CM_STR_CONFIG_SETTING_TOOLBAR_DROPDOWN_CLOSE_HELPTEXT cat = SC_BASIC + +[SDTC_CAR] +var = gui.cm_active_community +type = SLE_UINT8 +flags = SettingFlag::NotInSave, SettingFlag::NoNetworkSync, SettingFlag::GuiDropdown, SettingFlag::CityMania +def = 3 +min = 0 +max = 3 +interval = 1 +str = CM_STR_COMMUNITY_CITYMANIA +strval = CM_STR_COMMUNITY_NONE +cat = SC_BASIC