diff --git a/sources.cmake b/sources.cmake index 218dab4f8..272efb21f 100644 --- a/sources.cmake +++ b/sources.cmake @@ -135,15 +135,22 @@ src/modes/tutorial_world.cpp src/modes/world.cpp src/modes/world_status.cpp src/modes/world_with_rank.cpp -src/network/connect_message.cpp -src/network/kart_control_message.cpp -src/network/kart_update_message.cpp -src/network/message.cpp -src/network/network_kart.cpp +src/network/client_network_manager.cpp +src/network/event.cpp +src/network/http_functions.cpp +src/network/network_interface.cpp src/network/network_manager.cpp -src/network/race_info_message.cpp -src/network/race_result_message.cpp -src/network/race_state.cpp +src/network/protocol.cpp +src/network/protocol_manager.cpp +src/network/protocols/connect_to_server.cpp +src/network/protocols/get_peer_address.cpp +src/network/protocols/get_public_address.cpp +src/network/protocols/hide_public_address.cpp +src/network/protocols/lobby_room_protocol.cpp +src/network/protocols/show_public_address.cpp +src/network/server_network_manager.cpp +src/network/stk_host.cpp +src/network/stk_peer.cpp src/online/current_online_user.cpp src/online/http_connector.cpp src/online/online_user.cpp @@ -192,6 +199,7 @@ src/states_screens/help_screen_4.cpp src/states_screens/kart_selection.cpp src/states_screens/main_menu_screen.cpp src/states_screens/minimal_race_gui.cpp +src/states_screens/networking_lobby.cpp src/states_screens/online_screen.cpp src/states_screens/options_screen_audio.cpp src/states_screens/options_screen_input2.cpp @@ -389,25 +397,25 @@ src/modes/tutorial_world.hpp src/modes/world.hpp src/modes/world_status.hpp src/modes/world_with_rank.hpp -src/network/character_confirm_message.hpp -src/network/character_info_message.hpp -src/network/character_selected_message.hpp -src/network/connect_message.hpp -src/network/flyable_info.hpp -src/network/item_info.hpp -src/network/kart_control_message.hpp -src/network/kart_update_message.hpp -src/network/message.hpp -src/network/network_kart.hpp +src/network/client_network_manager.hpp +src/network/event.hpp +src/network/http_functions.hpp +src/network/network_interface.hpp src/network/network_manager.hpp -src/network/num_players_message.hpp -src/network/race_info_message.hpp -src/network/race_result_ack_message.hpp -src/network/race_result_message.hpp -src/network/race_start_message.hpp -src/network/race_state.hpp +src/network/protocol.hpp +src/network/protocol_manager.hpp +src/network/protocols/connect_to_server.hpp +src/network/protocols/get_peer_address.hpp +src/network/protocols/get_public_address.hpp +src/network/protocols/hide_public_address.hpp +src/network/protocols/lobby_room_protocol.hpp +src/network/protocols/show_public_address.hpp src/network/remote_kart_info.hpp -src/network/world_loaded_message.hpp +src/network/server_network_manager.hpp +src/network/singleton.hpp +src/network/stk_host.hpp +src/network/stk_peer.hpp +src/network/types.hpp src/online/current_online_user.hpp src/online/http_connector.hpp src/online/online_user.hpp @@ -459,6 +467,7 @@ src/states_screens/help_screen_4.hpp src/states_screens/kart_selection.hpp src/states_screens/main_menu_screen.hpp src/states_screens/minimal_race_gui.hpp +src/states_screens/networking_lobby.hpp src/states_screens/online_screen.hpp src/states_screens/options_screen_audio.hpp src/states_screens/options_screen_input2.hpp diff --git a/src/io/xml_node.cpp b/src/io/xml_node.cpp index d04d9ec19..4c56d94b3 100644 --- a/src/io/xml_node.cpp +++ b/src/io/xml_node.cpp @@ -41,7 +41,7 @@ XMLNode::XMLNode(const std::string &filename) m_file_name = filename; io::IXMLReader *xml = file_manager->createXMLReader(filename); - + if (xml == NULL) { throw std::runtime_error("Cannot find file "+filename); @@ -597,4 +597,4 @@ bool XMLNode::hasChildNamed(const char* name) const if (m_nodes[i]->getName() == name) return true; } return false; -} \ No newline at end of file +} diff --git a/src/items/attachment.cpp b/src/items/attachment.cpp index 1bbbdf2cc..9e2699211 100644 --- a/src/items/attachment.cpp +++ b/src/items/attachment.cpp @@ -33,7 +33,6 @@ #include "karts/kart_properties.hpp" #include "modes/three_strikes_battle.hpp" #include "modes/world.hpp" -#include "network/race_state.hpp" #include "network/network_manager.hpp" #include "utils/constants.hpp" @@ -260,11 +259,13 @@ void Attachment::hitBanana(Item *item, int new_attachment) // Save the information about the attachment in the race state // so that the clients can be updated. - if(network_manager->getMode()==NetworkManager::NW_SERVER) + if(NetworkManager::getInstance()->isPlayingOnline()) // if we're online { + /* race_state->itemCollected(m_kart->getWorldKartId(), item->getItemId(), - new_attachment); + new_attachment);*/ +//NETWORK_UPDATE_PLZ } if (add_a_new_item) diff --git a/src/items/flyable.cpp b/src/items/flyable.cpp index d0116415d..66f78c9c1 100644 --- a/src/items/flyable.cpp +++ b/src/items/flyable.cpp @@ -38,7 +38,6 @@ #include "karts/abstract_kart.hpp" #include "karts/explosion_animation.hpp" #include "modes/world.hpp" -#include "network/flyable_info.hpp" #include "physics/physics.hpp" #include "tracks/track.hpp" #include "utils/constants.hpp" @@ -416,11 +415,13 @@ bool Flyable::updateAndDelete(float dt) */ void Flyable::updateFromServer(const FlyableInfo &f, float dt) { +/* setXYZ(f.m_xyz); setRotation(f.m_rotation); - +*/ // Update the graphical position Moveable::update(dt); + } // updateFromServer // ---------------------------------------------------------------------------- diff --git a/src/items/flyable.hpp b/src/items/flyable.hpp index bfd46835f..f15bd7cb4 100644 --- a/src/items/flyable.hpp +++ b/src/items/flyable.hpp @@ -19,6 +19,7 @@ // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +//NETWORK_UPDATE_PLZ #ifndef HEADER_FLYABLE_HPP #define HEADER_FLYABLE_HPP diff --git a/src/items/item_manager.cpp b/src/items/item_manager.cpp index 4b7fc0ad1..529fd8793 100644 --- a/src/items/item_manager.cpp +++ b/src/items/item_manager.cpp @@ -290,7 +290,7 @@ void ItemManager::collectedItem(Item *item, AbstractKart *kart, int add_info) void ItemManager::checkItemHit(AbstractKart* kart) { // Only do this on the server - if(network_manager->getMode()==NetworkManager::NW_CLIENT) return; + if(NetworkManager::getInstance()->isServer()) return; // We could use m_items_in_quads to to check for item hits: take the quad // of the graph node of the kart, and only check items in that quad. But diff --git a/src/items/powerup.cpp b/src/items/powerup.cpp index d6bd8022c..94dc7bb4d 100644 --- a/src/items/powerup.cpp +++ b/src/items/powerup.cpp @@ -16,6 +16,7 @@ // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +//NETWORK_UPDATE_PLZ #include "items/powerup.hpp" #include "audio/sfx_base.hpp" @@ -29,8 +30,6 @@ #include "karts/controller/controller.hpp" #include "karts/kart_properties.hpp" #include "modes/world.hpp" -#include "network/network_manager.hpp" -#include "network/race_state.hpp" #include "physics/triangle_mesh.hpp" #include "tracks/track.hpp" #include "utils/string_utils.hpp" diff --git a/src/items/projectile_manager.cpp b/src/items/projectile_manager.cpp index f7846b684..6ea6b8069 100644 --- a/src/items/projectile_manager.cpp +++ b/src/items/projectile_manager.cpp @@ -16,6 +16,8 @@ // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +//NETWORK_UPDATE_PLZ + #include "items/projectile_manager.hpp" #include "graphics/explosion.hpp" @@ -27,7 +29,6 @@ #include "items/powerup.hpp" #include "items/rubber_ball.hpp" #include "network/network_manager.hpp" -#include "network/race_state.hpp" ProjectileManager *projectile_manager=0; @@ -66,7 +67,8 @@ void ProjectileManager::cleanup() /** General projectile update call. */ void ProjectileManager::update(float dt) { - if(network_manager->getMode()==NetworkManager::NW_CLIENT) + + if(NetworkManager::getInstance()->isClient()) { updateClient(dt); } @@ -101,21 +103,23 @@ void ProjectileManager::update(float dt) void ProjectileManager::updateServer(float dt) { // First update all projectiles on the track - if(network_manager->getMode()!=NetworkManager::NW_NONE) + + if(NetworkManager::getInstance()->isPlayingOnline()) //network_manager->getMode()!=NetworkManager::NW_NONE) { - race_state->setNumFlyables(m_active_projectiles.size()); + //race_state->setNumFlyables(m_active_projectiles.size()); } + Projectiles::iterator p = m_active_projectiles.begin(); while(p!=m_active_projectiles.end()) { bool can_be_deleted = (*p)->updateAndDelete(dt); - if(network_manager->getMode()!=NetworkManager::NW_NONE) + if(NetworkManager::getInstance()->isPlayingOnline()) //network_manager->getMode()!=NetworkManager::NW_NONE) { - race_state->setFlyableInfo(p-m_active_projectiles.begin(), + /*race_state->setFlyableInfo(p-m_active_projectiles.begin(), FlyableInfo((*p)->getXYZ(), (*p)->getRotation(), - can_be_deleted) ); + can_be_deleted) );*/ } if(can_be_deleted) { @@ -130,6 +134,7 @@ void ProjectileManager::updateServer(float dt) else p++; } // while p!=m_active_projectiles.end() + } // updateServer // ----------------------------------------------------------------------------- @@ -138,6 +143,7 @@ void ProjectileManager::updateServer(float dt) * (i.e. position, hit effects etc) */ void ProjectileManager::updateClient(float dt) { + /* unsigned int num_projectiles = race_state->getNumFlyables(); if(num_projectiles != m_active_projectiles.size()) fprintf(stderr, "Warning: num_projectiles %d active %d\n", @@ -154,7 +160,7 @@ void ProjectileManager::updateClient(float dt) (*i)->hit(NULL); } } // for i in m_active_projectiles - + */ } // updateClient // ----------------------------------------------------------------------------- Flyable *ProjectileManager::newProjectile(AbstractKart *kart, Track* track, diff --git a/src/karts/controller/kart_control.hpp b/src/karts/controller/kart_control.hpp index 78f789e7c..01619c4d5 100644 --- a/src/karts/controller/kart_control.hpp +++ b/src/karts/controller/kart_control.hpp @@ -19,9 +19,9 @@ #ifndef HEADER_KART_CONTROL_HPP #define HEADER_KART_CONTROL_HPP -#include "network/message.hpp" +//NETWORK_UPDATE_PLZ -/** +/** * \ingroup controller */ class KartControl @@ -52,15 +52,6 @@ public: reset(); } // ------------------------------------------------------------------------ - /** Construct kart control from a Message (i.e. unserialise) */ - KartControl(Message *m) - { - m_steer = m->getFloat(); - m_accel = m->getFloat(); - char c = m->getChar(); - setButtonsCompressed(c); - } // KartControl(Message*) - // ------------------------------------------------------------------------ /** Resets all controls. */ void reset() { @@ -74,17 +65,6 @@ public: m_look_back = false; } // reset // ------------------------------------------------------------------------ - /** Return the serialised size in bytes. */ - static int getLength() { return 9; } - // ------------------------------------------------------------------------ - /** Serialises the kart control into a message. */ - void serialise(Message *m) const - { - m->addFloat(m_steer); - m->addFloat(m_accel); - m->addChar(getButtonsCompressed()); - } // compress - // ------------------------------------------------------------------------ void uncompress(char *c) { m_steer = ((float*)c)[0]; diff --git a/src/karts/controller/skidding_ai.cpp b/src/karts/controller/skidding_ai.cpp index ef3158c93..029fb8a17 100644 --- a/src/karts/controller/skidding_ai.cpp +++ b/src/karts/controller/skidding_ai.cpp @@ -298,7 +298,7 @@ void SkiddingAI::update(float dt) #endif // The client does not do any AI computations. - if(network_manager->getMode()==NetworkManager::NW_CLIENT) + if(NetworkManager::getInstance()->isClient()) { AIBaseController::update(dt); return; diff --git a/src/karts/kart.cpp b/src/karts/kart.cpp index 97dfbbf58..bbf2714a4 100644 --- a/src/karts/kart.cpp +++ b/src/karts/kart.cpp @@ -57,7 +57,6 @@ #include "karts/max_speed.hpp" #include "karts/skidding.hpp" #include "modes/linear_world.hpp" -#include "network/race_state.hpp" #include "network/network_manager.hpp" #include "physics/btKart.hpp" #include "physics/btKartRaycast.hpp" @@ -81,6 +80,8 @@ # include #endif +//NETWORK_UPDATE_PLZ + /** The kart constructor. * \param ident The identifier for the kart model to use. * \param position The position (or rank) for this kart (between 1 and @@ -877,11 +878,11 @@ void Kart::collectedItem(Item *item, int add_info) // Attachments and powerups are stored in the corresponding // functions (hit{Red,Green}Item), so only coins need to be // stored here. - if(network_manager->getMode()==NetworkManager::NW_SERVER && + /*if(NetworkManager::getInstance()->isServer() && (type==Item::ITEM_NITRO_BIG || type==Item::ITEM_NITRO_SMALL) ) { race_state->itemCollected(getWorldKartId(), item->getItemId()); - } + }*/ if ( m_collected_energy > m_kart_properties->getNitroMax()) m_collected_energy = m_kart_properties->getNitroMax(); @@ -1017,9 +1018,9 @@ void Kart::update(float dt) // Store the actual kart controls at the start of update in the server // state. This makes it easier to reset some fields when they are not used // anymore (e.g. controls.fire). - if(network_manager->getMode()==NetworkManager::NW_SERVER) + if(NetworkManager::getInstance()->isServer()) { - race_state->storeKartControls(*this); + //race_state->storeKartControls(*this); } if (!m_flying) @@ -1836,10 +1837,8 @@ void Kart::updatePhysics(float dt) updateSliding(); - // Only compute the current speed if this is not the client. On a client the - // speed is actually received from the server. - if(network_manager->getMode()!=NetworkManager::NW_CLIENT) - m_speed = getVehicle()->getRigidBody()->getLinearVelocity().length(); + // Compute the speed of the kart. + m_speed = getVehicle()->getRigidBody()->getLinearVelocity().length(); // calculate direction of m_speed const btTransform& chassisTrans = getVehicle()->getChassisWorldTransform(); diff --git a/src/main.cpp b/src/main.cpp index 9af900f6b..3a20a3610 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -169,6 +169,8 @@ #include "modes/demo_world.hpp" #include "modes/profile_world.hpp" #include "network/network_manager.hpp" +#include "network/client_network_manager.hpp" +#include "network/server_network_manager.hpp" #include "race/grand_prix_manager.hpp" #include "race/highscore_manager.hpp" #include "race/history.hpp" @@ -681,22 +683,17 @@ int handleCmdLine(int argc, char **argv) } else if(sscanf(argv[i], "--server=%d",&n)==1) { - network_manager->setMode(NetworkManager::NW_SERVER); + NetworkManager::getInstance(); //create the server UserConfigParams::m_server_port = n; } else if( !strcmp(argv[i], "--server") ) { - network_manager->setMode(NetworkManager::NW_SERVER); + NetworkManager::getInstance(); } else if( sscanf(argv[i], "--port=%d", &n) ) { UserConfigParams::m_server_port=n; } - else if( sscanf(argv[i], "--client=%1023s", s) ) - { - network_manager->setMode(NetworkManager::NW_CLIENT); - UserConfigParams::m_server_address=s; - } else if ( sscanf(argv[i], "--gfx=%d", &n) ) { if (n) @@ -1170,9 +1167,10 @@ 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 (); - network_manager = new NetworkManager (); KartPropertiesManager::addKartSearchDir( file_manager->getAddonsFile("karts/")); track_manager->addTrackSearchDir( @@ -1219,7 +1217,8 @@ void cleanSuperTuxKart() INetworkHttp::destroy(); if(news_manager) delete news_manager; if(addons_manager) delete addons_manager; - if(network_manager) delete network_manager; + NetworkManager::kill(); + if(grand_prix_manager) delete grand_prix_manager; if(highscore_manager) delete highscore_manager; if(attachment_manager) delete attachment_manager; @@ -1477,7 +1476,7 @@ int main(int argc, char *argv[] ) { // This will setup the race manager etc. history->Load(); - network_manager->setupPlayerKartInfo(); +// network_manager->setupPlayerKartInfo(); race_manager->startNew(false); main_loop->run(); // well, actually run() will never return, since @@ -1486,20 +1485,6 @@ int main(int argc, char *argv[] ) exit(-3); } - // Initialise connection in case that a command line option was set - // configuring a client or server. Otherwise this function does nothing - // here (and will be called again from the network gui). - if(!network_manager->initialiseConnections()) - { - Log::error("main", "Problems initialising network connections,\n" - "Running in non-network mode."); - } - // On the server start with the network information page for now - if(network_manager->getMode()==NetworkManager::NW_SERVER) - { - // TODO - network menu - //menu_manager->pushMenu(MENUID_NETWORK_GUI); - } // Not replaying // ============= if(!ProfileWorld::isProfileMode()) @@ -1509,7 +1494,7 @@ int main(int argc, char *argv[] ) // Quickstart (-N) // =============== // all defaults are set in InitTuxkart() - network_manager->setupPlayerKartInfo(); +// network_manager->setupPlayerKartInfo(); race_manager->startNew(false); } } @@ -1519,7 +1504,7 @@ int main(int argc, char *argv[] ) // ========= race_manager->setMajorMode (RaceManager::MAJOR_MODE_SINGLE); race_manager->setDifficulty(RaceManager::DIFFICULTY_HARD); - network_manager->setupPlayerKartInfo(); +// network_manager->setupPlayerKartInfo(); race_manager->startNew(false); } main_loop->run(); diff --git a/src/main_loop.cpp b/src/main_loop.cpp index 6fc66e13d..321626bad 100644 --- a/src/main_loop.cpp +++ b/src/main_loop.cpp @@ -98,17 +98,17 @@ void MainLoop::updateRace(float dt) // Client: send current controls to server // But don't do this if the race is in finish phase (otherwise // messages can be mixed up in the race manager) - if(!World::getWorld()->isFinishPhase()) - network_manager->sendUpdates(); + /*if(!World::getWorld()->isFinishPhase()) + network_manager->sendUpdates();*/ if(ProfileWorld::isProfileMode()) dt=1.0f/60.0f; // Again, only receive updates if the race isn't over - once the // race results are displayed (i.e. game is in finish phase) // messages must be handled by the normal update of the network // manager - if(!World::getWorld()->isFinishPhase()) - network_manager->receiveUpdates(); - + /*if(!World::getWorld()->isFinishPhase()) + network_manager->receiveUpdates();*/ + World::getWorld()->updateWorld(dt); } // updateRace @@ -127,13 +127,13 @@ void MainLoop::run() m_prev_time = m_curr_time; float dt = getLimitedDt(); - network_manager->update(dt); +// network_manager->update(dt); if (World::getWorld()) // race is active if world exists { // Busy wait if race_manager is active (i.e. creating of world is done) // till all clients have reached this state. - if (network_manager->getState()==NetworkManager::NS_READY_SET_GO_BARRIER) continue; + //if (network_manager->getState()==NetworkManager::NS_READY_SET_GO_BARRIER) continue; updateRace(dt); } // if race is active diff --git a/src/modes/demo_world.cpp b/src/modes/demo_world.cpp index 681382e7e..4801ab4cd 100644 --- a/src/modes/demo_world.cpp +++ b/src/modes/demo_world.cpp @@ -149,7 +149,7 @@ bool DemoWorld::updateIdleTimeAndStartDemo(float dt) m_do_demo = true; race_manager->setNumKarts(m_num_karts); race_manager->setLocalKartInfo(0, "tux"); - network_manager->setupPlayerKartInfo(); +// network_manager->setupPlayerKartInfo(); race_manager->startSingleRace(m_demo_tracks[0], m_num_laps, false); m_demo_tracks.push_back(m_demo_tracks[0]); m_demo_tracks.erase(m_demo_tracks.begin()); diff --git a/src/modes/linear_world.cpp b/src/modes/linear_world.cpp index d7aa84f17..610f4d629 100644 --- a/src/modes/linear_world.cpp +++ b/src/modes/linear_world.cpp @@ -322,10 +322,10 @@ void LinearWorld::newLap(unsigned int kart_index) // A client does not detect race finished by itself, it will // receive a message from the server. So a client does not do // anything here. - if(network_manager->getMode()!=NetworkManager::NW_CLIENT) + /*if(network_manager->getMode()!=NetworkManager::NW_CLIENT) { kart->finishedRace(getTime()); - } + }*/ } float time_per_lap; if (kart_info.m_race_lap == 1) // just completed first lap diff --git a/src/modes/overworld.cpp b/src/modes/overworld.cpp index 35c395d59..3a569810e 100644 --- a/src/modes/overworld.cpp +++ b/src/modes/overworld.cpp @@ -83,7 +83,7 @@ void OverWorld::enterOverWorld() ->setSinglePlayer( StateManager::get()->getActivePlayer(0) ); StateManager::get()->enterGameState(); - network_manager->setupPlayerKartInfo(); +// network_manager->setupPlayerKartInfo(); race_manager->startNew(false); if(race_manager->haveKartLastPositionOnOverworld()){ OverWorld *ow = (OverWorld*)World::getWorld(); diff --git a/src/modes/world.cpp b/src/modes/world.cpp index e28424c51..e5492d51c 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" @@ -119,7 +117,7 @@ World::World() : WorldStatus(), m_clear_color(255,100,101,140) */ void World::init() { - race_state = new RaceState(); +// race_state = new RaceState(); m_faster_music_active = false; m_fastest_kart = 0; m_eliminated_karts = 0; @@ -175,7 +173,7 @@ void World::init() if(ReplayPlay::get()) ReplayPlay::get()->Load(); - network_manager->worldLoaded(); +// network_manager->worldLoaded(); powerup_manager->updateWeightsForRace(num_karts); } // init @@ -361,7 +359,7 @@ World::~World() // gui and this must be deleted. delete m_race_gui; } - delete race_state; +// delete race_state; for ( unsigned int i = 0 ; i < m_karts.size() ; i++ ) delete m_karts[i]; @@ -749,7 +747,7 @@ void World::updateWorld(float dt) ->setSinglePlayer( StateManager::get()->getActivePlayer(0) ); StateManager::get()->enterGameState(); - network_manager->setupPlayerKartInfo(); +// network_manager->setupPlayerKartInfo(); race_manager->startNew(false); } else @@ -803,10 +801,10 @@ void World::update(float dt) if(history->replayHistory()) dt=history->getNextDelta(); WorldStatus::update(dt); // Clear race state so that new information can be stored - race_state->clear(); +// race_state->clear(); - if(network_manager->getMode()!=NetworkManager::NW_CLIENT && - !history->dontDoPhysics()) +// if(network_manager->getMode()!=NetworkManager::NW_CLIENT && +// !history->dontDoPhysics()) { m_physics->update(dt); } diff --git a/src/modes/world_status.cpp b/src/modes/world_status.cpp index 522d0e01e..d3f4389e9 100644 --- a/src/modes/world_status.cpp +++ b/src/modes/world_status.cpp @@ -112,8 +112,8 @@ void WorldStatus::enterRaceOverState() */ void WorldStatus::terminateRace() { - if(network_manager->getMode()==NetworkManager::NW_SERVER) - network_manager->sendRaceResults(); +// if(network_manager->getMode()==NetworkManager::NW_SERVER) +// network_manager->sendRaceResults(); } // terminateRace //----------------------------------------------------------------------------- diff --git a/src/network/character_confirm_message.hpp b/src/network/character_confirm_message.hpp deleted file mode 100644 index 527794928..000000000 --- a/src/network/character_confirm_message.hpp +++ /dev/null @@ -1,71 +0,0 @@ -// -// SuperTuxKart - a fun racing game with go-kart -// Copyright (C) 2008 Joerg Henrichs -// -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License -// as published by the Free Software Foundation; either version 3 -// of the License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -#ifndef HEADER_CHARACTER_CONFIRM_MESSAGE_HPP -#define HEADER_CHARACTER_CONFIRM_MESSAGE_HPP - -#include - -#include "network/message.hpp" - - -/** This message is from the server to all clients to inform them about a - * newly selected character. This means that this character is not available - * anymore. The message contains the hostid of the client who selected this - * character (0 in case of server), so that this message acts as a - * confirmation for the corresponding client (or a reject if the message has - * a different hostid, meaning that another client selected the character - * earlier). - */ -class CharacterConfirmMessage : public Message -{ -private: - /** The host id. */ - int m_host_id; - /** Name of the selected kart. */ - std::string m_kart_name; -public: - /** Constructor, takes the name of the kart name and the host id. - * \param kart_name Name of the kart. - * \param host_id Id of the host who selected this character. - */ - CharacterConfirmMessage(const std::string &kart_name, int host_id) - : Message(Message::MT_CHARACTER_CONFIRM) - { - allocate(getStringLength(kart_name) + getCharLength()); - addString(kart_name); - addChar(host_id); - } // CharacterConfirmMessage - - // ------------------------------------------------------------------------ - /** Unpacks a character confirm message. - * \param pkt Received enet packet. - */ - CharacterConfirmMessage(ENetPacket* pkt):Message(pkt, MT_CHARACTER_CONFIRM) - { - m_kart_name = getString(); - m_host_id = getChar(); - } // CharacterConfirmMessage(EnetPacket) - // ------------------------------------------------------------------------ - /** Returns the kart name contained in a received message. */ - const std::string &getKartName() const { return m_kart_name; } - /** Returns the host id contained in a received message. */ - int getHostId() const { return m_host_id; } - -}; // CharacterConfirmMessage -#endif diff --git a/src/network/character_info_message.hpp b/src/network/character_info_message.hpp deleted file mode 100644 index 443a2d670..000000000 --- a/src/network/character_info_message.hpp +++ /dev/null @@ -1,50 +0,0 @@ -// -// SuperTuxKart - a fun racing game with go-kart -// Copyright (C) 2008 Joerg Henrichs -// -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License -// as published by the Free Software Foundation; either version 3 -// of the License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -#ifndef HEADER_CHARACTER_INFO_MESSAGE_HPP -#define HEADER_CHARACTER_INFO_MESSAGE_HPP - -#include "karts/kart_properties_manager.hpp" -#include "network/message.hpp" - -/** This message is sent from the server to the clients and contains the list - * of available characters. Additionally, it contains the clients id. - */ -class CharacterInfoMessage : public Message -{ -// Add the remote host id to this message (to avoid sending this separately) -public: - CharacterInfoMessage(int hostid) : Message(Message::MT_CHARACTER_INFO) - { - std::vector all_karts = - kart_properties_manager->getAllAvailableKarts(); - allocate(getCharLength()+getStringVectorLength(all_karts)); - addChar(hostid); - addStringVector(all_karts); - } - // ------------------------------------------------------------------------ - CharacterInfoMessage(ENetPacket* pkt):Message(pkt, MT_CHARACTER_INFO) - { - int hostid=getChar(); - network_manager->setHostId(hostid); - std::vector all_karts; - all_karts = getStringVector(); - kart_properties_manager->setUnavailableKarts(all_karts); - } -}; // CharacterInfoMessage -#endif diff --git a/src/network/character_selected_message.hpp b/src/network/character_selected_message.hpp deleted file mode 100644 index 9e8a61961..000000000 --- a/src/network/character_selected_message.hpp +++ /dev/null @@ -1,105 +0,0 @@ -// -// SuperTuxKart - a fun racing game with go-kart -// Copyright (C) 2008 Joerg Henrichs -// -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License -// as published by the Free Software Foundation; either version 3 -// of the License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -#ifndef HEADER_CHARACTER_SELECTED_MESSAGE_HPP -#define HEADER_CHARACTER_SELECTED_MESSAGE_HPP - -#include "network/message.hpp" -#include "network/remote_kart_info.hpp" -#include "race/race_manager.hpp" - -/** This message is send contains information about selected karts. It is send - * from the client to the server to indicate a selected kart, and from the - * server to the clients to indicate that a kart was selected. In the latter - * case it contains the hostid of the successful selecter. This way a client - * selecting a kart can check if its selection was successful or not, and - * other clients are informed that a certain kart is not available anymore. - */ -class CharacterSelectedMessage : public Message -{ -private: - /** Number of local players on a host. If the message is send from the - * server to the clients, this field instead contains the host id of - * the host which selected the kart - */ - int m_num_local_players; - /** Stores information about the selected kart. */ - RemoteKartInfo m_kart_info; - -public: - /** Contains information about a selected kart. When send from the client - * to the server, it contains the number of local players (which - * technically needs only to be sent once); when send from from the server - * to the clients this field instead contains the host id of the host - * selected the character. This allows the client to detect if a selected - * kart was not confirmed by the server (i.e. another client or the server - * has selected the kart first - * \param player_id The local player id. - * \param host_id If this value is specified (>-1), then this value is - * used in the message instead of the number of local - * players. - */ - CharacterSelectedMessage(int player_id, int host_id=-1) - : Message(Message::MT_CHARACTER_INFO) - { - m_kart_info = race_manager->getLocalKartInfo(player_id); - m_num_local_players = race_manager->getNumLocalPlayers(); - - allocate(getCharLength() // m_kart_info.getLocalPlayerId()) - +getStringLength(m_kart_info.getKartName()) - +m_kart_info.getPlayerName().size() + 1 // FIXME: encoding issues - +getCharLength()); // m_num_local_players) - addChar(m_kart_info.getLocalPlayerId()); - addString(m_kart_info.getKartName()); - addString(core::stringc(m_kart_info.getPlayerName().c_str()).c_str()); // FIXME: encoding issues - // Piggy backing this information saves sending it as a separate - // message. It is actually only required in the first message - if(host_id>-1) - addChar(host_id); - else - addChar(race_manager->getNumLocalPlayers()); - } // CharacterSelectedMessage - - // ------------------------------------------------------------------------ - /** Unpacks a character selected message. The additional field is either - * the number of local players (when send from client to server), or the - * hostid of the host selected the character. - * \param pkt Received enet packet. - */ - CharacterSelectedMessage(ENetPacket* pkt):Message(pkt, MT_CHARACTER_INFO) - { - m_kart_info.setLocalPlayerId(getChar()); - m_kart_info.setKartName(getString()); - m_kart_info.setPlayerName(core::stringw(getString().c_str())); // FIXME: encoding issues - m_num_local_players = getChar(); - } // CharacterSelectedMessage(EnetPacket) - - // ------------------------------------------------------------------------ - /** Returns the remote kart info structure of the selected kart. */ - const RemoteKartInfo& getKartInfo () const { return m_kart_info; } - - /** Returns the number of local players. */ - int getNumPlayers() const { return m_num_local_players; } - - /** Returns the host id of the host who selected the kart successfully. - * This information is actually stored in m_num_local_players field, which - * is used when a client receives this message. - */ - int getHostId () const { return m_num_local_players; } -}; // CharacterSelectedMessage -#endif diff --git a/src/network/client_network_manager.cpp b/src/network/client_network_manager.cpp new file mode 100644 index 000000000..fd98e9ca5 --- /dev/null +++ b/src/network/client_network_manager.cpp @@ -0,0 +1,123 @@ +// +// SuperTuxKart - a fun racing game with go-kart +// Copyright (C) 2013 SuperTuxKart-Team +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 3 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +#include "network/client_network_manager.hpp" + +#include "network/protocols/get_public_address.hpp" +#include "network/protocols/hide_public_address.hpp" +#include "network/protocols/show_public_address.hpp" +#include "network/protocols/get_peer_address.hpp" +#include "network/protocols/connect_to_server.hpp" + +#include "utils/log.hpp" + +ClientNetworkManager::ClientNetworkManager() +{ +} + +ClientNetworkManager::~ClientNetworkManager() +{ +} + +void ClientNetworkManager::run() +{ + if (enet_initialize() != 0) + { + Log::error("ClientNetworkManager", "Could not initialize enet.\n"); + return; + } + m_localhost = new STKHost(); + m_localhost->setupClient(1, 2, 0, 0); + m_localhost->startListening(); + + 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 char* data) +{ + if (m_peers.size() > 1) + Log::warn("ClientNetworkManager", "Ambiguous send of data.\n"); + m_peers[0]->sendPacket(data); +} + +STKPeer* ClientNetworkManager::getPeer() +{ + return m_peers[0]; +} diff --git a/src/network/client_network_manager.hpp b/src/network/client_network_manager.hpp new file mode 100644 index 000000000..33704187a --- /dev/null +++ b/src/network/client_network_manager.hpp @@ -0,0 +1,47 @@ +// +// SuperTuxKart - a fun racing game with go-kart +// Copyright (C) 2013 SuperTuxKart-Team +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 3 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +#ifndef CLIENT_NETWORK_MANAGER_HPP +#define CLIENT_NETWORK_MANAGER_HPP + +#include "network/network_manager.hpp" + +class ClientNetworkManager : public NetworkManager +{ + friend class Singleton; + public: + static ClientNetworkManager* getInstance() + { + return Singleton::getInstance(); + } + + virtual void run(); + + bool connectToHost(std::string serverNickname); + + virtual void sendPacket(const char* data); + + STKPeer* getPeer(); + virtual bool isServer() { return false; } + + protected: + ClientNetworkManager(); + virtual ~ClientNetworkManager(); +}; + +#endif // CLIENT_NETWORK_MANAGER_HPP diff --git a/src/network/connect_message.cpp b/src/network/connect_message.cpp deleted file mode 100644 index 03660c158..000000000 --- a/src/network/connect_message.cpp +++ /dev/null @@ -1,77 +0,0 @@ -// -// SuperTuxKart - a fun racing game with go-kart -// Copyright (C) 2008 Joerg Henrichs -// -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License -// as published by the Free Software Foundation; either version 3 -// of the License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -#include "network/connect_message.hpp" - -#include -#include -#include -#ifndef WIN32 -# include -#endif - -#include "config/player.hpp" -#include "karts/kart_properties_manager.hpp" -#include "states_screens/state_manager.hpp" -#include "tracks/track_manager.hpp" - -// ---------------------------------------------------------------------------- -/** Creates the connect message. It includes the id of the client (currently - * player name @ hostname), and the list of available tracks. - */ -ConnectMessage::ConnectMessage() : Message(MT_CONNECT) -{ - setId(); - const std::vector &all_tracks = - track_manager->getAllTrackIdentifiers(); - std::vector all_karts = - kart_properties_manager->getAllAvailableKarts(); - allocate(getStringLength(m_id) + getStringVectorLength(all_tracks) - + getStringVectorLength(all_karts)); - addString(m_id); - addStringVector(all_tracks); - addStringVector(all_karts); -} // ConnectMessage - -// ---------------------------------------------------------------------------- -/** Unpacks a connect message. The id of the client is stored in this object, - * and the list of tracks is used to set tracks that are not available on - * the client to be 'unavailable' on the server. - * \param pkt Enet packet. - */ -ConnectMessage::ConnectMessage(ENetPacket* pkt):Message(pkt, MT_CONNECT) -{ - m_id = getString(); - std::vector all_tracks = getStringVector(); - std::vector all_karts = getStringVector(); - track_manager->setUnavailableTracks(all_tracks); - kart_properties_manager->setUnavailableKarts(all_karts); -} // ConnectMessage - -// ---------------------------------------------------------------------------- -/** Sets the id, i.e. player name @ hostname, of this client. - */ -void ConnectMessage::setId() -{ - char hostname[256]; - gethostname(hostname, 255); - const std::string& id = core::stringc(StateManager::get()->getActivePlayerProfile(0)->getName()).c_str(); - std::ostringstream o; - o << id << '@' << hostname; - m_id = o.str(); -} // ConnectMessage diff --git a/src/network/event.cpp b/src/network/event.cpp new file mode 100644 index 000000000..e6a34aae5 --- /dev/null +++ b/src/network/event.cpp @@ -0,0 +1,74 @@ +// +// SuperTuxKart - a fun racing game with go-kart +// Copyright (C) 2013 SuperTuxKart-Team +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 3 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +#include "network/event.hpp" +#include "network/network_manager.hpp" + +Event::Event(ENetEvent* event) +{ + switch (event->type) + { + case ENET_EVENT_TYPE_CONNECT: + type = EVENT_TYPE_CONNECTED; + break; + case ENET_EVENT_TYPE_DISCONNECT: + type = EVENT_TYPE_DISCONNECTED; + break; + case ENET_EVENT_TYPE_RECEIVE: + type = EVENT_TYPE_MESSAGE; + break; + default: + break; + } + if (type == EVENT_TYPE_MESSAGE) + data = std::string((char*)(event->packet->data)); + else if (event->data) + data = std::string((char*)(event->data)); + + if (event->packet) + m_packet = event->packet; + + std::vector peers = NetworkManager::getInstance()->getPeers(); + peer = NULL; + for (unsigned int i = 0; i < peers.size(); i++) + { + if (*peers[i] == event->peer) + { + peer = peers[i]; + return; + } + } + if (peer == NULL) // peer does not exist, create him + { + STKPeer* new_peer = new STKPeer(); + new_peer->m_peer = event->peer; + peer = new_peer; + } +} + +Event::~Event() +{ + if (m_packet) + enet_packet_destroy(m_packet); +} + +void Event::removeFront(int size) +{ + data.erase(0, size); +} + diff --git a/src/network/event.hpp b/src/network/event.hpp new file mode 100644 index 000000000..8aa1939b1 --- /dev/null +++ b/src/network/event.hpp @@ -0,0 +1,72 @@ +// +// SuperTuxKart - a fun racing game with go-kart +// Copyright (C) 2013 SuperTuxKart-Team +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 3 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +#ifndef EVENT_HPP +#define EVENT_HPP + +#include "network/stk_peer.hpp" +#include +#include + +/*! + * \enum EVENT_TYPE + * \brief Represents a network event type. + */ +enum EVENT_TYPE +{ + EVENT_TYPE_CONNECTED, //!< A peer is connected + EVENT_TYPE_DISCONNECTED,//!< A peer is disconnected + EVENT_TYPE_MESSAGE //!< A message between server and client protocols +}; + +/*! + * \class Event + * \brief Class representing an event that need to pass trough the system. + * 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 + * all times, and then the user of this class can rely only on the address/port + * of the peer, and not on values that might change over time. + */ +class Event +{ + public: + /*! \brief Constructor + * \param event : The event that needs to be translated. + */ + Event(ENetEvent* 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. + std::string 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. +}; + +#endif // EVENT_HPP diff --git a/src/network/flyable_info.hpp b/src/network/flyable_info.hpp deleted file mode 100644 index eedc33585..000000000 --- a/src/network/flyable_info.hpp +++ /dev/null @@ -1,70 +0,0 @@ -// -// SuperTuxKart - a fun racing game with go-kart -// Copyright (C) 2008 Joerg Henrichs -// -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License -// as published by the Free Software Foundation; either version 3 -// of the License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -#ifndef HEADER_FLYABLE_INFO_HPP -#define HEADER_FLYABLE_INFO_HPP - -#include "network/message.hpp" - -/** Class used to transfer information about projectiles from server to client. - * It contains only the coordinates, rotation, and explosion state. - */ -class FlyableInfo -{ -public: - Vec3 m_xyz; /** Position of object. */ - btQuaternion m_rotation; /** Orientation of object */ - bool m_exploded; /** If the object exploded in the current frame. */ - - /** Constructor to initialise all fields. - */ - FlyableInfo(const Vec3& xyz, const btQuaternion &rotation, bool exploded) : - m_xyz(xyz), m_rotation(rotation), m_exploded(exploded) - {}; - // ------------------------------------------------------------------------ - /** Allow this object to be stored in std::vector fields. - */ - FlyableInfo() {}; - // ------------------------------------------------------------------------ - /** Construct a FlyableInfo from a message (which is unpacked). - */ - FlyableInfo(Message *m) - { - m_xyz = m->getVec3(); - m_rotation = m->getQuaternion(); - m_exploded = m->getBool(); - } // FlyableInfo(Message) - // ------------------------------------------------------------------------ - /** Returns the length of the serialised message. */ - static int getLength() - { - return Message::getVec3Length() - + Message::getQuaternionLength() - + Message::getBoolLength(); - } // getLength - // ------------------------------------------------------------------------ - void serialise(Message *m) - { - m->addVec3(m_xyz); - m->addQuaternion(m_rotation); - m->addBool(m_exploded); - } // serialise -}; - -#endif - diff --git a/src/network/http_functions.cpp b/src/network/http_functions.cpp new file mode 100644 index 000000000..8ff861a05 --- /dev/null +++ b/src/network/http_functions.cpp @@ -0,0 +1,67 @@ +// +// SuperTuxKart - a fun racing game with go-kart +// Copyright (C) 2013 SuperTuxKart-Team +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 3 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +#include "network/http_functions.hpp" + +#include "utils/log.hpp" + +#include +#include +#include +#include +#include + +namespace HTTP +{ +CURL *curl; +CURLcode res; + +static size_t WriteCallback(void *contents, size_t size, size_t nmemb, void *userp) +{ + ((std::string*)userp)->append((char*)contents, size * nmemb); + return size * nmemb; +} + +void init() +{ + curl_global_init(CURL_GLOBAL_DEFAULT); + curl = curl_easy_init(); + if(!curl) + Log::error("HTTP", "Error while loading cURL library.\n"); +} + +std::string getPage(std::string url) +{ + std::string readBuffer; + curl_easy_setopt(curl, CURLOPT_URL, url.c_str()); + curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteCallback); + curl_easy_setopt(curl, CURLOPT_WRITEDATA, &readBuffer); + res = curl_easy_perform(curl); + if(res != CURLE_OK) + Log::error("HTTP", "curl_easy_perform() failed: %s\n", curl_easy_strerror(res)); + + return readBuffer; +} + +void shutdown() +{ + curl_easy_cleanup(curl); + curl_global_cleanup(); +} + +} diff --git a/src/network/kart_update_message.hpp b/src/network/http_functions.hpp similarity index 72% rename from src/network/kart_update_message.hpp rename to src/network/http_functions.hpp index 7d3a38fc4..970b9c1dd 100644 --- a/src/network/kart_update_message.hpp +++ b/src/network/http_functions.hpp @@ -1,6 +1,6 @@ // // SuperTuxKart - a fun racing game with go-kart -// Copyright (C) 2008 Joerg Henrichs +// Copyright (C) 2013 SuperTuxKart-Team // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License @@ -16,15 +16,20 @@ // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -#ifndef HEADER_KART_UPDATE_MESSAGE_HPP -#define HEADER_KART_UPDATE_MESSAGE_HPP +#ifndef HTTP_FUNCTIONS_HPP +#define HTTP_FUNCTIONS_HPP -#include "network/message.hpp" +#include -class KartUpdateMessage : public Message +namespace HTTP { -public: - KartUpdateMessage(); - KartUpdateMessage(ENetPacket* pkt); -}; // KartUpdateMessage -#endif + +void init(); +void shutdown(); + +std::string getPage(std::string url); + + +} + +#endif // HTTP_FUNCTIONS_HPP diff --git a/src/network/item_info.hpp b/src/network/item_info.hpp deleted file mode 100644 index 0334e2ee0..000000000 --- a/src/network/item_info.hpp +++ /dev/null @@ -1,66 +0,0 @@ -// -// SuperTuxKart - a fun racing game with go-kart -// Copyright (C) 2008 Joerg Henrichs -// -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License -// as published by the Free Software Foundation; either version 3 -// of the License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -#ifndef HEADER_ITEM_INFO_HPP -#define HEADER_ITEM_INFO_HPP -/** Class used to transfer information about collected items from -* server to client. -*/ -class ItemInfo -{ -public: - /** Kart id (in world) of the kart collecting the item. */ - unsigned char m_kart_id; - /** Index of the collected item. This is set to -1 if a kart - * triggers a rescue (i.e. attaches the butterfly).] - */ - short m_item_id; - /** Additional info used, depending on item type. This is usually - * the type of the collected item. - */ - char m_add_info; - - /** Constructor to initialise all fields. */ - ItemInfo(int kart, int item, char add_info) : - m_kart_id(kart), m_item_id(item), - m_add_info(add_info) - {} - // ------------------------------------------------------------- - /** Construct ItemInfo from a message (which is unpacked). */ - ItemInfo(Message *m) - { - m_kart_id = m->getChar(); - m_item_id = m->getShort(); - m_add_info = m->getChar(); - } - // ------------------------------------------------------------- - /*** Returns size in bytes necessary to store ItemInfo. */ - static int getLength() {return 2*Message::getCharLength() - + Message::getShortLength();} - // ------------------------------------------------------------- - /** Serialises this object into the message object */ - void serialise(Message *m) - { - m->addChar(m_kart_id); - m->addShort(m_item_id); - m->addChar(m_add_info); - } // serialise -}; // ItemInfo - -#endif - diff --git a/src/network/kart_control_message.cpp b/src/network/kart_control_message.cpp deleted file mode 100644 index db6cea020..000000000 --- a/src/network/kart_control_message.cpp +++ /dev/null @@ -1,61 +0,0 @@ -// -// SuperTuxKart - a fun racing game with go-kart -// Copyright (C) 2008 Joerg Henrichs -// -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License -// as published by the Free Software Foundation; either version 3 -// of the License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -#include "network/kart_control_message.hpp" - -#include "karts/controller/controller.hpp" -#include "modes/world.hpp" -#include "network/network_kart.hpp" - -KartControlMessage::KartControlMessage() - : Message(Message::MT_KART_CONTROL) -{ - World *world=World::getWorld(); - unsigned int num_local_players = race_manager->getNumLocalPlayers(); - unsigned int control_size = KartControl::getLength(); - allocate(control_size*num_local_players); - for(unsigned int i=0; igetLocalPlayerKart(i); - const KartControl& controls = kart->getControls(); - controls.serialise(this); - } -} // KartControlMessage -// ---------------------------------------------------------------------------- -/** Receives a kart control message. - * \param kart_id_offset is the global id of the first kart on the host from - * which this packet was received. - */ -KartControlMessage::KartControlMessage(ENetPacket* pkt, int kart_id_offset, - int num_local_players) - : Message(pkt, MT_KART_CONTROL) -{ - // FIXME: This probably does not work anymore - it assume that - // num_local_Players is the number of all local karts, while it might - // only be the number of all network karts. - for(int i=kart_id_offset; igetKart(i); - if(kart->getController()->isNetworkController()) - { - ((NetworkKart*)kart)->setControl(kc); - } - } -}; // KartControlMessage - diff --git a/src/network/kart_update_message.cpp b/src/network/kart_update_message.cpp deleted file mode 100644 index 2b16cc0e9..000000000 --- a/src/network/kart_update_message.cpp +++ /dev/null @@ -1,62 +0,0 @@ -// -// SuperTuxKart - a fun racing game with go-kart -// Copyright (C) 2008 Joerg Henrichs -// -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License -// as published by the Free Software Foundation; either version 3 -// of the License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -#include "network/kart_update_message.hpp" - -#include "karts/abstract_kart.hpp" -#include "modes/world.hpp" - -KartUpdateMessage::KartUpdateMessage() - : Message(Message::MT_KART_INFO) -{ - World *world = World::getWorld(); - unsigned int num_karts = world->getNumKarts(); - - // Send the number of karts and for each kart the compressed - // control structure (3 ints) and xyz,hpr (4 floats: quaternion: - allocate(getCharLength()+ - num_karts*(KartControl::getLength() + getVec3Length() - +getQuaternionLength()) ); - addChar(num_karts); - for(unsigned int i=0; igetKart(i); - const KartControl& kc=kart->getControls(); - kc.serialise(this); - addVec3(kart->getXYZ()); - addQuaternion(kart->getRotation()); - } // for i -} // KartUpdateMessage -// ---------------------------------------------------------------------------- -KartUpdateMessage::KartUpdateMessage(ENetPacket* pkt) - : Message(pkt, MT_KART_INFO) -{ - World *world = World::getWorld(); - unsigned int num_karts = getInt(); - for(unsigned int i=0; igetKart(i); - kart->setXYZ(xyz); - kart->setRotation(q); - } // for i -}; // KartUpdateMessage - diff --git a/src/network/message.cpp b/src/network/message.cpp deleted file mode 100644 index b1f754c02..000000000 --- a/src/network/message.cpp +++ /dev/null @@ -1,225 +0,0 @@ -// -// SuperTuxKart - a fun racing game with go-kart -// Copyright (C) 2008 Joerg Henrichs, Stephen Leak -// -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License -// as published by the Free Software Foundation; either version 3 -// of the License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -#include "network/message.hpp" - -#include -#include -#include -#include - -/** Creates a message to be sent. - * This only initialised the data structures, it does not reserve any memory. - * A call to allocate() is therefore necessary. - * \param type The type of the message - */ -Message::Message(MessageType type) -{ - assert(sizeof(int)==4); - m_type = type; - m_pos = 0; - m_data_size = -1; - m_data = NULL; - m_needs_destroy = 0; // enet destroys message after send -} // Message - -// ---------------------------------------------------------------------------- -/** Handles a received message. - * The message in pkt is received, and the message type is checked. - * \param pkt The ENetPacket - * \param m The type of the message. The type is checked via an assert! - */ - -Message::Message(ENetPacket* pkt, MessageType m) -{ - receive(pkt, m); -} - -// ---------------------------------------------------------------------------- -/** Loads the message in pkt, and checks for the correct message type. - * Paramaters: - * \param pkt The ENetPacket - * \param m The type of the message. The type is checked via an assert! - */ -void Message::receive(ENetPacket* pkt, MessageType m) -{ - assert(sizeof(int)==4); - m_pkt = pkt; - m_data_size = pkt->dataLength; - m_data = (char*)pkt->data; - m_type = (MessageType)m_data[0]; - if(m_type!=m) - printf("type %d %d\n",m_type,m); - assert(m_type==m); - m_pos = 1; - m_needs_destroy = true; -} // Message - -// ---------------------------------------------------------------------------- -/** Frees the memory allocated for this message. */ -Message::~Message() -{ - clear(); -} // ~Message - -// ---------------------------------------------------------------------------- -/** Frees the memory for a received message. - * Calls enet_packet_destroy if necessary (i.e. if the message was received). - * The memory for a message created to be sent does not need to be freed, it - * is handled by enet. */ -void Message::clear() -{ - if(m_needs_destroy) - enet_packet_destroy(m_pkt); -} // clear - -// ---------------------------------------------------------------------------- -/** Reserves the memory for a message. - * \param size Number of bytes to reserve. - */ -void Message::allocate(int size) -{ - m_data_size = size+1; - m_pkt = enet_packet_create (NULL, m_data_size, ENET_PACKET_FLAG_RELIABLE); - m_data = (char*)m_pkt->data; - m_data[0] = m_type; - m_pos = 1; -} // allocate - -// ---------------------------------------------------------------------------- -/** Adds an integer value to the message. - * \param data The integer value to add. - */ -void Message::addInt(int data) -{ - assert((int)(m_pos + sizeof(int)) <= m_data_size); - int l=htonl(data); - memcpy(m_data+m_pos, &l, sizeof(int)); - m_pos+=sizeof(int); -} // addInt - -// ---------------------------------------------------------------------------- -/** Extracts an integer value from a message. - * \return The extracted integer. - */ -int Message::getInt() -{ - m_pos+=sizeof(int); - return ntohl(*(int*)(&m_data[m_pos-sizeof(int)])); -} // getInt - -// ---------------------------------------------------------------------------- -/** Adds a short value to the message. - * \param data The integer value to add. - */ -void Message::addShort(short data) -{ - assert((int)(m_pos + sizeof(short)) <= m_data_size); - int l=htons(data); - memcpy(m_data+m_pos, &l, sizeof(short)); - m_pos+=sizeof(short); -} // addShort - -// ---------------------------------------------------------------------------- -/** Extracts a short value from a message. - * \return The short value. - */ -short Message::getShort() -{ - m_pos+=sizeof(short); - return ntohs(*(short*)(&m_data[m_pos-sizeof(short)])); -} // getShort - -// ---------------------------------------------------------------------------- -/** Adds a floating point value to the message. - * \param data Floating point value to add. - */ -void Message::addFloat(const float data) -{ - // The simple approach of using addInt(*(int*)&data) - // does not work (at least with optimisation on certain g++ versions, - // see getFloat for more details) - int n; - memcpy(&n, &data, sizeof(float)); - addInt(n); -} // addFloat -// ---------------------------------------------------------------------------- -float Message::getFloat() -{ - int i = getInt(); - float f; - memcpy(&f, &i, sizeof(int)); - return f; - // The 'obvious' way: - // float *f = (float*) &i; - // return *f; - // does NOT work, see http://www.velocityreviews.com/forums/showthread.php?t=537336 - // for details -} // getFloat - -// ---------------------------------------------------------------------------- -void Message::addString(const std::string &data) -{ - int len = data.size()+1; // copy 0 end byte - assert((int)(m_pos+len) <=m_data_size); - memcpy (&(m_data[m_pos]), data.c_str(), len); - m_pos += len; -} // addString - -// ---------------------------------------------------------------------------- -std::string Message::getString() -{ - char *str = (char*) &(m_data[m_pos]); - int len = strlen(str)+1; - m_pos += len; - return std::string(str); -} // getString - -// ---------------------------------------------------------------------------- -/** Returns the number of bytes necessary to store a string vector. - * \param vs std::vector - */ -int Message::getStringVectorLength(const std::vector& vs) -{ - int len=getShortLength(); - for(unsigned int i=0; i to the message. - */ -void Message::addStringVector(const std::vector& vs) -{ - assert(vs.size()<32767); - addShort(vs.size()); - for(unsigned short i=0; i Message::getStringVector() -{ - std::vector vs; - vs.resize(getShort()); - for(unsigned int i=0; i -#include -#include -#include -#include "btBulletDynamicsCommon.h" - -using std::memcpy; - -#include "enet/enet.h" - -#include "utils/vec3.hpp" - -// sjl: when a message is received, need to work out what kind of message it -// is and therefore what to do with it - -/** Base class to serialises/deserialises messages. - * This is the base class for all messages being exchange between client - * and server. It handles the interface to enet, and adds a message type - * (which is checked via an assert to help finding bugs by receiving a - * message of an incorrect type). It also takes care of endianess (though - * floats are converted via a byte swap, too - so it must be guaranteed - * that the float representation between all machines is identical). - */ -class Message -{ -public: - /** Contains all tags used in identifying a message. */ - enum MessageType {MT_CONNECT=1, MT_CHARACTER_INFO, MT_CHARACTER_CONFIRM, - MT_RACE_INFO, MT_RACE_START, MT_WORLD_LOADED, - MT_KART_INFO, MT_KART_CONTROL, MT_RACE_STATE, - MT_RACE_RESULT, MT_RACE_RESULT_ACK - }; -private: - ENetPacket *m_pkt; - char *m_data; - MessageType m_type; - int m_data_size; - unsigned int m_pos; // simple stack counter for constructing packet data - bool m_needs_destroy; // only received messages need to be destroyed - -public: - void addInt(int data); - void addShort(short data); - void addString(const std::string &data); - void addStringVector(const std::vector& vs); - void addUInt(unsigned int data) { addInt(*(int*)&data); } - void addFloat(const float data); - void addBool(bool data) { addChar(data?1:0); } - void addChar(char data) { addCharArray((char*)&data,1);} - void addCharArray(char *c, unsigned int n=1) - { assert((int)(m_pos+n)<=m_data_size); - memcpy(m_data+m_pos,c,n); - m_pos+=n; } -#ifndef WIN32 // on windows size_t is unsigned int - void addSizeT(size_t data) { addInt((int)data); } -#endif - void addIntArray(int *d, unsigned int n) - { for(unsigned int i=0; - i - getStringVector(); - char getChar() {char c;getCharArray(&c,1); - return c; } - void getCharArray(char *c, int n=1) {memcpy(c,m_data+m_pos,n); - m_pos+=n; - return; } - Vec3 getVec3() { Vec3 v; - v.setX(getFloat()); - v.setY(getFloat()); - v.setZ(getFloat()); - return v; } - btQuaternion getQuaternion() { btQuaternion q; - q.setX(getFloat()); - q.setY(getFloat()); - q.setZ(getFloat()); - q.setW(getFloat()); - return q; } - static int getIntLength() { return sizeof(int); } - static int getUIntLength() { return sizeof(int); } - static int getShortLength() { return sizeof(short); } - static int getCharLength() { return sizeof(char); } - static int getBoolLength() { return sizeof(char); } - static int getFloatLength() { return sizeof(float); } - static int getStringLength(const std::string& s) { return s.size()+1;} - static int getVec3Length() { return 3*sizeof(float); } - static int getQuaternionLength() { return 4*sizeof(float); } - static int getStringVectorLength(const std::vector& vs); -#ifndef WIN32 - static int getSizeTLength(size_t n) { return sizeof(int); } -#endif - -public: - Message(MessageType m); - Message(ENetPacket *pkt, MessageType m); - void receive(ENetPacket *pkt, MessageType m); - ~Message(); - void clear(); - void allocate(int size); - MessageType getType() const { return m_type; } - ENetPacket* getPacket() const { assert(m_data_size>-1); return m_pkt; } - /** Return the type of a message without unserialising the message */ - static MessageType peekType(ENetPacket *pkt) - { return (MessageType)pkt->data[0];} - -}; // Message - - -#endif - diff --git a/src/network/kart_control_message.hpp b/src/network/network_interface.cpp similarity index 68% rename from src/network/kart_control_message.hpp rename to src/network/network_interface.cpp index 6127f62b9..262083330 100644 --- a/src/network/kart_control_message.hpp +++ b/src/network/network_interface.cpp @@ -1,6 +1,6 @@ // // SuperTuxKart - a fun racing game with go-kart -// Copyright (C) 2008 Joerg Henrichs +// Copyright (C) 2013 SuperTuxKart-Team // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License @@ -16,16 +16,13 @@ // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -#ifndef HEADER_KART_CONTROL_MESSAGE_HPP -#define HEADER_KART_CONTROL_MESSAGE_HPP +#include "network/network_interface.hpp" -#include "network/message.hpp" -class KartControlMessage : public Message +NetworkInterface::NetworkInterface() { -public: - KartControlMessage(); - KartControlMessage(ENetPacket* pkt, int kart_id_offset, - int num_local_players); -}; // KartUpdateMessage -#endif +} + +NetworkInterface::~NetworkInterface() +{ +} diff --git a/src/network/race_info_message.hpp b/src/network/network_interface.hpp similarity index 57% rename from src/network/race_info_message.hpp rename to src/network/network_interface.hpp index 52404b3f5..c2b7f287c 100644 --- a/src/network/race_info_message.hpp +++ b/src/network/network_interface.hpp @@ -1,6 +1,6 @@ // // SuperTuxKart - a fun racing game with go-kart -// Copyright (C) 2008 Joerg Henrichs +// Copyright (C) 2013 SuperTuxKart-Team // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License @@ -16,18 +16,30 @@ // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -#ifndef HEADER_RACE_INFO_MESSAGE_HPP -#define HEADER_RACE_INFO_MESSAGE_HPP +#ifndef NETWORK_INTERFACE_H +#define NETWORK_INTERFACE_H -#include +#include "network/singleton.hpp" +#include "network/types.hpp" +#include "network/network_manager.hpp" -#include "network/message.hpp" -#include "network/remote_kart_info.hpp" +#include +#include +#include -class RaceInfoMessage : public Message + +class NetworkInterface : public Singleton { -public: - RaceInfoMessage(const std::vector& kart_info); - RaceInfoMessage(ENetPacket* pkt); -}; // RaceInfoMessage -#endif + friend class Singleton; + public: + + void initNetwork(bool server); + + protected: + // protected functions + NetworkInterface(); + virtual ~NetworkInterface(); + +}; + +#endif // NETWORK_INTERFACE_H diff --git a/src/network/network_kart.cpp b/src/network/network_kart.cpp deleted file mode 100644 index 42cf8a3cc..000000000 --- a/src/network/network_kart.cpp +++ /dev/null @@ -1,43 +0,0 @@ -// -// SuperTuxKart - a fun racing game with go-kart -// Copyright (C) 2004-2005 Steve Baker -// Copyright (C) 2006 SuperTuxKart-Team, Joerg Henrichs, Steve Baker -// -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License -// as published by the Free Software Foundation; either version 3 -// of the License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -#include "network/network_manager.hpp" -#include "network/network_kart.hpp" - -/** A network kart. On the server, it receives its control information (steering etc) - from the network manager. - */ -NetworkKart::NetworkKart(const std::string &kart_name, - unsigned int world_kart_id, int position, - const btTransform &init_transform, - int global_player_id, - RaceManager::KartType type) - : Kart(kart_name, world_kart_id, position, - init_transform) -{ - m_global_player_id = global_player_id; -} // NetworkKart - -// ---------------------------------------------------------------------------- -void NetworkKart::setControl(const KartControl& kc) -{ - assert(network_manager->getMode()==NetworkManager::NW_SERVER); - m_controls = kc; -} // setControl - diff --git a/src/network/network_manager.cpp b/src/network/network_manager.cpp index 2554e070d..308168257 100644 --- a/src/network/network_manager.cpp +++ b/src/network/network_manager.cpp @@ -1,6 +1,6 @@ // // SuperTuxKart - a fun racing game with go-kart -// Copyright (C) 2008 Joerg Henrichs, Stephen Leak +// Copyright (C) 2013 SuperTuxKart-Team // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License @@ -18,723 +18,126 @@ #include "network/network_manager.hpp" -#include "config/stk_config.hpp" -#include "config/user_config.hpp" -#include "karts/kart_properties_manager.hpp" -#include "modes/world.hpp" -#include "network/connect_message.hpp" -#include "network/character_info_message.hpp" -#include "network/character_selected_message.hpp" -#include "network/race_info_message.hpp" -#include "network/race_start_message.hpp" -#include "network/world_loaded_message.hpp" -#include "network/race_state.hpp" -#include "network/kart_control_message.hpp" -#include "network/character_confirm_message.hpp" -#include "network/race_result_message.hpp" -#include "network/race_result_ack_message.hpp" -#include "race/race_manager.hpp" +#include "network/protocols/hide_public_address.hpp" +#include "network/protocols/show_public_address.hpp" +#include "network/protocols/get_public_address.hpp" + +#include "network/protocol_manager.hpp" +#include "network/client_network_manager.hpp" +#include "network/server_network_manager.hpp" + +#include "utils/log.hpp" + +#include +#include + +void* protocolManagerUpdate(void* data) +{ + ProtocolManager* manager = static_cast(data); + while(1) + { + manager->update(); + } + return NULL; +} -NetworkManager* network_manager = 0; NetworkManager::NetworkManager() { - m_mode = NW_NONE; - m_state = NS_ACCEPT_CONNECTIONS; - m_host = NULL; + m_public_address.ip = 0; + m_public_address.port = 0; + m_protocol_manager_update_thread = NULL; + m_localhost = NULL; +} - m_num_clients = 0; - m_host_id = 0; - - if (enet_initialize () != 0) - { - fprintf (stderr, "An error occurred while initializing ENet.\n"); - exit(-1); - } -} // NetworkManager - -// ----------------------------------------------------------------------------- -bool NetworkManager::initialiseConnections() +NetworkManager::~NetworkManager() { - switch(m_mode) - { - case NW_NONE: return true; - case NW_CLIENT: return initClient(); - case NW_SERVER: return initServer(); - } - return true; -} // NetworkManager - -// ----------------------------------------------------------------------------- -NetworkManager::~NetworkManager() -{ - if(m_mode==NW_SERVER || m_mode==NW_CLIENT) enet_host_destroy(m_host); - enet_deinitialize(); -} // ~NetworkManager - -// ----------------------------------------------------------------------------- -bool NetworkManager::initServer() -{ - ENetAddress address; - address.host = ENET_HOST_ANY; - address.port = UserConfigParams::m_server_port; - - m_host = enet_host_create (& address /* the address to bind the server host to */, - stk_config->m_max_karts /* number of connections */, - 0 /* channel limit */, - 0 /* incoming bandwidth */, - 0 /* outgoing bandwidth */ ); - if (m_host == NULL) + if (m_protocol_manager_update_thread) + pthread_cancel(*m_protocol_manager_update_thread);//, SIGKILL); + + ProtocolManager::kill(); + + if (m_localhost) + delete m_localhost; + while(!m_peers.empty()) { - fprintf (stderr, - "An error occurred while trying to create an ENet server host.\n" - "Progressing in non-network mode\n"); - m_mode = NW_NONE; - return false; + delete m_peers.back(); + m_peers.pop_back(); } +} - m_server = NULL; - m_clients.push_back(NULL); // server has host_id=0, so put a dummy entry at 0 in client array - - m_client_names.push_back("server"); - return true; -} // initServer - -// ----------------------------------------------------------------------------- -/** Initialises the client. This function tries to connect to the server. - */ -bool NetworkManager::initClient() +void NetworkManager::run() { - m_host = enet_host_create (NULL /* create a client host */, - 1 /* only allow 1 outgoing connection */, - 0 /* channel limit */, - 0 /* downstream bandwidth unlimited */, - 0 /* upstream bandwidth unlimited */ ); + ProtocolManager::getInstance(); + m_protocol_manager_update_thread = (pthread_t*)(malloc(sizeof(pthread_t))); + pthread_create(m_protocol_manager_update_thread, NULL, protocolManagerUpdate, ProtocolManager::getInstance()); +} - if (m_host == NULL) - { - fprintf (stderr, - "An error occurred while trying to create an ENet client host.\n"); - return false; - } - - ENetAddress address; - ENetEvent event; - ENetPeer *peer; - - enet_address_set_host (& address, UserConfigParams::m_server_address.c_str()); - address.port = UserConfigParams::m_server_port; - - /* Initiate the connection, allocating the two channels 0 and 1. */ - peer = enet_host_connect (m_host, &address, 2, 0); - - if (peer == NULL) - { - fprintf(stderr, - "No available peers for initiating an ENet connection.\n"); - return false; - } - - /* Wait up to 5 seconds for the connection attempt to succeed. */ - if (enet_host_service (m_host, & event, 5000) <= 0 || - event.type != ENET_EVENT_TYPE_CONNECT) - { - /* Either the 5 seconds are up or a disconnect event was */ - /* received. Reset the peer in the event the 5 seconds */ - /* had run out without any significant event. */ - enet_peer_reset (peer); - - fprintf(stderr, "Connection to '%s:%d' failed.\n", - UserConfigParams::m_server_address.c_str(), (int)UserConfigParams::m_server_port); - return false; - } - m_server = peer; - return true; -} // initClient - -// ---------------------------------------------------------------------------- -/** Switches the network manager to client mode. This function sets the state - * to waiting_for_chars (so that the message from the server containing all - * available characters can be received). - */ -void NetworkManager::becomeClient() +bool NetworkManager::connect(TransportAddress peer) { - m_mode = NW_CLIENT; - m_state = NS_WAIT_FOR_AVAILABLE_CHARACTERS; -} // becomeClient + if (peerExists(peer)) + return isConnectedTo(peer); + + return STKPeer::connectToHost(m_localhost, peer, 2, 0); +} -// ---------------------------------------------------------------------------- -/** Switches the network manager to server mode. This function sets the state - * to accepting connections. - */ -void NetworkManager::becomeServer() +void NetworkManager::setManualSocketsMode(bool manual) { - m_mode = NW_SERVER; - m_state = NS_ACCEPT_CONNECTIONS; -} // becomeServer - -// ---------------------------------------------------------------------------- -/** Called in case of an error, to switch back to non-networking mode. -*/ -void NetworkManager::disableNetworking() -{ - m_mode=NW_NONE; - if (m_host != NULL) - { - enet_host_destroy(m_host); - m_host = NULL; - } - // FIXME: what other enet data structures do we have to free/reset??? - -} // disableNetworking - -// ---------------------------------------------------------------------------- -void NetworkManager::handleNewConnection(ENetEvent *event) -{ - // Only accept while waiting for connections - if(m_state!=NS_ACCEPT_CONNECTIONS) return; - - // The logical connection (from STK point of view) happens when - // the connection message is received. But for now reserve the - // space in the data structures (e.g. in case that two connects - // happen before a connect message is received - m_client_names.push_back("NOT SET YET"); - m_clients.push_back(event->peer); - event->peer->data = (void*)int(m_clients.size()-1); // save hostid in peer data - -} // handleNewConnection - -// ---------------------------------------------------------------------------- -void NetworkManager::handleDisconnection(ENetEvent *event) -{ - if(m_state!=NS_ACCEPT_CONNECTIONS) - { - fprintf(stderr, "Disconnect while in race - close your eyes and hope for the best.\n"); - return; - } - fprintf(stderr, "%x:%d disconnected (host id %d).\n", event->peer->address.host, - event->peer->address.port, (int)(long)event->peer->data ); - m_num_clients--; -} // handleDisconnection - -// ---------------------------------------------------------------------------- -void NetworkManager::handleMessageAtServer(ENetEvent *event) -{ // handle message at server (from client) - - switch(m_state) - { - case NS_ACCEPT_CONNECTIONS: - { - ConnectMessage m(event->packet); - m_client_names[(int)(long)event->peer->data] = m.getId(); - m_num_clients++; - return; - } - case NS_KART_CONFIRMED: // Fall through - case NS_CHARACTER_SELECT: - { - CharacterSelectedMessage m(event->packet); - unsigned int hostid=(unsigned int)(long)event->peer->data; - assert(hostid>=1 && hostid<=m_num_clients); - if(m_num_local_players[hostid]==-1) // first package from that host - { - m_num_local_players[hostid] = m.getNumPlayers(); - m_num_all_players += m.getNumPlayers(); - // count how many hosts have sent (at least) one message - m_barrier_count ++; - } - RemoteKartInfo ki=m.getKartInfo(); - ki.setHostId(hostid); - m_kart_info.push_back(ki); - - int kart_id = kart_properties_manager->getKartId(ki.getKartName()); - kart_properties_manager->testAndSetKart(kart_id); - // TODO - character selection screen in networking - /* - CharSel *menu = dynamic_cast(menu_manager->getCurrentMenu()); - if(menu) - menu->updateAvailableCharacters(); - */ - - // Broadcast the information about a selected kart to all clients - CharacterConfirmMessage ccm(ki.getKartName(), hostid); - broadcastToClients(ccm); - // See if this was the last message, i.e. we have received at least - // one message from each client, and the size of the kart_info - // array is the same as the number of all players (which does not - // yet include the number of players on the host). - if(m_barrier_count == (int)m_num_clients && - m_num_all_players==(int)m_kart_info.size()) - { - // we can't send the race info yet, since the server might - // not yet have selected all characters! - m_state = NS_ALL_REMOTE_CHARACTERS_DONE; - } - break; - } - case NS_READY_SET_GO_BARRIER: - { - m_barrier_count ++; - if(m_barrier_count==(int)m_num_clients) - { - m_state = NS_RACING; - RaceStartMessage m; - broadcastToClients(m); - } - break; - } - case NS_RACE_RESULT_BARRIER: - { - // Other message, esp. kart control, are silently ignored. - // FIXME: we might want to make sure that no such message actually arrives - if(Message::peekType(event->packet)!=Message::MT_RACE_RESULT_ACK) - { - enet_packet_destroy(event->packet); - return; - } - m_barrier_count++; - if(m_barrier_count==(int)m_num_clients) - { - m_state = NS_MAIN_MENU; - } - break; - } - default: assert(0); // should not happen - } // switch m_state -} // handleMessageAtServer - -// ---------------------------------------------------------------------------- -void NetworkManager::handleMessageAtClient(ENetEvent *event) -{ // handle message at client (from server) - switch(m_state) - { - case NS_WAIT_FOR_AVAILABLE_CHARACTERS: - { - CharacterInfoMessage m(event->packet); - // FIXME: handle list of available characters - m_state = NS_CHARACTER_SELECT; - break; - } - case NS_CHARACTER_SELECT: - { - CharacterConfirmMessage m(event->packet); - kart_properties_manager->selectKartName(m.getKartName()); - // TODO - karts selection screen in networking - /* - CharSel *menu = dynamic_cast(menu_manager->getCurrentMenu()); - if(menu) - menu->updateAvailableCharacters(); - */ - break; - } - case NS_WAIT_FOR_KART_CONFIRMATION: - { - CharacterConfirmMessage m(event->packet); - kart_properties_manager->selectKartName(m.getKartName()); - - // If the current menu is the character selection menu, - // update the menu so that the newly taken character is removed. - // TODO - kart selection screen and networking - /* - CharSel *menu = dynamic_cast(menu_manager->getCurrentMenu()); - if(menu) - menu->updateAvailableCharacters();*/ - // Check if we received a message about the kart we just selected. - // If so, the menu needs to progress, otherwise a different kart - // must be selected by the current player. - if(m.getKartName()==m_kart_to_confirm) - { - int host_id = m.getHostId(); - m_state = (host_id == getMyHostId()) ? NS_KART_CONFIRMED - : NS_CHARACTER_SELECT; - } // m.getkartName()==m_kart_to_confirm - break; - } // wait for kart confirmation - case NS_WAIT_FOR_RACE_DATA: - { - // It is possible that character confirm messages arrive at the - // client when it has already left the character selection screen. - // In this case the messages can simply be ignored. - if(Message::peekType(event->packet)==Message::MT_CHARACTER_CONFIRM) - { - // Receiving it will automatically free the memory. - CharacterConfirmMessage m(event->packet); - return; - } - RaceInfoMessage m(event->packet); - // The constructor actually sets the information in the race manager - m_state = NS_LOADING_WORLD; - break; - } - case NS_READY_SET_GO_BARRIER: - { - // Not actually needed, but the destructor of RaceStartMessage - // will free the memory of the event. - RaceStartMessage m(event->packet); - m_state = NS_RACING; - break; - } - case NS_RACING: - { - assert(false); // should never be here while racing - break; - } - case NS_RACE_RESULT_BARRIER: - { - RaceResultAckMessage message(event->packet); - // TODO - race results menu in networking - /* - RaceResultsGUI *menu = dynamic_cast(menu_manager->getCurrentMenu()); - if(menu) - menu->setSelectedWidget(message.getSelectedMenu());*/ - m_state = NS_RACE_RESULT_BARRIER_OVER; - break; - } - default: - { - printf("received unknown message: type %d\n", - Message::peekType(event->packet)); - // assert(0); // should not happen - } - } // switch m_state -} // handleMessageAtClient - -// ---------------------------------------------------------------------------- -void NetworkManager::update(float dt) -{ - if(m_mode==NW_NONE) return; - // Messages during racing are handled in the sendUpdates/receiveUpdate - // calls, so don't do anything in this case. - if(m_state==NS_RACING) return; - - ENetEvent event; - int result = enet_host_service (m_host, &event, 0); - if(result==0) return; - if(result<0) - { - fprintf(stderr, "Error while receiving messages -> ignored.\n"); - return; - } - switch (event.type) - { - case ENET_EVENT_TYPE_CONNECT: handleNewConnection(&event); break; - case ENET_EVENT_TYPE_RECEIVE: - if(m_mode==NW_SERVER) - handleMessageAtServer(&event); - else - handleMessageAtClient(&event); - break; - case ENET_EVENT_TYPE_DISCONNECT: handleDisconnection(&event); break; - case ENET_EVENT_TYPE_NONE: break; - } -} // update - -// ---------------------------------------------------------------------------- -void NetworkManager::broadcastToClients(Message &m) -{ - enet_host_broadcast(m_host, 0, m.getPacket()); - enet_host_flush(m_host); -} // broadcastToClients - -// ---------------------------------------------------------------------------- -void NetworkManager::sendToServer(Message &m) -{ - enet_peer_send(m_server, 0, m.getPacket()); - enet_host_flush(m_host); -} // sendToServer - -// ---------------------------------------------------------------------------- -/** Cleans up character related data structures. Must be called before any - * character related data is set. - */ -void NetworkManager::initCharacterDataStructures() -{ - // This is called the first time the character selection menu is displayed - - if(m_mode==NW_CLIENT) - { - // Change state to wait for list of characters from server - m_state = NS_WAIT_FOR_AVAILABLE_CHARACTERS; - } - else // Server or no network - { - if(m_mode==NW_SERVER) - { - // server: create message with all valid characters - // ================================================ - for(unsigned int i=1; i<=m_num_clients; i++) - { - CharacterInfoMessage m(i); - enet_peer_send(m_clients[i], 0, m.getPacket()); - } - enet_host_flush(m_host); - } - // For server and no network: - // ========================== - // Prepare the data structures to receive and - // store information from all clients. - m_num_local_players.clear(); - // Server (hostid 0) is not included in the num_clients count. So to - // be able to use the hostid as index, we have to allocate one - // additional element. - m_num_local_players.resize(m_num_clients+1, -1); - m_num_local_players[0] = race_manager->getNumLocalPlayers(); - m_kart_info.clear(); - m_num_all_players = 0; - // use barrier count to see if we had at least one message from each host - m_barrier_count = 0; - m_state = NS_CHARACTER_SELECT; - } - -} // switchTocharacterSelection - -// ---------------------------------------------------------------------------- -/** Called on the client to send the data about the selected kart to the - * server and wait for confirmation. - * \param player_id Local id of the player which selected the kart. - * \param kart_id Identifier of the selected kart. this is used to wait till - * a message about this kart is received back from the server. - */ -void NetworkManager::sendCharacterSelected(int player_id, - const std::string &kart_id) -{ - if(m_mode==NW_SERVER) - { - CharacterConfirmMessage ccm(kart_id, getMyHostId()); - broadcastToClients(ccm); - } - else if(m_mode==NW_CLIENT) - { - CharacterSelectedMessage m(player_id); - sendToServer(m); - // Wait till we receive confirmation about the selected character. - m_state = NS_WAIT_FOR_KART_CONFIRMATION; - m_kart_to_confirm = kart_id; - } -} // sendCharacterSelected - -// ---------------------------------------------------------------------------- -void NetworkManager::waitForRaceInformation() -{ - m_state = NS_WAIT_FOR_RACE_DATA; -} // waitForRaceInformation - -// ---------------------------------------------------------------------------- -void NetworkManager::worldLoaded() -{ - if(m_mode==NW_CLIENT) - { - WorldLoadedMessage m; - sendToServer(m); - m_state = NS_READY_SET_GO_BARRIER; - } -} // worldLoaded - -// ---------------------------------------------------------------------------- -/** Receive and store the information from sendKartsInformation() -*/ -void NetworkManager::setupPlayerKartInfo() -{ - // Not sure if this should be here, but without it extra uncontrolled - // human players accumulate after each race. - m_kart_info.clear(); - - // Get the local kart info - for(unsigned int i=0; igetNumLocalPlayers(); i++) - m_kart_info.push_back(race_manager->getLocalKartInfo(i)); - - // Now sort by (hostid, playerid) - std::sort(m_kart_info.begin(), m_kart_info.end()); - - // Set the player kart information - race_manager->setNumPlayers(m_kart_info.size()); - - // Set the global player ID for each player - for(unsigned int i=0; isetPlayerKart(i, m_kart_info[i]); - } - - // Compute the id of the first kart from each host - m_kart_id_offset.resize(m_num_clients+1); - m_kart_id_offset[0]=0; - for(unsigned int i=1; i<=m_num_clients; i++) - m_kart_id_offset[i]=m_kart_id_offset[i-1]+m_num_local_players[i-1]; - - race_manager->computeRandomKartList(); -} // setupPlayerKartInfo - -// ---------------------------------------------------------------------------- -/** Sends the information from the race_manager to all clients. -*/ -void NetworkManager::sendRaceInformationToClients() -{ - if(m_mode==NW_SERVER) - { - setupPlayerKartInfo(); - RaceInfoMessage m(m_kart_info); - broadcastToClients(m); - } - beginReadySetGoBarrier(); -} // sendRaceInformationToClients - -// ---------------------------------------------------------------------------- -void NetworkManager::beginReadySetGoBarrier() -{ - m_state = NS_READY_SET_GO_BARRIER; - m_barrier_count = 0; - if(m_num_clients==0) m_state = NS_RACING; -} // beginReadySetGoBarrier -// ---------------------------------------------------------------------------- -void NetworkManager::sendConnectMessage() -{ - ConnectMessage msg; - sendToServer(msg); -} // sendConnectMessage -// ---------------------------------------------------------------------------- -/*** Send all kart controls and kart positions to all clients -*/ -void NetworkManager::sendUpdates() -{ - if(m_mode==NW_SERVER) - { - race_state->serialise(); - broadcastToClients(*race_state); - } - else if(m_mode==NW_CLIENT) - { - KartControlMessage m; - sendToServer(m); - } -} // sendUpdates - -// ---------------------------------------------------------------------------- -void NetworkManager::receiveUpdates() -{ - if(m_mode==NW_NONE) return; // do nothing if not networking - // The server receives m_num_clients messages, each client one message - int num_messages = m_mode==NW_SERVER ? m_num_clients : 1; - ENetEvent event; - bool correct=true; - - for(int i=0; ienterRaceOverState(); - return; - } - race_state->receive(event.packet); - } - } // for istopListening(); else + m_localhost->startListening(); +} + +void NetworkManager::notifyEvent(Event* event) +{ + Log::info("NetworkManager", "EVENT received\n"); + switch (event->type) { - broadcastToClients(m); + case EVENT_TYPE_MESSAGE: + Log::info("NetworkManager", "Message, Sender : %u, message = \"%s\"\n", event->peer->getAddress(), event->data.c_str()); + break; + case EVENT_TYPE_DISCONNECTED: + Log::info("NetworkManager", "Somebody is now disconnected. There are now %lu peers.\n", m_peers.size()); + Log::info("NetworkManager", "Disconnected host: %i.%i.%i.%i:%i\n", event->peer->getAddress()>>24&0xff, event->peer->getAddress()>>16&0xff, event->peer->getAddress()>>8&0xff, event->peer->getAddress()&0xff,event->peer->getPort()); + // remove the peer: + for (unsigned int i = 0; i < m_peers.size(); i++) + { + if (m_peers[i] == event->peer) + { + delete m_peers[i]; + m_peers.erase(m_peers.begin()+i, m_peers.begin()+i+1); + break; + } + } + Log::fatal("NetworkManager", "The peer that has been disconnected was not registered by the Network Manager.\n"); + break; + case EVENT_TYPE_CONNECTED: + Log::info("NetworkManager", "A client has just connected. There are now %lu peers.\n", m_peers.size() + 1); + // create the new peer: + m_peers.push_back(event->peer); + break; } -} // sendRaceResultAck + ProtocolManager::getInstance()->notifyEvent(event); +} + +void NetworkManager::setLogin(std::string username, std::string password) +{ + m_player_login.username = username; + m_player_login.password = password; +} + +void NetworkManager::setPublicAddress(TransportAddress addr) +{ + m_public_address = addr; +} + +bool NetworkManager::peerExists(TransportAddress peer) +{ + return m_localhost->peerExists(peer); +} + +bool NetworkManager::isConnectedTo(TransportAddress peer) +{ + return m_localhost->isConnectedTo(peer); +} diff --git a/src/network/network_manager.hpp b/src/network/network_manager.hpp index 83d55f556..a8931862b 100644 --- a/src/network/network_manager.hpp +++ b/src/network/network_manager.hpp @@ -1,6 +1,6 @@ // // SuperTuxKart - a fun racing game with go-kart -// Copyright (C) 2008 Joerg Henrichs, Stephen Leak +// Copyright (C) 2013 SuperTuxKart-Team // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License @@ -16,107 +16,58 @@ // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -#ifndef HEADER_NETWORK_MANAGER_HPP -#define HEADER_NETWORK_MANAGER_HPP +#ifndef NETWORKMANAGER_HPP +#define NETWORKMANAGER_HPP + +#include "network/stk_peer.hpp" +#include "network/stk_host.hpp" + +#include "network/protocol_manager.hpp" +#include "network/singleton.hpp" +#include "network/types.hpp" +#include "network/event.hpp" -#include #include -#include "enet/enet.h" - -#include "network/remote_kart_info.hpp" - - -class Message; - -class NetworkManager +class NetworkManager : public Singleton { -public: - // The mode the network manager is operating in - enum NetworkMode {NW_SERVER, NW_CLIENT, NW_NONE}; + friend class Singleton; + public: + virtual void run(); + + // network management functions + virtual bool connect(TransportAddress peer); + virtual void setManualSocketsMode(bool manual); + virtual void notifyEvent(Event* event); + virtual void sendPacket(const char* data) = 0; - // States for the finite state machine. First for server: - enum NetworkState {NS_MAIN_MENU, // before char sel gui - NS_ACCEPT_CONNECTIONS, // server: accept connections - NS_WAIT_FOR_AVAILABLE_CHARACTERS, // client: wait for list - NS_ALL_REMOTE_CHARACTERS_DONE, // server: all client data received - NS_WAIT_FOR_KART_CONFIRMATION, // client: wait for confirmation - // if character selection was ok - NS_KART_CONFIRMED, // Character was confirmed - NS_WAIT_FOR_RACE_DATA, // client: wait for race info - NS_READY_SET_GO_BARRIER, // c&s: barrier before r.s.g. - NS_CHARACTER_SELECT, // c&s: character select in progress - NS_LOADING_WORLD, // client: loading world - NS_RACING, - NS_WAIT_FOR_RACE_RESULT, // clients: waiting for race results - NS_RACE_RESULT_BARRIER , // Wait till all ack results - NS_RACE_RESULT_BARRIER_OVER // Barrier is over, goto next state - }; -private: - - NetworkMode m_mode; - NetworkState m_state; - unsigned int m_num_clients; - std::vector m_kart_info; - int m_host_id; - std::vector m_client_names; - std::vector m_num_local_players; - std::vector m_kart_id_offset; // kart id of first kart on host i - int m_num_all_players; - int m_barrier_count; - - ENetHost *m_host; // me - ENetPeer *m_server; // (clients only) - std::vector m_clients; // (server only) pos in vector is client host_id - /** Name of the kart that a client is waiting for confirmation for. */ - std::string m_kart_to_confirm; - - bool initServer(); - bool initClient(); - void handleNewConnection(ENetEvent *event); - void handleMessageAtServer(ENetEvent *event); - void handleMessageAtClient(ENetEvent *event); - void handleDisconnection(ENetEvent *event); - // the first cast to long avoid compiler errors on 64 bit systems - // about lost precision, then cast long to int to get the right type - unsigned int getHostId(ENetPeer *p) const {return (int)(long)p->data; } - - void sendToServer(Message &m); - void broadcastToClients(Message &m); -public: - NetworkManager(); - ~NetworkManager(); - void setMode(NetworkMode m) {m_mode = m; } - NetworkMode getMode() const {return m_mode; } - void becomeServer(); - void becomeClient(); - void setState(NetworkState s) {m_state = s; } - NetworkState getState() const {return m_state; } - int getMyHostId() const {return m_host_id; } - void setHostId(int host_id) {m_host_id = host_id; } - unsigned int getNumClients() const {return m_num_clients; } - const std::string& - getClientName(int i) const {return m_client_names[i];} - bool initialiseConnections(); - void update(float dt); - - void disableNetworking(); - void sendConnectMessage(); // client send initial info to server - void initCharacterDataStructures(); - void sendCharacterSelected(int player_id, const std::string &kartid); - void waitForRaceInformation(); - void worldLoaded(); - void setupPlayerKartInfo(); - void beginReadySetGoBarrier(); - void sendRaceInformationToClients(); - void sendUpdates(); - void receiveUpdates(); - void waitForClientData(); - void sendRaceResults(); - void beginRaceResultBarrier(); - void sendRaceResultAck(char menu_selection=-1); + // raw data management + void setLogin(std::string username, std::string password); + void setPublicAddress(TransportAddress addr); + + // getters + virtual bool peerExists(TransportAddress peer); + virtual bool isConnectedTo(TransportAddress peer); + + virtual bool isServer() = 0; + inline bool isClient() { return !isServer(); } + bool isPlayingOnline() { return m_playing_online; } + STKHost* getHost() { return m_localhost; } + std::vector getPeers() { return m_peers; } + + protected: + NetworkManager(); + virtual ~NetworkManager(); + + // protected members + std::vector m_peers; + STKHost* m_localhost; + bool m_playing_online; + + TransportAddress m_public_address; + PlayerLogin m_player_login; + + pthread_t* m_protocol_manager_update_thread; }; -extern NetworkManager *network_manager; - -#endif +#endif // NETWORKMANAGER_HPP diff --git a/src/network/connect_message.hpp b/src/network/protocol.cpp similarity index 60% rename from src/network/connect_message.hpp rename to src/network/protocol.cpp index 1875b5718..366ac7b6d 100644 --- a/src/network/connect_message.hpp +++ b/src/network/protocol.cpp @@ -1,6 +1,6 @@ // // SuperTuxKart - a fun racing game with go-kart -// Copyright (C) 2008 Joerg Henrichs +// Copyright (C) 2013 SuperTuxKart-Team // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License @@ -16,22 +16,34 @@ // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -#ifndef HEADER_CONNECT_MESSAGE_HPP -#define HEADER_CONNECT_MESSAGE_HPP +#include "network/protocol.hpp" -#include - -#include "network/message.hpp" - -class ConnectMessage : public Message +Protocol::Protocol(CallbackObject* callback_object, PROTOCOL_TYPE type) { -private: - std::string m_id; - void setId(); -public: - ConnectMessage(); - ConnectMessage(ENetPacket* pkt); - const std::string& - getId() { return m_id; } -}; // ConnectMessage -#endif + m_callback_object = callback_object; + m_type = type; +} + +Protocol::~Protocol() +{ +} + +void Protocol::pause() +{ + m_listener->requestPause(this); +} +void Protocol::unpause() +{ + m_listener->requestUnpause(this); +} + + +void Protocol::setListener(ProtocolManager* listener) +{ + m_listener = listener; +} + +PROTOCOL_TYPE Protocol::getProtocolType() +{ + return m_type; +} diff --git a/src/network/protocol.hpp b/src/network/protocol.hpp new file mode 100644 index 000000000..84dfdf6eb --- /dev/null +++ b/src/network/protocol.hpp @@ -0,0 +1,105 @@ +// +// SuperTuxKart - a fun racing game with go-kart +// Copyright (C) 2013 SuperTuxKart-Team +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 3 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +#ifndef PROTOCOL_HPP +#define PROTOCOL_HPP + +#include "network/protocol_manager.hpp" +#include "network/types.hpp" + +#include + +/** \enum PROTOCOL_TYPE + * \brief The types that protocols can have. This is used to select which protocol receives which event. + * \ingroup network + */ +enum PROTOCOL_TYPE +{ + PROTOCOL_NONE = 0, //!< No protocol type assigned. + PROTOCOL_CONNECTION = 1, //!< Protocol that deals with client-server connection. + PROTOCOL_LOBBY_ROOM = 2, //!< Protocol that is used during the lobby room phase. + PROTOCOL_SILENT = 0xffff //!< Used for protocols that do not subscribe to any network event. +}; + +/** \class Protocol + * \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. + * \ingroup network + */ +class Protocol +{ + public: + /*! + * \brief Constructor + * + * Sets the basic protocol parameters, as the callback object and the protocol type. + * + * \param callback_object The callback object that will be used by the protocol. Protocols that do not use callback objects must set it to NULL. + * \param type The type of the protocol. + */ + Protocol(CallbackObject* callback_object, PROTOCOL_TYPE type); + /*! + * \brief Destructor + */ + 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). + * This function must be called by the subclasse's pause function if re-defined. + */ + virtual void pause(); + /*! + * \brief Called when the protocol is unpaused. + * This function must be called by the subclasse's unpause function if re-defined. + */ + virtual void unpause(); + /*! + * \brief Called by the protocol listener as often as possible. Must be re-defined. + */ + virtual void update() = 0; + + /*! + * \brief Method to get a protocol's type. + * \return The protocol type. + */ + PROTOCOL_TYPE getProtocolType(); + protected: + ProtocolManager* m_listener; //!< The protocol listener + PROTOCOL_TYPE m_type; //!< The type of the protocol + CallbackObject* m_callback_object; //!< The callback object, if needed +}; + +#endif // PROTOCOL_HPP diff --git a/src/network/protocol_manager.cpp b/src/network/protocol_manager.cpp new file mode 100644 index 000000000..4b6190814 --- /dev/null +++ b/src/network/protocol_manager.cpp @@ -0,0 +1,308 @@ +// +// SuperTuxKart - a fun racing game with go-kart +// Copyright (C) 2013 SuperTuxKart-Team +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 3 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +#include "network/protocol_manager.hpp" + +#include "network/protocol.hpp" +#include "network/network_manager.hpp" +#include "utils/log.hpp" + +#include +#include + +ProtocolManager::ProtocolManager() +{ + pthread_mutex_init(&m_events_mutex, NULL); + pthread_mutex_init(&m_protocols_mutex, NULL); + pthread_mutex_init(&m_requests_mutex, NULL); + pthread_mutex_init(&m_id_mutex, NULL); + m_next_protocol_id = 0; +} + +ProtocolManager::~ProtocolManager() +{ + pthread_mutex_lock(&m_events_mutex); + pthread_mutex_lock(&m_protocols_mutex); + pthread_mutex_lock(&m_requests_mutex); + pthread_mutex_lock(&m_id_mutex); + for (unsigned int i = 0; i < m_protocols.size() ; i++) + delete m_protocols[i].protocol; + for (unsigned int i = 0; i < m_events_to_process.size() ; i++) + delete m_events_to_process[i]; + m_protocols.clear(); + m_requests.clear(); + m_events_to_process.clear(); + pthread_mutex_unlock(&m_events_mutex); + 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); + pthread_mutex_destroy(&m_id_mutex); +} + +void ProtocolManager::notifyEvent(Event* event) +{ + pthread_mutex_lock(&m_events_mutex); + m_events_to_process.push_back(event); // add the event to the queue + pthread_mutex_unlock(&m_events_mutex); +} + +void ProtocolManager::sendMessage(Protocol* sender, std::string message) +{ + std::string newMessage = " " + message; // add one byte to add protocol type + newMessage[0] = (char)(sender->getProtocolType()); + NetworkManager::getInstance()->sendPacket(newMessage.c_str()); +} + +int ProtocolManager::requestStart(Protocol* protocol) +{ + // create the request + ProtocolRequest req; + ProtocolInfo info; + info.protocol = protocol; + info.state = PROTOCOL_STATE_RUNNING; + assignProtocolId(&info); // assign a unique id to the protocol. + req.protocol_info = info; + req.type = PROTOCOL_REQUEST_START; + // add it to the request stack + pthread_mutex_lock(&m_requests_mutex); + m_requests.push_back(req); + pthread_mutex_unlock(&m_requests_mutex); + + return info.id; +} + +void ProtocolManager::requestStop(Protocol* protocol) +{ + // create the request + ProtocolRequest req; + req.protocol_info.protocol = protocol; + req.type = PROTOCOL_REQUEST_STOP; + // add it to the request stack + pthread_mutex_lock(&m_requests_mutex); + m_requests.push_back(req); + pthread_mutex_unlock(&m_requests_mutex); +} + +void ProtocolManager::requestPause(Protocol* protocol) +{ + // create the request + ProtocolRequest req; + req.protocol_info.protocol = protocol; + req.type = PROTOCOL_REQUEST_PAUSE; + // add it to the request stack + pthread_mutex_lock(&m_requests_mutex); + m_requests.push_back(req); + pthread_mutex_unlock(&m_requests_mutex); +} + +void ProtocolManager::requestUnpause(Protocol* protocol) +{ + // create the request + ProtocolRequest req; + req.protocol_info.protocol = protocol; + req.type = PROTOCOL_REQUEST_UNPAUSE; + // add it to the request stack + pthread_mutex_lock(&m_requests_mutex); + m_requests.push_back(req); + pthread_mutex_unlock(&m_requests_mutex); +} + +void ProtocolManager::requestTerminate(Protocol* protocol) +{ + // create the request + ProtocolRequest req; + req.protocol_info.protocol = protocol; + req.type = PROTOCOL_REQUEST_TERMINATE; + // add it to the request stack + pthread_mutex_lock(&m_requests_mutex); + m_requests.push_back(req); + pthread_mutex_unlock(&m_requests_mutex); +} + +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); + // add the protocol to the protocol vector so that it's updated + pthread_mutex_lock(&m_protocols_mutex); + m_protocols.push_back(protocol); + pthread_mutex_unlock(&m_protocols_mutex); + // setup the protocol and notify it that it's started + protocol.protocol->setListener(this); + protocol.protocol->setup(); +} +void ProtocolManager::stopProtocol(ProtocolInfo protocol) +{ + +} +void ProtocolManager::pauseProtocol(ProtocolInfo protocol) +{ + for (unsigned int i = 0; i < m_protocols.size(); i++) + { + if (m_protocols[i].protocol == protocol.protocol && m_protocols[i].state == PROTOCOL_STATE_RUNNING) + { + m_protocols[i].state = PROTOCOL_STATE_PAUSED; + m_protocols[i].protocol->pause(); + } + } +} +void ProtocolManager::unpauseProtocol(ProtocolInfo protocol) +{ + for (unsigned int i = 0; i < m_protocols.size(); i++) + { + if (m_protocols[i].protocol == protocol.protocol && m_protocols[i].state == PROTOCOL_STATE_PAUSED) + { + m_protocols[i].state = PROTOCOL_STATE_RUNNING; + m_protocols[i].protocol->unpause(); + } + } +} +void ProtocolManager::protocolTerminated(ProtocolInfo protocol) +{ + pthread_mutex_lock(&m_protocols_mutex); // be sure that noone accesses the protocols vector while we erase a protocol + int offset = 0; + for (unsigned int i = 0; i < m_protocols.size(); i++) + { + if (m_protocols[i-offset].protocol == protocol.protocol) + { + delete m_protocols[i].protocol; + m_protocols.erase(m_protocols.begin()+(i-offset), m_protocols.begin()+(i-offset)+1); + offset++; + } + } + Log::info("ProtocolManager", "A protocol has been terminated. There are %ld protocols running.\n", m_protocols.size()); + pthread_mutex_unlock(&m_protocols_mutex); +} + +void ProtocolManager::update() +{ + // before updating, notice protocols that they have received information + pthread_mutex_lock(&m_events_mutex); // secure threads + int size = m_events_to_process.size(); + for (int i = 0; i < size; i++) + { + Event* event = m_events_to_process.back(); + + PROTOCOL_TYPE searchedProtocol = PROTOCOL_NONE; + if (event->data.size() > 0) + searchedProtocol = (PROTOCOL_TYPE)(event->data[0]); + event->removeFront(1); // remove the first byte which indicates the protocol + for (unsigned int i = 0; i < m_protocols.size() ; i++) + { + if (m_protocols[i].protocol->getProtocolType() == searchedProtocol || event->type != EVENT_TYPE_MESSAGE) // pass data to protocols even when paused + m_protocols[i].protocol->notifyEvent(event); + } + delete event; + m_events_to_process.pop_back(); + } + pthread_mutex_unlock(&m_events_mutex); // release the mutex + + // now update all protocols + pthread_mutex_lock(&m_protocols_mutex); + for (unsigned int i = 0; i < m_protocols.size(); i++) + { + if (m_protocols[i].state == PROTOCOL_STATE_RUNNING) + m_protocols[i].protocol->update(); + } + 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++) + { + switch (m_requests[i].type) + { + case PROTOCOL_REQUEST_START: + startProtocol(m_requests[i].protocol_info); + break; + case PROTOCOL_REQUEST_STOP: + stopProtocol(m_requests[i].protocol_info); + break; + case PROTOCOL_REQUEST_PAUSE: + pauseProtocol(m_requests[i].protocol_info); + break; + case PROTOCOL_REQUEST_UNPAUSE: + unpauseProtocol(m_requests[i].protocol_info); + break; + case PROTOCOL_REQUEST_TERMINATE: + protocolTerminated(m_requests[i].protocol_info); + break; + } + } + m_requests.clear(); + pthread_mutex_unlock(&m_requests_mutex); +} + +int ProtocolManager::runningProtocolsCount() +{ + return m_protocols.size(); +} + +PROTOCOL_STATE ProtocolManager::getProtocolState(uint32_t id) +{ + for (unsigned int i = 0; i < m_protocols.size(); i++) + { + if (m_protocols[i].id == id) // we know a protocol with that id + return m_protocols[i].state; // return its state + } + // the protocol isn't running right now + for (unsigned int i = 0; i < m_requests.size(); i++) + { + 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 +} + +PROTOCOL_STATE ProtocolManager::getProtocolState(Protocol* protocol) +{ + for (unsigned int i = 0; i < m_protocols.size(); i++) + { + if (m_protocols[i].protocol == protocol) // the protocol is known + return m_protocols[i].state; // return its state + } + for (unsigned int i = 0; i < m_requests.size(); i++) + { + if (m_requests[i].protocol_info.protocol == protocol) // the protocol is going to be started + return PROTOCOL_STATE_RUNNING; // we can say it's running + } + return PROTOCOL_STATE_TERMINATED; // we don't know this protocol at all, it's finished +} + +int ProtocolManager::getProtocolID(Protocol* protocol) +{ + for (unsigned int i = 0; i < m_protocols.size(); i++) + { + if (m_protocols[i].protocol == protocol) + return m_protocols[i].id; + } + return 0; +} + +void ProtocolManager::assignProtocolId(ProtocolInfo* protocol_info) +{ + pthread_mutex_lock(&m_id_mutex); + protocol_info->id = m_next_protocol_id; + m_next_protocol_id++; + pthread_mutex_unlock(&m_id_mutex); +} + + diff --git a/src/network/protocol_manager.hpp b/src/network/protocol_manager.hpp new file mode 100644 index 000000000..1193eab14 --- /dev/null +++ b/src/network/protocol_manager.hpp @@ -0,0 +1,266 @@ +// +// SuperTuxKart - a fun racing game with go-kart +// Copyright (C) 2013 SuperTuxKart-Team +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 3 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +/*! \file protocol_manager.hpp + * \brief Contains structures and enumerations related to protocol management. + */ + +#ifndef PROTOCOL_MANAGER_HPP +#define PROTOCOL_MANAGER_HPP + +#include "network/singleton.hpp" +#include "network/event.hpp" + +#include +#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_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 + * 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_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 +*/ +typedef struct ProtocolInfo +{ + PROTOCOL_STATE state; //!< The state of the protocol + 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. +*/ +typedef struct ProtocolRequest +{ + PROTOCOL_REQUEST_TYPE type; //!< The type of request + 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 + * special thread, to ensure that they are processed independently from the + * 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. + */ + virtual void notifyEvent(Event* event); + /*! + * \brief WILL BE COMMENTED LATER + */ + virtual void sendMessage(Protocol* sender, std::string 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. + * \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); + /*! + * \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 + * protocols that they have events to process. Then ask all protocols + * 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. + */ + virtual int runningProtocolsCount(); + /*! + * \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. + */ + 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. + */ + virtual PROTOCOL_STATE getProtocolState(Protocol* protocol); + /*! + * \brief Get the id of a protocol. + * \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); + + protected: + // protected functions + /*! + * \brief Constructor + */ + ProtocolManager(); + /*! + * \brief Destructor + */ + virtual ~ProtocolManager(); + /*! + * \brief Assign an id to a protocol. + * This function will assign m_next_protocol_id as the protocol id. + * This id starts at 0 at the beginning and is increased by 1 each time + * a protocol starts. + * \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. + * \param protocol : ProtocolInfo to start. + */ + virtual void startProtocol(ProtocolInfo protocol); + /*! + * \brief Stops a protocol. + * Coes nothing. Noone can stop running protocols for now. + * \param protocol : ProtocolInfo to stop. + */ + virtual void stopProtocol(ProtocolInfo protocol); + /*! + * \brief Pauses a protocol. + * Pauses a protocol and tells it that it's being paused. + * \param protocol : ProtocolInfo to pause. + */ + virtual void pauseProtocol(ProtocolInfo protocol); + /*! + * \brief Unpauses a protocol. + * Unpauses a protocol and notifies it. + * \param protocol : ProtocolInfo to unpause. + */ + virtual void unpauseProtocol(ProtocolInfo protocol); + /*! + * \brief Notes that a protocol is terminated. + * Remove a protocol from the protocols vector. + * \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 + * state and their unique id. + */ + std::vector m_protocols; + /*! + * \brief Contains the network events to pass to protocols. + */ + std::vector m_events_to_process; + /*! + * \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. + * If a protocol has an id lower than this value, it means that it have + * been formerly started. + */ + unsigned int m_next_protocol_id; + + // mutexes: + /*! Used to ensure that the event queue is used thread-safely. */ + pthread_mutex_t m_events_mutex; + /*! Used to ensure that the protocol vector is used thread-safely. */ + pthread_mutex_t m_protocols_mutex; + /*! Used to ensure that the request vector is used thread-safely. */ + pthread_mutex_t m_requests_mutex; + /*! Used to ensure that the protocol id is used in a thread-safe way.*/ + pthread_mutex_t m_id_mutex; + +}; + +#endif // PROTOCOL_MANAGER_HPP diff --git a/src/network/protocols/connect_to_server.cpp b/src/network/protocols/connect_to_server.cpp new file mode 100644 index 000000000..6034d7588 --- /dev/null +++ b/src/network/protocols/connect_to_server.cpp @@ -0,0 +1,106 @@ +// +// SuperTuxKart - a fun racing game with go-kart +// Copyright (C) 2013 SuperTuxKart-Team +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 3 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +#include "network/protocols/connect_to_server.hpp" + +#include "network/client_network_manager.hpp" +#include "utils/time.hpp" +#include "utils/log.hpp" + +// ---------------------------------------------------------------------------- + +ConnectToServer::ConnectToServer(CallbackObject* callback_object) : + Protocol(callback_object, PROTOCOL_CONNECTION) +{ + m_server_ip = 0; + m_server_port = 0; + m_state = NONE; +} + +// ---------------------------------------------------------------------------- + +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) + { + Log::info("ConnectToServer", "The Connect To Server protocol has \ + received an event notifying that he's connected to the peer. \ + The peer sent \"%s\"\n", event->data.c_str()); + m_state = DONE; // we received a message, we are connected + } +} + +// ---------------------------------------------------------------------------- + +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); + } +} + +// ---------------------------------------------------------------------------- + +void ConnectToServer::update() +{ + if (m_state == NONE) + { + static double target = 0; + double currentTime = Time::getRealTime(); + if (currentTime > target) + { + 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"); + } + } + else if (m_state == DONE) + { + m_listener->requestTerminate(this); + } +} + +// ---------------------------------------------------------------------------- + +void ConnectToServer::setServerAddress(uint32_t ip, uint16_t port) +{ + m_server_ip = ip; + m_server_port = port; +} + +// ---------------------------------------------------------------------------- + diff --git a/src/network/num_players_message.hpp b/src/network/protocols/connect_to_server.hpp similarity index 52% rename from src/network/num_players_message.hpp rename to src/network/protocols/connect_to_server.hpp index 4279f9eb9..ad67412f9 100644 --- a/src/network/num_players_message.hpp +++ b/src/network/protocols/connect_to_server.hpp @@ -1,6 +1,6 @@ // // SuperTuxKart - a fun racing game with go-kart -// Copyright (C) 2008 Joerg Henrichs +// Copyright (C) 2013 SuperTuxKart-Team // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License @@ -16,27 +16,34 @@ // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -#ifndef HEADER_NUM_PLAYERS_MESSAGE_HPP -#define HEADER_NUM_PLAYERS_MESSAGE_HPP +#ifndef CONNECT_TO_SERVER_HPP +#define CONNECT_TO_SERVER_HPP +#include "network/protocol.hpp" #include -#include -#ifndef WIN32 -# include -#endif -#include "network/message.hpp" -#include "race/race_manager.hpp" - -class NumPlayersMessage : public Message +class ConnectToServer : public Protocol, public CallbackObject { -private: - int m_num_players -public: - NumPlayersMessage():Message(Message::MT_CONNECT) { m_num_players=race } - NumPlayersMessage(ENetPacket* pkt):Message(pkt) - { m_id=getString(); } - const std::string& - getNumPlayers() { return m_num_players; } -}; // ConnectMessage -#endif + public: + ConnectToServer(CallbackObject* callback_object); + 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; + + enum STATE + { + NONE, + DONE + }; + STATE m_state; +}; + +#endif // CONNECT_TO_SERVER_HPP diff --git a/src/network/protocols/get_peer_address.cpp b/src/network/protocols/get_peer_address.cpp new file mode 100644 index 000000000..ffa2a0b1c --- /dev/null +++ b/src/network/protocols/get_peer_address.cpp @@ -0,0 +1,95 @@ +// +// SuperTuxKart - a fun racing game with go-kart +// Copyright (C) 2013 SuperTuxKart-Team +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 3 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +#include "network/protocols/get_peer_address.hpp" + +#include "network/http_functions.hpp" +#include "utils/time.hpp" +#include "utils/log.hpp" + +GetPeerAddress::GetPeerAddress(CallbackObject* callback_object) : Protocol(callback_object, PROTOCOL_SILENT) +{ +} + +GetPeerAddress::~GetPeerAddress() +{ +} + +void GetPeerAddress::notifyEvent(Event* event) +{ + // nothing there. If we receive events, they must be ignored +} + +void GetPeerAddress::setup() +{ + m_state = NONE; +} + +void GetPeerAddress::update() +{ + if (m_state == NONE) + { + static double target = 0; + double current_time = Time::getRealTime(); + if (current_time > target) + { + 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 == "") + { + 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; + } + 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; + } + } + } + else if (m_state == DONE) + { + m_listener->requestTerminate(this); + } +} + +void GetPeerAddress::setPeerName(std::string peer_name) +{ + m_peer_name = peer_name; +} diff --git a/src/network/protocols/get_peer_address.hpp b/src/network/protocols/get_peer_address.hpp new file mode 100644 index 000000000..5359d00f3 --- /dev/null +++ b/src/network/protocols/get_peer_address.hpp @@ -0,0 +1,47 @@ +// +// SuperTuxKart - a fun racing game with go-kart +// Copyright (C) 2013 SuperTuxKart-Team +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 3 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +#ifndef GET_PEER_ADDRESS_HPP +#define GET_PEER_ADDRESS_HPP + +#include "network/protocol.hpp" + +class GetPeerAddress : public Protocol +{ + public: + GetPeerAddress(CallbackObject* callback_object); + virtual ~GetPeerAddress(); + + virtual void notifyEvent(Event* event); + virtual void setup(); + virtual void update(); + + void setPeerName(std::string peer_name); + protected: + std::string m_peer_name; + + enum STATE + { + NONE, + DONE + }; + STATE m_state; + +}; + +#endif // GET_PEER_ADDRESS_HPP diff --git a/src/network/protocols/get_public_address.cpp b/src/network/protocols/get_public_address.cpp new file mode 100644 index 000000000..218645b2a --- /dev/null +++ b/src/network/protocols/get_public_address.cpp @@ -0,0 +1,206 @@ +// +// SuperTuxKart - a fun racing game with go-kart +// Copyright (C) 2013 SuperTuxKart-Team +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 3 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +#include "network/protocols/get_public_address.hpp" + +#include "network/network_manager.hpp" +#include "network/client_network_manager.hpp" +#include "network/protocols/connect_to_server.hpp" +#include "network/network_interface.hpp" + +#include "utils/log.hpp" + +#include + +int stunRand() +{ + static bool init = false; + if (!init) + { + srand(time(NULL)); + init = true; + } + return rand(); +} + +GetPublicAddress::GetPublicAddress(CallbackObject* callback_object) : Protocol(callback_object, PROTOCOL_SILENT) +{ +} + +GetPublicAddress::~GetPublicAddress() +{ +} + +void GetPublicAddress::notifyEvent(Event* event) +{ + +} + +void GetPublicAddress::setup() +{ + m_state = NOTHING_DONE; +} + +void GetPublicAddress::update() +{ + if (m_state == NOTHING_DONE) + { + // format : 00MMMMMCMMMCMMMM (cf rfc 5389) + uint16_t message_type = 0b0000000000000001; // binding request + m_stun_tansaction_id[0] = stunRand(); + m_stun_tansaction_id[1] = stunRand(); + m_stun_tansaction_id[2] = stunRand(); + uint16_t message_length = 0x0000; + + uint8_t bytes[21]; // the message to be sent + // bytes 0-1 : the type of the message, + bytes[0] = (uint8_t)(message_type>>8); + bytes[1] = (uint8_t)(message_type); + + // bytes 2-3 : message length added to header (attributes) + bytes[2] = (uint8_t)(message_length>>8); + bytes[3] = (uint8_t)(message_length); + + // bytes 4-7 : magic cookie to recognize the stun protocol + bytes[4] = (uint8_t)(m_stun_magic_cookie>>24); + bytes[5] = (uint8_t)(m_stun_magic_cookie>>16); + bytes[6] = (uint8_t)(m_stun_magic_cookie>>8); + bytes[7] = (uint8_t)(m_stun_magic_cookie); + + // bytes 8-19 : the transaction id + bytes[8] = (uint8_t)(m_stun_tansaction_id[0]>>24); + bytes[9] = (uint8_t)(m_stun_tansaction_id[0]>>16); + bytes[10] = (uint8_t)(m_stun_tansaction_id[0]>>8); + bytes[11] = (uint8_t)(m_stun_tansaction_id[0]); + bytes[12] = (uint8_t)(m_stun_tansaction_id[1]>>24); + bytes[13] = (uint8_t)(m_stun_tansaction_id[1]>>16); + bytes[14] = (uint8_t)(m_stun_tansaction_id[1]>>8); + bytes[15] = (uint8_t)(m_stun_tansaction_id[1]); + bytes[16] = (uint8_t)(m_stun_tansaction_id[2]>>24); + bytes[17] = (uint8_t)(m_stun_tansaction_id[2]>>16); + bytes[18] = (uint8_t)(m_stun_tansaction_id[2]>>8); + bytes[19] = (uint8_t)(m_stun_tansaction_id[2]); + bytes[20] = '\0'; + + Log::info("GetPublicAddress", "Querrying STUN server 132.177.123.6\n"); + unsigned int dst = (132<<24)+(177<<16)+(123<<8)+6; + NetworkManager::getInstance()->setManualSocketsMode(true); + NetworkManager::getInstance()->getHost()->sendRawPacket(bytes, 20, TransportAddress(dst, 3478)); + m_state = TEST_SENT; + } + if (m_state == TEST_SENT) + { + unsigned int dst = (132<<24)+(177<<16)+(123<<8)+6; + uint8_t* data = NetworkManager::getInstance()->getHost()->receiveRawPacket(TransportAddress(dst, 3478)); + assert(data); + + // check that the stun response is a response, contains the magic cookie and the transaction ID + if ( data[0] == 0b01 && + data[1] == 0b01 && + data[4] == (uint8_t)(m_stun_magic_cookie>>24) && + data[5] == (uint8_t)(m_stun_magic_cookie>>16) && + data[6] == (uint8_t)(m_stun_magic_cookie>>8) && + data[7] == (uint8_t)(m_stun_magic_cookie)) + { + if( + data[8] == (uint8_t)(m_stun_tansaction_id[0]>>24) && + data[9] == (uint8_t)(m_stun_tansaction_id[0]>>16) && + data[10] == (uint8_t)(m_stun_tansaction_id[0]>>8 ) && + data[11] == (uint8_t)(m_stun_tansaction_id[0] ) && + data[12] == (uint8_t)(m_stun_tansaction_id[1]>>24) && + data[13] == (uint8_t)(m_stun_tansaction_id[1]>>16) && + data[14] == (uint8_t)(m_stun_tansaction_id[1]>>8 ) && + data[15] == (uint8_t)(m_stun_tansaction_id[1] ) && + data[16] == (uint8_t)(m_stun_tansaction_id[2]>>24) && + data[17] == (uint8_t)(m_stun_tansaction_id[2]>>16) && + 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"); + int message_size = data[2]*256+data[3]; + + // parse the stun message now: + bool finish = false; + uint8_t* attributes = data+20; + if (message_size == 0) + { + Log::error("GetPublicAddress", "STUN answer does not contain any information.\n"); + finish = true; + } + if (message_size < 4) // cannot even read the size + { + Log::error("GetPublicAddress", "STUN message is not valid.\n"); + finish = true; + } + uint16_t port; + uint32_t address; + bool valid = false; + while(!finish) + { + int type = attributes[0]*256+attributes[1]; + int size = attributes[2]*256+attributes[3]; + switch(type) + { + case 0: + case 1: + assert(size == 8); + assert(attributes[5] = 0x01); // IPv4 only + port = attributes[6]*256+attributes[7]; + address = (attributes[8]<<24 & 0xFF000000)+(attributes[9]<<16 & 0x00FF0000)+(attributes[10]<<8 & 0x0000FF00)+(attributes[11] & 0x000000FF); + finish = true; + valid = true; + continue; + break; + default: + break; + } + attributes = attributes + 4 + size; + message_size -= 4 + size; + if (message_size == 0) + finish = true; + if (message_size < 4) // cannot even read the size + { + Log::error("GetPublicAddress", "STUN message is not valid.\n"); + 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); + m_state = ADDRESS_KNOWN; + NetworkManager::getInstance()->setManualSocketsMode(false); + TransportAddress* addr = static_cast(m_callback_object); + addr->ip = address; + addr->port = port; + } + else + m_state = NOTHING_DONE; // need to re-send the stun request + } + else + { + m_state = NOTHING_DONE; // need to re-send the stun request + } + } + } + if (m_state == ADDRESS_KNOWN) + { + // terminate the protocol + m_listener->requestTerminate(this); + } +} diff --git a/src/network/protocols/get_public_address.hpp b/src/network/protocols/get_public_address.hpp new file mode 100644 index 000000000..596ab2c1b --- /dev/null +++ b/src/network/protocols/get_public_address.hpp @@ -0,0 +1,47 @@ +// +// SuperTuxKart - a fun racing game with go-kart +// Copyright (C) 2013 SuperTuxKart-Team +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 3 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +#ifndef GET_PUBLIC_ADDRESS_HPP +#define GET_PUBLIC_ADDRESS_HPP + +#include "network/protocol.hpp" + +class GetPublicAddress : public Protocol +{ + public: + GetPublicAddress(CallbackObject* callback_object); + virtual ~GetPublicAddress(); + + virtual void notifyEvent(Event* event); + + virtual void setup(); + virtual void update(); + + protected: + enum STATE + { + NOTHING_DONE, + TEST_SENT, + ADDRESS_KNOWN + }; + STATE m_state; + uint32_t m_stun_tansaction_id[3]; + static const uint32_t m_stun_magic_cookie = 0x2112A442; +}; + +#endif // GET_PUBLIC_ADDRESS_HPP diff --git a/src/network/protocols/hide_public_address.cpp b/src/network/protocols/hide_public_address.cpp new file mode 100644 index 000000000..5394e8dd9 --- /dev/null +++ b/src/network/protocols/hide_public_address.cpp @@ -0,0 +1,73 @@ +// +// SuperTuxKart - a fun racing game with go-kart +// Copyright (C) 2013 SuperTuxKart-Team +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 3 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +#include "network/protocols/hide_public_address.hpp" + +#include "network/http_functions.hpp" +#include "utils/log.hpp" + +HidePublicAddress::HidePublicAddress(CallbackObject* callback_object) : Protocol(callback_object, PROTOCOL_SILENT) +{ +} + +HidePublicAddress::~HidePublicAddress() +{ +} + +void HidePublicAddress::notifyEvent(Event* event) +{ +} + +void HidePublicAddress::setup() +{ + m_state = NONE; +} + +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') + { + Log::info("HidePublicAddress", "Public address hidden successfully.\n"); + m_state = DONE; + } + if (result[0] == 'f' && result[1] == 'a' && result[2] == 'i' && result[3] == 'l') + { + Log::warn("HidePublicAddress", "Public address still visible. Re-set nick:password and retry.\n"); + m_state = NONE; + pause(); + } + } + 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 new file mode 100644 index 000000000..625fc8c35 --- /dev/null +++ b/src/network/protocols/hide_public_address.hpp @@ -0,0 +1,49 @@ +// +// SuperTuxKart - a fun racing game with go-kart +// Copyright (C) 2013 SuperTuxKart-Team +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 3 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +#ifndef HIDE_PUBLIC_ADDRESS_HPP +#define HIDE_PUBLIC_ADDRESS_HPP + +#include "network/protocol.hpp" +#include + +class HidePublicAddress : public Protocol +{ + public: + HidePublicAddress(CallbackObject* callback_object); + 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 + { + NONE, + DONE + }; + STATE m_state; +}; + +#endif // HIDE_PUBLIC_ADDRESS_HPP diff --git a/src/network/race_start_message.hpp b/src/network/protocols/lobby_room_protocol.cpp similarity index 55% rename from src/network/race_start_message.hpp rename to src/network/protocols/lobby_room_protocol.cpp index eac2d7594..cc39b340e 100644 --- a/src/network/race_start_message.hpp +++ b/src/network/protocols/lobby_room_protocol.cpp @@ -1,6 +1,6 @@ // // SuperTuxKart - a fun racing game with go-kart -// Copyright (C) 2008 Joerg Henrichs +// Copyright (C) 2013 SuperTuxKart-Team // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License @@ -16,25 +16,35 @@ // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -#ifndef HEADER_RACE_START_MESSAGE_HPP -#define HEADER_RACE_START_MESSAGE_HPP +#include "network/protocols/lobby_room_protocol.hpp" -#include "network/message.hpp" -#include "network/remote_kart_info.hpp" -#include "race/race_manager.hpp" +#include "utils/log.hpp" -class RaceStartMessage : public Message +LobbyRoomProtocol::LobbyRoomProtocol(CallbackObject* callback_object) : Protocol(callback_object, PROTOCOL_LOBBY_ROOM) { -private: -// For now this is an empty message -public: - RaceStartMessage() : Message(Message::MT_RACE_START) - { - allocate(0); - } // RaceStartMessage +} - RaceStartMessage(ENetPacket* pkt):Message(pkt, MT_RACE_START) +LobbyRoomProtocol::~LobbyRoomProtocol() +{ +} + +void LobbyRoomProtocol::notifyEvent(Event* event) +{ + if (event->type == EVENT_TYPE_MESSAGE) { + Log::info("LobbyRoomProtocol", "Message from %u : \"%s\"\n", event->peer->getAddress(), event->data.c_str()); } -}; // RaceStartMessage -#endif +} + +void LobbyRoomProtocol::setup() +{ +} + +void LobbyRoomProtocol::update() +{ +} + +void LobbyRoomProtocol::sendMessage(std::string message) +{ + +} diff --git a/src/network/race_result_message.hpp b/src/network/protocols/lobby_room_protocol.hpp similarity index 50% rename from src/network/race_result_message.hpp rename to src/network/protocols/lobby_room_protocol.hpp index 95d3a6152..59e28b450 100644 --- a/src/network/race_result_message.hpp +++ b/src/network/protocols/lobby_room_protocol.hpp @@ -1,6 +1,6 @@ // // SuperTuxKart - a fun racing game with go-kart -// Copyright (C) 2008 Joerg Henrichs +// Copyright (C) 2013 SuperTuxKart-Team // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License @@ -16,30 +16,32 @@ // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -#ifndef HEADER_RACE_RESULT_MESSAGE_HPP -#define HEADER_RACE_RESULT_MESSAGE_HPP +#ifndef LOBBY_ROOM_PROTOCOL_HPP +#define LOBBY_ROOM_PROTOCOL_HPP -#include +#include "network/protocol.hpp" -#include "network/message.hpp" - - -/** This message is from the server to all clients to inform them about the - * result of a race. The clients wait for this message before they finish - * a race. +/*! + * \class LobbyRoomProtocol + * \brief Class used while the game is being prepared. + * This protocol starts when a server opens a game, or when a client joins a game. + * It is used to exchange data about the race settings, like kart selection. */ -class RaceResultMessage : public Message +class LobbyRoomProtocol : public Protocol { - struct RaceResult { - float m_time; - int m_score; - }; // RaceResult -private: - std::vector m_all_results; -public: - RaceResultMessage(); - RaceResultMessage(ENetPacket* pkt); - void addRaceResult(int kart_id, float time, int points); - void getRaceResult(int kart_id, float &time, int &points); -}; // RaceResultMessage -#endif + public: + LobbyRoomProtocol(CallbackObject* callback_object); + virtual ~LobbyRoomProtocol(); + + virtual void notifyEvent(Event* event); + + virtual void setup(); + + virtual void update(); + + void sendMessage(std::string message); + + protected: +}; + +#endif // LOBBY_ROOM_PROTOCOL_HPP diff --git a/src/network/protocols/show_public_address.cpp b/src/network/protocols/show_public_address.cpp new file mode 100644 index 000000000..bc4248c04 --- /dev/null +++ b/src/network/protocols/show_public_address.cpp @@ -0,0 +1,83 @@ +// +// SuperTuxKart - a fun racing game with go-kart +// Copyright (C) 2013 SuperTuxKart-Team +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 3 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +#include "network/protocols/show_public_address.hpp" + +#include "network/http_functions.hpp" +#include "utils/log.hpp" + +ShowPublicAddress::ShowPublicAddress(CallbackObject* callback_object) : Protocol(callback_object, PROTOCOL_SILENT) +{ +} + +ShowPublicAddress::~ShowPublicAddress() +{ +} + +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') + { + Log::info("ShowPublicAddress", "Address set.\n"); + m_state = DONE; + } + if (result[0] == 'f' && result[1] == 'a' && result[2] == 'i' && result[3] == 'l') + { + Log::warn("ShowPublicAddress", "Login fail. Please re-set username:password and unpause the protocol.\n"); + m_state = NONE; + pause(); + } + } + 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 new file mode 100644 index 000000000..fde549e11 --- /dev/null +++ b/src/network/protocols/show_public_address.hpp @@ -0,0 +1,53 @@ +// +// SuperTuxKart - a fun racing game with go-kart +// Copyright (C) 2013 SuperTuxKart-Team +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 3 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +#ifndef SHOW_PUBLIC_ADDRESS_HPP +#define SHOW_PUBLIC_ADDRESS_HPP + +#include "network/protocol.hpp" +#include + +class ShowPublicAddress : public Protocol +{ + public: + ShowPublicAddress(CallbackObject* callback_object); + 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 + { + NONE, + DONE + }; + STATE m_state; +}; + +#endif // HIDE_PUBLIC_ADDRESS_HPP diff --git a/src/network/race_info_message.cpp b/src/network/race_info_message.cpp deleted file mode 100644 index 4d2b6aa0b..000000000 --- a/src/network/race_info_message.cpp +++ /dev/null @@ -1,116 +0,0 @@ -// -// SuperTuxKart - a fun racing game with go-kart -// Copyright (C) 2008 Joerg Henrichs -// -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License -// as published by the Free Software Foundation; either version 3 -// of the License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -#include "network/race_info_message.hpp" - -#include "race/grand_prix_manager.hpp" -#include "race/race_manager.hpp" - -RaceInfoMessage::RaceInfoMessage(const std::vector& kart_info) - : Message(Message::MT_RACE_INFO) -{ - const GrandPrixData *cup=NULL; - int len = 2*getCharLength() // major, difficulty - + getIntLength() // minor - which is too big for a char/short! - + getCharLength(); // num karts - if(race_manager->getMajorMode()==RaceManager::MAJOR_MODE_GRAND_PRIX) - { - cup = race_manager->getGrandPrix(); - len += getStringLength(cup->getId()); - } - else - { - len += getStringLength(race_manager->getTrackName()); - len += getCharLength(); // num laps - } - len += getCharLength(); // kart_info.size() - for(unsigned int i=0; i& rkl=race_manager->getAIKartList(); - len += getStringVectorLength(rkl); - - allocate(len); - addChar(race_manager->getMajorMode() ); - addInt (race_manager->getMinorMode() ); - addChar(race_manager->getDifficulty() ); - addChar(race_manager->getNumberOfKarts()); - if(race_manager->getMajorMode()==RaceManager::MAJOR_MODE_GRAND_PRIX) - addString(cup->getId()); - else - { - addString(race_manager->getTrackName()); - addChar(race_manager->getNumLaps()); - } - - addChar(kart_info.size()); - for(unsigned int i=0; isetMajorMode ( RaceManager::MajorRaceModeType(getChar()) ); - race_manager->setMinorMode ( RaceManager::MinorRaceModeType(getInt()) ); - race_manager->setDifficulty( RaceManager::Difficulty (getChar()) ); - race_manager->setNumKarts ( getChar() ); - if(race_manager->getMajorMode()==RaceManager::MAJOR_MODE_GRAND_PRIX) - { - const GrandPrixData *cup = grand_prix_manager->getGrandPrix(getString()); - race_manager->setGrandPrix(*cup); - } - else - { - race_manager->setTrack(getString()); - race_manager->setNumLaps(getChar()); - } - - std::vector kart_info; - kart_info.resize(getChar()); - - for(unsigned int i=0; isetNumPlayers(kart_info.size()); - for(unsigned int i=0; isetPlayerKart(i, kart_info[i]); - } - std::vector rkl=getStringVector(); - race_manager->setAIKartList(rkl); -} // RaceInfoMessage diff --git a/src/network/race_result_ack_message.hpp b/src/network/race_result_ack_message.hpp deleted file mode 100644 index eda990208..000000000 --- a/src/network/race_result_ack_message.hpp +++ /dev/null @@ -1,58 +0,0 @@ -// -// SuperTuxKart - a fun racing game with go-kart -// Copyright (C) 2008 Joerg Henrichs -// -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License -// as published by the Free Software Foundation; either version 3 -// of the License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -#ifndef HEADER_RACE_RESULT_ACK_MESSAGE_HPP -#define HEADER_RACE_RESULT_ACK_MESSAGE_HPP - -#include - -#include "network/message.hpp" - - -/** This message is sent from the clients to the server when the race result - * screen was acknowledged, and then from the server to all clients to - * finish synchronisation. - */ -class RaceResultAckMessage : public Message -{ -private: - char m_menu_selected; -public: - /** Constructor, creates an empty message - */ - RaceResultAckMessage(char menu_choice) : Message(Message::MT_RACE_RESULT_ACK) - { - allocate(getCharLength()); - addChar(menu_choice); - } // RaceResultAckMessage - - // ------------------------------------------------------------------------ - /** Receives the ack message. - * \param pkt Received enet packet. - */ - RaceResultAckMessage(ENetPacket* pkt):Message(pkt, MT_RACE_RESULT_ACK) - { - m_menu_selected = getChar(); - } // RaceResultAckMessage(EnetPacket) - // ------------------------------------------------------------------------ - /** Returns the menu selected on the server after this message is received - * on a client. */ - char getSelectedMenu() const {return m_menu_selected; } - -}; // RaceResultAckMessageMessage -#endif diff --git a/src/network/race_result_message.cpp b/src/network/race_result_message.cpp deleted file mode 100644 index eeaacd656..000000000 --- a/src/network/race_result_message.cpp +++ /dev/null @@ -1,60 +0,0 @@ -// -// SuperTuxKart - a fun racing game with go-kart -// Copyright (C) 2008 Joerg Henrichs -// -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License -// as published by the Free Software Foundation; either version 3 -// of the License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -#include "network/race_result_message.hpp" - -#include "karts/abstract_kart.hpp" -#include "modes/world.hpp" -#include "race/race_manager.hpp" - -/** Creates a message containing the finishing time and rank of each kart. - * This message is serialised so that it can be sent. - */ -RaceResultMessage::RaceResultMessage() : Message(MT_RACE_RESULT) -{ - World *world = World::getWorld(); - const unsigned int num_karts = world->getNumKarts(); - allocate(num_karts * (getFloatLength()+getCharLength())); - for(unsigned int i=0; igetKart(i); - addFloat(kart->getFinishTime()); - addChar(kart->getPosition()); - } // for i in karts -} // RaceResultMessage - -// ---------------------------------------------------------------------------- -/** De-serialises a race result message and sets the appropriate results in - * the kart and the race manager. - * \param pkt The enet message paket. - */ -RaceResultMessage::RaceResultMessage(ENetPacket* pkt) - : Message(pkt, MT_RACE_RESULT) -{ - World *world = World::getWorld(); - const unsigned int num_karts = world->getNumKarts(); - for(unsigned int i=0; igetKart(i); - float time = getFloat(); - char position = getChar(); - kart->setPosition(position); - kart->finishedRace(time); - } -} // RaceResultMessage - diff --git a/src/network/race_state.cpp b/src/network/race_state.cpp deleted file mode 100644 index db5c66c83..000000000 --- a/src/network/race_state.cpp +++ /dev/null @@ -1,195 +0,0 @@ -// -// SuperTuxKart - a fun racing game with go-kart -// Copyright (C) 2008 Joerg Henrichs -// -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License -// as published by the Free Software Foundation; either version 3 -// of the License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -#include "network/race_state.hpp" - -#include "items/item_manager.hpp" -#include "items/powerup.hpp" -#include "items/projectile_manager.hpp" -#include "karts/rescue_animation.hpp" -#include "modes/world.hpp" -#include "network/network_manager.hpp" -#include "physics/physics.hpp" - -RaceState *race_state=NULL; - -// ---------------------------------------------------------------------------- -void RaceState::serialise() -{ - // First compute the overall size needed - // ===================================== - int len = 0; - - // 1. Add all kart information - // --------------------------- - unsigned int num_karts = World::getWorld()->getCurrentNumKarts(); - KartControl c; - // Send the number of karts and for each kart the compressed - // control structure, xyz,hpr, and speed (which is necessary to - // display the speed, and e.g. to determine when a parachute is detached) - len += 1 + num_karts*(KartControl::getLength() - + getVec3Length()+getQuaternionLength() - + getFloatLength()) ; - - // 2. Add information about collected items - // --------------------------------------- - len += 1 + m_item_info.size()* ItemInfo::getLength(); - - // 3. Add rocket positions - // ----------------------- - len += 2 + m_flyable_info.size()*FlyableInfo::getLength(); - - // 4. Add collisions - // ================= - len += 1 + m_collision_info.size()*getCharLength(); - - // Now add the data - // ================ - allocate(len); - - // 1. Kart positions - // ----------------- - addChar(num_karts); - World *world = World::getWorld(); - for(unsigned int i=0; igetKart(i); - m_kart_controls[i].serialise(this); - addVec3(kart->getXYZ()); - addQuaternion(kart->getRotation()); - addFloat(kart->getSpeed()); - } // for i - - // 2. Collected items - // ----------------- - addChar(m_item_info.size()); - for(unsigned int i=0; igetKart(i); - // Firing needs to be done from here to guarantee that any potential - // new rockets are created before the update for the rockets is handled - if(kc.m_fire) - kart->getPowerup()->use(); - kart->setXYZ(xyz); - kart->setRotation(q); - kart->setSpeed(getFloat()); - } // for i - - // 2. Collected Items - // ----------------- - unsigned short num_items=getChar(); - for(unsigned int i=0; igetKart(hi.m_kart_id)); - else - { - Item *item = ItemManager::get()->getItem(hi.m_item_id); - ItemManager::get()->collectedItem(item, - world->getKart(hi.m_kart_id), - hi.m_add_info); - } - } - - // 3. Projectiles - // -------------- - unsigned short num_flyables = getShort(); - m_flyable_info.clear(); - m_flyable_info.resize(num_flyables); - for(unsigned short i=0; igetKart(kart_id1)->crashed(NULL, normal); - } - else - { - // FIXME: KartKartCollision now takes information about the - // collision points. This either needs to be added as the third - // parameter, or perhaps the outcome of the collision (the - // impulse) could be added. - world->getPhysics()->KartKartCollision( - world->getKart(kart_id1), Vec3(0,0,0), - world->getKart(kart_id2), Vec3(0,0,0)); - } - } // for(i=0; i - -#include "items/flyable.hpp" -#include "items/item.hpp" -#include "karts/abstract_kart.hpp" -#include "karts/controller/kart_control.hpp" -#include "modes/world.hpp" -#include "network/flyable_info.hpp" -#include "network/item_info.hpp" -#include "network/message.hpp" -#include "utils/aligned_array.hpp" - -/** This class stores the state information of a (single) race, e.g. the - position and orientation of karts, collisions that have happened etc. - It is used for the network version to update the clients with the - 'official' state information from the server. - */ -class RaceState : public Message -{ -private: - - /** Updates about collected items. */ - std::vector m_item_info; - /** Updates about existing flyables. */ - AlignedArray m_flyable_info; - /** Stores the controls of each kart at the beginning of its update(). */ - std::vector m_kart_controls; - /** Collision information. This vector stores information about which - * kart collided with which kart or track (kartid=-1) */ - std::vector m_collision_info; - - public: - /** Initialise the global race state. */ - RaceState() : Message(MT_RACE_STATE) - { - m_kart_controls.resize(World::getWorld()->getNumKarts()); - } // RaceState() - // -------------------------------------------------------------------- - void itemCollected(int kartid, int item_id, char add_info=-1) - { - m_item_info.push_back(ItemInfo(kartid, item_id, add_info)); - } // itemCollected - // -------------------------------------------------------------------- - /** Collects information about collision in which at least one kart was - * involved. Other collision (e.g. projectiles, moving physics) are - * not needed on the client, so it's not stored at all. If a kart - * track collision happens, the second kart id is -1 (necessary to - * play back sound effects). A simple int vector is used to store the - * pair of collision, so the first collision is using the index 0 and - * 1; the second one 2 and 3 etc. - * \param kartId1 World id of the kart involved in the collision. - * \param kartId2 World id of the 2nd kart involved in the collision, - * or -1 if it's the track (which is the default). - */ - void addCollision(signed char kartId1, signed char kartId2=-1) - { - m_collision_info.push_back(kartId1); - m_collision_info.push_back(kartId2); - } // addCollision - // -------------------------------------------------------------------- - void setNumFlyables(int n) { m_flyable_info.resize(n); } - // -------------------------------------------------------------------- - void setFlyableInfo(int n, const FlyableInfo& fi) - { - m_flyable_info[n] = fi; - } - // -------------------------------------------------------------------- - /** Stores the current kart control (at the time kart->update() is - * called. This allows modifications of kart->m_control during the - * update (e.g. see in kart::update() how firing is handled). - */ - void storeKartControls(const AbstractKart& kart) - { - m_kart_controls[kart.getWorldKartId()] = kart.getControls(); - } // storeKartControls - // -------------------------------------------------------------------- - void serialise(); - void receive(ENetPacket *pkt); - void clear(); // Removes all currently stored information - unsigned int getNumFlyables() const {return m_flyable_info.size(); } - const FlyableInfo - &getFlyable(unsigned int i) const {return m_flyable_info[i];} - }; // RaceState - -extern RaceState *race_state; - -#endif - diff --git a/src/network/server_network_manager.cpp b/src/network/server_network_manager.cpp new file mode 100644 index 000000000..8ebe083fa --- /dev/null +++ b/src/network/server_network_manager.cpp @@ -0,0 +1,117 @@ +// +// SuperTuxKart - a fun racing game with go-kart +// Copyright (C) 2013 SuperTuxKart-Team +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 3 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +#include "network/server_network_manager.hpp" + +#include "network/protocols/get_public_address.hpp" +#include "network/protocols/hide_public_address.hpp" +#include "network/protocols/show_public_address.hpp" +#include "network/protocols/get_peer_address.hpp" +#include "network/protocols/connect_to_server.hpp" + +#include "utils/log.hpp" + +#include +#include + +ServerNetworkManager::ServerNetworkManager() +{ + m_localhost = NULL; +} + +ServerNetworkManager::~ServerNetworkManager() +{ +} + +void ServerNetworkManager::run() +{ + if (enet_initialize() != 0) + { + Log::error("ServerNetworkManager", "Could not initialize enet.\n"); + return; + } + NetworkManager::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 char* data) +{ + m_localhost->broadcastPacket(data); +} diff --git a/src/network/server_network_manager.hpp b/src/network/server_network_manager.hpp new file mode 100644 index 000000000..1895a70f9 --- /dev/null +++ b/src/network/server_network_manager.hpp @@ -0,0 +1,49 @@ +// +// SuperTuxKart - a fun racing game with go-kart +// Copyright (C) 2013 SuperTuxKart-Team +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 3 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +#ifndef SERVER_NETWORK_MANAGER_HPP +#define SERVER_NETWORK_MANAGER_HPP + +#include "network/network_manager.hpp" + + +class ServerNetworkManager : public NetworkManager +{ + friend class Singleton; + public: + static ServerNetworkManager* getInstance() + { + return Singleton::getInstance(); + } + + virtual void run(); + + void start(); + bool connectToPeer(std::string peer_username); + + virtual void sendPacket(const char* data); + + virtual bool isServer() { return false; } + + protected: + ServerNetworkManager(); + virtual ~ServerNetworkManager(); + +}; + +#endif // SERVER_NETWORK_MANAGER_HPP diff --git a/src/network/singleton.hpp b/src/network/singleton.hpp new file mode 100644 index 000000000..168d8d720 --- /dev/null +++ b/src/network/singleton.hpp @@ -0,0 +1,65 @@ +// +// SuperTuxKart - a fun racing game with go-kart +// Copyright (C) 2013 SuperTuxKart-Team +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 3 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +#ifndef SINGLETON_HPP +#define SINGLETON_HPP + +#include "utils/log.hpp" + +template +class Singleton +{ + protected: + Singleton () { m_singleton = NULL; } + virtual ~Singleton () + { + Log::info("Singleton", "Destroyed singleton."); + } + + public: + template + static S *getInstance () + { + if (m_singleton == NULL) + m_singleton = new S; + + 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."); + return result; + } + static T *getInstance() + { + return (dynamic_cast (m_singleton)); + } + + static void kill () + { + if (m_singleton) + { + delete m_singleton; + } + } + + private: + static T *m_singleton; +}; + +template T *Singleton::m_singleton = NULL; + +#endif // SINGLETON_HPP diff --git a/src/network/stk_host.cpp b/src/network/stk_host.cpp new file mode 100644 index 000000000..6adfe761a --- /dev/null +++ b/src/network/stk_host.cpp @@ -0,0 +1,232 @@ +// +// SuperTuxKart - a fun racing game with go-kart +// Copyright (C) 2013 SuperTuxKart-Team +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 3 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +#include "network/stk_host.hpp" + +#include "network/network_manager.hpp" +#include "utils/log.hpp" + +#include +#include +#include +#include + +// ---------------------------------------------------------------------------- + +void* STKHost::receive_data(void* self) +{ + ENetEvent event; + ENetHost* host = (((STKHost*)(self))->m_host); + while (1) + { + while (enet_host_service(host, &event, 0) != 0) { + Event* evt = new Event(&event); + NetworkManager::getInstance()->notifyEvent(evt); + } + } + return NULL; +} + +// ---------------------------------------------------------------------------- + +STKHost::STKHost() +{ + m_host = NULL; + m_listening_thread = NULL; +} + +// ---------------------------------------------------------------------------- + +STKHost::~STKHost() +{ + if (m_listening_thread) + { + pthread_cancel(*m_listening_thread);//, SIGKILL); + delete m_listening_thread; + m_listening_thread = NULL; + } + if (m_host) + { + enet_host_destroy(m_host); + } +} + +// ---------------------------------------------------------------------------- + +void STKHost::setupServer(uint32_t address, uint16_t port, int peer_count, + int channel_limit, uint32_t max_incoming_bandwidth, + uint32_t max_outgoing_bandwidth) +{ + ENetAddress* addr = (ENetAddress*)(malloc(sizeof(ENetAddress))); + addr->host = address; + addr->port = port; + + m_host = enet_host_create(addr, peer_count, channel_limit, + 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"); + exit (EXIT_FAILURE); + } +} + +// ---------------------------------------------------------------------------- + +void STKHost::setupClient(int peer_count, int channel_limit, + uint32_t max_incoming_bandwidth, + uint32_t max_outgoing_bandwidth) +{ + m_host = enet_host_create(NULL, peer_count, 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"); + exit (EXIT_FAILURE); + } +} + +// ---------------------------------------------------------------------------- + +void STKHost::startListening() +{ + m_listening_thread = (pthread_t*)(malloc(sizeof(pthread_t))); + pthread_create(m_listening_thread, NULL, &STKHost::receive_data, this); +} + +// ---------------------------------------------------------------------------- + +void STKHost::stopListening() +{ + if(m_listening_thread) + { + pthread_cancel(*m_listening_thread); + m_listening_thread = NULL; + } +} + +// ---------------------------------------------------------------------------- + +void STKHost::sendRawPacket(uint8_t* data, int length, TransportAddress dst) +{ + struct sockaddr_in to; + int to_len = sizeof(to); + memset(&to,0,to_len); + + to.sin_family = AF_INET; + to.sin_port = htons(dst.port); + to.sin_addr.s_addr = htonl(dst.ip); + + sendto(m_host->socket, data, length, 0,(sockaddr*)&to, to_len); +} + +// ---------------------------------------------------------------------------- + +uint8_t* STKHost::receiveRawPacket() +{ + uint8_t* buffer; // max size needed normally (only used for stun) + buffer = (uint8_t*)(malloc(sizeof(uint8_t)*2048)); + memset(buffer, 0, 2048); + + int len = recv(m_host->socket,buffer,2048, 0); + int i = 0; + // wait to receive the message because enet sockets are non-blocking + while(len < 0) + { + i++; + len = recv(m_host->socket,buffer,2048, 0); + usleep(1000); + } + return buffer; +} + +// ---------------------------------------------------------------------------- + +uint8_t* STKHost::receiveRawPacket(TransportAddress sender) +{ + uint8_t* buffer; // max size needed normally (only used for stun) + buffer = (uint8_t*)(malloc(sizeof(uint8_t)*2048)); + memset(buffer, 0, 2048); + + socklen_t from_len; + struct sockaddr addr; + + from_len = sizeof(addr); + int len = recvfrom(m_host->socket, buffer, 2048, 0, &addr, &from_len); + + int i = 0; + // wait to receive the message because enet sockets are non-blocking + while(len < 0 || ( + (uint8_t)(addr.sa_data[2]) != (sender.ip>>24&0xff) + && (uint8_t)(addr.sa_data[3]) != (sender.ip>>16&0xff) + && (uint8_t)(addr.sa_data[4]) != (sender.ip>>8&0xff) + && (uint8_t)(addr.sa_data[5]) != (sender.ip&0xff))) + { + i++; + len = recvfrom(m_host->socket, buffer, 2048, 0, &addr, &from_len); + usleep(1000); // wait 1 millisecond between two checks + } + if (addr.sa_family == AF_INET) + { + 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); + } + return buffer; +} + +// ---------------------------------------------------------------------------- + +void STKHost::broadcastPacket(const char* data) +{ + ENetPacket* packet = enet_packet_create(data, strlen(data)+1, + ENET_PACKET_FLAG_RELIABLE); + enet_host_broadcast(m_host, 0, packet); +} + +// ---------------------------------------------------------------------------- + +bool STKHost::peerExists(TransportAddress peer) +{ + for (unsigned int i = 0; i < m_host->peerCount; i++) + { + if (m_host->peers[i].address.host == peer.ip && + m_host->peers[i].address.port == peer.port) + { + return true; + } + } + return false; +} + +// ---------------------------------------------------------------------------- + +bool STKHost::isConnectedTo(TransportAddress peer) +{ + for (unsigned int i = 0; i < m_host->peerCount; i++) + { + if (m_host->peers[i].address.host == peer.ip && + m_host->peers[i].address.port == peer.port && + m_host->peers[i].state == ENET_PEER_STATE_CONNECTED) + { + return true; + } + } + return false; +} diff --git a/src/network/stk_host.hpp b/src/network/stk_host.hpp new file mode 100644 index 000000000..8bae95e08 --- /dev/null +++ b/src/network/stk_host.hpp @@ -0,0 +1,141 @@ +// +// SuperTuxKart - a fun racing game with go-kart +// Copyright (C) 2013 SuperTuxKart-Team +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 3 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +/*! \file stk_host.hpp + * \brief Defines an interface to use network low-level functions easily. + */ +#ifndef STK_HOST_HPP +#define STK_HOST_HPP + +#include +#include "network/types.hpp" + +/*! \class STKHost + * \brief Represents the local host. + * This host is either a server host or a client host. A client host is in + * charge of connecting to a server. A server opens a socket for incoming + * connections. + * By default, this host will use ENet to exchange packets. It also defines an + * interface for ENet use. Nevertheless, this class can be used to send and/or + * receive packets whithout ENet adding its headers. + * This class is used by the Network Manager to send packets. + */ +class STKHost +{ + friend class STKPeer; // allow direct enet modifications in implementations + public: + /*! \enum HOST_TYPE + * \brief Defines three host types for the server. + * These values tells the host where he will accept connections from. + */ + enum HOST_TYPE + { + HOST_ANY = 0, //!< Any host. + HOST_BROADCAST = 0xFFFFFFFF, //!< Defines the broadcast address. + PORT_ANY = 0 //!< Any port. + }; + + /*! \brief Constructor */ + STKHost(); + /*! \brief Destructor */ + virtual ~STKHost(); + + /*! \brief Thread function checking if data is received. + * This function tries to get data from network low-level functions as + * often as possible. When something is received, it generates an + * event and passes it to the Network Manager. + * \param self : used to pass the ENet host to the function. + */ + static void* receive_data(void* self); + + /*! \brief Setups the host as a server. + * \param address : The IPv4 address of incoming connections. + * \param port : The port on which the server listens. + * \param peer_count : The maximum number of peers. + * \param channel_limit : The maximum number of channels per peer. + * \param max_incoming_bandwidth : The maximum incoming bandwidth. + * \param max_outgoing_bandwidth : The maximum outgoing bandwidth. + */ + void setupServer(uint32_t address, uint16_t port, + int peer_count, int channel_limit, + uint32_t max_incoming_bandwidth, + uint32_t max_outgoing_bandwidth); + /*! \brief Setups the host as a client. + * In fact there is only one peer connected to this host. + * \param peer_count : The maximum number of peers. + * \param channel_limit : The maximum number of channels per peer. + * \param max_incoming_bandwidth : The maximum incoming bandwidth. + * \param max_outgoing_bandwidth : The maximum outgoing bandwidth. + */ + void setupClient(int peer_count, int channel_limit, + uint32_t max_incoming_bandwidth, + uint32_t max_outgoing_bandwidth); + + /*! \brief Starts the listening of events from ENet. + * Starts a thread that updates it as often as possible. + */ + void startListening(); + /*! \brief Stops the listening of events from ENet. + * Stops the thread that was receiving events. + */ + void stopListening(); + + /*! \brief Sends a packet whithout ENet adding its headers. + * This function is used in particular to achieve the STUN protocol. + * \param data : Data to send. + * \param length : Length of the sent data. + * \param dst : Destination of the packet. + */ + void sendRawPacket(uint8_t* data, int length, + TransportAddress dst); + /*! \brief Receives a packet directly from the network interface. + * Receive a packet whithout ENet processing it. + * \return A string containing the data of the received packet. + */ + uint8_t* receiveRawPacket(); + /*! \brief Receives a packet directly from the network interface and + * filter its address. + * Receive a packet whithout ENet processing it. Checks that the + * sender of the packet is the one that corresponds to the sender + * parameter. Does not check the port right now. + * \param sender : Transport address of the original sender of the + * wanted packet. + * \return A string containing the data of the received packet + * matching the sender's ip address. + */ + uint8_t* receiveRawPacket(TransportAddress sender); + /*! \brief Broadcasts a packet to all peers. + * \param data : Data to send. + */ + void broadcastPacket(const char* data); + + /*! \brief Tells if a peer is known. + * \return True if the peer is known, false elseway. + */ + bool peerExists(TransportAddress peer_address); + /*! \brief Tells if a peer is known and connected. + * \return True if the peer is known and connected, false elseway. + */ + bool isConnectedTo(TransportAddress peer_address); + protected: + ENetHost* m_host; //!< ENet host interfacing sockets. + pthread_t* m_listening_thread; //!< Thread listening network events. + +}; + +#endif // STK_HOST_HPP diff --git a/src/network/stk_peer.cpp b/src/network/stk_peer.cpp new file mode 100644 index 000000000..3ea5a0006 --- /dev/null +++ b/src/network/stk_peer.cpp @@ -0,0 +1,81 @@ +// +// SuperTuxKart - a fun racing game with go-kart +// Copyright (C) 2013 SuperTuxKart-Team +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 3 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +#include "network/stk_peer.hpp" + +#include "utils/log.hpp" + +#include + +STKPeer::STKPeer() +{ + m_peer = NULL; +} + +STKPeer::~STKPeer() +{ + if (m_peer) + { + //free(m_peer); + m_peer = NULL; + } +} + +bool STKPeer::connectToHost(STKHost* localhost, TransportAddress host, uint32_t channel_count, uint32_t data) +{ + ENetAddress address; + address.host = host.ip; + address.port = host.port; + + ENetPeer* peer = enet_host_connect(localhost->m_host, &address, 2, 0); + if (peer == NULL) + { + Log::error("STKPeer", "Could not try to connect to server.\n"); + return false; + } + Log::info("STKPeer", "Connecting to %i.%i.%i.%i:%i.\n", (peer->address.host>>0)&0xff,(peer->address.host>>8)&0xff,(peer->address.host>>16)&0xff,(peer->address.host>>24)&0xff,peer->address.port); + return true; +} + +void STKPeer::sendPacket(const char* data) +{ + //Log::info("STKPeer", "sending packet to %i.%i.%i.%i:%i", (m_peer->address.host>>24)&0xff,(m_peer->address.host>>16)&0xff,(m_peer->address.host>>8)&0xff,(m_peer->address.host>>0)&0xff,m_peer->address.port); + + ENetPacket* packet = enet_packet_create(data, strlen(data)+1,ENET_PACKET_FLAG_RELIABLE); + enet_peer_send(m_peer, 0, packet); +} + +uint32_t STKPeer::getAddress() +{ + return m_peer->address.host; +} + +uint16_t STKPeer::getPort() +{ + return m_peer->address.port; +} + +bool STKPeer::isConnected() +{ + 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) +{ + return peer==m_peer; +} diff --git a/src/network/network_kart.hpp b/src/network/stk_peer.hpp similarity index 55% rename from src/network/network_kart.hpp rename to src/network/stk_peer.hpp index 892439a24..cc3709b93 100644 --- a/src/network/network_kart.hpp +++ b/src/network/stk_peer.hpp @@ -1,6 +1,6 @@ // // SuperTuxKart - a fun racing game with go-kart -// Copyright (C) 2008 Joerg Henrichs +// Copyright (C) 2013 SuperTuxKart-Team // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License @@ -16,22 +16,30 @@ // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -#ifndef HEADER_NETWORK_KART_HPP -#define HEADER_NETWORK_KART_HPP +#ifndef STK_PEER_HPP +#define STK_PEER_HPP -#include "karts/kart.hpp" +#include "network/stk_host.hpp" +#include -class Track; - -class NetworkKart : public Kart +class STKPeer { -private: - int m_global_player_id; // to identify this kart to the network manager -public: - NetworkKart(const std::string& kart_name, unsigned int world_kart_id, - int position, const btTransform& init_transform, - int global_player_id, RaceManager::KartType type); - void setControl(const KartControl& kc); - virtual bool isNetworkKart() const { return true; } -}; // NetworkKart -#endif + friend class Event; + public: + STKPeer(); + virtual ~STKPeer(); + + virtual void sendPacket(const char* data); + + static bool connectToHost(STKHost* localhost, TransportAddress host, uint32_t channel_count, uint32_t data); + + bool isConnected(); + + uint32_t getAddress(); + uint16_t getPort(); + bool operator==(ENetPeer* peer); + protected: + ENetPeer* m_peer; +}; + +#endif // STK_PEER_HPP diff --git a/src/network/types.hpp b/src/network/types.hpp new file mode 100644 index 000000000..dd5b62709 --- /dev/null +++ b/src/network/types.hpp @@ -0,0 +1,68 @@ +// +// SuperTuxKart - a fun racing game with go-kart +// Copyright (C) 2013 SuperTuxKart-Team +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 3 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +/*! \file types.hpp + * \brief Declares the general types that are used by the network. + */ +#ifndef TYPES_HPP +#define TYPES_HPP + +#include +#include + +/*! \class CallbackObject + * \brief Class that must be inherited to pass objects to protocols. + */ +class CallbackObject +{ + public: + CallbackObject() {} + ~CallbackObject() {} + +}; + +/*! \class TransportAddress + * \brief Describes a transport-layer address. + * For IP networks, a transport address is the couple ip:port. + */ +class TransportAddress : public CallbackObject +{ + public: + TransportAddress(uint32_t p_ip = 0, uint16_t p_port = 0) + { ip = p_ip; port = p_port; } + ~TransportAddress() {} + + uint32_t ip; //!< The IPv4 address + uint16_t port; //!< The port number +}; + +/*! \class PlayerLogin + * \brief Contains the information needed to authenticate a user. + */ +class PlayerLogin : public CallbackObject +{ + public: + PlayerLogin() {} + ~PlayerLogin() { username.clear(); password.clear(); } + + std::string username; //!< Username of the player + std::string password; //!< Password of the player +}; + + +#endif // TYPES_HPP diff --git a/src/network/world_loaded_message.hpp b/src/network/world_loaded_message.hpp deleted file mode 100644 index 682e0fa05..000000000 --- a/src/network/world_loaded_message.hpp +++ /dev/null @@ -1,31 +0,0 @@ -// -// SuperTuxKart - a fun racing game with go-kart -// Copyright (C) 2008 Joerg Henrichs -// -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License -// as published by the Free Software Foundation; either version 3 -// of the License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -#ifndef HEADER_WORLD_LOADED_HPP -#define HEADER_WORLD_LOADED_HPP - -#include "network/message.hpp" - -class WorldLoadedMessage : public Message -{ -// For now this is an empty message -public: - WorldLoadedMessage() :Message(MT_WORLD_LOADED) {allocate(0);} - WorldLoadedMessage(ENetPacket* pkt):Message(pkt, MT_WORLD_LOADED) {} -}; // WorldLoadedMessage -#endif diff --git a/src/physics/physics.cpp b/src/physics/physics.cpp index eaaeee67d..22a470b9b 100644 --- a/src/physics/physics.cpp +++ b/src/physics/physics.cpp @@ -19,9 +19,12 @@ #include "physics/physics.hpp" #include "animations/three_d_animation.hpp" +#include "karts/abstract_kart.hpp" #include "karts/kart_properties.hpp" #include "karts/rescue_animation.hpp" -#include "network/race_state.hpp" +#include "items/flyable.hpp" +#include "items/item.hpp" +#include "modes/world.hpp" #include "graphics/stars.hpp" #include "karts/explosion_animation.hpp" #include "physics/btKart.hpp" @@ -156,8 +159,8 @@ void Physics::update(float dt) { AbstractKart *a=p->getUserPointer(0)->getPointerKart(); AbstractKart *b=p->getUserPointer(1)->getPointerKart(); - race_state->addCollision(a->getWorldKartId(), - b->getWorldKartId()); +// race_state->addCollision(a->getWorldKartId(), +// b->getWorldKartId()); KartKartCollision(p->getUserPointer(0)->getPointerKart(), p->getContactPointCS(0), p->getUserPointer(1)->getPointerKart(), @@ -443,7 +446,7 @@ btScalar Physics::solveGroup(btCollisionObject** bodies, int numBodies, else if(upB->is(UserPointer::UP_KART)) { AbstractKart *kart=upB->getPointerKart(); - race_state->addCollision(kart->getWorldKartId()); +// race_state->addCollision(kart->getWorldKartId()); int n = contact_manifold->getContactPoint(0).m_index0; const Material *m = n>=0 ? upA->getPointerTriangleMesh()->getMaterial(n) @@ -463,7 +466,7 @@ btScalar Physics::solveGroup(btCollisionObject** bodies, int numBodies, if(upB->is(UserPointer::UP_TRACK)) { AbstractKart *kart = upA->getPointerKart(); - race_state->addCollision(kart->getWorldKartId()); +// race_state->addCollision(kart->getWorldKartId()); int n = contact_manifold->getContactPoint(0).m_index1; const Material *m = n>=0 ? upB->getPointerTriangleMesh()->getMaterial(n) diff --git a/src/race/history.hpp b/src/race/history.hpp index 22aa430ed..71d38a034 100644 --- a/src/race/history.hpp +++ b/src/race/history.hpp @@ -20,6 +20,7 @@ #define HEADER_HISTORY_HPP #include +#include #include "LinearMath/btQuaternion.h" diff --git a/src/race/race_manager.cpp b/src/race/race_manager.cpp index b7247bedf..d68334a2a 100644 --- a/src/race/race_manager.cpp +++ b/src/race/race_manager.cpp @@ -143,9 +143,9 @@ void RaceManager::setLocalKartInfo(unsigned int player_id, assert(0<=player_id && player_id getKart(kart) != NULL); - m_local_player_karts[player_id] = RemoteKartInfo(player_id, kart, +/* m_local_player_karts[player_id] = RemoteKartInfo(player_id, kart, StateManager::get()->getActivePlayerProfile(player_id)->getName(), - network_manager->getMyHostId()); + network_manager->getMyHostId());*/ } // setLocalKartInfo //----------------------------------------------------------------------------- @@ -293,7 +293,7 @@ void RaceManager::startNew(bool from_overworld) // Create the kart status data structure to keep track of scores, times, ... // ========================================================================== m_kart_status.clear(); - + printf("%u %lu %lu\n", (unsigned int)m_num_karts, m_ai_kart_list.size(), m_player_karts.size()); assert((unsigned int)m_num_karts == m_ai_kart_list.size()+m_player_karts.size()); // First add the AI karts (randomly chosen) @@ -321,8 +321,8 @@ void RaceManager::startNew(bool from_overworld) // ------------------------------------------------- for(int i=m_player_karts.size()-1; i>=0; i--) { - KartType kt=(m_player_karts[i].getHostId()==network_manager->getMyHostId()) - ? KT_PLAYER : KT_NETWORK_PLAYER; + KartType kt= KT_PLAYER; //(m_player_karts[i].getHostId()==network_manager->getMyHostId()) + //? KT_PLAYER : KT_NETWORK_PLAYER; m_kart_status.push_back(KartStatus(m_player_karts[i].getKartName(), i, m_player_karts[i].getLocalPlayerId(), m_player_karts[i].getGlobalPlayerId(), @@ -510,20 +510,20 @@ void RaceManager::next() user_config->saveConfig(); } - if(network_manager->getMode()==NetworkManager::NW_SERVER) - network_manager->beginReadySetGoBarrier(); - else - network_manager->setState(NetworkManager::NS_WAIT_FOR_RACE_DATA); +// if(network_manager->getMode()==NetworkManager::NW_SERVER) +// network_manager->beginReadySetGoBarrier(); +// else +// network_manager->setState(NetworkManager::NS_WAIT_FOR_RACE_DATA); startNextRace(); } else { // Back to main menu. Change the state of the state of the // network manager. - if(network_manager->getMode()==NetworkManager::NW_SERVER) - network_manager->setState(NetworkManager::NS_MAIN_MENU); - else - network_manager->setState(NetworkManager::NS_WAIT_FOR_AVAILABLE_CHARACTERS); +// if(network_manager->getMode()==NetworkManager::NW_SERVER) +// network_manager->setState(NetworkManager::NS_MAIN_MENU); +// else +// network_manager->setState(NetworkManager::NS_WAIT_FOR_AVAILABLE_CHARACTERS); exitRace(); } } // next @@ -753,7 +753,7 @@ void RaceManager::startGP(const GrandPrixData* gp, bool from_overworld) StateManager::get()->enterGameState(); setGrandPrix(*gp); setCoinTarget( 0 ); // Might still be set from a previous challenge - network_manager->setupPlayerKartInfo(); +// network_manager->setupPlayerKartInfo(); setMajorMode(RaceManager::MAJOR_MODE_GRAND_PRIX); startNew(from_overworld); @@ -778,7 +778,7 @@ void RaceManager::startSingleRace(const std::string &track_ident, setMajorMode(RaceManager::MAJOR_MODE_SINGLE); setCoinTarget( 0 ); // Might still be set from a previous challenge - network_manager->setupPlayerKartInfo(); +// network_manager->setupPlayerKartInfo(); startNew(from_overworld); } diff --git a/src/states_screens/dialogs/race_paused_dialog.cpp b/src/states_screens/dialogs/race_paused_dialog.cpp index 3e46dea4b..3e98e0caa 100644 --- a/src/states_screens/dialogs/race_paused_dialog.cpp +++ b/src/states_screens/dialogs/race_paused_dialog.cpp @@ -146,7 +146,7 @@ GUIEngine::EventPropagation else if (selection == "restart") { ModalDialog::dismiss(); - network_manager->setState(NetworkManager::NS_MAIN_MENU); +// network_manager->setState(NetworkManager::NS_MAIN_MENU); World::getWorld()->scheduleUnpause(); race_manager->rerunRace(); return GUIEngine::EVENT_BLOCK; diff --git a/src/states_screens/dialogs/select_challenge.cpp b/src/states_screens/dialogs/select_challenge.cpp index 174d67358..2ff9a7a0c 100644 --- a/src/states_screens/dialogs/select_challenge.cpp +++ b/src/states_screens/dialogs/select_challenge.cpp @@ -201,7 +201,7 @@ GUIEngine::EventPropagation SelectChallengeDialog::processEvent(const std::strin // Initialise global data - necessary even in local games to avoid // many if tests in other places (e.g. if network_game call // network_manager else call race_manager). - network_manager->initCharacterDataStructures(); +// network_manager->initCharacterDataStructures(); // Launch challenge if (eventSource == "novice") @@ -228,7 +228,7 @@ GUIEngine::EventPropagation SelectChallengeDialog::processEvent(const std::strin } // Sets up kart info, including random list of kart for AI - network_manager->setupPlayerKartInfo(); +// network_manager->setupPlayerKartInfo(); race_manager->startNew(true); irr_driver->hidePointer(); diff --git a/src/states_screens/help_screen_1.cpp b/src/states_screens/help_screen_1.cpp index 20ac321d9..a11e208e1 100644 --- a/src/states_screens/help_screen_1.cpp +++ b/src/states_screens/help_screen_1.cpp @@ -82,7 +82,7 @@ void HelpScreen1::eventCallback(Widget* widget, const std::string& name, const i ->setSinglePlayer( StateManager::get()->getActivePlayer(0) ); StateManager::get()->enterGameState(); - network_manager->setupPlayerKartInfo(); +// network_manager->setupPlayerKartInfo(); race_manager->startNew(false); } else if (name == "category") diff --git a/src/states_screens/main_menu_screen.cpp b/src/states_screens/main_menu_screen.cpp index 06b632b00..bd6288e7c 100644 --- a/src/states_screens/main_menu_screen.cpp +++ b/src/states_screens/main_menu_screen.cpp @@ -332,7 +332,7 @@ void MainMenuScreen::eventCallback(Widget* widget, const std::string& name, ->setSinglePlayer( StateManager::get()->getActivePlayer(0) ); StateManager::get()->enterGameState(); - network_manager->setupPlayerKartInfo(); +// network_manager->setupPlayerKartInfo(); race_manager->startNew(false); } else if (selection == "story")