]> git.lizzy.rs Git - dragonfireclient.git/blobdiff - builtin/mainmenu/common.lua
Merge branch 'master' of https://github.com/minetest/minetest
[dragonfireclient.git] / builtin / mainmenu / common.lua
index 384c083d662c79912623c0273dc0983b83b1d310..cd896f9ec2001f7f80211ccfe873b21660a81aec 100644 (file)
 --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()
+       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 '?'
+       if     n > 99 then return '99+'
+       elseif n >= 0 then return tostring(n)
+       else return '?' end
+end
+
+local function configure_selected_world_params(idx)
+       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 then
+               core.settings:set("enable_damage", worldconfig.enable_damage)
        end
 end
 
 --------------------------------------------------------------------------------
-function render_favorite(spec,render_details)
-       local text = ""
+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
 
-       if spec.name ~= nil then
-               text = text .. core.formspec_escape(spec.name:trim())
 
---             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()
-
-                       if spec.port ~= nil then
-                               text = text .. ":" .. spec.port
-                       end
+--------------------------------------------------------------------------------
+function render_serverlist_row(spec, is_favorite)
+       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
 
-       if not render_details then
-               return text
+       local grey_out = not is_server_protocol_compat(spec.proto_min, spec.proto_max)
+
+       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,"
+               else
+                       details = details .. "5,"
+               end
+       else
+               details = details .. "0,"
+       end
 
-       if spec.clients ~= nil and spec.clients_max ~= nil then
-               local clients_color = ''
+       if spec.clients and spec.clients_max 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
 
-               details = details ..
-                               clients_color .. ',' ..
-                               render_client_count(spec.clients) .. ',' ..
-                               '/,' ..
-                               render_client_count(spec.clients_max) .. ','
+               details = details .. clients_color .. ',' ..
+                       render_client_count(spec.clients) .. ',/,' ..
+                       render_client_count(spec.clients_max) .. ','
+
+       elseif grey_out then
+               details = details .. '#aaaaaa,?,/,?,'
        else
                details = details .. ',?,/,?,'
        end
@@ -106,114 +141,136 @@ function render_favorite(spec,render_details)
                details = details .. "0,"
        end
 
-       return details .. text
+       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)
-       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
+       local temp = core.get_temp_path()
+       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()
 
-       for i,v in ipairs(current_worldlist) do
-               if retval ~= "" then
-                       retval = retval ..","
-               end
-
+       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) .. "\\]"
+                               " \\[" .. core.formspec_escape(v.gameid) .. "\\]"
        end
 
        return 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))
+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
 
-       if fields["key_down"] then
-               local oldidx = core.get_textlist_index(textlist)
+--------------------------------------------------------------------------------
+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 .. ";"
 
-               if oldidx ~= nil and oldidx < menudata.worldlist:size() then
-                       local newidx = oldidx + 1
-                       core.setting_set(settingname,
-                               menudata.worldlist:get_raw_index(newidx))
-               end
-               
-               return true
+       for i = 1, #textlines do
+               textlines[i] = textlines[i]:gsub("\r", "")
+               retval = retval .. core.formspec_escape(textlines[i]) .. ","
        end
-       
-       return false
+
+       retval = retval .. ";0;"
+       if transparency then retval = retval .. "true" end
+       retval = retval .. "]"
+
+       return retval
 end
 
 --------------------------------------------------------------------------------
-function asyncOnlineFavourites()
+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(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
 
-       menudata.favorites = {}
-       core.handle_async(
-               function(param)
-                       return core.get_favorites("online")
-               end,
-               nil,
-               function(result)
-                       if core.setting_getbool("public_serverlist") then
-                               menudata.favorites = result
-                               core.event_handler("Refresh")
+       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 then
+                       if not world_conf:write() then
+                               core.log("error", "Failed to write world config file")
                        end
+                       world_conf:set(setting, value)
+                       world_conf:write()
+               else
+                       return world_conf:get(setting)
                end
-               )
+       else
+               return nil
+       end
 end
 
---------------------------------------------------------------------------------
-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","")
-               retval = retval .. core.formspec_escape(textlines[i]) .. ","
-       end
-       
-       retval = retval .. ";0;"
-       
-       if transparency then
-               retval = retval .. "true"
+function menu_worldmt_legacy(selected)
+       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 then
+                       core.settings:set(mode_name, mode_val)
+               else
+                       menu_worldmt(selected, mode_name, core.settings:get(mode_name))
+               end
        end
-       
-       retval = retval .. "]"
-
-       return retval
 end