Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add visited servers section to serverlist #15660

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions LICENSE.txt
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,9 @@ srifqi:
textures/base/pack/joystick_off.png
textures/base/pack/minimap_btn.png

siliconsniffer:
textures/base/pack/server_visited.png

Zughy:
textures/base/pack/cdb_downloading.png
textures/base/pack/cdb_queued.png
Expand Down
101 changes: 96 additions & 5 deletions builtin/mainmenu/serverlistmgr.lua
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@ serverlistmgr = {
-- list of locally favorites servers
favorites = nil,

-- list of last visited servers
last_visited = nil,

-- list of servers fetched from public list
servers = nil,
}
Expand Down Expand Up @@ -113,12 +116,14 @@ local function order_server_list_internal(list)
end

local function order_server_list(list)
-- split the list into two parts and sort them separately, to keep empty
-- split the list into three parts and sort them separately, to keep empty
-- servers at the bottom.
local nonempty, empty = {}, {}
local visited, nonempty, empty = {}, {}, {}

for _, fav in ipairs(list) do
if (fav.clients or 0) > 0 then
if fav.last_visited then
table.insert(visited, fav)
elseif (fav.clients or 0) > 0 then
table.insert(nonempty, fav)
else
table.insert(empty, fav)
Expand All @@ -128,8 +133,11 @@ local function order_server_list(list)
order_server_list_internal(nonempty)
order_server_list_internal(empty)

table.insert_all(nonempty, empty)
return nonempty
local result = {}
table.insert_all(result, visited)
table.insert_all(result, nonempty)
table.insert_all(result, empty)
return result
end

local public_downloading = false
Expand Down Expand Up @@ -231,6 +239,15 @@ local function get_favorites_path(folder)
return base .. core.settings:get("serverlist_file")
end

--------------------------------------------------------------------------------
local function get_last_visited_path(folder)
local base = core.get_user_path() .. DIR_DELIM .. "client" .. DIR_DELIM .. "serverlist" .. DIR_DELIM
if folder then
return base
end
return base .. "last_visited.json"
end

--------------------------------------------------------------------------------
local function save_favorites(favorites)
local filename = core.settings:get("serverlist_file")
Expand All @@ -243,6 +260,12 @@ local function save_favorites(favorites)
core.safe_file_write(get_favorites_path(), core.write_json(favorites))
end

--------------------------------------------------------------------------------
local function save_last_visited(visited)
assert(core.create_dir(get_last_visited_path(true)))
core.safe_file_write(get_last_visited_path(), core.write_json(visited))
end

--------------------------------------------------------------------------------
function serverlistmgr.read_legacy_favorites(path)
local file = io.open(path, "r")
Expand Down Expand Up @@ -326,6 +349,21 @@ local function read_favorites()
return favs
end

--------------------------------------------------------------------------------
local function read_last_visited()
local path = get_last_visited_path()

local file = io.open(path, "r")
if not file then
return {}
end

local json = file:read("*all")
file:close()

return core.parse_json(json)
end

--------------------------------------------------------------------------------
local function delete_favorite(favorites, del_favorite)
for i=1, #favorites do
Expand All @@ -338,6 +376,18 @@ local function delete_favorite(favorites, del_favorite)
end
end

--------------------------------------------------------------------------------
local function delete_last_visited(visited, del_visited)
for i=1, #visited do
local vis = visited[i]

if vis.address == del_visited.address and vis.port == del_visited.port then
table.remove(visited, i)
return
end
end
end

--------------------------------------------------------------------------------
function serverlistmgr.get_favorites()
if serverlistmgr.favorites then
Expand All @@ -359,6 +409,16 @@ function serverlistmgr.get_favorites()
return serverlistmgr.favorites
end

-------------------------------------------------------------------------------
function serverlistmgr.get_last_visited()
if serverlistmgr.last_visited then
return serverlistmgr.last_visited
end

serverlistmgr.last_visited = read_last_visited()
return serverlistmgr.last_visited
end

--------------------------------------------------------------------------------
function serverlistmgr.add_favorite(new_favorite)
assert(type(new_favorite.port) == "number")
Expand All @@ -377,9 +437,40 @@ function serverlistmgr.add_favorite(new_favorite)
save_favorites(favorites)
end

-------------------------------------------------------------------------------
function serverlistmgr.add_last_visited(new_visited)
assert(type(new_visited.port) == "number")
assert(new_visited.address)

-- Whitelist visited keys
new_visited = {
name = new_visited.name,
address = new_visited.address,
port = new_visited.port,
description = new_visited.description,
}

local visited = serverlistmgr.get_last_visited()
delete_last_visited(visited, new_visited)
table.insert(visited, 1, new_visited)

if #visited > 5 then
table.remove(visited, #visited)
end

save_last_visited(visited)
end

--------------------------------------------------------------------------------
function serverlistmgr.delete_favorite(del_favorite)
local favorites = serverlistmgr.get_favorites()
delete_favorite(favorites, del_favorite)
save_favorites(favorites)
end

-------------------------------------------------------------------------------
function serverlistmgr.delete_last_visited(del_visited)
local visited = serverlistmgr.get_last_visited()
delete_last_visited(visited, del_visited)
save_last_visited(visited)
end
86 changes: 67 additions & 19 deletions builtin/mainmenu/tab_online.lua
Original file line number Diff line number Diff line change
Expand Up @@ -15,28 +15,45 @@
--with this program; if not, write to the Free Software Foundation, Inc.,
--51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.

local last_visited_collapsed = false
local function get_sorted_servers()
local servers = {
fav = {},
visited = {},
public = {},
incompatible = {}
}

local favs = serverlistmgr.get_favorites()
local taken_favs = {}
local visited_list = serverlistmgr.get_last_visited()
local taken_visited = {}

local result = menudata.search_result or serverlistmgr.servers
for _, server in ipairs(result) do
server.is_favorite = false
server.is_visited = 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

for index, visited in ipairs(visited_list) do
if server.address == visited.address and server.port == visited.port then
taken_visited[index] = true
server.is_visited = 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_visited and not last_visited_collapsed then
table.insert(servers.visited, server)
elseif server.is_compatible then
table.insert(servers.public, server)
else
Expand All @@ -50,6 +67,20 @@ local function get_sorted_servers()
table.insert(servers.fav, fav)
end
end
for index, visited in ipairs(visited_list) do
if not taken_visited[index] then
table.insert(servers.visited, visited)
if #servers.visited >= 5 then
break -- Limit to 5 visited servers
end
else
if visited.is_compatible ~= false then -- Only add if not explicitly incompatible
table.insert(servers.public, visited)
else
table.insert(servers.incompatible, visited)
end
end
end
end

return servers
Expand Down Expand Up @@ -211,8 +242,9 @@ local function get_formspec(tabview, name, tabdata)
"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") .. ";" ..
"6=" .. core.formspec_escape(defaulttexturedir .. "server_visited.png") .. "," ..
"7=" .. core.formspec_escape(defaulttexturedir .. "server_public.png") .. "," ..
"8=" .. core.formspec_escape(defaulttexturedir .. "server_incompatible.png") .. ";" ..
"color,span=1;" ..
"text,align=inline;"..
"color,span=1;" ..
Expand All @@ -235,23 +267,36 @@ local function get_formspec(tabview, name, tabdata)

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,,"
visited = "6,#ff9900," .. fgettext("Last Visited") .. (last_visited_collapsed and " ►" or " ▼") .. ",,,0,0,,",
public = "7,#4bdd42," .. fgettext("Public Servers") .. ",,,0,0,,",
incompatible = "8,"..mt_color_grey.."," .. fgettext("Incompatible Servers") .. ",,,0,0,,"
}
local order = {"fav", "public", "incompatible"}
local order = {"fav", "visited", "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
end
local section_servers = servers[section]
if section == "visited" then
-- Always show the visited divider, even when collapsed
tabdata.lookup[#rows + 1] = "last_visited_divider"
rows[#rows + 1] = dividers[section]

-- Only add the servers if not collapsed and there are servers to show
if not last_visited_collapsed and next(section_servers) ~= nil then
for _, server in ipairs(section_servers) do
tabdata.lookup[#rows + 1] = server
rows[#rows + 1] = render_serverlist_row(server)
end
end
elseif 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
end

retval = retval .. table.concat(rows, ",")

Expand Down Expand Up @@ -414,6 +459,11 @@ local function main_button_handler(tabview, fields, name, tabdata)
return true
end

if tabdata.lookup[event.row] == "last_visited_divider" then
last_visited_collapsed = not last_visited_collapsed
return true
end

gamedata.address = server.address
gamedata.port = server.port
gamedata.playername = fields.te_name
Expand Down Expand Up @@ -446,12 +496,10 @@ local function main_button_handler(tabview, fields, name, tabdata)

if fields.btn_delete_favorite then
local idx = core.get_table_index("servers")
if not idx then return end
local server = tabdata.lookup[idx]
if not server then return end
local server = find_selected_server()

serverlistmgr.delete_favorite(server)
set_selected_server(server)
set_selected_server(tabdata.lookup[idx+1])
return true
end

Expand Down Expand Up @@ -509,7 +557,7 @@ local function main_button_handler(tabview, fields, name, tabdata)
if server and server.address == gamedata.address and
server.port == gamedata.port then

serverlistmgr.add_favorite(server)
serverlistmgr.add_last_visited(server)

gamedata.servername = server.name
gamedata.serverdescription = server.description
Expand Down
Binary file added textures/base/pack/server_visited.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading