1
0
Fork 0
mirror of https://github.com/luanti-org/luanti.git synced 2025-09-15 18:57:08 +00:00

Use virtual paths to specify exact mod to enable (#11784)

This commit is contained in:
rubenwardy 2022-01-30 22:40:53 +00:00 committed by GitHub
parent 8c0331d244
commit 128f6359e9
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
11 changed files with 223 additions and 80 deletions

View file

@ -205,14 +205,19 @@ local function handle_buttons(this, fields)
local mods = worldfile:to_table()
local rawlist = this.data.list:get_raw_list()
local was_set = {}
for i = 1, #rawlist do
local mod = rawlist[i]
if not mod.is_modpack and
not mod.is_game_content then
if modname_valid(mod.name) then
worldfile:set("load_mod_" .. mod.name,
mod.enabled and "true" or "false")
if mod.enabled then
worldfile:set("load_mod_" .. mod.name, mod.virtual_path)
was_set[mod.name] = true
elseif not was_set[mod.name] then
worldfile:set("load_mod_" .. mod.name, "false")
end
elseif mod.enabled then
gamedata.errormessage = fgettext_ne("Failed to enable mo" ..
"d \"$1\" as it contains disallowed characters. " ..
@ -256,12 +261,26 @@ local function handle_buttons(this, fields)
if fields.btn_enable_all_mods then
local list = this.data.list:get_raw_list()
-- When multiple copies of a mod are installed, we need to avoid enabling multiple of them
-- at a time. So lets first collect all the enabled mods, and then use this to exclude
-- multiple enables.
local was_enabled = {}
for i = 1, #list do
if not list[i].is_game_content
and not list[i].is_modpack then
list[i].enabled = true
and not list[i].is_modpack and list[i].enabled then
was_enabled[list[i].name] = true
end
end
for i = 1, #list do
if not list[i].is_game_content and not list[i].is_modpack and
not was_enabled[list[i].name] then
list[i].enabled = true
was_enabled[list[i].name] = true
end
end
enabled_all = true
return true
end

View file

@ -378,7 +378,7 @@ local function parse_config_file(read_all, parse_mods)
-- Parse mods
local mods_category_initialized = false
local mods = {}
get_mods(core.get_modpath(), mods)
get_mods(core.get_modpath(), "mods", mods)
for _, mod in ipairs(mods) do
local path = mod.path .. DIR_DELIM .. FILENAME
local file = io.open(path, "r")

View file

@ -100,12 +100,13 @@ local function load_texture_packs(txtpath, retval)
end
end
function get_mods(path,retval,modpack)
function get_mods(path, virtual_path, retval, modpack)
local mods = core.get_dir_list(path, true)
for _, name in ipairs(mods) do
if name:sub(1, 1) ~= "." then
local prefix = path .. DIR_DELIM .. name
local mod_path = path .. DIR_DELIM .. name
local mod_virtual_path = virtual_path .. "/" .. name
local toadd = {
dir_name = name,
parent_dir = path,
@ -114,18 +115,18 @@ function get_mods(path,retval,modpack)
-- Get config file
local mod_conf
local modpack_conf = io.open(prefix .. DIR_DELIM .. "modpack.conf")
local modpack_conf = io.open(mod_path .. DIR_DELIM .. "modpack.conf")
if modpack_conf then
toadd.is_modpack = true
modpack_conf:close()
mod_conf = Settings(prefix .. DIR_DELIM .. "modpack.conf"):to_table()
mod_conf = Settings(mod_path .. DIR_DELIM .. "modpack.conf"):to_table()
if mod_conf.name then
name = mod_conf.name
toadd.is_name_explicit = true
end
else
mod_conf = Settings(prefix .. DIR_DELIM .. "mod.conf"):to_table()
mod_conf = Settings(mod_path .. DIR_DELIM .. "mod.conf"):to_table()
if mod_conf.name then
name = mod_conf.name
toadd.is_name_explicit = true
@ -136,12 +137,13 @@ function get_mods(path,retval,modpack)
toadd.name = name
toadd.author = mod_conf.author
toadd.release = tonumber(mod_conf.release) or 0
toadd.path = prefix
toadd.path = mod_path
toadd.virtual_path = mod_virtual_path
toadd.type = "mod"
-- Check modpack.txt
-- Note: modpack.conf is already checked above
local modpackfile = io.open(prefix .. DIR_DELIM .. "modpack.txt")
local modpackfile = io.open(mod_path .. DIR_DELIM .. "modpack.txt")
if modpackfile then
modpackfile:close()
toadd.is_modpack = true
@ -153,7 +155,7 @@ function get_mods(path,retval,modpack)
elseif toadd.is_modpack then
toadd.type = "modpack"
toadd.is_modpack = true
get_mods(prefix, retval, name)
get_mods(mod_path, mod_virtual_path, retval, name)
end
end
end
@ -397,6 +399,14 @@ function pkgmgr.is_modpack_entirely_enabled(data, name)
return true
end
local function disable_all_by_name(list, name, except)
for i=1, #list do
if list[i].name == name and list[i] ~= except then
list[i].enabled = false
end
end
end
---------- toggles or en/disables a mod or modpack and its dependencies --------
local function toggle_mod_or_modpack(list, toggled_mods, enabled_mods, toset, mod)
if not mod.is_modpack then
@ -404,6 +414,9 @@ local function toggle_mod_or_modpack(list, toggled_mods, enabled_mods, toset, mo
if toset == nil then
toset = not mod.enabled
end
if toset then
disable_all_by_name(list, mod.name, mod)
end
if mod.enabled ~= toset then
mod.enabled = toset
toggled_mods[#toggled_mods+1] = mod.name
@ -648,8 +661,8 @@ function pkgmgr.preparemodlist(data)
--read global mods
local modpaths = core.get_modpaths()
for _, modpath in ipairs(modpaths) do
get_mods(modpath, global_mods)
for key, modpath in pairs(modpaths) do
get_mods(modpath, key, global_mods)
end
for i=1,#global_mods,1 do
@ -688,22 +701,37 @@ function pkgmgr.preparemodlist(data)
DIR_DELIM .. "world.mt"
local worldfile = Settings(filename)
for key,value in pairs(worldfile:to_table()) do
for key, value in pairs(worldfile:to_table()) do
if key:sub(1, 9) == "load_mod_" then
key = key:sub(10)
local element = nil
for i=1,#retval,1 do
local mod_found = false
local fallback_found = false
local fallback_mod = nil
for i=1, #retval do
if retval[i].name == key and
not retval[i].is_modpack then
element = retval[i]
break
not retval[i].is_modpack then
if core.is_yes(value) or retval[i].virtual_path == value then
retval[i].enabled = true
mod_found = true
break
elseif fallback_found then
-- Only allow fallback if only one mod matches
fallback_mod = nil
else
fallback_found = true
fallback_mod = retval[i]
end
end
end
if element ~= nil then
element.enabled = value ~= "false" and value ~= "nil" and value
else
core.log("info", "Mod: " .. key .. " " .. dump(value) .. " but not found")
if not mod_found then
if fallback_mod and value:find("/") then
fallback_mod.enabled = true
else
core.log("info", "Mod: " .. key .. " " .. dump(value) .. " but not found")
end
end
end
end
@ -797,7 +825,7 @@ function pkgmgr.get_game_mods(gamespec, retval)
if gamespec ~= nil and
gamespec.gamemods_path ~= nil and
gamespec.gamemods_path ~= "" then
get_mods(gamespec.gamemods_path, retval)
get_mods(gamespec.gamemods_path, ("games/%s/mods"):format(gamespec.id), retval)
end
end