diff --git a/src/addons/addon.cpp b/src/addons/addon.cpp index b9354642e..68d005b56 100644 --- a/src/addons/addon.cpp +++ b/src/addons/addon.cpp @@ -25,6 +25,7 @@ #include "io/file_manager.hpp" #include "io/xml_node.hpp" +#include "utils/constants.hpp" #include "utils/string_utils.hpp" Addon::SortOrder Addon::m_sort_order=Addon::SO_DEFAULT; @@ -98,6 +99,9 @@ Addon::Addon(const XMLNode &xml) xml.get("icon-revision", &m_icon_revision ); xml.get("size", &m_size ); + xml.get("min-include-version",&m_min_include_ver ); + xml.get("max-include-version",&m_max_include_ver ); + }; // Addon(const XML&) // ---------------------------------------------------------------------------- @@ -115,6 +119,8 @@ void Addon::copyInstallData(const Addon &addon) m_designer = addon.m_designer; m_status = addon.m_status; m_date = addon.m_date; + m_min_include_ver=addon.m_min_include_ver; + m_max_include_ver=addon.m_max_include_ver; // Support if the type of an addon changes, e.g. this ie necessary // when we introduce 'arena' as type (formerly arenas had type 'track'). m_type = addon.m_type; @@ -149,3 +155,16 @@ std::string Addon::getDateAsString() const { return Time::toString(m_date); } // getDateAsString + +// ---------------------------------------------------------------------------- +bool Addon::testIncluded(const std::string &min_ver, const std::string &max_ver) +{ + if (min_ver.length() == 0 || max_ver.length() == 0) + return false; + + int current_version = StringUtils::versionToInt(STK_VERSION); + int min_version = StringUtils::versionToInt(min_ver); + int max_version = StringUtils::versionToInt(max_ver); + + return (min_version <= current_version && max_version >= current_version); +} diff --git a/src/addons/addon.hpp b/src/addons/addon.hpp index d3baf5aa4..5114cd5b2 100644 --- a/src/addons/addon.hpp +++ b/src/addons/addon.hpp @@ -92,6 +92,10 @@ private: bool m_installed; /** Compressed size of the addon package. */ int m_size; + /** Minimum version addon is included with. */ + std::string m_min_include_ver; + /** Maximum version addon is included with. */ + std::string m_max_include_ver; /** Type, must be 'kart' or 'track'. */ std::string m_type; @@ -114,6 +118,12 @@ public: /** Returns the name of the addon. */ const core::stringw& getName() const { return m_name; } // ------------------------------------------------------------------------ + /** Returns the minimum version the addon was included with. */ + const std::string& getMinIncludeVer() const {return m_min_include_ver; } + // ------------------------------------------------------------------------ + /** Returns the maximum version the addon was included with. */ + const std::string& getMaxIncludeVer() const {return m_max_include_ver; } + // ------------------------------------------------------------------------ /** Returns the type of the addon. */ const std::string& getType() const { return m_type; } // ------------------------------------------------------------------------ @@ -216,6 +226,10 @@ public: return ""; // Ignore compiler warning } // getTypeDirectory + // ------------------------------------------------------------------------ + /** Returns if the current version is between min and max versions */ + bool testIncluded(const std::string &min_ver, const std::string &max_ver); + // ------------------------------------------------------------------------ /** Returns if a certain status flag is set. */ bool testStatus(AddonStatus n) const {return (m_status & n) !=0; } diff --git a/src/addons/addons_manager.cpp b/src/addons/addons_manager.cpp index 017ce5d9b..55f8d29b0 100644 --- a/src/addons/addons_manager.cpp +++ b/src/addons/addons_manager.cpp @@ -110,6 +110,10 @@ void AddonsManager::initOnline(const XMLNode *xml) 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) diff --git a/src/addons/news_manager.cpp b/src/addons/news_manager.cpp index 94501fda4..ba22f508f 100644 --- a/src/addons/news_manager.cpp +++ b/src/addons/news_manager.cpp @@ -276,8 +276,8 @@ bool NewsManager::conditionFulfilled(const std::string &cond) // ================================ if(cond[0]=="stkversion") { - int news_version = versionToInt(cond[2]); - int stk_version = versionToInt(STK_VERSION); + int news_version = StringUtils::versionToInt(cond[2]); + int stk_version = StringUtils::versionToInt(STK_VERSION); if(cond[1]=="=") { if(stk_version!=news_version) return false; @@ -324,58 +324,6 @@ bool NewsManager::conditionFulfilled(const std::string &cond) return true; } // conditionFulfilled -// ---------------------------------------------------------------------------- -/** Converts a version string (in the form of 'X.Y.Za-rcU' into an - * integer number. - * \param s The version string to convert. - */ -int NewsManager::versionToInt(const std::string &version_string) -{ - // Special case: SVN - if(version_string=="SVN" || version_string=="svn") - // SVN version will be version 99.99.99i-rcJ - return 1000000*99 - + 10000*99 - + 100*99 - + 10* 9 - + 9; - - std::string s=version_string; - // To guarantee that a release gets a higher version number than - // a release candidate, we assign a 'release_candidate' number - // of 9 to versions which are not a RC. We assert that any RC - // is less than 9 to guarantee the ordering. - int release_candidate=9; - if(sscanf(s.substr(s.length()-4, 4).c_str(), "-rc%d", - &release_candidate)==1) - { - s = s.substr(0, s.length()-4); - // Otherwise a RC can get a higher version number than - // the corresponding release! If this should ever get - // triggered, multiply all scaling factors above and - // below by 10, to get two digits for RC numbers. - assert(release_candidate<9); - } - int very_minor=0; - if(s[s.size()-1]>='a' && s[s.size()-1]<='z') - { - very_minor = s[s.size()-1]-'a'+1; - s = s.substr(0, s.size()-1); - } - std::vector l = StringUtils::split(s, '.'); - while(l.size()<3) - l.push_back(0); - int version = 1000000*atoi(l[0].c_str()) - + 10000*atoi(l[1].c_str()) - + 100*atoi(l[2].c_str()) - + 10*very_minor - + release_candidate; - - if(version<=0) - printf("Invalid version string '%s'.\n", s.c_str()); - return version; -} // versionToInt - // ---------------------------------------------------------------------------- /** Reads the information about which message was dislpayed how often from * the user config file. diff --git a/src/addons/news_manager.hpp b/src/addons/news_manager.hpp index 97a42b2a7..89e80f751 100644 --- a/src/addons/news_manager.hpp +++ b/src/addons/news_manager.hpp @@ -83,7 +83,6 @@ private: const std::string &filename); void updateUserConfigFile() const; bool conditionFulfilled(const std::string &cond); - int versionToInt(const std::string &s); void updateMessageDisplayCount(); public: diff --git a/src/utils/string_utils.cpp b/src/utils/string_utils.cpp index 826158978..ba3f813dc 100644 --- a/src/utils/string_utils.cpp +++ b/src/utils/string_utils.cpp @@ -640,6 +640,58 @@ namespace StringUtils return hash; } + + // ------------------------------------------------------------------------ + /** Converts a version string (in the form of 'X.Y.Za-rcU' into an + * integer number. + * \param s The version string to convert. + */ + int versionToInt(const std::string &version_string) + { + // Special case: SVN + if(version_string=="SVN" || version_string=="svn") + // SVN version will be version 99.99.99i-rcJ + return 1000000*99 + + 10000*99 + + 100*99 + + 10* 9 + + 9; + + std::string s=version_string; + // To guarantee that a release gets a higher version number than + // a release candidate, we assign a 'release_candidate' number + // of 9 to versions which are not a RC. We assert that any RC + // is less than 9 to guarantee the ordering. + int release_candidate=9; + if(sscanf(s.substr(s.length()-4, 4).c_str(), "-rc%d", + &release_candidate)==1) + { + s = s.substr(0, s.length()-4); + // Otherwise a RC can get a higher version number than + // the corresponding release! If this should ever get + // triggered, multiply all scaling factors above and + // below by 10, to get two digits for RC numbers. + assert(release_candidate<9); + } + int very_minor=0; + if(s[s.size()-1]>='a' && s[s.size()-1]<='z') + { + very_minor = s[s.size()-1]-'a'+1; + s = s.substr(0, s.size()-1); + } + std::vector l = StringUtils::split(s, '.'); + while(l.size()<3) + l.push_back(0); + int version = 1000000*atoi(l[0].c_str()) + + 10000*atoi(l[1].c_str()) + + 100*atoi(l[2].c_str()) + + 10*very_minor + + release_candidate; + + if(version<=0) + printf("Invalid version string '%s'.\n", s.c_str()); + return version; + } // versionToInt } // namespace StringUtils diff --git a/src/utils/string_utils.hpp b/src/utils/string_utils.hpp index 2bcacf8f8..a60547089 100644 --- a/src/utils/string_utils.hpp +++ b/src/utils/string_utils.hpp @@ -27,6 +27,7 @@ namespace StringUtils { + int versionToInt(const std::string &s); bool hasSuffix(const std::string& lhs, const std::string rhs); bool startsWith(const std::string& str, const std::string& prefix); @@ -365,7 +366,6 @@ namespace StringUtils /** Compute a simple hash of a string */ unsigned int simpleHash(const char* input); - } // namespace StringUtils #endif