diff --git a/builtin/mainmenu/dlg_config_world.lua b/builtin/mainmenu/dlg_config_world.lua index 36cc5580c..db6963b78 100644 --- a/builtin/mainmenu/dlg_config_world.lua +++ b/builtin/mainmenu/dlg_config_world.lua @@ -85,8 +85,13 @@ 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 + with_error[mod.virtual_path] = { type = "error", reason = "invalid" } + 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 @@ -155,6 +160,24 @@ local function get_formspec(data) local hard_deps_str = table.concat(hard_deps, ",") local soft_deps_str = table.concat(soft_deps, ",") + local error_message = "" + + local error = with_error[mod.virtual_path] + if error and + error.type == "error" and + -- do not display "unsatisfied_depends" error as message because is + -- is displayed by dependency list + error.reason ~= "unsatisfied_depends" + then + error_message = error_message .. + 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. " .. + "Dependencies are not visible because of this.") + end + end + retval = retval .. "label[0,0.7;" .. fgettext("Mod:") .. "]" .. "label[0.75,0.7;" .. mod.name .. "]" @@ -163,7 +186,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_message .. ";]" else retval = retval .. "label[0,1.25;" .. fgettext("No hard dependencies") .. @@ -171,7 +195,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_message .. ";]" end else if soft_deps_str == "" then @@ -179,7 +204,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_message .. ";]" else retval = retval .. "label[0,1.25;" .. fgettext("Dependencies:") .. "]" .. @@ -188,7 +214,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_message .. ";]" end end end diff --git a/src/content/mods.h b/src/content/mods.h index fc98d9298..475f997ef 100644 --- a/src/content/mods.h +++ b/src/content/mods.h @@ -34,6 +34,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 91aa5b405..804cf85cb 100644 --- a/src/script/common/c_content.cpp +++ b/src/script/common/c_content.cpp @@ -2599,4 +2599,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/cpp_api/s_base.cpp b/src/script/cpp_api/s_base.cpp index ba931b22a..49be9144c 100644 --- a/src/script/cpp_api/s_base.cpp +++ b/src/script/cpp_api/s_base.cpp @@ -233,6 +233,11 @@ std::string ScriptApiBase::getCurrentModNameInsecure(lua_State *L) void ScriptApiBase::loadMod(const std::string &script_path, const std::string &mod_name) { + if (!fs::IsFile(script_path)) { + 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); loadScript(script_path); diff --git a/src/script/lua_api/l_mainmenu.cpp b/src/script/lua_api/l_mainmenu.cpp index 4b878ee1c..ed4ca476f 100644 --- a/src/script/lua_api/l_mainmenu.cpp +++ b/src/script/lua_api/l_mainmenu.cpp @@ -461,9 +461,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)) { - throw LuaError("Not a mod!"); - } + spec.valid = parseModContents(spec); } modmgr.addMods(modSpecs);