--- a/src/addons/addons_manager.cpp 2020-08-28 10:16:23.000000000 +0200 +++ b/src/addons/addons_manager.cpp 2023-12-09 23:08:13.240106458 +0100 @@ -22,7 +22,6 @@ #include "addons/addons_manager.hpp" -#include "addons/news_manager.hpp" #include "addons/zip.hpp" #include "config/user_config.hpp" #include "io/file_manager.hpp" @@ -52,21 +51,12 @@ // ---------------------------------------------------------------------------- /** Initialises the non-online component of the addons manager (i.e. handling - * the list of already installed addons). The online component is initialised - * later from a separate thread started from the news manager (see - * NewsManager::init() ). + * the list of already installed addons). */ AddonsManager::AddonsManager() : m_addons_list(std::vector() ), m_state(STATE_INIT) { m_downloaded_icons = false; - // Clean .part file which may be left behind - std::string addons_part = file_manager->getAddonsFile("addons.xml.part"); - if (file_manager->fileExists(addons_part)) - file_manager->removeFile(addons_part); - - m_file_installed = file_manager->getAddonsFile("addons_installed.xml"); - // Load the addons list (even if internet is disabled) m_addons_list.lock(); // Clear the list in case that a reinit is being done. @@ -85,77 +75,11 @@ } // ~AddonsManager // ---------------------------------------------------------------------------- -/** This init function is called from a separate thread (started in - * news_manager, since the news.xml file contains the address of the - * addons.xml URL). - * \param xml The news.xml file, which inclues the data about the addons.xml - * file (in the 'include' node). - * \param force_refresh Download addons.xml, even if the usual waiting period - * between downloads hasn't passed yet. +/** This init function is called from a separate thread. */ void AddonsManager::init(const XMLNode *xml, bool force_refresh) { - std::string addon_list_url(""); - StkTime::TimeType mtime(0); - const XMLNode *include = xml->getNode("include"); - std::string filename=file_manager->getAddonsFile("addons.xml"); - // Prevent downloading when .part file created, which is already downloaded - std::string filename_part=file_manager->getAddonsFile("addons.xml.part"); - if(!include) - { - file_manager->removeFile(filename); - setErrorState(); - NewsManager::get()->addNewsMessage(_("Failed to connect to the SuperTuxKart add-ons server.")); - return; - } - - include->get("file", &addon_list_url); - int frequency = 0; - include->get("frequency", &frequency); - - int64_t tmp; - include->get("mtime", &tmp); - mtime = tmp; - - bool download = - ( mtime > UserConfigParams::m_addons_last_updated +frequency || - force_refresh || - !file_manager->fileExists(filename) ) - && UserConfigParams::m_internet_status == RequestManager::IPERM_ALLOWED - && !file_manager->fileExists(filename_part); - - if (download) - { - Log::info("addons", "Downloading updated addons.xml."); - auto download_request = std::make_shared("addons.xml"); - download_request->setURL(addon_list_url); - download_request->executeNow(); - if(download_request->hadDownloadError()) - { - Log::error("addons", "Error on download addons.xml: %s.", - download_request->getDownloadErrorMessage()); - return; - } - UserConfigParams::m_addons_last_updated=StkTime::getTimeSinceEpoch(); - } - else - Log::info("addons", "Using cached addons.xml."); - - const XMLNode* xml_addons = NULL; - try - { - xml_addons = new XMLNode(filename); - } - catch (std::exception& e) - { - Log::error("addons", "Error %s", e.what()); - } - if (!xml_addons) - return; - addons_manager->initAddons(xml_addons); // will free xml_addons - if(UserConfigParams::logAddons()) - Log::info("addons", "Addons manager list downloaded."); } // init // ---------------------------------------------------------------------------- @@ -168,139 +92,6 @@ */ void AddonsManager::initAddons(const XMLNode *xml) { - m_addons_list.lock(); - // Clear the list in case that a reinit is being done. - m_addons_list.getData().clear(); - loadInstalledAddons(); - m_addons_list.unlock(); - - for(unsigned int i=0; igetNumNodes(); i++) - { - const XMLNode *node = xml->getNode(i); - const std::string &name = node->getName(); - // Ignore news/redirect, which is handled by the NewsManager - if(name=="include" || name=="message") - continue; - if(node->getName()=="track" || node->getName()=="kart" || - node->getName()=="arena" ) - { - Addon addon(*node); - int index = getAddonIndex(addon.getId()); - - int stk_version=0; - node->get("format", &stk_version); - int testing=-1; - node->get("testing", &testing); - - bool wrong_version=false; - - if(addon.getType()=="kart") - wrong_version = stk_version m_min_kart_version || - stk_version >stk_config->m_max_kart_version ; - else - wrong_version = stk_version m_min_track_version || - stk_version >stk_config->m_max_track_version ; - // If the add-on is included, behave like it is a wrong version - if (addon.testIncluded(addon.getMinIncludeVer(), addon.getMaxIncludeVer())) - wrong_version = true; - - // Check which version to use: only for this stk version, - // and not addons that are marked as hidden (testing=0) - if(wrong_version|| testing==0) - { - // If the version is too old (e.g. after an update of stk) - // remove a cached icon. - std::string full_path = - file_manager->getAddonsFile("icons/" - +addon.getIconBasename()); - if(file_manager->fileExists(full_path)) - { - if(UserConfigParams::logAddons()) - Log::warn("addons", "Removing cached icon '%s'.", - addon.getIconBasename().c_str()); - file_manager->removeFile(full_path); - } - continue; - } - - m_addons_list.lock(); - if(index>=0) - { - Addon& tmplist_addon = m_addons_list.getData()[index]; - - // Only copy the data if a newer revision is found (ignore unapproved - // revisions unless player is in the mode to see them) - if (tmplist_addon.getRevision() < addon.getRevision() && - (addon.testStatus(Addon::AS_APPROVED) || UserConfigParams::m_artist_debug_mode)) - { - m_addons_list.getData()[index].copyInstallData(addon); - } - } - else - { - m_addons_list.getData().push_back(addon); - index = (int) m_addons_list.getData().size()-1; - } - // Mark that this addon still exists on the server - m_addons_list.getData()[index].setStillExists(); - m_addons_list.unlock(); - } - else - { - Log::error("addons", "Found invalid node '%s' while downloading addons.", - node->getName().c_str()); - Log::error("addons", "Ignored."); - } - } // for igetNumNodes - delete xml; - - // Now remove all items from the addons-installed list, that are not - // on the server anymore (i.e. not in the addons.xml file), and not - // installed. If found, remove the icon cached for this addon. - // Note that if (due to a bug) an icon is shared (i.e. same icon on - // an addon that's still on the server and an invalid entry in the - // addons installed file), it will be re-downloaded later. - m_addons_list.lock(); - unsigned int count = (unsigned int) m_addons_list.getData().size(); - - for(unsigned int i=0; igetAddonsFile("icons/"+icon); - if(file_manager->fileExists(icon_file)) - { - file_manager->removeFile(icon_file); - // Ignore errors silently. - } - m_addons_list.getData()[i] = m_addons_list.getData()[count-1]; - m_addons_list.getData().pop_back(); - count--; - } - m_addons_list.unlock(); - - for (unsigned int i = 0; i < m_addons_list.getData().size(); i++) - { - Addon& addon = m_addons_list.getData()[i]; - const std::string& icon = addon.getIconBasename(); - const std::string& icon_full = - file_manager->getAddonsFile("icons/" + icon); - if (!addon.iconNeedsUpdate() && file_manager->fileExists(icon_full)) - addon.setIconReady(); - } // for i < m_addons_list.size() - - m_state.setAtomic(STATE_READY); } // initAddons // ---------------------------------------------------------------------------- @@ -309,7 +100,6 @@ */ void AddonsManager::reInit() { - m_state.setAtomic(STATE_INIT); } // reInit // ---------------------------------------------------------------------------- @@ -320,53 +110,6 @@ */ void AddonsManager::checkInstalledAddons() { - bool something_was_changed = false; - - // Lock the whole addons list to make sure a consistent view is - // written back to disk. The network thread might still be - // downloading icons and modify content - m_addons_list.lock(); - - // First karts - // ----------- - for(unsigned int i=0; igetNumberOfKarts(); i++) - { - const KartProperties *kp = kart_properties_manager->getKartById(i); - const std::string &dir=kp->getKartDir(); - if(dir.find(file_manager->getAddonsDir())==std::string::npos) - continue; - int n = getAddonIndex(kp->getIdent()); - if(n<0) continue; - if(!m_addons_list.getData()[n].isInstalled()) - { - Log::info("addons", "Marking '%s' as being installed.", - kp->getIdent().c_str()); - m_addons_list.getData()[n].setInstalled(true); - something_was_changed = true; - } - } - - // Then tracks - // ----------- - for(unsigned int i=0; igetNumberOfTracks(); i++) - { - const Track *track = track_manager->getTrack(i); - const std::string &dir=track->getFilename(); - if(dir.find(file_manager->getAddonsDir())==std::string::npos) - continue; - int n = getAddonIndex(track->getIdent()); - if(n<0) continue; - if(!m_addons_list.getData()[n].isInstalled()) - { - Log::info("addons", "Marking '%s' as being installed.", - track->getIdent().c_str()); - m_addons_list.getData()[n].setInstalled(true); - something_was_changed = true; - } - } - if(something_was_changed) - saveInstalled(); - m_addons_list.unlock(); } // checkInstalledAddons // ---------------------------------------------------------------------------- @@ -374,83 +117,13 @@ void AddonsManager::downloadIconForAddon(const std::string& addon_id, std::weak_ptr result) { - Addon* addon = getAddon(addon_id); - if (!addon) - return; - const std::string &icon = addon->getIconBasename(); - const std::string &icon_full = - file_manager->getAddonsFile("icons/" + icon); - if (addon->iconNeedsUpdate() || - !file_manager->fileExists(icon_full)) - { - const std::string& url = addon->getIconURL(); - const std::string& icon = addon->getIconBasename(); - if (icon.empty()) - { - if (UserConfigParams::logAddons()) - { - Log::error("addons", "No icon or image specified for '%s'.", - addon->getId().c_str()); - } - return; - } - // A simple class that will notify the addon via a callback - class IconRequest : public Online::HTTPRequest - { - std::weak_ptr m_result; - Addon* m_addon; // stores this addon object - void callback() - { - m_addon->setIconReady(); - if (std::shared_ptr result = m_result.lock()) - *result = true; - if (!hadDownloadError()) - addons_manager->m_downloaded_icons = true; - } // callback - public: - IconRequest(const std::string& filename, - const std::string& url, - Addon* addon, std::weak_ptr result) - : HTTPRequest(filename,/*priority*/1) - { - m_addon = addon; - m_result = result; - setURL(url); - } // IconRequest - }; - auto r = - std::make_shared("icons/"+icon, url, addon, result); - r->queue(); - } } // downloadIconForAddon // ---------------------------------------------------------------------------- -/** Loads the installed addons from .../addons/addons_installed.xml. +/** Loads the installed addons. */ void AddonsManager::loadInstalledAddons() { - /* checking for installed addons */ - if(UserConfigParams::logAddons()) - { - Log::info("addons", "Loading an xml file for installed addons: %s.", - m_file_installed.c_str()); - } - const XMLNode *xml = file_manager->createXMLTree(m_file_installed); - if(!xml) - return; - - for(unsigned int i=0; igetNumNodes(); i++) - { - const XMLNode *node=xml->getNode(i); - if(node->getName()=="kart" || node->getName()=="arena" || - node->getName()=="track" ) - { - Addon addon(*node); - m_addons_list.getData().push_back(addon); - } - } // for i <= xml->getNumNodes() - - delete xml; } // loadInstalledAddons // ---------------------------------------------------------------------------- @@ -498,70 +171,6 @@ */ bool AddonsManager::install(const Addon &addon) { - - //extract the zip in the addons folder called like the addons name - std::string base_name = StringUtils::getBasename(addon.getZipFileName()); - std::string from = file_manager->getAddonsFile("tmp/"+base_name); - std::string to = addon.getDataDir(); - - // Remove old addon first (including non official way to install addons) - AddonsPack::uninstallByName(addon.getDirName(), true/*force_clear*/); - if (file_manager->isDirectory(to)) - file_manager->removeDirectory(to); - - file_manager->checkAndCreateDirForAddons(to); - - bool success = extract_zip(from, to, true/*recursive*/); - if (!success) - { - // TODO: show a message in the interface - Log::error("addons", "Failed to unzip '%s' to '%s'.", - from.c_str(), to.c_str()); - } - - if(!file_manager->removeFile(from)) - { - Log::error("addons", "Problems removing temporary file '%s'.", - from.c_str()); - } - if (!success) - return false; - - int index = getAddonIndex(addon.getId()); - assert(index>=0 && index < (int)m_addons_list.getData().size()); - m_addons_list.getData()[index].setInstalled(true); - - if(addon.getType()=="kart") - { - // We have to remove the mesh of the kart since otherwise it remains - // cashed (if a kart is updated), and will therefore be found again - // when reloading the karts. This is important on one hand since we - // reload all karts (this function is easily available) and existing - // karts will not reload their meshes. - const KartProperties *prop = - kart_properties_manager->getKart(addon.getId()); - // If the model already exist, first remove the old kart - if(prop) - kart_properties_manager->removeKart(addon.getId()); - kart_properties_manager->loadKart(addon.getDataDir()); - } - else if (addon.getType()=="track" || addon.getType()=="arena") - { - Track *track = track_manager->getTrack(addon.getId()); - if(track) - track_manager->removeTrack(addon.getId()); - - try - { - track_manager->loadTrack(addon.getDataDir()); - } - catch (std::exception& e) - { - Log::error("addons", "Cannot load track '%s' : %s.", - addon.getDataDir().c_str(), e.what()); - } - } - saveInstalled(); return true; } // install @@ -572,45 +181,7 @@ */ bool AddonsManager::uninstall(const Addon &addon) { - Log::info("addons", "Uninstalling '%s'.", - core::stringc(addon.getName()).c_str()); - - // addon is a const reference, and to avoid removing the const, we - // find the proper index again to modify the installed state - int index = getAddonIndex(addon.getId()); - assert(index>=0 && index < (int)m_addons_list.getData().size()); - m_addons_list.getData()[index].setInstalled(false); - - //remove the addons directory - bool error = false; - // if the user deleted the data directory for an add-on with - // filesystem tools, removeTrack/removeKart will trigger an assert - // because the kart/track was never added in the first place - if (file_manager->fileExists(addon.getDataDir())) - { - error = !file_manager->removeDirectory(addon.getDataDir()); - - // Even if an error happened when removing the data files - // still remove the addon, since it is unknown if e.g. only - // some files were successfully removed. Since we can not - // know if the addon is still functional, better remove it. - // On the other hand, in case of a problem the user will have - // the option in the GUI to try again. In this case - // removeTrack/Kart would not find the addon and assert. So - // check first if the track is still known. - if(addon.getType()=="kart") - { - if(kart_properties_manager->getKart(addon.getId())) - kart_properties_manager->removeKart(addon.getId()); - } - else if(addon.getType()=="track" || addon.getType()=="arena") - { - if(track_manager->getTrack(addon.getId())) - track_manager->removeTrack(addon.getId()); - } - } - saveInstalled(); - return !error; + return true; } // uninstall // ---------------------------------------------------------------------------- @@ -621,30 +192,6 @@ */ void AddonsManager::saveInstalled() { - // Put the addons in the xml file - // Manually because the irrlicht xml writer doesn't seem finished, FIXME ? - std::ofstream xml_installed( - FileUtils::getPortableWritingPath(m_file_installed)); - - // Write the header of the xml file - xml_installed << "" << std::endl; - - // Get server address from config - const std::string server = stk_config->m_server_addons; - - // Find the third slash (end of the domain) - std::string::size_type index = server.find('/'); - index = server.find('/', index + 2) + 1; // Omit one slash - xml_installed << "" - << std::endl; - - for(unsigned int i = 0; i < m_addons_list.getData().size(); i++) - { - m_addons_list.getData()[i].writeXML(&xml_installed); - } - xml_installed << "" << std::endl; - xml_installed.close(); - m_downloaded_icons = false; } // saveInstalled #endif --- a/src/addons/news_manager.cpp 2020-08-28 10:16:23.000000000 +0200 +++ b/src/addons/news_manager.cpp 2023-12-09 23:11:32.080108164 +0100 @@ -46,26 +46,12 @@ m_error_message.setAtomic(""); m_force_refresh = false; - // Clean .part file which may be left behind - std::string news_part = file_manager->getAddonsFile(m_news_filename + ".part"); - if (file_manager->fileExists(news_part)) - file_manager->removeFile(news_part); - init(false); } // NewsManage // --------------------------------------------------------------------------- NewsManager::~NewsManager() { - // If the download thread doesn't finish on time we detach the thread to - // avoid exception - if (m_download_thread.joinable()) - { - if (!CanBeDeleted::canBeDeletedNow()) - m_download_thread.detach(); - else - m_download_thread.join(); - } } // ~NewsManager // --------------------------------------------------------------------------- @@ -78,21 +64,6 @@ */ void NewsManager::init(bool force_refresh) { - if (m_download_thread.joinable()) - return; - - m_force_refresh = force_refresh; - - // The rest (which potentially involves downloading m_news_filename) is handled - // in a separate thread, so that the GUI remains responsive. It is only - // started if internet access is enabled, else nothing is done in the - // thread anyway (and the addons menu is disabled as a result). - if(UserConfigParams::m_internet_status==RequestManager::IPERM_ALLOWED) - { - CanBeDeleted::resetCanBeDeleted(); - m_download_thread = std::thread(std::bind( - &NewsManager::downloadNews, this)); - } } //init // --------------------------------------------------------------------------- @@ -102,117 +73,6 @@ */ void NewsManager::downloadNews() { - VS::setThreadName("downloadNews"); - clearErrorMessage(); - - std::string xml_file = file_manager->getAddonsFile(m_news_filename); - // Prevent downloading when .part file created, which is already downloaded - std::string xml_file_part = file_manager->getAddonsFile(m_news_filename + ".part"); - bool news_exists = file_manager->fileExists(xml_file); - - // The news message must be updated if either it has never been updated, - // or if the time of the last update was more than news_frequency ago, - // or because a 'refresh' was explicitly requested by the user, or no - // m_news_filename file exists. - bool download = ( UserConfigParams::m_news_last_updated==0 || - UserConfigParams::m_news_last_updated - +UserConfigParams::m_news_frequency - < StkTime::getTimeSinceEpoch() || - m_force_refresh || - !news_exists ) - && UserConfigParams::m_internet_status==RequestManager::IPERM_ALLOWED - && !file_manager->fileExists(xml_file_part); - const XMLNode *xml = NULL; - - if(!download && news_exists) - { - // If (so far) we don't need to download, there should be an existing - // file. Try to read this, and do some basic checks - xml = new XMLNode(xml_file); - // A proper news file has at least a version number, mtime, frequency - // and an include node (which contains addon data) defined. If this is - // not the case, assume that it is an invalid download, or a corrupt - // local file. Try downloading again after resetting the news server - // back to the default. - int version=-1; - if( !xml->get("version", &version) || version!=1 || - !xml->get("mtime", &version) || - !xml->getNode("include") || - !xml->get("frequency", &version) ) - { - delete xml; - xml = NULL; - download = true; - } // if xml not consistemt - } // if !download - - if(download) - { - core::stringw error_message(""); - - auto download_req = std::make_shared(m_news_filename); - download_req->setAddonsURL(m_news_filename); - - // Initialise the online portion of the addons manager. - if(UserConfigParams::logAddons()) - Log::info("addons", "Downloading news."); - download_req->executeNow(); - - if(download_req->hadDownloadError()) - { - // Assume that the server address is wrong. And retry - // with the default server address again (just in case - // that a redirect went wrong, or a wrong/incorrect - // address somehow made its way into the config file. - // We need a new object, since the state of the old - // download request is now done. - download_req = std::make_shared(m_news_filename); - - // make sure the new server address is actually used - download_req->setAddonsURL(m_news_filename); - download_req->executeNow(); - - if(download_req->hadDownloadError()) - { - // This message must be translated dynamically in the main menu. - // If it would be translated here, it wouldn't be translated - // if the language is changed in the menu! - error_message = N_("Error downloading news: '%s'."); - const char *const curl_error = download_req->getDownloadErrorMessage(); - error_message = StringUtils::insertValues(error_message, curl_error); - addons_manager->setErrorState(); - setErrorMessage(error_message); - Log::error("news", core::stringc(error_message).c_str()); - } // hadDownloadError - } // hadDownloadError - - if(!download_req->hadDownloadError()) - UserConfigParams::m_news_last_updated = StkTime::getTimeSinceEpoch(); - - // No download error, update the last_updated time value, and delete - // the potentially loaded xml file - delete xml; - xml = NULL; - } // hadDownloadError - - if(xml) delete xml; - xml = NULL; - - // Process new.xml now. - if(file_manager->fileExists(xml_file)) - { - xml = new XMLNode(xml_file); - checkRedirect(xml); - updateNews(xml, xml_file); - if (addons_manager) - addons_manager->init(xml, m_force_refresh); - delete xml; - } - - // We can't finish stk (esp. delete the file manager) before - // this part of the code is reached (since otherwise the file - // manager might be access after it was deleted). - CanBeDeleted::setCanBeDeleted(); } // downloadNews // --------------------------------------------------------------------------- @@ -222,57 +82,6 @@ */ void NewsManager::checkRedirect(const XMLNode *xml) { - if (stk_config->m_allow_news_redirects) - { - // NOTE: Before 0.10 there were just two redirect attributes - // "redirect" - addons server (contains /dl/xml/ path) - // "hw-report-server" - hardware report server - - // Redirect for the new addons server - std::string new_addons_server; - if (xml->get("redirect-server-addons", &new_addons_server) == 1 && !new_addons_server.empty()) - { - if (UserConfigParams::logAddons()) - { - Log::info("[Addons]", "Current addons server: '%s'\n [Addons] New addons server: '%s'", - stk_config->m_server_addons.c_str(), new_addons_server.c_str()); - } - stk_config->m_server_addons = new_addons_server; - } - - // Redirect for the API server - std::string new_api_server; - if (xml->get("redirect-server-api", &new_api_server) == 1 && !new_api_server.empty()) - { - if (UserConfigParams::logAddons()) - { - Log::info("[Addons]", "Current API server: '%s'\n [Addons] New API server: '%s'", - stk_config->m_server_api.c_str(), new_api_server.c_str()); - } - stk_config->m_server_api = new_api_server; - } - - // Redirect for the hardware report server - std::string new_hardware_report_server; - if (xml->get("redirect-server-hardware-report", &new_hardware_report_server) == 1 && !new_hardware_report_server.empty()) - { - Log::info("hw report", "Current hardware report server: '%s'\n [hw report] New hardware report server: '%s'", - stk_config->m_server_hardware_report.c_str(), new_hardware_report_server.c_str()); - stk_config->m_server_hardware_report = new_hardware_report_server; - } - } - - // Update menu/game polling interval - float polling; - if (xml->get("menu-polling-interval", &polling)) - { - RequestManager::get()->setMenuPollingInterval(polling); - } - if (xml->get("game-polling-interval", &polling)) - { - RequestManager::get()->setGamePollingInterval(polling); - } - } // checkRedirect // ---------------------------------------------------------------------------- @@ -285,68 +94,6 @@ */ void NewsManager::updateNews(const XMLNode *xml, const std::string &filename) { - - m_all_news_messages = ""; - const core::stringw message_divider=" +++ "; - // This function is also called in case of a reinit, so - // we have to delete existing news messages here first. - m_news.lock(); - m_news.getData().clear(); - m_news.unlock(); - bool error = true; - int frequency=0; - if(xml->get("frequency", &frequency)) - UserConfigParams::m_news_frequency = frequency; - - for(unsigned int i=0; igetNumNodes(); i++) - { - const XMLNode *node = xml->getNode(i); - if(node->getName()!="message") continue; - core::stringw news; - node->get("content", &news); - int id=-1; - node->get("id", &id); - bool important=false; - node->get("important", &important); - - std::string cond; - node->get("condition", &cond); - if(!conditionFulfilled(cond)) - continue; - m_news.lock(); - { - - if(!important) - m_all_news_messages += m_all_news_messages.size()>0 - ? message_divider + news - : news; - else - // Define this if news messages should be removed - // after being shown a certain number of times. - { - NewsMessage n(news, id, important); - m_news.getData().push_back(n); - } - } // m_news.lock() - m_news.unlock(); - - error = false; - } - if(error) - { - // In case of an error (e.g. the file only contains - // an error message from the server), delete the file - // so that it is not read again (and this will force - // a new read on the next start, instead of waiting - // for some time). - file_manager->removeFile(filename); - NewsMessage n(_("Failed to connect to the SuperTuxKart add-ons server."), -1); - m_news.lock(); - m_news.getData().push_back(n); - - m_all_news_messages=""; - m_news.unlock(); - } } // updateNews // ---------------------------------------------------------------------------- @@ -356,10 +103,6 @@ */ void NewsManager::addNewsMessage(const core::stringw &s) { - NewsMessage n(s, -1); - m_news.lock(); - m_news.getData().push_back(n); - m_news.unlock(); } // addNewsMessage // ---------------------------------------------------------------------------- /** Returns the important message with the smallest id that has not been @@ -368,30 +111,7 @@ */ const core::stringw NewsManager::getImportantMessage() { - int index = -1; - m_news.lock(); - for(unsigned int i=0; iUserConfigParams::m_last_important_message_id && - (index == -1 || - m.getMessageId() < m_news.getData()[index].getMessageId() ) ) - { - index = i; - } // if new unshown important message with smaller message id - } core::stringw message(""); - if(index>=0) - { - const NewsMessage &m = m_news.getData()[index]; - message = m.getNews(); - UserConfigParams::m_last_important_message_id = m.getMessageId(); - - } - m_news.unlock(); - return message; } // getImportantMessage @@ -403,35 +123,7 @@ */ const core::stringw NewsManager::getNextNewsMessage() { - // Only display error message in case of a problem. - if(m_error_message.getAtomic().size()>0) - return _(m_error_message.getAtomic().c_str()); - - m_news.lock(); - if(m_all_news_messages.size()>0) - { - // Copy the news message while it is locked. - core::stringw anm = m_all_news_messages; - m_news.unlock(); - return anm; - } - - if(m_news.getData().size()==0) - { - // Lock - m_news.unlock(); - return ""; - } - core::stringw m(""); - { - m_current_news_message++; - if(m_current_news_message >= (int)m_news.getData().size()) - m_current_news_message = 0; - - m = m_news.getData()[m_current_news_message].getNews(); - } - m_news.unlock(); return _(m.c_str()); } // getNextNewsMessage @@ -447,66 +139,6 @@ */ bool NewsManager::conditionFulfilled(const std::string &cond) { - std::vector cond_list; - cond_list = StringUtils::split(cond, ';'); - for(unsigned int i=0; i cond = StringUtils::split(cond_list[i],' '); - if(cond.size()!=3) - { - Log::warn("NewsManager", "Invalid condition '%s' - assumed to " - "be true.", cond_list[i].c_str()); - continue; - } - // Check for stkversion comparisons - // ================================ - if(cond[0]=="stkversion") - { - int news_version = StringUtils::versionToInt(cond[2]); - int stk_version = StringUtils::versionToInt(STK_VERSION); - if(cond[1]=="=") - { - if(stk_version!=news_version) return false; - continue; - } - if(cond[1]=="<") - { - if(stk_version>=news_version) return false; - continue; - } - if(cond[1]==">") - { - if(stk_version<=news_version) return false; - continue; - } - Log::warn("NewsManager", "Invalid comparison in condition '%s' - " - "assumed true.", cond_list[i].c_str()); - } - // Check for addons not installed - // ============================== - else if(cond[1]=="not" && cond[2]=="installed") - { - // The addons_manager cannot be accessed, since it's - // being initialised after the news manager. So a simple - // test is made to see if the directory exists. It is - // necessary to check for karts and tracks separately, - // since it's not possible to know if the addons is - // a kart or a track. - const std::string dir=file_manager->getAddonsDir(); - if(file_manager->fileExists(dir+"/karts/"+cond[0])) - return false; - if(file_manager->fileExists(dir+"/tracks/"+cond[0])) - return false; - continue; - } - else - { - Log::warn("NewsManager", "Invalid condition '%s' - assumed to " - "be true.", cond_list[i].c_str()); - continue; - } - - } // for i < cond_list return true; } // conditionFulfilled --- a/src/states_screens/main_menu_screen.cpp 2020-08-28 10:16:23.000000000 +0200 +++ b/src/states_screens/main_menu_screen.cpp 2023-12-09 23:41:26.040123548 +0100 @@ -19,7 +19,6 @@ #include "states_screens/main_menu_screen.hpp" -#include "addons/news_manager.hpp" #include "challenges/story_mode_timer.hpp" #include "challenges/unlock_manager.hpp" #include "config/player_manager.hpp" @@ -41,7 +40,6 @@ #include "modes/demo_world.hpp" #include "network/network_config.hpp" #include "online/request_manager.hpp" -#include "states_screens/addons_screen.hpp" #include "states_screens/credits.hpp" #include "states_screens/cutscene_general.hpp" #include "states_screens/grand_prix_editor_screen.hpp" @@ -81,9 +79,6 @@ void MainMenuScreen::loadedFromFile() { - LabelWidget* w = getWidget("info_addons"); - w->setScrollSpeed(GUIEngine::getFontHeight() / 2); - RibbonWidget* rw_top = getWidget("menu_toprow"); assert(rw_top != NULL); @@ -148,18 +143,6 @@ input_manager->getDeviceManager()->clearLatestUsedDevice(); #ifndef SERVER_ONLY - if (addons_manager && addons_manager->isLoading()) - { - IconButtonWidget* w = getWidget("addons"); - w->setActive(false); - w->resetAllBadges(); - w->setBadge(LOADING_BADGE); - } - - LabelWidget* w = getWidget("info_addons"); - const core::stringw &news_text = NewsManager::get()->getNextNewsMessage(); - w->setText(news_text, true); - w->update(0.01f); #endif RibbonWidget* r = getWidget("menu_bottomrow"); @@ -185,41 +168,6 @@ void MainMenuScreen::onUpdate(float delta) { #ifndef SERVER_ONLY - NewsManager::get()->joinDownloadThreadIfExit(); - - IconButtonWidget* addons_icon = getWidget("addons"); - if (addons_icon != NULL) - { - if (addons_manager->wasError()) - { - addons_icon->setActive(true); - addons_icon->resetAllBadges(); - addons_icon->setBadge(BAD_BADGE); - } - else if (addons_manager->isLoading() && UserConfigParams::m_internet_status - == Online::RequestManager::IPERM_ALLOWED) - { - // Addons manager is still initialising/downloading. - addons_icon->setActive(false); - addons_icon->resetAllBadges(); - addons_icon->setBadge(LOADING_BADGE); - } - else - { - addons_icon->setActive(true); - addons_icon->resetAllBadges(); - } - // maybe add a new badge when not allowed to access the net - } - - LabelWidget* w = getWidget("info_addons"); - w->update(delta); - if(w->scrolledOff()) - { - const core::stringw &news_text = NewsManager::get()->getNextNewsMessage(); - w->setText(news_text, true); - } - PlayerProfile *player = PlayerManager::getCurrentPlayer(); if (!player) return; @@ -560,31 +508,6 @@ } OnlineScreen::getInstance()->push(); } - else if (selection == "addons") - { - // Don't go to addons if there is no internet, unless some addons are - // already installed (so that you can delete addons without being online). - if(UserConfigParams::m_internet_status!=RequestManager::IPERM_ALLOWED) - { - if (!addons_manager->anyAddonsInstalled()) - { - new MessageDialog(_("You can not download addons without internet access. " - "If you want to download addons, go in the options menu, " - "and check \"Connect to the Internet\".")); - return; - } - else - { - AddonsScreen::getInstance()->push(); - new MessageDialog(_("You can not download addons without internet access. " - "If you want to download addons, go in the options menu, " - "and check \"Connect to the Internet\".\n\n" - "You can however delete already downloaded addons.")); - return; - } - } - AddonsScreen::getInstance()->push(); - } else if (selection == "gpEditor") { GrandPrixEditorScreen::getInstance()->push(); @@ -608,25 +531,6 @@ void MainMenuScreen::onDisabledItemClicked(const std::string& item) { #ifndef SERVER_ONLY - if (item == "addons") - { - if (UserConfigParams::m_internet_status != RequestManager::IPERM_ALLOWED) - { - new MessageDialog( _("The add-ons module is currently disabled in " - "the Options screen") ); - } - else if (addons_manager->wasError()) - { - new MessageDialog( _("Sorry, an error occurred while contacting " - "the add-ons website. Make sure you are " - "connected to the Internet and that " - "SuperTuxKart is not blocked by a firewall")); - } - else if (addons_manager->isLoading()) - { - new MessageDialog( _("Please wait while the add-ons are loading")); - } - } #endif } // onDisabledItemClicked --- a/src/io/file_manager.cpp 1990-01-01 01:00:00.000000000 +0100 +++ b/src/io/file_manager.cpp 2023-12-10 16:28:49.560026623 +0100 @@ -1090,18 +1090,6 @@ "falling back to '.'.", m_addons_dir.c_str()); m_addons_dir = "./"; } - - if (!checkAndCreateDirectory(m_addons_dir + "icons/")) - { - Log::error("FileManager", "Failed to create add-ons icon dir at '%s'.", - (m_addons_dir + "icons/").c_str()); - } - if (!checkAndCreateDirectory(m_addons_dir + "tmp/")) - { - Log::error("FileManager", "Failed to create add-ons tmp dir at '%s'.", - (m_addons_dir + "tmp/").c_str()); - } - } // checkAndCreateAddonsDir // ---------------------------------------------------------------------------- --- a/data/gui/screens/main_menu.stkgui 2020-08-28 10:16:23.000000000 +0200 +++ b/data/gui/screens/main_menu.stkgui 2023-12-10 00:11:36.830139076 +0100 @@ -16,9 +16,6 @@ -