Update mainmenu/init.lua
This commit is contained in:
parent
8e71b514e4
commit
67d5e435db
1 changed files with 524 additions and 125 deletions
|
|
@ -22,59 +22,46 @@ state = {}
|
|||
local fe = minetest.formspec_escape
|
||||
local hte = minetest.hypertext_escape
|
||||
|
||||
--FIXME: Replace with /content because pause menu
|
||||
dofile(minetest.get_builtin_path().."mainmenu/settings/settingtypes.lua")
|
||||
|
||||
---[[
|
||||
|
||||
minetest.set_formspec_prepend("\
|
||||
style[*;textcolor=#aaa]\
|
||||
style_type[field;border=false]\
|
||||
style_type[pwdfield;border=false]\
|
||||
style_type[image_button;border=false]\
|
||||
style_type[button;border=false;bgimg="..assets.."btn_bg_2.png;bgimg_middle=8,8]\
|
||||
style_type[button:hovered;border=false;bgimg="..assets.."btn_bg_2_hover.png;bgimg_middle=8,8]\
|
||||
style[nobg,nobg:hovered,nobg:focused,nobg:hovered+focused;border=false;bgimg="..default_textures.."blank.png;bgimg_middle=0]\
|
||||
")
|
||||
|
||||
-- Prepended to the meta menu's formspec.
|
||||
local meta_header = "formspec_version[8]\
|
||||
size["..size.x..","..size.y.."]\
|
||||
padding[0,0]\
|
||||
style[*;textcolor=#aaa]\
|
||||
style_type[image_button;border=false]\
|
||||
style_type[button;border=false;bgimg="..assets.."btn_bg.png;bgimg_middle=8,8]\
|
||||
bgcolor[#000;true;#151618]\
|
||||
style_type[box;bordercolors=#124722;borderwidths=-5;colors=#151618]\
|
||||
box[0,0;"..size.x..","..size.y..";]\
|
||||
image[0,"..(size.y *0.08)..");"..size.x..","..(size.x *(72/672))..";"..default_textures.."menu_header.png]\
|
||||
"
|
||||
local meta_footer = "\
|
||||
style[nobg;border=false;bgimg="..default_textures.."blank.png;bgimg_middle=0]\
|
||||
style[show_servers_view;border=false;bgimg="..fe(assets).."menu_servers.png;bgimg_middle=0]\
|
||||
style[show_servers_view:hovered;border=false;bgimg="..fe(assets).."menu_servers_hovered.png;bgimg_middle=0]\
|
||||
button["..(size.x *0.05)..","..(size.y *0.3)..";4,4;show_servers_view;]\
|
||||
button["..(size.x *0.05)..","..(size.y *0.3 +4)..";4,0.5;nobg;Servers]\
|
||||
style[show_content_view;border=false;bgimg="..fe(assets).."menu_content.png;bgimg_middle=0]\
|
||||
style[show_content_view:hovered;border=false;bgimg="..fe(assets).."menu_content_hovered.png;bgimg_middle=0]\
|
||||
button["..(size.x -(size.x *0.05) -4)..","..(size.y *0.3)..";4,4;show_content_view;]\
|
||||
button["..(size.x -(size.x *0.05) -4)..","..(size.y *0.3 +4)..";4,0.5;nobg;Content]\
|
||||
"
|
||||
-- box[0,0;"..size.x..","..size.y..";]\
|
||||
|
||||
-- Prepended to game menus' formspecs.
|
||||
local game_header = "formspec_version[8]\
|
||||
size["..size.x..","..size.y.."]\
|
||||
padding[0,0]\
|
||||
style[*;textcolor=#aaa]\
|
||||
style_type[image_button;border=false]\
|
||||
style_type[button;border=false;bgimg="..assets.."btn_bg.png;bgimg_middle=8,8]\
|
||||
bgcolor[#0000;true;#0000]\
|
||||
"
|
||||
local servers_header = "formspec_version[8]\
|
||||
size["..size.x..","..size.y.."]\
|
||||
padding[0,0]\
|
||||
style[*;textcolor=#aaa]\
|
||||
style_type[image_button;border=false]\
|
||||
style_type[field;border=false]\
|
||||
style_type[pwdfield;border=false]\
|
||||
style_type[button;border=false;bgimg="..assets.."btn_bg_2.png;bgimg_middle=8,8]\
|
||||
style_type[button:hovered;border=false;bgimg="..assets.."btn_bg_2_hover.png;bgimg_middle=8,8]\
|
||||
bgcolor[#0000;true;#151618]\
|
||||
"
|
||||
|
||||
local content_header = "formspec_version[8]\
|
||||
size["..size.x..","..size.y.."]\
|
||||
padding[0,0]\
|
||||
style[*;textcolor=#aaa]\
|
||||
style_type[image_button;border=false]\
|
||||
style_type[button;border=false;bgimg="..assets.."btn_bg.png;bgimg_middle=8,8]\
|
||||
bgcolor[#0000;true;#151618]\
|
||||
"
|
||||
|
||||
|
|
@ -194,7 +181,7 @@ local function get_worlds_for_game(id)
|
|||
end
|
||||
|
||||
-- Returns a list of content available for download.
|
||||
function get_all_content()
|
||||
function get_available_content()
|
||||
local version = minetest.get_version()
|
||||
local cdb = minetest.settings:get("contentdb_url")
|
||||
local url = cdb.."/api/packages/?type=mod&type=game&type=txp&protocol_version="..minetest.get_max_supp_proto().."&engine_version="..minetest.urlencode(version.string)
|
||||
|
|
@ -232,6 +219,88 @@ function get_all_content()
|
|||
return out
|
||||
end
|
||||
|
||||
-- Returns a list of all the installed mods.
|
||||
function get_all_mods(dir)
|
||||
local all = false
|
||||
if not dir then
|
||||
if state.all_mods then return state.all_mods end
|
||||
dir = minetest.get_modpath()
|
||||
all = true
|
||||
end
|
||||
local out = {}
|
||||
for _, x in ipairs(minetest.get_dir_list(dir, true)) do
|
||||
local info = minetest.get_content_info(dir.."/"..x)
|
||||
if info.type == "mod" then
|
||||
out[#out +1] = info
|
||||
end
|
||||
end
|
||||
if all then
|
||||
state.all_mods = out
|
||||
end
|
||||
return out
|
||||
end
|
||||
|
||||
-- Returns a list of all the installed games.
|
||||
function get_all_games(dir)
|
||||
local all = false
|
||||
if not dir then
|
||||
if state.all_games then return state.all_games end
|
||||
dir = minetest.get_gamepath()
|
||||
all = true
|
||||
end
|
||||
local out = {}
|
||||
for _, x in ipairs(minetest.get_dir_list(dir, true)) do
|
||||
local info = minetest.get_content_info(dir.."/"..x)
|
||||
if info.type == "game" then
|
||||
out[#out +1] = info
|
||||
end
|
||||
end
|
||||
if all then
|
||||
state.all_games = out
|
||||
end
|
||||
return out
|
||||
end
|
||||
|
||||
-- Returns a list of all the installed texture packs.
|
||||
function get_all_texture_packs(dir)
|
||||
local all = false
|
||||
if not dir then
|
||||
if state.all_texture_packs then return state.all_texture_packs end
|
||||
dir = minetest.get_texturepath()
|
||||
all = true
|
||||
end
|
||||
local out = {}
|
||||
for _, x in ipairs(minetest.get_dir_list(dir, true)) do
|
||||
local info = minetest.get_content_info(dir.."/"..x)
|
||||
if info.type == "txp" then
|
||||
out[#out +1] = info
|
||||
end
|
||||
end
|
||||
if all then
|
||||
state.all_texture_packs = out
|
||||
end
|
||||
return out
|
||||
end
|
||||
|
||||
-- Return a list of all content, as a conglomeration of the lists of mods, games, and texture packs.
|
||||
function get_all_content()
|
||||
if not state.all_content then
|
||||
state.all_content = {}
|
||||
table.insert_all(state.all_content, get_all_mods())
|
||||
table.insert_all(state.all_content, get_all_games())
|
||||
table.insert_all(state.all_content, get_all_texture_packs())
|
||||
table.sort(state.all_content, function(a, b)
|
||||
if not a then
|
||||
return b ~= nil
|
||||
elseif not b then
|
||||
return a == nil
|
||||
end
|
||||
return a.name < b.name
|
||||
end)
|
||||
end
|
||||
return state.all_content
|
||||
end
|
||||
|
||||
-- Parses text as .conf format.
|
||||
function parse_conf_text(txt)
|
||||
local out = {}
|
||||
|
|
@ -557,7 +626,7 @@ local function evaluate_template_expression(expr, vars, depth)
|
|||
vars = {item = vars}
|
||||
end
|
||||
|
||||
-- Expand all variables so we can deal with a constexpr
|
||||
-- Expand all variables so we can deal with a constexpr.
|
||||
local offset = 1
|
||||
while offset < 100000 do
|
||||
local a, b, name = expr:find("@([%a]+)", offset)
|
||||
|
|
@ -709,8 +778,7 @@ function show_meta_menu(v)
|
|||
"
|
||||
if dist == 0 then
|
||||
fs = fs.."\
|
||||
style[_game_label;bgimg="..default_textures.."blank.png]\
|
||||
button["..(lc -(scale /2))..","..(size.y /2 +4)..";4,0.5;_game_label;"..fe(x.title).."]\
|
||||
button["..(lc -(scale /2))..","..(size.y /2 +4)..";4,0.5;nobg;"..fe(x.title).."]\
|
||||
"
|
||||
end
|
||||
end
|
||||
|
|
@ -723,7 +791,20 @@ function show_meta_menu(v)
|
|||
scrollbar[0,-800;"..size.x..",0;horizontal;carousel;"..(v or "").."]\
|
||||
"
|
||||
|
||||
minetest.update_formspec(meta_header..fs..meta_footer)
|
||||
minetest.update_formspec(meta_header..fs.."\
|
||||
style[show_servers_view;border=false;bgimg="..fe(assets).."menu_servers.png;bgimg_middle=0]\
|
||||
style[show_servers_view:hovered;border=false;bgimg="..fe(assets).."menu_servers_hovered.png;bgimg_middle=0]\
|
||||
button["..(size.x *0.05)..","..(size.y *0.3)..";4,4;show_servers_view;]\
|
||||
button["..(size.x *0.05)..","..(size.y *0.3 +4)..";4,0.5;nobg;Servers]\
|
||||
style[show_content_view;border=false;bgimg="..fe(assets).."menu_content.png;bgimg_middle=0]\
|
||||
style[show_content_view:hovered;border=false;bgimg="..fe(assets).."menu_content_hovered.png;bgimg_middle=0]\
|
||||
button["..(size.x -(size.x *0.05) -4)..","..(size.y *0.3)..";4,4;show_content_view;]\
|
||||
button["..(size.x -(size.x *0.05) -4)..","..(size.y *0.3 +4)..";4,0.5;nobg;Content]\
|
||||
style[show_settings_view,show_about_view;bgimg="..assets.."menu_tab_bg.png]\
|
||||
style[show_settings_view:hovered,show_about_view:hovered;bgimg="..assets.."menu_tab_bg.png;bgcolor=#fffd]\
|
||||
button[1,0;2,0.5;show_about_view;About]\
|
||||
button["..(size.x -3)..",0;2,0.5;show_settings_view;Settings]\
|
||||
")
|
||||
end
|
||||
|
||||
-- Shows games' custom menus.
|
||||
|
|
@ -823,6 +904,13 @@ function show_game_menu(args)
|
|||
")
|
||||
end
|
||||
|
||||
function add_favorite_server(address, port)
|
||||
state.favorite_servers[#state.favorite_servers +1] = {address = address, port = port}
|
||||
local f = io.open(minetest.get_user_path().."/client/serverlist/favoriteservers.json", "w")
|
||||
f:write(minetest.write_json(state.favorite_servers))
|
||||
f:flush()
|
||||
f:close()
|
||||
end
|
||||
|
||||
function refresh_server_list()
|
||||
minetest.handle_async(
|
||||
|
|
@ -843,17 +931,9 @@ function refresh_server_list()
|
|||
end,
|
||||
nil,
|
||||
function(result)
|
||||
state.serverlist = result
|
||||
-- If we need to load the server list, we need to read the list of favorite servers as well.
|
||||
local favorite_servers = minetest.parse_json(read_file(minetest.get_user_path().."/client/serverlist/favoriteservers.json") or "{}")
|
||||
if #favorite_servers > 0 then
|
||||
for _, x in ipairs(favorite_servers) do
|
||||
x.favorite = true
|
||||
end
|
||||
table.insert_all(favorite_servers, state.serverlist)
|
||||
state.serverlist = favorite_servers
|
||||
end
|
||||
state.favorite_servers = favorite_servers
|
||||
local list = table.copy(state.favorite_servers)
|
||||
table.insert_all(list, result)
|
||||
state.serverlist = list
|
||||
if state.loc == "servers" then
|
||||
show_servers_menu()
|
||||
end
|
||||
|
|
@ -861,6 +941,94 @@ function refresh_server_list()
|
|||
)
|
||||
end
|
||||
|
||||
function search_server_list(input)
|
||||
if input:trim() == "" then
|
||||
return nil
|
||||
end
|
||||
|
||||
local search_str = ""
|
||||
local words = {}
|
||||
local mods = {}
|
||||
local games = {}
|
||||
local players = {}
|
||||
|
||||
input = input:lower()
|
||||
|
||||
for x in input:gmatch("%S+") do
|
||||
if x:sub(1, 4) == "mod:" then
|
||||
mods[#mods +1] = x:sub(5)
|
||||
elseif x:sub(1, 7) == "player:" then
|
||||
players[#players +1] = x:sub(8)
|
||||
elseif x:sub(1, 5) == "game:" then
|
||||
games[#games +1] = x:sub(6)
|
||||
else
|
||||
words[#words +1] = x
|
||||
end
|
||||
end
|
||||
|
||||
-- print(dump({words = words, mods= mods, players =players, games = games}, " "))
|
||||
|
||||
local out = {}
|
||||
for _, x in ipairs(state.serverlist) do
|
||||
local passed = true
|
||||
|
||||
for _, a in ipairs(words) do
|
||||
if not (x.description and x.description:lower():find(a, 1, true) or x.name and x.name:lower():find(a, 1, true)) then
|
||||
passed = false
|
||||
end
|
||||
end
|
||||
|
||||
-- If only `continue` existed...
|
||||
if passed then
|
||||
if #games > 0 then
|
||||
passed = false
|
||||
end
|
||||
for _, a in ipairs(games) do
|
||||
if a == x.gameid then
|
||||
passed = true
|
||||
end
|
||||
end
|
||||
|
||||
if passed then
|
||||
if x.mods and #mods > 0 then
|
||||
local found = 0
|
||||
for _, a in ipairs(x.mods) do
|
||||
for _, b in ipairs(mods) do
|
||||
if a == b then
|
||||
found = found +1
|
||||
end
|
||||
end
|
||||
end
|
||||
passed = found == #mods
|
||||
else
|
||||
passed = not not x.mods
|
||||
end
|
||||
|
||||
if passed then
|
||||
if x.clients_list and #players > 0 then
|
||||
local found = 0
|
||||
for _, a in ipairs(x.clients_list) do
|
||||
for _, b in ipairs(players) do
|
||||
if a:lower() == b then
|
||||
found = found +1
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
passed = found == #players
|
||||
else
|
||||
passed = not not x.clients_list
|
||||
end
|
||||
if passed then
|
||||
out[#out +1] = x
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
return out
|
||||
end
|
||||
|
||||
-- Shows the server list.
|
||||
function show_servers_menu()
|
||||
local fs = ""
|
||||
|
|
@ -872,23 +1040,28 @@ function show_servers_menu()
|
|||
for _, x in ipairs(favorite_servers) do
|
||||
x.favorite = true
|
||||
end
|
||||
state.favorite_servers = favorite_servers
|
||||
state.serverlist = favorite_servers
|
||||
-- fs = "\
|
||||
-- hypertext[0,0;"..size.x..","..size.y..";ht;<global valign=middle halign=center><tag name=action color=#222 hovercolor=#444>\
|
||||
-- <style size=72 color=#222><b>Fetching server list...</b></style>]\
|
||||
-- "
|
||||
end
|
||||
|
||||
-- Overlay dialogs don't occlude area tooltips, so such tooltips are disabled in that case.
|
||||
local showing_dialog = state.joining_server or state.connecting_to_server or state.showing_server_mods or state.showing_server_players
|
||||
|
||||
local current_server
|
||||
local joining_server
|
||||
|
||||
fs = "\
|
||||
style[servers_filter;border=false;textcolor=#aaa]\
|
||||
image["..(size.x *0.095)..","..(size.y *0.1 -0.85)..";"..(size.x *0.81 -2.55)..",0.75;"..assets.."btn_bg_2_light.png;8,8]\
|
||||
field["..(size.x *0.095 +0.1)..","..(size.y *0.1 -0.85)..";"..(size.x *0.81 -2.2)..",0.75;servers_filter;;"..(state.menu_vars.servers_filter or "").."]\
|
||||
image["..(size.x *0.095)..","..(size.y *0.1 -0.85)..";"..(size.x *0.81 -5.65)..",0.75;"..assets.."btn_bg_2_light.png;8,8]\
|
||||
field["..(size.x *0.095 +0.1)..","..(size.y *0.1 -0.85)..";"..(size.x *0.81 -5.45)..",0.75;servers_filter;;"..(state.menu_vars.servers_filter or "").."]\
|
||||
style[servers_search,servers_refresh,servers_cancel;bgimg="..assets.."btn_bg_2.png;bgimg_middle=8,8]\
|
||||
image_button["..(size.x *0.91 -0.85)..","..(size.y *0.1 -0.85)..";0.75,0.75;"..assets.."refresh.png;servers_refresh;]\
|
||||
image_button["..(size.x *0.91 -1.7)..","..(size.y *0.1 -0.85)..";0.75,0.75;"..assets.."cancel.png;servers_cancel;]\
|
||||
image_button["..(size.x *0.91 -2.55)..","..(size.y *0.1 -0.85)..";0.75,0.75;"..assets.."search.png;servers_search;]\
|
||||
image_button["..(size.x *0.91 -5.65)..","..(size.y *0.1 -0.85)..";0.75,0.75;"..assets.."search.png;servers_search;]\
|
||||
tooltip[servers_search;Search server list;#444;#aaa]\
|
||||
image_button["..(size.x *0.91 -4.8)..","..(size.y *0.1 -0.85)..";0.75,0.75;"..assets.."cancel.png;servers_cancel;]\
|
||||
tooltip[servers_cancel;Cancel search;#444;#aaa]\
|
||||
image_button["..(size.x *0.91 -3.95)..","..(size.y *0.1 -0.85)..";0.75,0.75;"..assets.."refresh.png;servers_refresh;]\
|
||||
tooltip[servers_refresh;Refresh server list;#444;#aaa]\
|
||||
button["..(size.x *0.91 -3.1)..","..(size.y *0.1 -0.85)..";3,0.75;direct_connection;Direct Connection...]\
|
||||
image["..(size.x *0.095)..","..(size.y *0.1)..";"..(size.x *0.81)..","..(size.y *0.8)..";"..assets.."btn_bg.png;8,8]\
|
||||
scroll_container[0,"..(size.y *0.1 +0.1)..";"..size.x..","..(size.y *0.8 -0.2)..";serverscroll;vertical;;0,0]\
|
||||
"
|
||||
|
|
@ -896,47 +1069,7 @@ function show_servers_menu()
|
|||
local infox = state.current_server and size.x *0.6 or size.x *0.9
|
||||
local max = size.x *0.9
|
||||
local i = 0
|
||||
-- if #state.favorite_servers > 0 then
|
||||
-- fs = fs.."\
|
||||
-- box["..listx..","..(i *0.5)..";"..(infox -listx)..",0.5;#"..(i %2 == 1 and "373530" or "403e39").."ff]\
|
||||
-- box["..(listx -0.05)..","..(i *0.5 +0.2)..";"..(infox -listx +0.1)..",0.1;#292d2fff]\
|
||||
-- box["..((infox -listx) /2 -1.5)..","..(i *0.5)..";3,0.5;#"..(i %2 == 1 and "373530" or "403e39").."ff]\
|
||||
-- box["..((infox -listx) /2 -1.55)..","..(i *0.5 +0.125)..";0.1,0.25;#292d2fff]\
|
||||
-- box["..((infox -listx) /2 +1.45)..","..(i *0.5 +0.125)..";0.1,0.25;#292d2fff]\
|
||||
-- hypertext["..((infox -listx) /2 -1.5)..","..(i *0.5)..";3,0.5;;<global valign=middle halign=center color=#aaa>Favorite Servers]\
|
||||
-- "
|
||||
-- i = i +1
|
||||
-- end
|
||||
-- for idx, x in ipairs(state.favorite_servers) do
|
||||
-- if x.address and x.port then
|
||||
-- local address = minetest.encode_base64(x.address)
|
||||
-- if address == state.current_server then
|
||||
-- current_server = x
|
||||
-- end
|
||||
-- if address == state.joining_server then
|
||||
-- joining_server = x
|
||||
-- end
|
||||
-- fs = fs.."\
|
||||
-- style[serverinfof"..idx..";border=false;bgimg="..assets.."white.png;bgimg_middle=0;bgcolor=#"..(i %2 == 1 and "373530" or "403e39").."ff]\
|
||||
-- style[serverinfof"..idx..":hovered;border=false;bgimg="..assets.."white.png;bgimg_middle=0]\
|
||||
-- button["..listx..","..(i *0.5)..";"..(infox -listx)..",0.5;serverinfof"..idx..";]\
|
||||
-- label["..(listx +0.1)..","..(i *0.5 +0.25)..";"..fe(x.address..":"..x.port).."]\
|
||||
-- "
|
||||
-- i = i +1
|
||||
-- end
|
||||
-- end
|
||||
-- if i > 0 then
|
||||
-- fs = fs.."\
|
||||
-- box["..listx..","..(i *0.5)..";"..(infox -listx)..",0.5;#"..(i %2 == 1 and "373530" or "403e39").."ff]\
|
||||
-- box["..(listx -0.05)..","..(i *0.5 +0.2)..";"..(infox -listx +0.1)..",0.1;#292d2fff]\
|
||||
-- box["..((infox -listx) /2 -1.5)..","..(i *0.5)..";3,0.5;#"..(i %2 == 1 and "373530" or "403e39").."ff]\
|
||||
-- box["..((infox -listx) /2 -1.55)..","..(i *0.5 +0.125)..";0.1,0.25;#292d2fff]\
|
||||
-- box["..((infox -listx) /2 +1.45)..","..(i *0.5 +0.125)..";0.1,0.25;#292d2fff]\
|
||||
-- hypertext["..((infox -listx) /2 -1.5)..","..(i *0.5)..";3,0.5;;<global valign=middle halign=center color=#aaa>Public Servers]\
|
||||
-- "
|
||||
-- i = i +1
|
||||
-- end
|
||||
for idx, x in ipairs(state.serverlist) do
|
||||
for idx, x in ipairs(state.serverlist_filtered or state.serverlist) do
|
||||
-- Skip incompatible servers. You can't join them, so showing them is rather pointless.
|
||||
if (x.proto_max or version.proto_min) >= version.proto_min then
|
||||
local ping_lvl = 0
|
||||
|
|
@ -955,8 +1088,6 @@ function show_servers_menu()
|
|||
if name == "" then
|
||||
name = minetest.colorize("#888", x.address..":"..x.port)
|
||||
end
|
||||
-- Otherwise, the colons in an IPv6 address would make the style element blow up.
|
||||
--local address = minetest.encode_base64(x.address)
|
||||
local label_offset = 0.1
|
||||
fs = fs.."\
|
||||
style[serverinfo"..idx..";border=false;bgimg="..assets.."white.png;bgimg_middle=0;bgcolor=#"..(i %2 == 1 and "373530" or "403e39").."ff]\
|
||||
|
|
@ -964,17 +1095,50 @@ function show_servers_menu()
|
|||
button["..listx..","..(i *0.5)..";"..(infox -listx)..",0.5;serverinfo"..idx..";]\
|
||||
"
|
||||
if x.favorite then
|
||||
-- The overlay dialog doesn't occlude area tooltips, so they are disabled in that case.
|
||||
fs = fs.."\
|
||||
image["..(listx)..","..(i *0.5)..";0.5,0.5;"..assets.."menu_servers_favorite.png]\
|
||||
"..(state.joining_server and "" or "tooltip["..(listx)..","..(i *0.5)..";0.5,0.5;Favorite server;#444;#aaa]\
|
||||
"..(showing_dialog and "" or "tooltip["..(listx)..","..(i *0.5)..";0.5,0.5;Favorite server;#444;#aaa]\
|
||||
")
|
||||
label_offset = 0.6
|
||||
end
|
||||
local clients = ""
|
||||
local color = "#aaa"
|
||||
local icons_offset = (infox -0.6)
|
||||
if x.clients then
|
||||
icons_offset = icons_offset -1
|
||||
clients = x.clients..(x.clients_max and "/"..x.clients_max or "")
|
||||
if x.clients > 0 and x.clients_max then
|
||||
local percent = x.clients /x.clients_max
|
||||
if percent < 0.75 then
|
||||
color = "#638b67"
|
||||
elseif percent < 1 then
|
||||
color = "#a69174"
|
||||
else
|
||||
color = "#9d5b5b"
|
||||
end
|
||||
end
|
||||
fs = fs.."\
|
||||
hypertext["..icons_offset..","..(i *0.5)..";1,0.5;;<global valign=middle halign=center color="..color..">"..fe(clients).."]\
|
||||
"
|
||||
end
|
||||
if x.pvp == false then
|
||||
icons_offset = icons_offset -0.5
|
||||
fs = fs.."\
|
||||
image["..(icons_offset)..","..(i *0.5)..";0.5,0.5;"..assets.."menu_servers_peaceful.png]\
|
||||
"..(showing_dialog and "" or "tooltip["..(icons_offset)..","..(i *0.5)..";0.5,0.5;Peaceful;#444;#aaa]\
|
||||
")
|
||||
end
|
||||
if x.creative then
|
||||
icons_offset = icons_offset -0.5
|
||||
fs = fs.."\
|
||||
image["..(icons_offset)..","..(i *0.5)..";0.5,0.5;"..assets.."menu_servers_creative.png]\
|
||||
"..(showing_dialog and "" or "tooltip["..(icons_offset)..","..(i *0.5)..";0.5,0.5;Creative;#444;#aaa]\
|
||||
")
|
||||
end
|
||||
fs = fs.."\
|
||||
label["..(listx +label_offset)..","..(i *0.5 +0.25)..";"..fe(name).."]\
|
||||
"..((x.ping or x.lag) and "image["..(infox -0.6)..","..(i *0.5)..";0.5,0.5;"..assets.."menu_servers_icon_ping_"..ping_lvl..".png]\
|
||||
"..(state.joining_server and "" or "tooltip["..(infox -0.6)..","..(i *0.5)..";0.5,0.5;Ping: "..math.floor(lag)..";#444;#aaa]\
|
||||
"..(showing_dialog and "" or "tooltip["..(infox -0.6)..","..(i *0.5)..";0.5,0.5;Ping: "..math.floor(lag)..";#444;#aaa]\
|
||||
") or "")
|
||||
i = i +1
|
||||
end
|
||||
|
|
@ -984,6 +1148,11 @@ function show_servers_menu()
|
|||
hypertext["..listx..","..(i *0.5)..";"..(infox -listx)..",0.5;;<global valign=middle halign=center color=#777>Loading...]\
|
||||
"
|
||||
end
|
||||
if i < 1 then
|
||||
fs = fs.."\
|
||||
hypertext["..listx..","..(i *0.5)..";"..(infox -listx)..",0.5;;<global valign=middle halign=center color=#777>No servers found.]\
|
||||
"
|
||||
end
|
||||
fs = fs.."\
|
||||
scroll_container_end[]\
|
||||
scrollbar[-800,0;1,1;vertical;serverscroll;"..(state.menu_vars.serverscroll and tonumber(state.menu_vars.serverscroll:sub(5)) or 0).."]\
|
||||
|
|
@ -996,7 +1165,31 @@ function show_servers_menu()
|
|||
box["..((max -infox) *0.7 -0.05)..",0.75;0.1,0.5;#292d2fff]\
|
||||
hypertext[0.2,0.8;"..((max -infox) *0.7 -0.2)..",0.5;server_address;<global valign=middle color=#aaa>"..fe(hte(state.current_server.address)).."]\
|
||||
hypertext["..((max -infox) *0.7 +0.1)..",0.8;"..((max -infox) *0.3 -0.2)..",0.5;server_port;<global valign=middle color=#aaa>"..fe(hte(tostring(state.current_server.port))).."]\
|
||||
hypertext[0.1,1.5;"..(max -infox -0.2)..","..((size.y *0.8 -1.5 -1.05))..";server_desc;<global color=#aaa>"..fe(hte(state.current_server.description or "")).."]\
|
||||
"
|
||||
local buttons_offset = 0.1
|
||||
if state.current_server.mods then
|
||||
fs = fs.."\
|
||||
image_button["..buttons_offset..",1.5;0.5,0.5;"..assets.."menu_servers_mods.png;show_server_mods;]\
|
||||
tooltip[show_server_mods;Show mod list;#444;#aaa]\
|
||||
"
|
||||
buttons_offset = buttons_offset +0.5
|
||||
end
|
||||
if state.current_server.clients then
|
||||
fs = fs.."\
|
||||
image_button["..buttons_offset..",1.5;0.5,0.5;"..assets.."menu_servers_players.png;show_server_players;]\
|
||||
tooltip[show_server_players;Show player list;#444;#aaa]\
|
||||
"
|
||||
buttons_offset = buttons_offset +0.5
|
||||
end
|
||||
if state.current_server.favorite then
|
||||
fs = fs.."\
|
||||
image_button["..buttons_offset..",1.5;0.5,0.5;"..assets.."menu_servers_unfavorite.png;unfavorite_server;]\
|
||||
tooltip[unfavorite_server;Remove from favorites;#444;#aaa]\
|
||||
"
|
||||
buttons_offset = buttons_offset +0.5
|
||||
end
|
||||
fs = fs.."\
|
||||
hypertext[0.1,2.25;"..(max -infox -0.2)..","..((size.y *0.8 -1.5 -1.05))..";server_desc;<global color=#aaa>"..fe(hte(state.current_server.description or "")).."]\
|
||||
button[0.1,"..(size.y *0.8 -1)..";"..(max -infox -0.2)..",0.75;join_server;Join Server]\
|
||||
container_end[]\
|
||||
"
|
||||
|
|
@ -1006,28 +1199,98 @@ function show_servers_menu()
|
|||
button[0,"..(size.y -1)..";1,1;to_meta_menu;<]\
|
||||
"
|
||||
|
||||
if state.joining_server or state.connecting_to_server then
|
||||
local offset = 0
|
||||
if state.server_connection_error then
|
||||
offset = offset +1
|
||||
fs= fs.."\
|
||||
hypertext[0,0;"..(size.x *0.5)..",1;;<global valign=middle color=#faa>"..fe(hte(state.server_connection_error)).."]\
|
||||
if state.showing_server_mods then
|
||||
fs = fs.."\
|
||||
box[0,0;"..size.x..","..size.y..";#0008]\
|
||||
style[_even,_even:hovered;border=false;bgimg="..assets.."white.png;bgimg_middle=0;bgcolor=#403e39ff]\
|
||||
style[_odd,_odd:hovered;border=false;bgimg="..assets.."white.png;bgimg_middle=0;bgcolor=#373530ff]\
|
||||
image["..(size.x /4 -0.1)..","..(size.y /4 -0.1)..";"..(size.x /2 +0.2)..","..(size.y /2 +0.2)..";"..assets.."btn_bg.png;8,8]\
|
||||
scroll_container["..(size.x /4)..","..(size.y /4)..";"..(size.x /2)..","..(size.y /2 -1)..";modsscroll;vertical;;0,0]\
|
||||
"
|
||||
for i, x in ipairs(state.current_server.mods) do
|
||||
fs = fs.."\
|
||||
button[0,"..(i *0.5 -0.5)..";"..(infox -listx)..",0.5;"..(i %2 == 1 and "_odd" or "_even")..";]\
|
||||
label[0.1,"..(i *0.5 -0.25)..";"..fe(x).."]\
|
||||
"
|
||||
end
|
||||
fs = fs.."\
|
||||
scroll_container_end[]\
|
||||
scrollbar[-800,0;1,1;vertical;modsscroll;]\
|
||||
button["..(size.x /4)..","..(size.y *0.75 -0.875)..";"..(size.x /2)..",0.75;close_dialog;Back]\
|
||||
"
|
||||
end
|
||||
|
||||
if state.showing_server_players then
|
||||
fs = fs.."\
|
||||
box[0,0;"..size.x..","..size.y..";#0008]\
|
||||
style[_even,_even:hovered;border=false;bgimg="..assets.."white.png;bgimg_middle=0;bgcolor=#403e39ff]\
|
||||
style[_odd,_odd:hovered;border=false;bgimg="..assets.."white.png;bgimg_middle=0;bgcolor=#373530ff]\
|
||||
image["..(size.x /4 -0.1)..","..(size.y /4 -0.1)..";"..(size.x /2 +0.2)..","..(size.y /2 +0.2)..";"..assets.."btn_bg.png;8,8]\
|
||||
scroll_container["..(size.x /4)..","..(size.y /4)..";"..(size.x /2)..","..(size.y /2 -1)..";modsscroll;vertical;;0,0]\
|
||||
"
|
||||
for i, x in ipairs(state.current_server.clients_list) do
|
||||
fs = fs.."\
|
||||
button[0,"..(i *0.5 -0.5)..";"..(infox -listx)..",0.5;"..(i %2 == 1 and "_odd" or "_even")..";]\
|
||||
label[0.1,"..(i *0.5 -0.25)..";"..fe(x).."]\
|
||||
"
|
||||
end
|
||||
fs = fs.."\
|
||||
scroll_container_end[]\
|
||||
scrollbar[-800,0;1,1;vertical;modsscroll;]\
|
||||
button["..(size.x /4)..","..(size.y *0.75 -0.875)..";"..(size.x /2)..",0.75;close_dialog;Back]\
|
||||
"
|
||||
end
|
||||
|
||||
if state.joining_server or state.connecting_to_server then
|
||||
local offset = 0
|
||||
fs = fs.."\
|
||||
box[0,0;"..size.x..","..size.y..";#0008]\
|
||||
image["..(size.x *0.25 -0.2)..","..(size.y *0.25 -0.1)..";"..(size.x *0.5 +0.4)..","..(size.y *0.5 +0.2)..";"..assets.."btn_bg.png;8,8]\
|
||||
scroll_container["..(size.x *0.25)..","..(size.y *0.25)..";"..(size.x *0.5)..","..(size.y *0.5 +0.2)..";serverconfscroll;vertical;;0,0]\
|
||||
hypertext[0,"..offset..";"..(size.x *0.5)..",0.75;;<global valign=middle halign=center color=#aaa>Connecting to <b>"..fe(hte(state.current_server.name or state.current_server.address..":"..state.current_server.port)).."</b>...]\
|
||||
"
|
||||
|
||||
if state.server_connection_error then
|
||||
offset = offset +0.75
|
||||
fs = fs.."\
|
||||
hypertext[0,0;"..(size.x *0.5)..",0.75;;<global valign=middle color=#9d5b5b>"..fe(hte(state.server_connection_error.msg)).."]\
|
||||
set_focus["..fe(state.server_connection_error.element)..";true]\
|
||||
"
|
||||
else
|
||||
fs = fs.."\
|
||||
set_focus[server_"..(state.joining_server and "username" or "address")..";true]\
|
||||
"
|
||||
end
|
||||
if state.joining_server then
|
||||
fs = fs.."\
|
||||
hypertext[0,"..offset..";"..(size.x *0.5)..",0.75;;<global valign=middle halign=center color=#aaa>Connecting to <b>"..fe(hte(state.current_server.name or state.current_server.address..":"..state.current_server.port)).."</b>...]\
|
||||
"
|
||||
offset = offset +1
|
||||
else
|
||||
fs = fs.."\
|
||||
set_focus[server_address;true]\
|
||||
hypertext[0,"..offset..";"..(size.x *0.5)..",0.75;;<global valign=middle halign=center color=#aaa>Connecting to server...]\
|
||||
"
|
||||
offset = offset +1
|
||||
fs = fs.."\
|
||||
image[0,"..(0.25 +offset)..";"..(size.x *0.5)..",0.75;"..assets.."btn_bg_2_light.png;8,8]\
|
||||
label[0.2,"..(0.1 +offset)..";Address]\
|
||||
field[0.2,"..(0.25 +offset)..";"..(size.x *0.4 -0.4)..",0.75;server_address;;"..(state.menu_vars.server_address or "").."]\
|
||||
box["..(size.x *0.4 -0.25)..","..(0.25 +offset)..";0.1,0.75;#292d2fff]\
|
||||
label["..(size.x *0.4 -0.2)..","..(0.1 +offset)..";Port]\
|
||||
field["..(size.x *0.4)..","..(0.25 +offset)..";"..(size.x *0.1 -0.2)..",0.75;server_port;;"..(state.menu_vars.server_port or "").."]\
|
||||
"
|
||||
offset = offset +1
|
||||
end
|
||||
fs = fs.."\
|
||||
image[0,"..(0.25 +offset)..";"..(size.x *0.5)..",0.75;"..assets.."btn_bg_2_light.png;8,8]\
|
||||
label[0.2,"..(0.1 +offset)..";Username]\
|
||||
field[0.2,"..(0.25 +offset)..";"..(size.x *0.5 -0.4)..",0.75;server_username;;"..minetest.settings:get("name").."]\
|
||||
image[0,"..(1.25 +offset)..";"..(size.x *0.5)..",0.75;"..assets.."btn_bg_2_light.png;8,8]\
|
||||
label[0.2,"..(1.1 +offset)..";Username]\
|
||||
field[0.2,"..(1.25 +offset)..";"..(size.x *0.5 -0.4)..",0.75;server_username;;"..minetest.settings:get("name").."]\
|
||||
image[0,"..(2.25 +offset)..";"..(size.x *0.5)..",0.75;"..assets.."btn_bg_2_light.png;8,8]\
|
||||
style[server_password;border=false;textcolor=#aaa;bgimg="..assets.."btn_bg.png]\
|
||||
label[0.2,"..(2.1 +offset)..";Password]\
|
||||
pwdfield[0.2,"..(2.25 +offset)..";"..(size.x *0.5 -0.4)..",0.75;server_password;]\
|
||||
button[0,"..(3.25 +offset)..";"..(size.x *0.5)..",0.75;cancel_join_server;Cancel]\
|
||||
button[0,"..(4.25 +offset)..";"..(size.x *0.5)..",0.75;confirm_join_server;Join]\
|
||||
label[0.2,"..(1.1 +offset)..";Password]\
|
||||
pwdfield[0.2,"..(1.25 +offset)..";"..(size.x *0.5 -0.4)..",0.75;server_password;]\
|
||||
button[0,"..(2.25 +offset)..";"..(size.x *0.5)..",0.75;cancel_join_server;Cancel]\
|
||||
button[0,"..(3.25 +offset)..";"..(size.x *0.5)..",0.75;confirm_join_server;Join]\
|
||||
scroll_container_end[]\
|
||||
scrollbar[-800,0;1,1;vertical;serverconfscroll;"..(state.menu_vars.serverconfscroll and tonumber(state.menu_vars.serverconfscroll:sub(5)) or 0).."]\
|
||||
"
|
||||
|
|
@ -1038,6 +1301,90 @@ end
|
|||
-- Shows the content manager.
|
||||
function show_content_menu()
|
||||
local fs = ""
|
||||
|
||||
if not state.all_content then
|
||||
get_all_content()
|
||||
end
|
||||
|
||||
local w = size.x
|
||||
local h = size.y -1.1
|
||||
|
||||
fs = "\
|
||||
scroll_container[0,1.1;"..w..","..h..";contentscroll;horizontal;;]\
|
||||
"
|
||||
|
||||
local cols = math.floor(w /2.5)
|
||||
local spacing_x = w %2.5 /cols +0.5
|
||||
|
||||
local rows = math.floor(h /3)
|
||||
local spacing_y = h %3 /rows +0.5
|
||||
|
||||
local pages = math.ceil(#state.all_content /(rows *cols))
|
||||
local page = state.content_page or 1
|
||||
|
||||
local offset = page /10
|
||||
|
||||
local x = 0
|
||||
local y = 0
|
||||
local i = (page -1) *(rows *cols) +1
|
||||
|
||||
while true do
|
||||
local pkg = state.all_content[i]
|
||||
if not pkg then break end
|
||||
local icon = pkg.type == "game" and pkg.path.."/menu/icon.png" or pkg.path.."/icon.png"
|
||||
if not file_exists(icon) then
|
||||
icon = assets.."menu_content.png"
|
||||
end
|
||||
local title = pkg.title:trim()
|
||||
if title == "" then
|
||||
title = pkg.name
|
||||
end
|
||||
fs = fs.."\
|
||||
image_button["..(x *(2 +spacing_x) +(spacing_x /2) +offset)..","..(y *(2 +spacing_y) +(spacing_y /2))..";2,2;"..fe(icon)..";view_package_"..fe(pkg.path)..";]\
|
||||
tooltip[view_package_"..fe(pkg.path)..";"..fe(title)..";#444;#aaa]\
|
||||
hypertext["..(x *(2 +spacing_x) +(spacing_x /2) +offset)..","..(y *(2 +spacing_y) +(spacing_y /2) +2)..";2,0.5;nobg;<global color=#aaa valign=middle halign=center>"..fe(hte(title)).."]\
|
||||
"
|
||||
i = i +1
|
||||
x = x +1
|
||||
if x > cols -1 then
|
||||
x = 0
|
||||
y = y +1
|
||||
if y > rows -1 then break end
|
||||
end
|
||||
end
|
||||
|
||||
fs = fs.."\
|
||||
box[0,0;"..(pages *w)..",1;#0000]\
|
||||
scroll_container_end[]\
|
||||
scrollbaroptions[min=1;max="..pages..";smallstep=1]\
|
||||
scrollbar[-800,0;1,1;horizontal;contentscroll;"..page.."]\
|
||||
"
|
||||
|
||||
fs = fs.."\
|
||||
box[0,0;"..size.x..",1;#403e39ff]\
|
||||
box[0,1;"..size.x..",0.1;#292d2fff]\
|
||||
image_button[0,0;1,1;"..assets.."search.png;test;]\
|
||||
image_button[1,0;1,1;"..assets.."cancel.png;test;]\
|
||||
style[test;bgimg="..assets.."white.png;bgimg_middle=0;bgcolor=#403e39ff]\
|
||||
style[test:hovered;bgimg="..assets.."white.png;bgimg_middle=0]\
|
||||
image[2,0.125;"..(size.x -9)..",0.75;"..assets.."btn_bg_2_light.png;8,8]\
|
||||
field[2.1,0.125;"..(size.x -9.2)..",0.75;content_filter;;]\
|
||||
button["..(w -7)..",0;4,1;test;Browse Online Content...]\
|
||||
button["..(w -3)..",0;3,1;test;Add Content...]\
|
||||
"
|
||||
|
||||
local start = w /2 -(pages *0.125)
|
||||
|
||||
for i = 1, pages do
|
||||
fs = fs.."\
|
||||
image_button["..(start +(i *0.25))..","..(size.y -0.5)..";0.25,0.25;"..assets..(i == page and "circle_light.png" or "circle.png")..";page"..i..";]\
|
||||
"
|
||||
end
|
||||
|
||||
if state.current_package then
|
||||
|
||||
end
|
||||
|
||||
minetest.update_formspec(content_header..fs.."\
|
||||
button[0,"..(size.y -1)..";1,1;to_meta_menu;<]\
|
||||
")
|
||||
|
|
@ -1074,26 +1421,67 @@ function minetest.button_handler(data)
|
|||
if data.servers_refresh then
|
||||
refresh_server_list()
|
||||
elseif data.servers_search or data.key_enter_field == "servers_filter" then
|
||||
state.servers_filter = data.servers_filter
|
||||
state.serverlist_filtered = search_server_list(data.servers_filter)
|
||||
show_servers_menu()
|
||||
elseif data.servers_cancel then
|
||||
state.servers_filter = nil
|
||||
state.serverlist_filtered = nil
|
||||
show_servers_menu()
|
||||
elseif data.show_server_mods then
|
||||
state.showing_server_mods = true
|
||||
show_servers_menu()
|
||||
elseif data.show_server_players then
|
||||
state.showing_server_players = true
|
||||
show_servers_menu()
|
||||
elseif data.close_dialog then
|
||||
state.showing_server_players = nil
|
||||
state.showing_server_mods = nil
|
||||
show_servers_menu()
|
||||
elseif data.direct_connection then
|
||||
state.connecting_to_server = true
|
||||
show_servers_menu()
|
||||
elseif data.join_server then
|
||||
state.joining_server = true
|
||||
show_servers_menu()
|
||||
elseif data.cancel_join_server then
|
||||
state.joining_server = nil
|
||||
state.connecting_to_server = nil
|
||||
show_servers_menu()
|
||||
elseif data.confirm_join_server or data.key_enter_field == "server_username" or data.key_enter_field == "server_password" then
|
||||
elseif data.confirm_join_server or data.key_enter_field == "server_username" or data.key_enter_field == "server_password" or data.key_enter_field == "server_address" then
|
||||
minetest.settings:set("name", data.server_username)
|
||||
minetest.settings:set("address", state.current_server.address)
|
||||
minetest.settings:set("remote_port", state.current_server.port)
|
||||
if not tonumber(data.server_port) then
|
||||
state.server_connection_error = {
|
||||
msg = "Invalid port.",
|
||||
element = "server_port"
|
||||
}
|
||||
show_servers_menu()
|
||||
state.server_connection_error = nil
|
||||
return
|
||||
end
|
||||
local address
|
||||
local port
|
||||
if state.connecting_to_server then
|
||||
address = data.server_address:lower()
|
||||
port = data.server_port:lower()
|
||||
else
|
||||
address = state.current_server.address:lower()
|
||||
port = state.current_server.port:lower()
|
||||
end
|
||||
local is_favorite = false
|
||||
for _, x in ipairs(state.favorite_servers) do
|
||||
if x.address == address and x.port == port then
|
||||
is_favorite = true
|
||||
end
|
||||
end
|
||||
if not is_favorite then
|
||||
add_favorite_server(address, port)
|
||||
end
|
||||
minetest.settings:set("address", address)
|
||||
minetest.settings:set("remote_port", port)
|
||||
gamedata = {
|
||||
playername = data.server_username,
|
||||
password = data.server_password,
|
||||
address = state.current_server.address,
|
||||
port = state.current_server.port,
|
||||
address = address,
|
||||
port = port,
|
||||
selected_world = 0,
|
||||
singleplayer = false
|
||||
}
|
||||
|
|
@ -1106,15 +1494,23 @@ function minetest.button_handler(data)
|
|||
if idx:sub(1, 1) == "f" then
|
||||
state.current_server = state.favorite_servers[tonumber(idx:sub(2))]
|
||||
else
|
||||
state.current_server = state.serverlist[tonumber(idx)]
|
||||
state.current_server = (state.serverlist_filtered or state.serverlist)[tonumber(idx)]
|
||||
end
|
||||
show_servers_menu()
|
||||
end
|
||||
end
|
||||
end
|
||||
elseif state.loc == "content" then
|
||||
for k, v in pairs(data) do
|
||||
|
||||
if data.contentscroll and data.contentscroll:sub(1, 4) == "CHG:" then
|
||||
state.content_page = tonumber(data.contentscroll:sub(5))
|
||||
show_content_menu()
|
||||
else
|
||||
for k, v in pairs(data) do
|
||||
if k:sub(1, 4) == "page" then
|
||||
state.content_page = tonumber(k:sub(5))
|
||||
show_content_menu()
|
||||
end
|
||||
end
|
||||
end
|
||||
elseif state.loc == "game" then
|
||||
for k, v in pairs(data) do
|
||||
|
|
@ -1149,10 +1545,13 @@ function minetest.button_handler(data)
|
|||
end
|
||||
|
||||
function minetest.event_handler(ev)
|
||||
-- Quit on quit
|
||||
-- When Esc is pressed, close the current dialog, or the game if we are on the meta menu.
|
||||
if ev == "MenuQuit" then
|
||||
if state.joining_server then
|
||||
if state.joining_server or state.connecting_to_server or state.showing_server_mods or state.showing_server_players then
|
||||
state.joining_server = nil
|
||||
state.connecting_to_server = nil
|
||||
state.showing_server_mods = nil
|
||||
state.showing_server_players = nil
|
||||
show_servers_menu()
|
||||
elseif state.loc ~= "games" then
|
||||
show_meta_menu()
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue