diff --git a/doc/protocols.xls b/doc/protocols.xls new file mode 100644 index 000000000..d9463dbe6 Binary files /dev/null and b/doc/protocols.xls differ diff --git a/src/network/game_setup.cpp b/src/network/game_setup.cpp index feee1e5d1..9147071f1 100644 --- a/src/network/game_setup.cpp +++ b/src/network/game_setup.cpp @@ -34,7 +34,7 @@ GameSetup::~GameSetup() //----------------------------------------------------------------------------- -void GameSetup::addPlayer(PlayerProfile profile) +void GameSetup::addPlayer(NetworkPlayerProfile profile) { m_players.push_back(profile); } @@ -45,7 +45,7 @@ void GameSetup::removePlayer(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) { 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