Mainmenu: Properly sort mods and games (#12758)

This also removes trivial and unused pkgmgr functions
Fixes a bug caused by sorting in 2133fc8
This commit is contained in:
SmallJoker 2022-09-12 19:24:54 +02:00 committed by GitHub
parent fe13f9dfd1
commit bc3dccca5c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 54 additions and 127 deletions

@ -519,18 +519,6 @@ end
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
-- mainmenu only functions -- mainmenu only functions
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
if INIT == "mainmenu" then
function core.get_game(index)
local games = core.get_games()
if index > 0 and index <= #games then
return games[index]
end
return nil
end
end
if core.gettext then -- for client and mainmenu if core.gettext then -- for client and mainmenu
function fgettext_ne(text, ...) function fgettext_ne(text, ...)
text = core.gettext(text) text = core.gettext(text)

@ -57,8 +57,7 @@ local function init_data(data)
hide_game = data.hide_gamemods, hide_game = data.hide_gamemods,
hide_modpackcontents = data.hide_modpackcontents hide_modpackcontents = data.hide_modpackcontents
}) })
data.list:add_sort_mechanism("alphabetic", sort_mod_list) -- Sorting is already done by pgkmgr.get_mods
data.list:set_sortmode("alphabetic")
end end

@ -346,22 +346,21 @@ end
local install_dialog = {} local install_dialog = {}
function install_dialog.get_formspec() function install_dialog.get_formspec()
local selected_game, selected_game_idx = pkgmgr.find_by_gameid(core.settings:get("menu_last_game"))
if not selected_game_idx then
selected_game_idx = 1
selected_game = pkgmgr.games[1]
end
local game_list = {}
for i, game in ipairs(pkgmgr.games) do
game_list[i] = core.formspec_escape(game[i].title)
end
local package = install_dialog.package local package = install_dialog.package
local raw_deps = install_dialog.raw_deps local raw_deps = install_dialog.raw_deps
local will_install_deps = install_dialog.will_install_deps local will_install_deps = install_dialog.will_install_deps
local selected_game_idx = 1
local selected_gameid = core.settings:get("menu_last_game")
local games = table.copy(pkgmgr.games)
for i=1, #games do
if selected_gameid and games[i].id == selected_gameid then
selected_game_idx = i
end
games[i] = core.formspec_escape(games[i].title)
end
local selected_game = pkgmgr.games[selected_game_idx]
local deps_to_install = 0 local deps_to_install = 0
local deps_not_found = 0 local deps_not_found = 0
@ -408,7 +407,7 @@ function install_dialog.get_formspec()
"container[0.375,0.70]", "container[0.375,0.70]",
"label[0,0.25;", fgettext("Base Game:"), "]", "label[0,0.25;", fgettext("Base Game:"), "]",
"dropdown[2,0;4.25,0.5;selected_game;", table.concat(games, ","), ";", selected_game_idx, "]", "dropdown[2,0;4.25,0.5;selected_game;", table.concat(game_list, ","), ";", selected_game_idx, "]",
"label[0,0.8;", fgettext("Dependencies:"), "]", "label[0,0.8;", fgettext("Dependencies:"), "]",

@ -104,14 +104,12 @@ local function create_world_formspec(dialogdata)
local current_mg = dialogdata.mg local current_mg = dialogdata.mg
local mapgens = core.get_mapgen_names() local mapgens = core.get_mapgen_names()
local gameid = core.settings:get("menu_last_game")
local flags = dialogdata.flags local flags = dialogdata.flags
local game = pkgmgr.find_by_gameid(gameid) local game = pkgmgr.find_by_gameid(core.settings:get("menu_last_game"))
if game == nil then if game == nil then
-- should never happen but just pick the first game -- should never happen but just pick the first game
game = pkgmgr.get_game(1) game = pkgmgr.games[1]
core.settings:set("menu_last_game", game.id) core.settings:set("menu_last_game", game.id)
end end
@ -355,7 +353,7 @@ local function create_world_buttonhandler(this, fields)
fields["key_enter"] then fields["key_enter"] then
local worldname = fields["te_world_name"] local worldname = fields["te_world_name"]
local game, gameindex = pkgmgr.find_by_gameid(core.settings:get("menu_last_game")) local game, _ = pkgmgr.find_by_gameid(core.settings:get("menu_last_game"))
local message local message
if game == nil then if game == nil then
@ -399,7 +397,7 @@ local function create_world_buttonhandler(this, fields)
mgvalleys_spflags = table_to_flags(this.data.flags.valleys), mgvalleys_spflags = table_to_flags(this.data.flags.valleys),
mgflat_spflags = table_to_flags(this.data.flags.flat), mgflat_spflags = table_to_flags(this.data.flags.flat),
} }
message = core.create_world(worldname, gameindex, settings) message = core.create_world(worldname, game.id, settings)
end end
if message == nil then if message == nil then

@ -344,9 +344,7 @@ local function parse_config_file(read_all, parse_mods)
if parse_mods then if parse_mods then
-- Parse games -- Parse games
local games_category_initialized = false local games_category_initialized = false
local index = 1 for _, game in ipairs(pkgmgr.games) do
local game = pkgmgr.get_game(index)
while game do
local path = game.path .. DIR_DELIM .. FILENAME local path = game.path .. DIR_DELIM .. FILENAME
local file = io.open(path, "r") local file = io.open(path, "r")
if file then if file then
@ -370,15 +368,12 @@ local function parse_config_file(read_all, parse_mods)
file:close() file:close()
end end
index = index + 1
game = pkgmgr.get_game(index)
end end
-- Parse mods -- Parse mods
local mods_category_initialized = false local mods_category_initialized = false
local mods = {} local mods = {}
get_mods(core.get_modpath(), "mods", mods) pkgmgr.get_mods(core.get_modpath(), "mods", mods)
for _, mod in ipairs(mods) do for _, mod in ipairs(mods) do
local path = mod.path .. DIR_DELIM .. FILENAME local path = mod.path .. DIR_DELIM .. FILENAME
local file = io.open(path, "r") local file = io.open(path, "r")
@ -409,7 +404,7 @@ local function parse_config_file(read_all, parse_mods)
-- Parse client mods -- Parse client mods
local clientmods_category_initialized = false local clientmods_category_initialized = false
local clientmods = {} local clientmods = {}
get_mods(core.get_clientmodpath(), "clientmods", clientmods) pkgmgr.get_mods(core.get_clientmodpath(), "clientmods", clientmods)
for _, mod in ipairs(clientmods) do for _, mod in ipairs(clientmods) do
local path = mod.path .. DIR_DELIM .. FILENAME local path = mod.path .. DIR_DELIM .. FILENAME
local file = io.open(path, "r") local file = io.open(path, "r")

@ -100,7 +100,15 @@ local function load_texture_packs(txtpath, retval)
end end
end end
function get_mods(path, virtual_path, retval, modpack) --modmanager implementation
pkgmgr = {}
--- Scans a directory recursively for mods and adds them to `listing`
-- @param path Absolute directory path to scan recursively
-- @param virtual_path Prettified unique path (e.g. "mods", "mods/mt_modpack")
-- @param listing Input. Flat array to insert located mods and modpacks
-- @param modpack Currently processing modpack or nil/"" if none (recursion)
function pkgmgr.get_mods(path, virtual_path, listing, modpack)
local mods = core.get_dir_list(path, true) local mods = core.get_dir_list(path, true)
for _, name in ipairs(mods) do for _, name in ipairs(mods) do
@ -111,7 +119,7 @@ function get_mods(path, virtual_path, retval, modpack)
dir_name = name, dir_name = name,
parent_dir = path, parent_dir = path,
} }
retval[#retval + 1] = toadd listing[#listing + 1] = toadd
-- Get config file -- Get config file
local mod_conf local mod_conf
@ -156,15 +164,19 @@ function get_mods(path, virtual_path, retval, modpack)
elseif toadd.is_modpack then elseif toadd.is_modpack then
toadd.type = "modpack" toadd.type = "modpack"
toadd.is_modpack = true toadd.is_modpack = true
get_mods(mod_path, mod_virtual_path, retval, name) pkgmgr.get_mods(mod_path, mod_virtual_path, listing, name)
end end
end end
end end
if not modpack then
-- Sort all when the recursion is done
table.sort(listing, function(a, b)
return a.virtual_path:lower() < b.virtual_path:lower()
end)
end
end end
--modmanager implementation
pkgmgr = {}
function pkgmgr.get_texture_packs() function pkgmgr.get_texture_packs()
local txtpath = core.get_texturepath() local txtpath = core.get_texturepath()
local txtpath_system = core.get_texturepath_share() local txtpath_system = core.get_texturepath_share()
@ -593,7 +605,7 @@ function pkgmgr.preparemodlist(data)
--read global mods --read global mods
local modpaths = core.get_modpaths() local modpaths = core.get_modpaths()
for key, modpath in pairs(modpaths) do for key, modpath in pairs(modpaths) do
get_mods(modpath, key, global_mods) pkgmgr.get_mods(modpath, key, global_mods)
end end
for i=1,#global_mods,1 do for i=1,#global_mods,1 do
@ -700,35 +712,6 @@ function pkgmgr.comparemod(elem1,elem2)
return true return true
end end
--------------------------------------------------------------------------------
function pkgmgr.mod_exists(basename)
if pkgmgr.global_mods == nil then
pkgmgr.refresh_globals()
end
if pkgmgr.global_mods:raw_index_by_uid(basename) > 0 then
return true
end
return false
end
--------------------------------------------------------------------------------
function pkgmgr.get_global_mod(idx)
if pkgmgr.global_mods == nil then
return nil
end
if idx == nil or idx < 1 or
idx > pkgmgr.global_mods:size() then
return nil
end
return pkgmgr.global_mods:get_list()[idx]
end
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
function pkgmgr.refresh_globals() function pkgmgr.refresh_globals()
local function is_equal(element,uid) --uid match local function is_equal(element,uid) --uid match
@ -744,9 +727,9 @@ end
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
function pkgmgr.find_by_gameid(gameid) function pkgmgr.find_by_gameid(gameid)
for i=1,#pkgmgr.games,1 do for i, game in ipairs(pkgmgr.games) do
if pkgmgr.games[i].id == gameid then if game.id == gameid then
return pkgmgr.games[i], i return game, i
end end
end end
return nil, nil return nil, nil
@ -757,33 +740,10 @@ function pkgmgr.get_game_mods(gamespec, retval)
if gamespec ~= nil and if gamespec ~= nil and
gamespec.gamemods_path ~= nil and gamespec.gamemods_path ~= nil and
gamespec.gamemods_path ~= "" then gamespec.gamemods_path ~= "" then
get_mods(gamespec.gamemods_path, ("games/%s/mods"):format(gamespec.id), retval) pkgmgr.get_mods(gamespec.gamemods_path, ("games/%s/mods"):format(gamespec.id), retval)
end end
end end
--------------------------------------------------------------------------------
function pkgmgr.get_game_modlist(gamespec)
local retval = ""
local game_mods = {}
pkgmgr.get_game_mods(gamespec, game_mods)
for i=1,#game_mods,1 do
if retval ~= "" then
retval = retval..","
end
retval = retval .. game_mods[i].name
end
return retval
end
--------------------------------------------------------------------------------
function pkgmgr.get_game(index)
if index > 0 and index <= #pkgmgr.games then
return pkgmgr.games[index]
end
return nil
end
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
function pkgmgr.update_gamelist() function pkgmgr.update_gamelist()
pkgmgr.games = core.get_games() pkgmgr.games = core.get_games()
@ -792,19 +752,6 @@ function pkgmgr.update_gamelist()
end) end)
end end
--------------------------------------------------------------------------------
function pkgmgr.gamelist()
local retval = ""
if #pkgmgr.games > 0 then
retval = retval .. core.formspec_escape(pkgmgr.games[1].title)
for i=2,#pkgmgr.games,1 do
retval = retval .. "," .. core.formspec_escape(pkgmgr.games[i].title)
end
end
return retval
end
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
-- read initial data -- read initial data
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------

@ -247,9 +247,9 @@ Package - content which is downloadable from the content db, may or may not be i
* returns path to global gamepath * returns path to global gamepath
* core.get_texturepath() (possible in async calls) * core.get_texturepath() (possible in async calls)
* returns path to default textures * returns path to default textures
* core.get_game(index) * core.get_games() -> table of all games (possible in async calls)
* `name` in return value is deprecated, use `title` instead. * `name` in return value is deprecated, use `title` instead.
* returns: * returns a table (ipairs) with values:
{ {
id = <id>, id = <id>,
@ -261,8 +261,6 @@ Package - content which is downloadable from the content db, may or may not be i
DEPRECATED: DEPRECATED:
addon_mods_paths = {[1] = <path>,}, addon_mods_paths = {[1] = <path>,},
} }
* core.get_games() -> table of all games in upper format (possible in async calls)
* core.get_content_info(path) * core.get_content_info(path)
* returns * returns
@ -323,7 +321,7 @@ core.get_worlds() -> list of worlds (possible in async calls)
gameid = <gameid of world>, gameid = <gameid of world>,
}, },
} }
core.create_world(worldname, gameid) core.create_world(worldname, gameid, init_settings)
core.delete_world(index) core.delete_world(index)

@ -523,7 +523,7 @@ int ModApiMainMenu::l_show_keys_menu(lua_State *L)
int ModApiMainMenu::l_create_world(lua_State *L) int ModApiMainMenu::l_create_world(lua_State *L)
{ {
const char *name = luaL_checkstring(L, 1); const char *name = luaL_checkstring(L, 1);
int gameidx = luaL_checkinteger(L,2) -1; const char *gameid = luaL_checkstring(L, 2);
StringMap use_settings; StringMap use_settings;
luaL_checktype(L, 3, LUA_TTABLE); luaL_checktype(L, 3, LUA_TTABLE);
@ -540,8 +540,11 @@ int ModApiMainMenu::l_create_world(lua_State *L)
+ sanitizeDirName(name, "world_"); + sanitizeDirName(name, "world_");
std::vector<SubgameSpec> games = getAvailableGames(); std::vector<SubgameSpec> games = getAvailableGames();
if (gameidx < 0 || gameidx >= (int) games.size()) { auto game_it = std::find_if(games.begin(), games.end(), [gameid] (const SubgameSpec &spec) {
lua_pushstring(L, "Invalid game index"); return spec.id == gameid;
});
if (game_it == games.end()) {
lua_pushstring(L, "Game ID not found");
return 1; return 1;
} }
@ -556,7 +559,7 @@ int ModApiMainMenu::l_create_world(lua_State *L)
// Create world if it doesn't exist // Create world if it doesn't exist
try { try {
loadGameConfAndInitWorld(path, name, games[gameidx], true); loadGameConfAndInitWorld(path, name, *game_it, true);
lua_pushnil(L); lua_pushnil(L);
} catch (const BaseException &e) { } catch (const BaseException &e) {
auto err = std::string("Failed to initialize world: ") + e.what(); auto err = std::string("Failed to initialize world: ") + e.what();