diff --git a/src/network/event.cpp b/src/network/event.cpp index 0f4835e6d..1be77e397 100644 --- a/src/network/event.cpp +++ b/src/network/event.cpp @@ -42,10 +42,7 @@ Event::Event(ENetEvent* event) } if (type == EVENT_TYPE_MESSAGE) { - data = NetworkString(std::string((char*)(event->packet->data), event->packet->dataLength-1)); - } - else if (event->data) - { + m_data = NetworkString(std::string((char*)(event->packet->data), event->packet->dataLength-1)); } m_packet = NULL; @@ -80,7 +77,7 @@ Event::Event(ENetEvent* event) Event::Event(const Event& event) { m_packet = NULL; - data = event.data; + m_data = event.m_data; // copy the peer peer = event.peer; type = event.type; @@ -94,6 +91,6 @@ Event::~Event() void Event::removeFront(int size) { - data.removeFront(size); + m_data.removeFront(size); } diff --git a/src/network/event.hpp b/src/network/event.hpp index ce3a97629..50477f5bb 100644 --- a/src/network/event.hpp +++ b/src/network/event.hpp @@ -65,11 +65,13 @@ class Event */ void removeFront(int size); + NetworkString data() const { return m_data; } + EVENT_TYPE type; //!< Type of the event. - NetworkString data; //!< Copy of the data passed by the event. STKPeer** peer; //!< Pointer to the peer that triggered that event. private: + NetworkString m_data; //!< Copy of the data passed by the event. ENetPacket* m_packet; //!< A pointer on the ENetPacket to be deleted. }; diff --git a/src/network/game_setup.cpp b/src/network/game_setup.cpp index a59112707..fe670c309 100644 --- a/src/network/game_setup.cpp +++ b/src/network/game_setup.cpp @@ -43,7 +43,7 @@ GameSetup::~GameSetup() void GameSetup::addPlayer(NetworkPlayerProfile* profile) { m_players.push_back(profile); - Log::verbose("GameSetup", "New player in the game setup. Global id : %u, " + Log::info("GameSetup", "New player in the game setup. Global id : %u, " "Race id : %d.", profile->user_profile->getUserID(), profile->race_id); } diff --git a/src/network/network_manager.cpp b/src/network/network_manager.cpp index 5e44bac61..77737e7a3 100644 --- a/src/network/network_manager.cpp +++ b/src/network/network_manager.cpp @@ -116,7 +116,7 @@ void NetworkManager::notifyEvent(Event* event) ((addr>>24)&0xff), ((addr>>16)&0xff), ((addr>>8)&0xff), - (addr&0xff), event->data.c_str()); + (addr&0xff), event->data().c_str()); } diff --git a/src/network/protocol.hpp b/src/network/protocol.hpp index 2d5494f7f..e5f1f0eff 100644 --- a/src/network/protocol.hpp +++ b/src/network/protocol.hpp @@ -61,53 +61,51 @@ class Protocol * \param type The type of the protocol. */ Protocol(CallbackObject* callback_object, PROTOCOL_TYPE type); - /*! - * \brief Destructor + /*! \brief Destructor */ virtual ~Protocol(); - /*! - * \brief Notify a protocol matching the Event type of that event. - * \param event : Pointer to the event. + /*! \brief Notify a protocol matching the Event type of that event. + * \param event : Pointer to the event. + * \return True if the event has been treated, false elseway */ - virtual void notifyEvent(Event* event) = 0; + virtual bool notifyEvent(Event* event) { return false; } - /*! - * \brief Set the protocol listener. - * \param listener : Pointer to the listener. + /*! \brief Notify a protocol matching the Event type of that event. + * This update is done asynchronously : + * \param event : Pointer to the event. + * \return True if the event has been treated, false elseway + */ + virtual bool notifyEventAsynchronous(Event* event) { return false; } + + /*! \brief Set the protocol listener. + * \param listener : Pointer to the listener. */ void setListener(ProtocolManager* listener); - /*! - * \brief Called when the protocol is going to start. Must be re-defined by subclasses. + /*! \brief Called when the protocol is going to start. Must be re-defined by subclasses. */ virtual void setup() = 0; - /*! - * \brief Called when the protocol is paused (by an other entity or by itself). - * This function must be called by the subclasse's pause function if re-defined. + /*! \brief Called when the protocol is paused (by an other entity or by itself). + * This function must be called by the subclasse's pause function if re-defined. */ virtual void pause(); - /*! - * \brief Called when the protocol is unpaused. - * This function must be called by the subclasse's unpause function if re-defined. + /*! \brief Called when the protocol is unpaused. + * This function must be called by the subclasse's unpause function if re-defined. */ virtual void unpause(); - /*! - * \brief Called by the protocol listener, synchronously with the main loop. Must be re-defined. + /*! \brief Called by the protocol listener, synchronously with the main loop. Must be re-defined. */ virtual void update() = 0; - /*! - * \brief Called by the protocol listener as often as possible. Must be re-defined. + /*! \brief Called by the protocol listener as often as possible. Must be re-defined. */ virtual void asynchronousUpdate() = 0; - /*! - * \brief Called when the protocol is to be killed. + /*! \brief Called when the protocol is to be killed. */ virtual void kill(); - /*! - * \brief Method to get a protocol's type. - * \return The protocol type. + /*! \brief Method to get a protocol's type. + * \return The protocol type. */ PROTOCOL_TYPE getProtocolType(); protected: diff --git a/src/network/protocol_manager.cpp b/src/network/protocol_manager.cpp index 4bc7d6097..37230a267 100644 --- a/src/network/protocol_manager.cpp +++ b/src/network/protocol_manager.cpp @@ -34,7 +34,7 @@ void* protocolManagerUpdate(void* data) while(!manager->exit()) { manager->update(); - irr_driver->getDevice()->sleep(20); + usleep(20000); } return NULL; } @@ -44,7 +44,7 @@ void* protocolManagerAsynchronousUpdate(void* data) while(!manager->exit()) { manager->asynchronousUpdate(); - irr_driver->getDevice()->sleep(20); + usleep(20000); } return NULL; } @@ -83,7 +83,7 @@ ProtocolManager::~ProtocolManager() for (unsigned int i = 0; i < m_protocols.size() ; i++) delete m_protocols[i].protocol; for (unsigned int i = 0; i < m_events_to_process.size() ; i++) - delete m_events_to_process[i]; + delete m_events_to_process[i].event; m_protocols.clear(); m_requests.clear(); m_events_to_process.clear(); @@ -105,7 +105,49 @@ void ProtocolManager::notifyEvent(Event* event) { pthread_mutex_lock(&m_events_mutex); Event* event2 = new Event(*event); - m_events_to_process.push_back(event2); // add the event to the queue + // register protocols that will receive this event + std::vector protocols_ids; + PROTOCOL_TYPE searchedProtocol = PROTOCOL_NONE; + if (event2->type == EVENT_TYPE_MESSAGE) + { + if (event2->data().size() > 0) + { + searchedProtocol = (PROTOCOL_TYPE)(event2->data()[0]); + event2->removeFront(1); + } + else + { + Log::warn("ProtocolManager", "Not enough data."); + } + } + if (event2->type == EVENT_TYPE_CONNECTED) + { + searchedProtocol = PROTOCOL_CONNECTION; + } + Log::verbose("ProtocolManager", "Received event for protocols of type %d", searchedProtocol); + pthread_mutex_lock(&m_protocols_mutex); + for (unsigned int i = 0; i < m_protocols.size() ; i++) + { + if (m_protocols[i].protocol->getProtocolType() == searchedProtocol || event2->type == EVENT_TYPE_DISCONNECTED) // pass data to protocols even when paused + { + protocols_ids.push_back(m_protocols[i].id); + } + } + pthread_mutex_unlock(&m_protocols_mutex); + if (searchedProtocol == PROTOCOL_NONE) // no protocol was aimed, show the msg to debug + { + Log::debug("ProtocolManager", "NO PROTOCOL : Message is \"%s\"", event2->data().c_str()); + } + + if (protocols_ids.size() != 0) + { + EventProcessingInfo epi; + epi.event = event2; + epi.protocols_ids = protocols_ids; + m_events_to_process.push_back(epi); // add the event to the queue + } + else + Log::warn("ProtocolManager", "Received an event that has no destination protocol."); pthread_mutex_unlock(&m_events_mutex); } @@ -274,36 +316,50 @@ void ProtocolManager::protocolTerminated(ProtocolInfo protocol) pthread_mutex_unlock(&m_protocols_mutex); } -void ProtocolManager::propagateEvent(Event* event) +bool ProtocolManager::propagateEvent(EventProcessingInfo* event, bool synchronous) { - PROTOCOL_TYPE searchedProtocol = PROTOCOL_NONE; - if (event->type == EVENT_TYPE_MESSAGE) + int index = 0; + for (unsigned int i = 0; i < m_protocols.size(); i++) { - if (event->data.size() > 0) - searchedProtocol = (PROTOCOL_TYPE)(event->data.getAndRemoveUInt8()); + if (event->protocols_ids[index] == m_protocols[i].id) + { + bool result = false; + if (synchronous) + result = m_protocols[i].protocol->notifyEvent(event->event); + else + result = m_protocols[i].protocol->notifyEventAsynchronous(event->event); + if (result) + event->protocols_ids.pop_back(); + else + index++; + } } - if (event->type == EVENT_TYPE_CONNECTED) + if (event->protocols_ids.size() == 0) { - searchedProtocol = PROTOCOL_CONNECTION; + // because we made a copy of the event + delete event->event->peer; // no more need of that + delete event->event; + return true; } - Log::verbose("ProtocolManager", "Received event for protocols of type %d", searchedProtocol); - for (unsigned int i = 0; i < m_protocols.size() ; i++) - { - if (m_protocols[i].protocol->getProtocolType() == searchedProtocol || event->type == EVENT_TYPE_DISCONNECTED) // pass data to protocols even when paused - m_protocols[i].protocol->notifyEvent(event); - } - if (searchedProtocol == PROTOCOL_NONE) // no protocol was aimed, show the msg to debug - { - Log::debug("ProtocolManager", "NO PROTOCOL : Message is \"%s\"", event->data.c_str()); - } - - // because we made a copy of the event - delete event->peer; // no more need of that - delete event; + return false; } void ProtocolManager::update() { + // before updating, notice protocols that they have received events + pthread_mutex_lock(&m_events_mutex); // secure threads + int size = m_events_to_process.size(); + int offset = 0; + for (int i = 0; i < size; i++) + { + bool result = propagateEvent(&m_events_to_process[i+offset], true); + if (result) + { + m_events_to_process.erase(m_events_to_process.begin()+i+offset,m_events_to_process.begin()+i+offset+1); + offset --; + } + } + pthread_mutex_unlock(&m_events_mutex); // release the mutex // now update all protocols pthread_mutex_lock(&m_protocols_mutex); for (unsigned int i = 0; i < m_protocols.size(); i++) @@ -317,16 +373,19 @@ void ProtocolManager::update() void ProtocolManager::asynchronousUpdate() { // before updating, notice protocols that they have received information + pthread_mutex_lock(&m_events_mutex); // secure threads int size = m_events_to_process.size(); + int offset = 0; for (int i = 0; i < size; i++) { - pthread_mutex_lock(&m_events_mutex); // secure threads - Event* event = m_events_to_process.back(); - m_events_to_process.pop_back(); - pthread_mutex_unlock(&m_events_mutex); // release the mutex - - propagateEvent(event); + bool result = propagateEvent(&m_events_to_process[i+offset], false); + if (result) + { + m_events_to_process.erase(m_events_to_process.begin()+i+offset,m_events_to_process.begin()+i+offset+1); + offset --; + } } + pthread_mutex_unlock(&m_events_mutex); // release the mutex // now update all protocols that need to be updated in asynchronous mode pthread_mutex_lock(&m_asynchronous_protocols_mutex); diff --git a/src/network/protocol_manager.hpp b/src/network/protocol_manager.hpp index ceb88ba45..f2dd28a52 100644 --- a/src/network/protocol_manager.hpp +++ b/src/network/protocol_manager.hpp @@ -78,6 +78,15 @@ typedef struct ProtocolRequest ProtocolInfo protocol_info; //!< The concerned protocol information } ProtocolRequest; +/*! \struct ProtocolRequest + * \brief Used to pass the event to protocols that need it + */ +typedef struct EventProcessingInfo +{ + Event* event; + std::vector protocols_ids; +} EventProcessingInfo; + /*! * \class ProtocolManager * \brief Manages the protocols at runtime. @@ -269,7 +278,7 @@ class ProtocolManager : public Singleton */ virtual void protocolTerminated(ProtocolInfo protocol); - void propagateEvent(Event* event); + bool propagateEvent(EventProcessingInfo* event, bool synchronous); // protected members /*! @@ -281,7 +290,7 @@ class ProtocolManager : public Singleton /*! * \brief Contains the network events to pass to protocols. */ - std::vector m_events_to_process; + std::vector m_events_to_process; /*! * \brief Contains the requests to start/stop etc... protocols. */ diff --git a/src/network/protocols/client_lobby_room_protocol.cpp b/src/network/protocols/client_lobby_room_protocol.cpp index 060858251..01ddc9864 100644 --- a/src/network/protocols/client_lobby_room_protocol.cpp +++ b/src/network/protocols/client_lobby_room_protocol.cpp @@ -68,14 +68,22 @@ void ClientLobbyRoomProtocol::leave() //----------------------------------------------------------------------------- -void ClientLobbyRoomProtocol::notifyEvent(Event* event) +bool ClientLobbyRoomProtocol::notifyEvent(Event* event) +{ + return false; +} + +//----------------------------------------------------------------------------- + +bool ClientLobbyRoomProtocol::notifyEventAsynchronous(Event* event) { assert(m_setup); // assert that the setup exists if (event->type == EVENT_TYPE_MESSAGE) { - assert(event->data.size()); // assert that data isn't empty - uint8_t message_type = event->data.getAndRemoveUInt8(); - + NetworkString data = event->data(); + assert(data.size()); // assert that data isn't empty + uint8_t message_type = data[0]; + event->removeFront(1); Log::info("ClientLobbyRoomProtocol", "Message of type %d", message_type); if (message_type == 0x01) // new player connected newPlayer(event); @@ -107,6 +115,7 @@ void ClientLobbyRoomProtocol::notifyEvent(Event* event) NetworkManager::getInstance()->reset(); NetworkManager::getInstance()->removePeer(*event->peer); // prolly the same as m_server } // disconnection + return true; } //----------------------------------------------------------------------------- @@ -185,14 +194,15 @@ void ClientLobbyRoomProtocol::update() */ void ClientLobbyRoomProtocol::newPlayer(Event* event) { - if (event->data.size() != 7 || event->data[0] != 4 || event->data[5] != 1) // 7 bytes remains now + NetworkString data = event->data(); + if (data.size() != 7 || data[0] != 4 || data[5] != 1) // 7 bytes remains now { Log::error("ClientLobbyRoomProtocol", "A message notifying a new player wasn't formated as expected."); return; } - uint32_t global_id = event->data.gui32(1); - uint8_t race_id = event->data.gui8(6); + uint32_t global_id = data.gui32(1); + uint8_t race_id = data.gui8(6); if (global_id == Online::CurrentUser::get()->getUserID()) { @@ -227,12 +237,13 @@ void ClientLobbyRoomProtocol::newPlayer(Event* event) */ void ClientLobbyRoomProtocol::disconnectedPlayer(Event* event) { - if (event->data.size() != 2 || event->data[0] != 1) + NetworkString data = event->data(); + if (data.size() != 2 || data[0] != 1) { Log::error("ClientLobbyRoomProtocol", "A message notifying a new player wasn't formated as expected."); return; } - uint8_t id = event->data[1]; + uint8_t id = data[1]; if (m_setup->removePlayer(id)) { Log::info("ClientLobbyRoomProtocol", "Peer removed successfully."); @@ -257,14 +268,15 @@ void ClientLobbyRoomProtocol::disconnectedPlayer(Event* event) */ void ClientLobbyRoomProtocol::connectionAccepted(Event* event) { - if (event->data.size() < 12 || event->data[0] != 1 || event->data[2] != 4 || event->data[7] != 4) // 12 bytes remains now + NetworkString data = event->data(); + if (data.size() < 12 || data[0] != 1 || data[2] != 4 || data[7] != 4) // 12 bytes remains now { Log::error("ClientLobbyRoomProtocol", "A message notifying an accepted connection wasn't formated as expected."); return; } STKPeer* peer = *(event->peer); - uint32_t global_id = event->data.gui32(8); + uint32_t global_id = data.gui32(8); if (global_id == Online::CurrentUser::get()->getUserID()) { Log::info("ClientLobbyRoomProtocol", "The server accepted the connection."); @@ -272,15 +284,15 @@ void ClientLobbyRoomProtocol::connectionAccepted(Event* event) // self profile NetworkPlayerProfile* profile = new NetworkPlayerProfile(); profile->kart_name = ""; - profile->race_id = event->data.gui8(1); + profile->race_id = data.gui8(1); profile->user_profile = Online::CurrentUser::get(); m_setup->addPlayer(profile); // connection token - uint32_t token = event->data.gui32(3); + uint32_t token = data.gui32(3); peer->setClientServerToken(token); // add all players - event->data.removeFront(12); // remove the 12 first bytes - int remaining = event->data.size(); + data.removeFront(12); // remove the 12 first bytes + int remaining = data.size(); if (remaining%7 != 0) { Log::error("ClientLobbyRoomProtocol", "ConnectionAccepted : Error in the server list"); @@ -288,17 +300,17 @@ void ClientLobbyRoomProtocol::connectionAccepted(Event* event) remaining /= 7; for (int i = 0; i < remaining; i++) { - if (event->data[0] != 1 || event->data[2] != 4) + if (data[0] != 1 || data[2] != 4) Log::error("ClientLobbyRoomProtocol", "Bad format in players list."); - uint8_t race_id = event->data[1]; - uint32_t global_id = event->data.gui32(3); + uint8_t race_id = data[1]; + uint32_t global_id = data.gui32(3); Online::User* new_user = new Online::User(global_id); NetworkPlayerProfile* profile2 = new NetworkPlayerProfile(); profile2->race_id = race_id; profile2->user_profile = new_user; profile2->kart_name = ""; m_setup->addPlayer(profile2); - event->data.removeFront(7); + data.removeFront(7); } // add self @@ -323,13 +335,14 @@ void ClientLobbyRoomProtocol::connectionAccepted(Event* event) */ void ClientLobbyRoomProtocol::connectionRefused(Event* event) { - if (event->data.size() != 2 || event->data[0] != 1) // 2 bytes remains now + NetworkString data = event->data(); + if (data.size() != 2 || data[0] != 1) // 2 bytes remains now { Log::error("ClientLobbyRoomProtocol", "A message notifying a refused connection wasn't formated as expected."); return; } - switch (event->data[1]) // the second byte + switch (data[1]) // the second byte { case 0: Log::info("ClientLobbyRoomProtocol", "Connection refused : too many players."); @@ -357,13 +370,14 @@ void ClientLobbyRoomProtocol::connectionRefused(Event* event) */ void ClientLobbyRoomProtocol::kartSelectionRefused(Event* event) { - if (event->data.size() != 2 || event->data[0] != 1) + NetworkString data = event->data(); + if (data.size() != 2 || data[0] != 1) { Log::error("ClientLobbyRoomProtocol", "A message notifying a refused kart selection wasn't formated as expected."); return; } - switch (event->data[1]) // the error code + switch (data[1]) // the error code { case 0: Log::info("ClientLobbyRoomProtocol", "Kart selection refused : already taken."); @@ -391,24 +405,26 @@ void ClientLobbyRoomProtocol::kartSelectionRefused(Event* event) */ void ClientLobbyRoomProtocol::kartSelectionUpdate(Event* event) { - if (event->data.size() < 3 || event->data[0] != 1) + NetworkString data = event->data(); + if (data.size() < 3 || data[0] != 1) { Log::error("ClientLobbyRoomProtocol", "A message notifying a kart selection update wasn't formated as expected."); return; } - uint8_t player_id = event->data[1]; - uint8_t kart_name_length = event->data[2]; - std::string data = event->data.getString(3, kart_name_length); - if (data.size() != kart_name_length) + uint8_t player_id = data[1]; + uint8_t kart_name_length = data[2]; + std::string kart_name = data.getString(3, kart_name_length); + if (kart_name.size() != kart_name_length) { - Log::error("ClientLobbyRoomProtocol", "Kart names sizes differ: told: %d, real: %d.", kart_name_length, data.size()); + Log::error("ClientLobbyRoomProtocol", "Kart names sizes differ: told: %d, real: %d.", kart_name_length, kart_name.size()); return; } - if (!m_setup->isKartAvailable(data)) + if (!m_setup->isKartAvailable(kart_name)) { Log::error("ClientLobbyRoomProtocol", "The updated kart is taken already."); } - m_setup->setPlayerKart(player_id, data); + m_setup->setPlayerKart(player_id, kart_name); + NetworkKartSelectionScreen::getInstance()->playerSelected(player_id, kart_name); } //----------------------------------------------------------------------------- @@ -425,13 +441,14 @@ void ClientLobbyRoomProtocol::kartSelectionUpdate(Event* event) */ void ClientLobbyRoomProtocol::startGame(Event* event) { - if (event->data.size() < 5 || event->data[0] != 4) + NetworkString data = event->data(); + if (data.size() < 5 || data[0] != 4) { Log::error("ClientLobbyRoomProtocol", "A message notifying a kart " "selection update wasn't formated as expected."); return; } - uint8_t token = event->data.gui32(1); + uint8_t token = data.gui32(1); if (token == NetworkManager::getInstance()->getPeers()[0]->getClientServerToken()) { m_state = PLAYING; @@ -457,13 +474,14 @@ void ClientLobbyRoomProtocol::startGame(Event* event) */ void ClientLobbyRoomProtocol::startSelection(Event* event) { - if (event->data.size() < 5 || event->data[0] != 4) + NetworkString data = event->data(); + if (data.size() < 5 || data[0] != 4) { Log::error("ClientLobbyRoomProtocol", "A message notifying a kart " "selection update wasn't formated as expected."); return; } - uint8_t token = event->data.gui32(1); + uint8_t token = data.gui32(1); if (token == NetworkManager::getInstance()->getPeers()[0]->getClientServerToken()) { m_state = KART_SELECTION; diff --git a/src/network/protocols/client_lobby_room_protocol.hpp b/src/network/protocols/client_lobby_room_protocol.hpp index 5866e4ff0..970d1b17a 100644 --- a/src/network/protocols/client_lobby_room_protocol.hpp +++ b/src/network/protocols/client_lobby_room_protocol.hpp @@ -13,7 +13,8 @@ class ClientLobbyRoomProtocol : public LobbyRoomProtocol void sendMessage(std::string message); void leave(); - virtual void notifyEvent(Event* event); + virtual bool notifyEvent(Event* event); + virtual bool notifyEventAsynchronous(Event* event); virtual void setup(); virtual void update(); virtual void asynchronousUpdate() {} diff --git a/src/network/protocols/connect_to_peer.cpp b/src/network/protocols/connect_to_peer.cpp index d810234af..62ebac13a 100644 --- a/src/network/protocols/connect_to_peer.cpp +++ b/src/network/protocols/connect_to_peer.cpp @@ -46,13 +46,14 @@ ConnectToPeer::~ConnectToPeer() // ---------------------------------------------------------------------------- -void ConnectToPeer::notifyEvent(Event* event) +bool ConnectToPeer::notifyEventAsynchronous(Event* event) { if (event->type == EVENT_TYPE_CONNECTED) { Log::debug("ConnectToPeer", "Received event notifying peer connection."); m_state = CONNECTED; // we received a message, we are connected } + return true; } // ---------------------------------------------------------------------------- diff --git a/src/network/protocols/connect_to_peer.hpp b/src/network/protocols/connect_to_peer.hpp index 03bbab88d..97bad8327 100644 --- a/src/network/protocols/connect_to_peer.hpp +++ b/src/network/protocols/connect_to_peer.hpp @@ -29,7 +29,7 @@ class ConnectToPeer : public Protocol, public CallbackObject ConnectToPeer(uint32_t peer_id); virtual ~ConnectToPeer(); - virtual void notifyEvent(Event* event); + virtual bool notifyEventAsynchronous(Event* event); virtual void setup(); virtual void update() {} virtual void asynchronousUpdate(); diff --git a/src/network/protocols/connect_to_server.cpp b/src/network/protocols/connect_to_server.cpp index 72c6445b8..660b0265a 100644 --- a/src/network/protocols/connect_to_server.cpp +++ b/src/network/protocols/connect_to_server.cpp @@ -60,7 +60,7 @@ ConnectToServer::~ConnectToServer() // ---------------------------------------------------------------------------- -void ConnectToServer::notifyEvent(Event* event) +bool ConnectToServer::notifyEventAsynchronous(Event* event) { if (event->type == EVENT_TYPE_CONNECTED) { @@ -68,6 +68,7 @@ void ConnectToServer::notifyEvent(Event* event) "received an event notifying that he's connected to the peer."); m_state = CONNECTED; // we received a message, we are connected } + return true; } // ---------------------------------------------------------------------------- @@ -184,6 +185,7 @@ void ConnectToServer::asynchronousUpdate() break; case DONE: m_listener->requestTerminate(this); + m_state = EXITING; break; } } diff --git a/src/network/protocols/connect_to_server.hpp b/src/network/protocols/connect_to_server.hpp index c49523e48..7f95a512a 100644 --- a/src/network/protocols/connect_to_server.hpp +++ b/src/network/protocols/connect_to_server.hpp @@ -30,7 +30,7 @@ class ConnectToServer : public Protocol, public CallbackObject ConnectToServer(uint32_t server_id, uint32_t host_id); //!< Specify server id virtual ~ConnectToServer(); - virtual void notifyEvent(Event* event); + virtual bool notifyEventAsynchronous(Event* event); virtual void setup(); virtual void update() {} virtual void asynchronousUpdate(); @@ -53,7 +53,8 @@ class ConnectToServer : public Protocol, public CallbackObject CONNECTING, CONNECTED, HIDING_ADDRESS, - DONE + DONE, + EXITING }; STATE m_state; }; diff --git a/src/network/protocols/controller_events_protocol.cpp b/src/network/protocols/controller_events_protocol.cpp index ed91740a3..341d007d3 100644 --- a/src/network/protocols/controller_events_protocol.cpp +++ b/src/network/protocols/controller_events_protocol.cpp @@ -42,7 +42,7 @@ void ControllerEventsProtocol::setup() { peer = peers[j]; } - Log::info("ControllerEventsProtocol", "Compared %s and %s", + Log::info("ControllerEventsProtocol", "Compared %s and %s", peers[j]->getPlayerProfile()->kart_name.c_str(), karts[i]->getIdent().c_str()); } } @@ -61,20 +61,21 @@ void ControllerEventsProtocol::setup() //----------------------------------------------------------------------------- -void ControllerEventsProtocol::notifyEvent(Event* event) +bool ControllerEventsProtocol::notifyEventAsynchronous(Event* event) { - if (event->data.size() < 17) + NetworkString data = event->data(); + if (data.size() < 17) { - Log::error("ControllerEventsProtocol", "The data supplied was not complete. Size was %d.", event->data.size()); - return; + Log::error("ControllerEventsProtocol", "The data supplied was not complete. Size was %d.", data.size()); + return true; } - uint32_t token = event->data.gui32(); - NetworkString pure_message = event->data; + uint32_t token = data.gui32(); + NetworkString pure_message = data; pure_message.removeFront(4); if (token != (*event->peer)->getClientServerToken()) { Log::error("ControllerEventsProtocol", "Bad token from peer."); - return; + return true; } NetworkString ns = pure_message; float event_timestamp = ns.getFloat(); @@ -103,12 +104,12 @@ void ControllerEventsProtocol::notifyEvent(Event* event) if (ns.size() > 0 && ns.size() != 9) { Log::warn("ControllerEventProtocol", "The data seems corrupted. Remains %d", ns.size()); - return; + return true; } if (client_index < 0) { Log::warn("ControllerEventProtocol", "Couldn't have a client id."); - return; + return true; } if (m_listener->isServer()) { @@ -124,6 +125,7 @@ void ControllerEventsProtocol::notifyEvent(Event* event) //Log::info("ControllerEventsProtocol", "Sizes are %d and %d", ns2.size(), pure_message.size()); } } + return true; } //----------------------------------------------------------------------------- diff --git a/src/network/protocols/controller_events_protocol.hpp b/src/network/protocols/controller_events_protocol.hpp index 3500765bd..9a65c0d2c 100644 --- a/src/network/protocols/controller_events_protocol.hpp +++ b/src/network/protocols/controller_events_protocol.hpp @@ -16,8 +16,8 @@ class ControllerEventsProtocol : public Protocol ControllerEventsProtocol(); virtual ~ControllerEventsProtocol(); + virtual bool notifyEventAsynchronous(Event* event); virtual void setup(); - virtual void notifyEvent(Event* event); virtual void update(); virtual void asynchronousUpdate() {} diff --git a/src/network/protocols/game_events_protocol.cpp b/src/network/protocols/game_events_protocol.cpp index 2b9ded2fd..d6a359983 100644 --- a/src/network/protocols/game_events_protocol.cpp +++ b/src/network/protocols/game_events_protocol.cpp @@ -8,10 +8,6 @@ GameEventsProtocol::~GameEventsProtocol() { } -void GameEventsProtocol::notifyEvent(Event* event) -{ -} - void GameEventsProtocol::setup() { } diff --git a/src/network/protocols/game_events_protocol.hpp b/src/network/protocols/game_events_protocol.hpp index 0a3d6107c..1d4ca970b 100644 --- a/src/network/protocols/game_events_protocol.hpp +++ b/src/network/protocols/game_events_protocol.hpp @@ -10,7 +10,8 @@ class GameEventsProtocol : public Protocol GameEventsProtocol(); virtual ~GameEventsProtocol(); - virtual void notifyEvent(Event* event); + virtual bool notifyEvent(Event* event) { return true; } + virtual bool notifyEventAsynchronous(Event* event) { return true; } virtual void setup(); virtual void update(); virtual void asynchronousUpdate() {} diff --git a/src/network/protocols/get_peer_address.cpp b/src/network/protocols/get_peer_address.cpp index 4b71feb13..6206d6a06 100644 --- a/src/network/protocols/get_peer_address.cpp +++ b/src/network/protocols/get_peer_address.cpp @@ -34,11 +34,6 @@ GetPeerAddress::~GetPeerAddress() { } -void GetPeerAddress::notifyEvent(Event* event) -{ - // nothing there. If we receive events, they must be ignored -} - void GetPeerAddress::setup() { m_state = NONE; diff --git a/src/network/protocols/get_peer_address.hpp b/src/network/protocols/get_peer_address.hpp index 4007387fd..771825d97 100644 --- a/src/network/protocols/get_peer_address.hpp +++ b/src/network/protocols/get_peer_address.hpp @@ -28,7 +28,8 @@ class GetPeerAddress : public Protocol GetPeerAddress(uint32_t peer_id, CallbackObject* callback_object); virtual ~GetPeerAddress(); - virtual void notifyEvent(Event* event); + virtual bool notifyEvent(Event* event) { return true; } + virtual bool notifyEventAsynchronous(Event* event) { return true; } virtual void setup(); virtual void update() {} virtual void asynchronousUpdate(); diff --git a/src/network/protocols/get_public_address.cpp b/src/network/protocols/get_public_address.cpp index 1483ea1ef..a700d34f9 100644 --- a/src/network/protocols/get_public_address.cpp +++ b/src/network/protocols/get_public_address.cpp @@ -46,11 +46,6 @@ GetPublicAddress::~GetPublicAddress() { } -void GetPublicAddress::notifyEvent(Event* event) -{ - -} - void GetPublicAddress::setup() { m_state = NOTHING_DONE; diff --git a/src/network/protocols/get_public_address.hpp b/src/network/protocols/get_public_address.hpp index b564207b7..b591ba429 100644 --- a/src/network/protocols/get_public_address.hpp +++ b/src/network/protocols/get_public_address.hpp @@ -27,8 +27,8 @@ class GetPublicAddress : public Protocol GetPublicAddress(CallbackObject* callback_object); virtual ~GetPublicAddress(); - virtual void notifyEvent(Event* event); - + virtual bool notifyEvent(Event* event) { return true; } + virtual bool notifyEventAsynchronous(Event* event) { return true; } virtual void setup(); virtual void update() {} virtual void asynchronousUpdate(); diff --git a/src/network/protocols/hide_public_address.cpp b/src/network/protocols/hide_public_address.cpp index 8bebc6c5a..4a6882a3b 100644 --- a/src/network/protocols/hide_public_address.cpp +++ b/src/network/protocols/hide_public_address.cpp @@ -32,10 +32,6 @@ HidePublicAddress::~HidePublicAddress() { } -void HidePublicAddress::notifyEvent(Event* event) -{ -} - void HidePublicAddress::setup() { m_state = NONE; diff --git a/src/network/protocols/hide_public_address.hpp b/src/network/protocols/hide_public_address.hpp index ed58fbdd1..e91ac3db7 100644 --- a/src/network/protocols/hide_public_address.hpp +++ b/src/network/protocols/hide_public_address.hpp @@ -29,7 +29,8 @@ class HidePublicAddress : public Protocol HidePublicAddress(); virtual ~HidePublicAddress(); - virtual void notifyEvent(Event* event); + virtual bool notifyEvent(Event* event) { return true; } + virtual bool notifyEventAsynchronous(Event* event) { return true; } virtual void setup(); virtual void update() {} virtual void asynchronousUpdate(); diff --git a/src/network/protocols/kart_update_protocol.cpp b/src/network/protocols/kart_update_protocol.cpp index 0652c22c5..f9642fc90 100644 --- a/src/network/protocols/kart_update_protocol.cpp +++ b/src/network/protocols/kart_update_protocol.cpp @@ -28,15 +28,15 @@ KartUpdateProtocol::~KartUpdateProtocol() { } -void KartUpdateProtocol::notifyEvent(Event* event) +bool KartUpdateProtocol::notifyEventAsynchronous(Event* event) { if (event->type != EVENT_TYPE_MESSAGE) - return; - NetworkString ns = event->data; + return true; + NetworkString ns = event->data(); if (ns.size() < 36) { Log::info("KartUpdateProtocol", "Message too short."); - return; + return true; } float game_time = ns.getFloat(0); ns.removeFront(4); @@ -60,6 +60,7 @@ void KartUpdateProtocol::notifyEvent(Event* event) pthread_mutex_unlock(&m_positions_updates_mutex); ns.removeFront(32); } + return true; } void KartUpdateProtocol::setup() diff --git a/src/network/protocols/kart_update_protocol.hpp b/src/network/protocols/kart_update_protocol.hpp index dd24f45a0..fceb22616 100644 --- a/src/network/protocols/kart_update_protocol.hpp +++ b/src/network/protocols/kart_update_protocol.hpp @@ -14,7 +14,7 @@ class KartUpdateProtocol : public Protocol KartUpdateProtocol(); virtual ~KartUpdateProtocol(); - virtual void notifyEvent(Event* event); + virtual bool notifyEventAsynchronous(Event* event); virtual void setup(); virtual void update(); virtual void asynchronousUpdate() {}; diff --git a/src/network/protocols/lobby_room_protocol.hpp b/src/network/protocols/lobby_room_protocol.hpp index f5d10b897..d132359dd 100644 --- a/src/network/protocols/lobby_room_protocol.hpp +++ b/src/network/protocols/lobby_room_protocol.hpp @@ -35,11 +35,10 @@ class LobbyRoomProtocol : public Protocol public: LobbyRoomProtocol(CallbackObject* callback_object); virtual ~LobbyRoomProtocol(); - - virtual void notifyEvent(Event* event) = 0; + virtual void setup() = 0; virtual void update() = 0; - + protected: GameSetup* m_setup; //!< The game setup. }; diff --git a/src/network/protocols/ping_protocol.cpp b/src/network/protocols/ping_protocol.cpp index 4a4c29332..7cfa790bc 100644 --- a/src/network/protocols/ping_protocol.cpp +++ b/src/network/protocols/ping_protocol.cpp @@ -31,10 +31,6 @@ PingProtocol::~PingProtocol() { } -void PingProtocol::notifyEvent(Event* event) -{ -} - void PingProtocol::setup() { m_last_ping_time = 0; diff --git a/src/network/protocols/ping_protocol.hpp b/src/network/protocols/ping_protocol.hpp index 61f35b978..70d2a7662 100644 --- a/src/network/protocols/ping_protocol.hpp +++ b/src/network/protocols/ping_protocol.hpp @@ -10,7 +10,8 @@ class PingProtocol : public Protocol PingProtocol(const TransportAddress& ping_dst, double delay_between_pings); virtual ~PingProtocol(); - virtual void notifyEvent(Event* event); + virtual bool notifyEvent(Event* event) { return true; } + virtual bool notifyEventAsynchronous(Event* event) { return true; } virtual void setup(); virtual void update() {} virtual void asynchronousUpdate(); diff --git a/src/network/protocols/quick_join_protocol.cpp b/src/network/protocols/quick_join_protocol.cpp index 80504b824..d29baf91d 100644 --- a/src/network/protocols/quick_join_protocol.cpp +++ b/src/network/protocols/quick_join_protocol.cpp @@ -33,10 +33,6 @@ QuickJoinProtocol::~QuickJoinProtocol() { } -void QuickJoinProtocol::notifyEvent(Event* event) -{ -} - void QuickJoinProtocol::setup() { m_state = NONE; diff --git a/src/network/protocols/quick_join_protocol.hpp b/src/network/protocols/quick_join_protocol.hpp index 9cefedf32..144e49d20 100644 --- a/src/network/protocols/quick_join_protocol.hpp +++ b/src/network/protocols/quick_join_protocol.hpp @@ -10,7 +10,8 @@ class QuickJoinProtocol : public Protocol QuickJoinProtocol(CallbackObject* callback_object, uint32_t* server_id); virtual ~QuickJoinProtocol(); - virtual void notifyEvent(Event* event); + virtual bool notifyEvent(Event* event) { return true; } + virtual bool notifyEventAsynchronous(Event* event) { return true; } virtual void setup(); virtual void update() {} virtual void asynchronousUpdate(); diff --git a/src/network/protocols/request_connection.cpp b/src/network/protocols/request_connection.cpp index 16a7f8b88..ca5991377 100644 --- a/src/network/protocols/request_connection.cpp +++ b/src/network/protocols/request_connection.cpp @@ -32,10 +32,6 @@ RequestConnection::~RequestConnection() { } -void RequestConnection::notifyEvent(Event* event) -{ -} - void RequestConnection::setup() { m_state = NONE; diff --git a/src/network/protocols/request_connection.hpp b/src/network/protocols/request_connection.hpp index 05527731b..2bffccdd3 100644 --- a/src/network/protocols/request_connection.hpp +++ b/src/network/protocols/request_connection.hpp @@ -10,7 +10,8 @@ class RequestConnection : public Protocol RequestConnection(uint32_t server_id); virtual ~RequestConnection(); - virtual void notifyEvent(Event* event); + virtual bool notifyEvent(Event* event) { return true; } + virtual bool notifyEventAsynchronous(Event* event) { return true; } virtual void setup(); virtual void update() {} virtual void asynchronousUpdate(); diff --git a/src/network/protocols/server_lobby_room_protocol.cpp b/src/network/protocols/server_lobby_room_protocol.cpp index bf5fb9750..b8daeb8cf 100644 --- a/src/network/protocols/server_lobby_room_protocol.cpp +++ b/src/network/protocols/server_lobby_room_protocol.cpp @@ -57,14 +57,15 @@ void ServerLobbyRoomProtocol::setup() //----------------------------------------------------------------------------- -void ServerLobbyRoomProtocol::notifyEvent(Event* event) +bool ServerLobbyRoomProtocol::notifyEventAsynchronous(Event* event) { assert(m_setup); // assert that the setup exists if (event->type == EVENT_TYPE_MESSAGE) { - assert(event->data.size()); // message not empty + NetworkString data = event->data(); + assert(data.size()); // message not empty uint8_t message_type; - message_type = event->data.getAndRemoveUInt8(); + message_type = data.getAndRemoveUInt8(); Log::info("ServerLobbyRoomProtocol", "Message received with type %d.", message_type); if (message_type == 0x01) // player requesting connection connectionRequested(event); @@ -78,6 +79,7 @@ void ServerLobbyRoomProtocol::notifyEvent(Event* event) { kartDisconnected(event); } // if (event->type == EVENT_TYPE_DISCONNECTED) + return true; } //----------------------------------------------------------------------------- @@ -232,13 +234,14 @@ void ServerLobbyRoomProtocol::kartDisconnected(Event* event) void ServerLobbyRoomProtocol::connectionRequested(Event* event) { STKPeer* peer = *(event->peer); - if (event->data.size() != 5 || event->data[0] != 4) + NetworkString data = event->data(); + if (data.size() != 5 || data[0] != 4) { - Log::warn("ServerLobbyRoomProtocol", "The server is sending a badly formated message. Size is %d and first byte %d", event->data.size(), event->data[0]); + Log::warn("ServerLobbyRoomProtocol", "The server is sending a badly formated message. Size is %d and first byte %d", data.size(), data[0]); return; } uint32_t player_id = 0; - player_id = event->data.getUInt32(1); + player_id = data.getUInt32(1); // can we add the player ? if (m_setup->getPlayerCount() < 16) // accept player { @@ -308,23 +311,24 @@ void ServerLobbyRoomProtocol::connectionRequested(Event* event) */ void ServerLobbyRoomProtocol::kartSelectionRequested(Event* event) { - if (event->data.size() < 6 || event->data[0] != 4) + NetworkString data = event->data(); + if (data.size() < 6 || data[0] != 4) { Log::warn("ServerLobbyRoomProtocol", "The server is sending a badly " "formated message. Size is %d and first byte %d", - event->data.size(), event->data[0]); + data.size(), data[0]); return; } STKPeer* peer = *(event->peer); - uint32_t token = event->data.gui32(1); + uint32_t token = data.gui32(1); if (token != peer->getClientServerToken()) { Log::warn("ServerLobbyRoomProtocol", "Peer sending bad token. Request " "aborted."); return; } - uint8_t kart_name_size = event->data.gui8(5); - std::string kart_name = event->data.gs(6, kart_name_size); + uint8_t kart_name_size = data.gui8(5); + std::string kart_name = data.gs(6, kart_name_size); if (kart_name.size() != kart_name_size) { Log::error("ServerLobbyRoomProtocol", "Kart names sizes differ: told:" diff --git a/src/network/protocols/server_lobby_room_protocol.hpp b/src/network/protocols/server_lobby_room_protocol.hpp index d4a2516ab..bbe9a5d2f 100644 --- a/src/network/protocols/server_lobby_room_protocol.hpp +++ b/src/network/protocols/server_lobby_room_protocol.hpp @@ -9,7 +9,7 @@ class ServerLobbyRoomProtocol : public LobbyRoomProtocol ServerLobbyRoomProtocol(); virtual ~ServerLobbyRoomProtocol(); - virtual void notifyEvent(Event* event); + virtual bool notifyEventAsynchronous(Event* event); virtual void setup(); virtual void update(); virtual void asynchronousUpdate() {}; diff --git a/src/network/protocols/show_public_address.cpp b/src/network/protocols/show_public_address.cpp index f9ce19071..9d56fc7d6 100644 --- a/src/network/protocols/show_public_address.cpp +++ b/src/network/protocols/show_public_address.cpp @@ -32,10 +32,6 @@ ShowPublicAddress::~ShowPublicAddress() { } -void ShowPublicAddress::notifyEvent(Event* event) -{ -} - void ShowPublicAddress::setup() { m_state = NONE; diff --git a/src/network/protocols/show_public_address.hpp b/src/network/protocols/show_public_address.hpp index 1e069f79f..fb84f8477 100644 --- a/src/network/protocols/show_public_address.hpp +++ b/src/network/protocols/show_public_address.hpp @@ -29,7 +29,8 @@ class ShowPublicAddress : public Protocol ShowPublicAddress(); virtual ~ShowPublicAddress(); - virtual void notifyEvent(Event* event); + virtual bool notifyEvent(Event* event) { return true; } + virtual bool notifyEventAsynchronous(Event* event) { return true; } virtual void setup(); virtual void update() {} virtual void asynchronousUpdate(); diff --git a/src/network/protocols/start_game_protocol.cpp b/src/network/protocols/start_game_protocol.cpp index 10fec94ff..09309a847 100644 --- a/src/network/protocols/start_game_protocol.cpp +++ b/src/network/protocols/start_game_protocol.cpp @@ -32,20 +32,21 @@ StartGameProtocol::~StartGameProtocol() { } -void StartGameProtocol::notifyEvent(Event* event) +bool StartGameProtocol::notifyEventAsynchronous(Event* event) { - if (event->data.size() < 5) + NetworkString data = event->data(); + if (data.size() < 5) { Log::error("StartGameProtocol", "Too short message."); - return; + return true; } - uint32_t token = event->data.gui32(); - uint8_t ready = event->data.gui8(4); + uint32_t token = data.gui32(); + uint8_t ready = data.gui8(4); STKPeer* peer = (*(event->peer)); if (peer->getClientServerToken() != token) { Log::error("StartGameProtocol", "Bad token received."); - return; + return true; } if (m_listener->isServer() && ready) // on server, player is ready { @@ -61,17 +62,17 @@ void StartGameProtocol::notifyEvent(Event* event) protocol->startCountdown(5000); // 5 seconds countdown Log::info("StartGameProtocol", "All players ready, starting countdown."); m_ready = true; - return; + return true; } else Log::error("StartGameProtocol", "The Synchronization protocol hasn't been started."); } } - else + else // on the client, we shouldn't even receive messages. { Log::error("StartGameProtocol", "Received a message with bad format."); } - // on the client, we shouldn't even receive messages. + return true; } void StartGameProtocol::setup() diff --git a/src/network/protocols/start_game_protocol.hpp b/src/network/protocols/start_game_protocol.hpp index 23d7fcbc1..f58f71aae 100644 --- a/src/network/protocols/start_game_protocol.hpp +++ b/src/network/protocols/start_game_protocol.hpp @@ -24,7 +24,7 @@ class StartGameProtocol : public Protocol StartGameProtocol(GameSetup* game_setup); virtual ~StartGameProtocol(); - virtual void notifyEvent(Event* event); + virtual bool notifyEventAsynchronous(Event* event); virtual void setup(); virtual void update(); virtual void asynchronousUpdate() {} diff --git a/src/network/protocols/start_server.cpp b/src/network/protocols/start_server.cpp index 8afec9a6d..cc992329b 100644 --- a/src/network/protocols/start_server.cpp +++ b/src/network/protocols/start_server.cpp @@ -31,10 +31,6 @@ StartServer::~StartServer() { } -void StartServer::notifyEvent(Event* event) -{ -} - void StartServer::setup() { m_state = NONE; diff --git a/src/network/protocols/start_server.hpp b/src/network/protocols/start_server.hpp index c56d8352c..5fce8a458 100644 --- a/src/network/protocols/start_server.hpp +++ b/src/network/protocols/start_server.hpp @@ -14,7 +14,8 @@ class StartServer : public Protocol StartServer(); virtual ~StartServer(); - virtual void notifyEvent(Event* event); + virtual bool notifyEvent(Event* event) { return true; } + virtual bool notifyEventAsynchronous(Event* event) { return true; } virtual void setup(); virtual void update() {} virtual void asynchronousUpdate(); diff --git a/src/network/protocols/stop_server.cpp b/src/network/protocols/stop_server.cpp index 187104d8b..97698e0cf 100644 --- a/src/network/protocols/stop_server.cpp +++ b/src/network/protocols/stop_server.cpp @@ -31,8 +31,9 @@ StopServer::~StopServer() { } -void StopServer::notifyEvent(Event* event) +bool StopServer::notifyEventAsynchronous(Event* event) { + return true; } void StopServer::setup() diff --git a/src/network/protocols/stop_server.hpp b/src/network/protocols/stop_server.hpp index 7ad35723c..5b5c7a553 100644 --- a/src/network/protocols/stop_server.hpp +++ b/src/network/protocols/stop_server.hpp @@ -13,7 +13,7 @@ class StopServer : public Protocol StopServer(); virtual ~StopServer(); - virtual void notifyEvent(Event* event); + virtual bool notifyEventAsynchronous(Event* event); virtual void setup(); virtual void update() {} virtual void asynchronousUpdate(); diff --git a/src/network/protocols/synchronization_protocol.cpp b/src/network/protocols/synchronization_protocol.cpp index f9f4c626c..ec33ef5ed 100644 --- a/src/network/protocols/synchronization_protocol.cpp +++ b/src/network/protocols/synchronization_protocol.cpp @@ -30,19 +30,20 @@ SynchronizationProtocol::~SynchronizationProtocol() //----------------------------------------------------------------------------- -void SynchronizationProtocol::notifyEvent(Event* event) +bool SynchronizationProtocol::notifyEventAsynchronous(Event* event) { if (event->type != EVENT_TYPE_MESSAGE) - return; - if (event->data.size() < 10) + return true; + NetworkString data = event->data(); + if (data.size() < 10) { Log::warn("SynchronizationProtocol", "Received a message too short."); - return; + return true; } - uint8_t talk_id = event->data.gui8(); - uint32_t token = event->data.gui32(1); - uint32_t request = event->data.gui8(5); - uint32_t sequence = event->data.gui32(6); + uint8_t talk_id = data.gui8(); + uint32_t token = data.gui32(1); + uint32_t request = data.gui8(5); + uint32_t sequence = data.gui32(6); std::vector peers = NetworkManager::getInstance()->getPeers(); @@ -51,7 +52,7 @@ void SynchronizationProtocol::notifyEvent(Event* event) if (talk_id > peers.size()) { Log::warn("SynchronizationProtocol", "The ID isn't known."); - return; + return true; } } @@ -66,18 +67,18 @@ void SynchronizationProtocol::notifyEvent(Event* event) if (peers[peer_id]->getClientServerToken() != token) { Log::warn("SynchronizationProtocol", "Bad token from peer %d", talk_id); - return; + return true; } if (request) { NetworkString response; - response.ai8(event->data.gui8(talk_id)).ai32(token).ai8(0).ai32(sequence); + response.ai8(data.gui8(talk_id)).ai32(token).ai8(0).ai32(sequence); m_listener->sendMessage(this, peers[peer_id], response, false); Log::verbose("SynchronizationProtocol", "Answering sequence %u", sequence); - if (event->data.size() == 14 && !m_listener->isServer()) // countdown time in the message + if (data.size() == 14 && !m_listener->isServer()) // countdown time in the message { - uint32_t time_to_start = event->data.gui32(10); + uint32_t time_to_start = data.gui32(10); Log::debug("SynchronizationProtocol", "Request to start game in %d.", time_to_start); if (!m_countdown_activated) startCountdown(time_to_start); @@ -92,7 +93,7 @@ void SynchronizationProtocol::notifyEvent(Event* event) if (sequence >= m_pings[peer_id].size()) { Log::warn("SynchronizationProtocol", "The sequence# %u isn't known.", sequence); - return; + return true; } double current_time = Time::getRealTime(); m_total_diff[peer_id] += current_time - m_pings[peer_id][sequence]; @@ -103,6 +104,7 @@ void SynchronizationProtocol::notifyEvent(Event* event) Log::debug("SynchronizationProtocol", "Ping is %u", m_average_ping[peer_id]); } + return true; } //----------------------------------------------------------------------------- diff --git a/src/network/protocols/synchronization_protocol.hpp b/src/network/protocols/synchronization_protocol.hpp index 53fe36ca5..c04afb829 100644 --- a/src/network/protocols/synchronization_protocol.hpp +++ b/src/network/protocols/synchronization_protocol.hpp @@ -11,7 +11,7 @@ class SynchronizationProtocol : public Protocol SynchronizationProtocol(); virtual ~SynchronizationProtocol(); - virtual void notifyEvent(Event* event); + virtual bool notifyEventAsynchronous(Event* event); virtual void setup(); virtual void update() {} virtual void asynchronousUpdate(); diff --git a/src/network/stk_host.cpp b/src/network/stk_host.cpp index 6012881eb..6244ada2c 100644 --- a/src/network/stk_host.cpp +++ b/src/network/stk_host.cpp @@ -161,7 +161,7 @@ uint8_t* STKHost::receiveRawPacket() { i++; len = recv(m_host->socket,(char*)buffer,2048, 0); - irr_driver->getDevice()->sleep(1); + usleep(1000); } return buffer; } @@ -190,7 +190,7 @@ uint8_t* STKHost::receiveRawPacket(TransportAddress sender) { i++; len = recvfrom(m_host->socket, (char*)buffer, 2048, 0, &addr, &from_len); - irr_driver->getDevice()->sleep(1); // wait 1 millisecond between two checks + usleep(1000); // wait 1 millisecond between two checks } if (addr.sa_family == AF_INET) { diff --git a/src/states_screens/kart_selection.cpp b/src/states_screens/kart_selection.cpp index 96b9fb194..ca496208c 100644 --- a/src/states_screens/kart_selection.cpp +++ b/src/states_screens/kart_selection.cpp @@ -38,6 +38,7 @@ #include "karts/kart_properties.hpp" #include "karts/kart_properties_manager.hpp" #include "modes/overworld.hpp" +#include "online/user.hpp" #include "states_screens/race_setup_screen.hpp" #include "states_screens/state_manager.hpp" #include "utils/translation.hpp" @@ -182,17 +183,20 @@ void PlayerNameSpinner::markAsCorrect() PlayerKartWidget::PlayerKartWidget(KartSelectionScreen* parent, StateManager::ActivePlayer* associatedPlayer, + Online::User* associatedUser, core::recti area, const int playerID, std::string kartGroup, const int irrlichtWidgetID) : Widget(WTYPE_DIV) { #ifdef DEBUG - assert(associatedPlayer->ok()); + if (associatedPlayer) + assert(associatedPlayer->ok()); m_magic_number = 0x33445566; #endif m_ready_text = NULL; m_parent_screen = parent; + m_associated_user = associatedUser; m_associatedPlayer = associatedPlayer; x_speed = 1.0f; y_speed = 1.0f; @@ -214,13 +218,15 @@ PlayerKartWidget::PlayerKartWidget(KartSelectionScreen* parent, target_h = m_h; // ---- Player identity spinner + m_player_ident_spinner = NULL; + m_player_ident_spinner = new PlayerNameSpinner(parent, m_playerID); m_player_ident_spinner->m_x = player_name_x; m_player_ident_spinner->m_y = player_name_y; m_player_ident_spinner->m_w = player_name_w; m_player_ident_spinner->m_h = player_name_h; - if (parent->m_multiplayer) + if (parent->m_multiplayer && associatedPlayer) { if (associatedPlayer->getDevice()->getType() == DT_KEYBOARD) { @@ -231,6 +237,10 @@ PlayerKartWidget::PlayerKartWidget(KartSelectionScreen* parent, m_player_ident_spinner->setBadge(GAMEPAD_BADGE); } } + else if (m_associated_user) // online user, FIXME is that useful ? + { + m_player_ident_spinner->setBadge(OK_BADGE); + } if (irrlichtWidgetID == -1) { @@ -415,18 +425,21 @@ void PlayerKartWidget::add() assert(KartSelectionScreen::getRunningInstance() ->m_kart_widgets.contains(this)); - bool mineInList = false; - for (int p=0; pactivePlayerCount(); p++) + if (m_associatedPlayer) // if player is local { -#ifdef DEBUG - assert(StateManager::get()->getActivePlayer(p)->ok()); -#endif - if (StateManager::get()->getActivePlayer(p) == m_associatedPlayer) + bool mineInList = false; + for (int p=0; pactivePlayerCount(); p++) { - mineInList = true; +#ifdef DEBUG + assert(StateManager::get()->getActivePlayer(p)->ok()); +#endif + if (StateManager::get()->getActivePlayer(p) == m_associatedPlayer) + { + mineInList = true; + } } + assert(mineInList); } - assert(mineInList); //m_player_ID_label->add(); @@ -447,6 +460,13 @@ void PlayerKartWidget::add() m_model_view->update(0); m_player_ident_spinner->clearLabels(); + + irr::core::stringw name; // name of the player + if (m_associatedPlayer) + name = m_associatedPlayer->getProfile()->getName(); + if (m_associated_user) + name = m_associated_user->getUserName(); + if (m_parent_screen->m_multiplayer) { const int playerAmount = UserConfigParams::m_all_players.size(); @@ -457,17 +477,15 @@ void PlayerKartWidget::add() } // select the right player profile in the spinner - m_player_ident_spinner->setValue(m_associatedPlayer->getProfile() - ->getName() ); + m_player_ident_spinner->setValue(name); } else { - m_player_ident_spinner->addLabel( m_associatedPlayer->getProfile()->getName() ); + m_player_ident_spinner->addLabel(name); m_player_ident_spinner->setVisible(false); } - assert(m_player_ident_spinner->getStringValue() == - m_associatedPlayer->getProfile()->getName()); + assert(m_player_ident_spinner->getStringValue() == name); } // add // ------------------------------------------------------------------------ @@ -1179,7 +1197,7 @@ bool KartSelectionScreen::playerJoin(InputDevice* device, bool firstPlayer) // ---- Create player/kart widget PlayerKartWidget* newPlayerWidget = - new PlayerKartWidget(this, aplayer, kartsArea, m_kart_widgets.size(), + new PlayerKartWidget(this, aplayer, NULL, kartsArea, m_kart_widgets.size(), selected_kart_group); manualAddWidget(newPlayerWidget); diff --git a/src/states_screens/kart_selection.hpp b/src/states_screens/kart_selection.hpp index d350fa224..4a363ecac 100644 --- a/src/states_screens/kart_selection.hpp +++ b/src/states_screens/kart_selection.hpp @@ -34,6 +34,10 @@ namespace GUIEngine class BubbleWidget; enum EventPropagation; } +namespace Online +{ + class User; +} class InputDevice; class PlayerKartWidget; class KartHoverListener; @@ -234,8 +238,9 @@ class PlayerKartWidget : public GUIEngine::Widget, float x_speed, y_speed, w_speed, h_speed; /** Object representing this player */ - StateManager::ActivePlayer* m_associatedPlayer; + StateManager::ActivePlayer* m_associatedPlayer; // local info int m_playerID; + Online::User* m_associated_user; // network info /** Internal name of the spinner; useful to interpret spinner events, * which contain the name of the activated object */ @@ -267,6 +272,7 @@ public: PlayerKartWidget(KartSelectionScreen* parent, StateManager::ActivePlayer* associatedPlayer, + Online::User* associatedUser, core::recti area, const int playerID, std::string kartGroup, const int irrlichtWidgetID=-1); diff --git a/src/states_screens/network_kart_selection.cpp b/src/states_screens/network_kart_selection.cpp index f0fd79f25..3aad251f5 100644 --- a/src/states_screens/network_kart_selection.cpp +++ b/src/states_screens/network_kart_selection.cpp @@ -1,11 +1,19 @@ #include "states_screens/network_kart_selection.hpp" +#include "audio/sfx_manager.hpp" +#include "challenges/unlock_manager.hpp" +#include "items/item_manager.hpp" +#include "karts/kart_properties.hpp" +#include "karts/kart_properties_manager.hpp" #include "network/protocol_manager.hpp" #include "network/protocols/client_lobby_room_protocol.hpp" #include "network/network_manager.hpp" #include "online/current_user.hpp" #include "states_screens/state_manager.hpp" +static const char RANDOM_KART_ID[] = "randomkart"; +static const char ID_LOCKED[] = "locked/"; + using namespace GUIEngine; DEFINE_SCREEN_SINGLETON( NetworkKartSelectionScreen ); @@ -26,8 +34,9 @@ void NetworkKartSelectionScreen::init() RibbonWidget* tabs = getWidget("kartgroups"); assert( tabs != NULL ); - tabs->setVisible(false); tabs->select( "standard", PLAYER_ID_GAME_MASTER); // select standard kart group + tabs->setDeactivated(); + tabs->setVisible(false); // change the back button image (because it makes the game quit) IconButtonWidget* back_button = getWidget("back"); @@ -44,7 +53,7 @@ void NetworkKartSelectionScreen::init() } std::vector players = setup->getPlayers(); - + Log::info("NKSS", "There are %d players", players.size()); // ---- Get available area for karts // make a copy of the area, ands move it to be outside the screen Widget* kartsAreaWidget = getWidget("playerskarts"); @@ -58,16 +67,21 @@ void NetworkKartSelectionScreen::init() for (unsigned int i = 0; i < players.size(); i++) { if (players[i]->user_profile == Online::CurrentUser::get()) - return; // it is me, don't add again + { + m_id_mapping.insert(m_id_mapping.begin(),players[i]->race_id); //!< first kart widget always me + Log::info("NKSS", "Insert %d at pos 0", players[i]->race_id); + continue; // it is me, don't add again + } + Log::info("NKSS", "Adding %d at pos %d", players[i]->race_id, i); + m_id_mapping.push_back(players[i]->race_id); - StateManager::ActivePlayer* aplayer = - StateManager::get()->getActivePlayer(players[i]->race_id); + StateManager::ActivePlayer* aplayer = NULL; // player is remote std::string selected_kart_group = "standard"; // standard group PlayerKartWidget* newPlayerWidget = - new PlayerKartWidget(this, aplayer, kartsArea, m_kart_widgets.size(), + new PlayerKartWidget(this, aplayer, players[i]->user_profile, kartsArea, m_kart_widgets.size(), selected_kart_group); manualAddWidget(newPlayerWidget); @@ -91,8 +105,102 @@ void NetworkKartSelectionScreen::init() void NetworkKartSelectionScreen::playerConfirm(const int playerID) { + DynamicRibbonWidget* w = getWidget("karts"); + assert(w != NULL); + const std::string selection = w->getSelectionIDString(playerID); + if (StringUtils::startsWith(selection, ID_LOCKED)) + { + unlock_manager->playLockSound(); + return; + } + + if (playerID == PLAYER_ID_GAME_MASTER) + { + UserConfigParams::m_default_kart = selection; + } + + if (m_kart_widgets[playerID].getKartInternalName().size() == 0) + { + sfx_manager->quickSound( "anvil" ); + return; + } + if(playerID == PLAYER_ID_GAME_MASTER) // self + { + ClientLobbyRoomProtocol* protocol = static_cast( + ProtocolManager::getInstance()->getProtocol(PROTOCOL_LOBBY_ROOM)); + protocol->requestKartSelection(selection); + } } +void NetworkKartSelectionScreen::considerKartHovered(uint8_t widget_id, std::string selection) +{ + ModelViewWidget* w3 = m_kart_widgets[widget_id].m_model_view; + assert( w3 != NULL ); + + if (selection == RANDOM_KART_ID) + { + // Random kart + scene::IMesh* model = + ItemManager::getItemModel(Item::ITEM_BONUS_BOX); + w3->clearModels(); + w3->addModel( model, Vec3(0.0f, -12.0f, 0.0f), + Vec3(35.0f, 35.0f, 35.0f) ); + w3->update(0); + m_kart_widgets[widget_id].m_kart_name->setText( + _("Random Kart"), false ); + } + else + { + const KartProperties *kp = + kart_properties_manager->getKart(selection); + if (kp != NULL) + { + const KartModel &kart_model = kp->getMasterKartModel(); + + //w3->clearModels(); + w3->addModel( kart_model.getModel(), Vec3(0,0,0), + Vec3(35.0f, 35.0f, 35.0f), + kart_model.getBaseFrame() ); + w3->addModel( kart_model.getWheelModel(0), + kart_model.getWheelGraphicsPosition(0) ); + w3->addModel( kart_model.getWheelModel(1), + kart_model.getWheelGraphicsPosition(1) ); + w3->addModel( kart_model.getWheelModel(2), + kart_model.getWheelGraphicsPosition(2) ); + w3->addModel( kart_model.getWheelModel(3), + kart_model.getWheelGraphicsPosition(3) ); + w3->update(0); + + m_kart_widgets[widget_id].m_kart_name->setText( + selection.c_str(), false ); + } + else + { + fprintf(stderr, "[KartSelectionScreen] WARNING: could not " + "find a kart named '%s'\n", + selection.c_str()); + } + } +} + +void NetworkKartSelectionScreen::playerSelected(uint8_t race_id, std::string kart_name) +{ + uint8_t widget_id = -1; + for (unsigned int i = 0; i < m_id_mapping.size(); i++) + { + Log::info("NKSS", "Checking race id %d : mapped of %d is %d", race_id, i, m_id_mapping[i]); + if (m_id_mapping[i] == race_id) + widget_id = i; + } + + assert(widget_id>=0 && widget_id < m_kart_widgets.size()); + + considerKartHovered(widget_id,kart_name); + m_kart_widgets[widget_id].setKartInternalName(kart_name); + m_kart_widgets[widget_id].markAsReady(); // mark player ready +} + + /** * Callback handling events from the kart selection menu */ @@ -101,7 +209,7 @@ void NetworkKartSelectionScreen::eventCallback(GUIEngine::Widget* widget, const { if (name == "karts") { - + KartSelectionScreen::eventCallback(widget, name, playerID); } else if (name == "back") { diff --git a/src/states_screens/network_kart_selection.hpp b/src/states_screens/network_kart_selection.hpp index fbcc82423..524fb433c 100644 --- a/src/states_screens/network_kart_selection.hpp +++ b/src/states_screens/network_kart_selection.hpp @@ -8,16 +8,22 @@ class NetworkKartSelectionScreen : public KartSelectionScreen, public GUIEngine: { friend class GUIEngine::ScreenSingleton; protected: + //!< map the id of the kart widgets to race ids + std::vector m_id_mapping; + NetworkKartSelectionScreen(); virtual ~NetworkKartSelectionScreen(); virtual void playerConfirm(const int playerID); + void considerKartHovered(uint8_t widget_id, std::string selection); public: virtual void init() OVERRIDE; virtual void eventCallback(GUIEngine::Widget* widget, const std::string& name, const int playerID) OVERRIDE; virtual bool onEscapePressed() OVERRIDE; + + virtual void playerSelected(uint8_t race_id, std::string kart_name); }; #endif // NETWORK_KART_SELECTION_HPP