//============================================================================== void AddonManager::setAddonStates(const State& newStates) { const StateMap& stateMap = newStates.getMap(); AddonMap::iterator addons = mAddonMap.begin(); StateMap::const_iterator states = stateMap.begin(); while( mAddonMap.end() != addons && stateMap.end() != states ) { if( addons->first == states->first ) { Addon* addon = addons->second.get(); if(addon && states->second) addon->setAddonState(*states->second); ++addons; ++states; } else if( addons->first < states->first ) { ++addons; } else { ++states; } } }
//============================================================================== void AddonManager::setAddonProperties(const Properties& newProperties) { const PropertiesMap& propertiesMap = newProperties.getMap(); AddonMap::iterator addons = mAddonMap.begin(); PropertiesMap::const_iterator props = propertiesMap.begin(); while( mAddonMap.end() != addons && propertiesMap.end() != props ) { if( addons->first == props->first ) { Addon* addon = addons->second.get(); if(addon) addon->setAddonProperties(*props->second); ++addons; ++props; } else if( addons->first < props->first ) { ++addons; } else { ++props; } } }
/** Removes all files froma login. * \param addon The addon to be removed. * \return True if uninstallation was successful. */ bool AddonsManager::uninstall(const Addon &addon) { std::cout << "[addons] Uninstalling <" << core::stringc(addon.getName()).c_str() << ">\n"; // 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()); if(addon.getType()=="kart") { kart_properties_manager->removeKart(addon.getId()); } else if(addon.getType()=="track" || addon.getType()=="arena") { track_manager->removeTrack(addon.getId()); } } saveInstalled(); return !error; } // uninstall
void AddonMenu::toggle_addon(const Addon& addon) { if(addon.is_enabled()) { m_addon_manager.disable_addon(addon.get_id()); } else { m_addon_manager.enable_addon(addon.get_id()); } if(addon.get_type() == Addon::LANGUAGEPACK) { std::unique_ptr<Dialog> dialog(new Dialog); dialog->set_text(_("Please restart SuperTux\nfor these changes to take effect.")); dialog->add_cancel_button(_("OK")); MenuManager::instance().set_dialog(std::move(dialog)); } }
/** Compares two addons according to the sort order currently defined. * \param a The addon to compare this addon to. */ bool operator<(const Addon &a) const { switch(m_sort_order) { case SO_DEFAULT: if(testStatus(AS_FEATURED) && !a.testStatus(AS_FEATURED)) return true; if(!testStatus(AS_FEATURED) && a.testStatus(AS_FEATURED)) return false; // Otherwise fall through to name comparison! case SO_NAME: // m_id is the lower case name return m_id < a.m_id; break; case SO_DATE: return m_date > a.m_date; break; } // switch // Fix compiler warning. return true; } // operator<
/** Removes all files froma login. * \param addon The addon to be removed. * \return True if uninstallation was successful. */ bool AddonsManager::uninstall(const Addon &addon) { std::cout << "[addons] Uninstalling <" << core::stringc(addon.getName()).c_str() << ">\n"; // 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 = !file_manager->removeDirectory(addon.getDataDir()); if(addon.getType()=="kart") { kart_properties_manager->removeKart(addon.getId()); } else if(addon.getType()=="track" || addon.getType()=="arena") { track_manager->removeTrack(addon.getId()); } saveInstalled(); return !error; } // uninstall
void AddonMenu::install_addon(const Addon& addon) { auto addon_id = addon.get_id(); TransferStatusPtr status = m_addon_manager.request_install_addon(addon_id); std::unique_ptr<DownloadDialog> dialog(new DownloadDialog(status, false, m_auto_install_langpack)); dialog->set_title(str(boost::format( _("Downloading %s") ) % generate_menu_item_text(addon))); status->then([this, addon_id](bool success) { if (success) { try { m_addon_manager.enable_addon(addon_id); if(m_auto_install_langpack) { MenuManager::instance().set_dialog({}); MenuManager::instance().clear_menu_stack(); return; } } catch(const std::exception& err) { log_warning << "Enabling add-on failed: " << err.what() << std::endl; } refresh(); } else { if(m_auto_install_langpack) { MenuManager::instance().set_dialog({}); MenuManager::instance().clear_menu_stack(); } } }); MenuManager::instance().set_dialog(std::move(dialog)); }
/** Installs or updates (i.e. = install on top of an existing installation) an * addon. It checks for the directories and then unzips the file (which must * already have been downloaded). * \param addon Addon data for the addon to install. * \return true if installation was successful. */ bool AddonsManager::install(const Addon &addon) { bool success=true; const std::string &id = addon.getId(); file_manager->checkAndCreateDirForAddons(id, addon.getTypeDirectory()); //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(); success = extract_zip(from, to); if (!success) { // TODO: show a message in the interface std::cerr << "[addons] Failed to unzip '" << from << "' to '" << to << "'\n"; std::cerr << "[addons] Zip file will not be removed.\n"; return false; } if(!file_manager->removeFile(from)) { std::cerr << "[addons] Problems removing temporary file '" << from << "'.\n"; } 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) { fprintf(stderr, "[AddonsManager] ERROR: Cannot load track <%s> : %s\n", addon.getDataDir().c_str(), e.what()); } } saveInstalled(); return true; } // install
bool AddonMenu::addon_visible(const Addon& addon) const { bool is_langpack = (addon.get_type() == Addon::LANGUAGEPACK); return (m_language_pack_mode && is_langpack) || (!m_language_pack_mode && !is_langpack); }