aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorest31 <MTest31@outlook.com>2015-02-17 01:37:14 +0100
committerLoic Blot <loic.blot@unix-experience.fr>2015-02-18 16:17:03 +0100
commit82bfa2ee7b90f678b687fb42405ca775c517be13 (patch)
tree5f55ebb512aad9b995dda71f98195dd4473c3dfc
parent9ef2e5000f6df5a0c16e0343c6af59967150db42 (diff)
downloadminetest-82bfa2ee7b90f678b687fb42405ca775c517be13.tar.gz
minetest-82bfa2ee7b90f678b687fb42405ca775c517be13.tar.bz2
minetest-82bfa2ee7b90f678b687fb42405ca775c517be13.zip
Server: announce MIN/MAX protocol version supported to serverlist. Client: check serverlist
Client now informs about incompatible servers from the list, this permits to prevent the protocol movements. Server announces its supported protocol versions to master server
-rw-r--r--builtin/common/misc_helpers.lua8
-rw-r--r--builtin/mainmenu/common.lua56
-rw-r--r--builtin/mainmenu/tab_multiplayer.lua13
-rw-r--r--builtin/mainmenu/tab_simple_main.lua7
-rw-r--r--doc/menu_lua_api.txt12
-rw-r--r--src/script/lua_api/l_mainmenu.cpp28
-rw-r--r--src/script/lua_api/l_mainmenu.h6
-rw-r--r--src/serverlist.cpp11
8 files changed, 129 insertions, 12 deletions
diff --git a/builtin/common/misc_helpers.lua b/builtin/common/misc_helpers.lua
index d9ebc39c3..39fca7d1e 100644
--- a/builtin/common/misc_helpers.lua
+++ b/builtin/common/misc_helpers.lua
@@ -564,7 +564,7 @@ if INIT == "mainmenu" then
return nil
end
- function fgettext(text, ...)
+ function fgettext_ne(text, ...)
text = core.gettext(text)
local arg = {n=select('#', ...), ...}
if arg.n >= 1 then
@@ -586,7 +586,11 @@ if INIT == "mainmenu" then
end
text = result
end
- return core.formspec_escape(text)
+ return text
+ end
+
+ function fgettext(text, ...)
+ return core.formspec_escape(fgettext_ne(text, ...))
end
end
diff --git a/builtin/mainmenu/common.lua b/builtin/mainmenu/common.lua
index 549c0967b..f32d77f2a 100644
--- a/builtin/mainmenu/common.lua
+++ b/builtin/mainmenu/common.lua
@@ -16,10 +16,16 @@
--51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
--------------------------------------------------------------------------------
-- Global menu data
----------------------------------------------------------------------------------
+--------------------------------------------------------------------------------
menudata = {}
--------------------------------------------------------------------------------
+-- Local cached values
+--------------------------------------------------------------------------------
+local min_supp_proto = core.get_min_supp_proto()
+local max_supp_proto = core.get_max_supp_proto()
+
+--------------------------------------------------------------------------------
-- Menu helper functions
--------------------------------------------------------------------------------
@@ -43,6 +49,25 @@ function image_column(tooltip, flagname)
end
--------------------------------------------------------------------------------
+function order_favorite_list(list)
+ local res = {}
+ --orders the favorite list after support
+ for i=1,#list,1 do
+ local fav = list[i]
+ if is_server_protocol_compat(fav.proto_min, fav.proto_max) then
+ table.insert(res, fav)
+ end
+ end
+ for i=1,#list,1 do
+ local fav = list[i]
+ if not is_server_protocol_compat(fav.proto_min, fav.proto_max) then
+ table.insert(res, fav)
+ end
+ end
+ return res
+end
+
+--------------------------------------------------------------------------------
function render_favorite(spec,render_details)
local text = ""
@@ -68,6 +93,7 @@ function render_favorite(spec,render_details)
end
local details = ""
+ local grey_out = not is_server_protocol_compat(spec.proto_max, spec.proto_min)
if spec.clients ~= nil and spec.clients_max ~= nil then
local clients_color = ''
@@ -87,11 +113,17 @@ function render_favorite(spec,render_details)
clients_color = '#ffba97' -- 90-100%: orange
end
+ if grey_out then
+ clients_color = '#aaaaaa'
+ end
+
details = details ..
clients_color .. ',' ..
render_client_count(spec.clients) .. ',' ..
'/,' ..
render_client_count(spec.clients_max) .. ','
+ elseif grey_out then
+ details = details .. '#aaaaaa,?,/,?,'
else
details = details .. ',?,/,?,'
end
@@ -114,7 +146,7 @@ function render_favorite(spec,render_details)
details = details .. "0,"
end
- return details .. text
+ return details .. (grey_out and '#aaaaaa,' or ',') .. text
end
--------------------------------------------------------------------------------
@@ -195,7 +227,7 @@ function asyncOnlineFavourites()
nil,
function(result)
if core.setting_getbool("public_serverlist") then
- menudata.favorites = result
+ menudata.favorites = order_favorite_list(result)
core.event_handler("Refresh")
end
end
@@ -225,3 +257,21 @@ function text2textlist(xpos,ypos,width,height,tl_name,textlen,text,transparency)
return retval
end
+
+--------------------------------------------------------------------------------
+function is_server_protocol_compat(proto_min, proto_max)
+ return not ((min_supp_proto > (proto_max or 24)) or (max_supp_proto < (proto_min or 13)))
+end
+--------------------------------------------------------------------------------
+function is_server_protocol_compat_or_error(proto_min, proto_max)
+ if not is_server_protocol_compat(proto_min, proto_max) then
+ gamedata.errormessage = fgettext_ne("Protocol version mismatch, server " ..
+ ((proto_min ~= proto_max) and "supports protocols between $1 and $2" or "enforces protocol version $1") ..
+ ", we " ..
+ ((min_supp_proto ~= max_supp_proto) and "support protocols between version $3 and $4." or "only support protocol version $3"),
+ proto_min or 13, proto_max or 24, min_supp_proto, max_supp_proto)
+ return false
+ end
+
+ return true
+end
diff --git a/builtin/mainmenu/tab_multiplayer.lua b/builtin/mainmenu/tab_multiplayer.lua
index 734cb5d3e..f9ac78f17 100644
--- a/builtin/mainmenu/tab_multiplayer.lua
+++ b/builtin/mainmenu/tab_multiplayer.lua
@@ -62,6 +62,7 @@ local function get_formspec(tabview, name, tabdata)
image_column(fgettext("Creative mode"), "creative") .. ",padding=1;" ..
image_column(fgettext("Damage enabled"), "damage") .. ",padding=0.25;" ..
image_column(fgettext("PvP enabled"), "pvp") .. ",padding=0.25;" ..
+ "color,span=1;" ..
"text,padding=1]" -- name
else
retval = retval .. "tablecolumns[text]"
@@ -88,7 +89,6 @@ end
--------------------------------------------------------------------------------
local function main_button_handler(tabview, fields, name, tabdata)
-
if fields["te_name"] ~= nil then
gamedata.playername = fields["te_name"]
core.setting_set("name", fields["te_name"])
@@ -98,6 +98,10 @@ local function main_button_handler(tabview, fields, name, tabdata)
local event = core.explode_table_event(fields["favourites"])
if event.type == "DCL" then
if event.row <= #menudata.favorites then
+ if not is_server_protocol_compat_or_error(menudata.favorites[event.row].proto_min,
+ menudata.favorites[event.row].proto_max) then
+ return true
+ end
gamedata.address = menudata.favorites[event.row].address
gamedata.port = menudata.favorites[event.row].port
gamedata.playername = fields["te_name"]
@@ -189,7 +193,7 @@ local function main_button_handler(tabview, fields, name, tabdata)
local current_favourite = core.get_table_index("favourites")
if current_favourite == nil then return end
core.delete_favorite(current_favourite)
- menudata.favorites = core.get_favorites()
+ menudata.favorites = order_favorite_list(core.get_favorites())
tabdata.fav_selected = nil
core.setting_set("address","")
@@ -214,6 +218,11 @@ local function main_button_handler(tabview, fields, name, tabdata)
gamedata.servername = menudata.favorites[fav_idx].name
gamedata.serverdescription = menudata.favorites[fav_idx].description
+
+ if not is_server_protocol_compat_or_error(menudata.favorites[fav_idx].proto_min,
+ menudata.favorites[fav_idx].proto_max)then
+ return true
+ end
else
gamedata.servername = ""
gamedata.serverdescription = ""
diff --git a/builtin/mainmenu/tab_simple_main.lua b/builtin/mainmenu/tab_simple_main.lua
index 87bd551c0..b9a6b650f 100644
--- a/builtin/mainmenu/tab_simple_main.lua
+++ b/builtin/mainmenu/tab_simple_main.lua
@@ -45,6 +45,7 @@ local function get_formspec(tabview, name, tabdata)
image_column(fgettext("Creative mode"), "creative") .. ",padding=1;" ..
image_column(fgettext("Damage enabled"), "damage") .. ",padding=0.25;" ..
image_column(fgettext("PvP enabled"), "pvp") .. ",padding=0.25;" ..
+ "color,span=1;" ..
"text,padding=1]" -- name
else
retval = retval .. "tablecolumns[text]"
@@ -87,7 +88,6 @@ local function get_formspec(tabview, name, tabdata)
end
--------------------------------------------------------------------------------
-
local function main_button_handler(tabview, fields, name, tabdata)
if fields["btn_start_singleplayer"] then
@@ -159,6 +159,11 @@ local function main_button_handler(tabview, fields, name, tabdata)
gamedata.servername = menudata.favorites[fav_idx].name
gamedata.serverdescription = menudata.favorites[fav_idx].description
+
+ if not is_server_protocol_compat_or_error(menudata.favorites[fav_idx].proto_min,
+ menudata.favorites[fav_idx].proto_max) then
+ return true
+ end
else
gamedata.servername = ""
gamedata.serverdescription = ""
diff --git a/doc/menu_lua_api.txt b/doc/menu_lua_api.txt
index 5c0f90df6..f76124a0d 100644
--- a/doc/menu_lua_api.txt
+++ b/doc/menu_lua_api.txt
@@ -197,9 +197,11 @@ core.delete_world(index)
Helpers:
core.gettext(string) -> string
^ look up the translation of a string in the gettext message catalog
-fgettext(string, ...) -> string
+fgettext_ne(string, ...)
^ call core.gettext(string), replace "$1"..."$9" with the given
-^ extra arguments, call core.formspec_escape and return the result
+^ extra arguments and return the result
+fgettext(string, ...) -> string
+^ same as fgettext_ne(), but calls core.formspec_escape before returning result
core.parse_json(string[, nullvalue]) -> something (possible in async calls)
^ see core.parse_json (lua_api.txt)
dump(obj, dumped={})
@@ -211,6 +213,12 @@ string:trim()
core.is_yes(arg) (possible in async calls)
^ returns whether arg can be interpreted as yes
+Version compat:
+core.get_min_supp_proto()
+^ returns the minimum supported network protocol version
+core.get_max_supp_proto()
+^ returns the maximum supported network protocol version
+
Async:
core.handle_async(async_job,parameters,finished)
^ execute a function asynchronously
diff --git a/src/script/lua_api/l_mainmenu.cpp b/src/script/lua_api/l_mainmenu.cpp
index 0d8365106..2bed2a255 100644
--- a/src/script/lua_api/l_mainmenu.cpp
+++ b/src/script/lua_api/l_mainmenu.cpp
@@ -472,6 +472,7 @@ int ModApiMainMenu::l_get_favorites(lua_State *L)
for (unsigned int i = 0; i < servers.size(); i++)
{
+
lua_pushnumber(L,index);
lua_newtable(L);
@@ -509,6 +510,18 @@ int ModApiMainMenu::l_get_favorites(lua_State *L)
lua_settable(L, top_lvl2);
}
+ if (servers[i]["proto_min"].asString().size()) {
+ lua_pushstring(L,"proto_min");
+ lua_pushinteger(L,servers[i]["proto_min"].asInt());
+ lua_settable(L, top_lvl2);
+ }
+
+ if (servers[i]["proto_max"].asString().size()) {
+ lua_pushstring(L,"proto_max");
+ lua_pushinteger(L,servers[i]["proto_max"].asInt());
+ lua_settable(L, top_lvl2);
+ }
+
if (servers[i]["password"].asString().size()) {
lua_pushstring(L,"password");
lua_pushboolean(L,servers[i]["password"].asBool());
@@ -1083,6 +1096,19 @@ int ModApiMainMenu::l_get_screen_info(lua_State *L)
}
/******************************************************************************/
+int ModApiMainMenu::l_get_min_supp_proto(lua_State *L)
+{
+ lua_pushinteger(L, CLIENT_PROTOCOL_VERSION_MIN);
+ return 1;
+}
+
+int ModApiMainMenu::l_get_max_supp_proto(lua_State *L)
+{
+ lua_pushinteger(L, CLIENT_PROTOCOL_VERSION_MAX);
+ return 1;
+}
+
+/******************************************************************************/
int ModApiMainMenu::l_do_async_callback(lua_State *L)
{
GUIEngine* engine = getGuiEngine(L);
@@ -1142,6 +1168,8 @@ void ModApiMainMenu::Initialize(lua_State *L, int top)
API_FCT(gettext);
API_FCT(get_video_drivers);
API_FCT(get_screen_info);
+ API_FCT(get_min_supp_proto);
+ API_FCT(get_max_supp_proto);
API_FCT(do_async_callback);
}
diff --git a/src/script/lua_api/l_mainmenu.h b/src/script/lua_api/l_mainmenu.h
index ff61dd97a..8b21a93aa 100644
--- a/src/script/lua_api/l_mainmenu.h
+++ b/src/script/lua_api/l_mainmenu.h
@@ -137,6 +137,12 @@ private:
static int l_get_video_drivers(lua_State *L);
+ //version compatibility
+ static int l_get_min_supp_proto(lua_State *L);
+
+ static int l_get_max_supp_proto(lua_State *L);
+
+
// async
static int l_do_async_callback(lua_State *L);
diff --git a/src/serverlist.cpp b/src/serverlist.cpp
index 472a6b85c..a3353340e 100644
--- a/src/serverlist.cpp
+++ b/src/serverlist.cpp
@@ -28,6 +28,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "filesys.h"
#include "porting.h"
#include "log.h"
+#include "network/networkprotocol.h"
#include "json/json.h"
#include "convert_json.h"
#include "httpfetch.h"
@@ -67,8 +68,11 @@ std::vector<ServerListSpec> getLocal()
std::vector<ServerListSpec> getOnline()
{
- Json::Value root = fetchJsonValue(
- (g_settings->get("serverlist_url") + "/list").c_str(), NULL);
+ std::ostringstream geturl;
+ geturl << g_settings->get("serverlist_url") <<
+ "/list?proto_version_min=" << CLIENT_PROTOCOL_VERSION_MIN <<
+ "&proto_version_max=" << CLIENT_PROTOCOL_VERSION_MAX;
+ Json::Value root = fetchJsonValue(geturl.str(), NULL);
std::vector<ServerListSpec> server_list;
@@ -205,9 +209,12 @@ void sendAnnounce(const std::string &action,
server["address"] = g_settings->get("server_address");
}
if (action != "delete") {
+ bool strict_checking = g_settings->getBool("strict_protocol_version_checking");
server["name"] = g_settings->get("server_name");
server["description"] = g_settings->get("server_description");
server["version"] = minetest_version_simple;
+ server["proto_min"] = strict_checking ? LATEST_PROTOCOL_VERSION : SERVER_PROTOCOL_VERSION_MIN;
+ server["proto_max"] = strict_checking ? LATEST_PROTOCOL_VERSION : SERVER_PROTOCOL_VERSION_MAX;
server["url"] = g_settings->get("server_url");
server["creative"] = g_settings->getBool("creative_mode");
server["damage"] = g_settings->getBool("enable_damage");