diff --git a/doc/protocols.xls b/doc/protocols.xls index c4374fe63..39be981d5 100644 Binary files a/doc/protocols.xls and b/doc/protocols.xls differ diff --git a/src/network/client_network_manager.cpp b/src/network/client_network_manager.cpp index 2848e7e94..b0ab35946 100644 --- a/src/network/client_network_manager.cpp +++ b/src/network/client_network_manager.cpp @@ -23,6 +23,7 @@ #include "network/protocols/show_public_address.hpp" #include "network/protocols/get_peer_address.hpp" #include "network/protocols/connect_to_server.hpp" +#include "network/protocols/client_lobby_room_protocol.hpp" #include "utils/log.hpp" @@ -35,7 +36,7 @@ void* waitInput(void* data) std::string str = ""; bool stop = false; int n = 0; - + while(!stop) { getline(std::cin, str); @@ -55,7 +56,15 @@ void* waitInput(void* data) { ProtocolManager::getInstance()->requestStart(new ConnectToServer(n)); } - else + else if (str == "select") + { + std::string str2; + getline(std::cin, str2); + Protocol* protocol = ProtocolManager::getInstance()->getProtocol(PROTOCOL_LOBBY_ROOM); + ClientLobbyRoomProtocol* clrp = static_cast(protocol); + clrp->requestKartSelection(str2); + } + else { NetworkString msg; msg.ai8(0); @@ -65,7 +74,7 @@ void* waitInput(void* data) } exit(0); - + return NULL; } @@ -79,9 +88,9 @@ ClientNetworkManager::~ClientNetworkManager() { } -void ClientNetworkManager::run() +void ClientNetworkManager::run() { - if (enet_initialize() != 0) + if (enet_initialize() != 0) { Log::error("ClientNetworkManager", "Could not initialize enet.\n"); return; @@ -89,11 +98,11 @@ void ClientNetworkManager::run() m_localhost = new STKHost(); m_localhost->setupClient(1, 2, 0, 0); m_localhost->startListening(); - + // listen keyboard console input m_thread_keyboard = (pthread_t*)(malloc(sizeof(pthread_t))); pthread_create(m_thread_keyboard, NULL, waitInput, NULL); - + NetworkManager::run(); } diff --git a/src/network/event.cpp b/src/network/event.cpp index 5ca437dcf..8328f0e2f 100644 --- a/src/network/event.cpp +++ b/src/network/event.cpp @@ -47,11 +47,11 @@ Event::Event(ENetEvent* event) else if (event->data) { } - + m_packet = NULL; if (event->packet) m_packet = event->packet; - + if (m_packet) enet_packet_destroy(m_packet); // we got all we need, just remove the data. @@ -73,7 +73,16 @@ Event::Event(ENetEvent* event) Log::verbose("Event", "Creating a new peer, address are STKPeer:%ld, Peer:%ld", (long int)(new_peer), (long int)(event->peer)); } } - + +Event::Event(const Event& event) +{ + m_packet = NULL; + data = event.data; + // copy the peer + peer = new STKPeer(*event.peer); + type = event.type; +} + Event::~Event() { } diff --git a/src/network/event.hpp b/src/network/event.hpp index b9eaa5ed9..8ec8083df 100644 --- a/src/network/event.hpp +++ b/src/network/event.hpp @@ -37,7 +37,7 @@ enum EVENT_TYPE /*! * \class Event * \brief Class representing an event that need to pass trough the system. - * This is used to remove ENet dependency in the network. + * This is used to remove ENet dependency in the network. * It interfaces the ENetEvent structure. * The user has to be extremely careful about the peer. * Indeed, when packets are logged, the state of the peer cannot be stored at @@ -51,20 +51,24 @@ class Event * \param event : The event that needs to be translated. */ Event(ENetEvent* event); + /*! \brief Constructor + * \param event : The event to copy. + */ + Event(const Event& event); /*! \brief Destructor * frees the memory of the ENetPacket. */ ~Event(); - + /*! \brief Remove bytes at the beginning of data. * \param size : The number of bytes to remove. */ void removeFront(int size); - + 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: 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 83a3e31b7..9a19ab0db 100644 --- a/src/network/game_setup.cpp +++ b/src/network/game_setup.cpp @@ -34,19 +34,20 @@ GameSetup::~GameSetup() //----------------------------------------------------------------------------- -void GameSetup::addPlayer(NetworkPlayerProfile profile) +void GameSetup::addPlayer(NetworkPlayerProfile* profile) { m_players.push_back(profile); } //----------------------------------------------------------------------------- - + bool 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) { + delete m_players[i]; m_players.erase(m_players.begin()+i, m_players.begin()+i+1); Log::verbose("GameSetup", "Removed a player from the game setup."); return true; @@ -56,12 +57,12 @@ bool GameSetup::removePlayer(uint32_t id) } //----------------------------------------------------------------------------- - + bool GameSetup::removePlayer(uint8_t id) { for (unsigned int i = 0; i < m_players.size(); i++) { - if (m_players[i].race_id == id) // check the given id + if (m_players[i]->race_id == id) // check the given id { m_players.erase(m_players.begin()+i, m_players.begin()+i+1); Log::verbose("GameSetup", "Removed a player from the game setup."); @@ -72,28 +73,42 @@ bool GameSetup::removePlayer(uint8_t id) } //----------------------------------------------------------------------------- - + +void GameSetup::setPlayerKart(uint8_t id, std::string kart_name) +{ + for (unsigned int i = 0; i < m_players.size(); i++) + { + if (m_players[i]->race_id == id) + { + m_players[i]->kart_name = kart_name; + Log::info("GameSetup", "Player %d took kart %s", id, kart_name.c_str()); + } + } +} + +//----------------------------------------------------------------------------- + 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 m_players[i]; } } return NULL; } //----------------------------------------------------------------------------- - + const NetworkPlayerProfile* GameSetup::getProfile(uint8_t id) { for (unsigned int i = 0; i < m_players.size(); i++) { - if (m_players[i].race_id == id) + if (m_players[i]->race_id == id) { - return &m_players[i]; + return m_players[i]; } } return NULL; @@ -105,7 +120,7 @@ bool GameSetup::isKartAvailable(std::string kart_name) { for (unsigned int i = 0; i < m_players.size(); i++) { - if (m_players[i].kart_name == kart_name) + if (m_players[i]->kart_name == kart_name) return false; } return true; diff --git a/src/network/game_setup.hpp b/src/network/game_setup.hpp index 93cc0918c..aa3ea34a4 100644 --- a/src/network/game_setup.hpp +++ b/src/network/game_setup.hpp @@ -28,14 +28,14 @@ #include /*! \class PlayerProfile - * \brief Contains the profile of a player. + * \brief Contains the profile of a player. */ -class NetworkPlayerProfile +class NetworkPlayerProfile { public: 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 @@ -50,19 +50,22 @@ class GameSetup public: GameSetup(); virtual ~GameSetup(); - + void addPlayer(NetworkPlayerProfile profile); //!< Add a player. + void addPlayer(NetworkPlayerProfile* profile); //!< Add a player. bool removePlayer(uint32_t id); //!< Remove a player by id. bool removePlayer(uint8_t id); //!< Remove a player by local id. - + void setPlayerKart(uint8_t id, std::string kart_name); //!< Set the kart of a player + int getPlayerCount() { return m_players.size(); } 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 - + bool isKartAvailable(std::string kart_name); - + bool isKartAllowed(std::string kart_name) {return true; } + protected: - std::vector m_players; //!< Information about players + std::vector m_players; //!< Information about players NetworkPlayerProfile m_self_profile; //!< Information about self (client only) }; diff --git a/src/network/network_manager.cpp b/src/network/network_manager.cpp index 874c3193e..f19d8ce55 100644 --- a/src/network/network_manager.cpp +++ b/src/network/network_manager.cpp @@ -43,12 +43,12 @@ NetworkManager::NetworkManager() //----------------------------------------------------------------------------- -NetworkManager::~NetworkManager() +NetworkManager::~NetworkManager() { ProtocolManager::kill(); - + if (m_localhost) - delete m_localhost; + delete m_localhost; while(!m_peers.empty()) { delete m_peers.back(); @@ -59,7 +59,7 @@ NetworkManager::~NetworkManager() //----------------------------------------------------------------------------- void NetworkManager::run() -{ +{ // create the protocol manager ProtocolManager::getInstance(); } @@ -70,7 +70,7 @@ bool NetworkManager::connect(TransportAddress peer) { if (peerExists(peer)) return isConnectedTo(peer); - + return STKPeer::connectToHost(m_localhost, peer, 2, 0); } @@ -89,54 +89,55 @@ void NetworkManager::setManualSocketsMode(bool manual) void NetworkManager::notifyEvent(Event* event) { Log::info("NetworkManager", "EVENT received of type %d", (int)(event->type)); - switch (event->type) + + if (event->type == EVENT_TYPE_CONNECTED) { - case EVENT_TYPE_CONNECTED: - Log::debug("NetworkManager", "A client has just connected. There are now %lu peers.", m_peers.size() + 1); - Log::verbose("NetworkManager", "Address of event->peer after connection : %ld", (long int)(event->peer)); - // create the new peer: - m_peers.push_back(event->peer); - break; - case EVENT_TYPE_DISCONNECTED: - { - Log::debug("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: - bool removed = false; - for (unsigned int i = 0; i < m_peers.size(); i++) - { - Log::error("NetworkManager", "Saved : %ld, Sender : %ld", (long int)(m_peers[i]), (long int)(event->peer)); - if (m_peers[i] == event->peer && !removed) // remove only one - { - delete m_peers[i]; - m_peers.erase(m_peers.begin()+i, m_peers.begin()+i+1); - Log::verbose("NetworkManager", "The peer has been removed from the Network Manager."); - removed = true; - } - else if (m_peers[i] == event->peer) - { - Log::fatal("NetworkManager", "Multiple peers match the disconnected one."); - } - } - if (!removed) - Log::warn("NetworkManager", "The peer that has been disconnected was not registered by the Network Manager."); - - Log::debug("NetworkManager", "Somebody is now disconnected. There are now %lu peers.", m_peers.size()); - - - } break; - case EVENT_TYPE_MESSAGE: - { - //exit(0); - uint32_t addr = event->peer->getAddress(); - Log::info("NetworkManager", "Message, Sender : %i.%i.%i.%i, message = \"%s\"", - ((addr>>24)&0xff), - ((addr>>16)&0xff), - ((addr>>8)&0xff), - (addr&0xff), event->data.c_str()); - - } break; + Log::debug("NetworkManager", "A client has just connected. There are now %lu peers.", m_peers.size() + 1); + Log::verbose("NetworkManager", "Address of event->peer after connection : %ld", (long int)(event->peer)); + // create the new peer: + m_peers.push_back(event->peer); } + if (event->type == EVENT_TYPE_MESSAGE) + { + uint32_t addr = event->peer->getAddress(); + Log::info("NetworkManager", "Message, Sender : %i.%i.%i.%i, message = \"%s\"", + ((addr>>24)&0xff), + ((addr>>16)&0xff), + ((addr>>8)&0xff), + (addr&0xff), event->data.c_str()); + + } + + // notify for the event now. ProtocolManager::getInstance()->notifyEvent(event); + + if (event->type == EVENT_TYPE_DISCONNECTED) + { + Log::debug("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: + bool removed = false; + for (unsigned int i = 0; i < m_peers.size(); i++) + { + Log::error("NetworkManager", "Saved : %ld, Sender : %ld", (long int)(m_peers[i]), (long int)(event->peer)); + if (m_peers[i] == event->peer && !removed) // remove only one + { + delete m_peers[i]; + m_peers.erase(m_peers.begin()+i, m_peers.begin()+i+1); + Log::verbose("NetworkManager", "The peer has been removed from the Network Manager."); + removed = true; + } + else if (m_peers[i] == event->peer) + { + Log::fatal("NetworkManager", "Multiple peers match the disconnected one."); + } + } + if (!removed) + Log::warn("NetworkManager", "The peer that has been disconnected was not registered by the Network Manager."); + + Log::debug("NetworkManager", "Somebody is now disconnected. There are now %lu peers.", m_peers.size()); + } + + delete event; } //----------------------------------------------------------------------------- diff --git a/src/network/network_string.hpp b/src/network/network_string.hpp index 30473c070..6f2c36b70 100644 --- a/src/network/network_string.hpp +++ b/src/network/network_string.hpp @@ -141,6 +141,7 @@ class NetworkString inline uint8_t getUInt8(int pos = 0) { return get(pos); } inline char getChar(int pos = 0) { return get(pos); } inline unsigned char getUChar(int pos = 0) { return get(pos); } + std::string getString(int pos = 0) { return std::string(m_string.c_str()+pos); } inline int gi(int pos = 0) { return get(pos); } inline uint32_t gui(int pos = 0) { return get(pos); } @@ -149,6 +150,7 @@ class NetworkString inline uint8_t gui8(int pos = 0) { return get(pos); } inline char gc(int pos = 0) { return get(pos); } inline unsigned char guc(int pos = 0) { return get(pos); } + std::string gs(int pos = 0) { return std::string(m_string.c_str()+pos); } double getDouble(int pos = 0) //!< BEWARE OF PRECISION { diff --git a/src/network/protocol.cpp b/src/network/protocol.cpp index 7154c1014..e4a34f310 100644 --- a/src/network/protocol.cpp +++ b/src/network/protocol.cpp @@ -18,6 +18,8 @@ #include "network/protocol.hpp" +#include "network/protocol_manager.hpp" + Protocol::Protocol(CallbackObject* callback_object, PROTOCOL_TYPE type) { m_callback_object = callback_object; @@ -43,7 +45,7 @@ void Protocol::kill() void Protocol::setListener(ProtocolManager* listener) { - m_listener = listener; + m_listener = listener; } PROTOCOL_TYPE Protocol::getProtocolType() diff --git a/src/network/protocol.hpp b/src/network/protocol.hpp index a0d727c1c..2c0d0298e 100644 --- a/src/network/protocol.hpp +++ b/src/network/protocol.hpp @@ -19,10 +19,12 @@ #ifndef PROTOCOL_HPP #define PROTOCOL_HPP -#include "network/protocol_manager.hpp" +#include "network/event.hpp" #include "network/types.hpp" #include "utils/types.hpp" +class ProtocolManager; + /** \enum PROTOCOL_TYPE * \brief The types that protocols can have. This is used to select which protocol receives which event. * \ingroup network @@ -36,7 +38,7 @@ enum PROTOCOL_TYPE }; /** \class Protocol - * \brief Abstract class used to define the global protocol functions. + * \brief Abstract class used to define the global protocol functions. * A protocol is an entity that is started at a point, and that is updated by a thread. * A protocol can be terminated by an other class, or it can terminate itself if has fulfilled its role. * This class must be inherited to make any network job. @@ -57,44 +59,44 @@ class Protocol /*! * \brief Destructor */ - virtual ~Protocol(); - + virtual ~Protocol(); + /*! * \brief Notify a protocol matching the Event type of that event. * \param event : Pointer to the event. */ virtual void notifyEvent(Event* event) = 0; - - /*! + + /*! * \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. */ virtual void setup() = 0; - /*! - * \brief Called when the protocol is paused (by an other entity or by itself). + /*! + * \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. + /*! + * \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 as often as possible. Must be re-defined. */ virtual void update() = 0; - /*! + /*! * \brief Called when the protocol is to be killed. */ virtual void kill(); - - /*! + + /*! * \brief Method to get a protocol's type. * \return The protocol type. */ diff --git a/src/network/protocol_manager.cpp b/src/network/protocol_manager.cpp index 2c3eb3372..6915ce46c 100644 --- a/src/network/protocol_manager.cpp +++ b/src/network/protocol_manager.cpp @@ -37,7 +37,7 @@ void* protocolManagerUpdate(void* data) return NULL; } -ProtocolManager::ProtocolManager() +ProtocolManager::ProtocolManager() { pthread_mutex_init(&m_events_mutex, NULL); pthread_mutex_init(&m_protocols_mutex, NULL); @@ -45,8 +45,8 @@ ProtocolManager::ProtocolManager() pthread_mutex_init(&m_id_mutex, NULL); pthread_mutex_init(&m_exit_mutex, NULL); m_next_protocol_id = 0; - - + + pthread_mutex_lock(&m_exit_mutex); // will let the update function run m_update_thread = (pthread_t*)(malloc(sizeof(pthread_t))); pthread_create(m_update_thread, NULL, protocolManagerUpdate, this); @@ -70,7 +70,7 @@ ProtocolManager::~ProtocolManager() pthread_mutex_unlock(&m_protocols_mutex); pthread_mutex_unlock(&m_requests_mutex); pthread_mutex_unlock(&m_id_mutex); - + pthread_mutex_destroy(&m_events_mutex); pthread_mutex_destroy(&m_protocols_mutex); pthread_mutex_destroy(&m_requests_mutex); @@ -80,8 +80,9 @@ ProtocolManager::~ProtocolManager() void ProtocolManager::notifyEvent(Event* event) { + Event* event2 = new Event(*event); pthread_mutex_lock(&m_events_mutex); - m_events_to_process.push_back(event); // add the event to the queue + m_events_to_process.push_back(event2); // add the event to the queue pthread_mutex_unlock(&m_events_mutex); } @@ -89,7 +90,7 @@ void ProtocolManager::sendMessage(Protocol* sender, const NetworkString& message { NetworkString newMessage; newMessage.ai8(sender->getProtocolType()); // add one byte to add protocol type - newMessage += message; + newMessage += message; NetworkManager::getInstance()->sendPacket(newMessage); } @@ -97,14 +98,14 @@ void ProtocolManager::sendMessage(Protocol* sender, STKPeer* peer, const Network { NetworkString newMessage; newMessage.ai8(sender->getProtocolType()); // add one byte to add protocol type - newMessage += message; + newMessage += message; NetworkManager::getInstance()->sendPacket(peer, newMessage); } void ProtocolManager::sendMessageExcept(Protocol* sender, STKPeer* peer, const NetworkString& message) { NetworkString newMessage; newMessage.ai8(sender->getProtocolType()); // add one byte to add protocol type - newMessage += message; + newMessage += message; NetworkManager::getInstance()->sendPacketExcept(peer, newMessage); } @@ -122,7 +123,7 @@ uint32_t ProtocolManager::requestStart(Protocol* protocol) pthread_mutex_lock(&m_requests_mutex); m_requests.push_back(req); pthread_mutex_unlock(&m_requests_mutex); - + return info.id; } @@ -187,7 +188,7 @@ void ProtocolManager::startProtocol(ProtocolInfo protocol) } void ProtocolManager::stopProtocol(ProtocolInfo protocol) { - + } void ProtocolManager::pauseProtocol(ProtocolInfo protocol) { @@ -239,7 +240,7 @@ void ProtocolManager::update() Event* event = m_events_to_process.back(); m_events_to_process.pop_back(); pthread_mutex_unlock(&m_events_mutex); // release the mutex - + PROTOCOL_TYPE searchedProtocol = PROTOCOL_NONE; if (event->type == EVENT_TYPE_MESSAGE) { @@ -259,9 +260,10 @@ void ProtocolManager::update() { Log::debug("ProtocolManager", "Message is \"%s\"", event->data.c_str()); } + delete event->peer; // because we made a copy of the peer delete event; } - + // now update all protocols pthread_mutex_lock(&m_protocols_mutex); for (unsigned int i = 0; i < m_protocols.size(); i++) @@ -269,8 +271,8 @@ void ProtocolManager::update() if (m_protocols[i].state == PROTOCOL_STATE_RUNNING) m_protocols[i].protocol->update(); } - pthread_mutex_unlock(&m_protocols_mutex); - + pthread_mutex_unlock(&m_protocols_mutex); + // process queued events for protocols pthread_mutex_lock(&m_requests_mutex); for (unsigned int i = 0; i < m_requests.size(); i++) @@ -316,7 +318,7 @@ PROTOCOL_STATE ProtocolManager::getProtocolState(uint32_t id) if (m_requests[i].protocol_info.id == id) // the protocol is going to be started return PROTOCOL_STATE_RUNNING; // we can say it's running } - return PROTOCOL_STATE_TERMINATED; // else, it's already finished + return PROTOCOL_STATE_TERMINATED; // else, it's already finished } PROTOCOL_STATE ProtocolManager::getProtocolState(Protocol* protocol) @@ -354,6 +356,16 @@ Protocol* ProtocolManager::getProtocol(uint32_t id) return NULL; } +Protocol* ProtocolManager::getProtocol(PROTOCOL_TYPE type) +{ + for (unsigned int i = 0; i < m_protocols.size(); i++) + { + if (m_protocols[i].protocol->getProtocolType() == type) + return m_protocols[i].protocol; + } + return NULL; +} + bool ProtocolManager::isServer() { return NetworkManager::getInstance()->isServer(); diff --git a/src/network/protocol_manager.hpp b/src/network/protocol_manager.hpp index dbb3dc732..1345ebb4c 100644 --- a/src/network/protocol_manager.hpp +++ b/src/network/protocol_manager.hpp @@ -26,39 +26,38 @@ #include "network/singleton.hpp" #include "network/event.hpp" #include "network/network_string.hpp" +#include "network/protocol.hpp" #include "utils/types.hpp" #include -class Protocol; - -/*! +/*! * \enum PROTOCOL_STATE * \brief Defines the three states that a protocol can have. */ enum PROTOCOL_STATE { PROTOCOL_STATE_RUNNING, //!< The protocol is being updated everytime. - PROTOCOL_STATE_PAUSED, //!< The protocol is paused. + PROTOCOL_STATE_PAUSED, //!< The protocol is paused. PROTOCOL_STATE_TERMINATED //!< The protocol is terminated/does not exist. }; -/*! +/*! * \enum PROTOCOL_REQUEST_TYPE * \brief Defines actions that can be done about protocols. - * This enum is used essentially to keep the manager thread-safe and + * This enum is used essentially to keep the manager thread-safe and * to avoid protocols modifying directly their state. */ enum PROTOCOL_REQUEST_TYPE { PROTOCOL_REQUEST_START, //!< Start a protocol - PROTOCOL_REQUEST_STOP, //!< Stop a protocol + PROTOCOL_REQUEST_STOP, //!< Stop a protocol PROTOCOL_REQUEST_PAUSE, //!< Pause a protocol PROTOCOL_REQUEST_UNPAUSE, //!< Unpause a protocol PROTOCOL_REQUEST_TERMINATE //!< Terminate a protocol }; -/*! +/*! * \struct ProtocolInfo * \brief Stores the information needed to manage protocols */ @@ -68,7 +67,7 @@ typedef struct ProtocolInfo Protocol* protocol; //!< A pointer to the protocol uint32_t id; //!< The unique id of the protocol } ProtocolInfo; - + /*! * \struct ProtocolRequest * \brief Represents a request to do an action about a protocol. @@ -79,43 +78,43 @@ typedef struct ProtocolRequest ProtocolInfo protocol_info; //!< The concerned protocol information } ProtocolRequest; -/*! +/*! * \class ProtocolManager * \brief Manages the protocols at runtime. - * - * This class is in charge of storing and managing protocols. - * It is a singleton as there can be only one protocol manager per game - * instance. Any game object that wants to start a protocol must create a - * protocol and give it to this singleton. The protocols are updated in a + * + * This class is in charge of storing and managing protocols. + * It is a singleton as there can be only one protocol manager per game + * instance. Any game object that wants to start a protocol must create a + * protocol and give it to this singleton. The protocols are updated in a * special thread, to ensure that they are processed independently from the - * frames per second. Then, the management of protocols is thread-safe: any + * frames per second. Then, the management of protocols is thread-safe: any * object can start/pause/stop protocols whithout problems. */ class ProtocolManager : public Singleton { friend class Singleton; - + public: /*! * \brief Function that processes incoming events. * This function is called by the network manager each time there is an - * incoming packet. + * incoming packet. */ virtual void notifyEvent(Event* event); - /*! + /*! * \brief WILL BE COMMENTED LATER */ virtual void sendMessage(Protocol* sender, const NetworkString& message); - /*! + /*! * \brief WILL BE COMMENTED LATER */ virtual void sendMessage(Protocol* sender, STKPeer* peer, const NetworkString& message); - /*! + /*! * \brief WILL BE COMMENTED LATER */ virtual void sendMessageExcept(Protocol* sender, STKPeer* peer, const NetworkString& message); - - /*! + + /*! * \brief Asks the manager to start a protocol. * This function will store the request, and process it at a time it is * thread-safe. @@ -123,48 +122,48 @@ class ProtocolManager : public Singleton * \return The unique id of the protocol that is being started. */ virtual uint32_t requestStart(Protocol* protocol); - /*! + /*! * \brief Asks the manager to stop a protocol. * This function will store the request, and process it at a time it is * thread-safe. * \param protocol : A pointer to the protocol to stop */ virtual void requestStop(Protocol* protocol); - /*! + /*! * \brief Asks the manager to pause a protocol. * This function will store the request, and process it at a time it is * thread-safe. * \param protocol : A pointer to the protocol to pause */ virtual void requestPause(Protocol* protocol); - /*! + /*! * \brief Asks the manager to unpause a protocol. * This function will store the request, and process it at a time it is * thread-safe. * \param protocol : A pointer to the protocol to unpause */ virtual void requestUnpause(Protocol* protocol); - /*! + /*! * \brief Notifies the manager that a protocol is terminated. * This function will store the request, and process it at a time it is * thread-safe. * \param protocol : A pointer to the protocol that is finished */ virtual void requestTerminate(Protocol* protocol); - - /*! + + /*! * \brief Updates the manager. - * - * This function processes the events queue, notifies the concerned + * + * This function processes the events queue, notifies the concerned * protocols that they have events to process. Then ask all protocols - * to update themselves. Finally processes stored requests about + * to update themselves. Finally processes stored requests about * starting, stoping, pausing etc... protocols. * This function is called by a thread as often as possible. * This function is not FPS-dependant. */ virtual void update(); - - /*! + + /*! * \brief Get the number of protocols running. * \return The number of protocols that are actually running. */ @@ -172,13 +171,13 @@ class ProtocolManager : public Singleton /*! * \brief Get the state of a protocol using its id. * \param id : The id of the protocol you seek the state. - * \return The state of the protocol. + * \return The state of the protocol. */ virtual PROTOCOL_STATE getProtocolState(uint32_t id); /*! * \brief Get the state of a protocol using a pointer on it. * \param protocol : A pointer to the protocol you seek the state. - * \return The state of the protocol. + * \return The state of the protocol. */ virtual PROTOCOL_STATE getProtocolState(Protocol* protocol); /*! @@ -187,29 +186,35 @@ class ProtocolManager : public Singleton * \return The id of the protocol pointed by the protocol parameter. */ virtual uint32_t getProtocolID(Protocol* protocol); - + /*! - * \brief Get a protocol using his id. + * \brief Get a protocol using its id. * \param id : Unique ID of the seek protocol. * \return The protocol that has the ID id. */ virtual Protocol* getProtocol(uint32_t id); - + /*! + * \brief Get a protocol using its type. + * \param type : The type of the protocol. + * \return The protocol that matches the given type. + */ + virtual Protocol* getProtocol(PROTOCOL_TYPE type); + /*! \brief Know whether the app is a server. * \return True if this application is in server mode, false elseway. */ bool isServer(); - + /*! \brief Tells if we need to stop the update thread. */ int exit(); - + protected: // protected functions - /*! + /*! * \brief Constructor */ ProtocolManager(); - /*! + /*! * \brief Destructor */ virtual ~ProtocolManager(); @@ -221,7 +226,7 @@ class ProtocolManager : public Singleton * \param protocol_info : The protocol info that needs an id. */ void assignProtocolId(ProtocolInfo* protocol_info); - + /*! * \brief Starts a protocol. * Add the protocol info to the m_protocols vector. @@ -252,11 +257,11 @@ class ProtocolManager : public Singleton * \param protocol : ProtocolInfo concerned. */ virtual void protocolTerminated(ProtocolInfo protocol); - + // protected members - /*! + /*! * \brief Contains the running protocols. - * This stores the protocols that are either running or paused, their + * This stores the protocols that are either running or paused, their * state and their unique id. */ std::vector m_protocols; @@ -268,13 +273,13 @@ class ProtocolManager : public Singleton * \brief Contains the requests to start/stop etc... protocols. */ std::vector m_requests; - /*! \brief The next id to assign to a protocol. - * This value is incremented by 1 each time a protocol is started. + /*! \brief The next id to assign to a protocol. + * This value is incremented by 1 each time a protocol is started. * If a protocol has an id lower than this value, it means that it have - * been formerly started. + * been formerly started. */ uint32_t m_next_protocol_id; - + // mutexes: /*! Used to ensure that the event queue is used thread-safely. */ pthread_mutex_t m_events_mutex; @@ -286,10 +291,10 @@ class ProtocolManager : public Singleton pthread_mutex_t m_id_mutex; /*! Used when need to quit.*/ pthread_mutex_t m_exit_mutex; - + /*! Update thread.*/ pthread_t* m_update_thread; - + }; #endif // PROTOCOL_MANAGER_HPP diff --git a/src/network/protocols/client_lobby_room_protocol.cpp b/src/network/protocols/client_lobby_room_protocol.cpp index 0a6e64011..47ff95068 100644 --- a/src/network/protocols/client_lobby_room_protocol.cpp +++ b/src/network/protocols/client_lobby_room_protocol.cpp @@ -4,10 +4,10 @@ #include "online/current_online_user.hpp" #include "utils/log.hpp" -ClientLobbyRoomProtocol::ClientLobbyRoomProtocol(const TransportAddress& server_address) - : LobbyRoomProtocol(NULL) -{ - m_server_address = server_address; +ClientLobbyRoomProtocol::ClientLobbyRoomProtocol(const TransportAddress& server_address) + : LobbyRoomProtocol(NULL) +{ + m_server_address = server_address; m_server = NULL; } @@ -45,7 +45,7 @@ void ClientLobbyRoomProtocol::notifyEvent(Event* event) assert(event->data.size()); // assert that data isn't empty Log::verbose("ClientLobbyRoomProtocol", "Message from %u : \"%s\"", event->peer->getAddress(), event->data.c_str()); uint8_t message_type = event->data.getAndRemoveUInt8(); - + if (message_type == 0x01) // new player connected newPlayer(event); else if (message_type == 0x02) // player disconnected @@ -102,7 +102,7 @@ void ClientLobbyRoomProtocol::update() /*! \brief Called when a new player is connected to the server * \param event : Event providing the information. - * + * * Format of the data : * Byte 0 1 5 6 7 * ------------------------------------------------ @@ -120,9 +120,9 @@ void ClientLobbyRoomProtocol::newPlayer(Event* event) uint32_t global_id = event->data.gui32(1); - NetworkPlayerProfile profile; - profile.kart_name = ""; - profile.race_id = event->data.gui8(6); + NetworkPlayerProfile* profile = new NetworkPlayerProfile(); + profile->kart_name = ""; + profile->race_id = event->data.gui8(6); if (global_id == CurrentOnlineUser::get()->getUserID()) { @@ -131,7 +131,7 @@ void ClientLobbyRoomProtocol::newPlayer(Event* event) else { Log::verbose("ClientLobbyRoomProtocol", "New player connected."); - profile.user_profile = new OnlineUser(global_id); + profile->user_profile = new OnlineUser(global_id); m_setup->addPlayer(profile); } } @@ -140,7 +140,7 @@ void ClientLobbyRoomProtocol::newPlayer(Event* event) /*! \brief Called when a new player is disconnected * \param event : Event providing the information. - * + * * Format of the data : * Byte 0 1 2 * ------------------------- @@ -170,7 +170,7 @@ void ClientLobbyRoomProtocol::disconnectedPlayer(Event* event) /*! \brief Called when the server accepts the connection. * \param event : Event providing the information. - * + * * Format of the data : * Byte 0 1 2 3 7 8 12 * ---------------------------------------------------------- @@ -186,15 +186,15 @@ void ClientLobbyRoomProtocol::connectionAccepted(Event* event) return; } - NetworkPlayerProfile profile; - profile.kart_name = ""; - profile.race_id = event->data.gui8(1); + NetworkPlayerProfile* profile = new NetworkPlayerProfile(); + profile->kart_name = ""; + profile->race_id = event->data.gui8(1); uint32_t token = event->data.gui32(3); uint32_t global_id = event->data.gui32(8); if (global_id == CurrentOnlineUser::get()->getUserID()) { Log::info("ClientLobbyRoomProtocol", "The server accepted the connection."); - profile.user_profile = CurrentOnlineUser::get(); + profile->user_profile = CurrentOnlineUser::get(); m_setup->addPlayer(profile); event->peer->setClientServerToken(token); m_server = event->peer; @@ -206,7 +206,7 @@ void ClientLobbyRoomProtocol::connectionAccepted(Event* event) /*! \brief Called when the server refuses the connection. * \param event : Event providing the information. - * + * * Format of the data : * Byte 0 1 2 * -------------------- @@ -240,7 +240,7 @@ void ClientLobbyRoomProtocol::connectionRefused(Event* event) /*! \brief Called when the server refuses the kart selection request. * \param event : Event providing the information. - * + * * Format of the data : * Byte 0 1 2 * -------------------- @@ -272,11 +272,11 @@ void ClientLobbyRoomProtocol::kartSelectionRefused(Event* event) //----------------------------------------------------------------------------- -/*! \brief Called when the server refuses the kart selection request. +/*! \brief Called when the server tells to update a player's kart. * \param event : Event providing the information. - * + * * Format of the data : - * Byte 0 1 2 3 N+3 + * Byte 0 1 2 3 N+3 * ------------------------------------------------ * Size | 1 | 1 | 1 | N | * Data | 1 | race id | N (kart name size) | kart name | @@ -284,9 +284,24 @@ void ClientLobbyRoomProtocol::kartSelectionRefused(Event* event) */ void ClientLobbyRoomProtocol::kartSelectionUpdate(Event* event) { - if (event->data[0] != 1) + if (event->data.size() < 3 || event->data[0] != 1) { - Log::error("ClientLobbyRoomProtocol", "A message notifying a refused connection wasn't formated as expected."); + 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); + if (data.size() != kart_name_length) + { + Log::error("ClientLobbyRoomProtocol", "Kart names sizes differ: told: %d, real: %d.", kart_name_length, data.size()); + return; + } + if (!m_setup->isKartAvailable(data)) + { + Log::error("ClientLobbyRoomProtocol", "The updated kart is taken already."); + } + m_setup->setPlayerKart(player_id, data); } + +//----------------------------------------------------------------------------- diff --git a/src/network/protocols/client_lobby_room_protocol.hpp b/src/network/protocols/client_lobby_room_protocol.hpp index 3ced1c1a7..63d916694 100644 --- a/src/network/protocols/client_lobby_room_protocol.hpp +++ b/src/network/protocols/client_lobby_room_protocol.hpp @@ -8,15 +8,15 @@ class ClientLobbyRoomProtocol : public LobbyRoomProtocol public: ClientLobbyRoomProtocol(const TransportAddress& server_address); virtual ~ClientLobbyRoomProtocol(); - + void requestKartSelection(std::string kart_name); void sendMessage(std::string message); - + virtual void notifyEvent(Event* event); virtual void setup(); virtual void update(); - - + + protected: void newPlayer(Event* event); void disconnectedPlayer(Event* event); @@ -25,9 +25,9 @@ class ClientLobbyRoomProtocol : public LobbyRoomProtocol void kartSelectionRefused(Event* event); void kartSelectionUpdate(Event* event); - TransportAddress m_server_address; + TransportAddress m_server_address; STKPeer* m_server; - + enum STATE { NONE, diff --git a/src/network/protocols/get_peer_address.cpp b/src/network/protocols/get_peer_address.cpp index 4b394b2e0..d4ad1d75a 100644 --- a/src/network/protocols/get_peer_address.cpp +++ b/src/network/protocols/get_peer_address.cpp @@ -18,6 +18,7 @@ #include "network/protocols/get_peer_address.hpp" +#include "network/protocol_manager.hpp" #include "network/http_functions.hpp" #include "online/http_connector.hpp" #include "online/current_online_user.hpp" @@ -47,7 +48,7 @@ void GetPeerAddress::update() { if (m_state == NONE) { - + HTTPConnector * connector = new HTTPConnector((std::string)UserConfigParams::m_server_multiplayer + "address-management.php"); connector->setParameter("id",CurrentOnlineUser::get()->getUserID()); connector->setParameter("token",CurrentOnlineUser::get()->getToken()); diff --git a/src/network/protocols/hide_public_address.cpp b/src/network/protocols/hide_public_address.cpp index dece8c762..b4b0a5547 100644 --- a/src/network/protocols/hide_public_address.cpp +++ b/src/network/protocols/hide_public_address.cpp @@ -18,6 +18,7 @@ #include "network/protocols/hide_public_address.hpp" +#include "network/protocol_manager.hpp" #include "online/http_connector.hpp" #include "online/current_online_user.hpp" #include "config/user_config.hpp" diff --git a/src/network/protocols/request_connection.cpp b/src/network/protocols/request_connection.cpp index bc76e55ba..4b4a1fd5d 100644 --- a/src/network/protocols/request_connection.cpp +++ b/src/network/protocols/request_connection.cpp @@ -1,5 +1,6 @@ #include "network/protocols/request_connection.hpp" +#include "network/protocol_manager.hpp" #include "online/http_connector.hpp" #include "online/current_online_user.hpp" #include "config/user_config.hpp" @@ -53,7 +54,7 @@ void RequestConnection::update() Log::error("RequestConnection", "Fail to make a request."); } m_state = DONE; - + break; } case DONE: diff --git a/src/network/protocols/server_lobby_room_protocol.cpp b/src/network/protocols/server_lobby_room_protocol.cpp index 2a70f4851..acbbf733b 100644 --- a/src/network/protocols/server_lobby_room_protocol.cpp +++ b/src/network/protocols/server_lobby_room_protocol.cpp @@ -46,62 +46,17 @@ void ServerLobbyRoomProtocol::notifyEvent(Event* event) uint8_t message_type; message_type = event->data.getAndRemoveUInt8(); Log::info("ServerLobbyRoomProtocol", "Message received with type %d.", message_type); - if (message_type == 1) // player requesting connection - { - if (event->data.size() != 5 || event->data[0] != 4) - { - Log::warn("LobbyRoomProtocol", "A player is sending a badly formated message. Size is %d and first byte %d", event->data.size(), event->data[0]); - return; - } - Log::verbose("LobbyRoomProtocol", "New player."); - int player_id = 0; - player_id = event->data.getUInt32(1); - // can we add the player ? - if (m_setup->getPlayerCount() < 16) // accept player - { - // 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 - NetworkString message; - // new player (1) -- size of id -- id -- size of local id -- local id; - message.ai8(1).ai8(4).ai32(player_id).ai8(1).ai8(m_next_id); - m_listener->sendMessageExcept(this, event->peer, message); - // send a message to the one that asked to connect - NetworkString message_ack; - // 0b10000001 (connection success) ; - RandomGenerator token_generator; - // use 4 random numbers because rand_max is probably 2^15-1. - uint32_t token = (uint32_t)(((token_generator.get(RAND_MAX)<<24) & 0xff) + - ((token_generator.get(RAND_MAX)<<16) & 0xff) + - ((token_generator.get(RAND_MAX)<<8) & 0xff) + - ((token_generator.get(RAND_MAX) & 0xff))); - // connection success (129) -- size of token -- token - message_ack.ai8(0x81).ai8(1).ai8(m_next_id).ai8(4).ai32(token).ai8(4).ai32(player_id); - m_listener->sendMessage(this, event->peer, message_ack); - } // accept player - else // refuse the connection with code 0 (too much players) - { - NetworkString message; - message.ai8(0x80); // 128 means connection refused - message.ai8(1); // 1 bytes for the error code - message.ai8(0); // 0 = too much players - // send only to the peer that made the request - m_listener->sendMessage(this, event->peer, message); - } - } + if (message_type == 0x01) // player requesting connection + connectionRequested(event); + if (message_type == 0x02) // player requesting kart selection + kartSelectionRequested(event); } // if (event->type == EVENT_TYPE_MESSAGE) else if (event->type == EVENT_TYPE_CONNECTED) { } // if (event->type == EVENT_TYPE_CONNECTED) else if (event->type == EVENT_TYPE_DISCONNECTED) { - + kartDisconnected(event); } // if (event->type == EVENT_TYPE_DISCONNECTED) } @@ -188,3 +143,137 @@ void ServerLobbyRoomProtocol::update() } //----------------------------------------------------------------------------- +void ServerLobbyRoomProtocol::kartDisconnected(Event* event) +{ + if (event->peer->getPlayerProfile() != NULL) // others knew him + { + NetworkString msg; + msg.ai8(0x02).ai8(1).ai8(event->peer->getPlayerProfile()->race_id); + m_listener->sendMessage(this, msg); + } +} + +//----------------------------------------------------------------------------- + +/*! \brief Called when a player asks for a connection. + * \param event : Event providing the information. + * + * Format of the data : + * Byte 0 1 5 + * ------------------------ + * Size | 1 | 4 | + * Data | 4 | global player id | + * ------------------------ + */ +void ServerLobbyRoomProtocol::connectionRequested(Event* event) +{ + if (event->data.size() != 5 || event->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]); + return; + } + Log::verbose("ServerLobbyRoomProtocol", "New player."); + int player_id = 0; + player_id = event->data.getUInt32(1); + // can we add the player ? + if (m_setup->getPlayerCount() < 16) // accept player + { + // add the player to the game setup + while(m_setup->getProfile(m_next_id)!=NULL) + m_next_id++; + NetworkPlayerProfile* profile = new NetworkPlayerProfile(); + profile->race_id = m_next_id; + profile->kart_name = ""; + profile->user_profile = new OnlineUser("Unnamed Player"); + m_setup->addPlayer(profile); + event->peer->setPlayerProfile(profile); + // notify everybody that there is a new player + NetworkString message; + // new player (1) -- size of id -- id -- size of local id -- local id; + message.ai8(1).ai8(4).ai32(player_id).ai8(1).ai8(m_next_id); + m_listener->sendMessageExcept(this, event->peer, message); + // send a message to the one that asked to connect + NetworkString message_ack; + // 0b10000001 (connection success) ; + RandomGenerator token_generator; + // use 4 random numbers because rand_max is probably 2^15-1. + uint32_t token = (uint32_t)(((token_generator.get(RAND_MAX)<<24) & 0xff) + + ((token_generator.get(RAND_MAX)<<16) & 0xff) + + ((token_generator.get(RAND_MAX)<<8) & 0xff) + + ((token_generator.get(RAND_MAX) & 0xff))); + // connection success (129) -- size of token -- token + message_ack.ai8(0x81).ai8(1).ai8(m_next_id).ai8(4).ai32(token).ai8(4).ai32(player_id); + m_listener->sendMessage(this, event->peer, message_ack); + } // accept player + else // refuse the connection with code 0 (too much players) + { + NetworkString message; + message.ai8(0x80); // 128 means connection refused + message.ai8(1); // 1 bytes for the error code + message.ai8(0); // 0 = too much players + // send only to the peer that made the request + m_listener->sendMessage(this, event->peer, message); + } +} + +//----------------------------------------------------------------------------- + +/*! \brief Called when a player asks to select a kart. + * \param event : Event providing the information. + * + * Format of the data : + * Byte 0 1 5 6 N+6 + * --------------------------------------------------- + * Size | 1 | 4 | 1 | N | + * Data | 4 | priv token | N (kart name size) | kart name | + * --------------------------------------------------- + */ +void ServerLobbyRoomProtocol::kartSelectionRequested(Event* event) +{ + if (event->data.size() < 6 || event->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]); + return; + } + uint32_t token = event->data.gui32(1); + if (token != event->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); + if (kart_name.size() != kart_name_size) + { + Log::error("ServerLobbyRoomProtocol", "Kart names sizes differ: told:" + "%d, real: %d.", kart_name_size, kart_name.size()); + return; + } + if (!m_setup->isKartAvailable(kart_name)) + { + NetworkString answer; + answer.ai8(0x82).ai8(1).ai8(0); // kart is already taken + m_listener->sendMessage(this, event->peer, answer); + return; + } + // check if this kart is authorized + if (!m_setup->isKartAllowed(kart_name)) + { + NetworkString answer; + answer.ai8(0x82).ai8(1).ai8(1); // kart is not authorized + m_listener->sendMessage(this, event->peer, answer); + return; + } + // send a kart update to everyone + NetworkString answer; + // kart update (3), 1, race id + answer.ai8(0x03).ai8(1).ai8(event->peer->getPlayerProfile()->race_id); + // kart name size, kart name + answer.ai8(kart_name.size()).as(kart_name); + m_listener->sendMessage(this, answer); +} + +//----------------------------------------------------------------------------- diff --git a/src/network/protocols/server_lobby_room_protocol.hpp b/src/network/protocols/server_lobby_room_protocol.hpp index b1b9e8cfd..eccf77cb2 100644 --- a/src/network/protocols/server_lobby_room_protocol.hpp +++ b/src/network/protocols/server_lobby_room_protocol.hpp @@ -8,18 +8,22 @@ class ServerLobbyRoomProtocol : public LobbyRoomProtocol public: ServerLobbyRoomProtocol(); virtual ~ServerLobbyRoomProtocol(); - + virtual void notifyEvent(Event* event); virtual void setup(); virtual void update(); - + protected: + void kartDisconnected(Event* event); + void connectionRequested(Event* event); + void kartSelectionRequested(Event* event); + uint8_t m_next_id; //!< Next id to assign to a peer. std::vector m_peers; std::vector m_incoming_peers_ids; uint32_t m_current_protocol_id; TransportAddress m_public_address; - + enum STATE { NONE, diff --git a/src/network/stk_peer.cpp b/src/network/stk_peer.cpp index 87d9e9ff6..19789ba06 100644 --- a/src/network/stk_peer.cpp +++ b/src/network/stk_peer.cpp @@ -25,13 +25,14 @@ STKPeer::STKPeer() { m_peer = NULL; + m_player_profile = NULL; } STKPeer::~STKPeer() { if (m_peer) { - //free(m_peer); + free(m_peer); m_peer = NULL; } } @@ -39,15 +40,15 @@ STKPeer::~STKPeer() bool STKPeer::connectToHost(STKHost* localhost, TransportAddress host, uint32_t channel_count, uint32_t data) { ENetAddress address; - address.host = + address.host = ((host.ip & 0xff000000) >> 24) + ((host.ip & 0x00ff0000) >> 8) + ((host.ip & 0x0000ff00) << 8) + ((host.ip & 0x000000ff) << 24); // because ENet wants little endian address.port = host.port; - + ENetPeer* peer = enet_host_connect(localhost->m_host, &address, 2, 0); - if (peer == NULL) + if (peer == NULL) { Log::error("STKPeer", "Could not try to connect to server.\n"); return false; @@ -65,7 +66,7 @@ void STKPeer::sendPacket(NetworkString const& data) { Log::verbose("STKPeer", "sending packet of size %d to %i.%i.%i.%i:%i", data.size(), (m_peer->address.host>>0)&0xff,(m_peer->address.host>>8)&0xff,(m_peer->address.host>>16)&0xff,(m_peer->address.host>>24)&0xff,m_peer->address.port); ENetPacket* packet = enet_packet_create(data.c_str(), data.size()+1,ENET_PACKET_FLAG_RELIABLE); - + enet_peer_send(m_peer, 0, packet); } diff --git a/src/network/stk_peer.hpp b/src/network/stk_peer.hpp index b8667f218..f15f925a3 100644 --- a/src/network/stk_peer.hpp +++ b/src/network/stk_peer.hpp @@ -21,6 +21,7 @@ #include "network/stk_host.hpp" #include "network/network_string.hpp" +#include "network/game_setup.hpp" #include class STKPeer @@ -29,9 +30,9 @@ class STKPeer public: STKPeer(); virtual ~STKPeer(); - + virtual void sendPacket(const NetworkString& data); - + static bool connectToHost(STKHost* localhost, TransportAddress host, uint32_t channel_count, uint32_t data); void disconnect(); @@ -39,16 +40,19 @@ class STKPeer bool isConnected() const; void setClientServerToken(const uint32_t& token) { m_client_server_token = token; m_token_set = true; } void unsetClientServerToken() { m_token_set = false; } - + void setPlayerProfile(NetworkPlayerProfile* profile) { m_player_profile = profile; } + uint32_t getAddress() const; uint16_t getPort() const; uint32_t getClientServerToken() const { return m_client_server_token; } bool isClientServerTokenSet() const { return m_token_set; } - + NetworkPlayerProfile* getPlayerProfile() { return m_player_profile; } + bool operator==(const ENetPeer* peer) const; - + protected: ENetPeer* m_peer; + NetworkPlayerProfile* m_player_profile; uint32_t m_client_server_token; bool m_token_set; };