Skip to content

Commit 67aa75d

Browse files
rubenwardysfan5
andauthoredJan 22, 2021
Use JSON for favorites, move server list code to Lua (#10085)
Co-authored-by: sfan5 <sfan5@live.de>
1 parent 4fcd000 commit 67aa75d

17 files changed

+388
-528
lines changed
 

Diff for: ‎builtin/mainmenu/common.lua

-53
Original file line numberDiff line numberDiff line change
@@ -62,24 +62,6 @@ function image_column(tooltip, flagname)
6262
"5=" .. core.formspec_escape(defaulttexturedir .. "server_ping_1.png")
6363
end
6464

65-
--------------------------------------------------------------------------------
66-
function order_favorite_list(list)
67-
local res = {}
68-
--orders the favorite list after support
69-
for i = 1, #list do
70-
local fav = list[i]
71-
if is_server_protocol_compat(fav.proto_min, fav.proto_max) then
72-
res[#res + 1] = fav
73-
end
74-
end
75-
for i = 1, #list do
76-
local fav = list[i]
77-
if not is_server_protocol_compat(fav.proto_min, fav.proto_max) then
78-
res[#res + 1] = fav
79-
end
80-
end
81-
return res
82-
end
8365

8466
--------------------------------------------------------------------------------
8567
function render_serverlist_row(spec, is_favorite)
@@ -226,41 +208,6 @@ function menu_handle_key_up_down(fields, textlist, settingname)
226208
return false
227209
end
228210

229-
--------------------------------------------------------------------------------
230-
function asyncOnlineFavourites()
231-
if not menudata.public_known then
232-
menudata.public_known = {{
233-
name = fgettext("Loading..."),
234-
description = fgettext_ne("Try reenabling public serverlist and check your internet connection.")
235-
}}
236-
end
237-
menudata.favorites = menudata.public_known
238-
menudata.favorites_is_public = true
239-
240-
if not menudata.public_downloading then
241-
menudata.public_downloading = true
242-
else
243-
return
244-
end
245-
246-
core.handle_async(
247-
function(param)
248-
return core.get_favorites("online")
249-
end,
250-
nil,
251-
function(result)
252-
menudata.public_downloading = nil
253-
local favs = order_favorite_list(result)
254-
if favs[1] then
255-
menudata.public_known = favs
256-
menudata.favorites = menudata.public_known
257-
menudata.favorites_is_public = true
258-
end
259-
core.event_handler("Refresh")
260-
end
261-
)
262-
end
263-
264211
--------------------------------------------------------------------------------
265212
function text2textlist(xpos, ypos, width, height, tl_name, textlen, text, transparency)
266213
local textlines = core.wrap_text(text, textlen, true)

Diff for: ‎builtin/mainmenu/init.lua

+1
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ dofile(basepath .. "fstk" .. DIR_DELIM .. "ui.lua")
3434
dofile(menupath .. DIR_DELIM .. "async_event.lua")
3535
dofile(menupath .. DIR_DELIM .. "common.lua")
3636
dofile(menupath .. DIR_DELIM .. "pkgmgr.lua")
37+
dofile(menupath .. DIR_DELIM .. "serverlistmgr.lua")
3738
dofile(menupath .. DIR_DELIM .. "textures.lua")
3839

3940
dofile(menupath .. DIR_DELIM .. "dlg_config_world.lua")

Diff for: ‎builtin/mainmenu/serverlistmgr.lua

+241
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,241 @@
1+
--Minetest
2+
--Copyright (C) 2020 rubenwardy
3+
--
4+
--This program is free software; you can redistribute it and/or modify
5+
--it under the terms of the GNU Lesser General Public License as published by
6+
--the Free Software Foundation; either version 2.1 of the License, or
7+
--(at your option) any later version.
8+
--
9+
--This program is distributed in the hope that it will be useful,
10+
--but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
--MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12+
--GNU Lesser General Public License for more details.
13+
--
14+
--You should have received a copy of the GNU Lesser General Public License along
15+
--with this program; if not, write to the Free Software Foundation, Inc.,
16+
--51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17+
18+
serverlistmgr = {}
19+
20+
--------------------------------------------------------------------------------
21+
local function order_server_list(list)
22+
local res = {}
23+
--orders the favorite list after support
24+
for i = 1, #list do
25+
local fav = list[i]
26+
if is_server_protocol_compat(fav.proto_min, fav.proto_max) then
27+
res[#res + 1] = fav
28+
end
29+
end
30+
for i = 1, #list do
31+
local fav = list[i]
32+
if not is_server_protocol_compat(fav.proto_min, fav.proto_max) then
33+
res[#res + 1] = fav
34+
end
35+
end
36+
return res
37+
end
38+
39+
local public_downloading = false
40+
41+
--------------------------------------------------------------------------------
42+
function serverlistmgr.sync()
43+
if not serverlistmgr.servers then
44+
serverlistmgr.servers = {{
45+
name = fgettext("Loading..."),
46+
description = fgettext_ne("Try reenabling public serverlist and check your internet connection.")
47+
}}
48+
end
49+
50+
if public_downloading then
51+
return
52+
end
53+
public_downloading = true
54+
55+
core.handle_async(
56+
function(param)
57+
local http = core.get_http_api()
58+
local url = ("%s/list?proto_version_min=%d&proto_version_max=%d"):format(
59+
core.settings:get("serverlist_url"),
60+
core.get_min_supp_proto(),
61+
core.get_max_supp_proto())
62+
63+
local response = http.fetch_sync({ url = url })
64+
if not response.succeeded then
65+
return {}
66+
end
67+
68+
local retval = core.parse_json(response.data)
69+
return retval and retval.list or {}
70+
end,
71+
nil,
72+
function(result)
73+
public_downloading = nil
74+
local favs = order_server_list(result)
75+
if favs[1] then
76+
serverlistmgr.servers = favs
77+
end
78+
core.event_handler("Refresh")
79+
end
80+
)
81+
end
82+
83+
--------------------------------------------------------------------------------
84+
local function get_favorites_path()
85+
local base = core.get_user_path() .. DIR_DELIM .. "client" .. DIR_DELIM .. "serverlist" .. DIR_DELIM
86+
return base .. core.settings:get("serverlist_file")
87+
end
88+
89+
--------------------------------------------------------------------------------
90+
local function save_favorites(favorites)
91+
local filename = core.settings:get("serverlist_file")
92+
-- If setting specifies legacy format change the filename to the new one
93+
if filename:sub(#filename - 3):lower() == ".txt" then
94+
core.settings:set("serverlist_file", filename:sub(1, #filename - 4) .. ".json")
95+
end
96+
97+
local path = get_favorites_path()
98+
core.create_dir(path)
99+
core.safe_file_write(path, core.write_json(favorites))
100+
end
101+
102+
--------------------------------------------------------------------------------
103+
function serverlistmgr.read_legacy_favorites(path)
104+
local file = io.open(path, "r")
105+
if not file then
106+
return nil
107+
end
108+
109+
local lines = {}
110+
for line in file:lines() do
111+
lines[#lines + 1] = line
112+
end
113+
file:close()
114+
115+
local favorites = {}
116+
117+
local i = 1
118+
while i < #lines do
119+
local function pop()
120+
local line = lines[i]
121+
i = i + 1
122+
return line and line:trim()
123+
end
124+
125+
if pop():lower() == "[server]" then
126+
local name = pop()
127+
local address = pop()
128+
local port = tonumber(pop())
129+
local description = pop()
130+
131+
if name == "" then
132+
name = nil
133+
end
134+
135+
if description == "" then
136+
description = nil
137+
end
138+
139+
if not address or #address < 3 then
140+
core.log("warning", "Malformed favorites file, missing address at line " .. i)
141+
elseif not port or port < 1 or port > 65535 then
142+
core.log("warning", "Malformed favorites file, missing port at line " .. i)
143+
elseif (name and name:upper() == "[SERVER]") or
144+
(address and address:upper() == "[SERVER]") or
145+
(description and description:upper() == "[SERVER]") then
146+
core.log("warning", "Potentially malformed favorites file, overran at line " .. i)
147+
else
148+
favorites[#favorites + 1] = {
149+
name = name,
150+
address = address,
151+
port = port,
152+
description = description
153+
}
154+
end
155+
end
156+
end
157+
158+
return favorites
159+
end
160+
161+
--------------------------------------------------------------------------------
162+
local function read_favorites()
163+
local path = get_favorites_path()
164+
165+
-- If new format configured fall back to reading the legacy file
166+
if path:sub(#path - 4):lower() == ".json" then
167+
local file = io.open(path, "r")
168+
if file then
169+
local json = file:read("*all")
170+
file:close()
171+
return core.parse_json(json)
172+
end
173+
174+
path = path:sub(1, #path - 5) .. ".txt"
175+
end
176+
177+
local favs = serverlistmgr.read_legacy_favorites(path)
178+
if favs then
179+
save_favorites(favs)
180+
os.remove(path)
181+
end
182+
return favs
183+
end
184+
185+
--------------------------------------------------------------------------------
186+
local function delete_favorite(favorites, del_favorite)
187+
for i=1, #favorites do
188+
local fav = favorites[i]
189+
190+
if fav.address == del_favorite.address and fav.port == del_favorite.port then
191+
table.remove(favorites, i)
192+
return
193+
end
194+
end
195+
end
196+
197+
--------------------------------------------------------------------------------
198+
function serverlistmgr.get_favorites()
199+
if serverlistmgr.favorites then
200+
return serverlistmgr.favorites
201+
end
202+
203+
serverlistmgr.favorites = {}
204+
205+
-- Add favorites, removing duplicates
206+
local seen = {}
207+
for _, fav in ipairs(read_favorites() or {}) do
208+
local key = ("%s:%d"):format(fav.address:lower(), fav.port)
209+
if not seen[key] then
210+
seen[key] = true
211+
serverlistmgr.favorites[#serverlistmgr.favorites + 1] = fav
212+
end
213+
end
214+
215+
return serverlistmgr.favorites
216+
end
217+
218+
--------------------------------------------------------------------------------
219+
function serverlistmgr.add_favorite(new_favorite)
220+
assert(type(new_favorite.port) == "number")
221+
222+
-- Whitelist favorite keys
223+
new_favorite = {
224+
name = new_favorite.name,
225+
address = new_favorite.address,
226+
port = new_favorite.port,
227+
description = new_favorite.description,
228+
}
229+
230+
local favorites = serverlistmgr.get_favorites()
231+
delete_favorite(favorites, new_favorite)
232+
table.insert(favorites, 1, new_favorite)
233+
save_favorites(favorites)
234+
end
235+
236+
--------------------------------------------------------------------------------
237+
function serverlistmgr.delete_favorite(del_favorite)
238+
local favorites = serverlistmgr.get_favorites()
239+
delete_favorite(favorites, del_favorite)
240+
save_favorites(favorites)
241+
end

0 commit comments

Comments
 (0)
Please sign in to comment.