From 8656a12d12f87ba737c3a9471d017d7ad7691704 Mon Sep 17 00:00:00 2001 From: unitraxx Date: Tue, 30 Jul 2013 22:05:06 +0000 Subject: [PATCH] Undoing last commit which was not what I wanted after all. git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/branches/uni@13391 178a84e3-b1eb-0310-8ba1-8eac791a3b58 --- data/gui/online/lobby.stkgui | 8 +- diff.patch | 9473 +++++++++++++++++ doc/protocols.xls | Bin 10240 -> 0 bytes src/addons/network_http.hpp | 2 +- src/config/user_config.hpp | 14 +- src/guiengine/modaldialog.cpp | 5 +- src/ide/vc9/supertuxkart.vcproj | 266 +- src/io/xml_node.cpp | 18 +- src/io/xml_node.hpp | 1 - src/items/attachment.cpp | 11 + src/items/flyable.cpp | 14 + src/items/flyable.hpp | 2 + src/items/item_manager.cpp | 4 + src/items/powerup.cpp | 2 + src/items/projectile_manager.cpp | 49 +- src/items/projectile_manager.hpp | 1 + src/items/rubber_ball.cpp | 2 - src/karts/controller/end_controller.cpp | 1 + src/karts/controller/kart_control.hpp | 23 +- src/karts/controller/skidding_ai.cpp | 8 + src/karts/kart.cpp | 25 +- src/main.cpp | 73 +- src/main_loop.cpp | 19 + src/modes/demo_world.cpp | 3 +- src/modes/linear_world.cpp | 9 +- src/modes/overworld.cpp | 3 +- src/modes/world.cpp | 13 +- src/modes/world_status.cpp | 3 + src/network/character_confirm_message.hpp | 71 + src/network/character_info_message.hpp | 50 + src/network/character_selected_message.hpp | 105 + src/network/client_network_manager.cpp | 94 - src/network/client_network_manager.hpp | 46 - src/network/connect_message.cpp | 77 + ...public_address.hpp => connect_message.hpp} | 40 +- src/network/event.cpp | 81 - src/network/event.hpp | 72 - src/network/flyable_info.hpp | 70 + src/network/game_setup.cpp | 100 - src/network/game_setup.hpp | 67 - src/network/http_functions.cpp | 67 - src/network/item_info.hpp | 66 + src/network/kart_control_message.cpp | 61 + ...interface.cpp => kart_control_message.hpp} | 19 +- src/network/kart_update_message.cpp | 62 + ..._functions.hpp => kart_update_message.hpp} | 25 +- src/network/message.cpp | 225 + src/network/message.hpp | 143 + src/network/network_kart.cpp | 43 + ...network_interface.hpp => network_kart.hpp} | 39 +- src/network/network_manager.cpp | 819 +- src/network/network_manager.hpp | 154 +- src/network/network_string.cpp | 8 - src/network/network_string.hpp | 211 - src/network/num_players_message.hpp | 42 + src/network/protocol.hpp | 108 - src/network/protocol_manager.cpp | 377 - src/network/protocol_manager.hpp | 295 - src/network/protocols/connect_to_peer.cpp | 122 - src/network/protocols/connect_to_peer.hpp | 53 - src/network/protocols/connect_to_server.cpp | 155 - src/network/protocols/connect_to_server.hpp | 57 - src/network/protocols/get_peer_address.cpp | 89 - src/network/protocols/get_peer_address.hpp | 47 - src/network/protocols/get_public_address.cpp | 206 - src/network/protocols/get_public_address.hpp | 47 - src/network/protocols/hide_public_address.cpp | 76 - src/network/protocols/lobby_room_protocol.cpp | 338 - src/network/protocols/lobby_room_protocol.hpp | 102 - src/network/protocols/ping_protocol.cpp | 33 - src/network/protocols/ping_protocol.hpp | 23 - src/network/protocols/request_connection.cpp | 64 - src/network/protocols/request_connection.hpp | 28 - src/network/protocols/show_public_address.cpp | 80 - src/network/protocols/start_server.cpp | 62 - src/network/protocols/start_server.hpp | 29 - src/network/protocols/stop_server.cpp | 61 - src/network/protocols/stop_server.hpp | 29 - src/network/race_info_message.cpp | 116 + .../{protocol.cpp => race_info_message.hpp} | 43 +- src/network/race_result_ack_message.hpp | 58 + src/network/race_result_message.cpp | 60 + src/network/race_result_message.hpp | 45 + ...lic_address.hpp => race_start_message.hpp} | 43 +- src/network/race_state.cpp | 195 + src/network/race_state.hpp | 109 + src/network/server_network_manager.cpp | 99 - src/network/server_network_manager.hpp | 50 - src/network/singleton.hpp | 65 - src/network/stk_host.cpp | 239 - src/network/stk_host.hpp | 145 - src/network/stk_peer.cpp | 85 - src/network/stk_peer.hpp | 54 - src/network/types.cpp | 9 - src/network/types.hpp | 71 - src/network/world_loaded_message.hpp | 31 + src/physics/physics.cpp | 8 +- src/race/history.hpp | 1 - src/race/race_manager.cpp | 50 +- src/race/race_manager.hpp | 3 - src/states_screens/dialogs/login_dialog.cpp | 20 +- .../dialogs/race_paused_dialog.cpp | 2 +- .../dialogs/select_challenge.cpp | 4 +- .../dialogs/track_info_dialog.cpp | 1 + src/states_screens/help_screen_1.cpp | 3 +- src/states_screens/main_menu_screen.cpp | 3 +- .../networking_lobby_settings.cpp | 114 - .../networking_lobby_settings.hpp | 78 - src/states_screens/online_screen.cpp | 28 +- src/tracks/track.cpp | 12 +- src/utils/types.hpp | 2 - 111 files changed, 12301 insertions(+), 4935 deletions(-) create mode 100644 diff.patch delete mode 100644 doc/protocols.xls create mode 100644 src/network/character_confirm_message.hpp create mode 100644 src/network/character_info_message.hpp create mode 100644 src/network/character_selected_message.hpp delete mode 100644 src/network/client_network_manager.cpp delete mode 100644 src/network/client_network_manager.hpp create mode 100644 src/network/connect_message.cpp rename src/network/{protocols/show_public_address.hpp => connect_message.hpp} (59%) delete mode 100644 src/network/event.cpp delete mode 100644 src/network/event.hpp create mode 100644 src/network/flyable_info.hpp delete mode 100644 src/network/game_setup.cpp delete mode 100644 src/network/game_setup.hpp delete mode 100644 src/network/http_functions.cpp create mode 100644 src/network/item_info.hpp create mode 100644 src/network/kart_control_message.cpp rename src/network/{network_interface.cpp => kart_control_message.hpp} (68%) create mode 100644 src/network/kart_update_message.cpp rename src/network/{http_functions.hpp => kart_update_message.hpp} (72%) create mode 100644 src/network/message.cpp create mode 100644 src/network/message.hpp create mode 100644 src/network/network_kart.cpp rename src/network/{network_interface.hpp => network_kart.hpp} (56%) delete mode 100644 src/network/network_string.cpp delete mode 100644 src/network/network_string.hpp create mode 100644 src/network/num_players_message.hpp delete mode 100644 src/network/protocol.hpp delete mode 100644 src/network/protocol_manager.cpp delete mode 100644 src/network/protocol_manager.hpp delete mode 100644 src/network/protocols/connect_to_peer.cpp delete mode 100644 src/network/protocols/connect_to_peer.hpp delete mode 100644 src/network/protocols/connect_to_server.cpp delete mode 100644 src/network/protocols/connect_to_server.hpp delete mode 100644 src/network/protocols/get_peer_address.cpp delete mode 100644 src/network/protocols/get_peer_address.hpp delete mode 100644 src/network/protocols/get_public_address.cpp delete mode 100644 src/network/protocols/get_public_address.hpp delete mode 100644 src/network/protocols/hide_public_address.cpp delete mode 100644 src/network/protocols/lobby_room_protocol.cpp delete mode 100644 src/network/protocols/lobby_room_protocol.hpp delete mode 100644 src/network/protocols/ping_protocol.cpp delete mode 100644 src/network/protocols/ping_protocol.hpp delete mode 100644 src/network/protocols/request_connection.cpp delete mode 100644 src/network/protocols/request_connection.hpp delete mode 100644 src/network/protocols/show_public_address.cpp delete mode 100644 src/network/protocols/start_server.cpp delete mode 100644 src/network/protocols/start_server.hpp delete mode 100644 src/network/protocols/stop_server.cpp delete mode 100644 src/network/protocols/stop_server.hpp create mode 100644 src/network/race_info_message.cpp rename src/network/{protocol.cpp => race_info_message.hpp} (59%) create mode 100644 src/network/race_result_ack_message.hpp create mode 100644 src/network/race_result_message.cpp create mode 100644 src/network/race_result_message.hpp rename src/network/{protocols/hide_public_address.hpp => race_start_message.hpp} (58%) create mode 100644 src/network/race_state.cpp create mode 100644 src/network/race_state.hpp delete mode 100644 src/network/server_network_manager.cpp delete mode 100644 src/network/server_network_manager.hpp delete mode 100644 src/network/singleton.hpp delete mode 100644 src/network/stk_host.cpp delete mode 100644 src/network/stk_host.hpp delete mode 100644 src/network/stk_peer.cpp delete mode 100644 src/network/stk_peer.hpp delete mode 100644 src/network/types.cpp delete mode 100644 src/network/types.hpp create mode 100644 src/network/world_loaded_message.hpp delete mode 100644 src/states_screens/networking_lobby_settings.cpp delete mode 100644 src/states_screens/networking_lobby_settings.hpp diff --git a/data/gui/online/lobby.stkgui b/data/gui/online/lobby.stkgui index e0ccb94a9..81bbd2256 100644 --- a/data/gui/online/lobby.stkgui +++ b/data/gui/online/lobby.stkgui @@ -38,12 +38,8 @@ - - - + diff --git a/diff.patch b/diff.patch new file mode 100644 index 000000000..ddd9d40ac --- /dev/null +++ b/diff.patch @@ -0,0 +1,9473 @@ +Index: src/items/projectile_manager.hpp +=================================================================== +--- src/items/projectile_manager.hpp (revision 13389) ++++ src/items/projectile_manager.hpp (revision 13390) +@@ -53,7 +53,6 @@ + * being shown or have a sfx playing. */ + HitEffects m_active_hit_effects; + +- void updateClient(float dt); + void updateServer(float dt); + public: + ProjectileManager() {} +Index: src/items/powerup.cpp +=================================================================== +--- src/items/powerup.cpp (revision 13389) ++++ src/items/powerup.cpp (revision 13390) +@@ -29,8 +29,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" +Index: src/items/rubber_ball.cpp +=================================================================== +--- src/items/rubber_ball.cpp (revision 13389) ++++ src/items/rubber_ball.cpp (revision 13390) +@@ -419,6 +419,8 @@ + // at it directly, stop interpolating, instead fly straight + // towards it. + Vec3 diff = m_target->getXYZ()-getXYZ(); ++ if(diff.length()==0) ++ printf("diff=0\n"); + *next_xyz = getXYZ() + (dt*m_speed/diff.length())*diff; + + Vec3 old_vec = getXYZ()-m_previous_xyz; +Index: src/items/flyable.cpp +=================================================================== +--- src/items/flyable.cpp (revision 13389) ++++ src/items/flyable.cpp (revision 13390) +@@ -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" +@@ -411,19 +410,6 @@ + } // updateAndDelete + + // ---------------------------------------------------------------------------- +-/** Updates the position of a projectile based on information received frmo the +- * server. +- */ +-void Flyable::updateFromServer(const FlyableInfo &f, float dt) +-{ +- setXYZ(f.m_xyz); +- setRotation(f.m_rotation); +- +- // Update the graphical position +- Moveable::update(dt); +-} // updateFromServer +- +-// ---------------------------------------------------------------------------- + /** Returns true if the item hit the kart who shot it (to avoid that an item + * that's too close to the shoter hits the shoter). + * \param kart Kart who was hit. +Index: src/items/flyable.hpp +=================================================================== +--- src/items/flyable.hpp (revision 13389) ++++ src/items/flyable.hpp (revision 13390) +@@ -34,7 +34,6 @@ + #include "tracks/terrain_info.hpp" + + class AbstractKart; +-class FlyableInfo; + class HitEffect; + class PhysicalObject; + class XMLNode; +@@ -169,7 +168,6 @@ + virtual bool updateAndDelete(float); + virtual const core::stringw getHitString(const AbstractKart *kart) const = 0; + virtual HitEffect* getHitEffect() const; +- void updateFromServer(const FlyableInfo &f, float dt); + bool isOwnerImmunity(const AbstractKart *kart_hit) const; + virtual bool hit(AbstractKart* kart, PhysicalObject* obj=NULL); + void explode(AbstractKart* kart, PhysicalObject* obj=NULL, +Index: src/items/item_manager.cpp +=================================================================== +--- src/items/item_manager.cpp (revision 13389) ++++ src/items/item_manager.cpp (revision 13390) +@@ -29,7 +29,6 @@ + #include "io/file_manager.hpp" + #include "karts/abstract_kart.hpp" + #include "modes/linear_world.hpp" +-#include "network/network_manager.hpp" + #include "tracks/quad_graph.hpp" + #include "tracks/track.hpp" + #include "utils/string_utils.hpp" +@@ -289,9 +288,6 @@ + */ + void ItemManager::checkItemHit(AbstractKart* kart) + { +- // Only do this on the server +- if(network_manager->getMode()==NetworkManager::NW_CLIENT) 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 + // then we also need to check for any adjacent quads (since an item just +Index: src/items/attachment.cpp +=================================================================== +--- src/items/attachment.cpp (revision 13389) ++++ src/items/attachment.cpp (revision 13390) +@@ -33,8 +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" + + /** Initialises the attachment each kart has. +@@ -258,15 +256,6 @@ + new_attachment = m_random.get(3); + } // switch + +- // Save the information about the attachment in the race state +- // so that the clients can be updated. +- if(network_manager->getMode()==NetworkManager::NW_SERVER) +- { +- race_state->itemCollected(m_kart->getWorldKartId(), +- item->getItemId(), +- new_attachment); +- } +- + if (add_a_new_item) + { + switch (new_attachment) +Index: src/items/projectile_manager.cpp +=================================================================== +--- src/items/projectile_manager.cpp (revision 13389) ++++ src/items/projectile_manager.cpp (revision 13390) +@@ -26,8 +26,6 @@ + #include "items/powerup_manager.hpp" + #include "items/powerup.hpp" + #include "items/rubber_ball.hpp" +-#include "network/network_manager.hpp" +-#include "network/race_state.hpp" + + ProjectileManager *projectile_manager=0; + +@@ -66,14 +64,7 @@ + /** General projectile update call. */ + void ProjectileManager::update(float dt) + { +- if(network_manager->getMode()==NetworkManager::NW_CLIENT) +- { +- updateClient(dt); +- } +- else +- { +- updateServer(dt); +- } ++ updateServer(dt); + + HitEffects::iterator he = m_active_hit_effects.begin(); + while(he!=m_active_hit_effects.end()) +@@ -100,23 +91,10 @@ + /** Updates all rockets on the server (or no networking). */ + void ProjectileManager::updateServer(float dt) + { +- // First update all projectiles on the track +- if(network_manager->getMode()!=NetworkManager::NW_NONE) +- { +- 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) +- { +- race_state->setFlyableInfo(p-m_active_projectiles.begin(), +- FlyableInfo((*p)->getXYZ(), +- (*p)->getRotation(), +- can_be_deleted) ); +- } + if(can_be_deleted) + { + HitEffect *he = (*p)->getHitEffect(); +@@ -130,33 +108,10 @@ + else + p++; + } // while p!=m_active_projectiles.end() ++ + } // updateServer + + // ----------------------------------------------------------------------------- +-/** Updates all rockets and hit effects on the client. +- * updateClient takes the information in race_state and updates all rockets +- * (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", +- num_projectiles, (int)m_active_projectiles.size()); +- +- unsigned int indx=0; +- for(Projectiles::iterator i = m_active_projectiles.begin(); +- i != m_active_projectiles.end(); ++i, ++indx) +- { +- const FlyableInfo &f = race_state->getFlyable(indx); +- (*i)->updateFromServer(f, dt); +- if(f.m_exploded) +- { +- (*i)->hit(NULL); +- } +- } // for i in m_active_projectiles +- +-} // updateClient +-// ----------------------------------------------------------------------------- + Flyable *ProjectileManager::newProjectile(AbstractKart *kart, Track* track, + PowerupManager::PowerupType type) + { +Index: src/physics/physics.cpp +=================================================================== +--- src/physics/physics.cpp (revision 13389) ++++ src/physics/physics.cpp (revision 13390) +@@ -19,9 +19,11 @@ + #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 "modes/world.hpp" + #include "graphics/stars.hpp" + #include "karts/explosion_animation.hpp" + #include "physics/btKart.hpp" +@@ -156,8 +158,6 @@ + { + AbstractKart *a=p->getUserPointer(0)->getPointerKart(); + AbstractKart *b=p->getUserPointer(1)->getPointerKart(); +- race_state->addCollision(a->getWorldKartId(), +- b->getWorldKartId()); + KartKartCollision(p->getUserPointer(0)->getPointerKart(), + p->getContactPointCS(0), + p->getUserPointer(1)->getPointerKart(), +@@ -443,7 +443,6 @@ + else if(upB->is(UserPointer::UP_KART)) + { + AbstractKart *kart=upB->getPointerKart(); +- race_state->addCollision(kart->getWorldKartId()); + int n = contact_manifold->getContactPoint(0).m_index0; + const Material *m + = n>=0 ? upA->getPointerTriangleMesh()->getMaterial(n) +@@ -463,7 +462,6 @@ + if(upB->is(UserPointer::UP_TRACK)) + { + AbstractKart *kart = upA->getPointerKart(); +- race_state->addCollision(kart->getWorldKartId()); + int n = contact_manifold->getContactPoint(0).m_index1; + const Material *m + = n>=0 ? upB->getPointerTriangleMesh()->getMaterial(n) +Index: src/karts/kart.cpp +=================================================================== +--- src/karts/kart.cpp (revision 13389) ++++ src/karts/kart.cpp (revision 13390) +@@ -57,8 +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" + #include "physics/btUprightConstraint.hpp" +@@ -878,15 +876,6 @@ + default : break; + } // switch TYPE + +- // 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 && +- (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(); + m_controller->collectedItem(*item, add_info, old_energy); +@@ -1018,14 +1007,6 @@ + + m_slipstream->update(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) +- { +- race_state->storeKartControls(*this); +- } +- + if (!m_flying) + { + // When really on air, free fly, when near ground, try to glide / adjust for landing +@@ -1884,10 +1865,8 @@ + + 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(); +Index: src/karts/controller/skidding_ai.cpp +=================================================================== +--- src/karts/controller/skidding_ai.cpp (revision 13389) ++++ src/karts/controller/skidding_ai.cpp (revision 13390) +@@ -54,7 +54,6 @@ + #include "items/powerup.hpp" + #include "modes/linear_world.hpp" + #include "modes/profile_world.hpp" +-#include "network/network_manager.hpp" + #include "race/race_manager.hpp" + #include "tracks/quad_graph.hpp" + #include "tracks/track.hpp" +@@ -297,13 +296,6 @@ + return; + #endif + +- // The client does not do any AI computations. +- if(network_manager->getMode()==NetworkManager::NW_CLIENT) +- { +- AIBaseController::update(dt); +- return; +- } +- + // If the kart needs to be rescued, do it now (and nothing else) + if(isStuck() && !m_kart->getKartAnimation()) + { +Index: src/karts/controller/kart_control.hpp +=================================================================== +--- src/karts/controller/kart_control.hpp (revision 13389) ++++ src/karts/controller/kart_control.hpp (revision 13390) +@@ -19,9 +19,8 @@ + #ifndef HEADER_KART_CONTROL_HPP + #define HEADER_KART_CONTROL_HPP + +-#include "network/message.hpp" + +-/** ++/** + * \ingroup controller + */ + class KartControl +@@ -52,15 +51,6 @@ + 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 +64,6 @@ + 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]; +Index: src/karts/controller/end_controller.cpp +=================================================================== +--- src/karts/controller/end_controller.cpp (revision 13389) ++++ src/karts/controller/end_controller.cpp (revision 13390) +@@ -43,7 +43,6 @@ + #include "karts/max_speed.hpp" + #include "karts/rescue_animation.hpp" + #include "modes/linear_world.hpp" +-#include "network/network_manager.hpp" + #include "race/race_manager.hpp" + #include "states_screens/race_result_gui.hpp" + #include "tracks/quad_graph.hpp" +Index: src/states_screens/networking_lobby_settings.hpp +=================================================================== +--- src/states_screens/networking_lobby_settings.hpp (revision 0) ++++ src/states_screens/networking_lobby_settings.hpp (revision 13390) +@@ -0,0 +1,78 @@ ++// SuperTuxKart - a fun racing game with go-kart ++// Copyright (C) 2013 Glenn De Jonghe ++// ++// 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_NETWORKING_LOBBY_SETTINGS_HPP ++#define HEADER_NETWORKING_LOBBY_SETTINGS_HPP ++ ++#include "guiengine/screen.hpp" ++#include "guiengine/widgets/label_widget.hpp" ++#include "guiengine/widgets/ribbon_widget.hpp" ++#include "guiengine/widgets/icon_button_widget.hpp" ++ ++namespace GUIEngine { class Widget; class ListWidget; } ++ ++/** ++ * \brief Handles the main menu ++ * \ingroup states_screens ++ */ ++class NetworkingLobbySettings : public GUIEngine::Screen, ++ public GUIEngine::ScreenSingleton ++{ ++private: ++ friend class GUIEngine::ScreenSingleton; ++ ++ NetworkingLobbySettings(); ++ ++ /** \brief Checks if the user is still signed in. */ ++ bool hasLostConnection(); ++ /** \brief Sets which widget has to be focused. Depends on the user state. */ ++ void setInitialFocus(); ++ ++public: ++ ++ enum Action ++ { ++ Create = 1, // A new server should be created ++ Edit = 2, // The settings of the server should be edited ++ }; ++ ++ virtual void onUpdate(float delta, irr::video::IVideoDriver* driver) OVERRIDE; ++ ++ /** \brief implement callback from parent class GUIEngine::Screen */ ++ virtual void loadedFromFile() OVERRIDE; ++ ++ /** \brief implement callback from parent class GUIEngine::Screen */ ++ virtual void eventCallback(GUIEngine::Widget* widget, const std::string& name, ++ const int playerID) OVERRIDE; ++ ++ /** \brief implement callback from parent class GUIEngine::Screen */ ++ virtual void beforeAddingWidget() OVERRIDE; ++ ++ /** \brief implement callback from parent class GUIEngine::Screen */ ++ virtual void init() OVERRIDE; ++ ++ /** \brief implement callback from parent class GUIEngine::Screen */ ++ virtual void tearDown() OVERRIDE; ++ ++ /** \brief implement callback from parent class GUIEngine::Screen */ ++ virtual void onDisabledItemClicked(const std::string& item) OVERRIDE; ++ ++ /** \brief Implements the callback when a dialog gets closed. */ ++ virtual void onDialogClose() OVERRIDE; ++}; ++ ++#endif + +Property changes on: src/states_screens/networking_lobby_settings.hpp +___________________________________________________________________ +Added: svn:mime-type +## -0,0 +1 ## ++text/plain +\ No newline at end of property +Index: src/states_screens/dialogs/track_info_dialog.cpp +=================================================================== +--- src/states_screens/dialogs/track_info_dialog.cpp (revision 13389) ++++ src/states_screens/dialogs/track_info_dialog.cpp (revision 13390) +@@ -28,7 +28,6 @@ + #include "io/file_manager.hpp" + #include "karts/kart_properties.hpp" + #include "karts/kart_properties_manager.hpp" +-#include "network/network_manager.hpp" + #include "race/highscores.hpp" + #include "race/highscore_manager.hpp" + #include "race/race_manager.hpp" +Index: src/states_screens/dialogs/select_challenge.cpp +=================================================================== +--- src/states_screens/dialogs/select_challenge.cpp (revision 13389) ++++ src/states_screens/dialogs/select_challenge.cpp (revision 13390) +@@ -201,7 +201,7 @@ + // 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 @@ + } + + // Sets up kart info, including random list of kart for AI +- network_manager->setupPlayerKartInfo(); ++ race_manager->setupPlayerKartInfo(); + race_manager->startNew(true); + + irr_driver->hidePointer(); +Index: src/states_screens/dialogs/login_dialog.cpp +=================================================================== +--- src/states_screens/dialogs/login_dialog.cpp (revision 13389) ++++ src/states_screens/dialogs/login_dialog.cpp (revision 13390) +@@ -109,16 +109,16 @@ + { + const stringw username = m_username_widget->getText().trim(); + const stringw password = m_password_widget->getText().trim(); +- if (username.size() < 4 || username.size() > 30 || password.size() < 8 || password.size() > 30) ++ stringw info = ""; ++ if(CurrentOnlineUser::get()->signIn(username,password,info)) + { +- sfx_manager->quickSound("anvil"); +- m_info_widget->setErrorColor(); +- m_info_widget->setText(_("Username and/or password invalid."), false); ++ m_self_destroy = true; + } + else + { +- m_options_widget->setDeactivated(); +- m_sign_in_request = Online::CurrentUser::get()->requestSignIn(username,password, m_remember_widget->getState()); ++ sfx_manager->quickSound( "anvil" ); ++ m_message_widget->setColor(irr::video::SColor(255, 255, 0, 0)); ++ m_message_widget->setText(info, false); + } + } + +@@ -144,11 +144,6 @@ + m_open_registration_dialog = true; + return GUIEngine::EVENT_BLOCK; + } +- else if(selection == m_recovery_widget->m_properties[PROP_ID]) +- { +- m_open_recovery_dialog = true; +- return GUIEngine::EVENT_BLOCK; +- } + } + return GUIEngine::EVENT_LET; + } +@@ -162,8 +157,7 @@ + const int playerID = PLAYER_ID_GAME_MASTER; + if (GUIEngine::isFocusedForPlayer(m_options_widget, playerID)) + return; +- if (m_sign_in_widget->isActivated()) +- login(); ++ login(); + } + + // ----------------------------------------------------------------------------- +Index: src/states_screens/dialogs/race_paused_dialog.cpp +=================================================================== +--- src/states_screens/dialogs/race_paused_dialog.cpp (revision 13389) ++++ src/states_screens/dialogs/race_paused_dialog.cpp (revision 13390) +@@ -146,7 +146,7 @@ + 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; +Index: src/states_screens/networking_lobby_settings.cpp +=================================================================== +--- src/states_screens/networking_lobby_settings.cpp (revision 0) ++++ src/states_screens/networking_lobby_settings.cpp (revision 13390) +@@ -0,0 +1,114 @@ ++// SuperTuxKart - a fun racing game with go-kart ++// Copyright (C) 2013 Glenn De Jonghe ++// ++// 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. ++ ++#define DEBUG_MENU_ITEM 0 ++ ++#include "states_screens/networking_lobby_settings.hpp" ++ ++#include ++#include ++ ++#include "challenges/game_slot.hpp" ++#include "challenges/unlock_manager.hpp" ++#include "graphics/irr_driver.hpp" ++#include "guiengine/scalable_font.hpp" ++#include "input/device_manager.hpp" ++#include "input/input_manager.hpp" ++#include "io/file_manager.hpp" ++#include "main_loop.hpp" ++#include "states_screens/online_screen.hpp" ++#include "states_screens/state_manager.hpp" ++#include "states_screens/dialogs/message_dialog.hpp" ++#include "modes/demo_world.hpp" ++#include "utils/translation.hpp" ++ ++#include "online/current_online_user.hpp" ++ ++ ++using namespace GUIEngine; ++ ++DEFINE_SCREEN_SINGLETON( NetworkingLobbySettings ); ++ ++// ---------------------------------------------------------------------------- ++ ++NetworkingLobbySettings::NetworkingLobbySettings() : Screen("online/lobby_settings.stkgui") ++{ ++ ++} // NetworkingLobbySettings ++ ++// ---------------------------------------------------------------------------- ++ ++void NetworkingLobbySettings::loadedFromFile() ++{ ++ ++} // loadedFromFile ++ ++// ---------------------------------------------------------------------------- ++bool NetworkingLobbySettings::hasLostConnection() ++{ ++ return !CurrentOnlineUser::get()->isSignedIn(); ++} ++ ++// ---------------------------------------------------------------------------- ++void NetworkingLobbySettings::beforeAddingWidget() ++{ ++ ++} // beforeAddingWidget ++ ++ ++ ++// ---------------------------------------------------------------------------- ++void NetworkingLobbySettings::init() ++{ ++ Screen::init(); ++ setInitialFocus(); ++ DemoWorld::resetIdleTime(); //FIXME : what's this?} // init ++} ++// ---------------------------------------------------------------------------- ++void NetworkingLobbySettings::onUpdate(float delta, irr::video::IVideoDriver* driver) ++{ ++} // onUpdate ++ ++// ---------------------------------------------------------------------------- ++ ++void NetworkingLobbySettings::eventCallback(Widget* widget, const std::string& name, const int playerID) ++{ ++ ++} // eventCallback ++ ++// ---------------------------------------------------------------------------- ++ ++void NetworkingLobbySettings::tearDown() ++{ ++} // tearDown ++ ++// ---------------------------------------------------------------------------- ++void NetworkingLobbySettings::onDisabledItemClicked(const std::string& item) ++{ ++ ++} // onDisabledItemClicked ++ ++// ---------------------------------------------------------------------------- ++void NetworkingLobbySettings::setInitialFocus() ++{ ++} // setInitialFocus ++ ++// ---------------------------------------------------------------------------- ++void NetworkingLobbySettings::onDialogClose() ++{ ++ setInitialFocus(); ++} // onDialogClose() + +Property changes on: src/states_screens/networking_lobby_settings.cpp +___________________________________________________________________ +Added: svn:mime-type +## -0,0 +1 ## ++text/plain +\ No newline at end of property +Index: src/states_screens/help_screen_1.cpp +=================================================================== +--- src/states_screens/help_screen_1.cpp (revision 13389) ++++ src/states_screens/help_screen_1.cpp (revision 13390) +@@ -24,7 +24,6 @@ + #include "input/device_manager.hpp" + #include "input/input_manager.hpp" + #include "karts/kart_properties_manager.hpp" +-#include "network/network_manager.hpp" + #include "race/race_manager.hpp" + #include "states_screens/help_screen_2.hpp" + #include "states_screens/help_screen_3.hpp" +@@ -82,7 +81,7 @@ + ->setSinglePlayer( StateManager::get()->getActivePlayer(0) ); + + StateManager::get()->enterGameState(); +- network_manager->setupPlayerKartInfo(); ++ race_manager->setupPlayerKartInfo(); + race_manager->startNew(false); + } + else if (name == "category") +Index: src/states_screens/online_screen.cpp +=================================================================== +--- src/states_screens/online_screen.cpp (revision 13389) ++++ src/states_screens/online_screen.cpp (revision 13390) +@@ -34,14 +34,16 @@ + #include "states_screens/dialogs/login_dialog.hpp" + #include "states_screens/dialogs/registration_dialog.hpp" + #include "states_screens/networking_lobby.hpp" +-#include "states_screens/server_selection.hpp" +-#include "states_screens/create_server_screen.hpp" ++#include "states_screens/networking_lobby_settings.hpp" + #include "modes/demo_world.hpp" + #include "online/servers_manager.hpp" + #include "online/messages.hpp" + + ++#include "network/protocol_manager.hpp" ++#include "network/protocols/connect_to_server.hpp" + ++ + using namespace GUIEngine; + using namespace Online; + +@@ -216,23 +218,14 @@ + } + else if (selection == "create_server") + { +- StateManager::get()->pushScreen(CreateServerScreen::getInstance()); ++ //if (m_recorded_state == Registered) ++ StateManager::get()->pushScreen(NetworkingLobbySettings::getInstance()); + } + else if (selection == "quick_play") + { +- //FIXME temporary and the request join + join sequence should be placed in one method somewhere +- /* +- Server * server = ServersManager::get()->getQuickPlay(); +- irr::core::stringw info; +- if (Online::CurrentUser::get()->requestJoin( server->getServerId(), info)) +- { +- ServersManager::get()->setJoinedServer(server); +- StateManager::get()->pushScreen(NetworkingLobby::getInstance()); +- } +- else +- { +- sfx_manager->quickSound( "anvil" ); +- }*/ ++ //if (m_recorded_state == Registered || m_recorded_state == Guest) FIXME ++ StateManager::get()->pushScreen(NetworkingLobby::getInstance()); ++ ProtocolManager::getInstance()->requestStart(new ConnectToServer(7)); + } + + } // eventCallback +@@ -251,7 +244,8 @@ + } + else if (item =="create_server") + { +- new LoginDialog(LoginDialog::Registration_Required); ++ StateManager::get()->pushScreen(NetworkingLobbySettings::getInstance()); ++ // FIXME temporary; new LoginDialog(LoginDialog::Registration_Required); + } + else if (item == "quick_play") + { +Index: src/states_screens/main_menu_screen.cpp +=================================================================== +--- src/states_screens/main_menu_screen.cpp (revision 13389) ++++ src/states_screens/main_menu_screen.cpp (revision 13390) +@@ -37,7 +37,6 @@ + #include "modes/cutscene_world.hpp" + #include "modes/overworld.hpp" + #include "modes/demo_world.hpp" +-#include "network/network_manager.hpp" + #include "states_screens/online_screen.hpp" + #include "states_screens/addons_screen.hpp" + #include "states_screens/credits.hpp" +@@ -332,7 +331,7 @@ + ->setSinglePlayer( StateManager::get()->getActivePlayer(0) ); + + StateManager::get()->enterGameState(); +- network_manager->setupPlayerKartInfo(); ++ race_manager->setupPlayerKartInfo(); + race_manager->startNew(false); + } + else if (selection == "story") +Index: src/tracks/track.cpp +=================================================================== +--- src/tracks/track.cpp (revision 13389) ++++ src/tracks/track.cpp (revision 13390) +@@ -494,8 +494,16 @@ + core::dimension2du size = m_mini_map_size + .getOptimalSize(!nonpower,!nonsquare); + m_mini_map = QuadGraph::get()->makeMiniMap(size, "minimap::"+m_ident); +- m_minimap_x_scale = float(m_mini_map_size.Width) / float(m_mini_map->getSize().Width); +- m_minimap_y_scale = float(m_mini_map_size.Height) / float(m_mini_map->getSize().Height); ++ if (m_mini_map) ++ { ++ m_minimap_x_scale = float(m_mini_map_size.Width) / float(m_mini_map->getSize().Width); ++ m_minimap_y_scale = float(m_mini_map_size.Height) / float(m_mini_map->getSize().Height); ++ } ++ else ++ { ++ m_minimap_x_scale = 0; ++ m_minimap_y_scale = 0; ++ } + } + } // loadQuadGraph + // ----------------------------------------------------------------------------- +Index: src/network/race_info_message.hpp +=================================================================== +--- src/network/race_info_message.hpp (revision 13389) ++++ src/network/race_info_message.hpp (revision 13390) +@@ -1,33 +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_INFO_MESSAGE_HPP +-#define HEADER_RACE_INFO_MESSAGE_HPP +- +-#include +- +-#include "network/message.hpp" +-#include "network/remote_kart_info.hpp" +- +-class RaceInfoMessage : public Message +-{ +-public: +- RaceInfoMessage(const std::vector& kart_info); +- RaceInfoMessage(ENetPacket* pkt); +-}; // RaceInfoMessage +-#endif +Index: src/network/flyable_info.hpp +=================================================================== +--- src/network/flyable_info.hpp (revision 13389) ++++ src/network/flyable_info.hpp (revision 13390) +@@ -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 +- +Index: src/network/race_result_ack_message.hpp +=================================================================== +--- src/network/race_result_ack_message.hpp (revision 13389) ++++ src/network/race_result_ack_message.hpp (revision 13390) +@@ -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 +Index: src/network/race_start_message.hpp +=================================================================== +--- src/network/race_start_message.hpp (revision 13389) ++++ src/network/race_start_message.hpp (revision 13390) +@@ -1,40 +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_START_MESSAGE_HPP +-#define HEADER_RACE_START_MESSAGE_HPP +- +-#include "network/message.hpp" +-#include "network/remote_kart_info.hpp" +-#include "race/race_manager.hpp" +- +-class RaceStartMessage : public Message +-{ +-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) +- { +- } +-}; // RaceStartMessage +-#endif +Index: src/network/connect_message.hpp +=================================================================== +--- src/network/connect_message.hpp (revision 13389) ++++ src/network/connect_message.hpp (revision 13390) +@@ -1,37 +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_CONNECT_MESSAGE_HPP +-#define HEADER_CONNECT_MESSAGE_HPP +- +-#include +- +-#include "network/message.hpp" +- +-class ConnectMessage : public Message +-{ +-private: +- std::string m_id; +- void setId(); +-public: +- ConnectMessage(); +- ConnectMessage(ENetPacket* pkt); +- const std::string& +- getId() { return m_id; } +-}; // ConnectMessage +-#endif +Index: src/network/kart_control_message.cpp +=================================================================== +--- src/network/kart_control_message.cpp (revision 13389) ++++ src/network/kart_control_message.cpp (revision 13390) +@@ -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 +- +Index: src/network/num_players_message.hpp +=================================================================== +--- src/network/num_players_message.hpp (revision 13389) ++++ src/network/num_players_message.hpp (revision 13390) +@@ -1,42 +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_NUM_PLAYERS_MESSAGE_HPP +-#define HEADER_NUM_PLAYERS_MESSAGE_HPP +- +-#include +-#include +-#ifndef WIN32 +-# include +-#endif +- +-#include "network/message.hpp" +-#include "race/race_manager.hpp" +- +-class NumPlayersMessage : public Message +-{ +-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 +Index: src/network/kart_update_message.cpp +=================================================================== +--- src/network/kart_update_message.cpp (revision 13389) ++++ src/network/kart_update_message.cpp (revision 13390) +@@ -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 +- +Index: src/network/world_loaded_message.hpp +=================================================================== +--- src/network/world_loaded_message.hpp (revision 13389) ++++ src/network/world_loaded_message.hpp (revision 13390) +@@ -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 +Index: src/network/race_state.cpp +=================================================================== +--- src/network/race_state.cpp (revision 13389) ++++ src/network/race_state.cpp (revision 13390) +@@ -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 +-// 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 +- +Index: src/network/race_result_message.cpp +=================================================================== +--- src/network/race_result_message.cpp (revision 13389) ++++ src/network/race_result_message.cpp (revision 13390) +@@ -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 +- +Index: src/network/kart_update_message.hpp +=================================================================== +--- src/network/kart_update_message.hpp (revision 13389) ++++ src/network/kart_update_message.hpp (revision 13390) +@@ -1,30 +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_KART_UPDATE_MESSAGE_HPP +-#define HEADER_KART_UPDATE_MESSAGE_HPP +- +-#include "network/message.hpp" +- +-class KartUpdateMessage : public Message +-{ +-public: +- KartUpdateMessage(); +- KartUpdateMessage(ENetPacket* pkt); +-}; // KartUpdateMessage +-#endif +Index: src/network/character_selected_message.hpp +=================================================================== +--- src/network/character_selected_message.hpp (revision 13389) ++++ src/network/character_selected_message.hpp (revision 13390) +@@ -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 +Index: src/network/item_info.hpp +=================================================================== +--- src/network/item_info.hpp (revision 13389) ++++ src/network/item_info.hpp (revision 13390) +@@ -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 +- +Index: src/network/network_kart.hpp +=================================================================== +--- src/network/network_kart.hpp (revision 13389) ++++ src/network/network_kart.hpp (revision 13390) +@@ -1,37 +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_NETWORK_KART_HPP +-#define HEADER_NETWORK_KART_HPP +- +-#include "karts/kart.hpp" +- +-class Track; +- +-class NetworkKart : public Kart +-{ +-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 +Index: src/network/race_state.hpp +=================================================================== +--- src/network/race_state.hpp (revision 13389) ++++ src/network/race_state.hpp (revision 13390) +@@ -1,109 +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_STATE_HPP +-#define HEADER_RACE_STATE_HPP +- +-#include +- +-#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 +- +Index: src/network/character_info_message.hpp +=================================================================== +--- src/network/character_info_message.hpp (revision 13389) ++++ src/network/character_info_message.hpp (revision 13390) +@@ -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 +Index: src/network/race_result_message.hpp +=================================================================== +--- src/network/race_result_message.hpp (revision 13389) ++++ src/network/race_result_message.hpp (revision 13390) +@@ -1,45 +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_MESSAGE_HPP +-#define HEADER_RACE_RESULT_MESSAGE_HPP +- +-#include +- +-#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 RaceResultMessage : public Message +-{ +- 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 +Index: src/network/character_confirm_message.hpp +=================================================================== +--- src/network/character_confirm_message.hpp (revision 13389) ++++ src/network/character_confirm_message.hpp (revision 13390) +@@ -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 +Index: src/network/message.cpp +=================================================================== +--- src/network/message.cpp (revision 13389) ++++ src/network/message.cpp (revision 13390) +@@ -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 +- +Index: src/network/race_info_message.cpp +=================================================================== +--- src/network/race_info_message.cpp (revision 13389) ++++ src/network/race_info_message.cpp (revision 13390) +@@ -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 +Index: src/network/connect_message.cpp +=================================================================== +--- src/network/connect_message.cpp (revision 13389) ++++ src/network/connect_message.cpp (revision 13390) +@@ -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 +Index: src/network/stk_host.cpp +=================================================================== +--- src/network/stk_host.cpp (revision 0) ++++ src/network/stk_host.cpp (revision 13390) +@@ -0,0 +1,239 @@ ++// ++// 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 "graphics/irr_driver.hpp" // get access to irrlicht sleep function ++#include "network/network_manager.hpp" ++#include "utils/log.hpp" ++ ++#include ++#ifdef WIN32 ++# include "Ws2tcpip.h" ++# define inet_ntop InetNtop ++#else ++# include ++#endif ++#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::error("STKHost", "An error occurred while trying to create an ENet \ ++ server host."); ++ 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::error("STKHost", "An error occurred while trying to create an ENet \ ++ client host."); ++ 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, (char*)data, length, 0,(sockaddr*)&to, to_len); ++ printf("Raw packet sent to %u:%u\n", dst.ip, dst.port); ++} ++ ++// ---------------------------------------------------------------------------- ++ ++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,(char*)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,(char*)buffer,2048, 0); ++ irr_driver->getDevice()->sleep(1); ++ } ++ 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, (char*)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, (char*)buffer, 2048, 0, &addr, &from_len); ++ irr_driver->getDevice()->sleep(1); // 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", s); ++ } ++ return buffer; ++} ++ ++// ---------------------------------------------------------------------------- ++ ++void STKHost::broadcastPacket(const NetworkString& data) ++{ ++ ENetPacket* packet = enet_packet_create(data.c_str(), data.size()+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 == turnEndianness(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 == turnEndianness(peer.ip) && ++ m_host->peers[i].address.port == peer.port && ++ m_host->peers[i].state == ENET_PEER_STATE_CONNECTED) ++ { ++ return true; ++ } ++ } ++ return false; ++} +Index: src/network/game_setup.hpp +=================================================================== +--- src/network/game_setup.hpp (revision 0) ++++ src/network/game_setup.hpp (revision 13390) +@@ -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. ++ ++/*! \file game_setup.hpp ++ */ ++ ++#ifndef GAME_SETUP_HPP ++#define GAME_SETUP_HPP ++ ++#include "online/online_user.hpp" ++ ++#include ++#include ++ ++/*! \class PlayerProfile ++ * \brief Contains the profile of a player. ++ */ ++class NetworkPlayerProfile ++{ ++ public: ++ NetworkPlayerProfile() { race_id = 0; user_profile = NULL; } ++ ~NetworkPlayerProfile() {} ++ ++ uint8_t race_id; //!< The id of the player for the race ++ std::string kart_name; //!< The selected kart. ++ OnlineUser* user_profile; //!< Pointer to the lobby profile ++}; ++ ++/*! \class GameSetup ++ * \brief Used to store the needed data about the players that join a game. ++ * This class stores all the possible information about players in a lobby. ++ */ ++class GameSetup ++{ ++ public: ++ GameSetup(); ++ virtual ~GameSetup(); ++ ++ void addPlayer(NetworkPlayerProfile profile); //!< Add a player. ++ void removePlayer(uint32_t id); //!< Remove a player by id. ++ void removePlayer(uint8_t id); //!< Remove a player by local id. ++ ++ int getPlayerCount() { return m_players.size(); } ++ const NetworkPlayerProfile* getProfile(uint32_t id); //!< Get a profile by database id ++ const NetworkPlayerProfile* getProfile(uint8_t id); //!< Get the profile by the lobby id ++ ++ protected: ++ std::vector m_players; //!< Information about players ++ NetworkPlayerProfile m_self_profile; //!< Information about self (client only) ++}; ++ ++#endif // GAME_SETUP_HPP +Index: src/network/protocol_manager.hpp +=================================================================== +--- src/network/protocol_manager.hpp (revision 0) ++++ src/network/protocol_manager.hpp (revision 13390) +@@ -0,0 +1,295 @@ ++// ++// 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 "network/network_string.hpp" ++#include "utils/types.hpp" ++ ++#include ++ ++class Protocol; ++ ++/*! ++ * \enum PROTOCOL_STATE ++ * \brief Defines the three states that a protocol can have. ++ */ ++enum PROTOCOL_STATE ++{ ++ PROTOCOL_STATE_RUNNING, //!< The protocol is being updated everytime. ++ PROTOCOL_STATE_PAUSED, //!< The protocol is paused. ++ PROTOCOL_STATE_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, const NetworkString& message); ++ /*! ++ * \brief WILL BE COMMENTED LATER ++ */ ++ virtual void sendMessage(Protocol* sender, STKPeer* peer, const NetworkString& message); ++ /*! ++ * \brief WILL BE COMMENTED LATER ++ */ ++ virtual void sendMessageExcept(Protocol* sender, STKPeer* peer, const NetworkString& message); ++ ++ /*! ++ * \brief Asks the manager to start a protocol. ++ * This function will store the request, and process it at a time it is ++ * thread-safe. ++ * \param protocol : A pointer to the protocol to start ++ * \return The unique id of the protocol that is being started. ++ */ ++ virtual uint32_t requestStart(Protocol* protocol); ++ /*! ++ * \brief Asks the manager to stop a protocol. ++ * This function will store the request, and process it at a time it is ++ * thread-safe. ++ * \param protocol : A pointer to the protocol to stop ++ */ ++ virtual void requestStop(Protocol* protocol); ++ /*! ++ * \brief Asks the manager to pause a protocol. ++ * This function will store the request, and process it at a time it is ++ * thread-safe. ++ * \param protocol : A pointer to the protocol to pause ++ */ ++ virtual void requestPause(Protocol* protocol); ++ /*! ++ * \brief Asks the manager to unpause a protocol. ++ * This function will store the request, and process it at a time it is ++ * thread-safe. ++ * \param protocol : A pointer to the protocol to unpause ++ */ ++ virtual void requestUnpause(Protocol* protocol); ++ /*! ++ * \brief Notifies the manager that a protocol is terminated. ++ * This function will store the request, and process it at a time it is ++ * thread-safe. ++ * \param protocol : A pointer to the protocol that is finished ++ */ ++ virtual void requestTerminate(Protocol* protocol); ++ ++ /*! ++ * \brief Updates the manager. ++ * ++ * This function processes the events queue, notifies the concerned ++ * 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 uint32_t getProtocolID(Protocol* protocol); ++ ++ /*! ++ * \brief Get a protocol using his id. ++ * \param id : Unique ID of the seek protocol. ++ * \return The protocol that has the ID id. ++ */ ++ virtual Protocol* getProtocol(uint32_t id); ++ ++ /*! \brief Know whether the app is a server. ++ * \return True if this application is in server mode, false elseway. ++ */ ++ bool isServer(); ++ ++ /*! \brief Tells if we need to stop the update thread. */ ++ int exit(); ++ ++ 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. ++ */ ++ uint32_t 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; ++ /*! Used when need to quit.*/ ++ pthread_mutex_t m_exit_mutex; ++ ++ /*! Update thread.*/ ++ pthread_t* m_update_thread; ++ ++}; ++ ++#endif // PROTOCOL_MANAGER_HPP +Index: src/network/protocol.cpp +=================================================================== +--- src/network/protocol.cpp (revision 0) ++++ src/network/protocol.cpp (revision 13390) +@@ -0,0 +1,52 @@ ++// ++// 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.hpp" ++ ++Protocol::Protocol(CallbackObject* callback_object, PROTOCOL_TYPE type) ++{ ++ 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::kill() ++{ ++} ++ ++void Protocol::setListener(ProtocolManager* listener) ++{ ++ m_listener = listener; ++} ++ ++PROTOCOL_TYPE Protocol::getProtocolType() ++{ ++ return m_type; ++} +Index: src/network/stk_host.hpp +=================================================================== +--- src/network/stk_host.hpp (revision 0) ++++ src/network/stk_host.hpp (revision 13390) +@@ -0,0 +1,145 @@ ++// ++// 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 "network/types.hpp" ++#include "network/network_string.hpp" ++ ++#include ++ ++#include ++ ++/*! \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 NetworkString& 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 +Index: src/network/protocols/get_peer_address.cpp +=================================================================== +--- src/network/protocols/get_peer_address.cpp (revision 0) ++++ src/network/protocols/get_peer_address.cpp (revision 13390) +@@ -0,0 +1,89 @@ ++// ++// 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 "online/http_connector.hpp" ++#include "online/current_online_user.hpp" ++#include "config/user_config.hpp" ++#include "utils/log.hpp" ++ ++GetPeerAddress::GetPeerAddress(uint32_t peer_id, CallbackObject* callback_object) : Protocol(callback_object, PROTOCOL_SILENT) ++{ ++ m_peer_id = peer_id; ++} ++ ++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) ++ { ++ ++ HTTPConnector * connector = new HTTPConnector((std::string)UserConfigParams::m_server_multiplayer + "address-management.php"); ++ connector->setParameter("id",CurrentOnlineUser::get()->getUserID()); ++ connector->setParameter("token",CurrentOnlineUser::get()->getToken()); ++ connector->setParameter("peer_id",m_peer_id); ++ connector->setParameter("action","get"); ++ ++ const XMLNode * result = connector->getXMLFromPage(); ++ std::string rec_success; ++ ++ if(result->get("success", &rec_success)) ++ { ++ if (rec_success == "yes") ++ { ++ TransportAddress* addr = static_cast(m_callback_object); ++ result->get("ip", &addr->ip); ++ result->get("port", &addr->port); ++ Log::info("GetPeerAddress", "Address gotten successfully."); ++ } ++ else ++ { ++ Log::error("GetPeerAddress", "Fail to get address."); ++ } ++ } ++ else ++ { ++ Log::error("GetPeerAddress", "Fail to get address."); ++ } ++ m_state = DONE; ++ } ++ else if (m_state == DONE) ++ { ++ m_listener->requestTerminate(this); ++ } ++} ++ ++void GetPeerAddress::setPeerID(uint32_t peer_id) ++{ ++ m_peer_id = peer_id; ++} +Index: src/network/protocols/get_peer_address.hpp +=================================================================== +--- src/network/protocols/get_peer_address.hpp (revision 0) ++++ src/network/protocols/get_peer_address.hpp (revision 13390) +@@ -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(uint32_t peer_id, CallbackObject* callback_object); ++ virtual ~GetPeerAddress(); ++ ++ virtual void notifyEvent(Event* event); ++ virtual void setup(); ++ virtual void update(); ++ ++ void setPeerID(uint32_t m_peer_id); ++ protected: ++ uint32_t m_peer_id; ++ ++ enum STATE ++ { ++ NONE, ++ DONE ++ }; ++ STATE m_state; ++ ++}; ++ ++#endif // GET_PEER_ADDRESS_HPP +Index: src/network/protocols/connect_to_peer.cpp +=================================================================== +--- src/network/protocols/connect_to_peer.cpp (revision 0) ++++ src/network/protocols/connect_to_peer.cpp (revision 13390) +@@ -0,0 +1,122 @@ ++// ++// 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_peer.hpp" ++ ++#include "network/client_network_manager.hpp" ++#include "network/protocols/get_public_address.hpp" ++#include "network/protocols/get_peer_address.hpp" ++#include "network/protocols/show_public_address.hpp" ++#include "network/protocols/hide_public_address.hpp" ++#include "network/protocols/request_connection.hpp" ++#include "network/protocols/ping_protocol.hpp" ++#include "online/current_online_user.hpp" ++#include "utils/time.hpp" ++#include "utils/log.hpp" ++ ++// ---------------------------------------------------------------------------- ++ ++ConnectToPeer::ConnectToPeer(uint32_t peer_id) : ++ Protocol(NULL, PROTOCOL_CONNECTION) ++{ ++ m_peer_id = peer_id; ++ m_state = NONE; ++} ++ ++// ---------------------------------------------------------------------------- ++ ++ConnectToPeer::~ConnectToPeer() ++{ ++} ++ ++// ---------------------------------------------------------------------------- ++ ++void ConnectToPeer::notifyEvent(Event* event) ++{ ++ if (event->type == EVENT_TYPE_CONNECTED) ++ { ++ Log::info("ConnectToPeer", "The Connect To Server protocol has \ ++ received an event notifying that he's connected to the peer."); ++ m_state = CONNECTED; // we received a message, we are connected ++ } ++} ++ ++// ---------------------------------------------------------------------------- ++ ++void ConnectToPeer::setup() ++{ ++ m_state = NONE; ++ m_public_address.ip = 0; ++ m_public_address.port = 0; ++ m_peer_address.ip = 0; ++ m_peer_address.port = 0; ++ m_current_protocol_id = 0; ++} ++ ++// ---------------------------------------------------------------------------- ++ ++void ConnectToPeer::update() ++{ ++ switch(m_state) ++ { ++ case NONE: ++ { ++ m_current_protocol_id = m_listener->requestStart(new GetPeerAddress(m_peer_id, &m_peer_address)); ++ m_state = WAITING_PEER_ADDRESS; ++ break; ++ } ++ case WAITING_PEER_ADDRESS: ++ if (m_listener->getProtocolState(m_current_protocol_id) ++ == PROTOCOL_STATE_TERMINATED) // we know the peer address ++ { ++ if (m_peer_address.ip != 0 && m_peer_address.port != 0) ++ { ++ m_state = CONNECTING; ++ m_current_protocol_id = m_listener->requestStart(new PingProtocol(m_peer_address, 2.0)); ++ } ++ else ++ { ++ Log::error("ConnectToPeer", "The peer you want to connect to has hidden his address."); ++ m_state = DONE; ++ } ++ } ++ break; ++ case CONNECTING: // waiting the peer to connect ++ { ++ static double timer = 0; ++ if (Time::getRealTime() > timer+5.0) // every 5 seconds ++ { ++ timer = Time::getRealTime(); ++ NetworkManager::getInstance()->connect(m_peer_address); ++ } ++ break; ++ } ++ case CONNECTED: ++ { ++ m_listener->requestTerminate( m_listener->getProtocol(m_current_protocol_id)); // kill the ping protocol because we're connected ++ m_state = DONE; ++ break; ++ } ++ case DONE: ++ m_listener->requestTerminate(this); ++ break; ++ } ++} ++ ++// ---------------------------------------------------------------------------- ++ +Index: src/network/protocols/request_connection.cpp +=================================================================== +--- src/network/protocols/request_connection.cpp (revision 0) ++++ src/network/protocols/request_connection.cpp (revision 13390) +@@ -0,0 +1,64 @@ ++#include "network/protocols/request_connection.hpp" ++ ++#include "online/http_connector.hpp" ++#include "online/current_online_user.hpp" ++#include "config/user_config.hpp" ++ ++RequestConnection::RequestConnection(uint32_t server_id) : Protocol(NULL, PROTOCOL_SILENT) ++{ ++ m_server_id = server_id; ++} ++ ++RequestConnection::~RequestConnection() ++{ ++} ++ ++void RequestConnection::notifyEvent(Event* event) ++{ ++} ++ ++void RequestConnection::setup() ++{ ++ m_state = NONE; ++} ++ ++void RequestConnection::update() ++{ ++ switch (m_state) ++ { ++ case NONE: ++ { ++ HTTPConnector * connector = new HTTPConnector((std::string)UserConfigParams::m_server_multiplayer + "address-management.php"); ++ connector->setParameter("id",CurrentOnlineUser::get()->getUserID()); ++ connector->setParameter("token",CurrentOnlineUser::get()->getToken()); ++ connector->setParameter("server_id",m_server_id); ++ connector->setParameter("action","request-connection"); ++ ++ const XMLNode * result = connector->getXMLFromPage(); ++ std::string rec_success; ++ ++ if(result->get("success", &rec_success)) ++ { ++ if (rec_success == "yes") ++ { ++ Log::info("RequestConnection", "Connection Request made successfully."); ++ } ++ else ++ { ++ Log::error("RequestConnection", "Fail to make a request."); ++ } ++ } ++ else ++ { ++ Log::error("RequestConnection", "Fail to make a request."); ++ } ++ m_state = DONE; ++ ++ break; ++ } ++ case DONE: ++ m_listener->requestTerminate(this); ++ break; ++ } ++} ++ +Index: src/network/protocols/stop_server.cpp +=================================================================== +--- src/network/protocols/stop_server.cpp (revision 0) ++++ src/network/protocols/stop_server.cpp (revision 13390) +@@ -0,0 +1,61 @@ ++#include "network/protocols/stop_server.hpp" ++ ++#include "network/network_manager.hpp" ++#include "online/current_online_user.hpp" ++#include "online/http_connector.hpp" ++#include "config/user_config.hpp" ++ ++StopServer::StopServer() : Protocol(NULL, PROTOCOL_SILENT) ++{ ++} ++ ++StopServer::~StopServer() ++{ ++} ++ ++void StopServer::notifyEvent(Event* event) ++{ ++} ++ ++void StopServer::setup() ++{ ++ m_state = NONE; ++} ++ ++void StopServer::update() ++{ ++ if (m_state == NONE) ++ { ++ TransportAddress addr = NetworkManager::getInstance()->getPublicAddress(); ++ HTTPConnector * connector = new HTTPConnector((std::string)UserConfigParams::m_server_multiplayer + "address-management.php"); ++ connector->setParameter("id",CurrentOnlineUser::get()->getUserID()); ++ connector->setParameter("token",CurrentOnlineUser::get()->getToken()); ++ connector->setParameter("address",addr.ip); ++ connector->setParameter("port",addr.port); ++ connector->setParameter("action","stop-server"); ++ ++ const XMLNode * result = connector->getXMLFromPage(); ++ std::string rec_success; ++ ++ if(result->get("success", &rec_success)) ++ { ++ if(rec_success == "yes") ++ { ++ Log::info("StopServer", "Server is now offline."); ++ } ++ else ++ { ++ Log::error("StopServer", "Fail to stop server."); ++ } ++ } ++ else ++ { ++ Log::error("StopServer", "Fail to stop server."); ++ } ++ m_state = DONE; ++ } ++ else if (m_state == DONE) ++ { ++ m_listener->requestTerminate(this); ++ } ++} +Index: src/network/protocols/connect_to_peer.hpp +=================================================================== +--- src/network/protocols/connect_to_peer.hpp (revision 0) ++++ src/network/protocols/connect_to_peer.hpp (revision 13390) +@@ -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 CONNECT_TO_SERVER_HPP ++#define CONNECT_TO_SERVER_HPP ++ ++#include "network/protocol.hpp" ++#include "network/types.hpp" ++#include ++ ++class ConnectToPeer : public Protocol, public CallbackObject ++{ ++ public: ++ ConnectToPeer(uint32_t peer_id); ++ virtual ~ConnectToPeer(); ++ ++ virtual void notifyEvent(Event* event); ++ virtual void setup(); ++ virtual void update(); ++ ++ protected: ++ TransportAddress m_peer_address; ++ TransportAddress m_public_address; ++ uint32_t m_peer_id; ++ uint32_t m_current_protocol_id; ++ ++ enum STATE ++ { ++ NONE, ++ WAITING_PEER_ADDRESS, ++ CONNECTING, ++ CONNECTED, ++ DONE ++ }; ++ STATE m_state; ++}; ++ ++#endif // CONNECT_TO_SERVER_HPP +Index: src/network/protocols/hide_public_address.cpp +=================================================================== +--- src/network/protocols/hide_public_address.cpp (revision 0) ++++ src/network/protocols/hide_public_address.cpp (revision 13390) +@@ -0,0 +1,76 @@ ++// ++// 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 "online/http_connector.hpp" ++#include "online/current_online_user.hpp" ++#include "config/user_config.hpp" ++#include "utils/log.hpp" ++ ++HidePublicAddress::HidePublicAddress() : Protocol(NULL, PROTOCOL_SILENT) ++{ ++} ++ ++HidePublicAddress::~HidePublicAddress() ++{ ++} ++ ++void HidePublicAddress::notifyEvent(Event* event) ++{ ++} ++ ++void HidePublicAddress::setup() ++{ ++ m_state = NONE; ++} ++ ++void HidePublicAddress::update() ++{ ++ if (m_state == NONE) ++ { ++ HTTPConnector * connector = new HTTPConnector((std::string)UserConfigParams::m_server_multiplayer + "address-management.php"); ++ connector->setParameter("id",CurrentOnlineUser::get()->getUserID()); ++ connector->setParameter("token",CurrentOnlineUser::get()->getToken()); ++ connector->setParameter("action","unset"); ++ ++ const XMLNode * result = connector->getXMLFromPage(); ++ std::string rec_success; ++ ++ if(result->get("success", &rec_success)) ++ { ++ if(rec_success == "yes") ++ { ++ Log::info("ShowPublicAddress", "Address hidden successfully."); ++ } ++ else ++ { ++ Log::error("ShowPublicAddress", "Fail to hide address."); ++ } ++ } ++ else ++ { ++ Log::error("ShowPublicAddress", "Fail to hide address."); ++ } ++ m_state = DONE; ++ } ++ else if (m_state == DONE) ++ { ++ m_listener->requestTerminate(this); ++ } ++} +Index: src/network/protocols/request_connection.hpp +=================================================================== +--- src/network/protocols/request_connection.hpp (revision 0) ++++ src/network/protocols/request_connection.hpp (revision 13390) +@@ -0,0 +1,28 @@ ++#ifndef REQUEST_CONNECTION_HPP ++#define REQUEST_CONNECTION_HPP ++ ++#include "network/protocol.hpp" ++ ++class RequestConnection : public Protocol ++{ ++ public: ++ RequestConnection(uint32_t server_id); ++ virtual ~RequestConnection(); ++ ++ virtual void notifyEvent(Event* event); ++ virtual void setup(); ++ virtual void update(); ++ ++ protected: ++ uint32_t m_server_id; ++ ++ enum STATE ++ { ++ NONE, ++ DONE ++ }; ++ STATE m_state; ++ ++}; ++ ++#endif // REQUEST_CONNECTION_HPP +Index: src/network/protocols/ping_protocol.cpp +=================================================================== +--- src/network/protocols/ping_protocol.cpp (revision 0) ++++ src/network/protocols/ping_protocol.cpp (revision 13390) +@@ -0,0 +1,33 @@ ++#include "network/protocols/ping_protocol.hpp" ++ ++#include "network/network_manager.hpp" ++#include "utils/time.hpp" ++ ++PingProtocol::PingProtocol(const TransportAddress& ping_dst, double delay_between_pings) : Protocol(NULL, PROTOCOL_SILENT) ++{ ++ m_ping_dst = ping_dst; ++ m_delay_between_pings = delay_between_pings; ++} ++ ++PingProtocol::~PingProtocol() ++{ ++} ++ ++void PingProtocol::notifyEvent(Event* event) ++{ ++} ++ ++void PingProtocol::setup() ++{ ++ m_last_ping_time = 0; ++} ++ ++void PingProtocol::update() ++{ ++ if (Time::getRealTime() > m_last_ping_time+m_delay_between_pings) ++ { ++ m_last_ping_time = Time::getRealTime(); ++ uint8_t data = 0; ++ NetworkManager::getInstance()->getHost()->sendRawPacket(&data, 1, m_ping_dst); ++ } ++} +Index: src/network/protocols/stop_server.hpp +=================================================================== +--- src/network/protocols/stop_server.hpp (revision 0) ++++ src/network/protocols/stop_server.hpp (revision 13390) +@@ -0,0 +1,29 @@ ++#ifndef STOP_SERVER_HPP ++#define STOP_SERVER_HPP ++ ++#include "network/protocol.hpp" ++ ++ ++/*! \brief Removes the server info from the database ++ */ ++ ++class StopServer : public Protocol ++{ ++ public: ++ StopServer(); ++ virtual ~StopServer(); ++ ++ virtual void notifyEvent(Event* event); ++ virtual void setup(); ++ virtual void update(); ++ ++ protected: ++ enum STATE ++ { ++ NONE, ++ DONE ++ }; ++ STATE m_state; ++}; ++ ++#endif // STOP_SERVER_HPP +Index: src/network/protocols/connect_to_server.cpp +=================================================================== +--- src/network/protocols/connect_to_server.cpp (revision 0) ++++ src/network/protocols/connect_to_server.cpp (revision 13390) +@@ -0,0 +1,155 @@ ++// ++// 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 "network/protocols/get_public_address.hpp" ++#include "network/protocols/get_peer_address.hpp" ++#include "network/protocols/show_public_address.hpp" ++#include "network/protocols/hide_public_address.hpp" ++#include "network/protocols/request_connection.hpp" ++#include "network/protocols/ping_protocol.hpp" ++#include "network/protocols/lobby_room_protocol.hpp" ++#include "online/current_online_user.hpp" ++#include "utils/time.hpp" ++#include "utils/log.hpp" ++ ++// ---------------------------------------------------------------------------- ++ ++ConnectToServer::ConnectToServer(uint32_t server_id) : ++ Protocol(NULL, PROTOCOL_CONNECTION) ++{ ++ m_server_id = server_id; ++ m_state = NONE; ++} ++ ++// ---------------------------------------------------------------------------- ++ ++ConnectToServer::~ConnectToServer() ++{ ++} ++ ++// ---------------------------------------------------------------------------- ++ ++void ConnectToServer::notifyEvent(Event* event) ++{ ++ if (event->type == EVENT_TYPE_CONNECTED) ++ { ++ Log::info("ConnectToServer", "The Connect To Server protocol has \ ++ received an event notifying that he's connected to the peer."); ++ m_state = CONNECTED; // we received a message, we are connected ++ } ++} ++ ++// ---------------------------------------------------------------------------- ++ ++void ConnectToServer::setup() ++{ ++ m_state = NONE; ++ m_public_address.ip = 0; ++ m_public_address.port = 0; ++ m_server_address.ip = 0; ++ m_server_address.port = 0; ++ m_current_protocol_id = 0; ++} ++ ++// ---------------------------------------------------------------------------- ++ ++void ConnectToServer::update() ++{ ++ switch(m_state) ++ { ++ case NONE: ++ { ++ m_current_protocol_id = m_listener->requestStart(new GetPublicAddress(&m_public_address)); ++ m_state = WAITING_SELF_ADDRESS; ++ break; ++ } ++ case WAITING_SELF_ADDRESS: ++ if (m_listener->getProtocolState(m_current_protocol_id) ++ == PROTOCOL_STATE_TERMINATED) // now we know the public addr ++ { ++ m_state = SELF_ADDRESS_KNOWN; ++ NetworkManager::getInstance()->setPublicAddress(m_public_address); // set our public address ++ m_current_protocol_id = m_listener->requestStart(new GetPeerAddress(m_server_id, &m_server_address)); ++ } ++ break; ++ case SELF_ADDRESS_KNOWN: ++ if (m_listener->getProtocolState(m_current_protocol_id) ++ == PROTOCOL_STATE_TERMINATED) // now we have the server's address ++ { ++ if (m_server_address.ip == 0 || m_server_address.port == 0) ++ { ++ m_state = HIDING_ADDRESS; ++ m_current_protocol_id = m_listener->requestStart(new HidePublicAddress()); ++ return; ++ } ++ m_state = PEER_ADDRESS_KNOWN; ++ m_current_protocol_id = m_listener->requestStart(new ShowPublicAddress()); ++ } ++ break; ++ case PEER_ADDRESS_KNOWN: ++ if (m_listener->getProtocolState(m_current_protocol_id) ++ == PROTOCOL_STATE_TERMINATED) // now our public address is public ++ { ++ m_state = SELF_ADDRESS_SHOWN; ++ m_current_protocol_id = m_listener->requestStart(new RequestConnection(m_server_id)); ++ } ++ break; ++ case SELF_ADDRESS_SHOWN: ++ if (m_listener->getProtocolState(m_current_protocol_id) ++ == PROTOCOL_STATE_TERMINATED) // we have put a request to access the server ++ { ++ m_state = CONNECTING; ++ m_current_protocol_id = m_listener->requestStart(new PingProtocol(m_server_address, 2.0)); ++ } ++ break; ++ case CONNECTING: // waiting the server to answer our connection ++ { ++ static double timer = 0; ++ if (Time::getRealTime() > timer+5.0) // every 5 seconds ++ { ++ timer = Time::getRealTime(); ++ NetworkManager::getInstance()->connect(m_server_address); ++ } ++ break; ++ } ++ case CONNECTED: ++ { ++ m_listener->requestTerminate( m_listener->getProtocol(m_current_protocol_id)); // kill the ping protocol because we're connected ++ m_current_protocol_id = m_listener->requestStart(new HidePublicAddress()); ++ m_state = HIDING_ADDRESS; ++ break; ++ } ++ case HIDING_ADDRESS: ++ if (m_listener->getProtocolState(m_current_protocol_id) ++ == PROTOCOL_STATE_TERMINATED) // we have hidden our address ++ { ++ m_state = DONE; ++ m_listener->requestStart(new ClientLobbyRoomProtocol(m_server_address)); ++ } ++ break; ++ case DONE: ++ m_listener->requestTerminate(this); ++ break; ++ } ++} ++ ++// ---------------------------------------------------------------------------- ++ +Index: src/network/protocols/hide_public_address.hpp +=================================================================== +--- src/network/protocols/hide_public_address.hpp (revision 0) ++++ src/network/protocols/hide_public_address.hpp (revision 13390) +@@ -0,0 +1,45 @@ ++// ++// 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(); ++ virtual ~HidePublicAddress(); ++ ++ virtual void notifyEvent(Event* event); ++ virtual void setup(); ++ virtual void update(); ++ ++ protected: ++ ++ enum STATE ++ { ++ NONE, ++ DONE ++ }; ++ STATE m_state; ++}; ++ ++#endif // HIDE_PUBLIC_ADDRESS_HPP +Index: src/network/protocols/get_public_address.cpp +=================================================================== +--- src/network/protocols/get_public_address.cpp (revision 0) ++++ src/network/protocols/get_public_address.cpp (revision 13390) +@@ -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((unsigned int)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 = 0x0001; // 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"); ++ 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] == 0x01 && ++ data[1] == 0x01 && ++ 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::info("GetPublicAddress", "The STUN server responded with a valid answer"); ++ 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."); ++ finish = true; ++ } ++ if (message_size < 4) // cannot even read the size ++ { ++ Log::error("GetPublicAddress", "STUN message is not valid."); ++ 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."); ++ 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", 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); ++ } ++} +Index: src/network/protocols/start_server.cpp +=================================================================== +--- src/network/protocols/start_server.cpp (revision 0) ++++ src/network/protocols/start_server.cpp (revision 13390) +@@ -0,0 +1,62 @@ ++#include "network/protocols/start_server.hpp" ++ ++#include "network/network_manager.hpp" ++#include "online/current_online_user.hpp" ++#include "online/http_connector.hpp" ++#include "config/user_config.hpp" ++ ++StartServer::StartServer() : Protocol(NULL, PROTOCOL_SILENT) ++{ ++} ++ ++StartServer::~StartServer() ++{ ++} ++ ++void StartServer::notifyEvent(Event* event) ++{ ++} ++ ++void StartServer::setup() ++{ ++ m_state = NONE; ++} ++ ++void StartServer::update() ++{ ++ if (m_state == NONE) ++ { ++ TransportAddress addr = NetworkManager::getInstance()->getPublicAddress(); ++ HTTPConnector * connector = new HTTPConnector((std::string)UserConfigParams::m_server_multiplayer + "address-management.php"); ++ connector->setParameter("id",CurrentOnlineUser::get()->getUserID()); ++ connector->setParameter("token",CurrentOnlineUser::get()->getToken()); ++ connector->setParameter("address",addr.ip); ++ connector->setParameter("port",addr.port); ++ connector->setParameter("max_players",UserConfigParams::m_server_max_players); ++ connector->setParameter("action","start-server"); ++ ++ const XMLNode * result = connector->getXMLFromPage(); ++ std::string rec_success; ++ ++ if(result->get("success", &rec_success)) ++ { ++ if(rec_success == "yes") ++ { ++ Log::info("StartServer", "Server is now online."); ++ } ++ else ++ { ++ Log::error("StartServer", "Fail to start server."); ++ } ++ } ++ else ++ { ++ Log::error("StartServer", "Fail to start server."); ++ } ++ m_state = DONE; ++ } ++ else if (m_state == DONE) ++ { ++ m_listener->requestTerminate(this); ++ } ++} +Index: src/network/protocols/show_public_address.cpp +=================================================================== +--- src/network/protocols/show_public_address.cpp (revision 0) ++++ src/network/protocols/show_public_address.cpp (revision 13390) +@@ -0,0 +1,80 @@ ++// ++// 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/network_manager.hpp" ++#include "online/http_connector.hpp" ++#include "online/current_online_user.hpp" ++#include "config/user_config.hpp" ++#include "utils/log.hpp" ++ ++ShowPublicAddress::ShowPublicAddress() : Protocol(NULL, PROTOCOL_SILENT) ++{ ++} ++ ++ShowPublicAddress::~ShowPublicAddress() ++{ ++} ++ ++void ShowPublicAddress::notifyEvent(Event* event) ++{ ++} ++ ++void ShowPublicAddress::setup() ++{ ++ m_state = NONE; ++} ++ ++void ShowPublicAddress::update() ++{ ++ if (m_state == NONE) ++ { ++ HTTPConnector * connector = new HTTPConnector((std::string)UserConfigParams::m_server_multiplayer + "address-management.php"); ++ connector->setParameter("id",CurrentOnlineUser::get()->getUserID()); ++ connector->setParameter("token",CurrentOnlineUser::get()->getToken()); ++ TransportAddress addr = NetworkManager::getInstance()->getPublicAddress(); ++ connector->setParameter("address",addr.ip); ++ connector->setParameter("port",addr.port); ++ connector->setParameter("action","set"); ++ ++ const XMLNode * result = connector->getXMLFromPage(); ++ std::string rec_success; ++ ++ if(result->get("success", &rec_success)) ++ { ++ if(rec_success == "yes") ++ { ++ Log::info("ShowPublicAddress", "Address shown successfully."); ++ } ++ else ++ { ++ Log::error("ShowPublicAddress", "Fail to show address."); ++ } ++ } ++ else ++ { ++ Log::error("ShowPublicAddress", "Fail to show address."); ++ } ++ m_state = DONE; ++ } ++ else if (m_state == DONE) ++ { ++ m_listener->requestTerminate(this); ++ } ++} +Index: src/network/protocols/ping_protocol.hpp +=================================================================== +--- src/network/protocols/ping_protocol.hpp (revision 0) ++++ src/network/protocols/ping_protocol.hpp (revision 13390) +@@ -0,0 +1,23 @@ ++#ifndef PING_PROTOCOL_HPP ++#define PING_PROTOCOL_HPP ++ ++#include "network/protocol.hpp" ++ ++ ++class PingProtocol : public Protocol ++{ ++ public: ++ PingProtocol(const TransportAddress& ping_dst, double delay_between_pings); ++ virtual ~PingProtocol(); ++ ++ virtual void notifyEvent(Event* event); ++ virtual void setup(); ++ virtual void update(); ++ ++ protected: ++ TransportAddress m_ping_dst; ++ double m_delay_between_pings; ++ double m_last_ping_time; ++}; ++ ++#endif // PING_PROTOCOL_HPP +Index: src/network/protocols/lobby_room_protocol.cpp +=================================================================== +--- src/network/protocols/lobby_room_protocol.cpp (revision 0) ++++ src/network/protocols/lobby_room_protocol.cpp (revision 13390) +@@ -0,0 +1,338 @@ ++// ++// 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/lobby_room_protocol.hpp" ++ ++#include "network/network_manager.hpp" ++#include "network/protocol_manager.hpp" ++#include "network/client_network_manager.hpp" ++#include "network/protocols/get_public_address.hpp" ++#include "network/protocols/show_public_address.hpp" ++#include "network/protocols/connect_to_peer.hpp" ++#include "network/protocols/start_server.hpp" ++#include "online/current_online_user.hpp" ++#include "online/http_connector.hpp" ++#include "config/user_config.hpp" ++#include "utils/log.hpp" ++#include "utils/random_generator.hpp" ++#include "utils/time.hpp" ++ ++#include ++ ++LobbyRoomProtocol::LobbyRoomProtocol(CallbackObject* callback_object) : Protocol(callback_object, PROTOCOL_LOBBY_ROOM) ++{ ++ m_setup = NULL; ++} ++ ++//----------------------------------------------------------------------------- ++ ++LobbyRoomProtocol::~LobbyRoomProtocol() ++{ ++} ++ ++//----------------------------------------------------------------------------- ++ ++void ClientLobbyRoomProtocol::setup() ++{ ++ m_setup = NetworkManager::getInstance()->setupNewGame(); // create a new setup ++ m_state = NONE; ++ Log::info("ClientLobbyRoomProtocol", "Starting the protocol."); ++} ++ ++//----------------------------------------------------------------------------- ++ ++void ServerLobbyRoomProtocol::setup() ++{ ++ m_setup = NetworkManager::getInstance()->setupNewGame(); // create a new setup ++ m_next_id = 0; ++ m_state = NONE; ++ m_public_address.ip = 0; ++ m_public_address.port = 0; ++ Log::info("ServerLobbyRoomProtocol", "Starting the protocol."); ++} ++ ++//----------------------------------------------------------------------------- ++ ++void ClientLobbyRoomProtocol::notifyEvent(Event* event) ++{ ++ assert(m_setup); // assert that the setup exists ++ if (event->type == EVENT_TYPE_MESSAGE) ++ { ++ assert(event->data.size()); // assert that data isn't empty ++ Log::verbose("LobbyRoomProtocol", "Message from %u : \"%s\"", event->peer->getAddress(), event->data.c_str()); ++ uint8_t message_type = event->data.getAndRemoveUInt8(); ++ if (message_type == 1) // new player connected ++ { ++ if (event->data.size() != 7 || event->data[0] != 4 || event->data[5] != 1) // 7 bytes remains now ++ { ++ Log::error("LobbyRoomProtocol", "A message notifying a new player wasn't formated as expected."); ++ return; ++ } ++ ++ uint32_t global_id = event->data.gui32(1); ++ ++ NetworkPlayerProfile profile; ++ profile.kart_name = ""; ++ profile.race_id = event->data.gui8(6); ++ ++ if (global_id == CurrentOnlineUser::get()->getUserID()) ++ { ++ Log::error("LobbyRoomProtocol", "The server notified me that i'm a new player in the room (not normal)."); ++ } ++ else ++ { ++ Log::verbose("LobbyRoomProtocol", "New player connected."); ++ profile.user_profile = new OnlineUser(""); ///! INSERT THE ID OF THE PLAYER HERE (global_id) ++ m_setup->addPlayer(profile); ++ } ++ } // new player connected ++ else if (message_type == 0x81) // connection accepted ++ { ++ if (event->data.size() != 12 || event->data[0] != 1 || event->data[2] != 4 || event->data[7] != 4) // 12 bytes remains now ++ { ++ Log::error("LobbyRoomProtocol", "A message notifying an accepted connection wasn't formated as expected."); ++ return; ++ } ++ ++ NetworkPlayerProfile profile; ++ profile.kart_name = ""; ++ profile.race_id = event->data.gui8(1); ++ uint32_t token = event->data.gui32(3); ++ uint32_t global_id = event->data.gui32(8); ++ if (global_id == CurrentOnlineUser::get()->getUserID()) ++ { ++ Log::info("LobbyRoomProtocol", "The server accepted the connection."); ++ profile.user_profile = CurrentOnlineUser::get(); ++ m_setup->addPlayer(profile); ++ event->peer->setClientServerToken(token); ++ m_state = CONNECTED; ++ } ++ } // connection accepted ++ else if (message_type == 0x80) // connection refused ++ { ++ if (event->data.size() != 2 || event->data[0] != 1) // 2 bytes remains now ++ { ++ Log::error("LobbyRoomProtocol", "A message notifying a refused connection wasn't formated as expected."); ++ return; ++ } ++ ++ Log::info("LobbyRoomProtocol", "The connection has been refused."); ++ switch (event->data[1]) // the second byte ++ { ++ case 0: ++ Log::info("LobbyRoomProtocol", "Too many clients in the race."); ++ break; ++ case 1: ++ Log::info("LobbyRoomProtocol", "The host has banned you."); ++ break; ++ default: ++ break; ++ } ++ } // connection refused ++ } // if (event->type == EVENT_TYPE_MESSAGE) ++ else if (event->type == EVENT_TYPE_CONNECTED) ++ { ++ } // if (event->type == EVENT_TYPE_CONNECTED) ++ else if (event->type == EVENT_TYPE_DISCONNECTED) ++ { ++ } // if (event->type == EVENT_TYPE_DISCONNECTED) ++} ++ ++//----------------------------------------------------------------------------- ++ ++void ServerLobbyRoomProtocol::notifyEvent(Event* event) ++{ ++ assert(m_setup); // assert that the setup exists ++ if (event->type == EVENT_TYPE_MESSAGE) ++ { ++ assert(event->data.size()); // message not empty ++ uint8_t message_type; ++ message_type = event->data.getAndRemoveUInt8(); ++ Log::info("ServerLobbyRoomProtocol", "Message received with type %d.", message_type); ++ if (message_type == 1) // player requesting connection ++ { ++ if (event->data.size() != 5 || event->data[0] != 4) ++ { ++ Log::warn("LobbyRoomProtocol", "A player is sending a badly formated message. Size is %d and first byte %d", event->data.size(), event->data[0]); ++ return; ++ } ++ Log::verbose("LobbyRoomProtocol", "New player."); ++ int player_id = 0; ++ player_id = event->data.getUInt32(1); ++ // can we add the player ? ++ if (m_setup->getPlayerCount() < 16) // accept player ++ { ++ // add the player to the game setup ++ while(m_setup->getProfile(m_next_id)!=NULL) ++ m_next_id++; ++ NetworkPlayerProfile profile; ++ profile.race_id = m_next_id; ++ profile.kart_name = ""; ++ profile.user_profile = new OnlineUser("Unnamed Player"); ++ m_setup->addPlayer(profile); ++ // notify everybody that there is a new player ++ NetworkString message; ++ // new player (1) -- size of id -- id -- size of local id -- local id; ++ message.ai8(1).ai8(4).ai32(player_id).ai8(1).ai8(m_next_id); ++ m_listener->sendMessageExcept(this, event->peer, message); ++ // send a message to the one that asked to connect ++ NetworkString message_ack; ++ // 0b10000001 (connection success) ; ++ RandomGenerator token_generator; ++ // use 4 random numbers because rand_max is probably 2^15-1. ++ uint32_t token = (uint32_t)(((token_generator.get(RAND_MAX)<<24) & 0xff) + ++ ((token_generator.get(RAND_MAX)<<16) & 0xff) + ++ ((token_generator.get(RAND_MAX)<<8) & 0xff) + ++ ((token_generator.get(RAND_MAX) & 0xff))); ++ // connection success (129) -- size of token -- token ++ message_ack.ai8(0x81).ai8(1).ai8(m_next_id).ai8(4).ai32(token).ai8(4).ai32(player_id); ++ m_listener->sendMessage(this, event->peer, message_ack); ++ } // accept player ++ else // refuse the connection with code 0 (too much players) ++ { ++ NetworkString message; ++ message.ai8(0x80); // 128 means connection refused ++ message.ai8(1); // 1 bytes for the error code ++ message.ai8(0); // 0 = too much players ++ // send only to the peer that made the request ++ m_listener->sendMessage(this, event->peer, message); ++ } ++ } ++ } // if (event->type == EVENT_TYPE_MESSAGE) ++ else if (event->type == EVENT_TYPE_CONNECTED) ++ { ++ } // if (event->type == EVENT_TYPE_CONNECTED) ++ else if (event->type == EVENT_TYPE_DISCONNECTED) ++ { ++ ++ } // if (event->type == EVENT_TYPE_DISCONNECTED) ++} ++ ++//----------------------------------------------------------------------------- ++ ++void ClientLobbyRoomProtocol::update() ++{ ++ switch (m_state) ++ { ++ case NONE: ++ if (NetworkManager::getInstance()->isConnectedTo(m_server_address)) ++ { ++ m_state = LINKED; ++ } ++ break; ++ case LINKED: ++ { ++ NetworkString ns; ++ // 1 (connection request), 4 (size of id), global id ++ ns.ai8(1).ai8(4).ai32(CurrentOnlineUser::get()->getUserID()); ++ m_listener->sendMessage(this, ns); ++ m_state = REQUESTING_CONNECTION; ++ break; ++ } ++ case REQUESTING_CONNECTION: ++ break; ++ case CONNECTED: ++ break; ++ case DONE: ++ m_listener->requestTerminate(this); ++ break; ++ } ++} ++ ++//----------------------------------------------------------------------------- ++ ++void ServerLobbyRoomProtocol::update() ++{ ++ switch (m_state) ++ { ++ case NONE: ++ m_current_protocol_id = m_listener->requestStart(new GetPublicAddress(&m_public_address)); ++ m_state = GETTING_PUBLIC_ADDRESS; ++ break; ++ case GETTING_PUBLIC_ADDRESS: ++ if (m_listener->getProtocolState(m_current_protocol_id) == PROTOCOL_STATE_TERMINATED) ++ { ++ NetworkManager::getInstance()->setPublicAddress(m_public_address); ++ m_current_protocol_id = m_listener->requestStart(new StartServer()); ++ m_state = LAUNCHING_SERVER; ++ Log::info("ServerLobbyRoomProtocol", "Public address known."); ++ } ++ break; ++ case LAUNCHING_SERVER: ++ if (m_listener->getProtocolState(m_current_protocol_id) == PROTOCOL_STATE_TERMINATED) ++ { ++ m_state = WORKING; ++ Log::info("ServerLobbyRoomProtocol", "Server setup"); ++ } ++ break; ++ case WORKING: ++ { ++ // first poll every 5 seconds ++ static double last_poll_time = 0; ++ if (Time::getRealTime() > last_poll_time+10.0) ++ { ++ last_poll_time = Time::getRealTime(); ++ HTTPConnector * connector = new HTTPConnector((std::string)UserConfigParams::m_server_multiplayer + "address-management.php"); ++ connector->setParameter("id",CurrentOnlineUser::get()->getUserID()); ++ connector->setParameter("token",CurrentOnlineUser::get()->getToken()); ++ connector->setParameter("action","poll-connection-requests"); ++ ++ const XMLNode * result = connector->getXMLFromPage(); ++ std::string rec_success; ++ if(result->get("success", &rec_success)) ++ { ++ if(rec_success == "yes") ++ { ++ const XMLNode * users_xml = result->getNode("users"); ++ uint32_t id = 0; ++ for (unsigned int i = 0; i < users_xml->getNumNodes(); i++) ++ { ++ users_xml->getNode(i)->get("id", &id); ++ Log::info("ServerLobbyRoomProtocol", "User with id %d wants to connect.", id); ++ m_incoming_peers_ids.push_back(id); ++ } ++ } ++ else ++ { ++ Log::error("ServerLobbyRoomProtocol", "INSERT SOME ERROR MESSAGE"); ++ } ++ } ++ else ++ { ++ Log::error("ServerLobbyRoomProtocol", "Cannot retrieve the list"); ++ } ++ } ++ ++ // now ++ for (unsigned int i = 0; i < m_incoming_peers_ids.size(); i++) ++ { ++ m_listener->requestStart(new ConnectToPeer(m_incoming_peers_ids[i])); ++ } ++ m_incoming_peers_ids.clear(); ++ ++ break; ++ } ++ case DONE: ++ m_listener->requestTerminate(this); ++ break; ++ } ++} ++//----------------------------------------------------------------------------- ++ ++ ++ +Index: src/network/protocols/connect_to_server.hpp +=================================================================== +--- src/network/protocols/connect_to_server.hpp (revision 0) ++++ src/network/protocols/connect_to_server.hpp (revision 13390) +@@ -0,0 +1,57 @@ ++// ++// 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 CONNECT_TO_SERVER_HPP ++#define CONNECT_TO_SERVER_HPP ++ ++#include "network/protocol.hpp" ++#include "network/types.hpp" ++#include ++ ++class ConnectToServer : public Protocol, public CallbackObject ++{ ++ public: ++ ConnectToServer(uint32_t server_id); ++ virtual ~ConnectToServer(); ++ ++ virtual void notifyEvent(Event* event); ++ virtual void setup(); ++ virtual void update(); ++ ++ protected: ++ TransportAddress m_server_address; ++ TransportAddress m_public_address; ++ uint32_t m_server_id; ++ uint32_t m_current_protocol_id; ++ ++ enum STATE ++ { ++ NONE, ++ WAITING_SELF_ADDRESS, ++ SELF_ADDRESS_KNOWN, ++ PEER_ADDRESS_KNOWN, ++ SELF_ADDRESS_SHOWN, ++ CONNECTING, ++ CONNECTED, ++ HIDING_ADDRESS, ++ DONE ++ }; ++ STATE m_state; ++}; ++ ++#endif // CONNECT_TO_SERVER_HPP +Index: src/network/protocols/get_public_address.hpp +=================================================================== +--- src/network/protocols/get_public_address.hpp (revision 0) ++++ src/network/protocols/get_public_address.hpp (revision 13390) +@@ -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 +Index: src/network/protocols/show_public_address.hpp +=================================================================== +--- src/network/protocols/show_public_address.hpp (revision 0) ++++ src/network/protocols/show_public_address.hpp (revision 13390) +@@ -0,0 +1,45 @@ ++// ++// 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(); ++ virtual ~ShowPublicAddress(); ++ ++ virtual void notifyEvent(Event* event); ++ virtual void setup(); ++ virtual void update(); ++ ++ protected: ++ ++ enum STATE ++ { ++ NONE, ++ DONE ++ }; ++ STATE m_state; ++}; ++ ++#endif // HIDE_PUBLIC_ADDRESS_HPP +Index: src/network/protocols/start_server.hpp +=================================================================== +--- src/network/protocols/start_server.hpp (revision 0) ++++ src/network/protocols/start_server.hpp (revision 13390) +@@ -0,0 +1,29 @@ ++#ifndef START_SERVER_HPP ++#define START_SERVER_HPP ++ ++#include "network/protocol.hpp" ++ ++/*! ++ * This protocol tells to the database that the server is up and running, ++ * and shows online the public IP:port that stores the NetworkManager. ++ */ ++class StartServer : public Protocol ++{ ++ public: ++ StartServer(); ++ virtual ~StartServer(); ++ ++ virtual void notifyEvent(Event* event); ++ virtual void setup(); ++ virtual void update(); ++ ++ protected: ++ enum STATE ++ { ++ NONE, ++ DONE ++ }; ++ STATE m_state; ++}; ++ ++#endif // START_SERVER_HPP +Index: src/network/protocols/lobby_room_protocol.hpp +=================================================================== +--- src/network/protocols/lobby_room_protocol.hpp (revision 0) ++++ src/network/protocols/lobby_room_protocol.hpp (revision 13390) +@@ -0,0 +1,102 @@ ++// ++// 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 LOBBY_ROOM_PROTOCOL_HPP ++#define LOBBY_ROOM_PROTOCOL_HPP ++ ++#include "network/protocol.hpp" ++ ++#include "network/game_setup.hpp" ++#include "network/network_string.hpp" ++ ++/*! ++ * \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 LobbyRoomProtocol : public Protocol ++{ ++ public: ++ LobbyRoomProtocol(CallbackObject* callback_object); ++ virtual ~LobbyRoomProtocol(); ++ ++ virtual void notifyEvent(Event* event) = 0; ++ virtual void setup() = 0; ++ virtual void update() = 0; ++ ++ protected: ++ GameSetup* m_setup; //!< The game setup. ++}; ++ ++class ClientLobbyRoomProtocol : public LobbyRoomProtocol ++{ ++ public: ++ ClientLobbyRoomProtocol(const TransportAddress& server_address) : LobbyRoomProtocol(NULL) ++ { m_server_address = server_address;} ++ virtual ~ClientLobbyRoomProtocol() {} ++ ++ virtual void notifyEvent(Event* event); ++ virtual void setup(); ++ virtual void update(); ++ ++ void sendMessage(std::string message); ++ ++ protected: ++ TransportAddress m_server_address; ++ ++ enum STATE ++ { ++ NONE, ++ LINKED, ++ REQUESTING_CONNECTION, ++ CONNECTED, ++ DONE ++ }; ++ STATE m_state; ++}; ++ ++class ServerLobbyRoomProtocol : public LobbyRoomProtocol ++{ ++ public: ++ ServerLobbyRoomProtocol() : LobbyRoomProtocol(NULL) {} ++ virtual ~ServerLobbyRoomProtocol() {} ++ ++ virtual void notifyEvent(Event* event); ++ virtual void setup(); ++ virtual void update(); ++ ++ protected: ++ uint8_t m_next_id; //!< Next id to assign to a peer. ++ std::vector m_peers; ++ std::vector m_incoming_peers_ids; ++ uint32_t m_current_protocol_id; ++ TransportAddress m_public_address; ++ ++ enum STATE ++ { ++ NONE, ++ GETTING_PUBLIC_ADDRESS, ++ LAUNCHING_SERVER, ++ WORKING, ++ DONE ++ }; ++ STATE m_state; ++}; ++ ++#endif // LOBBY_ROOM_PROTOCOL_HPP +Index: src/network/types.cpp +=================================================================== +--- src/network/types.cpp (revision 0) ++++ src/network/types.cpp (revision 13390) +@@ -0,0 +1,9 @@ ++#include "network/types.hpp" ++ ++uint32_t turnEndianness(uint32_t val) ++{ ++ return ((val&0xff000000)>>24) ++ +((val&0x00ff0000)>>8) ++ +((val&0x0000ff00)<<8) ++ +((val&0x000000ff)<<24); ++} +Index: src/network/protocol.hpp +=================================================================== +--- src/network/protocol.hpp (revision 0) ++++ src/network/protocol.hpp (revision 13390) +@@ -0,0 +1,108 @@ ++// ++// 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 "utils/types.hpp" ++ ++/** \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 Called when the protocol is to be killed. ++ */ ++ virtual void kill(); ++ ++ /*! ++ * \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 +Index: src/network/singleton.hpp +=================================================================== +--- src/network/singleton.hpp (revision 0) ++++ src/network/singleton.hpp (revision 13390) +@@ -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::debug("Singleton", "THE SINGLETON HAS NOT BEEN REALOCATED, IT 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 +Index: src/network/http_functions.cpp +=================================================================== +--- src/network/http_functions.cpp (revision 0) ++++ src/network/http_functions.cpp (revision 13390) +@@ -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(); ++} ++ ++} +Index: src/network/types.hpp +=================================================================== +--- src/network/types.hpp (revision 0) ++++ src/network/types.hpp (revision 13390) +@@ -0,0 +1,71 @@ ++// ++// 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 "utils/types.hpp" ++ ++#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 ++}; ++ ++uint32_t turnEndianness(uint32_t val); ++ ++ ++#endif // TYPES_HPP +Index: src/network/server_network_manager.cpp +=================================================================== +--- src/network/server_network_manager.cpp (revision 0) ++++ src/network/server_network_manager.cpp (revision 13390) +@@ -0,0 +1,99 @@ ++// ++// 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 "network/protocols/stop_server.hpp" ++ ++#include "main_loop.hpp" ++#include "utils/log.hpp" ++ ++#include ++#include ++#include ++#include ++#include ++ ++void* waitInput2(void* data) ++{ ++ std::string str = ""; ++ bool stop = false; ++ while(!stop) ++ { ++ getline(std::cin, str); ++ if (str == "quit") ++ { ++ stop = true; ++ } ++ } ++ ++ uint32_t id = ProtocolManager::getInstance()->requestStart(new StopServer()); ++ while(ProtocolManager::getInstance()->getProtocolState(id) != PROTOCOL_STATE_TERMINATED) ++ { ++ } ++ ++ main_loop->abort(); ++ exit(0); ++ ++ return NULL; ++} ++ ++ServerNetworkManager::ServerNetworkManager() ++{ ++ m_localhost = NULL; ++ m_thread_keyboard = NULL; ++} ++ ++ServerNetworkManager::~ServerNetworkManager() ++{ ++ if (m_thread_keyboard) ++ pthread_cancel(*m_thread_keyboard);//, SIGKILL); ++} ++ ++void ServerNetworkManager::run() ++{ ++ if (enet_initialize() != 0) ++ { ++ Log::error("ServerNetworkManager", "Could not initialize enet.\n"); ++ return; ++ } ++ m_localhost = new STKHost(); ++ m_localhost->setupServer(STKHost::HOST_ANY, 7321, 16, 2, 0, 0); ++ m_localhost->startListening(); ++ ++ // listen keyboard console input ++ m_thread_keyboard = (pthread_t*)(malloc(sizeof(pthread_t))); ++ pthread_create(m_thread_keyboard, NULL, waitInput2, NULL); ++ ++ NetworkManager::run(); ++} ++ ++void ServerNetworkManager::start() ++{ ++ ++} ++ ++void ServerNetworkManager::sendPacket(const NetworkString& data) ++{ ++ m_localhost->broadcastPacket(data); ++} +Index: src/network/network_interface.cpp +=================================================================== +--- src/network/network_interface.cpp (revision 0) ++++ src/network/network_interface.cpp (revision 13390) +@@ -0,0 +1,28 @@ ++// ++// 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/network_interface.hpp" ++ ++ ++NetworkInterface::NetworkInterface() ++{ ++} ++ ++NetworkInterface::~NetworkInterface() ++{ ++} +Index: src/network/stk_peer.cpp +=================================================================== +--- src/network/stk_peer.cpp (revision 0) ++++ src/network/stk_peer.cpp (revision 13390) +@@ -0,0 +1,85 @@ ++// ++// 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 & 0xff000000) >> 24) ++ + ((host.ip & 0x00ff0000) >> 8) ++ + ((host.ip & 0x0000ff00) << 8) ++ + ((host.ip & 0x000000ff) << 24); // because ENet wants little endian ++ address.port = host.port; ++ ++ ENetPeer* peer = enet_host_connect(localhost->m_host, &address, 2, 0); ++ if (peer == NULL) ++ { ++ 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(NetworkString const& data) ++{ ++ Log::info("STKPeer", "sending packet of size %d to %i.%i.%i.%i:%i", data.size(), (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.c_str(), data.size()+1,ENET_PACKET_FLAG_RELIABLE); ++ ++ enet_peer_send(m_peer, 0, packet); ++} ++ ++uint32_t STKPeer::getAddress() const ++{ ++ return m_peer->address.host; ++} ++ ++uint16_t STKPeer::getPort() const ++{ ++ return m_peer->address.port; ++} ++ ++bool STKPeer::isConnected() const ++{ ++ Log::info("STKPeer", "The peer state is %i\n", m_peer->state); ++ return (m_peer->state == ENET_PEER_STATE_CONNECTED); ++} ++bool STKPeer::operator==(const ENetPeer* peer) const ++{ ++ return peer==m_peer; ++} +Index: src/network/http_functions.hpp +=================================================================== +--- src/network/http_functions.hpp (revision 0) ++++ src/network/http_functions.hpp (revision 13390) +@@ -0,0 +1,35 @@ ++// ++// 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 HTTP_FUNCTIONS_HPP ++#define HTTP_FUNCTIONS_HPP ++ ++#include ++ ++namespace HTTP ++{ ++ ++void init(); ++void shutdown(); ++ ++std::string getPage(std::string url); ++ ++ ++} ++ ++#endif // HTTP_FUNCTIONS_HPP +Index: src/network/network_interface.hpp +=================================================================== +--- src/network/network_interface.hpp (revision 0) ++++ src/network/network_interface.hpp (revision 13390) +@@ -0,0 +1,44 @@ ++// ++// 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 NETWORK_INTERFACE_H ++#define NETWORK_INTERFACE_H ++ ++#include "network/singleton.hpp" ++#include "network/types.hpp" ++#include "network/network_manager.hpp" ++ ++#include ++#include ++ ++ ++class NetworkInterface : public Singleton ++{ ++ friend class Singleton; ++ public: ++ ++ void initNetwork(bool server); ++ ++ protected: ++ // protected functions ++ NetworkInterface(); ++ virtual ~NetworkInterface(); ++ ++}; ++ ++#endif // NETWORK_INTERFACE_H +Index: src/network/server_network_manager.hpp +=================================================================== +--- src/network/server_network_manager.hpp (revision 0) ++++ src/network/server_network_manager.hpp (revision 13390) +@@ -0,0 +1,50 @@ ++// ++// 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(); ++ ++ virtual void sendPacket(const NetworkString& data); ++ ++ virtual bool isServer() { return true; } ++ ++ protected: ++ ServerNetworkManager(); ++ virtual ~ServerNetworkManager(); ++ ++ pthread_t* m_thread_keyboard; ++ ++}; ++ ++#endif // SERVER_NETWORK_MANAGER_HPP +Index: src/network/network_string.cpp +=================================================================== +--- src/network/network_string.cpp (revision 0) ++++ src/network/network_string.cpp (revision 13390) +@@ -0,0 +1,8 @@ ++#include "network/network_string.hpp" ++ ++NetworkString operator+(NetworkString const& a, NetworkString const& b) ++{ ++ NetworkString ns(a); ++ ns += b; ++ return ns; ++} +Index: src/network/event.cpp +=================================================================== +--- src/network/event.cpp (revision 0) ++++ src/network/event.cpp (revision 13390) +@@ -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/event.hpp" ++#include "network/network_manager.hpp" ++ ++#include "utils/log.hpp" ++ ++#include ++ ++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), event->packet->dataLength-1); ++ } ++ else if (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.removeFront(size); ++} ++ +Index: src/network/client_network_manager.cpp +=================================================================== +--- src/network/client_network_manager.cpp (revision 0) ++++ src/network/client_network_manager.cpp (revision 13390) +@@ -0,0 +1,94 @@ ++// ++// 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" ++ ++#include ++#include ++#include ++ ++void* waitInput(void* data) ++{ ++ std::string str = ""; ++ bool stop = false; ++ while(!stop) ++ { ++ getline(std::cin, str); ++ if (str == "connect=") ++ { ++ int id = 0; ++ std::cin >> id; ++ ProtocolManager::getInstance()->requestStart(new ConnectToServer(id)); ++ } ++ if (str == "quit") ++ { ++ stop = true; ++ } ++ } ++ ++ exit(0); ++ ++ return NULL; ++} ++ ++ClientNetworkManager::ClientNetworkManager() ++{ ++ m_thread_keyboard = NULL; ++} ++ ++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(); ++ ++ // listen keyboard console input ++ m_thread_keyboard = (pthread_t*)(malloc(sizeof(pthread_t))); ++ pthread_create(m_thread_keyboard, NULL, waitInput, NULL); ++ ++ NetworkManager::run(); ++} ++ ++void ClientNetworkManager::sendPacket(const NetworkString& 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]; ++} +Index: src/network/stk_peer.hpp +=================================================================== +--- src/network/stk_peer.hpp (revision 0) ++++ src/network/stk_peer.hpp (revision 13390) +@@ -0,0 +1,54 @@ ++// ++// 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 STK_PEER_HPP ++#define STK_PEER_HPP ++ ++#include "network/stk_host.hpp" ++#include "network/network_string.hpp" ++#include ++ ++class STKPeer ++{ ++ friend class Event; ++ public: ++ STKPeer(); ++ virtual ~STKPeer(); ++ ++ virtual void sendPacket(const NetworkString& data); ++ ++ static bool connectToHost(STKHost* localhost, TransportAddress host, uint32_t channel_count, uint32_t data); ++ ++ bool isConnected() const; ++ void setClientServerToken(const uint32_t& token) { m_client_server_token = token; m_token_set = true; } ++ void unsetClientServerToken() { m_token_set = false; } ++ ++ uint32_t getAddress() const; ++ uint16_t getPort() const; ++ uint32_t getClientServerToken() const; ++ bool isClientServerTokenSet() const { return m_token_set; } ++ ++ bool operator==(const ENetPeer* peer) const; ++ ++ protected: ++ ENetPeer* m_peer; ++ uint32_t m_client_server_token; ++ bool m_token_set; ++}; ++ ++#endif // STK_PEER_HPP +Index: src/network/network_manager.cpp +=================================================================== +--- src/network/network_manager.cpp (revision 13389) ++++ src/network/network_manager.cpp (revision 13390) +@@ -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,170 @@ + + #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" + +-NetworkManager* network_manager = 0; ++#include "network/protocol_manager.hpp" ++#include "network/client_network_manager.hpp" ++#include "network/server_network_manager.hpp" + +-NetworkManager::NetworkManager() +-{ +- m_mode = NW_NONE; +- m_state = NS_ACCEPT_CONNECTIONS; +- m_host = NULL; ++#include "utils/log.hpp" + +- m_num_clients = 0; +- m_host_id = 0; ++#include ++#include + +- 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 ++ m_public_address.ip = 0; ++ m_public_address.port = 0; ++ m_localhost = NULL; ++ m_game_setup = NULL; ++} + +-// ----------------------------------------------------------------------------- +-NetworkManager::~NetworkManager() +-{ +- if(m_mode==NW_SERVER || m_mode==NW_CLIENT) enet_host_destroy(m_host); +- enet_deinitialize(); +-} // ~NetworkManager ++//----------------------------------------------------------------------------- + +-// ----------------------------------------------------------------------------- +-bool NetworkManager::initServer() ++NetworkManager::~NetworkManager() + { +- 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) ++ 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 ++void NetworkManager::run() ++{ ++ // create the protocol manager ++ ProtocolManager::getInstance(); ++} + +-// ----------------------------------------------------------------------------- +-/** Initialises the client. This function tries to connect to the server. +- */ +-bool NetworkManager::initClient() +-{ +- 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 */ ); ++//----------------------------------------------------------------------------- + +- 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() +-{ +- 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() ++void NetworkManager::setManualSocketsMode(bool manual) + { +- 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??? ++ if (manual) ++ m_localhost->stopListening(); ++ else ++ m_localhost->startListening(); ++} + +-} // disableNetworking ++//----------------------------------------------------------------------------- + +-// ---------------------------------------------------------------------------- +-void NetworkManager::handleNewConnection(ENetEvent *event) ++void NetworkManager::notifyEvent(Event* 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) ++ Log::info("NetworkManager", "EVENT received"); ++ switch (event->type) + { +- 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; +- } ++ case EVENT_TYPE_MESSAGE: ++ Log::info("NetworkManager", "Message, Sender : %u, message = \"%s\"", event->peer->getAddress(), event->data.c_str()); + break; +- } +- case NS_READY_SET_GO_BARRIER: ++ case EVENT_TYPE_DISCONNECTED: + { +- m_barrier_count ++; +- if(m_barrier_count==(int)m_num_clients) ++ Log::info("NetworkManager", "Somebody is now disconnected. There are now %lu peers.", m_peers.size()); ++ Log::info("NetworkManager", "Disconnected host: %i.%i.%i.%i:%i", event->peer->getAddress()>>24&0xff, event->peer->getAddress()>>16&0xff, event->peer->getAddress()>>8&0xff, event->peer->getAddress()&0xff,event->peer->getPort()); ++ // remove the peer: ++ bool removed = false; ++ for (unsigned int i = 0; i < m_peers.size(); i++) + { +- m_state = NS_RACING; +- RaceStartMessage m; +- broadcastToClients(m); ++ if (m_peers[i] == event->peer && !removed) // remove only one ++ { ++ delete m_peers[i]; ++ m_peers.erase(m_peers.begin()+i, m_peers.begin()+i+1); ++ Log::info("NetworkManager", "The peer has been removed from the Network Manager."); ++ removed = true; ++ } ++ else if (m_peers[i] == event->peer) ++ { ++ Log::fatal("NetworkManager", "Multiple peers match the disconnected one."); ++ } + } ++ if (!removed) ++ Log::fatal("NetworkManager", "The peer that has been disconnected was not registered by the Network Manager."); + 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; +- } ++ case EVENT_TYPE_CONNECTED: ++ Log::info("NetworkManager", "A client has just connected. There are now %lu peers.", m_peers.size() + 1); ++ // create the new peer: ++ m_peers.push_back(event->peer); + break; +- } +- 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 ++ ProtocolManager::getInstance()->notifyEvent(event); ++} + +-// ---------------------------------------------------------------------------- +-void NetworkManager::broadcastToClients(Message &m) +-{ +- enet_host_broadcast(m_host, 0, m.getPacket()); +- enet_host_flush(m_host); +-} // broadcastToClients ++//----------------------------------------------------------------------------- + +-// ---------------------------------------------------------------------------- +-void NetworkManager::sendToServer(Message &m) ++void NetworkManager::sendPacket(STKPeer* peer, const NetworkString& data) + { +- enet_peer_send(m_server, 0, m.getPacket()); +- enet_host_flush(m_host); +-} // sendToServer ++ if (peer) ++ peer->sendPacket(data); ++} + +-// ---------------------------------------------------------------------------- +-/** 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) ++void NetworkManager::sendPacketExcept(STKPeer* peer, const NetworkString& data) + { +- if(m_mode==NW_SERVER) ++ for (unsigned int i = 0; i < m_peers.size(); i++) + { +- CharacterConfirmMessage ccm(kart_id, getMyHostId()); +- broadcastToClients(ccm); ++ if (m_peers[i] != peer) ++ m_peers[i]->sendPacket(data); + } +- 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() ++GameSetup* NetworkManager::setupNewGame() + { +- if(m_mode==NW_CLIENT) +- { +- WorldLoadedMessage m; +- sendToServer(m); +- m_state = NS_READY_SET_GO_BARRIER; +- } +-} // worldLoaded ++ if (m_game_setup) ++ delete m_game_setup; ++ m_game_setup = new GameSetup(); ++ return m_game_setup; ++} + +-// ---------------------------------------------------------------------------- +-/** 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() ++void NetworkManager::setLogin(std::string username, std::string password) + { +- if(m_mode==NW_SERVER) +- { +- setupPlayerKartInfo(); +- RaceInfoMessage m(m_kart_info); +- broadcastToClients(m); +- } +- beginReadySetGoBarrier(); +-} // sendRaceInformationToClients ++ m_player_login.username = username; ++ m_player_login.password = password; ++} + +-// ---------------------------------------------------------------------------- +-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() ++void NetworkManager::setPublicAddress(TransportAddress addr) + { +- 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; ++ m_public_address = addr; ++} + +- for(int i=0; ienterRaceOverState(); +- return; +- } +- race_state->receive(event.packet); +- } +- } // for ipeerExists(peer); ++} + +-} // waitForClientData +-// ---------------------------------------------------------------------------- +-/** Sends the race result (kart positions and finishing times) from the server +- * to all clients. Clients keep on racing till they receive this message, and +- * will then copy the server's race results to the race manager. +- */ +-void NetworkManager::sendRaceResults() +-{ +- RaceResultMessage m; +- broadcastToClients(m); +-} // sendRaceResults ++//----------------------------------------------------------------------------- + +-// ---------------------------------------------------------------------------- +-/** Changes the mode to wait in a barrier for all clients and the server to +- * acknowledge the result screen. The server waits for a message from all +- * clients, upon which it sends a message to all clients. The clients wait +- * for this message before continuing. +- */ +-void NetworkManager::beginRaceResultBarrier() ++bool NetworkManager::isConnectedTo(TransportAddress peer) + { +- m_state = NS_RACE_RESULT_BARRIER; +- +- if(m_mode==NW_SERVER) +- { +- m_barrier_count = 0; +- // In case of no networking set the next state +- if(m_num_clients == 0) m_state = NS_MAIN_MENU; +- } +-} // beginRaceResultBarrier +- +-// ---------------------------------------------------------------------------- +-/** Sends a race 'result acknowledge' message from the clients to the server, +- * or from the server to the clients (in this case it contains the selected +- * menu choice from the server). +- */ +-void NetworkManager::sendRaceResultAck(char menu_selection) +-{ +- // Menu selection is actually not important for a client +- RaceResultAckMessage m(menu_selection); +- if (m_mode==NW_CLIENT) +- { +- sendToServer(m); +- } +- else +- { +- broadcastToClients(m); +- } +-} // sendRaceResultAck ++ return m_localhost->isConnectedTo(peer); ++} + +Property changes on: src/network/network_manager.cpp +___________________________________________________________________ +Deleted: svn:keywords +## -1 +0,0 ## +-Author Date Id Revision +\ No newline at end of property +Deleted: svn:eol-style +## -1 +0,0 ## +-native +\ No newline at end of property +Index: src/network/network_string.hpp +=================================================================== +--- src/network/network_string.hpp (revision 0) ++++ src/network/network_string.hpp (revision 13390) +@@ -0,0 +1,211 @@ ++#ifndef NETWORK_STRING_HPP ++#define NETWORK_STRING_HPP ++ ++#include "utils/types.hpp" ++ ++#include ++#include ++#include ++ ++typedef unsigned char uchar; ++ ++class NetworkString ++{ ++ union { ++ float f; ++ uint8_t i[4]; ++ } f_as_i; // float as integer ++ union { ++ double d; ++ uint8_t i[8]; ++ } d_as_i; // double as integer ++ public: ++ NetworkString() { } ++ NetworkString(const uint8_t& value) { m_string = (char)(value); } ++ NetworkString(NetworkString const& copy) { m_string = copy.m_string; } ++ NetworkString(std::string str) { m_string = str; } ++ ++ NetworkString& removeFront(int size) ++ { ++ m_string.erase(0, size); ++ return *this; ++ } ++ NetworkString& remove(int pos, int size) ++ { ++ m_string.erase(pos, size); ++ return *this; ++ } ++ ++ uint8_t operator[](const int& pos) ++ { ++ return getUInt8(pos); ++ } ++ ++ NetworkString& addUInt8(const uint8_t& value) ++ { ++ m_string += (char)(value); ++ return *this; ++ } ++ inline NetworkString& ai8(const uint8_t& value) { return addUInt8(value); } ++ NetworkString& addUInt16(const uint16_t& value) ++ { ++ m_string += (char)((value<<8)&0xff); ++ m_string += (char)(value&0xff); ++ return *this; ++ } ++ inline NetworkString& ai16(const uint16_t& value) { return addUInt16(value); } ++ NetworkString& addUInt32(const uint32_t& value) ++ { ++ m_string += (char)((value<<24)&0xff); ++ m_string += (char)((value<<16)&0xff); ++ m_string += (char)((value<<8)&0xff); ++ m_string += (char)(value&0xff); ++ return *this; ++ } ++ inline NetworkString& ai32(const uint32_t& value) { return addUInt32(value); } ++ NetworkString& addInt(const int& value) ++ { ++ m_string += (char)((value<<24)&0xff); ++ m_string += (char)((value<<16)&0xff); ++ m_string += (char)((value<<8)&0xff); ++ m_string += (char)(value&0xff); ++ return *this; ++ } ++ inline NetworkString& ai(const int& value) { return addInt(value); } ++ NetworkString& addFloat(const float& value) //!< BEWARE OF PRECISION ++ { ++ assert(sizeof(float)==4); ++ f_as_i.f = value; ++ m_string += (char)(f_as_i.i[0]); ++ m_string += (char)(f_as_i.i[1]); ++ m_string += (char)(f_as_i.i[2]); ++ m_string += (char)(f_as_i.i[3]); ++ return *this; ++ } ++ inline NetworkString& af(const float& value) { return addFloat(value); } ++ NetworkString& addDouble(const double& value) //!< BEWARE OF PRECISION ++ { ++ assert(sizeof(double)==8); ++ d_as_i.d = value; ++ m_string += (char)(d_as_i.i[0]); ++ m_string += (char)(d_as_i.i[1]); ++ m_string += (char)(d_as_i.i[2]); ++ m_string += (char)(d_as_i.i[3]); ++ m_string += (char)(d_as_i.i[4]); ++ m_string += (char)(d_as_i.i[5]); ++ m_string += (char)(d_as_i.i[6]); ++ m_string += (char)(d_as_i.i[7]); ++ return *this; ++ } ++ inline NetworkString& ad(const double& value) { return addDouble(value); } ++ NetworkString& operator+=(NetworkString const& value) ++ { ++ m_string += value.m_string; ++ return *this; ++ } ++ ++ const char* c_str() const ++ { ++ return m_string.c_str(); ++ } ++ int size() const ++ { ++ return m_string.size(); ++ } ++ ++ template ++ T get(int pos) ++ { ++ int a = n; ++ T result = 0; ++ while(a--) ++ { ++ result <<= 8; // offset one byte ++ result += ((uint8_t)(m_string[pos+n-1-a]) & 0xff); // add the data ++ } ++ return result; ++ } ++ ++ inline int getInt(int pos = 0) { return get(pos); } ++ inline uint32_t getUInt(int pos = 0) { return get(pos); } ++ inline uint32_t getUInt32(int pos = 0) { return get(pos); } ++ inline uint16_t getUInt16(int pos = 0) { return get(pos); } ++ inline uint8_t getUInt8(int pos = 0) { return get(pos); } ++ inline char getChar(int pos = 0) { return get(pos); } ++ inline unsigned char getUChar(int pos = 0) { return get(pos); } ++ ++ inline int gi(int pos = 0) { return get(pos); } ++ inline uint32_t gui(int pos = 0) { return get(pos); } ++ inline uint32_t gui32(int pos = 0) { return get(pos); } ++ inline uint16_t gui16(int pos = 0) { return get(pos); } ++ inline uint8_t gui8(int pos = 0) { return get(pos); } ++ inline char gc(int pos = 0) { return get(pos); } ++ inline unsigned char guc(int pos = 0) { return get(pos); } ++ ++ double getDouble(int pos = 0) //!< BEWARE OF PRECISION ++ { ++ for (int i = 0; i < 8; i++) ++ d_as_i.i[i] = m_string[pos+i]; ++ return d_as_i.d; ++ } ++ float getFloat(int pos = 0) //!< BEWARE OF PRECISION ++ { ++ for (int i = 0; i < 4; i++) ++ f_as_i.i[i] = m_string[pos+i]; ++ return f_as_i.f; ++ } ++ ++ //! Functions to get while removing ++ template ++ T getAndRemove(int pos) ++ { ++ int a = n; ++ T result = 0; ++ while(a--) ++ { ++ result <<= 8; // offset one byte ++ result += ((uint8_t)(m_string[pos+n-1-a]) & 0xff); // add the data ++ } ++ remove(pos,n); ++ return result; ++ } ++ ++ inline int getAndRemoveInt(int pos = 0) { return getAndRemove(pos); } ++ inline uint32_t getAndRemoveUInt(int pos = 0) { return getAndRemove(pos); } ++ inline uint32_t getAndRemoveUInt32(int pos = 0) { return getAndRemove(pos); } ++ inline uint16_t getAndRemoveUInt16(int pos = 0) { return getAndRemove(pos); } ++ inline uint8_t getAndRemoveUInt8(int pos = 0) { return getAndRemove(pos); } ++ inline char getAndRemoveChar(int pos = 0) { return getAndRemove(pos); } ++ inline unsigned char getAndRemoveUChar(int pos = 0) { return getAndRemove(pos); } ++ double getAndRemoveDouble(int pos = 0) //!< BEWARE OF PRECISION ++ { ++ for (int i = 0; i < 8; i++) ++ d_as_i.i[i] = m_string[pos+i]; ++ return d_as_i.d; ++ remove(pos, 8); ++ } ++ float getAndRemoveFloat(int pos = 0) //!< BEWARE OF PRECISION ++ { ++ for (int i = 0; i < 4; i++) ++ f_as_i.i[i] = m_string[pos+i]; ++ return f_as_i.f; ++ remove(pos, 4); ++ } ++ ++ inline NetworkString& gui8(uint8_t* dst) { *dst = getAndRemoveUInt8(0); return *this; } ++ inline NetworkString& gui16(uint16_t* dst) { *dst = getAndRemoveUInt16(0); return *this; } ++ inline NetworkString& gui32(uint32_t* dst) { *dst = getAndRemoveUInt32(0); return *this; } ++ inline NetworkString& gui(uint32_t* dst) { *dst = getAndRemoveUInt32(0); return *this; } ++ inline NetworkString& gi(int* dst) { *dst = getAndRemoveInt(0); return *this; } ++ inline NetworkString& gc(char* dst) { *dst = getAndRemoveChar(0); return *this; } ++ inline NetworkString& guc(uchar* dst) { *dst = getAndRemoveUChar(0); return *this; } ++ inline NetworkString& gd(double* dst) { *dst = getAndRemoveDouble(0); return *this; } ++ inline NetworkString& gf(float* dst) { *dst = getAndRemoveFloat(0); return *this; } ++ ++ protected: ++ std::string m_string; ++}; ++ ++NetworkString operator+(NetworkString const& a, NetworkString const& b); ++ ++#endif // NETWORK_STRING_HPP +Index: src/network/event.hpp +=================================================================== +--- src/network/event.hpp (revision 0) ++++ src/network/event.hpp (revision 13390) +@@ -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 "network/network_string.hpp" ++#include "utils/types.hpp" ++ ++/*! ++ * \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. ++ NetworkString data; //!< Copy of the data passed by the event. ++ STKPeer* peer; //!< Pointer to the peer that triggered that event. ++ ++ private: ++ ENetPacket* m_packet; //!< A pointer on the ENetPacket to be deleted. ++}; ++ ++#endif // EVENT_HPP +Index: src/network/client_network_manager.hpp +=================================================================== +--- src/network/client_network_manager.hpp (revision 0) ++++ src/network/client_network_manager.hpp (revision 13390) +@@ -0,0 +1,46 @@ ++// ++// 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(); ++ virtual void sendPacket(const NetworkString& data); ++ ++ STKPeer* getPeer(); ++ virtual bool isServer() { return false; } ++ ++ protected: ++ ClientNetworkManager(); ++ virtual ~ClientNetworkManager(); ++ ++ pthread_t* m_thread_keyboard; ++}; ++ ++#endif // CLIENT_NETWORK_MANAGER_HPP +Index: src/network/network_manager.hpp +=================================================================== +--- src/network/network_manager.hpp (revision 13389) ++++ src/network/network_manager.hpp (revision 13390) +@@ -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,67 @@ + // 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 +-#include ++#include "network/stk_peer.hpp" ++#include "network/stk_host.hpp" + +-#include "enet/enet.h" ++#include "network/protocol_manager.hpp" ++#include "network/singleton.hpp" ++#include "network/types.hpp" ++#include "network/event.hpp" ++#include "network/game_setup.hpp" + +-#include "network/remote_kart_info.hpp" ++#include + +- +-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); ++ ++ // message/packets related functions ++ virtual void notifyEvent(Event* event); ++ virtual void sendPacket(const NetworkString& data) = 0; ++ virtual void sendPacket(STKPeer* peer, const NetworkString& data); ++ virtual void sendPacketExcept(STKPeer* peer, const NetworkString& data); + +- // 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: ++ // Game related functions ++ virtual GameSetup* setupNewGame(); //!< Creates a new game setup and returns it + +- 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; } ++ TransportAddress getPublicAddress() { return m_public_address; } ++ GameSetup* getGameSetup() { return m_game_setup; } ++ ++ protected: ++ NetworkManager(); ++ virtual ~NetworkManager(); ++ ++ // protected members ++ std::vector m_peers; ++ STKHost* m_localhost; ++ bool m_playing_online; ++ GameSetup* m_game_setup; ++ ++ TransportAddress m_public_address; ++ PlayerLogin m_player_login; + }; + +-extern NetworkManager *network_manager; +- +-#endif ++#endif // NETWORKMANAGER_HPP + +Property changes on: src/network/network_manager.hpp +___________________________________________________________________ +Deleted: svn:keywords +## -1 +0,0 ## +-Author Date Id Revision +\ No newline at end of property +Deleted: svn:eol-style +## -1 +0,0 ## +-native +\ No newline at end of property +Index: src/network/game_setup.cpp +=================================================================== +--- src/network/game_setup.cpp (revision 0) ++++ src/network/game_setup.cpp (revision 13390) +@@ -0,0 +1,100 @@ ++// ++// 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/game_setup.hpp" ++ ++#include "utils/log.hpp" ++ ++//----------------------------------------------------------------------------- ++ ++GameSetup::GameSetup() ++{ ++} ++ ++//----------------------------------------------------------------------------- ++ ++GameSetup::~GameSetup() ++{ ++} ++ ++//----------------------------------------------------------------------------- ++ ++void GameSetup::addPlayer(NetworkPlayerProfile profile) ++{ ++ m_players.push_back(profile); ++} ++ ++//----------------------------------------------------------------------------- ++ ++void GameSetup::removePlayer(uint32_t id) ++{ ++ for (unsigned int i = 0; i < m_players.size(); i++) ++ { ++ if (m_players[i].user_profile->getUserID() == id) ++ { ++ m_players.erase(m_players.begin()+i, m_players.begin()+i+1); ++ Log::verbose("GameSetup", "Removed a player from the game setup."); ++ return; ++ } ++ } ++} ++ ++//----------------------------------------------------------------------------- ++ ++void GameSetup::removePlayer(uint8_t id) ++{ ++ for (unsigned int i = 0; i < m_players.size(); i++) ++ { ++ if (m_players[i].race_id == id) // check the given id ++ { ++ m_players.erase(m_players.begin()+i, m_players.begin()+i+1); ++ Log::verbose("GameSetup", "Removed a player from the game setup."); ++ return; ++ } ++ } ++} ++ ++//----------------------------------------------------------------------------- ++ ++const NetworkPlayerProfile* GameSetup::getProfile(uint32_t id) ++{ ++ for (unsigned int i = 0; i < m_players.size(); i++) ++ { ++ if (m_players[i].user_profile->getUserID() == id) ++ { ++ return &m_players[i]; ++ } ++ } ++ return NULL; ++} ++ ++//----------------------------------------------------------------------------- ++ ++const NetworkPlayerProfile* GameSetup::getProfile(uint8_t id) ++{ ++ for (unsigned int i = 0; i < m_players.size(); i++) ++ { ++ if (m_players[i].race_id == id) ++ { ++ return &m_players[i]; ++ } ++ } ++ return NULL; ++} ++ ++//----------------------------------------------------------------------------- +Index: src/network/protocol_manager.cpp +=================================================================== +--- src/network/protocol_manager.cpp (revision 0) ++++ src/network/protocol_manager.cpp (revision 13390) +@@ -0,0 +1,377 @@ ++// ++// 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 ++#include ++ ++void* protocolManagerUpdate(void* data) ++{ ++ ProtocolManager* manager = static_cast(data); ++ while(!manager->exit()) ++ { ++ manager->update(); ++ } ++ return NULL; ++} ++ ++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); ++ pthread_mutex_init(&m_exit_mutex, NULL); ++ m_next_protocol_id = 0; ++ ++ ++ pthread_mutex_lock(&m_exit_mutex); // will let the update function run ++ m_update_thread = (pthread_t*)(malloc(sizeof(pthread_t))); ++ pthread_create(m_update_thread, NULL, protocolManagerUpdate, this); ++} ++ ++ProtocolManager::~ProtocolManager() ++{ ++ pthread_mutex_unlock(&m_exit_mutex); // will stop the update function ++ 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); ++ pthread_mutex_destroy(&m_exit_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, const NetworkString& message) ++{ ++ NetworkString newMessage; ++ newMessage.ai8(sender->getProtocolType()); // add one byte to add protocol type ++ newMessage += message; ++ NetworkManager::getInstance()->sendPacket(newMessage); ++} ++ ++void ProtocolManager::sendMessage(Protocol* sender, STKPeer* peer, const NetworkString& message) ++{ ++ NetworkString newMessage; ++ newMessage.ai8(sender->getProtocolType()); // add one byte to add protocol type ++ newMessage += message; ++ NetworkManager::getInstance()->sendPacket(peer, newMessage); ++} ++void ProtocolManager::sendMessageExcept(Protocol* sender, STKPeer* peer, const NetworkString& message) ++{ ++ NetworkString newMessage; ++ newMessage.ai8(sender->getProtocolType()); // add one byte to add protocol type ++ newMessage += message; ++ NetworkManager::getInstance()->sendPacketExcept(peer, newMessage); ++} ++ ++uint32_t 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.", 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.", 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->type == EVENT_TYPE_MESSAGE) ++ { ++ if (event->data.size() > 0) ++ searchedProtocol = (PROTOCOL_TYPE)(event->data.getUInt8(0)); ++ event->removeFront(1); // remove the first byte which indicates the protocol ++ } ++ if (event->type == EVENT_TYPE_CONNECTED) ++ { ++ searchedProtocol = PROTOCOL_CONNECTION; ++ } ++ for (unsigned int i = 0; i < m_protocols.size() ; i++) ++ { ++ if (m_protocols[i].protocol->getProtocolType() == searchedProtocol || event->type == EVENT_TYPE_DISCONNECTED) // pass data to protocols even when paused ++ m_protocols[i].protocol->notifyEvent(event); ++ } ++ 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 ++} ++ ++uint32_t 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; ++} ++ ++Protocol* ProtocolManager::getProtocol(uint32_t id) ++{ ++ for (unsigned int i = 0; i < m_protocols.size(); i++) ++ { ++ if (m_protocols[i].id == id) ++ return m_protocols[i].protocol; ++ } ++ return NULL; ++} ++ ++bool ProtocolManager::isServer() ++{ ++ return NetworkManager::getInstance()->isServer(); ++} ++ ++int ProtocolManager::exit() ++{ ++ switch(pthread_mutex_trylock(&m_exit_mutex)) { ++ case 0: /* if we got the lock, unlock and return 1 (true) */ ++ pthread_mutex_unlock(&m_exit_mutex); ++ return 1; ++ case EBUSY: /* return 0 (false) if the mutex was locked */ ++ return 0; ++ } ++ return 1; ++} ++ ++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); ++} ++ ++ +Index: src/network/remote_kart_info.hpp +=================================================================== +--- src/network/remote_kart_info.hpp (revision 13389) ++++ src/network/remote_kart_info.hpp (revision 13390) + +Property changes on: src/network/remote_kart_info.hpp +___________________________________________________________________ +Deleted: svn:keywords +## -1 +0,0 ## +-Author Date Id Revision +\ No newline at end of property +Deleted: svn:eol-style +## -1 +0,0 ## +-native +\ No newline at end of property +Index: src/main_loop.cpp +=================================================================== +--- src/main_loop.cpp (revision 13389) ++++ src/main_loop.cpp (revision 13390) +@@ -29,7 +29,6 @@ + #include "input/wiimote_manager.hpp" + #include "modes/profile_world.hpp" + #include "modes/world.hpp" +-#include "network/network_manager.hpp" + #include "race/race_manager.hpp" + #include "states_screens/state_manager.hpp" + #include "utils/profiler.hpp" +@@ -94,21 +93,8 @@ + */ + void MainLoop::updateRace(float dt) + { +- // Server: Send the current position and previous controls to all clients +- // 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(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(); +- + World::getWorld()->updateWorld(dt); + } // updateRace + +@@ -127,13 +113,8 @@ + m_prev_time = m_curr_time; + float dt = getLimitedDt(); + +- 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; + updateRace(dt); + } // if race is active + +Index: src/utils/types.hpp +=================================================================== +--- src/utils/types.hpp (revision 13389) ++++ src/utils/types.hpp (revision 13390) +@@ -20,6 +20,8 @@ + #define HEADER_TYPES_HPP + + #ifdef _MSC_VER ++ typedef unsigned char uint8_t; ++ typedef unsigned short uint16_t; + typedef __int32 int32_t; + typedef unsigned __int32 uint32_t; + typedef __int64 int64_t; +Index: src/ide/vc9/supertuxkart.vcproj +=================================================================== +--- src/ide/vc9/supertuxkart.vcproj (revision 13389) ++++ src/ide/vc9/supertuxkart.vcproj (revision 13390) +@@ -1142,23 +1142,23 @@ + Name="network" + > + + + + + + + + + + + + + + + + + + ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ + + + + ++ ++ ++ ++ ++ ++ + +@@ -1509,6 +1585,10 @@ + > + + ++ ++ + +@@ -1525,6 +1605,10 @@ + > + + ++ ++ + +@@ -1638,6 +1722,22 @@ + > + + ++ ++ ++ ++ ++ ++ ++ ++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +- +- +- +- +- +- +- +- ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ + + + + ++ ++ ++ ++ ++ ++ + +@@ -2711,6 +2855,10 @@ + > + + ++ ++ + +@@ -2727,6 +2875,10 @@ + > + + ++ ++ + +@@ -2828,6 +2980,22 @@ + > + + ++ ++ ++ ++ ++ ++ ++ ++ + + setMode(NetworkManager::NW_SERVER); + UserConfigParams::m_server_port = n; + } + else if( !strcmp(argv[i], "--server") ) + { +- network_manager->setMode(NetworkManager::NW_SERVER); ++ NetworkManager::getInstance(); ++ Log::info("main", "Creating a server network manager."); + } +- else if( sscanf(argv[i], "--port=%d", &n) ) ++ else if( sscanf(argv[i], "--max-players=%d", &n) ) + { +- UserConfigParams::m_server_port=n; ++ UserConfigParams::m_server_max_players=n; + } +- else if( sscanf(argv[i], "--client=%1023s", s) ) ++ else if( sscanf(argv[i], "--login=%1023s", s) ) + { +- network_manager->setMode(NetworkManager::NW_CLIENT); +- UserConfigParams::m_server_address=s; ++ login = s; ++ try_login = true; + } ++ else if( sscanf(argv[i], "--password=%1023s", s) ) ++ { ++ password = s; ++ } + else if ( sscanf(argv[i], "--gfx=%d", &n) ) + { + if (n) +@@ -982,6 +994,9 @@ + } + else if( !strcmp(argv[i], "--no-graphics") ) + { ++ } ++ else if( !strcmp(argv[i], "--with-profile") ) ++ { + // Set default profile mode of 1 lap if we haven't already set one + if (!ProfileWorld::isProfileMode()) { + UserConfigParams::m_no_start_screen = true; +@@ -1091,6 +1106,12 @@ + UserConfigParams::m_sfx = false; // Disable sound effects + UserConfigParams::m_music = false;// and music when profiling + } ++ ++ if (try_login) ++ { ++ irr::core::stringw s; ++ CurrentOnlineUser::get()->signIn(login, password, s); ++ } + + return 1; + } // handleCmdLine +@@ -1173,7 +1194,6 @@ + powerup_manager = new PowerupManager (); + attachment_manager = new AttachmentManager (); + highscore_manager = new HighscoreManager (); +- network_manager = new NetworkManager (); + KartPropertiesManager::addKartSearchDir( + file_manager->getAddonsFile("karts/")); + track_manager->addTrackSearchDir( +@@ -1215,6 +1235,7 @@ + if(Online::HTTPManager::isRunning()) + Online::HTTPManager::get()->stopNetworkThread(); + //delete in reverse order of what they were created in. ++ //delete in reverse order of what they were created in. + //see InitTuxkart() + Referee::cleanup(); + if(ReplayPlay::get()) ReplayPlay::destroy(); +@@ -1222,7 +1243,8 @@ + 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; +@@ -1364,6 +1386,15 @@ + + //handleCmdLine() needs InitTuxkart() so it can't be called first + if(!handleCmdLine(argc, argv)) exit(0); ++ ++ // load the network manager ++ // If the server has been created (--server option), this will do nothing (just a warning): ++ NetworkManager::getInstance(); ++ NetworkManager::getInstance()->run(); ++ if (NetworkManager::getInstance()->isServer()) ++ { ++ ProtocolManager::getInstance()->requestStart(new ServerLobbyRoomProtocol()); ++ } + + addons_manager->checkInstalledAddons(); + +@@ -1480,7 +1511,7 @@ + { + // This will setup the race manager etc. + history->Load(); +- network_manager->setupPlayerKartInfo(); ++ race_manager->setupPlayerKartInfo(); + race_manager->startNew(false); + main_loop->run(); + // well, actually run() will never return, since +@@ -1489,20 +1520,6 @@ + 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()) +@@ -1512,7 +1529,7 @@ + // Quickstart (-N) + // =============== + // all defaults are set in InitTuxkart() +- network_manager->setupPlayerKartInfo(); ++ race_manager->setupPlayerKartInfo(); + race_manager->startNew(false); + } + } +@@ -1522,7 +1539,7 @@ + // ========= + race_manager->setMajorMode (RaceManager::MAJOR_MODE_SINGLE); + race_manager->setDifficulty(RaceManager::DIFFICULTY_HARD); +- network_manager->setupPlayerKartInfo(); ++ race_manager->setupPlayerKartInfo(); + race_manager->startNew(false); + } + main_loop->run(); +Index: src/config/user_config.hpp +=================================================================== +--- src/config/user_config.hpp (revision 13389) ++++ src/config/user_config.hpp (revision 13390) +@@ -487,13 +487,15 @@ + // not saved to file + + // ---- Networking +- PARAM_PREFIX StringUserConfigParam m_server_address +- PARAM_DEFAULT( StringUserConfigParam("localhost", "server_adress", +- "Information about last server used") ); + PARAM_PREFIX IntUserConfigParam m_server_port +- PARAM_DEFAULT( IntUserConfigParam(2305, "server_port", +- "Information about last server used") ); +- ++ PARAM_DEFAULT( IntUserConfigParam(7321, "server_port", ++ "Information about the port to listen on.") ); ++ ++ PARAM_PREFIX IntUserConfigParam m_server_max_players ++ PARAM_DEFAULT( IntUserConfigParam(16, "server_max_players", ++ "Maximum number of players on the server.") ); ++ ++ + // ---- Graphic Quality + PARAM_PREFIX GroupUserConfigParam m_graphics_quality + PARAM_DEFAULT( GroupUserConfigParam("GFX", +Index: src/io/xml_node.cpp +=================================================================== +--- src/io/xml_node.cpp (revision 13389) ++++ src/io/xml_node.cpp (revision 13390) +@@ -41,7 +41,7 @@ + m_file_name = filename; + + io::IXMLReader *xml = file_manager->createXMLReader(filename); +- ++ + if (xml == NULL) + { + throw std::runtime_error("Cannot find file "+filename); +@@ -320,6 +320,22 @@ + + + // ---------------------------------------------------------------------------- ++int XMLNode::get(const std::string &attribute, uint16_t *value) const ++{ ++ std::string s; ++ if(!get(attribute, &s)) return 0; ++ ++ if (!StringUtils::parseString(s, value)) ++ { ++ fprintf(stderr, "[XMLNode] WARNING: Expected uint but found '%s' for attribute '%s' of node '%s' in file %s\n", ++ s.c_str(), attribute.c_str(), m_name.c_str(), m_file_name.c_str()); ++ return 0; ++ } ++ ++ return 1; ++} // get(uint32_t) ++ ++// ---------------------------------------------------------------------------- + int XMLNode::get(const std::string &attribute, uint32_t *value) const + { + std::string s; +Index: src/io/xml_node.hpp +=================================================================== +--- src/io/xml_node.hpp (revision 13389) ++++ src/io/xml_node.hpp (revision 13390) +@@ -74,6 +74,7 @@ + int get(const std::string &attribute, std::string *value) const; + int get(const std::string &attribute, core::stringw *value) const; + int get(const std::string &attribute, int32_t *value) const; ++ int get(const std::string &attribute, uint16_t *value) const; + int get(const std::string &attribute, uint32_t *value) const; + int get(const std::string &attribute, int64_t *value) const; + int get(const std::string &attribute, float *value) const; +Index: src/modes/linear_world.cpp +=================================================================== +--- src/modes/linear_world.cpp (revision 13389) ++++ src/modes/linear_world.cpp (revision 13390) +@@ -25,7 +25,6 @@ + #include "karts/abstract_kart.hpp" + #include "karts/controller/controller.hpp" + #include "karts/kart_properties.hpp" +-#include "network/network_manager.hpp" + #include "physics/physics.hpp" + #include "race/history.hpp" + #include "states_screens/race_gui_base.hpp" +@@ -319,13 +318,7 @@ + // Race finished + if(kart_info.m_race_lap >= race_manager->getNumLaps() && raceHasLaps()) + { +- // 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) +- { +- kart->finishedRace(getTime()); +- } ++ kart->finishedRace(getTime()); + } + float time_per_lap; + if (kart_info.m_race_lap == 1) // just completed first lap +Index: src/modes/overworld.cpp +=================================================================== +--- src/modes/overworld.cpp (revision 13389) ++++ src/modes/overworld.cpp (revision 13390) +@@ -27,7 +27,6 @@ + #include "karts/rescue_animation.hpp" + #include "modes/overworld.hpp" + #include "physics/physics.hpp" +-#include "network/network_manager.hpp" + #include "states_screens/dialogs/select_challenge.hpp" + #include "states_screens/kart_selection.hpp" + #include "states_screens/race_gui_overworld.hpp" +@@ -83,7 +82,7 @@ + ->setSinglePlayer( StateManager::get()->getActivePlayer(0) ); + + StateManager::get()->enterGameState(); +- network_manager->setupPlayerKartInfo(); ++ race_manager->setupPlayerKartInfo(); + race_manager->startNew(false); + if(race_manager->haveKartLastPositionOnOverworld()){ + OverWorld *ow = (OverWorld*)World::getWorld(); +Index: src/modes/world.cpp +=================================================================== +--- src/modes/world.cpp (revision 13389) ++++ src/modes/world.cpp (revision 13390) +@@ -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" +@@ -133,7 +131,6 @@ + */ + void World::init() + { +- race_state = new RaceState(); + m_faster_music_active = false; + m_fastest_kart = 0; + m_eliminated_karts = 0; +@@ -189,8 +186,6 @@ + if(ReplayPlay::get()) + ReplayPlay::get()->Load(); + +- network_manager->worldLoaded(); +- + powerup_manager->updateWeightsForRace(num_karts); + } // init + +@@ -375,7 +370,6 @@ + // gui and this must be deleted. + delete m_race_gui; + } +- delete race_state; + + for ( unsigned int i = 0 ; i < m_karts.size() ; i++ ) + delete m_karts[i]; +@@ -768,7 +762,7 @@ + ->setSinglePlayer( StateManager::get()->getActivePlayer(0) ); + + StateManager::get()->enterGameState(); +- network_manager->setupPlayerKartInfo(); ++ race_manager->setupPlayerKartInfo(); + race_manager->startNew(true); + } + else +@@ -821,11 +815,8 @@ + if(ReplayPlay::get()) ReplayPlay::get()->update(dt); + if(history->replayHistory()) dt=history->getNextDelta(); + WorldStatus::update(dt); +- // Clear race state so that new information can be stored +- race_state->clear(); + +- if(network_manager->getMode()!=NetworkManager::NW_CLIENT && +- !history->dontDoPhysics()) ++ if (!history->dontDoPhysics()) + { + m_physics->update(dt); + } +Index: src/modes/world_status.cpp +=================================================================== +--- src/modes/world_status.cpp (revision 13389) ++++ src/modes/world_status.cpp (revision 13390) +@@ -26,7 +26,6 @@ + #include "karts/abstract_kart.hpp" + #include "modes/world.hpp" + #include "tracks/track.hpp" +-#include "network/network_manager.hpp" + + #include + +@@ -112,8 +111,6 @@ + */ + void WorldStatus::terminateRace() + { +- if(network_manager->getMode()==NetworkManager::NW_SERVER) +- network_manager->sendRaceResults(); + } // terminateRace + + //----------------------------------------------------------------------------- +Index: src/modes/demo_world.cpp +=================================================================== +--- src/modes/demo_world.cpp (revision 13389) ++++ src/modes/demo_world.cpp (revision 13390) +@@ -21,7 +21,6 @@ + #include "guiengine/modaldialog.hpp" + #include "input/device_manager.hpp" + #include "input/input_manager.hpp" +-#include "network/network_manager.hpp" + #include "race/race_manager.hpp" + #include "tracks/track.hpp" + #include "tracks/track_manager.hpp" +@@ -149,7 +148,7 @@ + m_do_demo = true; + race_manager->setNumKarts(m_num_karts); + race_manager->setLocalKartInfo(0, "tux"); +- network_manager->setupPlayerKartInfo(); ++ race_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()); +Index: src/addons/network_http.hpp +=================================================================== +--- src/addons/network_http.hpp (revision 13389) ++++ src/addons/network_http.hpp (revision 13390) +@@ -27,7 +27,7 @@ + #include + + #ifdef WIN32 +-# include ++# include + #endif + #include + +Index: src/guiengine/modaldialog.cpp +=================================================================== +--- src/guiengine/modaldialog.cpp (revision 13389) ++++ src/guiengine/modaldialog.cpp (revision 13390) +@@ -187,8 +187,9 @@ + { + if(modalWindow != NULL) delete modalWindow; + modalWindow = NULL; +- if(GUIEngine::getCurrentScreen() != NULL) +- GUIEngine::getCurrentScreen()->onDialogClose(); ++ GUIEngine::Screen* scr = GUIEngine::getCurrentScreen(); ++ if (scr) ++ scr->onDialogClose(); + } + + // ---------------------------------------------------------------------------- +Index: src/race/race_manager.cpp +=================================================================== +--- src/race/race_manager.cpp (revision 13389) ++++ src/race/race_manager.cpp (revision 13390) +@@ -42,7 +42,6 @@ + #include "modes/world.hpp" + #include "modes/three_strikes_battle.hpp" + #include "modes/soccer_world.hpp" +-#include "network/network_manager.hpp" + #include "states_screens/grand_prix_lose.hpp" + #include "states_screens/grand_prix_win.hpp" + #include "states_screens/kart_selection.hpp" +@@ -145,7 +144,7 @@ + + m_local_player_karts[player_id] = RemoteKartInfo(player_id, kart, + StateManager::get()->getActivePlayerProfile(player_id)->getName(), +- network_manager->getMyHostId()); ++ 0); + } // setLocalKartInfo + + //----------------------------------------------------------------------------- +@@ -293,8 +292,8 @@ + // Create the kart status data structure to keep track of scores, times, ... + // ========================================================================== + m_kart_status.clear(); ++ Log::verbose("RaceManager", "Nb of karts=%u, ai:%lu players:%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 +320,7 @@ + // ------------------------------------------------- + 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_kart_status.push_back(KartStatus(m_player_karts[i].getKartName(), i, + m_player_karts[i].getLocalPlayerId(), + m_player_karts[i].getGlobalPlayerId(), +@@ -509,21 +507,10 @@ + } + user_config->saveConfig(); + } +- +- 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); + exitRace(); + } + } // next +@@ -753,7 +740,7 @@ + StateManager::get()->enterGameState(); + setGrandPrix(*gp); + setCoinTarget( 0 ); // Might still be set from a previous challenge +- network_manager->setupPlayerKartInfo(); ++ race_manager->setupPlayerKartInfo(); + + setMajorMode(RaceManager::MAJOR_MODE_GRAND_PRIX); + startNew(from_overworld); +@@ -778,9 +765,36 @@ + setMajorMode(RaceManager::MAJOR_MODE_SINGLE); + + setCoinTarget( 0 ); // Might still be set from a previous challenge +- network_manager->setupPlayerKartInfo(); ++ race_manager->setupPlayerKartInfo(); + + startNew(from_overworld); + } + ++//----------------------------------------------------------------------------- ++/** Receive and store the information from sendKartsInformation() ++*/ ++void RaceManager::setupPlayerKartInfo() ++{ ++ std::vector m_kart_info; ++ ++ // Get the local kart info ++ for(unsigned int i=0; i ++#include + + #include "LinearMath/btQuaternion.h" + +Index: src/race/race_manager.hpp +=================================================================== +--- src/race/race_manager.hpp (revision 13389) ++++ src/race/race_manager.hpp (revision 13390) +@@ -674,6 +674,9 @@ + */ + void startSingleRace(const std::string &track_ident, const int num_laps, + bool from_overworld); ++ /** Receive and store the information from sendKartsInformation() ++ */ ++ void setupPlayerKartInfo(); + + bool raceWasStartedFromOverworld() const + { +Index: doc/protocols.xls +=================================================================== +Cannot display: file marked as a binary type. +svn:mime-type = application/octet-stream +Index: doc/protocols.xls +=================================================================== +--- doc/protocols.xls (revision 13389) ++++ doc/protocols.xls (revision 13390) + +Property changes on: doc/protocols.xls +___________________________________________________________________ +Added: svn:mime-type +## -0,0 +1 ## ++application/octet-stream +\ No newline at end of property +Index: data/gui/online/lobby.stkgui +=================================================================== +--- data/gui/online/lobby.stkgui (revision 13389) ++++ data/gui/online/lobby.stkgui (revision 13390) +@@ -38,8 +38,12 @@ + + + +- ++ ++ ++ + + + +Index: . +=================================================================== +--- . (revision 13389) ++++ . (revision 13390) + +Property changes on: . +___________________________________________________________________ +Modified: svn:mergeinfo + Merged /main/branches/hilnius:r12848-13076 + Merged /main/branches/networking:r13064-13147 diff --git a/doc/protocols.xls b/doc/protocols.xls deleted file mode 100644 index 2b854a9c0bd7f7c5750031d1cb833485645d6a85..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 10240 zcmeHNYiwLc6+U<0jvagLW}VoM(`z?zUQU`Or8SSXP93+2k~o&*7N{zf_4+zlvfkb9 zuH(8A;J&2(pi)RB_(3G7lu95Z9s&Up1=4>YK|x5B3cpfBepDdjA`l8{W4`aqy?b{z z*NqcZphlU|+?jLc%z4e3$BzB`-?d+S z%gY`b&0Fasa*)%B$Ro_qgezti!1D@~>qZwU;i~#M2JN|8sSC z$`7Jn2~Vy;^fxd5JbY@?JU4lM-f8@>)QI1{0)B7>{EijyO@VmMyCr=hJb5)4eWD(I zLp{DqKQtdtM0lJVdLJJ|-+vWldBD8G4DtWys_5 znSjv5dX#@7O5cN!NMUMfVWLo&9WNCsg-jubi|j!sJ?)eradM&P06tc% zWD9xBs%h-C#2T={^LX}Y$KE!zP;tuJK}`_VfpjGep&mcG0w%a2Kbp?XX?G#-K+6N! zl9M4@bWuzh?2kI>d^Udq*JdNgE`uZFxX@{GsDgX77lK@+Z0*LC{IgEEO|0YM;9NSb zUt7-h**K4LIHeX8gWLI-GjA7j=>?|*FJ-6g!i-%x>9{C_?~y_#owKvk&~;qN>;ogv zaUz{@fQ62S)1`_%SDa2)=%dfrpR(_{8^ouG&ZlRosgjhOnYpqv4RC@jFwGRE9ZcFt zA)hxsuw9zl>X7M7#wk{uY1mjSWluwnT`8P$@(^+&SC~@mVCi^`UB=RKjqQzco}6>a zl@$G7&eY0Re5b2&*~wKE(+*6MC;F(9If-d1&%)^APU*B$g0qe~<#PIjQwGjBt6!`$ z@c9Vt$$4Z)GPoya6|ylejyx%I_?ChFrhGzdIRPsQGNtzj88L<7$eHkkdN|&dY$#AbAC)-Ux68QeF!U-x7h4DB(0MJl z)$4t#IzErqtTI2-hgA-D9o|1N>AP^Br@t?94o;fJFgnVXZR!#mZL@|JbnYD4zM>0* zgmc|lW`2A@*XtatPYr^}N5-ERIklyUC9@(KIcIx+8rCld?Kv@|W z8R(zP&N^kAyVpcvHk}_FE0ku_x&DE>_73b%VcND_i)m{^a6JLI zjRCmc2Hg9wp3#Mq42ckDkydz6NY(>~Ne;zOhXEO?2wHs5Gx%r~AHxNhi_=iW!7J)Q zjD-|tK;($Vc^@8Gh--)88LDq;MJ?oh~yQ) zs9u*Ug1F^q@``}h?Whf}NR<~gYSYI@QpLd8)-`CL5PX9hg>s;to%$qg`XYe1N(~eR z#Mm)V3=pHnKyg64cM_sLZGxlPg)Bh)F+s1yVM$-r`Z(mJkiEVL+CG;kC^>ItTnv4* z#7Lmuaf4NeYsQz5Pzk%MeU!i(Gr1(-BcDqG{_2x1my)Z@=hCEH<`GuSxancDXdw zacKgVwi+(fv!}{44hb7wh>_?^U?ld*S6vB=gcN4g=*hYC^<1M8xIc0B>BBzNitF9? zb2GT7s(x+;_mqSln+j3?X61gn%e}dddo#GFboV1A_Y0pVcV?d__ho41@@!F_w#&1n zj%SPVq-W{%7R;MJuPx9&1q-~sL|tDKApCYy`xtA!F5Ht-IQGoAqd02C%P=73Z5Trj@jTchd)%>Ipx%yWM9OJJUlH!N{+`FH0i8tu z5J&S_-%2;H2Q18R7!geilL=lXMK0)99^y8AG@B_E%7vMVJ^EC}$=M&jch_Wk%E5b| zhRK83nHj#m-Eczu8KF1G;R=?d6~KaVees2F{NwVmlgaOVB_TVv{_v07Fn)yMZ6pWL zX3USfxM|dQ7?Gz?xX7PJ;YH;P3NIJuP}ov`s*()%cvZHw2bP&C+o^}>N9i$_VY)6#g+eIRM+eO+W)`!f6M #ifdef WIN32 -# include +# include #endif #include diff --git a/src/config/user_config.hpp b/src/config/user_config.hpp index fb2485c55..548c938be 100644 --- a/src/config/user_config.hpp +++ b/src/config/user_config.hpp @@ -487,15 +487,13 @@ namespace UserConfigParams // not saved to file // ---- Networking + PARAM_PREFIX StringUserConfigParam m_server_address + PARAM_DEFAULT( StringUserConfigParam("localhost", "server_adress", + "Information about last server used") ); PARAM_PREFIX IntUserConfigParam m_server_port - PARAM_DEFAULT( IntUserConfigParam(7321, "server_port", - "Information about the port to listen on.") ); - - PARAM_PREFIX IntUserConfigParam m_server_max_players - PARAM_DEFAULT( IntUserConfigParam(16, "server_max_players", - "Maximum number of players on the server.") ); - - + PARAM_DEFAULT( IntUserConfigParam(2305, "server_port", + "Information about last server used") ); + // ---- Graphic Quality PARAM_PREFIX GroupUserConfigParam m_graphics_quality PARAM_DEFAULT( GroupUserConfigParam("GFX", diff --git a/src/guiengine/modaldialog.cpp b/src/guiengine/modaldialog.cpp index 87a97e7a9..35dc19fbe 100644 --- a/src/guiengine/modaldialog.cpp +++ b/src/guiengine/modaldialog.cpp @@ -187,9 +187,8 @@ void ModalDialog::dismiss() { if(modalWindow != NULL) delete modalWindow; modalWindow = NULL; - GUIEngine::Screen* scr = GUIEngine::getCurrentScreen(); - if (scr) - scr->onDialogClose(); + if(GUIEngine::getCurrentScreen() != NULL) + GUIEngine::getCurrentScreen()->onDialogClose(); } // ---------------------------------------------------------------------------- diff --git a/src/ide/vc9/supertuxkart.vcproj b/src/ide/vc9/supertuxkart.vcproj index 6b7ba31cb..75f6825ce 100644 --- a/src/ide/vc9/supertuxkart.vcproj +++ b/src/ide/vc9/supertuxkart.vcproj @@ -1142,23 +1142,23 @@ Name="network" > - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -1584,10 +1508,6 @@ RelativePath="..\..\states_screens\dialogs\gp_info_dialog.cpp" > - - @@ -1604,10 +1524,6 @@ RelativePath="..\..\states_screens\dialogs\race_paused_dialog.cpp" > - - @@ -1722,22 +1638,6 @@ > - - - - - - - - + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -2854,10 +2710,6 @@ RelativePath="..\..\states_screens\dialogs\gp_info_dialog.hpp" > - - @@ -2874,10 +2726,6 @@ RelativePath="..\..\states_screens\dialogs\race_paused_dialog.hpp" > - - @@ -2980,22 +2828,6 @@ > - - - - - - - - createXMLReader(filename); - + if (xml == NULL) { throw std::runtime_error("Cannot find file "+filename); @@ -319,22 +319,6 @@ int XMLNode::get(const std::string &attribute, int64_t *value) const } // get(int64_t) -// ---------------------------------------------------------------------------- -int XMLNode::get(const std::string &attribute, uint16_t *value) const -{ - std::string s; - if(!get(attribute, &s)) return 0; - - if (!StringUtils::parseString(s, value)) - { - fprintf(stderr, "[XMLNode] WARNING: Expected uint but found '%s' for attribute '%s' of node '%s' in file %s\n", - s.c_str(), attribute.c_str(), m_name.c_str(), m_file_name.c_str()); - return 0; - } - - return 1; -} // get(uint32_t) - // ---------------------------------------------------------------------------- int XMLNode::get(const std::string &attribute, uint32_t *value) const { diff --git a/src/io/xml_node.hpp b/src/io/xml_node.hpp index 37e4ade41..953d52f8a 100644 --- a/src/io/xml_node.hpp +++ b/src/io/xml_node.hpp @@ -74,7 +74,6 @@ public: int get(const std::string &attribute, std::string *value) const; int get(const std::string &attribute, core::stringw *value) const; int get(const std::string &attribute, int32_t *value) const; - int get(const std::string &attribute, uint16_t *value) const; int get(const std::string &attribute, uint32_t *value) const; int get(const std::string &attribute, int64_t *value) const; int get(const std::string &attribute, float *value) const; diff --git a/src/items/attachment.cpp b/src/items/attachment.cpp index 7d7fbb6a0..1bbbdf2cc 100644 --- a/src/items/attachment.cpp +++ b/src/items/attachment.cpp @@ -33,6 +33,8 @@ #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" /** Initialises the attachment each kart has. @@ -256,6 +258,15 @@ void Attachment::hitBanana(Item *item, int new_attachment) new_attachment = m_random.get(3); } // switch + // Save the information about the attachment in the race state + // so that the clients can be updated. + if(network_manager->getMode()==NetworkManager::NW_SERVER) + { + race_state->itemCollected(m_kart->getWorldKartId(), + item->getItemId(), + new_attachment); + } + if (add_a_new_item) { switch (new_attachment) diff --git a/src/items/flyable.cpp b/src/items/flyable.cpp index b1ee43129..d0116415d 100644 --- a/src/items/flyable.cpp +++ b/src/items/flyable.cpp @@ -38,6 +38,7 @@ #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" @@ -409,6 +410,19 @@ bool Flyable::updateAndDelete(float dt) return false; } // updateAndDelete +// ---------------------------------------------------------------------------- +/** Updates the position of a projectile based on information received frmo the + * server. + */ +void Flyable::updateFromServer(const FlyableInfo &f, float dt) +{ + setXYZ(f.m_xyz); + setRotation(f.m_rotation); + + // Update the graphical position + Moveable::update(dt); +} // updateFromServer + // ---------------------------------------------------------------------------- /** Returns true if the item hit the kart who shot it (to avoid that an item * that's too close to the shoter hits the shoter). diff --git a/src/items/flyable.hpp b/src/items/flyable.hpp index 9030209f3..bfd46835f 100644 --- a/src/items/flyable.hpp +++ b/src/items/flyable.hpp @@ -34,6 +34,7 @@ using namespace irr; #include "tracks/terrain_info.hpp" class AbstractKart; +class FlyableInfo; class HitEffect; class PhysicalObject; class XMLNode; @@ -168,6 +169,7 @@ public: virtual bool updateAndDelete(float); virtual const core::stringw getHitString(const AbstractKart *kart) const = 0; virtual HitEffect* getHitEffect() const; + void updateFromServer(const FlyableInfo &f, float dt); bool isOwnerImmunity(const AbstractKart *kart_hit) const; virtual bool hit(AbstractKart* kart, PhysicalObject* obj=NULL); void explode(AbstractKart* kart, PhysicalObject* obj=NULL, diff --git a/src/items/item_manager.cpp b/src/items/item_manager.cpp index a76db40fe..4b7fc0ad1 100644 --- a/src/items/item_manager.cpp +++ b/src/items/item_manager.cpp @@ -29,6 +29,7 @@ #include "io/file_manager.hpp" #include "karts/abstract_kart.hpp" #include "modes/linear_world.hpp" +#include "network/network_manager.hpp" #include "tracks/quad_graph.hpp" #include "tracks/track.hpp" #include "utils/string_utils.hpp" @@ -288,6 +289,9 @@ 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; + // 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 // then we also need to check for any adjacent quads (since an item just diff --git a/src/items/powerup.cpp b/src/items/powerup.cpp index a4264b16a..d6bd8022c 100644 --- a/src/items/powerup.cpp +++ b/src/items/powerup.cpp @@ -29,6 +29,8 @@ #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 18e299560..f7846b684 100644 --- a/src/items/projectile_manager.cpp +++ b/src/items/projectile_manager.cpp @@ -26,6 +26,8 @@ #include "items/powerup_manager.hpp" #include "items/powerup.hpp" #include "items/rubber_ball.hpp" +#include "network/network_manager.hpp" +#include "network/race_state.hpp" ProjectileManager *projectile_manager=0; @@ -64,7 +66,14 @@ void ProjectileManager::cleanup() /** General projectile update call. */ void ProjectileManager::update(float dt) { - updateServer(dt); + if(network_manager->getMode()==NetworkManager::NW_CLIENT) + { + updateClient(dt); + } + else + { + updateServer(dt); + } HitEffects::iterator he = m_active_hit_effects.begin(); while(he!=m_active_hit_effects.end()) @@ -91,10 +100,23 @@ void ProjectileManager::update(float dt) /** Updates all rockets on the server (or no networking). */ void ProjectileManager::updateServer(float dt) { + // First update all projectiles on the track + if(network_manager->getMode()!=NetworkManager::NW_NONE) + { + 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) + { + race_state->setFlyableInfo(p-m_active_projectiles.begin(), + FlyableInfo((*p)->getXYZ(), + (*p)->getRotation(), + can_be_deleted) ); + } if(can_be_deleted) { HitEffect *he = (*p)->getHitEffect(); @@ -108,9 +130,32 @@ void ProjectileManager::updateServer(float dt) else p++; } // while p!=m_active_projectiles.end() - } // updateServer +// ----------------------------------------------------------------------------- +/** Updates all rockets and hit effects on the client. + * updateClient takes the information in race_state and updates all rockets + * (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", + num_projectiles, (int)m_active_projectiles.size()); + + unsigned int indx=0; + for(Projectiles::iterator i = m_active_projectiles.begin(); + i != m_active_projectiles.end(); ++i, ++indx) + { + const FlyableInfo &f = race_state->getFlyable(indx); + (*i)->updateFromServer(f, dt); + if(f.m_exploded) + { + (*i)->hit(NULL); + } + } // for i in m_active_projectiles + +} // updateClient // ----------------------------------------------------------------------------- Flyable *ProjectileManager::newProjectile(AbstractKart *kart, Track* track, PowerupManager::PowerupType type) diff --git a/src/items/projectile_manager.hpp b/src/items/projectile_manager.hpp index 8fb513502..f0906ca6b 100644 --- a/src/items/projectile_manager.hpp +++ b/src/items/projectile_manager.hpp @@ -53,6 +53,7 @@ private: * being shown or have a sfx playing. */ HitEffects m_active_hit_effects; + void updateClient(float dt); void updateServer(float dt); public: ProjectileManager() {} diff --git a/src/items/rubber_ball.cpp b/src/items/rubber_ball.cpp index 592a7f86d..35361ae29 100644 --- a/src/items/rubber_ball.cpp +++ b/src/items/rubber_ball.cpp @@ -419,8 +419,6 @@ void RubberBall::moveTowardsTarget(Vec3 *next_xyz, float dt) // at it directly, stop interpolating, instead fly straight // towards it. Vec3 diff = m_target->getXYZ()-getXYZ(); - if(diff.length()==0) - printf("diff=0\n"); *next_xyz = getXYZ() + (dt*m_speed/diff.length())*diff; Vec3 old_vec = getXYZ()-m_previous_xyz; diff --git a/src/karts/controller/end_controller.cpp b/src/karts/controller/end_controller.cpp index 8b72439c2..ccea9e9eb 100644 --- a/src/karts/controller/end_controller.cpp +++ b/src/karts/controller/end_controller.cpp @@ -43,6 +43,7 @@ #include "karts/max_speed.hpp" #include "karts/rescue_animation.hpp" #include "modes/linear_world.hpp" +#include "network/network_manager.hpp" #include "race/race_manager.hpp" #include "states_screens/race_result_gui.hpp" #include "tracks/quad_graph.hpp" diff --git a/src/karts/controller/kart_control.hpp b/src/karts/controller/kart_control.hpp index ed330d820..78f789e7c 100644 --- a/src/karts/controller/kart_control.hpp +++ b/src/karts/controller/kart_control.hpp @@ -19,8 +19,9 @@ #ifndef HEADER_KART_CONTROL_HPP #define HEADER_KART_CONTROL_HPP +#include "network/message.hpp" -/** +/** * \ingroup controller */ class KartControl @@ -51,6 +52,15 @@ 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() { @@ -64,6 +74,17 @@ 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 b75800b79..ef3158c93 100644 --- a/src/karts/controller/skidding_ai.cpp +++ b/src/karts/controller/skidding_ai.cpp @@ -54,6 +54,7 @@ #include "items/powerup.hpp" #include "modes/linear_world.hpp" #include "modes/profile_world.hpp" +#include "network/network_manager.hpp" #include "race/race_manager.hpp" #include "tracks/quad_graph.hpp" #include "tracks/track.hpp" @@ -296,6 +297,13 @@ void SkiddingAI::update(float dt) return; #endif + // The client does not do any AI computations. + if(network_manager->getMode()==NetworkManager::NW_CLIENT) + { + AIBaseController::update(dt); + return; + } + // If the kart needs to be rescued, do it now (and nothing else) if(isStuck() && !m_kart->getKartAnimation()) { diff --git a/src/karts/kart.cpp b/src/karts/kart.cpp index 62d3f0e69..aa2c9b0dd 100644 --- a/src/karts/kart.cpp +++ b/src/karts/kart.cpp @@ -57,6 +57,8 @@ #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" #include "physics/btUprightConstraint.hpp" @@ -876,6 +878,15 @@ void Kart::collectedItem(Item *item, int add_info) default : break; } // switch TYPE + // 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 && + (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(); m_controller->collectedItem(*item, add_info, old_energy); @@ -1007,6 +1018,14 @@ void Kart::update(float dt) m_slipstream->update(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) + { + race_state->storeKartControls(*this); + } + if (!m_flying) { // When really on air, free fly, when near ground, try to glide / adjust for landing @@ -1865,8 +1884,10 @@ void Kart::updatePhysics(float dt) updateSliding(); - // Compute the speed of the kart. - m_speed = getVehicle()->getRigidBody()->getLinearVelocity().length(); + // 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(); // calculate direction of m_speed const btTransform& chassisTrans = getVehicle()->getChassisWorldTransform(); diff --git a/src/main.cpp b/src/main.cpp index e8973cc76..c1789f6e3 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -169,11 +169,7 @@ #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 "network/protocol_manager.hpp" -#include "network/protocols/lobby_room_protocol.hpp" -#include "online/current_online_user.hpp" +#include "online/http_manager.hpp" #include "race/grand_prix_manager.hpp" #include "race/highscore_manager.hpp" #include "race/history.hpp" @@ -394,7 +390,6 @@ void cmdLineHelp (char* invocation) " --profile-time=n Enable automatic driven profile mode for n " "seconds.\n" " --no-graphics Do not display the actual race.\n" - " --with-profile Enables the profile mode.\n" " --demo-mode t Enables demo mode after t seconds idle time in " "main menu.\n" " --demo-tracks t1,t2 List of tracks to be used in demo mode. No\n" @@ -608,9 +603,6 @@ int handleCmdLine(int argc, char **argv) { int n; char s[1024]; - - bool try_login = false; - irr::core::stringw login, password; for(int i=1; isetMode(NetworkManager::NW_SERVER); UserConfigParams::m_server_port = n; } else if( !strcmp(argv[i], "--server") ) { - NetworkManager::getInstance(); - Log::info("main", "Creating a server network manager."); + network_manager->setMode(NetworkManager::NW_SERVER); } - else if( sscanf(argv[i], "--max-players=%d", &n) ) + else if( sscanf(argv[i], "--port=%d", &n) ) { - UserConfigParams::m_server_max_players=n; + UserConfigParams::m_server_port=n; } - else if( sscanf(argv[i], "--login=%1023s", s) ) + else if( sscanf(argv[i], "--client=%1023s", s) ) { - login = s; - try_login = true; - } - else if( sscanf(argv[i], "--password=%1023s", s) ) - { - password = s; + network_manager->setMode(NetworkManager::NW_CLIENT); + UserConfigParams::m_server_address=s; } else if ( sscanf(argv[i], "--gfx=%d", &n) ) { @@ -993,9 +981,6 @@ int handleCmdLine(int argc, char **argv) race_manager->setNumLaps(999999); // profile end depends on time } else if( !strcmp(argv[i], "--no-graphics") ) - { - } - else if( !strcmp(argv[i], "--with-profile") ) { // Set default profile mode of 1 lap if we haven't already set one if (!ProfileWorld::isProfileMode()) { @@ -1106,12 +1091,6 @@ int handleCmdLine(int argc, char **argv) UserConfigParams::m_sfx = false; // Disable sound effects UserConfigParams::m_music = false;// and music when profiling } - - if (try_login) - { - irr::core::stringw s; - CurrentOnlineUser::get()->signIn(login, password, s); - } return 1; } // handleCmdLine @@ -1194,6 +1173,7 @@ void initRest() powerup_manager = new PowerupManager (); attachment_manager = new AttachmentManager (); highscore_manager = new HighscoreManager (); + network_manager = new NetworkManager (); KartPropertiesManager::addKartSearchDir( file_manager->getAddonsFile("karts/")); track_manager->addTrackSearchDir( @@ -1235,7 +1215,6 @@ void cleanSuperTuxKart() if(Online::HTTPManager::isRunning()) Online::HTTPManager::get()->stopNetworkThread(); //delete in reverse order of what they were created in. - //delete in reverse order of what they were created in. //see InitTuxkart() Referee::cleanup(); if(ReplayPlay::get()) ReplayPlay::destroy(); @@ -1243,8 +1222,7 @@ void cleanSuperTuxKart() INetworkHttp::destroy(); if(news_manager) delete news_manager; if(addons_manager) delete addons_manager; - NetworkManager::kill(); - + if(network_manager) delete network_manager; if(grand_prix_manager) delete grand_prix_manager; if(highscore_manager) delete highscore_manager; if(attachment_manager) delete attachment_manager; @@ -1386,15 +1364,6 @@ int main(int argc, char *argv[] ) //handleCmdLine() needs InitTuxkart() so it can't be called first if(!handleCmdLine(argc, argv)) exit(0); - - // load the network manager - // If the server has been created (--server option), this will do nothing (just a warning): - NetworkManager::getInstance(); - NetworkManager::getInstance()->run(); - if (NetworkManager::getInstance()->isServer()) - { - ProtocolManager::getInstance()->requestStart(new ServerLobbyRoomProtocol()); - } addons_manager->checkInstalledAddons(); @@ -1511,7 +1480,7 @@ int main(int argc, char *argv[] ) { // This will setup the race manager etc. history->Load(); - race_manager->setupPlayerKartInfo(); + network_manager->setupPlayerKartInfo(); race_manager->startNew(false); main_loop->run(); // well, actually run() will never return, since @@ -1520,6 +1489,20 @@ 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()) @@ -1529,7 +1512,7 @@ int main(int argc, char *argv[] ) // Quickstart (-N) // =============== // all defaults are set in InitTuxkart() - race_manager->setupPlayerKartInfo(); + network_manager->setupPlayerKartInfo(); race_manager->startNew(false); } } @@ -1539,7 +1522,7 @@ int main(int argc, char *argv[] ) // ========= race_manager->setMajorMode (RaceManager::MAJOR_MODE_SINGLE); race_manager->setDifficulty(RaceManager::DIFFICULTY_HARD); - race_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 54ea7ca9a..8524dbed0 100644 --- a/src/main_loop.cpp +++ b/src/main_loop.cpp @@ -29,6 +29,7 @@ #include "input/wiimote_manager.hpp" #include "modes/profile_world.hpp" #include "modes/world.hpp" +#include "network/network_manager.hpp" #include "race/race_manager.hpp" #include "states_screens/state_manager.hpp" #include "utils/profiler.hpp" @@ -93,8 +94,21 @@ float MainLoop::getLimitedDt() */ void MainLoop::updateRace(float dt) { + // Server: Send the current position and previous controls to all clients + // 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(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(); + World::getWorld()->updateWorld(dt); } // updateRace @@ -113,8 +127,13 @@ void MainLoop::run() m_prev_time = m_curr_time; float dt = getLimitedDt(); + 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; updateRace(dt); } // if race is active diff --git a/src/modes/demo_world.cpp b/src/modes/demo_world.cpp index db0616866..681382e7e 100644 --- a/src/modes/demo_world.cpp +++ b/src/modes/demo_world.cpp @@ -21,6 +21,7 @@ #include "guiengine/modaldialog.hpp" #include "input/device_manager.hpp" #include "input/input_manager.hpp" +#include "network/network_manager.hpp" #include "race/race_manager.hpp" #include "tracks/track.hpp" #include "tracks/track_manager.hpp" @@ -148,7 +149,7 @@ bool DemoWorld::updateIdleTimeAndStartDemo(float dt) m_do_demo = true; race_manager->setNumKarts(m_num_karts); race_manager->setLocalKartInfo(0, "tux"); - race_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 81cadfa95..c519703c1 100644 --- a/src/modes/linear_world.cpp +++ b/src/modes/linear_world.cpp @@ -25,6 +25,7 @@ #include "karts/abstract_kart.hpp" #include "karts/controller/controller.hpp" #include "karts/kart_properties.hpp" +#include "network/network_manager.hpp" #include "physics/physics.hpp" #include "race/history.hpp" #include "states_screens/race_gui_base.hpp" @@ -318,7 +319,13 @@ void LinearWorld::newLap(unsigned int kart_index) // Race finished if(kart_info.m_race_lap >= race_manager->getNumLaps() && raceHasLaps()) { - kart->finishedRace(getTime()); + // 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) + { + 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 76ef4e3cf..65cdf8f10 100644 --- a/src/modes/overworld.cpp +++ b/src/modes/overworld.cpp @@ -27,6 +27,7 @@ #include "karts/rescue_animation.hpp" #include "modes/overworld.hpp" #include "physics/physics.hpp" +#include "network/network_manager.hpp" #include "states_screens/dialogs/select_challenge.hpp" #include "states_screens/kart_selection.hpp" #include "states_screens/race_gui_overworld.hpp" @@ -82,7 +83,7 @@ void OverWorld::enterOverWorld() ->setSinglePlayer( StateManager::get()->getActivePlayer(0) ); StateManager::get()->enterGameState(); - race_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 f30255a65..92e76e05f 100644 --- a/src/modes/world.cpp +++ b/src/modes/world.cpp @@ -42,6 +42,8 @@ #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" @@ -131,6 +133,7 @@ World::World() : WorldStatus(), m_clear_color(255,100,101,140) */ void World::init() { + race_state = new RaceState(); m_faster_music_active = false; m_fastest_kart = 0; m_eliminated_karts = 0; @@ -186,6 +189,8 @@ void World::init() if(ReplayPlay::get()) ReplayPlay::get()->Load(); + network_manager->worldLoaded(); + powerup_manager->updateWeightsForRace(num_karts); } // init @@ -370,6 +375,7 @@ World::~World() // gui and this must be deleted. delete m_race_gui; } + delete race_state; for ( unsigned int i = 0 ; i < m_karts.size() ; i++ ) delete m_karts[i]; @@ -762,7 +768,7 @@ void World::updateWorld(float dt) ->setSinglePlayer( StateManager::get()->getActivePlayer(0) ); StateManager::get()->enterGameState(); - race_manager->setupPlayerKartInfo(); + network_manager->setupPlayerKartInfo(); race_manager->startNew(true); } else @@ -815,8 +821,11 @@ void World::update(float dt) if(ReplayPlay::get()) ReplayPlay::get()->update(dt); if(history->replayHistory()) dt=history->getNextDelta(); WorldStatus::update(dt); + // Clear race state so that new information can be stored + race_state->clear(); - if (!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 294009f1e..522d0e01e 100644 --- a/src/modes/world_status.cpp +++ b/src/modes/world_status.cpp @@ -26,6 +26,7 @@ #include "karts/abstract_kart.hpp" #include "modes/world.hpp" #include "tracks/track.hpp" +#include "network/network_manager.hpp" #include @@ -111,6 +112,8 @@ void WorldStatus::enterRaceOverState() */ void WorldStatus::terminateRace() { + 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 new file mode 100644 index 000000000..527794928 --- /dev/null +++ b/src/network/character_confirm_message.hpp @@ -0,0 +1,71 @@ +// +// 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 new file mode 100644 index 000000000..443a2d670 --- /dev/null +++ b/src/network/character_info_message.hpp @@ -0,0 +1,50 @@ +// +// 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 new file mode 100644 index 000000000..9e8a61961 --- /dev/null +++ b/src/network/character_selected_message.hpp @@ -0,0 +1,105 @@ +// +// 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 deleted file mode 100644 index 5ab2787b9..000000000 --- a/src/network/client_network_manager.cpp +++ /dev/null @@ -1,94 +0,0 @@ -// -// 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" - -#include -#include -#include - -void* waitInput(void* data) -{ - std::string str = ""; - bool stop = false; - while(!stop) - { - getline(std::cin, str); - if (str == "connect=") - { - int id = 0; - std::cin >> id; - ProtocolManager::getInstance()->requestStart(new ConnectToServer(id)); - } - if (str == "quit") - { - stop = true; - } - } - - exit(0); - - return NULL; -} - -ClientNetworkManager::ClientNetworkManager() -{ - m_thread_keyboard = NULL; -} - -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(); - - // listen keyboard console input - m_thread_keyboard = (pthread_t*)(malloc(sizeof(pthread_t))); - pthread_create(m_thread_keyboard, NULL, waitInput, NULL); - - NetworkManager::run(); -} - -void ClientNetworkManager::sendPacket(const NetworkString& 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 deleted file mode 100644 index 6a71d44a5..000000000 --- a/src/network/client_network_manager.hpp +++ /dev/null @@ -1,46 +0,0 @@ -// -// 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(); - virtual void sendPacket(const NetworkString& data); - - STKPeer* getPeer(); - virtual bool isServer() { return false; } - - protected: - ClientNetworkManager(); - virtual ~ClientNetworkManager(); - - pthread_t* m_thread_keyboard; -}; - -#endif // CLIENT_NETWORK_MANAGER_HPP diff --git a/src/network/connect_message.cpp b/src/network/connect_message.cpp new file mode 100644 index 000000000..03660c158 --- /dev/null +++ b/src/network/connect_message.cpp @@ -0,0 +1,77 @@ +// +// 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/protocols/show_public_address.hpp b/src/network/connect_message.hpp similarity index 59% rename from src/network/protocols/show_public_address.hpp rename to src/network/connect_message.hpp index 8406c1428..1875b5718 100644 --- a/src/network/protocols/show_public_address.hpp +++ b/src/network/connect_message.hpp @@ -1,6 +1,6 @@ // // SuperTuxKart - a fun racing game with go-kart -// Copyright (C) 2013 SuperTuxKart-Team +// 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 @@ -16,30 +16,22 @@ // 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 +#ifndef HEADER_CONNECT_MESSAGE_HPP +#define HEADER_CONNECT_MESSAGE_HPP -#include "network/protocol.hpp" #include -class ShowPublicAddress : public Protocol -{ - public: - ShowPublicAddress(); - virtual ~ShowPublicAddress(); - - virtual void notifyEvent(Event* event); - virtual void setup(); - virtual void update(); - - protected: - - enum STATE - { - NONE, - DONE - }; - STATE m_state; -}; +#include "network/message.hpp" -#endif // HIDE_PUBLIC_ADDRESS_HPP +class ConnectMessage : public Message +{ +private: + std::string m_id; + void setId(); +public: + ConnectMessage(); + ConnectMessage(ENetPacket* pkt); + const std::string& + getId() { return m_id; } +}; // ConnectMessage +#endif diff --git a/src/network/event.cpp b/src/network/event.cpp deleted file mode 100644 index c4a400e02..000000000 --- a/src/network/event.cpp +++ /dev/null @@ -1,81 +0,0 @@ -// -// 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" - -#include "utils/log.hpp" - -#include - -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), event->packet->dataLength-1); - } - else if (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.removeFront(size); -} - diff --git a/src/network/event.hpp b/src/network/event.hpp deleted file mode 100644 index b9eaa5ed9..000000000 --- a/src/network/event.hpp +++ /dev/null @@ -1,72 +0,0 @@ -// -// 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 "network/network_string.hpp" -#include "utils/types.hpp" - -/*! - * \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. - NetworkString data; //!< Copy of the data passed by the event. - STKPeer* peer; //!< Pointer to the peer that triggered that event. - - private: - ENetPacket* m_packet; //!< A pointer on the ENetPacket to be deleted. -}; - -#endif // EVENT_HPP diff --git a/src/network/flyable_info.hpp b/src/network/flyable_info.hpp new file mode 100644 index 000000000..eedc33585 --- /dev/null +++ b/src/network/flyable_info.hpp @@ -0,0 +1,70 @@ +// +// 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/game_setup.cpp b/src/network/game_setup.cpp deleted file mode 100644 index 9147071f1..000000000 --- a/src/network/game_setup.cpp +++ /dev/null @@ -1,100 +0,0 @@ -// -// 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/game_setup.hpp" - -#include "utils/log.hpp" - -//----------------------------------------------------------------------------- - -GameSetup::GameSetup() -{ -} - -//----------------------------------------------------------------------------- - -GameSetup::~GameSetup() -{ -} - -//----------------------------------------------------------------------------- - -void GameSetup::addPlayer(NetworkPlayerProfile profile) -{ - m_players.push_back(profile); -} - -//----------------------------------------------------------------------------- - -void GameSetup::removePlayer(uint32_t id) -{ - for (unsigned int i = 0; i < m_players.size(); i++) - { - if (m_players[i].user_profile->getUserID() == id) - { - m_players.erase(m_players.begin()+i, m_players.begin()+i+1); - Log::verbose("GameSetup", "Removed a player from the game setup."); - return; - } - } -} - -//----------------------------------------------------------------------------- - -void GameSetup::removePlayer(uint8_t id) -{ - for (unsigned int i = 0; i < m_players.size(); i++) - { - if (m_players[i].race_id == id) // check the given id - { - m_players.erase(m_players.begin()+i, m_players.begin()+i+1); - Log::verbose("GameSetup", "Removed a player from the game setup."); - return; - } - } -} - -//----------------------------------------------------------------------------- - -const NetworkPlayerProfile* GameSetup::getProfile(uint32_t id) -{ - for (unsigned int i = 0; i < m_players.size(); i++) - { - if (m_players[i].user_profile->getUserID() == id) - { - return &m_players[i]; - } - } - return NULL; -} - -//----------------------------------------------------------------------------- - -const NetworkPlayerProfile* GameSetup::getProfile(uint8_t id) -{ - for (unsigned int i = 0; i < m_players.size(); i++) - { - if (m_players[i].race_id == id) - { - return &m_players[i]; - } - } - return NULL; -} - -//----------------------------------------------------------------------------- diff --git a/src/network/game_setup.hpp b/src/network/game_setup.hpp deleted file mode 100644 index dc07dcc05..000000000 --- a/src/network/game_setup.hpp +++ /dev/null @@ -1,67 +0,0 @@ -// -// 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 game_setup.hpp - */ - -#ifndef GAME_SETUP_HPP -#define GAME_SETUP_HPP - -#include "online/online_user.hpp" - -#include -#include - -/*! \class PlayerProfile - * \brief Contains the profile of a player. - */ -class NetworkPlayerProfile -{ - public: - NetworkPlayerProfile() { race_id = 0; user_profile = NULL; } - ~NetworkPlayerProfile() {} - - uint8_t race_id; //!< The id of the player for the race - std::string kart_name; //!< The selected kart. - OnlineUser* user_profile; //!< Pointer to the lobby profile -}; - -/*! \class GameSetup - * \brief Used to store the needed data about the players that join a game. - * This class stores all the possible information about players in a lobby. - */ -class GameSetup -{ - public: - GameSetup(); - virtual ~GameSetup(); - - void addPlayer(NetworkPlayerProfile profile); //!< Add a player. - void removePlayer(uint32_t id); //!< Remove a player by id. - void removePlayer(uint8_t id); //!< Remove a player by local id. - - int getPlayerCount() { return m_players.size(); } - const NetworkPlayerProfile* getProfile(uint32_t id); //!< Get a profile by database id - const NetworkPlayerProfile* getProfile(uint8_t id); //!< Get the profile by the lobby id - - protected: - std::vector m_players; //!< Information about players - NetworkPlayerProfile m_self_profile; //!< Information about self (client only) -}; - -#endif // GAME_SETUP_HPP diff --git a/src/network/http_functions.cpp b/src/network/http_functions.cpp deleted file mode 100644 index 8ff861a05..000000000 --- a/src/network/http_functions.cpp +++ /dev/null @@ -1,67 +0,0 @@ -// -// 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/item_info.hpp b/src/network/item_info.hpp new file mode 100644 index 000000000..0334e2ee0 --- /dev/null +++ b/src/network/item_info.hpp @@ -0,0 +1,66 @@ +// +// 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 new file mode 100644 index 000000000..db6cea020 --- /dev/null +++ b/src/network/kart_control_message.cpp @@ -0,0 +1,61 @@ +// +// 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/network_interface.cpp b/src/network/kart_control_message.hpp similarity index 68% rename from src/network/network_interface.cpp rename to src/network/kart_control_message.hpp index 262083330..6127f62b9 100644 --- a/src/network/network_interface.cpp +++ b/src/network/kart_control_message.hpp @@ -1,6 +1,6 @@ // // SuperTuxKart - a fun racing game with go-kart -// Copyright (C) 2013 SuperTuxKart-Team +// 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 @@ -16,13 +16,16 @@ // 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_interface.hpp" +#ifndef HEADER_KART_CONTROL_MESSAGE_HPP +#define HEADER_KART_CONTROL_MESSAGE_HPP +#include "network/message.hpp" -NetworkInterface::NetworkInterface() +class KartControlMessage : public Message { -} - -NetworkInterface::~NetworkInterface() -{ -} +public: + KartControlMessage(); + KartControlMessage(ENetPacket* pkt, int kart_id_offset, + int num_local_players); +}; // KartUpdateMessage +#endif diff --git a/src/network/kart_update_message.cpp b/src/network/kart_update_message.cpp new file mode 100644 index 000000000..2b16cc0e9 --- /dev/null +++ b/src/network/kart_update_message.cpp @@ -0,0 +1,62 @@ +// +// 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/http_functions.hpp b/src/network/kart_update_message.hpp similarity index 72% rename from src/network/http_functions.hpp rename to src/network/kart_update_message.hpp index 970b9c1dd..7d3a38fc4 100644 --- a/src/network/http_functions.hpp +++ b/src/network/kart_update_message.hpp @@ -1,6 +1,6 @@ // // SuperTuxKart - a fun racing game with go-kart -// Copyright (C) 2013 SuperTuxKart-Team +// 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 @@ -16,20 +16,15 @@ // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -#ifndef HTTP_FUNCTIONS_HPP -#define HTTP_FUNCTIONS_HPP +#ifndef HEADER_KART_UPDATE_MESSAGE_HPP +#define HEADER_KART_UPDATE_MESSAGE_HPP -#include +#include "network/message.hpp" -namespace HTTP +class KartUpdateMessage : public Message { - -void init(); -void shutdown(); - -std::string getPage(std::string url); - - -} - -#endif // HTTP_FUNCTIONS_HPP +public: + KartUpdateMessage(); + KartUpdateMessage(ENetPacket* pkt); +}; // KartUpdateMessage +#endif diff --git a/src/network/message.cpp b/src/network/message.cpp new file mode 100644 index 000000000..b1f754c02 --- /dev/null +++ b/src/network/message.cpp @@ -0,0 +1,225 @@ +// +// 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/network_kart.cpp b/src/network/network_kart.cpp new file mode 100644 index 000000000..42cf8a3cc --- /dev/null +++ b/src/network/network_kart.cpp @@ -0,0 +1,43 @@ +// +// 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_interface.hpp b/src/network/network_kart.hpp similarity index 56% rename from src/network/network_interface.hpp rename to src/network/network_kart.hpp index 65e5a4f4b..892439a24 100644 --- a/src/network/network_interface.hpp +++ b/src/network/network_kart.hpp @@ -1,6 +1,6 @@ // // SuperTuxKart - a fun racing game with go-kart -// Copyright (C) 2013 SuperTuxKart-Team +// 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 @@ -16,29 +16,22 @@ // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -#ifndef NETWORK_INTERFACE_H -#define NETWORK_INTERFACE_H +#ifndef HEADER_NETWORK_KART_HPP +#define HEADER_NETWORK_KART_HPP -#include "network/singleton.hpp" -#include "network/types.hpp" -#include "network/network_manager.hpp" +#include "karts/kart.hpp" -#include -#include +class Track; - -class NetworkInterface : public Singleton +class NetworkKart : public Kart { - friend class Singleton; - public: - - void initNetwork(bool server); - - protected: - // protected functions - NetworkInterface(); - virtual ~NetworkInterface(); - -}; - -#endif // NETWORK_INTERFACE_H +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 diff --git a/src/network/network_manager.cpp b/src/network/network_manager.cpp index 463e2b1cf..2554e070d 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) 2013 SuperTuxKart-Team +// 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 @@ -18,170 +18,723 @@ #include "network/network_manager.hpp" -#include "network/protocols/hide_public_address.hpp" -#include "network/protocols/show_public_address.hpp" -#include "network/protocols/get_public_address.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/protocol_manager.hpp" -#include "network/client_network_manager.hpp" -#include "network/server_network_manager.hpp" - -#include "utils/log.hpp" - -#include -#include - -//----------------------------------------------------------------------------- +NetworkManager* network_manager = 0; NetworkManager::NetworkManager() { - m_public_address.ip = 0; - m_public_address.port = 0; - m_localhost = NULL; - m_game_setup = NULL; -} + m_mode = NW_NONE; + m_state = NS_ACCEPT_CONNECTIONS; + m_host = NULL; -//----------------------------------------------------------------------------- + m_num_clients = 0; + m_host_id = 0; -NetworkManager::~NetworkManager() + if (enet_initialize () != 0) + { + fprintf (stderr, "An error occurred while initializing ENet.\n"); + exit(-1); + } +} // NetworkManager + +// ----------------------------------------------------------------------------- +bool NetworkManager::initialiseConnections() { - ProtocolManager::kill(); - - if (m_localhost) - delete m_localhost; - while(!m_peers.empty()) + 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) { - delete m_peers.back(); - m_peers.pop_back(); + 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; } -} -//----------------------------------------------------------------------------- + m_server = NULL; + m_clients.push_back(NULL); // server has host_id=0, so put a dummy entry at 0 in client array -void NetworkManager::run() -{ - // create the protocol manager - ProtocolManager::getInstance(); -} + m_client_names.push_back("server"); + return true; +} // initServer -//----------------------------------------------------------------------------- - -bool NetworkManager::connect(TransportAddress peer) +// ----------------------------------------------------------------------------- +/** Initialises the client. This function tries to connect to the server. + */ +bool NetworkManager::initClient() { - if (peerExists(peer)) - return isConnectedTo(peer); - - return STKPeer::connectToHost(m_localhost, peer, 2, 0); -} + 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 */ ); -//----------------------------------------------------------------------------- - -void NetworkManager::setManualSocketsMode(bool manual) -{ - if (manual) - m_localhost->stopListening(); - else - m_localhost->startListening(); -} - -//----------------------------------------------------------------------------- - -void NetworkManager::notifyEvent(Event* event) -{ - Log::info("NetworkManager", "EVENT received"); - switch (event->type) + if (m_host == NULL) { - case EVENT_TYPE_MESSAGE: - Log::info("NetworkManager", "Message, Sender : %u, message = \"%s\"", event->peer->getAddress(), event->data.c_str()); - break; - case EVENT_TYPE_DISCONNECTED: + 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() +{ + m_mode = NW_CLIENT; + m_state = NS_WAIT_FOR_AVAILABLE_CHARACTERS; +} // becomeClient + +// ---------------------------------------------------------------------------- +/** Switches the network manager to server mode. This function sets the state + * to accepting connections. + */ +void NetworkManager::becomeServer() +{ + 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: { - Log::info("NetworkManager", "Somebody is now disconnected. There are now %lu peers.", m_peers.size()); - Log::info("NetworkManager", "Disconnected host: %i.%i.%i.%i:%i", event->peer->getAddress()>>24&0xff, event->peer->getAddress()>>16&0xff, event->peer->getAddress()>>8&0xff, event->peer->getAddress()&0xff,event->peer->getPort()); - // remove the peer: - bool removed = false; - for (unsigned int i = 0; i < m_peers.size(); i++) + 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 { - if (m_peers[i] == event->peer && !removed) // remove only one - { - delete m_peers[i]; - m_peers.erase(m_peers.begin()+i, m_peers.begin()+i+1); - Log::info("NetworkManager", "The peer has been removed from the Network Manager."); - removed = true; - } - else if (m_peers[i] == event->peer) - { - Log::fatal("NetworkManager", "Multiple peers match the disconnected one."); - } + 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; } - if (!removed) - Log::fatal("NetworkManager", "The peer that has been disconnected was not registered by the Network Manager."); break; } - case EVENT_TYPE_CONNECTED: - Log::info("NetworkManager", "A client has just connected. There are now %lu peers.", m_peers.size() + 1); - // create the new peer: - m_peers.push_back(event->peer); + 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; - } - ProtocolManager::getInstance()->notifyEvent(event); -} + } + 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::sendPacket(STKPeer* peer, const NetworkString& data) -{ - if (peer) - peer->sendPacket(data); -} - -//----------------------------------------------------------------------------- - -void NetworkManager::sendPacketExcept(STKPeer* peer, const NetworkString& data) -{ - for (unsigned int i = 0; i < m_peers.size(); i++) +// ---------------------------------------------------------------------------- +void NetworkManager::handleMessageAtClient(ENetEvent *event) +{ // handle message at client (from server) + switch(m_state) { - if (m_peers[i] != peer) - m_peers[i]->sendPacket(data); + 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 -//----------------------------------------------------------------------------- - -GameSetup* NetworkManager::setupNewGame() +// ---------------------------------------------------------------------------- +void NetworkManager::broadcastToClients(Message &m) { - if (m_game_setup) - delete m_game_setup; - m_game_setup = new GameSetup(); - return m_game_setup; -} + enet_host_broadcast(m_host, 0, m.getPacket()); + enet_host_flush(m_host); +} // broadcastToClients -//----------------------------------------------------------------------------- - - -void NetworkManager::setLogin(std::string username, std::string password) +// ---------------------------------------------------------------------------- +void NetworkManager::sendToServer(Message &m) { - m_player_login.username = username; - m_player_login.password = password; -} + enet_peer_send(m_server, 0, m.getPacket()); + enet_host_flush(m_host); +} // sendToServer -//----------------------------------------------------------------------------- - -void NetworkManager::setPublicAddress(TransportAddress addr) +// ---------------------------------------------------------------------------- +/** Cleans up character related data structures. Must be called before any + * character related data is set. + */ +void NetworkManager::initCharacterDataStructures() { - m_public_address = addr; -} + // 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; + } -bool NetworkManager::peerExists(TransportAddress peer) +} // 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) { - return m_localhost->peerExists(peer); -} + 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 -//----------------------------------------------------------------------------- - -bool NetworkManager::isConnectedTo(TransportAddress peer) +// ---------------------------------------------------------------------------- +void NetworkManager::waitForRaceInformation() { - return m_localhost->isConnectedTo(peer); -} + 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 i #include -class NetworkManager : public Singleton +#include "enet/enet.h" + +#include "network/remote_kart_info.hpp" + + +class Message; + +class NetworkManager { - friend class Singleton; - public: - virtual void run(); - - // network management functions - virtual bool connect(TransportAddress peer); - virtual void setManualSocketsMode(bool manual); - - // message/packets related functions - virtual void notifyEvent(Event* event); - virtual void sendPacket(const NetworkString& data) = 0; - virtual void sendPacket(STKPeer* peer, const NetworkString& data); - virtual void sendPacketExcept(STKPeer* peer, const NetworkString& data); +public: + // The mode the network manager is operating in + enum NetworkMode {NW_SERVER, NW_CLIENT, NW_NONE}; - // Game related functions - virtual GameSetup* setupNewGame(); //!< Creates a new game setup and returns it + // 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: - // 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; } - TransportAddress getPublicAddress() { return m_public_address; } - GameSetup* getGameSetup() { return m_game_setup; } - - protected: - NetworkManager(); - virtual ~NetworkManager(); - - // protected members - std::vector m_peers; - STKHost* m_localhost; - bool m_playing_online; - GameSetup* m_game_setup; - - TransportAddress m_public_address; - PlayerLogin m_player_login; + 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); }; -#endif // NETWORKMANAGER_HPP +extern NetworkManager *network_manager; + +#endif diff --git a/src/network/network_string.cpp b/src/network/network_string.cpp deleted file mode 100644 index 251c98fb5..000000000 --- a/src/network/network_string.cpp +++ /dev/null @@ -1,8 +0,0 @@ -#include "network/network_string.hpp" - -NetworkString operator+(NetworkString const& a, NetworkString const& b) -{ - NetworkString ns(a); - ns += b; - return ns; -} diff --git a/src/network/network_string.hpp b/src/network/network_string.hpp deleted file mode 100644 index ae3aa6b5f..000000000 --- a/src/network/network_string.hpp +++ /dev/null @@ -1,211 +0,0 @@ -#ifndef NETWORK_STRING_HPP -#define NETWORK_STRING_HPP - -#include "utils/types.hpp" - -#include -#include -#include - -typedef unsigned char uchar; - -class NetworkString -{ - union { - float f; - uint8_t i[4]; - } f_as_i; // float as integer - union { - double d; - uint8_t i[8]; - } d_as_i; // double as integer - public: - NetworkString() { } - NetworkString(const uint8_t& value) { m_string = (char)(value); } - NetworkString(NetworkString const& copy) { m_string = copy.m_string; } - NetworkString(std::string str) { m_string = str; } - - NetworkString& removeFront(int size) - { - m_string.erase(0, size); - return *this; - } - NetworkString& remove(int pos, int size) - { - m_string.erase(pos, size); - return *this; - } - - uint8_t operator[](const int& pos) - { - return getUInt8(pos); - } - - NetworkString& addUInt8(const uint8_t& value) - { - m_string += (char)(value); - return *this; - } - inline NetworkString& ai8(const uint8_t& value) { return addUInt8(value); } - NetworkString& addUInt16(const uint16_t& value) - { - m_string += (char)((value<<8)&0xff); - m_string += (char)(value&0xff); - return *this; - } - inline NetworkString& ai16(const uint16_t& value) { return addUInt16(value); } - NetworkString& addUInt32(const uint32_t& value) - { - m_string += (char)((value<<24)&0xff); - m_string += (char)((value<<16)&0xff); - m_string += (char)((value<<8)&0xff); - m_string += (char)(value&0xff); - return *this; - } - inline NetworkString& ai32(const uint32_t& value) { return addUInt32(value); } - NetworkString& addInt(const int& value) - { - m_string += (char)((value<<24)&0xff); - m_string += (char)((value<<16)&0xff); - m_string += (char)((value<<8)&0xff); - m_string += (char)(value&0xff); - return *this; - } - inline NetworkString& ai(const int& value) { return addInt(value); } - NetworkString& addFloat(const float& value) //!< BEWARE OF PRECISION - { - assert(sizeof(float)==4); - f_as_i.f = value; - m_string += (char)(f_as_i.i[0]); - m_string += (char)(f_as_i.i[1]); - m_string += (char)(f_as_i.i[2]); - m_string += (char)(f_as_i.i[3]); - return *this; - } - inline NetworkString& af(const float& value) { return addFloat(value); } - NetworkString& addDouble(const double& value) //!< BEWARE OF PRECISION - { - assert(sizeof(double)==8); - d_as_i.d = value; - m_string += (char)(d_as_i.i[0]); - m_string += (char)(d_as_i.i[1]); - m_string += (char)(d_as_i.i[2]); - m_string += (char)(d_as_i.i[3]); - m_string += (char)(d_as_i.i[4]); - m_string += (char)(d_as_i.i[5]); - m_string += (char)(d_as_i.i[6]); - m_string += (char)(d_as_i.i[7]); - return *this; - } - inline NetworkString& ad(const double& value) { return addDouble(value); } - NetworkString& operator+=(NetworkString const& value) - { - m_string += value.m_string; - return *this; - } - - const char* c_str() const - { - return m_string.c_str(); - } - int size() const - { - return m_string.size(); - } - - template - T get(int pos) - { - int a = n; - T result = 0; - while(a--) - { - result <<= 8; // offset one byte - result += ((uint8_t)(m_string[pos+n-1-a]) & 0xff); // add the data - } - return result; - } - - inline int getInt(int pos = 0) { return get(pos); } - inline uint32_t getUInt(int pos = 0) { return get(pos); } - inline uint32_t getUInt32(int pos = 0) { return get(pos); } - inline uint16_t getUInt16(int pos = 0) { return get(pos); } - inline uint8_t getUInt8(int pos = 0) { return get(pos); } - inline char getChar(int pos = 0) { return get(pos); } - inline unsigned char getUChar(int pos = 0) { return get(pos); } - - inline int gi(int pos = 0) { return get(pos); } - inline uint32_t gui(int pos = 0) { return get(pos); } - inline uint32_t gui32(int pos = 0) { return get(pos); } - inline uint16_t gui16(int pos = 0) { return get(pos); } - inline uint8_t gui8(int pos = 0) { return get(pos); } - inline char gc(int pos = 0) { return get(pos); } - inline unsigned char guc(int pos = 0) { return get(pos); } - - double getDouble(int pos = 0) //!< BEWARE OF PRECISION - { - for (int i = 0; i < 8; i++) - d_as_i.i[i] = m_string[pos+i]; - return d_as_i.d; - } - float getFloat(int pos = 0) //!< BEWARE OF PRECISION - { - for (int i = 0; i < 4; i++) - f_as_i.i[i] = m_string[pos+i]; - return f_as_i.f; - } - - //! Functions to get while removing - template - T getAndRemove(int pos) - { - int a = n; - T result = 0; - while(a--) - { - result <<= 8; // offset one byte - result += ((uint8_t)(m_string[pos+n-1-a]) & 0xff); // add the data - } - remove(pos,n); - return result; - } - - inline int getAndRemoveInt(int pos = 0) { return getAndRemove(pos); } - inline uint32_t getAndRemoveUInt(int pos = 0) { return getAndRemove(pos); } - inline uint32_t getAndRemoveUInt32(int pos = 0) { return getAndRemove(pos); } - inline uint16_t getAndRemoveUInt16(int pos = 0) { return getAndRemove(pos); } - inline uint8_t getAndRemoveUInt8(int pos = 0) { return getAndRemove(pos); } - inline char getAndRemoveChar(int pos = 0) { return getAndRemove(pos); } - inline unsigned char getAndRemoveUChar(int pos = 0) { return getAndRemove(pos); } - double getAndRemoveDouble(int pos = 0) //!< BEWARE OF PRECISION - { - for (int i = 0; i < 8; i++) - d_as_i.i[i] = m_string[pos+i]; - return d_as_i.d; - remove(pos, 8); - } - float getAndRemoveFloat(int pos = 0) //!< BEWARE OF PRECISION - { - for (int i = 0; i < 4; i++) - f_as_i.i[i] = m_string[pos+i]; - return f_as_i.f; - remove(pos, 4); - } - - inline NetworkString& gui8(uint8_t* dst) { *dst = getAndRemoveUInt8(0); return *this; } - inline NetworkString& gui16(uint16_t* dst) { *dst = getAndRemoveUInt16(0); return *this; } - inline NetworkString& gui32(uint32_t* dst) { *dst = getAndRemoveUInt32(0); return *this; } - inline NetworkString& gui(uint32_t* dst) { *dst = getAndRemoveUInt32(0); return *this; } - inline NetworkString& gi(int* dst) { *dst = getAndRemoveInt(0); return *this; } - inline NetworkString& gc(char* dst) { *dst = getAndRemoveChar(0); return *this; } - inline NetworkString& guc(uchar* dst) { *dst = getAndRemoveUChar(0); return *this; } - inline NetworkString& gd(double* dst) { *dst = getAndRemoveDouble(0); return *this; } - inline NetworkString& gf(float* dst) { *dst = getAndRemoveFloat(0); return *this; } - - protected: - std::string m_string; -}; - -NetworkString operator+(NetworkString const& a, NetworkString const& b); - -#endif // NETWORK_STRING_HPP diff --git a/src/network/num_players_message.hpp b/src/network/num_players_message.hpp new file mode 100644 index 000000000..4279f9eb9 --- /dev/null +++ b/src/network/num_players_message.hpp @@ -0,0 +1,42 @@ +// +// 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_NUM_PLAYERS_MESSAGE_HPP +#define HEADER_NUM_PLAYERS_MESSAGE_HPP + +#include +#include +#ifndef WIN32 +# include +#endif + +#include "network/message.hpp" +#include "race/race_manager.hpp" + +class NumPlayersMessage : public Message +{ +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 diff --git a/src/network/protocol.hpp b/src/network/protocol.hpp deleted file mode 100644 index a0d727c1c..000000000 --- a/src/network/protocol.hpp +++ /dev/null @@ -1,108 +0,0 @@ -// -// 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 "utils/types.hpp" - -/** \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 Called when the protocol is to be killed. - */ - virtual void kill(); - - /*! - * \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 deleted file mode 100644 index f2ff081e9..000000000 --- a/src/network/protocol_manager.cpp +++ /dev/null @@ -1,377 +0,0 @@ -// -// 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 -#include - -void* protocolManagerUpdate(void* data) -{ - ProtocolManager* manager = static_cast(data); - while(!manager->exit()) - { - manager->update(); - } - return NULL; -} - -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); - pthread_mutex_init(&m_exit_mutex, NULL); - m_next_protocol_id = 0; - - - pthread_mutex_lock(&m_exit_mutex); // will let the update function run - m_update_thread = (pthread_t*)(malloc(sizeof(pthread_t))); - pthread_create(m_update_thread, NULL, protocolManagerUpdate, this); -} - -ProtocolManager::~ProtocolManager() -{ - pthread_mutex_unlock(&m_exit_mutex); // will stop the update function - 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); - pthread_mutex_destroy(&m_exit_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, const NetworkString& message) -{ - NetworkString newMessage; - newMessage.ai8(sender->getProtocolType()); // add one byte to add protocol type - newMessage += message; - NetworkManager::getInstance()->sendPacket(newMessage); -} - -void ProtocolManager::sendMessage(Protocol* sender, STKPeer* peer, const NetworkString& message) -{ - NetworkString newMessage; - newMessage.ai8(sender->getProtocolType()); // add one byte to add protocol type - newMessage += message; - NetworkManager::getInstance()->sendPacket(peer, newMessage); -} -void ProtocolManager::sendMessageExcept(Protocol* sender, STKPeer* peer, const NetworkString& message) -{ - NetworkString newMessage; - newMessage.ai8(sender->getProtocolType()); // add one byte to add protocol type - newMessage += message; - NetworkManager::getInstance()->sendPacketExcept(peer, newMessage); -} - -uint32_t 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.", 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.", 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->type == EVENT_TYPE_MESSAGE) - { - if (event->data.size() > 0) - searchedProtocol = (PROTOCOL_TYPE)(event->data.getUInt8(0)); - event->removeFront(1); // remove the first byte which indicates the protocol - } - if (event->type == EVENT_TYPE_CONNECTED) - { - searchedProtocol = PROTOCOL_CONNECTION; - } - for (unsigned int i = 0; i < m_protocols.size() ; i++) - { - if (m_protocols[i].protocol->getProtocolType() == searchedProtocol || event->type == EVENT_TYPE_DISCONNECTED) // pass data to protocols even when paused - m_protocols[i].protocol->notifyEvent(event); - } - 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 -} - -uint32_t 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; -} - -Protocol* ProtocolManager::getProtocol(uint32_t id) -{ - for (unsigned int i = 0; i < m_protocols.size(); i++) - { - if (m_protocols[i].id == id) - return m_protocols[i].protocol; - } - return NULL; -} - -bool ProtocolManager::isServer() -{ - return NetworkManager::getInstance()->isServer(); -} - -int ProtocolManager::exit() -{ - switch(pthread_mutex_trylock(&m_exit_mutex)) { - case 0: /* if we got the lock, unlock and return 1 (true) */ - pthread_mutex_unlock(&m_exit_mutex); - return 1; - case EBUSY: /* return 0 (false) if the mutex was locked */ - return 0; - } - return 1; -} - -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 deleted file mode 100644 index dbb3dc732..000000000 --- a/src/network/protocol_manager.hpp +++ /dev/null @@ -1,295 +0,0 @@ -// -// 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 "network/network_string.hpp" -#include "utils/types.hpp" - -#include - -class Protocol; - -/*! - * \enum PROTOCOL_STATE - * \brief Defines the three states that a protocol can have. - */ -enum PROTOCOL_STATE -{ - PROTOCOL_STATE_RUNNING, //!< The protocol is being updated everytime. - PROTOCOL_STATE_PAUSED, //!< The protocol is paused. - PROTOCOL_STATE_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, const NetworkString& message); - /*! - * \brief WILL BE COMMENTED LATER - */ - virtual void sendMessage(Protocol* sender, STKPeer* peer, const NetworkString& message); - /*! - * \brief WILL BE COMMENTED LATER - */ - virtual void sendMessageExcept(Protocol* sender, STKPeer* peer, const NetworkString& message); - - /*! - * \brief Asks the manager to start a protocol. - * This function will store the request, and process it at a time it is - * thread-safe. - * \param protocol : A pointer to the protocol to start - * \return The unique id of the protocol that is being started. - */ - virtual uint32_t requestStart(Protocol* protocol); - /*! - * \brief Asks the manager to stop a protocol. - * This function will store the request, and process it at a time it is - * thread-safe. - * \param protocol : A pointer to the protocol to stop - */ - virtual void requestStop(Protocol* protocol); - /*! - * \brief Asks the manager to pause a protocol. - * This function will store the request, and process it at a time it is - * thread-safe. - * \param protocol : A pointer to the protocol to pause - */ - virtual void requestPause(Protocol* protocol); - /*! - * \brief Asks the manager to unpause a protocol. - * This function will store the request, and process it at a time it is - * thread-safe. - * \param protocol : A pointer to the protocol to unpause - */ - virtual void requestUnpause(Protocol* protocol); - /*! - * \brief Notifies the manager that a protocol is terminated. - * This function will store the request, and process it at a time it is - * thread-safe. - * \param protocol : A pointer to the protocol that is finished - */ - virtual void requestTerminate(Protocol* protocol); - - /*! - * \brief Updates the manager. - * - * This function processes the events queue, notifies the concerned - * 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 uint32_t getProtocolID(Protocol* protocol); - - /*! - * \brief Get a protocol using his id. - * \param id : Unique ID of the seek protocol. - * \return The protocol that has the ID id. - */ - virtual Protocol* getProtocol(uint32_t id); - - /*! \brief Know whether the app is a server. - * \return True if this application is in server mode, false elseway. - */ - bool isServer(); - - /*! \brief Tells if we need to stop the update thread. */ - int exit(); - - 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. - */ - uint32_t 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; - /*! Used when need to quit.*/ - pthread_mutex_t m_exit_mutex; - - /*! Update thread.*/ - pthread_t* m_update_thread; - -}; - -#endif // PROTOCOL_MANAGER_HPP diff --git a/src/network/protocols/connect_to_peer.cpp b/src/network/protocols/connect_to_peer.cpp deleted file mode 100644 index 37081c437..000000000 --- a/src/network/protocols/connect_to_peer.cpp +++ /dev/null @@ -1,122 +0,0 @@ -// -// 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_peer.hpp" - -#include "network/client_network_manager.hpp" -#include "network/protocols/get_public_address.hpp" -#include "network/protocols/get_peer_address.hpp" -#include "network/protocols/show_public_address.hpp" -#include "network/protocols/hide_public_address.hpp" -#include "network/protocols/request_connection.hpp" -#include "network/protocols/ping_protocol.hpp" -#include "online/current_online_user.hpp" -#include "utils/time.hpp" -#include "utils/log.hpp" - -// ---------------------------------------------------------------------------- - -ConnectToPeer::ConnectToPeer(uint32_t peer_id) : - Protocol(NULL, PROTOCOL_CONNECTION) -{ - m_peer_id = peer_id; - m_state = NONE; -} - -// ---------------------------------------------------------------------------- - -ConnectToPeer::~ConnectToPeer() -{ -} - -// ---------------------------------------------------------------------------- - -void ConnectToPeer::notifyEvent(Event* event) -{ - if (event->type == EVENT_TYPE_CONNECTED) - { - Log::info("ConnectToPeer", "The Connect To Server protocol has \ - received an event notifying that he's connected to the peer."); - m_state = CONNECTED; // we received a message, we are connected - } -} - -// ---------------------------------------------------------------------------- - -void ConnectToPeer::setup() -{ - m_state = NONE; - m_public_address.ip = 0; - m_public_address.port = 0; - m_peer_address.ip = 0; - m_peer_address.port = 0; - m_current_protocol_id = 0; -} - -// ---------------------------------------------------------------------------- - -void ConnectToPeer::update() -{ - switch(m_state) - { - case NONE: - { - m_current_protocol_id = m_listener->requestStart(new GetPeerAddress(m_peer_id, &m_peer_address)); - m_state = WAITING_PEER_ADDRESS; - break; - } - case WAITING_PEER_ADDRESS: - if (m_listener->getProtocolState(m_current_protocol_id) - == PROTOCOL_STATE_TERMINATED) // we know the peer address - { - if (m_peer_address.ip != 0 && m_peer_address.port != 0) - { - m_state = CONNECTING; - m_current_protocol_id = m_listener->requestStart(new PingProtocol(m_peer_address, 2.0)); - } - else - { - Log::error("ConnectToPeer", "The peer you want to connect to has hidden his address."); - m_state = DONE; - } - } - break; - case CONNECTING: // waiting the peer to connect - { - static double timer = 0; - if (Time::getRealTime() > timer+5.0) // every 5 seconds - { - timer = Time::getRealTime(); - NetworkManager::getInstance()->connect(m_peer_address); - } - break; - } - case CONNECTED: - { - m_listener->requestTerminate( m_listener->getProtocol(m_current_protocol_id)); // kill the ping protocol because we're connected - m_state = DONE; - break; - } - case DONE: - m_listener->requestTerminate(this); - break; - } -} - -// ---------------------------------------------------------------------------- - diff --git a/src/network/protocols/connect_to_peer.hpp b/src/network/protocols/connect_to_peer.hpp deleted file mode 100644 index a8bf4f9be..000000000 --- a/src/network/protocols/connect_to_peer.hpp +++ /dev/null @@ -1,53 +0,0 @@ -// -// 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 CONNECT_TO_SERVER_HPP -#define CONNECT_TO_SERVER_HPP - -#include "network/protocol.hpp" -#include "network/types.hpp" -#include - -class ConnectToPeer : public Protocol, public CallbackObject -{ - public: - ConnectToPeer(uint32_t peer_id); - virtual ~ConnectToPeer(); - - virtual void notifyEvent(Event* event); - virtual void setup(); - virtual void update(); - - protected: - TransportAddress m_peer_address; - TransportAddress m_public_address; - uint32_t m_peer_id; - uint32_t m_current_protocol_id; - - enum STATE - { - NONE, - WAITING_PEER_ADDRESS, - CONNECTING, - CONNECTED, - DONE - }; - STATE m_state; -}; - -#endif // CONNECT_TO_SERVER_HPP diff --git a/src/network/protocols/connect_to_server.cpp b/src/network/protocols/connect_to_server.cpp deleted file mode 100644 index 75d5d762d..000000000 --- a/src/network/protocols/connect_to_server.cpp +++ /dev/null @@ -1,155 +0,0 @@ -// -// 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 "network/protocols/get_public_address.hpp" -#include "network/protocols/get_peer_address.hpp" -#include "network/protocols/show_public_address.hpp" -#include "network/protocols/hide_public_address.hpp" -#include "network/protocols/request_connection.hpp" -#include "network/protocols/ping_protocol.hpp" -#include "network/protocols/lobby_room_protocol.hpp" -#include "online/current_online_user.hpp" -#include "utils/time.hpp" -#include "utils/log.hpp" - -// ---------------------------------------------------------------------------- - -ConnectToServer::ConnectToServer(uint32_t server_id) : - Protocol(NULL, PROTOCOL_CONNECTION) -{ - m_server_id = server_id; - m_state = NONE; -} - -// ---------------------------------------------------------------------------- - -ConnectToServer::~ConnectToServer() -{ -} - -// ---------------------------------------------------------------------------- - -void ConnectToServer::notifyEvent(Event* event) -{ - if (event->type == EVENT_TYPE_CONNECTED) - { - Log::info("ConnectToServer", "The Connect To Server protocol has \ - received an event notifying that he's connected to the peer."); - m_state = CONNECTED; // we received a message, we are connected - } -} - -// ---------------------------------------------------------------------------- - -void ConnectToServer::setup() -{ - m_state = NONE; - m_public_address.ip = 0; - m_public_address.port = 0; - m_server_address.ip = 0; - m_server_address.port = 0; - m_current_protocol_id = 0; -} - -// ---------------------------------------------------------------------------- - -void ConnectToServer::update() -{ - switch(m_state) - { - case NONE: - { - m_current_protocol_id = m_listener->requestStart(new GetPublicAddress(&m_public_address)); - m_state = WAITING_SELF_ADDRESS; - break; - } - case WAITING_SELF_ADDRESS: - if (m_listener->getProtocolState(m_current_protocol_id) - == PROTOCOL_STATE_TERMINATED) // now we know the public addr - { - m_state = SELF_ADDRESS_KNOWN; - NetworkManager::getInstance()->setPublicAddress(m_public_address); // set our public address - m_current_protocol_id = m_listener->requestStart(new GetPeerAddress(m_server_id, &m_server_address)); - } - break; - case SELF_ADDRESS_KNOWN: - if (m_listener->getProtocolState(m_current_protocol_id) - == PROTOCOL_STATE_TERMINATED) // now we have the server's address - { - if (m_server_address.ip == 0 || m_server_address.port == 0) - { - m_state = HIDING_ADDRESS; - m_current_protocol_id = m_listener->requestStart(new HidePublicAddress()); - return; - } - m_state = PEER_ADDRESS_KNOWN; - m_current_protocol_id = m_listener->requestStart(new ShowPublicAddress()); - } - break; - case PEER_ADDRESS_KNOWN: - if (m_listener->getProtocolState(m_current_protocol_id) - == PROTOCOL_STATE_TERMINATED) // now our public address is public - { - m_state = SELF_ADDRESS_SHOWN; - m_current_protocol_id = m_listener->requestStart(new RequestConnection(m_server_id)); - } - break; - case SELF_ADDRESS_SHOWN: - if (m_listener->getProtocolState(m_current_protocol_id) - == PROTOCOL_STATE_TERMINATED) // we have put a request to access the server - { - m_state = CONNECTING; - m_current_protocol_id = m_listener->requestStart(new PingProtocol(m_server_address, 2.0)); - } - break; - case CONNECTING: // waiting the server to answer our connection - { - static double timer = 0; - if (Time::getRealTime() > timer+5.0) // every 5 seconds - { - timer = Time::getRealTime(); - NetworkManager::getInstance()->connect(m_server_address); - } - break; - } - case CONNECTED: - { - m_listener->requestTerminate( m_listener->getProtocol(m_current_protocol_id)); // kill the ping protocol because we're connected - m_current_protocol_id = m_listener->requestStart(new HidePublicAddress()); - m_state = HIDING_ADDRESS; - break; - } - case HIDING_ADDRESS: - if (m_listener->getProtocolState(m_current_protocol_id) - == PROTOCOL_STATE_TERMINATED) // we have hidden our address - { - m_state = DONE; - m_listener->requestStart(new ClientLobbyRoomProtocol(m_server_address)); - } - break; - case DONE: - m_listener->requestTerminate(this); - break; - } -} - -// ---------------------------------------------------------------------------- - diff --git a/src/network/protocols/connect_to_server.hpp b/src/network/protocols/connect_to_server.hpp deleted file mode 100644 index 36789ec5e..000000000 --- a/src/network/protocols/connect_to_server.hpp +++ /dev/null @@ -1,57 +0,0 @@ -// -// 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 CONNECT_TO_SERVER_HPP -#define CONNECT_TO_SERVER_HPP - -#include "network/protocol.hpp" -#include "network/types.hpp" -#include - -class ConnectToServer : public Protocol, public CallbackObject -{ - public: - ConnectToServer(uint32_t server_id); - virtual ~ConnectToServer(); - - virtual void notifyEvent(Event* event); - virtual void setup(); - virtual void update(); - - protected: - TransportAddress m_server_address; - TransportAddress m_public_address; - uint32_t m_server_id; - uint32_t m_current_protocol_id; - - enum STATE - { - NONE, - WAITING_SELF_ADDRESS, - SELF_ADDRESS_KNOWN, - PEER_ADDRESS_KNOWN, - SELF_ADDRESS_SHOWN, - CONNECTING, - CONNECTED, - HIDING_ADDRESS, - 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 deleted file mode 100644 index f78f73135..000000000 --- a/src/network/protocols/get_peer_address.cpp +++ /dev/null @@ -1,89 +0,0 @@ -// -// 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 "online/http_connector.hpp" -#include "online/current_online_user.hpp" -#include "config/user_config.hpp" -#include "utils/log.hpp" - -GetPeerAddress::GetPeerAddress(uint32_t peer_id, CallbackObject* callback_object) : Protocol(callback_object, PROTOCOL_SILENT) -{ - m_peer_id = peer_id; -} - -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) - { - - HTTPConnector * connector = new HTTPConnector((std::string)UserConfigParams::m_server_multiplayer + "address-management.php"); - connector->setParameter("id",CurrentOnlineUser::get()->getUserID()); - connector->setParameter("token",CurrentOnlineUser::get()->getToken()); - connector->setParameter("peer_id",m_peer_id); - connector->setParameter("action","get"); - - const XMLNode * result = connector->getXMLFromPage(); - std::string rec_success; - - if(result->get("success", &rec_success)) - { - if (rec_success == "yes") - { - TransportAddress* addr = static_cast(m_callback_object); - result->get("ip", &addr->ip); - result->get("port", &addr->port); - Log::info("GetPeerAddress", "Address gotten successfully."); - } - else - { - Log::error("GetPeerAddress", "Fail to get address."); - } - } - else - { - Log::error("GetPeerAddress", "Fail to get address."); - } - m_state = DONE; - } - else if (m_state == DONE) - { - m_listener->requestTerminate(this); - } -} - -void GetPeerAddress::setPeerID(uint32_t peer_id) -{ - m_peer_id = peer_id; -} diff --git a/src/network/protocols/get_peer_address.hpp b/src/network/protocols/get_peer_address.hpp deleted file mode 100644 index 4ffab3bdb..000000000 --- a/src/network/protocols/get_peer_address.hpp +++ /dev/null @@ -1,47 +0,0 @@ -// -// 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(uint32_t peer_id, CallbackObject* callback_object); - virtual ~GetPeerAddress(); - - virtual void notifyEvent(Event* event); - virtual void setup(); - virtual void update(); - - void setPeerID(uint32_t m_peer_id); - protected: - uint32_t m_peer_id; - - 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 deleted file mode 100644 index 2ef997440..000000000 --- a/src/network/protocols/get_public_address.cpp +++ /dev/null @@ -1,206 +0,0 @@ -// -// 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((unsigned int)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 = 0x0001; // 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"); - 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] == 0x01 && - data[1] == 0x01 && - 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::info("GetPublicAddress", "The STUN server responded with a valid answer"); - 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."); - finish = true; - } - if (message_size < 4) // cannot even read the size - { - Log::error("GetPublicAddress", "STUN message is not valid."); - 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."); - 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", 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 deleted file mode 100644 index 596ab2c1b..000000000 --- a/src/network/protocols/get_public_address.hpp +++ /dev/null @@ -1,47 +0,0 @@ -// -// 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 deleted file mode 100644 index 1a1b377a2..000000000 --- a/src/network/protocols/hide_public_address.cpp +++ /dev/null @@ -1,76 +0,0 @@ -// -// 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 "online/http_connector.hpp" -#include "online/current_online_user.hpp" -#include "config/user_config.hpp" -#include "utils/log.hpp" - -HidePublicAddress::HidePublicAddress() : Protocol(NULL, PROTOCOL_SILENT) -{ -} - -HidePublicAddress::~HidePublicAddress() -{ -} - -void HidePublicAddress::notifyEvent(Event* event) -{ -} - -void HidePublicAddress::setup() -{ - m_state = NONE; -} - -void HidePublicAddress::update() -{ - if (m_state == NONE) - { - HTTPConnector * connector = new HTTPConnector((std::string)UserConfigParams::m_server_multiplayer + "address-management.php"); - connector->setParameter("id",CurrentOnlineUser::get()->getUserID()); - connector->setParameter("token",CurrentOnlineUser::get()->getToken()); - connector->setParameter("action","unset"); - - const XMLNode * result = connector->getXMLFromPage(); - std::string rec_success; - - if(result->get("success", &rec_success)) - { - if(rec_success == "yes") - { - Log::info("ShowPublicAddress", "Address hidden successfully."); - } - else - { - Log::error("ShowPublicAddress", "Fail to hide address."); - } - } - else - { - Log::error("ShowPublicAddress", "Fail to hide address."); - } - m_state = DONE; - } - else if (m_state == DONE) - { - m_listener->requestTerminate(this); - } -} diff --git a/src/network/protocols/lobby_room_protocol.cpp b/src/network/protocols/lobby_room_protocol.cpp deleted file mode 100644 index ed374cd2e..000000000 --- a/src/network/protocols/lobby_room_protocol.cpp +++ /dev/null @@ -1,338 +0,0 @@ -// -// 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/lobby_room_protocol.hpp" - -#include "network/network_manager.hpp" -#include "network/protocol_manager.hpp" -#include "network/client_network_manager.hpp" -#include "network/protocols/get_public_address.hpp" -#include "network/protocols/show_public_address.hpp" -#include "network/protocols/connect_to_peer.hpp" -#include "network/protocols/start_server.hpp" -#include "online/current_online_user.hpp" -#include "online/http_connector.hpp" -#include "config/user_config.hpp" -#include "utils/log.hpp" -#include "utils/random_generator.hpp" -#include "utils/time.hpp" - -#include - -LobbyRoomProtocol::LobbyRoomProtocol(CallbackObject* callback_object) : Protocol(callback_object, PROTOCOL_LOBBY_ROOM) -{ - m_setup = NULL; -} - -//----------------------------------------------------------------------------- - -LobbyRoomProtocol::~LobbyRoomProtocol() -{ -} - -//----------------------------------------------------------------------------- - -void ClientLobbyRoomProtocol::setup() -{ - m_setup = NetworkManager::getInstance()->setupNewGame(); // create a new setup - m_state = NONE; - Log::info("ClientLobbyRoomProtocol", "Starting the protocol."); -} - -//----------------------------------------------------------------------------- - -void ServerLobbyRoomProtocol::setup() -{ - m_setup = NetworkManager::getInstance()->setupNewGame(); // create a new setup - m_next_id = 0; - m_state = NONE; - m_public_address.ip = 0; - m_public_address.port = 0; - Log::info("ServerLobbyRoomProtocol", "Starting the protocol."); -} - -//----------------------------------------------------------------------------- - -void ClientLobbyRoomProtocol::notifyEvent(Event* event) -{ - assert(m_setup); // assert that the setup exists - if (event->type == EVENT_TYPE_MESSAGE) - { - assert(event->data.size()); // assert that data isn't empty - Log::verbose("LobbyRoomProtocol", "Message from %u : \"%s\"", event->peer->getAddress(), event->data.c_str()); - uint8_t message_type = event->data.getAndRemoveUInt8(); - if (message_type == 1) // new player connected - { - if (event->data.size() != 7 || event->data[0] != 4 || event->data[5] != 1) // 7 bytes remains now - { - Log::error("LobbyRoomProtocol", "A message notifying a new player wasn't formated as expected."); - return; - } - - uint32_t global_id = event->data.gui32(1); - - NetworkPlayerProfile profile; - profile.kart_name = ""; - profile.race_id = event->data.gui8(6); - - if (global_id == CurrentOnlineUser::get()->getUserID()) - { - Log::error("LobbyRoomProtocol", "The server notified me that i'm a new player in the room (not normal)."); - } - else - { - Log::verbose("LobbyRoomProtocol", "New player connected."); - profile.user_profile = new OnlineUser(""); ///! INSERT THE ID OF THE PLAYER HERE (global_id) - m_setup->addPlayer(profile); - } - } // new player connected - else if (message_type == 0x81) // connection accepted - { - if (event->data.size() != 12 || event->data[0] != 1 || event->data[2] != 4 || event->data[7] != 4) // 12 bytes remains now - { - Log::error("LobbyRoomProtocol", "A message notifying an accepted connection wasn't formated as expected."); - return; - } - - NetworkPlayerProfile profile; - profile.kart_name = ""; - profile.race_id = event->data.gui8(1); - uint32_t token = event->data.gui32(3); - uint32_t global_id = event->data.gui32(8); - if (global_id == CurrentOnlineUser::get()->getUserID()) - { - Log::info("LobbyRoomProtocol", "The server accepted the connection."); - profile.user_profile = CurrentOnlineUser::get(); - m_setup->addPlayer(profile); - event->peer->setClientServerToken(token); - m_state = CONNECTED; - } - } // connection accepted - else if (message_type == 0x80) // connection refused - { - if (event->data.size() != 2 || event->data[0] != 1) // 2 bytes remains now - { - Log::error("LobbyRoomProtocol", "A message notifying a refused connection wasn't formated as expected."); - return; - } - - Log::info("LobbyRoomProtocol", "The connection has been refused."); - switch (event->data[1]) // the second byte - { - case 0: - Log::info("LobbyRoomProtocol", "Too many clients in the race."); - break; - case 1: - Log::info("LobbyRoomProtocol", "The host has banned you."); - break; - default: - break; - } - } // connection refused - } // if (event->type == EVENT_TYPE_MESSAGE) - else if (event->type == EVENT_TYPE_CONNECTED) - { - } // if (event->type == EVENT_TYPE_CONNECTED) - else if (event->type == EVENT_TYPE_DISCONNECTED) - { - } // if (event->type == EVENT_TYPE_DISCONNECTED) -} - -//----------------------------------------------------------------------------- - -void ServerLobbyRoomProtocol::notifyEvent(Event* event) -{ - assert(m_setup); // assert that the setup exists - if (event->type == EVENT_TYPE_MESSAGE) - { - assert(event->data.size()); // message not empty - uint8_t message_type; - message_type = event->data.getAndRemoveUInt8(); - Log::info("ServerLobbyRoomProtocol", "Message received with type %d.", message_type); - if (message_type == 1) // player requesting connection - { - if (event->data.size() != 5 || event->data[0] != 4) - { - Log::warn("LobbyRoomProtocol", "A player is sending a badly formated message. Size is %d and first byte %d", event->data.size(), event->data[0]); - return; - } - Log::verbose("LobbyRoomProtocol", "New player."); - int player_id = 0; - player_id = event->data.getUInt32(1); - // can we add the player ? - if (m_setup->getPlayerCount() < 16) // accept player - { - // add the player to the game setup - while(m_setup->getProfile(m_next_id)!=NULL) - m_next_id++; - NetworkPlayerProfile profile; - profile.race_id = m_next_id; - profile.kart_name = ""; - profile.user_profile = new OnlineUser("Unnamed Player"); - m_setup->addPlayer(profile); - // notify everybody that there is a new player - NetworkString message; - // new player (1) -- size of id -- id -- size of local id -- local id; - message.ai8(1).ai8(4).ai32(player_id).ai8(1).ai8(m_next_id); - m_listener->sendMessageExcept(this, event->peer, message); - // send a message to the one that asked to connect - NetworkString message_ack; - // 0b10000001 (connection success) ; - RandomGenerator token_generator; - // use 4 random numbers because rand_max is probably 2^15-1. - uint32_t token = (uint32_t)(((token_generator.get(RAND_MAX)<<24) & 0xff) + - ((token_generator.get(RAND_MAX)<<16) & 0xff) + - ((token_generator.get(RAND_MAX)<<8) & 0xff) + - ((token_generator.get(RAND_MAX) & 0xff))); - // connection success (129) -- size of token -- token - message_ack.ai8(0x81).ai8(1).ai8(m_next_id).ai8(4).ai32(token).ai8(4).ai32(player_id); - m_listener->sendMessage(this, event->peer, message_ack); - } // accept player - else // refuse the connection with code 0 (too much players) - { - NetworkString message; - message.ai8(0x80); // 128 means connection refused - message.ai8(1); // 1 bytes for the error code - message.ai8(0); // 0 = too much players - // send only to the peer that made the request - m_listener->sendMessage(this, event->peer, message); - } - } - } // if (event->type == EVENT_TYPE_MESSAGE) - else if (event->type == EVENT_TYPE_CONNECTED) - { - } // if (event->type == EVENT_TYPE_CONNECTED) - else if (event->type == EVENT_TYPE_DISCONNECTED) - { - - } // if (event->type == EVENT_TYPE_DISCONNECTED) -} - -//----------------------------------------------------------------------------- - -void ClientLobbyRoomProtocol::update() -{ - switch (m_state) - { - case NONE: - if (NetworkManager::getInstance()->isConnectedTo(m_server_address)) - { - m_state = LINKED; - } - break; - case LINKED: - { - NetworkString ns; - // 1 (connection request), 4 (size of id), global id - ns.ai8(1).ai8(4).ai32(CurrentOnlineUser::get()->getUserID()); - m_listener->sendMessage(this, ns); - m_state = REQUESTING_CONNECTION; - break; - } - case REQUESTING_CONNECTION: - break; - case CONNECTED: - break; - case DONE: - m_listener->requestTerminate(this); - break; - } -} - -//----------------------------------------------------------------------------- - -void ServerLobbyRoomProtocol::update() -{ - switch (m_state) - { - case NONE: - m_current_protocol_id = m_listener->requestStart(new GetPublicAddress(&m_public_address)); - m_state = GETTING_PUBLIC_ADDRESS; - break; - case GETTING_PUBLIC_ADDRESS: - if (m_listener->getProtocolState(m_current_protocol_id) == PROTOCOL_STATE_TERMINATED) - { - NetworkManager::getInstance()->setPublicAddress(m_public_address); - m_current_protocol_id = m_listener->requestStart(new StartServer()); - m_state = LAUNCHING_SERVER; - Log::info("ServerLobbyRoomProtocol", "Public address known."); - } - break; - case LAUNCHING_SERVER: - if (m_listener->getProtocolState(m_current_protocol_id) == PROTOCOL_STATE_TERMINATED) - { - m_state = WORKING; - Log::info("ServerLobbyRoomProtocol", "Server setup"); - } - break; - case WORKING: - { - // first poll every 5 seconds - static double last_poll_time = 0; - if (Time::getRealTime() > last_poll_time+10.0) - { - last_poll_time = Time::getRealTime(); - HTTPConnector * connector = new HTTPConnector((std::string)UserConfigParams::m_server_multiplayer + "address-management.php"); - connector->setParameter("id",CurrentOnlineUser::get()->getUserID()); - connector->setParameter("token",CurrentOnlineUser::get()->getToken()); - connector->setParameter("action","poll-connection-requests"); - - const XMLNode * result = connector->getXMLFromPage(); - std::string rec_success; - if(result->get("success", &rec_success)) - { - if(rec_success == "yes") - { - const XMLNode * users_xml = result->getNode("users"); - uint32_t id = 0; - for (unsigned int i = 0; i < users_xml->getNumNodes(); i++) - { - users_xml->getNode(i)->get("id", &id); - Log::info("ServerLobbyRoomProtocol", "User with id %d wants to connect.", id); - m_incoming_peers_ids.push_back(id); - } - } - else - { - Log::error("ServerLobbyRoomProtocol", "INSERT SOME ERROR MESSAGE"); - } - } - else - { - Log::error("ServerLobbyRoomProtocol", "Cannot retrieve the list"); - } - } - - // now - for (unsigned int i = 0; i < m_incoming_peers_ids.size(); i++) - { - m_listener->requestStart(new ConnectToPeer(m_incoming_peers_ids[i])); - } - m_incoming_peers_ids.clear(); - - break; - } - case DONE: - m_listener->requestTerminate(this); - break; - } -} -//----------------------------------------------------------------------------- - - - diff --git a/src/network/protocols/lobby_room_protocol.hpp b/src/network/protocols/lobby_room_protocol.hpp deleted file mode 100644 index 72ba74a1f..000000000 --- a/src/network/protocols/lobby_room_protocol.hpp +++ /dev/null @@ -1,102 +0,0 @@ -// -// 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 LOBBY_ROOM_PROTOCOL_HPP -#define LOBBY_ROOM_PROTOCOL_HPP - -#include "network/protocol.hpp" - -#include "network/game_setup.hpp" -#include "network/network_string.hpp" - -/*! - * \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 LobbyRoomProtocol : public Protocol -{ - public: - LobbyRoomProtocol(CallbackObject* callback_object); - virtual ~LobbyRoomProtocol(); - - virtual void notifyEvent(Event* event) = 0; - virtual void setup() = 0; - virtual void update() = 0; - - protected: - GameSetup* m_setup; //!< The game setup. -}; - -class ClientLobbyRoomProtocol : public LobbyRoomProtocol -{ - public: - ClientLobbyRoomProtocol(const TransportAddress& server_address) : LobbyRoomProtocol(NULL) - { m_server_address = server_address;} - virtual ~ClientLobbyRoomProtocol() {} - - virtual void notifyEvent(Event* event); - virtual void setup(); - virtual void update(); - - void sendMessage(std::string message); - - protected: - TransportAddress m_server_address; - - enum STATE - { - NONE, - LINKED, - REQUESTING_CONNECTION, - CONNECTED, - DONE - }; - STATE m_state; -}; - -class ServerLobbyRoomProtocol : public LobbyRoomProtocol -{ - public: - ServerLobbyRoomProtocol() : LobbyRoomProtocol(NULL) {} - virtual ~ServerLobbyRoomProtocol() {} - - virtual void notifyEvent(Event* event); - virtual void setup(); - virtual void update(); - - protected: - uint8_t m_next_id; //!< Next id to assign to a peer. - std::vector m_peers; - std::vector m_incoming_peers_ids; - uint32_t m_current_protocol_id; - TransportAddress m_public_address; - - enum STATE - { - NONE, - GETTING_PUBLIC_ADDRESS, - LAUNCHING_SERVER, - WORKING, - DONE - }; - STATE m_state; -}; - -#endif // LOBBY_ROOM_PROTOCOL_HPP diff --git a/src/network/protocols/ping_protocol.cpp b/src/network/protocols/ping_protocol.cpp deleted file mode 100644 index 84abdd873..000000000 --- a/src/network/protocols/ping_protocol.cpp +++ /dev/null @@ -1,33 +0,0 @@ -#include "network/protocols/ping_protocol.hpp" - -#include "network/network_manager.hpp" -#include "utils/time.hpp" - -PingProtocol::PingProtocol(const TransportAddress& ping_dst, double delay_between_pings) : Protocol(NULL, PROTOCOL_SILENT) -{ - m_ping_dst = ping_dst; - m_delay_between_pings = delay_between_pings; -} - -PingProtocol::~PingProtocol() -{ -} - -void PingProtocol::notifyEvent(Event* event) -{ -} - -void PingProtocol::setup() -{ - m_last_ping_time = 0; -} - -void PingProtocol::update() -{ - if (Time::getRealTime() > m_last_ping_time+m_delay_between_pings) - { - m_last_ping_time = Time::getRealTime(); - uint8_t data = 0; - NetworkManager::getInstance()->getHost()->sendRawPacket(&data, 1, m_ping_dst); - } -} diff --git a/src/network/protocols/ping_protocol.hpp b/src/network/protocols/ping_protocol.hpp deleted file mode 100644 index 2001967c6..000000000 --- a/src/network/protocols/ping_protocol.hpp +++ /dev/null @@ -1,23 +0,0 @@ -#ifndef PING_PROTOCOL_HPP -#define PING_PROTOCOL_HPP - -#include "network/protocol.hpp" - - -class PingProtocol : public Protocol -{ - public: - PingProtocol(const TransportAddress& ping_dst, double delay_between_pings); - virtual ~PingProtocol(); - - virtual void notifyEvent(Event* event); - virtual void setup(); - virtual void update(); - - protected: - TransportAddress m_ping_dst; - double m_delay_between_pings; - double m_last_ping_time; -}; - -#endif // PING_PROTOCOL_HPP diff --git a/src/network/protocols/request_connection.cpp b/src/network/protocols/request_connection.cpp deleted file mode 100644 index b00591ed0..000000000 --- a/src/network/protocols/request_connection.cpp +++ /dev/null @@ -1,64 +0,0 @@ -#include "network/protocols/request_connection.hpp" - -#include "online/http_connector.hpp" -#include "online/current_online_user.hpp" -#include "config/user_config.hpp" - -RequestConnection::RequestConnection(uint32_t server_id) : Protocol(NULL, PROTOCOL_SILENT) -{ - m_server_id = server_id; -} - -RequestConnection::~RequestConnection() -{ -} - -void RequestConnection::notifyEvent(Event* event) -{ -} - -void RequestConnection::setup() -{ - m_state = NONE; -} - -void RequestConnection::update() -{ - switch (m_state) - { - case NONE: - { - HTTPConnector * connector = new HTTPConnector((std::string)UserConfigParams::m_server_multiplayer + "address-management.php"); - connector->setParameter("id",CurrentOnlineUser::get()->getUserID()); - connector->setParameter("token",CurrentOnlineUser::get()->getToken()); - connector->setParameter("server_id",m_server_id); - connector->setParameter("action","request-connection"); - - const XMLNode * result = connector->getXMLFromPage(); - std::string rec_success; - - if(result->get("success", &rec_success)) - { - if (rec_success == "yes") - { - Log::info("RequestConnection", "Connection Request made successfully."); - } - else - { - Log::error("RequestConnection", "Fail to make a request."); - } - } - else - { - Log::error("RequestConnection", "Fail to make a request."); - } - m_state = DONE; - - break; - } - case DONE: - m_listener->requestTerminate(this); - break; - } -} - diff --git a/src/network/protocols/request_connection.hpp b/src/network/protocols/request_connection.hpp deleted file mode 100644 index 0b96967d0..000000000 --- a/src/network/protocols/request_connection.hpp +++ /dev/null @@ -1,28 +0,0 @@ -#ifndef REQUEST_CONNECTION_HPP -#define REQUEST_CONNECTION_HPP - -#include "network/protocol.hpp" - -class RequestConnection : public Protocol -{ - public: - RequestConnection(uint32_t server_id); - virtual ~RequestConnection(); - - virtual void notifyEvent(Event* event); - virtual void setup(); - virtual void update(); - - protected: - uint32_t m_server_id; - - enum STATE - { - NONE, - DONE - }; - STATE m_state; - -}; - -#endif // REQUEST_CONNECTION_HPP diff --git a/src/network/protocols/show_public_address.cpp b/src/network/protocols/show_public_address.cpp deleted file mode 100644 index e1c083914..000000000 --- a/src/network/protocols/show_public_address.cpp +++ /dev/null @@ -1,80 +0,0 @@ -// -// 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/network_manager.hpp" -#include "online/http_connector.hpp" -#include "online/current_online_user.hpp" -#include "config/user_config.hpp" -#include "utils/log.hpp" - -ShowPublicAddress::ShowPublicAddress() : Protocol(NULL, PROTOCOL_SILENT) -{ -} - -ShowPublicAddress::~ShowPublicAddress() -{ -} - -void ShowPublicAddress::notifyEvent(Event* event) -{ -} - -void ShowPublicAddress::setup() -{ - m_state = NONE; -} - -void ShowPublicAddress::update() -{ - if (m_state == NONE) - { - HTTPConnector * connector = new HTTPConnector((std::string)UserConfigParams::m_server_multiplayer + "address-management.php"); - connector->setParameter("id",CurrentOnlineUser::get()->getUserID()); - connector->setParameter("token",CurrentOnlineUser::get()->getToken()); - TransportAddress addr = NetworkManager::getInstance()->getPublicAddress(); - connector->setParameter("address",addr.ip); - connector->setParameter("port",addr.port); - connector->setParameter("action","set"); - - const XMLNode * result = connector->getXMLFromPage(); - std::string rec_success; - - if(result->get("success", &rec_success)) - { - if(rec_success == "yes") - { - Log::info("ShowPublicAddress", "Address shown successfully."); - } - else - { - Log::error("ShowPublicAddress", "Fail to show address."); - } - } - else - { - Log::error("ShowPublicAddress", "Fail to show address."); - } - m_state = DONE; - } - else if (m_state == DONE) - { - m_listener->requestTerminate(this); - } -} diff --git a/src/network/protocols/start_server.cpp b/src/network/protocols/start_server.cpp deleted file mode 100644 index e6c785bc8..000000000 --- a/src/network/protocols/start_server.cpp +++ /dev/null @@ -1,62 +0,0 @@ -#include "network/protocols/start_server.hpp" - -#include "network/network_manager.hpp" -#include "online/current_online_user.hpp" -#include "online/http_connector.hpp" -#include "config/user_config.hpp" - -StartServer::StartServer() : Protocol(NULL, PROTOCOL_SILENT) -{ -} - -StartServer::~StartServer() -{ -} - -void StartServer::notifyEvent(Event* event) -{ -} - -void StartServer::setup() -{ - m_state = NONE; -} - -void StartServer::update() -{ - if (m_state == NONE) - { - TransportAddress addr = NetworkManager::getInstance()->getPublicAddress(); - HTTPConnector * connector = new HTTPConnector((std::string)UserConfigParams::m_server_multiplayer + "address-management.php"); - connector->setParameter("id",CurrentOnlineUser::get()->getUserID()); - connector->setParameter("token",CurrentOnlineUser::get()->getToken()); - connector->setParameter("address",addr.ip); - connector->setParameter("port",addr.port); - connector->setParameter("max_players",UserConfigParams::m_server_max_players); - connector->setParameter("action","start-server"); - - const XMLNode * result = connector->getXMLFromPage(); - std::string rec_success; - - if(result->get("success", &rec_success)) - { - if(rec_success == "yes") - { - Log::info("StartServer", "Server is now online."); - } - else - { - Log::error("StartServer", "Fail to start server."); - } - } - else - { - Log::error("StartServer", "Fail to start server."); - } - m_state = DONE; - } - else if (m_state == DONE) - { - m_listener->requestTerminate(this); - } -} diff --git a/src/network/protocols/start_server.hpp b/src/network/protocols/start_server.hpp deleted file mode 100644 index 9982a3bd3..000000000 --- a/src/network/protocols/start_server.hpp +++ /dev/null @@ -1,29 +0,0 @@ -#ifndef START_SERVER_HPP -#define START_SERVER_HPP - -#include "network/protocol.hpp" - -/*! - * This protocol tells to the database that the server is up and running, - * and shows online the public IP:port that stores the NetworkManager. - */ -class StartServer : public Protocol -{ - public: - StartServer(); - virtual ~StartServer(); - - virtual void notifyEvent(Event* event); - virtual void setup(); - virtual void update(); - - protected: - enum STATE - { - NONE, - DONE - }; - STATE m_state; -}; - -#endif // START_SERVER_HPP diff --git a/src/network/protocols/stop_server.cpp b/src/network/protocols/stop_server.cpp deleted file mode 100644 index b74f3f4c7..000000000 --- a/src/network/protocols/stop_server.cpp +++ /dev/null @@ -1,61 +0,0 @@ -#include "network/protocols/stop_server.hpp" - -#include "network/network_manager.hpp" -#include "online/current_online_user.hpp" -#include "online/http_connector.hpp" -#include "config/user_config.hpp" - -StopServer::StopServer() : Protocol(NULL, PROTOCOL_SILENT) -{ -} - -StopServer::~StopServer() -{ -} - -void StopServer::notifyEvent(Event* event) -{ -} - -void StopServer::setup() -{ - m_state = NONE; -} - -void StopServer::update() -{ - if (m_state == NONE) - { - TransportAddress addr = NetworkManager::getInstance()->getPublicAddress(); - HTTPConnector * connector = new HTTPConnector((std::string)UserConfigParams::m_server_multiplayer + "address-management.php"); - connector->setParameter("id",CurrentOnlineUser::get()->getUserID()); - connector->setParameter("token",CurrentOnlineUser::get()->getToken()); - connector->setParameter("address",addr.ip); - connector->setParameter("port",addr.port); - connector->setParameter("action","stop-server"); - - const XMLNode * result = connector->getXMLFromPage(); - std::string rec_success; - - if(result->get("success", &rec_success)) - { - if(rec_success == "yes") - { - Log::info("StopServer", "Server is now offline."); - } - else - { - Log::error("StopServer", "Fail to stop server."); - } - } - else - { - Log::error("StopServer", "Fail to stop server."); - } - m_state = DONE; - } - else if (m_state == DONE) - { - m_listener->requestTerminate(this); - } -} diff --git a/src/network/protocols/stop_server.hpp b/src/network/protocols/stop_server.hpp deleted file mode 100644 index 3c07f2e98..000000000 --- a/src/network/protocols/stop_server.hpp +++ /dev/null @@ -1,29 +0,0 @@ -#ifndef STOP_SERVER_HPP -#define STOP_SERVER_HPP - -#include "network/protocol.hpp" - - -/*! \brief Removes the server info from the database - */ - -class StopServer : public Protocol -{ - public: - StopServer(); - virtual ~StopServer(); - - virtual void notifyEvent(Event* event); - virtual void setup(); - virtual void update(); - - protected: - enum STATE - { - NONE, - DONE - }; - STATE m_state; -}; - -#endif // STOP_SERVER_HPP diff --git a/src/network/race_info_message.cpp b/src/network/race_info_message.cpp new file mode 100644 index 000000000..4d2b6aa0b --- /dev/null +++ b/src/network/race_info_message.cpp @@ -0,0 +1,116 @@ +// +// 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/protocol.cpp b/src/network/race_info_message.hpp similarity index 59% rename from src/network/protocol.cpp rename to src/network/race_info_message.hpp index 7154c1014..52404b3f5 100644 --- a/src/network/protocol.cpp +++ b/src/network/race_info_message.hpp @@ -1,6 +1,6 @@ // // SuperTuxKart - a fun racing game with go-kart -// Copyright (C) 2013 SuperTuxKart-Team +// 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 @@ -16,37 +16,18 @@ // 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.hpp" +#ifndef HEADER_RACE_INFO_MESSAGE_HPP +#define HEADER_RACE_INFO_MESSAGE_HPP -Protocol::Protocol(CallbackObject* callback_object, PROTOCOL_TYPE type) -{ - m_callback_object = callback_object; - m_type = type; -} +#include -Protocol::~Protocol() -{ -} +#include "network/message.hpp" +#include "network/remote_kart_info.hpp" -void Protocol::pause() +class RaceInfoMessage : public Message { - m_listener->requestPause(this); -} -void Protocol::unpause() -{ - m_listener->requestUnpause(this); -} - -void Protocol::kill() -{ -} - -void Protocol::setListener(ProtocolManager* listener) -{ - m_listener = listener; -} - -PROTOCOL_TYPE Protocol::getProtocolType() -{ - return m_type; -} +public: + RaceInfoMessage(const std::vector& kart_info); + RaceInfoMessage(ENetPacket* pkt); +}; // RaceInfoMessage +#endif diff --git a/src/network/race_result_ack_message.hpp b/src/network/race_result_ack_message.hpp new file mode 100644 index 000000000..eda990208 --- /dev/null +++ b/src/network/race_result_ack_message.hpp @@ -0,0 +1,58 @@ +// +// 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 new file mode 100644 index 000000000..eeaacd656 --- /dev/null +++ b/src/network/race_result_message.cpp @@ -0,0 +1,60 @@ +// +// 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_result_message.hpp b/src/network/race_result_message.hpp new file mode 100644 index 000000000..95d3a6152 --- /dev/null +++ b/src/network/race_result_message.hpp @@ -0,0 +1,45 @@ +// +// 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_MESSAGE_HPP +#define HEADER_RACE_RESULT_MESSAGE_HPP + +#include + +#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 RaceResultMessage : public Message +{ + 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 diff --git a/src/network/protocols/hide_public_address.hpp b/src/network/race_start_message.hpp similarity index 58% rename from src/network/protocols/hide_public_address.hpp rename to src/network/race_start_message.hpp index a7746d7fc..eac2d7594 100644 --- a/src/network/protocols/hide_public_address.hpp +++ b/src/network/race_start_message.hpp @@ -1,6 +1,6 @@ // // SuperTuxKart - a fun racing game with go-kart -// Copyright (C) 2013 SuperTuxKart-Team +// 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 @@ -16,30 +16,25 @@ // 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 +#ifndef HEADER_RACE_START_MESSAGE_HPP +#define HEADER_RACE_START_MESSAGE_HPP -#include "network/protocol.hpp" -#include +#include "network/message.hpp" +#include "network/remote_kart_info.hpp" +#include "race/race_manager.hpp" -class HidePublicAddress : public Protocol +class RaceStartMessage : public Message { - public: - HidePublicAddress(); - virtual ~HidePublicAddress(); - - virtual void notifyEvent(Event* event); - virtual void setup(); - virtual void update(); - - protected: - - enum STATE - { - NONE, - DONE - }; - STATE m_state; -}; +private: +// For now this is an empty message +public: + RaceStartMessage() : Message(Message::MT_RACE_START) + { + allocate(0); + } // RaceStartMessage -#endif // HIDE_PUBLIC_ADDRESS_HPP + RaceStartMessage(ENetPacket* pkt):Message(pkt, MT_RACE_START) + { + } +}; // RaceStartMessage +#endif diff --git a/src/network/race_state.cpp b/src/network/race_state.cpp new file mode 100644 index 000000000..db5c66c83 --- /dev/null +++ b/src/network/race_state.cpp @@ -0,0 +1,195 @@ +// +// 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 deleted file mode 100644 index 6a87eaf01..000000000 --- a/src/network/server_network_manager.cpp +++ /dev/null @@ -1,99 +0,0 @@ -// -// 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 "network/protocols/stop_server.hpp" - -#include "main_loop.hpp" -#include "utils/log.hpp" - -#include -#include -#include -#include -#include - -void* waitInput2(void* data) -{ - std::string str = ""; - bool stop = false; - while(!stop) - { - getline(std::cin, str); - if (str == "quit") - { - stop = true; - } - } - - uint32_t id = ProtocolManager::getInstance()->requestStart(new StopServer()); - while(ProtocolManager::getInstance()->getProtocolState(id) != PROTOCOL_STATE_TERMINATED) - { - } - - main_loop->abort(); - exit(0); - - return NULL; -} - -ServerNetworkManager::ServerNetworkManager() -{ - m_localhost = NULL; - m_thread_keyboard = NULL; -} - -ServerNetworkManager::~ServerNetworkManager() -{ - if (m_thread_keyboard) - pthread_cancel(*m_thread_keyboard);//, SIGKILL); -} - -void ServerNetworkManager::run() -{ - if (enet_initialize() != 0) - { - Log::error("ServerNetworkManager", "Could not initialize enet.\n"); - return; - } - m_localhost = new STKHost(); - m_localhost->setupServer(STKHost::HOST_ANY, 7321, 16, 2, 0, 0); - m_localhost->startListening(); - - // listen keyboard console input - m_thread_keyboard = (pthread_t*)(malloc(sizeof(pthread_t))); - pthread_create(m_thread_keyboard, NULL, waitInput2, NULL); - - NetworkManager::run(); -} - -void ServerNetworkManager::start() -{ - -} - -void ServerNetworkManager::sendPacket(const NetworkString& data) -{ - m_localhost->broadcastPacket(data); -} diff --git a/src/network/server_network_manager.hpp b/src/network/server_network_manager.hpp deleted file mode 100644 index e06b969b9..000000000 --- a/src/network/server_network_manager.hpp +++ /dev/null @@ -1,50 +0,0 @@ -// -// 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(); - - virtual void sendPacket(const NetworkString& data); - - virtual bool isServer() { return true; } - - protected: - ServerNetworkManager(); - virtual ~ServerNetworkManager(); - - pthread_t* m_thread_keyboard; - -}; - -#endif // SERVER_NETWORK_MANAGER_HPP diff --git a/src/network/singleton.hpp b/src/network/singleton.hpp deleted file mode 100644 index 65cf27dd4..000000000 --- a/src/network/singleton.hpp +++ /dev/null @@ -1,65 +0,0 @@ -// -// 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::debug("Singleton", "THE SINGLETON HAS NOT BEEN REALOCATED, IT 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 deleted file mode 100644 index 471754ba3..000000000 --- a/src/network/stk_host.cpp +++ /dev/null @@ -1,239 +0,0 @@ -// -// 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 "graphics/irr_driver.hpp" // get access to irrlicht sleep function -#include "network/network_manager.hpp" -#include "utils/log.hpp" - -#include -#ifdef WIN32 -# include "Ws2tcpip.h" -# define inet_ntop InetNtop -#else -# include -#endif -#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::error("STKHost", "An error occurred while trying to create an ENet \ - server host."); - 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::error("STKHost", "An error occurred while trying to create an ENet \ - client host."); - 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, (char*)data, length, 0,(sockaddr*)&to, to_len); - printf("Raw packet sent to %u:%u\n", dst.ip, dst.port); -} - -// ---------------------------------------------------------------------------- - -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,(char*)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,(char*)buffer,2048, 0); - irr_driver->getDevice()->sleep(1); - } - 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, (char*)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, (char*)buffer, 2048, 0, &addr, &from_len); - irr_driver->getDevice()->sleep(1); // 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", s); - } - return buffer; -} - -// ---------------------------------------------------------------------------- - -void STKHost::broadcastPacket(const NetworkString& data) -{ - ENetPacket* packet = enet_packet_create(data.c_str(), data.size()+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 == turnEndianness(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 == turnEndianness(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 deleted file mode 100644 index bd2e1ee23..000000000 --- a/src/network/stk_host.hpp +++ /dev/null @@ -1,145 +0,0 @@ -// -// 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 "network/types.hpp" -#include "network/network_string.hpp" - -#include - -#include - -/*! \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 NetworkString& 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 deleted file mode 100644 index 48994caae..000000000 --- a/src/network/stk_peer.cpp +++ /dev/null @@ -1,85 +0,0 @@ -// -// 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 & 0xff000000) >> 24) - + ((host.ip & 0x00ff0000) >> 8) - + ((host.ip & 0x0000ff00) << 8) - + ((host.ip & 0x000000ff) << 24); // because ENet wants little endian - address.port = host.port; - - ENetPeer* peer = enet_host_connect(localhost->m_host, &address, 2, 0); - if (peer == NULL) - { - 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(NetworkString const& data) -{ - Log::info("STKPeer", "sending packet of size %d to %i.%i.%i.%i:%i", data.size(), (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.c_str(), data.size()+1,ENET_PACKET_FLAG_RELIABLE); - - enet_peer_send(m_peer, 0, packet); -} - -uint32_t STKPeer::getAddress() const -{ - return m_peer->address.host; -} - -uint16_t STKPeer::getPort() const -{ - return m_peer->address.port; -} - -bool STKPeer::isConnected() const -{ - Log::info("STKPeer", "The peer state is %i\n", m_peer->state); - return (m_peer->state == ENET_PEER_STATE_CONNECTED); -} -bool STKPeer::operator==(const ENetPeer* peer) const -{ - return peer==m_peer; -} diff --git a/src/network/stk_peer.hpp b/src/network/stk_peer.hpp deleted file mode 100644 index c84ae673a..000000000 --- a/src/network/stk_peer.hpp +++ /dev/null @@ -1,54 +0,0 @@ -// -// 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 STK_PEER_HPP -#define STK_PEER_HPP - -#include "network/stk_host.hpp" -#include "network/network_string.hpp" -#include - -class STKPeer -{ - friend class Event; - public: - STKPeer(); - virtual ~STKPeer(); - - virtual void sendPacket(const NetworkString& data); - - static bool connectToHost(STKHost* localhost, TransportAddress host, uint32_t channel_count, uint32_t data); - - bool isConnected() const; - void setClientServerToken(const uint32_t& token) { m_client_server_token = token; m_token_set = true; } - void unsetClientServerToken() { m_token_set = false; } - - uint32_t getAddress() const; - uint16_t getPort() const; - uint32_t getClientServerToken() const; - bool isClientServerTokenSet() const { return m_token_set; } - - bool operator==(const ENetPeer* peer) const; - - protected: - ENetPeer* m_peer; - uint32_t m_client_server_token; - bool m_token_set; -}; - -#endif // STK_PEER_HPP diff --git a/src/network/types.cpp b/src/network/types.cpp deleted file mode 100644 index deb244c32..000000000 --- a/src/network/types.cpp +++ /dev/null @@ -1,9 +0,0 @@ -#include "network/types.hpp" - -uint32_t turnEndianness(uint32_t val) -{ - return ((val&0xff000000)>>24) - +((val&0x00ff0000)>>8) - +((val&0x0000ff00)<<8) - +((val&0x000000ff)<<24); -} diff --git a/src/network/types.hpp b/src/network/types.hpp deleted file mode 100644 index 81d8f2bc0..000000000 --- a/src/network/types.hpp +++ /dev/null @@ -1,71 +0,0 @@ -// -// 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 "utils/types.hpp" - -#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 -}; - -uint32_t turnEndianness(uint32_t val); - - -#endif // TYPES_HPP diff --git a/src/network/world_loaded_message.hpp b/src/network/world_loaded_message.hpp new file mode 100644 index 000000000..682e0fa05 --- /dev/null +++ b/src/network/world_loaded_message.hpp @@ -0,0 +1,31 @@ +// +// 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 5c528ff57..eaaeee67d 100644 --- a/src/physics/physics.cpp +++ b/src/physics/physics.cpp @@ -19,11 +19,9 @@ #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 "items/flyable.hpp" -#include "modes/world.hpp" +#include "network/race_state.hpp" #include "graphics/stars.hpp" #include "karts/explosion_animation.hpp" #include "physics/btKart.hpp" @@ -158,6 +156,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()); KartKartCollision(p->getUserPointer(0)->getPointerKart(), p->getContactPointCS(0), p->getUserPointer(1)->getPointerKart(), @@ -443,6 +443,7 @@ btScalar Physics::solveGroup(btCollisionObject** bodies, int numBodies, else if(upB->is(UserPointer::UP_KART)) { AbstractKart *kart=upB->getPointerKart(); + race_state->addCollision(kart->getWorldKartId()); int n = contact_manifold->getContactPoint(0).m_index0; const Material *m = n>=0 ? upA->getPointerTriangleMesh()->getMaterial(n) @@ -462,6 +463,7 @@ btScalar Physics::solveGroup(btCollisionObject** bodies, int numBodies, if(upB->is(UserPointer::UP_TRACK)) { AbstractKart *kart = upA->getPointerKart(); + 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 71d38a034..22aa430ed 100644 --- a/src/race/history.hpp +++ b/src/race/history.hpp @@ -20,7 +20,6 @@ #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 2c61ea0ad..b7247bedf 100644 --- a/src/race/race_manager.cpp +++ b/src/race/race_manager.cpp @@ -42,6 +42,7 @@ #include "modes/world.hpp" #include "modes/three_strikes_battle.hpp" #include "modes/soccer_world.hpp" +#include "network/network_manager.hpp" #include "states_screens/grand_prix_lose.hpp" #include "states_screens/grand_prix_win.hpp" #include "states_screens/kart_selection.hpp" @@ -144,7 +145,7 @@ void RaceManager::setLocalKartInfo(unsigned int player_id, m_local_player_karts[player_id] = RemoteKartInfo(player_id, kart, StateManager::get()->getActivePlayerProfile(player_id)->getName(), - 0); + network_manager->getMyHostId()); } // setLocalKartInfo //----------------------------------------------------------------------------- @@ -292,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(); - Log::verbose("RaceManager", "Nb of karts=%u, ai:%lu players:%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) @@ -320,7 +321,8 @@ void RaceManager::startNew(bool from_overworld) // ------------------------------------------------- for(int i=m_player_karts.size()-1; i>=0; i--) { - KartType kt= KT_PLAYER; + KartType kt=(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(), @@ -507,10 +509,21 @@ 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); 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); exitRace(); } } // next @@ -740,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 - race_manager->setupPlayerKartInfo(); + network_manager->setupPlayerKartInfo(); setMajorMode(RaceManager::MAJOR_MODE_GRAND_PRIX); startNew(from_overworld); @@ -765,36 +778,9 @@ void RaceManager::startSingleRace(const std::string &track_ident, setMajorMode(RaceManager::MAJOR_MODE_SINGLE); setCoinTarget( 0 ); // Might still be set from a previous challenge - race_manager->setupPlayerKartInfo(); + network_manager->setupPlayerKartInfo(); startNew(from_overworld); } -//----------------------------------------------------------------------------- -/** Receive and store the information from sendKartsInformation() -*/ -void RaceManager::setupPlayerKartInfo() -{ - std::vector m_kart_info; - - // Get the local kart info - for(unsigned int i=0; igetText().trim(); const stringw password = m_password_widget->getText().trim(); - stringw info = ""; - if(CurrentOnlineUser::get()->signIn(username,password,info)) + if (username.size() < 4 || username.size() > 30 || password.size() < 8 || password.size() > 30) { - m_self_destroy = true; + sfx_manager->quickSound("anvil"); + m_info_widget->setErrorColor(); + m_info_widget->setText(_("Username and/or password invalid."), false); } else { - sfx_manager->quickSound( "anvil" ); - m_message_widget->setColor(irr::video::SColor(255, 255, 0, 0)); - m_message_widget->setText(info, false); + m_options_widget->setDeactivated(); + m_sign_in_request = Online::CurrentUser::get()->requestSignIn(username,password, m_remember_widget->getState()); } } @@ -144,6 +144,11 @@ GUIEngine::EventPropagation LoginDialog::processEvent(const std::string& eventSo m_open_registration_dialog = true; return GUIEngine::EVENT_BLOCK; } + else if(selection == m_recovery_widget->m_properties[PROP_ID]) + { + m_open_recovery_dialog = true; + return GUIEngine::EVENT_BLOCK; + } } return GUIEngine::EVENT_LET; } @@ -157,7 +162,8 @@ void LoginDialog::onEnterPressedInternal() const int playerID = PLAYER_ID_GAME_MASTER; if (GUIEngine::isFocusedForPlayer(m_options_widget, playerID)) return; - login(); + if (m_sign_in_widget->isActivated()) + login(); } // ----------------------------------------------------------------------------- diff --git a/src/states_screens/dialogs/race_paused_dialog.cpp b/src/states_screens/dialogs/race_paused_dialog.cpp index 3e98e0caa..3e46dea4b 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 c8267be1b..174d67358 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 - race_manager->setupPlayerKartInfo(); + network_manager->setupPlayerKartInfo(); race_manager->startNew(true); irr_driver->hidePointer(); diff --git a/src/states_screens/dialogs/track_info_dialog.cpp b/src/states_screens/dialogs/track_info_dialog.cpp index 0272be680..a9ea32304 100644 --- a/src/states_screens/dialogs/track_info_dialog.cpp +++ b/src/states_screens/dialogs/track_info_dialog.cpp @@ -28,6 +28,7 @@ #include "io/file_manager.hpp" #include "karts/kart_properties.hpp" #include "karts/kart_properties_manager.hpp" +#include "network/network_manager.hpp" #include "race/highscores.hpp" #include "race/highscore_manager.hpp" #include "race/race_manager.hpp" diff --git a/src/states_screens/help_screen_1.cpp b/src/states_screens/help_screen_1.cpp index edd38a1f6..20ac321d9 100644 --- a/src/states_screens/help_screen_1.cpp +++ b/src/states_screens/help_screen_1.cpp @@ -24,6 +24,7 @@ #include "input/device_manager.hpp" #include "input/input_manager.hpp" #include "karts/kart_properties_manager.hpp" +#include "network/network_manager.hpp" #include "race/race_manager.hpp" #include "states_screens/help_screen_2.hpp" #include "states_screens/help_screen_3.hpp" @@ -81,7 +82,7 @@ void HelpScreen1::eventCallback(Widget* widget, const std::string& name, const i ->setSinglePlayer( StateManager::get()->getActivePlayer(0) ); StateManager::get()->enterGameState(); - race_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 677d2c554..06b632b00 100644 --- a/src/states_screens/main_menu_screen.cpp +++ b/src/states_screens/main_menu_screen.cpp @@ -37,6 +37,7 @@ #include "modes/cutscene_world.hpp" #include "modes/overworld.hpp" #include "modes/demo_world.hpp" +#include "network/network_manager.hpp" #include "states_screens/online_screen.hpp" #include "states_screens/addons_screen.hpp" #include "states_screens/credits.hpp" @@ -331,7 +332,7 @@ void MainMenuScreen::eventCallback(Widget* widget, const std::string& name, ->setSinglePlayer( StateManager::get()->getActivePlayer(0) ); StateManager::get()->enterGameState(); - race_manager->setupPlayerKartInfo(); + network_manager->setupPlayerKartInfo(); race_manager->startNew(false); } else if (selection == "story") diff --git a/src/states_screens/networking_lobby_settings.cpp b/src/states_screens/networking_lobby_settings.cpp deleted file mode 100644 index 8e82fc313..000000000 --- a/src/states_screens/networking_lobby_settings.cpp +++ /dev/null @@ -1,114 +0,0 @@ -// SuperTuxKart - a fun racing game with go-kart -// Copyright (C) 2013 Glenn De Jonghe -// -// 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. - -#define DEBUG_MENU_ITEM 0 - -#include "states_screens/networking_lobby_settings.hpp" - -#include -#include - -#include "challenges/game_slot.hpp" -#include "challenges/unlock_manager.hpp" -#include "graphics/irr_driver.hpp" -#include "guiengine/scalable_font.hpp" -#include "input/device_manager.hpp" -#include "input/input_manager.hpp" -#include "io/file_manager.hpp" -#include "main_loop.hpp" -#include "states_screens/online_screen.hpp" -#include "states_screens/state_manager.hpp" -#include "states_screens/dialogs/message_dialog.hpp" -#include "modes/demo_world.hpp" -#include "utils/translation.hpp" - -#include "online/current_online_user.hpp" - - -using namespace GUIEngine; - -DEFINE_SCREEN_SINGLETON( NetworkingLobbySettings ); - -// ---------------------------------------------------------------------------- - -NetworkingLobbySettings::NetworkingLobbySettings() : Screen("online/lobby_settings.stkgui") -{ - -} // NetworkingLobbySettings - -// ---------------------------------------------------------------------------- - -void NetworkingLobbySettings::loadedFromFile() -{ - -} // loadedFromFile - -// ---------------------------------------------------------------------------- -bool NetworkingLobbySettings::hasLostConnection() -{ - return !CurrentOnlineUser::get()->isSignedIn(); -} - -// ---------------------------------------------------------------------------- -void NetworkingLobbySettings::beforeAddingWidget() -{ - -} // beforeAddingWidget - - - -// ---------------------------------------------------------------------------- -void NetworkingLobbySettings::init() -{ - Screen::init(); - setInitialFocus(); - DemoWorld::resetIdleTime(); //FIXME : what's this?} // init -} -// ---------------------------------------------------------------------------- -void NetworkingLobbySettings::onUpdate(float delta, irr::video::IVideoDriver* driver) -{ -} // onUpdate - -// ---------------------------------------------------------------------------- - -void NetworkingLobbySettings::eventCallback(Widget* widget, const std::string& name, const int playerID) -{ - -} // eventCallback - -// ---------------------------------------------------------------------------- - -void NetworkingLobbySettings::tearDown() -{ -} // tearDown - -// ---------------------------------------------------------------------------- -void NetworkingLobbySettings::onDisabledItemClicked(const std::string& item) -{ - -} // onDisabledItemClicked - -// ---------------------------------------------------------------------------- -void NetworkingLobbySettings::setInitialFocus() -{ -} // setInitialFocus - -// ---------------------------------------------------------------------------- -void NetworkingLobbySettings::onDialogClose() -{ - setInitialFocus(); -} // onDialogClose() diff --git a/src/states_screens/networking_lobby_settings.hpp b/src/states_screens/networking_lobby_settings.hpp deleted file mode 100644 index 234af94df..000000000 --- a/src/states_screens/networking_lobby_settings.hpp +++ /dev/null @@ -1,78 +0,0 @@ -// SuperTuxKart - a fun racing game with go-kart -// Copyright (C) 2013 Glenn De Jonghe -// -// 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_NETWORKING_LOBBY_SETTINGS_HPP -#define HEADER_NETWORKING_LOBBY_SETTINGS_HPP - -#include "guiengine/screen.hpp" -#include "guiengine/widgets/label_widget.hpp" -#include "guiengine/widgets/ribbon_widget.hpp" -#include "guiengine/widgets/icon_button_widget.hpp" - -namespace GUIEngine { class Widget; class ListWidget; } - -/** - * \brief Handles the main menu - * \ingroup states_screens - */ -class NetworkingLobbySettings : public GUIEngine::Screen, - public GUIEngine::ScreenSingleton -{ -private: - friend class GUIEngine::ScreenSingleton; - - NetworkingLobbySettings(); - - /** \brief Checks if the user is still signed in. */ - bool hasLostConnection(); - /** \brief Sets which widget has to be focused. Depends on the user state. */ - void setInitialFocus(); - -public: - - enum Action - { - Create = 1, // A new server should be created - Edit = 2, // The settings of the server should be edited - }; - - virtual void onUpdate(float delta, irr::video::IVideoDriver* driver) OVERRIDE; - - /** \brief implement callback from parent class GUIEngine::Screen */ - virtual void loadedFromFile() OVERRIDE; - - /** \brief implement callback from parent class GUIEngine::Screen */ - virtual void eventCallback(GUIEngine::Widget* widget, const std::string& name, - const int playerID) OVERRIDE; - - /** \brief implement callback from parent class GUIEngine::Screen */ - virtual void beforeAddingWidget() OVERRIDE; - - /** \brief implement callback from parent class GUIEngine::Screen */ - virtual void init() OVERRIDE; - - /** \brief implement callback from parent class GUIEngine::Screen */ - virtual void tearDown() OVERRIDE; - - /** \brief implement callback from parent class GUIEngine::Screen */ - virtual void onDisabledItemClicked(const std::string& item) OVERRIDE; - - /** \brief Implements the callback when a dialog gets closed. */ - virtual void onDialogClose() OVERRIDE; -}; - -#endif diff --git a/src/states_screens/online_screen.cpp b/src/states_screens/online_screen.cpp index faca86948..2933c5735 100644 --- a/src/states_screens/online_screen.cpp +++ b/src/states_screens/online_screen.cpp @@ -34,15 +34,13 @@ #include "states_screens/dialogs/login_dialog.hpp" #include "states_screens/dialogs/registration_dialog.hpp" #include "states_screens/networking_lobby.hpp" -#include "states_screens/networking_lobby_settings.hpp" +#include "states_screens/server_selection.hpp" +#include "states_screens/create_server_screen.hpp" #include "modes/demo_world.hpp" #include "online/servers_manager.hpp" #include "online/messages.hpp" -#include "network/protocol_manager.hpp" -#include "network/protocols/connect_to_server.hpp" - using namespace GUIEngine; using namespace Online; @@ -218,14 +216,23 @@ void OnlineScreen::eventCallback(Widget* widget, const std::string& name, const } else if (selection == "create_server") { - //if (m_recorded_state == Registered) - StateManager::get()->pushScreen(NetworkingLobbySettings::getInstance()); + StateManager::get()->pushScreen(CreateServerScreen::getInstance()); } else if (selection == "quick_play") { - //if (m_recorded_state == Registered || m_recorded_state == Guest) FIXME - StateManager::get()->pushScreen(NetworkingLobby::getInstance()); - ProtocolManager::getInstance()->requestStart(new ConnectToServer(7)); + //FIXME temporary and the request join + join sequence should be placed in one method somewhere + /* + Server * server = ServersManager::get()->getQuickPlay(); + irr::core::stringw info; + if (Online::CurrentUser::get()->requestJoin( server->getServerId(), info)) + { + ServersManager::get()->setJoinedServer(server); + StateManager::get()->pushScreen(NetworkingLobby::getInstance()); + } + else + { + sfx_manager->quickSound( "anvil" ); + }*/ } } // eventCallback @@ -244,8 +251,7 @@ void OnlineScreen::onDisabledItemClicked(const std::string& item) } else if (item =="create_server") { - StateManager::get()->pushScreen(NetworkingLobbySettings::getInstance()); - // FIXME temporary; new LoginDialog(LoginDialog::Registration_Required); + new LoginDialog(LoginDialog::Registration_Required); } else if (item == "quick_play") { diff --git a/src/tracks/track.cpp b/src/tracks/track.cpp index bca42f20b..c16d41fcd 100644 --- a/src/tracks/track.cpp +++ b/src/tracks/track.cpp @@ -494,16 +494,8 @@ void Track::loadQuadGraph(unsigned int mode_id, const bool reverse) core::dimension2du size = m_mini_map_size .getOptimalSize(!nonpower,!nonsquare); m_mini_map = QuadGraph::get()->makeMiniMap(size, "minimap::"+m_ident); - if (m_mini_map) - { - m_minimap_x_scale = float(m_mini_map_size.Width) / float(m_mini_map->getSize().Width); - m_minimap_y_scale = float(m_mini_map_size.Height) / float(m_mini_map->getSize().Height); - } - else - { - m_minimap_x_scale = 0; - m_minimap_y_scale = 0; - } + m_minimap_x_scale = float(m_mini_map_size.Width) / float(m_mini_map->getSize().Width); + m_minimap_y_scale = float(m_mini_map_size.Height) / float(m_mini_map->getSize().Height); } } // loadQuadGraph // ----------------------------------------------------------------------------- diff --git a/src/utils/types.hpp b/src/utils/types.hpp index 6d094cf91..dd8ace861 100644 --- a/src/utils/types.hpp +++ b/src/utils/types.hpp @@ -20,8 +20,6 @@ #define HEADER_TYPES_HPP #ifdef _MSC_VER - typedef unsigned char uint8_t; - typedef unsigned short uint16_t; typedef __int32 int32_t; typedef unsigned __int32 uint32_t; typedef __int64 int64_t;