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 serverstable-0.4
parent
8941ea0cc9
commit
5a0ed780f5
|
@ -564,7 +564,7 @@ if INIT == "mainmenu" then
|
||||||
return nil
|
return nil
|
||||||
end
|
end
|
||||||
|
|
||||||
function fgettext(text, ...)
|
function fgettext_ne(text, ...)
|
||||||
text = core.gettext(text)
|
text = core.gettext(text)
|
||||||
local arg = {n=select('#', ...), ...}
|
local arg = {n=select('#', ...), ...}
|
||||||
if arg.n >= 1 then
|
if arg.n >= 1 then
|
||||||
|
@ -586,7 +586,11 @@ if INIT == "mainmenu" then
|
||||||
end
|
end
|
||||||
text = result
|
text = result
|
||||||
end
|
end
|
||||||
return core.formspec_escape(text)
|
return text
|
||||||
|
end
|
||||||
|
|
||||||
|
function fgettext(text, ...)
|
||||||
|
return core.formspec_escape(fgettext_ne(text, ...))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -16,9 +16,15 @@
|
||||||
--51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
--51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
--------------------------------------------------------------------------------
|
--------------------------------------------------------------------------------
|
||||||
-- Global menu data
|
-- Global menu data
|
||||||
---------------------------------------------------------------------------------
|
--------------------------------------------------------------------------------
|
||||||
menudata = {}
|
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
|
-- Menu helper functions
|
||||||
--------------------------------------------------------------------------------
|
--------------------------------------------------------------------------------
|
||||||
|
@ -42,6 +48,25 @@ function image_column(tooltip, flagname)
|
||||||
"1=" .. core.formspec_escape(defaulttexturedir .. "server_flags_" .. flagname .. ".png")
|
"1=" .. core.formspec_escape(defaulttexturedir .. "server_flags_" .. flagname .. ".png")
|
||||||
end
|
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)
|
function render_favorite(spec,render_details)
|
||||||
local text = ""
|
local text = ""
|
||||||
|
@ -68,6 +93,7 @@ function render_favorite(spec,render_details)
|
||||||
end
|
end
|
||||||
|
|
||||||
local details = ""
|
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
|
if spec.clients ~= nil and spec.clients_max ~= nil then
|
||||||
local clients_color = ''
|
local clients_color = ''
|
||||||
|
@ -87,11 +113,17 @@ function render_favorite(spec,render_details)
|
||||||
clients_color = '#ffba97' -- 90-100%: orange
|
clients_color = '#ffba97' -- 90-100%: orange
|
||||||
end
|
end
|
||||||
|
|
||||||
|
if grey_out then
|
||||||
|
clients_color = '#aaaaaa'
|
||||||
|
end
|
||||||
|
|
||||||
details = details ..
|
details = details ..
|
||||||
clients_color .. ',' ..
|
clients_color .. ',' ..
|
||||||
render_client_count(spec.clients) .. ',' ..
|
render_client_count(spec.clients) .. ',' ..
|
||||||
'/,' ..
|
'/,' ..
|
||||||
render_client_count(spec.clients_max) .. ','
|
render_client_count(spec.clients_max) .. ','
|
||||||
|
elseif grey_out then
|
||||||
|
details = details .. '#aaaaaa,?,/,?,'
|
||||||
else
|
else
|
||||||
details = details .. ',?,/,?,'
|
details = details .. ',?,/,?,'
|
||||||
end
|
end
|
||||||
|
@ -114,7 +146,7 @@ function render_favorite(spec,render_details)
|
||||||
details = details .. "0,"
|
details = details .. "0,"
|
||||||
end
|
end
|
||||||
|
|
||||||
return details .. text
|
return details .. (grey_out and '#aaaaaa,' or ',') .. text
|
||||||
end
|
end
|
||||||
|
|
||||||
--------------------------------------------------------------------------------
|
--------------------------------------------------------------------------------
|
||||||
|
@ -195,7 +227,7 @@ function asyncOnlineFavourites()
|
||||||
nil,
|
nil,
|
||||||
function(result)
|
function(result)
|
||||||
if core.setting_getbool("public_serverlist") then
|
if core.setting_getbool("public_serverlist") then
|
||||||
menudata.favorites = result
|
menudata.favorites = order_favorite_list(result)
|
||||||
core.event_handler("Refresh")
|
core.event_handler("Refresh")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -225,3 +257,21 @@ function text2textlist(xpos,ypos,width,height,tl_name,textlen,text,transparency)
|
||||||
|
|
||||||
return retval
|
return retval
|
||||||
end
|
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
|
||||||
|
|
|
@ -62,6 +62,7 @@ local function get_formspec(tabview, name, tabdata)
|
||||||
image_column(fgettext("Creative mode"), "creative") .. ",padding=1;" ..
|
image_column(fgettext("Creative mode"), "creative") .. ",padding=1;" ..
|
||||||
image_column(fgettext("Damage enabled"), "damage") .. ",padding=0.25;" ..
|
image_column(fgettext("Damage enabled"), "damage") .. ",padding=0.25;" ..
|
||||||
image_column(fgettext("PvP enabled"), "pvp") .. ",padding=0.25;" ..
|
image_column(fgettext("PvP enabled"), "pvp") .. ",padding=0.25;" ..
|
||||||
|
"color,span=1;" ..
|
||||||
"text,padding=1]" -- name
|
"text,padding=1]" -- name
|
||||||
else
|
else
|
||||||
retval = retval .. "tablecolumns[text]"
|
retval = retval .. "tablecolumns[text]"
|
||||||
|
@ -88,7 +89,6 @@ end
|
||||||
|
|
||||||
--------------------------------------------------------------------------------
|
--------------------------------------------------------------------------------
|
||||||
local function main_button_handler(tabview, fields, name, tabdata)
|
local function main_button_handler(tabview, fields, name, tabdata)
|
||||||
|
|
||||||
if fields["te_name"] ~= nil then
|
if fields["te_name"] ~= nil then
|
||||||
gamedata.playername = fields["te_name"]
|
gamedata.playername = fields["te_name"]
|
||||||
core.setting_set("name", 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"])
|
local event = core.explode_table_event(fields["favourites"])
|
||||||
if event.type == "DCL" then
|
if event.type == "DCL" then
|
||||||
if event.row <= #menudata.favorites 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.address = menudata.favorites[event.row].address
|
||||||
gamedata.port = menudata.favorites[event.row].port
|
gamedata.port = menudata.favorites[event.row].port
|
||||||
gamedata.playername = fields["te_name"]
|
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")
|
local current_favourite = core.get_table_index("favourites")
|
||||||
if current_favourite == nil then return end
|
if current_favourite == nil then return end
|
||||||
core.delete_favorite(current_favourite)
|
core.delete_favorite(current_favourite)
|
||||||
menudata.favorites = core.get_favorites()
|
menudata.favorites = order_favorite_list(core.get_favorites())
|
||||||
tabdata.fav_selected = nil
|
tabdata.fav_selected = nil
|
||||||
|
|
||||||
core.setting_set("address","")
|
core.setting_set("address","")
|
||||||
|
@ -215,6 +219,11 @@ local function main_button_handler(tabview, fields, name, tabdata)
|
||||||
|
|
||||||
gamedata.servername = menudata.favorites[fav_idx].name
|
gamedata.servername = menudata.favorites[fav_idx].name
|
||||||
gamedata.serverdescription = menudata.favorites[fav_idx].description
|
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
|
else
|
||||||
gamedata.servername = ""
|
gamedata.servername = ""
|
||||||
gamedata.serverdescription = ""
|
gamedata.serverdescription = ""
|
||||||
|
|
|
@ -45,6 +45,7 @@ local function get_formspec(tabview, name, tabdata)
|
||||||
image_column(fgettext("Creative mode"), "creative") .. ",padding=1;" ..
|
image_column(fgettext("Creative mode"), "creative") .. ",padding=1;" ..
|
||||||
image_column(fgettext("Damage enabled"), "damage") .. ",padding=0.25;" ..
|
image_column(fgettext("Damage enabled"), "damage") .. ",padding=0.25;" ..
|
||||||
image_column(fgettext("PvP enabled"), "pvp") .. ",padding=0.25;" ..
|
image_column(fgettext("PvP enabled"), "pvp") .. ",padding=0.25;" ..
|
||||||
|
"color,span=1;" ..
|
||||||
"text,padding=1]" -- name
|
"text,padding=1]" -- name
|
||||||
else
|
else
|
||||||
retval = retval .. "tablecolumns[text]"
|
retval = retval .. "tablecolumns[text]"
|
||||||
|
@ -87,7 +88,6 @@ local function get_formspec(tabview, name, tabdata)
|
||||||
end
|
end
|
||||||
|
|
||||||
--------------------------------------------------------------------------------
|
--------------------------------------------------------------------------------
|
||||||
|
|
||||||
local function main_button_handler(tabview, fields, name, tabdata)
|
local function main_button_handler(tabview, fields, name, tabdata)
|
||||||
|
|
||||||
if fields["btn_start_singleplayer"] then
|
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.servername = menudata.favorites[fav_idx].name
|
||||||
gamedata.serverdescription = menudata.favorites[fav_idx].description
|
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
|
else
|
||||||
gamedata.servername = ""
|
gamedata.servername = ""
|
||||||
gamedata.serverdescription = ""
|
gamedata.serverdescription = ""
|
||||||
|
|
|
@ -197,9 +197,11 @@ core.delete_world(index)
|
||||||
Helpers:
|
Helpers:
|
||||||
core.gettext(string) -> string
|
core.gettext(string) -> string
|
||||||
^ look up the translation of a string in the gettext message catalog
|
^ 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
|
^ 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)
|
core.parse_json(string[, nullvalue]) -> something (possible in async calls)
|
||||||
^ see core.parse_json (lua_api.txt)
|
^ see core.parse_json (lua_api.txt)
|
||||||
dump(obj, dumped={})
|
dump(obj, dumped={})
|
||||||
|
@ -211,6 +213,12 @@ string:trim()
|
||||||
core.is_yes(arg) (possible in async calls)
|
core.is_yes(arg) (possible in async calls)
|
||||||
^ returns whether arg can be interpreted as yes
|
^ 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:
|
Async:
|
||||||
core.handle_async(async_job,parameters,finished)
|
core.handle_async(async_job,parameters,finished)
|
||||||
^ execute a function asynchronously
|
^ execute a function asynchronously
|
||||||
|
|
|
@ -472,6 +472,7 @@ int ModApiMainMenu::l_get_favorites(lua_State *L)
|
||||||
|
|
||||||
for (unsigned int i = 0; i < servers.size(); i++)
|
for (unsigned int i = 0; i < servers.size(); i++)
|
||||||
{
|
{
|
||||||
|
|
||||||
lua_pushnumber(L,index);
|
lua_pushnumber(L,index);
|
||||||
|
|
||||||
lua_newtable(L);
|
lua_newtable(L);
|
||||||
|
@ -509,6 +510,18 @@ int ModApiMainMenu::l_get_favorites(lua_State *L)
|
||||||
lua_settable(L, top_lvl2);
|
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()) {
|
if (servers[i]["password"].asString().size()) {
|
||||||
lua_pushstring(L,"password");
|
lua_pushstring(L,"password");
|
||||||
lua_pushboolean(L,servers[i]["password"].asBool());
|
lua_pushboolean(L,servers[i]["password"].asBool());
|
||||||
|
@ -1082,6 +1095,19 @@ int ModApiMainMenu::l_get_screen_info(lua_State *L)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
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)
|
int ModApiMainMenu::l_do_async_callback(lua_State *L)
|
||||||
{
|
{
|
||||||
|
@ -1142,6 +1168,8 @@ void ModApiMainMenu::Initialize(lua_State *L, int top)
|
||||||
API_FCT(gettext);
|
API_FCT(gettext);
|
||||||
API_FCT(get_video_drivers);
|
API_FCT(get_video_drivers);
|
||||||
API_FCT(get_screen_info);
|
API_FCT(get_screen_info);
|
||||||
|
API_FCT(get_min_supp_proto);
|
||||||
|
API_FCT(get_max_supp_proto);
|
||||||
API_FCT(do_async_callback);
|
API_FCT(do_async_callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -137,6 +137,12 @@ private:
|
||||||
|
|
||||||
static int l_get_video_drivers(lua_State *L);
|
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
|
// async
|
||||||
static int l_do_async_callback(lua_State *L);
|
static int l_do_async_callback(lua_State *L);
|
||||||
|
|
||||||
|
|
|
@ -28,6 +28,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
#include "filesys.h"
|
#include "filesys.h"
|
||||||
#include "porting.h"
|
#include "porting.h"
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
|
#include "network/networkprotocol.h"
|
||||||
#include "json/json.h"
|
#include "json/json.h"
|
||||||
#include "convert_json.h"
|
#include "convert_json.h"
|
||||||
#include "httpfetch.h"
|
#include "httpfetch.h"
|
||||||
|
@ -67,8 +68,11 @@ std::vector<ServerListSpec> getLocal()
|
||||||
|
|
||||||
std::vector<ServerListSpec> getOnline()
|
std::vector<ServerListSpec> getOnline()
|
||||||
{
|
{
|
||||||
Json::Value root = fetchJsonValue(
|
std::ostringstream geturl;
|
||||||
(g_settings->get("serverlist_url") + "/list").c_str(), NULL);
|
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;
|
std::vector<ServerListSpec> server_list;
|
||||||
|
|
||||||
|
@ -205,9 +209,12 @@ void sendAnnounce(const std::string &action,
|
||||||
server["address"] = g_settings->get("server_address");
|
server["address"] = g_settings->get("server_address");
|
||||||
}
|
}
|
||||||
if (action != "delete") {
|
if (action != "delete") {
|
||||||
|
bool strict_checking = g_settings->getBool("strict_protocol_version_checking");
|
||||||
server["name"] = g_settings->get("server_name");
|
server["name"] = g_settings->get("server_name");
|
||||||
server["description"] = g_settings->get("server_description");
|
server["description"] = g_settings->get("server_description");
|
||||||
server["version"] = minetest_version_simple;
|
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["url"] = g_settings->get("server_url");
|
||||||
server["creative"] = g_settings->getBool("creative_mode");
|
server["creative"] = g_settings->getBool("creative_mode");
|
||||||
server["damage"] = g_settings->getBool("enable_damage");
|
server["damage"] = g_settings->getBool("enable_damage");
|
||||||
|
|
Loading…
Reference in New Issue