]> git.lizzy.rs Git - minetest.git/blobdiff - builtin/mainmenu/common.lua
Add unit tests for pkgmgr.install_dir
[minetest.git] / builtin / mainmenu / common.lua
index cbc95bc8501a2bf5b46ee4dc95e341b7c4aa00de..81e28f2bb3b6cecbcc41048656307c8ced4d65fa 100644 (file)
 --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 = core.get_min_supp_proto()
-local max_supp_proto = core.get_max_supp_proto()
+local min_supp_proto, max_supp_proto
+
+function common_update_cached_supp_proto()
+       min_supp_proto = core.get_min_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)
-       else
-               return '?'
-       end
+       if     n > 999 then return '99+'
+       elseif n >= 0  then return tostring(n)
+       else return '?' end
 end
 
 local function configure_selected_world_params(idx)
-       local worldconfig = modmgr.get_worldconfig(
-               menudata.worldlist:get_list()[idx].path)
-
-       if worldconfig.creative_mode ~= nil then
-               core.setting_set("creative_mode", worldconfig.creative_mode)
+       local worldconfig = pkgmgr.get_worldconfig(menudata.worldlist:get_list()[idx].path)
+       if worldconfig.creative_mode then
+               core.settings:set("creative_mode", worldconfig.creative_mode)
        end
-       if worldconfig.enable_damage ~= nil then
-               core.setting_set("enable_damage", worldconfig.enable_damage)
+       if worldconfig.enable_damage then
+               core.settings:set("enable_damage", worldconfig.enable_damage)
        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 .. "server_flags_" .. flagname .. ".png")
-end
-
---------------------------------------------------------------------------------
-function order_favorite_list(list)
-       local res = {}
-       --orders the favorite list after support
-       for i=1,#list,1 do
-               local fav = list[i]
-               if is_server_protocol_compat(fav.proto_min, fav.proto_max) then
-                       table.insert(res, fav)
-               end
-       end
-       for i=1,#list,1 do
-               local fav = list[i]
-               if not is_server_protocol_compat(fav.proto_min, fav.proto_max) then
-                       table.insert(res, fav)
+function render_serverlist_row(spec)
+       local text = ""
+       if spec.name then
+               text = text .. core.formspec_escape(spec.name:trim())
+       elseif spec.address then
+               text = text .. core.formspec_escape(spec.address:trim())
+               if spec.port then
+                       text = text .. ":" .. spec.port
                end
        end
-       return res
-end
 
---------------------------------------------------------------------------------
-function render_favorite(spec,render_details)
-       local text = ""
-
-       if spec.name ~= nil then
-               text = text .. core.formspec_escape(spec.name:trim())
+       local grey_out = not spec.is_compatible
 
---             if spec.description ~= nil and
---                     core.formspec_escape(spec.description):trim() ~= "" then
---                     text = text .. " (" .. core.formspec_escape(spec.description) .. ")"
---             end
-       else
-               if spec.address ~= nil then
-                       text = text .. spec.address:trim()
+       local details = {}
 
-                       if spec.port ~= nil then
-                               text = text .. ":" .. spec.port
-                       end
+       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
+                       table.insert(details, "4")
                end
+       else
+               table.insert(details, "0")
        end
 
-       if not render_details then
-               return text
-       end
-
-       local details = ""
-       local grey_out = not is_server_protocol_compat(spec.proto_max, spec.proto_min)
+       table.insert(details, ",")
 
-       if spec.clients ~= nil and spec.clients_max ~= nil then
-               local clients_color = ''
+       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
                -- (relatively to clients_max)
-               if spec.clients == 0 then
-                       clients_color = ''        -- 0 players: default/white
-               elseif spec.clients == spec.clients_max then
-                       clients_color = '#dd5b5b' -- full server: red (darker)
-               elseif clients_percent <= 60 then
-                       clients_color = '#a1e587' -- 0-60%: green
-               elseif clients_percent <= 90 then
-                       clients_color = '#ffdc97' -- 60-90%: yellow
-               else
-                       clients_color = '#ffba97' -- 90-100%: orange
+               local clients_color
+               if     grey_out               then clients_color = '#aaaaaa'
+               elseif spec.clients == 0      then clients_color = ''        -- 0 players: default/white
+               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
                end
 
-               if grey_out then
-                       clients_color = '#aaaaaa'
-               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,"
-       end
-
-       return details .. (grey_out and '#aaaaaa,' or ',') .. text
-end
-
---------------------------------------------------------------------------------
-os.tempfolder = function()
-       if core.setting_get("TMPFolder") then
-               return core.setting_get("TMPFolder") .. DIR_DELIM .. "MT_" .. math.random(0,10000)
+               table.insert(details, "0")
        end
 
-       local filetocheck = os.tmpname()
-       os.remove(filetocheck)
-
-       local randname = "MTTempModFolder_" .. math.random(0,10000)
-       if DIR_DELIM == "\\" then
-               local tempfolder = os.getenv("TEMP")
-               return tempfolder .. filetocheck
-       else
-               local backstring = filetocheck:reverse()
-               return filetocheck:sub(0,filetocheck:len()-backstring:find(DIR_DELIM)+1) ..randname
-       end
+       table.insert(details, color)
+       table.insert(details, text)
 
+       return table.concat(details, ",")
+end
+---------------------------------------------------------------------------------
+os.tmpname = function()
+       error('do not use') -- instead use core.get_temp_path()
 end
-
 --------------------------------------------------------------------------------
-function menu_render_worldlist()
-       local retval = ""
 
+function menu_render_worldlist()
+       local retval = {}
        local current_worldlist = menudata.worldlist:get_list()
 
-       for i,v in ipairs(current_worldlist) do
-               if retval ~= "" then
-                       retval = retval ..","
-               end
-
-               retval = retval .. core.formspec_escape(v.name) ..
-                                       " \\[" .. core.formspec_escape(v.gameid) .. "\\]"
+       for i, v in ipairs(current_worldlist) do
+               retval[#retval+1] = core.formspec_escape(v.name)
        end
 
-       return retval
+       return table.concat(retval, ",")
 end
 
---------------------------------------------------------------------------------
-function menu_handle_key_up_down(fields,textlist,settingname)
-       if fields["key_up"] then
-               local oldidx = core.get_textlist_index(textlist)
-
-               if oldidx ~= nil and oldidx > 1 then
-                       local newidx = oldidx -1
-                       core.setting_set(settingname,
-                               menudata.worldlist:get_raw_index(newidx))
-
-                       configure_selected_world_params(newidx)
-               end
-               return true
-       end
-
-       if fields["key_down"] then
-               local oldidx = core.get_textlist_index(textlist)
-
-               if oldidx ~= nil and oldidx < menudata.worldlist:size() then
-                       local newidx = oldidx + 1
-                       core.setting_set(settingname,
-                               menudata.worldlist:get_raw_index(newidx))
-
-                       configure_selected_world_params(newidx)
+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
+               if fields.key_up and oldidx and oldidx > 1 then
+                       newidx = oldidx - 1
+               elseif fields.key_down and oldidx and
+                               oldidx < menudata.worldlist:size() then
+                       newidx = oldidx + 1
                end
-               
+               core.settings:set(settingname, menudata.worldlist:get_raw_index(newidx))
+               configure_selected_world_params(newidx)
                return true
        end
-       
        return false
 end
 
---------------------------------------------------------------------------------
-function asyncOnlineFavourites()
-
-       if not menudata.public_known then
-               menudata.public_known = {{
-                       name = fgettext("Loading..."),
-                       description = fgettext("Try reenabling public serverlist and check your internet connection.")
-               }}
-       end
-       menudata.favorites = menudata.public_known
-       core.handle_async(
-               function(param)
-                       return core.get_favorites("online")
-               end,
-               nil,
-               function(result)
-                       if core.setting_getbool("public_serverlist") then
-                               local favs = order_favorite_list(result)
-                               if favs[1] then
-                                       menudata.public_known = favs
-                                       menudata.favorites = menudata.public_known
-                               end
-                               core.event_handler("Refresh")
-                       end
-               end
-       )
-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 ..
+                       "," .. height .. ";" .. tl_name .. ";"
 
---------------------------------------------------------------------------------
-function text2textlist(xpos,ypos,width,height,tl_name,textlen,text,transparency)
-       local textlines = core.splittext(text,textlen)
-       
-       local retval = "textlist[" .. xpos .. "," .. ypos .. ";"
-                                                               .. width .. "," .. height .. ";"
-                                                               .. tl_name .. ";"
-       
-       for i=1, #textlines, 1 do
-               textlines[i] = textlines[i]:gsub("\r","")
+       for i = 1, #textlines do
+               textlines[i] = textlines[i]:gsub("\r", "")
                retval = retval .. core.formspec_escape(textlines[i]) .. ","
        end
-       
+
        retval = retval .. ";0;"
-       
-       if transparency then
-               retval = retval .. "true"
-       end
-       
+       if transparency then retval = retval .. "true" end
        retval = retval .. "]"
 
        return retval
 end
 
---------------------------------------------------------------------------------
-function is_server_protocol_compat(proto_min, proto_max)
-       return not ((min_supp_proto > (proto_max or 24)) or (max_supp_proto < (proto_min or 13)))
+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.
+               return true
+       end
+       return min_supp_proto <= server_proto_max and max_supp_proto >= server_proto_min
 end
---------------------------------------------------------------------------------
-function is_server_protocol_compat_or_error(proto_min, proto_max)
-       if not is_server_protocol_compat(proto_min, proto_max) then
-               gamedata.errormessage = fgettext_ne("Protocol version mismatch, server " ..
-                       ((proto_min ~= proto_max) and "supports protocols between $1 and $2" or "enforces protocol version $1") ..
-                       ", we " ..
-                       ((min_supp_proto ~= max_supp_proto) and "support protocols between version $3 and $4." or "only support protocol version $3"),
-                       proto_min or 13, proto_max or 24, min_supp_proto, max_supp_proto)
+
+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
+               local s_p_min = server_proto_min
+               local s_p_max = server_proto_max
+
+               if s_p_min ~= s_p_max then
+                       server_prot_ver_info = fgettext_ne("Server supports protocol versions between $1 and $2. ",
+                               s_p_min, s_p_max)
+               else
+                       server_prot_ver_info = fgettext_ne("Server enforces protocol version $1. ",
+                               s_p_min)
+               end
+               if min_supp_proto ~= max_supp_proto then
+                       client_prot_ver_info= fgettext_ne("We support protocol versions between version $1 and $2.",
+                               min_supp_proto, max_supp_proto)
+               else
+                       client_prot_ver_info = fgettext_ne("We only support protocol version $1.", min_supp_proto)
+               end
+               gamedata.errormessage = fgettext_ne("Protocol version mismatch. ")
+                       .. server_prot_ver_info
+                       .. client_prot_ver_info
                return false
        end
 
        return true
 end
---------------------------------------------------------------------------------
+
 function menu_worldmt(selected, setting, value)
        local world = menudata.worldlist:get_list()[selected]
        if world then
                local filename = world.path .. DIR_DELIM .. "world.mt"
                local world_conf = Settings(filename)
 
-               if value ~= nil then
+               if value then
                        if not world_conf:write() then
                                core.log("error", "Failed to write world config file")
                        end
@@ -322,13 +226,21 @@ function menu_worldmt(selected, setting, value)
 end
 
 function menu_worldmt_legacy(selected)
-       local modes_names = {"creative_mode", "enable_damage"}
+       local modes_names = {"creative_mode", "enable_damage", "server_announce"}
        for _, mode_name in pairs(modes_names) do
                local mode_val = menu_worldmt(selected, mode_name)
-               if mode_val ~= nil then
-                       core.setting_set(mode_name, mode_val)
+               if mode_val then
+                       core.settings:set(mode_name, mode_val)
                else
-                       menu_worldmt(selected, mode_name, core.setting_get(mode_name))
+                       menu_worldmt(selected, mode_name, core.settings:get(mode_name))
                end
        end
 end
+
+function confirmation_formspec(message, confirm_id, confirm_label, cancel_id, cancel_label)
+       return "size[10,2.5,true]" ..
+                       "label[0.5,0.5;" .. message .. "]" ..
+                       "style[" .. confirm_id .. ";bgcolor=red]" ..
+                       "button[0.5,1.5;2.5,0.5;" .. confirm_id .. ";" .. confirm_label .. "]" ..
+                       "button[7.0,1.5;2.5,0.5;" .. cancel_id .. ";" .. cancel_label .. "]"
+end