]> git.lizzy.rs Git - dragonfireclient.git/blobdiff - builtin/mainmenu/common.lua
Include tile definitions in get_node_def; Client-side minetest.object_refs table
[dragonfireclient.git] / builtin / mainmenu / common.lua
index c555ec92f75b7082af5a86943a0b953044fa1664..6db3510481e1701c89d2090f8de2f7643513cdc1 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 = {}
 
---------------------------------------------------------------------------------
--- Menu helper functions
---------------------------------------------------------------------------------
+-- Local cached values
+local min_supp_proto, max_supp_proto
 
---------------------------------------------------------------------------------
-function render_favorite(spec,render_details)
-       local text = ""
+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()
 
-       if spec.name ~= nil then
-               text = text .. core.formspec_escape(spec.name:trim())
+-- Menu helper functions
 
---             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 function render_client_count(n)
+       if     n > 999 then return '99+'
+       elseif n >= 0  then return tostring(n)
+       else return '?' end
+end
 
-                       if spec.port ~= nil then
-                               text = text .. ":" .. spec.port
-                       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
 
-       if not render_details then
-               return text
+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
 
-       local details = ""
-       if spec.password == true then
-               details = details .. "*"
+       local grey_out = not spec.is_compatible
+
+       local details = {}
+
+       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
-               details = details .. "_"
+               table.insert(details, "0")
        end
 
-       if spec.creative then
-               details = details .. "C"
+       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
+               -- (relatively to clients_max)
+               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
+
+               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.damage then
-               details = details .. "D"
+       if spec.creative then
+               table.insert(details, "1") -- creative icon
        else
-               details = details .. "_"
+               table.insert(details, "0")
        end
 
        if spec.pvp then
-               details = details .. "P"
+               table.insert(details, "2") -- pvp icon
+       elseif spec.damage then
+               table.insert(details, "1") -- heart icon
        else
-               details = details .. "_"
+               table.insert(details, "0")
        end
-       details = details .. " "
-
-       local playercount = ""
 
-       if spec.clients ~= nil and
-               spec.clients_max ~= nil then
-               playercount = string.format("%03d",spec.clients) .. "/" ..
-                                               string.format("%03d",spec.clients_max) .. " "
-       end
+       table.insert(details, color)
+       table.insert(details, text)
 
-       return playercount .. core.formspec_escape(details) ..  text
+       return table.concat(details, ",")
 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
-               
+       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
+       retval = retval .. "]"
+
+       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.
                return true
        end
-       
-       return false
+       return min_supp_proto <= server_proto_max and max_supp_proto >= server_proto_min
 end
 
---------------------------------------------------------------------------------
-function asyncOnlineFavourites()
-
-       menudata.favorites = {}
-       core.handle_async(
-               function(param)
-                       return core.get_favorites("online")
-               end,
-               nil,
-               function(result)
-                       menudata.favorites = result
-                       core.event_handler("Refresh")
+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 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(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
-       
-       retval = retval .. "]"
+end
 
-       return retval
+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
 end