diff --git a/src/main.cpp b/src/main.cpp index 7ed89dc78..1c3f17533 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1045,10 +1045,11 @@ int handleCmdLine() if(CommandLine::has("--network-console")) STKHost::m_enable_console = true; + core::stringw server_password; if (CommandLine::has("--server-password", &s)) { - core::stringw pw = StringUtils::xmlDecode(s); - NetworkConfig::get()->setPassword(StringUtils::wideToUtf8(pw)); + server_password = StringUtils::xmlDecode(s); + NetworkConfig::get()->setPassword(StringUtils::wideToUtf8(server_password)); } if (CommandLine::has("--server-id-file", &s)) @@ -1084,7 +1085,7 @@ int handleCmdLine() NetworkConfig::get()->getMaxPlayers(), 0, race_manager->getDifficulty(), NetworkConfig::get()->getServerGameMode(race_manager->getMinorMode(), - race_manager->getMajorMode()), ip); + race_manager->getMajorMode()), ip, !server_password.empty()); NetworkingLobby::getInstance()->setJoinedServer(server); STKHost::create(server); } diff --git a/src/network/network_config.cpp b/src/network/network_config.cpp index 400b54d59..34c55b218 100644 --- a/src/network/network_config.cpp +++ b/src/network/network_config.cpp @@ -23,6 +23,7 @@ NetworkConfig *NetworkConfig::m_network_config = NULL; bool NetworkConfig::m_disable_lan = false; +const uint8_t NetworkConfig::m_server_version = 1; /** \class NetworkConfig * This class is the interface between STK and the online code, particularly diff --git a/src/network/network_config.hpp b/src/network/network_config.hpp index c97c5f7d8..b71c0be00 100644 --- a/src/network/network_config.hpp +++ b/src/network/network_config.hpp @@ -93,6 +93,9 @@ public: * WAN code to be used when connection client and server). */ static bool m_disable_lan; + /** Server version, will be advanced if there are protocol changes. */ + static const uint8_t m_server_version; + /** Singleton get, which creates this object if necessary. */ static NetworkConfig *get() { diff --git a/src/network/protocols/server_lobby.cpp b/src/network/protocols/server_lobby.cpp index faf30fd5f..dab4f346c 100644 --- a/src/network/protocols/server_lobby.cpp +++ b/src/network/protocols/server_lobby.cpp @@ -425,6 +425,11 @@ void ServerLobby::registerServer() request->addParameter("game_mode", NetworkConfig::get()->getServerGameMode(race_manager->getMinorMode(), race_manager->getMajorMode())); + request->addParameter("password", + (unsigned)(!NetworkConfig::get()->getPassword().empty())); + request->addParameter("version", + (unsigned)NetworkConfig::m_server_version); + Log::info("ServerLobby", "Public server addr %s", addr.toString().c_str()); request->executeNow(); diff --git a/src/network/server.cpp b/src/network/server.cpp index cb205c025..ef698e35e 100644 --- a/src/network/server.cpp +++ b/src/network/server.cpp @@ -56,6 +56,7 @@ Server::Server(const XMLNode& xml) xml.get("port", &port); m_address.setPort(port); xml.get("private_port", &m_private_port); + xml.get("password", &m_password_protected); } // Server(const XML&) // ---------------------------------------------------------------------------- @@ -69,10 +70,11 @@ Server::Server(const XMLNode& xml) * \param difficulty The difficulty of server. * \param server_mode The game modes of server (including minor and major). * \param address IP and port of the server. + * \param password_protected True if can only be joined with a password. */ Server::Server(unsigned server_id, const core::stringw &name, int max_players, int current_players, unsigned difficulty, unsigned server_mode, - const TransportAddress &address) + const TransportAddress &address, bool password_protected) { m_name = name; m_lower_case_name = StringUtils::toLowerCase(StringUtils::wideToUtf8(name)); @@ -87,6 +89,7 @@ Server::Server(unsigned server_id, const core::stringw &name, int max_players, m_difficulty = (RaceManager::Difficulty)difficulty; m_minor_mode = NetworkConfig::get()->getLocalGameMode(server_mode).first; m_major_mode = NetworkConfig::get()->getLocalGameMode(server_mode).second; + m_password_protected = password_protected; } // server(server_id, ...) // ---------------------------------------------------------------------------- diff --git a/src/network/server.hpp b/src/network/server.hpp index 058a31864..0ee2339dd 100644 --- a/src/network/server.hpp +++ b/src/network/server.hpp @@ -74,13 +74,16 @@ protected: RaceManager::Difficulty m_difficulty; + bool m_password_protected; + public: /** Initialises the object from an XML node. */ Server(const XMLNode &xml); Server(unsigned server_id, const irr::core::stringw &name, int max_players, int current_players, unsigned difficulty, - unsigned server_mode, const TransportAddress &address); + unsigned server_mode, const TransportAddress &address, + bool password_protected); bool filterByWords(const irr::core::stringw words) const; // ------------------------------------------------------------------------ /** Returns ip address and port of this server. */ @@ -114,7 +117,8 @@ public: { return m_major_mode; } // ------------------------------------------------------------------------ RaceManager::Difficulty getDifficulty() const { return m_difficulty; } - + // ------------------------------------------------------------------------ + bool isPasswordProtected() const { return m_password_protected; } }; // Server #endif // HEADER_SERVER_HPP diff --git a/src/network/servers_manager.cpp b/src/network/servers_manager.cpp index 01bb43ae3..37a1d4eaa 100644 --- a/src/network/servers_manager.cpp +++ b/src/network/servers_manager.cpp @@ -160,6 +160,12 @@ Online::XMLRequest* ServersManager::getLANRefreshRequest() const if (len > 0) { BareNetworkString s(buffer, len); + uint8_t version = s.getUInt8(); + if (version != NetworkConfig::m_server_version) + { + Log::verbose("ServersManager", "Skipping a server"); + continue; + } irr::core::stringw name; // bytes_read is the number of bytes read s.decodeStringW(&name); @@ -169,9 +175,10 @@ Online::XMLRequest* ServersManager::getLANRefreshRequest() const uint8_t difficulty = s.getUInt8(); uint8_t mode = s.getUInt8(); sender.setPort(port); + uint8_t password = s.getUInt8(); servers_now.emplace_back(std::make_shared (cur_server_id++, name, max_players, players, - difficulty, mode, sender)); + difficulty, mode, sender, password)); } // if received_data } // while still waiting m_success = true; @@ -229,6 +236,14 @@ void ServersManager::setWanServers(bool success, const XMLNode* input) const XMLNode *servers_xml = input->getNode("servers"); for (unsigned int i = 0; i < servers_xml->getNumNodes(); i++) { + unsigned version = 0; + servers_xml->getNode(i)->get("version", &version); + assert(version != 0); + if (version != NetworkConfig::m_server_version) + { + Log::verbose("ServersManager", "Skipping a server"); + continue; + } m_servers.emplace_back( std::make_shared(*servers_xml->getNode(i))); } diff --git a/src/network/stk_host.cpp b/src/network/stk_host.cpp index a738e48e5..9d2c33075 100644 --- a/src/network/stk_host.cpp +++ b/src/network/stk_host.cpp @@ -872,10 +872,9 @@ void STKHost::handleDirectSocketRequest(Network* direct_socket) name = name.substr(0, 255); // Send the answer, consisting of server name, max players, - // current players, and the client's ip address and port - // number (which solves the problem which network interface - // might be the right one if there is more than one). + // current players BareNetworkString s((int)name.size()+1+11); + s.addUInt8(NetworkConfig::m_server_version); s.encodeString(name); s.addUInt8(NetworkConfig::get()->getMaxPlayers()); s.addUInt8(0); // FIXME: current number of connected players @@ -884,6 +883,7 @@ void STKHost::handleDirectSocketRequest(Network* direct_socket) s.addUInt8((uint8_t) NetworkConfig::get()->getServerGameMode(race_manager->getMinorMode(), race_manager->getMajorMode())); + s.addUInt8(!NetworkConfig::get()->getPassword().empty()); direct_socket->sendRawPacket(s, sender); } // if message is server-requested else if (command == connection_cmd) diff --git a/src/states_screens/create_server_screen.cpp b/src/states_screens/create_server_screen.cpp index 7587371bc..a824902a8 100644 --- a/src/states_screens/create_server_screen.cpp +++ b/src/states_screens/create_server_screen.cpp @@ -186,7 +186,7 @@ void CreateServerScreen::createServer() max_players, /*current_player*/0, (RaceManager::Difficulty) difficulty_widget->getSelection(PLAYER_ID_GAME_MASTER), NetworkConfig::get()->getServerGameMode(race_manager->getMinorMode(), - race_manager->getMajorMode()), server_address); + race_manager->getMajorMode()), server_address, !password_w.empty()); #undef USE_GRAPHICS_SERVER #ifdef USE_GRAPHICS_SERVER