From 6b35cbb8fdeb3b98e2d2132980b1b388ce48481c Mon Sep 17 00:00:00 2001 From: hilnius Date: Thu, 4 Jul 2013 22:49:45 +0000 Subject: [PATCH] adding connection stuff in the lobby protocol, and a xls file in doc/ to describe the protocol git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/branches/networking@13084 178a84e3-b1eb-0310-8ba1-8eac791a3b58 --- doc/protocols.xls | Bin 0 -> 7168 bytes src/network/game_setup.cpp | 13 +-- src/network/game_setup.hpp | 18 ++-- src/network/network_manager.cpp | 45 ++++++++-- src/network/network_manager.hpp | 8 ++ src/network/protocol_manager.cpp | 5 ++ src/network/protocol_manager.hpp | 5 ++ src/network/protocols/lobby_room_protocol.cpp | 78 ++++++++++++++++-- src/network/protocols/lobby_room_protocol.hpp | 4 + 9 files changed, 149 insertions(+), 27 deletions(-) create mode 100644 doc/protocols.xls diff --git a/doc/protocols.xls b/doc/protocols.xls new file mode 100644 index 0000000000000000000000000000000000000000..d9463dbe679b7360a229dc8d7c7cc8064944b7f6 GIT binary patch literal 7168 zcmeHLTWnNS6y0~8x4im*DHH^+RZ0s5X+ebepvXgrJepD;F(f!`Z((HGY1%=oi8`Vt zerN*n;SUKR!9-)?BO3jX#NwA9zG6axeu04xqlqKY7zi+~wa>ks>Cl1J5EavNv(ICl zefBNTgXrL%M~I4_oVUEO6QD zE9WqTNeqKH=TVRiDg#Xdv3`n|-bBNj=<0PW&?YH-X>nw|^djw-LCo^lLp406P{mkU z7VZ~g;lCcwg#Nq*u4gOO7uuiuH}~-%=vwQa`##tIRM0d~IS5C9RD!BN(?K&pF;F#V zCTJF@1~eNq2XqT)E@&R;R*(a_4O9!d9drk1KBx|~08|fZ04)S90yTmbgO-5q1T6(| zEX`iZ{9VYe0Nw3jtGqOCp^03f1 z`)ii`ERXZZ%eJYuNLCFEgeb#tntW3Vli>S^syrBj`$Bs#d!jd!{I(AYlM=c2r=FP%vB zVxKUXW{BIKc*b?=I|kG4Km!%1NU=F8PndlY5y`+yKOEapS#--d#B6 zjX-Ar%^}n)Jw^86Vzbsls;Au1YCIFRy8E2IWPH%=$1oFJPO95U?{+;1y>4>YJxuZD zRA)TtB)VXmR^@lrt;O}AxQSDrq%C%)dff)7dnn$Yb_U#}+nIK|Anq~eUT4K}$k@Y* z-gu9j!(*jJ4q{;FtaREj5Heoi<%A)?7mYdjDn^`qQ!t@jm}s6Al{&cEyh;fSMDbh1z0~#`~3b2JSTuE;MWFYTFY%?tnuBwWWIEy^UK_ z{XOwyZCz7y-I^G#I=J{;o2@mz%XR8nUsUlgXIDV)dgNbRd}{yVQ`yxG z1^J^=iw9j72FGu|G+K?8-`-Cxc^I-M$+K!f_+-pjjb*lqRprY8aDHB%F9&grbSv{^ zF4^SFd^wEA!r21;h(zSV)OHa_yz^XP zxHfUhjOi2Klq_7!IYR0WLDpQ4D~PMQFNy6Y1`cw_+MmI-Tt-p(? zBZ3}Rt4Enq2qi3N)f2&}s`XJ}>LMudc|qx%i*g-V6w;mH-b5iirpF+y5ry=aUIZy2 zik>?9Ffpa@h`I<$e5_D9$84nADxD7twy{+@4;M-38uvU@kwM#>>p2%b6AhGH@6$c0cZ+=IJ*JlLYn>}t9|{(23If?8oM|^uAF}P$oUJ~c2~S}(3V9DKK!1B{s`nxz((Y` zlv+Kk3n?AqX%LO`5{U2S10Wtphe34uw?NeR6ZRdxh1q6zBH5eRJK!K&5@Va?pcYW3 z=Ex>aB=de~VdmnFbCU7UNVek6OYPN1TI6_e>sI^yX?jId+^tT|9&^&FL1Zc36V7ZhNOU$4)vaX?nPrA sKliY+p2)DQgN9D+gR6g_$Jd{ge`EYSaMGUs8getUserID() == id) { m_players.erase(m_players.begin()+i, m_players.begin()+i+1); Log::verbose("GameSetup", "Removed a player from the game setup."); @@ -71,20 +71,21 @@ void GameSetup::removePlayer(uint8_t id) //----------------------------------------------------------------------------- -const PlayerProfile* GameSetup::getProfile(uint32_t id) +const NetworkPlayerProfile* GameSetup::getProfile(uint32_t id) { for (unsigned int i = 0; i < m_players.size(); i++) { - if (m_players[i].user_profile.getUserID() == id) + if (m_players[i].user_profile->getUserID() == id) { return &m_players[i]; } } + return NULL; } //----------------------------------------------------------------------------- -const PlayerProfile* GameSetup::getProfile(uint8_t id) +const NetworkPlayerProfile* GameSetup::getProfile(uint8_t id) { for (unsigned int i = 0; i < m_players.size(); i++) { @@ -93,5 +94,7 @@ const PlayerProfile* GameSetup::getProfile(uint8_t id) return &m_players[i]; } } + return NULL; } + //----------------------------------------------------------------------------- diff --git a/src/network/game_setup.hpp b/src/network/game_setup.hpp index 0cd8a010a..24b165ab7 100644 --- a/src/network/game_setup.hpp +++ b/src/network/game_setup.hpp @@ -30,15 +30,15 @@ /*! \class PlayerProfile * \brief Contains the profile of a player. */ -class PlayerProfile +class NetworkPlayerProfile { public: - PlayerProfile() : user_profile("") {} - ~PlayerProfile() {} + NetworkPlayerProfile() { race_id = 0; user_profile = NULL; } + ~NetworkPlayerProfile() {} uint8_t race_id; //!< The id of the player for the race std::string kart_name; //!< The selected kart. - OnlineUser user_profile; //!< Pointer to the lobby profile + OnlineUser* user_profile; //!< Pointer to the lobby profile }; /*! \class GameSetup @@ -51,16 +51,16 @@ class GameSetup GameSetup(); virtual ~GameSetup(); - void addPlayer(PlayerProfile profile); //!< Add a player. + void addPlayer(NetworkPlayerProfile profile); //!< Add a player. void removePlayer(uint32_t id); //!< Remove a player by id. void removePlayer(uint8_t id); //!< Remove a player by local id. - const PlayerProfile* getProfile(uint32_t id); //!< Get a profile by database id - const PlayerProfile* getProfile(uint8_t id); //!< Get the profile by the lobby id + const NetworkPlayerProfile* getProfile(uint32_t id); //!< Get a profile by database id + const NetworkPlayerProfile* getProfile(uint8_t id); //!< Get the profile by the lobby id protected: - std::vector m_players; //!< Information about players - PlayerProfile m_self_profile; //!< Information about self + std::vector m_players; //!< Information about players + NetworkPlayerProfile m_self_profile; //!< Information about self }; #endif // GAME_SETUP_HPP diff --git a/src/network/network_manager.cpp b/src/network/network_manager.cpp index 308168257..d87bbd13a 100644 --- a/src/network/network_manager.cpp +++ b/src/network/network_manager.cpp @@ -41,6 +41,7 @@ void* protocolManagerUpdate(void* data) return NULL; } +//----------------------------------------------------------------------------- NetworkManager::NetworkManager() { @@ -50,6 +51,8 @@ NetworkManager::NetworkManager() m_localhost = NULL; } +//----------------------------------------------------------------------------- + NetworkManager::~NetworkManager() { if (m_protocol_manager_update_thread) @@ -66,13 +69,18 @@ NetworkManager::~NetworkManager() } } +//----------------------------------------------------------------------------- + void NetworkManager::run() { ProtocolManager::getInstance(); m_protocol_manager_update_thread = (pthread_t*)(malloc(sizeof(pthread_t))); - pthread_create(m_protocol_manager_update_thread, NULL, protocolManagerUpdate, ProtocolManager::getInstance()); + pthread_create(m_protocol_manager_update_thread, NULL, protocolManagerUpdate, + ProtocolManager::getInstance()); } +//----------------------------------------------------------------------------- + bool NetworkManager::connect(TransportAddress peer) { if (peerExists(peer)) @@ -81,6 +89,8 @@ bool NetworkManager::connect(TransportAddress peer) return STKPeer::connectToHost(m_localhost, peer, 2, 0); } +//----------------------------------------------------------------------------- + void NetworkManager::setManualSocketsMode(bool manual) { if (manual) @@ -89,17 +99,19 @@ void NetworkManager::setManualSocketsMode(bool manual) m_localhost->startListening(); } +//----------------------------------------------------------------------------- + void NetworkManager::notifyEvent(Event* event) { - Log::info("NetworkManager", "EVENT received\n"); + Log::info("NetworkManager", "EVENT received"); switch (event->type) { case EVENT_TYPE_MESSAGE: - Log::info("NetworkManager", "Message, Sender : %u, message = \"%s\"\n", event->peer->getAddress(), event->data.c_str()); + Log::info("NetworkManager", "Message, Sender : %u, message = \"%s\"", event->peer->getAddress(), event->data.c_str()); break; case EVENT_TYPE_DISCONNECTED: - Log::info("NetworkManager", "Somebody is now disconnected. There are now %lu peers.\n", m_peers.size()); - Log::info("NetworkManager", "Disconnected host: %i.%i.%i.%i:%i\n", event->peer->getAddress()>>24&0xff, event->peer->getAddress()>>16&0xff, event->peer->getAddress()>>8&0xff, event->peer->getAddress()&0xff,event->peer->getPort()); + Log::info("NetworkManager", "Somebody is now disconnected. There are now %lu peers.", m_peers.size()); + Log::info("NetworkManager", "Disconnected host: %i.%i.%i.%i:%i", event->peer->getAddress()>>24&0xff, event->peer->getAddress()>>16&0xff, event->peer->getAddress()>>8&0xff, event->peer->getAddress()&0xff,event->peer->getPort()); // remove the peer: for (unsigned int i = 0; i < m_peers.size(); i++) { @@ -110,10 +122,10 @@ void NetworkManager::notifyEvent(Event* event) break; } } - Log::fatal("NetworkManager", "The peer that has been disconnected was not registered by the Network Manager.\n"); + Log::fatal("NetworkManager", "The peer that has been disconnected was not registered by the Network Manager."); break; case EVENT_TYPE_CONNECTED: - Log::info("NetworkManager", "A client has just connected. There are now %lu peers.\n", m_peers.size() + 1); + Log::info("NetworkManager", "A client has just connected. There are now %lu peers.", m_peers.size() + 1); // create the new peer: m_peers.push_back(event->peer); break; @@ -121,22 +133,41 @@ void NetworkManager::notifyEvent(Event* event) ProtocolManager::getInstance()->notifyEvent(event); } +//----------------------------------------------------------------------------- + +GameSetup* NetworkManager::setupNewGame() +{ + if (m_game_setup) + delete m_game_setup; + m_game_setup = new GameSetup(); + return m_game_setup; +} + +//----------------------------------------------------------------------------- + + void NetworkManager::setLogin(std::string username, std::string password) { m_player_login.username = username; m_player_login.password = password; } +//----------------------------------------------------------------------------- + void NetworkManager::setPublicAddress(TransportAddress addr) { m_public_address = addr; } +//----------------------------------------------------------------------------- + bool NetworkManager::peerExists(TransportAddress peer) { return m_localhost->peerExists(peer); } +//----------------------------------------------------------------------------- + bool NetworkManager::isConnectedTo(TransportAddress peer) { return m_localhost->isConnectedTo(peer); diff --git a/src/network/network_manager.hpp b/src/network/network_manager.hpp index a8931862b..3eb7b2953 100644 --- a/src/network/network_manager.hpp +++ b/src/network/network_manager.hpp @@ -26,6 +26,7 @@ #include "network/singleton.hpp" #include "network/types.hpp" #include "network/event.hpp" +#include "network/game_setup.hpp" #include @@ -38,9 +39,14 @@ class NetworkManager : public Singleton // network management functions virtual bool connect(TransportAddress peer); virtual void setManualSocketsMode(bool manual); + + // message/packets related functions virtual void notifyEvent(Event* event); virtual void sendPacket(const char* data) = 0; + // Game related functions + virtual GameSetup* setupNewGame(); //!< Creates a new game setup and returns it + // raw data management void setLogin(std::string username, std::string password); void setPublicAddress(TransportAddress addr); @@ -54,6 +60,7 @@ class NetworkManager : public Singleton bool isPlayingOnline() { return m_playing_online; } STKHost* getHost() { return m_localhost; } std::vector getPeers() { return m_peers; } + GameSetup* getGameSetup() { return m_game_setup; } protected: NetworkManager(); @@ -63,6 +70,7 @@ class NetworkManager : public Singleton std::vector m_peers; STKHost* m_localhost; bool m_playing_online; + GameSetup* m_game_setup; TransportAddress m_public_address; PlayerLogin m_player_login; diff --git a/src/network/protocol_manager.cpp b/src/network/protocol_manager.cpp index c9094acb4..2bc01d248 100644 --- a/src/network/protocol_manager.cpp +++ b/src/network/protocol_manager.cpp @@ -300,6 +300,11 @@ int ProtocolManager::getProtocolID(Protocol* protocol) return 0; } +bool ProtocolManager::isServer() +{ + return NetworkManager::getInstance()->isServer(); +} + void ProtocolManager::assignProtocolId(ProtocolInfo* protocol_info) { pthread_mutex_lock(&m_id_mutex); diff --git a/src/network/protocol_manager.hpp b/src/network/protocol_manager.hpp index 1193eab14..5a5cad558 100644 --- a/src/network/protocol_manager.hpp +++ b/src/network/protocol_manager.hpp @@ -179,6 +179,11 @@ class ProtocolManager : public Singleton */ virtual int getProtocolID(Protocol* protocol); + /*! \brief Know whether the app is a server. + * \return True if this application is in server mode, false elseway. + */ + bool isServer(); + protected: // protected functions /*! diff --git a/src/network/protocols/lobby_room_protocol.cpp b/src/network/protocols/lobby_room_protocol.cpp index c62528e63..6a343d7a6 100644 --- a/src/network/protocols/lobby_room_protocol.cpp +++ b/src/network/protocols/lobby_room_protocol.cpp @@ -18,10 +18,16 @@ #include "network/protocols/lobby_room_protocol.hpp" +#include "network/network_manager.hpp" #include "utils/log.hpp" +#include "online/current_online_user.hpp" + +#include LobbyRoomProtocol::LobbyRoomProtocol(CallbackObject* callback_object) : Protocol(callback_object, PROTOCOL_LOBBY_ROOM) { + m_setup = NULL; + m_next_id = 0; } LobbyRoomProtocol::~LobbyRoomProtocol() @@ -30,23 +36,83 @@ LobbyRoomProtocol::~LobbyRoomProtocol() void LobbyRoomProtocol::notifyEvent(Event* event) { + assert(m_setup); // assert that the setup exists Log::setLogLevel(1); if (event->type == EVENT_TYPE_MESSAGE) { - + assert(event->data.size()); // assert that data isn't empty Log::verbose("LobbyRoomProtocol", "Message from %u : \"%s\"", event->peer->getAddress(), event->data.c_str()); - } + if (!m_listener->isServer()) // if we're a client + { + if (event->data[0] == (char)(1)) // new player connected + { + assert(event->data[1] == (char)(4)); // id is on 4 bytes + assert(event->data[6] == (char)(1)); // local id on 1 byte + assert(event->data.size() == 8); // the message was 8 bytes + + NetworkPlayerProfile profile; + profile.kart_name = ""; + profile.race_id = (uint8_t)(event->data[7]); + uint32_t global_id = 0; + global_id += (uint8_t)(event->data[2])<<24; + global_id += (uint8_t)(event->data[3])<<16; + global_id += (uint8_t)(event->data[4])<<8; + global_id += (uint8_t)(event->data[5]); + if (global_id == CurrentOnlineUser::get()->getUserID()) + { + Log::verbose("LobbyRoomProtocol", "The server confirmed that we are logged."); + profile.user_profile = CurrentOnlineUser::get(); + } + else + { + Log::verbose("LobbyRoomProtocol", "New player connected."); + profile.user_profile = new OnlineUser(""); ///! INSERT THE ID OF THE PLAYER HERE (global_id) + } + m_setup->addPlayer(profile); + } // if (event->data[0] == (char)(1)) + else + { + } + } // if (!m_listener->isServer()) + } // if (event->type == EVENT_TYPE_MESSAGE) if (event->type == EVENT_TYPE_CONNECTED) { - Log::verbose("LobbyRoomProtocol", "New player."); - // add the player to the game setup - - } + if (m_listener->isServer()) // if we're the server + { + Log::verbose("LobbyRoomProtocol", "New player."); + int player_id = 0; + // add the player to the game setup + while(m_setup->getProfile(m_next_id)!=NULL) + m_next_id++; + NetworkPlayerProfile profile; + profile.race_id = m_next_id; + profile.kart_name = ""; + profile.user_profile = new OnlineUser("Unnamed Player"); + m_setup->addPlayer(profile); + // notify everybody that there is a new player + std::string message; + message += (char)(1); // 1 means new player + message += (char)(4); // 4 bytes for the id + message += (char)((player_id<<24)&0xff); // 1rst id byte + message += (char)((player_id<<16)&0xff); // 2nd id byte + message += (char)((player_id<<8)&0xff); // 3rd id byte + message += (char)(player_id&0xff); // 4th id byte + message += (char)(1); // 1 byte for local id + message += (char)(m_next_id); // 1 byte of local id + m_listener->sendMessage(this, message); + } + else + { + Log::verbose("LobbyRoomProtocol", "Connected."); + } + } // if (event->type == EVENT_TYPE_CONNECTED) Log::setLogLevel(3); } void LobbyRoomProtocol::setup() { + m_setup = NetworkManager::getInstance()->setupNewGame(); // create a new setup + m_next_id = 0; } void LobbyRoomProtocol::update() diff --git a/src/network/protocols/lobby_room_protocol.hpp b/src/network/protocols/lobby_room_protocol.hpp index 59e28b450..f3a25cc6d 100644 --- a/src/network/protocols/lobby_room_protocol.hpp +++ b/src/network/protocols/lobby_room_protocol.hpp @@ -21,6 +21,8 @@ #include "network/protocol.hpp" +#include "network/game_setup.hpp" + /*! * \class LobbyRoomProtocol * \brief Class used while the game is being prepared. @@ -42,6 +44,8 @@ class LobbyRoomProtocol : public Protocol void sendMessage(std::string message); protected: + GameSetup* m_setup; //!< The game setup. + uint8_t m_next_id; }; #endif // LOBBY_ROOM_PROTOCOL_HPP