2 --Copyright (C) 2020 rubenwardy
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.
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.
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.
20 --------------------------------------------------------------------------------
21 local function order_server_list(list)
23 --orders the favorite list after support
26 if is_server_protocol_compat(fav.proto_min, fav.proto_max) then
32 if not is_server_protocol_compat(fav.proto_min, fav.proto_max) then
39 local public_downloading = false
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.")
50 local serverlist_url = core.settings:get("serverlist_url") or ""
51 if not core.get_http_api or serverlist_url == "" then
52 serverlistmgr.servers = {{
53 name = fgettext("Public server list is disabled"),
59 if public_downloading then
62 public_downloading = true
66 local http = core.get_http_api()
67 local url = ("%s/list?proto_version_min=%d&proto_version_max=%d"):format(
68 core.settings:get("serverlist_url"),
69 core.get_min_supp_proto(),
70 core.get_max_supp_proto())
72 local response = http.fetch_sync({ url = url })
73 if not response.succeeded then
77 local retval = core.parse_json(response.data)
78 return retval and retval.list or {}
82 public_downloading = nil
83 local favs = order_server_list(result)
85 serverlistmgr.servers = favs
87 core.event_handler("Refresh")
92 --------------------------------------------------------------------------------
93 local function get_favorites_path(folder)
94 local base = core.get_user_path() .. DIR_DELIM .. "client" .. DIR_DELIM .. "serverlist" .. DIR_DELIM
98 return base .. core.settings:get("serverlist_file")
101 --------------------------------------------------------------------------------
102 local function save_favorites(favorites)
103 local filename = core.settings:get("serverlist_file")
104 -- If setting specifies legacy format change the filename to the new one
105 if filename:sub(#filename - 3):lower() == ".txt" then
106 core.settings:set("serverlist_file", filename:sub(1, #filename - 4) .. ".json")
109 assert(core.create_dir(get_favorites_path(true)))
110 core.safe_file_write(get_favorites_path(), core.write_json(favorites))
113 --------------------------------------------------------------------------------
114 function serverlistmgr.read_legacy_favorites(path)
115 local file = io.open(path, "r")
121 for line in file:lines() do
122 lines[#lines + 1] = line
131 local line = lines[i]
133 return line and line:trim()
136 if pop():lower() == "[server]" then
138 local address = pop()
139 local port = tonumber(pop())
140 local description = pop()
146 if description == "" then
150 if not address or #address < 3 then
151 core.log("warning", "Malformed favorites file, missing address at line " .. i)
152 elseif not port or port < 1 or port > 65535 then
153 core.log("warning", "Malformed favorites file, missing port at line " .. i)
154 elseif (name and name:upper() == "[SERVER]") or
155 (address and address:upper() == "[SERVER]") or
156 (description and description:upper() == "[SERVER]") then
157 core.log("warning", "Potentially malformed favorites file, overran at line " .. i)
159 favorites[#favorites + 1] = {
163 description = description
172 --------------------------------------------------------------------------------
173 local function read_favorites()
174 local path = get_favorites_path()
176 -- If new format configured fall back to reading the legacy file
177 if path:sub(#path - 4):lower() == ".json" then
178 local file = io.open(path, "r")
180 local json = file:read("*all")
182 return core.parse_json(json)
185 path = path:sub(1, #path - 5) .. ".txt"
188 local favs = serverlistmgr.read_legacy_favorites(path)
196 --------------------------------------------------------------------------------
197 local function delete_favorite(favorites, del_favorite)
198 for i=1, #favorites do
199 local fav = favorites[i]
201 if fav.address == del_favorite.address and fav.port == del_favorite.port then
202 table.remove(favorites, i)
208 --------------------------------------------------------------------------------
209 function serverlistmgr.get_favorites()
210 if serverlistmgr.favorites then
211 return serverlistmgr.favorites
214 serverlistmgr.favorites = {}
216 -- Add favorites, removing duplicates
218 for _, fav in ipairs(read_favorites() or {}) do
219 local key = ("%s:%d"):format(fav.address:lower(), fav.port)
220 if not seen[key] then
222 serverlistmgr.favorites[#serverlistmgr.favorites + 1] = fav
226 return serverlistmgr.favorites
229 --------------------------------------------------------------------------------
230 function serverlistmgr.add_favorite(new_favorite)
231 assert(type(new_favorite.port) == "number")
233 -- Whitelist favorite keys
235 name = new_favorite.name,
236 address = new_favorite.address,
237 port = new_favorite.port,
238 description = new_favorite.description,
241 local favorites = serverlistmgr.get_favorites()
242 delete_favorite(favorites, new_favorite)
243 table.insert(favorites, 1, new_favorite)
244 save_favorites(favorites)
247 --------------------------------------------------------------------------------
248 function serverlistmgr.delete_favorite(del_favorite)
249 local favorites = serverlistmgr.get_favorites()
250 delete_favorite(favorites, del_favorite)
251 save_favorites(favorites)