diff --git a/builtin/settingtypes.txt b/builtin/settingtypes.txt index ec00b3b89..205d427fb 100644 --- a/builtin/settingtypes.txt +++ b/builtin/settingtypes.txt @@ -810,6 +810,14 @@ bind_address (Bind address) string # to new servers, but they may not support all new features that you are expecting. strict_protocol_version_checking (Strict protocol checking) bool false +# Define the oldest clients allowed to connect. +# Older clients are compatible in the sense that they will not crash when connecting +# to new servers, but they may not support all new features that you are expecting. +# This allows for more fine-grained control than strict_protocol_version_checking. +# Minetest still enforces its own internal minimum, and enabling +# strict_protocol_version_checking will effectively override this. +protocol_version_min (Protocol version minimum) int 1 1 65535 + # Specifies URL from which client fetches media instead of using UDP. # $filename should be accessible from $remote_media$filename via cURL # (obviously, remote_media should end with a slash). diff --git a/minetest.conf.example b/minetest.conf.example index 42ffecde3..d88abe92a 100644 --- a/minetest.conf.example +++ b/minetest.conf.example @@ -760,6 +760,15 @@ # type: bool # strict_protocol_version_checking = false +# Define the oldest clients allowed to connect. +# Older clients are compatible in the sense that they will not crash when connecting +# to new servers, but they may not support all new features that you are expecting. +# This allows more fine-grained control than strict_protocol_version_checking. +# Minetest may still enforce its own internal minimum, and enabling +# strict_protocol_version_checking will effectively override this. +# type: int min: 1 max: 65535 +# protocol_version_min = 1 + # Specifies URL from which client fetches media instead of using UDP. # $filename should be accessible from $remote_media$filename via cURL # (obviously, remote_media should end with a slash). diff --git a/src/defaultsettings.cpp b/src/defaultsettings.cpp index d61a91d40..90d7df05f 100644 --- a/src/defaultsettings.cpp +++ b/src/defaultsettings.cpp @@ -365,6 +365,7 @@ void set_default_settings() settings->setDefault("max_packets_per_iteration", "1024"); settings->setDefault("port", "30000"); settings->setDefault("strict_protocol_version_checking", "false"); + settings->setDefault("protocol_version_min", "1"); settings->setDefault("player_transfer_distance", "0"); settings->setDefault("max_simultaneous_block_sends_per_client", "40"); settings->setDefault("time_send_interval", "5"); diff --git a/src/network/serverpackethandler.cpp b/src/network/serverpackethandler.cpp index bce2b2261..92ff4d031 100644 --- a/src/network/serverpackethandler.cpp +++ b/src/network/serverpackethandler.cpp @@ -147,10 +147,8 @@ void Server::handleCommand_Init(NetworkPacket* pkt) client->net_proto_version = net_proto_version; - if ((g_settings->getBool("strict_protocol_version_checking") && - net_proto_version != LATEST_PROTOCOL_VERSION) || - net_proto_version < SERVER_PROTOCOL_VERSION_MIN || - net_proto_version > SERVER_PROTOCOL_VERSION_MAX) { + if (net_proto_version < Server::getProtocolVersionMin() || + net_proto_version > Server::getProtocolVersionMax()) { actionstream << "Server: A mismatched client tried to connect from " << addr_s << " proto_max=" << (int)max_net_proto_version << std::endl; DenyAccess(peer_id, SERVER_ACCESSDENIED_WRONG_VERSION); diff --git a/src/server.cpp b/src/server.cpp index 67c3a8592..19b506ddd 100644 --- a/src/server.cpp +++ b/src/server.cpp @@ -4191,3 +4191,20 @@ bool Server::migrateModStorageDatabase(const GameParams &game_params, const Sett return succeeded; } + +u16 Server::getProtocolVersionMin() +{ + u16 min_proto = g_settings->getU16("protocol_version_min"); + if (g_settings->getBool("strict_protocol_version_checking")) + min_proto = LATEST_PROTOCOL_VERSION; + return rangelim(min_proto, + SERVER_PROTOCOL_VERSION_MIN, + SERVER_PROTOCOL_VERSION_MAX); +} + +u16 Server::getProtocolVersionMax() +{ + return g_settings->getBool("strict_protocol_version_checking") + ? LATEST_PROTOCOL_VERSION + : SERVER_PROTOCOL_VERSION_MAX; +} diff --git a/src/server.h b/src/server.h index 4ef374352..a4f975432 100644 --- a/src/server.h +++ b/src/server.h @@ -383,6 +383,9 @@ public: static bool migrateModStorageDatabase(const GameParams &game_params, const Settings &cmd_args); + static u16 getProtocolVersionMin(); + static u16 getProtocolVersionMax(); + // Lua files registered for init of async env, pair of modname + path std::vector> m_async_init_files; diff --git a/src/serverlist.cpp b/src/serverlist.cpp index 29e3ac9a6..e702ba73d 100644 --- a/src/serverlist.cpp +++ b/src/serverlist.cpp @@ -27,6 +27,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include #include "convert_json.h" #include "httpfetch.h" +#include "server.h" namespace ServerList { @@ -50,12 +51,11 @@ void sendAnnounce(AnnounceAction action, server["address"] = g_settings->get("server_address"); } if (action != AA_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"] = g_version_string; - 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["proto_min"] = Server::getProtocolVersionMin(); + server["proto_max"] = Server::getProtocolVersionMax(); server["url"] = g_settings->get("server_url"); server["creative"] = g_settings->getBool("creative_mode"); server["damage"] = g_settings->getBool("enable_damage");