From 350c391b057257155f35a381bd980269cb4c7493 Mon Sep 17 00:00:00 2001 From: ZavGaro Date: Tue, 20 Aug 2024 21:25:33 +0300 Subject: [PATCH 1/7] Ignore incomplete mods instead throwing LuaError --- src/script/lua_api/l_mainmenu.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/script/lua_api/l_mainmenu.cpp b/src/script/lua_api/l_mainmenu.cpp index a5913e807..acc600a6c 100644 --- a/src/script/lua_api/l_mainmenu.cpp +++ b/src/script/lua_api/l_mainmenu.cpp @@ -451,7 +451,8 @@ int ModApiMainMenu::l_check_mod_configuration(lua_State *L) spec.path = modpath; spec.virtual_path = virtual_path; if (!parseModContents(spec)) { - throw LuaError("Not a mod!"); + warningstream << "Mod \"" << spec.name + << "\" has no \"init.lua\" or \"modpack.conf\"" << std::endl; } } From ac8de2173a2d33cd8678fece231ddc79bf53234c Mon Sep 17 00:00:00 2001 From: ZavGaro Date: Tue, 20 Aug 2024 21:29:52 +0300 Subject: [PATCH 2/7] Do not load mod if given init script doesn't exist --- src/script/cpp_api/s_base.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/script/cpp_api/s_base.cpp b/src/script/cpp_api/s_base.cpp index e9907f304..cddd8cd34 100644 --- a/src/script/cpp_api/s_base.cpp +++ b/src/script/cpp_api/s_base.cpp @@ -266,6 +266,11 @@ std::string ScriptApiBase::getCurrentModName(lua_State *L) void ScriptApiBase::loadMod(const std::string &script_path, const std::string &mod_name) { + if (!fs::IsFile(script_path)) { + errorstream << "Mod error: Failed to load mod \"" << mod_name + << "\" as script \"" << script_path << "\" does not exist" << std::endl; + return; + } ModNameStorer mod_name_storer(getStack(), mod_name); loadScript(script_path); From 6c1d3ce8fae8884e4ff72de6cea89e7a419cd0fe Mon Sep 17 00:00:00 2001 From: ZavGaro Date: Wed, 21 Aug 2024 09:42:46 +0300 Subject: [PATCH 3/7] Trow mod error exception if given init script doesn't exist on mod loading --- src/script/cpp_api/s_base.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/script/cpp_api/s_base.cpp b/src/script/cpp_api/s_base.cpp index cddd8cd34..e83157bd9 100644 --- a/src/script/cpp_api/s_base.cpp +++ b/src/script/cpp_api/s_base.cpp @@ -267,9 +267,9 @@ void ScriptApiBase::loadMod(const std::string &script_path, const std::string &mod_name) { if (!fs::IsFile(script_path)) { - errorstream << "Mod error: Failed to load mod \"" << mod_name - << "\" as script \"" << script_path << "\" does not exist" << std::endl; - return; + throw ModError("Failed to load mod \"" + mod_name + + "\" as it's initialization script at \"" + script_path + + "\" does not exist. Try to reinstall/update mod or disable it."); } ModNameStorer mod_name_storer(getStack(), mod_name); From 19334bfb25192da06a1d31e808f5db5fda67c587 Mon Sep 17 00:00:00 2001 From: ZavGaro Date: Wed, 21 Aug 2024 11:47:32 +0300 Subject: [PATCH 4/7] Add `valid` field to mod and set it to false for incomplete mods --- src/content/mods.h | 1 + src/script/common/c_content.cpp | 3 +++ src/script/lua_api/l_mainmenu.cpp | 5 +---- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/content/mods.h b/src/content/mods.h index 228684c6e..6597eaeae 100644 --- a/src/content/mods.h +++ b/src/content/mods.h @@ -49,6 +49,7 @@ struct ModSpec std::unordered_set optdepends; std::unordered_set unsatisfied_depends; + bool valid = true; /// False if incomplete bool part_of_modpack = false; bool is_modpack = false; diff --git a/src/script/common/c_content.cpp b/src/script/common/c_content.cpp index 6f7d86447..c22ed121d 100644 --- a/src/script/common/c_content.cpp +++ b/src/script/common/c_content.cpp @@ -2576,4 +2576,7 @@ void push_mod_spec(lua_State *L, const ModSpec &spec, bool include_unsatisfied) lua_rawseti(L, -2, i++); } lua_setfield(L, -2, "unsatisfied_depends"); + + lua_pushboolean(L, spec.valid); + lua_setfield(L, -2, "valid"); } diff --git a/src/script/lua_api/l_mainmenu.cpp b/src/script/lua_api/l_mainmenu.cpp index acc600a6c..e8246c15d 100644 --- a/src/script/lua_api/l_mainmenu.cpp +++ b/src/script/lua_api/l_mainmenu.cpp @@ -450,10 +450,7 @@ int ModApiMainMenu::l_check_mod_configuration(lua_State *L) spec.name = fs::GetFilenameFromPath(modpath.c_str()); spec.path = modpath; spec.virtual_path = virtual_path; - if (!parseModContents(spec)) { - warningstream << "Mod \"" << spec.name - << "\" has no \"init.lua\" or \"modpack.conf\"" << std::endl; - } + spec.valid = parseModContents(spec); } modmgr.addMods(modSpecs); From eba2c7425d07949ba9324711e9c35761e83ebf39 Mon Sep 17 00:00:00 2001 From: ZavGaro Date: Wed, 21 Aug 2024 12:02:13 +0300 Subject: [PATCH 5/7] Handle new mod error in mod selection menu - Check mod.valid value and add mod to `with_error` if it is false - Add `reason` to error - Add `error_messages` for errors other than `unsatisfied_depends` - Add text area for error messages --- builtin/mainmenu/dlg_config_world.lua | 38 +++++++++++++++++++++++---- 1 file changed, 33 insertions(+), 5 deletions(-) diff --git a/builtin/mainmenu/dlg_config_world.lua b/builtin/mainmenu/dlg_config_world.lua index e8f49b230..aa4059b10 100644 --- a/builtin/mainmenu/dlg_config_world.lua +++ b/builtin/mainmenu/dlg_config_world.lua @@ -98,8 +98,14 @@ local function check_mod_configuration(world_path, all_mods) -- Build the table of errors local with_error = {} + for _, mod in ipairs(config_status.satisfied_mods) do + if not mod.valid then + local error = { type = "error", reason = "invalid" } + with_error[mod.virtual_path] = error + end + end for _, mod in ipairs(config_status.unsatisfied_mods) do - local error = { type = "warning" } + local error = { type = "warning", reason = "unsatisfied_depends" } with_error[mod.virtual_path] = error for _, depname in ipairs(mod.unsatisfied_depends) do @@ -168,6 +174,24 @@ local function get_formspec(data) local hard_deps_str = table.concat(hard_deps, ",") local soft_deps_str = table.concat(soft_deps, ",") + local error_messages = "" + + local error = with_error[mod.virtual_path] + if error and + error.type == "error" and + -- do not handle this error by message because is is handled by + -- dependency list + error.reason ~= "unsatisfied_depends" + then + error_messages = error_messages .. + fgettext(minetest.colorize(mt_color_red, "Errors:") .. "\n") + if error.reason == "invalid" then + error_messages = error_messages .. fgettext( + "Mod is incomplete because it has no \"init.lua\" file. " .. + "Dependencies are not visible because of this.") + end + end + retval = retval .. "label[0,0.7;" .. fgettext("Mod:") .. "]" .. "label[0.75,0.7;" .. mod.name .. "]" @@ -176,7 +200,8 @@ local function get_formspec(data) if soft_deps_str == "" then retval = retval .. "label[0,1.25;" .. - fgettext("No (optional) dependencies") .. "]" + fgettext("No (optional) dependencies") .. "]" .. + "textarea[0.25,1.75;5.75,7.2;;" .. error_messages .. ";]" else retval = retval .. "label[0,1.25;" .. fgettext("No hard dependencies") .. @@ -184,7 +209,8 @@ local function get_formspec(data) "label[0,1.75;" .. fgettext("Optional dependencies:") .. "]" .. "textlist[0,2.25;5,4;world_config_optdepends;" .. - soft_deps_str .. ";0]" + soft_deps_str .. ";0]" .. + "textarea[0.25,6.5;3.45,1.75;;" .. error_messages .. ";]" end else if soft_deps_str == "" then @@ -192,7 +218,8 @@ local function get_formspec(data) "label[0,1.25;" .. fgettext("Dependencies:") .. "]" .. "textlist[0,1.75;5,4;world_config_depends;" .. hard_deps_str .. ";0]" .. - "label[0,6;" .. fgettext("No optional dependencies") .. "]" + "label[0,6;" .. fgettext("No optional dependencies") .. "]" .. + "textarea[0.25,6.5;3.45,1.75;;" .. error_messages .. ";]" else retval = retval .. "label[0,1.25;" .. fgettext("Dependencies:") .. "]" .. @@ -201,7 +228,8 @@ local function get_formspec(data) "label[0,3.9;" .. fgettext("Optional dependencies:") .. "]" .. "textlist[0,4.375;5,1.8;world_config_optdepends;" .. - soft_deps_str .. ";0]" + soft_deps_str .. ";0]" .. + "textarea[0.25,6.5;3.45,1.75;;" .. error_messages .. ";]" end end end From 9b79e00d1227e1291ee07c83210eb563b01a95c0 Mon Sep 17 00:00:00 2001 From: ZavGaro Date: Wed, 21 Aug 2024 13:23:28 +0300 Subject: [PATCH 6/7] Small corrections in dlg_config_world.lua --- builtin/mainmenu/dlg_config_world.lua | 33 +++++++++++++-------------- 1 file changed, 16 insertions(+), 17 deletions(-) diff --git a/builtin/mainmenu/dlg_config_world.lua b/builtin/mainmenu/dlg_config_world.lua index aa4059b10..51c98c517 100644 --- a/builtin/mainmenu/dlg_config_world.lua +++ b/builtin/mainmenu/dlg_config_world.lua @@ -100,8 +100,7 @@ local function check_mod_configuration(world_path, all_mods) local with_error = {} for _, mod in ipairs(config_status.satisfied_mods) do if not mod.valid then - local error = { type = "error", reason = "invalid" } - with_error[mod.virtual_path] = error + with_error[mod.virtual_path] = { type = "error", reason = "invalid" } end end for _, mod in ipairs(config_status.unsatisfied_mods) do @@ -174,22 +173,22 @@ local function get_formspec(data) local hard_deps_str = table.concat(hard_deps, ",") local soft_deps_str = table.concat(soft_deps, ",") - local error_messages = "" + local error_message = "" local error = with_error[mod.virtual_path] if error and error.type == "error" and - -- do not handle this error by message because is is handled by - -- dependency list + -- do not display "unsatisfied_depends" error as message because is + -- is displayed by dependency list error.reason ~= "unsatisfied_depends" - then - error_messages = error_messages .. - fgettext(minetest.colorize(mt_color_red, "Errors:") .. "\n") - if error.reason == "invalid" then - error_messages = error_messages .. fgettext( - "Mod is incomplete because it has no \"init.lua\" file. " .. - "Dependencies are not visible because of this.") - end + then + error_message = error_message .. + fgettext(minetest.colorize(mt_color_red, "Errors:") .. "\n") + if error.reason == "invalid" then + error_message = error_message .. fgettext( + "Mod is incomplete because it has no \"init.lua\" file. " .. + "Dependencies are not visible because of this.") + end end retval = retval .. @@ -201,7 +200,7 @@ local function get_formspec(data) retval = retval .. "label[0,1.25;" .. fgettext("No (optional) dependencies") .. "]" .. - "textarea[0.25,1.75;5.75,7.2;;" .. error_messages .. ";]" + "textarea[0.25,1.75;5.75,7.2;;" .. error_message .. ";]" else retval = retval .. "label[0,1.25;" .. fgettext("No hard dependencies") .. @@ -210,7 +209,7 @@ local function get_formspec(data) "]" .. "textlist[0,2.25;5,4;world_config_optdepends;" .. soft_deps_str .. ";0]" .. - "textarea[0.25,6.5;3.45,1.75;;" .. error_messages .. ";]" + "textarea[0.25,6.5;3.45,1.75;;" .. error_message .. ";]" end else if soft_deps_str == "" then @@ -219,7 +218,7 @@ local function get_formspec(data) "textlist[0,1.75;5,4;world_config_depends;" .. hard_deps_str .. ";0]" .. "label[0,6;" .. fgettext("No optional dependencies") .. "]" .. - "textarea[0.25,6.5;3.45,1.75;;" .. error_messages .. ";]" + "textarea[0.25,6.5;3.45,1.75;;" .. error_message .. ";]" else retval = retval .. "label[0,1.25;" .. fgettext("Dependencies:") .. "]" .. @@ -229,7 +228,7 @@ local function get_formspec(data) "]" .. "textlist[0,4.375;5,1.8;world_config_optdepends;" .. soft_deps_str .. ";0]" .. - "textarea[0.25,6.5;3.45,1.75;;" .. error_messages .. ";]" + "textarea[0.25,6.5;3.45,1.75;;" .. error_message .. ";]" end end end From 66316d2098b16d3a52d8ff4ccc78cd4e1a7c1923 Mon Sep 17 00:00:00 2001 From: ZavGaro Date: Fri, 23 Aug 2024 09:50:59 +0300 Subject: [PATCH 7/7] Fix fgettext() usage in dlg_config_world.lua --- builtin/mainmenu/dlg_config_world.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/builtin/mainmenu/dlg_config_world.lua b/builtin/mainmenu/dlg_config_world.lua index 51c98c517..2ea19df81 100644 --- a/builtin/mainmenu/dlg_config_world.lua +++ b/builtin/mainmenu/dlg_config_world.lua @@ -183,7 +183,7 @@ local function get_formspec(data) error.reason ~= "unsatisfied_depends" then error_message = error_message .. - fgettext(minetest.colorize(mt_color_red, "Errors:") .. "\n") + minetest.colorize(mt_color_red, fgettext("Errors:")) .. "\n" if error.reason == "invalid" then error_message = error_message .. fgettext( "Mod is incomplete because it has no \"init.lua\" file. " ..