From 5e6df0e7be46afe1dbdf6406e1109a8676a22092 Mon Sep 17 00:00:00 2001 From: rubenwardy Date: Sat, 16 Jan 2021 17:51:40 +0000 Subject: ContentDB: Ignore content not installed from ContentDB --- builtin/mainmenu/dlg_contentstore.lua | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'builtin/mainmenu') diff --git a/builtin/mainmenu/dlg_contentstore.lua b/builtin/mainmenu/dlg_contentstore.lua index b5f71e753..3ad9ed28a 100644 --- a/builtin/mainmenu/dlg_contentstore.lua +++ b/builtin/mainmenu/dlg_contentstore.lua @@ -580,7 +580,7 @@ function store.update_paths() local mod_hash = {} pkgmgr.refresh_globals() for _, mod in pairs(pkgmgr.global_mods:get_list()) do - if mod.author then + if mod.author and mod.release > 0 then mod_hash[mod.author:lower() .. "/" .. mod.name] = mod end end @@ -588,14 +588,14 @@ function store.update_paths() local game_hash = {} pkgmgr.update_gamelist() for _, game in pairs(pkgmgr.games) do - if game.author ~= "" then + if game.author ~= "" and game.release > 0 then game_hash[game.author:lower() .. "/" .. game.id] = game end end local txp_hash = {} for _, txp in pairs(pkgmgr.get_texture_packs()) do - if txp.author then + if txp.author and txp.release > 0 then txp_hash[txp.author:lower() .. "/" .. txp.name] = txp end end -- cgit v1.2.3 From eb8af614a5ee876a2bc9312506bfcfda20501232 Mon Sep 17 00:00:00 2001 From: Zughy <63455151+Zughy@users.noreply.github.com> Date: Wed, 20 Jan 2021 22:32:18 +0000 Subject: Local tab: rename 'Configure' to 'Select Mods' (#10779) Co-authored-by: Zughy <4279489-marco_a@users.noreply.gitlab.com> Co-authored-by: rubenwardy --- builtin/mainmenu/tab_local.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'builtin/mainmenu') diff --git a/builtin/mainmenu/tab_local.lua b/builtin/mainmenu/tab_local.lua index 2eb4752bc..0e06c3bef 100644 --- a/builtin/mainmenu/tab_local.lua +++ b/builtin/mainmenu/tab_local.lua @@ -116,7 +116,7 @@ local function get_formspec(tabview, name, tabdata) retval = retval .. "button[3.9,3.8;2.8,1;world_delete;".. fgettext("Delete") .. "]" .. - "button[6.55,3.8;2.8,1;world_configure;".. fgettext("Configure") .. "]" .. + "button[6.55,3.8;2.8,1;world_configure;".. fgettext("Select Mods") .. "]" .. "button[9.2,3.8;2.8,1;world_create;".. fgettext("New") .. "]" .. "label[3.9,-0.05;".. fgettext("Select World:") .. "]".. "checkbox[0,-0.20;cb_creative_mode;".. fgettext("Creative Mode") .. ";" .. -- cgit v1.2.3 From 8ff209c4122fb83310939bf1b73f56b704a3c982 Mon Sep 17 00:00:00 2001 From: Zughy <63455151+Zughy@users.noreply.github.com> Date: Thu, 21 Jan 2021 19:01:37 +0000 Subject: Load system-wide texture packs too (#10791) Co-authored-by: Zughy <4279489-marco_a@users.noreply.gitlab.com> --- builtin/mainmenu/pkgmgr.lua | 59 ++++++++++++++++++++++++++------------------- 1 file changed, 34 insertions(+), 25 deletions(-) (limited to 'builtin/mainmenu') diff --git a/builtin/mainmenu/pkgmgr.lua b/builtin/mainmenu/pkgmgr.lua index 5b8807310..bfb5d269a 100644 --- a/builtin/mainmenu/pkgmgr.lua +++ b/builtin/mainmenu/pkgmgr.lua @@ -72,6 +72,34 @@ local function cleanup_path(temppath) return temppath end +local function load_texture_packs(txtpath, retval) + local list = core.get_dir_list(txtpath, true) + local current_texture_path = core.settings:get("texture_path") + + for _, item in ipairs(list) do + if item ~= "base" then + local name = item + + local path = txtpath .. DIR_DELIM .. item .. DIR_DELIM + if path == current_texture_path then + name = fgettext("$1 (Enabled)", name) + end + + local conf = Settings(path .. "texture_pack.conf") + + retval[#retval + 1] = { + name = item, + author = conf:get("author"), + release = tonumber(conf:get("release") or "0"), + list_name = name, + type = "txp", + path = path, + enabled = path == current_texture_path, + } + end + end +end + function get_mods(path,retval,modpack) local mods = core.get_dir_list(path, true) @@ -112,7 +140,7 @@ function get_mods(path,retval,modpack) toadd.type = "mod" -- Check modpack.txt - -- Note: modpack.conf is already checked above + -- Note: modpack.conf is already checked above local modpackfile = io.open(prefix .. DIR_DELIM .. "modpack.txt") if modpackfile then modpackfile:close() @@ -136,32 +164,13 @@ pkgmgr = {} function pkgmgr.get_texture_packs() local txtpath = core.get_texturepath() - local list = core.get_dir_list(txtpath, true) + local txtpath_system = core.get_texturepath_share() local retval = {} - local current_texture_path = core.settings:get("texture_path") - - for _, item in ipairs(list) do - if item ~= "base" then - local name = item - - local path = txtpath .. DIR_DELIM .. item .. DIR_DELIM - if path == current_texture_path then - name = fgettext("$1 (Enabled)", name) - end - - local conf = Settings(path .. "texture_pack.conf") - - retval[#retval + 1] = { - name = item, - author = conf:get("author"), - release = tonumber(conf:get("release") or "0"), - list_name = name, - type = "txp", - path = path, - enabled = path == current_texture_path, - } - end + load_texture_packs(txtpath, retval) + -- on portable versions these two paths coincide. It avoids loading the path twice + if txtpath ~= txtpath_system then + load_texture_packs(txtpath_system, retval) end table.sort(retval, function(a, b) -- cgit v1.2.3 From 67aa75d444d0e5cfff2728dbbcffd6f95b2fe88b Mon Sep 17 00:00:00 2001 From: rubenwardy Date: Fri, 22 Jan 2021 15:08:57 +0000 Subject: Use JSON for favorites, move server list code to Lua (#10085) Co-authored-by: sfan5 --- builtin/mainmenu/common.lua | 53 ------ builtin/mainmenu/init.lua | 1 + builtin/mainmenu/serverlistmgr.lua | 241 ++++++++++++++++++++++++ builtin/mainmenu/tab_online.lua | 115 +++++------ builtin/mainmenu/tests/favorites_wellformed.txt | 29 +++ builtin/mainmenu/tests/serverlistmgr_spec.lua | 36 ++++ builtin/settingtypes.txt | 2 +- doc/menu_lua_api.txt | 26 --- minetest.conf.example | 2 +- src/client/clientlauncher.cpp | 8 - src/defaultsettings.cpp | 2 +- src/script/lua_api/l_mainmenu.cpp | 206 +------------------- src/script/lua_api/l_mainmenu.h | 4 - src/script/lua_api/l_util.cpp | 13 ++ src/script/lua_api/l_util.h | 3 + src/serverlist.cpp | 162 ---------------- src/serverlist.h | 13 -- 17 files changed, 388 insertions(+), 528 deletions(-) create mode 100644 builtin/mainmenu/serverlistmgr.lua create mode 100644 builtin/mainmenu/tests/favorites_wellformed.txt create mode 100644 builtin/mainmenu/tests/serverlistmgr_spec.lua (limited to 'builtin/mainmenu') diff --git a/builtin/mainmenu/common.lua b/builtin/mainmenu/common.lua index 2bd8aa8a5..01f9a30b9 100644 --- a/builtin/mainmenu/common.lua +++ b/builtin/mainmenu/common.lua @@ -62,24 +62,6 @@ function image_column(tooltip, flagname) "5=" .. core.formspec_escape(defaulttexturedir .. "server_ping_1.png") end --------------------------------------------------------------------------------- -function order_favorite_list(list) - local res = {} - --orders the favorite list after support - for i = 1, #list do - local fav = list[i] - if is_server_protocol_compat(fav.proto_min, fav.proto_max) then - res[#res + 1] = fav - end - end - for i = 1, #list do - local fav = list[i] - if not is_server_protocol_compat(fav.proto_min, fav.proto_max) then - res[#res + 1] = fav - end - end - return res -end -------------------------------------------------------------------------------- function render_serverlist_row(spec, is_favorite) @@ -226,41 +208,6 @@ function menu_handle_key_up_down(fields, textlist, settingname) return false end --------------------------------------------------------------------------------- -function asyncOnlineFavourites() - if not menudata.public_known then - menudata.public_known = {{ - name = fgettext("Loading..."), - description = fgettext_ne("Try reenabling public serverlist and check your internet connection.") - }} - end - menudata.favorites = menudata.public_known - menudata.favorites_is_public = true - - if not menudata.public_downloading then - menudata.public_downloading = true - else - return - end - - core.handle_async( - function(param) - return core.get_favorites("online") - end, - nil, - function(result) - menudata.public_downloading = nil - local favs = order_favorite_list(result) - if favs[1] then - menudata.public_known = favs - menudata.favorites = menudata.public_known - menudata.favorites_is_public = true - end - core.event_handler("Refresh") - end - ) -end - -------------------------------------------------------------------------------- function text2textlist(xpos, ypos, width, height, tl_name, textlen, text, transparency) local textlines = core.wrap_text(text, textlen, true) diff --git a/builtin/mainmenu/init.lua b/builtin/mainmenu/init.lua index 656d1d149..45089c7c9 100644 --- a/builtin/mainmenu/init.lua +++ b/builtin/mainmenu/init.lua @@ -34,6 +34,7 @@ dofile(basepath .. "fstk" .. DIR_DELIM .. "ui.lua") dofile(menupath .. DIR_DELIM .. "async_event.lua") dofile(menupath .. DIR_DELIM .. "common.lua") dofile(menupath .. DIR_DELIM .. "pkgmgr.lua") +dofile(menupath .. DIR_DELIM .. "serverlistmgr.lua") dofile(menupath .. DIR_DELIM .. "textures.lua") dofile(menupath .. DIR_DELIM .. "dlg_config_world.lua") diff --git a/builtin/mainmenu/serverlistmgr.lua b/builtin/mainmenu/serverlistmgr.lua new file mode 100644 index 000000000..d98736e54 --- /dev/null +++ b/builtin/mainmenu/serverlistmgr.lua @@ -0,0 +1,241 @@ +--Minetest +--Copyright (C) 2020 rubenwardy +-- +--This program is free software; you can redistribute it and/or modify +--it under the terms of the GNU Lesser General Public License as published by +--the Free Software Foundation; either version 2.1 of the License, or +--(at your option) any later version. +-- +--This program is distributed in the hope that it will be useful, +--but WITHOUT ANY WARRANTY; without even the implied warranty of +--MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +--GNU Lesser General Public License for more details. +-- +--You should have received a copy of the GNU Lesser General Public License along +--with this program; if not, write to the Free Software Foundation, Inc., +--51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +serverlistmgr = {} + +-------------------------------------------------------------------------------- +local function order_server_list(list) + local res = {} + --orders the favorite list after support + for i = 1, #list do + local fav = list[i] + if is_server_protocol_compat(fav.proto_min, fav.proto_max) then + res[#res + 1] = fav + end + end + for i = 1, #list do + local fav = list[i] + if not is_server_protocol_compat(fav.proto_min, fav.proto_max) then + res[#res + 1] = fav + end + end + return res +end + +local public_downloading = false + +-------------------------------------------------------------------------------- +function serverlistmgr.sync() + if not serverlistmgr.servers then + serverlistmgr.servers = {{ + name = fgettext("Loading..."), + description = fgettext_ne("Try reenabling public serverlist and check your internet connection.") + }} + end + + if public_downloading then + return + end + public_downloading = true + + core.handle_async( + function(param) + local http = core.get_http_api() + local url = ("%s/list?proto_version_min=%d&proto_version_max=%d"):format( + core.settings:get("serverlist_url"), + core.get_min_supp_proto(), + core.get_max_supp_proto()) + + local response = http.fetch_sync({ url = url }) + if not response.succeeded then + return {} + end + + local retval = core.parse_json(response.data) + return retval and retval.list or {} + end, + nil, + function(result) + public_downloading = nil + local favs = order_server_list(result) + if favs[1] then + serverlistmgr.servers = favs + end + core.event_handler("Refresh") + end + ) +end + +-------------------------------------------------------------------------------- +local function get_favorites_path() + local base = core.get_user_path() .. DIR_DELIM .. "client" .. DIR_DELIM .. "serverlist" .. DIR_DELIM + return base .. core.settings:get("serverlist_file") +end + +-------------------------------------------------------------------------------- +local function save_favorites(favorites) + local filename = core.settings:get("serverlist_file") + -- If setting specifies legacy format change the filename to the new one + if filename:sub(#filename - 3):lower() == ".txt" then + core.settings:set("serverlist_file", filename:sub(1, #filename - 4) .. ".json") + end + + local path = get_favorites_path() + core.create_dir(path) + core.safe_file_write(path, core.write_json(favorites)) +end + +-------------------------------------------------------------------------------- +function serverlistmgr.read_legacy_favorites(path) + local file = io.open(path, "r") + if not file then + return nil + end + + local lines = {} + for line in file:lines() do + lines[#lines + 1] = line + end + file:close() + + local favorites = {} + + local i = 1 + while i < #lines do + local function pop() + local line = lines[i] + i = i + 1 + return line and line:trim() + end + + if pop():lower() == "[server]" then + local name = pop() + local address = pop() + local port = tonumber(pop()) + local description = pop() + + if name == "" then + name = nil + end + + if description == "" then + description = nil + end + + if not address or #address < 3 then + core.log("warning", "Malformed favorites file, missing address at line " .. i) + elseif not port or port < 1 or port > 65535 then + core.log("warning", "Malformed favorites file, missing port at line " .. i) + elseif (name and name:upper() == "[SERVER]") or + (address and address:upper() == "[SERVER]") or + (description and description:upper() == "[SERVER]") then + core.log("warning", "Potentially malformed favorites file, overran at line " .. i) + else + favorites[#favorites + 1] = { + name = name, + address = address, + port = port, + description = description + } + end + end + end + + return favorites +end + +-------------------------------------------------------------------------------- +local function read_favorites() + local path = get_favorites_path() + + -- If new format configured fall back to reading the legacy file + if path:sub(#path - 4):lower() == ".json" then + local file = io.open(path, "r") + if file then + local json = file:read("*all") + file:close() + return core.parse_json(json) + end + + path = path:sub(1, #path - 5) .. ".txt" + end + + local favs = serverlistmgr.read_legacy_favorites(path) + if favs then + save_favorites(favs) + os.remove(path) + end + return favs +end + +-------------------------------------------------------------------------------- +local function delete_favorite(favorites, del_favorite) + for i=1, #favorites do + local fav = favorites[i] + + if fav.address == del_favorite.address and fav.port == del_favorite.port then + table.remove(favorites, i) + return + end + end +end + +-------------------------------------------------------------------------------- +function serverlistmgr.get_favorites() + if serverlistmgr.favorites then + return serverlistmgr.favorites + end + + serverlistmgr.favorites = {} + + -- Add favorites, removing duplicates + local seen = {} + for _, fav in ipairs(read_favorites() or {}) do + local key = ("%s:%d"):format(fav.address:lower(), fav.port) + if not seen[key] then + seen[key] = true + serverlistmgr.favorites[#serverlistmgr.favorites + 1] = fav + end + end + + return serverlistmgr.favorites +end + +-------------------------------------------------------------------------------- +function serverlistmgr.add_favorite(new_favorite) + assert(type(new_favorite.port) == "number") + + -- Whitelist favorite keys + new_favorite = { + name = new_favorite.name, + address = new_favorite.address, + port = new_favorite.port, + description = new_favorite.description, + } + + local favorites = serverlistmgr.get_favorites() + delete_favorite(favorites, new_favorite) + table.insert(favorites, 1, new_favorite) + save_favorites(favorites) +end + +-------------------------------------------------------------------------------- +function serverlistmgr.delete_favorite(del_favorite) + local favorites = serverlistmgr.get_favorites() + delete_favorite(favorites, del_favorite) + save_favorites(favorites) +end diff --git a/builtin/mainmenu/tab_online.lua b/builtin/mainmenu/tab_online.lua index 8f1341161..e6748ed88 100644 --- a/builtin/mainmenu/tab_online.lua +++ b/builtin/mainmenu/tab_online.lua @@ -20,11 +20,11 @@ local function get_formspec(tabview, name, tabdata) -- Update the cached supported proto info, -- it may have changed after a change by the settings menu. common_update_cached_supp_proto() - local fav_selected + local selected if menudata.search_result then - fav_selected = menudata.search_result[tabdata.fav_selected] + selected = menudata.search_result[tabdata.selected] else - fav_selected = menudata.favorites[tabdata.fav_selected] + selected = serverlistmgr.servers[tabdata.selected] end if not tabdata.search_for then @@ -58,18 +58,18 @@ local function get_formspec(tabview, name, tabdata) -- Connect "button[9.88,4.9;2.3,1;btn_mp_connect;" .. fgettext("Connect") .. "]" - if tabdata.fav_selected and fav_selected then + if tabdata.selected and selected then if gamedata.fav then retval = retval .. "button[7.73,4.9;2.3,1;btn_delete_favorite;" .. fgettext("Del. Favorite") .. "]" end - if fav_selected.description then + if selected.description then retval = retval .. "textarea[8.1,2.3;4.23,2.9;;;" .. core.formspec_escape((gamedata.serverdescription or ""), true) .. "]" end end - --favourites + --favorites retval = retval .. "tablecolumns[" .. image_column(fgettext("Favorite"), "favorite") .. ";" .. image_column(fgettext("Ping")) .. ",padding=0.25;" .. @@ -83,13 +83,12 @@ local function get_formspec(tabview, name, tabdata) image_column(fgettext("PvP enabled"), "pvp") .. ",padding=0.25;" .. "color,span=1;" .. "text,padding=1]" .. - "table[-0.15,0.6;7.75,5.15;favourites;" + "table[-0.15,0.6;7.75,5.15;favorites;" if menudata.search_result then + local favs = serverlistmgr.get_favorites() for i = 1, #menudata.search_result do - local favs = core.get_favorites("local") local server = menudata.search_result[i] - for fav_id = 1, #favs do if server.address == favs[fav_id].address and server.port == favs[fav_id].port then @@ -103,29 +102,30 @@ local function get_formspec(tabview, name, tabdata) retval = retval .. render_serverlist_row(server, server.is_favorite) end - elseif #menudata.favorites > 0 then - local favs = core.get_favorites("local") + elseif #serverlistmgr.servers > 0 then + local favs = serverlistmgr.get_favorites() if #favs > 0 then for i = 1, #favs do - for j = 1, #menudata.favorites do - if menudata.favorites[j].address == favs[i].address and - menudata.favorites[j].port == favs[i].port then - table.insert(menudata.favorites, i, table.remove(menudata.favorites, j)) + for j = 1, #serverlistmgr.servers do + if serverlistmgr.servers[j].address == favs[i].address and + serverlistmgr.servers[j].port == favs[i].port then + table.insert(serverlistmgr.servers, i, table.remove(serverlistmgr.servers, j)) + end end - end - if favs[i].address ~= menudata.favorites[i].address then - table.insert(menudata.favorites, i, favs[i]) + if favs[i].address ~= serverlistmgr.servers[i].address then + table.insert(serverlistmgr.servers, i, favs[i]) end end end - retval = retval .. render_serverlist_row(menudata.favorites[1], (#favs > 0)) - for i = 2, #menudata.favorites do - retval = retval .. "," .. render_serverlist_row(menudata.favorites[i], (i <= #favs)) + + retval = retval .. render_serverlist_row(serverlistmgr.servers[1], (#favs > 0)) + for i = 2, #serverlistmgr.servers do + retval = retval .. "," .. render_serverlist_row(serverlistmgr.servers[i], (i <= #favs)) end end - if tabdata.fav_selected then - retval = retval .. ";" .. tabdata.fav_selected .. "]" + if tabdata.selected then + retval = retval .. ";" .. tabdata.selected .. "]" else retval = retval .. ";0]" end @@ -135,21 +135,20 @@ end -------------------------------------------------------------------------------- local function main_button_handler(tabview, fields, name, tabdata) - local serverlist = menudata.search_result or menudata.favorites + local serverlist = menudata.search_result or serverlistmgr.servers if fields.te_name then gamedata.playername = fields.te_name core.settings:set("name", fields.te_name) end - if fields.favourites then - local event = core.explode_table_event(fields.favourites) + if fields.favorites then + local event = core.explode_table_event(fields.favorites) local fav = serverlist[event.row] if event.type == "DCL" then if event.row <= #serverlist then - if menudata.favorites_is_public and - not is_server_protocol_compat_or_error( + if not is_server_protocol_compat_or_error( fav.proto_min, fav.proto_max) then return true end @@ -178,7 +177,7 @@ local function main_button_handler(tabview, fields, name, tabdata) if event.type == "CHG" then if event.row <= #serverlist then gamedata.fav = false - local favs = core.get_favorites("local") + local favs = serverlistmgr.get_favorites() local address = fav.address local port = fav.port gamedata.serverdescription = fav.description @@ -194,28 +193,28 @@ local function main_button_handler(tabview, fields, name, tabdata) core.settings:set("address", address) core.settings:set("remote_port", port) end - tabdata.fav_selected = event.row + tabdata.selected = event.row end return true end end if fields.key_up or fields.key_down then - local fav_idx = core.get_table_index("favourites") + local fav_idx = core.get_table_index("favorites") local fav = serverlist[fav_idx] if fav_idx then if fields.key_up and fav_idx > 1 then fav_idx = fav_idx - 1 - elseif fields.key_down and fav_idx < #menudata.favorites then + elseif fields.key_down and fav_idx < #serverlistmgr.servers then fav_idx = fav_idx + 1 end else fav_idx = 1 end - if not menudata.favorites or not fav then - tabdata.fav_selected = 0 + if not serverlistmgr.servers or not fav then + tabdata.selected = 0 return true end @@ -227,17 +226,17 @@ local function main_button_handler(tabview, fields, name, tabdata) core.settings:set("remote_port", port) end - tabdata.fav_selected = fav_idx + tabdata.selected = fav_idx return true end if fields.btn_delete_favorite then - local current_favourite = core.get_table_index("favourites") - if not current_favourite then return end + local current_favorite = core.get_table_index("favorites") + if not current_favorite then return end - core.delete_favorite(current_favourite) - asyncOnlineFavourites() - tabdata.fav_selected = nil + serverlistmgr.delete_favorite(serverlistmgr.servers[current_favorite]) + serverlistmgr.sync() + tabdata.selected = nil core.settings:set("address", "") core.settings:set("remote_port", "30000") @@ -251,11 +250,11 @@ local function main_button_handler(tabview, fields, name, tabdata) end if fields.btn_mp_search or fields.key_enter_field == "te_search" then - tabdata.fav_selected = 1 + tabdata.selected = 1 local input = fields.te_search:lower() tabdata.search_for = fields.te_search - if #menudata.favorites < 2 then + if #serverlistmgr.servers < 2 then return true end @@ -275,8 +274,8 @@ local function main_button_handler(tabview, fields, name, tabdata) -- Search the serverlist local search_result = {} - for i = 1, #menudata.favorites do - local server = menudata.favorites[i] + for i = 1, #serverlistmgr.servers do + local server = serverlistmgr.servers[i] local found = 0 for k = 1, #keywords do local keyword = keywords[k] @@ -293,7 +292,7 @@ local function main_button_handler(tabview, fields, name, tabdata) end end if found > 0 then - local points = (#menudata.favorites - i) / 5 + found + local points = (#serverlistmgr.servers - i) / 5 + found server.points = points table.insert(search_result, server) end @@ -312,7 +311,7 @@ local function main_button_handler(tabview, fields, name, tabdata) end if fields.btn_mp_refresh then - asyncOnlineFavourites() + serverlistmgr.sync() return true end @@ -321,30 +320,36 @@ local function main_button_handler(tabview, fields, name, tabdata) gamedata.playername = fields.te_name gamedata.password = fields.te_pwd gamedata.address = fields.te_address - gamedata.port = fields.te_port + gamedata.port = tonumber(fields.te_port) gamedata.selected_world = 0 - local fav_idx = core.get_table_index("favourites") + local fav_idx = core.get_table_index("favorites") local fav = serverlist[fav_idx] if fav_idx and fav_idx <= #serverlist and - fav.address == fields.te_address and - fav.port == fields.te_port then + fav.address == gamedata.address and + fav.port == gamedata.port then + + serverlistmgr.add_favorite(fav) gamedata.servername = fav.name gamedata.serverdescription = fav.description - if menudata.favorites_is_public and - not is_server_protocol_compat_or_error( + if not is_server_protocol_compat_or_error( fav.proto_min, fav.proto_max) then return true end else gamedata.servername = "" gamedata.serverdescription = "" + + serverlistmgr.add_favorite({ + address = gamedata.address, + port = gamedata.port, + }) end - core.settings:set("address", fields.te_address) - core.settings:set("remote_port", fields.te_port) + core.settings:set("address", gamedata.address) + core.settings:set("remote_port", gamedata.port) core.start() return true @@ -354,7 +359,7 @@ end local function on_change(type, old_tab, new_tab) if type == "LEAVE" then return end - asyncOnlineFavourites() + serverlistmgr.sync() end -------------------------------------------------------------------------------- diff --git a/builtin/mainmenu/tests/favorites_wellformed.txt b/builtin/mainmenu/tests/favorites_wellformed.txt new file mode 100644 index 000000000..8b87b4398 --- /dev/null +++ b/builtin/mainmenu/tests/favorites_wellformed.txt @@ -0,0 +1,29 @@ +[server] + +127.0.0.1 +30000 + + +[server] + +localhost +30000 + + +[server] + +vps.rubenwardy.com +30001 + + +[server] + +gundul.ddnss.de +39155 + + +[server] +VanessaE's Dreambuilder creative Server +daconcepts.com +30000 +VanessaE's Dreambuilder creative-mode server. Lots of mods, whitelisted buckets. diff --git a/builtin/mainmenu/tests/serverlistmgr_spec.lua b/builtin/mainmenu/tests/serverlistmgr_spec.lua new file mode 100644 index 000000000..148e9b794 --- /dev/null +++ b/builtin/mainmenu/tests/serverlistmgr_spec.lua @@ -0,0 +1,36 @@ +_G.core = {} +_G.unpack = table.unpack +_G.serverlistmgr = {} + +dofile("builtin/common/misc_helpers.lua") +dofile("builtin/mainmenu/serverlistmgr.lua") + +local base = "builtin/mainmenu/tests/" + +describe("legacy favorites", function() + it("loads well-formed correctly", function() + local favs = serverlistmgr.read_legacy_favorites(base .. "favorites_wellformed.txt") + + local expected = { + { + address = "127.0.0.1", + port = 30000, + }, + + { address = "localhost", port = 30000 }, + + { address = "vps.rubenwardy.com", port = 30001 }, + + { address = "gundul.ddnss.de", port = 39155 }, + + { + address = "daconcepts.com", + port = 30000, + name = "VanessaE's Dreambuilder creative Server", + description = "VanessaE's Dreambuilder creative-mode server. Lots of mods, whitelisted buckets." + }, + } + + assert.same(expected, favs) + end) +end) diff --git a/builtin/settingtypes.txt b/builtin/settingtypes.txt index 7e23b5641..21118134e 100644 --- a/builtin/settingtypes.txt +++ b/builtin/settingtypes.txt @@ -964,7 +964,7 @@ serverlist_url (Serverlist URL) string servers.minetest.net # File in client/serverlist/ that contains your favorite servers displayed in the # Multiplayer Tab. -serverlist_file (Serverlist file) string favoriteservers.txt +serverlist_file (Serverlist file) string favoriteservers.json # Maximum size of the out chat queue. # 0 to disable queueing and -1 to make the queue size unlimited. diff --git a/doc/menu_lua_api.txt b/doc/menu_lua_api.txt index 1bcf697e9..db49c1736 100644 --- a/doc/menu_lua_api.txt +++ b/doc/menu_lua_api.txt @@ -253,32 +253,6 @@ Package - content which is downloadable from the content db, may or may not be i } -Favorites ---------- - -core.get_favorites(location) -> list of favorites (possible in async calls) -^ location: "local" or "online" -^ returns { - [1] = { - clients = , - clients_max = , - version = , - password = , - creative = , - damage = , - pvp = , - description = , - name = , - address =
, - port = - clients_list = - mods = - }, - ... -} -core.delete_favorite(id, location) -> success - - Logging ------- diff --git a/minetest.conf.example b/minetest.conf.example index 086339037..3bb357813 100644 --- a/minetest.conf.example +++ b/minetest.conf.example @@ -1160,7 +1160,7 @@ # File in client/serverlist/ that contains your favorite servers displayed in the # Multiplayer Tab. # type: string -# serverlist_file = favoriteservers.txt +# serverlist_file = favoriteservers.json # Maximum size of the out chat queue. # 0 to disable queueing and -1 to make the queue size unlimited. diff --git a/src/client/clientlauncher.cpp b/src/client/clientlauncher.cpp index 29427f609..7245f29f0 100644 --- a/src/client/clientlauncher.cpp +++ b/src/client/clientlauncher.cpp @@ -487,14 +487,6 @@ bool ClientLauncher::launch_game(std::string &error_message, start_data.socket_port = myrand_range(49152, 65535); } else { g_settings->set("name", start_data.name); - if (!start_data.address.empty()) { - ServerListSpec server; - server["name"] = server_name; - server["address"] = start_data.address; - server["port"] = itos(start_data.socket_port); - server["description"] = server_description; - ServerList::insert(server); - } } if (start_data.name.length() > PLAYERNAME_SIZE - 1) { diff --git a/src/defaultsettings.cpp b/src/defaultsettings.cpp index e8fb18e05..114351d86 100644 --- a/src/defaultsettings.cpp +++ b/src/defaultsettings.cpp @@ -283,7 +283,7 @@ void set_default_settings(Settings *settings) // Main menu settings->setDefault("main_menu_path", ""); - settings->setDefault("serverlist_file", "favoriteservers.txt"); + settings->setDefault("serverlist_file", "favoriteservers.json"); #if USE_FREETYPE settings->setDefault("freetype", "true"); diff --git a/src/script/lua_api/l_mainmenu.cpp b/src/script/lua_api/l_mainmenu.cpp index 5070ec7d4..4733c4003 100644 --- a/src/script/lua_api/l_mainmenu.cpp +++ b/src/script/lua_api/l_mainmenu.cpp @@ -274,207 +274,6 @@ int ModApiMainMenu::l_get_worlds(lua_State *L) return 1; } -/******************************************************************************/ -int ModApiMainMenu::l_get_favorites(lua_State *L) -{ - std::string listtype = "local"; - - if (!lua_isnone(L, 1)) { - listtype = luaL_checkstring(L, 1); - } - - std::vector servers; - - if(listtype == "online") { - servers = ServerList::getOnline(); - } else { - servers = ServerList::getLocal(); - } - - lua_newtable(L); - int top = lua_gettop(L); - unsigned int index = 1; - - for (const Json::Value &server : servers) { - - lua_pushnumber(L, index); - - lua_newtable(L); - int top_lvl2 = lua_gettop(L); - - if (!server["clients"].asString().empty()) { - std::string clients_raw = server["clients"].asString(); - char* endptr = 0; - int numbervalue = strtol(clients_raw.c_str(), &endptr,10); - - if ((!clients_raw.empty()) && (*endptr == 0)) { - lua_pushstring(L, "clients"); - lua_pushnumber(L, numbervalue); - lua_settable(L, top_lvl2); - } - } - - if (!server["clients_max"].asString().empty()) { - - std::string clients_max_raw = server["clients_max"].asString(); - char* endptr = 0; - int numbervalue = strtol(clients_max_raw.c_str(), &endptr,10); - - if ((!clients_max_raw.empty()) && (*endptr == 0)) { - lua_pushstring(L, "clients_max"); - lua_pushnumber(L, numbervalue); - lua_settable(L, top_lvl2); - } - } - - if (!server["version"].asString().empty()) { - lua_pushstring(L, "version"); - std::string topush = server["version"].asString(); - lua_pushstring(L, topush.c_str()); - lua_settable(L, top_lvl2); - } - - if (!server["proto_min"].asString().empty()) { - lua_pushstring(L, "proto_min"); - lua_pushinteger(L, server["proto_min"].asInt()); - lua_settable(L, top_lvl2); - } - - if (!server["proto_max"].asString().empty()) { - lua_pushstring(L, "proto_max"); - lua_pushinteger(L, server["proto_max"].asInt()); - lua_settable(L, top_lvl2); - } - - if (!server["password"].asString().empty()) { - lua_pushstring(L, "password"); - lua_pushboolean(L, server["password"].asBool()); - lua_settable(L, top_lvl2); - } - - if (!server["creative"].asString().empty()) { - lua_pushstring(L, "creative"); - lua_pushboolean(L, server["creative"].asBool()); - lua_settable(L, top_lvl2); - } - - if (!server["damage"].asString().empty()) { - lua_pushstring(L, "damage"); - lua_pushboolean(L, server["damage"].asBool()); - lua_settable(L, top_lvl2); - } - - if (!server["pvp"].asString().empty()) { - lua_pushstring(L, "pvp"); - lua_pushboolean(L, server["pvp"].asBool()); - lua_settable(L, top_lvl2); - } - - if (!server["description"].asString().empty()) { - lua_pushstring(L, "description"); - std::string topush = server["description"].asString(); - lua_pushstring(L, topush.c_str()); - lua_settable(L, top_lvl2); - } - - if (!server["name"].asString().empty()) { - lua_pushstring(L, "name"); - std::string topush = server["name"].asString(); - lua_pushstring(L, topush.c_str()); - lua_settable(L, top_lvl2); - } - - if (!server["address"].asString().empty()) { - lua_pushstring(L, "address"); - std::string topush = server["address"].asString(); - lua_pushstring(L, topush.c_str()); - lua_settable(L, top_lvl2); - } - - if (!server["port"].asString().empty()) { - lua_pushstring(L, "port"); - std::string topush = server["port"].asString(); - lua_pushstring(L, topush.c_str()); - lua_settable(L, top_lvl2); - } - - if (server.isMember("ping")) { - float ping = server["ping"].asFloat(); - lua_pushstring(L, "ping"); - lua_pushnumber(L, ping); - lua_settable(L, top_lvl2); - } - - if (server["clients_list"].isArray()) { - unsigned int index_lvl2 = 1; - lua_pushstring(L, "clients_list"); - lua_newtable(L); - int top_lvl3 = lua_gettop(L); - for (const Json::Value &client : server["clients_list"]) { - lua_pushnumber(L, index_lvl2); - std::string topush = client.asString(); - lua_pushstring(L, topush.c_str()); - lua_settable(L, top_lvl3); - index_lvl2++; - } - lua_settable(L, top_lvl2); - } - - if (server["mods"].isArray()) { - unsigned int index_lvl2 = 1; - lua_pushstring(L, "mods"); - lua_newtable(L); - int top_lvl3 = lua_gettop(L); - for (const Json::Value &mod : server["mods"]) { - - lua_pushnumber(L, index_lvl2); - std::string topush = mod.asString(); - lua_pushstring(L, topush.c_str()); - lua_settable(L, top_lvl3); - index_lvl2++; - } - lua_settable(L, top_lvl2); - } - - lua_settable(L, top); - index++; - } - return 1; -} - -/******************************************************************************/ -int ModApiMainMenu::l_delete_favorite(lua_State *L) -{ - std::vector servers; - - std::string listtype = "local"; - - if (!lua_isnone(L,2)) { - listtype = luaL_checkstring(L,2); - } - - if ((listtype != "local") && - (listtype != "online")) - return 0; - - - if(listtype == "online") { - servers = ServerList::getOnline(); - } else { - servers = ServerList::getLocal(); - } - - int fav_idx = luaL_checkinteger(L,1) -1; - - if ((fav_idx >= 0) && - (fav_idx < (int) servers.size())) { - - ServerList::deleteEntry(servers[fav_idx]); - } - - return 0; -} - /******************************************************************************/ int ModApiMainMenu::l_get_games(lua_State *L) { @@ -1130,11 +929,9 @@ void ModApiMainMenu::Initialize(lua_State *L, int top) API_FCT(get_content_info); API_FCT(start); API_FCT(close); - API_FCT(get_favorites); API_FCT(show_keys_menu); API_FCT(create_world); API_FCT(delete_world); - API_FCT(delete_favorite); API_FCT(set_background); API_FCT(set_topleft_text); API_FCT(get_mapgen_names); @@ -1170,7 +967,6 @@ void ModApiMainMenu::InitializeAsync(lua_State *L, int top) { API_FCT(get_worlds); API_FCT(get_games); - API_FCT(get_favorites); API_FCT(get_mapgen_names); API_FCT(get_user_path); API_FCT(get_modpath); @@ -1186,5 +982,7 @@ void ModApiMainMenu::InitializeAsync(lua_State *L, int top) //API_FCT(extract_zip); //TODO remove dependency to GuiEngine API_FCT(may_modify_path); API_FCT(download_file); + API_FCT(get_min_supp_proto); + API_FCT(get_max_supp_proto); //API_FCT(gettext); (gettext lib isn't threadsafe) } diff --git a/src/script/lua_api/l_mainmenu.h b/src/script/lua_api/l_mainmenu.h index 0b02ed892..580a0df72 100644 --- a/src/script/lua_api/l_mainmenu.h +++ b/src/script/lua_api/l_mainmenu.h @@ -74,10 +74,6 @@ private: static int l_get_mapgen_names(lua_State *L); - static int l_get_favorites(lua_State *L); - - static int l_delete_favorite(lua_State *L); - static int l_gettext(lua_State *L); //packages diff --git a/src/script/lua_api/l_util.cpp b/src/script/lua_api/l_util.cpp index 6490eb578..203a0dd28 100644 --- a/src/script/lua_api/l_util.cpp +++ b/src/script/lua_api/l_util.cpp @@ -250,6 +250,17 @@ int ModApiUtil::l_get_builtin_path(lua_State *L) return 1; } +// get_user_path() +int ModApiUtil::l_get_user_path(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + + std::string path = porting::path_user; + lua_pushstring(L, path.c_str()); + + return 1; +} + // compress(data, method, level) int ModApiUtil::l_compress(lua_State *L) { @@ -486,6 +497,7 @@ void ModApiUtil::Initialize(lua_State *L, int top) API_FCT(is_yes); API_FCT(get_builtin_path); + API_FCT(get_user_path); API_FCT(compress); API_FCT(decompress); @@ -539,6 +551,7 @@ void ModApiUtil::InitializeAsync(lua_State *L, int top) API_FCT(is_yes); API_FCT(get_builtin_path); + API_FCT(get_user_path); API_FCT(compress); API_FCT(decompress); diff --git a/src/script/lua_api/l_util.h b/src/script/lua_api/l_util.h index b6c1b58af..dbdd62b99 100644 --- a/src/script/lua_api/l_util.h +++ b/src/script/lua_api/l_util.h @@ -68,6 +68,9 @@ private: // get_builtin_path() static int l_get_builtin_path(lua_State *L); + // get_user_path() + static int l_get_user_path(lua_State *L); + // compress(data, method, ...) static int l_compress(lua_State *L); diff --git a/src/serverlist.cpp b/src/serverlist.cpp index 80a8c2f1a..3bcab3d58 100644 --- a/src/serverlist.cpp +++ b/src/serverlist.cpp @@ -17,181 +17,19 @@ with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ -#include #include -#include -#include - #include "version.h" #include "settings.h" #include "serverlist.h" #include "filesys.h" -#include "porting.h" #include "log.h" #include "network/networkprotocol.h" #include #include "convert_json.h" #include "httpfetch.h" -#include "util/string.h" namespace ServerList { - -std::string getFilePath() -{ - std::string serverlist_file = g_settings->get("serverlist_file"); - - std::string dir_path = "client" DIR_DELIM "serverlist" DIR_DELIM; - fs::CreateDir(porting::path_user + DIR_DELIM "client"); - fs::CreateDir(porting::path_user + DIR_DELIM + dir_path); - return porting::path_user + DIR_DELIM + dir_path + serverlist_file; -} - - -std::vector getLocal() -{ - std::string path = ServerList::getFilePath(); - std::string liststring; - fs::ReadFile(path, liststring); - - return deSerialize(liststring); -} - - -std::vector getOnline() -{ - std::ostringstream geturl; - - u16 proto_version_min = CLIENT_PROTOCOL_VERSION_MIN; - - geturl << g_settings->get("serverlist_url") << - "/list?proto_version_min=" << proto_version_min << - "&proto_version_max=" << CLIENT_PROTOCOL_VERSION_MAX; - Json::Value root = fetchJsonValue(geturl.str(), NULL); - - std::vector server_list; - - if (!root.isObject()) { - return server_list; - } - - root = root["list"]; - if (!root.isArray()) { - return server_list; - } - - for (const Json::Value &i : root) { - if (i.isObject()) { - server_list.push_back(i); - } - } - - return server_list; -} - - -// Delete a server from the local favorites list -bool deleteEntry(const ServerListSpec &server) -{ - std::vector serverlist = ServerList::getLocal(); - for (std::vector::iterator it = serverlist.begin(); - it != serverlist.end();) { - if ((*it)["address"] == server["address"] && - (*it)["port"] == server["port"]) { - it = serverlist.erase(it); - } else { - ++it; - } - } - - std::string path = ServerList::getFilePath(); - std::ostringstream ss(std::ios_base::binary); - ss << ServerList::serialize(serverlist); - if (!fs::safeWriteToFile(path, ss.str())) - return false; - return true; -} - -// Insert a server to the local favorites list -bool insert(const ServerListSpec &server) -{ - // Remove duplicates - ServerList::deleteEntry(server); - - std::vector serverlist = ServerList::getLocal(); - - // Insert new server at the top of the list - serverlist.insert(serverlist.begin(), server); - - std::string path = ServerList::getFilePath(); - std::ostringstream ss(std::ios_base::binary); - ss << ServerList::serialize(serverlist); - if (!fs::safeWriteToFile(path, ss.str())) - return false; - - return true; -} - -std::vector deSerialize(const std::string &liststring) -{ - std::vector serverlist; - std::istringstream stream(liststring); - std::string line, tmp; - while (std::getline(stream, line)) { - std::transform(line.begin(), line.end(), line.begin(), ::toupper); - if (line == "[SERVER]") { - ServerListSpec server; - std::getline(stream, tmp); - server["name"] = tmp; - std::getline(stream, tmp); - server["address"] = tmp; - std::getline(stream, tmp); - server["port"] = tmp; - bool unique = true; - for (const ServerListSpec &added : serverlist) { - if (server["name"] == added["name"] - && server["port"] == added["port"]) { - unique = false; - break; - } - } - if (!unique) - continue; - std::getline(stream, tmp); - server["description"] = tmp; - serverlist.push_back(server); - } - } - return serverlist; -} - -const std::string serialize(const std::vector &serverlist) -{ - std::string liststring; - for (const ServerListSpec &it : serverlist) { - liststring += "[server]\n"; - liststring += it["name"].asString() + '\n'; - liststring += it["address"].asString() + '\n'; - liststring += it["port"].asString() + '\n'; - liststring += it["description"].asString() + '\n'; - liststring += '\n'; - } - return liststring; -} - -const std::string serializeJson(const std::vector &serverlist) -{ - Json::Value root; - Json::Value list(Json::arrayValue); - for (const ServerListSpec &it : serverlist) { - list.append(it); - } - root["list"] = list; - - return fastWriteJson(root); -} - - #if USE_CURL void sendAnnounce(AnnounceAction action, const u16 port, diff --git a/src/serverlist.h b/src/serverlist.h index 2b82b7431..4a0bd5efa 100644 --- a/src/serverlist.h +++ b/src/serverlist.h @@ -24,21 +24,8 @@ with this program; if not, write to the Free Software Foundation, Inc., #pragma once -typedef Json::Value ServerListSpec; - namespace ServerList { -std::vector getLocal(); -std::vector getOnline(); - -bool deleteEntry(const ServerListSpec &server); -bool insert(const ServerListSpec &server); - -std::vector deSerialize(const std::string &liststring); -const std::string serialize(const std::vector &serverlist); -std::vector deSerializeJson(const std::string &liststring); -const std::string serializeJson(const std::vector &serverlist); - #if USE_CURL enum AnnounceAction {AA_START, AA_UPDATE, AA_DELETE}; void sendAnnounce(AnnounceAction, u16 port, -- cgit v1.2.3 From 82deed2d7d5573f1fa463516732475563da59569 Mon Sep 17 00:00:00 2001 From: rubenwardy Date: Thu, 28 Jan 2021 11:24:36 +0000 Subject: ContentDB: Order installed content first (#10864) --- builtin/mainmenu/dlg_contentstore.lua | 36 +++++++++++++++++++++++++++++++++-- 1 file changed, 34 insertions(+), 2 deletions(-) (limited to 'builtin/mainmenu') diff --git a/builtin/mainmenu/dlg_contentstore.lua b/builtin/mainmenu/dlg_contentstore.lua index 3ad9ed28a..7328f3358 100644 --- a/builtin/mainmenu/dlg_contentstore.lua +++ b/builtin/mainmenu/dlg_contentstore.lua @@ -23,7 +23,9 @@ if not minetest.get_http_api then return end -local store = { packages = {}, packages_full = {} } +-- Unordered preserves the original order of the ContentDB API, +-- before the package list is ordered based on installed state. +local store = { packages = {}, packages_full = {}, packages_full_unordered = {} } local http = minetest.get_http_api() @@ -572,6 +574,7 @@ function store.load() end end + store.packages_full_unordered = store.packages_full store.packages = store.packages_full store.loaded = true end @@ -619,6 +622,33 @@ function store.update_paths() end end +function store.sort_packages() + local ret = {} + + -- Add installed content + for i=1, #store.packages_full_unordered do + local package = store.packages_full_unordered[i] + if package.path then + ret[#ret + 1] = package + end + end + + -- Sort installed content by title + table.sort(ret, function(a, b) + return a.title < b.title + end) + + -- Add uninstalled content + for i=1, #store.packages_full_unordered do + local package = store.packages_full_unordered[i] + if not package.path then + ret[#ret + 1] = package + end + end + + store.packages_full = ret +end + function store.filter_packages(query) if query == "" and filter_type == 1 then store.packages = store.packages_full @@ -652,7 +682,6 @@ function store.filter_packages(query) store.packages[#store.packages + 1] = package end end - end function store.get_formspec(dlgdata) @@ -960,6 +989,9 @@ function create_store_dlg(type) store.load() end + store.update_paths() + store.sort_packages() + search_string = "" cur_page = 1 -- cgit v1.2.3 From 3a8c37181a9bf9624f3243e8e884f12ae7692609 Mon Sep 17 00:00:00 2001 From: rubenwardy Date: Sun, 7 Feb 2021 15:27:24 +0000 Subject: Use consistent temp folder path (#10892) --- builtin/mainmenu/common.lua | 36 ++++++++---------------------------- doc/menu_lua_api.txt | 1 + src/defaultsettings.cpp | 1 - src/filesys.cpp | 6 ++---- src/script/lua_api/l_mainmenu.cpp | 11 +++++++++++ src/script/lua_api/l_mainmenu.h | 2 ++ 6 files changed, 24 insertions(+), 33 deletions(-) (limited to 'builtin/mainmenu') diff --git a/builtin/mainmenu/common.lua b/builtin/mainmenu/common.lua index 01f9a30b9..cd896f9ec 100644 --- a/builtin/mainmenu/common.lua +++ b/builtin/mainmenu/common.lua @@ -146,35 +146,15 @@ end -------------------------------------------------------------------------------- os.tempfolder = function() - if core.settings:get("TMPFolder") then - return core.settings:get("TMPFolder") .. DIR_DELIM .. "MT_" .. math.random(0,10000) - end - - local filetocheck = os.tmpname() - os.remove(filetocheck) - - -- luacheck: ignore - -- https://blogs.msdn.microsoft.com/vcblog/2014/06/18/c-runtime-crt-features-fixes-and-breaking-changes-in-visual-studio-14-ctp1/ - -- The C runtime (CRT) function called by os.tmpname is tmpnam. - -- Microsofts tmpnam implementation in older CRT / MSVC releases is defective. - -- tmpnam return values starting with a backslash characterize this behavior. - -- https://sourceforge.net/p/mingw-w64/bugs/555/ - -- MinGW tmpnam implementation is forwarded to the CRT directly. - -- https://sourceforge.net/p/mingw-w64/discussion/723797/thread/55520785/ - -- MinGW links to an older CRT release (msvcrt.dll). - -- Due to legal concerns MinGW will never use a newer CRT. - -- - -- Make use of TEMP to compose the temporary filename if an old - -- style tmpnam return value is detected. - if filetocheck:sub(1, 1) == "\\" then - local tempfolder = os.getenv("TEMP") - return tempfolder .. filetocheck - end + local temp = core.get_temp_path() + return temp .. DIR_DELIM .. "MT_" .. math.random(0, 10000) +end - local randname = "MTTempModFolder_" .. math.random(0,10000) - local backstring = filetocheck:reverse() - return filetocheck:sub(0, filetocheck:len() - backstring:find(DIR_DELIM) + 1) .. - randname +-------------------------------------------------------------------------------- +os.tmpname = function() + local path = os.tempfolder() + io.open(path, "w"):close() + return path end -------------------------------------------------------------------------------- diff --git a/doc/menu_lua_api.txt b/doc/menu_lua_api.txt index db49c1736..b3975bc1d 100644 --- a/doc/menu_lua_api.txt +++ b/doc/menu_lua_api.txt @@ -85,6 +85,7 @@ core.get_video_drivers() core.get_mapgen_names([include_hidden=false]) -> table of map generator algorithms registered in the core (possible in async calls) core.get_cache_path() -> path of cache +core.get_temp_path() -> path of temp folder HTTP Requests diff --git a/src/defaultsettings.cpp b/src/defaultsettings.cpp index d34ec324b..41c4922a4 100644 --- a/src/defaultsettings.cpp +++ b/src/defaultsettings.cpp @@ -461,7 +461,6 @@ void set_default_settings() settings->setDefault("screen_h", "0"); settings->setDefault("fullscreen", "true"); settings->setDefault("touchtarget", "true"); - settings->setDefault("TMPFolder", porting::path_cache); settings->setDefault("touchscreen_threshold","20"); settings->setDefault("fixed_virtual_joystick", "false"); settings->setDefault("virtual_joystick_triggers_aux", "false"); diff --git a/src/filesys.cpp b/src/filesys.cpp index eeba0c564..5ffb4506e 100644 --- a/src/filesys.cpp +++ b/src/filesys.cpp @@ -27,9 +27,6 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "log.h" #include "config.h" #include "porting.h" -#ifdef __ANDROID__ -#include "settings.h" // For g_settings -#endif namespace fs { @@ -359,8 +356,9 @@ std::string TempPath() compatible with lua's os.tmpname which under the default configuration hardcodes mkstemp("/tmp/lua_XXXXXX"). */ + #ifdef __ANDROID__ - return g_settings->get("TMPFolder"); + return porting::path_cache; #else return DIR_DELIM "tmp"; #endif diff --git a/src/script/lua_api/l_mainmenu.cpp b/src/script/lua_api/l_mainmenu.cpp index 4733c4003..ba7f708a4 100644 --- a/src/script/lua_api/l_mainmenu.cpp +++ b/src/script/lua_api/l_mainmenu.cpp @@ -529,6 +529,7 @@ int ModApiMainMenu::l_get_texturepath(lua_State *L) return 1; } +/******************************************************************************/ int ModApiMainMenu::l_get_texturepath_share(lua_State *L) { std::string gamepath = fs::RemoveRelativePathComponents( @@ -537,12 +538,20 @@ int ModApiMainMenu::l_get_texturepath_share(lua_State *L) return 1; } +/******************************************************************************/ int ModApiMainMenu::l_get_cache_path(lua_State *L) { lua_pushstring(L, fs::RemoveRelativePathComponents(porting::path_cache).c_str()); return 1; } +/******************************************************************************/ +int ModApiMainMenu::l_get_temp_path(lua_State *L) +{ + lua_pushstring(L, fs::TempPath().c_str()); + return 1; +} + /******************************************************************************/ int ModApiMainMenu::l_create_dir(lua_State *L) { const char *path = luaL_checkstring(L, 1); @@ -942,6 +951,7 @@ void ModApiMainMenu::Initialize(lua_State *L, int top) API_FCT(get_texturepath); API_FCT(get_texturepath_share); API_FCT(get_cache_path); + API_FCT(get_temp_path); API_FCT(create_dir); API_FCT(delete_dir); API_FCT(copy_dir); @@ -975,6 +985,7 @@ void ModApiMainMenu::InitializeAsync(lua_State *L, int top) API_FCT(get_texturepath); API_FCT(get_texturepath_share); API_FCT(get_cache_path); + API_FCT(get_temp_path); API_FCT(create_dir); API_FCT(delete_dir); API_FCT(copy_dir); diff --git a/src/script/lua_api/l_mainmenu.h b/src/script/lua_api/l_mainmenu.h index 580a0df72..49ce7c251 100644 --- a/src/script/lua_api/l_mainmenu.h +++ b/src/script/lua_api/l_mainmenu.h @@ -122,6 +122,8 @@ private: static int l_get_cache_path(lua_State *L); + static int l_get_temp_path(lua_State *L); + static int l_create_dir(lua_State *L); static int l_delete_dir(lua_State *L); -- cgit v1.2.3 From b28749057a614075c1f9ba3f96bb86a6e248a210 Mon Sep 17 00:00:00 2001 From: rubenwardy Date: Tue, 9 Feb 2021 12:39:36 +0000 Subject: Fix crash in tab_online when cURL is disabled --- builtin/mainmenu/serverlistmgr.lua | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'builtin/mainmenu') diff --git a/builtin/mainmenu/serverlistmgr.lua b/builtin/mainmenu/serverlistmgr.lua index d98736e54..9876d8ac5 100644 --- a/builtin/mainmenu/serverlistmgr.lua +++ b/builtin/mainmenu/serverlistmgr.lua @@ -47,6 +47,15 @@ function serverlistmgr.sync() }} end + local serverlist_url = core.settings:get("serverlist_url") or "" + if not core.get_http_api or serverlist_url == "" then + serverlistmgr.servers = {{ + name = fgettext("Public server list is disabled"), + description = "" + }} + return + end + if public_downloading then return end -- cgit v1.2.3 From 4db7fb4a3be9de29460919ff2dc042e0812f31bd Mon Sep 17 00:00:00 2001 From: rubenwardy Date: Wed, 10 Feb 2021 11:02:34 +0000 Subject: Replace 'minetest.' with 'core.' in builtin --- builtin/common/information_formspecs.lua | 2 +- builtin/game/item.lua | 2 +- builtin/game/statbars.lua | 4 ++-- builtin/mainmenu/dlg_config_world.lua | 2 +- builtin/mainmenu/dlg_contentstore.lua | 18 +++++++++--------- builtin/mainmenu/dlg_create_world.lua | 2 +- builtin/mainmenu/pkgmgr.lua | 6 +++--- 7 files changed, 18 insertions(+), 18 deletions(-) (limited to 'builtin/mainmenu') diff --git a/builtin/common/information_formspecs.lua b/builtin/common/information_formspecs.lua index 8afa5bc87..3e2f1f079 100644 --- a/builtin/common/information_formspecs.lua +++ b/builtin/common/information_formspecs.lua @@ -115,7 +115,7 @@ core.register_on_player_receive_fields(function(player, formname, fields) return end - local event = minetest.explode_table_event(fields.list) + local event = core.explode_table_event(fields.list) if event.type ~= "INV" then local name = player:get_player_name() core.show_formspec(name, "__builtin:help_cmds", diff --git a/builtin/game/item.lua b/builtin/game/item.lua index 881aff52e..b68177c22 100644 --- a/builtin/game/item.lua +++ b/builtin/game/item.lua @@ -678,7 +678,7 @@ end -- Item definition defaults -- -local default_stack_max = tonumber(minetest.settings:get("default_stack_max")) or 99 +local default_stack_max = tonumber(core.settings:get("default_stack_max")) or 99 core.nodedef_default = { -- Item properties diff --git a/builtin/game/statbars.lua b/builtin/game/statbars.lua index d192029c5..db5087a16 100644 --- a/builtin/game/statbars.lua +++ b/builtin/game/statbars.lua @@ -84,8 +84,8 @@ local function update_builtin_statbars(player) end if hud.id_breathbar and (not show_breathbar or breath == breath_max) then - minetest.after(1, function(player_name, breath_bar) - local player = minetest.get_player_by_name(player_name) + core.after(1, function(player_name, breath_bar) + local player = core.get_player_by_name(player_name) if player then player:hud_remove(breath_bar) end diff --git a/builtin/mainmenu/dlg_config_world.lua b/builtin/mainmenu/dlg_config_world.lua index 2cf70c9c9..9bdf92a74 100644 --- a/builtin/mainmenu/dlg_config_world.lua +++ b/builtin/mainmenu/dlg_config_world.lua @@ -74,7 +74,7 @@ local function get_formspec(data) "label[1.75,0;" .. data.worldspec.name .. "]" if mod.is_modpack or mod.type == "game" then - local info = minetest.formspec_escape( + local info = core.formspec_escape( core.get_content_info(mod.path).description) if info == "" then if mod.is_modpack then diff --git a/builtin/mainmenu/dlg_contentstore.lua b/builtin/mainmenu/dlg_contentstore.lua index 7328f3358..b0736a4fd 100644 --- a/builtin/mainmenu/dlg_contentstore.lua +++ b/builtin/mainmenu/dlg_contentstore.lua @@ -15,7 +15,7 @@ --with this program; if not, write to the Free Software Foundation, Inc., --51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -if not minetest.get_http_api then +if not core.get_http_api then function create_store_dlg() return messagebox("store", fgettext("ContentDB is not available when Minetest was compiled without cURL")) @@ -27,7 +27,7 @@ end -- before the package list is ordered based on installed state. local store = { packages = {}, packages_full = {}, packages_full_unordered = {} } -local http = minetest.get_http_api() +local http = core.get_http_api() -- Screenshot local screenshot_dir = core.get_cache_path() .. DIR_DELIM .. "cdb" @@ -152,7 +152,7 @@ local function start_install(package) end local function queue_download(package) - local max_concurrent_downloads = tonumber(minetest.settings:get("contentdb_max_concurrent_downloads")) + local max_concurrent_downloads = tonumber(core.settings:get("contentdb_max_concurrent_downloads")) if number_downloading < max_concurrent_downloads then start_install(package) else @@ -320,7 +320,7 @@ function install_dialog.get_formspec() selected_game_idx = i end - games[i] = minetest.formspec_escape(games[i].name) + games[i] = core.formspec_escape(games[i].name) end local selected_game = pkgmgr.games[selected_game_idx] @@ -331,7 +331,7 @@ function install_dialog.get_formspec() local formatted_deps = {} for _, dep in pairs(install_dialog.dependencies) do formatted_deps[#formatted_deps + 1] = "#fff" - formatted_deps[#formatted_deps + 1] = minetest.formspec_escape(dep.name) + formatted_deps[#formatted_deps + 1] = core.formspec_escape(dep.name) if dep.installed then formatted_deps[#formatted_deps + 1] = "#ccf" formatted_deps[#formatted_deps + 1] = fgettext("Already installed") @@ -402,7 +402,7 @@ function install_dialog.handle_submit(this, fields) end if fields.will_install_deps ~= nil then - install_dialog.will_install_deps = minetest.is_yes(fields.will_install_deps) + install_dialog.will_install_deps = core.is_yes(fields.will_install_deps) return true end @@ -553,7 +553,7 @@ function store.load() end end - local timeout = tonumber(minetest.settings:get("curl_file_download_timeout")) + local timeout = tonumber(core.settings:get("curl_file_download_timeout")) local response = http.fetch_sync({ url = url, timeout = timeout }) if not response.succeeded then return @@ -793,8 +793,8 @@ function store.get_formspec(dlgdata) -- title formspec[#formspec + 1] = "label[1.875,0.1;" formspec[#formspec + 1] = core.formspec_escape( - minetest.colorize(mt_color_green, package.title) .. - minetest.colorize("#BFBFBF", " by " .. package.author)) + core.colorize(mt_color_green, package.title) .. + core.colorize("#BFBFBF", " by " .. package.author)) formspec[#formspec + 1] = "]" -- buttons diff --git a/builtin/mainmenu/dlg_create_world.lua b/builtin/mainmenu/dlg_create_world.lua index 5931496c1..1938747fe 100644 --- a/builtin/mainmenu/dlg_create_world.lua +++ b/builtin/mainmenu/dlg_create_world.lua @@ -443,7 +443,7 @@ local function create_world_buttonhandler(this, fields) end if fields["mgv6_biomes"] then - local entry = minetest.formspec_escape(fields["mgv6_biomes"]) + local entry = core.formspec_escape(fields["mgv6_biomes"]) for b=1, #mgv6_biomes do if entry == mgv6_biomes[b][1] then local ftable = core.settings:get_flags("mgv6_spflags") diff --git a/builtin/mainmenu/pkgmgr.lua b/builtin/mainmenu/pkgmgr.lua index bfb5d269a..19127d8d3 100644 --- a/builtin/mainmenu/pkgmgr.lua +++ b/builtin/mainmenu/pkgmgr.lua @@ -459,7 +459,7 @@ function pkgmgr.enable_mod(this, toset) if not toset then -- Mod(s) were disabled, so no dependencies need to be enabled table.sort(toggled_mods) - minetest.log("info", "Following mods were disabled: " .. + core.log("info", "Following mods were disabled: " .. table.concat(toggled_mods, ", ")) return end @@ -496,7 +496,7 @@ function pkgmgr.enable_mod(this, toset) enabled_mods[name] = true local mod_to_enable = list[mod_ids[name]] if not mod_to_enable then - minetest.log("warning", "Mod dependency \"" .. name .. + core.log("warning", "Mod dependency \"" .. name .. "\" not found!") else if mod_to_enable.enabled == false then @@ -517,7 +517,7 @@ function pkgmgr.enable_mod(this, toset) -- Log the list of enabled mods table.sort(toggled_mods) - minetest.log("info", "Following mods were enabled: " .. + core.log("info", "Following mods were enabled: " .. table.concat(toggled_mods, ", ")) end -- cgit v1.2.3 From 35b476c65df9c78935e166b94ca686015b43960f Mon Sep 17 00:00:00 2001 From: sfan5 Date: Thu, 18 Feb 2021 19:52:59 +0100 Subject: Update credits tab and mailmap --- .mailmap | 74 +++++++++++++++++++++++++++++----------- builtin/mainmenu/tab_credits.lua | 54 +++++++++++++++-------------- 2 files changed, 82 insertions(+), 46 deletions(-) (limited to 'builtin/mainmenu') diff --git a/.mailmap b/.mailmap index c487460a0..fcc763411 100644 --- a/.mailmap +++ b/.mailmap @@ -1,33 +1,67 @@ +# Documentation: https://git-scm.com/docs/git-check-mailmap#_mapping_authors + 0gb.us <0gb.us@0gb.us> -Calinou -Perttu Ahola celeron55 +Calinou +Calinou +Perttu Ahola Perttu Ahola celeron55 -Craig Robbins +Zeno- +Zeno- +Diego Martínez Diego Martínez +Ilya Zhuravlev Ilya Zhuravlev kwolekr -PilzAdam PilzAdam -PilzAdam Pilz Adam -PilzAdam PilzAdam +PilzAdam +PilzAdam proller proller RealBadAngel RealBadAngel Selat ShadowNinja ShadowNinja -Shen Zheyu arsdragonfly -Pavel Elagin elagin -Esteban I. Ruiz Moreno Esteban I. RM -manuel duarte manuel joaquim -manuel duarte sweetbomber -Diego Martínez kaeza -Diego Martínez Diego Martinez -Lord James Lord89James -BlockMen Block Men -sfan5 Sfan5 -DannyDark dannydark -Ilya Pavlov Ilya -Ilya Zhuravlev xyzz +Esteban I. Ruiz Moreno +Esteban I. Ruiz Moreno +Lord James +BlockMen +sfan5 +DannyDark +Ilya Pavlov sapier sapier sapier sapier - +SmallJoker +Loïc Blot +Loïc Blot +numzero Vitaliy +numzero +Jean-Patrick Guerrero +Jean-Patrick Guerrero +HybridDog <3192173+HybridDog@users.noreply.github.com> +srfqi +Dániel Juhász +rubenwardy +rubenwardy +Paul Ouellette +Vanessa Dannenberg +ClobberXD +ClobberXD +ClobberXD <36130650+ClobberXD@users.noreply.github.com> +Auke Kok +Auke Kok +Desour +Nathanaël Courant +Ezhh +paramat +paramat +lhofhansl +red-001 +Wuzzy +Wuzzy +Jordach +MoNTE48 +v-rob +v-rob <31123645+v-rob@users.noreply.github.com> +EvidenceB <49488517+EvidenceBKidscode@users.noreply.github.com> +gregorycu +Rogier +Rogier diff --git a/builtin/mainmenu/tab_credits.lua b/builtin/mainmenu/tab_credits.lua index 075274798..a34dd58bb 100644 --- a/builtin/mainmenu/tab_credits.lua +++ b/builtin/mainmenu/tab_credits.lua @@ -23,28 +23,37 @@ local core_developers = { "Nathanaël Courant (Nore/Ekdohibs) ", "Loic Blot (nerzhul/nrz) ", "paramat", - "Auke Kok (sofar) ", "Andrew Ward (rubenwardy) ", "Krock/SmallJoker ", "Lars Hofhansl ", + "Pierre-Yves Rollo ", + "v-rob ", } +-- For updating active/previous contributors, see the script in ./util/gather_git_credits.py + local active_contributors = { - "Hugues Ross [Formspecs]", + "Wuzzy [devtest game, visual corrections]", + "Zughy [Visual improvements, various fixes]", "Maksim (MoNTE48) [Android]", - "DS [Formspecs]", - "pyrollo [Formspecs: Hypertext]", - "v-rob [Formspecs]", - "Jordach [set_sky]", - "random-geek [Formspecs]", - "Wuzzy [Pathfinder, builtin, translations]", - "ANAND (ClobberXD) [Fixes, per-player FOV]", - "Warr1024 [Fixes]", - "Paul Ouellette (pauloue) [Fixes, Script API]", - "Jean-Patrick G (kilbith) [Audiovisuals]", - "HybridDog [Script API]", + "numzero [Graphics and rendering]", + "appgurueu [Various internal fixes]", + "Desour [Formspec and vector API changes]", + "HybridDog [Rendering fixes and documentation]", + "Hugues Ross [Graphics-related improvements]", + "ANAND (ClobberXD) [Mouse buttons rebinding]", + "luk3yx [Fixes]", + "hecks [Audiovisuals, Lua API]", + "LoneWolfHT [Object crosshair, documentation fixes]", + "Lejo [Server-related improvements]", + "EvidenceB [Compass HUD element]", + "Paul Ouellette (pauloue) [Lua API, documentation]", + "TheTermos [Collision detection, physics]", + "David CARLIER [Unix & Haiku build fixes]", "dcbrwn [Object shading]", - "srifqi [Fixes]", + "Elias Fleckenstein [API features/fixes]", + "Jean-Patrick Guerrero (kilbith) [model element, visual fixes]", + "k.h.lai [Memory leak fixes, documentation]", } local previous_core_developers = { @@ -60,30 +69,23 @@ local previous_core_developers = { "sapier", "Zeno", "ShadowNinja ", + "Auke Kok (sofar) ", } local previous_contributors = { "Nils Dagsson Moskopp (erlehmann) [Minetest Logo]", - "Dániel Juhász (juhdanad) ", "red-001 ", - "numberZero [Audiovisuals: meshgen]", "Giuseppe Bilotta", + "Dániel Juhász (juhdanad) ", "MirceaKitsune ", "Constantin Wenger (SpeedProg)", "Ciaran Gultnieks (CiaranG)", "stujones11 [Android UX improvements]", - "Jeija [HTTP, particles]", - "Vincent Glize (Dumbeldor) [Cleanups, CSM APIs]", - "Ben Deutsch [Rendering, Fixes, SQLite auth]", - "TeTpaAka [Hand overriding, nametag colors]", - "Rui [Sound Pitch]", - "Duane Robertson [MGValleys]", - "Raymoo [Tool Capabilities]", "Rogier [Fixes]", "Gregory Currie (gregorycu) [optimisation]", - "TriBlade9 [Audiovisuals]", - "T4im [Profiler]", - "Jurgen Doser (doserj) ", + "srifqi [Fixes]", + "JacobF", + "Jeija [HTTP, particles]", } local function buildCreditList(source) -- cgit v1.2.3 From d51d0d77c4e88dec8f9670942e19595cbb3a0234 Mon Sep 17 00:00:00 2001 From: Yaman Qalieh Date: Wed, 24 Feb 2021 05:50:19 -0500 Subject: Allow toggling of texture pack by double clicking --- builtin/mainmenu/tab_content.lua | 15 +++++++++++++++ 1 file changed, 15 insertions(+) (limited to 'builtin/mainmenu') diff --git a/builtin/mainmenu/tab_content.lua b/builtin/mainmenu/tab_content.lua index 336730bf4..fb7f121f8 100644 --- a/builtin/mainmenu/tab_content.lua +++ b/builtin/mainmenu/tab_content.lua @@ -145,11 +145,26 @@ local function get_formspec(tabview, name, tabdata) return retval end +-------------------------------------------------------------------------------- +local function handle_doubleclick(pkg) + if pkg.type == "txp" then + if core.settings:get("texture_path") == pkg.path then + core.settings:set("texture_path", "") + else + core.settings:set("texture_path", pkg.path) + end + packages = nil + end +end + -------------------------------------------------------------------------------- local function handle_buttons(tabview, fields, tabname, tabdata) if fields["pkglist"] ~= nil then local event = core.explode_table_event(fields["pkglist"]) tabdata.selected_pkg = event.row + if event.type == "DCL" then + handle_doubleclick(packages:get_list()[tabdata.selected_pkg]) + end return true end -- cgit v1.2.3 From b390bd2ea5c40cb96af1699a6a18f59dcdb1495b Mon Sep 17 00:00:00 2001 From: rubenwardy Date: Sun, 28 Feb 2021 17:10:40 +0000 Subject: pkgmgr: Fix crash when .conf release field is invalid Fixes #10942 --- builtin/mainmenu/pkgmgr.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'builtin/mainmenu') diff --git a/builtin/mainmenu/pkgmgr.lua b/builtin/mainmenu/pkgmgr.lua index 19127d8d3..4aa05d838 100644 --- a/builtin/mainmenu/pkgmgr.lua +++ b/builtin/mainmenu/pkgmgr.lua @@ -90,7 +90,7 @@ local function load_texture_packs(txtpath, retval) retval[#retval + 1] = { name = item, author = conf:get("author"), - release = tonumber(conf:get("release") or "0"), + release = tonumber(conf:get("release")) or 0, list_name = name, type = "txp", path = path, @@ -135,7 +135,7 @@ function get_mods(path,retval,modpack) -- Read from config toadd.name = name toadd.author = mod_conf.author - toadd.release = tonumber(mod_conf.release or "0") + toadd.release = tonumber(mod_conf.release) or 0 toadd.path = prefix toadd.type = "mod" -- cgit v1.2.3 From c401a06f8a669d1fd4194010ccf23d7043d70fb1 Mon Sep 17 00:00:00 2001 From: Elias Fleckenstein <54945686+EliasFleckenstein03@users.noreply.github.com> Date: Mon, 1 Mar 2021 12:13:47 +0100 Subject: Make pkgmgr handle modpacks containing modpacks properly fixes #10550 --- builtin/mainmenu/pkgmgr.lua | 39 +++++++++++++++++---------------------- 1 file changed, 17 insertions(+), 22 deletions(-) (limited to 'builtin/mainmenu') diff --git a/builtin/mainmenu/pkgmgr.lua b/builtin/mainmenu/pkgmgr.lua index 4aa05d838..787936e31 100644 --- a/builtin/mainmenu/pkgmgr.lua +++ b/builtin/mainmenu/pkgmgr.lua @@ -413,18 +413,7 @@ function pkgmgr.is_modpack_entirely_enabled(data, name) end ---------- toggles or en/disables a mod or modpack and its dependencies -------- -function pkgmgr.enable_mod(this, toset) - local list = this.data.list:get_list() - local mod = list[this.data.selected_mod] - - -- Game mods can't be enabled or disabled - if mod.is_game_content then - return - end - - local toggled_mods = {} - - local enabled_mods = {} +local function toggle_mod_or_modpack(list, toggled_mods, enabled_mods, toset, mod) if not mod.is_modpack then -- Toggle or en/disable the mod if toset == nil then @@ -443,19 +432,25 @@ function pkgmgr.enable_mod(this, toset) -- interleaved unsupported for i = 1, #list do if list[i].modpack == mod.name then - if toset == nil then - toset = not list[i].enabled - end - if list[i].enabled ~= toset then - list[i].enabled = toset - toggled_mods[#toggled_mods+1] = list[i].name - end - if toset then - enabled_mods[list[i].name] = true - end + toggle_mod_or_modpack(list, toggled_mods, enabled_mods, toset, list[i]) end end end +end + +function pkgmgr.enable_mod(this, toset) + local list = this.data.list:get_list() + local mod = list[this.data.selected_mod] + + -- Game mods can't be enabled or disabled + if mod.is_game_content then + return + end + + local toggled_mods = {} + local enabled_mods = {} + toggle_mod_or_modpack(list, toggled_mods, enabled_mods, toset, mod) + if not toset then -- Mod(s) were disabled, so no dependencies need to be enabled table.sort(toggled_mods) -- cgit v1.2.3 From 042131d91d0f61d1252d240aa799f3b12b509cfe Mon Sep 17 00:00:00 2001 From: sfan5 Date: Sat, 20 Mar 2021 19:48:25 +0100 Subject: Mainmenu: Improve "Join Game" tab (#11078) --- LICENSE.txt | 10 +- builtin/fstk/tabview.lua | 50 +-- builtin/mainmenu/common.lua | 108 +++---- builtin/mainmenu/tab_online.lua | 456 ++++++++++++++------------- textures/base/pack/server_favorite.png | Bin 0 -> 916 bytes textures/base/pack/server_flags_favorite.png | Bin 916 -> 0 bytes textures/base/pack/server_incompatible.png | Bin 0 -> 385 bytes textures/base/pack/server_public.png | Bin 0 -> 492 bytes 8 files changed, 306 insertions(+), 318 deletions(-) create mode 100644 textures/base/pack/server_favorite.png delete mode 100644 textures/base/pack/server_flags_favorite.png create mode 100644 textures/base/pack/server_incompatible.png create mode 100644 textures/base/pack/server_public.png (limited to 'builtin/mainmenu') diff --git a/LICENSE.txt b/LICENSE.txt index 9b8ee851a..2d1c0c795 100644 --- a/LICENSE.txt +++ b/LICENSE.txt @@ -14,6 +14,9 @@ https://www.apache.org/licenses/LICENSE-2.0.html Textures by Zughy are under CC BY-SA 4.0 https://creativecommons.org/licenses/by-sa/4.0/ +textures/base/pack/server_public.png is under CC-BY 4.0, taken from Twitter's Twemoji set +https://creativecommons.org/licenses/by/4.0/ + Authors of media files ----------------------- Everything not listed in here: @@ -39,10 +42,10 @@ erlehmann: misc/minetest.svg textures/base/pack/logo.png -JRottm +JRottm: textures/base/pack/player_marker.png -srifqi +srifqi: textures/base/pack/chat_hide_btn.png textures/base/pack/chat_show_btn.png textures/base/pack/joystick_bg.png @@ -58,6 +61,9 @@ Zughy: textures/base/pack/cdb_update.png textures/base/pack/cdb_viewonline.png +appgurueu: + textures/base/pack/server_incompatible.png + License of Minetest source code ------------------------------- diff --git a/builtin/fstk/tabview.lua b/builtin/fstk/tabview.lua index 3715e231b..424d329fb 100644 --- a/builtin/fstk/tabview.lua +++ b/builtin/fstk/tabview.lua @@ -58,26 +58,20 @@ end -------------------------------------------------------------------------------- local function get_formspec(self) - local formspec = "" + if self.hidden or (self.parent ~= nil and self.parent.hidden) then + return "" + end + local tab = self.tablist[self.last_tab_index] - if not self.hidden and (self.parent == nil or not self.parent.hidden) then + local content, prepend = tab.get_formspec(self, tab.name, tab.tabdata, tab.tabsize) - if self.parent == nil then - local tsize = self.tablist[self.last_tab_index].tabsize or - {width=self.width, height=self.height} - formspec = formspec .. - string.format("size[%f,%f,%s]",tsize.width,tsize.height, - dump(self.fixed_size)) - end - formspec = formspec .. self:tab_header() - formspec = formspec .. - self.tablist[self.last_tab_index].get_formspec( - self, - self.tablist[self.last_tab_index].name, - self.tablist[self.last_tab_index].tabdata, - self.tablist[self.last_tab_index].tabsize - ) + if self.parent == nil and not prepend then + local tsize = tab.tabsize or {width=self.width, height=self.height} + prepend = string.format("size[%f,%f,%s]", tsize.width, tsize.height, + dump(self.fixed_size)) end + + local formspec = (prepend or "") .. self:tab_header() .. content return formspec end @@ -97,14 +91,9 @@ local function handle_buttons(self,fields) return true end - if self.tablist[self.last_tab_index].button_handler ~= nil then - return - self.tablist[self.last_tab_index].button_handler( - self, - fields, - self.tablist[self.last_tab_index].name, - self.tablist[self.last_tab_index].tabdata - ) + local tab = self.tablist[self.last_tab_index] + if tab.button_handler ~= nil then + return tab.button_handler(self, fields, tab.name, tab.tabdata) end return false @@ -122,14 +111,9 @@ local function handle_events(self,event) return true end - if self.tablist[self.last_tab_index].evt_handler ~= nil then - return - self.tablist[self.last_tab_index].evt_handler( - self, - event, - self.tablist[self.last_tab_index].name, - self.tablist[self.last_tab_index].tabdata - ) + local tab = self.tablist[self.last_tab_index] + if tab.evt_handler ~= nil then + return tab.evt_handler(self, event, tab.name, tab.tabdata) end return false diff --git a/builtin/mainmenu/common.lua b/builtin/mainmenu/common.lua index cd896f9ec..6db351048 100644 --- a/builtin/mainmenu/common.lua +++ b/builtin/mainmenu/common.lua @@ -14,14 +14,11 @@ --You should have received a copy of the GNU Lesser General Public License along --with this program; if not, write to the Free Software Foundation, Inc., --51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. --------------------------------------------------------------------------------- + -- Global menu data --------------------------------------------------------------------------------- menudata = {} --------------------------------------------------------------------------------- -- Local cached values --------------------------------------------------------------------------------- local min_supp_proto, max_supp_proto function common_update_cached_supp_proto() @@ -29,14 +26,12 @@ function common_update_cached_supp_proto() max_supp_proto = core.get_max_supp_proto() end common_update_cached_supp_proto() --------------------------------------------------------------------------------- + -- Menu helper functions --------------------------------------------------------------------------------- --------------------------------------------------------------------------------- local function render_client_count(n) - if n > 99 then return '99+' - elseif n >= 0 then return tostring(n) + if n > 999 then return '99+' + elseif n >= 0 then return tostring(n) else return '?' end end @@ -50,21 +45,7 @@ local function configure_selected_world_params(idx) end end --------------------------------------------------------------------------------- -function image_column(tooltip, flagname) - return "image,tooltip=" .. core.formspec_escape(tooltip) .. "," .. - "0=" .. core.formspec_escape(defaulttexturedir .. "blank.png") .. "," .. - "1=" .. core.formspec_escape(defaulttexturedir .. - (flagname and "server_flags_" .. flagname .. ".png" or "blank.png")) .. "," .. - "2=" .. core.formspec_escape(defaulttexturedir .. "server_ping_4.png") .. "," .. - "3=" .. core.formspec_escape(defaulttexturedir .. "server_ping_3.png") .. "," .. - "4=" .. core.formspec_escape(defaulttexturedir .. "server_ping_2.png") .. "," .. - "5=" .. core.formspec_escape(defaulttexturedir .. "server_ping_1.png") -end - - --------------------------------------------------------------------------------- -function render_serverlist_row(spec, is_favorite) +function render_serverlist_row(spec) local text = "" if spec.name then text = text .. core.formspec_escape(spec.name:trim()) @@ -75,31 +56,29 @@ function render_serverlist_row(spec, is_favorite) end end - local grey_out = not is_server_protocol_compat(spec.proto_min, spec.proto_max) + local grey_out = not spec.is_compatible - local details - if is_favorite then - details = "1," - else - details = "0," - end + local details = {} - if spec.ping then - local ping = spec.ping * 1000 - if ping <= 50 then - details = details .. "2," - elseif ping <= 100 then - details = details .. "3," - elseif ping <= 250 then - details = details .. "4," + if spec.lag or spec.ping then + local lag = (spec.lag or 0) * 1000 + (spec.ping or 0) * 250 + if lag <= 125 then + table.insert(details, "1") + elseif lag <= 175 then + table.insert(details, "2") + elseif lag <= 250 then + table.insert(details, "3") else - details = details .. "5," + table.insert(details, "4") end else - details = details .. "0," + table.insert(details, "0") end - if spec.clients and spec.clients_max then + table.insert(details, ",") + + local color = (grey_out and "#aaaaaa") or ((spec.is_favorite and "#ddddaa") or "#ffffff") + if spec.clients and (spec.clients_max or 0) > 0 then local clients_percent = 100 * spec.clients / spec.clients_max -- Choose a color depending on how many clients are connected @@ -110,38 +89,35 @@ function render_serverlist_row(spec, is_favorite) elseif clients_percent <= 60 then clients_color = '#a1e587' -- 0-60%: green elseif clients_percent <= 90 then clients_color = '#ffdc97' -- 60-90%: yellow elseif clients_percent == 100 then clients_color = '#dd5b5b' -- full server: red (darker) - else clients_color = '#ffba97' -- 90-100%: orange + else clients_color = '#ffba97' -- 90-100%: orange end - details = details .. clients_color .. ',' .. - render_client_count(spec.clients) .. ',/,' .. - render_client_count(spec.clients_max) .. ',' - - elseif grey_out then - details = details .. '#aaaaaa,?,/,?,' + table.insert(details, clients_color) + table.insert(details, render_client_count(spec.clients) .. " / " .. + render_client_count(spec.clients_max)) else - details = details .. ',?,/,?,' + table.insert(details, color) + table.insert(details, "?") end if spec.creative then - details = details .. "1," - else - details = details .. "0," - end - - if spec.damage then - details = details .. "1," + table.insert(details, "1") -- creative icon else - details = details .. "0," + table.insert(details, "0") end if spec.pvp then - details = details .. "1," + table.insert(details, "2") -- pvp icon + elseif spec.damage then + table.insert(details, "1") -- heart icon else - details = details .. "0," + table.insert(details, "0") end - return details .. (grey_out and '#aaaaaa,' or ',') .. text + table.insert(details, color) + table.insert(details, text) + + return table.concat(details, ",") end -------------------------------------------------------------------------------- @@ -150,14 +126,13 @@ os.tempfolder = function() return temp .. DIR_DELIM .. "MT_" .. math.random(0, 10000) end --------------------------------------------------------------------------------- os.tmpname = function() local path = os.tempfolder() io.open(path, "w"):close() return path end - -------------------------------------------------------------------------------- + function menu_render_worldlist() local retval = "" local current_worldlist = menudata.worldlist:get_list() @@ -171,7 +146,6 @@ function menu_render_worldlist() return retval end --------------------------------------------------------------------------------- function menu_handle_key_up_down(fields, textlist, settingname) local oldidx, newidx = core.get_textlist_index(textlist), 1 if fields.key_up or fields.key_down then @@ -188,7 +162,6 @@ function menu_handle_key_up_down(fields, textlist, settingname) return false end --------------------------------------------------------------------------------- function text2textlist(xpos, ypos, width, height, tl_name, textlen, text, transparency) local textlines = core.wrap_text(text, textlen, true) local retval = "textlist[" .. xpos .. "," .. ypos .. ";" .. width .. @@ -206,7 +179,6 @@ function text2textlist(xpos, ypos, width, height, tl_name, textlen, text, transp return retval end --------------------------------------------------------------------------------- function is_server_protocol_compat(server_proto_min, server_proto_max) if (not server_proto_min) or (not server_proto_max) then -- There is no info. Assume the best and act as if we would be compatible. @@ -214,7 +186,7 @@ function is_server_protocol_compat(server_proto_min, server_proto_max) end return min_supp_proto <= server_proto_max and max_supp_proto >= server_proto_min end --------------------------------------------------------------------------------- + function is_server_protocol_compat_or_error(server_proto_min, server_proto_max) if not is_server_protocol_compat(server_proto_min, server_proto_max) then local server_prot_ver_info, client_prot_ver_info @@ -242,7 +214,7 @@ function is_server_protocol_compat_or_error(server_proto_min, server_proto_max) return true end --------------------------------------------------------------------------------- + function menu_worldmt(selected, setting, value) local world = menudata.worldlist:get_list()[selected] if world then diff --git a/builtin/mainmenu/tab_online.lua b/builtin/mainmenu/tab_online.lua index e6748ed88..fb7409864 100644 --- a/builtin/mainmenu/tab_online.lua +++ b/builtin/mainmenu/tab_online.lua @@ -15,17 +15,50 @@ --with this program; if not, write to the Free Software Foundation, Inc., --51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. --------------------------------------------------------------------------------- +local function get_sorted_servers() + local servers = { + fav = {}, + public = {}, + incompatible = {} + } + + local favs = serverlistmgr.get_favorites() + local taken_favs = {} + local result = menudata.search_result or serverlistmgr.servers + for _, server in ipairs(result) do + server.is_favorite = false + for index, fav in ipairs(favs) do + if server.address == fav.address and server.port == fav.port then + taken_favs[index] = true + server.is_favorite = true + break + end + end + server.is_compatible = is_server_protocol_compat(server.proto_min, server.proto_max) + if server.is_favorite then + table.insert(servers.fav, server) + elseif server.is_compatible then + table.insert(servers.public, server) + else + table.insert(servers.incompatible, server) + end + end + + if not menudata.search_result then + for index, fav in ipairs(favs) do + if not taken_favs[index] then + table.insert(servers.fav, fav) + end + end + end + + return servers +end + local function get_formspec(tabview, name, tabdata) -- Update the cached supported proto info, -- it may have changed after a change by the settings menu. common_update_cached_supp_proto() - local selected - if menudata.search_result then - selected = menudata.search_result[tabdata.selected] - else - selected = serverlistmgr.servers[tabdata.selected] - end if not tabdata.search_for then tabdata.search_for = "" @@ -33,128 +66,221 @@ local function get_formspec(tabview, name, tabdata) local retval = -- Search - "field[0.15,0.075;5.91,1;te_search;;" .. core.formspec_escape(tabdata.search_for) .. "]" .. - "image_button[5.63,-.165;.83,.83;" .. core.formspec_escape(defaulttexturedir .. "search.png") .. ";btn_mp_search;]" .. - "image_button[6.3,-.165;.83,.83;" .. core.formspec_escape(defaulttexturedir .. "clear.png") .. ";btn_mp_clear;]" .. - "image_button[6.97,-.165;.83,.83;" .. core.formspec_escape(defaulttexturedir .. "refresh.png") - .. ";btn_mp_refresh;]" .. + "field[0.25,0.25;7,0.75;te_search;;" .. core.formspec_escape(tabdata.search_for) .. "]" .. + "container[7.25,0.25]" .. + "image_button[0,0;0.75,0.75;" .. core.formspec_escape(defaulttexturedir .. "search.png") .. ";btn_mp_search;]" .. + "image_button[0.75,0;0.75,0.75;" .. core.formspec_escape(defaulttexturedir .. "clear.png") .. ";btn_mp_clear;]" .. + "image_button[1.5,0;0.75,0.75;" .. core.formspec_escape(defaulttexturedir .. "refresh.png") .. ";btn_mp_refresh;]" .. + "tooltip[btn_mp_clear;" .. fgettext("Clear") .. "]" .. + "tooltip[btn_mp_search;" .. fgettext("Search") .. "]" .. + "tooltip[btn_mp_refresh;" .. fgettext("Refresh") .. "]" .. + "container_end[]" .. + + "container[9.75,0]" .. + "box[0,0;5.75,7;#666666]" .. -- Address / Port - "label[7.75,-0.25;" .. fgettext("Address / Port") .. "]" .. - "field[8,0.65;3.25,0.5;te_address;;" .. + "label[0.25,0.35;" .. fgettext("Address") .. "]" .. + "label[4.25,0.35;" .. fgettext("Port") .. "]" .. + "field[0.25,0.5;4,0.75;te_address;;" .. core.formspec_escape(core.settings:get("address")) .. "]" .. - "field[11.1,0.65;1.4,0.5;te_port;;" .. + "field[4.25,0.5;1.25,0.75;te_port;;" .. core.formspec_escape(core.settings:get("remote_port")) .. "]" .. -- Name / Password - "label[7.75,0.95;" .. fgettext("Name / Password") .. "]" .. - "field[8,1.85;2.9,0.5;te_name;;" .. + "label[0.25,1.55;" .. fgettext("Name") .. "]" .. + "label[3,1.55;" .. fgettext("Password") .. "]" .. + "field[0.25,1.75;2.75,0.75;te_name;;" .. core.formspec_escape(core.settings:get("name")) .. "]" .. - "pwdfield[10.73,1.85;1.77,0.5;te_pwd;]" .. + "pwdfield[3,1.75;2.5,0.75;te_pwd;]" .. -- Description Background - "box[7.73,2.25;4.25,2.6;#999999]".. + "label[0.25,2.75;" .. fgettext("Server Description") .. "]" .. + "box[0.25,3;5.25,2.75;#999999]".. -- Connect - "button[9.88,4.9;2.3,1;btn_mp_connect;" .. fgettext("Connect") .. "]" + "button[3,6;2.5,0.75;btn_mp_connect;" .. fgettext("Connect") .. "]" - if tabdata.selected and selected then + if tabdata.selected then if gamedata.fav then - retval = retval .. "button[7.73,4.9;2.3,1;btn_delete_favorite;" .. + retval = retval .. "button[0.25,6;2.5,0.75;btn_delete_favorite;" .. fgettext("Del. Favorite") .. "]" end - if selected.description then - retval = retval .. "textarea[8.1,2.3;4.23,2.9;;;" .. - core.formspec_escape((gamedata.serverdescription or ""), true) .. "]" + if gamedata.serverdescription then + retval = retval .. "textarea[0.25,3;5.25,2.75;;;" .. + core.formspec_escape(gamedata.serverdescription) .. "]" end end - --favorites + retval = retval .. "container_end[]" + + -- Table retval = retval .. "tablecolumns[" .. - image_column(fgettext("Favorite"), "favorite") .. ";" .. - image_column(fgettext("Ping")) .. ",padding=0.25;" .. - "color,span=3;" .. - "text,align=right;" .. -- clients - "text,align=center,padding=0.25;" .. -- "/" - "text,align=right,padding=0.25;" .. -- clients_max - image_column(fgettext("Creative mode"), "creative") .. ",padding=1;" .. - image_column(fgettext("Damage enabled"), "damage") .. ",padding=0.25;" .. - --~ PvP = Player versus Player - image_column(fgettext("PvP enabled"), "pvp") .. ",padding=0.25;" .. + "image,tooltip=" .. fgettext("Ping") .. "," .. + "0=" .. core.formspec_escape(defaulttexturedir .. "blank.png") .. "," .. + "1=" .. core.formspec_escape(defaulttexturedir .. "server_ping_4.png") .. "," .. + "2=" .. core.formspec_escape(defaulttexturedir .. "server_ping_3.png") .. "," .. + "3=" .. core.formspec_escape(defaulttexturedir .. "server_ping_2.png") .. "," .. + "4=" .. core.formspec_escape(defaulttexturedir .. "server_ping_1.png") .. "," .. + "5=" .. core.formspec_escape(defaulttexturedir .. "server_favorite.png") .. "," .. + "6=" .. core.formspec_escape(defaulttexturedir .. "server_public.png") .. "," .. + "7=" .. core.formspec_escape(defaulttexturedir .. "server_incompatible.png") .. ";" .. "color,span=1;" .. - "text,padding=1]" .. - "table[-0.15,0.6;7.75,5.15;favorites;" - - if menudata.search_result then - local favs = serverlistmgr.get_favorites() - for i = 1, #menudata.search_result do - local server = menudata.search_result[i] - for fav_id = 1, #favs do - if server.address == favs[fav_id].address and - server.port == favs[fav_id].port then - server.is_favorite = true - end - end - - if i ~= 1 then - retval = retval .. "," - end - - retval = retval .. render_serverlist_row(server, server.is_favorite) - end - elseif #serverlistmgr.servers > 0 then - local favs = serverlistmgr.get_favorites() - if #favs > 0 then - for i = 1, #favs do - for j = 1, #serverlistmgr.servers do - if serverlistmgr.servers[j].address == favs[i].address and - serverlistmgr.servers[j].port == favs[i].port then - table.insert(serverlistmgr.servers, i, table.remove(serverlistmgr.servers, j)) - end - end - if favs[i].address ~= serverlistmgr.servers[i].address then - table.insert(serverlistmgr.servers, i, favs[i]) - end + "text,align=inline;".. + "color,span=1;" .. + "text,align=inline,width=4.25;" .. + "image,tooltip=" .. fgettext("Creative mode") .. "," .. + "0=" .. core.formspec_escape(defaulttexturedir .. "blank.png") .. "," .. + "1=" .. core.formspec_escape(defaulttexturedir .. "server_flags_creative.png") .. "," .. + "align=inline,padding=0.25,width=1.5;" .. + --~ PvP = Player versus Player + "image,tooltip=" .. fgettext("Damage / PvP") .. "," .. + "0=" .. core.formspec_escape(defaulttexturedir .. "blank.png") .. "," .. + "1=" .. core.formspec_escape(defaulttexturedir .. "server_flags_damage.png") .. "," .. + "2=" .. core.formspec_escape(defaulttexturedir .. "server_flags_pvp.png") .. "," .. + "align=inline,padding=0.25,width=1.5;" .. + "color,align=inline,span=1;" .. + "text,align=inline,padding=1]" .. + "table[0.25,1;9.25,5.75;servers;" + + local servers = get_sorted_servers() + + local dividers = { + fav = "5,#ffff00," .. fgettext("Favorites") .. ",,,0,0,,", + public = "6,#4bdd42," .. fgettext("Public Servers") .. ",,,0,0,,", + incompatible = "7,"..mt_color_grey.."," .. fgettext("Incompatible Servers") .. ",,,0,0,," + } + local order = {"fav", "public", "incompatible"} + + tabdata.lookup = {} -- maps row number to server + local rows = {} + for _, section in ipairs(order) do + local section_servers = servers[section] + if next(section_servers) ~= nil then + rows[#rows + 1] = dividers[section] + for _, server in ipairs(section_servers) do + tabdata.lookup[#rows + 1] = server + rows[#rows + 1] = render_serverlist_row(server) end end - - retval = retval .. render_serverlist_row(serverlistmgr.servers[1], (#favs > 0)) - for i = 2, #serverlistmgr.servers do - retval = retval .. "," .. render_serverlist_row(serverlistmgr.servers[i], (i <= #favs)) - end end + retval = retval .. table.concat(rows, ",") + if tabdata.selected then retval = retval .. ";" .. tabdata.selected .. "]" else retval = retval .. ";0]" end - return retval + return retval, "size[15.5,7,false]real_coordinates[true]" end -------------------------------------------------------------------------------- -local function main_button_handler(tabview, fields, name, tabdata) - local serverlist = menudata.search_result or serverlistmgr.servers +local function search_server_list(input) + menudata.search_result = nil + if #serverlistmgr.servers < 2 then + return + end + + -- setup the keyword list + local keywords = {} + for word in input:gmatch("%S+") do + word = word:gsub("(%W)", "%%%1") + table.insert(keywords, word) + end + + if #keywords == 0 then + return + end + + menudata.search_result = {} + + -- Search the serverlist + local search_result = {} + for i = 1, #serverlistmgr.servers do + local server = serverlistmgr.servers[i] + local found = 0 + for k = 1, #keywords do + local keyword = keywords[k] + if server.name then + local sername = server.name:lower() + local _, count = sername:gsub(keyword, keyword) + found = found + count * 4 + end + + if server.description then + local desc = server.description:lower() + local _, count = desc:gsub(keyword, keyword) + found = found + count * 2 + end + end + if found > 0 then + local points = (#serverlistmgr.servers - i) / 5 + found + server.points = points + table.insert(search_result, server) + end + end + + if #search_result == 0 then + return + end + + table.sort(search_result, function(a, b) + return a.points > b.points + end) + menudata.search_result = search_result +end + +local function set_selected_server(tabdata, idx, server) + -- reset selection + if idx == nil or server == nil then + tabdata.selected = nil + + core.settings:set("address", "") + core.settings:set("remote_port", "30000") + return + end + + local address = server.address + local port = server.port + gamedata.serverdescription = server.description + + gamedata.fav = false + for _, fav in ipairs(serverlistmgr.get_favorites()) do + if address == fav.address and port == fav.port then + gamedata.fav = true + break + end + end + + if address and port then + core.settings:set("address", address) + core.settings:set("remote_port", port) + end + tabdata.selected = idx +end + +local function main_button_handler(tabview, fields, name, tabdata) if fields.te_name then gamedata.playername = fields.te_name core.settings:set("name", fields.te_name) end - if fields.favorites then - local event = core.explode_table_event(fields.favorites) - local fav = serverlist[event.row] + if fields.servers then + local event = core.explode_table_event(fields.servers) + local server = tabdata.lookup[event.row] - if event.type == "DCL" then - if event.row <= #serverlist then + if server then + if event.type == "DCL" then if not is_server_protocol_compat_or_error( - fav.proto_min, fav.proto_max) then + server.proto_min, server.proto_max) then return true end - gamedata.address = fav.address - gamedata.port = fav.port + gamedata.address = server.address + gamedata.port = server.port gamedata.playername = fields.te_name gamedata.selected_world = 0 @@ -162,84 +288,32 @@ local function main_button_handler(tabview, fields, name, tabdata) gamedata.password = fields.te_pwd end - gamedata.servername = fav.name - gamedata.serverdescription = fav.description + gamedata.servername = server.name + gamedata.serverdescription = server.description if gamedata.address and gamedata.port then core.settings:set("address", gamedata.address) core.settings:set("remote_port", gamedata.port) core.start() end + return true end - return true - end - - if event.type == "CHG" then - if event.row <= #serverlist then - gamedata.fav = false - local favs = serverlistmgr.get_favorites() - local address = fav.address - local port = fav.port - gamedata.serverdescription = fav.description - - for i = 1, #favs do - if fav.address == favs[i].address and - fav.port == favs[i].port then - gamedata.fav = true - end - end - - if address and port then - core.settings:set("address", address) - core.settings:set("remote_port", port) - end - tabdata.selected = event.row - end - return true - end - end - - if fields.key_up or fields.key_down then - local fav_idx = core.get_table_index("favorites") - local fav = serverlist[fav_idx] - - if fav_idx then - if fields.key_up and fav_idx > 1 then - fav_idx = fav_idx - 1 - elseif fields.key_down and fav_idx < #serverlistmgr.servers then - fav_idx = fav_idx + 1 + if event.type == "CHG" then + set_selected_server(tabdata, event.row, server) + return true end - else - fav_idx = 1 - end - - if not serverlistmgr.servers or not fav then - tabdata.selected = 0 - return true - end - - local address = fav.address - local port = fav.port - gamedata.serverdescription = fav.description - if address and port then - core.settings:set("address", address) - core.settings:set("remote_port", port) end - - tabdata.selected = fav_idx - return true end if fields.btn_delete_favorite then - local current_favorite = core.get_table_index("favorites") - if not current_favorite then return end - - serverlistmgr.delete_favorite(serverlistmgr.servers[current_favorite]) - serverlistmgr.sync() - tabdata.selected = nil - - core.settings:set("address", "") - core.settings:set("remote_port", "30000") + local idx = core.get_table_index("servers") + if not idx then return end + local server = tabdata.lookup[idx] + if not server then return end + + serverlistmgr.delete_favorite(server) + -- the server at [idx+1] will be at idx once list is refreshed + set_selected_server(tabdata, idx, tabdata.lookup[idx+1]) return true end @@ -250,63 +324,13 @@ local function main_button_handler(tabview, fields, name, tabdata) end if fields.btn_mp_search or fields.key_enter_field == "te_search" then - tabdata.selected = 1 - local input = fields.te_search:lower() tabdata.search_for = fields.te_search - - if #serverlistmgr.servers < 2 then - return true - end - - menudata.search_result = {} - - -- setup the keyword list - local keywords = {} - for word in input:gmatch("%S+") do - word = word:gsub("(%W)", "%%%1") - table.insert(keywords, word) + search_server_list(fields.te_search:lower()) + if menudata.search_result then + -- first server in row 2 due to header + set_selected_server(tabdata, 2, menudata.search_result[1]) end - if #keywords == 0 then - menudata.search_result = nil - return true - end - - -- Search the serverlist - local search_result = {} - for i = 1, #serverlistmgr.servers do - local server = serverlistmgr.servers[i] - local found = 0 - for k = 1, #keywords do - local keyword = keywords[k] - if server.name then - local sername = server.name:lower() - local _, count = sername:gsub(keyword, keyword) - found = found + count * 4 - end - - if server.description then - local desc = server.description:lower() - local _, count = desc:gsub(keyword, keyword) - found = found + count * 2 - end - end - if found > 0 then - local points = (#serverlistmgr.servers - i) / 5 + found - server.points = points - table.insert(search_result, server) - end - end - if #search_result > 0 then - table.sort(search_result, function(a, b) - return a.points > b.points - end) - menudata.search_result = search_result - local first_server = search_result[1] - core.settings:set("address", first_server.address) - core.settings:set("remote_port", first_server.port) - gamedata.serverdescription = first_server.description - end return true end @@ -322,20 +346,22 @@ local function main_button_handler(tabview, fields, name, tabdata) gamedata.address = fields.te_address gamedata.port = tonumber(fields.te_port) gamedata.selected_world = 0 - local fav_idx = core.get_table_index("favorites") - local fav = serverlist[fav_idx] - if fav_idx and fav_idx <= #serverlist and - fav.address == gamedata.address and - fav.port == gamedata.port then + local idx = core.get_table_index("servers") + local server = idx and tabdata.lookup[idx] + + set_selected_server(tabdata) - serverlistmgr.add_favorite(fav) + if server and server.address == gamedata.address and + server.port == gamedata.port then - gamedata.servername = fav.name - gamedata.serverdescription = fav.description + serverlistmgr.add_favorite(server) + + gamedata.servername = server.name + gamedata.serverdescription = server.description if not is_server_protocol_compat_or_error( - fav.proto_min, fav.proto_max) then + server.proto_min, server.proto_max) then return true end else @@ -354,6 +380,7 @@ local function main_button_handler(tabview, fields, name, tabdata) core.start() return true end + return false end @@ -362,7 +389,6 @@ local function on_change(type, old_tab, new_tab) serverlistmgr.sync() end --------------------------------------------------------------------------------- return { name = "online", caption = fgettext("Join Game"), diff --git a/textures/base/pack/server_favorite.png b/textures/base/pack/server_favorite.png new file mode 100644 index 000000000..6a3fc5efe Binary files /dev/null and b/textures/base/pack/server_favorite.png differ diff --git a/textures/base/pack/server_flags_favorite.png b/textures/base/pack/server_flags_favorite.png deleted file mode 100644 index 6a3fc5efe..000000000 Binary files a/textures/base/pack/server_flags_favorite.png and /dev/null differ diff --git a/textures/base/pack/server_incompatible.png b/textures/base/pack/server_incompatible.png new file mode 100644 index 000000000..9076ab58f Binary files /dev/null and b/textures/base/pack/server_incompatible.png differ diff --git a/textures/base/pack/server_public.png b/textures/base/pack/server_public.png new file mode 100644 index 000000000..46a48fac8 Binary files /dev/null and b/textures/base/pack/server_public.png differ -- cgit v1.2.3 From f4118a4fdebe5c8a4a467afe5b3f49a0bd74c37a Mon Sep 17 00:00:00 2001 From: SmallJoker Date: Tue, 30 Mar 2021 21:49:15 +0200 Subject: Consistent title bar + render information in mainmenu (#10764) --- builtin/mainmenu/init.lua | 4 +- builtin/mainmenu/tab_about.lua | 145 ++++++++++++++++++++++++++++++++++++++ builtin/mainmenu/tab_credits.lua | 140 ------------------------------------ doc/menu_lua_api.txt | 3 +- src/client/game.cpp | 12 ++++ src/script/lua_api/l_mainmenu.cpp | 12 ++-- 6 files changed, 165 insertions(+), 151 deletions(-) create mode 100644 builtin/mainmenu/tab_about.lua delete mode 100644 builtin/mainmenu/tab_credits.lua (limited to 'builtin/mainmenu') diff --git a/builtin/mainmenu/init.lua b/builtin/mainmenu/init.lua index 45089c7c9..0c8578cd6 100644 --- a/builtin/mainmenu/init.lua +++ b/builtin/mainmenu/init.lua @@ -49,7 +49,7 @@ local tabs = {} tabs.settings = dofile(menupath .. DIR_DELIM .. "tab_settings.lua") tabs.content = dofile(menupath .. DIR_DELIM .. "tab_content.lua") -tabs.credits = dofile(menupath .. DIR_DELIM .. "tab_credits.lua") +tabs.about = dofile(menupath .. DIR_DELIM .. "tab_about.lua") tabs.local_game = dofile(menupath .. DIR_DELIM .. "tab_local.lua") tabs.play_online = dofile(menupath .. DIR_DELIM .. "tab_online.lua") @@ -98,7 +98,7 @@ local function init_globals() tv_main:add(tabs.content) tv_main:add(tabs.settings) - tv_main:add(tabs.credits) + tv_main:add(tabs.about) tv_main:set_global_event_handler(main_event_handler) tv_main:set_fixed_size(false) diff --git a/builtin/mainmenu/tab_about.lua b/builtin/mainmenu/tab_about.lua new file mode 100644 index 000000000..a1a7d4bfb --- /dev/null +++ b/builtin/mainmenu/tab_about.lua @@ -0,0 +1,145 @@ +--Minetest +--Copyright (C) 2013 sapier +-- +--This program is free software; you can redistribute it and/or modify +--it under the terms of the GNU Lesser General Public License as published by +--the Free Software Foundation; either version 2.1 of the License, or +--(at your option) any later version. +-- +--This program is distributed in the hope that it will be useful, +--but WITHOUT ANY WARRANTY; without even the implied warranty of +--MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +--GNU Lesser General Public License for more details. +-- +--You should have received a copy of the GNU Lesser General Public License along +--with this program; if not, write to the Free Software Foundation, Inc., +--51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +-------------------------------------------------------------------------------- + +local core_developers = { + "Perttu Ahola (celeron55) ", + "sfan5 ", + "Nathanaël Courant (Nore/Ekdohibs) ", + "Loic Blot (nerzhul/nrz) ", + "paramat", + "Andrew Ward (rubenwardy) ", + "Krock/SmallJoker ", + "Lars Hofhansl ", + "Pierre-Yves Rollo ", + "v-rob ", +} + +-- For updating active/previous contributors, see the script in ./util/gather_git_credits.py + +local active_contributors = { + "Wuzzy [devtest game, visual corrections]", + "Zughy [Visual improvements, various fixes]", + "Maksim (MoNTE48) [Android]", + "numzero [Graphics and rendering]", + "appgurueu [Various internal fixes]", + "Desour [Formspec and vector API changes]", + "HybridDog [Rendering fixes and documentation]", + "Hugues Ross [Graphics-related improvements]", + "ANAND (ClobberXD) [Mouse buttons rebinding]", + "luk3yx [Fixes]", + "hecks [Audiovisuals, Lua API]", + "LoneWolfHT [Object crosshair, documentation fixes]", + "Lejo [Server-related improvements]", + "EvidenceB [Compass HUD element]", + "Paul Ouellette (pauloue) [Lua API, documentation]", + "TheTermos [Collision detection, physics]", + "David CARLIER [Unix & Haiku build fixes]", + "dcbrwn [Object shading]", + "Elias Fleckenstein [API features/fixes]", + "Jean-Patrick Guerrero (kilbith) [model element, visual fixes]", + "k.h.lai [Memory leak fixes, documentation]", +} + +local previous_core_developers = { + "BlockMen", + "Maciej Kasatkin (RealBadAngel) [RIP]", + "Lisa Milne (darkrose) ", + "proller", + "Ilya Zhuravlev (xyz) ", + "PilzAdam ", + "est31 ", + "kahrl ", + "Ryan Kwolek (kwolekr) ", + "sapier", + "Zeno", + "ShadowNinja ", + "Auke Kok (sofar) ", +} + +local previous_contributors = { + "Nils Dagsson Moskopp (erlehmann) [Minetest Logo]", + "red-001 ", + "Giuseppe Bilotta", + "Dániel Juhász (juhdanad) ", + "MirceaKitsune ", + "Constantin Wenger (SpeedProg)", + "Ciaran Gultnieks (CiaranG)", + "stujones11 [Android UX improvements]", + "Rogier [Fixes]", + "Gregory Currie (gregorycu) [optimisation]", + "srifqi [Fixes]", + "JacobF", + "Jeija [HTTP, particles]", +} + +local function buildCreditList(source) + local ret = {} + for i = 1, #source do + ret[i] = core.formspec_escape(source[i]) + end + return table.concat(ret, ",,") +end + +return { + name = "about", + caption = fgettext("About"), + cbf_formspec = function(tabview, name, tabdata) + local logofile = defaulttexturedir .. "logo.png" + local version = core.get_version() + local fs = "image[0.75,0.5;2.2,2.2;" .. core.formspec_escape(logofile) .. "]" .. + "style[label_button;border=false]" .. + "button[0.5,2;2.5,2;label_button;" .. version.project .. " " .. version.string .. "]" .. + "button[0.75,2.75;2,2;homepage;minetest.net]" .. + "tablecolumns[color;text]" .. + "tableoptions[background=#00000000;highlight=#00000000;border=false]" .. + "table[3.5,-0.25;8.5,6.05;list_credits;" .. + "#FFFF00," .. fgettext("Core Developers") .. ",," .. + buildCreditList(core_developers) .. ",,," .. + "#FFFF00," .. fgettext("Active Contributors") .. ",," .. + buildCreditList(active_contributors) .. ",,," .. + "#FFFF00," .. fgettext("Previous Core Developers") ..",," .. + buildCreditList(previous_core_developers) .. ",,," .. + "#FFFF00," .. fgettext("Previous Contributors") .. ",," .. + buildCreditList(previous_contributors) .. "," .. + ";1]" + + -- Render information + fs = fs .. "label[0.75,4.9;" .. + fgettext("Active renderer:") .. "\n" .. + core.formspec_escape(core.get_screen_info().render_info) .. "]" + + if PLATFORM ~= "Android" then + fs = fs .. "tooltip[userdata;" .. + fgettext("Opens the directory that contains user-provided worlds, games, mods,\n" .. + "and texture packs in a file manager / explorer.") .. "]" + fs = fs .. "button[0,4;3.5,1;userdata;" .. fgettext("Open User Data Directory") .. "]" + end + + return fs + end, + cbf_button_handler = function(this, fields, name, tabdata) + if fields.homepage then + core.open_url("https://www.minetest.net") + end + + if fields.userdata then + core.open_dir(core.get_user_path()) + end + end, +} diff --git a/builtin/mainmenu/tab_credits.lua b/builtin/mainmenu/tab_credits.lua deleted file mode 100644 index a34dd58bb..000000000 --- a/builtin/mainmenu/tab_credits.lua +++ /dev/null @@ -1,140 +0,0 @@ ---Minetest ---Copyright (C) 2013 sapier --- ---This program is free software; you can redistribute it and/or modify ---it under the terms of the GNU Lesser General Public License as published by ---the Free Software Foundation; either version 2.1 of the License, or ---(at your option) any later version. --- ---This program is distributed in the hope that it will be useful, ---but WITHOUT ANY WARRANTY; without even the implied warranty of ---MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ---GNU Lesser General Public License for more details. --- ---You should have received a copy of the GNU Lesser General Public License along ---with this program; if not, write to the Free Software Foundation, Inc., ---51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - --------------------------------------------------------------------------------- - -local core_developers = { - "Perttu Ahola (celeron55) ", - "sfan5 ", - "Nathanaël Courant (Nore/Ekdohibs) ", - "Loic Blot (nerzhul/nrz) ", - "paramat", - "Andrew Ward (rubenwardy) ", - "Krock/SmallJoker ", - "Lars Hofhansl ", - "Pierre-Yves Rollo ", - "v-rob ", -} - --- For updating active/previous contributors, see the script in ./util/gather_git_credits.py - -local active_contributors = { - "Wuzzy [devtest game, visual corrections]", - "Zughy [Visual improvements, various fixes]", - "Maksim (MoNTE48) [Android]", - "numzero [Graphics and rendering]", - "appgurueu [Various internal fixes]", - "Desour [Formspec and vector API changes]", - "HybridDog [Rendering fixes and documentation]", - "Hugues Ross [Graphics-related improvements]", - "ANAND (ClobberXD) [Mouse buttons rebinding]", - "luk3yx [Fixes]", - "hecks [Audiovisuals, Lua API]", - "LoneWolfHT [Object crosshair, documentation fixes]", - "Lejo [Server-related improvements]", - "EvidenceB [Compass HUD element]", - "Paul Ouellette (pauloue) [Lua API, documentation]", - "TheTermos [Collision detection, physics]", - "David CARLIER [Unix & Haiku build fixes]", - "dcbrwn [Object shading]", - "Elias Fleckenstein [API features/fixes]", - "Jean-Patrick Guerrero (kilbith) [model element, visual fixes]", - "k.h.lai [Memory leak fixes, documentation]", -} - -local previous_core_developers = { - "BlockMen", - "Maciej Kasatkin (RealBadAngel) [RIP]", - "Lisa Milne (darkrose) ", - "proller", - "Ilya Zhuravlev (xyz) ", - "PilzAdam ", - "est31 ", - "kahrl ", - "Ryan Kwolek (kwolekr) ", - "sapier", - "Zeno", - "ShadowNinja ", - "Auke Kok (sofar) ", -} - -local previous_contributors = { - "Nils Dagsson Moskopp (erlehmann) [Minetest Logo]", - "red-001 ", - "Giuseppe Bilotta", - "Dániel Juhász (juhdanad) ", - "MirceaKitsune ", - "Constantin Wenger (SpeedProg)", - "Ciaran Gultnieks (CiaranG)", - "stujones11 [Android UX improvements]", - "Rogier [Fixes]", - "Gregory Currie (gregorycu) [optimisation]", - "srifqi [Fixes]", - "JacobF", - "Jeija [HTTP, particles]", -} - -local function buildCreditList(source) - local ret = {} - for i = 1, #source do - ret[i] = core.formspec_escape(source[i]) - end - return table.concat(ret, ",,") -end - -return { - name = "credits", - caption = fgettext("Credits"), - cbf_formspec = function(tabview, name, tabdata) - local logofile = defaulttexturedir .. "logo.png" - local version = core.get_version() - local fs = "image[0.75,0.5;2.2,2.2;" .. core.formspec_escape(logofile) .. "]" .. - "style[label_button;border=false]" .. - "button[0.5,2;2.5,2;label_button;" .. version.project .. " " .. version.string .. "]" .. - "button[0.75,2.75;2,2;homepage;minetest.net]" .. - "tablecolumns[color;text]" .. - "tableoptions[background=#00000000;highlight=#00000000;border=false]" .. - "table[3.5,-0.25;8.5,6.05;list_credits;" .. - "#FFFF00," .. fgettext("Core Developers") .. ",," .. - buildCreditList(core_developers) .. ",,," .. - "#FFFF00," .. fgettext("Active Contributors") .. ",," .. - buildCreditList(active_contributors) .. ",,," .. - "#FFFF00," .. fgettext("Previous Core Developers") ..",," .. - buildCreditList(previous_core_developers) .. ",,," .. - "#FFFF00," .. fgettext("Previous Contributors") .. ",," .. - buildCreditList(previous_contributors) .. "," .. - ";1]" - - if PLATFORM ~= "Android" then - fs = fs .. "tooltip[userdata;" .. - fgettext("Opens the directory that contains user-provided worlds, games, mods,\n" .. - "and texture packs in a file manager / explorer.") .. "]" - fs = fs .. "button[0,4.75;3.5,1;userdata;" .. fgettext("Open User Data Directory") .. "]" - end - - return fs - end, - cbf_button_handler = function(this, fields, name, tabdata) - if fields.homepage then - core.open_url("https://www.minetest.net") - end - - if fields.userdata then - core.open_dir(core.get_user_path()) - end - end, -} diff --git a/doc/menu_lua_api.txt b/doc/menu_lua_api.txt index 90ec527b0..f4dfff261 100644 --- a/doc/menu_lua_api.txt +++ b/doc/menu_lua_api.txt @@ -204,7 +204,8 @@ core.get_screen_info() display_width = , display_height = , window_width = , - window_height = + window_height = , + render_info = } diff --git a/src/client/game.cpp b/src/client/game.cpp index 31c782c51..334f1da67 100644 --- a/src/client/game.cpp +++ b/src/client/game.cpp @@ -1390,9 +1390,21 @@ bool Game::createClient(const GameStartData &start_data) std::wstring str = utf8_to_wide(PROJECT_NAME_C); str += L" "; str += utf8_to_wide(g_version_hash); + { + const wchar_t *text = nullptr; + if (simple_singleplayer_mode) + text = wgettext("Singleplayer"); + else + text = wgettext("Multiplayer"); + str += L" ["; + str += text; + str += L"]"; + delete text; + } str += L" ["; str += driver->getName(); str += L"]"; + device->setWindowCaption(str.c_str()); LocalPlayer *player = client->getEnv().getLocalPlayer(); diff --git a/src/script/lua_api/l_mainmenu.cpp b/src/script/lua_api/l_mainmenu.cpp index ba7f708a4..6826ece05 100644 --- a/src/script/lua_api/l_mainmenu.cpp +++ b/src/script/lua_api/l_mainmenu.cpp @@ -856,14 +856,6 @@ int ModApiMainMenu::l_get_screen_info(lua_State *L) lua_pushnumber(L,RenderingEngine::getDisplayDensity()); lua_settable(L, top); - lua_pushstring(L,"display_width"); - lua_pushnumber(L,RenderingEngine::getDisplaySize().X); - lua_settable(L, top); - - lua_pushstring(L,"display_height"); - lua_pushnumber(L,RenderingEngine::getDisplaySize().Y); - lua_settable(L, top); - const v2u32 &window_size = RenderingEngine::get_instance()->getWindowSize(); lua_pushstring(L,"window_width"); lua_pushnumber(L, window_size.X); @@ -872,6 +864,10 @@ int ModApiMainMenu::l_get_screen_info(lua_State *L) lua_pushstring(L,"window_height"); lua_pushnumber(L, window_size.Y); lua_settable(L, top); + + lua_pushstring(L, "render_info"); + lua_pushstring(L, wide_to_utf8(RenderingEngine::get_video_driver()->getName()).c_str()); + lua_settable(L, top); return 1; } -- cgit v1.2.3 From 0abc1e98edb87b2e23eecccfd6b1393ac7fb4f56 Mon Sep 17 00:00:00 2001 From: sfan5 Date: Fri, 9 Apr 2021 22:36:10 +0200 Subject: Fix server favorites not saving when client/serverlist/ doesn't exist already (#11152) --- builtin/mainmenu/serverlistmgr.lua | 10 ++++++---- src/script/lua_api/l_mainmenu.cpp | 19 +++++++++++-------- src/script/lua_api/l_mainmenu.h | 2 +- 3 files changed, 18 insertions(+), 13 deletions(-) (limited to 'builtin/mainmenu') diff --git a/builtin/mainmenu/serverlistmgr.lua b/builtin/mainmenu/serverlistmgr.lua index 9876d8ac5..964d0c584 100644 --- a/builtin/mainmenu/serverlistmgr.lua +++ b/builtin/mainmenu/serverlistmgr.lua @@ -90,8 +90,11 @@ function serverlistmgr.sync() end -------------------------------------------------------------------------------- -local function get_favorites_path() +local function get_favorites_path(folder) local base = core.get_user_path() .. DIR_DELIM .. "client" .. DIR_DELIM .. "serverlist" .. DIR_DELIM + if folder then + return base + end return base .. core.settings:get("serverlist_file") end @@ -103,9 +106,8 @@ local function save_favorites(favorites) core.settings:set("serverlist_file", filename:sub(1, #filename - 4) .. ".json") end - local path = get_favorites_path() - core.create_dir(path) - core.safe_file_write(path, core.write_json(favorites)) + assert(core.create_dir(get_favorites_path(true))) + core.safe_file_write(get_favorites_path(), core.write_json(favorites)) end -------------------------------------------------------------------------------- diff --git a/src/script/lua_api/l_mainmenu.cpp b/src/script/lua_api/l_mainmenu.cpp index 6826ece05..6488cd0fc 100644 --- a/src/script/lua_api/l_mainmenu.cpp +++ b/src/script/lua_api/l_mainmenu.cpp @@ -716,21 +716,24 @@ int ModApiMainMenu::l_get_mainmenu_path(lua_State *L) } /******************************************************************************/ -bool ModApiMainMenu::mayModifyPath(const std::string &path) +bool ModApiMainMenu::mayModifyPath(std::string path) { + path = fs::RemoveRelativePathComponents(path); + if (fs::PathStartsWith(path, fs::TempPath())) return true; - if (fs::PathStartsWith(path, fs::RemoveRelativePathComponents(porting::path_user + DIR_DELIM "games"))) - return true; + std::string path_user = fs::RemoveRelativePathComponents(porting::path_user); - if (fs::PathStartsWith(path, fs::RemoveRelativePathComponents(porting::path_user + DIR_DELIM "mods"))) + if (fs::PathStartsWith(path, path_user + DIR_DELIM "client")) return true; - - if (fs::PathStartsWith(path, fs::RemoveRelativePathComponents(porting::path_user + DIR_DELIM "textures"))) + if (fs::PathStartsWith(path, path_user + DIR_DELIM "games")) return true; - - if (fs::PathStartsWith(path, fs::RemoveRelativePathComponents(porting::path_user + DIR_DELIM "worlds"))) + if (fs::PathStartsWith(path, path_user + DIR_DELIM "mods")) + return true; + if (fs::PathStartsWith(path, path_user + DIR_DELIM "textures")) + return true; + if (fs::PathStartsWith(path, path_user + DIR_DELIM "worlds")) return true; if (fs::PathStartsWith(path, fs::RemoveRelativePathComponents(porting::path_cache))) diff --git a/src/script/lua_api/l_mainmenu.h b/src/script/lua_api/l_mainmenu.h index 49ce7c251..33ac9e721 100644 --- a/src/script/lua_api/l_mainmenu.h +++ b/src/script/lua_api/l_mainmenu.h @@ -58,7 +58,7 @@ private: * @param path path to check * @return true if the path may be modified */ - static bool mayModifyPath(const std::string &path); + static bool mayModifyPath(std::string path); //api calls -- cgit v1.2.3