diff --git a/src/io/xml_node.cpp b/src/io/xml_node.cpp index 4c56d94b3..264bba0aa 100644 --- a/src/io/xml_node.cpp +++ b/src/io/xml_node.cpp @@ -319,6 +319,22 @@ int XMLNode::get(const std::string &attribute, int64_t *value) const } // get(int64_t) +// ---------------------------------------------------------------------------- +int XMLNode::get(const std::string &attribute, uint16_t *value) const +{ + std::string s; + if(!get(attribute, &s)) return 0; + + if (!StringUtils::parseString(s, value)) + { + fprintf(stderr, "[XMLNode] WARNING: Expected uint but found '%s' for attribute '%s' of node '%s' in file %s\n", + s.c_str(), attribute.c_str(), m_name.c_str(), m_file_name.c_str()); + return 0; + } + + return 1; +} // get(uint32_t) + // ---------------------------------------------------------------------------- int XMLNode::get(const std::string &attribute, uint32_t *value) const { diff --git a/src/io/xml_node.hpp b/src/io/xml_node.hpp index 953d52f8a..37e4ade41 100644 --- a/src/io/xml_node.hpp +++ b/src/io/xml_node.hpp @@ -74,6 +74,7 @@ public: int get(const std::string &attribute, std::string *value) const; int get(const std::string &attribute, core::stringw *value) const; int get(const std::string &attribute, int32_t *value) const; + int get(const std::string &attribute, uint16_t *value) const; int get(const std::string &attribute, uint32_t *value) const; int get(const std::string &attribute, int64_t *value) const; int get(const std::string &attribute, float *value) const; diff --git a/src/main.cpp b/src/main.cpp index 9de152de3..1e3b037d9 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -171,6 +171,9 @@ #include "network/network_manager.hpp" #include "network/client_network_manager.hpp" #include "network/server_network_manager.hpp" +#include "network/protocol_manager.hpp" +#include "network/protocols/lobby_room_protocol.hpp" +#include "online/current_online_user.hpp" #include "race/grand_prix_manager.hpp" #include "race/highscore_manager.hpp" #include "race/history.hpp" @@ -689,6 +692,7 @@ int handleCmdLine(int argc, char **argv) else if( !strcmp(argv[i], "--server") ) { NetworkManager::getInstance(); + Log::info("main", "Creating a server network manager."); } else if( sscanf(argv[i], "--port=%d", &n) ) { @@ -1167,8 +1171,6 @@ void initRest() kart_properties_manager = new KartPropertiesManager(); projectile_manager = new ProjectileManager (); powerup_manager = new PowerupManager (); - // If the server has been created (--server option), this will do nothing: - NetworkManager::getInstance(); attachment_manager = new AttachmentManager (); highscore_manager = new HighscoreManager (); KartPropertiesManager::addKartSearchDir( @@ -1360,6 +1362,17 @@ int main(int argc, char *argv[] ) //handleCmdLine() needs InitTuxkart() so it can't be called first if(!handleCmdLine(argc, argv)) exit(0); + + // load the network manager + // If the server has been created (--server option), this will do nothing (just a warning): + NetworkManager::getInstance(); + NetworkManager::getInstance()->run(); + if (NetworkManager::getInstance()->isServer()) + { + irr::core::stringw str; + CurrentOnlineUser::get()->signIn("server", "serverpass", str); + ProtocolManager::getInstance()->requestStart(new ServerLobbyRoomProtocol()); + } addons_manager->checkInstalledAddons(); diff --git a/src/modes/world.cpp b/src/modes/world.cpp index 427a27caf..c9014c11e 100644 --- a/src/modes/world.cpp +++ b/src/modes/world.cpp @@ -42,8 +42,6 @@ #include "karts/kart_properties_manager.hpp" #include "modes/overworld.hpp" #include "modes/profile_world.hpp" -#include "network/network_manager.hpp" -#include "network/race_state.hpp" #include "physics/btKart.hpp" #include "physics/physics.hpp" #include "physics/triangle_mesh.hpp" @@ -118,7 +116,6 @@ World::World() : WorldStatus(), m_clear_color(255,100,101,140) */ void World::init() { - race_state = new RaceState(); m_faster_music_active = false; m_fastest_kart = 0; m_eliminated_karts = 0; @@ -174,8 +171,6 @@ void World::init() if(ReplayPlay::get()) ReplayPlay::get()->Load(); - network_manager->worldLoaded(); - powerup_manager->updateWeightsForRace(num_karts); } // init @@ -360,7 +355,6 @@ World::~World() // gui and this must be deleted. delete m_race_gui; } - delete race_state; for ( unsigned int i = 0 ; i < m_karts.size() ; i++ ) delete m_karts[i]; @@ -748,7 +742,7 @@ void World::updateWorld(float dt) ->setSinglePlayer( StateManager::get()->getActivePlayer(0) ); StateManager::get()->enterGameState(); - network_manager->setupPlayerKartInfo(); + race_manager->setupPlayerKartInfo(); race_manager->startNew(true); } else @@ -801,11 +795,8 @@ void World::update(float dt) if(ReplayPlay::get()) ReplayPlay::get()->update(dt); if(history->replayHistory()) dt=history->getNextDelta(); WorldStatus::update(dt); - // Clear race state so that new information can be stored - race_state->clear(); - if(network_manager->getMode()!=NetworkManager::NW_CLIENT && - !history->dontDoPhysics()) + if (!history->dontDoPhysics()) { m_physics->update(dt); } diff --git a/src/network/client_network_manager.cpp b/src/network/client_network_manager.cpp index 5dadb2198..e8861a964 100644 --- a/src/network/client_network_manager.cpp +++ b/src/network/client_network_manager.cpp @@ -48,68 +48,6 @@ void ClientNetworkManager::run() NetworkManager::run(); } -bool ClientNetworkManager::connectToHost(std::string serverNickname) -{ - Log::info("ClientNetworkManager", "Starting the connection to host protocol\n"); - // step 1 : retreive public address - Protocol* protocol = new GetPublicAddress(&m_public_address); - ProtocolManager::getInstance()->requestStart(protocol); - while (ProtocolManager::getInstance()->getProtocolState(protocol) != PROTOCOL_STATE_TERMINATED ) - { - } - Log::info("ClientNetworkManager", "The public address is known.\n"); - - // step 2 : show the public address for others (here, the server) - ShowPublicAddress* spa = new ShowPublicAddress(NULL); - spa->setPassword(m_player_login.password); - spa->setUsername(m_player_login.username); - spa->setPublicAddress(m_public_address.ip, m_public_address.port); - ProtocolManager::getInstance()->requestStart(spa); - while (ProtocolManager::getInstance()->getProtocolState(spa) != PROTOCOL_STATE_TERMINATED ) - { - } - Log::info("ClientNetworkManager", "The public address is being shown online.\n"); - - // step 3 : get the server's addres. - TransportAddress addr; - GetPeerAddress* gpa = new GetPeerAddress(&addr); - gpa->setPeerName(serverNickname); - ProtocolManager::getInstance()->requestStart(gpa); - while (ProtocolManager::getInstance()->getProtocolState(gpa) != PROTOCOL_STATE_TERMINATED ) - { - } - Log::info("ClientNetworkManager", "The public address of the server is known.\n"); - - // step 4 : connect to the server - ConnectToServer* cts = new ConnectToServer(NULL); - cts->setServerAddress(addr.ip, addr.port); - ProtocolManager::getInstance()->requestStart(cts); - while (ProtocolManager::getInstance()->getProtocolState(cts) != PROTOCOL_STATE_TERMINATED ) - { - } - bool success = false; - if (m_localhost->isConnectedTo(TransportAddress(addr.ip, addr.port))) - { - success = true; - Log::info("ClientNetworkManager", "Connection success. You are now connected to a server.\n"); - } - else - { - Log::error("ClientNetworkManager", "We are NOT connected to the server.\n"); - } - // step 5 : hide our public address - HidePublicAddress* hpa = new HidePublicAddress(NULL); - hpa->setPassword(m_player_login.password); - hpa->setUsername(m_player_login.username); - ProtocolManager::getInstance()->requestStart(hpa); - while (ProtocolManager::getInstance()->getProtocolState(hpa) != PROTOCOL_STATE_TERMINATED ) - { - } - Log::info("ClientNetworkManager", "The public address is now hidden online.\n"); - - return success; -} - void ClientNetworkManager::sendPacket(const NetworkString& data) { if (m_peers.size() > 1) diff --git a/src/network/client_network_manager.hpp b/src/network/client_network_manager.hpp index aa85c118f..b5f48f434 100644 --- a/src/network/client_network_manager.hpp +++ b/src/network/client_network_manager.hpp @@ -31,9 +31,6 @@ class ClientNetworkManager : public NetworkManager } virtual void run(); - - bool connectToHost(std::string serverNickname); - virtual void sendPacket(const NetworkString& data); STKPeer* getPeer(); diff --git a/src/network/network_manager.cpp b/src/network/network_manager.cpp index 923211777..096b2e0c0 100644 --- a/src/network/network_manager.cpp +++ b/src/network/network_manager.cpp @@ -49,6 +49,7 @@ NetworkManager::NetworkManager() m_public_address.port = 0; m_protocol_manager_update_thread = NULL; m_localhost = NULL; + m_game_setup = NULL; } //----------------------------------------------------------------------------- diff --git a/src/network/network_manager.hpp b/src/network/network_manager.hpp index 47a1620d8..456b0930c 100644 --- a/src/network/network_manager.hpp +++ b/src/network/network_manager.hpp @@ -62,6 +62,7 @@ class NetworkManager : public Singleton bool isPlayingOnline() { return m_playing_online; } STKHost* getHost() { return m_localhost; } std::vector getPeers() { return m_peers; } + TransportAddress getPublicAddress() { return m_public_address; } GameSetup* getGameSetup() { return m_game_setup; } protected: diff --git a/src/network/network_string.hpp b/src/network/network_string.hpp index 722553a53..90069c1a6 100644 --- a/src/network/network_string.hpp +++ b/src/network/network_string.hpp @@ -132,6 +132,15 @@ 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); } + + inline int gi(int pos = 0) { return get(pos); } + inline uint32_t gui(int pos = 0) { return get(pos); } + inline uint32_t gui32(int pos = 0) { return get(pos); } + inline uint16_t gui16(int pos = 0) { return get(pos); } + 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); } + double getDouble(int pos = 0) //!< BEWARE OF PRECISION { for (int i = 0; i < 8; i++) @@ -182,15 +191,15 @@ class NetworkString remove(pos, 4); } - inline NetworkString& gui8(uint8_t* dst) { *dst = getAndRemoveUInt8(0); } - inline NetworkString& gui16(uint16_t* dst) { *dst = getAndRemoveUInt16(0); } - inline NetworkString& gui32(uint32_t* dst) { *dst = getAndRemoveUInt32(0); } - inline NetworkString& gui(uint32_t* dst) { *dst = getAndRemoveUInt32(0); } - inline NetworkString& gi(int* dst) { *dst = getAndRemoveInt(0); } - inline NetworkString& gc(char* dst) { *dst = getAndRemoveChar(0); } - inline NetworkString& guc(uchar* dst) { *dst = getAndRemoveUChar(0); } - inline NetworkString& gd(double* dst) { *dst = getAndRemoveDouble(0); } - inline NetworkString& gf(float* dst) { *dst = getAndRemoveFloat(0); } + inline NetworkString& gui8(uint8_t* dst) { *dst = getAndRemoveUInt8(0); return *this; } + inline NetworkString& gui16(uint16_t* dst) { *dst = getAndRemoveUInt16(0); return *this; } + inline NetworkString& gui32(uint32_t* dst) { *dst = getAndRemoveUInt32(0); return *this; } + inline NetworkString& gui(uint32_t* dst) { *dst = getAndRemoveUInt32(0); return *this; } + inline NetworkString& gi(int* dst) { *dst = getAndRemoveInt(0); return *this; } + inline NetworkString& gc(char* dst) { *dst = getAndRemoveChar(0); return *this; } + inline NetworkString& guc(uchar* dst) { *dst = getAndRemoveUChar(0); return *this; } + inline NetworkString& gd(double* dst) { *dst = getAndRemoveDouble(0); return *this; } + inline NetworkString& gf(float* dst) { *dst = getAndRemoveFloat(0); return *this; } protected: std::string m_string; diff --git a/src/network/protocol.cpp b/src/network/protocol.cpp index 366ac7b6d..7154c1014 100644 --- a/src/network/protocol.cpp +++ b/src/network/protocol.cpp @@ -37,6 +37,9 @@ void Protocol::unpause() m_listener->requestUnpause(this); } +void Protocol::kill() +{ +} void Protocol::setListener(ProtocolManager* listener) { diff --git a/src/network/protocol.hpp b/src/network/protocol.hpp index 84dfdf6eb..f30425aa4 100644 --- a/src/network/protocol.hpp +++ b/src/network/protocol.hpp @@ -90,6 +90,10 @@ class Protocol * \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. diff --git a/src/network/protocol_manager.cpp b/src/network/protocol_manager.cpp index f179dc0ed..8ce417f33 100644 --- a/src/network/protocol_manager.cpp +++ b/src/network/protocol_manager.cpp @@ -88,7 +88,7 @@ void ProtocolManager::sendMessageExcept(Protocol* sender, STKPeer* peer, const N NetworkManager::getInstance()->sendPacketExcept(peer, newMessage); } -int ProtocolManager::requestStart(Protocol* protocol) +uint32_t ProtocolManager::requestStart(Protocol* protocol) { // create the request ProtocolRequest req; @@ -156,7 +156,7 @@ void ProtocolManager::requestTerminate(Protocol* protocol) void ProtocolManager::startProtocol(ProtocolInfo protocol) { - Log::info("ProtocolManager", "A new protocol with id=%u has been started. There are %ld protocols running.\n", protocol.id, m_protocols.size()+1); + Log::info("ProtocolManager", "A new protocol with id=%u has been started. There are %ld protocols running.", protocol.id, m_protocols.size()+1); // add the protocol to the protocol vector so that it's updated pthread_mutex_lock(&m_protocols_mutex); m_protocols.push_back(protocol); @@ -204,7 +204,7 @@ void ProtocolManager::protocolTerminated(ProtocolInfo protocol) offset++; } } - Log::info("ProtocolManager", "A protocol has been terminated. There are %ld protocols running.\n", m_protocols.size()); + Log::info("ProtocolManager", "A protocol has been terminated. There are %ld protocols running.", m_protocols.size()); pthread_mutex_unlock(&m_protocols_mutex); } @@ -306,7 +306,7 @@ PROTOCOL_STATE ProtocolManager::getProtocolState(Protocol* protocol) return PROTOCOL_STATE_TERMINATED; // we don't know this protocol at all, it's finished } -int ProtocolManager::getProtocolID(Protocol* protocol) +uint32_t ProtocolManager::getProtocolID(Protocol* protocol) { for (unsigned int i = 0; i < m_protocols.size(); i++) { @@ -316,6 +316,16 @@ int ProtocolManager::getProtocolID(Protocol* protocol) return 0; } +Protocol* ProtocolManager::getProtocol(uint32_t id) +{ + for (unsigned int i = 0; i < m_protocols.size(); i++) + { + if (m_protocols[i].id == id) + 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 7051f163b..b2b0bdbd9 100644 --- a/src/network/protocol_manager.hpp +++ b/src/network/protocol_manager.hpp @@ -122,7 +122,7 @@ class ProtocolManager : public Singleton * \param protocol : A pointer to the protocol to start * \return The unique id of the protocol that is being started. */ - virtual int requestStart(Protocol* protocol); + 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 @@ -186,7 +186,14 @@ class ProtocolManager : public Singleton * \param protocol : A pointer to the protocol you seek the id. * \return The id of the protocol pointed by the protocol parameter. */ - virtual int getProtocolID(Protocol* protocol); + virtual uint32_t getProtocolID(Protocol* protocol); + + /*! + * \brief Get a protocol using his id. + * \param id : Unique ID of the seek protocol. + * \return The protocol that has the ID id. + */ + virtual Protocol* getProtocol(uint32_t id); /*! \brief Know whether the app is a server. * \return True if this application is in server mode, false elseway. @@ -263,7 +270,7 @@ class ProtocolManager : public Singleton * If a protocol has an id lower than this value, it means that it have * been formerly started. */ - unsigned int m_next_protocol_id; + uint32_t m_next_protocol_id; // mutexes: /*! Used to ensure that the event queue is used thread-safely. */ diff --git a/src/network/protocols/connect_to_server.cpp b/src/network/protocols/connect_to_server.cpp index 9a915fe11..bc73e6ea3 100644 --- a/src/network/protocols/connect_to_server.cpp +++ b/src/network/protocols/connect_to_server.cpp @@ -19,16 +19,22 @@ #include "network/protocols/connect_to_server.hpp" #include "network/client_network_manager.hpp" +#include "network/protocols/get_public_address.hpp" +#include "network/protocols/get_peer_address.hpp" +#include "network/protocols/show_public_address.hpp" +#include "network/protocols/hide_public_address.hpp" +#include "network/protocols/request_connection.hpp" +#include "network/protocols/ping_protocol.hpp" +#include "online/current_online_user.hpp" #include "utils/time.hpp" #include "utils/log.hpp" // ---------------------------------------------------------------------------- -ConnectToServer::ConnectToServer(CallbackObject* callback_object) : - Protocol(callback_object, PROTOCOL_CONNECTION) +ConnectToServer::ConnectToServer(uint32_t server_id) : + Protocol(NULL, PROTOCOL_CONNECTION) { - m_server_ip = 0; - m_server_port = 0; + m_server_id = server_id; m_state = NONE; } @@ -42,13 +48,11 @@ ConnectToServer::~ConnectToServer() void ConnectToServer::notifyEvent(Event* event) { - if (event->type == EVENT_TYPE_CONNECTED && - event->peer->getAddress() == m_server_ip && - event->peer->getPort() == m_server_port) + if (event->type == EVENT_TYPE_CONNECTED) { Log::info("ConnectToServer", "The Connect To Server protocol has \ received an event notifying that he's connected to the peer."); - m_state = DONE; // we received a message, we are connected + m_state = CONNECTING; // we received a message, we are connected } } @@ -57,49 +61,86 @@ void ConnectToServer::notifyEvent(Event* event) void ConnectToServer::setup() { m_state = NONE; - if (m_server_ip == 0 || m_server_port == 0 ) - { - Log::error("ConnectToServer", "You have to set the server's public \ - ip:port of the server.\n"); - m_listener->requestTerminate(this); - } + m_public_address.ip = 0; + m_public_address.port = 0; + m_server_address.ip = 0; + m_server_address.port = 0; + m_current_protocol_id = 0; } // ---------------------------------------------------------------------------- void ConnectToServer::update() { - if (m_state == NONE) + switch(m_state) { - static double target = 0; - double currentTime = Time::getRealTime(); - if (currentTime > target) + case NONE: { - NetworkManager::getInstance()->connect( - TransportAddress(m_server_ip, m_server_port)); - if (NetworkManager::getInstance()->isConnectedTo( - TransportAddress(m_server_ip, m_server_port))) - { - m_state = DONE; - return; - } - target = currentTime+5; - Log::info("ConnectToServer", "Retrying to connect in 5 seconds.\n"); + m_current_protocol_id = m_listener->requestStart(new GetPublicAddress(&m_public_address)); + m_state = WAITING_SELF_ADDRESS; + break; } - } - else if (m_state == DONE) - { - m_listener->requestTerminate(this); + case WAITING_SELF_ADDRESS: + if (m_listener->getProtocolState(m_current_protocol_id) + == PROTOCOL_STATE_TERMINATED) // now we know the public addr + { + m_state = SELF_ADDRESS_KNOWN; + NetworkManager::getInstance()->setPublicAddress(m_public_address); // set our public address + m_current_protocol_id = m_listener->requestStart(new GetPeerAddress(m_server_id, &m_server_address)); + } + break; + case SELF_ADDRESS_KNOWN: + if (m_listener->getProtocolState(m_current_protocol_id) + == PROTOCOL_STATE_TERMINATED) // now we have the server's address + { + m_state = PEER_ADDRESS_KNOWN; + m_current_protocol_id = m_listener->requestStart(new ShowPublicAddress()); + } + break; + case PEER_ADDRESS_KNOWN: + if (m_listener->getProtocolState(m_current_protocol_id) + == PROTOCOL_STATE_TERMINATED) // now our public address is public + { + m_state = SELF_ADDRESS_SHOWN; + m_current_protocol_id = m_listener->requestStart(new RequestConnection(m_server_id)); + } + break; + case SELF_ADDRESS_SHOWN: + if (m_listener->getProtocolState(m_current_protocol_id) + == PROTOCOL_STATE_TERMINATED) // we have put a request to access the server + { + m_state = REQUEST_DONE; + m_current_protocol_id = m_listener->requestStart(new PingProtocol(m_server_address, 0.5)); + } + break; + case REQUEST_DONE: + if (m_listener->getProtocolState(m_current_protocol_id) + == PROTOCOL_STATE_TERMINATED) // we have put a request to access the server + { + m_state = CONNECTING; + } + break; + case CONNECTING: // waiting the server to answer our connection + break; + case CONNECTED: + { + m_listener->requestTerminate( m_listener->getProtocol(m_current_protocol_id)); // kill the ping protocol because we're connected + m_current_protocol_id = m_listener->requestStart(new HidePublicAddress()); + m_state = HIDING_ADDRESS; + break; + } + case HIDING_ADDRESS: + if (m_listener->getProtocolState(m_current_protocol_id) + == PROTOCOL_STATE_TERMINATED) // we have hidden our address + { + m_state = DONE; + } + break; + case DONE: + m_listener->requestTerminate(this); + break; } } // ---------------------------------------------------------------------------- -void ConnectToServer::setServerAddress(uint32_t ip, uint16_t port) -{ - m_server_ip = ip; - m_server_port = port; -} - -// ---------------------------------------------------------------------------- - diff --git a/src/network/protocols/connect_to_server.hpp b/src/network/protocols/connect_to_server.hpp index ad67412f9..321699986 100644 --- a/src/network/protocols/connect_to_server.hpp +++ b/src/network/protocols/connect_to_server.hpp @@ -20,27 +20,36 @@ #define CONNECT_TO_SERVER_HPP #include "network/protocol.hpp" +#include "network/types.hpp" #include class ConnectToServer : public Protocol, public CallbackObject { public: - ConnectToServer(CallbackObject* callback_object); + ConnectToServer(uint32_t server_id); virtual ~ConnectToServer(); virtual void notifyEvent(Event* event); virtual void setup(); virtual void update(); - void setServerAddress(uint32_t ip, uint16_t port); - protected: - uint32_t m_server_ip; - uint16_t m_server_port; + TransportAddress m_server_address; + TransportAddress m_public_address; + uint32_t m_server_id; + uint32_t m_current_protocol_id; enum STATE { NONE, + WAITING_SELF_ADDRESS, + SELF_ADDRESS_KNOWN, + PEER_ADDRESS_KNOWN, + SELF_ADDRESS_SHOWN, + REQUEST_DONE, + CONNECTING, + CONNECTED, + HIDING_ADDRESS, DONE }; STATE m_state; diff --git a/src/network/protocols/get_peer_address.cpp b/src/network/protocols/get_peer_address.cpp index ffa2a0b1c..f78f73135 100644 --- a/src/network/protocols/get_peer_address.cpp +++ b/src/network/protocols/get_peer_address.cpp @@ -19,11 +19,14 @@ #include "network/protocols/get_peer_address.hpp" #include "network/http_functions.hpp" -#include "utils/time.hpp" +#include "online/http_connector.hpp" +#include "online/current_online_user.hpp" +#include "config/user_config.hpp" #include "utils/log.hpp" -GetPeerAddress::GetPeerAddress(CallbackObject* callback_object) : Protocol(callback_object, PROTOCOL_SILENT) +GetPeerAddress::GetPeerAddress(uint32_t peer_id, CallbackObject* callback_object) : Protocol(callback_object, PROTOCOL_SILENT) { + m_peer_id = peer_id; } GetPeerAddress::~GetPeerAddress() @@ -44,44 +47,35 @@ void GetPeerAddress::update() { if (m_state == NONE) { - static double target = 0; - double current_time = Time::getRealTime(); - if (current_time > target) + + 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()); + connector->setParameter("peer_id",m_peer_id); + connector->setParameter("action","get"); + + const XMLNode * result = connector->getXMLFromPage(); + std::string rec_success; + + if(result->get("success", &rec_success)) { - char url[512]; - sprintf(url, "http://stkconnect.freeserver.me/log.php?get&nick=%s", m_peer_name.c_str()); - std::string result = HTTP::getPage(url); - if (result == "") + if (rec_success == "yes") { - Log::error("GetPeerAddress", "The host you try to reach does not exist. Change the host name please.\n"); - pause(); - return; - } - std::string ip_addr = result; - ip_addr.erase(ip_addr.find_first_of(':')); - std::string port_nb = result; - port_nb.erase(0, port_nb.find_first_of(':')+1); - uint32_t dst_ip = (uint32_t)(atoi(ip_addr.c_str())); - uint16_t dst_port = (uint32_t)(atoi(port_nb.c_str())); - if (dst_ip == 0 || dst_port == 0) - { - Log::info("GetPeerAddress", "The host you try to reach is not online. There will be a new try in 10 seconds.\n"); - target = current_time+10; + TransportAddress* addr = static_cast(m_callback_object); + result->get("ip", &addr->ip); + result->get("port", &addr->port); + Log::info("GetPeerAddress", "Address gotten successfully."); } else { - Log::info("GetPeerAddress", "Public ip of target is %i.%i.%i.%i:%i\n", (dst_ip>>24)&0xff, (dst_ip>>16)&0xff, (dst_ip>>8)&0xff, dst_ip&0xff, dst_port); - uint32_t server_ip = ((dst_ip&0x000000ff)<<24) // change the server IP to have a network-byte order - + ((dst_ip&0x0000ff00)<<8) - + ((dst_ip&0x00ff0000)>>8) - + ((dst_ip&0xff000000)>>24); - uint16_t server_port = dst_port; - TransportAddress* addr = static_cast(m_callback_object); - addr->ip = server_ip; - addr->port = server_port; - m_state = DONE; + Log::error("GetPeerAddress", "Fail to get address."); } } + else + { + Log::error("GetPeerAddress", "Fail to get address."); + } + m_state = DONE; } else if (m_state == DONE) { @@ -89,7 +83,7 @@ void GetPeerAddress::update() } } -void GetPeerAddress::setPeerName(std::string peer_name) +void GetPeerAddress::setPeerID(uint32_t peer_id) { - m_peer_name = peer_name; + m_peer_id = peer_id; } diff --git a/src/network/protocols/get_peer_address.hpp b/src/network/protocols/get_peer_address.hpp index 5359d00f3..4ffab3bdb 100644 --- a/src/network/protocols/get_peer_address.hpp +++ b/src/network/protocols/get_peer_address.hpp @@ -24,16 +24,16 @@ class GetPeerAddress : public Protocol { public: - GetPeerAddress(CallbackObject* callback_object); + GetPeerAddress(uint32_t peer_id, CallbackObject* callback_object); virtual ~GetPeerAddress(); virtual void notifyEvent(Event* event); virtual void setup(); virtual void update(); - void setPeerName(std::string peer_name); + void setPeerID(uint32_t m_peer_id); protected: - std::string m_peer_name; + uint32_t m_peer_id; enum STATE { diff --git a/src/network/protocols/get_public_address.cpp b/src/network/protocols/get_public_address.cpp index 218645b2a..3ba967368 100644 --- a/src/network/protocols/get_public_address.cpp +++ b/src/network/protocols/get_public_address.cpp @@ -97,7 +97,7 @@ void GetPublicAddress::update() bytes[19] = (uint8_t)(m_stun_tansaction_id[2]); bytes[20] = '\0'; - Log::info("GetPublicAddress", "Querrying STUN server 132.177.123.6\n"); + Log::info("GetPublicAddress", "Querrying STUN server 132.177.123.6"); unsigned int dst = (132<<24)+(177<<16)+(123<<8)+6; NetworkManager::getInstance()->setManualSocketsMode(true); NetworkManager::getInstance()->getHost()->sendRawPacket(bytes, 20, TransportAddress(dst, 3478)); @@ -131,7 +131,7 @@ void GetPublicAddress::update() data[18] == (uint8_t)(m_stun_tansaction_id[2]>>8 ) && data[19] == (uint8_t)(m_stun_tansaction_id[2] )) { - Log::error("GetPublicAddress", "The STUN server responded with a valid answer\n"); + Log::info("GetPublicAddress", "The STUN server responded with a valid answer"); int message_size = data[2]*256+data[3]; // parse the stun message now: @@ -139,12 +139,12 @@ void GetPublicAddress::update() uint8_t* attributes = data+20; if (message_size == 0) { - Log::error("GetPublicAddress", "STUN answer does not contain any information.\n"); + Log::error("GetPublicAddress", "STUN answer does not contain any information."); finish = true; } if (message_size < 4) // cannot even read the size { - Log::error("GetPublicAddress", "STUN message is not valid.\n"); + Log::error("GetPublicAddress", "STUN message is not valid."); finish = true; } uint16_t port; @@ -175,14 +175,14 @@ void GetPublicAddress::update() finish = true; if (message_size < 4) // cannot even read the size { - Log::error("GetPublicAddress", "STUN message is not valid.\n"); + Log::error("GetPublicAddress", "STUN message is not valid."); finish = true; } } // finished parsing, we know our public transport address if (valid) { - Log::info("GetPublicAddress", "The public address has been found : %i.%i.%i.%i:%i\n", address>>24&0xff, address>>16&0xff, address>>8&0xff, address&0xff, port); + Log::info("GetPublicAddress", "The public address has been found : %i.%i.%i.%i:%i", address>>24&0xff, address>>16&0xff, address>>8&0xff, address&0xff, port); m_state = ADDRESS_KNOWN; NetworkManager::getInstance()->setManualSocketsMode(false); TransportAddress* addr = static_cast(m_callback_object); diff --git a/src/network/protocols/hide_public_address.cpp b/src/network/protocols/hide_public_address.cpp index 5394e8dd9..1a1b377a2 100644 --- a/src/network/protocols/hide_public_address.cpp +++ b/src/network/protocols/hide_public_address.cpp @@ -18,10 +18,12 @@ #include "network/protocols/hide_public_address.hpp" -#include "network/http_functions.hpp" +#include "online/http_connector.hpp" +#include "online/current_online_user.hpp" +#include "config/user_config.hpp" #include "utils/log.hpp" -HidePublicAddress::HidePublicAddress(CallbackObject* callback_object) : Protocol(callback_object, PROTOCOL_SILENT) +HidePublicAddress::HidePublicAddress() : Protocol(NULL, PROTOCOL_SILENT) { } @@ -42,32 +44,33 @@ void HidePublicAddress::update() { if (m_state == NONE) { - char url[512]; - sprintf(url, "http://stkconnect.freeserver.me/log.php?logout&nick=%s&pwd=%s", m_username.c_str(), m_password.c_str()); - std::string result = HTTP::getPage(url); - if (result[0] == 's' && result[1] == 'u' && result[2] == 'c' && result[3] == 'c' && result[4] == 'e' && result[5] == 's' && result[6] == 's') + 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()); + connector->setParameter("action","unset"); + + const XMLNode * result = connector->getXMLFromPage(); + std::string rec_success; + + if(result->get("success", &rec_success)) { - Log::info("HidePublicAddress", "Public address hidden successfully.\n"); - m_state = DONE; + if(rec_success == "yes") + { + Log::info("ShowPublicAddress", "Address hidden successfully."); + } + else + { + Log::error("ShowPublicAddress", "Fail to hide address."); + } } - if (result[0] == 'f' && result[1] == 'a' && result[2] == 'i' && result[3] == 'l') + else { - Log::warn("HidePublicAddress", "Public address still visible. Re-set nick:password and retry.\n"); - m_state = NONE; - pause(); + Log::error("ShowPublicAddress", "Fail to hide address."); } + m_state = DONE; } else if (m_state == DONE) { m_listener->requestTerminate(this); } } - -void HidePublicAddress::setUsername(std::string username) -{ - m_username = username; -} -void HidePublicAddress::setPassword(std::string password) -{ - m_password = password; -} diff --git a/src/network/protocols/hide_public_address.hpp b/src/network/protocols/hide_public_address.hpp index 625fc8c35..a7746d7fc 100644 --- a/src/network/protocols/hide_public_address.hpp +++ b/src/network/protocols/hide_public_address.hpp @@ -25,18 +25,14 @@ class HidePublicAddress : public Protocol { public: - HidePublicAddress(CallbackObject* callback_object); + HidePublicAddress(); virtual ~HidePublicAddress(); virtual void notifyEvent(Event* event); virtual void setup(); virtual void update(); - virtual void setUsername(std::string username); - virtual void setPassword(std::string password); protected: - std::string m_username; - std::string m_password; enum STATE { diff --git a/src/network/protocols/lobby_room_protocol.cpp b/src/network/protocols/lobby_room_protocol.cpp index 984cb77f1..5f099c224 100644 --- a/src/network/protocols/lobby_room_protocol.cpp +++ b/src/network/protocols/lobby_room_protocol.cpp @@ -19,9 +19,13 @@ #include "network/protocols/lobby_room_protocol.hpp" #include "network/network_manager.hpp" +#include "network/client_network_manager.hpp" #include "online/current_online_user.hpp" +#include "online/http_connector.hpp" +#include "config/user_config.hpp" #include "utils/log.hpp" #include "utils/random_generator.hpp" +#include "utils/time.hpp" #include @@ -73,18 +77,15 @@ void ClientLobbyRoomProtocol::notifyEvent(Event* event) return; } + uint32_t global_id = event->data.gui32(1); + NetworkPlayerProfile profile; profile.kart_name = ""; + profile.race_id = event->data.gui8(6); - profile.race_id = (uint8_t)(event->data[7]); - uint32_t global_id = 0; - global_id += (uint8_t)(event->data[2])<<24; - global_id += (uint8_t)(event->data[3])<<16; - global_id += (uint8_t)(event->data[4])<<8; - global_id += (uint8_t)(event->data[5]); if (global_id == CurrentOnlineUser::get()->getUserID()) { - Log::fatal("LobbyRoomProtocol", "The server notified me that i'm a new player in the room (not normal)."); + Log::error("LobbyRoomProtocol", "The server notified me that i'm a new player in the room (not normal)."); } else { @@ -95,7 +96,7 @@ void ClientLobbyRoomProtocol::notifyEvent(Event* event) } // new player connected else if (message_type == 0b10000001) // connection accepted { - if (event->data.size() != 7 || event->data[0] != 4 || event->data[5] != 1) // 7 bytes remains now + if (event->data.size() != 12 || event->data[0] != 1 || event->data[2] != 4 || event->data[7] != 4) // 7 bytes remains now { Log::error("LobbyRoomProtocol", "A message notifying an accepted connection wasn't formated as expected."); return; @@ -103,44 +104,36 @@ void ClientLobbyRoomProtocol::notifyEvent(Event* event) NetworkPlayerProfile profile; profile.kart_name = ""; - profile.race_id = (uint8_t)(event->data[7]); - uint32_t global_id = 0; - global_id += (uint8_t)(event->data[2])<<24; - global_id += (uint8_t)(event->data[3])<<16; - global_id += (uint8_t)(event->data[4])<<8; - global_id += (uint8_t)(event->data[5]); + 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("LobbyRoomProtocol", "The server accepted the connection."); profile.user_profile = CurrentOnlineUser::get(); m_setup->addPlayer(profile); - } - else - { - Log::fatal("LobbyRoomProtocol", "The server told you that you have a different id than yours."); + event->peer->setClientServerToken(token); } } // connection accepted else if (message_type == 0b10000000) // connection refused { - if (event->data.size() != 2 || event->data[0] != 1) // 2 bytes remains now + if (event->data.size() != 2 || event->data[0] != 1) // 2 bytes remains now { Log::error("LobbyRoomProtocol", "A message notifying a refused connection wasn't formated as expected."); return; } - else // the message is correctly made + + Log::info("LobbyRoomProtocol", "The connection has been refused."); + switch (event->data[1]) // the second byte { - Log::info("LobbyRoomProtocol", "The connection has been refused."); - switch (event->data[1]) // the second byte - { - case 0: - Log::info("LobbyRoomProtocol", "Too many clients in the race."); - break; - case 1: - Log::info("LobbyRoomProtocol", "The host has banned you."); - break; - default: - break; - } + case 0: + Log::info("LobbyRoomProtocol", "Too many clients in the race."); + break; + case 1: + Log::info("LobbyRoomProtocol", "The host has banned you."); + break; + default: + break; } } // connection refused } // if (event->type == EVENT_TYPE_MESSAGE) @@ -161,54 +154,55 @@ void ServerLobbyRoomProtocol::notifyEvent(Event* event) Log::setLogLevel(1); if (event->type == EVENT_TYPE_MESSAGE) { - if ((uint8_t)(event->data[0]) == 1) // player requesting connection + assert(event->data.size()); // message not empty + uint8_t message_type; + event->data.gui8(&message_type); + if (message_type == 1) // player requesting connection { - if (event->data.size() != 5 || event->data[1] != (char)(4)) + if (event->data.size() != 5 || event->data[0] != 4) { Log::warn("LobbyRoomProtocol", "A player is sending a badly formated message."); + return; } - else // well-formated message + Log::verbose("LobbyRoomProtocol", "New player."); + int player_id = 0; + // can we add the player ? + if (m_setup->getPlayerCount() < 16) // accept player { - Log::verbose("LobbyRoomProtocol", "New player."); - int player_id = 0; - // 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; - // 0b1000001 (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(0b1000001).ai8(4).ai32(token); - m_listener->sendMessage(this, event->peer, message_ack); - } // accept player - else // refuse the connection with code 0 (too much players) - { - NetworkString message; - message.ai8(0b10000000); // 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); - } + // 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; + // 0b1000001 (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(0b1000001).ai8(4).ai32(token).ai8(4).ai32(token); + m_listener->sendMessage(this, event->peer, message_ack); + } // accept player + else // refuse the connection with code 0 (too much players) + { + NetworkString message; + message.ai8(0b10000000); // 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 (event->type == EVENT_TYPE_MESSAGE) @@ -226,12 +220,56 @@ void ServerLobbyRoomProtocol::notifyEvent(Event* event) void ClientLobbyRoomProtocol::update() { + switch (m_state) + { + case NONE: + break; + case CONNECTED: + break; + case DONE: + m_listener->requestTerminate(this); + break; + } } //----------------------------------------------------------------------------- void ServerLobbyRoomProtocol::update() { + switch (m_state) + { + case WORKING: + static double last_poll_time = 0; + if (Time::getRealTime() > last_poll_time+5.0) + { + last_poll_time = Time::getRealTime(); + 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()); + connector->setParameter("action","poll-connection-requests"); + + const XMLNode * result = connector->getXMLFromPage(); + std::string rec_success; + + if(result->getName() == "users") + { + uint32_t id = 0; + for (unsigned int i = 0; i < result->getNumNodes(); i++) + { + result->getNode(i)->get("id", &id); + Log::info("ServerLobbyRoomProtocol", "User with id %d wants to connect.", id); + } + } + else + { + Log::error("ServerLobbyRoomProtocol", "Cannot retreive the list"); + } + } + break; + case DONE: + m_listener->requestTerminate(this); + break; + } } //----------------------------------------------------------------------------- diff --git a/src/network/protocols/lobby_room_protocol.hpp b/src/network/protocols/lobby_room_protocol.hpp index 3b86f47a3..e963f4ba0 100644 --- a/src/network/protocols/lobby_room_protocol.hpp +++ b/src/network/protocols/lobby_room_protocol.hpp @@ -62,8 +62,6 @@ class ClientLobbyRoomProtocol : public LobbyRoomProtocol enum STATE { NONE, - GETTING_SERVER_ADDRESS, - REQUESTING_CONNECTION, CONNECTED, DONE }; diff --git a/src/network/protocols/ping_protocol.cpp b/src/network/protocols/ping_protocol.cpp new file mode 100644 index 000000000..602a7a944 --- /dev/null +++ b/src/network/protocols/ping_protocol.cpp @@ -0,0 +1,33 @@ +#include "network/protocols/ping_protocol.hpp" + +#include "network/network_manager.hpp" +#include "utils/time.hpp" + +PingProtocol::PingProtocol(const TransportAddress& ping_dst, double delay_between_pings) : Protocol(NULL, PROTOCOL_SILENT) +{ + m_ping_dst = ping_dst; + m_delay_between_pings = delay_between_pings; +} + +PingProtocol::~PingProtocol() +{ +} + +void PingProtocol::notifyEvent(Event* event) +{ +} + +void PingProtocol::setup() +{ + m_last_ping_time = 0; +} + +void PingProtocol::update() +{ + if (Time::getRealTime() > m_last_ping_time+m_delay_between_pings) + { + m_last_ping_time = Time::getRealTime(); + uint8_t data = 0; + NetworkManager::getInstance()->getHost()->sendRawPacket(&data, 0, m_ping_dst); + } +} diff --git a/src/network/protocols/ping_protocol.hpp b/src/network/protocols/ping_protocol.hpp new file mode 100644 index 000000000..2001967c6 --- /dev/null +++ b/src/network/protocols/ping_protocol.hpp @@ -0,0 +1,23 @@ +#ifndef PING_PROTOCOL_HPP +#define PING_PROTOCOL_HPP + +#include "network/protocol.hpp" + + +class PingProtocol : public Protocol +{ + public: + PingProtocol(const TransportAddress& ping_dst, double delay_between_pings); + virtual ~PingProtocol(); + + virtual void notifyEvent(Event* event); + virtual void setup(); + virtual void update(); + + protected: + TransportAddress m_ping_dst; + double m_delay_between_pings; + double m_last_ping_time; +}; + +#endif // PING_PROTOCOL_HPP diff --git a/src/network/protocols/request_connection.cpp b/src/network/protocols/request_connection.cpp new file mode 100644 index 000000000..b00591ed0 --- /dev/null +++ b/src/network/protocols/request_connection.cpp @@ -0,0 +1,64 @@ +#include "network/protocols/request_connection.hpp" + +#include "online/http_connector.hpp" +#include "online/current_online_user.hpp" +#include "config/user_config.hpp" + +RequestConnection::RequestConnection(uint32_t server_id) : Protocol(NULL, PROTOCOL_SILENT) +{ + m_server_id = server_id; +} + +RequestConnection::~RequestConnection() +{ +} + +void RequestConnection::notifyEvent(Event* event) +{ +} + +void RequestConnection::setup() +{ + m_state = NONE; +} + +void RequestConnection::update() +{ + switch (m_state) + { + case 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()); + connector->setParameter("server_id",m_server_id); + connector->setParameter("action","request-connection"); + + const XMLNode * result = connector->getXMLFromPage(); + std::string rec_success; + + if(result->get("success", &rec_success)) + { + if (rec_success == "yes") + { + Log::info("RequestConnection", "Connection Request made successfully."); + } + else + { + Log::error("RequestConnection", "Fail to make a request."); + } + } + else + { + Log::error("RequestConnection", "Fail to make a request."); + } + m_state = DONE; + + break; + } + case DONE: + m_listener->requestTerminate(this); + break; + } +} + diff --git a/src/network/protocols/request_connection.hpp b/src/network/protocols/request_connection.hpp new file mode 100644 index 000000000..0b96967d0 --- /dev/null +++ b/src/network/protocols/request_connection.hpp @@ -0,0 +1,28 @@ +#ifndef REQUEST_CONNECTION_HPP +#define REQUEST_CONNECTION_HPP + +#include "network/protocol.hpp" + +class RequestConnection : public Protocol +{ + public: + RequestConnection(uint32_t server_id); + virtual ~RequestConnection(); + + virtual void notifyEvent(Event* event); + virtual void setup(); + virtual void update(); + + protected: + uint32_t m_server_id; + + enum STATE + { + NONE, + DONE + }; + STATE m_state; + +}; + +#endif // REQUEST_CONNECTION_HPP diff --git a/src/network/protocols/show_public_address.cpp b/src/network/protocols/show_public_address.cpp index bc4248c04..e1c083914 100644 --- a/src/network/protocols/show_public_address.cpp +++ b/src/network/protocols/show_public_address.cpp @@ -18,10 +18,13 @@ #include "network/protocols/show_public_address.hpp" -#include "network/http_functions.hpp" +#include "network/network_manager.hpp" +#include "online/http_connector.hpp" +#include "online/current_online_user.hpp" +#include "config/user_config.hpp" #include "utils/log.hpp" -ShowPublicAddress::ShowPublicAddress(CallbackObject* callback_object) : Protocol(callback_object, PROTOCOL_SILENT) +ShowPublicAddress::ShowPublicAddress() : Protocol(NULL, PROTOCOL_SILENT) { } @@ -36,48 +39,42 @@ void ShowPublicAddress::notifyEvent(Event* event) void ShowPublicAddress::setup() { m_state = NONE; - if (m_public_ip == 0 || m_public_port == 0 || m_username == "" || m_password == "") - { - Log::error("ShowPublicAddress", "You have to set the public ip:port, username:password and the host nickname before starting this protocol.\n"); - m_listener->requestTerminate(this); - } } void ShowPublicAddress::update() { if (m_state == NONE) { - char url[512]; - sprintf(url, "http://stkconnect.freeserver.me/log.php?set&nick=%s&ip=%u&port=%u&pwd=%s", m_username.c_str(), m_public_ip, m_public_port, m_password.c_str()); - std::string result = HTTP::getPage(url); - if (result[0] == 's' && result[1] == 'u' && result[2] == 'c' && result[3] == 'c' && result[4] == 'e' && result[5] == 's' && result[6] == 's') + 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()); + TransportAddress addr = NetworkManager::getInstance()->getPublicAddress(); + connector->setParameter("address",addr.ip); + connector->setParameter("port",addr.port); + connector->setParameter("action","set"); + + const XMLNode * result = connector->getXMLFromPage(); + std::string rec_success; + + if(result->get("success", &rec_success)) { - Log::info("ShowPublicAddress", "Address set.\n"); - m_state = DONE; + if(rec_success == "yes") + { + Log::info("ShowPublicAddress", "Address shown successfully."); + } + else + { + Log::error("ShowPublicAddress", "Fail to show address."); + } } - if (result[0] == 'f' && result[1] == 'a' && result[2] == 'i' && result[3] == 'l') + else { - Log::warn("ShowPublicAddress", "Login fail. Please re-set username:password and unpause the protocol.\n"); - m_state = NONE; - pause(); + Log::error("ShowPublicAddress", "Fail to show address."); } + m_state = DONE; } else if (m_state == DONE) { m_listener->requestTerminate(this); } } - -void ShowPublicAddress::setUsername(std::string username) -{ - m_username = username; -} -void ShowPublicAddress::setPassword(std::string password) -{ - m_password = password; -} -void ShowPublicAddress::setPublicAddress(uint32_t ip, uint16_t port) -{ - m_public_ip = ip; - m_public_port = port; -} diff --git a/src/network/protocols/show_public_address.hpp b/src/network/protocols/show_public_address.hpp index fde549e11..8406c1428 100644 --- a/src/network/protocols/show_public_address.hpp +++ b/src/network/protocols/show_public_address.hpp @@ -25,22 +25,14 @@ class ShowPublicAddress : public Protocol { public: - ShowPublicAddress(CallbackObject* callback_object); + ShowPublicAddress(); virtual ~ShowPublicAddress(); virtual void notifyEvent(Event* event); virtual void setup(); virtual void update(); - virtual void setUsername(std::string username); - virtual void setPassword(std::string password); - virtual void setPublicAddress(uint32_t ip, uint16_t port); - protected: - std::string m_username; - std::string m_password; - uint32_t m_public_ip; - uint16_t m_public_port; enum STATE { diff --git a/src/network/server_network_manager.cpp b/src/network/server_network_manager.cpp index ececdc9a7..ee5524780 100644 --- a/src/network/server_network_manager.cpp +++ b/src/network/server_network_manager.cpp @@ -50,65 +50,7 @@ void ServerNetworkManager::run() void ServerNetworkManager::start() { - m_localhost = new STKHost(); - m_localhost->setupServer(STKHost::HOST_ANY, 7321, 32, 2, 0, 0); - m_localhost->startListening(); - Log::info("ServerNetworkManager", "Server now setup, listening on port 7321.\n"); - - Log::info("ServerNetworkManager", "Starting the global protocol\n"); - // step 1 : retreive public address - Protocol* protocol = new GetPublicAddress(&m_public_address); - ProtocolManager::getInstance()->requestStart(protocol); - while (ProtocolManager::getInstance()->getProtocolState(protocol) != PROTOCOL_STATE_TERMINATED ) - { - } - Log::info("ServerNetworkManager", "The public address is known.\n"); - - // step 2 : show the public address for others (here, the server) - ShowPublicAddress* spa = new ShowPublicAddress(NULL); - spa->setPassword(m_player_login.password); - spa->setUsername(m_player_login.username); - spa->setPublicAddress(m_public_address.ip, m_public_address.port); - ProtocolManager::getInstance()->requestStart(spa); - while (ProtocolManager::getInstance()->getProtocolState(spa) != PROTOCOL_STATE_TERMINATED ) - { - } - Log::info("ServerNetworkManager", "The public address is being shown online.\n"); -} -bool ServerNetworkManager::connectToPeer(std::string peer_username) -{ - Log::info("ServerNetworkManager", "Starting the connection to host protocol\n"); - - // step 3 : get the peer's addres. - TransportAddress addr; - GetPeerAddress* gpa = new GetPeerAddress(&addr); - gpa->setPeerName(peer_username); - ProtocolManager::getInstance()->requestStart(gpa); - while (ProtocolManager::getInstance()->getProtocolState(gpa) != PROTOCOL_STATE_TERMINATED ) - { - } - Log::info("ServerNetworkManager", "The public address of the peer is known.\n"); - - // step 2 : connect to the peer - ConnectToServer* cts = new ConnectToServer(NULL); - cts->setServerAddress(addr.ip, addr.port); - ProtocolManager::getInstance()->requestStart(cts); - while (ProtocolManager::getInstance()->getProtocolState(cts) != PROTOCOL_STATE_TERMINATED ) - { - } - bool success = false; - if (isConnectedTo(addr)) - { - success = true; - Log::info("ServerNetworkManager", "Connection success : you are now connected to the peer.\n"); - } - else - { - Log::warn("ServerNetworkManager", "We are NOT connected to the peer.\n"); - } - - return success; } void ServerNetworkManager::sendPacket(const NetworkString& data) diff --git a/src/network/server_network_manager.hpp b/src/network/server_network_manager.hpp index 82cc6f8cc..2ac0a3a02 100644 --- a/src/network/server_network_manager.hpp +++ b/src/network/server_network_manager.hpp @@ -34,11 +34,10 @@ class ServerNetworkManager : public NetworkManager virtual void run(); void start(); - bool connectToPeer(std::string peer_username); virtual void sendPacket(const NetworkString& data); - virtual bool isServer() { return false; } + virtual bool isServer() { return true; } protected: ServerNetworkManager(); diff --git a/src/network/singleton.hpp b/src/network/singleton.hpp index 168d8d720..65cf27dd4 100644 --- a/src/network/singleton.hpp +++ b/src/network/singleton.hpp @@ -40,7 +40,7 @@ class Singleton S* result = (dynamic_cast (m_singleton)); if (result == NULL) - Log::fatal("Singleton", "THE SINGLETON HAS NOT BEEN REALOCATED, BUT IS NOT OF THE REQUESTED TYPE."); + Log::debug("Singleton", "THE SINGLETON HAS NOT BEEN REALOCATED, IT IS NOT OF THE REQUESTED TYPE."); return result; } static T *getInstance() diff --git a/src/network/stk_host.cpp b/src/network/stk_host.cpp index d7b71b123..e4dc12fb9 100644 --- a/src/network/stk_host.cpp +++ b/src/network/stk_host.cpp @@ -80,8 +80,8 @@ void STKHost::setupServer(uint32_t address, uint16_t port, int peer_count, max_incoming_bandwidth, max_outgoing_bandwidth); if (m_host == NULL) { - Log::info("STKHost", "An error occurred while trying to create an ENet \ - server host.\n"); + Log::error("STKHost", "An error occurred while trying to create an ENet \ + server host."); exit (EXIT_FAILURE); } } @@ -96,8 +96,8 @@ void STKHost::setupClient(int peer_count, int channel_limit, max_incoming_bandwidth, max_outgoing_bandwidth); if (m_host == NULL) { - Log::info("STKHost", "An error occurred while trying to create an ENet \ - client host.\n"); + Log::error("STKHost", "An error occurred while trying to create an ENet \ + client host."); exit (EXIT_FAILURE); } } @@ -134,6 +134,7 @@ void STKHost::sendRawPacket(uint8_t* data, int length, TransportAddress dst) to.sin_addr.s_addr = htonl(dst.ip); sendto(m_host->socket, data, length, 0,(sockaddr*)&to, to_len); + printf("Raw packet sent to %u:%u\n", dst.ip, dst.port); } // ---------------------------------------------------------------------------- @@ -186,7 +187,7 @@ uint8_t* STKHost::receiveRawPacket(TransportAddress sender) { char s[20]; inet_ntop(AF_INET, &(((struct sockaddr_in *)&addr)->sin_addr), s, 20); - Log::info("STKHost", "IPv4 Address of the sender was %s\n", s); + Log::info("STKHost", "IPv4 Address of the sender was %s", s); } return buffer; } diff --git a/src/network/stk_peer.cpp b/src/network/stk_peer.cpp index 83b972bc1..7fbe383ae 100644 --- a/src/network/stk_peer.cpp +++ b/src/network/stk_peer.cpp @@ -60,22 +60,22 @@ void STKPeer::sendPacket(NetworkString const& data) enet_peer_send(m_peer, 0, packet); } -uint32_t STKPeer::getAddress() +uint32_t STKPeer::getAddress() const { return m_peer->address.host; } -uint16_t STKPeer::getPort() +uint16_t STKPeer::getPort() const { return m_peer->address.port; } -bool STKPeer::isConnected() +bool STKPeer::isConnected() const { Log::info("STKPeer", "The peer state is %i\n", m_peer->state); return (m_peer->state == ENET_PEER_STATE_CONNECTED); } -bool STKPeer::operator==(ENetPeer* peer) +bool STKPeer::operator==(const ENetPeer* peer) const { return peer==m_peer; } diff --git a/src/network/stk_peer.hpp b/src/network/stk_peer.hpp index 244b50bea..c84ae673a 100644 --- a/src/network/stk_peer.hpp +++ b/src/network/stk_peer.hpp @@ -34,13 +34,21 @@ class STKPeer static bool connectToHost(STKHost* localhost, TransportAddress host, uint32_t channel_count, uint32_t data); - bool isConnected(); + bool isConnected() const; + void setClientServerToken(const uint32_t& token) { m_client_server_token = token; m_token_set = true; } + void unsetClientServerToken() { m_token_set = false; } + + uint32_t getAddress() const; + uint16_t getPort() const; + uint32_t getClientServerToken() const; + bool isClientServerTokenSet() const { return m_token_set; } + + bool operator==(const ENetPeer* peer) const; - uint32_t getAddress(); - uint16_t getPort(); - bool operator==(ENetPeer* peer); protected: ENetPeer* m_peer; + uint32_t m_client_server_token; + bool m_token_set; }; #endif // STK_PEER_HPP diff --git a/src/online/current_online_user.hpp b/src/online/current_online_user.hpp index 987d77a9d..fb92041ac 100644 --- a/src/online/current_online_user.hpp +++ b/src/online/current_online_user.hpp @@ -59,8 +59,9 @@ class CurrentOnlineUser : public OnlineUser bool signOut(); /** Returns the username if signed in. */ irr::core::stringw getUserName() const; - bool isSignedIn(){ return m_is_signed_in; } - bool isGuest(){ return m_is_guest; } + std::string getToken() const { return m_token; } + bool isSignedIn() { return m_is_signed_in; } + bool isGuest() { return m_is_guest; } }; // class CurrentOnlineUser diff --git a/src/online/http_connector.cpp b/src/online/http_connector.cpp index 6637fa39e..524f9efa4 100644 --- a/src/online/http_connector.cpp +++ b/src/online/http_connector.cpp @@ -80,9 +80,9 @@ std::string HTTPConnector::getPage() curl_easy_setopt(this->curl, CURLOPT_FILE, &readBuffer); res = curl_easy_perform(this->curl); if(res != CURLE_OK) - Log::error("online/http_functions", "curl_easy_perform() failed: %s", curl_easy_strerror(res)); + Log::error("online/http_functions", "curl_easy_perform() failed: \"%s\"", curl_easy_strerror(res)); else - Log::info("online/http_functions", "Received : %s", readBuffer.c_str()); + Log::info("online/http_functions", "Received : \"%s\"", readBuffer.c_str()); m_parameters.clear(); return readBuffer; } diff --git a/src/states_screens/online_screen.cpp b/src/states_screens/online_screen.cpp index 2e891b6f7..927047975 100644 --- a/src/states_screens/online_screen.cpp +++ b/src/states_screens/online_screen.cpp @@ -42,6 +42,9 @@ #include "online/current_online_user.hpp" +#include "network/protocol_manager.hpp" +#include "network/protocols/connect_to_server.hpp" + using namespace GUIEngine; @@ -192,6 +195,7 @@ void OnlineScreen::eventCallback(Widget* widget, const std::string& name, const { //if (m_recorded_state == Registered || m_recorded_state == Guest) FIXME StateManager::get()->pushScreen(NetworkingLobby::getInstance()); + ProtocolManager::getInstance()->requestStart(new ConnectToServer(3)); } } // eventCallback