From 5994371145dd6b914700ea3db3721ff25ac856ee Mon Sep 17 00:00:00 2001 From: KotIsOff Date: Sat, 23 Aug 2025 01:33:06 +0300 Subject: [PATCH 01/13] =?UTF-8?q?=D0=9F=D1=80=D0=BE=D0=B2=D0=B5=D1=80?= =?UTF-8?q?=D0=BA=D0=B0=20=D0=B2=D0=B5=D1=80=D1=81=D0=B8=D0=B9=20=D0=B7?= =?UTF-8?q?=D0=B0=D0=B2=D0=B8=D1=81=D0=B8=D0=BC=D0=BE=D1=81=D1=82=D0=B5?= =?UTF-8?q?=D0=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Добавил проверку версий установленных зависимостей паков. --- res/layouts/pages/content.xml.lua | 13 +++++++++++-- res/texts/en_US.txt | 1 + res/texts/ru_RU.txt | 1 + src/content/ContentPack.cpp | 10 +++++++++- src/content/ContentPack.hpp | 1 + src/content/PacksManager.cpp | 8 ++++++++ src/logic/scripting/lua/libs/libpack.cpp | 3 ++- 7 files changed, 33 insertions(+), 4 deletions(-) diff --git a/res/layouts/pages/content.xml.lua b/res/layouts/pages/content.xml.lua index 3f1903f3..50288d17 100644 --- a/res/layouts/pages/content.xml.lua +++ b/res/layouts/pages/content.xml.lua @@ -181,8 +181,9 @@ function check_dependencies(packinfo) return end for i,dep in ipairs(packinfo.dependencies) do - local depid = dep:sub(2,-1) - if dep:sub(1,1) == '!' then + local depid, depver = unpack(string.split(dep:sub(2,-1), "@")) + + if dep:sub(1,1) == '!' then if not table.has(packs_all, depid) then return string.format( "%s (%s)", gui.str("error.dependency-not-found"), depid @@ -192,6 +193,14 @@ function check_dependencies(packinfo) table.insert(required, depid) end end + + local dep_pack = pack.get_info(depid); + + if depver ~= "*" or depver ~= dep_pack.version then + return string.format("%s (%s@%s != %s)", gui.str("error.dependency-version-not-met"), depid, dep_pack.version, depver); + end + + debug.print(packinfo); end return end diff --git a/res/texts/en_US.txt b/res/texts/en_US.txt index 57a6cb6b..267566cd 100644 --- a/res/texts/en_US.txt +++ b/res/texts/en_US.txt @@ -7,6 +7,7 @@ world.convert-block-layouts=Blocks fields have changes! Convert world files? pack.remove-confirm=Do you want to erase all pack(s) content from the world forever? error.pack-not-found=Could not to find pack error.dependency-not-found=Dependency pack is not found +error.dependency-version-not-met=Dependency pack version is not met. world.delete-confirm=Do you want to delete world forever? world.generators.default=Default world.generators.flat=Flat diff --git a/res/texts/ru_RU.txt b/res/texts/ru_RU.txt index d2d7c63e..f7f11a36 100644 --- a/res/texts/ru_RU.txt +++ b/res/texts/ru_RU.txt @@ -32,6 +32,7 @@ devtools.output=Вывод error.pack-not-found=Не удалось найти пакет error.dependency-not-found=Используемая зависимость не найдена +error.dependency-version-not-met=Версия зависимости не соответствует необходимой pack.remove-confirm=Удалить весь поставляемый паком/паками контент из мира (безвозвратно)? # Подсказки diff --git a/src/content/ContentPack.cpp b/src/content/ContentPack.cpp index ac8c8d59..8c3ea541 100644 --- a/src/content/ContentPack.cpp +++ b/src/content/ContentPack.cpp @@ -132,7 +132,15 @@ ContentPack ContentPack::read(const io::path& folder) { level = DependencyLevel::weak; break; } - pack.dependencies.push_back({level, depName}); + + std::string depVersion = "*"; + size_t version_pos = depName.rfind("@"); + if (version_pos != std::string::npos){ + depVersion = depName.substr(version_pos + 1); + depName = depName.substr(0, version_pos); + } + + pack.dependencies.push_back({level, depName, depVersion}); } } diff --git a/src/content/ContentPack.hpp b/src/content/ContentPack.hpp index f4e44801..f8bc760c 100644 --- a/src/content/ContentPack.hpp +++ b/src/content/ContentPack.hpp @@ -35,6 +35,7 @@ enum class DependencyLevel { struct DependencyPack { DependencyLevel level; std::string id; + std::string verison; }; struct ContentPackStats { diff --git a/src/content/PacksManager.cpp b/src/content/PacksManager.cpp index 0e9925c8..76cc54d7 100644 --- a/src/content/PacksManager.cpp +++ b/src/content/PacksManager.cpp @@ -105,6 +105,14 @@ static bool resolve_dependencies( // added continue; } + if (dep.verison == "*" || dep.verison == found->second.version){ + // dependency pack version mets the required one + continue; + } else { + throw contentpack_error( + dep.id, io::path(), "does not meet required version '" + dep.verison +"' of '" + pack->id + "'" + ); + } if (!util::contains(allNames, dep.id) && dep.level != DependencyLevel::weak) { diff --git a/src/logic/scripting/lua/libs/libpack.cpp b/src/logic/scripting/lua/libs/libpack.cpp index adc45096..be38fcb2 100644 --- a/src/logic/scripting/lua/libs/libpack.cpp +++ b/src/logic/scripting/lua/libs/libpack.cpp @@ -114,7 +114,8 @@ static int l_pack_get_info( default: throw std::runtime_error(""); } - lua::pushfstring(L, "%s%s", prefix.c_str(), dpack.id.c_str()); + + lua::pushfstring(L, "%s%s@%s", prefix.c_str(), dpack.id.c_str(), dpack.verison.c_str()); lua::rawseti(L, i + 1); } lua::setfield(L, "dependencies"); From bbbd6c44014f71f6dd0306e9395bcdf3e2ac77b9 Mon Sep 17 00:00:00 2001 From: KotIsOff <71443736+kotisoff@users.noreply.github.com> Date: Sat, 23 Aug 2025 01:34:50 +0300 Subject: [PATCH 02/13] fixed comment typo --- src/content/PacksManager.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/content/PacksManager.cpp b/src/content/PacksManager.cpp index 76cc54d7..c898d590 100644 --- a/src/content/PacksManager.cpp +++ b/src/content/PacksManager.cpp @@ -106,7 +106,7 @@ static bool resolve_dependencies( continue; } if (dep.verison == "*" || dep.verison == found->second.version){ - // dependency pack version mets the required one + // dependency pack version meets the required one continue; } else { throw contentpack_error( From 3131068ad8aa64202e64d0766ed9efde753ac19a Mon Sep 17 00:00:00 2001 From: KotIsOff Date: Sat, 23 Aug 2025 01:42:13 +0300 Subject: [PATCH 03/13] removed print --- res/layouts/pages/content.xml.lua | 1 - 1 file changed, 1 deletion(-) diff --git a/res/layouts/pages/content.xml.lua b/res/layouts/pages/content.xml.lua index 50288d17..1c49f72d 100644 --- a/res/layouts/pages/content.xml.lua +++ b/res/layouts/pages/content.xml.lua @@ -200,7 +200,6 @@ function check_dependencies(packinfo) return string.format("%s (%s@%s != %s)", gui.str("error.dependency-version-not-met"), depid, dep_pack.version, depver); end - debug.print(packinfo); end return end From 5d91d94433e7b6b0158ca6f10c9425a7ba564ae0 Mon Sep 17 00:00:00 2001 From: KotIsOff Date: Sat, 23 Aug 2025 01:46:13 +0300 Subject: [PATCH 04/13] moved depver lua code in dep level condition --- res/layouts/pages/content.xml.lua | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/res/layouts/pages/content.xml.lua b/res/layouts/pages/content.xml.lua index 1c49f72d..e57cea5f 100644 --- a/res/layouts/pages/content.xml.lua +++ b/res/layouts/pages/content.xml.lua @@ -189,17 +189,16 @@ function check_dependencies(packinfo) "%s (%s)", gui.str("error.dependency-not-found"), depid ) end + + local dep_pack = pack.get_info(depid); + if depver ~= "*" or depver ~= dep_pack.version then + return string.format("%s (%s@%s != %s)", gui.str("error.dependency-version-not-met"), depid, dep_pack.version, depver); + end + if table.has(packs_installed, packinfo.id) then table.insert(required, depid) end end - - local dep_pack = pack.get_info(depid); - - if depver ~= "*" or depver ~= dep_pack.version then - return string.format("%s (%s@%s != %s)", gui.str("error.dependency-version-not-met"), depid, dep_pack.version, depver); - end - end return end From 74238d08445e532891f62f503ed1ff580bd22084 Mon Sep 17 00:00:00 2001 From: KotIsOff Date: Sat, 23 Aug 2025 02:00:07 +0300 Subject: [PATCH 05/13] fixed condition double yat --- res/layouts/pages/content.xml.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/res/layouts/pages/content.xml.lua b/res/layouts/pages/content.xml.lua index e57cea5f..8ce1cebc 100644 --- a/res/layouts/pages/content.xml.lua +++ b/res/layouts/pages/content.xml.lua @@ -191,10 +191,10 @@ function check_dependencies(packinfo) end local dep_pack = pack.get_info(depid); - if depver ~= "*" or depver ~= dep_pack.version then + if depver ~= "*" and depver ~= dep_pack.version then return string.format("%s (%s@%s != %s)", gui.str("error.dependency-version-not-met"), depid, dep_pack.version, depver); end - + if table.has(packs_installed, packinfo.id) then table.insert(required, depid) end From f91b734aeaee5ed490133db26c5f1fd211fec5ef Mon Sep 17 00:00:00 2001 From: KotIsOff Date: Sat, 23 Aug 2025 16:43:42 +0300 Subject: [PATCH 06/13] docs for dependency version --- doc/en/content-packs.md | 5 +++++ doc/ru/content-packs.md | 7 ++++++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/doc/en/content-packs.md b/doc/en/content-packs.md index c32d1b03..b7a78938 100644 --- a/doc/en/content-packs.md +++ b/doc/en/content-packs.md @@ -30,6 +30,11 @@ If prefix is not specified, '!' level will be used. Example: '~randutil' - weak dependency 'randutil'. +Dependency version is indicated by postfix after '@' symbol. +If postfix is not specified, '*' (any) version will be used. + +Example: 'randutil@1.0' - dependency 'randutil' which requires version 1.0. + Example: ```json { diff --git a/doc/ru/content-packs.md b/doc/ru/content-packs.md index 77a78636..716e25ef 100644 --- a/doc/ru/content-packs.md +++ b/doc/ru/content-packs.md @@ -30,7 +30,12 @@ - '~' - слабая зависимость Отсутствие префикса интерпретируется как '!'. -Пример: '~randutil' - слабая зависимость 'randutil'. +Пример: '~randutil@1.0' - слабая зависимость 'randutil'. + +Версии зависимостей указываются с помощью постфикса через '@'. +Отсутствие версии зависимости интерпретируется как '*', т.е. любая версия. + +Пример: 'randutil@1.0' - зависимость 'randutil' версии 1.0. Пример: ```json From 45bc4037ecc7fa7d39d0c36ac7d642a83670a47d Mon Sep 17 00:00:00 2001 From: KotIsOff Date: Sat, 23 Aug 2025 16:46:31 +0300 Subject: [PATCH 07/13] fix: escaping for '*' symbol --- doc/en/content-packs.md | 2 +- doc/ru/content-packs.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/en/content-packs.md b/doc/en/content-packs.md index b7a78938..53e095b9 100644 --- a/doc/en/content-packs.md +++ b/doc/en/content-packs.md @@ -31,7 +31,7 @@ If prefix is not specified, '!' level will be used. Example: '~randutil' - weak dependency 'randutil'. Dependency version is indicated by postfix after '@' symbol. -If postfix is not specified, '*' (any) version will be used. +If postfix is not specified, '\*' (any) version will be used. Example: 'randutil@1.0' - dependency 'randutil' which requires version 1.0. diff --git a/doc/ru/content-packs.md b/doc/ru/content-packs.md index 716e25ef..34ccaab7 100644 --- a/doc/ru/content-packs.md +++ b/doc/ru/content-packs.md @@ -33,7 +33,7 @@ Пример: '~randutil@1.0' - слабая зависимость 'randutil'. Версии зависимостей указываются с помощью постфикса через '@'. -Отсутствие версии зависимости интерпретируется как '*', т.е. любая версия. +Отсутствие версии зависимости интерпретируется как '\*', т.е. любая версия. Пример: 'randutil@1.0' - зависимость 'randutil' версии 1.0. From 5b18639d94d6ef304bddfd73cc8b6211bb4d09c8 Mon Sep 17 00:00:00 2001 From: KotIsOff Date: Mon, 25 Aug 2025 21:21:05 +0300 Subject: [PATCH 08/13] slightly corrected docs --- doc/en/content-packs.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/en/content-packs.md b/doc/en/content-packs.md index 53e095b9..10c70afb 100644 --- a/doc/en/content-packs.md +++ b/doc/en/content-packs.md @@ -30,8 +30,8 @@ If prefix is not specified, '!' level will be used. Example: '~randutil' - weak dependency 'randutil'. -Dependency version is indicated by postfix after '@' symbol. -If postfix is not specified, '\*' (any) version will be used. +Dependency version is indicated after '@' symbol. +If version is not specified, '\*' (any) version will be used. Example: 'randutil@1.0' - dependency 'randutil' which requires version 1.0. From 7aa4c33721ab9c0238b8caf49f7305e9d1052ac2 Mon Sep 17 00:00:00 2001 From: KotIsOff Date: Tue, 26 Aug 2025 01:52:26 +0300 Subject: [PATCH 09/13] dependency version operators MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit а также сделал и вынес Version в ContentPackVersion ну и подправил луа скрипты. требуются тесты --- res/layouts/pages/content.xml.lua | 84 +++++++++++++++++++++++- src/content/ContentPack.cpp | 41 ++++++++++-- src/content/ContentPack.hpp | 10 ++- src/content/ContentPackVersion.cpp | 66 +++++++++++++++++++ src/content/ContentPackVersion.hpp | 51 ++++++++++++++ src/content/PacksManager.cpp | 14 +++- src/logic/scripting/lua/libs/libpack.cpp | 2 +- 7 files changed, 255 insertions(+), 13 deletions(-) create mode 100644 src/content/ContentPackVersion.cpp create mode 100644 src/content/ContentPackVersion.hpp diff --git a/res/layouts/pages/content.xml.lua b/res/layouts/pages/content.xml.lua index 8ce1cebc..1fe5c160 100644 --- a/res/layouts/pages/content.xml.lua +++ b/res/layouts/pages/content.xml.lua @@ -176,6 +176,81 @@ function place_pack(panel, packinfo, callback, position_func) end end +local Version = {}; + +function Version.matches_pattern(version) + for _, letter in string.gmatch(version, "%s+") do + if type(letter) ~= "number" or letter ~= "." then + return false; + end + + local t = string.split(version, "."); + + return #t == 2 or #t == 3; + end +end + +function Version.__equal(ver1, ver2) + return ver1[1] == ver2[1] and ver1[2] == ver2[2] and ver1[3] == ver2[3]; +end + +function Version.__more(ver1, ver2) + if ver1[1] ~= ver2[1] then return ver1[1] > ver2[1] end; + if ver1[2] ~= ver2[2] then return ver1[2] > ver2[2] end; + return ver1[3] > ver2[3]; +end + +function Version.__less(ver1, ver2) + return Version.__more(ver2, ver1); +end + +function Version.__more_or_equal(ver1, ver2) + return not Version.__less(ver1, ver2); +end + +function Version.__less_or_equal(ver1, ver2) + return not Version.__more(ver1, ver2); +end + +function Version.compare(op, ver1, ver2) + ver1 = string.split(ver1, "."); + ver2 = string.split(ver2, "."); + + if op == "=" then return Version.__equal(ver1, ver2); + elseif op == ">" then return Version.__more(ver1, ver2); + elseif op == "<" then return Version.__less(ver1, ver2); + elseif op == ">=" then return Version.__more_or_equal(ver1, ver2); + elseif op == "<=" then return Version.__less_or_equal(ver1, ver2); + else return false; end +end + +function Version.parse(version) + local op = string.sub(version, 1, 2); + if op == ">=" or op == "=>" then + return ">=", string.sub(version, #op + 1); + elseif op == "<=" or op == "=<" then + return "<=", string.sub(version, #op + 1); + end + + op = string.sub(version, 1, 1); + if op == ">" or op == "<" then + return op, string.sub(version, #op + 1); + end + + return "=", version; +end + +local function compare_version(dependent_version, actual_version) + if Version.matches_pattern(dependent_version) and Version.matches_pattern(actual_version) then + local op, dep_ver = Version.parse_version(dependent_version); + Version.compare(op, dep_ver, actual_version); + elseif dependent_version == "*" or dependent_version == actual_version then + return true; + else + return false; + end +end + function check_dependencies(packinfo) if packinfo.dependencies == nil then return @@ -190,9 +265,14 @@ function check_dependencies(packinfo) ) end + local dep_pack = pack.get_info(depid); - if depver ~= "*" and depver ~= dep_pack.version then - return string.format("%s (%s@%s != %s)", gui.str("error.dependency-version-not-met"), depid, dep_pack.version, depver); + + if not compare_version(depver, dep_pack.version) then + local op, ver = Version.parse(depver); + + print(string.format("%s: %s !%s %s (%s)", gui.str("error.dependency-version-not-met"), dep_pack.version, op, ver, depid)); + return string.format("%s: %s != %s (%s)", gui.str("error.dependency-version-not-met"), dep_pack.version, ver, depid); end if table.has(packs_installed, packinfo.id) then diff --git a/src/content/ContentPack.cpp b/src/content/ContentPack.cpp index 8c3ea541..49d7ee1f 100644 --- a/src/content/ContentPack.cpp +++ b/src/content/ContentPack.cpp @@ -133,14 +133,43 @@ ContentPack ContentPack::read(const io::path& folder) { break; } - std::string depVersion = "*"; - size_t version_pos = depName.rfind("@"); - if (version_pos != std::string::npos){ - depVersion = depName.substr(version_pos + 1); - depName = depName.substr(0, version_pos); + std::string depVer = "*"; + std::string depVerOperator = "="; + + size_t versionPos = depName.rfind("@"); + if (versionPos != std::string::npos) { + depVer = depName.substr(versionPos + 1); + depName = depName.substr(0, versionPos); + + if (depVer.size() >= 2) { + std::string op = depVer.substr(0, 2); + std::uint8_t op_size = 0; + + // Two symbol operators + if (op == ">=" || op == "=>" || op == "<=" || op == "=<") { + op_size = 2; + depVerOperator = op; + } + + // One symbol operators + else { + op = depVer.substr(0, 1); + + if (op == ">" || op == "<") { + op_size = 1; + depVerOperator = op; + } + } + + depVer = depVer.substr(op_size); + } else { + if (depVer == ">" || depVer == "<"){ + depVer = "*"; + } + } } - pack.dependencies.push_back({level, depName, depVersion}); + pack.dependencies.push_back({level, depName, depVer, depVerOperator}); } } diff --git a/src/content/ContentPack.hpp b/src/content/ContentPack.hpp index f8bc760c..0069553a 100644 --- a/src/content/ContentPack.hpp +++ b/src/content/ContentPack.hpp @@ -20,11 +20,16 @@ public: io::path folder, const std::string& message ); - + std::string getPackId() const; io::path getFolder() const; }; +enum class DependencyVersionOperator { + equal, more, less, + more_or_equal, less_or_equal +}; + enum class DependencyLevel { required, // dependency must be installed optional, // dependency will be installed if found @@ -35,7 +40,8 @@ enum class DependencyLevel { struct DependencyPack { DependencyLevel level; std::string id; - std::string verison; + std::string version; + std::string op; }; struct ContentPackStats { diff --git a/src/content/ContentPackVersion.cpp b/src/content/ContentPackVersion.cpp new file mode 100644 index 00000000..b8a0564b --- /dev/null +++ b/src/content/ContentPackVersion.cpp @@ -0,0 +1,66 @@ +#include "ContentPackVersion.hpp" + +#include +#include +#include + +#include "coders/commons.hpp" + +Version::Version(const std::string& version) { + major = 0; + minor = 0; + patch = 0; + + std::vector parts; + + std::stringstream ss(version); + std::string part; + while (std::getline(ss, part, '.')) { + if (!part.empty()) { + parts.push_back(std::stoi(part)); + } + } + + if (parts.size() > 0) major = parts[0]; + if (parts.size() > 1) minor = parts[1]; + if (parts.size() > 2) patch = parts[2]; +} + +DependencyVersionOperator Version::string_to_operator(const std::string& op) { + if (op == "=") + return DependencyVersionOperator::equal; + else if (op == ">") + return DependencyVersionOperator::more; + else if (op == "<") + return DependencyVersionOperator::less; + else if (op == ">=" || op == "=>") + return DependencyVersionOperator::more_or_equal; + else if (op == "<=" || op == "=<") + return DependencyVersionOperator::less_or_equal; + else return DependencyVersionOperator::equal; +} + +bool isNumber(const std::string& s) { + return !s.empty() && std::all_of(s.begin(), s.end(), ::is_digit); +} + +bool Version::matches_pattern(const std::string& version) { + for (char c : version) { + if (!isdigit(c) && c != '.') { + return false; + } + } + + std::stringstream ss(version); + + std::vector parts; + std::string part; + while (std::getline(ss, part, '.')) { + if (part.empty()) return false; + if (!isNumber(part)) return false; + + parts.push_back(part); + } + + return parts.size() == 2 || parts.size() == 3; +} \ No newline at end of file diff --git a/src/content/ContentPackVersion.hpp b/src/content/ContentPackVersion.hpp new file mode 100644 index 00000000..ef298b9e --- /dev/null +++ b/src/content/ContentPackVersion.hpp @@ -0,0 +1,51 @@ +#include + +#include "content/ContentPack.hpp" + +class Version { + public: + int major; + int minor; + int patch; + + Version(const std::string& version); + + bool operator==(const Version& other) const { + return major == other.major && minor == other.minor && patch == other.patch; + } + + bool operator<(const Version& other) const { + if (major != other.major) return major < other.major; + if (minor != other.minor) return minor < other.minor; + return patch < other.patch; + } + + + bool operator>(const Version& other) const { + return other < *this; + } + + bool operator>=(const Version& other) const { + return !(*this < other); + } + + bool operator<=(const Version& other) const { + return !(*this > other); + } + + bool process_operator(const std::string& op, const Version& other) const { + auto dep_op = Version::string_to_operator(op); + + switch(dep_op) { + case DependencyVersionOperator::equal: return *this == other; + case DependencyVersionOperator::more: return *this > other; + case DependencyVersionOperator::less: return *this < other; + case DependencyVersionOperator::less_or_equal: return *this <= other; + case DependencyVersionOperator::more_or_equal: return *this >= other; + default: return false; + } + } + + static DependencyVersionOperator string_to_operator(const std::string& op); + static bool matches_pattern(const std::string& version); +}; \ No newline at end of file diff --git a/src/content/PacksManager.cpp b/src/content/PacksManager.cpp index c898d590..1e2ed49f 100644 --- a/src/content/PacksManager.cpp +++ b/src/content/PacksManager.cpp @@ -3,6 +3,7 @@ #include #include +#include "ContentPackVersion.hpp" #include "util/listutil.hpp" PacksManager::PacksManager() = default; @@ -105,12 +106,21 @@ static bool resolve_dependencies( // added continue; } - if (dep.verison == "*" || dep.verison == found->second.version){ + + auto dep_pack = found -> second; + + if (Version::matches_pattern(dep.version) && Version::matches_pattern(dep_pack.version) + && Version(dep_pack.version) + .process_operator(dep.op, Version(dep.version)) + ) { // dependency pack version meets the required one continue; + } else if (dep.version == "*" || dep.version == dep_pack.version){ + // fallback: dependency pack version also meets required one + continue; } else { throw contentpack_error( - dep.id, io::path(), "does not meet required version '" + dep.verison +"' of '" + pack->id + "'" + dep.id, io::path(), "does not meet required version '" + dep.op + dep.version +"' of '" + pack->id + "'" ); } diff --git a/src/logic/scripting/lua/libs/libpack.cpp b/src/logic/scripting/lua/libs/libpack.cpp index be38fcb2..fc5e2252 100644 --- a/src/logic/scripting/lua/libs/libpack.cpp +++ b/src/logic/scripting/lua/libs/libpack.cpp @@ -115,7 +115,7 @@ static int l_pack_get_info( throw std::runtime_error(""); } - lua::pushfstring(L, "%s%s@%s", prefix.c_str(), dpack.id.c_str(), dpack.verison.c_str()); + lua::pushfstring(L, "%s%s@%s%s", prefix.c_str(), dpack.id.c_str(), dpack.op.c_str(), dpack.version.c_str()); lua::rawseti(L, i + 1); } lua::setfield(L, "dependencies"); From 01b3229aac8a07be7eadf85f8997d00c9a422930 Mon Sep 17 00:00:00 2001 From: KotIsOff Date: Tue, 26 Aug 2025 01:59:00 +0300 Subject: [PATCH 10/13] fix: match wrong magic symbol --- res/layouts/pages/content.xml.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/res/layouts/pages/content.xml.lua b/res/layouts/pages/content.xml.lua index 1fe5c160..8ed37630 100644 --- a/res/layouts/pages/content.xml.lua +++ b/res/layouts/pages/content.xml.lua @@ -179,7 +179,7 @@ end local Version = {}; function Version.matches_pattern(version) - for _, letter in string.gmatch(version, "%s+") do + for _, letter in string.gmatch(version, "%.+") do if type(letter) ~= "number" or letter ~= "." then return false; end From a0c66d56d89aeabb2462b7e732b59f92e79f2464 Mon Sep 17 00:00:00 2001 From: KotIsOff Date: Tue, 26 Aug 2025 02:10:16 +0300 Subject: [PATCH 11/13] docs for operators --- doc/en/content-packs.md | 4 ++-- doc/ru/content-packs.md | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/doc/en/content-packs.md b/doc/en/content-packs.md index 10c70afb..a41f95f9 100644 --- a/doc/en/content-packs.md +++ b/doc/en/content-packs.md @@ -30,10 +30,10 @@ If prefix is not specified, '!' level will be used. Example: '~randutil' - weak dependency 'randutil'. -Dependency version is indicated after '@' symbol. +Dependency version is indicated after '@' symbol and have operators to restrict acceptable versions. If version is not specified, '\*' (any) version will be used. -Example: 'randutil@1.0' - dependency 'randutil' which requires version 1.0. +Example: 'randutil@>=1.0' - dependency 'randutil' which requires version 1.0 or newer. Example: ```json diff --git a/doc/ru/content-packs.md b/doc/ru/content-packs.md index 34ccaab7..4245555f 100644 --- a/doc/ru/content-packs.md +++ b/doc/ru/content-packs.md @@ -30,12 +30,12 @@ - '~' - слабая зависимость Отсутствие префикса интерпретируется как '!'. -Пример: '~randutil@1.0' - слабая зависимость 'randutil'. +Пример: '~randutil' - слабая зависимость 'randutil'. -Версии зависимостей указываются с помощью постфикса через '@'. +Версии зависимостей указываются после '@' и имеют операторы для ограничения допустимых версий. Отсутствие версии зависимости интерпретируется как '\*', т.е. любая версия. -Пример: 'randutil@1.0' - зависимость 'randutil' версии 1.0. +Пример: 'randutil@>=1.0' - зависимость 'randutil' версии 1.0 и старше. Пример: ```json From f44747587f95b872758de8c5e64a389a3b68d5a2 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Sun, 14 Sep 2025 12:57:19 +0300 Subject: [PATCH 12/13] format ContentPackVersion --- src/content/ContentPackVersion.cpp | 5 +- src/content/ContentPackVersion.hpp | 92 ++++++++++++++++-------------- 2 files changed, 52 insertions(+), 45 deletions(-) diff --git a/src/content/ContentPackVersion.cpp b/src/content/ContentPackVersion.cpp index b8a0564b..d8d46dce 100644 --- a/src/content/ContentPackVersion.cpp +++ b/src/content/ContentPackVersion.cpp @@ -37,7 +37,8 @@ DependencyVersionOperator Version::string_to_operator(const std::string& op) { return DependencyVersionOperator::more_or_equal; else if (op == "<=" || op == "=<") return DependencyVersionOperator::less_or_equal; - else return DependencyVersionOperator::equal; + else + return DependencyVersionOperator::equal; } bool isNumber(const std::string& s) { @@ -63,4 +64,4 @@ bool Version::matches_pattern(const std::string& version) { } return parts.size() == 2 || parts.size() == 3; -} \ No newline at end of file +} diff --git a/src/content/ContentPackVersion.hpp b/src/content/ContentPackVersion.hpp index ef298b9e..5d30c1e7 100644 --- a/src/content/ContentPackVersion.hpp +++ b/src/content/ContentPackVersion.hpp @@ -3,49 +3,55 @@ #include "content/ContentPack.hpp" class Version { - public: - int major; - int minor; - int patch; +public: + int major; + int minor; + int patch; - Version(const std::string& version); - - bool operator==(const Version& other) const { - return major == other.major && minor == other.minor && patch == other.patch; + Version(const std::string& version); + + bool operator==(const Version& other) const { + return major == other.major && minor == other.minor && + patch == other.patch; + } + + bool operator<(const Version& other) const { + if (major != other.major) return major < other.major; + if (minor != other.minor) return minor < other.minor; + return patch < other.patch; + } + + bool operator>(const Version& other) const { + return other < *this; + } + + bool operator>=(const Version& other) const { + return !(*this < other); + } + + bool operator<=(const Version& other) const { + return !(*this > other); + } + + bool process_operator(const std::string& op, const Version& other) const { + auto dep_op = Version::string_to_operator(op); + + switch (dep_op) { + case DependencyVersionOperator::equal: + return *this == other; + case DependencyVersionOperator::more: + return *this > other; + case DependencyVersionOperator::less: + return *this < other; + case DependencyVersionOperator::less_or_equal: + return *this <= other; + case DependencyVersionOperator::more_or_equal: + return *this >= other; + default: + return false; } + } - bool operator<(const Version& other) const { - if (major != other.major) return major < other.major; - if (minor != other.minor) return minor < other.minor; - return patch < other.patch; - } - - - bool operator>(const Version& other) const { - return other < *this; - } - - bool operator>=(const Version& other) const { - return !(*this < other); - } - - bool operator<=(const Version& other) const { - return !(*this > other); - } - - bool process_operator(const std::string& op, const Version& other) const { - auto dep_op = Version::string_to_operator(op); - - switch(dep_op) { - case DependencyVersionOperator::equal: return *this == other; - case DependencyVersionOperator::more: return *this > other; - case DependencyVersionOperator::less: return *this < other; - case DependencyVersionOperator::less_or_equal: return *this <= other; - case DependencyVersionOperator::more_or_equal: return *this >= other; - default: return false; - } - } - - static DependencyVersionOperator string_to_operator(const std::string& op); - static bool matches_pattern(const std::string& version); -}; \ No newline at end of file + static DependencyVersionOperator string_to_operator(const std::string& op); + static bool matches_pattern(const std::string& version); +}; From 53e1528d5c60aefc3a02dd1d2f050a4e55ce6c51 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Sun, 14 Sep 2025 12:59:09 +0300 Subject: [PATCH 13/13] fix ContentPack enums formatting --- src/content/ContentPack.cpp | 6 +++--- src/content/ContentPack.hpp | 10 +++++----- src/content/ContentPackVersion.cpp | 12 ++++++------ src/content/ContentPackVersion.hpp | 10 +++++----- src/content/PacksManager.cpp | 6 +++--- src/logic/scripting/lua/libs/libpack.cpp | 6 +++--- 6 files changed, 25 insertions(+), 25 deletions(-) diff --git a/src/content/ContentPack.cpp b/src/content/ContentPack.cpp index 49d7ee1f..522b818f 100644 --- a/src/content/ContentPack.cpp +++ b/src/content/ContentPack.cpp @@ -118,18 +118,18 @@ ContentPack ContentPack::read(const io::path& folder) { const auto& dependencies = *found; for (const auto& elem : dependencies) { std::string depName = elem.asString(); - auto level = DependencyLevel::required; + auto level = DependencyLevel::REQUIRED; switch (depName.at(0)) { case '!': depName = depName.substr(1); break; case '?': depName = depName.substr(1); - level = DependencyLevel::optional; + level = DependencyLevel::OPTIONAL; break; case '~': depName = depName.substr(1); - level = DependencyLevel::weak; + level = DependencyLevel::WEAK; break; } diff --git a/src/content/ContentPack.hpp b/src/content/ContentPack.hpp index 0069553a..1aa3a9ea 100644 --- a/src/content/ContentPack.hpp +++ b/src/content/ContentPack.hpp @@ -26,14 +26,14 @@ public: }; enum class DependencyVersionOperator { - equal, more, less, - more_or_equal, less_or_equal + EQUAL, GREATHER, LESS, + GREATHER_OR_EQUAL, LESS_OR_EQUAL }; enum class DependencyLevel { - required, // dependency must be installed - optional, // dependency will be installed if found - weak, // only affects packs order + REQUIRED, // dependency must be installed + OPTIONAL, // dependency will be installed if found + WEAK, // only affects packs order }; /// @brief Content-pack that should be installed earlier the dependent diff --git a/src/content/ContentPackVersion.cpp b/src/content/ContentPackVersion.cpp index d8d46dce..7a3d8801 100644 --- a/src/content/ContentPackVersion.cpp +++ b/src/content/ContentPackVersion.cpp @@ -28,17 +28,17 @@ Version::Version(const std::string& version) { DependencyVersionOperator Version::string_to_operator(const std::string& op) { if (op == "=") - return DependencyVersionOperator::equal; + return DependencyVersionOperator::EQUAL; else if (op == ">") - return DependencyVersionOperator::more; + return DependencyVersionOperator::GREATHER; else if (op == "<") - return DependencyVersionOperator::less; + return DependencyVersionOperator::LESS; else if (op == ">=" || op == "=>") - return DependencyVersionOperator::more_or_equal; + return DependencyVersionOperator::GREATHER_OR_EQUAL; else if (op == "<=" || op == "=<") - return DependencyVersionOperator::less_or_equal; + return DependencyVersionOperator::LESS_OR_EQUAL; else - return DependencyVersionOperator::equal; + return DependencyVersionOperator::EQUAL; } bool isNumber(const std::string& s) { diff --git a/src/content/ContentPackVersion.hpp b/src/content/ContentPackVersion.hpp index 5d30c1e7..e922ddd3 100644 --- a/src/content/ContentPackVersion.hpp +++ b/src/content/ContentPackVersion.hpp @@ -37,15 +37,15 @@ public: auto dep_op = Version::string_to_operator(op); switch (dep_op) { - case DependencyVersionOperator::equal: + case DependencyVersionOperator::EQUAL: return *this == other; - case DependencyVersionOperator::more: + case DependencyVersionOperator::GREATHER: return *this > other; - case DependencyVersionOperator::less: + case DependencyVersionOperator::LESS: return *this < other; - case DependencyVersionOperator::less_or_equal: + case DependencyVersionOperator::LESS_OR_EQUAL: return *this <= other; - case DependencyVersionOperator::more_or_equal: + case DependencyVersionOperator::GREATHER_OR_EQUAL: return *this >= other; default: return false; diff --git a/src/content/PacksManager.cpp b/src/content/PacksManager.cpp index 1e2ed49f..2d9759cb 100644 --- a/src/content/PacksManager.cpp +++ b/src/content/PacksManager.cpp @@ -91,7 +91,7 @@ static bool resolve_dependencies( } auto found = packs.find(dep.id); bool exists = found != packs.end(); - if (!exists && dep.level == DependencyLevel::required) { + if (!exists && dep.level == DependencyLevel::REQUIRED) { throw contentpack_error( dep.id, io::path(), "dependency of '" + pack->id + "'" ); @@ -100,7 +100,7 @@ static bool resolve_dependencies( // ignored for optional or weak dependencies continue; } - if (resolveWeaks && dep.level == DependencyLevel::weak) { + if (resolveWeaks && dep.level == DependencyLevel::WEAK) { // dependency pack is found but not added yet // resolveWeaks is used on second iteration, so it's will not be // added @@ -125,7 +125,7 @@ static bool resolve_dependencies( } if (!util::contains(allNames, dep.id) && - dep.level != DependencyLevel::weak) { + dep.level != DependencyLevel::WEAK) { allNames.push_back(dep.id); queue.push(&found->second); } diff --git a/src/logic/scripting/lua/libs/libpack.cpp b/src/logic/scripting/lua/libs/libpack.cpp index fc5e2252..29ceef99 100644 --- a/src/logic/scripting/lua/libs/libpack.cpp +++ b/src/logic/scripting/lua/libs/libpack.cpp @@ -102,13 +102,13 @@ static int l_pack_get_info( auto& dpack = pack.dependencies[i]; std::string prefix; switch (dpack.level) { - case DependencyLevel::required: + case DependencyLevel::REQUIRED: prefix = "!"; break; - case DependencyLevel::optional: + case DependencyLevel::OPTIONAL: prefix = "?"; break; - case DependencyLevel::weak: + case DependencyLevel::WEAK: prefix = "~"; break; default: